aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS15
-rw-r--r--COPYRIGHT2
-rw-r--r--Makefile1
-rw-r--r--NEWS44
-rw-r--r--README300
-rw-r--r--audio/adlib.cpp (renamed from audio/softsynth/adlib.cpp)50
-rw-r--r--audio/alsa_opl.cpp349
-rw-r--r--audio/decoders/3do.cpp343
-rw-r--r--audio/decoders/3do.h158
-rw-r--r--audio/decoders/aiff.cpp212
-rw-r--r--audio/decoders/aiff.h16
-rw-r--r--audio/decoders/mp3.cpp17
-rw-r--r--audio/decoders/quicktime.cpp9
-rw-r--r--audio/decoders/wave.h10
-rw-r--r--audio/fmopl.cpp184
-rw-r--r--audio/fmopl.h154
-rw-r--r--audio/midiparser.h3
-rw-r--r--audio/midiparser_xmidi.cpp49
-rw-r--r--audio/miles.h83
-rw-r--r--audio/miles_adlib.cpp1274
-rw-r--r--audio/miles_mt32.cpp912
-rw-r--r--audio/mods/protracker.cpp9
-rw-r--r--audio/module.mk10
-rw-r--r--audio/softsynth/mt32/Analog.cpp348
-rw-r--r--audio/softsynth/mt32/Analog.h57
-rw-r--r--audio/softsynth/mt32/BReverbModel.cpp10
-rw-r--r--audio/softsynth/mt32/BReverbModel.h2
-rw-r--r--audio/softsynth/mt32/LA32FloatWaveGenerator.cpp2
-rw-r--r--audio/softsynth/mt32/LA32Ramp.cpp2
-rw-r--r--audio/softsynth/mt32/LA32WaveGenerator.cpp10
-rw-r--r--audio/softsynth/mt32/MemoryRegion.h124
-rw-r--r--audio/softsynth/mt32/MidiEventQueue.h67
-rw-r--r--audio/softsynth/mt32/Part.cpp1
-rw-r--r--audio/softsynth/mt32/Partial.cpp5
-rw-r--r--audio/softsynth/mt32/PartialManager.cpp1
-rw-r--r--audio/softsynth/mt32/Poly.cpp1
-rw-r--r--audio/softsynth/mt32/Poly.h1
-rw-r--r--audio/softsynth/mt32/ROMInfo.cpp15
-rw-r--r--audio/softsynth/mt32/ROMInfo.h4
-rw-r--r--audio/softsynth/mt32/Structures.h47
-rw-r--r--audio/softsynth/mt32/Synth.cpp248
-rw-r--r--audio/softsynth/mt32/Synth.h347
-rw-r--r--audio/softsynth/mt32/TVA.cpp1
-rw-r--r--audio/softsynth/mt32/TVF.cpp1
-rw-r--r--audio/softsynth/mt32/TVP.cpp1
-rw-r--r--audio/softsynth/mt32/Tables.cpp5
-rw-r--r--audio/softsynth/mt32/Tables.h15
-rw-r--r--audio/softsynth/mt32/Types.h40
-rw-r--r--audio/softsynth/mt32/internals.h83
-rw-r--r--audio/softsynth/mt32/module.mk1
-rw-r--r--audio/softsynth/mt32/mt32emu.h67
-rw-r--r--audio/softsynth/opl/dosbox.cpp12
-rw-r--r--audio/softsynth/opl/dosbox.h8
-rw-r--r--audio/softsynth/opl/mame.cpp14
-rw-r--r--audio/softsynth/opl/mame.h8
-rw-r--r--audio/timestamp.cpp6
-rw-r--r--backends/audiocd/sdl/sdl-audiocd.cpp7
-rw-r--r--backends/audiocd/sdl/sdl-audiocd.h4
-rw-r--r--backends/events/sdl/sdl-events.cpp210
-rw-r--r--backends/events/sdl/sdl-events.h31
-rw-r--r--backends/events/symbiansdl/symbiansdl-events.cpp4
-rw-r--r--backends/fs/amigaos4/amigaos4-fs.cpp8
-rw-r--r--backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp6
-rw-r--r--backends/graphics/dinguxsdl/dinguxsdl-graphics.h2
-rw-r--r--backends/graphics/gph/gph-graphics.cpp6
-rw-r--r--backends/graphics/gph/gph-graphics.h2
-rw-r--r--backends/graphics/linuxmotosdl/linuxmotosdl-graphics.cpp6
-rw-r--r--backends/graphics/linuxmotosdl/linuxmotosdl-graphics.h2
-rw-r--r--backends/graphics/maemosdl/maemosdl-graphics.cpp6
-rw-r--r--backends/graphics/maemosdl/maemosdl-graphics.h2
-rw-r--r--backends/graphics/opengl/opengl-graphics.cpp84
-rw-r--r--backends/graphics/opengl/opengl-graphics.h17
-rw-r--r--backends/graphics/openglsdl/openglsdl-graphics.cpp145
-rw-r--r--backends/graphics/openglsdl/openglsdl-graphics.h8
-rw-r--r--backends/graphics/openpandora/op-graphics.cpp4
-rw-r--r--backends/graphics/openpandora/op-graphics.h2
-rw-r--r--backends/graphics/samsungtvsdl/samsungtvsdl-graphics.cpp4
-rw-r--r--backends/graphics/samsungtvsdl/samsungtvsdl-graphics.h2
-rw-r--r--backends/graphics/sdl/sdl-graphics.cpp39
-rw-r--r--backends/graphics/sdl/sdl-graphics.h34
-rw-r--r--backends/graphics/surfacesdl/surfacesdl-graphics.cpp125
-rw-r--r--backends/graphics/surfacesdl/surfacesdl-graphics.h16
-rw-r--r--backends/graphics/symbiansdl/symbiansdl-graphics.cpp4
-rw-r--r--backends/graphics/symbiansdl/symbiansdl-graphics.h2
-rw-r--r--backends/graphics/wincesdl/wincesdl-graphics.cpp4
-rw-r--r--backends/graphics/wincesdl/wincesdl-graphics.h2
-rw-r--r--backends/log/log.cpp4
-rw-r--r--backends/mixer/doublebuffersdl/doublebuffersdl-mixer.cpp4
-rw-r--r--backends/mixer/sdl/sdl-mixer.cpp4
-rw-r--r--backends/module.mk2
-rw-r--r--backends/platform/android/android.cpp12
-rw-r--r--backends/platform/android/android.h8
-rw-r--r--backends/platform/android/android.mk200
-rw-r--r--backends/platform/android/jni.cpp46
-rw-r--r--backends/platform/android/jni.h2
-rw-r--r--backends/platform/android/org/scummvm/scummvm/PluginProvider.java63
-rw-r--r--backends/platform/android/org/scummvm/scummvm/ScummVM.java7
-rw-r--r--backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java7
-rw-r--r--backends/platform/android/org/scummvm/scummvm/ScummVMApplication.java31
-rw-r--r--backends/platform/android/org/scummvm/scummvm/Unpacker.java388
-rw-r--r--backends/platform/dingux/dingux.cpp2
-rw-r--r--backends/platform/gph/gph-backend.cpp2
-rw-r--r--backends/platform/linuxmoto/linuxmoto-sdl.cpp2
-rw-r--r--backends/platform/maemo/maemo.cpp21
-rw-r--r--backends/platform/maemo/maemo.h2
-rw-r--r--backends/platform/openpandora/op-backend.cpp2
-rw-r--r--backends/platform/samsungtv/samsungtv.cpp2
-rw-r--r--backends/platform/sdl/macosx/macosx.cpp7
-rw-r--r--backends/platform/sdl/macosx/macosx.h1
-rw-r--r--backends/platform/sdl/module.mk4
-rw-r--r--backends/platform/sdl/sdl-sys.h117
-rw-r--r--backends/platform/sdl/sdl-window.cpp223
-rw-r--r--backends/platform/sdl/sdl-window.h112
-rw-r--r--backends/platform/sdl/sdl.cpp171
-rw-r--r--backends/platform/sdl/sdl.h11
-rw-r--r--backends/platform/sdl/win32/win32-main.cpp2
-rw-r--r--backends/platform/sdl/win32/win32-window.cpp59
-rw-r--r--backends/platform/sdl/win32/win32-window.h (renamed from engines/zvision/detection.h)22
-rw-r--r--backends/platform/sdl/win32/win32.cpp30
-rw-r--r--backends/platform/sdl/win32/win32.h1
-rw-r--r--backends/platform/symbian/AdaptAllMMPs.pl5
-rw-r--r--backends/platform/symbian/BuildPackageUpload_LocalSettings.pl40
-rw-r--r--backends/platform/symbian/README2
-rw-r--r--backends/platform/symbian/S60/ScummVM_S60.mmp.in2
-rw-r--r--backends/platform/symbian/S60/ScummVM_S60_App.mmp2
-rw-r--r--backends/platform/symbian/S60v3/ScummVM_A0000658_S60v3.mmp.in2
-rw-r--r--backends/platform/symbian/S60v3/ScummVM_S60v3.mmp.in2
-rw-r--r--backends/platform/symbian/S80/ScummVM_S80.mmp.in2
-rw-r--r--backends/platform/symbian/S80/ScummVM_S80_App.mmp2
-rw-r--r--backends/platform/symbian/S90/Scummvm_S90.mmp.in2
-rw-r--r--backends/platform/symbian/S90/Scummvm_S90_App.mmp2
-rw-r--r--backends/platform/symbian/UIQ2/ScummVM.rss2
-rw-r--r--backends/platform/symbian/UIQ3/ScummVM.rss2
-rw-r--r--backends/platform/symbian/UIQ3/ScummVM_A0000658.rss2
-rw-r--r--backends/platform/symbian/UIQ3/ScummVM_A0000658_UIQ3.mmp.in2
-rw-r--r--backends/platform/symbian/UIQ3/ScummVM_UIQ3.mmp.in2
-rw-r--r--backends/platform/symbian/UIQ3/scummvm_A0000658_loc.rss2
-rw-r--r--backends/platform/symbian/help/ScummVM.rtf78
-rw-r--r--backends/platform/symbian/mmp/config.mmh2
-rw-r--r--backends/platform/symbian/mmp/scummvm_access.mmp.in52
-rw-r--r--backends/platform/symbian/mmp/scummvm_agi.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_agos.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_avalanche.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_base.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_bbvs.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_cge.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_cge2.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_cine.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_composer.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_cruise.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_draci.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_drascula.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_dreamweb.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_fullpipe.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_gob.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_groovie.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_hopkins.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_hugo.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_kyra.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_lastexpress.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_lure.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_m4.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_made.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_mads.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_mohawk.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_mortevielle.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_neverhood.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_parallaction.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_pegasus.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_prince.mmp.in52
-rw-r--r--backends/platform/symbian/mmp/scummvm_queen.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_saga.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_sci.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_scumm.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_sky.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_sword1.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_sword2.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_sword25.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_teenagent.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_testbed.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_tinsel.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_toltecs.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_tony.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_toon.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_touche.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_tsage.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_tucker.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_voyeur.mmp.in24
-rw-r--r--backends/platform/symbian/mmp/scummvm_wintermute.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_zvision.mmp.in3
-rw-r--r--backends/platform/symbian/res/ScummVmAif.rss2
-rw-r--r--backends/platform/symbian/res/scummvm.rss2
-rw-r--r--backends/platform/symbian/res/scummvm_A0000658.rss2
-rw-r--r--backends/platform/symbian/src/ScummVm.hrh2
-rw-r--r--backends/platform/symbian/src/SymbianOS.cpp8
-rw-r--r--backends/platform/symbian/src/SymbianOS.h1
-rw-r--r--backends/platform/wince/wince-sdl.cpp2
-rw-r--r--backends/taskbar/win32/win32-taskbar.cpp18
-rw-r--r--backends/taskbar/win32/win32-taskbar.h6
-rw-r--r--base/main.cpp31
-rw-r--r--common/dcl.cpp221
-rw-r--r--common/dcl.h17
-rw-r--r--common/endian.h219
-rw-r--r--common/fft.cpp8
-rw-r--r--common/fft.h2
-rw-r--r--common/stream.h96
-rwxr-xr-xconfigure37
-rw-r--r--devtools/create_project/create_project.cpp33
-rw-r--r--devtools/create_project/xcode.cpp443
-rw-r--r--devtools/create_project/xcode.h42
-rwxr-xr-xdevtools/credits.pl15
-rw-r--r--devtools/scumm-md5.txt22
-rw-r--r--dists/android/AndroidManifest.xml19
-rw-r--r--dists/android/AndroidManifest.xml.in19
-rw-r--r--dists/android/custom_rules.xml31
-rw-r--r--dists/android/jni/Android.mk9
-rwxr-xr-xdists/android/mkplugin.sh16
-rw-r--r--dists/android/plugin-manifest.xml35
-rw-r--r--dists/android/plugin-manifest.xml.in35
-rw-r--r--dists/android/plugin-strings.xml6
-rw-r--r--dists/android/project.properties11
-rw-r--r--dists/android/res/drawable/gradient.xml7
-rw-r--r--dists/android/res/layout/main.xml4
-rw-r--r--dists/android/res/layout/splash.xml19
-rw-r--r--dists/codeblocks/readme.txt2
-rw-r--r--dists/debian/copyright2
-rw-r--r--dists/iphone/readme.txt7
-rw-r--r--dists/iphone/scummvm.xcodeproj/project.pbxproj12331
-rw-r--r--dists/macosx/Info.plist4
-rw-r--r--dists/macosx/Info.plist.in4
-rw-r--r--dists/scummvm.rc2
-rw-r--r--dists/scummvm.rc.in2
-rw-r--r--dists/win32/scummvm.nsi2
-rw-r--r--dists/win32/scummvm.nsi.in2
-rw-r--r--doc/de/Liesmich412
-rw-r--r--doc/de/Neues96
-rw-r--r--doc/de/Spieletitel Original-Deutsch Deutsch-Original61
-rw-r--r--engines/access/access.cpp20
-rw-r--r--engines/access/amazon/amazon_game.cpp21
-rw-r--r--engines/access/amazon/amazon_logic.cpp134
-rw-r--r--engines/access/amazon/amazon_logic.h2
-rw-r--r--engines/access/amazon/amazon_scripts.cpp32
-rw-r--r--engines/access/animation.cpp4
-rw-r--r--engines/access/animation.h1
-rw-r--r--engines/access/asurface.cpp20
-rw-r--r--engines/access/asurface.h12
-rw-r--r--engines/access/bubble_box.h1
-rw-r--r--engines/access/char.cpp4
-rw-r--r--engines/access/char.h3
-rw-r--r--engines/access/decompress.cpp49
-rw-r--r--engines/access/decompress.h3
-rw-r--r--engines/access/events.cpp2
-rw-r--r--engines/access/files.cpp4
-rw-r--r--engines/access/files.h2
-rw-r--r--engines/access/font.cpp2
-rw-r--r--engines/access/inventory.cpp1
-rw-r--r--engines/access/player.cpp9
-rw-r--r--engines/access/player.h1
-rw-r--r--engines/access/resources.cpp20
-rw-r--r--engines/access/room.cpp6
-rw-r--r--engines/access/room.h1
-rw-r--r--engines/access/screen.cpp15
-rw-r--r--engines/access/screen.h6
-rw-r--r--engines/access/scripts.cpp6
-rw-r--r--engines/access/sound.cpp152
-rw-r--r--engines/access/sound.h13
-rw-r--r--engines/access/video.cpp13
-rw-r--r--engines/agi/agi.cpp94
-rw-r--r--engines/agi/agi.h5
-rw-r--r--engines/agi/detection.cpp63
-rw-r--r--engines/agi/detection_tables.h174
-rw-r--r--engines/agi/font.h271
-rw-r--r--engines/agi/graphics.cpp11
-rw-r--r--engines/agi/graphics.h2
-rw-r--r--engines/agi/loader_v2.cpp8
-rw-r--r--engines/agi/loader_v3.cpp5
-rw-r--r--engines/agi/preagi.cpp8
-rw-r--r--engines/agi/preagi_mickey.cpp2
-rw-r--r--engines/agi/sound_pcjr.cpp13
-rw-r--r--engines/agi/text.cpp4
-rw-r--r--engines/agos/agos.cpp4
-rw-r--r--engines/agos/detection_tables.h8
-rw-r--r--engines/agos/drivers/accolade/adlib.cpp883
-rw-r--r--engines/agos/drivers/accolade/driverfile.cpp166
-rw-r--r--engines/agos/drivers/accolade/mididriver.h44
-rw-r--r--engines/agos/drivers/accolade/mt32.cpp278
-rw-r--r--engines/agos/gfx.cpp7
-rw-r--r--engines/agos/input.cpp1
-rw-r--r--engines/agos/midi.cpp359
-rw-r--r--engines/agos/midi.h22
-rw-r--r--engines/agos/midiparser_s1d.cpp39
-rw-r--r--engines/agos/module.mk3
-rw-r--r--engines/agos/res_snd.cpp5
-rw-r--r--engines/agos/rooms.cpp3
-rw-r--r--engines/agos/saveload.cpp7
-rw-r--r--engines/agos/sound.cpp4
-rw-r--r--engines/agos/zones.cpp3
-rw-r--r--engines/bbvs/minigames/bbairguitar.cpp115
-rw-r--r--engines/bbvs/minigames/bbairguitar.h11
-rw-r--r--engines/bbvs/sound.h2
-rw-r--r--engines/cge2/detection.cpp10
-rw-r--r--engines/cine/detection_tables.h14
-rw-r--r--engines/cine/sound.cpp127
-rw-r--r--engines/cruise/sound.cpp114
-rw-r--r--engines/drascula/actors.cpp10
-rw-r--r--engines/drascula/detection.cpp3
-rw-r--r--engines/drascula/talk.cpp47
-rw-r--r--engines/engine.cpp31
-rw-r--r--engines/engine.h28
-rw-r--r--engines/fullpipe/gameloader.cpp2
-rw-r--r--engines/fullpipe/inventory.cpp2
-rw-r--r--engines/fullpipe/mgm.cpp7
-rw-r--r--engines/fullpipe/modal.cpp2
-rw-r--r--engines/fullpipe/motion.cpp2
-rw-r--r--engines/fullpipe/scene.cpp6
-rw-r--r--engines/fullpipe/scenes/scene04.cpp9
-rw-r--r--engines/fullpipe/scenes/scene16.cpp2
-rw-r--r--engines/fullpipe/scenes/scene23.cpp4
-rw-r--r--engines/fullpipe/statics.cpp11
-rw-r--r--engines/gob/gob.cpp3
-rw-r--r--engines/gob/sound/adlib.cpp133
-rw-r--r--engines/gob/sound/adlib.h32
-rw-r--r--engines/gob/sound/adlplayer.cpp11
-rw-r--r--engines/gob/sound/adlplayer.h4
-rw-r--r--engines/gob/sound/musplayer.cpp22
-rw-r--r--engines/gob/sound/musplayer.h3
-rw-r--r--engines/gob/sound/sound.cpp18
-rw-r--r--engines/gob/sound/sound.h1
-rw-r--r--engines/gob/surface.cpp7
-rw-r--r--engines/gob/surface.h2
-rw-r--r--engines/groovie/music.cpp57
-rw-r--r--engines/groovie/music.h2
-rw-r--r--engines/hopkins/lines.cpp2
-rw-r--r--engines/hugo/mouse.cpp14
-rw-r--r--engines/kyra/sound_adlib.cpp68
-rw-r--r--engines/lure/res.h1
-rw-r--r--engines/made/database.cpp6
-rw-r--r--engines/made/made.cpp2
-rw-r--r--engines/made/music.cpp52
-rw-r--r--engines/made/music.h3
-rw-r--r--engines/made/pmvplayer.cpp20
-rw-r--r--engines/made/redreader.cpp16
-rw-r--r--engines/made/resource.cpp4
-rw-r--r--engines/made/screenfx.cpp9
-rw-r--r--engines/made/screenfx.h1
-rw-r--r--engines/made/script.cpp5
-rw-r--r--engines/made/script.h1
-rw-r--r--engines/made/scriptfuncs.cpp2
-rw-r--r--engines/made/sound.cpp26
-rw-r--r--engines/made/sound.h17
-rw-r--r--engines/mads/action.cpp7
-rw-r--r--engines/mads/action.h4
-rw-r--r--engines/mads/animation.cpp23
-rw-r--r--engines/mads/animation.h9
-rw-r--r--engines/mads/assets.cpp4
-rw-r--r--engines/mads/assets.h4
-rw-r--r--engines/mads/audio.cpp4
-rw-r--r--engines/mads/audio.h4
-rw-r--r--engines/mads/compression.cpp4
-rw-r--r--engines/mads/compression.h4
-rw-r--r--engines/mads/debugger.cpp6
-rw-r--r--engines/mads/debugger.h6
-rw-r--r--engines/mads/detection.cpp67
-rw-r--r--engines/mads/detection_tables.h18
-rw-r--r--engines/mads/dialogs.cpp8
-rw-r--r--engines/mads/dialogs.h4
-rw-r--r--engines/mads/dragonsphere/dragonsphere_scenes.cpp8
-rw-r--r--engines/mads/dragonsphere/dragonsphere_scenes.h4
-rw-r--r--engines/mads/dragonsphere/game_dragonsphere.cpp4
-rw-r--r--engines/mads/dragonsphere/game_dragonsphere.h4
-rw-r--r--engines/mads/events.cpp19
-rw-r--r--engines/mads/events.h11
-rw-r--r--engines/mads/font.cpp4
-rw-r--r--engines/mads/font.h4
-rw-r--r--engines/mads/game.cpp53
-rw-r--r--engines/mads/game.h9
-rw-r--r--engines/mads/game_data.cpp4
-rw-r--r--engines/mads/game_data.h4
-rw-r--r--engines/mads/globals.cpp4
-rw-r--r--engines/mads/globals.h4
-rw-r--r--engines/mads/hotspots.cpp13
-rw-r--r--engines/mads/hotspots.h6
-rw-r--r--engines/mads/inventory.cpp4
-rw-r--r--engines/mads/inventory.h4
-rw-r--r--engines/mads/mads.cpp67
-rw-r--r--engines/mads/mads.h14
-rw-r--r--engines/mads/menu_views.cpp36
-rw-r--r--engines/mads/menu_views.h7
-rw-r--r--engines/mads/messages.cpp22
-rw-r--r--engines/mads/messages.h8
-rw-r--r--engines/mads/module.mk2
-rw-r--r--engines/mads/msurface.cpp34
-rw-r--r--engines/mads/msurface.h11
-rw-r--r--engines/mads/nebular/dialogs_nebular.cpp162
-rw-r--r--engines/mads/nebular/dialogs_nebular.h7
-rw-r--r--engines/mads/nebular/game_nebular.cpp146
-rw-r--r--engines/mads/nebular/game_nebular.h7
-rw-r--r--engines/mads/nebular/globals_nebular.cpp4
-rw-r--r--engines/mads/nebular/globals_nebular.h8
-rw-r--r--engines/mads/nebular/menu_nebular.cpp8
-rw-r--r--engines/mads/nebular/menu_nebular.h4
-rw-r--r--engines/mads/nebular/nebular_scenes.cpp13
-rw-r--r--engines/mads/nebular/nebular_scenes.h22
-rw-r--r--engines/mads/nebular/nebular_scenes1.cpp68
-rw-r--r--engines/mads/nebular/nebular_scenes1.h4
-rw-r--r--engines/mads/nebular/nebular_scenes2.cpp146
-rw-r--r--engines/mads/nebular/nebular_scenes2.h4
-rw-r--r--engines/mads/nebular/nebular_scenes3.cpp141
-rw-r--r--engines/mads/nebular/nebular_scenes3.h4
-rw-r--r--engines/mads/nebular/nebular_scenes4.cpp72
-rw-r--r--engines/mads/nebular/nebular_scenes4.h4
-rw-r--r--engines/mads/nebular/nebular_scenes5.cpp106
-rw-r--r--engines/mads/nebular/nebular_scenes5.h4
-rw-r--r--engines/mads/nebular/nebular_scenes6.cpp152
-rw-r--r--engines/mads/nebular/nebular_scenes6.h6
-rw-r--r--engines/mads/nebular/nebular_scenes7.cpp65
-rw-r--r--engines/mads/nebular/nebular_scenes7.h4
-rw-r--r--engines/mads/nebular/nebular_scenes8.cpp70
-rw-r--r--engines/mads/nebular/nebular_scenes8.h4
-rw-r--r--engines/mads/nebular/sound_nebular.cpp150
-rw-r--r--engines/mads/nebular/sound_nebular.h80
-rw-r--r--engines/mads/palette.cpp72
-rw-r--r--engines/mads/palette.h16
-rw-r--r--engines/mads/phantom/game_phantom.cpp94
-rw-r--r--engines/mads/phantom/game_phantom.h15
-rw-r--r--engines/mads/phantom/globals_phantom.cpp49
-rw-r--r--engines/mads/phantom/globals_phantom.h143
-rw-r--r--engines/mads/phantom/phantom_scenes.cpp13
-rw-r--r--engines/mads/phantom/phantom_scenes.h84
-rw-r--r--engines/mads/phantom/phantom_scenes1.cpp282
-rw-r--r--engines/mads/phantom/phantom_scenes1.h89
-rw-r--r--engines/mads/player.cpp40
-rw-r--r--engines/mads/player.h4
-rw-r--r--engines/mads/rails.cpp4
-rw-r--r--engines/mads/rails.h4
-rw-r--r--engines/mads/resources.cpp4
-rw-r--r--engines/mads/resources.h4
-rw-r--r--engines/mads/scene.cpp21
-rw-r--r--engines/mads/scene.h8
-rw-r--r--engines/mads/scene_data.cpp8
-rw-r--r--engines/mads/scene_data.h1
-rw-r--r--engines/mads/screen.cpp182
-rw-r--r--engines/mads/screen.h27
-rw-r--r--engines/mads/sequence.cpp44
-rw-r--r--engines/mads/sequence.h13
-rw-r--r--engines/mads/sound.cpp30
-rw-r--r--engines/mads/sound.h12
-rw-r--r--engines/mads/sprites.cpp51
-rw-r--r--engines/mads/sprites.h12
-rw-r--r--engines/mads/staticres.cpp4
-rw-r--r--engines/mads/staticres.h4
-rw-r--r--engines/mads/user_interface.cpp161
-rw-r--r--engines/mads/user_interface.h11
-rw-r--r--engines/mohawk/configure.engine2
-rw-r--r--engines/mohawk/console.cpp31
-rw-r--r--engines/mohawk/cursors.cpp6
-rw-r--r--engines/mohawk/detection_tables.h16
-rw-r--r--engines/mohawk/livingbooks.cpp87
-rw-r--r--engines/mohawk/livingbooks_code.cpp55
-rw-r--r--engines/mohawk/livingbooks_code.h5
-rw-r--r--engines/mohawk/myst.cpp12
-rw-r--r--engines/mohawk/myst_areas.cpp24
-rw-r--r--engines/mohawk/myst_graphics.cpp165
-rw-r--r--engines/mohawk/myst_graphics.h27
-rw-r--r--engines/mohawk/myst_stacks/channelwood.cpp34
-rw-r--r--engines/mohawk/myst_stacks/dni.cpp56
-rw-r--r--engines/mohawk/myst_stacks/intro.cpp23
-rw-r--r--engines/mohawk/myst_stacks/mechanical.cpp64
-rw-r--r--engines/mohawk/myst_stacks/myst.cpp258
-rw-r--r--engines/mohawk/myst_stacks/stoneship.cpp62
-rw-r--r--engines/mohawk/riven.cpp22
-rw-r--r--engines/mohawk/riven_external.cpp85
-rw-r--r--engines/mohawk/riven_scripts.cpp8
-rw-r--r--engines/mohawk/video.cpp569
-rw-r--r--engines/mohawk/video.h315
-rw-r--r--engines/mortevielle/actions.cpp6
-rw-r--r--engines/mortevielle/dialogs.cpp6
-rw-r--r--engines/mortevielle/graphics.cpp2
-rw-r--r--engines/mortevielle/mortevielle.h4
-rw-r--r--engines/mortevielle/outtext.cpp24
-rw-r--r--engines/mortevielle/utils.cpp80
-rw-r--r--engines/neverhood/menumodule.cpp2
-rw-r--r--engines/parallaction/adlib.cpp38
-rw-r--r--engines/pegasus/menu.cpp4
-rw-r--r--engines/pegasus/sound.cpp10
-rw-r--r--engines/queen/midiadlib.cpp139
-rw-r--r--engines/queen/midiadlib.h128
-rw-r--r--engines/queen/music.cpp8
-rw-r--r--engines/queen/walk.cpp4
-rw-r--r--engines/saga/detection_tables.h33
-rw-r--r--engines/saga/introproc_ihnm.cpp4
-rw-r--r--engines/saga/introproc_ite.cpp70
-rw-r--r--engines/saga/music.cpp48
-rw-r--r--engines/saga/music.h3
-rw-r--r--engines/saga/saga.cpp6
-rw-r--r--engines/saga/saga.h4
-rw-r--r--engines/saga/scene.cpp26
-rw-r--r--engines/saga/scene.h2
-rw-r--r--engines/saga/script.cpp6
-rw-r--r--engines/saga/sndres.cpp15
-rw-r--r--engines/sci/console.cpp438
-rw-r--r--engines/sci/console.h6
-rw-r--r--engines/sci/detection.cpp31
-rw-r--r--engines/sci/detection_tables.h41
-rw-r--r--engines/sci/engine/file.cpp3
-rw-r--r--engines/sci/engine/kernel.cpp45
-rw-r--r--engines/sci/engine/kernel.h2
-rw-r--r--engines/sci/engine/kernel_tables.h4
-rw-r--r--engines/sci/engine/kevent.cpp13
-rw-r--r--engines/sci/engine/kfile.cpp5
-rw-r--r--engines/sci/engine/kgraphics.cpp10
-rw-r--r--engines/sci/engine/kmovement.cpp27
-rw-r--r--engines/sci/engine/kparse.cpp3
-rw-r--r--engines/sci/engine/kvideo.cpp2
-rw-r--r--engines/sci/engine/savegame.cpp76
-rw-r--r--engines/sci/engine/savegame.h8
-rw-r--r--engines/sci/engine/script.cpp416
-rw-r--r--engines/sci/engine/script.h36
-rw-r--r--engines/sci/engine/script_patches.cpp743
-rw-r--r--engines/sci/engine/script_patches.h9
-rw-r--r--engines/sci/engine/state.cpp6
-rw-r--r--engines/sci/engine/state.h4
-rw-r--r--engines/sci/engine/vm.cpp18
-rw-r--r--engines/sci/engine/workarounds.cpp955
-rw-r--r--engines/sci/engine/workarounds.h2
-rw-r--r--engines/sci/graphics/paint16.cpp19
-rw-r--r--engines/sci/graphics/portrait.cpp63
-rw-r--r--engines/sci/graphics/screen.cpp17
-rw-r--r--engines/sci/graphics/screen.h1
-rw-r--r--engines/sci/parser/vocabulary.cpp77
-rw-r--r--engines/sci/parser/vocabulary.h12
-rw-r--r--engines/sci/resource.h2
-rw-r--r--engines/sci/resource_audio.cpp4
-rw-r--r--engines/sci/sci.cpp17
-rw-r--r--engines/sci/sci.h3
-rw-r--r--engines/sci/sound/audio.cpp17
-rw-r--r--engines/sci/sound/drivers/adlib.cpp53
-rw-r--r--engines/sci/sound/midiparser_sci.cpp19
-rw-r--r--engines/sci/sound/music.cpp112
-rw-r--r--engines/sci/sound/music.h14
-rw-r--r--engines/sci/sound/soundcmd.cpp46
-rw-r--r--engines/sci/sound/soundcmd.h2
-rw-r--r--engines/scumm/debugger.cpp2
-rw-r--r--engines/scumm/detection_tables.h7
-rw-r--r--engines/scumm/help.cpp16
-rw-r--r--engines/scumm/players/player_ad.cpp48
-rw-r--r--engines/scumm/players/player_ad.h20
-rw-r--r--engines/scumm/saveload.cpp2
-rw-r--r--engines/scumm/script_v6.cpp6
-rw-r--r--engines/scumm/scumm-md5.h24
-rw-r--r--engines/scumm/scumm.cpp52
-rw-r--r--engines/scumm/scumm.h3
-rw-r--r--engines/scumm/smush/smush_player.cpp5
-rw-r--r--engines/scumm/string.cpp7
-rw-r--r--engines/sherlock/animation.cpp324
-rw-r--r--engines/sherlock/animation.h86
-rw-r--r--engines/sherlock/configure.engine3
-rw-r--r--engines/sherlock/debugger.cpp138
-rw-r--r--engines/sherlock/debugger.h76
-rw-r--r--engines/sherlock/decompress.cpp128
-rw-r--r--engines/sherlock/detection.cpp245
-rw-r--r--engines/sherlock/detection_tables.h171
-rw-r--r--engines/sherlock/events.cpp318
-rw-r--r--engines/sherlock/events.h194
-rw-r--r--engines/sherlock/fixed_text.cpp38
-rw-r--r--engines/sherlock/fixed_text.h66
-rw-r--r--engines/sherlock/fonts.cpp204
-rw-r--r--engines/sherlock/fonts.h105
-rw-r--r--engines/sherlock/image_file.cpp1085
-rw-r--r--engines/sherlock/image_file.h207
-rw-r--r--engines/sherlock/inventory.cpp246
-rw-r--r--engines/sherlock/inventory.h150
-rw-r--r--engines/sherlock/journal.cpp706
-rw-r--r--engines/sherlock/journal.h105
-rw-r--r--engines/sherlock/map.cpp52
-rw-r--r--engines/sherlock/map.h61
-rw-r--r--engines/sherlock/module.mk71
-rw-r--r--engines/sherlock/music.cpp598
-rw-r--r--engines/sherlock/music.h131
-rw-r--r--engines/sherlock/objects.cpp1533
-rw-r--r--engines/sherlock/objects.h478
-rw-r--r--engines/sherlock/people.cpp332
-rw-r--r--engines/sherlock/people.h168
-rw-r--r--engines/sherlock/resources.cpp372
-rw-r--r--engines/sherlock/resources.h170
-rw-r--r--engines/sherlock/saveload.cpp278
-rw-r--r--engines/sherlock/saveload.h151
-rw-r--r--engines/sherlock/scalpel/3do/movie_decoder.cpp510
-rw-r--r--engines/sherlock/scalpel/3do/movie_decoder.h127
-rw-r--r--engines/sherlock/scalpel/darts.cpp553
-rw-r--r--engines/sherlock/scalpel/darts.h130
-rw-r--r--engines/sherlock/scalpel/drivers/adlib.cpp646
-rw-r--r--engines/sherlock/scalpel/drivers/mididriver.h41
-rw-r--r--engines/sherlock/scalpel/drivers/mt32.cpp282
-rw-r--r--engines/sherlock/scalpel/scalpel.cpp1160
-rw-r--r--engines/sherlock/scalpel/scalpel.h133
-rw-r--r--engines/sherlock/scalpel/scalpel_debugger.cpp91
-rw-r--r--engines/sherlock/scalpel/scalpel_debugger.h54
-rw-r--r--engines/sherlock/scalpel/scalpel_fixed_text.cpp377
-rw-r--r--engines/sherlock/scalpel/scalpel_fixed_text.h108
-rw-r--r--engines/sherlock/scalpel/scalpel_inventory.cpp296
-rw-r--r--engines/sherlock/scalpel/scalpel_inventory.h74
-rw-r--r--engines/sherlock/scalpel/scalpel_journal.cpp667
-rw-r--r--engines/sherlock/scalpel/scalpel_journal.h102
-rw-r--r--engines/sherlock/scalpel/scalpel_map.cpp596
-rw-r--r--engines/sherlock/scalpel/scalpel_map.h173
-rw-r--r--engines/sherlock/scalpel/scalpel_people.cpp532
-rw-r--r--engines/sherlock/scalpel/scalpel_people.h114
-rw-r--r--engines/sherlock/scalpel/scalpel_saveload.cpp261
-rw-r--r--engines/sherlock/scalpel/scalpel_saveload.h69
-rw-r--r--engines/sherlock/scalpel/scalpel_scene.cpp726
-rw-r--r--engines/sherlock/scalpel/scalpel_scene.h96
-rw-r--r--engines/sherlock/scalpel/scalpel_screen.cpp93
-rw-r--r--engines/sherlock/scalpel/scalpel_screen.h66
-rw-r--r--engines/sherlock/scalpel/scalpel_talk.cpp844
-rw-r--r--engines/sherlock/scalpel/scalpel_talk.h99
-rw-r--r--engines/sherlock/scalpel/scalpel_user_interface.cpp2189
-rw-r--r--engines/sherlock/scalpel/scalpel_user_interface.h223
-rw-r--r--engines/sherlock/scalpel/settings.cpp343
-rw-r--r--engines/sherlock/scalpel/settings.h63
-rw-r--r--engines/sherlock/scalpel/tsage/logo.cpp684
-rw-r--r--engines/sherlock/scalpel/tsage/logo.h250
-rw-r--r--engines/sherlock/scalpel/tsage/resources.cpp373
-rw-r--r--engines/sherlock/scalpel/tsage/resources.h139
-rw-r--r--engines/sherlock/scene.cpp1437
-rw-r--r--engines/sherlock/scene.h323
-rw-r--r--engines/sherlock/screen.cpp553
-rw-r--r--engines/sherlock/screen.h243
-rw-r--r--engines/sherlock/sherlock.cpp282
-rw-r--r--engines/sherlock/sherlock.h229
-rw-r--r--engines/sherlock/sound.cpp269
-rw-r--r--engines/sherlock/sound.h106
-rw-r--r--engines/sherlock/surface.cpp307
-rw-r--r--engines/sherlock/surface.h185
-rw-r--r--engines/sherlock/talk.cpp1297
-rw-r--r--engines/sherlock/talk.h381
-rw-r--r--engines/sherlock/tattoo/tattoo.cpp576
-rw-r--r--engines/sherlock/tattoo/tattoo.h127
-rw-r--r--engines/sherlock/tattoo/tattoo_darts.cpp967
-rw-r--r--engines/sherlock/tattoo/tattoo_darts.h172
-rw-r--r--engines/sherlock/tattoo/tattoo_debugger.cpp35
-rw-r--r--engines/sherlock/tattoo/tattoo_debugger.h44
-rw-r--r--engines/sherlock/tattoo/tattoo_fixed_text.cpp107
-rw-r--r--engines/sherlock/tattoo/tattoo_fixed_text.h114
-rw-r--r--engines/sherlock/tattoo/tattoo_inventory.cpp63
-rw-r--r--engines/sherlock/tattoo/tattoo_inventory.h48
-rw-r--r--engines/sherlock/tattoo/tattoo_journal.cpp900
-rw-r--r--engines/sherlock/tattoo/tattoo_journal.h103
-rw-r--r--engines/sherlock/tattoo/tattoo_map.cpp439
-rw-r--r--engines/sherlock/tattoo/tattoo_map.h93
-rw-r--r--engines/sherlock/tattoo/tattoo_people.cpp1432
-rw-r--r--engines/sherlock/tattoo/tattoo_people.h270
-rw-r--r--engines/sherlock/tattoo/tattoo_resources.cpp329
-rw-r--r--engines/sherlock/tattoo/tattoo_resources.h42
-rw-r--r--engines/sherlock/tattoo/tattoo_scene.cpp821
-rw-r--r--engines/sherlock/tattoo/tattoo_scene.h147
-rw-r--r--engines/sherlock/tattoo/tattoo_talk.cpp882
-rw-r--r--engines/sherlock/tattoo/tattoo_talk.h101
-rw-r--r--engines/sherlock/tattoo/tattoo_user_interface.cpp862
-rw-r--r--engines/sherlock/tattoo/tattoo_user_interface.h229
-rw-r--r--engines/sherlock/tattoo/widget_base.cpp299
-rw-r--r--engines/sherlock/tattoo/widget_base.h125
-rw-r--r--engines/sherlock/tattoo/widget_inventory.cpp762
-rw-r--r--engines/sherlock/tattoo/widget_inventory.h159
-rw-r--r--engines/sherlock/tattoo/widget_lab.cpp193
-rw-r--r--engines/sherlock/tattoo/widget_lab.h66
-rw-r--r--engines/sherlock/tattoo/widget_talk.cpp529
-rw-r--r--engines/sherlock/tattoo/widget_talk.h92
-rw-r--r--engines/sherlock/tattoo/widget_text.cpp223
-rw-r--r--engines/sherlock/tattoo/widget_text.h80
-rw-r--r--engines/sherlock/tattoo/widget_tooltip.cpp220
-rw-r--r--engines/sherlock/tattoo/widget_tooltip.h87
-rw-r--r--engines/sherlock/tattoo/widget_verbs.cpp311
-rw-r--r--engines/sherlock/tattoo/widget_verbs.h72
-rw-r--r--engines/sherlock/user_interface.cpp205
-rw-r--r--engines/sherlock/user_interface.h138
-rw-r--r--engines/sky/music/adlibchannel.cpp12
-rw-r--r--engines/sky/music/adlibchannel.h5
-rw-r--r--engines/sky/music/adlibmusic.cpp56
-rw-r--r--engines/sky/music/adlibmusic.h18
-rw-r--r--engines/sword25/fmv/movieplayer.cpp2
-rw-r--r--engines/sword25/kernel/outputpersistenceblock.cpp7
-rw-r--r--engines/sword25/kernel/outputpersistenceblock.h1
-rw-r--r--engines/sword25/module.mk7
-rw-r--r--engines/sword25/script/luascript.cpp61
-rw-r--r--engines/sword25/util/double_serialization.cpp68
-rw-r--r--engines/sword25/util/double_serialization.h61
-rw-r--r--engines/sword25/util/lua_persist.cpp802
-rw-r--r--engines/sword25/util/lua_persistence.h67
-rw-r--r--engines/sword25/util/lua_persistence_util.cpp393
-rw-r--r--engines/sword25/util/lua_persistence_util.h122
-rw-r--r--engines/sword25/util/lua_unpersist.cpp722
-rw-r--r--engines/sword25/util/pluto/CHANGELOG37
-rw-r--r--engines/sword25/util/pluto/FILEFORMAT168
-rw-r--r--engines/sword25/util/pluto/README133
-rw-r--r--engines/sword25/util/pluto/THANKS9
-rw-r--r--engines/sword25/util/pluto/pdep.cpp112
-rw-r--r--engines/sword25/util/pluto/pdep/README5
-rw-r--r--engines/sword25/util/pluto/pdep/lzio.h65
-rw-r--r--engines/sword25/util/pluto/pdep/pdep.h42
-rw-r--r--engines/sword25/util/pluto/pluto.cpp2083
-rw-r--r--engines/sword25/util/pluto/pluto.h25
-rw-r--r--engines/sword25/util/pluto/plzio.cpp74
-rw-r--r--engines/tinsel/music.cpp81
-rw-r--r--engines/tinsel/music.h4
-rw-r--r--engines/tinsel/tinsel.cpp5
-rw-r--r--engines/toltecs/music.cpp38
-rw-r--r--engines/toltecs/music.h1
-rw-r--r--engines/tony/mpal/mpal.cpp4
-rw-r--r--engines/tony/window.cpp2
-rw-r--r--engines/toon/anim.cpp28
-rw-r--r--engines/toon/character.cpp5
-rw-r--r--engines/toon/font.cpp6
-rw-r--r--engines/toon/toon.cpp364
-rw-r--r--engines/toon/toon.h4
-rw-r--r--engines/tsage/blue_force/blueforce_scenes8.cpp4
-rw-r--r--engines/tsage/blue_force/blueforce_scenes8.h2
-rw-r--r--engines/tsage/blue_force/blueforce_scenes9.cpp4
-rw-r--r--engines/tsage/core.cpp9
-rw-r--r--engines/tsage/detection.cpp1
-rw-r--r--engines/tsage/detection_tables.h16
-rw-r--r--engines/tsage/globals.cpp7
-rw-r--r--engines/tsage/graphics.cpp3
-rw-r--r--engines/tsage/graphics.h4
-rw-r--r--engines/tsage/module.mk1
-rw-r--r--engines/tsage/resources.h4
-rw-r--r--engines/tsage/ringworld/ringworld_scenes3.cpp14
-rw-r--r--engines/tsage/ringworld/ringworld_scenes3.h2
-rw-r--r--engines/tsage/sherlock/sherlock_logo.cpp356
-rw-r--r--engines/tsage/sherlock/sherlock_logo.h78
-rw-r--r--engines/tsage/sound.cpp42
-rw-r--r--engines/tsage/sound.h24
-rw-r--r--engines/tsage/tsage.cpp10
-rw-r--r--engines/tsage/tsage.h3
-rw-r--r--engines/voyeur/events.cpp4
-rw-r--r--engines/voyeur/files_threads.cpp1
-rw-r--r--engines/wintermute/base/base_file_manager.cpp2
-rw-r--r--engines/wintermute/base/base_keyboard_state.cpp101
-rw-r--r--engines/wintermute/base/base_keyboard_state.h2
-rw-r--r--engines/wintermute/base/base_script_holder.cpp2
-rw-r--r--engines/wintermute/debugger.cpp2
-rw-r--r--engines/zvision/configure.engine2
-rw-r--r--engines/zvision/core/clock.h10
-rw-r--r--engines/zvision/core/console.cpp159
-rw-r--r--engines/zvision/core/console.h4
-rw-r--r--engines/zvision/core/events.cpp150
-rw-r--r--engines/zvision/detection.cpp149
-rw-r--r--engines/zvision/detection_tables.h277
-rw-r--r--engines/zvision/file/lzss_read_stream.cpp5
-rw-r--r--engines/zvision/file/save_manager.cpp (renamed from engines/zvision/core/save_manager.cpp)145
-rw-r--r--engines/zvision/file/save_manager.h (renamed from engines/zvision/core/save_manager.h)20
-rw-r--r--engines/zvision/file/search_manager.cpp85
-rw-r--r--engines/zvision/file/search_manager.h21
-rw-r--r--engines/zvision/graphics/cursors/cursor.cpp40
-rw-r--r--engines/zvision/graphics/cursors/cursor.h1
-rw-r--r--engines/zvision/graphics/cursors/cursor_manager.cpp42
-rw-r--r--engines/zvision/graphics/cursors/cursor_manager.h4
-rw-r--r--engines/zvision/graphics/effects/fog.cpp18
-rw-r--r--engines/zvision/graphics/effects/fog.h5
-rw-r--r--engines/zvision/graphics/effects/light.cpp6
-rw-r--r--engines/zvision/graphics/effects/light.h4
-rw-r--r--engines/zvision/graphics/effects/wave.cpp4
-rw-r--r--engines/zvision/graphics/effects/wave.h4
-rw-r--r--engines/zvision/graphics/graphics_effect.h (renamed from engines/zvision/graphics/effect.h)14
-rw-r--r--engines/zvision/graphics/render_manager.cpp873
-rw-r--r--engines/zvision/graphics/render_manager.h148
-rw-r--r--engines/zvision/graphics/render_table.cpp21
-rw-r--r--engines/zvision/graphics/truetype_font.cpp265
-rw-r--r--engines/zvision/module.mk22
-rw-r--r--engines/zvision/scripting/actions.cpp557
-rw-r--r--engines/zvision/scripting/actions.h35
-rw-r--r--engines/zvision/scripting/control.cpp1
-rw-r--r--engines/zvision/scripting/control.h5
-rw-r--r--engines/zvision/scripting/controls/fist_control.cpp58
-rw-r--r--engines/zvision/scripting/controls/fist_control.h6
-rw-r--r--engines/zvision/scripting/controls/hotmov_control.cpp53
-rw-r--r--engines/zvision/scripting/controls/hotmov_control.h5
-rw-r--r--engines/zvision/scripting/controls/input_control.cpp58
-rw-r--r--engines/zvision/scripting/controls/input_control.h10
-rw-r--r--engines/zvision/scripting/controls/lever_control.cpp7
-rw-r--r--engines/zvision/scripting/controls/lever_control.h1
-rw-r--r--engines/zvision/scripting/controls/paint_control.cpp12
-rw-r--r--engines/zvision/scripting/controls/paint_control.h1
-rw-r--r--engines/zvision/scripting/controls/safe_control.cpp57
-rw-r--r--engines/zvision/scripting/controls/safe_control.h8
-rw-r--r--engines/zvision/scripting/controls/save_control.cpp13
-rw-r--r--engines/zvision/scripting/controls/titler_control.cpp8
-rw-r--r--engines/zvision/scripting/controls/titler_control.h1
-rw-r--r--engines/zvision/scripting/effects/animation_effect.cpp (renamed from engines/zvision/scripting/sidefx/animation_node.cpp)167
-rw-r--r--engines/zvision/scripting/effects/animation_effect.h (renamed from engines/zvision/scripting/sidefx/animation_node.h)15
-rw-r--r--engines/zvision/scripting/effects/distort_effect.cpp (renamed from engines/zvision/scripting/sidefx/distort_node.cpp)7
-rw-r--r--engines/zvision/scripting/effects/distort_effect.h (renamed from engines/zvision/scripting/sidefx/distort_node.h)4
-rw-r--r--engines/zvision/scripting/effects/music_effect.cpp (renamed from engines/zvision/scripting/sidefx/music_node.cpp)170
-rw-r--r--engines/zvision/scripting/effects/music_effect.h (renamed from engines/zvision/scripting/sidefx/music_node.h)39
-rw-r--r--engines/zvision/scripting/effects/region_effect.cpp (renamed from engines/zvision/scripting/sidefx/region_node.cpp)6
-rw-r--r--engines/zvision/scripting/effects/region_effect.h (renamed from engines/zvision/scripting/sidefx/region_node.h)10
-rw-r--r--engines/zvision/scripting/effects/syncsound_effect.cpp (renamed from engines/zvision/scripting/sidefx/syncsound_node.cpp)6
-rw-r--r--engines/zvision/scripting/effects/syncsound_effect.h (renamed from engines/zvision/scripting/sidefx/syncsound_node.h)6
-rw-r--r--engines/zvision/scripting/effects/timer_effect.cpp (renamed from engines/zvision/scripting/sidefx/timer_node.cpp)4
-rw-r--r--engines/zvision/scripting/effects/timer_effect.h (renamed from engines/zvision/scripting/sidefx/timer_node.h)4
-rw-r--r--engines/zvision/scripting/effects/ttytext_effect.cpp (renamed from engines/zvision/scripting/sidefx/ttytext_node.cpp)46
-rw-r--r--engines/zvision/scripting/effects/ttytext_effect.h (renamed from engines/zvision/scripting/sidefx/ttytext_node.h)8
-rw-r--r--engines/zvision/scripting/menu.cpp (renamed from engines/zvision/core/menu.cpp)352
-rw-r--r--engines/zvision/scripting/menu.h (renamed from engines/zvision/core/menu.h)34
-rw-r--r--engines/zvision/scripting/scr_file_handling.cpp89
-rw-r--r--engines/zvision/scripting/script_manager.cpp251
-rw-r--r--engines/zvision/scripting/script_manager.h48
-rw-r--r--engines/zvision/scripting/scripting_effect.h (renamed from engines/zvision/scripting/sidefx.h)48
-rw-r--r--engines/zvision/sound/zork_raw.cpp41
-rw-r--r--engines/zvision/sound/zork_raw.h14
-rw-r--r--engines/zvision/text/string_manager.cpp14
-rw-r--r--engines/zvision/text/string_manager.h3
-rw-r--r--engines/zvision/text/subtitles.cpp (renamed from engines/zvision/graphics/subtitles.cpp)11
-rw-r--r--engines/zvision/text/subtitles.h (renamed from engines/zvision/graphics/subtitles.h)2
-rw-r--r--engines/zvision/text/text.cpp536
-rw-r--r--engines/zvision/text/text.h73
-rw-r--r--engines/zvision/text/truetype_font.cpp265
-rw-r--r--engines/zvision/text/truetype_font.h (renamed from engines/zvision/graphics/truetype_font.h)26
-rw-r--r--engines/zvision/video/rlf_decoder.cpp62
-rw-r--r--engines/zvision/video/rlf_decoder.h8
-rw-r--r--engines/zvision/video/video.cpp25
-rw-r--r--engines/zvision/video/zork_avi_decoder.cpp21
-rw-r--r--engines/zvision/zvision.cpp520
-rw-r--r--engines/zvision/zvision.h125
-rw-r--r--graphics/fonts/ttf.cpp6
-rw-r--r--gui/Tooltip.cpp2
-rw-r--r--gui/Tooltip.h33
-rw-r--r--gui/about.cpp2
-rw-r--r--gui/credits.h21
-rw-r--r--gui/debugger.cpp56
-rw-r--r--gui/dialog.cpp2
-rw-r--r--gui/launcher.cpp4
-rw-r--r--gui/options.cpp6
-rw-r--r--gui/saveload-dialog.cpp17
-rw-r--r--gui/themes/translations.datbin470115 -> 466386 bytes
-rw-r--r--icons/scummvm.infobin17326 -> 23078 bytes
-rw-r--r--icons/scummvm_drawer.infobin20738 -> 22916 bytes
-rw-r--r--image/codecs/cinepak.cpp559
-rw-r--r--image/codecs/cinepak.h20
-rw-r--r--image/codecs/cinepak_tables.h780
-rw-r--r--image/codecs/codec.cpp148
-rw-r--r--image/codecs/codec.h29
-rw-r--r--image/codecs/qtrle.cpp164
-rw-r--r--image/codecs/qtrle.h15
-rw-r--r--image/codecs/rpza.cpp270
-rw-r--r--image/codecs/rpza.h14
-rw-r--r--po/POTFILES1
-rw-r--r--po/be_BY.po568
-rw-r--r--po/ca_ES.po569
-rw-r--r--po/cs_CZ.po567
-rw-r--r--po/da_DA.po568
-rw-r--r--po/de_DE.po698
-rw-r--r--po/es_ES.po569
-rw-r--r--po/eu.po565
-rw-r--r--po/fi_FI.po566
-rw-r--r--po/fr_FR.po567
-rw-r--r--po/gl_ES.po569
-rw-r--r--po/hu_HU.po567
-rw-r--r--po/it_IT.po568
-rw-r--r--po/nb_NO.po567
-rw-r--r--po/nl_NL.po549
-rw-r--r--po/nn_NO.po556
-rw-r--r--po/pl_PL.po568
-rw-r--r--po/pt_BR.po565
-rw-r--r--po/ru_RU.po568
-rw-r--r--po/scummvm.pot542
-rw-r--r--po/se_SE.po568
-rw-r--r--po/uk_UA.po569
-rw-r--r--ports.mk4
-rw-r--r--test/audio/timestamp.h13
-rw-r--r--test/common/endian.h12
-rw-r--r--test/common/memoryreadstream.h16
-rw-r--r--test/common/memoryreadstreamendian.h32
-rwxr-xr-xtest/cxxtest/cxxtestgen.py2
-rw-r--r--video/avi_decoder.cpp24
-rw-r--r--video/avi_decoder.h7
-rw-r--r--video/module.mk1
-rw-r--r--video/mpegps_decoder.cpp732
-rw-r--r--video/mpegps_decoder.h189
-rw-r--r--video/qt_decoder.cpp270
-rw-r--r--video/qt_decoder.h12
-rw-r--r--video/theora_decoder.cpp4
-rw-r--r--video/theora_decoder.h6
-rw-r--r--video/video_decoder.cpp24
-rw-r--r--video/video_decoder.h32
885 files changed, 76273 insertions, 29154 deletions
diff --git a/AUTHORS b/AUTHORS
index 9470217230..e2cad187fe 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -259,8 +259,10 @@ ScummVM Team
Einar Johan T. Somaaen
Tobia Tesan
- ZVision:
+ Z-Vision:
Adrian Astley
+ Filippos Karapetis
+ Anton Yarcev
Backend Teams
-------------
@@ -483,7 +485,7 @@ Other contributions
German:
Simon Sawatzki
- Lothar Serra Mari - (retired)
+ Lothar Serra Mari
Hungarian:
Alex Bevilacqua
@@ -524,6 +526,12 @@ Other contributions
Victor Gonzalez - Soltys Spanish translation
Alejandro Gomez de la Munoza - Soltys Spanish translation
+ CGE2:
+ Arnaud Boutonne - Sfinx English translation
+ Thierry Crozat - Sfinx English translation
+ Peter Bozso - Sfinx English translation editor
+ Ryan Clark - Sfinx English translation editor
+
Drascula:
Thierry Crozat - Improve French translation
@@ -557,6 +565,7 @@ Other contributions
Jeroen Janssen - Numerous readability and bugfix patches
Keith Kaisershot - Several Pegasus Prime patches
Andreas Karlsson - Initial port for SymbianOS
+ Stefan Kristiansson - Initial work on SDL2 support
Claudio Matsuoka - Daily Linux builds
Thomas Mayer - PSP port contributions
Sean Murray - ScummVM tools GUI application (GSoC 2007
@@ -661,7 +670,7 @@ Special thanks to
Jimmi Thogersen - For ScummRev, and much obscure code/documentation
Tristan - For additional work on the original MT-32 emulator
James Woodcock - Soundtrack enhancements
- Anton Yartsev - For the original re-implementation of the ZVision
+ Anton Yartsev - For the original re-implementation of the Z-Vision
engine
Tony Warriner and everyone at Revolution Software Ltd. for sharing with us
diff --git a/COPYRIGHT b/COPYRIGHT
index 3344dd64d1..8e6b12cd04 100644
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -1,5 +1,5 @@
ScummVM
-Copyright (C) 2001-2014 by the following:
+Copyright (C) 2001-2015 by the following:
If you have contributed to this project then you deserve to be on this
list. Contact us (see: AUTHORS) and we'll add you.
diff --git a/Makefile b/Makefile
index 93a84a5c7b..36b4592b20 100644
--- a/Makefile
+++ b/Makefile
@@ -91,6 +91,7 @@ ifeq "$(findstring config.mk,$(MAKEFILE_LIST))" "config.mk"
LDFLAGS="$(SAVED_LDFLAGS)" CXX="$(SAVED_CXX)" \
CXXFLAGS="$(SAVED_CXXFLAGS)" CPPFLAGS="$(SAVED_CPPFLAGS)" \
ASFLAGS="$(SAVED_ASFLAGS)" WINDRESFLAGS="$(SAVED_WINDRESFLAGS)" \
+ SDL_CONFIG="$(SAVED_SDL_CONFIG)" \
$(srcdir)/configure $(SAVED_CONFIGFLAGS)
else
$(error You need to run $(srcdir)/configure before you can run make. Check $(srcdir)/configure --help for a list of parameters)
diff --git a/NEWS b/NEWS
index 762af70962..3e411f0346 100644
--- a/NEWS
+++ b/NEWS
@@ -3,15 +3,57 @@ For a more comprehensive changelog of the latest experimental code, see:
1.8.0 (????-??-??)
New Games:
+ - Added support for Rex Nebular and the Cosmic Gender Bender.
- Added support for Sfinx.
+ - Added support for Zork Nemesis: The Forbidden Lands.
+ - Added support for Zork: Grand Inquisitor.
+
+ General:
+ - Updated Munt MT-32 emulation code to version 1.5.0.
+
+ 3 Skulls of the Toltecs:
+ - Improved AdLib music support.
+
+ AGI:
+ - It is now possible to disable mouse support (except for Amiga versions
+ and fanmade games, that require a mouse).
+ - Fix incorrect volume attenuation in PCjr sound code (bug #6858).
+
+ AGOS:
+ - Fixed arpeggio effect used in music of Amiga version of Elvira 1.
+ - Fixed loading and saving progress in the PC version of Waxworks.
+ - Fixed verb area been removed in Amiga versions of Simon the Sorcerer 1.
+ - Added Accolade AdLib & MT32 music drivers for the games:
+ Elvira 1, Elvira 2, Waxworks and Simon the Sorcerer 1 demo.
Broken Sword 1:
- - Fix speech endianness detection on big endian systems for the mac
+ - Fix speech endianness detection on big endian systems for the Macintosh
version (bug #6720).
- Fix crash when reloading a game from the Main Menu while in the bull's
head scene (bug #6728). It may have been happening in other scenes as
well.
+ MADE:
+ - Improved AdLib music support in Return to Zork.
+
+ SAGA:
+ - Improved AdLib music support.
+
+ SCI:
+ - Handling of music priority has been greatly improved.
+ - A lot of fixes for original game script bugs that also occurred when
+ using the original interpreter.
+ KQ6 (Dual Mode), LSL5, QfG1 (EGA), QfG1 (VGA), QfG2, QfG3, SQ1, SQ4 (CD)
+ - Restoring from the ScummVM in-game menu should now work all the time.
+ - Improve support for Japanese PC-9801 games.
+
+ SCUMM:
+ - It is now possible to play Maniac Mansion from within Day of the
+ Tentacle, with a few caveats. See README for details.
+
+ Tinsel:
+ - Improved AdLib music support in Discworld 1.
+
1.7.0 (2014-07-21)
New Games:
- Added support for Chivalry is Not Dead.
diff --git a/README b/README
index 5b0569089c..2a1d7c390e 100644
--- a/README
+++ b/README
@@ -15,26 +15,27 @@ Table of Contents:
* 2.1 Reporting Bugs
3.0) Supported Games
* 3.1 Copy Protection
- * 3.2 Commodore64 games notes
- * 3.3 Maniac Mansion NES notes
- * 3.4 Macintosh games notes
- * 3.5 Multi-CD games notes
- * 3.6 The Curse of Monkey Island notes
- * 3.7 Broken Sword games notes
- * 3.8 Beneath a Steel Sky notes
- * 3.9 Flight of the Amazon Queen notes
- * 3.10 Gobliiins notes
- * 3.11 Inherit the Earth: Quest for the Orb notes
- * 3.12 Simon the Sorcerer notes
- * 3.13 The Feeble Files notes
- * 3.14 The Legend of Kyrandia notes
- * 3.15 Sierra AGI games Predictive Input Dialog notes
- * 3.16 Mickey's Space Adventure notes
- * 3.17 Winnie the Pooh notes
- * 3.18 Troll's Tale notes
- * 3.19 Dragon History notes
- * 3.20 Simultaneous speech and subtitles in Sierra SCI games
- * 3.21 Known Problems
+ * 3.2 Day of the Tentacle notes
+ * 3.3 Commodore64 games notes
+ * 3.4 Maniac Mansion NES notes
+ * 3.5 Macintosh games notes
+ * 3.6 Multi-CD games notes
+ * 3.7 The Curse of Monkey Island notes
+ * 3.8 Broken Sword games notes
+ * 3.9 Beneath a Steel Sky notes
+ * 3.10 Flight of the Amazon Queen notes
+ * 3.11 Gobliiins notes
+ * 3.12 Inherit the Earth: Quest for the Orb notes
+ * 3.13 Simon the Sorcerer notes
+ * 3.14 The Feeble Files notes
+ * 3.15 The Legend of Kyrandia notes
+ * 3.16 Sierra AGI games Predictive Input Dialog notes
+ * 3.17 Mickey's Space Adventure notes
+ * 3.18 Winnie the Pooh notes
+ * 3.19 Troll's Tale notes
+ * 3.20 Dragon History notes
+ * 3.21 Simultaneous speech and subtitles in Sierra SCI games
+ * 3.22 Known Problems
4.0) Supported Platforms
5.0) Running ScummVM
* 5.1 Command Line Options
@@ -200,7 +201,7 @@ SCUMM Games by LucasArts:
The Dig [dig]
The Curse of Monkey Island [comi]
-AGI Games by Sierra:
+AGI and preAGI Games by Sierra:
The Black Cauldron [bc]
Gold Rush! [goldrush]
King's Quest I [kq1]
@@ -217,6 +218,9 @@ AGI Games by Sierra:
Space Quest I: The Sarien Encounter [sq1]
Space Quest II: Vohaul's Revenge [sq2]
Fanmade Games [agi-fanmade]
+ Mickey's Space Adventure [mickey]
+ Troll's Tale [troll]
+ Winnie the Pooh in the Hundred Acre Wood [winnie]
AGOS Games by Adventuresoft/Horrorsoft:
Elvira - Mistress of the Dark [elvira1]
@@ -235,6 +239,13 @@ AGOS Games by Adventuresoft/Horrorsoft:
- Swampy Adventures [swampy]
The Feeble Files [feeble]
+Composer Games by Animation Magic:
+ Darby the Dragon [darby]
+ Gregory and the Hot Air Balloon [gregory]
+ Magic Tales: Liam Finds a Story [liam]
+ The Princess and the Crab [princess]
+ Sleeping Cub's Test of Courage [sleepingcub]
+
GOB Games by Coktel Vision:
Bambou le sauveur de la jungle [bambou]
Bargon Attack [bargon]
@@ -250,6 +261,22 @@ GOB Games by Coktel Vision:
Urban Runner [urban]
Ween: The Prophecy [ween]
+Living Books Games:
+ Aesop's Fables: The Tortoise and the Hare [tortoise]
+ Arthur's Birthday [arthurbday]
+ Arthur's Teacher Trouble [arthur]
+ Dr. Seuss's ABC [seussabc]
+ Green Eggs and Ham [greeneggs]
+ Harry and the Haunted House [harryhh]
+ Just Grandma and Me [grandma]
+ Little Monster at School [lilmonster]
+ Ruff's Bone [ruff]
+ Sheila Rae, the Brave [sheila]
+ Stellaluna [stellaluna]
+ The Berenstain Bears Get in a Fight [bearfight]
+ The Berenstain Bears in the Dark [beardark]
+ The New Kid on the Block [newkid]
+
MADE Games by Activision:
Leather Goddesses of Phobos 2 [lgop2]
Return to Zork [rtz]
@@ -257,34 +284,106 @@ MADE Games by Activision:
The Manhole [manhole]
Other Games:
+ 3 Skulls of the Toltecs [toltecs]
+ Blue Force [blueforce]
Beneath a Steel Sky [sky]
Broken Sword: The Shadow of the Templars [sword1]
Broken Sword II: The Smoking Mirror [sword2]
+ Bud Tucker in Double Trouble [tucker]
Cruise for a Corpse [cruise]
Discworld [dw]
Discworld 2: Missing Presumed ...!? [dw2]
Dragon History [draci]
Drascula: The Vampire Strikes Back [drascula]
+ DreamWeb [dreamweb]
Eye of the Beholder [eob]
Eye of the Beholder II: The Legend of
Darkmoon [eob2]
Flight of the Amazon Queen [queen]
Future Wars [fw]
+ Hopkins FBI [hopkins]
+ Hugo's House of Horrors [hugo1]
+ Hugo 2: Whodunit? [hugo2]
+ Hugo 3: Jungle of Doom [hugo3]
+ I Have No Mouth, and I Must Scream [ihnm]
Inherit the Earth: Quest for the Orb [ite]
Nippon Safes Inc. [nippon]
Lands of Lore: The Throne of Chaos [lol]
+ Lure of the Temptress [lure]
+ Mortville Manor [mortevielle]
+ Nippon Safes Inc. [nippon]
+ Ringworld: Revenge Of The Patriarch [ringworld]
+ Return to Ringworld [ringworld2]
+ Sfinx [sfinx]
+ Soltys [soltys]
+ TeenAgent [teenagent]
The Journeyman Project: Pegasus Prime [pegasus]
The Legend of Kyrandia [kyra1]
The Legend of Kyrandia: The Hand of Fate [kyra2]
The Legend of Kyrandia: Malcolm's Revenge [kyra3]
+ The 7th Guest [t7g]
+ The Neverhood [neverhood]
+ Tony Tough and the Night of Roasted Moths [tony]
+ Toonstruck [toon]
Touche: The Adventures of the Fifth
Musketeer [touche]
+ Voyeur [voyeur]
+
+SCI Games by Sierra Entertainment:
+ Castle of Dr. Brain [castlebrain]
+ Codename: ICEMAN [iceman]
+ Conquests of Camelot [camelot]
+ Conquests of the Longbow [longbow]
+ EcoQuest: The Search for Cetus [ecoquest]
+ EcoQuest 2: Lost Secret of the Rainforest [ecoquest2]
+ Freddy Pharkas: Frontier Pharmacist [freddypharkas]
+ Hoyle's Book of Games 1 [hoyle1]
+ Hoyle's Book of Games 2 [hoyle2]
+ Hoyle's Book of Games 3 [hoyle3]
+ Hoyle Classic Card Games [hoyle4]
+ Jones in the Fast Lane [jones]
+ King's Quest I [kq1sci]
+ King's Quest IV [kq4sci]
+ King's Quest V [kq5]
+ King's Quest VI [kq6]
+ Laura Bow: The Colonel's Bequest [laurabow]
+ Laura Bow 2: The Dagger of Amon Ra [laurabow2]
+ Leisure Suit Larry 1 [lsl1sci]
+ Leisure Suit Larry 2 [lsl2]
+ Leisure Suit Larry 3 [lsl3]
+ Leisure Suit Larry 5 [lsl5]
+ Leisure Suit Larry 6 [lsl6]
+ Mixed-up Fairy Tales [fairytales]
+ Mixed-up Mother Goose [mothergoose]
+ Pepper's Adventures in Time [pepper]
+ Police Quest 1 [pq1sci]
+ Police Quest 2 [pq2]
+ Police Quest 3 [pq3]
+ Quest for Glory 1/Hero's Quest [qfg1]
+ Quest for Glory 1 [qfg1vga]
+ Quest for Glory 2 [qfg2]
+ Quest for Glory 3 [qfg3]
+ Slater & Charlie Go Camping [slater]
+ Space Quest I [sq1sci]
+ Space Quest III [sq3]
+ Space Quest IV [sq4]
+ Space Quest V [sq5]
+ The Island of Dr. Brain [islandbrain]
+
+Wintermute Games:
+ Chivalry is Not Dead [chivalry]
+
+Z-Vision Games by Activision:
+ Zork Nemesis: The Forbidden Lands [znemesis]
+ Zork: Grand Inquisitor [zgi]
SCUMM Games by Humongous Entertainment:
Backyard Baseball [baseball]
Backyard Baseball 2001 [baseball2001]
Backyard Baseball 2003 [baseball2003]
Backyard Football [football]
+ Backyard Football 2002 [football2002]
+ Bear Stormin' [brstorm]
Big Thinkers First Grade [thinker1]
Big Thinkers Kindergarten [thinkerk]
Blue's 123 Time Activities [Blues123Time]
@@ -309,6 +408,7 @@ SCUMM Games by Humongous Entertainment:
Let's Explore the Airport with Buzzy [airport]
Let's Explore the Farm with Buzzy [farm]
Let's Explore the Jungle with Buzzy [jungle]
+ Pajama Sam: Games to Play on Any Day [pjgames]
Pajama Sam 1: No Need to Hide When It's
Dark Outside [pajama]
Pajama Sam 2: Thunder and Lightning
@@ -333,38 +433,20 @@ SCUMM Games by Humongous Entertainment:
SPY Fox in Cheese Chase [chase]
SPY Fox in Hold the Mustard [mustard]
-Living Books Games:
- Aesop's Fables: The Tortoise and the Hare [tortoise]
- Arthur's Birthday [arthurbday]
- Arthur's Teacher Trouble [arthur]
- Dr. Seuss's ABC [seussabc]
- Green Eggs and Ham [greeneggs]
- Harry and the Haunted House [harryhh]
- Just Grandma and Me [grandma]
- Little Monster at School [lilmonster]
- Ruff's Bone [ruff]
- Sheila Rae, the Brave [sheila]
- Stellaluna [stellaluna]
- The Berenstain Bears Get in a Fight [bearfight]
- The Berenstain Bears in the Dark [beardark]
- The New Kid on the Block [newkid]
-
The following games should load, but are not yet fully playable. Play
these at your own risk, and please do not file bug reports about them.
If you want the latest updates on game compatibility, visit our web site
and view the compatibility chart.
- Backyard Football 2002 [football2002]
Backyard Soccer [soccer]
Backyard Soccer MLS [soccermls]
Backyard Soccer 2004 [soccer2004]
Blue's Treasure Hunt [BluesTreasureHunt]
- Pajama Sam: Games to Play on Any Day [pjgames]
The following games are based on the SCUMM engine, but NOT supported
by ScummVM (yet):
- Other Humongous Entertainment games
+ Moonbase Commander
Please be aware that the engines may contain bugs and unimplemented
features that sometimes make it impossible to finish the game. Save
@@ -410,7 +492,29 @@ ScummVM will skip copy protection in the following games:
* Zak McKracken and the Alien Mindbenders
-3.2) Commodore64 games notes:
+3.2) Day of the Tentacle notes:
+---- --------------------------
+
+At one point in the game, you come across a computer that allows you
+to play the original Maniac Mansion as an easter egg. ScummVM supports
+this, with a few caveats:
+
+ScummVM will scan your configuration file for a game that's in a
+'Maniac' sub-folder of your Day of the Tentacle folder. If you've
+copied the data files from the CD version, this should already be the
+case but you have to add the game to ScummVM as well.
+
+To return to Day of the Tentacle, press F5 and select "Return to
+Launcher".
+
+This means that you could in theory use any game as the easter egg.
+Indeed, there is a "secret" configuration setting, "easter_egg", to
+override the ID of the game to run. Be aware, though, that not all
+games support returning to the launcher, and setting it up to use Day
+of the Tentacle itself as the easter egg game is not recommended.
+
+
+3.3) Commodore64 games notes:
---- ------------------------
Both Maniac Mansion and Zak McKracken run but Maniac Mansion is not yet
playable. Simply name the D64 disks "maniac1.d64" and "maniac2.d64"
@@ -424,7 +528,7 @@ to Commodore64. We recommend using the much simpler approach described
in the previous paragraph.
-3.3) Maniac Mansion NES notes:
+3.4) Maniac Mansion NES notes:
---- -------------------------
Supported versions are English GB (E), French (F), German (G), Italian (I),
Swedish (SW) and English US (U). ScummVM requires just the PRG section
@@ -453,7 +557,7 @@ section. To do so use the 'extract_mm_nes' utility from the tools
package.
-3.4) Macintosh games notes:
+3.5) Macintosh games notes:
---- ----------------------
All LucasArts SCUMM based adventures, except COMI, also exist in versions
for the Macintosh. ScummVM can use most (all?) of them, however, in some
@@ -481,7 +585,7 @@ disk see:
http://wiki.scummvm.org/index.php/HOWTO-Mac_Games
-3.5) Multi-CD games notes:
+3.6) Multi-CD games notes:
---- ---------------------
In general, ScummVM does not deal very well with Multi-CD games. This is
because ScummVM assumes everything about a game can be found in one
@@ -496,7 +600,7 @@ files. Usually, when a file appears on more than one CD you can pick
either of them.
-3.6) The Curse of Monkey Island notes:
+3.7) The Curse of Monkey Island notes:
---- ---------------------------------
For this game, you will need the comi.la0, comi.la1 and comi.la2 files.
The comi.la0 file can be found on either CD, but since they are
@@ -508,7 +612,7 @@ two CDs. Some of the files appear on both CDs, but again they're
identical.
-3.7) Broken Sword games notes:
+3.8) Broken Sword games notes:
---- -------------------------
The instructions for the Broken Sword games are for the Sold-Out
Software versions, with each game on two CDs, since these were the
@@ -517,7 +621,7 @@ them. Hopefully they are general enough to be useful to other releases
as well.
-3.7.1) Broken Sword games cutscenes:
+3.8.1) Broken Sword games cutscenes:
------ -----------------------------
The cutscenes for the Broken Sword games have a bit of a history (see
the next section, if you are interested), but in general all you need to
@@ -558,7 +662,7 @@ currently does not work when running PlayStation videos. (Broken Sword
II already has subtitles; no extra work is needed for them.)
-3.7.2) Broken Sword games cutscenes, in retrospect:
+3.8.2) Broken Sword games cutscenes, in retrospect:
------ --------------------------------------------
The original releases of the Broken Sword games used RAD Game Tools's
Smacker(tm) format. As RAD was unwilling to open the older legacy
@@ -583,7 +687,7 @@ decoding MPEG movies added a lot of complexity, and they didn't look as
good as the Smacker and DXA versions anyway.
-3.7.3) Broken Sword:
+3.8.3) Broken Sword:
------ -------------
For this game, you will need all of the files from the clusters
directories on both CDs. For the Windows and Macintosh versions, you
@@ -600,7 +704,7 @@ makes little difference. The PlayStation version requires tunes.dat and
tunes.tab.
-3.7.4) Broken Sword II:
+3.8.4) Broken Sword II:
------ ----------------
For this game, you will need all of the files from the clusters
directories on both CDs. (Actually, a few of them may not be strictly
@@ -615,7 +719,7 @@ In addition, you will need the cd.inf and, optionally, the startup.inf
files from the sword2 directory on CD 1.
-3.8) Beneath a Steel Sky notes:
+3.9) Beneath a Steel Sky notes:
---- --------------------------
Starting with ScummVM 0.8.0 you need the additional 'SKY.CPT' file to
run Beneath a Steel Sky.
@@ -626,7 +730,7 @@ files (SKY.DNR, SKY.DSK), in your extrapath, or in the directory where
your ScummVM executable resides.
-3.9) Flight of the Amazon Queen notes:
+3.10) Flight of the Amazon Queen notes:
---- ---------------------------------
In order to use a non-freeware version of Flight of the Amazon Queen
(from original CD), you will need to place the 'queen.tbl' file
@@ -641,7 +745,7 @@ specific version, and thus removing the run-time dependency on the
sound effects with MP3, OGG or FLAC.
-3.10) Gobliiins notes:
+3.11) Gobliiins notes:
----- ----------------
The CD versions of the Gobliiins series contain one big audio track
which you need to rip (see the section on using compressed audio files)
@@ -651,7 +755,7 @@ track and its volume is therefore changed with the music volume control
as well.
-3.11) Inherit the Earth: Quest for the Orb notes:
+3.12) Inherit the Earth: Quest for the Orb notes:
----- -------------------------------------------
In order to run the Mac OS X Wyrmkeep re-release of the game you will
need to copy over data from the CD to your hard disk. If you're on a PC
@@ -671,14 +775,14 @@ format, as they should include both resource and data forks. Copy all
'ITE *' files.
-3.12) Simon the Sorcerer 1 and 2 notes:
+3.13) Simon the Sorcerer 1 and 2 notes:
----- ---------------------------------
If you have the dual version of Simon the Sorcerer 1 or 2 on CD, you
will find the Windows version in the main directory of the CD and the
DOS version in the DOS directory of the CD.
-3.13) The Feeble Files notes:
+3.14) The Feeble Files notes:
----- -----------------------
If you have the Windows version of The Feeble Files, there are several
things to note.
@@ -696,7 +800,7 @@ Rename voices.wav on CD3 to voices3.wav
Rename voices.wav on CD4 to voices4.wav
-3.14) The Legend of Kyrandia notes:
+3.15) The Legend of Kyrandia notes:
----- -----------------------------
To run The Legend of Kyrandia under ScummVM you need the 'kyra.dat'
file. The file should always be included in official ScummVM packages.
@@ -707,7 +811,7 @@ thus you only need to grab it in case ScummVM complains about the file
being missing.
-3.15) Sierra AGI games Predictive Input Dialog notes:
+3.16) Sierra AGI games Predictive Input Dialog notes:
----- -----------------------------------------------
The Predictive Input Dialog is a ScummVM aid for running AGI engine
games (which notoriously require command line input) on devices with
@@ -761,7 +865,7 @@ naturally mapping the functionality to the numeric keypad. Also, the
dialog's buttons can be navigated with the arrow and the enter keys.
-3.16) Mickey's Space Adventure notes:
+3.17) Mickey's Space Adventure notes:
----- -------------------------------
To run Mickey's Space Adventure under ScummVM, the original executable
of the game (mickey.exe) is needed together with the game's data files.
@@ -776,7 +880,7 @@ game's screen to change location, similar to many adventure games, which
is simpler and more straightforward than moving around using the menu.
-3.17) Winnie the Pooh notes:
+3.18) Winnie the Pooh notes:
----- ----------------------
It is possible to import saved games from the original interpreter of the
game into ScummVM.
@@ -791,14 +895,14 @@ game's screen to change location, similar to many adventure games, which
is simpler and more straightforward than moving around using the menu.
-3.18) Troll's Tale notes:
+3.19) Troll's Tale notes:
----- -------------------
The original game came in a PC booter disk, therefore it is necessary to
dump the contents of that disk in an image file and name it "troll.img"
to be able to play the game under ScummVM.
-3.19) Dragon History notes:
+3.20) Dragon History notes:
----- ---------------------
There are 4 language variants of the game: Czech, English, Polish and
German. Each of them is distributed in a separate archive. The only
@@ -816,7 +920,7 @@ All game files and the walkthrough can be downloaded from
http://www.ucw.cz/draci-historie/index-en.html
-3.20) Simultaneous speech and subtitles in Sierra SCI games:
+3.21) Simultaneous speech and subtitles in Sierra SCI games:
----- ------------------------------------------------------
Certain CD versions of Sierra SCI games had both speech and text
resources. Some have an option to toggle between the two, but there are
@@ -864,7 +968,7 @@ Space Quest 4 CD:
options dialog, or via ScummVM's audio options.
-3.21) Known Problems:
+3.22) Known Problems:
----- ---------------
This release has the following known problems. There is no need to
report them, although patches to fix them are welcome. If you discover a
@@ -909,7 +1013,11 @@ site, please see the section on reporting bugs.
Inherit the Earth: Quest for the Orb
- Amiga versions aren't supported
- Simon the Sorcerer 1:
+ Lure of the Temptress
+ - No Roland MT-32 support
+ - Sound support is incomplete and doesn't sound like original
+
+ Simon the Sorcerer 1:
- Subtitles aren't available in the English and German CD versions
as they are missing the majority of subtitles.
@@ -1244,6 +1352,7 @@ Engines which currently support returning to the Launcher are:
TOUCHE
TSAGE
TUCKER
+ ZVISION
5.5) Hotkeys:
@@ -1408,6 +1517,26 @@ other games.
t - Switch between 'Voice only',
'Voice and Text' and 'Text only'
+ Zork: Grand Inquisitor
+ Ctrl-s - Save
+ Ctrl-r - Restore
+ Ctrl-q - Quit
+ Ctrl-p - Preferences
+ F1 - Help
+ F5 - Inventory
+ F6 - Spellbook
+ F7 - Score
+ F8 - Put away current object/forget spell
+ F9 - Extract coin (must have the coin bag)
+ Space - Skips movies
+
+ Zork Nemesis: The Forbidden Lands
+ Ctrl-s - Save
+ Ctrl-r - Restore
+ Ctrl-q - Quit
+ Ctrl-p - Preferences
+ Space - Skips movies
+
Note that using Ctrl-f or Ctrl-g is not recommended: games can crash
when being run faster than their normal speed, as scripts will lose
synchronisation.
@@ -1527,6 +1656,7 @@ Where 'xxx' is exact the saved game slot (ie 001) under ScummVM
TOUCHE
TSAGE
TUCKER
+ ZVISION
--save-slot/-x:
@@ -1559,6 +1689,7 @@ Where 'xxx' is exact the saved game slot (ie 001) under ScummVM
TOUCHE
TSAGE
TUCKER
+ ZVISION
7.0) Music and Sound:
@@ -2137,6 +2268,10 @@ Sierra games using the AGI engine add the following non-standard keywords:
originalsaveload bool If true, the original save/load screens are
used instead of the enhanced ScummVM ones
+ altamigapalette bool Use an alternative palette, common for all
+ Amiga games. This was the old behavior
+ mousesupport bool Enables mouse support. Allows to use mouse
+ for movement and in game menus
Sierra games using the SCI engine add the following non-standard keywords:
@@ -2148,6 +2283,12 @@ Sierra games using the SCI engine add the following non-standard keywords:
native_fb01 bool If true, the music driver for an IBM Music
Feature card or a Yamaha FB-01 FM synth module
is used for MIDI output
+ use_cdaudio bool Use CD audio instead of in-game audio,
+ when available
+ windows_cursors bool Use the Windows cursors (smaller and monochrome)
+ instead of the DOS ones (King's Quest 6)
+ silver_cursors bool Use the alternate set of silver cursors,
+ instead of the normal golden ones (Space Quest 4)
Broken Sword II adds the following non-standard keywords:
@@ -2240,6 +2381,27 @@ The 7th Guest adds the following non-standard keyword:
normal speed, to avoid music synchronization
issues
+Zork Nemesis: The Forbidden Lands adds the following non-standard keywords:
+
+ originalsaveload bool If true, the original save/load screens are
+ used instead of the enhanced ScummVM ones
+ doublefps bool If true, game FPS are increased from 30 to 60
+ venusenabled bool If true, the in-game Venus help system is
+ enabled
+ noanimwhileturning bool If true, animations are disabled while turning
+ in panoramic mode
+
+Zork: Grand Inquisitor adds the following non-standard keywords:
+
+ originalsaveload bool If true, the original save/load screens are
+ used instead of the enhanced ScummVM ones
+ doublefps bool If true, game FPS are increased from 30 to 60
+ noanimwhileturning bool If true, animations are disabled while turning
+ in panoramic mode
+ mpegmovies bool If true, the hires MPEG movies are used in the
+ DVD version of the game, instead of the lowres
+ AVI ones
+
8.2) Custom game options that can be toggled via the GUI
---- ---------------------------------------------------
@@ -2308,9 +2470,11 @@ debug messages (see http://www.sysinternals.com/ntw2k/freeware/debugview.shtml).
* Type "./configure" in the ScummVM directory.
* You can now type 'make' to create a command line binary.
* To get a version you can run from Finder, type 'make bundle' which
- will create ScummVM.app (this only works out of the box if you
- installed SDL into /sw (as happens if you are using Fink). If you
- have installed SDL in another way, you will have to edit ports.mk).
+ will create ScummVM.app (this tries to detect where the static libraries
+ are installed, which should work in most cases, but if it doesn't you
+ will need to specify this path with --with-staticlib-prefix= when calling
+ configure - for example "./configure --with-staticlib-prefix=/Users/foo"
+ if the libraries are in /Users/foo/lib).
* For more information refer to:
http://wiki.scummvm.org/index.php/Compiling_ScummVM/MacOS_X_Crosscompiling
diff --git a/audio/softsynth/adlib.cpp b/audio/adlib.cpp
index 98519343b4..f609164495 100644
--- a/audio/softsynth/adlib.cpp
+++ b/audio/adlib.cpp
@@ -927,18 +927,20 @@ static void createLookupTable() {
//
////////////////////////////////////////
-class MidiDriver_ADLIB : public MidiDriver_Emulated {
+class MidiDriver_ADLIB : public MidiDriver {
friend class AdLibPart;
friend class AdLibPercussionChannel;
public:
- MidiDriver_ADLIB(Audio::Mixer *mixer);
+ MidiDriver_ADLIB();
int open();
void close();
void send(uint32 b);
void send(byte channel, uint32 b); // Supports higher than channel 15
uint32 property(int prop, uint32 param);
+ bool isOpen() const { return _isOpen; }
+ uint32 getBaseTempo() { return 1000000 / OPL::OPL::kDefaultCallbackFrequency; }
void setPitchBendRange(byte channel, uint range);
void sysEx_customInstrument(byte channel, uint32 type, const byte *instr);
@@ -946,10 +948,7 @@ public:
MidiChannel *allocateChannel();
MidiChannel *getPercussionChannel() { return &_percussion; } // Percussion partially supported
-
- // AudioStream API
- bool isStereo() const { return _opl->isStereo(); }
- int getRate() const { return _mixer->getOutputRate(); }
+ virtual void setTimerCallback(void *timerParam, Common::TimerManager::TimerProc timerProc);
private:
bool _scummSmallHeader; // FIXME: This flag controls a special mode for SCUMM V3 games
@@ -963,6 +962,9 @@ private:
byte *_regCacheSecondary;
#endif
+ Common::TimerManager::TimerProc _adlibTimerProc;
+ void *_adlibTimerParam;
+
int _timerCounter;
uint16 _channelTable2[9];
@@ -974,7 +976,8 @@ private:
AdLibPart _parts[32];
AdLibPercussionChannel _percussion;
- void generateSamples(int16 *buf, int len);
+ bool _isOpen;
+
void onTimer();
void partKeyOn(AdLibPart *part, const AdLibInstrument *instr, byte note, byte velocity, const AdLibInstrument *second, byte pan);
void partKeyOff(AdLibPart *part, byte note);
@@ -1376,8 +1379,7 @@ void AdLibPercussionChannel::sysEx_customInstrument(uint32 type, const byte *ins
// MidiDriver method implementations
-MidiDriver_ADLIB::MidiDriver_ADLIB(Audio::Mixer *mixer)
- : MidiDriver_Emulated(mixer) {
+MidiDriver_ADLIB::MidiDriver_ADLIB() {
uint i;
_scummSmallHeader = false;
@@ -1403,13 +1405,16 @@ MidiDriver_ADLIB::MidiDriver_ADLIB(Audio::Mixer *mixer)
_timerIncrease = 0xD69;
_timerThreshold = 0x411B;
_opl = 0;
+ _adlibTimerProc = 0;
+ _adlibTimerParam = 0;
+ _isOpen = false;
}
int MidiDriver_ADLIB::open() {
if (_isOpen)
return MERR_ALREADY_OPEN;
- MidiDriver_Emulated::open();
+ _isOpen = true;
int i;
AdLibVoice *voice;
@@ -1434,7 +1439,7 @@ int MidiDriver_ADLIB::open() {
_opl3Mode = false;
}
#endif
- _opl->init(getRate());
+ _opl->init();
_regCache = (byte *)calloc(256, 1);
@@ -1452,8 +1457,7 @@ int MidiDriver_ADLIB::open() {
}
#endif
- _mixer->playStream(Audio::Mixer::kPlainSoundType, &_mixerSoundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
-
+ _opl->start(new Common::Functor0Mem<void, MidiDriver_ADLIB>(this, &MidiDriver_ADLIB::onTimer));
return 0;
}
@@ -1462,7 +1466,8 @@ void MidiDriver_ADLIB::close() {
return;
_isOpen = false;
- _mixer->stopHandle(_mixerSoundHandle);
+ // Stop the OPL timer
+ _opl->stop();
uint i;
for (i = 0; i < ARRAYSIZE(_voices); ++i) {
@@ -1616,14 +1621,10 @@ void MidiDriver_ADLIB::adlibWriteSecondary(byte reg, byte value) {
}
#endif
-void MidiDriver_ADLIB::generateSamples(int16 *data, int len) {
- if (_opl->isStereo()) {
- len *= 2;
- }
- _opl->readBuffer(data, len);
-}
-
void MidiDriver_ADLIB::onTimer() {
+ if (_adlibTimerProc)
+ (*_adlibTimerProc)(_adlibTimerParam);
+
_timerCounter += _timerIncrease;
while (_timerCounter >= _timerThreshold) {
_timerCounter -= _timerThreshold;
@@ -1655,6 +1656,11 @@ void MidiDriver_ADLIB::onTimer() {
}
}
+void MidiDriver_ADLIB::setTimerCallback(void *timerParam, Common::TimerManager::TimerProc timerProc) {
+ _adlibTimerProc = timerProc;
+ _adlibTimerParam = timerParam;
+}
+
void MidiDriver_ADLIB::mcOff(AdLibVoice *voice) {
AdLibVoice *tmp;
@@ -2300,7 +2306,7 @@ MusicDevices AdLibEmuMusicPlugin::getDevices() const {
}
Common::Error AdLibEmuMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const {
- *mididriver = new MidiDriver_ADLIB(g_system->getMixer());
+ *mididriver = new MidiDriver_ADLIB();
return Common::kNoError;
}
diff --git a/audio/alsa_opl.cpp b/audio/alsa_opl.cpp
new file mode 100644
index 0000000000..6b9e48e987
--- /dev/null
+++ b/audio/alsa_opl.cpp
@@ -0,0 +1,349 @@
+/* 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 hardware OPL using ALSA Direct FM API.
+ *
+ * Caveats and limitations:
+ * - Pretends to be a softsynth (emitting silence).
+ * - Dual OPL2 mode requires OPL3 hardware.
+ * - Every register write leads to a series of register writes on the hardware,
+ * due to the lack of direct register access in the ALSA Direct FM API.
+ * - No timers
+ */
+
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+#include "common/scummsys.h"
+
+#include "common/debug.h"
+#include "common/str.h"
+#include "audio/fmopl.h"
+
+#include <sys/ioctl.h>
+#include <alsa/asoundlib.h>
+#include <sound/asound_fm.h>
+
+namespace OPL {
+namespace ALSA {
+
+class OPL : public ::OPL::RealOPL {
+private:
+ enum {
+ kOpl2Voices = 9,
+ kVoices = 18,
+ kOpl2Operators = 18,
+ kOperators = 36
+ };
+
+ Config::OplType _type;
+ int _iface;
+ snd_hwdep_t *_opl;
+ snd_dm_fm_voice _oper[kOperators];
+ snd_dm_fm_note _voice[kVoices];
+ snd_dm_fm_params _params;
+ int index[2];
+ static const int voiceToOper0[kVoices];
+ static const int regOffsetToOper[0x20];
+
+ void writeOplReg(int c, int r, int v);
+ void clear();
+
+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);
+};
+
+const int OPL::voiceToOper0[OPL::kVoices] =
+ { 0, 1, 2, 6, 7, 8, 12, 13, 14, 18, 19, 20, 24, 25, 26, 30, 31, 32 };
+
+const int OPL::regOffsetToOper[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 };
+
+OPL::OPL(Config::OplType type) : _type(type), _opl(nullptr), _iface(0) {
+}
+
+OPL::~OPL() {
+ stop();
+
+ if (_opl) {
+ snd_hwdep_ioctl(_opl, SNDRV_DM_FM_IOCTL_RESET, nullptr);
+ snd_hwdep_close(_opl);
+ }
+}
+
+void OPL::clear() {
+ index[0] = index[1] = 0;
+
+ memset(_oper, 0, sizeof(_oper));
+ memset(_voice, 0, sizeof(_voice));
+ memset(&_params, 0, sizeof(_params));
+
+ for (int i = 0; i < kOperators; ++i) {
+ _oper[i].op = (i / 3) % 2;
+ _oper[i].voice = (i / 6) * 3 + (i % 3);
+ }
+
+ for (int i = 0; i < kVoices; ++i)
+ _voice[i].voice = i;
+
+ // For OPL3 hardware we need to set up the panning in OPL2 modes
+ if (_iface == SND_HWDEP_IFACE_OPL3) {
+ if (_type == Config::kDualOpl2) {
+ for (int i = 0; i < kOpl2Operators; ++i)
+ _oper[i].left = 1; // FIXME below
+ for (int i = kOpl2Operators; i < kOperators; ++i)
+ _oper[i].right = 1;
+ } else if (_type == Config::kOpl2) {
+ for (int i = 0; i < kOpl2Operators; ++i) {
+ _oper[i].left = 1;
+ _oper[i].right = 1;
+ }
+ }
+ }
+}
+
+bool OPL::init() {
+ clear();
+
+ int card = -1;
+ snd_ctl_t *ctl;
+ snd_hwdep_info_t *info;
+ snd_hwdep_info_alloca(&info);
+
+ int iface = SND_HWDEP_IFACE_OPL3;
+ if (_type == Config::kOpl2)
+ iface = SND_HWDEP_IFACE_OPL2;
+
+ // Look for OPL hwdep interface
+ while (!snd_card_next(&card) && card >= 0) {
+ int dev = -1;
+ Common::String name = Common::String::format("hw:%d", card);
+
+ if (snd_ctl_open(&ctl, name.c_str(), 0) < 0)
+ continue;
+
+ while (!snd_ctl_hwdep_next_device(ctl, &dev) && dev >= 0) {
+ name = Common::String::format("hw:%d,%d", card, dev);
+
+ if (snd_hwdep_open(&_opl, name.c_str(), SND_HWDEP_OPEN_WRITE) < 0)
+ continue;
+
+ if (!snd_hwdep_info(_opl, info)) {
+ int found = snd_hwdep_info_get_iface(info);
+ // OPL3 can be used for (Dual) OPL2 mode
+ if (found == iface || found == SND_HWDEP_IFACE_OPL3) {
+ snd_ctl_close(ctl);
+ _iface = found;
+ reset();
+ return true;
+ }
+ }
+
+ // Wrong interface, try next device
+ snd_hwdep_close(_opl);
+ _opl = nullptr;
+ }
+
+ snd_ctl_close(ctl);
+ }
+
+ return false;
+}
+
+void OPL::reset() {
+ snd_hwdep_ioctl(_opl, SNDRV_DM_FM_IOCTL_RESET, nullptr);
+ if (_iface == SND_HWDEP_IFACE_OPL3)
+ snd_hwdep_ioctl(_opl, SNDRV_DM_FM_IOCTL_SET_MODE, (void *)SNDRV_DM_FM_MODE_OPL3);
+
+ clear();
+
+ // Sync up with the hardware
+ snd_hwdep_ioctl(_opl, SNDRV_DM_FM_IOCTL_SET_PARAMS, (void *)&_params);
+ for (uint i = 0; i < (_iface == SND_HWDEP_IFACE_OPL3 ? kVoices : kOpl2Voices); ++i)
+ snd_hwdep_ioctl(_opl, SNDRV_DM_FM_IOCTL_PLAY_NOTE, (void *)&_voice[i]);
+ for (uint i = 0; i < (_iface == SND_HWDEP_IFACE_OPL3 ? kOperators : kOpl2Operators); ++i)
+ snd_hwdep_ioctl(_opl, SNDRV_DM_FM_IOCTL_SET_VOICE, (void *)&_oper[i]);
+}
+
+void OPL::write(int port, int val) {
+ val &= 0xff;
+ int chip = (port & 2) >> 1;
+
+ if (port & 1) {
+ switch(_type) {
+ case Config::kOpl2:
+ writeOplReg(0, index[0], val);
+ break;
+ case Config::kDualOpl2:
+ if (port & 8) {
+ writeOplReg(0, index[0], val);
+ writeOplReg(1, index[1], val);
+ } else
+ writeOplReg(chip, index[chip], val);
+ break;
+ case Config::kOpl3:
+ writeOplReg(chip, index[chip], val);
+ }
+ } else {
+ switch(_type) {
+ case Config::kOpl2:
+ index[0] = val;
+ break;
+ case Config::kDualOpl2:
+ if (port & 8) {
+ index[0] = val;
+ index[1] = val;
+ } else
+ index[chip] = val;
+ break;
+ case Config::kOpl3:
+ index[chip] = val;
+ }
+ }
+}
+
+byte OPL::read(int port) {
+ return 0;
+}
+
+void OPL::writeReg(int r, int v) {
+ switch (_type) {
+ case Config::kOpl2:
+ writeOplReg(0, r, v);
+ break;
+ case Config::kDualOpl2:
+ writeOplReg(0, r, v);
+ writeOplReg(1, r, v);
+ break;
+ case Config::kOpl3:
+ writeOplReg(r >= 0x100, r & 0xff, v);
+ }
+}
+
+void OPL::writeOplReg(int c, int r, int v) {
+ if (r == 0x04 && c == 1 && _type == Config::kOpl3) {
+ snd_hwdep_ioctl(_opl, SNDRV_DM_FM_IOCTL_SET_CONNECTION, reinterpret_cast<void *>(v & 0x3f));
+ } else if (r == 0x08 && c == 0) {
+ _params.kbd_split = (v >> 6) & 0x1;
+ snd_hwdep_ioctl(_opl, SNDRV_DM_FM_IOCTL_SET_PARAMS, (void *)&_params);
+ } else if (r == 0xbd && c == 0) {
+ _params.hihat = v & 0x1;
+ _params.cymbal = (v >> 1) & 0x1;
+ _params.tomtom = (v >> 2) & 0x1;
+ _params.snare = (v >> 3) & 0x1;
+ _params.bass = (v >> 4) & 0x1;
+ _params.rhythm = (v >> 5) & 0x1;
+ _params.vib_depth = (v >> 6) & 0x1;
+ _params.am_depth = (v >> 7) & 0x1;
+ snd_hwdep_ioctl(_opl, SNDRV_DM_FM_IOCTL_SET_PARAMS, (void *)&_params);
+ } else if (r < 0xa0 || r >= 0xe0) {
+ // Operator
+ int idx = regOffsetToOper[r & 0x1f];
+
+ if (idx == -1)
+ return;
+
+ if (c == 1)
+ idx += kOpl2Operators;
+
+ switch (r & 0xf0) {
+ case 0x20:
+ case 0x30:
+ _oper[idx].harmonic = v & 0xf;
+ _oper[idx].kbd_scale = (v >> 4) & 0x1;
+ _oper[idx].do_sustain = (v >> 5) & 0x1;
+ _oper[idx].vibrato = (v >> 6) & 0x1;
+ _oper[idx].am = (v >> 7) & 0x1;
+ snd_hwdep_ioctl(_opl, SNDRV_DM_FM_IOCTL_SET_VOICE, (void *)&_oper[idx]);
+ break;
+ case 0x40:
+ case 0x50:
+ _oper[idx].volume = ~v & 0x3f;
+ _oper[idx].scale_level = (v >> 6) & 0x3;
+ snd_hwdep_ioctl(_opl, SNDRV_DM_FM_IOCTL_SET_VOICE, (void *)&_oper[idx]);
+ break;
+ case 0x60:
+ case 0x70:
+ _oper[idx].decay = v & 0xf;
+ _oper[idx].attack = (v >> 4) & 0xf;
+ snd_hwdep_ioctl(_opl, SNDRV_DM_FM_IOCTL_SET_VOICE, (void *)&_oper[idx]);
+ break;
+ case 0x80:
+ case 0x90:
+ _oper[idx].release = v & 0xf;
+ _oper[idx].sustain = (v >> 4) & 0xf;
+ snd_hwdep_ioctl(_opl, SNDRV_DM_FM_IOCTL_SET_VOICE, (void *)&_oper[idx]);
+ break;
+ case 0xe0:
+ case 0xf0:
+ _oper[idx].waveform = v & (_type == Config::kOpl3 ? 0x7 : 0x3);
+ snd_hwdep_ioctl(_opl, SNDRV_DM_FM_IOCTL_SET_VOICE, (void *)&_oper[idx]);
+ }
+ } else {
+ // Voice
+ int idx = r & 0xf;
+
+ if (idx >= kOpl2Voices)
+ return;
+
+ if (c == 1)
+ idx += kOpl2Voices;
+
+ int opIdx = voiceToOper0[idx];
+
+ switch (r & 0xf0) {
+ case 0xa0:
+ _voice[idx].fnum = (_voice[idx].fnum & 0x300) | (v & 0xff);
+ snd_hwdep_ioctl(_opl, SNDRV_DM_FM_IOCTL_PLAY_NOTE, (void *)&_voice[idx]);
+ break;
+ case 0xb0:
+ _voice[idx].fnum = ((v << 8) & 0x300) | (_voice[idx].fnum & 0xff);
+ _voice[idx].octave = (v >> 2) & 0x7;
+ _voice[idx].key_on = (v >> 5) & 0x1;
+ snd_hwdep_ioctl(_opl, SNDRV_DM_FM_IOCTL_PLAY_NOTE, (void *)&_voice[idx]);
+ break;
+ case 0xc0:
+ _oper[opIdx].connection = _oper[opIdx + 3].connection = v & 0x1;
+ _oper[opIdx].feedback = _oper[opIdx + 3].feedback = (v >> 1) & 0x7;
+ if (_type == Config::kOpl3) {
+ _oper[opIdx].left = _oper[opIdx + 3].left = (v >> 4) & 0x1;
+ _oper[opIdx].right = _oper[opIdx + 3].right = (v >> 5) & 0x1;
+ }
+ snd_hwdep_ioctl(_opl, SNDRV_DM_FM_IOCTL_SET_VOICE, (void *)&_oper[opIdx]);
+ }
+ }
+}
+
+OPL *create(Config::OplType type) {
+ return new OPL(type);
+}
+
+} // End of namespace ALSA
+} // End of namespace OPL
diff --git a/audio/decoders/3do.cpp b/audio/decoders/3do.cpp
new file mode 100644
index 0000000000..6d558d4c8c
--- /dev/null
+++ b/audio/decoders/3do.cpp
@@ -0,0 +1,343 @@
+/* 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/textconsole.h"
+#include "common/stream.h"
+#include "common/util.h"
+
+#include "audio/decoders/3do.h"
+#include "audio/decoders/raw.h"
+#include "audio/decoders/adpcm_intern.h"
+
+namespace Audio {
+
+// Reuses ADPCM table
+#define audio_3DO_ADP4_stepSizeTable Ima_ADPCMStream::_imaTable
+#define audio_3DO_ADP4_stepSizeIndex ADPCMStream::_stepAdjustTable
+
+RewindableAudioStream *make3DO_ADP4AudioStream(Common::SeekableReadStream *stream, uint16 sampleRate, bool stereo, uint32 *audioLengthMSecsPtr, DisposeAfterUse::Flag disposeAfterUse, audio_3DO_ADP4_PersistentSpace *persistentSpace) {
+ if (stereo) {
+ warning("make3DO_ADP4Stream(): stereo currently not supported");
+ return 0;
+ }
+
+ if (audioLengthMSecsPtr) {
+ // Caller requires the milliseconds of audio
+ uint32 audioLengthMSecs = stream->size() * 2 * 1000 / sampleRate; // 1 byte == 2 16-bit sample
+ if (stereo) {
+ audioLengthMSecs /= 2;
+ }
+ *audioLengthMSecsPtr = audioLengthMSecs;
+ }
+
+ return new Audio3DO_ADP4_Stream(stream, sampleRate, stereo, disposeAfterUse, persistentSpace);
+}
+
+Audio3DO_ADP4_Stream::Audio3DO_ADP4_Stream(Common::SeekableReadStream *stream, uint16 sampleRate, bool stereo, DisposeAfterUse::Flag disposeAfterUse, audio_3DO_ADP4_PersistentSpace *persistentSpace)
+ : _sampleRate(sampleRate), _stereo(stereo),
+ _stream(stream, disposeAfterUse) {
+
+ _callerDecoderData = persistentSpace;
+ memset(&_initialDecoderData, 0, sizeof(_initialDecoderData));
+ _initialRead = true;
+
+ reset();
+}
+
+void Audio3DO_ADP4_Stream::reset() {
+ memcpy(&_curDecoderData, &_initialDecoderData, sizeof(_curDecoderData));
+ _streamBytesLeft = _stream->size();
+ _stream->seek(0);
+}
+
+bool Audio3DO_ADP4_Stream::rewind() {
+ reset();
+ return true;
+}
+
+int16 Audio3DO_ADP4_Stream::decodeSample(byte compressedNibble) {
+ int16 currentStep = audio_3DO_ADP4_stepSizeTable[_curDecoderData.stepIndex];
+ int32 decodedSample = _curDecoderData.lastSample;
+ int16 delta = currentStep >> 3;
+
+ if (compressedNibble & 1)
+ delta += currentStep >> 2;
+
+ if (compressedNibble & 2)
+ delta += currentStep >> 1;
+
+ if (compressedNibble & 4)
+ delta += currentStep;
+
+ if (compressedNibble & 8) {
+ decodedSample -= delta;
+ } else {
+ decodedSample += delta;
+ }
+
+ _curDecoderData.lastSample = CLIP<int32>(decodedSample, -32768, 32767);
+
+ _curDecoderData.stepIndex += audio_3DO_ADP4_stepSizeIndex[compressedNibble & 0x07];
+ _curDecoderData.stepIndex = CLIP<int16>(_curDecoderData.stepIndex, 0, ARRAYSIZE(audio_3DO_ADP4_stepSizeTable) - 1);
+
+ return _curDecoderData.lastSample;
+}
+
+// Writes the requested amount (or less) of samples into buffer and returns the amount of samples, that got written
+int Audio3DO_ADP4_Stream::readBuffer(int16 *buffer, const int numSamples) {
+ int8 byteCache[AUDIO_3DO_CACHE_SIZE];
+ int8 *byteCachePtr = NULL;
+ int byteCacheSize = 0;
+ int requestedBytesLeft = 0;
+ int decodedSamplesCount = 0;
+
+ int8 compressedByte = 0;
+
+ if (endOfData())
+ return 0; // no more bytes left
+
+ if (_callerDecoderData) {
+ // copy caller decoder data over
+ memcpy(&_curDecoderData, _callerDecoderData, sizeof(_curDecoderData));
+ if (_initialRead) {
+ _initialRead = false;
+ memcpy(&_initialDecoderData, &_curDecoderData, sizeof(_initialDecoderData));
+ }
+ }
+
+ requestedBytesLeft = numSamples >> 1; // 1 byte for 2 16-bit sample
+ if (requestedBytesLeft > _streamBytesLeft)
+ requestedBytesLeft = _streamBytesLeft; // not enough bytes left
+
+ // in case caller requests an uneven amount of samples, we will return an even amount
+
+ // buffering, so that direct decoding of files and such runs way faster
+ while (requestedBytesLeft) {
+ if (requestedBytesLeft > AUDIO_3DO_CACHE_SIZE) {
+ byteCacheSize = AUDIO_3DO_CACHE_SIZE;
+ } else {
+ byteCacheSize = requestedBytesLeft;
+ }
+
+ requestedBytesLeft -= byteCacheSize;
+ _streamBytesLeft -= byteCacheSize;
+
+ // Fill our byte cache
+ _stream->read(byteCache, byteCacheSize);
+
+ byteCachePtr = byteCache;
+
+ // Mono
+ while (byteCacheSize) {
+ compressedByte = *byteCachePtr++;
+ byteCacheSize--;
+
+ buffer[decodedSamplesCount] = decodeSample(compressedByte >> 4);
+ decodedSamplesCount++;
+ buffer[decodedSamplesCount] = decodeSample(compressedByte & 0x0f);
+ decodedSamplesCount++;
+ }
+ }
+
+ if (_callerDecoderData) {
+ // copy caller decoder data back
+ memcpy(_callerDecoderData, &_curDecoderData, sizeof(_curDecoderData));
+ }
+
+ return decodedSamplesCount;
+}
+
+// ============================================================================
+static int16 audio_3DO_SDX2_SquareTable[256] = {
+ -32768,-32258,-31752,-31250,-30752,-30258,-29768,-29282,-28800,-28322,
+ -27848,-27378,-26912,-26450,-25992,-25538,-25088,-24642,-24200,-23762,
+ -23328,-22898,-22472,-22050,-21632,-21218,-20808,-20402,-20000,-19602,
+ -19208,-18818,-18432,-18050,-17672,-17298,-16928,-16562,-16200,-15842,
+ -15488,-15138,-14792,-14450,-14112,-13778,-13448,-13122,-12800,-12482,
+ -12168,-11858,-11552,-11250,-10952,-10658,-10368,-10082, -9800, -9522,
+ -9248, -8978, -8712, -8450, -8192, -7938, -7688, -7442, -7200, -6962,
+ -6728, -6498, -6272, -6050, -5832, -5618, -5408, -5202, -5000, -4802,
+ -4608, -4418, -4232, -4050, -3872, -3698, -3528, -3362, -3200, -3042,
+ -2888, -2738, -2592, -2450, -2312, -2178, -2048, -1922, -1800, -1682,
+ -1568, -1458, -1352, -1250, -1152, -1058, -968, -882, -800, -722,
+ -648, -578, -512, -450, -392, -338, -288, -242, -200, -162,
+ -128, -98, -72, -50, -32, -18, -8, -2, 0, 2,
+ 8, 18, 32, 50, 72, 98, 128, 162, 200, 242,
+ 288, 338, 392, 450, 512, 578, 648, 722, 800, 882,
+ 968, 1058, 1152, 1250, 1352, 1458, 1568, 1682, 1800, 1922,
+ 2048, 2178, 2312, 2450, 2592, 2738, 2888, 3042, 3200, 3362,
+ 3528, 3698, 3872, 4050, 4232, 4418, 4608, 4802, 5000, 5202,
+ 5408, 5618, 5832, 6050, 6272, 6498, 6728, 6962, 7200, 7442,
+ 7688, 7938, 8192, 8450, 8712, 8978, 9248, 9522, 9800, 10082,
+ 10368, 10658, 10952, 11250, 11552, 11858, 12168, 12482, 12800, 13122,
+ 13448, 13778, 14112, 14450, 14792, 15138, 15488, 15842, 16200, 16562,
+ 16928, 17298, 17672, 18050, 18432, 18818, 19208, 19602, 20000, 20402,
+ 20808, 21218, 21632, 22050, 22472, 22898, 23328, 23762, 24200, 24642,
+ 25088, 25538, 25992, 26450, 26912, 27378, 27848, 28322, 28800, 29282,
+ 29768, 30258, 30752, 31250, 31752, 32258
+};
+
+Audio3DO_SDX2_Stream::Audio3DO_SDX2_Stream(Common::SeekableReadStream *stream, uint16 sampleRate, bool stereo, DisposeAfterUse::Flag disposeAfterUse, audio_3DO_SDX2_PersistentSpace *persistentSpace)
+ : _sampleRate(sampleRate), _stereo(stereo),
+ _stream(stream, disposeAfterUse) {
+
+ _callerDecoderData = persistentSpace;
+ memset(&_initialDecoderData, 0, sizeof(_initialDecoderData));
+ _initialRead = true;
+
+ reset();
+}
+
+void Audio3DO_SDX2_Stream::reset() {
+ memcpy(&_curDecoderData, &_initialDecoderData, sizeof(_curDecoderData));
+ _streamBytesLeft = _stream->size();
+ _stream->seek(0);
+}
+
+bool Audio3DO_SDX2_Stream::rewind() {
+ reset();
+ return true;
+}
+
+// Writes the requested amount (or less) of samples into buffer and returns the amount of samples, that got written
+int Audio3DO_SDX2_Stream::readBuffer(int16 *buffer, const int numSamples) {
+ int8 byteCache[AUDIO_3DO_CACHE_SIZE];
+ int8 *byteCachePtr = NULL;
+ int byteCacheSize = 0;
+ int requestedBytesLeft = numSamples; // 1 byte per 16-bit sample
+ int decodedSamplesCount = 0;
+
+ int8 compressedByte = 0;
+ uint8 squareTableOffset = 0;
+ int16 decodedSample = 0;
+
+ if (endOfData())
+ return 0; // no more bytes left
+
+ if (_stereo) {
+ // We expect numSamples to be even in case of Stereo audio
+ assert((numSamples & 1) == 0);
+ }
+
+ if (_callerDecoderData) {
+ // copy caller decoder data over
+ memcpy(&_curDecoderData, _callerDecoderData, sizeof(_curDecoderData));
+ if (_initialRead) {
+ _initialRead = false;
+ memcpy(&_initialDecoderData, &_curDecoderData, sizeof(_initialDecoderData));
+ }
+ }
+
+ requestedBytesLeft = numSamples;
+ if (requestedBytesLeft > _streamBytesLeft)
+ requestedBytesLeft = _streamBytesLeft; // not enough bytes left
+
+ // buffering, so that direct decoding of files and such runs way faster
+ while (requestedBytesLeft) {
+ if (requestedBytesLeft > AUDIO_3DO_CACHE_SIZE) {
+ byteCacheSize = AUDIO_3DO_CACHE_SIZE;
+ } else {
+ byteCacheSize = requestedBytesLeft;
+ }
+
+ requestedBytesLeft -= byteCacheSize;
+ _streamBytesLeft -= byteCacheSize;
+
+ // Fill our byte cache
+ _stream->read(byteCache, byteCacheSize);
+
+ byteCachePtr = byteCache;
+
+ if (!_stereo) {
+ // Mono
+ while (byteCacheSize) {
+ compressedByte = *byteCachePtr++;
+ byteCacheSize--;
+ squareTableOffset = compressedByte + 128;
+
+ if (!(compressedByte & 1))
+ _curDecoderData.lastSample1 = 0;
+
+ decodedSample = _curDecoderData.lastSample1 + audio_3DO_SDX2_SquareTable[squareTableOffset];
+ _curDecoderData.lastSample1 = decodedSample;
+
+ buffer[decodedSamplesCount] = decodedSample;
+ decodedSamplesCount++;
+ }
+ } else {
+ // Stereo
+ while (byteCacheSize) {
+ compressedByte = *byteCachePtr++;
+ byteCacheSize--;
+ squareTableOffset = compressedByte + 128;
+
+ if (!(decodedSamplesCount & 1)) {
+ // First channel
+ if (!(compressedByte & 1))
+ _curDecoderData.lastSample1 = 0;
+
+ decodedSample = _curDecoderData.lastSample1 + audio_3DO_SDX2_SquareTable[squareTableOffset];
+ _curDecoderData.lastSample1 = decodedSample;
+ } else {
+ // Second channel
+ if (!(compressedByte & 1))
+ _curDecoderData.lastSample2 = 0;
+
+ decodedSample = _curDecoderData.lastSample2 + audio_3DO_SDX2_SquareTable[squareTableOffset];
+ _curDecoderData.lastSample2 = decodedSample;
+ }
+
+ buffer[decodedSamplesCount] = decodedSample;
+ decodedSamplesCount++;
+ }
+ }
+ }
+
+ if (_callerDecoderData) {
+ // copy caller decoder data back
+ memcpy(_callerDecoderData, &_curDecoderData, sizeof(_curDecoderData));
+ }
+
+ return decodedSamplesCount;
+}
+
+RewindableAudioStream *make3DO_SDX2AudioStream(Common::SeekableReadStream *stream, uint16 sampleRate, bool stereo, uint32 *audioLengthMSecsPtr, DisposeAfterUse::Flag disposeAfterUse, audio_3DO_SDX2_PersistentSpace *persistentSpace) {
+ if (stereo) {
+ if (stream->size() & 1) {
+ warning("make3DO_SDX2Stream(): stereo data is uneven size");
+ return 0;
+ }
+ }
+
+ if (audioLengthMSecsPtr) {
+ // Caller requires the milliseconds of audio
+ uint32 audioLengthMSecs = stream->size() * 1000 / sampleRate; // 1 byte == 1 16-bit sample
+ if (stereo) {
+ audioLengthMSecs /= 2;
+ }
+ *audioLengthMSecsPtr = audioLengthMSecs;
+ }
+
+ return new Audio3DO_SDX2_Stream(stream, sampleRate, stereo, disposeAfterUse, persistentSpace);
+}
+
+} // End of namespace Audio
diff --git a/audio/decoders/3do.h b/audio/decoders/3do.h
new file mode 100644
index 0000000000..7524358543
--- /dev/null
+++ b/audio/decoders/3do.h
@@ -0,0 +1,158 @@
+/* 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.
+ *
+ */
+
+/**
+ * @file
+ * Sound decoder used in engines:
+ * - sherlock (3DO version of Serrated Scalpel)
+ */
+
+#ifndef AUDIO_3DO_SDX2_H
+#define AUDIO_3DO_SDX2_H
+
+#include "common/scummsys.h"
+#include "common/types.h"
+#include "common/substream.h"
+
+#include "audio/audiostream.h"
+#include "audio/decoders/raw.h"
+
+namespace Common {
+class SeekableReadStream;
+}
+
+namespace Audio {
+
+class SeekableAudioStream;
+
+// amount of bytes to be used within the decoder classes as buffers
+#define AUDIO_3DO_CACHE_SIZE 1024
+
+// persistent spaces
+struct audio_3DO_ADP4_PersistentSpace {
+ int16 lastSample;
+ int16 stepIndex;
+};
+
+struct audio_3DO_SDX2_PersistentSpace {
+ int16 lastSample1;
+ int16 lastSample2;
+};
+
+class Audio3DO_ADP4_Stream : public RewindableAudioStream {
+public:
+ Audio3DO_ADP4_Stream(Common::SeekableReadStream *stream, uint16 sampleRate, bool stereo, DisposeAfterUse::Flag disposeAfterUse, audio_3DO_ADP4_PersistentSpace *persistentSpace);
+
+protected:
+ const uint16 _sampleRate;
+ const bool _stereo;
+
+ Common::DisposablePtr<Common::SeekableReadStream> _stream;
+ int32 _streamBytesLeft;
+
+ void reset();
+ bool rewind();
+ bool endOfData() const { return (_stream->pos() >= _stream->size()); }
+ bool isStereo() const { return _stereo; }
+ int getRate() const { return _sampleRate; }
+
+ int readBuffer(int16 *buffer, const int numSamples);
+
+ bool _initialRead;
+ audio_3DO_ADP4_PersistentSpace *_callerDecoderData;
+ audio_3DO_ADP4_PersistentSpace _initialDecoderData;
+ audio_3DO_ADP4_PersistentSpace _curDecoderData;
+
+private:
+ int16 decodeSample(byte compressedNibble);
+};
+
+class Audio3DO_SDX2_Stream : public RewindableAudioStream {
+public:
+ Audio3DO_SDX2_Stream(Common::SeekableReadStream *stream, uint16 sampleRate, bool stereo, DisposeAfterUse::Flag disposeAfterUse, audio_3DO_SDX2_PersistentSpace *persistentSpacePtr);
+
+protected:
+ const uint16 _sampleRate;
+ const bool _stereo;
+
+ Common::DisposablePtr<Common::SeekableReadStream> _stream;
+ int32 _streamBytesLeft;
+
+ void reset();
+ bool rewind();
+ bool endOfData() const { return (_stream->pos() >= _stream->size()); }
+ bool isStereo() const { return _stereo; }
+ int getRate() const { return _sampleRate; }
+
+ int readBuffer(int16 *buffer, const int numSamples);
+
+ bool _initialRead;
+ audio_3DO_SDX2_PersistentSpace *_callerDecoderData;
+ audio_3DO_SDX2_PersistentSpace _initialDecoderData;
+ audio_3DO_SDX2_PersistentSpace _curDecoderData;
+};
+
+/**
+ * Try to decode 3DO ADP4 data from the given seekable stream and create a SeekableAudioStream
+ * from that data.
+ *
+ * @param stream the SeekableReadStream from which to read the 3DO SDX2 data
+ * @sampleRate sample rate
+ * @stereo if it's stereo or mono
+ * @audioLengthMSecsPtr pointer to a uint32 variable, that is supposed to get the length of the audio in milliseconds
+ * @disposeAfterUse disposeAfterUse whether to delete the stream after use
+ * @persistentSpacePtr pointer to the persistent space structure
+ * @return a new SeekableAudioStream, or NULL, if an error occurred
+ */
+RewindableAudioStream *make3DO_ADP4AudioStream(
+ Common::SeekableReadStream *stream,
+ uint16 sampleRate,
+ bool stereo,
+ uint32 *audioLengthMSecsPtr = NULL, // returns the audio length in milliseconds
+ DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES,
+ audio_3DO_ADP4_PersistentSpace *persistentSpacePtr = NULL
+);
+
+/**
+ * Try to decode 3DO SDX2 data from the given seekable stream and create a SeekableAudioStream
+ * from that data.
+ *
+ * @param stream the SeekableReadStream from which to read the 3DO SDX2 data
+ * @sampleRate sample rate
+ * @stereo if it's stereo or mono
+ * @audioLengthMSecsPtr pointer to a uint32 variable, that is supposed to get the length of the audio in milliseconds
+ * @disposeAfterUse disposeAfterUse whether to delete the stream after use
+ * @persistentSpacePtr pointer to the persistent space structure
+ * @return a new SeekableAudioStream, or NULL, if an error occurred
+ */
+RewindableAudioStream *make3DO_SDX2AudioStream(
+ Common::SeekableReadStream *stream,
+ uint16 sampleRate,
+ bool stereo,
+ uint32 *audioLengthMSecsPtr = NULL, // returns the audio length in milliseconds
+ DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES,
+ audio_3DO_SDX2_PersistentSpace *persistentSpacePtr = NULL
+);
+
+} // End of namespace Audio
+
+#endif
diff --git a/audio/decoders/aiff.cpp b/audio/decoders/aiff.cpp
index b714721c02..72baf84582 100644
--- a/audio/decoders/aiff.cpp
+++ b/audio/decoders/aiff.cpp
@@ -24,16 +24,19 @@
* The code in this file is based on information found at
* http://www.borg.com/~jglatt/tech/aiff.htm
*
- * We currently only implement uncompressed AIFF. If we ever need AIFF-C, SoX
- * (http://sox.sourceforge.net) may be a good place to start from.
+ * Also partially based on libav's aiffdec.c
*/
+#include "common/debug.h"
#include "common/endian.h"
#include "common/stream.h"
+#include "common/substream.h"
#include "common/textconsole.h"
+#include "audio/audiostream.h"
#include "audio/decoders/aiff.h"
#include "audio/decoders/raw.h"
+#include "audio/decoders/3do.h"
namespace Audio {
@@ -62,23 +65,34 @@ uint32 readExtended(Common::SeekableReadStream &stream) {
return mantissa;
}
-bool loadAIFFFromStream(Common::SeekableReadStream &stream, int &size, int &rate, byte &flags) {
- byte buf[4];
+// AIFF versions
+static const uint32 kVersionAIFF = MKTAG('A', 'I', 'F', 'F');
+static const uint32 kVersionAIFC = MKTAG('A', 'I', 'F', 'C');
- stream.read(buf, 4);
- if (memcmp(buf, "FORM", 4) != 0) {
- warning("loadAIFFFromStream: No 'FORM' header");
- return false;
+// Codecs
+static const uint32 kCodecPCM = MKTAG('N', 'O', 'N', 'E'); // very original
+
+RewindableAudioStream *makeAIFFStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse) {
+ if (stream->readUint32BE() != MKTAG('F', 'O', 'R', 'M')) {
+ warning("makeAIFFStream: No 'FORM' header");
+
+ if (disposeAfterUse == DisposeAfterUse::YES)
+ delete stream;
+
+ return 0;
}
- stream.readUint32BE();
+ stream->readUint32BE(); // file size
+
+ uint32 version = stream->readUint32BE();
- // This could be AIFC, but we don't handle that case.
+ if (version != kVersionAIFF && version != kVersionAIFC) {
+ warning("makeAIFFStream: No 'AIFF' or 'AIFC' header");
+
+ if (disposeAfterUse == DisposeAfterUse::YES)
+ delete stream;
- stream.read(buf, 4);
- if (memcmp(buf, "AIFF", 4) != 0) {
- warning("loadAIFFFromStream: No 'AIFF' header");
- return false;
+ return 0;
}
// From here on, we only care about the COMM and SSND chunks, which are
@@ -87,95 +101,131 @@ bool loadAIFFFromStream(Common::SeekableReadStream &stream, int &size, int &rate
bool foundCOMM = false;
bool foundSSND = false;
- uint16 numChannels = 0, bitsPerSample = 0;
- uint32 numSampleFrames = 0, offset = 0, blockSize = 0, soundOffset = 0;
+ uint16 channels = 0, bitsPerSample = 0;
+ uint32 blockAlign = 0, rate = 0;
+ uint32 codec = kCodecPCM; // AIFF default
+ Common::SeekableReadStream *dataStream = 0;
- while (!(foundCOMM && foundSSND) && !stream.err() && !stream.eos()) {
- uint32 length, pos;
+ while (!(foundCOMM && foundSSND) && !stream->err() && !stream->eos()) {
+ uint32 tag = stream->readUint32BE();
+ uint32 length = stream->readUint32BE();
+ uint32 pos = stream->pos();
- stream.read(buf, 4);
- length = stream.readUint32BE();
- pos = stream.pos();
+ if (stream->eos() || stream->err())
+ break;
- if (memcmp(buf, "COMM", 4) == 0) {
+ switch (tag) {
+ case MKTAG('C', 'O', 'M', 'M'):
foundCOMM = true;
- numChannels = stream.readUint16BE();
- numSampleFrames = stream.readUint32BE();
- bitsPerSample = stream.readUint16BE();
- rate = readExtended(stream);
- size = numSampleFrames * numChannels * (bitsPerSample / 8);
- } else if (memcmp(buf, "SSND", 4) == 0) {
+ channels = stream->readUint16BE();
+ /* frameCount = */ stream->readUint32BE();
+ bitsPerSample = stream->readUint16BE();
+ rate = readExtended(*stream);
+
+ if (version == kVersionAIFC)
+ codec = stream->readUint32BE();
+ break;
+ case MKTAG('S', 'S', 'N', 'D'):
foundSSND = true;
- offset = stream.readUint32BE();
- blockSize = stream.readUint32BE();
- soundOffset = stream.pos();
+ /* uint32 offset = */ stream->readUint32BE();
+ blockAlign = stream->readUint32BE();
+ dataStream = new Common::SeekableSubReadStream(stream, stream->pos(), stream->pos() + length - 8, disposeAfterUse);
+ break;
+ case MKTAG('F', 'V', 'E', 'R'):
+ switch (stream->readUint32BE()) {
+ case 0:
+ version = kVersionAIFF;
+ break;
+ case 0xA2805140:
+ version = kVersionAIFC;
+ break;
+ default:
+ warning("Unknown AIFF version chunk version");
+ break;
+ }
+ break;
+ case MKTAG('w', 'a', 'v', 'e'):
+ warning("Found unhandled AIFF-C extra data chunk");
+
+ if (!dataStream && disposeAfterUse == DisposeAfterUse::YES)
+ delete stream;
+
+ delete dataStream;
+ return 0;
+ default:
+ debug(1, "Skipping AIFF '%s' chunk", tag2str(tag));
+ break;
}
- stream.seek(pos + length);
+ stream->seek(pos + length + (length & 1)); // ensure we're also word-aligned
}
if (!foundCOMM) {
- warning("loadAIFFFromStream: Cound not find 'COMM' chunk");
- return false;
- }
-
- if (!foundSSND) {
- warning("loadAIFFFromStream: Cound not find 'SSND' chunk");
- return false;
- }
-
- // We only implement a subset of the AIFF standard.
-
- if (numChannels < 1 || numChannels > 2) {
- warning("loadAIFFFromStream: Only 1 or 2 channels are supported, not %d", numChannels);
- return false;
- }
+ warning("makeAIFFStream: Cound not find 'COMM' chunk");
- if (bitsPerSample != 8 && bitsPerSample != 16) {
- warning("loadAIFFFromStream: Only 8 or 16 bits per sample are supported, not %d", bitsPerSample);
- return false;
- }
+ if (!dataStream && disposeAfterUse == DisposeAfterUse::YES)
+ delete stream;
- if (offset != 0 || blockSize != 0) {
- warning("loadAIFFFromStream: Block-aligned data is not supported");
- return false;
+ delete dataStream;
+ return 0;
}
- // Samples are always signed, and big endian.
-
- flags = 0;
- if (bitsPerSample == 16)
- flags |= Audio::FLAG_16BITS;
- if (numChannels == 2)
- flags |= Audio::FLAG_STEREO;
-
- stream.seek(soundOffset);
-
- // Stream now points at the sample data
-
- return true;
-}
-
-SeekableAudioStream *makeAIFFStream(Common::SeekableReadStream *stream,
- DisposeAfterUse::Flag disposeAfterUse) {
- int size, rate;
- byte *data, flags;
+ if (!foundSSND) {
+ warning("makeAIFFStream: Cound not find 'SSND' chunk");
- if (!loadAIFFFromStream(*stream, size, rate, flags)) {
if (disposeAfterUse == DisposeAfterUse::YES)
delete stream;
+
return 0;
}
- data = (byte *)malloc(size);
- assert(data);
- stream->read(data, size);
+ // We only implement a subset of the AIFF standard.
- if (disposeAfterUse == DisposeAfterUse::YES)
- delete stream;
+ if (channels < 1 || channels > 2) {
+ warning("makeAIFFStream: Only 1 or 2 channels are supported, not %d", channels);
+ delete dataStream;
+ return 0;
+ }
+
+ // Seek to the start of dataStream, required for at least FileStream
+ dataStream->seek(0);
+
+ switch (codec) {
+ case kCodecPCM:
+ case MKTAG('t', 'w', 'o', 's'):
+ case MKTAG('s', 'o', 'w', 't'): {
+ // PCM samples are always signed.
+ byte rawFlags = 0;
+ if (bitsPerSample == 16)
+ rawFlags |= Audio::FLAG_16BITS;
+ if (channels == 2)
+ rawFlags |= Audio::FLAG_STEREO;
+ if (codec == MKTAG('s', 'o', 'w', 't'))
+ rawFlags |= Audio::FLAG_LITTLE_ENDIAN;
+
+ return makeRawStream(dataStream, rate, rawFlags);
+ }
+ case MKTAG('i', 'm', 'a', '4'):
+ // TODO: Use QT IMA ADPCM
+ warning("Unhandled AIFF-C QT IMA ADPCM compression");
+ break;
+ case MKTAG('Q', 'D', 'M', '2'):
+ // TODO: Need to figure out how to integrate this
+ // (But hopefully never needed)
+ warning("Unhandled AIFF-C QDM2 compression");
+ break;
+ case MKTAG('A', 'D', 'P', '4'):
+ // ADP4 on 3DO
+ return make3DO_ADP4AudioStream(dataStream, rate, channels == 2);
+ case MKTAG('S', 'D', 'X', '2'):
+ // SDX2 on 3DO
+ return make3DO_SDX2AudioStream(dataStream, rate, channels == 2);
+ default:
+ warning("Unhandled AIFF-C compression tag '%s'", tag2str(codec));
+ }
- // Since we allocated our own buffer for the data, we must specify DisposeAfterUse::YES.
- return makeRawStream(data, size, rate, flags);
+ delete dataStream;
+ return 0;
}
} // End of namespace Audio
diff --git a/audio/decoders/aiff.h b/audio/decoders/aiff.h
index afb0342cfd..3af2efb4c9 100644
--- a/audio/decoders/aiff.h
+++ b/audio/decoders/aiff.h
@@ -23,6 +23,7 @@
/**
* @file
* Sound decoder used in engines:
+ * - bbvs
* - pegasus
* - saga
* - sci
@@ -41,28 +42,17 @@ class SeekableReadStream;
namespace Audio {
-class SeekableAudioStream;
-
-/**
- * Try to load an AIFF from the given seekable stream. Returns true if
- * successful. In that case, the stream's seek position will be set to the
- * start of the audio data, and size, rate and flags contain information
- * necessary for playback. Currently this function only supports uncompressed
- * raw PCM.
- */
-extern bool loadAIFFFromStream(Common::SeekableReadStream &stream, int &size, int &rate, byte &flags);
+class RewindableAudioStream;
/**
* Try to load an AIFF from the given seekable stream and create an AudioStream
* from that data.
*
- * This function uses loadAIFFFromStream() internally.
- *
* @param stream the SeekableReadStream from which to read the AIFF data
* @param disposeAfterUse whether to delete the stream after use
* @return a new SeekableAudioStream, or NULL, if an error occurred
*/
-SeekableAudioStream *makeAIFFStream(
+RewindableAudioStream *makeAIFFStream(
Common::SeekableReadStream *stream,
DisposeAfterUse::Flag disposeAfterUse);
diff --git a/audio/decoders/mp3.cpp b/audio/decoders/mp3.cpp
index c1b3faaeb1..feb531f5ae 100644
--- a/audio/decoders/mp3.cpp
+++ b/audio/decoders/mp3.cpp
@@ -246,6 +246,23 @@ void MP3Stream::initStream() {
_inStream->seek(0, SEEK_SET);
_curTime = mad_timer_zero;
_posInFrame = 0;
+
+ // Skip ID3 TAG if any
+ // ID3v1 (beginning with with 'TAG') is located at the end of files. So we can ignore those.
+ // ID3v2 can be located at the start of files and begins with a 10 bytes header, the first 3 bytes being 'ID3'.
+ // The tag size is coded on the last 4 bytes of the 10 bytes header as a 32 bit synchsafe integer.
+ // See http://id3.org/id3v2.4.0-structure for details.
+ char data[10];
+ _inStream->read(data, 10);
+ if (data[0] == 'I' && data[1] == 'D' && data[2] == '3') {
+ uint32 size = data[9] + 128 * (data[8] + 128 * (data[7] + 128 * data[6]));
+ // This size does not include an optional 10 bytes footer. Check if it is present.
+ if (data[5] & 0x10)
+ size += 10;
+ debug("Skipping ID3 TAG (%d bytes)", size + 10);
+ _inStream->seek(size, SEEK_CUR);
+ } else
+ _inStream->seek(0, SEEK_SET);
// Update state
_state = MP3_STATE_READY;
diff --git a/audio/decoders/quicktime.cpp b/audio/decoders/quicktime.cpp
index 331c850b1a..ff87e7a9f8 100644
--- a/audio/decoders/quicktime.cpp
+++ b/audio/decoders/quicktime.cpp
@@ -241,6 +241,15 @@ void QuickTimeAudioDecoder::QuickTimeAudioTrack::queueAudio(const Timestamp &len
// If we have any samples that we need to skip (ie. we seeked into
// the middle of a chunk), skip them here.
if (_skipSamples != Timestamp()) {
+ if (_skipSamples > chunkLength) {
+ // If the amount we need to skip is greater than the size
+ // of the chunk, just skip it altogether.
+ _curMediaPos = _curMediaPos + chunkLength;
+ _skipSamples = _skipSamples - chunkLength;
+ delete stream;
+ continue;
+ }
+
skipSamples(_skipSamples, stream);
_curMediaPos = _curMediaPos + _skipSamples;
chunkLength = chunkLength - _skipSamples;
diff --git a/audio/decoders/wave.h b/audio/decoders/wave.h
index 1dcaefd845..6bc9f72101 100644
--- a/audio/decoders/wave.h
+++ b/audio/decoders/wave.h
@@ -23,15 +23,25 @@
/**
* @file
* Sound decoder used in engines:
+ * - access
* - agos
+ * - cge
+ * - cge2
+ * - fullpipe
* - gob
+ * - hopkins
* - mohawk
+ * - prince
* - saga
* - sci
* - scumm
+ * - sherlock
* - sword1
* - sword2
+ * - tony
* - tucker
+ * - wintermute
+ * - zvision
*/
#ifndef AUDIO_WAVE_H
diff --git a/audio/fmopl.cpp b/audio/fmopl.cpp
index c18e544410..cc00ace264 100644
--- a/audio/fmopl.cpp
+++ b/audio/fmopl.cpp
@@ -22,21 +22,33 @@
#include "audio/fmopl.h"
+#include "audio/mixer.h"
#include "audio/softsynth/opl/dosbox.h"
#include "audio/softsynth/opl/mame.h"
#include "common/config-manager.h"
+#include "common/system.h"
#include "common/textconsole.h"
+#include "common/timer.h"
#include "common/translation.h"
namespace OPL {
+// Factory functions
+
+#ifdef USE_ALSA
+namespace ALSA {
+ OPL *create(Config::OplType type);
+} // End of namespace ALSA
+#endif // USE_ALSA
+
// Config implementation
enum OplEmulator {
kAuto = 0,
kMame = 1,
- kDOSBox = 2
+ kDOSBox = 2,
+ kALSA = 3
};
OPL::OPL() {
@@ -51,6 +63,9 @@ const Config::EmulatorDescription Config::_drivers[] = {
#ifndef DISABLE_DOSBOX_OPL
{ "db", _s("DOSBox OPL emulator"), kDOSBox, kFlagOpl2 | kFlagDualOpl2 | kFlagOpl3 },
#endif
+#ifdef USE_ALSA
+ { "alsa", _s("ALSA Direct FM"), kALSA, kFlagOpl2 | kFlagDualOpl2 | kFlagOpl3 },
+#endif
{ 0, 0, 0, 0 }
};
@@ -63,6 +78,15 @@ Config::DriverId Config::parse(const Common::String &name) {
return -1;
}
+const Config::EmulatorDescription *Config::findDriver(DriverId id) {
+ for (int i = 0; _drivers[i].name; ++i) {
+ if (_drivers[i].id == id)
+ return &_drivers[i];
+ }
+
+ return 0;
+}
+
Config::DriverId Config::detect(OplType type) {
uint32 flags = 0;
switch (type) {
@@ -80,12 +104,21 @@ Config::DriverId Config::detect(OplType type) {
}
DriverId drv = parse(ConfMan.get("opl_driver"));
+ if (drv == kAuto) {
+ // Since the "auto" can be explicitly set for a game, and this
+ // driver shows up in the GUI as "<default>", check if there is
+ // a global setting for it before resorting to auto-detection.
+ drv = parse(ConfMan.get("opl_driver", Common::ConfigManager::kApplicationDomain));
+ }
// When a valid driver is selected, check whether it supports
// the requested OPL chip.
if (drv != -1 && drv != kAuto) {
+ const EmulatorDescription *driverDesc = findDriver(drv);
// If the chip is supported, just use the driver.
- if ((flags & _drivers[drv].flags)) {
+ if (!driverDesc) {
+ warning("The selected OPL driver %d could not be found", drv);
+ } else if ((flags & driverDesc->flags)) {
return drv;
} else {
// Else we will output a warning and just
@@ -145,6 +178,11 @@ OPL *Config::create(DriverId driver, OplType type) {
return new DOSBox::OPL(type);
#endif
+#ifdef USE_ALSA
+ case kALSA:
+ return ALSA::create(type);
+#endif
+
default:
warning("Unsupported OPL emulator %d", driver);
// TODO: Maybe we should add some dummy emulator too, which just outputs
@@ -153,43 +191,143 @@ OPL *Config::create(DriverId driver, OplType type) {
}
}
+void OPL::start(TimerCallback *callback, int timerFrequency) {
+ _callback.reset(callback);
+ startCallbacks(timerFrequency);
+}
+
+void OPL::stop() {
+ stopCallbacks();
+ _callback.reset();
+}
+
bool OPL::_hasInstance = false;
-} // End of namespace OPL
+RealOPL::RealOPL() : _baseFreq(0), _remainingTicks(0) {
+}
-void OPLDestroy(FM_OPL *OPL) {
- delete OPL;
+RealOPL::~RealOPL() {
+ // Stop callbacks, just in case. If it's still playing at this
+ // point, there's probably a bigger issue, though. The subclass
+ // needs to call stop() or the pointer can still use be used in
+ // the mixer thread at the same time.
+ stop();
}
-void OPLResetChip(FM_OPL *OPL) {
- OPL->reset();
+void RealOPL::setCallbackFrequency(int timerFrequency) {
+ stopCallbacks();
+ startCallbacks(timerFrequency);
}
-void OPLWrite(FM_OPL *OPL, int a, int v) {
- OPL->write(a, v);
+void RealOPL::startCallbacks(int timerFrequency) {
+ _baseFreq = timerFrequency;
+ assert(_baseFreq > 0);
+
+ // We can't request more a timer faster than 100Hz. We'll handle this by calling
+ // the proc multiple times in onTimer() later on.
+ if (timerFrequency > kMaxFreq)
+ timerFrequency = kMaxFreq;
+
+ _remainingTicks = 0;
+ g_system->getTimerManager()->installTimerProc(timerProc, 1000000 / timerFrequency, this, "RealOPL");
}
-unsigned char OPLRead(FM_OPL *OPL, int a) {
- return OPL->read(a);
+void RealOPL::stopCallbacks() {
+ g_system->getTimerManager()->removeTimerProc(timerProc);
+ _baseFreq = 0;
+ _remainingTicks = 0;
}
-void OPLWriteReg(FM_OPL *OPL, int r, int v) {
- OPL->writeReg(r, v);
+void RealOPL::timerProc(void *refCon) {
+ static_cast<RealOPL *>(refCon)->onTimer();
}
-void YM3812UpdateOne(FM_OPL *OPL, int16 *buffer, int length) {
- OPL->readBuffer(buffer, length);
+void RealOPL::onTimer() {
+ uint callbacks = 1;
+
+ if (_baseFreq > kMaxFreq) {
+ // We run faster than our max, so run the callback multiple
+ // times to approximate the actual timer callback frequency.
+ uint totalTicks = _baseFreq + _remainingTicks;
+ callbacks = totalTicks / kMaxFreq;
+ _remainingTicks = totalTicks % kMaxFreq;
+ }
+
+ // Call the callback multiple times. The if is on the inside of the
+ // loop in case the callback removes itself.
+ for (uint i = 0; i < callbacks; i++)
+ if (_callback && _callback->isValid())
+ (*_callback)();
}
-FM_OPL *makeAdLibOPL(int rate) {
- FM_OPL *opl = OPL::Config::create();
+EmulatedOPL::EmulatedOPL() :
+ _nextTick(0),
+ _samplesPerTick(0),
+ _baseFreq(0),
+ _handle(new Audio::SoundHandle()) {
+}
- if (opl) {
- if (!opl->init(rate)) {
- delete opl;
- opl = 0;
+EmulatedOPL::~EmulatedOPL() {
+ // Stop callbacks, just in case. If it's still playing at this
+ // point, there's probably a bigger issue, though. The subclass
+ // needs to call stop() or the pointer can still use be used in
+ // the mixer thread at the same time.
+ stop();
+
+ delete _handle;
+}
+
+int EmulatedOPL::readBuffer(int16 *buffer, const int numSamples) {
+ const int stereoFactor = isStereo() ? 2 : 1;
+ int len = numSamples / stereoFactor;
+ int step;
+
+ do {
+ step = len;
+ if (step > (_nextTick >> FIXP_SHIFT))
+ step = (_nextTick >> FIXP_SHIFT);
+
+ generateSamples(buffer, step * stereoFactor);
+
+ _nextTick -= step << FIXP_SHIFT;
+ if (!(_nextTick >> FIXP_SHIFT)) {
+ if (_callback && _callback->isValid())
+ (*_callback)();
+
+ _nextTick += _samplesPerTick;
}
- }
- return opl;
+ buffer += step * stereoFactor;
+ len -= step;
+ } while (len);
+
+ return numSamples;
+}
+
+int EmulatedOPL::getRate() const {
+ return g_system->getMixer()->getOutputRate();
}
+
+void EmulatedOPL::startCallbacks(int timerFrequency) {
+ setCallbackFrequency(timerFrequency);
+ g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, _handle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
+}
+
+void EmulatedOPL::stopCallbacks() {
+ g_system->getMixer()->stopHandle(*_handle);
+}
+
+void EmulatedOPL::setCallbackFrequency(int timerFrequency) {
+ _baseFreq = timerFrequency;
+ assert(_baseFreq != 0);
+
+ int d = getRate() / _baseFreq;
+ int r = getRate() % _baseFreq;
+
+ // This is equivalent to (getRate() << FIXP_SHIFT) / BASE_FREQ
+ // but less prone to arithmetic overflow.
+
+ _samplesPerTick = (d << FIXP_SHIFT) + (r << FIXP_SHIFT) / _baseFreq;
+}
+
+} // End of namespace OPL
diff --git a/audio/fmopl.h b/audio/fmopl.h
index 85ac606c7a..ba0872d87b 100644
--- a/audio/fmopl.h
+++ b/audio/fmopl.h
@@ -23,8 +23,16 @@
#ifndef AUDIO_FMOPL_H
#define AUDIO_FMOPL_H
+#include "audio/audiostream.h"
+
+#include "common/func.h"
+#include "common/ptr.h"
#include "common/scummsys.h"
+namespace Audio {
+class SoundHandle;
+}
+
namespace Common {
class String;
}
@@ -71,6 +79,12 @@ public:
static DriverId parse(const Common::String &name);
/**
+ * @return The driver description for the given id or 0 in case it is not
+ * available.
+ */
+ static const EmulatorDescription *findDriver(DriverId id);
+
+ /**
* Detects a driver for the specific type.
*
* @return Returns a valid driver id on success, -1 otherwise.
@@ -92,6 +106,14 @@ private:
static const EmulatorDescription _drivers[];
};
+/**
+ * The type of the OPL timer callback functor.
+ */
+typedef Common::Functor0<void> TimerCallback;
+
+/**
+ * A representation of a Yamaha OPL chip.
+ */
class OPL {
private:
static bool _hasInstance;
@@ -102,10 +124,9 @@ public:
/**
* Initializes the OPL emulator.
*
- * @param rate output sample rate
* @return true on success, false on failure
*/
- virtual bool init(int rate) = 0;
+ virtual bool init() = 0;
/**
* Reinitializes the OPL emulator
@@ -140,6 +161,101 @@ public:
virtual void writeReg(int r, int v) = 0;
/**
+ * Start the OPL with callbacks.
+ */
+ void start(TimerCallback *callback, int timerFrequency = kDefaultCallbackFrequency);
+
+ /**
+ * Stop the OPL
+ */
+ void stop();
+
+ /**
+ * Change the callback frequency. This must only be called from a
+ * timer proc.
+ */
+ virtual void setCallbackFrequency(int timerFrequency) = 0;
+
+ enum {
+ /**
+ * The default callback frequency that start() uses
+ */
+ kDefaultCallbackFrequency = 250
+ };
+
+protected:
+ /**
+ * Start the callbacks.
+ */
+ virtual void startCallbacks(int timerFrequency) = 0;
+
+ /**
+ * Stop the callbacks.
+ */
+ virtual void stopCallbacks() = 0;
+
+ /**
+ * The functor for callbacks.
+ */
+ Common::ScopedPtr<TimerCallback> _callback;
+};
+
+/**
+ * An OPL that represents a real OPL, as opposed to an emulated one.
+ *
+ * This will use an actual timer instead of using one calculated from
+ * the number of samples in an AudioStream::readBuffer call.
+ */
+class RealOPL : public OPL {
+public:
+ RealOPL();
+ virtual ~RealOPL();
+
+ // OPL API
+ void setCallbackFrequency(int timerFrequency);
+
+protected:
+ // OPL API
+ void startCallbacks(int timerFrequency);
+ void stopCallbacks();
+
+private:
+ static void timerProc(void *refCon);
+ void onTimer();
+
+ uint _baseFreq;
+ uint _remainingTicks;
+
+ enum {
+ kMaxFreq = 100
+ };
+};
+
+/**
+ * An OPL that represents an emulated OPL.
+ *
+ * This will send callbacks based on the number of samples
+ * decoded in readBuffer().
+ */
+class EmulatedOPL : public OPL, protected Audio::AudioStream {
+public:
+ EmulatedOPL();
+ virtual ~EmulatedOPL();
+
+ // OPL API
+ void setCallbackFrequency(int timerFrequency);
+
+ // AudioStream API
+ int readBuffer(int16 *buffer, const int numSamples);
+ int getRate() const;
+ bool endOfData() const { return false; }
+
+protected:
+ // OPL API
+ void startCallbacks(int timerFrequency);
+ void stopCallbacks();
+
+ /**
* Read up to 'length' samples.
*
* Data will be in native endianess, 16 bit per sample, signed.
@@ -149,33 +265,21 @@ public:
* So if you request 4 samples from a stereo OPL, you will get
* a total of two left channel and two right channel samples.
*/
- virtual void readBuffer(int16 *buffer, int length) = 0;
-
- /**
- * Returns whether the setup OPL mode is stereo or not
- */
- virtual bool isStereo() const = 0;
-};
+ virtual void generateSamples(int16 *buffer, int numSamples) = 0;
-} // End of namespace OPL
+private:
+ int _baseFreq;
-// Legacy API
-// !You should not write any new code using the legacy API!
-typedef OPL::OPL FM_OPL;
+ enum {
+ FIXP_SHIFT = 16
+ };
-void OPLDestroy(FM_OPL *OPL);
+ int _nextTick;
+ int _samplesPerTick;
-void OPLResetChip(FM_OPL *OPL);
-void OPLWrite(FM_OPL *OPL, int a, int v);
-unsigned char OPLRead(FM_OPL *OPL, int a);
-void OPLWriteReg(FM_OPL *OPL, int r, int v);
-void YM3812UpdateOne(FM_OPL *OPL, int16 *buffer, int length);
+ Audio::SoundHandle *_handle;
+};
-/**
- * Legacy factory to create an AdLib (OPL2) chip.
- *
- * !You should not write any new code using the legacy API!
- */
-FM_OPL *makeAdLibOPL(int rate);
+} // End of namespace OPL
#endif
diff --git a/audio/midiparser.h b/audio/midiparser.h
index 9c10462cd7..2cca56b14c 100644
--- a/audio/midiparser.h
+++ b/audio/midiparser.h
@@ -370,6 +370,7 @@ public:
public:
typedef void (*XMidiCallbackProc)(byte eventData, void *refCon);
+ typedef void (*XMidiNewTimbreListProc)(MidiDriver_BASE *driver, const byte *timbreListPtr, uint32 timbreListSize);
MidiParser();
virtual ~MidiParser() { allNotesOff(); }
@@ -395,7 +396,7 @@ public:
static void defaultXMidiCallback(byte eventData, void *refCon);
static MidiParser *createParser_SMF();
- static MidiParser *createParser_XMIDI(XMidiCallbackProc proc = defaultXMidiCallback, void *refCon = 0);
+ static MidiParser *createParser_XMIDI(XMidiCallbackProc proc = defaultXMidiCallback, void *refCon = 0, XMidiNewTimbreListProc newTimbreListProc = NULL, MidiDriver_BASE *newTimbreListDriver = NULL);
static MidiParser *createParser_QT();
static void timerCallback(void *data) { ((MidiParser *) data)->onTimer(); }
};
diff --git a/audio/midiparser_xmidi.cpp b/audio/midiparser_xmidi.cpp
index 95aa5d72f3..8742d7aad1 100644
--- a/audio/midiparser_xmidi.cpp
+++ b/audio/midiparser_xmidi.cpp
@@ -43,6 +43,22 @@ protected:
XMidiCallbackProc _callbackProc;
void *_callbackData;
+ // TODO:
+ // This should possibly get cleaned up at some point, but it's very tricks.
+ // We need to support XMIDI TIMB for 7th guest, which uses
+ // Miles Audio drivers. The MT32 driver needs to get the TIMB chunk, so that it
+ // can install all required timbres before the song starts playing.
+ // But we can't easily implement this directly like for example creating
+ // a special Miles Audio class for usage in this XMIDI-class, because other engines use this
+ // XMIDI-parser but w/o using Miles Audio drivers.
+ XMidiNewTimbreListProc _newTimbreListProc;
+ MidiDriver_BASE *_newTimbreListDriver;
+
+ byte *_tracksTimbreList[120]; ///< Timbre-List for each track.
+ uint32 _tracksTimbreListSize[120]; ///< Size of the Timbre-List for each track.
+ byte *_activeTrackTimbreList;
+ uint32 _activeTrackTimbreListSize;
+
protected:
uint32 readVLQ2(byte * &data);
void parseNextEvent(EventInfo &info);
@@ -53,7 +69,17 @@ protected:
}
public:
- MidiParser_XMIDI(XMidiCallbackProc proc, void *data) : _callbackProc(proc), _callbackData(data), _loopCount(-1) {}
+ MidiParser_XMIDI(XMidiCallbackProc proc, void *data, XMidiNewTimbreListProc newTimbreListProc, MidiDriver_BASE *newTimbreListDriver) {
+ _callbackProc = proc;
+ _callbackData = data;
+ _loopCount = -1;
+ _newTimbreListProc = newTimbreListProc;
+ _newTimbreListDriver = newTimbreListDriver;
+ memset(_tracksTimbreList, 0, sizeof(_tracksTimbreList));
+ memset(_tracksTimbreListSize, 0, sizeof(_tracksTimbreListSize));
+ _activeTrackTimbreList = NULL;
+ _activeTrackTimbreListSize = 0;
+ }
~MidiParser_XMIDI() { }
bool loadMusic(byte *data, uint32 size);
@@ -322,11 +348,16 @@ bool MidiParser_XMIDI::loadMusic(byte *data, uint32 size) {
// Skip this.
pos += 4;
} else if (!memcmp(pos, "TIMB", 4)) {
- // Custom timbres?
- // We don't support them.
- // Read the length, skip it, and hope there was nothing there.
+ // Custom timbres
+ // chunk data is as follows:
+ // UINT16LE timbre count (amount of custom timbres used by this track)
+ // BYTE patchId
+ // BYTE bankId
+ // * timbre count
pos += 4;
len = read4high(pos);
+ _tracksTimbreList[tracksRead] = pos; // Skip the length bytes
+ _tracksTimbreListSize[tracksRead] = len;
pos += (len + 1) & ~1;
} else if (!memcmp(pos, "EVNT", 4)) {
// Ahh! What we're looking for at last.
@@ -350,6 +381,12 @@ bool MidiParser_XMIDI::loadMusic(byte *data, uint32 size) {
resetTracking();
setTempo(500000);
setTrack(0);
+ _activeTrackTimbreList = _tracksTimbreList[0];
+ _activeTrackTimbreListSize = _tracksTimbreListSize[0];
+
+ if (_newTimbreListProc)
+ _newTimbreListProc(_newTimbreListDriver, _activeTrackTimbreList, _activeTrackTimbreListSize);
+
return true;
}
@@ -360,6 +397,6 @@ void MidiParser::defaultXMidiCallback(byte eventData, void *data) {
warning("MidiParser: defaultXMidiCallback(%d)", eventData);
}
-MidiParser *MidiParser::createParser_XMIDI(XMidiCallbackProc proc, void *data) {
- return new MidiParser_XMIDI(proc, data);
+MidiParser *MidiParser::createParser_XMIDI(XMidiCallbackProc proc, void *data, XMidiNewTimbreListProc newTimbreListProc, MidiDriver_BASE *newTimbreListDriver) {
+ return new MidiParser_XMIDI(proc, data, newTimbreListProc, newTimbreListDriver);
}
diff --git a/audio/miles.h b/audio/miles.h
new file mode 100644
index 0000000000..23d5998fba
--- /dev/null
+++ b/audio/miles.h
@@ -0,0 +1,83 @@
+/* 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 AUDIO_MILES_MIDIDRIVER_H
+#define AUDIO_MILES_MIDIDRIVER_H
+
+#include "audio/mididrv.h"
+#include "common/error.h"
+#include "common/stream.h"
+
+namespace Audio {
+
+#define MILES_MIDI_CHANNEL_COUNT 16
+
+// Miles Audio supported controllers for control change messages
+#define MILES_CONTROLLER_SELECT_PATCH_BANK 114
+#define MILES_CONTROLLER_PROTECT_VOICE 112
+#define MILES_CONTROLLER_PROTECT_TIMBRE 113
+#define MILES_CONTROLLER_MODULATION 1
+#define MILES_CONTROLLER_VOLUME 7
+#define MILES_CONTROLLER_EXPRESSION 11
+#define MILES_CONTROLLER_PANNING 10
+#define MILES_CONTROLLER_SUSTAIN 64
+#define MILES_CONTROLLER_PITCH_RANGE 6
+#define MILES_CONTROLLER_RESET_ALL 121
+#define MILES_CONTROLLER_ALL_NOTES_OFF 123
+#define MILES_CONTROLLER_PATCH_REVERB 59
+#define MILES_CONTROLLER_PATCH_BENDER 60
+#define MILES_CONTROLLER_REVERB_MODE 61
+#define MILES_CONTROLLER_REVERB_TIME 62
+#define MILES_CONTROLLER_REVERB_LEVEL 63
+#define MILES_CONTROLLER_RHYTHM_KEY_TIMBRE 58
+
+// 3 SysEx controllers, each range 5
+// 32-36 for 1st queue
+// 37-41 for 2nd queue
+// 42-46 for 3rd queue
+#define MILES_CONTROLLER_SYSEX_RANGE_BEGIN 32
+#define MILES_CONTROLLER_SYSEX_RANGE_END 46
+
+#define MILES_CONTROLLER_SYSEX_QUEUE_COUNT 3
+#define MILES_CONTROLLER_SYSEX_QUEUE_SIZE 32
+
+#define MILES_CONTROLLER_SYSEX_COMMAND_ADDRESS1 0
+#define MILES_CONTROLLER_SYSEX_COMMAND_ADDRESS2 1
+#define MILES_CONTROLLER_SYSEX_COMMAND_ADDRESS3 2
+#define MILES_CONTROLLER_SYSEX_COMMAND_DATA 3
+#define MILES_CONTROLLER_SYSEX_COMMAND_SEND 4
+
+#define MILES_CONTROLLER_XMIDI_RANGE_BEGIN 110
+#define MILES_CONTROLLER_XMIDI_RANGE_END 120
+
+// Miles Audio actually used 0x4000, because they didn't shift the 2 bytes properly
+#define MILES_PITCHBENDER_DEFAULT 0x2000
+
+extern MidiDriver *MidiDriver_Miles_AdLib_create(const Common::String &filenameAdLib, const Common::String &filenameOPL3, Common::SeekableReadStream *streamAdLib = nullptr, Common::SeekableReadStream *streamOPL3 = nullptr);
+
+extern MidiDriver *MidiDriver_Miles_MT32_create(const Common::String &instrumentDataFilename);
+
+extern void MidiDriver_Miles_MT32_processXMIDITimbreChunk(MidiDriver_BASE *driver, const byte *timbreListPtr, uint32 timbreListSize);
+
+} // End of namespace Audio
+
+#endif // AUDIO_MILES_MIDIDRIVER_H
diff --git a/audio/miles_adlib.cpp b/audio/miles_adlib.cpp
new file mode 100644
index 0000000000..bf5c9d4a73
--- /dev/null
+++ b/audio/miles_adlib.cpp
@@ -0,0 +1,1274 @@
+/* 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/miles.h"
+
+#include "common/file.h"
+#include "common/system.h"
+#include "common/textconsole.h"
+
+#include "audio/fmopl.h"
+#include "audio/softsynth/emumidi.h"
+
+namespace Audio {
+
+// Miles Audio AdLib/OPL3 driver
+//
+// TODO: currently missing: OPL3 4-op voices
+//
+// Special cases (great for testing):
+// - sustain feature is used by Return To Zork (demo) right at the start
+// - sherlock holmes 2 does lots of priority sorts right at the start of the intro
+
+#define MILES_ADLIB_VIRTUAL_FMVOICES_COUNT_MAX 20
+#define MILES_ADLIB_PHYSICAL_FMVOICES_COUNT_MAX 18
+
+#define MILES_ADLIB_PERCUSSION_BANK 127
+
+#define MILES_ADLIB_STEREO_PANNING_THRESHOLD_LEFT 27
+#define MILES_ADLIB_STEREO_PANNING_THRESHOLD_RIGHT 100
+
+enum kMilesAdLibUpdateFlags {
+ kMilesAdLibUpdateFlags_None = 0,
+ kMilesAdLibUpdateFlags_Reg_20 = 1 << 0,
+ kMilesAdLibUpdateFlags_Reg_40 = 1 << 1,
+ kMilesAdLibUpdateFlags_Reg_60 = 1 << 2, // register 0x6x + 0x8x
+ kMilesAdLibUpdateFlags_Reg_C0 = 1 << 3,
+ kMilesAdLibUpdateFlags_Reg_E0 = 1 << 4,
+ kMilesAdLibUpdateFlags_Reg_A0 = 1 << 5, // register 0xAx + 0xBx
+ kMilesAdLibUpdateFlags_Reg_All = 0x3F
+};
+
+uint16 milesAdLibOperator1Register[MILES_ADLIB_PHYSICAL_FMVOICES_COUNT_MAX] = {
+ 0x0000, 0x0001, 0x0002, 0x0008, 0x0009, 0x000A, 0x0010, 0x0011, 0x0012,
+ 0x0100, 0x0101, 0x0102, 0x0108, 0x0109, 0x010A, 0x0110, 0x0111, 0x0112
+};
+
+uint16 milesAdLibOperator2Register[MILES_ADLIB_PHYSICAL_FMVOICES_COUNT_MAX] = {
+ 0x0003, 0x0004, 0x0005, 0x000B, 0x000C, 0x000D, 0x0013, 0x0014, 0x0015,
+ 0x0103, 0x0104, 0x0105, 0x010B, 0x010C, 0x010D, 0x0113, 0x0114, 0x0115
+};
+
+uint16 milesAdLibChannelRegister[MILES_ADLIB_PHYSICAL_FMVOICES_COUNT_MAX] = {
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, 0x0107, 0x0108
+};
+
+struct InstrumentEntry {
+ byte bankId;
+ byte patchId;
+ int16 transposition;
+ byte reg20op1;
+ byte reg40op1;
+ byte reg60op1;
+ byte reg80op1;
+ byte regE0op1;
+ byte reg20op2;
+ byte reg40op2;
+ byte reg60op2;
+ byte reg80op2;
+ byte regE0op2;
+ byte regC0;
+};
+
+// hardcoded, dumped from ADLIB.MDI
+uint16 milesAdLibFrequencyLookUpTable[] = {
+ 0x02B2, 0x02B4, 0x02B7, 0x02B9, 0x02BC, 0x02BE, 0x02C1, 0x02C3, 0x02C6, 0x02C9, 0x02CB, 0x02CE,
+ 0x02D0, 0x02D3, 0x02D6, 0x02D8, 0x02DB, 0x02DD, 0x02E0, 0x02E3, 0x02E5, 0x02E8, 0x02EB, 0x02ED,
+ 0x02F0, 0x02F3, 0x02F6, 0x02F8, 0x02FB, 0x02FE, 0x0301, 0x0303, 0x0306, 0x0309, 0x030C, 0x030F,
+ 0x0311, 0x0314, 0x0317, 0x031A, 0x031D, 0x0320, 0x0323, 0x0326, 0x0329, 0x032B, 0x032E, 0x0331,
+ 0x0334, 0x0337, 0x033A, 0x033D, 0x0340, 0x0343, 0x0346, 0x0349, 0x034C, 0x034F, 0x0352, 0x0356,
+ 0x0359, 0x035C, 0x035F, 0x0362, 0x0365, 0x0368, 0x036B, 0x036F, 0x0372, 0x0375, 0x0378, 0x037B,
+ 0x037F, 0x0382, 0x0385, 0x0388, 0x038C, 0x038F, 0x0392, 0x0395, 0x0399, 0x039C, 0x039F, 0x03A3,
+ 0x03A6, 0x03A9, 0x03AD, 0x03B0, 0x03B4, 0x03B7, 0x03BB, 0x03BE, 0x03C1, 0x03C5, 0x03C8, 0x03CC,
+ 0x03CF, 0x03D3, 0x03D7, 0x03DA, 0x03DE, 0x03E1, 0x03E5, 0x03E8, 0x03EC, 0x03F0, 0x03F3, 0x03F7,
+ 0x03FB, 0x03FE, 0xFE01, 0xFE03, 0xFE05, 0xFE07, 0xFE08, 0xFE0A, 0xFE0C, 0xFE0E, 0xFE10, 0xFE12,
+ 0xFE14, 0xFE16, 0xFE18, 0xFE1A, 0xFE1C, 0xFE1E, 0xFE20, 0xFE21, 0xFE23, 0xFE25, 0xFE27, 0xFE29,
+ 0xFE2B, 0xFE2D, 0xFE2F, 0xFE31, 0xFE34, 0xFE36, 0xFE38, 0xFE3A, 0xFE3C, 0xFE3E, 0xFE40, 0xFE42,
+ 0xFE44, 0xFE46, 0xFE48, 0xFE4A, 0xFE4C, 0xFE4F, 0xFE51, 0xFE53, 0xFE55, 0xFE57, 0xFE59, 0xFE5C,
+ 0xFE5E, 0xFE60, 0xFE62, 0xFE64, 0xFE67, 0xFE69, 0xFE6B, 0xFE6D, 0xFE6F, 0xFE72, 0xFE74, 0xFE76,
+ 0xFE79, 0xFE7B, 0xFE7D, 0xFE7F, 0xFE82, 0xFE84, 0xFE86, 0xFE89, 0xFE8B, 0xFE8D, 0xFE90, 0xFE92,
+ 0xFE95, 0xFE97, 0xFE99, 0xFE9C, 0xFE9E, 0xFEA1, 0xFEA3, 0xFEA5, 0xFEA8, 0xFEAA, 0xFEAD, 0xFEAF
+};
+
+// hardcoded, dumped from ADLIB.MDI
+uint16 milesAdLibVolumeSensitivityTable[] = {
+ 82, 85, 88, 91, 94, 97, 100, 103, 106, 109, 112, 115, 118, 121, 124, 127
+};
+
+
+class MidiDriver_Miles_AdLib : public MidiDriver {
+public:
+ MidiDriver_Miles_AdLib(InstrumentEntry *instrumentTablePtr, uint16 instrumentTableCount);
+ virtual ~MidiDriver_Miles_AdLib();
+
+ // MidiDriver
+ int open();
+ void close();
+ void send(uint32 b);
+ MidiChannel *allocateChannel() { return NULL; }
+ MidiChannel *getPercussionChannel() { return NULL; }
+
+ bool isOpen() const { return _isOpen; }
+ uint32 getBaseTempo() { return 1000000 / OPL::OPL::kDefaultCallbackFrequency; }
+
+ void setVolume(byte volume);
+ virtual uint32 property(int prop, uint32 param);
+
+ void setTimerCallback(void *timerParam, Common::TimerManager::TimerProc timerProc);
+
+private:
+ bool _modeOPL3;
+ byte _modePhysicalFmVoicesCount;
+ byte _modeVirtualFmVoicesCount;
+ bool _modeStereo;
+
+ // Structure to hold information about current status of MIDI Channels
+ struct MidiChannelEntry {
+ byte currentPatchBank;
+ const InstrumentEntry *currentInstrumentPtr;
+ uint16 currentPitchBender;
+ byte currentPitchRange;
+ byte currentVoiceProtection;
+
+ byte currentVolume;
+ byte currentVolumeExpression;
+
+ byte currentPanning;
+
+ byte currentModulation;
+ byte currentSustain;
+
+ byte currentActiveVoicesCount;
+
+ MidiChannelEntry() : currentPatchBank(0),
+ currentInstrumentPtr(NULL),
+ currentPitchBender(MILES_PITCHBENDER_DEFAULT),
+ currentPitchRange(0),
+ currentVoiceProtection(0),
+ currentVolume(0), currentVolumeExpression(0),
+ currentPanning(0),
+ currentModulation(0),
+ currentSustain(0),
+ currentActiveVoicesCount(0) { }
+ };
+
+ // Structure to hold information about current status of virtual FM Voices
+ struct VirtualFmVoiceEntry {
+ bool inUse;
+ byte actualMidiChannel;
+
+ const InstrumentEntry *currentInstrumentPtr;
+
+ bool isPhysical;
+ byte physicalFmVoice;
+
+ uint16 currentPriority;
+
+ byte currentOriginalMidiNote;
+ byte currentNote;
+ int16 currentTransposition;
+ byte currentVelocity;
+
+ bool sustained;
+
+ VirtualFmVoiceEntry(): inUse(false),
+ actualMidiChannel(0),
+ currentInstrumentPtr(NULL),
+ isPhysical(false), physicalFmVoice(0),
+ currentPriority(0),
+ currentOriginalMidiNote(0),
+ currentNote(0),
+ currentTransposition(0),
+ currentVelocity(0),
+ sustained(false) { }
+ };
+
+ // Structure to hold information about current status of physical FM Voices
+ struct PhysicalFmVoiceEntry {
+ bool inUse;
+ byte virtualFmVoice;
+
+ byte currentB0hReg;
+
+ PhysicalFmVoiceEntry(): inUse(false),
+ virtualFmVoice(0),
+ currentB0hReg(0) { }
+ };
+
+ OPL::OPL *_opl;
+ int _masterVolume;
+
+ Common::TimerManager::TimerProc _adlibTimerProc;
+ void *_adlibTimerParam;
+
+ bool _isOpen;
+
+ // stores information about all MIDI channels (not the actual OPL FM voice channels!)
+ MidiChannelEntry _midiChannels[MILES_MIDI_CHANNEL_COUNT];
+
+ // stores information about all virtual OPL FM voices
+ VirtualFmVoiceEntry _virtualFmVoices[MILES_ADLIB_VIRTUAL_FMVOICES_COUNT_MAX];
+
+ // stores information about all physical OPL FM voices
+ PhysicalFmVoiceEntry _physicalFmVoices[MILES_ADLIB_PHYSICAL_FMVOICES_COUNT_MAX];
+
+ // holds all instruments
+ InstrumentEntry *_instrumentTablePtr;
+ uint16 _instrumentTableCount;
+
+ bool circularPhysicalAssignment;
+ byte circularPhysicalAssignmentFmVoice;
+
+ void onTimer();
+
+ void resetData();
+ void resetAdLib();
+ void resetAdLibOperatorRegisters(byte baseRegister, byte value);
+ void resetAdLibFMVoiceChannelRegisters(byte baseRegister, byte value);
+
+ void setRegister(int reg, int value);
+
+ int16 searchFreeVirtualFmVoiceChannel();
+ int16 searchFreePhysicalFmVoiceChannel();
+
+ void noteOn(byte midiChannel, byte note, byte velocity);
+ void noteOff(byte midiChannel, byte note);
+
+ void prioritySort();
+
+ void releaseFmVoice(byte virtualFmVoice);
+
+ void releaseSustain(byte midiChannel);
+
+ void updatePhysicalFmVoice(byte virtualFmVoice, bool keyOn, uint16 registerUpdateFlags);
+
+ void controlChange(byte midiChannel, byte controllerNumber, byte controllerValue);
+ void programChange(byte midiChannel, byte patchId);
+
+ const InstrumentEntry *searchInstrument(byte bankId, byte patchId);
+
+ void pitchBendChange(byte MIDIchannel, byte parameter1, byte parameter2);
+};
+
+MidiDriver_Miles_AdLib::MidiDriver_Miles_AdLib(InstrumentEntry *instrumentTablePtr, uint16 instrumentTableCount)
+ : _masterVolume(15), _opl(0),
+ _adlibTimerProc(0), _adlibTimerParam(0), _isOpen(false) {
+
+ _instrumentTablePtr = instrumentTablePtr;
+ _instrumentTableCount = instrumentTableCount;
+
+ // Set up for OPL3, we will downgrade in case we can't create OPL3 emulator
+ // regular AdLib (OPL2) card
+ _modeOPL3 = true;
+ _modeVirtualFmVoicesCount = 20;
+ _modePhysicalFmVoicesCount = 18;
+ _modeStereo = true;
+
+ // Older Miles Audio drivers did not do a circular assign for physical FM-voices
+ // Sherlock Holmes 2 used the circular assign
+ circularPhysicalAssignment = true;
+ // this way the first circular physical FM-voice search will start at FM-voice 0
+ circularPhysicalAssignmentFmVoice = MILES_ADLIB_PHYSICAL_FMVOICES_COUNT_MAX;
+
+ resetData();
+}
+
+MidiDriver_Miles_AdLib::~MidiDriver_Miles_AdLib() {
+ delete[] _instrumentTablePtr; // is created in factory MidiDriver_Miles_AdLib_create()
+}
+
+int MidiDriver_Miles_AdLib::open() {
+ if (_modeOPL3) {
+ // Try to create OPL3 first
+ _opl = OPL::Config::create(OPL::Config::kOpl3);
+ }
+ if (!_opl) {
+ // not created yet, downgrade to OPL2
+ _modeOPL3 = false;
+ _modeVirtualFmVoicesCount = 16;
+ _modePhysicalFmVoicesCount = 9;
+ _modeStereo = false;
+
+ _opl = OPL::Config::create(OPL::Config::kOpl2);
+ }
+
+ if (!_opl) {
+ // We still got nothing -> can't do anything anymore
+ return -1;
+ }
+
+ _opl->init();
+
+ _isOpen = true;
+
+ _opl->start(new Common::Functor0Mem<void, MidiDriver_Miles_AdLib>(this, &MidiDriver_Miles_AdLib::onTimer));
+
+ resetAdLib();
+
+ return 0;
+}
+
+void MidiDriver_Miles_AdLib::close() {
+ delete _opl;
+ _isOpen = false;
+}
+
+void MidiDriver_Miles_AdLib::setVolume(byte volume) {
+ _masterVolume = volume;
+ //renewNotes(-1, true);
+}
+
+void MidiDriver_Miles_AdLib::onTimer() {
+ if (_adlibTimerProc)
+ (*_adlibTimerProc)(_adlibTimerParam);
+}
+
+void MidiDriver_Miles_AdLib::resetData() {
+ memset(_midiChannels, 0, sizeof(_midiChannels));
+ memset(_virtualFmVoices, 0, sizeof(_virtualFmVoices));
+ memset(_physicalFmVoices, 0, sizeof(_physicalFmVoices));
+
+ for (byte midiChannel = 0; midiChannel < MILES_MIDI_CHANNEL_COUNT; midiChannel++) {
+ // defaults, were sent to driver during driver initialization
+ _midiChannels[midiChannel].currentVolume = 0x7F;
+ _midiChannels[midiChannel].currentPanning = 0x40; // center
+ _midiChannels[midiChannel].currentVolumeExpression = 127;
+
+ // Miles Audio 2: hardcoded pitch range as a global (not channel specific), set to 12
+ // Miles Audio 3: pitch range per MIDI channel
+ _midiChannels[midiChannel].currentPitchBender = MILES_PITCHBENDER_DEFAULT;
+ _midiChannels[midiChannel].currentPitchRange = 12;
+ }
+
+}
+
+void MidiDriver_Miles_AdLib::resetAdLib() {
+ if (_modeOPL3) {
+ setRegister(0x105, 1); // enable OPL3
+ setRegister(0x104, 0); // activate 18 2-operator FM-voices
+ }
+
+ setRegister(0x01, 0x20); // enable waveform control on both operators
+ setRegister(0x04, 0xE0); // Timer control
+
+ setRegister(0x08, 0); // select FM music mode
+ setRegister(0xBD, 0); // disable Rhythm
+
+ // reset FM voice instrument data
+ resetAdLibOperatorRegisters(0x20, 0);
+ resetAdLibOperatorRegisters(0x60, 0);
+ resetAdLibOperatorRegisters(0x80, 0);
+ resetAdLibFMVoiceChannelRegisters(0xA0, 0);
+ resetAdLibFMVoiceChannelRegisters(0xB0, 0);
+ resetAdLibFMVoiceChannelRegisters(0xC0, 0);
+ resetAdLibOperatorRegisters(0xE0, 0);
+ resetAdLibOperatorRegisters(0x40, 0x3F);
+}
+
+void MidiDriver_Miles_AdLib::resetAdLibOperatorRegisters(byte baseRegister, byte value) {
+ byte physicalFmVoice = 0;
+
+ for (physicalFmVoice = 0; physicalFmVoice < _modePhysicalFmVoicesCount; physicalFmVoice++) {
+ setRegister(baseRegister + milesAdLibOperator1Register[physicalFmVoice], value);
+ setRegister(baseRegister + milesAdLibOperator2Register[physicalFmVoice], value);
+ }
+}
+
+void MidiDriver_Miles_AdLib::resetAdLibFMVoiceChannelRegisters(byte baseRegister, byte value) {
+ byte physicalFmVoice = 0;
+
+ for (physicalFmVoice = 0; physicalFmVoice < _modePhysicalFmVoicesCount; physicalFmVoice++) {
+ setRegister(baseRegister + milesAdLibChannelRegister[physicalFmVoice], value);
+ }
+}
+
+// MIDI messages can be found at http://www.midi.org/techspecs/midimessages.php
+void MidiDriver_Miles_AdLib::send(uint32 b) {
+ byte command = b & 0xf0;
+ byte channel = b & 0xf;
+ byte op1 = (b >> 8) & 0xff;
+ byte op2 = (b >> 16) & 0xff;
+
+ switch (command) {
+ case 0x80:
+ noteOff(channel, op1);
+ break;
+ case 0x90:
+ noteOn(channel, op1, op2);
+ break;
+ case 0xb0: // Control change
+ controlChange(channel, op1, op2);
+ break;
+ case 0xc0: // Program Change
+ programChange(channel, op1);
+ break;
+ case 0xa0: // Polyphonic key pressure (aftertouch)
+ case 0xd0: // Channel pressure (aftertouch)
+ // Aftertouch doesn't seem to be implemented in the Miles Audio AdLib driver
+ break;
+ case 0xe0:
+ pitchBendChange(channel, op1, op2);
+ break;
+ case 0xf0: // SysEx
+ warning("MILES-ADLIB: SysEx: %x", b);
+ break;
+ default:
+ warning("MILES-ADLIB: Unknown event %02x", command);
+ }
+}
+
+void MidiDriver_Miles_AdLib::setTimerCallback(void *timerParam, Common::TimerManager::TimerProc timerProc) {
+ _adlibTimerProc = timerProc;
+ _adlibTimerParam = timerParam;
+}
+
+int16 MidiDriver_Miles_AdLib::searchFreeVirtualFmVoiceChannel() {
+ for (byte virtualFmVoice = 0; virtualFmVoice < _modeVirtualFmVoicesCount; virtualFmVoice++) {
+ if (!_virtualFmVoices[virtualFmVoice].inUse)
+ return virtualFmVoice;
+ }
+ return -1;
+}
+
+int16 MidiDriver_Miles_AdLib::searchFreePhysicalFmVoiceChannel() {
+ if (!circularPhysicalAssignment) {
+ // Older assign logic
+ for (byte physicalFmVoice = 0; physicalFmVoice < _modePhysicalFmVoicesCount; physicalFmVoice++) {
+ if (!_physicalFmVoices[physicalFmVoice].inUse)
+ return physicalFmVoice;
+ }
+ } else {
+ // Newer one
+ // Remembers last physical FM-voice and searches from that spot
+ byte physicalFmVoice = circularPhysicalAssignmentFmVoice;
+ for (byte physicalFmVoiceCount = 0; physicalFmVoiceCount < _modePhysicalFmVoicesCount; physicalFmVoiceCount++) {
+ physicalFmVoice++;
+ if (physicalFmVoice >= _modePhysicalFmVoicesCount)
+ physicalFmVoice = 0;
+ if (!_physicalFmVoices[physicalFmVoice].inUse) {
+ circularPhysicalAssignmentFmVoice = physicalFmVoice;
+ return physicalFmVoice;
+ }
+ }
+ }
+ return -1;
+}
+
+void MidiDriver_Miles_AdLib::noteOn(byte midiChannel, byte note, byte velocity) {
+ const InstrumentEntry *instrumentPtr = NULL;
+
+ if (velocity == 0) {
+ noteOff(midiChannel, note);
+ return;
+ }
+
+ if (midiChannel == 9) {
+ // percussion channel
+ // search for instrument according to given note
+ instrumentPtr = searchInstrument(MILES_ADLIB_PERCUSSION_BANK, note);
+ } else {
+ // directly get instrument of channel
+ instrumentPtr = _midiChannels[midiChannel].currentInstrumentPtr;
+ }
+ if (!instrumentPtr) {
+ warning("MILES-ADLIB: noteOn: invalid instrument");
+ return;
+ }
+
+ //warning("Note On: channel %d, note %d, velocity %d, instrument %d/%d", midiChannel, note, velocity, instrumentPtr->bankId, instrumentPtr->patchId);
+
+ // look for free virtual FM voice
+ int16 virtualFmVoice = searchFreeVirtualFmVoiceChannel();
+
+ if (virtualFmVoice == -1) {
+ // Out of virtual voices, can't do anything about it
+ return;
+ }
+
+ // Scale back velocity
+ velocity = (velocity & 0x7F) >> 3;
+ velocity = milesAdLibVolumeSensitivityTable[velocity];
+
+ if (midiChannel != 9) {
+ _virtualFmVoices[virtualFmVoice].currentNote = note;
+ _virtualFmVoices[virtualFmVoice].currentTransposition = instrumentPtr->transposition;
+ } else {
+ // Percussion channel
+ _virtualFmVoices[virtualFmVoice].currentNote = instrumentPtr->transposition;
+ _virtualFmVoices[virtualFmVoice].currentTransposition = 0;
+ }
+
+ _virtualFmVoices[virtualFmVoice].inUse = true;
+ _virtualFmVoices[virtualFmVoice].actualMidiChannel = midiChannel;
+ _virtualFmVoices[virtualFmVoice].currentOriginalMidiNote = note;
+ _virtualFmVoices[virtualFmVoice].currentInstrumentPtr = instrumentPtr;
+ _virtualFmVoices[virtualFmVoice].currentVelocity = velocity;
+ _virtualFmVoices[virtualFmVoice].isPhysical = false;
+ _virtualFmVoices[virtualFmVoice].sustained = false;
+ _virtualFmVoices[virtualFmVoice].currentPriority = 32767;
+
+ int16 physicalFmVoice = searchFreePhysicalFmVoiceChannel();
+ if (physicalFmVoice == -1) {
+ // None found
+ // go through priorities and reshuffle voices
+ prioritySort();
+ return;
+ }
+
+ // Another voice active on this MIDI channel
+ _midiChannels[midiChannel].currentActiveVoicesCount++;
+
+ // Mark virtual FM-Voice as being connected to physical FM-Voice
+ _virtualFmVoices[virtualFmVoice].isPhysical = true;
+ _virtualFmVoices[virtualFmVoice].physicalFmVoice = physicalFmVoice;
+
+ // Mark physical FM-Voice as being connected to virtual FM-Voice
+ _physicalFmVoices[physicalFmVoice].inUse = true;
+ _physicalFmVoices[physicalFmVoice].virtualFmVoice = virtualFmVoice;
+
+ // Update the physical FM-Voice
+ updatePhysicalFmVoice(virtualFmVoice, true, kMilesAdLibUpdateFlags_Reg_All);
+}
+
+void MidiDriver_Miles_AdLib::noteOff(byte midiChannel, byte note) {
+ //warning("Note Off: channel %d, note %d", midiChannel, note);
+
+ // Search through all virtual FM-Voices for current midiChannel + note
+ for (byte virtualFmVoice = 0; virtualFmVoice < _modeVirtualFmVoicesCount; virtualFmVoice++) {
+ if (_virtualFmVoices[virtualFmVoice].inUse) {
+ if ((_virtualFmVoices[virtualFmVoice].actualMidiChannel == midiChannel) && (_virtualFmVoices[virtualFmVoice].currentOriginalMidiNote == note)) {
+ // found one
+ if (_midiChannels[midiChannel].currentSustain >= 64) {
+ _virtualFmVoices[virtualFmVoice].sustained = true;
+ continue;
+ }
+ //
+ releaseFmVoice(virtualFmVoice);
+ }
+ }
+ }
+}
+
+void MidiDriver_Miles_AdLib::prioritySort() {
+ byte virtualFmVoice = 0;
+ uint16 virtualPriority = 0;
+ uint16 virtualPriorities[MILES_ADLIB_VIRTUAL_FMVOICES_COUNT_MAX];
+ uint16 virtualFmVoicesCount = 0;
+ byte midiChannel = 0;
+
+ memset(&virtualPriorities, 0, sizeof(virtualPriorities));
+
+ //warning("prioritysort");
+
+ // First calculate priorities for all virtual FM voices, that are in use
+ for (virtualFmVoice = 0; virtualFmVoice < _modeVirtualFmVoicesCount; virtualFmVoice++) {
+ if (_virtualFmVoices[virtualFmVoice].inUse) {
+ virtualFmVoicesCount++;
+
+ midiChannel = _virtualFmVoices[virtualFmVoice].actualMidiChannel;
+ if (_midiChannels[midiChannel].currentVoiceProtection >= 64) {
+ // Voice protection enabled
+ virtualPriority = 0xFFFF;
+ } else {
+ virtualPriority = _virtualFmVoices[virtualFmVoice].currentPriority;
+ }
+ byte currentActiveVoicesCount = _midiChannels[midiChannel].currentActiveVoicesCount;
+ if (virtualPriority >= currentActiveVoicesCount) {
+ virtualPriority -= _midiChannels[midiChannel].currentActiveVoicesCount;
+ } else {
+ virtualPriority = 0; // overflow, should never happen
+ }
+ virtualPriorities[virtualFmVoice] = virtualPriority;
+ }
+ }
+
+ //
+ while (virtualFmVoicesCount) {
+ uint16 unvoicedHighestPriority = 0;
+ byte unvoicedHighestFmVoice = 0;
+ uint16 voicedLowestPriority = 65535;
+ byte voicedLowestFmVoice = 0;
+
+ for (virtualFmVoice = 0; virtualFmVoice < _modeVirtualFmVoicesCount; virtualFmVoice++) {
+ if (_virtualFmVoices[virtualFmVoice].inUse) {
+ virtualPriority = virtualPriorities[virtualFmVoice];
+ if (!_virtualFmVoices[virtualFmVoice].isPhysical) {
+ // currently not physical, so unvoiced
+ if (virtualPriority >= unvoicedHighestPriority) {
+ unvoicedHighestPriority = virtualPriority;
+ unvoicedHighestFmVoice = virtualFmVoice;
+ }
+ } else {
+ // currently physical, so voiced
+ if (virtualPriority <= voicedLowestPriority) {
+ voicedLowestPriority = virtualPriority;
+ voicedLowestFmVoice = virtualFmVoice;
+ }
+ }
+ }
+ }
+
+ if (unvoicedHighestPriority < voicedLowestPriority)
+ break; // We are done
+
+ if (unvoicedHighestPriority == 0)
+ break;
+
+ // Safety checks
+ assert(_virtualFmVoices[voicedLowestFmVoice].isPhysical);
+ assert(!_virtualFmVoices[unvoicedHighestFmVoice].isPhysical);
+
+ // Steal this physical voice
+ byte physicalFmVoice = _virtualFmVoices[voicedLowestFmVoice].physicalFmVoice;
+
+ //warning("MILES-ADLIB: stealing physical FM-Voice %d from virtual FM-Voice %d for virtual FM-Voice %d", physicalFmVoice, voicedLowestFmVoice, unvoicedHighestFmVoice);
+ //warning("priority old %d, priority new %d", unvoicedHighestPriority, voicedLowestPriority);
+
+ releaseFmVoice(voicedLowestFmVoice);
+
+ // Get some data of the unvoiced highest priority virtual FM Voice
+ midiChannel = _virtualFmVoices[unvoicedHighestFmVoice].actualMidiChannel;
+
+ // Another voice active on this MIDI channel
+ _midiChannels[midiChannel].currentActiveVoicesCount++;
+
+ // Mark virtual FM-Voice as being connected to physical FM-Voice
+ _virtualFmVoices[unvoicedHighestFmVoice].isPhysical = true;
+ _virtualFmVoices[unvoicedHighestFmVoice].physicalFmVoice = physicalFmVoice;
+
+ // Mark physical FM-Voice as being connected to virtual FM-Voice
+ _physicalFmVoices[physicalFmVoice].inUse = true;
+ _physicalFmVoices[physicalFmVoice].virtualFmVoice = unvoicedHighestFmVoice;
+
+ // Update the physical FM-Voice
+ updatePhysicalFmVoice(unvoicedHighestFmVoice, true, kMilesAdLibUpdateFlags_Reg_All);
+
+ virtualFmVoicesCount--;
+ }
+}
+
+void MidiDriver_Miles_AdLib::releaseFmVoice(byte virtualFmVoice) {
+ // virtual Voice not actually played? -> exit
+ if (!_virtualFmVoices[virtualFmVoice].isPhysical) {
+ _virtualFmVoices[virtualFmVoice].inUse = false;
+ return;
+ }
+
+ byte midiChannel = _virtualFmVoices[virtualFmVoice].actualMidiChannel;
+ byte physicalFmVoice = _virtualFmVoices[virtualFmVoice].physicalFmVoice;
+
+ // stop note from playing
+ updatePhysicalFmVoice(virtualFmVoice, false, kMilesAdLibUpdateFlags_Reg_A0);
+
+ // this virtual FM voice isn't physical anymore
+ _virtualFmVoices[virtualFmVoice].isPhysical = false;
+ _virtualFmVoices[virtualFmVoice].inUse = false;
+
+ // Remove physical FM-Voice from being active
+ _physicalFmVoices[physicalFmVoice].inUse = false;
+
+ // One less voice active on this MIDI channel
+ assert(_midiChannels[midiChannel].currentActiveVoicesCount);
+ _midiChannels[midiChannel].currentActiveVoicesCount--;
+}
+
+void MidiDriver_Miles_AdLib::releaseSustain(byte midiChannel) {
+ // Search through all virtual FM-Voices for currently sustained notes and call noteOff on them
+ for (byte virtualFmVoice = 0; virtualFmVoice < _modeVirtualFmVoicesCount; virtualFmVoice++) {
+ if (_virtualFmVoices[virtualFmVoice].inUse) {
+ if ((_virtualFmVoices[virtualFmVoice].actualMidiChannel == midiChannel) && (_virtualFmVoices[virtualFmVoice].sustained)) {
+ // is currently sustained
+ // so do a noteOff (which will check current sustain controller)
+ noteOff(midiChannel, _virtualFmVoices[virtualFmVoice].currentOriginalMidiNote);
+ }
+ }
+ }
+}
+
+void MidiDriver_Miles_AdLib::updatePhysicalFmVoice(byte virtualFmVoice, bool keyOn, uint16 registerUpdateFlags) {
+ byte midiChannel = _virtualFmVoices[virtualFmVoice].actualMidiChannel;
+
+ if (!_virtualFmVoices[virtualFmVoice].isPhysical) {
+ // virtual FM-Voice has no physical FM-Voice assigned? -> ignore
+ return;
+ }
+
+ byte physicalFmVoice = _virtualFmVoices[virtualFmVoice].physicalFmVoice;
+ const InstrumentEntry *instrumentPtr = _virtualFmVoices[virtualFmVoice].currentInstrumentPtr;
+
+ uint16 op1Reg = milesAdLibOperator1Register[physicalFmVoice];
+ uint16 op2Reg = milesAdLibOperator2Register[physicalFmVoice];
+ uint16 channelReg = milesAdLibChannelRegister[physicalFmVoice];
+
+ uint16 compositeVolume = 0;
+
+ if (registerUpdateFlags & kMilesAdLibUpdateFlags_Reg_40) {
+ // Calculate new volume
+ byte midiVolume = _midiChannels[midiChannel].currentVolume;
+ byte midiVolumeExpression = _midiChannels[midiChannel].currentVolumeExpression;
+ compositeVolume = midiVolume * midiVolumeExpression * 2;
+
+ compositeVolume = compositeVolume >> 8; // get upmost 8 bits
+ if (compositeVolume)
+ compositeVolume++; // round up in case result wasn't 0
+
+ compositeVolume = compositeVolume * _virtualFmVoices[virtualFmVoice].currentVelocity * 2;
+ compositeVolume = compositeVolume >> 8; // get upmost 8 bits
+ if (compositeVolume)
+ compositeVolume++; // round up in case result wasn't 0
+ }
+
+ if (registerUpdateFlags & kMilesAdLibUpdateFlags_Reg_20) {
+ // Amplitude Modulation / Vibrato / Envelope Generator Type / Keyboard Scaling Rate / Modulator Frequency Multiple
+ byte reg20op1 = instrumentPtr->reg20op1;
+ byte reg20op2 = instrumentPtr->reg20op2;
+
+ if (_midiChannels[midiChannel].currentModulation >= 64) {
+ // set bit 6 (Vibrato)
+ reg20op1 |= 0x40;
+ reg20op2 |= 0x40;
+ }
+ setRegister(0x20 + op1Reg, reg20op1);
+ setRegister(0x20 + op2Reg, reg20op2);
+ }
+
+ if (registerUpdateFlags & kMilesAdLibUpdateFlags_Reg_40) {
+ // Volume (Level Key Scaling / Total Level)
+ byte reg40op1 = instrumentPtr->reg40op1;
+ byte reg40op2 = instrumentPtr->reg40op2;
+
+ uint16 volumeOp1 = (~reg40op1) & 0x3F;
+ uint16 volumeOp2 = (~reg40op2) & 0x3F;
+
+ if (instrumentPtr->regC0 & 1) {
+ // operator 2 enabled
+ // scale volume factor
+ volumeOp1 = (volumeOp1 * compositeVolume) / 127;
+ // 2nd operator always scaled
+ }
+
+ volumeOp2 = (volumeOp2 * compositeVolume) / 127;
+
+ volumeOp1 = (~volumeOp1) & 0x3F; // negate it, so we get the proper value for the register
+ volumeOp2 = (~volumeOp2) & 0x3F; // ditto
+ reg40op1 = (reg40op1 & 0xC0) | volumeOp1; // keep "scaling level" and merge in our volume
+ reg40op2 = (reg40op2 & 0xC0) | volumeOp2;
+
+ setRegister(0x40 + op1Reg, reg40op1);
+ setRegister(0x40 + op2Reg, reg40op2);
+ }
+
+ if (registerUpdateFlags & kMilesAdLibUpdateFlags_Reg_60) {
+ // Attack Rate / Decay Rate
+ // Sustain Level / Release Rate
+ byte reg60op1 = instrumentPtr->reg60op1;
+ byte reg60op2 = instrumentPtr->reg60op2;
+ byte reg80op1 = instrumentPtr->reg80op1;
+ byte reg80op2 = instrumentPtr->reg80op2;
+
+ setRegister(0x60 + op1Reg, reg60op1);
+ setRegister(0x60 + op2Reg, reg60op2);
+ setRegister(0x80 + op1Reg, reg80op1);
+ setRegister(0x80 + op2Reg, reg80op2);
+ }
+
+ if (registerUpdateFlags & kMilesAdLibUpdateFlags_Reg_E0) {
+ // Waveform Select
+ byte regE0op1 = instrumentPtr->regE0op1;
+ byte regE0op2 = instrumentPtr->regE0op2;
+
+ setRegister(0xE0 + op1Reg, regE0op1);
+ setRegister(0xE0 + op2Reg, regE0op2);
+ }
+
+ if (registerUpdateFlags & kMilesAdLibUpdateFlags_Reg_C0) {
+ // Feedback / Algorithm
+ byte regC0 = instrumentPtr->regC0;
+
+ if (_modeOPL3) {
+ // Panning for OPL3
+ byte panning = _midiChannels[midiChannel].currentPanning;
+
+ if (panning <= MILES_ADLIB_STEREO_PANNING_THRESHOLD_LEFT) {
+ regC0 |= 0x20; // left speaker only
+ } else if (panning >= MILES_ADLIB_STEREO_PANNING_THRESHOLD_RIGHT) {
+ regC0 |= 0x10; // right speaker only
+ } else {
+ regC0 |= 0x30; // center
+ }
+ }
+
+ setRegister(0xC0 + channelReg, regC0);
+ }
+
+ if (registerUpdateFlags & kMilesAdLibUpdateFlags_Reg_A0) {
+ // Frequency / Key-On
+ // Octave / F-Number / Key-On
+ if (!keyOn) {
+ // turn off note
+ byte regB0 = _physicalFmVoices[physicalFmVoice].currentB0hReg & 0x1F; // remove bit 5 "key on"
+ setRegister(0xB0 + channelReg, regB0);
+
+ } else {
+ // turn on note, calculate frequency, octave...
+ int16 pitchBender = _midiChannels[midiChannel].currentPitchBender;
+ byte pitchRange = _midiChannels[midiChannel].currentPitchRange;
+ int16 currentNote = _virtualFmVoices[virtualFmVoice].currentNote;
+ int16 physicalNote = 0;
+ int16 halfTone = 0;
+ uint16 frequency = 0;
+ uint16 frequencyIdx = 0;
+ byte octave = 0;
+
+ pitchBender -= 0x2000;
+ pitchBender = pitchBender >> 5; // divide by 32
+ pitchBender = pitchBender * pitchRange; // pitchrange 12: now +0x0C00 to -0xC00
+ // difference between Miles Audio 2 + 3
+ // Miles Audio 2 used a pitch range of 12, which was basically hardcoded
+ // Miles Audio 3 used an array, which got set by control change events
+
+ currentNote += _virtualFmVoices->currentTransposition;
+
+ // Normalize note
+ currentNote -= 24;
+ do {
+ currentNote += 12;
+ } while (currentNote < 0);
+ currentNote += 12;
+
+ do {
+ currentNote -= 12;
+ } while (currentNote > 95);
+
+ // combine note + pitchbender, also adjust by 8 for rounding
+ currentNote = (currentNote << 8) + pitchBender + 8;
+
+ currentNote = currentNote >> 4; // get actual note
+
+ // Normalize
+ currentNote -= (12 * 16);
+ do {
+ currentNote += (12 * 16);
+ } while (currentNote < 0);
+
+ currentNote += (12 * 16);
+ do {
+ currentNote -= (12 * 16);
+ } while (currentNote > ((96 * 16) - 1));
+
+ physicalNote = currentNote >> 4;
+
+ halfTone = physicalNote % 12; // remainder of physicalNote / 12
+
+ frequencyIdx = (halfTone << 4) + (currentNote & 0x0F);
+ assert(frequencyIdx < sizeof(milesAdLibFrequencyLookUpTable));
+ frequency = milesAdLibFrequencyLookUpTable[frequencyIdx];
+
+ octave = (physicalNote / 12) - 1;
+
+ if (frequency & 0x8000)
+ octave++;
+
+ if (octave & 0x80) {
+ octave++;
+ frequency = frequency >> 1;
+ }
+
+ byte regA0 = frequency & 0xFF;
+ byte regB0 = ((frequency >> 8) & 0x03) | (octave << 2) | 0x20;
+
+ setRegister(0xA0 + channelReg, regA0);
+ setRegister(0xB0 + channelReg, regB0);
+
+ _physicalFmVoices[physicalFmVoice].currentB0hReg = regB0;
+ }
+ }
+
+ //warning("end of update voice");
+}
+
+void MidiDriver_Miles_AdLib::controlChange(byte midiChannel, byte controllerNumber, byte controllerValue) {
+ uint16 registerUpdateFlags = kMilesAdLibUpdateFlags_None;
+
+ switch (controllerNumber) {
+ case MILES_CONTROLLER_SELECT_PATCH_BANK:
+ //warning("patch bank channel %d, bank %x", midiChannel, controllerValue);
+ _midiChannels[midiChannel].currentPatchBank = controllerValue;
+ break;
+
+ case MILES_CONTROLLER_PROTECT_VOICE:
+ _midiChannels[midiChannel].currentVoiceProtection = controllerValue;
+ break;
+
+ case MILES_CONTROLLER_PROTECT_TIMBRE:
+ // It seems that this can get ignored, because we don't cache timbres at all
+ break;
+
+ case MILES_CONTROLLER_MODULATION:
+ _midiChannels[midiChannel].currentModulation = controllerValue;
+ registerUpdateFlags = kMilesAdLibUpdateFlags_Reg_20;
+ break;
+
+ case MILES_CONTROLLER_VOLUME:
+ _midiChannels[midiChannel].currentVolume = controllerValue;
+ registerUpdateFlags = kMilesAdLibUpdateFlags_Reg_40;
+ break;
+
+ case MILES_CONTROLLER_EXPRESSION:
+ _midiChannels[midiChannel].currentVolumeExpression = controllerValue;
+ registerUpdateFlags = kMilesAdLibUpdateFlags_Reg_40;
+ break;
+
+ case MILES_CONTROLLER_PANNING:
+ _midiChannels[midiChannel].currentPanning = controllerValue;
+ if (_modeStereo) {
+ // Update register only in case we are in stereo mode
+ registerUpdateFlags = kMilesAdLibUpdateFlags_Reg_C0;
+ }
+ break;
+
+ case MILES_CONTROLLER_SUSTAIN:
+ _midiChannels[midiChannel].currentSustain = controllerValue;
+ if (controllerValue < 64) {
+ releaseSustain(midiChannel);
+ }
+ break;
+
+ case MILES_CONTROLLER_PITCH_RANGE:
+ // Miles Audio 3 feature
+ _midiChannels[midiChannel].currentPitchRange = controllerValue;
+ break;
+
+ case MILES_CONTROLLER_RESET_ALL:
+ _midiChannels[midiChannel].currentSustain = 0;
+ releaseSustain(midiChannel);
+ _midiChannels[midiChannel].currentModulation = 0;
+ _midiChannels[midiChannel].currentVolumeExpression = 127;
+ _midiChannels[midiChannel].currentPitchBender = MILES_PITCHBENDER_DEFAULT;
+ registerUpdateFlags = kMilesAdLibUpdateFlags_Reg_20 | kMilesAdLibUpdateFlags_Reg_40 | kMilesAdLibUpdateFlags_Reg_A0;
+ break;
+
+ case MILES_CONTROLLER_ALL_NOTES_OFF:
+ for (byte virtualFmVoice = 0; virtualFmVoice < _modeVirtualFmVoicesCount; virtualFmVoice++) {
+ if (_virtualFmVoices[virtualFmVoice].inUse) {
+ // used
+ if (_virtualFmVoices[virtualFmVoice].actualMidiChannel == midiChannel) {
+ // by our current MIDI channel -> noteOff
+ noteOff(midiChannel, _virtualFmVoices[virtualFmVoice].currentNote);
+ }
+ }
+ }
+ break;
+
+ default:
+ //warning("MILES-ADLIB: Unsupported control change %d", controllerNumber);
+ break;
+ }
+
+ if (registerUpdateFlags) {
+ for (byte virtualFmVoice = 0; virtualFmVoice < _modeVirtualFmVoicesCount; virtualFmVoice++) {
+ if (_virtualFmVoices[virtualFmVoice].inUse) {
+ // used
+ if (_virtualFmVoices[virtualFmVoice].actualMidiChannel == midiChannel) {
+ // by our current MIDI channel -> update
+ updatePhysicalFmVoice(virtualFmVoice, true, registerUpdateFlags);
+ }
+ }
+ }
+ }
+}
+
+void MidiDriver_Miles_AdLib::programChange(byte midiChannel, byte patchId) {
+ const InstrumentEntry *instrumentPtr = NULL;
+ byte patchBank = _midiChannels[midiChannel].currentPatchBank;
+
+ //warning("patch channel %d, patch %x, bank %x", midiChannel, patchId, patchBank);
+
+ // we check, if we actually have data for the requested instrument...
+ instrumentPtr = searchInstrument(patchBank, patchId);
+ if (!instrumentPtr) {
+ warning("MILES-ADLIB: unknown instrument requested (%d, %d)", patchBank, patchId);
+ return;
+ }
+
+ // and remember it in that case for the current MIDI-channel
+ _midiChannels[midiChannel].currentInstrumentPtr = instrumentPtr;
+}
+
+const InstrumentEntry *MidiDriver_Miles_AdLib::searchInstrument(byte bankId, byte patchId) {
+ const InstrumentEntry *instrumentPtr = _instrumentTablePtr;
+
+ for (uint16 instrumentNr = 0; instrumentNr < _instrumentTableCount; instrumentNr++) {
+ if ((instrumentPtr->bankId == bankId) && (instrumentPtr->patchId == patchId)) {
+ return instrumentPtr;
+ }
+ instrumentPtr++;
+ }
+
+ return NULL;
+}
+
+void MidiDriver_Miles_AdLib::pitchBendChange(byte midiChannel, byte parameter1, byte parameter2) {
+ // Miles Audio actually didn't shift parameter 2 1 down in here
+ // which means in memory it used a 15-bit pitch bender, which also means the default was 0x4000
+ if ((parameter1 & 0x80) || (parameter2 & 0x80)) {
+ warning("MILES-ADLIB: invalid pitch bend change");
+ return;
+ }
+ _midiChannels[midiChannel].currentPitchBender = parameter1 | (parameter2 << 7);
+}
+
+void MidiDriver_Miles_AdLib::setRegister(int reg, int value) {
+ if (!(reg & 0x100)) {
+ _opl->write(0x220, reg);
+ _opl->write(0x221, value);
+ //warning("OPL write %x %x (%d)", reg, value, value);
+ } else {
+ _opl->write(0x222, reg & 0xFF);
+ _opl->write(0x223, value);
+ //warning("OPL3 write %x %x (%d)", reg & 0xFF, value, value);
+ }
+}
+
+uint32 MidiDriver_Miles_AdLib::property(int prop, uint32 param) {
+ return 0;
+}
+
+MidiDriver *MidiDriver_Miles_AdLib_create(const Common::String &filenameAdLib, const Common::String &filenameOPL3, Common::SeekableReadStream *streamAdLib, Common::SeekableReadStream *streamOPL3) {
+ // Load adlib instrument data from file SAMPLE.AD (OPL3: SAMPLE.OPL)
+ Common::String timbreFilename;
+ Common::SeekableReadStream *timbreStream = nullptr;
+
+ bool preferOPL3 = false;
+
+ Common::File *fileStream = new Common::File();
+ uint32 fileSize = 0;
+ uint32 fileDataOffset = 0;
+ uint32 fileDataLeft = 0;
+
+
+ uint32 streamSize = 0;
+ byte *streamDataPtr = nullptr;
+
+ byte curBankId = 0;
+ byte curPatchId = 0;
+
+ InstrumentEntry *instrumentTablePtr = nullptr;
+ uint16 instrumentTableCount = 0;
+ InstrumentEntry *instrumentPtr = nullptr;
+ uint32 instrumentOffset = 0;
+ uint16 instrumentDataSize = 0;
+
+ // Logic:
+ // We prefer OPL3 timbre data in case OPL3 is available in ScummVM
+ // If it's not or OPL3 timbre data is not available, we go for AdLib timbre data
+ // And if OPL3 is not available in ScummVM and also AdLib timbre data is not available,
+ // we then still go for OPL3 timbre data.
+ //
+ // Note: for most games OPL3 timbre data + AdLib timbre data is the same.
+ // And at least in theory we should still be able to use OPL3 timbre data even for AdLib.
+ // However there is a special OPL3-specific timbre format, which is currently not supported.
+ // In this case the error message "unsupported instrument size" should appear. I haven't found
+ // a game that uses it, which is why I haven't implemented it yet.
+
+ if (OPL::Config::detect(OPL::Config::kOpl3) >= 0) {
+ // OPL3 available, prefer OPL3 timbre data because of this
+ preferOPL3 = true;
+ }
+
+ // Check if streams were passed to us and select one of them
+ if ((streamAdLib) || (streamOPL3)) {
+ // At least one stream was passed by caller
+ if (preferOPL3) {
+ // Prefer OPL3 timbre stream in case OPL3 is available
+ timbreStream = streamOPL3;
+ }
+ if (!timbreStream) {
+ // Otherwise prefer AdLib timbre stream first
+ if (streamAdLib) {
+ timbreStream = streamAdLib;
+ } else {
+ // If not available, use OPL3 timbre stream
+ if (streamOPL3) {
+ timbreStream = streamOPL3;
+ }
+ }
+ }
+ }
+
+ // Now check if any filename was passed to us
+ if ((!filenameAdLib.empty()) || (!filenameOPL3.empty())) {
+ // If that's the case, check if one of those exists
+ if (preferOPL3) {
+ // OPL3 available
+ if (!filenameOPL3.empty()) {
+ if (fileStream->exists(filenameOPL3)) {
+ // If OPL3 available, prefer OPL3 timbre file in case file exists
+ timbreFilename = filenameOPL3;
+ }
+ }
+ if (timbreFilename.empty()) {
+ if (!filenameAdLib.empty()) {
+ if (fileStream->exists(filenameAdLib)) {
+ // otherwise use AdLib timbre file, if it exists
+ timbreFilename = filenameAdLib;
+ }
+ }
+ }
+ } else {
+ // OPL3 not available
+ // Prefer the AdLib one for now
+ if (!filenameAdLib.empty()) {
+ if (fileStream->exists(filenameAdLib)) {
+ // if AdLib file exists, use it
+ timbreFilename = filenameAdLib;
+ }
+ }
+ if (timbreFilename.empty()) {
+ if (!filenameOPL3.empty()) {
+ if (fileStream->exists(filenameOPL3)) {
+ // if OPL3 file exists, use it
+ timbreFilename = filenameOPL3;
+ }
+ }
+ }
+ }
+ if (timbreFilename.empty() && (!timbreStream)) {
+ // If none of them exists and also no stream was passed, we can't do anything about it
+ if (!filenameAdLib.empty()) {
+ if (!filenameOPL3.empty()) {
+ error("MILES-ADLIB: could not open timbre file (%s or %s)", filenameAdLib.c_str(), filenameOPL3.c_str());
+ } else {
+ error("MILES-ADLIB: could not open timbre file (%s)", filenameAdLib.c_str());
+ }
+ } else {
+ error("MILES-ADLIB: could not open timbre file (%s)", filenameOPL3.c_str());
+ }
+ }
+ }
+
+ if (!timbreFilename.empty()) {
+ // Filename was passed to us and file exists (this is the common case for most games)
+ // We prefer this situation
+
+ if (!fileStream->open(timbreFilename))
+ error("MILES-ADLIB: could not open timbre file (%s)", timbreFilename.c_str());
+
+ streamSize = fileStream->size();
+
+ streamDataPtr = new byte[streamSize];
+
+ if (fileStream->read(streamDataPtr, streamSize) != streamSize)
+ error("MILES-ADLIB: error while reading timbre file (%s)", timbreFilename.c_str());
+ fileStream->close();
+
+ } else if (timbreStream) {
+ // Timbre data was passed directly (possibly read from resource file by caller)
+ // Currently used by "Amazon Guardians of Eden", "Simon 2" and "Return To Zork"
+ streamSize = timbreStream->size();
+
+ streamDataPtr = new byte[streamSize];
+
+ if (timbreStream->read(streamDataPtr, streamSize) != streamSize)
+ error("MILES-ADLIB: error while reading timbre stream");
+
+ } else {
+ error("MILES-ADLIB: timbre filenames nor timbre stream were passed");
+ }
+
+ delete fileStream;
+
+ // File is like this:
+ // [patch:BYTE] [bank:BYTE] [patchoffset:UINT32]
+ // ...
+ // until patch + bank are both 0xFF, which signals end of header
+
+ // First we check how many entries there are
+ fileDataOffset = 0;
+ fileDataLeft = streamSize;
+ while (1) {
+ if (fileDataLeft < 6)
+ error("MILES-ADLIB: unexpected EOF in instrument file");
+
+ curPatchId = streamDataPtr[fileDataOffset++];
+ curBankId = streamDataPtr[fileDataOffset++];
+
+ if ((curBankId == 0xFF) && (curPatchId == 0xFF))
+ break;
+
+ fileDataOffset += 4; // skip over offset
+ instrumentTableCount++;
+ }
+
+ if (instrumentTableCount == 0)
+ error("MILES-ADLIB: no instruments in instrument file");
+
+ // Allocate space for instruments
+ instrumentTablePtr = new InstrumentEntry[instrumentTableCount];
+
+ // Now actually read all entries
+ instrumentPtr = instrumentTablePtr;
+
+ fileDataOffset = 0;
+ fileDataLeft = fileSize;
+ while (1) {
+ curPatchId = streamDataPtr[fileDataOffset++];
+ curBankId = streamDataPtr[fileDataOffset++];
+
+ if ((curBankId == 0xFF) && (curPatchId == 0xFF))
+ break;
+
+ instrumentOffset = READ_LE_UINT32(streamDataPtr + fileDataOffset);
+ fileDataOffset += 4;
+
+ instrumentPtr->bankId = curBankId;
+ instrumentPtr->patchId = curPatchId;
+
+ instrumentDataSize = READ_LE_UINT16(streamDataPtr + instrumentOffset);
+ if (instrumentDataSize != 14)
+ error("MILES-ADLIB: unsupported instrument size");
+
+ instrumentPtr->transposition = (signed char)streamDataPtr[instrumentOffset + 2];
+ instrumentPtr->reg20op1 = streamDataPtr[instrumentOffset + 3];
+ instrumentPtr->reg40op1 = streamDataPtr[instrumentOffset + 4];
+ instrumentPtr->reg60op1 = streamDataPtr[instrumentOffset + 5];
+ instrumentPtr->reg80op1 = streamDataPtr[instrumentOffset + 6];
+ instrumentPtr->regE0op1 = streamDataPtr[instrumentOffset + 7];
+ instrumentPtr->regC0 = streamDataPtr[instrumentOffset + 8];
+ instrumentPtr->reg20op2 = streamDataPtr[instrumentOffset + 9];
+ instrumentPtr->reg40op2 = streamDataPtr[instrumentOffset + 10];
+ instrumentPtr->reg60op2 = streamDataPtr[instrumentOffset + 11];
+ instrumentPtr->reg80op2 = streamDataPtr[instrumentOffset + 12];
+ instrumentPtr->regE0op2 = streamDataPtr[instrumentOffset + 13];
+
+ // Instrument read, next instrument please
+ instrumentPtr++;
+ }
+
+ // Free instrument file/stream data
+ delete[] streamDataPtr;
+
+ return new MidiDriver_Miles_AdLib(instrumentTablePtr, instrumentTableCount);
+}
+
+} // End of namespace Audio
diff --git a/audio/miles_mt32.cpp b/audio/miles_mt32.cpp
new file mode 100644
index 0000000000..dff863f119
--- /dev/null
+++ b/audio/miles_mt32.cpp
@@ -0,0 +1,912 @@
+/* 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/miles.h"
+
+#include "common/config-manager.h"
+#include "common/file.h"
+#include "common/mutex.h"
+#include "common/system.h"
+#include "common/textconsole.h"
+
+namespace Audio {
+
+// Miles Audio MT32 driver
+//
+
+#define MILES_MT32_PATCHES_COUNT 128
+#define MILES_MT32_CUSTOMTIMBRE_COUNT 64
+
+#define MILES_MT32_TIMBREBANK_STANDARD_ROLAND 0
+#define MILES_MT32_TIMBREBANK_MELODIC_MODULE 127
+
+#define MILES_MT32_PATCHDATA_COMMONPARAMETER_SIZE 14
+#define MILES_MT32_PATCHDATA_PARTIALPARAMETER_SIZE 58
+#define MILES_MT32_PATCHDATA_PARTIALPARAMETERS_COUNT 4
+#define MILES_MT32_PATCHDATA_TOTAL_SIZE (MILES_MT32_PATCHDATA_COMMONPARAMETER_SIZE + (MILES_MT32_PATCHDATA_PARTIALPARAMETER_SIZE * MILES_MT32_PATCHDATA_PARTIALPARAMETERS_COUNT))
+
+#define MILES_MT32_SYSEX_TERMINATOR 0xFF
+
+struct MilesMT32InstrumentEntry {
+ byte bankId;
+ byte patchId;
+ byte commonParameter[MILES_MT32_PATCHDATA_COMMONPARAMETER_SIZE + 1];
+ byte partialParameters[MILES_MT32_PATCHDATA_PARTIALPARAMETERS_COUNT][MILES_MT32_PATCHDATA_PARTIALPARAMETER_SIZE + 1];
+};
+
+const byte milesMT32SysExResetParameters[] = {
+ 0x01, MILES_MT32_SYSEX_TERMINATOR
+};
+
+const byte milesMT32SysExChansSetup[] = {
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, MILES_MT32_SYSEX_TERMINATOR
+};
+
+const byte milesMT32SysExPartialReserveTable[] = {
+ 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x04, MILES_MT32_SYSEX_TERMINATOR
+};
+
+const byte milesMT32SysExInitReverb[] = {
+ 0x00, 0x03, 0x02, MILES_MT32_SYSEX_TERMINATOR // Reverb mode 0, reverb time 3, reverb level 2
+};
+
+class MidiDriver_Miles_MT32 : public MidiDriver {
+public:
+ MidiDriver_Miles_MT32(MilesMT32InstrumentEntry *instrumentTablePtr, uint16 instrumentTableCount);
+ virtual ~MidiDriver_Miles_MT32();
+
+ // MidiDriver
+ int open();
+ void close();
+ bool isOpen() const { return _isOpen; }
+
+ void send(uint32 b);
+
+ MidiChannel *allocateChannel() {
+ if (_driver)
+ return _driver->allocateChannel();
+ return NULL;
+ }
+ MidiChannel *getPercussionChannel() {
+ if (_driver)
+ return _driver->getPercussionChannel();
+ return NULL;
+ }
+
+ void setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc) {
+ if (_driver)
+ _driver->setTimerCallback(timer_param, timer_proc);
+ }
+
+ uint32 getBaseTempo() {
+ if (_driver) {
+ return _driver->getBaseTempo();
+ }
+ return 1000000 / _baseFreq;
+ }
+
+protected:
+ Common::Mutex _mutex;
+ MidiDriver *_driver;
+ bool _MT32;
+ bool _nativeMT32;
+
+ bool _isOpen;
+ int _baseFreq;
+
+public:
+ void processXMIDITimbreChunk(const byte *timbreListPtr, uint32 timbreListSize);
+
+private:
+ void resetMT32();
+
+ void MT32SysEx(const uint32 targetAddress, const byte *dataPtr);
+
+ uint32 calculateSysExTargetAddress(uint32 baseAddress, uint32 index);
+
+ void writeRhythmSetup(byte note, byte customTimbreId);
+ void writePatchTimbre(byte patchId, byte timbreGroup, byte timbreId);
+ void writePatchByte(byte patchId, byte index, byte patchValue);
+ void writeToSystemArea(byte index, byte value);
+
+ void controlChange(byte midiChannel, byte controllerNumber, byte controllerValue);
+ void programChange(byte midiChannel, byte patchId);
+
+ const MilesMT32InstrumentEntry *searchCustomInstrument(byte patchBank, byte patchId);
+ int16 searchCustomTimbre(byte patchBank, byte patchId);
+
+ void setupPatch(byte patchBank, byte patchId);
+ int16 installCustomTimbre(byte patchBank, byte patchId);
+
+private:
+ struct MidiChannelEntry {
+ byte currentPatchBank;
+ byte currentPatchId;
+
+ bool usingCustomTimbre;
+ byte currentCustomTimbreId;
+
+ MidiChannelEntry() : currentPatchBank(0),
+ currentPatchId(0),
+ usingCustomTimbre(false),
+ currentCustomTimbreId(0) { }
+ };
+
+ struct MidiCustomTimbreEntry {
+ bool used;
+ bool protectionEnabled;
+ byte currentPatchBank;
+ byte currentPatchId;
+
+ uint32 lastUsedNoteCounter;
+
+ MidiCustomTimbreEntry() : used(false),
+ protectionEnabled(false),
+ currentPatchBank(0),
+ currentPatchId(0),
+ lastUsedNoteCounter(0) {}
+ };
+
+ struct MilesMT32SysExQueueEntry {
+ uint32 targetAddress;
+ byte dataPos;
+ byte data[MILES_CONTROLLER_SYSEX_QUEUE_SIZE + 1]; // 1 extra byte for terminator
+
+ MilesMT32SysExQueueEntry() : targetAddress(0),
+ dataPos(0) {
+ memset(data, 0, sizeof(data));
+ }
+ };
+
+ // stores information about all MIDI channels
+ MidiChannelEntry _midiChannels[MILES_MIDI_CHANNEL_COUNT];
+
+ // stores information about all custom timbres
+ MidiCustomTimbreEntry _customTimbres[MILES_MT32_CUSTOMTIMBRE_COUNT];
+
+ byte _patchesBank[MILES_MT32_PATCHES_COUNT];
+
+ // holds all instruments
+ MilesMT32InstrumentEntry *_instrumentTablePtr;
+ uint16 _instrumentTableCount;
+
+ uint32 _noteCounter; // used to figure out, which timbres are outdated
+
+ // SysEx Queues
+ MilesMT32SysExQueueEntry _sysExQueues[MILES_CONTROLLER_SYSEX_QUEUE_COUNT];
+};
+
+MidiDriver_Miles_MT32::MidiDriver_Miles_MT32(MilesMT32InstrumentEntry *instrumentTablePtr, uint16 instrumentTableCount) {
+ _instrumentTablePtr = instrumentTablePtr;
+ _instrumentTableCount = instrumentTableCount;
+
+ _driver = NULL;
+ _isOpen = false;
+ _MT32 = false;
+ _nativeMT32 = false;
+ _baseFreq = 250;
+
+ _noteCounter = 0;
+
+ memset(_patchesBank, 0, sizeof(_patchesBank));
+}
+
+MidiDriver_Miles_MT32::~MidiDriver_Miles_MT32() {
+ Common::StackLock lock(_mutex);
+ if (_driver) {
+ _driver->setTimerCallback(0, 0);
+ _driver->close();
+ delete _driver;
+ }
+ _driver = NULL;
+}
+
+int MidiDriver_Miles_MT32::open() {
+ assert(!_driver);
+
+ // Setup midi driver
+ MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_PREFER_MT32);
+ MusicType musicType = MidiDriver::getMusicType(dev);
+
+ switch (musicType) {
+ case MT_MT32:
+ _nativeMT32 = true;
+ break;
+ case MT_GM:
+ if (ConfMan.getBool("native_mt32")) {
+ _nativeMT32 = true;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (!_nativeMT32) {
+ error("MILES-MT32: non-mt32 currently not supported!");
+ }
+
+ _driver = MidiDriver::createMidi(dev);
+ if (!_driver)
+ return 255;
+
+ if (_nativeMT32)
+ _driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
+
+ int ret = _driver->open();
+ if (ret)
+ return ret;
+
+ if (_nativeMT32) {
+ _driver->sendMT32Reset();
+
+ resetMT32();
+ }
+
+ return 0;
+}
+
+void MidiDriver_Miles_MT32::close() {
+ if (_driver) {
+ _driver->close();
+ }
+}
+
+void MidiDriver_Miles_MT32::resetMT32() {
+ // reset all internal parameters / patches
+ MT32SysEx(0x7F0000, milesMT32SysExResetParameters);
+
+ // init part/channel assignments
+ MT32SysEx(0x10000D, milesMT32SysExChansSetup);
+
+ // partial reserve table
+ MT32SysEx(0x100004, milesMT32SysExPartialReserveTable);
+
+ // init reverb
+ MT32SysEx(0x100001, milesMT32SysExInitReverb);
+}
+
+void MidiDriver_Miles_MT32::MT32SysEx(const uint32 targetAddress, const byte *dataPtr) {
+ byte sysExMessage[270];
+ uint16 sysExPos = 0;
+ byte sysExByte = 0;
+ uint16 sysExChecksum = 0;
+
+ memset(&sysExMessage, 0, sizeof(sysExMessage));
+
+ sysExMessage[0] = 0x41; // Roland
+ sysExMessage[1] = 0x10;
+ sysExMessage[2] = 0x16; // Model MT32
+ sysExMessage[3] = 0x12; // Command DT1
+
+ sysExChecksum = 0;
+
+ sysExMessage[4] = (targetAddress >> 16) & 0xFF;
+ sysExMessage[5] = (targetAddress >> 8) & 0xFF;
+ sysExMessage[6] = targetAddress & 0xFF;
+
+ for (byte targetAddressByte = 4; targetAddressByte < 7; targetAddressByte++) {
+ assert(sysExMessage[targetAddressByte] < 0x80); // security check
+ sysExChecksum -= sysExMessage[targetAddressByte];
+ }
+
+ sysExPos = 7;
+ while (1) {
+ sysExByte = *dataPtr++;
+ if (sysExByte == MILES_MT32_SYSEX_TERMINATOR)
+ break; // Message done
+
+ assert(sysExPos < sizeof(sysExMessage));
+ assert(sysExByte < 0x80); // security check
+ sysExMessage[sysExPos++] = sysExByte;
+ sysExChecksum -= sysExByte;
+ }
+
+ // Calculate checksum
+ assert(sysExPos < sizeof(sysExMessage));
+ sysExMessage[sysExPos++] = sysExChecksum & 0x7f;
+
+ // Send SysEx
+ _driver->sysEx(sysExMessage, sysExPos);
+
+ // Wait the time it takes to send the SysEx data
+ uint32 delay = (sysExPos + 2) * 1000 / 3125;
+
+ // Plus an additional delay for the MT-32 rev00
+ if (_nativeMT32)
+ delay += 40;
+
+ g_system->delayMillis(delay);
+}
+
+// MIDI messages can be found at http://www.midi.org/techspecs/midimessages.php
+void MidiDriver_Miles_MT32::send(uint32 b) {
+ byte command = b & 0xf0;
+ byte midiChannel = b & 0xf;
+ byte op1 = (b >> 8) & 0xff;
+ byte op2 = (b >> 16) & 0xff;
+
+ switch (command) {
+ case 0x80: // note off
+ case 0x90: // note on
+ case 0xa0: // Polyphonic key pressure (aftertouch)
+ case 0xd0: // Channel pressure (aftertouch)
+ case 0xe0: // pitch bend change
+ _noteCounter++;
+ if (_midiChannels[midiChannel].usingCustomTimbre) {
+ // Remember that this timbre got used now
+ _customTimbres[_midiChannels[midiChannel].currentCustomTimbreId].lastUsedNoteCounter = _noteCounter;
+ }
+ _driver->send(b);
+ break;
+ case 0xb0: // Control change
+ controlChange(midiChannel, op1, op2);
+ break;
+ case 0xc0: // Program Change
+ programChange(midiChannel, op1);
+ break;
+ case 0xf0: // SysEx
+ warning("MILES-MT32: SysEx: %x", b);
+ break;
+ default:
+ warning("MILES-MT32: Unknown event %02x", command);
+ }
+}
+
+void MidiDriver_Miles_MT32::controlChange(byte midiChannel, byte controllerNumber, byte controllerValue) {
+ byte channelPatchId = 0;
+ byte channelCustomTimbreId = 0;
+
+ switch (controllerNumber) {
+ case MILES_CONTROLLER_SELECT_PATCH_BANK:
+ _midiChannels[midiChannel].currentPatchBank = controllerValue;
+ return;
+
+ case MILES_CONTROLLER_PATCH_REVERB:
+ channelPatchId = _midiChannels[midiChannel].currentPatchId;
+
+ writePatchByte(channelPatchId, 6, controllerValue);
+ _driver->send(0xC0 | midiChannel | (channelPatchId << 8)); // execute program change
+ return;
+
+ case MILES_CONTROLLER_PATCH_BENDER:
+ channelPatchId = _midiChannels[midiChannel].currentPatchId;
+
+ writePatchByte(channelPatchId, 4, controllerValue);
+ _driver->send(0xC0 | midiChannel | (channelPatchId << 8)); // execute program change
+ return;
+
+ case MILES_CONTROLLER_REVERB_MODE:
+ writeToSystemArea(1, controllerValue);
+ return;
+
+ case MILES_CONTROLLER_REVERB_TIME:
+ writeToSystemArea(2, controllerValue);
+ return;
+
+ case MILES_CONTROLLER_REVERB_LEVEL:
+ writeToSystemArea(3, controllerValue);
+ return;
+
+ case MILES_CONTROLLER_RHYTHM_KEY_TIMBRE:
+ if (_midiChannels[midiChannel].usingCustomTimbre) {
+ // custom timbre is set on current channel
+ writeRhythmSetup(controllerValue, _midiChannels[midiChannel].currentCustomTimbreId);
+ }
+ return;
+
+ case MILES_CONTROLLER_PROTECT_TIMBRE:
+ if (_midiChannels[midiChannel].usingCustomTimbre) {
+ // custom timbre set on current channel
+ channelCustomTimbreId = _midiChannels[midiChannel].currentCustomTimbreId;
+ if (controllerValue >= 64) {
+ // enable protection
+ _customTimbres[channelCustomTimbreId].protectionEnabled = true;
+ } else {
+ // disable protection
+ _customTimbres[channelCustomTimbreId].protectionEnabled = false;
+ }
+ }
+ return;
+
+ default:
+ break;
+ }
+
+ if ((controllerNumber >= MILES_CONTROLLER_SYSEX_RANGE_BEGIN) && (controllerNumber <= MILES_CONTROLLER_SYSEX_RANGE_END)) {
+ // send SysEx
+ byte sysExQueueNr = 0;
+
+ // figure out which queue is accessed
+ controllerNumber -= MILES_CONTROLLER_SYSEX_RANGE_BEGIN;
+ while (controllerNumber > MILES_CONTROLLER_SYSEX_COMMAND_SEND) {
+ sysExQueueNr++;
+ controllerNumber -= (MILES_CONTROLLER_SYSEX_COMMAND_SEND + 1);
+ }
+ assert(sysExQueueNr < MILES_CONTROLLER_SYSEX_QUEUE_COUNT);
+
+ byte sysExPos = _sysExQueues[sysExQueueNr].dataPos;
+ bool sysExSend = false;
+
+ switch(controllerNumber) {
+ case MILES_CONTROLLER_SYSEX_COMMAND_ADDRESS1:
+ _sysExQueues[sysExQueueNr].targetAddress &= 0x00FFFF;
+ _sysExQueues[sysExQueueNr].targetAddress |= (controllerValue << 16);
+ break;
+ case MILES_CONTROLLER_SYSEX_COMMAND_ADDRESS2:
+ _sysExQueues[sysExQueueNr].targetAddress &= 0xFF00FF;
+ _sysExQueues[sysExQueueNr].targetAddress |= (controllerValue << 8);
+ break;
+ case MILES_CONTROLLER_SYSEX_COMMAND_ADDRESS3:
+ _sysExQueues[sysExQueueNr].targetAddress &= 0xFFFF00;
+ _sysExQueues[sysExQueueNr].targetAddress |= controllerValue;
+ break;
+ case MILES_CONTROLLER_SYSEX_COMMAND_DATA:
+ if (sysExPos < MILES_CONTROLLER_SYSEX_QUEUE_SIZE) {
+ // Space left? put current byte into queue
+ _sysExQueues[sysExQueueNr].data[sysExPos] = controllerValue;
+ sysExPos++;
+ _sysExQueues[sysExQueueNr].dataPos = sysExPos;
+ if (sysExPos >= MILES_CONTROLLER_SYSEX_QUEUE_SIZE) {
+ // overflow? -> send it now
+ sysExSend = true;
+ }
+ }
+ break;
+ case MILES_CONTROLLER_SYSEX_COMMAND_SEND:
+ sysExSend = true;
+ break;
+ default:
+ assert(0);
+ }
+
+ if (sysExSend) {
+ if (sysExPos > 0) {
+ // data actually available? -> send it
+ _sysExQueues[sysExQueueNr].data[sysExPos] = MILES_MT32_SYSEX_TERMINATOR; // put terminator
+
+ // Execute SysEx
+ MT32SysEx(_sysExQueues[sysExQueueNr].targetAddress, _sysExQueues[sysExQueueNr].data);
+
+ // adjust target address to point at the end of the current data
+ _sysExQueues[sysExQueueNr].targetAddress += sysExPos;
+ // reset queue data buffer
+ _sysExQueues[sysExQueueNr].dataPos = 0;
+ }
+ }
+ return;
+ }
+
+ if ((controllerNumber >= MILES_CONTROLLER_XMIDI_RANGE_BEGIN) && (controllerNumber <= MILES_CONTROLLER_XMIDI_RANGE_END)) {
+ // XMIDI controllers? ignore those
+ return;
+ }
+
+ _driver->send(0xB0 | midiChannel | (controllerNumber << 8) | (controllerValue << 16));
+}
+
+void MidiDriver_Miles_MT32::programChange(byte midiChannel, byte patchId) {
+ byte channelPatchBank = _midiChannels[midiChannel].currentPatchBank;
+ byte activePatchBank = _patchesBank[patchId];
+
+ //warning("patch channel %d, patch %x, bank %x", midiChannel, patchId, channelPatchBank);
+
+ // remember patch id for the current MIDI-channel
+ _midiChannels[midiChannel].currentPatchId = patchId;
+
+ if (channelPatchBank != activePatchBank) {
+ // associate patch with timbre
+ setupPatch(channelPatchBank, patchId);
+ }
+
+ // If this is a custom patch, remember customTimbreId
+ int16 customTimbre = searchCustomTimbre(channelPatchBank, patchId);
+ if (customTimbre >= 0) {
+ _midiChannels[midiChannel].usingCustomTimbre = true;
+ _midiChannels[midiChannel].currentCustomTimbreId = customTimbre;
+ } else {
+ _midiChannels[midiChannel].usingCustomTimbre = false;
+ }
+
+ // Finally send program change to MT32
+ _driver->send(0xC0 | midiChannel | (patchId << 8));
+}
+
+int16 MidiDriver_Miles_MT32::searchCustomTimbre(byte patchBank, byte patchId) {
+ byte customTimbreId = 0;
+
+ for (customTimbreId = 0; customTimbreId < MILES_MT32_CUSTOMTIMBRE_COUNT; customTimbreId++) {
+ if (_customTimbres[customTimbreId].used) {
+ if ((_customTimbres[customTimbreId].currentPatchBank == patchBank) && (_customTimbres[customTimbreId].currentPatchId == patchId)) {
+ return customTimbreId;
+ }
+ }
+ }
+ return -1;
+}
+
+const MilesMT32InstrumentEntry *MidiDriver_Miles_MT32::searchCustomInstrument(byte patchBank, byte patchId) {
+ const MilesMT32InstrumentEntry *instrumentPtr = _instrumentTablePtr;
+
+ for (uint16 instrumentNr = 0; instrumentNr < _instrumentTableCount; instrumentNr++) {
+ if ((instrumentPtr->bankId == patchBank) && (instrumentPtr->patchId == patchId))
+ return instrumentPtr;
+ instrumentPtr++;
+ }
+ return NULL;
+}
+
+void MidiDriver_Miles_MT32::setupPatch(byte patchBank, byte patchId) {
+ _patchesBank[patchId] = patchBank;
+
+ if (patchBank) {
+ // non-built-in bank
+ int16 customTimbreId = searchCustomTimbre(patchBank, patchId);
+ if (customTimbreId >= 0) {
+ // now available? -> use this timbre
+ writePatchTimbre(patchId, 2, customTimbreId); // Group MEMORY
+ return;
+ }
+ }
+
+ // for built-in bank (or timbres, that are not available) use default MT32 timbres
+ byte timbreId = patchId & 0x3F;
+ if (!(patchId & 0x40)) {
+ writePatchTimbre(patchId, 0, timbreId); // Group A
+ } else {
+ writePatchTimbre(patchId, 1, timbreId); // Group B
+ }
+}
+
+void MidiDriver_Miles_MT32::processXMIDITimbreChunk(const byte *timbreListPtr, uint32 timbreListSize) {
+ uint16 timbreCount = 0;
+ uint32 expectedSize = 0;
+ const byte *timbreListSeeker = timbreListPtr;
+
+ if (timbreListSize < 2) {
+ warning("MILES-MT32: XMIDI-TIMB chunk - not enough bytes in chunk");
+ return;
+ }
+
+ timbreCount = READ_LE_UINT16(timbreListPtr);
+ expectedSize = timbreCount * 2;
+ if (expectedSize > timbreListSize) {
+ warning("MILES-MT32: XMIDI-TIMB chunk - size mismatch");
+ return;
+ }
+
+ timbreListSeeker += 2;
+
+ while (timbreCount) {
+ const byte patchId = *timbreListSeeker++;
+ const byte patchBank = *timbreListSeeker++;
+ int16 customTimbreId = 0;
+
+ switch (patchBank) {
+ case MILES_MT32_TIMBREBANK_STANDARD_ROLAND:
+ case MILES_MT32_TIMBREBANK_MELODIC_MODULE:
+ // ignore those 2 banks
+ break;
+
+ default:
+ // Check, if this timbre was already loaded
+ customTimbreId = searchCustomTimbre(patchBank, patchId);
+
+ if (customTimbreId < 0) {
+ // currently not loaded, try to install it
+ installCustomTimbre(patchBank, patchId);
+ }
+ }
+ timbreCount--;
+ }
+}
+
+//
+int16 MidiDriver_Miles_MT32::installCustomTimbre(byte patchBank, byte patchId) {
+ switch(patchBank) {
+ case MILES_MT32_TIMBREBANK_STANDARD_ROLAND: // Standard Roland MT32 bank
+ case MILES_MT32_TIMBREBANK_MELODIC_MODULE: // Reserved for melodic mode
+ return -1;
+ default:
+ break;
+ }
+
+ // Original driver did a search for custom timbre here
+ // and in case it was found, it would call setup_patch()
+ // we are called from within setup_patch(), so this isn't needed
+
+ int16 customTimbreId = -1;
+ int16 leastUsedTimbreId = -1;
+ uint32 leastUsedTimbreNoteCounter = _noteCounter;
+ const MilesMT32InstrumentEntry *instrumentPtr = NULL;
+
+ // Check, if requested instrument is actually available
+ instrumentPtr = searchCustomInstrument(patchBank, patchId);
+ if (!instrumentPtr) {
+ warning("MILES-MT32: instrument not found during installCustomTimbre()");
+ return -1; // not found -> bail out
+ }
+
+ // Look for an empty timbre slot
+ // or get the least used non-protected slot
+ for (byte customTimbreNr = 0; customTimbreNr < MILES_MT32_CUSTOMTIMBRE_COUNT; customTimbreNr++) {
+ if (!_customTimbres[customTimbreNr].used) {
+ // found an empty slot -> use this one
+ customTimbreId = customTimbreNr;
+ break;
+ } else {
+ // used slot
+ if (!_customTimbres[customTimbreNr].protectionEnabled) {
+ // not protected
+ uint32 customTimbreNoteCounter = _customTimbres[customTimbreNr].lastUsedNoteCounter;
+ if (customTimbreNoteCounter < leastUsedTimbreNoteCounter) {
+ leastUsedTimbreId = customTimbreNr;
+ leastUsedTimbreNoteCounter = customTimbreNoteCounter;
+ }
+ }
+ }
+ }
+
+ if (customTimbreId < 0) {
+ // no empty slot found, check if we got a least used non-protected slot
+ if (leastUsedTimbreId < 0) {
+ // everything is protected, bail out
+ warning("MILES-MT32: no non-protected timbre slots available during installCustomTimbre()");
+ return -1;
+ }
+ customTimbreId = leastUsedTimbreId;
+ }
+
+ // setup timbre slot
+ _customTimbres[customTimbreId].used = true;
+ _customTimbres[customTimbreId].currentPatchBank = patchBank;
+ _customTimbres[customTimbreId].currentPatchId = patchId;
+ _customTimbres[customTimbreId].lastUsedNoteCounter = _noteCounter;
+ _customTimbres[customTimbreId].protectionEnabled = false;
+
+ uint32 targetAddress = 0x080000 | (customTimbreId << 9);
+ uint32 targetAddressCommon = targetAddress + 0x000000;
+ uint32 targetAddressPartial1 = targetAddress + 0x00000E;
+ uint32 targetAddressPartial2 = targetAddress + 0x000048;
+ uint32 targetAddressPartial3 = targetAddress + 0x000102;
+ uint32 targetAddressPartial4 = targetAddress + 0x00013C;
+
+#if 0
+ byte parameterData[MILES_MT32_PATCHDATA_TOTAL_SIZE + 1];
+ uint16 parameterDataPos = 0;
+
+ memcpy(parameterData, instrumentPtr->commonParameter, MILES_MT32_PATCHDATA_COMMONPARAMETER_SIZE);
+ parameterDataPos += MILES_MT32_PATCHDATA_COMMONPARAMETER_SIZE;
+ memcpy(parameterData + parameterDataPos, instrumentPtr->partialParameters[0], MILES_MT32_PATCHDATA_PARTIALPARAMETER_SIZE);
+ parameterDataPos += MILES_MT32_PATCHDATA_PARTIALPARAMETER_SIZE;
+ memcpy(parameterData + parameterDataPos, instrumentPtr->partialParameters[1], MILES_MT32_PATCHDATA_PARTIALPARAMETER_SIZE);
+ parameterDataPos += MILES_MT32_PATCHDATA_PARTIALPARAMETER_SIZE;
+ memcpy(parameterData + parameterDataPos, instrumentPtr->partialParameters[2], MILES_MT32_PATCHDATA_PARTIALPARAMETER_SIZE);
+ parameterDataPos += MILES_MT32_PATCHDATA_PARTIALPARAMETER_SIZE;
+ memcpy(parameterData + parameterDataPos, instrumentPtr->partialParameters[3], MILES_MT32_PATCHDATA_PARTIALPARAMETER_SIZE);
+ parameterDataPos += MILES_MT32_PATCHDATA_PARTIALPARAMETER_SIZE;
+ parameterData[parameterDataPos] = MILES_MT32_SYSEX_TERMINATOR;
+
+ MT32SysEx(targetAddressCommon, parameterData);
+#endif
+
+ // upload common parameter data
+ MT32SysEx(targetAddressCommon, instrumentPtr->commonParameter);
+ // upload partial parameter data
+ MT32SysEx(targetAddressPartial1, instrumentPtr->partialParameters[0]);
+ MT32SysEx(targetAddressPartial2, instrumentPtr->partialParameters[1]);
+ MT32SysEx(targetAddressPartial3, instrumentPtr->partialParameters[2]);
+ MT32SysEx(targetAddressPartial4, instrumentPtr->partialParameters[3]);
+
+ setupPatch(patchBank, patchId);
+
+ return customTimbreId;
+}
+
+uint32 MidiDriver_Miles_MT32::calculateSysExTargetAddress(uint32 baseAddress, uint32 index) {
+ uint16 targetAddressLSB = baseAddress & 0xFF;
+ uint16 targetAddressKSB = (baseAddress >> 8) & 0xFF;
+ uint16 targetAddressMSB = (baseAddress >> 16) & 0xFF;
+
+ // add index to it, but use 7-bit of the index for each byte
+ targetAddressLSB += (index & 0x7F);
+ targetAddressKSB += ((index >> 7) & 0x7F);
+ targetAddressMSB += ((index >> 14) & 0x7F);
+
+ // adjust bytes, so that none of them is above or equal 0x80
+ while (targetAddressLSB >= 0x80) {
+ targetAddressLSB -= 0x80;
+ targetAddressKSB++;
+ }
+ while (targetAddressKSB >= 0x80) {
+ targetAddressKSB -= 0x80;
+ targetAddressMSB++;
+ }
+ assert(targetAddressMSB < 0x80);
+
+ // put everything together
+ return targetAddressLSB | (targetAddressKSB << 8) | (targetAddressMSB << 16);
+}
+
+void MidiDriver_Miles_MT32::writeRhythmSetup(byte note, byte customTimbreId) {
+ byte sysExData[2];
+ uint32 targetAddress = 0;
+
+ targetAddress = calculateSysExTargetAddress(0x030110, ((note - 24) << 2));
+
+ sysExData[0] = customTimbreId;
+ sysExData[1] = MILES_MT32_SYSEX_TERMINATOR; // terminator
+
+ MT32SysEx(targetAddress, sysExData);
+}
+
+void MidiDriver_Miles_MT32::writePatchTimbre(byte patchId, byte timbreGroup, byte timbreId) {
+ byte sysExData[3];
+ uint32 targetAddress = 0;
+
+ // write to patch memory (starts at 0x050000, each entry is 8 bytes)
+ targetAddress = calculateSysExTargetAddress(0x050000, patchId << 3);
+
+ sysExData[0] = timbreGroup; // 0 - group A, 1 - group B, 2 - memory, 3 - rhythm
+ sysExData[1] = timbreId; // timbre number (0-63)
+ sysExData[2] = MILES_MT32_SYSEX_TERMINATOR; // terminator
+
+ MT32SysEx(targetAddress, sysExData);
+}
+
+void MidiDriver_Miles_MT32::writePatchByte(byte patchId, byte index, byte patchValue) {
+ byte sysExData[2];
+ uint32 targetAddress = 0;
+
+ targetAddress = calculateSysExTargetAddress(0x050000, (patchId << 3) + index);
+
+ sysExData[0] = patchValue;
+ sysExData[1] = MILES_MT32_SYSEX_TERMINATOR; // terminator
+
+ MT32SysEx(targetAddress, sysExData);
+}
+
+void MidiDriver_Miles_MT32::writeToSystemArea(byte index, byte value) {
+ byte sysExData[2];
+ uint32 targetAddress = 0;
+
+ targetAddress = calculateSysExTargetAddress(0x100000, index);
+
+ sysExData[0] = value;
+ sysExData[1] = MILES_MT32_SYSEX_TERMINATOR; // terminator
+
+ MT32SysEx(targetAddress, sysExData);
+}
+
+MidiDriver *MidiDriver_Miles_MT32_create(const Common::String &instrumentDataFilename) {
+ MilesMT32InstrumentEntry *instrumentTablePtr = NULL;
+ uint16 instrumentTableCount = 0;
+
+ if (!instrumentDataFilename.empty()) {
+ // Load MT32 instrument data from file SAMPLE.MT
+ Common::File *fileStream = new Common::File();
+ uint32 fileSize = 0;
+ byte *fileDataPtr = NULL;
+ uint32 fileDataOffset = 0;
+ uint32 fileDataLeft = 0;
+
+ byte curBankId = 0;
+ byte curPatchId = 0;
+
+ MilesMT32InstrumentEntry *instrumentPtr = NULL;
+ uint32 instrumentOffset = 0;
+ uint16 instrumentDataSize = 0;
+
+ if (!fileStream->open(instrumentDataFilename))
+ error("MILES-MT32: could not open instrument file '%s'", instrumentDataFilename.c_str());
+
+ fileSize = fileStream->size();
+
+ fileDataPtr = new byte[fileSize];
+
+ if (fileStream->read(fileDataPtr, fileSize) != fileSize)
+ error("MILES-MT32: error while reading instrument file");
+ fileStream->close();
+ delete fileStream;
+
+ // File is like this:
+ // [patch:BYTE] [bank:BYTE] [patchoffset:UINT32]
+ // ...
+ // until patch + bank are both 0xFF, which signals end of header
+
+ // First we check how many entries there are
+ fileDataOffset = 0;
+ fileDataLeft = fileSize;
+ while (1) {
+ if (fileDataLeft < 6)
+ error("MILES-MT32: unexpected EOF in instrument file");
+
+ curPatchId = fileDataPtr[fileDataOffset++];
+ curBankId = fileDataPtr[fileDataOffset++];
+
+ if ((curBankId == 0xFF) && (curPatchId == 0xFF))
+ break;
+
+ fileDataOffset += 4; // skip over offset
+ instrumentTableCount++;
+ }
+
+ if (instrumentTableCount == 0)
+ error("MILES-MT32: no instruments in instrument file");
+
+ // Allocate space for instruments
+ instrumentTablePtr = new MilesMT32InstrumentEntry[instrumentTableCount];
+
+ // Now actually read all entries
+ instrumentPtr = instrumentTablePtr;
+
+ fileDataOffset = 0;
+ fileDataLeft = fileSize;
+ while (1) {
+ curPatchId = fileDataPtr[fileDataOffset++];
+ curBankId = fileDataPtr[fileDataOffset++];
+
+ if ((curBankId == 0xFF) && (curPatchId == 0xFF))
+ break;
+
+ instrumentOffset = READ_LE_UINT32(fileDataPtr + fileDataOffset);
+ fileDataOffset += 4;
+
+ instrumentPtr->bankId = curBankId;
+ instrumentPtr->patchId = curPatchId;
+
+ instrumentDataSize = READ_LE_UINT16(fileDataPtr + instrumentOffset);
+ if (instrumentDataSize != (MILES_MT32_PATCHDATA_TOTAL_SIZE + 2))
+ error("MILES-MT32: unsupported instrument size");
+
+ instrumentOffset += 2;
+ // Copy common parameter data
+ memcpy(instrumentPtr->commonParameter, fileDataPtr + instrumentOffset, MILES_MT32_PATCHDATA_COMMONPARAMETER_SIZE);
+ instrumentPtr->commonParameter[MILES_MT32_PATCHDATA_COMMONPARAMETER_SIZE] = MILES_MT32_SYSEX_TERMINATOR; // Terminator
+ instrumentOffset += MILES_MT32_PATCHDATA_COMMONPARAMETER_SIZE;
+
+ // Copy partial parameter data
+ for (byte partialNr = 0; partialNr < MILES_MT32_PATCHDATA_PARTIALPARAMETERS_COUNT; partialNr++) {
+ memcpy(&instrumentPtr->partialParameters[partialNr], fileDataPtr + instrumentOffset, MILES_MT32_PATCHDATA_PARTIALPARAMETER_SIZE);
+ instrumentPtr->partialParameters[partialNr][MILES_MT32_PATCHDATA_PARTIALPARAMETER_SIZE] = MILES_MT32_SYSEX_TERMINATOR; // Terminator
+ instrumentOffset += MILES_MT32_PATCHDATA_PARTIALPARAMETER_SIZE;
+ }
+
+ // Instrument read, next instrument please
+ instrumentPtr++;
+ }
+
+ // Free instrument file data
+ delete[] fileDataPtr;
+ }
+
+ return new MidiDriver_Miles_MT32(instrumentTablePtr, instrumentTableCount);
+}
+
+void MidiDriver_Miles_MT32_processXMIDITimbreChunk(MidiDriver_BASE *driver, const byte *timbreListPtr, uint32 timbreListSize) {
+ MidiDriver_Miles_MT32 *driverMT32 = dynamic_cast<MidiDriver_Miles_MT32 *>(driver);
+
+ if (driverMT32) {
+ driverMT32->processXMIDITimbreChunk(timbreListPtr, timbreListSize);
+ }
+}
+
+} // End of namespace Audio
diff --git a/audio/mods/protracker.cpp b/audio/mods/protracker.cpp
index 82067f67bd..2578e9488a 100644
--- a/audio/mods/protracker.cpp
+++ b/audio/mods/protracker.cpp
@@ -219,11 +219,10 @@ void ProtrackerStream::updateRow() {
case 0x0:
if (exy) {
_track[track].arpeggio = true;
- if (note.period) {
- _track[track].arpeggioNotes[0] = note.note;
- _track[track].arpeggioNotes[1] = note.note + ex;
- _track[track].arpeggioNotes[2] = note.note + ey;
- }
+ byte trackNote = _module.periodToNote(_track[track].period);
+ _track[track].arpeggioNotes[0] = trackNote;
+ _track[track].arpeggioNotes[1] = trackNote + ex;
+ _track[track].arpeggioNotes[2] = trackNote + ey;
}
break;
case 0x1:
diff --git a/audio/module.mk b/audio/module.mk
index 4e1c031c83..9e002d57ba 100644
--- a/audio/module.mk
+++ b/audio/module.mk
@@ -1,6 +1,7 @@
MODULE := audio
MODULE_OBJS := \
+ adlib.o \
audiostream.o \
fmopl.o \
mididrv.o \
@@ -9,11 +10,14 @@ MODULE_OBJS := \
midiparser_xmidi.o \
midiparser.o \
midiplayer.o \
+ miles_adlib.o \
+ miles_mt32.o \
mixer.o \
mpu401.o \
musicplugin.o \
null.o \
timestamp.o \
+ decoders/3do.o \
decoders/aac.o \
decoders/adpcm.o \
decoders/aiff.o \
@@ -36,7 +40,6 @@ MODULE_OBJS := \
mods/rjp1.o \
mods/soundfx.o \
mods/tfmx.o \
- softsynth/adlib.o \
softsynth/cms.o \
softsynth/opl/dbopl.o \
softsynth/opl/dosbox.o \
@@ -55,6 +58,11 @@ MODULE_OBJS := \
softsynth/sid.o \
softsynth/wave6581.o
+ifdef USE_ALSA
+MODULE_OBJS += \
+ alsa_opl.o
+endif
+
ifndef USE_ARM_SOUND_ASM
MODULE_OBJS += \
rate.o
diff --git a/audio/softsynth/mt32/Analog.cpp b/audio/softsynth/mt32/Analog.cpp
new file mode 100644
index 0000000000..8ac28e401a
--- /dev/null
+++ b/audio/softsynth/mt32/Analog.cpp
@@ -0,0 +1,348 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+//#include <cstring>
+#include "Analog.h"
+
+namespace MT32Emu {
+
+#if MT32EMU_USE_FLOAT_SAMPLES
+
+/* FIR approximation of the overall impulse response of the cascade composed of the sample & hold circuit and the low pass filter
+ * of the MT-32 first generation.
+ * The coefficients below are found by windowing the inverse DFT of the 1024 pin frequency response converted to the minimum phase.
+ * The frequency response of the LPF is computed directly, the effect of the S&H is approximated by multiplying the LPF frequency
+ * response by the corresponding sinc. Although, the LPF has DC gain of 3.2, we ignore this in the emulation and use normalised model.
+ * The peak gain of the normalised cascade appears about 1.7 near 11.8 kHz. Relative error doesn't exceed 1% for the frequencies
+ * below 12.5 kHz. In the higher frequency range, the relative error is below 8%. Peak error value is at 16 kHz.
+ */
+static const float COARSE_LPF_TAPS_MT32[] = {
+ 1.272473681f, -0.220267785f, -0.158039905f, 0.179603785f, -0.111484097f, 0.054137498f, -0.023518029f, 0.010997169f, -0.006935698f
+};
+
+// Similar approximation for new MT-32 and CM-32L/LAPC-I LPF. As the voltage controlled amplifier was introduced, LPF has unity DC gain.
+// The peak gain value shifted towards higher frequencies and a bit higher about 1.83 near 13 kHz.
+static const float COARSE_LPF_TAPS_CM32L[] = {
+ 1.340615635f, -0.403331694f, 0.036005517f, 0.066156844f, -0.069672532f, 0.049563806f, -0.031113416f, 0.019169774f, -0.012421368f
+};
+
+#else
+
+static const unsigned int COARSE_LPF_FRACTION_BITS = 14;
+
+// Integer versions of the FIRs above multiplied by (1 << 14) and rounded.
+static const SampleEx COARSE_LPF_TAPS_MT32[] = {
+ 20848, -3609, -2589, 2943, -1827, 887, -385, 180, -114
+};
+
+static const SampleEx COARSE_LPF_TAPS_CM32L[] = {
+ 21965, -6608, 590, 1084, -1142, 812, -510, 314, -204
+};
+
+#endif
+
+/* Combined FIR that both approximates the impulse response of the analogue circuits of sample & hold and the low pass filter
+ * in the audible frequency range (below 20 kHz) and attenuates unwanted mirror spectra above 28 kHz as well. It is a polyphase
+ * filter intended for resampling the signal to 48 kHz yet for applying high frequency boost.
+ * As with the filter above, the analogue LPF frequency response is obtained for 1536 pin grid for range up to 96 kHz and multiplied
+ * by the corresponding sinc. The result is further squared, windowed and passed to generalised Parks-McClellan routine as a desired response.
+ * Finally, the minimum phase factor is found that's essentially the coefficients below.
+ * Relative error in the audible frequency range doesn't exceed 0.0006%, attenuation in the stopband is better than 100 dB.
+ * This level of performance makes it nearly bit-accurate for standard 16-bit sample resolution.
+ */
+
+// FIR version for MT-32 first generation.
+static const float ACCURATE_LPF_TAPS_MT32[] = {
+ 0.003429281f, 0.025929869f, 0.096587777f, 0.228884848f, 0.372413431f, 0.412386503f, 0.263980018f,
+ -0.014504962f, -0.237394528f, -0.257043496f, -0.103436603f, 0.063996095f, 0.124562333f, 0.083703206f,
+ 0.013921662f, -0.033475018f, -0.046239712f, -0.029310921f, 0.00126585f, 0.021060961f, 0.017925605f,
+ 0.003559874f, -0.005105248f, -0.005647917f, -0.004157918f, -0.002065664f, 0.00158747f, 0.003762585f,
+ 0.001867137f, -0.001090028f, -0.001433979f, -0.00022367f, 4.34308E-05f, -0.000247827f, 0.000157087f,
+ 0.000605823f, 0.000197317f, -0.000370511f, -0.000261202f, 9.96069E-05f, 9.85073E-05f, -5.28754E-05f,
+ -1.00912E-05f, 7.69943E-05f, 2.03162E-05f, -5.67967E-05f, -3.30637E-05f, 1.61958E-05f, 1.73041E-05f
+};
+
+// FIR version for new MT-32 and CM-32L/LAPC-I.
+static const float ACCURATE_LPF_TAPS_CM32L[] = {
+ 0.003917452f, 0.030693861f, 0.116424199f, 0.275101674f, 0.43217361f, 0.431247894f, 0.183255659f,
+ -0.174955671f, -0.354240244f, -0.212401714f, 0.072259178f, 0.204655344f, 0.108336211f, -0.039099027f,
+ -0.075138174f, -0.026261906f, 0.00582663f, 0.003052193f, 0.00613657f, 0.017017951f, 0.008732535f,
+ -0.011027427f, -0.012933664f, 0.001158097f, 0.006765958f, 0.00046778f, -0.002191106f, 0.001561017f,
+ 0.001842871f, -0.001996876f, -0.002315836f, 0.000980965f, 0.001817454f, -0.000243272f, -0.000972848f,
+ 0.000149941f, 0.000498886f, -0.000204436f, -0.000347415f, 0.000142386f, 0.000249137f, -4.32946E-05f,
+ -0.000131231f, 3.88575E-07f, 4.48813E-05f, -1.31906E-06f, -1.03499E-05f, 7.71971E-06f, 2.86721E-06f
+};
+
+// According to the CM-64 PCB schematic, there is a difference in the values of the LPF entrance resistors for the reverb and non-reverb channels.
+// This effectively results in non-unity LPF DC gain for the reverb channel of 0.68 while the LPF has unity DC gain for the LA32 output channels.
+// In emulation, the reverb output gain is multiplied by this factor to compensate for the LPF gain difference.
+static const float CM32L_REVERB_TO_LA32_ANALOG_OUTPUT_GAIN_FACTOR = 0.68f;
+
+static const unsigned int OUTPUT_GAIN_FRACTION_BITS = 8;
+static const float OUTPUT_GAIN_MULTIPLIER = float(1 << OUTPUT_GAIN_FRACTION_BITS);
+
+static const unsigned int COARSE_LPF_DELAY_LINE_LENGTH = 8; // Must be a power of 2
+static const unsigned int ACCURATE_LPF_DELAY_LINE_LENGTH = 16; // Must be a power of 2
+static const unsigned int ACCURATE_LPF_NUMBER_OF_PHASES = 3; // Upsampling factor
+static const unsigned int ACCURATE_LPF_PHASE_INCREMENT_REGULAR = 2; // Downsampling factor
+static const unsigned int ACCURATE_LPF_PHASE_INCREMENT_OVERSAMPLED = 1; // No downsampling
+static const Bit32u ACCURATE_LPF_DELTAS_REGULAR[][ACCURATE_LPF_NUMBER_OF_PHASES] = { { 0, 0, 0 }, { 1, 1, 0 }, { 1, 2, 1 } };
+static const Bit32u ACCURATE_LPF_DELTAS_OVERSAMPLED[][ACCURATE_LPF_NUMBER_OF_PHASES] = { { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 1 } };
+
+class AbstractLowPassFilter {
+public:
+ static AbstractLowPassFilter &createLowPassFilter(AnalogOutputMode mode, bool oldMT32AnalogLPF);
+ static void muteRingBuffer(SampleEx *ringBuffer, unsigned int length);
+
+ virtual ~AbstractLowPassFilter() {}
+ virtual SampleEx process(SampleEx sample) = 0;
+ virtual bool hasNextSample() const;
+ virtual unsigned int getOutputSampleRate() const;
+ virtual unsigned int estimateInSampleCount(unsigned int outSamples) const;
+ virtual void addPositionIncrement(unsigned int) {}
+};
+
+class NullLowPassFilter : public AbstractLowPassFilter {
+public:
+ SampleEx process(SampleEx sample);
+};
+
+class CoarseLowPassFilter : public AbstractLowPassFilter {
+private:
+ const SampleEx * const LPF_TAPS;
+ SampleEx ringBuffer[COARSE_LPF_DELAY_LINE_LENGTH];
+ unsigned int ringBufferPosition;
+
+public:
+ CoarseLowPassFilter(bool oldMT32AnalogLPF);
+ SampleEx process(SampleEx sample);
+};
+
+class AccurateLowPassFilter : public AbstractLowPassFilter {
+private:
+ const float * const LPF_TAPS;
+ const Bit32u (* const deltas)[ACCURATE_LPF_NUMBER_OF_PHASES];
+ const unsigned int phaseIncrement;
+ const unsigned int outputSampleRate;
+
+ SampleEx ringBuffer[ACCURATE_LPF_DELAY_LINE_LENGTH];
+ unsigned int ringBufferPosition;
+ unsigned int phase;
+
+public:
+ AccurateLowPassFilter(bool oldMT32AnalogLPF, bool oversample);
+ SampleEx process(SampleEx sample);
+ bool hasNextSample() const;
+ unsigned int getOutputSampleRate() const;
+ unsigned int estimateInSampleCount(unsigned int outSamples) const;
+ void addPositionIncrement(unsigned int positionIncrement);
+};
+
+Analog::Analog(const AnalogOutputMode mode, const ControlROMFeatureSet *controlROMFeatures) :
+ leftChannelLPF(AbstractLowPassFilter::createLowPassFilter(mode, controlROMFeatures->isOldMT32AnalogLPF())),
+ rightChannelLPF(AbstractLowPassFilter::createLowPassFilter(mode, controlROMFeatures->isOldMT32AnalogLPF())),
+ synthGain(0),
+ reverbGain(0)
+{}
+
+Analog::~Analog() {
+ delete &leftChannelLPF;
+ delete &rightChannelLPF;
+}
+
+void Analog::process(Sample **outStream, const Sample *nonReverbLeft, const Sample *nonReverbRight, const Sample *reverbDryLeft, const Sample *reverbDryRight, const Sample *reverbWetLeft, const Sample *reverbWetRight, Bit32u outLength) {
+ if (outStream == NULL) {
+ leftChannelLPF.addPositionIncrement(outLength);
+ rightChannelLPF.addPositionIncrement(outLength);
+ return;
+ }
+
+ while (0 < (outLength--)) {
+ SampleEx outSampleL;
+ SampleEx outSampleR;
+
+ if (leftChannelLPF.hasNextSample()) {
+ outSampleL = leftChannelLPF.process(0);
+ outSampleR = rightChannelLPF.process(0);
+ } else {
+ SampleEx inSampleL = ((SampleEx)*(nonReverbLeft++) + (SampleEx)*(reverbDryLeft++)) * synthGain + (SampleEx)*(reverbWetLeft++) * reverbGain;
+ SampleEx inSampleR = ((SampleEx)*(nonReverbRight++) + (SampleEx)*(reverbDryRight++)) * synthGain + (SampleEx)*(reverbWetRight++) * reverbGain;
+
+#if !MT32EMU_USE_FLOAT_SAMPLES
+ inSampleL >>= OUTPUT_GAIN_FRACTION_BITS;
+ inSampleR >>= OUTPUT_GAIN_FRACTION_BITS;
+#endif
+
+ outSampleL = leftChannelLPF.process(inSampleL);
+ outSampleR = rightChannelLPF.process(inSampleR);
+ }
+
+ *((*outStream)++) = Synth::clipSampleEx(outSampleL);
+ *((*outStream)++) = Synth::clipSampleEx(outSampleR);
+ }
+}
+
+unsigned int Analog::getOutputSampleRate() const {
+ return leftChannelLPF.getOutputSampleRate();
+}
+
+Bit32u Analog::getDACStreamsLength(Bit32u outputLength) const {
+ return leftChannelLPF.estimateInSampleCount(outputLength);
+}
+
+void Analog::setSynthOutputGain(float useSynthGain) {
+#if MT32EMU_USE_FLOAT_SAMPLES
+ synthGain = useSynthGain;
+#else
+ if (OUTPUT_GAIN_MULTIPLIER < useSynthGain) useSynthGain = OUTPUT_GAIN_MULTIPLIER;
+ synthGain = SampleEx(useSynthGain * OUTPUT_GAIN_MULTIPLIER);
+#endif
+}
+
+void Analog::setReverbOutputGain(float useReverbGain, bool mt32ReverbCompatibilityMode) {
+ if (!mt32ReverbCompatibilityMode) useReverbGain *= CM32L_REVERB_TO_LA32_ANALOG_OUTPUT_GAIN_FACTOR;
+#if MT32EMU_USE_FLOAT_SAMPLES
+ reverbGain = useReverbGain;
+#else
+ if (OUTPUT_GAIN_MULTIPLIER < useReverbGain) useReverbGain = OUTPUT_GAIN_MULTIPLIER;
+ reverbGain = SampleEx(useReverbGain * OUTPUT_GAIN_MULTIPLIER);
+#endif
+}
+
+AbstractLowPassFilter &AbstractLowPassFilter::createLowPassFilter(AnalogOutputMode mode, bool oldMT32AnalogLPF) {
+ switch (mode) {
+ case AnalogOutputMode_COARSE:
+ return *new CoarseLowPassFilter(oldMT32AnalogLPF);
+ case AnalogOutputMode_ACCURATE:
+ return *new AccurateLowPassFilter(oldMT32AnalogLPF, false);
+ case AnalogOutputMode_OVERSAMPLED:
+ return *new AccurateLowPassFilter(oldMT32AnalogLPF, true);
+ default:
+ return *new NullLowPassFilter;
+ }
+}
+
+void AbstractLowPassFilter::muteRingBuffer(SampleEx *ringBuffer, unsigned int length) {
+
+#if MT32EMU_USE_FLOAT_SAMPLES
+
+ SampleEx *p = ringBuffer;
+ while (length--) {
+ *(p++) = 0.0f;
+ }
+
+#else
+
+ memset(ringBuffer, 0, length * sizeof(SampleEx));
+
+#endif
+
+}
+
+bool AbstractLowPassFilter::hasNextSample() const {
+ return false;
+}
+
+unsigned int AbstractLowPassFilter::getOutputSampleRate() const {
+ return SAMPLE_RATE;
+}
+
+unsigned int AbstractLowPassFilter::estimateInSampleCount(unsigned int outSamples) const {
+ return outSamples;
+}
+
+SampleEx NullLowPassFilter::process(const SampleEx inSample) {
+ return inSample;
+}
+
+CoarseLowPassFilter::CoarseLowPassFilter(bool oldMT32AnalogLPF) :
+ LPF_TAPS(oldMT32AnalogLPF ? COARSE_LPF_TAPS_MT32 : COARSE_LPF_TAPS_CM32L),
+ ringBufferPosition(0)
+{
+ muteRingBuffer(ringBuffer, COARSE_LPF_DELAY_LINE_LENGTH);
+}
+
+SampleEx CoarseLowPassFilter::process(const SampleEx inSample) {
+ static const unsigned int DELAY_LINE_MASK = COARSE_LPF_DELAY_LINE_LENGTH - 1;
+
+ SampleEx sample = LPF_TAPS[COARSE_LPF_DELAY_LINE_LENGTH] * ringBuffer[ringBufferPosition];
+ ringBuffer[ringBufferPosition] = Synth::clipSampleEx(inSample);
+
+ for (unsigned int i = 0; i < COARSE_LPF_DELAY_LINE_LENGTH; i++) {
+ sample += LPF_TAPS[i] * ringBuffer[(i + ringBufferPosition) & DELAY_LINE_MASK];
+ }
+
+ ringBufferPosition = (ringBufferPosition - 1) & DELAY_LINE_MASK;
+
+#if !MT32EMU_USE_FLOAT_SAMPLES
+ sample >>= COARSE_LPF_FRACTION_BITS;
+#endif
+
+ return sample;
+}
+
+AccurateLowPassFilter::AccurateLowPassFilter(const bool oldMT32AnalogLPF, const bool oversample) :
+ LPF_TAPS(oldMT32AnalogLPF ? ACCURATE_LPF_TAPS_MT32 : ACCURATE_LPF_TAPS_CM32L),
+ deltas(oversample ? ACCURATE_LPF_DELTAS_OVERSAMPLED : ACCURATE_LPF_DELTAS_REGULAR),
+ phaseIncrement(oversample ? ACCURATE_LPF_PHASE_INCREMENT_OVERSAMPLED : ACCURATE_LPF_PHASE_INCREMENT_REGULAR),
+ outputSampleRate(SAMPLE_RATE * ACCURATE_LPF_NUMBER_OF_PHASES / phaseIncrement),
+ ringBufferPosition(0),
+ phase(0)
+{
+ muteRingBuffer(ringBuffer, ACCURATE_LPF_DELAY_LINE_LENGTH);
+}
+
+SampleEx AccurateLowPassFilter::process(const SampleEx inSample) {
+ static const unsigned int DELAY_LINE_MASK = ACCURATE_LPF_DELAY_LINE_LENGTH - 1;
+
+ float sample = (phase == 0) ? LPF_TAPS[ACCURATE_LPF_DELAY_LINE_LENGTH * ACCURATE_LPF_NUMBER_OF_PHASES] * ringBuffer[ringBufferPosition] : 0.0f;
+ if (!hasNextSample()) {
+ ringBuffer[ringBufferPosition] = inSample;
+ }
+
+ for (unsigned int tapIx = phase, delaySampleIx = 0; delaySampleIx < ACCURATE_LPF_DELAY_LINE_LENGTH; delaySampleIx++, tapIx += ACCURATE_LPF_NUMBER_OF_PHASES) {
+ sample += LPF_TAPS[tapIx] * ringBuffer[(delaySampleIx + ringBufferPosition) & DELAY_LINE_MASK];
+ }
+
+ phase += phaseIncrement;
+ if (ACCURATE_LPF_NUMBER_OF_PHASES <= phase) {
+ phase -= ACCURATE_LPF_NUMBER_OF_PHASES;
+ ringBufferPosition = (ringBufferPosition - 1) & DELAY_LINE_MASK;
+ }
+
+ return SampleEx(ACCURATE_LPF_NUMBER_OF_PHASES * sample);
+}
+
+bool AccurateLowPassFilter::hasNextSample() const {
+ return phaseIncrement <= phase;
+}
+
+unsigned int AccurateLowPassFilter::getOutputSampleRate() const {
+ return outputSampleRate;
+}
+
+unsigned int AccurateLowPassFilter::estimateInSampleCount(unsigned int outSamples) const {
+ Bit32u cycleCount = outSamples / ACCURATE_LPF_NUMBER_OF_PHASES;
+ Bit32u remainder = outSamples - cycleCount * ACCURATE_LPF_NUMBER_OF_PHASES;
+ return cycleCount * phaseIncrement + deltas[remainder][phase];
+}
+
+void AccurateLowPassFilter::addPositionIncrement(const unsigned int positionIncrement) {
+ phase = (phase + positionIncrement * phaseIncrement) % ACCURATE_LPF_NUMBER_OF_PHASES;
+}
+
+}
diff --git a/audio/softsynth/mt32/Analog.h b/audio/softsynth/mt32/Analog.h
new file mode 100644
index 0000000000..a48db72485
--- /dev/null
+++ b/audio/softsynth/mt32/Analog.h
@@ -0,0 +1,57 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MT32EMU_ANALOG_H
+#define MT32EMU_ANALOG_H
+
+#include "mt32emu.h"
+
+namespace MT32Emu {
+
+class AbstractLowPassFilter;
+
+/* Analog class is dedicated to perform fair emulation of analogue circuitry of hardware units that is responsible
+ * for processing output signal after the DAC. It appears that the analogue circuit labeled "LPF" on the schematic
+ * also applies audible changes to the signal spectra. There is a significant boost of higher frequencies observed
+ * aside from quite poor attenuation of the mirror spectra above 16 kHz which is due to a relatively low filter order.
+ *
+ * As the final mixing of multiplexed output signal is performed after the DAC, this function is migrated here from Synth.
+ * Saying precisely, mixing is performed within the LPF as the entrance resistors are actually components of a LPF
+ * designed using the multiple feedback topology. Nevertheless, the schematic separates them.
+ */
+class Analog {
+public:
+ Analog(AnalogOutputMode mode, const ControlROMFeatureSet *controlROMFeatures);
+ ~Analog();
+ void process(Sample **outStream, const Sample *nonReverbLeft, const Sample *nonReverbRight, const Sample *reverbDryLeft, const Sample *reverbDryRight, const Sample *reverbWetLeft, const Sample *reverbWetRight, const Bit32u outLength);
+ unsigned int getOutputSampleRate() const;
+ Bit32u getDACStreamsLength(Bit32u outputLength) const;
+ void setSynthOutputGain(float synthGain);
+ void setReverbOutputGain(float reverbGain, bool mt32ReverbCompatibilityMode);
+
+private:
+ AbstractLowPassFilter &leftChannelLPF;
+ AbstractLowPassFilter &rightChannelLPF;
+ SampleEx synthGain;
+ SampleEx reverbGain;
+
+ Analog(Analog &);
+};
+
+}
+
+#endif
diff --git a/audio/softsynth/mt32/BReverbModel.cpp b/audio/softsynth/mt32/BReverbModel.cpp
index 37b3e9670d..5e02db8f99 100644
--- a/audio/softsynth/mt32/BReverbModel.cpp
+++ b/audio/softsynth/mt32/BReverbModel.cpp
@@ -15,7 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-//#include <memory.h>
+//#include <cstring>
#include "mt32emu.h"
#include "BReverbModel.h"
@@ -501,9 +501,9 @@ void BReverbModel::process(const Sample *inLeft, const Sample *inRight, Sample *
* Analysing of the algorithm suggests that the overflow is most probable when the combs output is added below.
* So, despite this isn't actually accurate, we only add the check here for performance reasons.
*/
- Sample outSample = Synth::clipBit16s(Synth::clipBit16s(Synth::clipBit16s(Synth::clipBit16s((Bit32s)outL1 + Bit32s(outL1 >> 1)) + (Bit32s)outL2) + Bit32s(outL2 >> 1)) + (Bit32s)outL3);
+ Sample outSample = Synth::clipSampleEx(Synth::clipSampleEx(Synth::clipSampleEx(Synth::clipSampleEx((SampleEx)outL1 + SampleEx(outL1 >> 1)) + (SampleEx)outL2) + SampleEx(outL2 >> 1)) + (SampleEx)outL3);
#else
- Sample outSample = Synth::clipBit16s((Bit32s)outL1 + Bit32s(outL1 >> 1) + (Bit32s)outL2 + Bit32s(outL2 >> 1) + (Bit32s)outL3);
+ Sample outSample = Synth::clipSampleEx((SampleEx)outL1 + SampleEx(outL1 >> 1) + (SampleEx)outL2 + SampleEx(outL2 >> 1) + (SampleEx)outL3);
#endif
*(outLeft++) = weirdMul(outSample, wetLevel, 0xFF);
}
@@ -515,9 +515,9 @@ void BReverbModel::process(const Sample *inLeft, const Sample *inRight, Sample *
Sample outSample = 1.5f * (outR1 + outR2) + outR3;
#elif MT32EMU_BOSS_REVERB_PRECISE_MODE
// See the note above for the left channel output.
- Sample outSample = Synth::clipBit16s(Synth::clipBit16s(Synth::clipBit16s(Synth::clipBit16s((Bit32s)outR1 + Bit32s(outR1 >> 1)) + (Bit32s)outR2) + Bit32s(outR2 >> 1)) + (Bit32s)outR3);
+ Sample outSample = Synth::clipSampleEx(Synth::clipSampleEx(Synth::clipSampleEx(Synth::clipSampleEx((SampleEx)outR1 + SampleEx(outR1 >> 1)) + (SampleEx)outR2) + SampleEx(outR2 >> 1)) + (SampleEx)outR3);
#else
- Sample outSample = Synth::clipBit16s((Bit32s)outR1 + Bit32s(outR1 >> 1) + (Bit32s)outR2 + Bit32s(outR2 >> 1) + (Bit32s)outR3);
+ Sample outSample = Synth::clipSampleEx((SampleEx)outR1 + SampleEx(outR1 >> 1) + (SampleEx)outR2 + SampleEx(outR2 >> 1) + (SampleEx)outR3);
#endif
*(outRight++) = weirdMul(outSample, wetLevel, 0xFF);
}
diff --git a/audio/softsynth/mt32/BReverbModel.h b/audio/softsynth/mt32/BReverbModel.h
index 9b840900c3..764daf1a9e 100644
--- a/audio/softsynth/mt32/BReverbModel.h
+++ b/audio/softsynth/mt32/BReverbModel.h
@@ -95,7 +95,6 @@ class BReverbModel {
const bool tapDelayMode;
Bit32u dryAmp;
Bit32u wetLevel;
- void mute();
static const BReverbSettings &getCM32L_LAPCSettings(const ReverbMode mode);
static const BReverbSettings &getMT32Settings(const ReverbMode mode);
@@ -107,6 +106,7 @@ public:
void open();
// May be called multiple times without an open() in between.
void close();
+ void mute();
void setParameters(Bit8u time, Bit8u level);
void process(const Sample *inLeft, const Sample *inRight, Sample *outLeft, Sample *outRight, unsigned long numSamples);
bool isActive() const;
diff --git a/audio/softsynth/mt32/LA32FloatWaveGenerator.cpp b/audio/softsynth/mt32/LA32FloatWaveGenerator.cpp
index 9265d80c88..42d820ebad 100644
--- a/audio/softsynth/mt32/LA32FloatWaveGenerator.cpp
+++ b/audio/softsynth/mt32/LA32FloatWaveGenerator.cpp
@@ -18,7 +18,7 @@
//#include <cmath>
#include "mt32emu.h"
#include "mmath.h"
-#include "LA32FloatWaveGenerator.h"
+#include "internals.h"
namespace MT32Emu {
diff --git a/audio/softsynth/mt32/LA32Ramp.cpp b/audio/softsynth/mt32/LA32Ramp.cpp
index 454612c842..2b31a330d2 100644
--- a/audio/softsynth/mt32/LA32Ramp.cpp
+++ b/audio/softsynth/mt32/LA32Ramp.cpp
@@ -50,8 +50,8 @@ We haven't fully explored:
//#include <cmath>
#include "mt32emu.h"
-#include "LA32Ramp.h"
#include "mmath.h"
+#include "internals.h"
namespace MT32Emu {
diff --git a/audio/softsynth/mt32/LA32WaveGenerator.cpp b/audio/softsynth/mt32/LA32WaveGenerator.cpp
index 7ac7cc6aaa..765f75fa61 100644
--- a/audio/softsynth/mt32/LA32WaveGenerator.cpp
+++ b/audio/softsynth/mt32/LA32WaveGenerator.cpp
@@ -15,15 +15,15 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-//#include <cmath>
-#include "mt32emu.h"
-#include "mmath.h"
-#include "LA32WaveGenerator.h"
-
#if MT32EMU_USE_FLOAT_SAMPLES
#include "LA32FloatWaveGenerator.cpp"
#else
+//#include <cmath>
+#include "mt32emu.h"
+#include "mmath.h"
+#include "internals.h"
+
namespace MT32Emu {
static const Bit32u SINE_SEGMENT_RELATIVE_LENGTH = 1 << 18;
diff --git a/audio/softsynth/mt32/MemoryRegion.h b/audio/softsynth/mt32/MemoryRegion.h
new file mode 100644
index 0000000000..c0cb041e11
--- /dev/null
+++ b/audio/softsynth/mt32/MemoryRegion.h
@@ -0,0 +1,124 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MT32EMU_MEMORY_REGION_H
+#define MT32EMU_MEMORY_REGION_H
+
+namespace MT32Emu {
+
+enum MemoryRegionType {
+ MR_PatchTemp, MR_RhythmTemp, MR_TimbreTemp, MR_Patches, MR_Timbres, MR_System, MR_Display, MR_Reset
+};
+
+class MemoryRegion {
+private:
+ Synth *synth;
+ Bit8u *realMemory;
+ Bit8u *maxTable;
+public:
+ MemoryRegionType type;
+ Bit32u startAddr, entrySize, entries;
+
+ MemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable, MemoryRegionType useType, Bit32u useStartAddr, Bit32u useEntrySize, Bit32u useEntries) {
+ synth = useSynth;
+ realMemory = useRealMemory;
+ maxTable = useMaxTable;
+ type = useType;
+ startAddr = useStartAddr;
+ entrySize = useEntrySize;
+ entries = useEntries;
+ }
+ int lastTouched(Bit32u addr, Bit32u len) const {
+ return (offset(addr) + len - 1) / entrySize;
+ }
+ int firstTouchedOffset(Bit32u addr) const {
+ return offset(addr) % entrySize;
+ }
+ int firstTouched(Bit32u addr) const {
+ return offset(addr) / entrySize;
+ }
+ Bit32u regionEnd() const {
+ return startAddr + entrySize * entries;
+ }
+ bool contains(Bit32u addr) const {
+ return addr >= startAddr && addr < regionEnd();
+ }
+ int offset(Bit32u addr) const {
+ return addr - startAddr;
+ }
+ Bit32u getClampedLen(Bit32u addr, Bit32u len) const {
+ if (addr + len > regionEnd())
+ return regionEnd() - addr;
+ return len;
+ }
+ Bit32u next(Bit32u addr, Bit32u len) const {
+ if (addr + len > regionEnd()) {
+ return regionEnd() - addr;
+ }
+ return 0;
+ }
+ Bit8u getMaxValue(int off) const {
+ if (maxTable == NULL)
+ return 0xFF;
+ return maxTable[off % entrySize];
+ }
+ Bit8u *getRealMemory() const {
+ return realMemory;
+ }
+ bool isReadable() const {
+ return getRealMemory() != NULL;
+ }
+ void read(unsigned int entry, unsigned int off, Bit8u *dst, unsigned int len) const;
+ void write(unsigned int entry, unsigned int off, const Bit8u *src, unsigned int len, bool init = false) const;
+};
+
+class PatchTempMemoryRegion : public MemoryRegion {
+public:
+ PatchTempMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_PatchTemp, MT32EMU_MEMADDR(0x030000), sizeof(MemParams::PatchTemp), 9) {}
+};
+class RhythmTempMemoryRegion : public MemoryRegion {
+public:
+ RhythmTempMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_RhythmTemp, MT32EMU_MEMADDR(0x030110), sizeof(MemParams::RhythmTemp), 85) {}
+};
+class TimbreTempMemoryRegion : public MemoryRegion {
+public:
+ TimbreTempMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_TimbreTemp, MT32EMU_MEMADDR(0x040000), sizeof(TimbreParam), 8) {}
+};
+class PatchesMemoryRegion : public MemoryRegion {
+public:
+ PatchesMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_Patches, MT32EMU_MEMADDR(0x050000), sizeof(PatchParam), 128) {}
+};
+class TimbresMemoryRegion : public MemoryRegion {
+public:
+ TimbresMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_Timbres, MT32EMU_MEMADDR(0x080000), sizeof(MemParams::PaddedTimbre), 64 + 64 + 64 + 64) {}
+};
+class SystemMemoryRegion : public MemoryRegion {
+public:
+ SystemMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_System, MT32EMU_MEMADDR(0x100000), sizeof(MemParams::System), 1) {}
+};
+class DisplayMemoryRegion : public MemoryRegion {
+public:
+ DisplayMemoryRegion(Synth *useSynth) : MemoryRegion(useSynth, NULL, NULL, MR_Display, MT32EMU_MEMADDR(0x200000), MAX_SYSEX_SIZE - 1, 1) {}
+};
+class ResetMemoryRegion : public MemoryRegion {
+public:
+ ResetMemoryRegion(Synth *useSynth) : MemoryRegion(useSynth, NULL, NULL, MR_Reset, MT32EMU_MEMADDR(0x7F0000), 0x3FFF, 1) {}
+};
+
+}
+
+#endif
diff --git a/audio/softsynth/mt32/MidiEventQueue.h b/audio/softsynth/mt32/MidiEventQueue.h
new file mode 100644
index 0000000000..b1948c5f8e
--- /dev/null
+++ b/audio/softsynth/mt32/MidiEventQueue.h
@@ -0,0 +1,67 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MT32EMU_MIDI_EVENT_QUEUE_H
+#define MT32EMU_MIDI_EVENT_QUEUE_H
+
+namespace MT32Emu {
+
+/**
+ * Used to safely store timestamped MIDI events in a local queue.
+ */
+struct MidiEvent {
+ Bit32u shortMessageData;
+ const Bit8u *sysexData;
+ Bit32u sysexLength;
+ Bit32u timestamp;
+
+ ~MidiEvent();
+ void setShortMessage(Bit32u shortMessageData, Bit32u timestamp);
+ void setSysex(const Bit8u *sysexData, Bit32u sysexLength, Bit32u timestamp);
+};
+
+/**
+ * Simple queue implementation using a ring buffer to store incoming MIDI event before the synth actually processes it.
+ * It is intended to:
+ * - get rid of prerenderer while retaining graceful partial abortion
+ * - add fair emulation of the MIDI interface delays
+ * - extend the synth interface with the default implementation of a typical rendering loop.
+ * THREAD SAFETY:
+ * It is safe to use either in a single thread environment or when there are only two threads - one performs only reading
+ * and one performs only writing. More complicated usage requires external synchronisation.
+ */
+class MidiEventQueue {
+private:
+ MidiEvent * const ringBuffer;
+ const Bit32u ringBufferMask;
+ volatile Bit32u startPosition;
+ volatile Bit32u endPosition;
+
+public:
+ MidiEventQueue(Bit32u ringBufferSize = DEFAULT_MIDI_EVENT_QUEUE_SIZE); // Must be a power of 2
+ ~MidiEventQueue();
+ void reset();
+ bool pushShortMessage(Bit32u shortMessageData, Bit32u timestamp);
+ bool pushSysex(const Bit8u *sysexData, Bit32u sysexLength, Bit32u timestamp);
+ const MidiEvent *peekMidiEvent();
+ void dropMidiEvent();
+ bool isFull() const;
+};
+
+}
+
+#endif
diff --git a/audio/softsynth/mt32/Part.cpp b/audio/softsynth/mt32/Part.cpp
index d92473b5db..cffc3ed744 100644
--- a/audio/softsynth/mt32/Part.cpp
+++ b/audio/softsynth/mt32/Part.cpp
@@ -19,6 +19,7 @@
//#include <cstring>
#include "mt32emu.h"
+#include "internals.h"
#include "PartialManager.h"
namespace MT32Emu {
diff --git a/audio/softsynth/mt32/Partial.cpp b/audio/softsynth/mt32/Partial.cpp
index 7dcc6e945a..7348087509 100644
--- a/audio/softsynth/mt32/Partial.cpp
+++ b/audio/softsynth/mt32/Partial.cpp
@@ -21,6 +21,7 @@
#include "mt32emu.h"
#include "mmath.h"
+#include "internals.h"
namespace MT32Emu {
@@ -312,8 +313,8 @@ bool Partial::produceOutput(Sample *leftBuf, Sample *rightBuf, unsigned long len
// Though, it is unknown whether this overflow is exploited somewhere.
Sample leftOut = Sample((sample * leftPanValue) >> 8);
Sample rightOut = Sample((sample * rightPanValue) >> 8);
- *leftBuf = Synth::clipBit16s((Bit32s)*leftBuf + (Bit32s)leftOut);
- *rightBuf = Synth::clipBit16s((Bit32s)*rightBuf + (Bit32s)rightOut);
+ *leftBuf = Synth::clipSampleEx((SampleEx)*leftBuf + (SampleEx)leftOut);
+ *rightBuf = Synth::clipSampleEx((SampleEx)*rightBuf + (SampleEx)rightOut);
leftBuf++;
rightBuf++;
#endif
diff --git a/audio/softsynth/mt32/PartialManager.cpp b/audio/softsynth/mt32/PartialManager.cpp
index fe73087581..8ca6e4e3d7 100644
--- a/audio/softsynth/mt32/PartialManager.cpp
+++ b/audio/softsynth/mt32/PartialManager.cpp
@@ -18,6 +18,7 @@
//#include <cstring>
#include "mt32emu.h"
+#include "internals.h"
#include "PartialManager.h"
namespace MT32Emu {
diff --git a/audio/softsynth/mt32/Poly.cpp b/audio/softsynth/mt32/Poly.cpp
index e07ceb4231..badcd8fb96 100644
--- a/audio/softsynth/mt32/Poly.cpp
+++ b/audio/softsynth/mt32/Poly.cpp
@@ -16,6 +16,7 @@
*/
#include "mt32emu.h"
+#include "internals.h"
namespace MT32Emu {
diff --git a/audio/softsynth/mt32/Poly.h b/audio/softsynth/mt32/Poly.h
index 9c6431ce36..e2614369bb 100644
--- a/audio/softsynth/mt32/Poly.h
+++ b/audio/softsynth/mt32/Poly.h
@@ -21,6 +21,7 @@
namespace MT32Emu {
class Part;
+class Partial;
enum PolyState {
POLY_Playing,
diff --git a/audio/softsynth/mt32/ROMInfo.cpp b/audio/softsynth/mt32/ROMInfo.cpp
index eb9622620f..7c0127078b 100644
--- a/audio/softsynth/mt32/ROMInfo.cpp
+++ b/audio/softsynth/mt32/ROMInfo.cpp
@@ -21,8 +21,8 @@
namespace MT32Emu {
static const ROMInfo *getKnownROMInfoFromList(unsigned int index) {
- static const ControlROMFeatureSet MT32_COMPATIBLE(true);
- static const ControlROMFeatureSet CM32L_COMPATIBLE(false);
+ static const ControlROMFeatureSet MT32_COMPATIBLE(true, true);
+ static const ControlROMFeatureSet CM32L_COMPATIBLE(false, false);
// Known ROMs
static const ROMInfo CTRL_MT32_V1_04 = {65536, "5a5cb5a77d7d55ee69657c2f870416daed52dea7", ROMInfo::Control, "ctrl_mt32_1_04", "MT-32 Control v1.04", ROMInfo::Full, NULL, &MT32_COMPATIBLE};
@@ -106,7 +106,6 @@ void ROMImage::freeROMImage(const ROMImage *romImage) {
delete romImage;
}
-
Common::File* ROMImage::getFile() const {
return file;
}
@@ -115,11 +114,17 @@ const ROMInfo* ROMImage::getROMInfo() const {
return romInfo;
}
-ControlROMFeatureSet::ControlROMFeatureSet(bool useDefaultReverbMT32Compatible) : defaultReverbMT32Compatible(useDefaultReverbMT32Compatible) {
-}
+ControlROMFeatureSet::ControlROMFeatureSet(bool useDefaultReverbMT32Compatible, bool useOldMT32AnalogLPF) :
+ defaultReverbMT32Compatible(useDefaultReverbMT32Compatible),
+ oldMT32AnalogLPF(useOldMT32AnalogLPF)
+{}
bool ControlROMFeatureSet::isDefaultReverbMT32Compatible() const {
return defaultReverbMT32Compatible;
}
+bool ControlROMFeatureSet::isOldMT32AnalogLPF() const {
+ return oldMT32AnalogLPF;
+}
+
}
diff --git a/audio/softsynth/mt32/ROMInfo.h b/audio/softsynth/mt32/ROMInfo.h
index cecbb6054f..4682620a15 100644
--- a/audio/softsynth/mt32/ROMInfo.h
+++ b/audio/softsynth/mt32/ROMInfo.h
@@ -77,10 +77,12 @@ public:
struct ControlROMFeatureSet {
private:
unsigned int defaultReverbMT32Compatible : 1;
+ unsigned int oldMT32AnalogLPF : 1;
public:
- ControlROMFeatureSet(bool defaultReverbMT32Compatible);
+ ControlROMFeatureSet(bool defaultReverbMT32Compatible, bool oldMT32AnalogLPF);
bool isDefaultReverbMT32Compatible() const;
+ bool isOldMT32AnalogLPF() const;
};
}
diff --git a/audio/softsynth/mt32/Structures.h b/audio/softsynth/mt32/Structures.h
index 35dcee90d6..4dada3a847 100644
--- a/audio/softsynth/mt32/Structures.h
+++ b/audio/softsynth/mt32/Structures.h
@@ -31,19 +31,6 @@ namespace MT32Emu {
#define MT32EMU_ALIGN_PACKED __attribute__((packed))
#endif
-typedef unsigned int Bit32u;
-typedef signed int Bit32s;
-typedef unsigned short int Bit16u;
-typedef signed short int Bit16s;
-typedef unsigned char Bit8u;
-typedef signed char Bit8s;
-
-#if MT32EMU_USE_FLOAT_SAMPLES
-typedef float Sample;
-#else
-typedef Bit16s Sample;
-#endif
-
// The following structures represent the MT-32's memory
// Since sysex allows this memory to be written to in blocks of bytes,
// we keep this packed so that we can copy data into the various
@@ -184,7 +171,37 @@ struct MemParams {
#pragma pack()
#endif
-struct ControlROMPCMStruct;
+struct ControlROMMap {
+ Bit16u idPos;
+ Bit16u idLen;
+ const char *idBytes;
+ Bit16u pcmTable; // 4 * pcmCount bytes
+ Bit16u pcmCount;
+ Bit16u timbreAMap; // 128 bytes
+ Bit16u timbreAOffset;
+ bool timbreACompressed;
+ Bit16u timbreBMap; // 128 bytes
+ Bit16u timbreBOffset;
+ bool timbreBCompressed;
+ Bit16u timbreRMap; // 2 * timbreRCount bytes
+ Bit16u timbreRCount;
+ Bit16u rhythmSettings; // 4 * rhythmSettingsCount bytes
+ Bit16u rhythmSettingsCount;
+ Bit16u reserveSettings; // 9 bytes
+ Bit16u panSettings; // 8 bytes
+ Bit16u programSettings; // 8 bytes
+ Bit16u rhythmMaxTable; // 4 bytes
+ Bit16u patchMaxTable; // 16 bytes
+ Bit16u systemMaxTable; // 23 bytes
+ Bit16u timbreMaxTable; // 72 bytes
+};
+
+struct ControlROMPCMStruct {
+ Bit8u pos;
+ Bit8u len;
+ Bit8u pitchLSB;
+ Bit8u pitchMSB;
+};
struct PCMWaveEntry {
Bit32u addr;
@@ -216,8 +233,6 @@ struct PatchCache {
const TimbreParam::PartialParam *partialParam;
};
-class Partial; // Forward reference for class defined in partial.h
-
}
#endif
diff --git a/audio/softsynth/mt32/Synth.cpp b/audio/softsynth/mt32/Synth.cpp
index 3bff429875..6df7eb9e31 100644
--- a/audio/softsynth/mt32/Synth.cpp
+++ b/audio/softsynth/mt32/Synth.cpp
@@ -22,12 +22,19 @@
#include "mt32emu.h"
#include "mmath.h"
-#include "PartialManager.h"
+#include "internals.h"
+
+#include "Analog.h"
#include "BReverbModel.h"
-#include "common/debug.h"
+#include "MemoryRegion.h"
+#include "MidiEventQueue.h"
+#include "PartialManager.h"
namespace MT32Emu {
+// MIDI interface data transfer rate in samples. Used to simulate the transfer delay.
+static const double MIDI_DATA_TRANSFER_RATE = (double)SAMPLE_RATE / 31250.0 * 8.0;
+
static const ControlROMMap ControlROMMaps[7] = {
// ID IDc IDbytes PCMmap PCMc tmbrA tmbrAO, tmbrAC tmbrB tmbrBO, tmbrBC tmbrR trC rhythm rhyC rsrv panpot prog rhyMax patMax sysMax timMax
{0x4014, 22, "\000 ver1.04 14 July 87 ", 0x3000, 128, 0x8000, 0x0000, false, 0xC000, 0x4000, false, 0x3200, 30, 0x73A6, 85, 0x57C7, 0x57E2, 0x57D0, 0x5252, 0x525E, 0x526E, 0x520A},
@@ -46,18 +53,15 @@ static inline void advanceStreamPosition(Sample *&stream, Bit32u posDelta) {
}
}
-Bit8u Synth::calcSysexChecksum(const Bit8u *data, Bit32u len, Bit8u checksum) {
+Bit8u Synth::calcSysexChecksum(const Bit8u *data, const Bit32u len, const Bit8u initChecksum) {
+ unsigned int checksum = -initChecksum;
for (unsigned int i = 0; i < len; i++) {
- checksum = checksum + data[i];
+ checksum -= data[i];
}
- checksum = checksum & 0x7f;
- if (checksum) {
- checksum = 0x80 - checksum;
- }
- return checksum;
+ return Bit8u(checksum & 0x7f);
}
-Synth::Synth(ReportHandler *useReportHandler) {
+Synth::Synth(ReportHandler *useReportHandler) : mt32ram(*new MemParams()), mt32default(*new MemParams()) {
isOpen = false;
reverbOverridden = false;
partialCount = DEFAULT_MAX_PARTIALS;
@@ -75,6 +79,7 @@ Synth::Synth(ReportHandler *useReportHandler) {
reverbModels[i] = NULL;
}
reverbModel = NULL;
+ analog = NULL;
setDACInputMode(DACInputMode_NICE);
setMIDIDelayMode(MIDIDelayMode_DELAY_SHORT_MESSAGES_ONLY);
setOutputGain(1.0f);
@@ -92,6 +97,8 @@ Synth::~Synth() {
if (isDefaultReportHandler) {
delete reportHandler;
}
+ delete &mt32ram;
+ delete &mt32default;
}
void ReportHandler::showLCDMessage(const char *data) {
@@ -126,7 +133,7 @@ void Synth::printDebug(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
#if MT32EMU_DEBUG_SAMPLESTAMPS > 0
- reportHandler->printDebug("[%u] ", renderedSampleCount);
+ reportHandler->printDebug("[%u] ", (char *)&renderedSampleCount);
#endif
reportHandler->printDebug(fmt, ap);
va_end(ap);
@@ -211,10 +218,7 @@ MIDIDelayMode Synth::getMIDIDelayMode() const {
void Synth::setOutputGain(float newOutputGain) {
if (newOutputGain < 0.0f) newOutputGain = -newOutputGain;
outputGain = newOutputGain;
-#if !MT32EMU_USE_FLOAT_SAMPLES
- if (256.0f < newOutputGain) newOutputGain = 256.0f;
- effectiveOutputGain = int(newOutputGain * 256.0f);
-#endif
+ if (analog != NULL) analog->setSynthOutputGain(newOutputGain);
}
float Synth::getOutputGain() const {
@@ -224,13 +228,7 @@ float Synth::getOutputGain() const {
void Synth::setReverbOutputGain(float newReverbOutputGain) {
if (newReverbOutputGain < 0.0f) newReverbOutputGain = -newReverbOutputGain;
reverbOutputGain = newReverbOutputGain;
- if (!isMT32ReverbCompatibilityMode()) newReverbOutputGain *= CM32L_REVERB_TO_LA32_ANALOG_OUTPUT_GAIN_FACTOR;
-#if MT32EMU_USE_FLOAT_SAMPLES
- effectiveReverbOutputGain = newReverbOutputGain;
-#else
- if (256.0f < newReverbOutputGain) newReverbOutputGain = 256.0f;
- effectiveReverbOutputGain = int(newReverbOutputGain * 256.0f);
-#endif
+ if (analog != NULL) analog->setReverbOutputGain(newReverbOutputGain, isMT32ReverbCompatibilityMode());
}
float Synth::getReverbOutputGain() const {
@@ -393,7 +391,11 @@ bool Synth::initTimbres(Bit16u mapAddress, Bit16u offset, int count, int startTi
return true;
}
-bool Synth::open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, unsigned int usePartialCount) {
+bool Synth::open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, AnalogOutputMode analogOutputMode) {
+ return open(controlROMImage, pcmROMImage, DEFAULT_MAX_PARTIALS, analogOutputMode);
+}
+
+bool Synth::open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, unsigned int usePartialCount, AnalogOutputMode analogOutputMode) {
if (isOpen) {
return false;
}
@@ -548,6 +550,10 @@ bool Synth::open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, u
midiQueue = new MidiEventQueue();
+ analog = new Analog(analogOutputMode, controlROMFeatures);
+ setOutputGain(outputGain);
+ setReverbOutputGain(reverbOutputGain);
+
isOpen = true;
isEnabled = false;
@@ -565,6 +571,9 @@ void Synth::close(bool forced) {
delete midiQueue;
midiQueue = NULL;
+ delete analog;
+ analog = NULL;
+
delete partialManager;
partialManager = NULL;
@@ -603,16 +612,37 @@ void Synth::flushMIDIQueue() {
}
}
-void Synth::setMIDIEventQueueSize(Bit32u useSize) {
- if (midiQueue != NULL) {
- flushMIDIQueue();
- delete midiQueue;
- midiQueue = new MidiEventQueue(useSize);
+Bit32u Synth::setMIDIEventQueueSize(Bit32u useSize) {
+ static const Bit32u MAX_QUEUE_SIZE = (1 << 24); // This results in about 256 Mb - much greater than any reasonable value
+
+ if (midiQueue == NULL) return 0;
+ flushMIDIQueue();
+
+ // Find a power of 2 that is >= useSize
+ Bit32u binarySize = 1;
+ if (useSize < MAX_QUEUE_SIZE) {
+ // Using simple linear search as this isn't time critical
+ while (binarySize < useSize) binarySize <<= 1;
+ } else {
+ binarySize = MAX_QUEUE_SIZE;
}
+ delete midiQueue;
+ midiQueue = new MidiEventQueue(binarySize);
+ return binarySize;
}
Bit32u Synth::getShortMessageLength(Bit32u msg) {
- if ((msg & 0xF0) == 0xF0) return 1;
+ if ((msg & 0xF0) == 0xF0) {
+ switch (msg & 0xFF) {
+ case 0xF1:
+ case 0xF3:
+ return 2;
+ case 0xF2:
+ return 3;
+ default:
+ return 1;
+ }
+ }
// NOTE: This calculation isn't quite correct
// as it doesn't consider the running status byte
return ((msg & 0xE0) == 0xC0) ? 2 : 3;
@@ -638,6 +668,7 @@ bool Synth::playMsg(Bit32u msg, Bit32u timestamp) {
if (midiDelayMode != MIDIDelayMode_IMMEDIATE) {
timestamp = addMIDIInterfaceDelay(getShortMessageLength(msg), timestamp);
}
+ if (!isEnabled) isEnabled = true;
return midiQueue->pushShortMessage(msg, timestamp);
}
@@ -650,16 +681,19 @@ bool Synth::playSysex(const Bit8u *sysex, Bit32u len, Bit32u timestamp) {
if (midiDelayMode == MIDIDelayMode_DELAY_ALL) {
timestamp = addMIDIInterfaceDelay(len, timestamp);
}
+ if (!isEnabled) isEnabled = true;
return midiQueue->pushSysex(sysex, len, timestamp);
}
void Synth::playMsgNow(Bit32u msg) {
- // FIXME: Implement active sensing
+ // NOTE: Active sense IS implemented in real hardware. However, realtime processing is clearly out of the library scope.
+ // It is assumed that realtime consumers of the library respond to these MIDI events as appropriate.
+
unsigned char code = (unsigned char)((msg & 0x0000F0) >> 4);
unsigned char chan = (unsigned char)(msg & 0x00000F);
unsigned char note = (unsigned char)((msg & 0x007F00) >> 8);
unsigned char velocity = (unsigned char)((msg & 0x7F0000) >> 16);
- isEnabled = true;
+ if (!isEnabled) isEnabled = true;
//printDebug("Playing chan %d, code 0x%01x note: 0x%02x", chan, code, note);
@@ -831,7 +865,7 @@ void Synth::playSysexWithoutHeader(unsigned char device, unsigned char command,
printDebug("playSysexWithoutHeader: Message is too short (%d bytes)!", len);
return;
}
- unsigned char checksum = calcSysexChecksum(sysex, len - 1, 0);
+ Bit8u checksum = calcSysexChecksum(sysex, len - 1);
if (checksum != sysex[len - 1]) {
printDebug("playSysexWithoutHeader: Message checksum is incorrect (provided: %02x, expected: %02x)!", sysex[len - 1], checksum);
return;
@@ -1410,9 +1444,8 @@ void MidiEvent::setSysex(const Bit8u *useSysexData, Bit32u useSysexLength, Bit32
memcpy(dstSysexData, useSysexData, sysexLength);
}
-MidiEventQueue::MidiEventQueue(Bit32u useRingBufferSize) : ringBufferSize(useRingBufferSize) {
- ringBuffer = new MidiEvent[ringBufferSize];
- memset(ringBuffer, 0, ringBufferSize * sizeof(MidiEvent));
+MidiEventQueue::MidiEventQueue(Bit32u useRingBufferSize) : ringBuffer(new MidiEvent[useRingBufferSize]), ringBufferMask(useRingBufferSize - 1) {
+ memset(ringBuffer, 0, useRingBufferSize * sizeof(MidiEvent));
reset();
}
@@ -1426,7 +1459,7 @@ void MidiEventQueue::reset() {
}
bool MidiEventQueue::pushShortMessage(Bit32u shortMessageData, Bit32u timestamp) {
- unsigned int newEndPosition = (endPosition + 1) % ringBufferSize;
+ Bit32u newEndPosition = (endPosition + 1) & ringBufferMask;
// Is ring buffer full?
if (startPosition == newEndPosition) return false;
ringBuffer[endPosition].setShortMessage(shortMessageData, timestamp);
@@ -1435,7 +1468,7 @@ bool MidiEventQueue::pushShortMessage(Bit32u shortMessageData, Bit32u timestamp)
}
bool MidiEventQueue::pushSysex(const Bit8u *sysexData, Bit32u sysexLength, Bit32u timestamp) {
- unsigned int newEndPosition = (endPosition + 1) % ringBufferSize;
+ Bit32u newEndPosition = (endPosition + 1) & ringBufferMask;
// Is ring buffer full?
if (startPosition == newEndPosition) return false;
ringBuffer[endPosition].setSysex(sysexData, sysexLength, timestamp);
@@ -1450,31 +1483,36 @@ const MidiEvent *MidiEventQueue::peekMidiEvent() {
void MidiEventQueue::dropMidiEvent() {
// Is ring buffer empty?
if (startPosition != endPosition) {
- startPosition = (startPosition + 1) % ringBufferSize;
+ startPosition = (startPosition + 1) & ringBufferMask;
}
}
+bool MidiEventQueue::isFull() const {
+ return startPosition == ((endPosition + 1) & ringBufferMask);
+}
+
+unsigned int Synth::getStereoOutputSampleRate() const {
+ return (analog == NULL) ? SAMPLE_RATE : analog->getOutputSampleRate();
+}
+
void Synth::render(Sample *stream, Bit32u len) {
- Sample tmpNonReverbLeft[MAX_SAMPLES_PER_RUN];
- Sample tmpNonReverbRight[MAX_SAMPLES_PER_RUN];
- Sample tmpReverbDryLeft[MAX_SAMPLES_PER_RUN];
- Sample tmpReverbDryRight[MAX_SAMPLES_PER_RUN];
- Sample tmpReverbWetLeft[MAX_SAMPLES_PER_RUN];
- Sample tmpReverbWetRight[MAX_SAMPLES_PER_RUN];
+ if (!isEnabled) {
+ renderedSampleCount += analog->getDACStreamsLength(len);
+ analog->process(NULL, NULL, NULL, NULL, NULL, NULL, NULL, len);
+ muteSampleBuffer(stream, len << 1);
+ return;
+ }
+
+ // As in AnalogOutputMode_ACCURATE mode output is upsampled, buffer size MAX_SAMPLES_PER_RUN is more than enough.
+ Sample tmpNonReverbLeft[MAX_SAMPLES_PER_RUN], tmpNonReverbRight[MAX_SAMPLES_PER_RUN];
+ Sample tmpReverbDryLeft[MAX_SAMPLES_PER_RUN], tmpReverbDryRight[MAX_SAMPLES_PER_RUN];
+ Sample tmpReverbWetLeft[MAX_SAMPLES_PER_RUN], tmpReverbWetRight[MAX_SAMPLES_PER_RUN];
while (len > 0) {
- Bit32u thisLen = len > MAX_SAMPLES_PER_RUN ? MAX_SAMPLES_PER_RUN : len;
- renderStreams(tmpNonReverbLeft, tmpNonReverbRight, tmpReverbDryLeft, tmpReverbDryRight, tmpReverbWetLeft, tmpReverbWetRight, thisLen);
- for (Bit32u i = 0; i < thisLen; i++) {
-#if MT32EMU_USE_FLOAT_SAMPLES
- *(stream++) = tmpNonReverbLeft[i] + tmpReverbDryLeft[i] + tmpReverbWetLeft[i];
- *(stream++) = tmpNonReverbRight[i] + tmpReverbDryRight[i] + tmpReverbWetRight[i];
-#else
- *(stream++) = clipBit16s((Bit32s)tmpNonReverbLeft[i] + (Bit32s)tmpReverbDryLeft[i] + (Bit32s)tmpReverbWetLeft[i]);
- *(stream++) = clipBit16s((Bit32s)tmpNonReverbRight[i] + (Bit32s)tmpReverbDryRight[i] + (Bit32s)tmpReverbWetRight[i]);
-#endif
- }
- len -= thisLen;
+ Bit32u thisPassLen = len > MAX_SAMPLES_PER_RUN ? MAX_SAMPLES_PER_RUN : len;
+ renderStreams(tmpNonReverbLeft, tmpNonReverbRight, tmpReverbDryLeft, tmpReverbDryRight, tmpReverbWetLeft, tmpReverbWetRight, analog->getDACStreamsLength(thisPassLen));
+ analog->process(&stream, tmpNonReverbLeft, tmpNonReverbRight, tmpReverbDryLeft, tmpReverbDryRight, tmpReverbWetLeft, tmpReverbWetRight, thisPassLen);
+ len -= thisPassLen;
}
}
@@ -1518,7 +1556,10 @@ void Synth::renderStreams(Sample *nonReverbLeft, Sample *nonReverbRight, Sample
// In GENERATION2 units, the output from LA32 goes to the Boss chip already bit-shifted.
// In NICE mode, it's also better to increase volume before the reverb processing to preserve accuracy.
void Synth::produceLA32Output(Sample *buffer, Bit32u len) {
-#if !MT32EMU_USE_FLOAT_SAMPLES
+#if MT32EMU_USE_FLOAT_SAMPLES
+ (void)buffer;
+ (void)len;
+#else
switch (dacInputMode) {
case DACInputMode_GENERATION2:
while (len--) {
@@ -1528,7 +1569,7 @@ void Synth::produceLA32Output(Sample *buffer, Bit32u len) {
break;
case DACInputMode_NICE:
while (len--) {
- *buffer = clipBit16s(Bit32s(*buffer) << 1);
+ *buffer = clipSampleEx(SampleEx(*buffer) << 1);
++buffer;
}
break;
@@ -1538,26 +1579,16 @@ void Synth::produceLA32Output(Sample *buffer, Bit32u len) {
#endif
}
-void Synth::convertSamplesToOutput(Sample *buffer, Bit32u len, bool reverb) {
- if (dacInputMode == DACInputMode_PURE) return;
-
+void Synth::convertSamplesToOutput(Sample *buffer, Bit32u len) {
#if MT32EMU_USE_FLOAT_SAMPLES
- float gain = reverb ? effectiveReverbOutputGain : outputGain;
- while (len--) {
- *(buffer++) *= gain;
- }
+ (void)buffer;
+ (void)len;
#else
- int gain = reverb ? effectiveReverbOutputGain : effectiveOutputGain;
if (dacInputMode == DACInputMode_GENERATION1) {
while (len--) {
- Bit32s target = Bit16s((*buffer & 0x8000) | ((*buffer << 1) & 0x7FFE));
- *(buffer++) = clipBit16s((target * gain) >> 8);
+ *buffer = Sample((*buffer & 0x8000) | ((*buffer << 1) & 0x7FFE));
+ ++buffer;
}
- return;
- }
- while (len--) {
- *buffer = clipBit16s((Bit32s(*buffer) * gain) >> 8);
- ++buffer;
}
#endif
}
@@ -1566,18 +1597,18 @@ void Synth::doRenderStreams(Sample *nonReverbLeft, Sample *nonReverbRight, Sampl
// Even if LA32 output isn't desired, we proceed anyway with temp buffers
Sample tmpBufNonReverbLeft[MAX_SAMPLES_PER_RUN], tmpBufNonReverbRight[MAX_SAMPLES_PER_RUN];
if (nonReverbLeft == NULL) nonReverbLeft = tmpBufNonReverbLeft;
- if (nonReverbLeft == NULL) nonReverbRight = tmpBufNonReverbRight;
+ if (nonReverbRight == NULL) nonReverbRight = tmpBufNonReverbRight;
Sample tmpBufReverbDryLeft[MAX_SAMPLES_PER_RUN], tmpBufReverbDryRight[MAX_SAMPLES_PER_RUN];
if (reverbDryLeft == NULL) reverbDryLeft = tmpBufReverbDryLeft;
if (reverbDryRight == NULL) reverbDryRight = tmpBufReverbDryRight;
- muteSampleBuffer(nonReverbLeft, len);
- muteSampleBuffer(nonReverbRight, len);
- muteSampleBuffer(reverbDryLeft, len);
- muteSampleBuffer(reverbDryRight, len);
-
if (isEnabled) {
+ muteSampleBuffer(nonReverbLeft, len);
+ muteSampleBuffer(nonReverbRight, len);
+ muteSampleBuffer(reverbDryLeft, len);
+ muteSampleBuffer(reverbDryRight, len);
+
for (unsigned int i = 0; i < getPartialCount(); i++) {
if (partialManager->shouldReverb(i)) {
partialManager->produceOutput(i, reverbDryLeft, reverbDryRight, len);
@@ -1591,8 +1622,8 @@ void Synth::doRenderStreams(Sample *nonReverbLeft, Sample *nonReverbRight, Sampl
if (isReverbEnabled()) {
reverbModel->process(reverbDryLeft, reverbDryRight, reverbWetLeft, reverbWetRight, len);
- if (reverbWetLeft != NULL) convertSamplesToOutput(reverbWetLeft, len, true);
- if (reverbWetRight != NULL) convertSamplesToOutput(reverbWetRight, len, true);
+ if (reverbWetLeft != NULL) convertSamplesToOutput(reverbWetLeft, len);
+ if (reverbWetRight != NULL) convertSamplesToOutput(reverbWetRight, len);
} else {
muteSampleBuffer(reverbWetLeft, len);
muteSampleBuffer(reverbWetRight, len);
@@ -1601,15 +1632,20 @@ void Synth::doRenderStreams(Sample *nonReverbLeft, Sample *nonReverbRight, Sampl
// Don't bother with conversion if the output is going to be unused
if (nonReverbLeft != tmpBufNonReverbLeft) {
produceLA32Output(nonReverbLeft, len);
- convertSamplesToOutput(nonReverbLeft, len, false);
+ convertSamplesToOutput(nonReverbLeft, len);
}
if (nonReverbRight != tmpBufNonReverbRight) {
produceLA32Output(nonReverbRight, len);
- convertSamplesToOutput(nonReverbRight, len, false);
+ convertSamplesToOutput(nonReverbRight, len);
}
- if (reverbDryLeft != tmpBufReverbDryLeft) convertSamplesToOutput(reverbDryLeft, len, false);
- if (reverbDryRight != tmpBufReverbDryRight) convertSamplesToOutput(reverbDryRight, len, false);
+ if (reverbDryLeft != tmpBufReverbDryLeft) convertSamplesToOutput(reverbDryLeft, len);
+ if (reverbDryRight != tmpBufReverbDryRight) convertSamplesToOutput(reverbDryRight, len);
} else {
+ // Avoid muting buffers that wasn't requested
+ if (nonReverbLeft != tmpBufNonReverbLeft) muteSampleBuffer(nonReverbLeft, len);
+ if (nonReverbRight != tmpBufNonReverbRight) muteSampleBuffer(nonReverbRight, len);
+ if (reverbDryLeft != tmpBufReverbDryLeft) muteSampleBuffer(reverbDryLeft, len);
+ if (reverbDryRight != tmpBufReverbDryRight) muteSampleBuffer(reverbDryRight, len);
muteSampleBuffer(reverbWetLeft, len);
muteSampleBuffer(reverbWetRight, len);
}
@@ -1651,14 +1687,48 @@ bool Synth::isActive() const {
return false;
}
-const Partial *Synth::getPartial(unsigned int partialNum) const {
- return partialManager->getPartial(partialNum);
-}
-
unsigned int Synth::getPartialCount() const {
return partialCount;
}
+void Synth::getPartStates(bool *partStates) const {
+ for (int partNumber = 0; partNumber < 9; partNumber++) {
+ const Part *part = parts[partNumber];
+ partStates[partNumber] = part->getActiveNonReleasingPartialCount() > 0;
+ }
+}
+
+void Synth::getPartialStates(PartialState *partialStates) const {
+ static const PartialState partialPhaseToState[8] = {
+ PartialState_ATTACK, PartialState_ATTACK, PartialState_ATTACK, PartialState_ATTACK,
+ PartialState_SUSTAIN, PartialState_SUSTAIN, PartialState_RELEASE, PartialState_INACTIVE
+ };
+
+ for (unsigned int partialNum = 0; partialNum < getPartialCount(); partialNum++) {
+ const Partial *partial = partialManager->getPartial(partialNum);
+ partialStates[partialNum] = partial->isActive() ? partialPhaseToState[partial->getTVA()->getPhase()] : PartialState_INACTIVE;
+ }
+}
+
+unsigned int Synth::getPlayingNotes(unsigned int partNumber, Bit8u *keys, Bit8u *velocities) const {
+ unsigned int playingNotes = 0;
+ if (isOpen && (partNumber < 9)) {
+ const Part *part = parts[partNumber];
+ const Poly *poly = part->getFirstActivePoly();
+ while (poly != NULL) {
+ keys[playingNotes] = (Bit8u)poly->getKey();
+ velocities[playingNotes] = (Bit8u)poly->getVelocity();
+ playingNotes++;
+ poly = poly->getNext();
+ }
+ }
+ return playingNotes;
+}
+
+const char *Synth::getPatchName(unsigned int partNumber) const {
+ return (!isOpen || partNumber > 8) ? NULL : parts[partNumber]->getCurrentInstr();
+}
+
const Part *Synth::getPart(unsigned int partNum) const {
if (partNum > 8) {
return NULL;
diff --git a/audio/softsynth/mt32/Synth.h b/audio/softsynth/mt32/Synth.h
index 37fb7b280a..97d4644ee2 100644
--- a/audio/softsynth/mt32/Synth.h
+++ b/audio/softsynth/mt32/Synth.h
@@ -19,15 +19,31 @@
#define MT32EMU_SYNTH_H
//#include <cstdarg>
+//#include <cstring>
namespace MT32Emu {
-class TableInitialiser;
+class Analog;
+class BReverbModel;
+class MemoryRegion;
+class MidiEventQueue;
+class Part;
+class Poly;
class Partial;
class PartialManager;
-class Part;
-class ROMImage;
-class BReverbModel;
+
+class PatchTempMemoryRegion;
+class RhythmTempMemoryRegion;
+class TimbreTempMemoryRegion;
+class PatchesMemoryRegion;
+class TimbresMemoryRegion;
+class SystemMemoryRegion;
+class DisplayMemoryRegion;
+class ResetMemoryRegion;
+
+struct ControlROMMap;
+struct PCMWaveEntry;
+struct MemParams;
/**
* Methods for emulating the connection between the LA32 and the DAC, which involves
@@ -43,8 +59,7 @@ enum DACInputMode {
// Produces samples that exactly match the bits output from the emulated LA32.
// * Nicer overdrive characteristics than the DAC hacks (it simply clips samples within range)
// * Much less likely to overdrive than any other mode.
- // * Half the volume of any of the other modes, meaning its volume relative to the reverb
- // output when mixed together directly will sound wrong.
+ // * Half the volume of any of the other modes.
// * Output gain is ignored for both LA32 and reverb output.
// * Perfect for developers while debugging :)
DACInputMode_PURE,
@@ -60,6 +75,7 @@ enum DACInputMode {
DACInputMode_GENERATION2
};
+// Methods for emulating the effective delay of incoming MIDI messages introduced by a MIDI interface.
enum MIDIDelayMode {
// Process incoming MIDI events immediately.
MIDIDelayMode_IMMEDIATE,
@@ -72,6 +88,35 @@ enum MIDIDelayMode {
MIDIDelayMode_DELAY_ALL
};
+// Methods for emulating the effects of analogue circuits of real hardware units on the output signal.
+enum AnalogOutputMode {
+ // Only digital path is emulated. The output samples correspond to the digital signal at the DAC entrance.
+ AnalogOutputMode_DIGITAL_ONLY,
+ // Coarse emulation of LPF circuit. High frequencies are boosted, sample rate remains unchanged.
+ AnalogOutputMode_COARSE,
+ // Finer emulation of LPF circuit. Output signal is upsampled to 48 kHz to allow emulation of audible mirror spectra above 16 kHz,
+ // which is passed through the LPF circuit without significant attenuation.
+ AnalogOutputMode_ACCURATE,
+ // Same as AnalogOutputMode_ACCURATE mode but the output signal is 2x oversampled, i.e. the output sample rate is 96 kHz.
+ // This makes subsequent resampling easier. Besides, due to nonlinear passband of the LPF emulated, it takes fewer number of MACs
+ // compared to a regular LPF FIR implementations.
+ AnalogOutputMode_OVERSAMPLED
+};
+
+enum ReverbMode {
+ REVERB_MODE_ROOM,
+ REVERB_MODE_HALL,
+ REVERB_MODE_PLATE,
+ REVERB_MODE_TAP_DELAY
+};
+
+enum PartialState {
+ PartialState_INACTIVE,
+ PartialState_ATTACK,
+ PartialState_SUSTAIN,
+ PartialState_RELEASE
+};
+
const Bit8u SYSEX_MANUFACTURER_ROLAND = 0x41;
const Bit8u SYSEX_MDL_MT32 = 0x16;
@@ -87,148 +132,10 @@ const Bit8u SYSEX_CMD_EOD = 0x45; // End of data
const Bit8u SYSEX_CMD_ERR = 0x4E; // Communications error
const Bit8u SYSEX_CMD_RJC = 0x4F; // Rejection
-const int MAX_SYSEX_SIZE = 512;
+const int MAX_SYSEX_SIZE = 512; // FIXME: Does this correspond to a real MIDI buffer used in h/w devices?
const unsigned int CONTROL_ROM_SIZE = 64 * 1024;
-struct ControlROMPCMStruct {
- Bit8u pos;
- Bit8u len;
- Bit8u pitchLSB;
- Bit8u pitchMSB;
-};
-
-struct ControlROMMap {
- Bit16u idPos;
- Bit16u idLen;
- const char *idBytes;
- Bit16u pcmTable; // 4 * pcmCount bytes
- Bit16u pcmCount;
- Bit16u timbreAMap; // 128 bytes
- Bit16u timbreAOffset;
- bool timbreACompressed;
- Bit16u timbreBMap; // 128 bytes
- Bit16u timbreBOffset;
- bool timbreBCompressed;
- Bit16u timbreRMap; // 2 * timbreRCount bytes
- Bit16u timbreRCount;
- Bit16u rhythmSettings; // 4 * rhythmSettingsCount bytes
- Bit16u rhythmSettingsCount;
- Bit16u reserveSettings; // 9 bytes
- Bit16u panSettings; // 8 bytes
- Bit16u programSettings; // 8 bytes
- Bit16u rhythmMaxTable; // 4 bytes
- Bit16u patchMaxTable; // 16 bytes
- Bit16u systemMaxTable; // 23 bytes
- Bit16u timbreMaxTable; // 72 bytes
-};
-
-enum MemoryRegionType {
- MR_PatchTemp, MR_RhythmTemp, MR_TimbreTemp, MR_Patches, MR_Timbres, MR_System, MR_Display, MR_Reset
-};
-
-enum ReverbMode {
- REVERB_MODE_ROOM,
- REVERB_MODE_HALL,
- REVERB_MODE_PLATE,
- REVERB_MODE_TAP_DELAY
-};
-
-class MemoryRegion {
-private:
- Synth *synth;
- Bit8u *realMemory;
- Bit8u *maxTable;
-public:
- MemoryRegionType type;
- Bit32u startAddr, entrySize, entries;
-
- MemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable, MemoryRegionType useType, Bit32u useStartAddr, Bit32u useEntrySize, Bit32u useEntries) {
- synth = useSynth;
- realMemory = useRealMemory;
- maxTable = useMaxTable;
- type = useType;
- startAddr = useStartAddr;
- entrySize = useEntrySize;
- entries = useEntries;
- }
- int lastTouched(Bit32u addr, Bit32u len) const {
- return (offset(addr) + len - 1) / entrySize;
- }
- int firstTouchedOffset(Bit32u addr) const {
- return offset(addr) % entrySize;
- }
- int firstTouched(Bit32u addr) const {
- return offset(addr) / entrySize;
- }
- Bit32u regionEnd() const {
- return startAddr + entrySize * entries;
- }
- bool contains(Bit32u addr) const {
- return addr >= startAddr && addr < regionEnd();
- }
- int offset(Bit32u addr) const {
- return addr - startAddr;
- }
- Bit32u getClampedLen(Bit32u addr, Bit32u len) const {
- if (addr + len > regionEnd())
- return regionEnd() - addr;
- return len;
- }
- Bit32u next(Bit32u addr, Bit32u len) const {
- if (addr + len > regionEnd()) {
- return regionEnd() - addr;
- }
- return 0;
- }
- Bit8u getMaxValue(int off) const {
- if (maxTable == NULL)
- return 0xFF;
- return maxTable[off % entrySize];
- }
- Bit8u *getRealMemory() const {
- return realMemory;
- }
- bool isReadable() const {
- return getRealMemory() != NULL;
- }
- void read(unsigned int entry, unsigned int off, Bit8u *dst, unsigned int len) const;
- void write(unsigned int entry, unsigned int off, const Bit8u *src, unsigned int len, bool init = false) const;
-};
-
-class PatchTempMemoryRegion : public MemoryRegion {
-public:
- PatchTempMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_PatchTemp, MT32EMU_MEMADDR(0x030000), sizeof(MemParams::PatchTemp), 9) {}
-};
-class RhythmTempMemoryRegion : public MemoryRegion {
-public:
- RhythmTempMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_RhythmTemp, MT32EMU_MEMADDR(0x030110), sizeof(MemParams::RhythmTemp), 85) {}
-};
-class TimbreTempMemoryRegion : public MemoryRegion {
-public:
- TimbreTempMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_TimbreTemp, MT32EMU_MEMADDR(0x040000), sizeof(TimbreParam), 8) {}
-};
-class PatchesMemoryRegion : public MemoryRegion {
-public:
- PatchesMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_Patches, MT32EMU_MEMADDR(0x050000), sizeof(PatchParam), 128) {}
-};
-class TimbresMemoryRegion : public MemoryRegion {
-public:
- TimbresMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_Timbres, MT32EMU_MEMADDR(0x080000), sizeof(MemParams::PaddedTimbre), 64 + 64 + 64 + 64) {}
-};
-class SystemMemoryRegion : public MemoryRegion {
-public:
- SystemMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_System, MT32EMU_MEMADDR(0x100000), sizeof(MemParams::System), 1) {}
-};
-class DisplayMemoryRegion : public MemoryRegion {
-public:
- DisplayMemoryRegion(Synth *useSynth) : MemoryRegion(useSynth, NULL, NULL, MR_Display, MT32EMU_MEMADDR(0x200000), MAX_SYSEX_SIZE - 1, 1) {}
-};
-class ResetMemoryRegion : public MemoryRegion {
-public:
- ResetMemoryRegion(Synth *useSynth) : MemoryRegion(useSynth, NULL, NULL, MR_Reset, MT32EMU_MEMADDR(0x7F0000), 0x3FFF, 1) {}
-};
-
class ReportHandler {
friend class Synth;
@@ -254,47 +161,6 @@ protected:
virtual void onProgramChanged(int /* partNum */, int /* bankNum */, const char * /* patchName */) {}
};
-/**
- * Used to safely store timestamped MIDI events in a local queue.
- */
-struct MidiEvent {
- Bit32u shortMessageData;
- const Bit8u *sysexData;
- Bit32u sysexLength;
- Bit32u timestamp;
-
- ~MidiEvent();
- void setShortMessage(Bit32u shortMessageData, Bit32u timestamp);
- void setSysex(const Bit8u *sysexData, Bit32u sysexLength, Bit32u timestamp);
-};
-
-/**
- * Simple queue implementation using a ring buffer to store incoming MIDI event before the synth actually processes it.
- * It is intended to:
- * - get rid of prerenderer while retaining graceful partial abortion
- * - add fair emulation of the MIDI interface delays
- * - extend the synth interface with the default implementation of a typical rendering loop.
- * THREAD SAFETY:
- * It is safe to use either in a single thread environment or when there are only two threads - one performs only reading
- * and one performs only writing. More complicated usage requires external synchronisation.
- */
-class MidiEventQueue {
-private:
- MidiEvent *ringBuffer;
- Bit32u ringBufferSize;
- volatile Bit32u startPosition;
- volatile Bit32u endPosition;
-
-public:
- MidiEventQueue(Bit32u ringBufferSize = DEFAULT_MIDI_EVENT_QUEUE_SIZE);
- ~MidiEventQueue();
- void reset();
- bool pushShortMessage(Bit32u shortMessageData, Bit32u timestamp);
- bool pushSysex(const Bit8u *sysexData, Bit32u sysexLength, Bit32u timestamp);
- const MidiEvent *peekMidiEvent();
- void dropMidiEvent();
-};
-
class Synth {
friend class Part;
friend class RhythmPart;
@@ -335,7 +201,7 @@ private:
volatile Bit32u lastReceivedMIDIEventTimestamp;
volatile Bit32u renderedSampleCount;
- MemParams mt32ram, mt32default;
+ MemParams &mt32ram, &mt32default;
BReverbModel *reverbModels[4];
BReverbModel *reverbModel;
@@ -346,12 +212,6 @@ private:
float outputGain;
float reverbOutputGain;
-#if MT32EMU_USE_FLOAT_SAMPLES
- float effectiveReverbOutputGain;
-#else
- int effectiveOutputGain;
- int effectiveReverbOutputGain;
-#endif
bool reversedStereoEnabled;
@@ -368,11 +228,12 @@ private:
// We emulate this by delaying new MIDI events processing until abortion finishes.
Poly *abortingPoly;
- Bit32u getShortMessageLength(Bit32u msg);
+ Analog *analog;
+
Bit32u addMIDIInterfaceDelay(Bit32u len, Bit32u timestamp);
void produceLA32Output(Sample *buffer, Bit32u len);
- void convertSamplesToOutput(Sample *buffer, Bit32u len, bool reverb);
+ void convertSamplesToOutput(Sample *buffer, Bit32u len);
bool isAbortingPoly() const;
void doRenderStreams(Sample *nonReverbLeft, Sample *nonReverbRight, Sample *reverbDryLeft, Sample *reverbDryRight, Sample *reverbWetLeft, Sample *reverbWetRight, Bit32u len);
@@ -404,13 +265,20 @@ private:
void newTimbreSet(int partNum, Bit8u timbreGroup, const char patchName[]);
void printDebug(const char *fmt, ...);
+ // partNum should be 0..7 for Part 1..8, or 8 for Rhythm
+ const Part *getPart(unsigned int partNum) const;
+
public:
- static inline Bit16s clipBit16s(Bit32s sample) {
+ static inline Sample clipSampleEx(SampleEx sampleEx) {
+#if MT32EMU_USE_FLOAT_SAMPLES
+ return sampleEx;
+#else
// Clamp values above 32767 to 32767, and values below -32768 to -32768
// FIXME: Do we really need this stuff? I think these branches are very well predicted. Instead, this introduces a chain.
// The version below is actually a bit faster on my system...
- //return ((sample + 0x8000) & ~0xFFFF) ? (sample >> 31) ^ 0x7FFF : (Bit16s)sample;
- return ((-0x8000 <= sample) && (sample <= 0x7FFF)) ? (Bit16s)sample : (sample >> 31) ^ 0x7FFF;
+ //return ((sampleEx + 0x8000) & ~0xFFFF) ? (sampleEx >> 31) ^ 0x7FFF : (Sample)sampleEx;
+ return ((-0x8000 <= sampleEx) && (sampleEx <= 0x7FFF)) ? (Sample)sampleEx : (sampleEx >> 31) ^ 0x7FFF;
+#endif
}
static inline void muteSampleBuffer(Sample *buffer, Bit32u len) {
@@ -426,7 +294,8 @@ public:
#endif
}
- static Bit8u calcSysexChecksum(const Bit8u *data, Bit32u len, Bit8u checksum);
+ static Bit32u getShortMessageLength(Bit32u msg);
+ static Bit8u calcSysexChecksum(const Bit8u *data, const Bit32u len, const Bit8u initChecksum = 0);
// Optionally sets callbacks for reporting various errors, information and debug messages
Synth(ReportHandler *useReportHandler = NULL);
@@ -435,8 +304,12 @@ public:
// Used to initialise the MT-32. Must be called before any other function.
// Returns true if initialization was sucessful, otherwise returns false.
// controlROMImage and pcmROMImage represent Control and PCM ROM images for use by synth.
- // usePartialCount sets the maximum number of partials playing simultaneously for this session.
- bool open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, unsigned int usePartialCount = DEFAULT_MAX_PARTIALS);
+ // usePartialCount sets the maximum number of partials playing simultaneously for this session (optional).
+ // analogOutputMode sets the mode for emulation of analogue circuitry of the hardware units (optional).
+ bool open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, unsigned int usePartialCount = DEFAULT_MAX_PARTIALS, AnalogOutputMode analogOutputMode = AnalogOutputMode_COARSE);
+
+ // Overloaded method which opens the synth with default partial count.
+ bool open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, AnalogOutputMode analogOutputMode);
// Closes the MT-32 and deallocates any memory used by the synthesizer
void close(bool forced = false);
@@ -444,29 +317,34 @@ public:
// All the enqueued events are processed by the synth immediately.
void flushMIDIQueue();
- // Sets size of the internal MIDI event queue.
+ // Sets size of the internal MIDI event queue. The queue size is set to the minimum power of 2 that is greater or equal to the size specified.
// The queue is flushed before reallocation.
- void setMIDIEventQueueSize(Bit32u);
+ // Returns the actual queue size being used.
+ Bit32u setMIDIEventQueueSize(Bit32u);
// Enqueues a MIDI event for subsequent playback.
- // The minimum delay involves the delay introduced while the event is transferred via MIDI interface
+ // The MIDI event will be processed not before the specified timestamp.
+ // The timestamp is measured as the global rendered sample count since the synth was created (at the native sample rate 32000 Hz).
+ // The minimum delay involves emulation of the delay introduced while the event is transferred via MIDI interface
// and emulation of the MCU busy-loop while it frees partials for use by a new Poly.
- // Calls from multiple threads must be synchronised, although,
- // no synchronisation is required with the rendering thread.
+ // Calls from multiple threads must be synchronised, although, no synchronisation is required with the rendering thread.
+ // The methods return false if the MIDI event queue is full and the message cannot be enqueued.
- // The MIDI event will be processed not before the specified timestamp.
- // The timestamp is measured as the global rendered sample count since the synth was created.
+ // Enqueues a single short MIDI message. The message must contain a status byte.
bool playMsg(Bit32u msg, Bit32u timestamp);
+ // Enqueues a single well formed System Exclusive MIDI message.
bool playSysex(const Bit8u *sysex, Bit32u len, Bit32u timestamp);
- // The MIDI event will be processed ASAP.
+
+ // Overloaded methods for the MIDI events to be processed ASAP.
bool playMsg(Bit32u msg);
bool playSysex(const Bit8u *sysex, Bit32u len);
// WARNING:
// The methods below don't ensure minimum 1-sample delay between sequential MIDI events,
// and a sequence of NoteOn and immediately succeeding NoteOff messages is always silent.
+ // A thread that invokes these methods must be explicitly synchronised with the thread performing sample rendering.
- // Sends a 4-byte MIDI message to the MT-32 for immediate playback.
+ // Sends a short MIDI message to the synth for immediate playback. The message must contain a status byte.
void playMsgNow(Bit32u msg);
void playMsgOnPart(unsigned char part, unsigned char code, unsigned char note, unsigned char velocity);
@@ -495,12 +373,17 @@ public:
void setMIDIDelayMode(MIDIDelayMode mode);
MIDIDelayMode getMIDIDelayMode() const;
- // Sets output gain factor. Applied to all output samples and unrelated with the synth's Master volume.
+ // Sets output gain factor for synth output channels. Applied to all output samples and unrelated with the synth's Master volume,
+ // it rather corresponds to the gain of the output analog circuitry of the hardware units. However, together with setReverbOutputGain()
+ // it offers to the user a capability to control the gain of reverb and non-reverb output channels independently.
// Ignored in DACInputMode_PURE
void setOutputGain(float);
float getOutputGain() const;
- // Sets output gain factor for the reverb wet output. setOutputGain() doesn't change reverb output gain.
+ // Sets output gain factor for the reverb wet output channels. It rather corresponds to the gain of the output
+ // analog circuitry of the hardware units. However, together with setOutputGain() it offers to the user a capability
+ // to control the gain of reverb and non-reverb output channels independently.
+ //
// Note: We're currently emulate CM-32L/CM-64 reverb quite accurately and the reverb output level closely
// corresponds to the level of digital capture. Although, according to the CM-64 PCB schematic,
// there is a difference in the reverb analogue circuit, and the resulting output gain is 0.68
@@ -512,12 +395,21 @@ public:
void setReversedStereoEnabled(bool enabled);
bool isReversedStereoEnabled();
- // Renders samples to the specified output stream.
- // The length is in frames, not bytes (in 16-bit stereo,
- // one frame is 4 bytes).
+ // Returns actual sample rate used in emulation of stereo analog circuitry of hardware units.
+ // See comment for render() below.
+ unsigned int getStereoOutputSampleRate() const;
+
+ // Renders samples to the specified output stream as if they were sampled at the analog stereo output.
+ // When AnalogOutputMode is set to ACCURATE, the output signal is upsampled to 48 kHz in order
+ // to retain emulation accuracy in whole audible frequency spectra. Otherwise, native digital signal sample rate is retained.
+ // getStereoOutputSampleRate() can be used to query actual sample rate of the output signal.
+ // The length is in frames, not bytes (in 16-bit stereo, one frame is 4 bytes).
void render(Sample *stream, Bit32u len);
- // Renders samples to the specified output streams (any or all of which may be NULL).
+ // Renders samples to the specified output streams as if they appeared at the DAC entrance.
+ // No further processing performed in analog circuitry emulation is applied to the signal.
+ // NULL may be specified in place of any or all of the stream buffers.
+ // The length is in samples, not bytes.
void renderStreams(Sample *nonReverbLeft, Sample *nonReverbRight, Sample *reverbDryLeft, Sample *reverbDryRight, Sample *reverbWetLeft, Sample *reverbWetRight, Bit32u len);
// Returns true when there is at least one active partial, otherwise false.
@@ -526,15 +418,28 @@ public:
// Returns true if hasActivePartials() returns true, or reverb is (somewhat unreliably) detected as being active.
bool isActive() const;
- const Partial *getPartial(unsigned int partialNum) const;
-
// Returns the maximum number of partials playing simultaneously.
unsigned int getPartialCount() const;
- void readMemory(Bit32u addr, Bit32u len, Bit8u *data);
+ // Fills in current states of all the parts into the array provided. The array must have at least 9 entries to fit values for all the parts.
+ // If the value returned for a part is true, there is at least one active non-releasing partial playing on this part.
+ // This info is useful in emulating behaviour of LCD display of the hardware units.
+ void getPartStates(bool *partStates) const;
- // partNum should be 0..7 for Part 1..8, or 8 for Rhythm
- const Part *getPart(unsigned int partNum) const;
+ // Fills in current states of all the partials into the array provided. The array must be large enough to accommodate states of all the partials.
+ void getPartialStates(PartialState *partialStates) const;
+
+ // Fills in information about currently playing notes on the specified part into the arrays provided. The arrays must be large enough
+ // to accommodate data for all the playing notes. The maximum number of simultaneously playing notes cannot exceed the number of partials.
+ // Argument partNumber should be 0..7 for Part 1..8, or 8 for Rhythm.
+ // Returns the number of currently playing notes on the specified part.
+ unsigned int getPlayingNotes(unsigned int partNumber, Bit8u *keys, Bit8u *velocities) const;
+
+ // Returns name of the patch set on the specified part.
+ // Argument partNumber should be 0..7 for Part 1..8, or 8 for Rhythm.
+ const char *getPatchName(unsigned int partNumber) const;
+
+ void readMemory(Bit32u addr, Bit32u len, Bit8u *data);
};
}
diff --git a/audio/softsynth/mt32/TVA.cpp b/audio/softsynth/mt32/TVA.cpp
index 3fefb791f2..894e53f14a 100644
--- a/audio/softsynth/mt32/TVA.cpp
+++ b/audio/softsynth/mt32/TVA.cpp
@@ -23,6 +23,7 @@
#include "mt32emu.h"
#include "mmath.h"
+#include "internals.h"
namespace MT32Emu {
diff --git a/audio/softsynth/mt32/TVF.cpp b/audio/softsynth/mt32/TVF.cpp
index bf8d50a7c9..164cf2b4cb 100644
--- a/audio/softsynth/mt32/TVF.cpp
+++ b/audio/softsynth/mt32/TVF.cpp
@@ -19,6 +19,7 @@
#include "mt32emu.h"
#include "mmath.h"
+#include "internals.h"
namespace MT32Emu {
diff --git a/audio/softsynth/mt32/TVP.cpp b/audio/softsynth/mt32/TVP.cpp
index 374646e5f1..a8003d96dc 100644
--- a/audio/softsynth/mt32/TVP.cpp
+++ b/audio/softsynth/mt32/TVP.cpp
@@ -19,6 +19,7 @@
//#include <cstdlib>
#include "mt32emu.h"
+#include "internals.h"
namespace MT32Emu {
diff --git a/audio/softsynth/mt32/Tables.cpp b/audio/softsynth/mt32/Tables.cpp
index ae9f11fff0..7e165b5a7a 100644
--- a/audio/softsynth/mt32/Tables.cpp
+++ b/audio/softsynth/mt32/Tables.cpp
@@ -16,14 +16,15 @@
*/
//#include <cmath>
-//#include <cstdlib>
-//#include <cstring>
#include "mt32emu.h"
#include "mmath.h"
+#include "Tables.h"
namespace MT32Emu {
+// UNUSED: const int MIDDLEC = 60;
+
const Tables &Tables::getInstance() {
static const Tables instance;
return instance;
diff --git a/audio/softsynth/mt32/Tables.h b/audio/softsynth/mt32/Tables.h
index e7b97af515..8865c7fac8 100644
--- a/audio/softsynth/mt32/Tables.h
+++ b/audio/softsynth/mt32/Tables.h
@@ -20,24 +20,11 @@
namespace MT32Emu {
-// Sample rate to use in mixing. With the progress of development, we've found way too many thing dependent.
-// In order to achieve further advance in emulation accuracy, sample rate made fixed throughout the emulator.
-// The output from the synth is supposed to be resampled to convert the sample rate.
-const unsigned int SAMPLE_RATE = 32000;
-
-// MIDI interface data transfer rate in samples. Used to simulate the transfer delay.
-const double MIDI_DATA_TRANSFER_RATE = (double)SAMPLE_RATE / 31250.0 * 8.0;
-
-const float CM32L_REVERB_TO_LA32_ANALOG_OUTPUT_GAIN_FACTOR = 0.68f;
-
-const int MIDDLEC = 60;
-
-class Synth;
-
class Tables {
private:
Tables();
Tables(Tables &);
+ ~Tables() {}
public:
static const Tables &getInstance();
diff --git a/audio/softsynth/mt32/Types.h b/audio/softsynth/mt32/Types.h
new file mode 100644
index 0000000000..934b1a1173
--- /dev/null
+++ b/audio/softsynth/mt32/Types.h
@@ -0,0 +1,40 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MT32EMU_TYPES_H
+#define MT32EMU_TYPES_H
+
+namespace MT32Emu {
+
+typedef unsigned int Bit32u;
+typedef signed int Bit32s;
+typedef unsigned short int Bit16u;
+typedef signed short int Bit16s;
+typedef unsigned char Bit8u;
+typedef signed char Bit8s;
+
+#if MT32EMU_USE_FLOAT_SAMPLES
+typedef float Sample;
+typedef float SampleEx;
+#else
+typedef Bit16s Sample;
+typedef Bit32s SampleEx;
+#endif
+
+}
+
+#endif
diff --git a/audio/softsynth/mt32/internals.h b/audio/softsynth/mt32/internals.h
new file mode 100644
index 0000000000..ef56819a42
--- /dev/null
+++ b/audio/softsynth/mt32/internals.h
@@ -0,0 +1,83 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MT32EMU_INTERNALS_H
+#define MT32EMU_INTERNALS_H
+
+// Debugging
+
+// 0: Standard debug output is not stamped with the rendered sample count
+// 1: Standard debug output is stamped with the rendered sample count
+// NOTE: The "samplestamp" corresponds to the end of the last completed rendering run.
+// This is important to bear in mind for debug output that occurs during a run.
+#define MT32EMU_DEBUG_SAMPLESTAMPS 0
+
+// 0: No debug output for initialisation progress
+// 1: Debug output for initialisation progress
+#define MT32EMU_MONITOR_INIT 0
+
+// 0: No debug output for MIDI events
+// 1: Debug output for weird MIDI events
+#define MT32EMU_MONITOR_MIDI 0
+
+// 0: No debug output for note on/off
+// 1: Basic debug output for note on/off
+// 2: Comprehensive debug output for note on/off
+#define MT32EMU_MONITOR_INSTRUMENTS 0
+
+// 0: No debug output for partial allocations
+// 1: Show partial stats when an allocation fails
+// 2: Show partial stats with every new poly
+// 3: Show individual partial allocations/deactivations
+#define MT32EMU_MONITOR_PARTIALS 0
+
+// 0: No debug output for sysex
+// 1: Basic debug output for sysex
+#define MT32EMU_MONITOR_SYSEX 0
+
+// 0: No debug output for sysex writes to the timbre areas
+// 1: Debug output with the name and location of newly-written timbres
+// 2: Complete dump of timbre parameters for newly-written timbres
+#define MT32EMU_MONITOR_TIMBRES 0
+
+// 0: No TVA/TVF-related debug output.
+// 1: Shows changes to TVA/TVF target, increment and phase.
+#define MT32EMU_MONITOR_TVA 0
+#define MT32EMU_MONITOR_TVF 0
+
+// Configuration
+
+// If non-zero, deletes reverb buffers that are not in use to save memory.
+// If zero, keeps reverb buffers for all modes around all the time to avoid allocating/freeing in the critical path.
+#define MT32EMU_REDUCE_REVERB_MEMORY 1
+
+// 0: Maximum speed at the cost of a bit lower emulation accuracy.
+// 1: Maximum achievable emulation accuracy.
+#define MT32EMU_BOSS_REVERB_PRECISE_MODE 0
+
+#include "Structures.h"
+#include "Tables.h"
+#include "Poly.h"
+#include "LA32Ramp.h"
+#include "LA32WaveGenerator.h"
+#include "TVA.h"
+#include "TVP.h"
+#include "TVF.h"
+#include "Partial.h"
+#include "Part.h"
+
+#endif
diff --git a/audio/softsynth/mt32/module.mk b/audio/softsynth/mt32/module.mk
index 1c8aa125ab..f966da8d08 100644
--- a/audio/softsynth/mt32/module.mk
+++ b/audio/softsynth/mt32/module.mk
@@ -1,6 +1,7 @@
MODULE := audio/softsynth/mt32
MODULE_OBJS := \
+ Analog.o \
BReverbModel.o \
LA32Ramp.o \
LA32WaveGenerator.o \
diff --git a/audio/softsynth/mt32/mt32emu.h b/audio/softsynth/mt32/mt32emu.h
index d738a5de35..1574c08f0d 100644
--- a/audio/softsynth/mt32/mt32emu.h
+++ b/audio/softsynth/mt32/mt32emu.h
@@ -18,63 +18,20 @@
#ifndef MT32EMU_MT32EMU_H
#define MT32EMU_MT32EMU_H
-// Debugging
-
-// 0: Standard debug output is not stamped with the rendered sample count
-// 1: Standard debug output is stamped with the rendered sample count
-// NOTE: The "samplestamp" corresponds to the end of the last completed rendering run.
-// This is important to bear in mind for debug output that occurs during a run.
-#define MT32EMU_DEBUG_SAMPLESTAMPS 0
-
-// 0: No debug output for initialisation progress
-// 1: Debug output for initialisation progress
-#define MT32EMU_MONITOR_INIT 0
-
-// 0: No debug output for MIDI events
-// 1: Debug output for weird MIDI events
-#define MT32EMU_MONITOR_MIDI 0
-
-// 0: No debug output for note on/off
-// 1: Basic debug output for note on/off
-// 2: Comprehensive debug output for note on/off
-#define MT32EMU_MONITOR_INSTRUMENTS 0
-
-// 0: No debug output for partial allocations
-// 1: Show partial stats when an allocation fails
-// 2: Show partial stats with every new poly
-// 3: Show individual partial allocations/deactivations
-#define MT32EMU_MONITOR_PARTIALS 0
-
-// 0: No debug output for sysex
-// 1: Basic debug output for sysex
-#define MT32EMU_MONITOR_SYSEX 0
-
-// 0: No debug output for sysex writes to the timbre areas
-// 1: Debug output with the name and location of newly-written timbres
-// 2: Complete dump of timbre parameters for newly-written timbres
-#define MT32EMU_MONITOR_TIMBRES 0
-
-// 0: No TVA/TVF-related debug output.
-// 1: Shows changes to TVA/TVF target, increment and phase.
-#define MT32EMU_MONITOR_TVA 0
-#define MT32EMU_MONITOR_TVF 0
-
// Configuration
-// If non-zero, deletes reverb buffers that are not in use to save memory.
-// If zero, keeps reverb buffers for all modes around all the time to avoid allocating/freeing in the critical path.
-#define MT32EMU_REDUCE_REVERB_MEMORY 1
-
-// 0: Maximum speed at the cost of a bit lower emulation accuracy.
-// 1: Maximum achievable emulation accuracy.
-#define MT32EMU_BOSS_REVERB_PRECISE_MODE 0
-
// 0: Use 16-bit signed samples and refined wave generator based on logarithmic fixed-point computations and LUTs. Maximum emulation accuracy and speed.
// 1: Use float samples in the wave generator and renderer. Maximum output quality and minimum noise.
#define MT32EMU_USE_FLOAT_SAMPLES 0
namespace MT32Emu
{
+// Sample rate to use in mixing. With the progress of development, we've found way too many thing dependent.
+// In order to achieve further advance in emulation accuracy, sample rate made fixed throughout the emulator,
+// except the emulation of analogue path.
+// The output from the synth is supposed to be resampled externally in order to convert to the desired sample rate.
+const unsigned int SAMPLE_RATE = 32000;
+
// The default value for the maximum number of partials playing simultaneously.
const unsigned int DEFAULT_MAX_PARTIALS = 32;
@@ -97,17 +54,7 @@ const unsigned int MAX_SAMPLES_PER_RUN = 4096;
const unsigned int DEFAULT_MIDI_EVENT_QUEUE_SIZE = 1024;
}
-#include "Structures.h"
-#include "common/file.h"
-#include "Tables.h"
-#include "Poly.h"
-#include "LA32Ramp.h"
-#include "LA32WaveGenerator.h"
-#include "TVA.h"
-#include "TVP.h"
-#include "TVF.h"
-#include "Partial.h"
-#include "Part.h"
+#include "Types.h"
#include "ROMInfo.h"
#include "Synth.h"
diff --git a/audio/softsynth/opl/dosbox.cpp b/audio/softsynth/opl/dosbox.cpp
index 5c3d833f54..3d90ec93d0 100644
--- a/audio/softsynth/opl/dosbox.cpp
+++ b/audio/softsynth/opl/dosbox.cpp
@@ -32,6 +32,7 @@
#include "dosbox.h"
#include "dbopl.h"
+#include "audio/mixer.h"
#include "common/system.h"
#include "common/scummsys.h"
#include "common/util.h"
@@ -148,6 +149,7 @@ OPL::OPL(Config::OplType type) : _type(type), _rate(0), _emulator(0) {
}
OPL::~OPL() {
+ stop();
free();
}
@@ -156,7 +158,7 @@ void OPL::free() {
_emulator = 0;
}
-bool OPL::init(int rate) {
+bool OPL::init() {
free();
memset(&_reg, 0, sizeof(_reg));
@@ -167,19 +169,19 @@ bool OPL::init(int rate) {
return false;
DBOPL::InitTables();
- _emulator->Setup(rate);
+ _rate = g_system->getMixer()->getOutputRate();
+ _emulator->Setup(_rate);
if (_type == Config::kDualOpl2) {
// Setup opl3 mode in the hander
_emulator->WriteReg(0x105, 1);
}
- _rate = rate;
return true;
}
void OPL::reset() {
- init(_rate);
+ init();
}
void OPL::write(int port, int val) {
@@ -307,7 +309,7 @@ void OPL::dualWrite(uint8 index, uint8 reg, uint8 val) {
_emulator->WriteReg(fullReg, val);
}
-void OPL::readBuffer(int16 *buffer, int length) {
+void OPL::generateSamples(int16 *buffer, int length) {
// For stereo OPL cards, we divide the sample count by 2,
// to match stereo AudioStream behavior.
if (_type != Config::kOpl2)
diff --git a/audio/softsynth/opl/dosbox.h b/audio/softsynth/opl/dosbox.h
index 513a49f6b8..c52f06761a 100644
--- a/audio/softsynth/opl/dosbox.h
+++ b/audio/softsynth/opl/dosbox.h
@@ -69,7 +69,7 @@ namespace DBOPL {
struct Chip;
} // end of namespace DBOPL
-class OPL : public ::OPL::OPL {
+class OPL : public ::OPL::EmulatedOPL {
private:
Config::OplType _type;
uint _rate;
@@ -87,7 +87,7 @@ public:
OPL(Config::OplType type);
~OPL();
- bool init(int rate);
+ bool init();
void reset();
void write(int a, int v);
@@ -95,8 +95,10 @@ public:
void writeReg(int r, int v);
- void readBuffer(int16 *buffer, int length);
bool isStereo() const { return _type != Config::kOpl2; }
+
+protected:
+ void generateSamples(int16 *buffer, int length);
};
} // End of namespace DOSBox
diff --git a/audio/softsynth/opl/mame.cpp b/audio/softsynth/opl/mame.cpp
index da75ba76ba..696169be09 100644
--- a/audio/softsynth/opl/mame.cpp
+++ b/audio/softsynth/opl/mame.cpp
@@ -31,6 +31,8 @@
#include "mame.h"
+#include "audio/mixer.h"
+#include "common/system.h"
#include "common/textconsole.h"
#include "common/util.h"
@@ -46,15 +48,19 @@ namespace OPL {
namespace MAME {
OPL::~OPL() {
+ stop();
MAME::OPLDestroy(_opl);
_opl = 0;
}
-bool OPL::init(int rate) {
- if (_opl)
+bool OPL::init() {
+ if (_opl) {
+ stopCallbacks();
MAME::OPLDestroy(_opl);
+ }
+
+ _opl = MAME::makeAdLibOPL(g_system->getMixer()->getOutputRate());
- _opl = MAME::makeAdLibOPL(rate);
return (_opl != 0);
}
@@ -74,7 +80,7 @@ void OPL::writeReg(int r, int v) {
MAME::OPLWriteReg(_opl, r, v);
}
-void OPL::readBuffer(int16 *buffer, int length) {
+void OPL::generateSamples(int16 *buffer, int length) {
MAME::YM3812UpdateOne(_opl, buffer, length);
}
diff --git a/audio/softsynth/opl/mame.h b/audio/softsynth/opl/mame.h
index bd479d9e45..67d80bb193 100644
--- a/audio/softsynth/opl/mame.h
+++ b/audio/softsynth/opl/mame.h
@@ -174,14 +174,14 @@ void YM3812UpdateOne(FM_OPL *OPL, int16 *buffer, int length);
FM_OPL *makeAdLibOPL(int rate);
// OPL API implementation
-class OPL : public ::OPL::OPL {
+class OPL : public ::OPL::EmulatedOPL {
private:
FM_OPL *_opl;
public:
OPL() : _opl(0) {}
~OPL();
- bool init(int rate);
+ bool init();
void reset();
void write(int a, int v);
@@ -189,8 +189,10 @@ public:
void writeReg(int r, int v);
- void readBuffer(int16 *buffer, int length);
bool isStereo() const { return false; }
+
+protected:
+ void generateSamples(int16 *buffer, int length);
};
} // End of namespace MAME
diff --git a/audio/timestamp.cpp b/audio/timestamp.cpp
index 1ce971631c..63752812e1 100644
--- a/audio/timestamp.cpp
+++ b/audio/timestamp.cpp
@@ -39,12 +39,10 @@ Timestamp::Timestamp(uint ms, uint fr) {
Timestamp::Timestamp(uint s, uint frames, uint fr) {
assert(fr > 0);
- _secs = s;
+ _secs = s + (frames / fr);
_framerateFactor = 1000 / Common::gcd<uint>(1000, fr);
_framerate = fr * _framerateFactor;
- _numFrames = frames * _framerateFactor;
-
- normalize();
+ _numFrames = (frames % fr) * _framerateFactor;
}
Timestamp Timestamp::convertToFramerate(uint newFramerate) const {
diff --git a/backends/audiocd/sdl/sdl-audiocd.cpp b/backends/audiocd/sdl/sdl-audiocd.cpp
index 5093c03a1c..c7b089af09 100644
--- a/backends/audiocd/sdl/sdl-audiocd.cpp
+++ b/backends/audiocd/sdl/sdl-audiocd.cpp
@@ -24,9 +24,12 @@
#if defined(SDL_BACKEND)
-#include "common/textconsole.h"
#include "backends/audiocd/sdl/sdl-audiocd.h"
+#if !SDL_VERSION_ATLEAST(1, 3, 0)
+
+#include "common/textconsole.h"
+
SdlAudioCDManager::SdlAudioCDManager()
:
_cdrom(0),
@@ -133,4 +136,6 @@ void SdlAudioCDManager::updateCD() {
}
}
+#endif // !SDL_VERSION_ATLEAST(1, 3, 0)
+
#endif
diff --git a/backends/audiocd/sdl/sdl-audiocd.h b/backends/audiocd/sdl/sdl-audiocd.h
index ff98fcdd77..783d4fe0f0 100644
--- a/backends/audiocd/sdl/sdl-audiocd.h
+++ b/backends/audiocd/sdl/sdl-audiocd.h
@@ -27,6 +27,8 @@
#include "backends/platform/sdl/sdl-sys.h"
+#if !SDL_VERSION_ATLEAST(1, 3, 0)
+
/**
* The SDL audio cd manager. Implements real audio cd playback.
*/
@@ -47,4 +49,6 @@ protected:
uint32 _cdEndTime, _cdStopTime;
};
+#endif // !SDL_VERSION_ATLEAST(1, 3, 0)
+
#endif
diff --git a/backends/events/sdl/sdl-events.cpp b/backends/events/sdl/sdl-events.cpp
index 2480e7c370..1e5119dbec 100644
--- a/backends/events/sdl/sdl-events.cpp
+++ b/backends/events/sdl/sdl-events.cpp
@@ -49,22 +49,55 @@
#define JOY_BUT_SPACE 4
#define JOY_BUT_F5 5
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+static uint32 convUTF8ToUTF32(const char *src) {
+ uint32 utf32 = 0;
+
+ char *dst = SDL_iconv_string(
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ "UTF-32BE",
+#else
+ "UTF-32LE",
+#endif
+ "UTF-8", src, SDL_strlen(src) + 1);
+
+ if (dst) {
+ utf32 = *((uint32 *)dst);
+ SDL_free(dst);
+ }
+
+ return utf32;
+}
+#endif
+
SdlEventSource::SdlEventSource()
- : EventSource(), _scrollLock(false), _joystick(0), _lastScreenID(0), _graphicsManager(0) {
+ : EventSource(), _scrollLock(false), _joystick(0), _lastScreenID(0), _graphicsManager(0)
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ , _queuedFakeKeyUp(false), _fakeKeyUp()
+#endif
+ {
// Reset mouse state
memset(&_km, 0, sizeof(_km));
int joystick_num = ConfMan.getInt("joystick_num");
- if (joystick_num > -1) {
+ if (joystick_num >= 0) {
// Initialize SDL joystick subsystem
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1) {
error("Could not initialize SDL: %s", SDL_GetError());
}
// Enable joystick
- if (SDL_NumJoysticks() > 0) {
- debug("Using joystick: %s", SDL_JoystickName(0));
+ if (SDL_NumJoysticks() > joystick_num) {
_joystick = SDL_JoystickOpen(joystick_num);
+ debug("Using joystick: %s",
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ SDL_JoystickName(_joystick)
+#else
+ SDL_JoystickName(joystick_num)
+#endif
+ );
+ } else {
+ warning("Invalid joystick: %d", joystick_num);
}
}
}
@@ -74,21 +107,24 @@ SdlEventSource::~SdlEventSource() {
SDL_JoystickClose(_joystick);
}
-int SdlEventSource::mapKey(SDLKey key, SDLMod mod, Uint16 unicode) {
- if (key >= SDLK_F1 && key <= SDLK_F9) {
+int SdlEventSource::mapKey(SDLKey sdlKey, SDLMod mod, Uint16 unicode) {
+ Common::KeyCode key = SDLToOSystemKeycode(sdlKey);
+
+ if (key >= Common::KEYCODE_F1 && key <= Common::KEYCODE_F9) {
return key - SDLK_F1 + Common::ASCII_F1;
- } else if (key >= SDLK_KP0 && key <= SDLK_KP9) {
- return key - SDLK_KP0 + '0';
- } else if (key >= SDLK_UP && key <= SDLK_PAGEDOWN) {
+ } else if (key >= Common::KEYCODE_KP0 && key <= Common::KEYCODE_KP9) {
+ return key - Common::KEYCODE_KP0 + '0';
+ } else if (key >= Common::KEYCODE_UP && key <= Common::KEYCODE_PAGEDOWN) {
return key;
} else if (unicode) {
return unicode;
} else if (key >= 'a' && key <= 'z' && (mod & KMOD_SHIFT)) {
return key & ~0x20;
- } else if (key >= SDLK_NUMLOCK && key <= SDLK_EURO) {
+ } else if (key >= Common::KEYCODE_NUMLOCK && key <= Common::KEYCODE_EURO) {
return 0;
+ } else {
+ return key;
}
- return key;
}
void SdlEventSource::processMouseEvent(Common::Event &event, int x, int y) {
@@ -171,7 +207,9 @@ void SdlEventSource::handleKbdMouse() {
_km.y_down_count = 1;
}
- SDL_WarpMouse((Uint16)_km.x, (Uint16)_km.y);
+ if (_graphicsManager) {
+ _graphicsManager->getWindow()->warpMouseInWindow((Uint16)_km.x, (Uint16)_km.y);
+ }
}
}
}
@@ -338,7 +376,9 @@ Common::KeyCode SdlEventSource::SDLToOSystemKeycode(const SDLKey key) {
case SDLK_HELP: return Common::KEYCODE_HELP;
case SDLK_PRINT: return Common::KEYCODE_PRINT;
case SDLK_SYSREQ: return Common::KEYCODE_SYSREQ;
+#if !SDL_VERSION_ATLEAST(2, 0, 0)
case SDLK_BREAK: return Common::KEYCODE_BREAK;
+#endif
case SDLK_MENU: return Common::KEYCODE_MENU;
case SDLK_POWER: return Common::KEYCODE_POWER;
case SDLK_UNDO: return Common::KEYCODE_UNDO;
@@ -349,6 +389,16 @@ Common::KeyCode SdlEventSource::SDLToOSystemKeycode(const SDLKey key) {
bool SdlEventSource::pollEvent(Common::Event &event) {
handleKbdMouse();
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ // In case we still need to send a key up event for a key down from a
+ // TEXTINPUT event we do this immediately.
+ if (_queuedFakeKeyUp) {
+ event = _fakeKeyUp;
+ _queuedFakeKeyUp = false;
+ return true;
+ }
+#endif
+
// If the screen changed, send an Common::EVENT_SCREEN_CHANGED
int screenID = ((OSystem_SDL *)g_system)->getGraphicsManager()->getScreenChangeID();
if (screenID != _lastScreenID) {
@@ -385,24 +435,73 @@ bool SdlEventSource::dispatchSDLEvent(SDL_Event &ev, Common::Event &event) {
case SDL_JOYAXISMOTION:
return handleJoyAxisMotion(ev, event);
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ case SDL_MOUSEWHEEL: {
+ Sint32 yDir = ev.wheel.y;
+#if SDL_VERSION_ATLEAST(2, 0, 4)
+ if (ev.wheel.direction == SDL_MOUSEWHEEL_FLIPPED) {
+ yDir *= -1;
+ }
+#endif
+ // HACK: It seems we want the mouse coordinates supplied
+ // with a mouse wheel event. However, SDL2 does not supply
+ // these, thus we use whatever we got last time. It seems
+ // these are always stored in _km.x, _km.y.
+ processMouseEvent(event, _km.x, _km.y);
+ if (yDir < 0) {
+ event.type = Common::EVENT_WHEELDOWN;
+ return true;
+ } else if (yDir > 0) {
+ event.type = Common::EVENT_WHEELUP;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ case SDL_TEXTINPUT: {
+ // When we get a TEXTINPUT event it means we got some user input for
+ // which no KEYDOWN exists. SDL 1.2 introduces a "fake" key down+up
+ // in such cases. We will do the same to mimic it's behavior.
+ event.type = Common::EVENT_KEYDOWN;
+
+ event.kbd = Common::KeyState(Common::KEYCODE_INVALID, convUTF8ToUTF32(ev.text.text), 0);
+
+ SDLModToOSystemKeyFlags(SDL_GetModState(), event);
+ // Set the scroll lock sticky flag
+ if (_scrollLock)
+ event.kbd.flags |= Common::KBD_SCRL;
+
+ // Fake a key up when we have a proper ascii value.
+ _queuedFakeKeyUp = (event.kbd.ascii != 0);
+ _fakeKeyUp = event;
+ _fakeKeyUp.type = Common::EVENT_KEYUP;
+
+ return _queuedFakeKeyUp;
+ }
+
+ case SDL_WINDOWEVENT:
+ switch (ev.window.event) {
+ case SDL_WINDOWEVENT_EXPOSED:
+ if (_graphicsManager)
+ _graphicsManager->notifyVideoExpose();
+ return false;
+
+ case SDL_WINDOWEVENT_RESIZED:
+ return handleResizeEvent(event, ev.window.data1, ev.window.data2);
+
+ default:
+ return false;
+ }
+#else
case SDL_VIDEOEXPOSE:
if (_graphicsManager)
_graphicsManager->notifyVideoExpose();
return false;
case SDL_VIDEORESIZE:
- if (_graphicsManager) {
- _graphicsManager->notifyResize(ev.resize.w, ev.resize.h);
-
- // If the screen changed, send an Common::EVENT_SCREEN_CHANGED
- int screenID = ((OSystem_SDL *)g_system)->getGraphicsManager()->getScreenChangeID();
- if (screenID != _lastScreenID) {
- _lastScreenID = screenID;
- event.type = Common::EVENT_SCREEN_CHANGED;
- return true;
- }
- }
- return false;
+ return handleResizeEvent(event, ev.resize.w, ev.resize.h);
+#endif
case SDL_QUIT:
event.type = Common::EVENT_QUIT;
@@ -427,7 +526,9 @@ bool SdlEventSource::handleKeyDown(SDL_Event &ev, Common::Event &event) {
// Ctrl-m toggles mouse capture
if (event.kbd.hasFlags(Common::KBD_CTRL) && ev.key.keysym.sym == 'm') {
- toggleMouseGrab();
+ if (_graphicsManager) {
+ _graphicsManager->getWindow()->toggleMouseGrab();
+ }
return false;
}
@@ -470,7 +571,7 @@ bool SdlEventSource::handleKeyDown(SDL_Event &ev, Common::Event &event) {
event.type = Common::EVENT_KEYDOWN;
event.kbd.keycode = SDLToOSystemKeycode(ev.key.keysym.sym);
- event.kbd.ascii = mapKey(ev.key.keysym.sym, (SDLMod)ev.key.keysym.mod, (Uint16)ev.key.keysym.unicode);
+ event.kbd.ascii = mapKey(ev.key.keysym.sym, (SDLMod)ev.key.keysym.mod, obtainUnicode(ev.key.keysym));
return true;
}
@@ -514,7 +615,7 @@ bool SdlEventSource::handleKeyUp(SDL_Event &ev, Common::Event &event) {
event.type = Common::EVENT_KEYUP;
event.kbd.keycode = SDLToOSystemKeycode(ev.key.keysym.sym);
- event.kbd.ascii = mapKey(ev.key.keysym.sym, (SDLMod)ev.key.keysym.mod, (Uint16)ev.key.keysym.unicode);
+ event.kbd.ascii = mapKey(ev.key.keysym.sym, (SDLMod)ev.key.keysym.mod, 0);
// Ctrl-Alt-<key> will change the GFX mode
SDLModToOSystemKeyFlags(mod, event);
@@ -750,13 +851,6 @@ bool SdlEventSource::remapKey(SDL_Event &ev, Common::Event &event) {
return false;
}
-void SdlEventSource::toggleMouseGrab() {
- if (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF)
- SDL_WM_GrabInput(SDL_GRAB_ON);
- else
- SDL_WM_GrabInput(SDL_GRAB_OFF);
-}
-
void SdlEventSource::resetKeyboadEmulation(int16 x_max, int16 y_max) {
_km.x_max = x_max;
_km.y_max = y_max;
@@ -764,4 +858,52 @@ void SdlEventSource::resetKeyboadEmulation(int16 x_max, int16 y_max) {
_km.last_time = 0;
}
+bool SdlEventSource::handleResizeEvent(Common::Event &event, int w, int h) {
+ if (_graphicsManager) {
+ _graphicsManager->notifyResize(w, h);
+
+ // If the screen changed, send an Common::EVENT_SCREEN_CHANGED
+ int screenID = ((OSystem_SDL *)g_system)->getGraphicsManager()->getScreenChangeID();
+ if (screenID != _lastScreenID) {
+ _lastScreenID = screenID;
+ event.type = Common::EVENT_SCREEN_CHANGED;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+uint32 SdlEventSource::obtainUnicode(const SDL_keysym keySym) {
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ SDL_Event events[2];
+
+ // In SDL2, the unicode field has been removed from the keysym struct.
+ // Instead a SDL_TEXTINPUT event is generated on key combinations that
+ // generates unicode.
+ // Here we peek into the event queue for the event to see if it exists.
+ int n = SDL_PeepEvents(events, 2, SDL_PEEKEVENT, SDL_KEYDOWN, SDL_TEXTINPUT);
+ // Make sure that the TEXTINPUT event belongs to this KEYDOWN
+ // event and not another pending one.
+ if ((n > 0 && events[0].type == SDL_TEXTINPUT)
+ || (n > 1 && events[0].type != SDL_KEYDOWN && events[1].type == SDL_TEXTINPUT)) {
+ // Remove the text input event we associate with the key press. This
+ // makes sure we never get any SDL_TEXTINPUT events which do "belong"
+ // to SDL_KEYDOWN events.
+ n = SDL_PeepEvents(events, 1, SDL_GETEVENT, SDL_TEXTINPUT, SDL_TEXTINPUT);
+ // This is basically a paranoia safety check because we know there
+ // must be a text input event in the queue.
+ if (n > 0) {
+ return convUTF8ToUTF32(events[0].text.text);
+ } else {
+ return 0;
+ }
+ } else {
+ return 0;
+ }
+#else
+ return keySym.unicode;
+#endif
+}
+
#endif
diff --git a/backends/events/sdl/sdl-events.h b/backends/events/sdl/sdl-events.h
index a1b6d5ec3c..caa60c1354 100644
--- a/backends/events/sdl/sdl-events.h
+++ b/backends/events/sdl/sdl-events.h
@@ -49,11 +49,6 @@ public:
*/
virtual void resetKeyboadEmulation(int16 x_max, int16 y_max);
- /**
- * Toggles mouse input grab
- */
- virtual void toggleMouseGrab();
-
protected:
/** @name Keyboard mouse emulation
* Disabled by fingolfin 2004-12-18.
@@ -130,7 +125,7 @@ protected:
/**
* Maps the ASCII value of key
*/
- virtual int mapKey(SDLKey key, SDLMod mod, Uint16 unicode);
+ int mapKey(SDLKey key, SDLMod mod, Uint16 unicode);
/**
* Configures the key modifiers flags status
@@ -141,6 +136,30 @@ protected:
* Translates SDL key codes to OSystem key codes
*/
Common::KeyCode SDLToOSystemKeycode(const SDLKey key);
+
+ /**
+ * Notify graphics manager of a resize request.
+ */
+ bool handleResizeEvent(Common::Event &event, int w, int h);
+
+ /**
+ * Extracts unicode information for the specific key sym.
+ * May only be used for key down events.
+ */
+ uint32 obtainUnicode(const SDL_keysym keySym);
+
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ /**
+ * Whether _fakeKeyUp contains an event we need to send.
+ */
+ bool _queuedFakeKeyUp;
+
+ /**
+ * A fake key up event when we receive a TEXTINPUT without any previous
+ * KEYDOWN event.
+ */
+ Common::Event _fakeKeyUp;
+#endif
};
#endif
diff --git a/backends/events/symbiansdl/symbiansdl-events.cpp b/backends/events/symbiansdl/symbiansdl-events.cpp
index 36018f1024..b0d2c25302 100644
--- a/backends/events/symbiansdl/symbiansdl-events.cpp
+++ b/backends/events/symbiansdl/symbiansdl-events.cpp
@@ -133,7 +133,9 @@ bool SymbianSdlEventSource::remapKey(SDL_Event &ev, Common::Event &event) {
_currentZone = 0;
event.type = Common::EVENT_MOUSEMOVE;
processMouseEvent(event, _mouseXZone[_currentZone], _mouseYZone[_currentZone]);
- SDL_WarpMouse(event.mouse.x, event.mouse.y);
+ if (_graphicsManager) {
+ _graphicsManager->getWindow()->warpMouseInWindow(event.mouse.x, event.mouse.y);
+ }
}
return true;
diff --git a/backends/fs/amigaos4/amigaos4-fs.cpp b/backends/fs/amigaos4/amigaos4-fs.cpp
index 7bebdf8ce6..6d5b099736 100644
--- a/backends/fs/amigaos4/amigaos4-fs.cpp
+++ b/backends/fs/amigaos4/amigaos4-fs.cpp
@@ -381,15 +381,17 @@ AbstractFSList AmigaOSFilesystemNode::listVolumes() const {
dosList = IDOS->NextDosEntry(dosList, LDF_VOLUMES);
while (dosList) {
if (dosList->dol_Type == DLT_VOLUME &&
- dosList->dol_Name) {
+ dosList->dol_Name &&
+ dosList->dol_Port) {
// The original line was
//if (dosList->dol_Type == DLT_VOLUME &&
//dosList->dol_Name &&
//dosList->dol_Task) {
// which errored using SDK 53.24 with a 'struct dosList' has no member called 'dol_Task'
- // I removed dol_Task because it's not used anywhere else
- // and it neither brought up further errors nor crashes or regressions
+ // The reason for that was that
+ // 1) dol_Task wasn't a task pointer, it is a message port instead
+ // 2) It was redefined to be dol_Port in dos/obsolete.h in afore mentioned SDK
// Copy name to buffer
IDOS->CopyStringBSTRToC(dosList->dol_Name, buffer, MAXPATHLEN);
diff --git a/backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp b/backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp
index 343efa4da6..0b9cc0c7e8 100644
--- a/backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp
+++ b/backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp
@@ -35,8 +35,8 @@ static const OSystem::GraphicsMode s_supportedGraphicsModes[] = {
{0, 0, 0}
};
-DINGUXSdlGraphicsManager::DINGUXSdlGraphicsManager(SdlEventSource *boss)
- : SurfaceSdlGraphicsManager(boss) {
+DINGUXSdlGraphicsManager::DINGUXSdlGraphicsManager(SdlEventSource *boss, SdlWindow *window)
+ : SurfaceSdlGraphicsManager(boss, window) {
}
const OSystem::GraphicsMode *DINGUXSdlGraphicsManager::getSupportedGraphicsModes() const {
@@ -122,7 +122,7 @@ void DINGUXSdlGraphicsManager::initSize(uint w, uint h) {
if (w > 320 || h > 240) {
setGraphicsMode(GFX_HALF);
setGraphicsModeIntern();
- _eventSource->toggleMouseGrab();
+ _window->toggleMouseGrab();
}
_transactionDetails.sizeChanged = true;
diff --git a/backends/graphics/dinguxsdl/dinguxsdl-graphics.h b/backends/graphics/dinguxsdl/dinguxsdl-graphics.h
index fc70e721cf..8a356106ad 100644
--- a/backends/graphics/dinguxsdl/dinguxsdl-graphics.h
+++ b/backends/graphics/dinguxsdl/dinguxsdl-graphics.h
@@ -34,7 +34,7 @@ enum {
class DINGUXSdlGraphicsManager : public SurfaceSdlGraphicsManager {
public:
- DINGUXSdlGraphicsManager(SdlEventSource *boss);
+ DINGUXSdlGraphicsManager(SdlEventSource *boss, SdlWindow *window);
bool hasFeature(OSystem::Feature f);
void setFeatureState(OSystem::Feature f, bool enable);
diff --git a/backends/graphics/gph/gph-graphics.cpp b/backends/graphics/gph/gph-graphics.cpp
index 247e5ed490..65cb3d1d65 100644
--- a/backends/graphics/gph/gph-graphics.cpp
+++ b/backends/graphics/gph/gph-graphics.cpp
@@ -35,8 +35,8 @@ static const OSystem::GraphicsMode s_supportedGraphicsModes[] = {
{0, 0, 0}
};
-GPHGraphicsManager::GPHGraphicsManager(SdlEventSource *sdlEventSource)
- : SurfaceSdlGraphicsManager(sdlEventSource) {
+GPHGraphicsManager::GPHGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window)
+ : SurfaceSdlGraphicsManager(sdlEventSource, window) {
}
const OSystem::GraphicsMode *GPHGraphicsManager::getSupportedGraphicsModes() const {
@@ -141,7 +141,7 @@ void GPHGraphicsManager::initSize(uint w, uint h, const Graphics::PixelFormat *f
if (w > 320 || h > 240) {
setGraphicsMode(GFX_HALF);
setGraphicsModeIntern();
- _eventSource->toggleMouseGrab();
+ _window->toggleMouseGrab();
}
_videoMode.overlayWidth = 320;
diff --git a/backends/graphics/gph/gph-graphics.h b/backends/graphics/gph/gph-graphics.h
index 4a68ea6eed..152d29ddf4 100644
--- a/backends/graphics/gph/gph-graphics.h
+++ b/backends/graphics/gph/gph-graphics.h
@@ -33,7 +33,7 @@ enum {
class GPHGraphicsManager : public SurfaceSdlGraphicsManager {
public:
- GPHGraphicsManager(SdlEventSource *boss);
+ GPHGraphicsManager(SdlEventSource *boss, SdlWindow *window);
bool hasFeature(OSystem::Feature f);
void setFeatureState(OSystem::Feature f, bool enable);
diff --git a/backends/graphics/linuxmotosdl/linuxmotosdl-graphics.cpp b/backends/graphics/linuxmotosdl/linuxmotosdl-graphics.cpp
index 22b271ae1a..52e5b42e8b 100644
--- a/backends/graphics/linuxmotosdl/linuxmotosdl-graphics.cpp
+++ b/backends/graphics/linuxmotosdl/linuxmotosdl-graphics.cpp
@@ -45,8 +45,8 @@ static const OSystem::GraphicsMode s_supportedGraphicsModes[] = {
{0, 0, 0}
};
-LinuxmotoSdlGraphicsManager::LinuxmotoSdlGraphicsManager(SdlEventSource *sdlEventSource)
- : SurfaceSdlGraphicsManager(sdlEventSource) {
+LinuxmotoSdlGraphicsManager::LinuxmotoSdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window)
+ : SurfaceSdlGraphicsManager(sdlEventSource, window) {
}
const OSystem::GraphicsMode *LinuxmotoSdlGraphicsManager::getSupportedGraphicsModes() const {
@@ -134,7 +134,7 @@ void LinuxmotoSdlGraphicsManager::initSize(uint w, uint h) {
if (w > 320 || h > 240) {
setGraphicsMode(GFX_HALF);
setGraphicsModeIntern();
- _eventSource->toggleMouseGrab();
+ _window->toggleMouseGrab();
}
_transactionDetails.sizeChanged = true;
diff --git a/backends/graphics/linuxmotosdl/linuxmotosdl-graphics.h b/backends/graphics/linuxmotosdl/linuxmotosdl-graphics.h
index 8760c5004d..d7a13b1cb4 100644
--- a/backends/graphics/linuxmotosdl/linuxmotosdl-graphics.h
+++ b/backends/graphics/linuxmotosdl/linuxmotosdl-graphics.h
@@ -27,7 +27,7 @@
class LinuxmotoSdlGraphicsManager : public SurfaceSdlGraphicsManager {
public:
- LinuxmotoSdlGraphicsManager(SdlEventSource *sdlEventSource);
+ LinuxmotoSdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window);
virtual void initSize(uint w, uint h);
virtual void setGraphicsModeIntern();
diff --git a/backends/graphics/maemosdl/maemosdl-graphics.cpp b/backends/graphics/maemosdl/maemosdl-graphics.cpp
index 07d6d32d3a..d954333537 100644
--- a/backends/graphics/maemosdl/maemosdl-graphics.cpp
+++ b/backends/graphics/maemosdl/maemosdl-graphics.cpp
@@ -21,16 +21,14 @@
*/
#if defined(MAEMO)
-#include "SDL_syswm.h"
-
#include "common/scummsys.h"
#include "backends/platform/maemo/maemo.h"
#include "backends/events/maemosdl/maemosdl-events.h"
#include "backends/graphics/maemosdl/maemosdl-graphics.h"
-MaemoSdlGraphicsManager::MaemoSdlGraphicsManager(SdlEventSource *sdlEventSource)
- : SurfaceSdlGraphicsManager(sdlEventSource) {
+MaemoSdlGraphicsManager::MaemoSdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window)
+ : SurfaceSdlGraphicsManager(sdlEventSource, window) {
}
bool MaemoSdlGraphicsManager::loadGFXMode() {
diff --git a/backends/graphics/maemosdl/maemosdl-graphics.h b/backends/graphics/maemosdl/maemosdl-graphics.h
index c255e94653..4cb84c81ee 100644
--- a/backends/graphics/maemosdl/maemosdl-graphics.h
+++ b/backends/graphics/maemosdl/maemosdl-graphics.h
@@ -29,7 +29,7 @@
class MaemoSdlGraphicsManager : public SurfaceSdlGraphicsManager {
public:
- MaemoSdlGraphicsManager(SdlEventSource *sdlEventSource);
+ MaemoSdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window);
protected:
virtual bool loadGFXMode();
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index c455c4ce2e..5821856c30 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -49,9 +49,9 @@ OpenGLGraphicsManager::OpenGLGraphicsManager()
_displayWidth(0), _displayHeight(0), _defaultFormat(), _defaultFormatAlpha(),
_gameScreen(nullptr), _gameScreenShakeOffset(0), _overlay(nullptr),
_overlayVisible(false), _cursor(nullptr),
- _cursorX(0), _cursorY(0), _cursorHotspotX(0), _cursorHotspotY(0), _cursorHotspotXScaled(0),
- _cursorHotspotYScaled(0), _cursorWidthScaled(0), _cursorHeightScaled(0), _cursorKeyColor(0),
- _cursorVisible(false), _cursorDontScale(false), _cursorPaletteEnabled(false)
+ _cursorX(0), _cursorY(0), _cursorDisplayX(0),_cursorDisplayY(0), _cursorHotspotX(0), _cursorHotspotY(0),
+ _cursorHotspotXScaled(0), _cursorHotspotYScaled(0), _cursorWidthScaled(0), _cursorHeightScaled(0),
+ _cursorKeyColor(0), _cursorVisible(false), _cursorDontScale(false), _cursorPaletteEnabled(false)
#ifdef USE_OSD
, _osdAlpha(0), _osdFadeStartTime(0), _osd(nullptr)
#endif
@@ -351,7 +351,7 @@ void OpenGLGraphicsManager::updateScreen() {
return;
}
- // Clear the screen buffer
+ // Clear the screen buffer.
GLCALL(glClear(GL_COLOR_BUFFER_BIT));
const GLfloat shakeOffset = _gameScreenShakeOffset * (GLfloat)_displayHeight / _gameScreen->getHeight();
@@ -370,12 +370,42 @@ void OpenGLGraphicsManager::updateScreen() {
// visible.
const GLfloat cursorOffset = _overlayVisible ? 0 : shakeOffset;
- _cursor->draw(_cursorX - _cursorHotspotXScaled, _cursorY - _cursorHotspotYScaled + cursorOffset,
+ _cursor->draw(_cursorDisplayX - _cursorHotspotXScaled,
+ _cursorDisplayY - _cursorHotspotYScaled + cursorOffset,
_cursorWidthScaled, _cursorHeightScaled);
}
+ // Fourth step: Draw black borders around the game screen when no overlay
+ // is visible. This makes sure that the mouse cursor etc. is only drawn
+ // in the actual game screen area in this case.
+ if (!_overlayVisible) {
+ GLCALL(glColor4f(0.0f, 0.0f, 0.0f, 1.0f));
+
+ GLCALL(glDisable(GL_TEXTURE_2D));
+ GLCALL(glDisableClientState(GL_TEXTURE_COORD_ARRAY));
+
+ // Top border.
+ drawRect(0, 0, _outputScreenWidth, _displayY);
+
+ // Left border.
+ drawRect(0, 0, _displayX, _outputScreenHeight);
+
+ // Bottom border.
+ const int y = _displayY + _displayHeight;
+ drawRect(0, y, _outputScreenWidth, _outputScreenHeight - y);
+
+ // Right border.
+ const int x = _displayX + _displayWidth;
+ drawRect(x, 0, _outputScreenWidth - x, _outputScreenHeight);
+
+ GLCALL(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
+ GLCALL(glEnable(GL_TEXTURE_2D));
+
+ GLCALL(glColor4f(1.0f, 1.0f, 1.0f, 1.0f));
+ }
+
#ifdef USE_OSD
- // Fourth step: Draw the OSD.
+ // Fifth step: Draw the OSD.
if (_osdAlpha > 0) {
Common::StackLock lock(_osdMutex);
@@ -435,10 +465,16 @@ int16 OpenGLGraphicsManager::getOverlayHeight() {
void OpenGLGraphicsManager::showOverlay() {
_overlayVisible = true;
+
+ // Update cursor position.
+ setMousePosition(_cursorX, _cursorY);
}
void OpenGLGraphicsManager::hideOverlay() {
_overlayVisible = false;
+
+ // Update cursor position.
+ setMousePosition(_cursorX, _cursorY);
}
Graphics::PixelFormat OpenGLGraphicsManager::getOverlayFormat() const {
@@ -892,8 +928,8 @@ void OpenGLGraphicsManager::adjustMousePosition(int16 &x, int16 &y) {
const int16 width = _gameScreen->getWidth();
const int16 height = _gameScreen->getHeight();
- x = (x * width) / _displayWidth;
- y = (y * height) / _displayHeight;
+ x = (x * width) / (int)_displayWidth;
+ y = (y * height) / (int)_displayHeight;
// Make sure we only supply valid coordinates.
x = CLIP<int16>(x, 0, width - 1);
@@ -901,6 +937,19 @@ void OpenGLGraphicsManager::adjustMousePosition(int16 &x, int16 &y) {
}
}
+void OpenGLGraphicsManager::setMousePosition(int x, int y) {
+ _cursorX = x;
+ _cursorY = y;
+
+ if (_overlayVisible) {
+ _cursorDisplayX = x;
+ _cursorDisplayY = y;
+ } else {
+ _cursorDisplayX = CLIP<int>(x, _displayX, _displayX + _displayWidth - 1);
+ _cursorDisplayY = CLIP<int>(y, _displayY, _displayY + _displayHeight - 1);
+ }
+}
+
Texture *OpenGLGraphicsManager::createTexture(const Graphics::PixelFormat &format, bool wantAlpha) {
GLenum glIntFormat, glFormat, glType;
if (format.bytesPerPixel == 1) {
@@ -1046,6 +1095,9 @@ void OpenGLGraphicsManager::recalculateDisplayArea() {
// We center the screen in the middle for now.
_displayX = (_outputScreenWidth - _displayWidth ) / 2;
_displayY = (_outputScreenHeight - _displayHeight) / 2;
+
+ // Update the cursor position to adjust for new display area.
+ setMousePosition(_cursorX, _cursorY);
}
void OpenGLGraphicsManager::updateCursorPalette() {
@@ -1163,4 +1215,20 @@ void OpenGLGraphicsManager::saveScreenshot(const Common::String &filename) const
delete[] pixels;
}
+void OpenGLGraphicsManager::drawRect(GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
+ if (w < 0 || h < 0) {
+ return;
+ }
+
+ const GLfloat vertices[4*2] = {
+ x, y,
+ x + w, y,
+ x, y + h,
+ x + w, y + h
+ };
+ GLCALL(glVertexPointer(2, GL_FLOAT, 0, vertices));
+
+ GLCALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
+}
+
} // End of namespace OpenGL
diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h
index dde21533b0..cec970e0cc 100644
--- a/backends/graphics/opengl/opengl-graphics.h
+++ b/backends/graphics/opengl/opengl-graphics.h
@@ -155,7 +155,7 @@ protected:
* @param x X coordinate in physical coordinates.
* @param y Y coordinate in physical coordinates.
*/
- void setMousePosition(int x, int y) { _cursorX = x; _cursorY = y; }
+ void setMousePosition(int x, int y);
/**
* Query the mouse position in physical coordinates.
@@ -394,6 +394,16 @@ private:
int _cursorY;
/**
+ * X coordinate used for drawing the cursor.
+ */
+ int _cursorDisplayX;
+
+ /**
+ * Y coordinate used for drawing the cursor.
+ */
+ int _cursorDisplayY;
+
+ /**
* The X offset for the cursor hotspot in unscaled coordinates.
*/
int _cursorHotspotX;
@@ -454,6 +464,11 @@ private:
*/
byte _cursorPalette[3 * 256];
+ /**
+ * Draws a rectangle
+ */
+ void drawRect(GLfloat x, GLfloat y, GLfloat w, GLfloat h);
+
#ifdef USE_OSD
//
// OSD
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp
index b028cd5b1a..a2b172f14a 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.cpp
+++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp
@@ -28,8 +28,13 @@
#include "common/translation.h"
#endif
-OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint desktopHeight, SdlEventSource *eventSource)
- : SdlGraphicsManager(eventSource), _lastVideoModeLoad(0), _hwScreen(nullptr), _lastRequestedWidth(0), _lastRequestedHeight(0),
+OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint desktopHeight, SdlEventSource *eventSource, SdlWindow *window)
+ : SdlGraphicsManager(eventSource, window), _lastRequestedHeight(0),
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ _glContext(),
+#else
+ _lastVideoModeLoad(0), _hwScreen(nullptr),
+#endif
_graphicsScale(2), _ignoreLoadVideoMode(false), _gotResize(false), _wantsFullScreen(false), _ignoreResizeEvents(0),
_desiredFullscreenWidth(0), _desiredFullscreenHeight(0) {
// Setup OpenGL attributes for SDL
@@ -40,16 +45,40 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
// Retrieve a list of working fullscreen modes
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ const int numModes = SDL_GetNumDisplayModes(0);
+ for (int i = 0; i < numModes; ++i) {
+ SDL_DisplayMode mode;
+ if (SDL_GetDisplayMode(0, i, &mode)) {
+ continue;
+ }
+
+ _fullscreenVideoModes.push_back(VideoMode(mode.w, mode.h));
+ }
+#else
const SDL_Rect *const *availableModes = SDL_ListModes(NULL, SDL_OPENGL | SDL_FULLSCREEN);
- if (availableModes != (void *)-1) {
+ // TODO: NULL means that there are no fullscreen modes supported. We
+ // should probably use this information and disable any fullscreen support
+ // in this case.
+ if (availableModes != NULL && availableModes != (void *)-1) {
for (;*availableModes; ++availableModes) {
const SDL_Rect *mode = *availableModes;
_fullscreenVideoModes.push_back(VideoMode(mode->w, mode->h));
}
+ }
+#endif
+
+ // Sort the modes in ascending order.
+ Common::sort(_fullscreenVideoModes.begin(), _fullscreenVideoModes.end());
- // Sort the modes in ascending order.
- Common::sort(_fullscreenVideoModes.begin(), _fullscreenVideoModes.end());
+ // Strip duplicates in video modes.
+ for (uint i = 0; i + 1 < _fullscreenVideoModes.size();) {
+ if (_fullscreenVideoModes[i] == _fullscreenVideoModes[i + 1]) {
+ _fullscreenVideoModes.remove_at(i);
+ } else {
+ ++i;
+ }
}
// In case SDL is fine with every mode we will force the desktop mode.
@@ -108,7 +137,7 @@ void OpenGLSdlGraphicsManager::setFeatureState(OSystem::Feature f, bool enable)
case OSystem::kFeatureIconifyWindow:
if (enable) {
- SDL_WM_IconifyWindow();
+ _window->iconifyWindow();
}
break;
@@ -120,11 +149,19 @@ void OpenGLSdlGraphicsManager::setFeatureState(OSystem::Feature f, bool enable)
bool OpenGLSdlGraphicsManager::getFeatureState(OSystem::Feature f) {
switch (f) {
case OSystem::kFeatureFullscreenMode:
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ if (_window) {
+ return (SDL_GetWindowFlags(_window->getSDLWindow()) & SDL_WINDOW_FULLSCREEN) != 0;
+ } else {
+ return _wantsFullScreen;
+ }
+#else
if (_hwScreen) {
return (_hwScreen->flags & SDL_FULLSCREEN) != 0;
} else {
return _wantsFullScreen;
}
+#endif
default:
return OpenGLGraphicsManager::getFeatureState(f);
@@ -201,13 +238,20 @@ void OpenGLSdlGraphicsManager::updateScreen() {
OpenGLGraphicsManager::updateScreen();
// Swap OpenGL buffers
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ SDL_GL_SwapWindow(_window->getSDLWindow());
+#else
SDL_GL_SwapBuffers();
+#endif
}
void OpenGLSdlGraphicsManager::notifyVideoExpose() {
}
void OpenGLSdlGraphicsManager::notifyResize(const uint width, const uint height) {
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ setActualScreenSize(width, height);
+#else
if (!_ignoreResizeEvents && _hwScreen && !(_hwScreen->flags & SDL_FULLSCREEN)) {
// We save that we handled a resize event here. We need to know this
// so we do not overwrite the users requested window size whenever we
@@ -218,6 +262,7 @@ void OpenGLSdlGraphicsManager::notifyResize(const uint width, const uint height)
g_system->quit();
}
}
+#endif
}
void OpenGLSdlGraphicsManager::transformMouseCoordinates(Common::Point &point) {
@@ -229,7 +274,7 @@ void OpenGLSdlGraphicsManager::notifyMousePos(Common::Point mouse) {
}
void OpenGLSdlGraphicsManager::setInternalMousePosition(int x, int y) {
- SDL_WarpMouse(x, y);
+ _window->warpMouseInWindow(x, y);
}
bool OpenGLSdlGraphicsManager::loadVideoMode(uint requestedWidth, uint requestedHeight, const Graphics::PixelFormat &format) {
@@ -300,6 +345,58 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
height = _desiredFullscreenHeight;
}
+ // This is pretty confusing since RGBA8888 talks about the memory
+ // layout here. This is a different logical layout depending on
+ // whether we run on little endian or big endian. However, we can
+ // only safely assume that RGBA8888 in memory layout is supported.
+ // Thus, we chose this one.
+ const Graphics::PixelFormat rgba8888 =
+#ifdef SCUMM_LITTLE_ENDIAN
+ Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24);
+#else
+ Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
+#endif
+
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ if (_glContext) {
+ notifyContextDestroy();
+
+ SDL_GL_DeleteContext(_glContext);
+ _glContext = nullptr;
+ }
+
+ _window->destroyWindow();
+
+ uint32 flags = SDL_WINDOW_OPENGL;
+ if (_wantsFullScreen) {
+ flags |= SDL_WINDOW_FULLSCREEN;
+ } else {
+ flags |= SDL_WINDOW_RESIZABLE;
+ }
+
+ if (!_window->createWindow(width, height, flags)) {
+ // We treat fullscreen requests as a "hint" for now. This means in
+ // case it is not available we simply ignore it.
+ if (_wantsFullScreen) {
+ _window->createWindow(width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
+ }
+
+ if (!_window->getSDLWindow()) {
+ return false;
+ }
+ }
+
+ _glContext = SDL_GL_CreateContext(_window->getSDLWindow());
+ if (!_glContext) {
+ return false;
+ }
+
+ notifyContextCreate(rgba8888, rgba8888);
+ int actualWidth, actualHeight;
+ getWindowDimensions(&actualWidth, &actualHeight);
+ setActualScreenSize(actualWidth, actualHeight);
+ return true;
+#else
// WORKAROUND: Working around infamous SDL bugs when switching
// resolutions too fast. This might cause the event system to supply
// incorrect mouse position events otherwise.
@@ -341,17 +438,6 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
_lastVideoModeLoad = SDL_GetTicks();
if (_hwScreen) {
- // This is pretty confusing since RGBA8888 talks about the memory
- // layout here. This is a different logical layout depending on
- // whether we run on little endian or big endian. However, we can
- // only safely assume that RGBA8888 in memory layout is supported.
- // Thus, we chose this one.
- const Graphics::PixelFormat rgba8888 =
-#ifdef SCUMM_LITTLE_ENDIAN
- Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24);
-#else
- Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
-#endif
notifyContextCreate(rgba8888, rgba8888);
setActualScreenSize(_hwScreen->w, _hwScreen->h);
}
@@ -363,6 +449,21 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
_ignoreResizeEvents = 10;
return _hwScreen != nullptr;
+#endif
+}
+
+void OpenGLSdlGraphicsManager::getWindowDimensions(int *width, int *height) {
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ SDL_GetWindowSize(_window->getSDLWindow(), width, height);
+#else
+ if (width) {
+ *width = _hwScreen->w;
+ }
+
+ if (height) {
+ *height = _hwScreen->h;
+ }
+#endif
}
bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) {
@@ -456,7 +557,9 @@ bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) {
// Calculate the next scaling setting. We approximate the
// current scale setting in case the user resized the
// window. Then we apply the direction change.
- _graphicsScale = MAX<int>(_hwScreen->w / _lastRequestedWidth, _hwScreen->h / _lastRequestedHeight);
+ int windowWidth = 0, windowHeight = 0;
+ getWindowDimensions(&windowWidth, &windowHeight);
+ _graphicsScale = MAX<int>(windowWidth / _lastRequestedWidth, windowHeight / _lastRequestedHeight);
_graphicsScale = MAX<int>(_graphicsScale + direction, 1);
// Since we overwrite a user resize here we reset its
@@ -472,7 +575,9 @@ bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) {
}
#ifdef USE_OSD
- const Common::String osdMsg = Common::String::format("Resolution: %dx%d", _hwScreen->w, _hwScreen->h);
+ int windowWidth = 0, windowHeight = 0;
+ getWindowDimensions(&windowWidth, &windowHeight);
+ const Common::String osdMsg = Common::String::format("Resolution: %dx%d", windowWidth, windowHeight);
displayMessageOnOSD(osdMsg.c_str());
#endif
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.h b/backends/graphics/openglsdl/openglsdl-graphics.h
index 9934ca79e2..845880eb14 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.h
+++ b/backends/graphics/openglsdl/openglsdl-graphics.h
@@ -32,7 +32,7 @@
class OpenGLSdlGraphicsManager : public OpenGL::OpenGLGraphicsManager, public SdlGraphicsManager, public Common::EventObserver {
public:
- OpenGLSdlGraphicsManager(uint desktopWidth, uint desktopHeight, SdlEventSource *eventSource);
+ OpenGLSdlGraphicsManager(uint desktopWidth, uint desktopHeight, SdlEventSource *eventSource, SdlWindow *window);
virtual ~OpenGLSdlGraphicsManager();
// GraphicsManager API
@@ -68,8 +68,14 @@ protected:
private:
bool setupMode(uint width, uint height);
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ SDL_GLContext _glContext;
+#else
uint32 _lastVideoModeLoad;
SDL_Surface *_hwScreen;
+#endif
+
+ void getWindowDimensions(int *width, int *height);
uint _lastRequestedWidth;
uint _lastRequestedHeight;
diff --git a/backends/graphics/openpandora/op-graphics.cpp b/backends/graphics/openpandora/op-graphics.cpp
index 1ded1614de..f4c9dc16cc 100644
--- a/backends/graphics/openpandora/op-graphics.cpp
+++ b/backends/graphics/openpandora/op-graphics.cpp
@@ -32,8 +32,8 @@
static SDL_Cursor *hiddenCursor;
-OPGraphicsManager::OPGraphicsManager(SdlEventSource *sdlEventSource)
- : SurfaceSdlGraphicsManager(sdlEventSource) {
+OPGraphicsManager::OPGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window)
+ : SurfaceSdlGraphicsManager(sdlEventSource, window) {
}
bool OPGraphicsManager::loadGFXMode() {
diff --git a/backends/graphics/openpandora/op-graphics.h b/backends/graphics/openpandora/op-graphics.h
index 8b498d632b..50994072bb 100644
--- a/backends/graphics/openpandora/op-graphics.h
+++ b/backends/graphics/openpandora/op-graphics.h
@@ -32,7 +32,7 @@ enum {
class OPGraphicsManager : public SurfaceSdlGraphicsManager {
public:
- OPGraphicsManager(SdlEventSource *sdlEventSource);
+ OPGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window);
bool loadGFXMode();
void unloadGFXMode();
diff --git a/backends/graphics/samsungtvsdl/samsungtvsdl-graphics.cpp b/backends/graphics/samsungtvsdl/samsungtvsdl-graphics.cpp
index 3603d8a861..0c98462891 100644
--- a/backends/graphics/samsungtvsdl/samsungtvsdl-graphics.cpp
+++ b/backends/graphics/samsungtvsdl/samsungtvsdl-graphics.cpp
@@ -28,8 +28,8 @@
#include "backends/events/samsungtvsdl/samsungtvsdl-events.h"
#include "backends/graphics/samsungtvsdl/samsungtvsdl-graphics.h"
-SamsungTVSdlGraphicsManager::SamsungTVSdlGraphicsManager(SdlEventSource *sdlEventSource)
- : SurfaceSdlGraphicsManager(sdlEventSource) {
+SamsungTVSdlGraphicsManager::SamsungTVSdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window)
+ : SurfaceSdlGraphicsManager(sdlEventSource, window) {
}
bool SamsungTVSdlGraphicsManager::hasFeature(OSystem::Feature f) {
diff --git a/backends/graphics/samsungtvsdl/samsungtvsdl-graphics.h b/backends/graphics/samsungtvsdl/samsungtvsdl-graphics.h
index 15ba3dca48..8699d77bc8 100644
--- a/backends/graphics/samsungtvsdl/samsungtvsdl-graphics.h
+++ b/backends/graphics/samsungtvsdl/samsungtvsdl-graphics.h
@@ -29,7 +29,7 @@
class SamsungTVSdlGraphicsManager : public SurfaceSdlGraphicsManager {
public:
- SamsungTVSdlGraphicsManager(SdlEventSource *sdlEventSource);
+ SamsungTVSdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window);
bool hasFeature(OSystem::Feature f);
void setFeatureState(OSystem::Feature f, bool enable);
diff --git a/backends/graphics/sdl/sdl-graphics.cpp b/backends/graphics/sdl/sdl-graphics.cpp
index b5e49fa397..a13ca45477 100644
--- a/backends/graphics/sdl/sdl-graphics.cpp
+++ b/backends/graphics/sdl/sdl-graphics.cpp
@@ -22,10 +22,12 @@
#include "backends/graphics/sdl/sdl-graphics.h"
+#include "backends/platform/sdl/sdl-sys.h"
#include "backends/events/sdl/sdl-events.h"
+#include "common/textconsole.h"
-SdlGraphicsManager::SdlGraphicsManager(SdlEventSource *source)
- : _eventSource(source) {
+SdlGraphicsManager::SdlGraphicsManager(SdlEventSource *source, SdlWindow *window)
+ : _eventSource(source), _window(window) {
}
SdlGraphicsManager::~SdlGraphicsManager() {
@@ -38,3 +40,36 @@ void SdlGraphicsManager::activateManager() {
void SdlGraphicsManager::deactivateManager() {
_eventSource->setGraphicsManager(0);
}
+
+SdlGraphicsManager::State SdlGraphicsManager::getState() {
+ State state;
+
+ state.screenWidth = getWidth();
+ state.screenHeight = getHeight();
+ state.aspectRatio = getFeatureState(OSystem::kFeatureAspectRatioCorrection);
+ state.fullscreen = getFeatureState(OSystem::kFeatureFullscreenMode);
+ state.cursorPalette = getFeatureState(OSystem::kFeatureCursorPalette);
+#ifdef USE_RGB_COLOR
+ state.pixelFormat = getScreenFormat();
+#endif
+ return state;
+}
+
+bool SdlGraphicsManager::setState(const State &state) {
+ beginGFXTransaction();
+#ifdef USE_RGB_COLOR
+ initSize(state.screenWidth, state.screenHeight, &state.pixelFormat);
+#else
+ initSize(state.screenWidth, state.screenHeight, 0);
+#endif
+ setFeatureState(OSystem::kFeatureAspectRatioCorrection, state.aspectRatio);
+ setFeatureState(OSystem::kFeatureFullscreenMode, state.fullscreen);
+ setFeatureState(OSystem::kFeatureCursorPalette, state.cursorPalette);
+
+ if (endGFXTransaction() != OSystem::kTransactionSuccess) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
diff --git a/backends/graphics/sdl/sdl-graphics.h b/backends/graphics/sdl/sdl-graphics.h
index 3ef540708a..7f8790a9b4 100644
--- a/backends/graphics/sdl/sdl-graphics.h
+++ b/backends/graphics/sdl/sdl-graphics.h
@@ -24,6 +24,7 @@
#define BACKENDS_GRAPHICS_SDL_SDLGRAPHICS_H
#include "backends/graphics/graphics.h"
+#include "backends/platform/sdl/sdl-window.h"
#include "common/rect.h"
@@ -36,7 +37,7 @@ class SdlEventSource;
*/
class SdlGraphicsManager : virtual public GraphicsManager {
public:
- SdlGraphicsManager(SdlEventSource *source);
+ SdlGraphicsManager(SdlEventSource *source, SdlWindow *window);
virtual ~SdlGraphicsManager();
/**
@@ -91,8 +92,39 @@ public:
*/
virtual void notifyMousePos(Common::Point mouse) = 0;
+ /**
+ * A (subset) of the graphic manager's state. This is used when switching
+ * between different SDL graphic managers on runtime.
+ */
+ struct State {
+ int screenWidth, screenHeight;
+ bool aspectRatio;
+ bool fullscreen;
+ bool cursorPalette;
+
+#ifdef USE_RGB_COLOR
+ Graphics::PixelFormat pixelFormat;
+#endif
+ };
+
+ /**
+ * Queries the current state of the graphic manager.
+ */
+ State getState();
+
+ /**
+ * Setup a basic state of the graphic manager.
+ */
+ bool setState(const State &state);
+
+ /**
+ * Queries the SDL window.
+ */
+ SdlWindow *getWindow() const { return _window; }
+
protected:
SdlEventSource *_eventSource;
+ SdlWindow *_window;
};
#endif
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index 7f3c99fcea..9cb14525ee 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -116,13 +116,19 @@ static AspectRatio getDesiredAspectRatio() {
}
#endif
-SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSource)
+SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window)
:
- SdlGraphicsManager(sdlEventSource),
+ SdlGraphicsManager(sdlEventSource, window),
#ifdef USE_OSD
_osdSurface(0), _osdAlpha(SDL_ALPHA_TRANSPARENT), _osdFadeStartTime(0),
#endif
- _hwscreen(0), _screen(0), _tmpscreen(0),
+ _hwscreen(0),
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ _renderer(nullptr), _screenTexture(nullptr),
+#else
+ _originalBitsPerPixel(0),
+#endif
+ _screen(0), _tmpscreen(0),
#ifdef USE_RGB_COLOR
_screenFormat(Graphics::PixelFormat::createFormatCLUT8()),
_cursorFormat(Graphics::PixelFormat::createFormatCLUT8()),
@@ -235,7 +241,7 @@ void SurfaceSdlGraphicsManager::setFeatureState(OSystem::Feature f, bool enable)
break;
case OSystem::kFeatureIconifyWindow:
if (enable)
- SDL_WM_IconifyWindow();
+ _window->iconifyWindow();
break;
default:
break;
@@ -681,12 +687,22 @@ static void fixupResolutionForAspectRatio(AspectRatio desiredAspectRatio, int &w
const int w = width;
const int h = height;
+ int bestW = 0, bestH = 0;
+ uint bestMetric = (uint)-1; // Metric is wasted space
+
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ const int numModes = SDL_GetNumDisplayModes(0);
+ SDL_DisplayMode modeData, *mode = &modeData;
+ for (int i = 0; i < numModes; ++i) {
+ if (SDL_GetDisplayMode(0, i, &modeData)) {
+ continue;
+ }
+#else
SDL_Rect const* const*availableModes = SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_SWSURFACE); //TODO : Maybe specify a pixel format
assert(availableModes);
- const SDL_Rect *bestMode = NULL;
- uint bestMetric = (uint)-1; // Metric is wasted space
while (const SDL_Rect *mode = *availableModes++) {
+#endif
if (mode->w < w)
continue;
if (mode->h < h)
@@ -699,15 +715,23 @@ static void fixupResolutionForAspectRatio(AspectRatio desiredAspectRatio, int &w
continue;
bestMetric = metric;
- bestMode = mode;
+ bestW = mode->w;
+ bestH = mode->h;
+
+ // Make editors a bit more happy by having the same amount of closing as
+ // opening curley braces.
+#if SDL_VERSION_ATLEAST(2, 0, 0)
}
+#else
+ }
+#endif
- if (!bestMode) {
+ if (!bestW || !bestH) {
warning("Unable to enforce the desired aspect ratio");
return;
}
- width = bestMode->w;
- height = bestMode->h;
+ width = bestW;
+ height = bestH;
}
bool SurfaceSdlGraphicsManager::loadGFXMode() {
@@ -774,7 +798,15 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
_hwscreen = g_eventRec.getSurface(_videoMode.hardwareWidth, _videoMode.hardwareHeight);
} else
#endif
- {
+ {
+ // Save the original bpp to be able to restore the video mode on unload
+#if !SDL_VERSION_ATLEAST(2, 0, 0)
+ if (_originalBitsPerPixel == 0) {
+ const SDL_VideoInfo *videoInfo = SDL_GetVideoInfo();
+ _originalBitsPerPixel = videoInfo->vfmt->BitsPerPixel;
+ }
+#endif
+
_hwscreen = SDL_SetVideoMode(_videoMode.hardwareWidth, _videoMode.hardwareHeight, 16,
_videoMode.fullscreen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE
);
@@ -876,6 +908,10 @@ void SurfaceSdlGraphicsManager::unloadGFXMode() {
_screen = NULL;
}
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ deinitializeRenderer();
+#endif
+
if (_hwscreen) {
SDL_FreeSurface(_hwscreen);
_hwscreen = NULL;
@@ -903,6 +939,13 @@ void SurfaceSdlGraphicsManager::unloadGFXMode() {
}
#endif
DestroyScalers();
+
+#if !SDL_VERSION_ATLEAST(2, 0, 0)
+ // Reset video mode to original
+ // This will ensure that any new graphic manager will use the initial BPP when listing available modes
+ if (_originalBitsPerPixel != 0)
+ SDL_SetVideoMode(_videoMode.screenWidth, _videoMode.screenHeight, _originalBitsPerPixel, _videoMode.fullscreen ? (SDL_FULLSCREEN | SDL_SWSURFACE) : SDL_SWSURFACE);
+#endif
}
bool SurfaceSdlGraphicsManager::hotswapGFXMode() {
@@ -1443,6 +1486,9 @@ void SurfaceSdlGraphicsManager::setPalette(const byte *colors, uint start, uint
base[i].r = b[0];
base[i].g = b[1];
base[i].b = b[2];
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ base[i].a = 255;
+#endif
}
if (start < _paletteDirtyStart)
@@ -1481,6 +1527,9 @@ void SurfaceSdlGraphicsManager::setCursorPalette(const byte *colors, uint start,
base[i].r = b[0];
base[i].g = b[1];
base[i].b = b[2];
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ base[i].a = 255;
+#endif
}
_cursorPaletteDisabled = false;
@@ -1710,7 +1759,7 @@ void SurfaceSdlGraphicsManager::warpMouse(int x, int y) {
int y1 = y;
// Don't change actual mouse position, when mouse is outside of our window (in case of windowed mode)
- if (!(SDL_GetAppState( ) & SDL_APPMOUSEFOCUS)) {
+ if (!_window->hasMouseFocus()) {
setMousePos(x, y); // but change game cursor position
return;
}
@@ -1720,9 +1769,9 @@ void SurfaceSdlGraphicsManager::warpMouse(int x, int y) {
if (_mouseCurState.x != x || _mouseCurState.y != y) {
if (!_overlayVisible)
- SDL_WarpMouse(x * _videoMode.scaleFactor, y1 * _videoMode.scaleFactor);
+ _window->warpMouseInWindow(x * _videoMode.scaleFactor, y1 * _videoMode.scaleFactor);
else
- SDL_WarpMouse(x, y1);
+ _window->warpMouseInWindow(x, y1);
// SDL_WarpMouse() generates a mouse movement event, so
// setMousePos() would be called eventually. However, the
@@ -2317,4 +2366,52 @@ void SurfaceSdlGraphicsManager::notifyMousePos(Common::Point mouse) {
setMousePos(mouse.x, mouse.y);
}
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+void SurfaceSdlGraphicsManager::deinitializeRenderer() {
+ SDL_DestroyTexture(_screenTexture);
+ _screenTexture = nullptr;
+
+ SDL_DestroyRenderer(_renderer);
+ _renderer = nullptr;
+
+ _window->destroyWindow();
+}
+
+SDL_Surface *SurfaceSdlGraphicsManager::SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags) {
+ deinitializeRenderer();
+
+ if (!_window->createWindow(width, height, (flags & SDL_FULLSCREEN) ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0)) {
+ return nullptr;
+ }
+
+ _renderer = SDL_CreateRenderer(_window->getSDLWindow(), -1, 0);
+ if (!_renderer) {
+ deinitializeRenderer();
+ return nullptr;
+ }
+
+ _screenTexture = SDL_CreateTexture(_renderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, width, height);
+ if (!_screenTexture) {
+ deinitializeRenderer();
+ return nullptr;
+ }
+
+ SDL_Surface *screen = SDL_CreateRGBSurface(0, width, height, 16, 0xF800, 0x7E0, 0x1F, 0);
+ if (!screen) {
+ deinitializeRenderer();
+ return nullptr;
+ } else {
+ return screen;
+ }
+}
+
+void SurfaceSdlGraphicsManager::SDL_UpdateRects(SDL_Surface *screen, int numrects, SDL_Rect *rects) {
+ SDL_UpdateTexture(_screenTexture, nullptr, screen->pixels, screen->pitch);
+
+ SDL_RenderClear(_renderer);
+ SDL_RenderCopy(_renderer, _screenTexture, NULL, NULL);
+ SDL_RenderPresent(_renderer);
+}
+#endif // SDL_VERSION_ATLEAST(2, 0, 0)
+
#endif
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.h b/backends/graphics/surfacesdl/surfacesdl-graphics.h
index 49bd66b3e5..2431ce8664 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.h
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.h
@@ -77,7 +77,7 @@ public:
*/
class SurfaceSdlGraphicsManager : public SdlGraphicsManager, public Common::EventObserver {
public:
- SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSource);
+ SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window);
virtual ~SurfaceSdlGraphicsManager();
virtual void activateManager();
@@ -166,6 +166,17 @@ protected:
/** Hardware screen */
SDL_Surface *_hwscreen;
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ /* SDL2 features a different API for 2D graphics. We create a wrapper
+ * around this API to keep the code paths as close as possible. */
+ SDL_Renderer *_renderer;
+ SDL_Texture *_screenTexture;
+ void deinitializeRenderer();
+
+ SDL_Surface *SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags);
+ void SDL_UpdateRects(SDL_Surface *screen, int numrects, SDL_Rect *rects);
+#endif
+
/** Unseen game screen */
SDL_Surface *_screen;
#ifdef USE_RGB_COLOR
@@ -225,6 +236,9 @@ protected:
};
VideoState _videoMode, _oldVideoMode;
+ // Original BPP to restore the video mode on unload
+ uint8 _originalBitsPerPixel;
+
/** Force full redraw on next updateScreen */
bool _forceFull;
diff --git a/backends/graphics/symbiansdl/symbiansdl-graphics.cpp b/backends/graphics/symbiansdl/symbiansdl-graphics.cpp
index e339fecd1c..c17cfd5efa 100644
--- a/backends/graphics/symbiansdl/symbiansdl-graphics.cpp
+++ b/backends/graphics/symbiansdl/symbiansdl-graphics.cpp
@@ -27,8 +27,8 @@
#include "backends/graphics/symbiansdl/symbiansdl-graphics.h"
#include "backends/platform/symbian/src/SymbianActions.h"
-SymbianSdlGraphicsManager::SymbianSdlGraphicsManager(SdlEventSource *sdlEventSource)
- : SurfaceSdlGraphicsManager(sdlEventSource) {
+SymbianSdlGraphicsManager::SymbianSdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window)
+ : SurfaceSdlGraphicsManager(sdlEventSource, window) {
}
int SymbianSdlGraphicsManager::getDefaultGraphicsMode() const {
diff --git a/backends/graphics/symbiansdl/symbiansdl-graphics.h b/backends/graphics/symbiansdl/symbiansdl-graphics.h
index f514db286c..fb9a49a834 100644
--- a/backends/graphics/symbiansdl/symbiansdl-graphics.h
+++ b/backends/graphics/symbiansdl/symbiansdl-graphics.h
@@ -27,7 +27,7 @@
class SymbianSdlGraphicsManager : public SurfaceSdlGraphicsManager {
public:
- SymbianSdlGraphicsManager(SdlEventSource *sdlEventSource);
+ SymbianSdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window);
public:
virtual bool hasFeature(OSystem::Feature f);
diff --git a/backends/graphics/wincesdl/wincesdl-graphics.cpp b/backends/graphics/wincesdl/wincesdl-graphics.cpp
index 8e4685dbd8..07f7d47262 100644
--- a/backends/graphics/wincesdl/wincesdl-graphics.cpp
+++ b/backends/graphics/wincesdl/wincesdl-graphics.cpp
@@ -42,8 +42,8 @@
#include "backends/platform/wince/CEScaler.h"
#include "backends/platform/wince/CEgui/ItemAction.h"
-WINCESdlGraphicsManager::WINCESdlGraphicsManager(SdlEventSource *sdlEventSource)
- : SurfaceSdlGraphicsManager(sdlEventSource),
+WINCESdlGraphicsManager::WINCESdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window)
+ : SurfaceSdlGraphicsManager(sdlEventSource, window),
_panelInitialized(false), _noDoubleTapRMB(false), _noDoubleTapPT(false),
_toolbarHighDrawn(false), _newOrientation(0), _orientationLandscape(0),
_panelVisible(true), _saveActiveToolbar(NAME_MAIN_PANEL), _panelStateForced(false),
diff --git a/backends/graphics/wincesdl/wincesdl-graphics.h b/backends/graphics/wincesdl/wincesdl-graphics.h
index 50b422c10d..9316c69e44 100644
--- a/backends/graphics/wincesdl/wincesdl-graphics.h
+++ b/backends/graphics/wincesdl/wincesdl-graphics.h
@@ -41,7 +41,7 @@ extern bool _hasSmartphoneResolution;
class WINCESdlGraphicsManager : public SurfaceSdlGraphicsManager {
public:
- WINCESdlGraphicsManager(SdlEventSource *sdlEventSource);
+ WINCESdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window);
const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
void initSize(uint w, uint h, const Graphics::PixelFormat *format = NULL);
diff --git a/backends/log/log.cpp b/backends/log/log.cpp
index 693399bae5..e37296aada 100644
--- a/backends/log/log.cpp
+++ b/backends/log/log.cpp
@@ -93,10 +93,12 @@ void Log::print(const char *message, const bool printTime) {
void Log::printTimeStamp() {
TimeDate date;
+ int curMonth;
_system->getTimeAndDate(date);
+ curMonth = date.tm_mon + 1; // month is base 0, we need base 1 (1 = january and so on)
_stream->writeString(Common::String::format("[%d-%02d-%02d %02d:%02d:%02d] ",
- date.tm_year + 1900, date.tm_mon, date.tm_mday,
+ date.tm_year + 1900, curMonth, date.tm_mday,
date.tm_hour, date.tm_min, date.tm_sec));
}
diff --git a/backends/mixer/doublebuffersdl/doublebuffersdl-mixer.cpp b/backends/mixer/doublebuffersdl/doublebuffersdl-mixer.cpp
index d59b0ebdfc..e5f63dc908 100644
--- a/backends/mixer/doublebuffersdl/doublebuffersdl-mixer.cpp
+++ b/backends/mixer/doublebuffersdl/doublebuffersdl-mixer.cpp
@@ -53,7 +53,11 @@ void DoubleBufferSDLMixerManager::startAudio() {
_soundThreadIsRunning = true;
// Finally start the thread
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ _soundThread = SDL_CreateThread(mixerProducerThreadEntry, "ScummVM Double Buffer Mixer", this);
+#else
_soundThread = SDL_CreateThread(mixerProducerThreadEntry, this);
+#endif
SdlMixerManager::startAudio();
}
diff --git a/backends/mixer/sdl/sdl-mixer.cpp b/backends/mixer/sdl/sdl-mixer.cpp
index e3b15b8c59..dc0c853808 100644
--- a/backends/mixer/sdl/sdl-mixer.cpp
+++ b/backends/mixer/sdl/sdl-mixer.cpp
@@ -57,10 +57,14 @@ void SdlMixerManager::init() {
error("Could not initialize SDL: %s", SDL_GetError());
}
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ const char *sdlDriverName = SDL_GetCurrentAudioDriver();
+#else
const int maxNameLen = 20;
char sdlDriverName[maxNameLen];
sdlDriverName[0] = '\0';
SDL_AudioDriverName(sdlDriverName, maxNameLen);
+#endif
debug(1, "Using SDL Audio Driver \"%s\"", sdlDriverName);
// Get the desired audio specs
diff --git a/backends/module.mk b/backends/module.mk
index 34e2928419..e5e2905781 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -74,9 +74,11 @@ MODULE_OBJS += \
# SDL 1.3 removed audio CD support
ifndef USE_SDL13
+ifndef USE_SDL2
MODULE_OBJS += \
audiocd/sdl/sdl-audiocd.o
endif
+endif
ifdef USE_OPENGL
MODULE_OBJS += \
diff --git a/backends/platform/android/android.cpp b/backends/platform/android/android.cpp
index 3ff1b939ef..798772cc24 100644
--- a/backends/platform/android/android.cpp
+++ b/backends/platform/android/android.cpp
@@ -396,12 +396,6 @@ void OSystem_Android::initBackend() {
EventsBaseBackend::initBackend();
}
-void OSystem_Android::addPluginDirectories(Common::FSList &dirs) const {
- ENTER();
-
- JNI::getPluginDirectories(dirs);
-}
-
bool OSystem_Android::hasFeature(Feature f) {
return (f == kFeatureFullscreenMode ||
f == kFeatureAspectRatioCorrection ||
@@ -600,10 +594,4 @@ Common::String OSystem_Android::getSystemProperty(const char *name) const {
return Common::String(value, len);
}
-#ifdef DYNAMIC_MODULES
-void AndroidPluginProvider::addCustomDirectories(Common::FSList &dirs) const {
- ((OSystem_Android *)g_system)->addPluginDirectories(dirs);
-}
-#endif
-
#endif
diff --git a/backends/platform/android/android.h b/backends/platform/android/android.h
index 28016f5e3e..ade84dd42d 100644
--- a/backends/platform/android/android.h
+++ b/backends/platform/android/android.h
@@ -96,13 +96,6 @@ extern void checkGlError(const char *expr, const char *file, int line);
#define GLTHREADCHECK do { } while (false)
#endif
-#ifdef DYNAMIC_MODULES
-class AndroidPluginProvider : public POSIXPluginProvider {
-protected:
- virtual void addCustomDirectories(Common::FSList &dirs) const;
-};
-#endif
-
class OSystem_Android : public EventsBaseBackend, public PaletteManager {
private:
// passed from the dark side
@@ -177,7 +170,6 @@ public:
virtual ~OSystem_Android();
virtual void initBackend();
- void addPluginDirectories(Common::FSList &dirs) const;
void enableZoning(bool enable) { _enable_zoning = enable; }
virtual bool hasFeature(Feature f);
diff --git a/backends/platform/android/android.mk b/backends/platform/android/android.mk
index 69aa9d8303..e11ad0724e 100644
--- a/backends/platform/android/android.mk
+++ b/backends/platform/android/android.mk
@@ -2,200 +2,106 @@
# These must be incremented for each market upload
ANDROID_VERSIONCODE = 6
-ANDROID_PLUGIN_VERSIONCODE = 6
-JAVA_FILES = \
- ScummVM.java \
- ScummVMEvents.java \
- ScummVMEventsHoneycomb.java \
- ScummVMApplication.java \
- ScummVMActivity.java \
- EditableSurfaceView.java \
- MouseHelper.java \
- Unpacker.java
+ANDROID_TARGET_VERSION = 14
-JAVA_FILES_PLUGIN = \
- PluginProvider.java
-
-JAVA_FILES_GEN = \
- Manifest.java \
- R.java
+NDK_BUILD = $(ANDROID_NDK)/ndk-build APP_ABI=$(ABI)
+SDK_ANDROID = $(ANDROID_SDK)/tools/android
PATH_DIST = $(srcdir)/dists/android
PATH_RESOURCES = $(PATH_DIST)/res
PORT_DISTFILES = $(PATH_DIST)/README.Android
+DIST_JAVA_SRC_DIR = $(srcdir)/backends/platform/android/org
RESOURCES = \
- $(PATH_RESOURCES)/values/strings.xml \
- $(PATH_RESOURCES)/values/margins.xml \
- $(PATH_RESOURCES)/values-television/margins.xml \
- $(PATH_RESOURCES)/layout/main.xml \
- $(PATH_RESOURCES)/layout/splash.xml \
- $(PATH_RESOURCES)/drawable/gradient.xml \
- $(PATH_RESOURCES)/drawable/scummvm.png \
- $(PATH_RESOURCES)/drawable/scummvm_big.png \
- $(PATH_RESOURCES)/drawable-xhdpi/ouya_icon.png
-
-PLUGIN_RESOURCES = \
- $(PATH_RESOURCES)/values/strings.xml \
- $(PATH_RESOURCES)/drawable/scummvm.png
-
-# FIXME: find/mark plugin entry points and add all this back again:
-#LDFLAGS += -Wl,--gc-sections
-#CXXFLAGS += -ffunction-sections -fdata-sections -fvisibility=hidden -fvisibility-inlines-hidden
-
-AAPT = $(ANDROID_SDK)/$(ANDROID_BTOOLS)/aapt
-ADB = $(ANDROID_SDK)/platform-tools/adb
-DX = $(ANDROID_SDK)/$(ANDROID_BTOOLS)/dx
-APKBUILDER = java -Xmx128M -classpath $(ANDROID_SDK)/tools/lib/sdklib.jar com.android.sdklib.build.ApkBuilderMain
-JAVAC ?= javac
-JAVACFLAGS = -source 1.5 -target 1.5
-
-ANDROID_JAR = $(ANDROID_SDK)/platforms/android-14/android.jar
+ $(PATH_BUILD_RES)/values/strings.xml \
+ $(PATH_BUILD_RES)/values-television/margins.xml \
+ $(PATH_BUILD_RES)/layout/main.xml \
+ $(PATH_BUILD_RES)/drawable/scummvm.png \
+ $(PATH_BUILD_RES)/drawable/scummvm_big.png \
+ $(PATH_BUILD_RES)/drawable-xhdpi/ouya_icon.png
+
+DIST_ANDROID_MK = $(PATH_DIST)/jni/Android.mk
+DIST_BUILD_XML = $(PATH_DIST)/custom_rules.xml
PATH_BUILD = ./build.tmp
PATH_BUILD_ASSETS = $(PATH_BUILD)/assets
-PATH_BUILD_CLASSES_MAIN_TOP = $(PATH_BUILD)/classes.main
-PATH_BUILD_CLASSES_PLUGIN_TOP = $(PATH_BUILD)/classes.plugin
-
-PATH_STAGE_PREFIX = build.stage
-PATH_STAGE_MAIN = $(PATH_STAGE_PREFIX).main
-
-PATH_REL = org/scummvm/scummvm
-PATH_SRC_TOP = $(srcdir)/backends/platform/android
-PATH_SRC = $(PATH_SRC_TOP)/$(PATH_REL)
-
-PATH_GEN_TOP = $(PATH_BUILD)/java
-PATH_GEN = $(PATH_GEN_TOP)/$(PATH_REL)
-PATH_CLASSES_MAIN = $(PATH_BUILD_CLASSES_MAIN_TOP)/$(PATH_REL)
-PATH_CLASSES_PLUGIN = $(PATH_BUILD_CLASSES_PLUGIN_TOP)/$(PATH_REL)
+PATH_BUILD_RES = $(PATH_BUILD)/res
+PATH_BUILD_LIBSCUMMVM = $(PATH_BUILD)/lib/$(ABI)/libscummvm.so
FILE_MANIFEST_SRC = $(srcdir)/dists/android/AndroidManifest.xml
FILE_MANIFEST = $(PATH_BUILD)/AndroidManifest.xml
-FILE_DEX = $(PATH_BUILD)/classes.dex
-FILE_DEX_PLUGIN = $(PATH_BUILD)/plugins/classes.dex
-FILE_RESOURCES = resources.ap_
-FILE_RESOURCES_MAIN = $(PATH_BUILD)/$(FILE_RESOURCES)
-
-SRC_GEN = $(addprefix $(PATH_GEN)/, $(JAVA_FILES_GEN))
-CLASSES_MAIN = $(addprefix $(PATH_CLASSES_MAIN)/, $(JAVA_FILES:%.java=%.class))
-CLASSES_GEN = $(addprefix $(PATH_CLASSES_MAIN)/, $(JAVA_FILES_GEN:%.java=%.class))
-CLASSES_PLUGIN = $(addprefix $(PATH_CLASSES_PLUGIN)/, $(JAVA_FILES_PLUGIN:%.java=%.class))
+APK_MAIN = ScummVM-debug.apk
+APK_MAIN_RELEASE = ScummVM-release-unsigned.apk
-APK_MAIN = scummvm.apk
-APK_PLUGINS = $(patsubst plugins/lib%.so, scummvm-engine-%.apk, $(PLUGINS))
-
-$(FILE_MANIFEST): $(FILE_MANIFEST_SRC)
+$(FILE_MANIFEST): $(FILE_MANIFEST_SRC) | $(PATH_BUILD)
@$(MKDIR) -p $(@D)
sed "s/@ANDROID_VERSIONCODE@/$(ANDROID_VERSIONCODE)/" < $< > $@
-$(SRC_GEN): $(FILE_MANIFEST) $(filter %.xml,$(RESOURCES)) $(ANDROID_JAR)
- @$(MKDIR) -p $(PATH_GEN_TOP)
- $(AAPT) package -m -J $(PATH_GEN_TOP) -M $< -S $(PATH_RESOURCES) -I $(ANDROID_JAR)
-
-$(PATH_CLASSES_MAIN)/%.class: $(PATH_GEN)/%.java $(SRC_GEN)
+$(PATH_BUILD)/res/%: $(PATH_DIST)/res/% | $(PATH_BUILD)
@$(MKDIR) -p $(@D)
- $(JAVAC) $(JAVACFLAGS) -cp $(PATH_SRC_TOP) -d $(PATH_BUILD_CLASSES_MAIN_TOP) -bootclasspath $(ANDROID_JAR) $<
+ $(CP) $< $@
-$(PATH_CLASSES_MAIN)/%.class: $(PATH_SRC)/%.java $(SRC_GEN)
+$(PATH_BUILD)/libs/%: $(PATH_DIST)/libs/% | $(PATH_BUILD)
@$(MKDIR) -p $(@D)
- $(JAVAC) $(JAVACFLAGS) -cp $(PATH_SRC_TOP):$(PATH_GEN_TOP) -d $(PATH_BUILD_CLASSES_MAIN_TOP) -bootclasspath $(ANDROID_JAR) $<
+ $(CP) $< $@
-$(PATH_CLASSES_PLUGIN)/%.class: $(PATH_SRC)/%.java
- @$(MKDIR) -p $(@D)
- $(JAVAC) $(JAVACFLAGS) -cp $(PATH_SRC_TOP) -d $(PATH_BUILD_CLASSES_PLUGIN_TOP) -bootclasspath $(ANDROID_JAR) $<
+$(PATH_BUILD_ASSETS): $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) $(DIST_FILES_SHADERS) $(DIST_BUILD_XML) | $(PATH_BUILD)
+ $(INSTALL) -d $(PATH_BUILD_ASSETS)
+ $(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) $(PATH_BUILD_ASSETS)/
+ $(INSTALL) -d $(PATH_BUILD)/jni
+ $(INSTALL) -c -m 644 $(DIST_ANDROID_MK) $(PATH_BUILD)/jni
+ $(INSTALL) -c -m 644 $(DIST_BUILD_XML) $(PATH_BUILD)
-$(FILE_DEX): $(CLASSES_MAIN) $(CLASSES_GEN)
- $(DX) --dex --output=$@ $(PATH_BUILD_CLASSES_MAIN_TOP)
+$(PATH_BUILD): $(DIST_ANDROID_MK)
+ $(MKDIR) -p $(PATH_BUILD) $(PATH_BUILD)/res
+ $(MKDIR) -p $(PATH_BUILD)/libs
-$(FILE_DEX_PLUGIN): $(CLASSES_PLUGIN)
- @$(MKDIR) -p $(@D)
- $(DX) --dex --output=$@ $(PATH_BUILD_CLASSES_PLUGIN_TOP)
+$(PATH_BUILD_LIBSCUMMVM): libscummvm.so | $(PATH_BUILD)
+ $(INSTALL) -c -m 644 libscummvm.so $(PATH_BUILD)
+ $(STRIP) $(PATH_BUILD)/libscummvm.so
+ cd $(PATH_BUILD); $(NDK_BUILD)
-$(PATH_BUILD)/%/AndroidManifest.xml: $(PATH_DIST)/mkplugin.sh $(srcdir)/configure $(PATH_DIST)/plugin-manifest.xml
- @$(MKDIR) -p $(@D)
- $(PATH_DIST)/mkplugin.sh $(srcdir)/configure $* $(PATH_DIST)/plugin-manifest.xml $(ANDROID_PLUGIN_VERSIONCODE) $@
+$(PATH_BUILD_RES): $(RESOURCES) | $(PATH_BUILD)
-$(PATH_STAGE_PREFIX).%/res/values/strings.xml: $(PATH_DIST)/mkplugin.sh $(srcdir)/configure $(PATH_DIST)/plugin-manifest.xml
- @$(MKDIR) -p $(@D)
- $(PATH_DIST)/mkplugin.sh $(srcdir)/configure $* $(PATH_DIST)/plugin-strings.xml $(ANDROID_PLUGIN_VERSIONCODE) $@
+setupapk: $(FILE_MANIFEST) $(PATH_BUILD_RES) $(PATH_BUILD_ASSETS) $(PATH_BUILD_LIBSCUMMVM) | $(PATH_BUILD)
+ $(SDK_ANDROID) update project -p $(PATH_BUILD) -t android-$(ANDROID_TARGET_VERSION) -n ScummVM
-$(PATH_STAGE_PREFIX).%/res/drawable/scummvm.png: $(PATH_RESOURCES)/drawable/scummvm.png
- @$(MKDIR) -p $(@D)
- $(CP) $< $@
+$(APK_MAIN): setupapk | $(PATH_BUILD)
+ (cd $(PATH_BUILD); ant debug -Dsource.dir="$(realpath $(DIST_JAVA_SRC_DIR))")
+ $(CP) $(PATH_BUILD)/bin/ScummVM-debug.apk $@
-$(FILE_RESOURCES_MAIN): $(FILE_MANIFEST) $(RESOURCES) $(ANDROID_JAR) $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA)
- $(INSTALL) -d $(PATH_BUILD_ASSETS)
- $(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) $(PATH_BUILD_ASSETS)/
- work_dir=`pwd`; \
- for i in $(PATH_BUILD_ASSETS)/*.zip; do \
- echo "recompress $$i"; \
- cd "$$work_dir"; \
- $(RM) -rf $(PATH_BUILD_ASSETS)/tmp; \
- $(MKDIR) $(PATH_BUILD_ASSETS)/tmp; \
- unzip -q $$i -d $(PATH_BUILD_ASSETS)/tmp; \
- cd $(PATH_BUILD_ASSETS)/tmp; \
- zip -r ../`basename $$i` *; \
- done
- @$(RM) -rf $(PATH_BUILD_ASSETS)/tmp
- $(AAPT) package -f -0 zip -M $< -S $(PATH_RESOURCES) -A $(PATH_BUILD_ASSETS) -I $(ANDROID_JAR) -F $@
-
-$(PATH_BUILD)/%/$(FILE_RESOURCES): $(PATH_BUILD)/%/AndroidManifest.xml $(PATH_STAGE_PREFIX).%/res/values/strings.xml $(PATH_STAGE_PREFIX).%/res/drawable/scummvm.png plugins/lib%.so $(ANDROID_JAR)
- $(AAPT) package -f -M $< -S $(PATH_STAGE_PREFIX).$*/res -I $(ANDROID_JAR) -F $@
-
-# Package installer won't delete old libscummvm.so on upgrade so
-# replace it with a zero size file
-$(APK_MAIN): $(EXECUTABLE) $(FILE_RESOURCES_MAIN) $(FILE_DEX)
- $(INSTALL) -d $(PATH_STAGE_MAIN)/common/lib/armeabi
- touch $(PATH_STAGE_MAIN)/common/lib/armeabi/libscummvm.so
- $(INSTALL) -d $(PATH_STAGE_MAIN)/common/mylib/armeabi
- $(INSTALL) -c -m 644 libscummvm.so $(PATH_STAGE_MAIN)/common/mylib/armeabi/
- $(STRIP) $(PATH_STAGE_MAIN)/common/mylib/armeabi/libscummvm.so
- $(APKBUILDER) $@ -z $(FILE_RESOURCES_MAIN) -f $(FILE_DEX) -rf $(PATH_STAGE_MAIN)/common || { $(RM) $@; exit 1; }
-
-scummvm-engine-%.apk: plugins/lib%.so $(PATH_BUILD)/%/$(FILE_RESOURCES) $(FILE_DEX_PLUGIN)
- $(INSTALL) -d $(PATH_STAGE_PREFIX).$*/apk/mylib/armeabi/
- $(INSTALL) -c -m 644 plugins/lib$*.so $(PATH_STAGE_PREFIX).$*/apk/mylib/armeabi/
- $(STRIP) $(PATH_STAGE_PREFIX).$*/apk/mylib/armeabi/lib$*.so
- $(APKBUILDER) $@ -z $(PATH_BUILD)/$*/$(FILE_RESOURCES) -f $(FILE_DEX_PLUGIN) -rf $(PATH_STAGE_PREFIX).$*/apk || { $(RM) $@; exit 1; }
-
-all: $(APK_MAIN) $(APK_PLUGINS)
+$(APK_MAIN_RELEASE): setupapk | $(PATH_BUILD)
+ (cd $(PATH_BUILD); ant release -Dsource.dir="$(realpath $(DIST_JAVA_SRC_DIR))")
+ $(CP) $(PATH_BUILD)/bin/ScummVM-release-unsigned.apk $@
+
+all: $(APK_MAIN)
clean: androidclean
androidclean:
- @$(RM) -rf $(PATH_BUILD) $(PATH_STAGE_PREFIX).* *.apk release
-
-# remove debugging signature
-release/%.apk: %.apk
- @$(MKDIR) -p $(@D)
- @$(RM) $@
- $(CP) $< $@.tmp
- zip -d $@.tmp META-INF/\*
- jarsigner $(JARSIGNER_FLAGS) $@.tmp release
- zipalign 4 $@.tmp $@
- $(RM) $@.tmp
+ @$(RM) -rf $(PATH_BUILD) *.apk release
-androidrelease: $(addprefix release/, $(APK_MAIN) $(APK_PLUGINS))
+androidrelease: $(APK_MAIN_RELEASE)
androidtestmain: $(APK_MAIN)
$(ADB) install -r $(APK_MAIN)
- $(ADB) shell am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -n org.scummvm.scummvm/.Unpacker
+ $(ADB) shell am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -n org.scummvm.scummvm/.ScummVMActivity
-androidtest: $(APK_MAIN) $(APK_PLUGINS)
+androidtest: $(APK_MAIN)
@set -e; for apk in $^; do \
$(ADB) install -r $$apk; \
done
- $(ADB) shell am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -n org.scummvm.scummvm/.Unpacker
+ $(ADB) shell am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -n org.scummvm.scummvm/.ScummVMActivity
# used by buildbot!
androiddistdebug: all
$(MKDIR) debug
- $(CP) $(APK_MAIN) $(APK_PLUGINS) debug/
+ $(CP) $(APK_MAIN) debug/
for i in $(DIST_FILES_DOCS) $(PORT_DISTFILES); do \
sed 's/$$/\r/' < $$i > debug/`basename $$i`.txt; \
done
-.PHONY: androidrelease androidtest
+.PHONY: androidrelease androidtest $(PATH_BUILD_SRC)
diff --git a/backends/platform/android/jni.cpp b/backends/platform/android/jni.cpp
index 764c84ce1c..22e6a749c2 100644
--- a/backends/platform/android/jni.cpp
+++ b/backends/platform/android/jni.cpp
@@ -79,7 +79,6 @@ jmethodID JNI::_MID_displayMessageOnOSD = 0;
jmethodID JNI::_MID_setWindowCaption = 0;
jmethodID JNI::_MID_showVirtualKeyboard = 0;
jmethodID JNI::_MID_getSysArchives = 0;
-jmethodID JNI::_MID_getPluginDirectories = 0;
jmethodID JNI::_MID_initSurface = 0;
jmethodID JNI::_MID_deinitSurface = 0;
@@ -293,46 +292,6 @@ void JNI::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) {
}
}
-void JNI::getPluginDirectories(Common::FSList &dirs) {
- JNIEnv *env = JNI::getEnv();
-
- jobjectArray array =
- (jobjectArray)env->CallObjectMethod(_jobj, _MID_getPluginDirectories);
-
- if (env->ExceptionCheck()) {
- LOGE("Error finding plugin directories");
-
- env->ExceptionDescribe();
- env->ExceptionClear();
-
- return;
- }
-
- jsize size = env->GetArrayLength(array);
- for (jsize i = 0; i < size; ++i) {
- jstring path_obj = (jstring)env->GetObjectArrayElement(array, i);
-
- if (path_obj == 0)
- continue;
-
- const char *path = env->GetStringUTFChars(path_obj, 0);
-
- if (path == 0) {
- LOGE("Error getting string characters from plugin directory");
-
- env->ExceptionClear();
- env->DeleteLocalRef(path_obj);
-
- continue;
- }
-
- dirs.push_back(Common::FSNode(path));
-
- env->ReleaseStringUTFChars(path_obj, path);
- env->DeleteLocalRef(path_obj);
- }
-}
-
bool JNI::initSurface() {
JNIEnv *env = JNI::getEnv();
@@ -454,7 +413,6 @@ void JNI::create(JNIEnv *env, jobject self, jobject asset_manager,
FIND_METHOD(, displayMessageOnOSD, "(Ljava/lang/String;)V");
FIND_METHOD(, showVirtualKeyboard, "(Z)V");
FIND_METHOD(, getSysArchives, "()[Ljava/lang/String;");
- FIND_METHOD(, getPluginDirectories, "()[Ljava/lang/String;");
FIND_METHOD(, initSurface, "()Ljavax/microedition/khronos/egl/EGLSurface;");
FIND_METHOD(, deinitSurface, "()V");
@@ -543,10 +501,6 @@ jint JNI::main(JNIEnv *env, jobject self, jobjectArray args) {
env->DeleteLocalRef(arg);
}
-#ifdef DYNAMIC_MODULES
- PluginManager::instance().addPluginProvider(new AndroidPluginProvider());
-#endif
-
LOGI("Entering scummvm_main with %d args", argc);
res = scummvm_main(argc, argv);
diff --git a/backends/platform/android/jni.h b/backends/platform/android/jni.h
index 326869b1ee..70feaaf72a 100644
--- a/backends/platform/android/jni.h
+++ b/backends/platform/android/jni.h
@@ -55,7 +55,6 @@ public:
static void setReadyForEvents(bool ready);
- static void getPluginDirectories(Common::FSList &dirs);
static void setWindowCaption(const char *caption);
static void getDPI(float *values);
static void displayMessageOnOSD(const char *msg);
@@ -93,7 +92,6 @@ private:
static jmethodID _MID_setWindowCaption;
static jmethodID _MID_showVirtualKeyboard;
static jmethodID _MID_getSysArchives;
- static jmethodID _MID_getPluginDirectories;
static jmethodID _MID_initSurface;
static jmethodID _MID_deinitSurface;
diff --git a/backends/platform/android/org/scummvm/scummvm/PluginProvider.java b/backends/platform/android/org/scummvm/scummvm/PluginProvider.java
deleted file mode 100644
index e27e8d41a8..0000000000
--- a/backends/platform/android/org/scummvm/scummvm/PluginProvider.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package org.scummvm.scummvm;
-
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.net.Uri;
-import android.os.Bundle;
-import android.util.Log;
-
-import java.util.ArrayList;
-
-public class PluginProvider extends BroadcastReceiver {
- private final static String LOG_TAG = "ScummVM";
-
- public final static String META_UNPACK_LIB =
- "org.scummvm.scummvm.meta.UNPACK_LIB";
-
- public void onReceive(Context context, Intent intent) {
- if (!intent.getAction().equals(ScummVMApplication.ACTION_PLUGIN_QUERY))
- return;
-
- Bundle extras = getResultExtras(true);
-
- final ActivityInfo info;
- final PackageInfo pinfo;
- try {
- info = context.getPackageManager()
- .getReceiverInfo(new ComponentName(context, this.getClass()),
- PackageManager.GET_META_DATA);
- pinfo = context.getPackageManager()
- .getPackageInfo(context.getPackageName(), 0);
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(LOG_TAG, "Error finding my own info?", e);
- return;
- }
-
- String host_version = extras.getString(ScummVMApplication.EXTRA_VERSION);
- if (!pinfo.versionName.equals(host_version)) {
- Log.e(LOG_TAG, "Plugin version " + pinfo.versionName + " is not equal to ScummVM version " + host_version);
- return;
- }
-
- String mylib = info.metaData.getString(META_UNPACK_LIB);
- if (mylib != null) {
- ArrayList<String> all_libs =
- extras.getStringArrayList(ScummVMApplication.EXTRA_UNPACK_LIBS);
- all_libs.add(new Uri.Builder()
- .scheme("plugin")
- .authority(context.getPackageName())
- .path(mylib)
- .toString());
-
- extras.putStringArrayList(ScummVMApplication.EXTRA_UNPACK_LIBS,
- all_libs);
- }
-
- setResultExtras(extras);
- }
-}
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVM.java b/backends/platform/android/org/scummvm/scummvm/ScummVM.java
index 5047502e61..3b370a583d 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVM.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVM.java
@@ -54,7 +54,6 @@ public abstract class ScummVM implements SurfaceHolder.Callback, Runnable {
abstract protected void getDPI(float[] values);
abstract protected void displayMessageOnOSD(String msg);
abstract protected void setWindowCaption(String caption);
- abstract protected String[] getPluginDirectories();
abstract protected void showVirtualKeyboard(boolean enable);
abstract protected String[] getSysArchives();
@@ -444,10 +443,6 @@ public abstract class ScummVM implements SurfaceHolder.Callback, Runnable {
}
}
- File cache_dir = ScummVMApplication.getLastCacheDir();
- String libname = System.mapLibraryName("scummvm");
- File libpath = new File(cache_dir, libname);
-
- System.load(libpath.getPath());
+ System.loadLibrary("scummvm");
}
}
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
index f4eb7ddd0b..5b2dcae175 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
@@ -84,13 +84,6 @@ public class ScummVMActivity extends Activity {
}
@Override
- protected String[] getPluginDirectories() {
- String[] dirs = new String[1];
- dirs[0] = ScummVMApplication.getLastCacheDir().getPath();
- return dirs;
- }
-
- @Override
protected void showVirtualKeyboard(final boolean enable) {
runOnUiThread(new Runnable() {
public void run() {
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMApplication.java b/backends/platform/android/org/scummvm/scummvm/ScummVMApplication.java
deleted file mode 100644
index 0adc166222..0000000000
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMApplication.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package org.scummvm.scummvm;
-
-import android.app.Application;
-
-import java.io.File;
-
-public class ScummVMApplication extends Application {
- public final static String ACTION_PLUGIN_QUERY = "org.scummvm.scummvm.action.PLUGIN_QUERY";
- public final static String EXTRA_UNPACK_LIBS = "org.scummvm.scummvm.extra.UNPACK_LIBS";
- public final static String EXTRA_VERSION = "org.scummvm.scummvm.extra.VERSION";
-
- private static File _cache_dir;
-
- @Override
- public void onCreate() {
- super.onCreate();
-
- // This is still on /data :(
- _cache_dir = getCacheDir();
- // This is mounted noexec :(
- //cache_dir = new File(Environment.getExternalStorageDirectory(),
- // "/.ScummVM.tmp");
- // This is owned by download manager and requires special
- // permissions to access :(
- //cache_dir = Environment.getDownloadCacheDirectory();
- }
-
- public static File getLastCacheDir() {
- return _cache_dir;
- }
-}
diff --git a/backends/platform/android/org/scummvm/scummvm/Unpacker.java b/backends/platform/android/org/scummvm/scummvm/Unpacker.java
deleted file mode 100644
index da76ceb5e5..0000000000
--- a/backends/platform/android/org/scummvm/scummvm/Unpacker.java
+++ /dev/null
@@ -1,388 +0,0 @@
-package org.scummvm.scummvm;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.ActivityNotFoundException;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.util.Log;
-import android.widget.ProgressBar;
-
-import java.io.IOException;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.zip.ZipFile;
-import java.util.zip.ZipEntry;
-
-public class Unpacker extends Activity {
- protected final static String LOG_TAG = "ScummVM";
- // TODO don't hardcode this
- private final static boolean PLUGINS_ENABLED = false;
- private final static String META_NEXT_ACTIVITY =
- "org.scummvm.unpacker.nextActivity";
- private ProgressBar mProgress;
- private File mUnpackDest; // location to unpack into
- private AsyncTask<String, Integer, Void> mUnpacker;
- private final static int REQUEST_MARKET = 1;
-
- // Android 3.1+ only
- public static final int FLAG_INCLUDE_STOPPED_PACKAGES = 32;
-
- private static class UnpackJob {
- public ZipFile zipfile;
- public Set<String> paths;
-
- public UnpackJob(ZipFile zipfile, Set<String> paths) {
- this.zipfile = zipfile;
- this.paths = paths;
- }
-
- public long UnpackSize() {
- long size = 0;
- for (String path: paths) {
- ZipEntry entry = zipfile.getEntry(path);
- if (entry != null) size += entry.getSize();
- }
- return size;
- }
- }
-
- private class UnpackTask extends AsyncTask<String, Integer, Void> {
- @Override
- protected void onProgressUpdate(Integer... progress) {
- mProgress.setIndeterminate(false);
- mProgress.setMax(progress[1]);
- mProgress.setProgress(progress[0]);
- mProgress.postInvalidate();
- }
-
- @Override
- protected void onPostExecute(Void result) {
- Bundle md = getMetaData();
- String nextActivity = md.getString(META_NEXT_ACTIVITY);
- if (nextActivity != null) {
- final ComponentName cn =
- ComponentName.unflattenFromString(nextActivity);
- if (cn != null) {
- final Intent origIntent = getIntent();
- Intent intent = new Intent();
- intent.setComponent(cn);
- if (origIntent.getExtras() != null)
- intent.putExtras(origIntent.getExtras());
- intent.putExtra(Intent.EXTRA_INTENT, origIntent);
- intent.setDataAndType(origIntent.getData(),
- origIntent.getType());
- //intent.fillIn(getIntent(), 0);
- intent.addFlags(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
- Log.i(LOG_TAG,
- "Starting next activity with intent " + intent);
- startActivity(intent);
- } else {
- Log.w(LOG_TAG,
- "Unable to extract a component name from " + nextActivity);
- }
- }
-
- finish();
- }
-
- @Override
- protected Void doInBackground(String... all_libs) {
- // This will contain all unpack jobs
- Map<String, UnpackJob> unpack_jobs =
- new HashMap<String, UnpackJob>(all_libs.length);
-
- // This will contain all unpack filenames (so we can
- // detect stale files in the unpack directory)
- Set<String> all_files = new HashSet<String>(all_libs.length);
-
- for (String lib: all_libs) {
- final Uri uri = Uri.parse(lib);
- final String pkg = uri.getAuthority();
- final String path = uri.getPath().substring(1); // skip first /
-
- all_files.add(new File(path).getName());
-
- UnpackJob job = unpack_jobs.get(pkg);
- if (job == null) {
- try {
- // getPackageResourcePath is hidden in Context,
- // but exposed in ContextWrapper...
- ContextWrapper context =
- new ContextWrapper(createPackageContext(pkg, 0));
- ZipFile zipfile =
- new ZipFile(context.getPackageResourcePath());
- job = new UnpackJob(zipfile, new HashSet<String>(1));
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(LOG_TAG, "Package " + pkg +
- " not found", e);
- continue;
- } catch (IOException e) {
- // FIXME: show some sort of GUI error dialog
- Log.e(LOG_TAG,
- "Error opening ZIP for package " + pkg, e);
- continue;
- }
- unpack_jobs.put(pkg, job);
- }
- job.paths.add(path);
- }
-
- // Delete stale filenames from mUnpackDest
- for (File file: mUnpackDest.listFiles()) {
- if (!all_files.contains(file.getName())) {
- Log.i(LOG_TAG,
- "Deleting stale cached file " + file);
- file.delete();
- }
- }
-
- int total_size = 0;
- for (UnpackJob job: unpack_jobs.values())
- total_size += job.UnpackSize();
-
- publishProgress(0, total_size);
-
- mUnpackDest.mkdirs();
-
- int progress = 0;
-
- for (UnpackJob job: unpack_jobs.values()) {
- try {
- ZipFile zipfile = job.zipfile;
- for (String path: job.paths) {
- ZipEntry zipentry = zipfile.getEntry(path);
- if (zipentry == null)
- throw new FileNotFoundException(
- "Couldn't find " + path + " in zip");
- File dest = new File(mUnpackDest, new File(path).getName());
- if (dest.exists() &&
- dest.lastModified() == zipentry.getTime() &&
- dest.length() == zipentry.getSize()) {
- // Already unpacked
- progress += zipentry.getSize();
- } else {
- if (dest.exists())
- Log.d(LOG_TAG,
- "Replacing " + dest.getPath() +
- " old.mtime=" + dest.lastModified() +
- " new.mtime=" + zipentry.getTime() +
- " old.size=" + dest.length() +
- " new.size=" + zipentry.getSize());
- else
- Log.i(LOG_TAG,
- "Extracting " + zipentry.getName() +
- " from " + zipfile.getName() +
- " to " + dest.getPath());
-
- long next_update = progress;
-
- InputStream in = zipfile.getInputStream(zipentry);
- OutputStream out = new FileOutputStream(dest);
- int len;
- byte[] buffer = new byte[4096];
- while ((len = in.read(buffer)) != -1) {
- out.write(buffer, 0, len);
- progress += len;
- if (progress >= next_update) {
- publishProgress(progress, total_size);
- // Arbitrary limit of 2% update steps
- next_update += total_size / 50;
- }
- }
-
- in.close();
- out.close();
- dest.setLastModified(zipentry.getTime());
- }
- publishProgress(progress, total_size);
- }
-
- zipfile.close();
- } catch (IOException e) {
- // FIXME: show some sort of GUI error dialog
- Log.e(LOG_TAG, "Error unpacking plugin", e);
- }
- }
-
- if (progress != total_size)
- Log.d(LOG_TAG, "Ended with progress " + progress +
- " != total size " + total_size);
-
- setResult(RESULT_OK);
-
- return null;
- }
- }
-
- private class PluginBroadcastReciever extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (!intent.getAction()
- .equals(ScummVMApplication.ACTION_PLUGIN_QUERY)) {
- Log.e(LOG_TAG,
- "Received unexpected action " + intent.getAction());
- return;
- }
-
- Bundle extras = getResultExtras(false);
- if (extras == null) {
- // Nothing for us to do.
- Unpacker.this.setResult(RESULT_OK);
- finish();
- }
-
- ArrayList<String> unpack_libs =
- extras.getStringArrayList(ScummVMApplication.EXTRA_UNPACK_LIBS);
-
- if (unpack_libs != null && !unpack_libs.isEmpty()) {
- final String[] libs =
- unpack_libs.toArray(new String[unpack_libs.size()]);
- mUnpacker = new UnpackTask().execute(libs);
- }
- }
- }
-
- private void initPlugins() {
- Bundle extras = new Bundle(1);
-
- ArrayList<String> unpack_libs = new ArrayList<String>(1);
- // This is the common ScummVM code (not really a "plugin" as such)
- unpack_libs.add(new Uri.Builder()
- .scheme("plugin")
- .authority(getPackageName())
- .path("mylib/armeabi/libscummvm.so")
- .toString());
- extras.putStringArrayList(ScummVMApplication.EXTRA_UNPACK_LIBS,
- unpack_libs);
-
- final PackageInfo info;
- try {
- info = getPackageManager().getPackageInfo(getPackageName(), 0);
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(LOG_TAG, "Error finding my own info?", e);
- return;
- }
- extras.putString(ScummVMApplication.EXTRA_VERSION, info.versionName);
-
- Intent intent = new Intent(ScummVMApplication.ACTION_PLUGIN_QUERY);
- // Android 3.1 defaults to FLAG_EXCLUDE_STOPPED_PACKAGES, and since
- // none of our plugins will ever be running, that is not helpful
- intent.setFlags(FLAG_INCLUDE_STOPPED_PACKAGES);
- sendOrderedBroadcast(intent, Manifest.permission.SCUMMVM_PLUGIN,
- new PluginBroadcastReciever(),
- null, RESULT_OK, null, extras);
- }
-
- @Override
- public void onCreate(Bundle b) {
- super.onCreate(b);
-
- mUnpackDest = ScummVMApplication.getLastCacheDir();
-
- setContentView(R.layout.splash);
- mProgress = (ProgressBar)findViewById(R.id.progress);
-
- setResult(RESULT_CANCELED);
-
- tryUnpack();
- }
-
- private void tryUnpack() {
- Intent intent = new Intent(ScummVMApplication.ACTION_PLUGIN_QUERY);
- List<ResolveInfo> plugins = getPackageManager()
- .queryBroadcastReceivers(intent, 0);
- if (PLUGINS_ENABLED && plugins.isEmpty()) {
- // No plugins installed
- AlertDialog.Builder alert = new AlertDialog.Builder(this)
- .setTitle(R.string.no_plugins_title)
- .setMessage(R.string.no_plugins_found)
- .setIcon(android.R.drawable.ic_dialog_alert)
- .setOnCancelListener(new DialogInterface.OnCancelListener() {
- public void onCancel(DialogInterface dialog) {
- finish();
- }
- })
- .setNegativeButton(R.string.quit,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- finish();
- }
- });
-
- final Uri uri = Uri.parse("market://search?q=ScummVM plugin");
- final Intent market_intent = new Intent(Intent.ACTION_VIEW, uri);
- if (getPackageManager().resolveActivity(market_intent, 0) != null) {
- alert.setPositiveButton(R.string.to_market,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
- try {
- startActivityForResult(market_intent,
- REQUEST_MARKET);
- } catch (ActivityNotFoundException e) {
- Log.e(LOG_TAG,
- "Error starting market", e);
- }
- }
- });
- }
-
- alert.show();
-
- } else {
- // Already have at least one plugin installed
- initPlugins();
- }
- }
-
- @Override
- public void onStop() {
- if (mUnpacker != null)
- mUnpacker.cancel(true);
- super.onStop();
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode,
- Intent data) {
- switch (requestCode) {
- case REQUEST_MARKET:
- if (resultCode != RESULT_OK)
- Log.w(LOG_TAG, "Market returned " + resultCode);
- tryUnpack();
- break;
- }
- }
-
- private Bundle getMetaData() {
- try {
- ActivityInfo ai = getPackageManager()
- .getActivityInfo(getComponentName(), PackageManager.GET_META_DATA);
- return ai.metaData;
- } catch (PackageManager.NameNotFoundException e) {
- Log.w(LOG_TAG, "Unable to find my own meta-data", e);
- return new Bundle();
- }
- }
-}
diff --git a/backends/platform/dingux/dingux.cpp b/backends/platform/dingux/dingux.cpp
index 2f11dd31ad..afd80acc1b 100644
--- a/backends/platform/dingux/dingux.cpp
+++ b/backends/platform/dingux/dingux.cpp
@@ -33,7 +33,7 @@ void OSystem_SDL_Dingux::initBackend() {
// Create the graphics manager
if (_graphicsManager == 0) {
- _graphicsManager = new DINGUXSdlGraphicsManager(_eventSource);
+ _graphicsManager = new DINGUXSdlGraphicsManager(_eventSource, _window);
}
// Call parent implementation of this method
diff --git a/backends/platform/gph/gph-backend.cpp b/backends/platform/gph/gph-backend.cpp
index d033191d54..fb1cbe030c 100644
--- a/backends/platform/gph/gph-backend.cpp
+++ b/backends/platform/gph/gph-backend.cpp
@@ -159,7 +159,7 @@ void OSystem_GPH::initBackend() {
// Create the graphics manager
if (_graphicsManager == 0) {
- _graphicsManager = new GPHGraphicsManager(_eventSource);
+ _graphicsManager = new GPHGraphicsManager(_eventSource, _window);
}
/* Pass to POSIX method to do the heavy lifting */
diff --git a/backends/platform/linuxmoto/linuxmoto-sdl.cpp b/backends/platform/linuxmoto/linuxmoto-sdl.cpp
index a0310079de..a2b527e6ce 100644
--- a/backends/platform/linuxmoto/linuxmoto-sdl.cpp
+++ b/backends/platform/linuxmoto/linuxmoto-sdl.cpp
@@ -31,7 +31,7 @@ void OSystem_LINUXMOTO::initBackend() {
_eventSource = new LinuxmotoSdlEventSource();
if (_graphicsManager == 0)
- _graphicsManager = new LinuxmotoSdlGraphicsManager(_eventSource);
+ _graphicsManager = new LinuxmotoSdlGraphicsManager(_eventSource, _window);
// Call parent implementation of this method
OSystem_POSIX::initBackend();
diff --git a/backends/platform/maemo/maemo.cpp b/backends/platform/maemo/maemo.cpp
index e81a208f7b..5fdcddac43 100644
--- a/backends/platform/maemo/maemo.cpp
+++ b/backends/platform/maemo/maemo.cpp
@@ -35,10 +35,6 @@
#include "common/textconsole.h"
#include "common/translation.h"
-
-#include <SDL/SDL_syswm.h>
-#include <X11/Xutil.h>
-
namespace Maemo {
OSystem_SDL_Maemo::OSystem_SDL_Maemo()
@@ -84,6 +80,15 @@ static void registerDefaultKeyBindings(Common::KeymapperDefaultBindings *_keymap
}
#endif
+void OSystem_SDL_Maemo::init() {
+ // Use an iconless window for Maemo
+ // also N900 is hit by SDL_WM_SetIcon bug (window cannot receive input)
+ // http://bugzilla.libsdl.org/show_bug.cgi?id=586
+ _window = new SdlIconlessWindow();
+
+ OSystem_POSIX::init();
+}
+
void OSystem_SDL_Maemo::initBackend() {
ConfMan.registerDefault("fullscreen", true);
ConfMan.registerDefault("aspect_ratio", true);
@@ -93,7 +98,7 @@ void OSystem_SDL_Maemo::initBackend() {
_eventSource = new MaemoSdlEventSource();
if (_graphicsManager == 0)
- _graphicsManager = new MaemoSdlGraphicsManager(_eventSource);
+ _graphicsManager = new MaemoSdlGraphicsManager(_eventSource, _window);
if (_eventObserver == 0)
_eventObserver = new MaemoSdlEventObserver((MaemoSdlEventSource *)_eventSource);
@@ -178,12 +183,6 @@ const Maemo::Model OSystem_SDL_Maemo::detectModel() {
return *model;
}
-void OSystem_SDL_Maemo::setupIcon() {
- // no Maemo version needs setupIcon
- // also N900 is hit by SDL_WM_SetIcon bug (window cannot receive input)
- // http://bugzilla.libsdl.org/show_bug.cgi?id=586
-}
-
#ifdef ENABLE_KEYMAPPER
static const Common::KeyTableEntry maemoKeys[] = {
// Function keys
diff --git a/backends/platform/maemo/maemo.h b/backends/platform/maemo/maemo.h
index 532a2de08c..6d6e09bee1 100644
--- a/backends/platform/maemo/maemo.h
+++ b/backends/platform/maemo/maemo.h
@@ -36,11 +36,11 @@ public:
OSystem_SDL_Maemo();
~OSystem_SDL_Maemo();
+ virtual void init();
virtual void initBackend();
virtual void quit();
virtual void fatalError();
virtual void setWindowCaption(const char *caption);
- virtual void setupIcon();
#ifdef ENABLE_KEYMAPPER
virtual Common::HardwareInputSet *getHardwareInputSet();
virtual Common::Keymap *getGlobalKeymap();
diff --git a/backends/platform/openpandora/op-backend.cpp b/backends/platform/openpandora/op-backend.cpp
index abe288f5d7..e7975a6aa0 100644
--- a/backends/platform/openpandora/op-backend.cpp
+++ b/backends/platform/openpandora/op-backend.cpp
@@ -147,7 +147,7 @@ void OSystem_OP::initBackend() {
// Create the graphics manager
if (_graphicsManager == 0) {
- _graphicsManager = new OPGraphicsManager(_eventSource);
+ _graphicsManager = new OPGraphicsManager(_eventSource, _window);
}
/* Pass to POSIX method to do the heavy lifting */
diff --git a/backends/platform/samsungtv/samsungtv.cpp b/backends/platform/samsungtv/samsungtv.cpp
index a1d15930f2..a766916fab 100644
--- a/backends/platform/samsungtv/samsungtv.cpp
+++ b/backends/platform/samsungtv/samsungtv.cpp
@@ -40,7 +40,7 @@ void OSystem_SDL_SamsungTV::initBackend() {
_eventSource = new SamsungTVSdlEventSource();
if (_graphicsManager == 0)
- _graphicsManager = new SamsungTVSdlGraphicsManager(_eventSource);
+ _graphicsManager = new SamsungTVSdlGraphicsManager(_eventSource, _window);
// Call parent implementation of this method
OSystem_POSIX::initBackend();
diff --git a/backends/platform/sdl/macosx/macosx.cpp b/backends/platform/sdl/macosx/macosx.cpp
index c48076c42f..38a2d7441c 100644
--- a/backends/platform/sdl/macosx/macosx.cpp
+++ b/backends/platform/sdl/macosx/macosx.cpp
@@ -47,6 +47,9 @@ OSystem_MacOSX::OSystem_MacOSX()
}
void OSystem_MacOSX::init() {
+ // Use an iconless window on OS X, as we use a nicer external icon there.
+ _window = new SdlIconlessWindow();
+
#if defined(USE_TASKBAR)
// Initialize taskbar manager
_taskbarManager = new MacOSXTaskbarManager();
@@ -101,10 +104,6 @@ void OSystem_MacOSX::addSysArchivesToSearchSet(Common::SearchSet &s, int priorit
}
}
-void OSystem_MacOSX::setupIcon() {
- // Don't set icon on OS X, as we use a nicer external icon there.
-}
-
bool OSystem_MacOSX::hasFeature(Feature f) {
if (f == kFeatureDisplayLogFile)
return true;
diff --git a/backends/platform/sdl/macosx/macosx.h b/backends/platform/sdl/macosx/macosx.h
index 50cef60353..c8b4beaeec 100644
--- a/backends/platform/sdl/macosx/macosx.h
+++ b/backends/platform/sdl/macosx/macosx.h
@@ -38,7 +38,6 @@ public:
virtual void init();
virtual void initBackend();
virtual void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0);
- virtual void setupIcon();
};
#endif
diff --git a/backends/platform/sdl/module.mk b/backends/platform/sdl/module.mk
index a17a326889..74dd506d31 100644
--- a/backends/platform/sdl/module.mk
+++ b/backends/platform/sdl/module.mk
@@ -1,7 +1,8 @@
MODULE := backends/platform/sdl
MODULE_OBJS := \
- sdl.o
+ sdl.o \
+ sdl-window.o
ifdef POSIX
MODULE_OBJS += \
@@ -19,6 +20,7 @@ endif
ifdef WIN32
MODULE_OBJS += \
win32/win32-main.o \
+ win32/win32-window.o \
win32/win32.o
endif
diff --git a/backends/platform/sdl/sdl-sys.h b/backends/platform/sdl/sdl-sys.h
index eec3741ed6..67ad84efd3 100644
--- a/backends/platform/sdl/sdl-sys.h
+++ b/backends/platform/sdl/sdl-sys.h
@@ -52,12 +52,84 @@ typedef struct { int FAKE; } FAKE_FILE;
#define strncasecmp FAKE_strncasecmp
#endif
+// HACK: SDL might include windows.h which defines its own ARRAYSIZE.
+// However, we want to use the version from common/util.h. Thus, we make sure
+// that we actually have this definition after including the SDL headers.
+#if defined(ARRAYSIZE) && defined(COMMON_UTIL_H)
+#define HACK_REDEFINE_ARRAYSIZE
+#undef ARRAYSIZE
+#endif
+
+// HACK to fix compilation with SDL 2.0 in MSVC.
+// In SDL 2.0, intrin.h is now included in SDL_cpuinfo.h, which includes
+// setjmp.h. SDL_cpuinfo.h is included from SDL.h and SDL_syswm.h.
+// Thus, we remove the exceptions for setjmp and longjmp before these two
+// includes. Unfortunately, we can't use SDL_VERSION_ATLEAST here, as SDL.h
+// hasn't been included yet at this point.
+#if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && defined(_MSC_VER)
+// We unset any fake definitions of setjmp/longjmp here
+
+#ifndef FORBIDDEN_SYMBOL_EXCEPTION_setjmp
+#undef setjmp
+#endif
+
+#ifndef FORBIDDEN_SYMBOL_EXCEPTION_longjmp
+#undef longjmp
+#endif
+
+#endif
+
#if defined(__SYMBIAN32__)
#include <esdl\SDL.h>
#else
#include <SDL.h>
#endif
+#include <SDL_syswm.h>
+
+// Restore the forbidden exceptions from the hack above
+#if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && defined(_MSC_VER)
+
+#ifndef FORBIDDEN_SYMBOL_EXCEPTION_setjmp
+#undef setjmp
+#define setjmp(a) FORBIDDEN_SYMBOL_REPLACEMENT
+#endif
+
+#ifndef FORBIDDEN_SYMBOL_EXCEPTION_longjmp
+#undef longjmp
+#define longjmp(a,b) FORBIDDEN_SYMBOL_REPLACEMENT
+#endif
+
+#endif
+
+// SDL_syswm.h will include windows.h on Win32. We need to undefine its
+// ARRAYSIZE definition because we supply our own.
+#undef ARRAYSIZE
+
+#ifdef HACK_REDEFINE_ARRAYSIZE
+#undef HACK_REDEFINE_ARRAYSIZE
+#define ARRAYSIZE(x) ((int)(sizeof(x) / sizeof(x[0])))
+#endif
+
+// In a moment of brilliance Xlib.h included by SDL_syswm.h #defines the
+// following names. In a moment of mental breakdown, which occured upon
+// gazing at Xlib.h, LordHoto decided to undefine them to prevent havoc.
+#ifdef Status
+#undef Status
+#endif
+
+#ifdef Bool
+#undef Bool
+#endif
+
+#ifdef True
+#undef True
+#endif
+
+#ifdef False
+#undef False
+#endif
+
// Finally forbid FILE again (if it was forbidden to start with)
#if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && !defined(FORBIDDEN_SYMBOL_EXCEPTION_FILE)
#undef FILE
@@ -74,5 +146,50 @@ typedef struct { int FAKE; } FAKE_FILE;
#define strncasecmp FORBIDDEN_SYMBOL_REPLACEMENT
#endif
+// SDL 2 has major API changes. We redefine constants which got renamed to
+// ease the transition. This is sometimes dangerous because the values changed
+// too!
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+
+// Type names which changed between SDL 1.2 and SDL 2.
+#define SDLKey SDL_Keycode
+#define SDLMod SDL_Keymod
+#define SDL_keysym SDL_Keysym
+
+// Key code constants which got renamed.
+#define SDLK_SCROLLOCK SDLK_SCROLLLOCK
+#define SDLK_NUMLOCK SDLK_NUMLOCKCLEAR
+#define SDLK_LSUPER SDLK_LGUI
+#define SDLK_RSUPER SDLK_RGUI
+#define SDLK_PRINT SDLK_PRINTSCREEN
+#define SDLK_COMPOSE SDLK_APPLICATION
+#define SDLK_KP0 SDLK_KP_0
+#define SDLK_KP1 SDLK_KP_1
+#define SDLK_KP2 SDLK_KP_2
+#define SDLK_KP3 SDLK_KP_3
+#define SDLK_KP4 SDLK_KP_4
+#define SDLK_KP5 SDLK_KP_5
+#define SDLK_KP6 SDLK_KP_6
+#define SDLK_KP7 SDLK_KP_7
+#define SDLK_KP8 SDLK_KP_8
+#define SDLK_KP9 SDLK_KP_9
+
+// Meta key constants which got renamed.
+#define KMOD_META KMOD_GUI
+
+// SDL surface flags which got removed.
+#define SDL_SRCCOLORKEY 0
+#define SDL_SRCALPHA 0
+#define SDL_FULLSCREEN 0x40000000
+
+// Compatibility implementations for removed functionality.
+int SDL_SetColors(SDL_Surface *surface, SDL_Color *colors, int firstcolor, int ncolors);
+int SDL_SetAlpha(SDL_Surface *surface, Uint32 flag, Uint8 alpha);
+
+#define SDL_SetColorKey SDL_SetColorKey_replacement
+int SDL_SetColorKey_replacement(SDL_Surface *surface, Uint32 flag, Uint32 key);
+
+#endif
+
#endif
diff --git a/backends/platform/sdl/sdl-window.cpp b/backends/platform/sdl/sdl-window.cpp
new file mode 100644
index 0000000000..6d35f77ae0
--- /dev/null
+++ b/backends/platform/sdl/sdl-window.cpp
@@ -0,0 +1,223 @@
+/* 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.
+ *
+ */
+
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+#include "backends/platform/sdl/sdl-window.h"
+
+#include "common/textconsole.h"
+
+#include "icons/scummvm.xpm"
+
+SdlWindow::SdlWindow()
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ : _window(nullptr), _inputGrabState(false), _windowCaption("ScummVM")
+#endif
+ {
+}
+
+SdlWindow::~SdlWindow() {
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ destroyWindow();
+#endif
+}
+
+void SdlWindow::setupIcon() {
+ int x, y, w, h, ncols, nbytes, i;
+ unsigned int rgba[256];
+ unsigned int *icon;
+
+ if (sscanf(scummvm_icon[0], "%d %d %d %d", &w, &h, &ncols, &nbytes) != 4) {
+ warning("Wrong format of scummvm_icon[0] (%s)", scummvm_icon[0]);
+
+ return;
+ }
+ if ((w > 512) || (h > 512) || (ncols > 255) || (nbytes > 1)) {
+ warning("Could not load the built-in icon (%d %d %d %d)", w, h, ncols, nbytes);
+ return;
+ }
+ icon = (unsigned int*)malloc(w*h*sizeof(unsigned int));
+ if (!icon) {
+ warning("Could not allocate temp storage for the built-in icon");
+ return;
+ }
+
+ for (i = 0; i < ncols; i++) {
+ unsigned char code;
+ char color[32];
+ memset(color, 0, sizeof(color));
+ unsigned int col;
+ if (sscanf(scummvm_icon[1 + i], "%c c %s", &code, color) != 2) {
+ warning("Wrong format of scummvm_icon[%d] (%s)", 1 + i, scummvm_icon[1 + i]);
+ }
+ if (!strcmp(color, "None"))
+ col = 0x00000000;
+ else if (!strcmp(color, "black"))
+ col = 0xFF000000;
+ else if (color[0] == '#') {
+ if (sscanf(color + 1, "%06x", &col) != 1) {
+ warning("Wrong format of color (%s)", color + 1);
+ }
+ col |= 0xFF000000;
+ } else {
+ warning("Could not load the built-in icon (%d %s - %s) ", code, color, scummvm_icon[1 + i]);
+ free(icon);
+ return;
+ }
+
+ rgba[code] = col;
+ }
+ for (y = 0; y < h; y++) {
+ const char *line = scummvm_icon[1 + ncols + y];
+ for (x = 0; x < w; x++) {
+ icon[x + w * y] = rgba[(int)line[x]];
+ }
+ }
+
+ SDL_Surface *sdl_surf = SDL_CreateRGBSurfaceFrom(icon, w, h, 32, w * 4, 0xFF0000, 0x00FF00, 0x0000FF, 0xFF000000);
+ if (!sdl_surf) {
+ warning("SDL_CreateRGBSurfaceFrom(icon) failed");
+ }
+
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ if (_window) {
+ SDL_SetWindowIcon(_window, sdl_surf);
+ }
+#else
+ SDL_WM_SetIcon(sdl_surf, NULL);
+#endif
+
+ SDL_FreeSurface(sdl_surf);
+ free(icon);
+}
+
+void SdlWindow::setWindowCaption(const Common::String &caption) {
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ _windowCaption = caption;
+ if (_window) {
+ SDL_SetWindowTitle(_window, caption.c_str());
+ }
+#else
+ SDL_WM_SetCaption(caption.c_str(), caption.c_str());
+#endif
+}
+
+void SdlWindow::toggleMouseGrab() {
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ if (_window) {
+ _inputGrabState = !(SDL_GetWindowGrab(_window) == SDL_TRUE);
+ SDL_SetWindowGrab(_window, _inputGrabState ? SDL_TRUE : SDL_FALSE);
+ }
+#else
+ if (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF) {
+ SDL_WM_GrabInput(SDL_GRAB_ON);
+ } else {
+ SDL_WM_GrabInput(SDL_GRAB_OFF);
+ }
+#endif
+}
+
+bool SdlWindow::hasMouseFocus() const {
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ if (_window) {
+ return (SDL_GetWindowFlags(_window) & SDL_WINDOW_MOUSE_FOCUS);
+ } else {
+ return false;
+ }
+#else
+ return (SDL_GetAppState() & SDL_APPMOUSEFOCUS);
+#endif
+}
+
+void SdlWindow::warpMouseInWindow(uint x, uint y) {
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ if (_window) {
+ SDL_WarpMouseInWindow(_window, x, y);
+ }
+#else
+ SDL_WarpMouse(x, y);
+#endif
+}
+
+void SdlWindow::iconifyWindow() {
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ if (_window) {
+ SDL_MinimizeWindow(_window);
+ }
+#else
+ SDL_WM_IconifyWindow();
+#endif
+}
+
+bool SdlWindow::getSDLWMInformation(SDL_SysWMinfo *info) const {
+ SDL_VERSION(&info->version);
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ return SDL_GetWindowWMInfo(_window, info);
+#else
+ return SDL_GetWMInfo(info);
+#endif
+}
+
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+SDL_Surface *copySDLSurface(SDL_Surface *src) {
+ const bool locked = SDL_MUSTLOCK(src) == SDL_TRUE;
+
+ if (locked) {
+ if (SDL_LockSurface(src) != 0) {
+ return nullptr;
+ }
+ }
+
+ SDL_Surface *res = SDL_CreateRGBSurfaceFrom(src->pixels,
+ src->w, src->h, src->format->BitsPerPixel,
+ src->pitch, src->format->Rmask, src->format->Gmask,
+ src->format->Bmask, src->format->Amask);
+
+ if (locked) {
+ SDL_UnlockSurface(src);
+ }
+
+ return res;
+}
+
+bool SdlWindow::createWindow(int width, int height, uint32 flags) {
+ destroyWindow();
+
+ if (_inputGrabState) {
+ flags |= SDL_WINDOW_INPUT_GRABBED;
+ }
+
+ _window = SDL_CreateWindow(_windowCaption.c_str(), SDL_WINDOWPOS_UNDEFINED,
+ SDL_WINDOWPOS_UNDEFINED, width, height, flags);
+ if (!_window) {
+ return false;
+ }
+ setupIcon();
+
+ return true;
+}
+
+void SdlWindow::destroyWindow() {
+ SDL_DestroyWindow(_window);
+ _window = nullptr;
+}
+#endif
diff --git a/backends/platform/sdl/sdl-window.h b/backends/platform/sdl/sdl-window.h
new file mode 100644
index 0000000000..58b898f824
--- /dev/null
+++ b/backends/platform/sdl/sdl-window.h
@@ -0,0 +1,112 @@
+/* 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 BACKENDS_PLATFORM_SDL_WINDOW_H
+#define BACKENDS_PLATFORM_SDL_WINDOW_H
+
+#include "backends/platform/sdl/sdl-sys.h"
+
+#include "common/str.h"
+
+class SdlWindow {
+public:
+ SdlWindow();
+ virtual ~SdlWindow();
+
+ /**
+ * Setup the window icon.
+ */
+ virtual void setupIcon();
+
+ /**
+ * Change the caption of the window.
+ *
+ * @param caption New window caption in UTF-8 encoding.
+ */
+ void setWindowCaption(const Common::String &caption);
+
+ /**
+ * Toggle mouse grab state. This decides whether the cursor can leave the
+ * window or not.
+ */
+ void toggleMouseGrab();
+
+ /**
+ * Check whether the application has mouse focus.
+ */
+ bool hasMouseFocus() const;
+
+ /**
+ * Warp the mouse to the specified position in window coordinates.
+ */
+ void warpMouseInWindow(uint x, uint y);
+
+ /**
+ * Iconifies the window.
+ */
+ void iconifyWindow();
+
+ /**
+ * Query platform specific SDL window manager information.
+ *
+ * Since this is an SDL internal structure clients are responsible
+ * for accessing it in a version safe manner.
+ */
+ bool getSDLWMInformation(SDL_SysWMinfo *info) const;
+
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+public:
+ /**
+ * @return The window ScummVM has setup with SDL.
+ */
+ SDL_Window *getSDLWindow() const { return _window; }
+
+ /**
+ * Creates a new SDL window (and destroies the old one).
+ *
+ * @param width Width of the window.
+ * @param height Height of the window.
+ * @param flags SDL flags passed to SDL_CreateWindow
+ * @return true on success, false otherwise
+ */
+ bool createWindow(int width, int height, uint32 flags);
+
+ /**
+ * Destroies the current SDL window.
+ */
+ void destroyWindow();
+
+protected:
+ SDL_Window *_window;
+
+private:
+ bool _inputGrabState;
+ Common::String _windowCaption;
+#endif
+};
+
+class SdlIconlessWindow : public SdlWindow {
+public:
+ virtual void setupIcon() {}
+};
+
+#endif
diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp
index 4dc5929dab..6d4dede212 100644
--- a/backends/platform/sdl/sdl.cpp
+++ b/backends/platform/sdl/sdl.cpp
@@ -52,8 +52,6 @@
#include "graphics/cursorman.h"
#endif
-#include "icons/scummvm.xpm"
-
#include <time.h> // for getTimeAndDate()
#ifdef USE_DETECTLANG
@@ -77,7 +75,8 @@ OSystem_SDL::OSystem_SDL()
_initedSDL(false),
_logger(0),
_mixerManager(0),
- _eventSource(0) {
+ _eventSource(0),
+ _window(0) {
}
@@ -95,6 +94,8 @@ OSystem_SDL::~OSystem_SDL() {
}
delete _graphicsManager;
_graphicsManager = 0;
+ delete _window;
+ _window = 0;
delete _eventManager;
_eventManager = 0;
delete _eventSource;
@@ -126,8 +127,10 @@ void OSystem_SDL::init() {
// Initialize SDL
initSDL();
+#if !SDL_VERSION_ATLEAST(2, 0, 0)
// Enable unicode support if possible
SDL_EnableUNICODE(1);
+#endif
// Disable OS cursor
SDL_ShowCursor(SDL_DISABLE);
@@ -147,6 +150,9 @@ void OSystem_SDL::init() {
if (_mutexManager == 0)
_mutexManager = new SdlMutexManager();
+ if (_window == 0)
+ _window = new SdlWindow();
+
#if defined(USE_TASKBAR)
if (_taskbarManager == 0)
_taskbarManager = new Common::TaskbarManager();
@@ -158,10 +164,14 @@ void OSystem_SDL::initBackend() {
// Check if backend has not been initialized
assert(!_inited);
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ const char *sdlDriverName = SDL_GetCurrentVideoDriver();
+#else
const int maxNameLen = 20;
char sdlDriverName[maxNameLen];
sdlDriverName[0] = '\0';
SDL_VideoDriverName(sdlDriverName, maxNameLen);
+#endif
// Using printf rather than debug() here as debug()/logging
// is not active by this point.
debug(1, "Using SDL Video Driver \"%s\"", sdlDriverName);
@@ -172,6 +182,13 @@ void OSystem_SDL::initBackend() {
_eventSource = new SdlEventSource();
#ifdef USE_OPENGL
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ SDL_DisplayMode displayMode;
+ if (!SDL_GetDesktopDisplayMode(0, &displayMode)) {
+ _desktopWidth = displayMode.w;
+ _desktopHeight = displayMode.h;
+ }
+#else
// Query the desktop resolution. We simply hope nothing tried to change
// the resolution so far.
const SDL_VideoInfo *videoInfo = SDL_GetVideoInfo();
@@ -180,6 +197,7 @@ void OSystem_SDL::initBackend() {
_desktopHeight = videoInfo->current_h;
}
#endif
+#endif
if (_graphicsManager == 0) {
#ifdef USE_OPENGL
@@ -196,7 +214,7 @@ void OSystem_SDL::initBackend() {
Common::String gfxMode(ConfMan.get("gfx_mode"));
for (uint i = _firstGLMode; i < _graphicsModeIds.size(); ++i) {
if (!scumm_stricmp(_graphicsModes[i].name, gfxMode.c_str())) {
- _graphicsManager = new OpenGLSdlGraphicsManager(_desktopWidth, _desktopHeight, _eventSource);
+ _graphicsManager = new OpenGLSdlGraphicsManager(_desktopWidth, _desktopHeight, _eventSource, _window);
_graphicsMode = i;
break;
}
@@ -205,7 +223,7 @@ void OSystem_SDL::initBackend() {
#endif
if (_graphicsManager == 0) {
- _graphicsManager = new SurfaceSdlGraphicsManager(_eventSource);
+ _graphicsManager = new SurfaceSdlGraphicsManager(_eventSource, _window);
}
}
@@ -238,7 +256,7 @@ void OSystem_SDL::initBackend() {
}
// Setup a custom program icon.
- setupIcon();
+ _window->setupIcon();
_inited = true;
@@ -314,7 +332,7 @@ void OSystem_SDL::setWindowCaption(const char *caption) {
}
}
- SDL_WM_SetCaption(cap.c_str(), cap.c_str());
+ _window->setWindowCaption(cap);
}
void OSystem_SDL::quit() {
@@ -421,68 +439,6 @@ Common::String OSystem_SDL::getSystemLanguage() const {
#endif // USE_DETECTLANG
}
-void OSystem_SDL::setupIcon() {
- int x, y, w, h, ncols, nbytes, i;
- unsigned int rgba[256];
- unsigned int *icon;
-
- if (sscanf(scummvm_icon[0], "%d %d %d %d", &w, &h, &ncols, &nbytes) != 4) {
- warning("Wrong format of scummvm_icon[0] (%s)", scummvm_icon[0]);
-
- return;
- }
- if ((w > 512) || (h > 512) || (ncols > 255) || (nbytes > 1)) {
- warning("Could not load the built-in icon (%d %d %d %d)", w, h, ncols, nbytes);
- return;
- }
- icon = (unsigned int*)malloc(w*h*sizeof(unsigned int));
- if (!icon) {
- warning("Could not allocate temp storage for the built-in icon");
- return;
- }
-
- for (i = 0; i < ncols; i++) {
- unsigned char code;
- char color[32];
- memset(color, 0, sizeof(color));
- unsigned int col;
- if (sscanf(scummvm_icon[1 + i], "%c c %s", &code, color) != 2) {
- warning("Wrong format of scummvm_icon[%d] (%s)", 1 + i, scummvm_icon[1 + i]);
- }
- if (!strcmp(color, "None"))
- col = 0x00000000;
- else if (!strcmp(color, "black"))
- col = 0xFF000000;
- else if (color[0] == '#') {
- if (sscanf(color + 1, "%06x", &col) != 1) {
- warning("Wrong format of color (%s)", color + 1);
- }
- col |= 0xFF000000;
- } else {
- warning("Could not load the built-in icon (%d %s - %s) ", code, color, scummvm_icon[1 + i]);
- free(icon);
- return;
- }
-
- rgba[code] = col;
- }
- for (y = 0; y < h; y++) {
- const char *line = scummvm_icon[1 + ncols + y];
- for (x = 0; x < w; x++) {
- icon[x + w * y] = rgba[(int)line[x]];
- }
- }
-
- SDL_Surface *sdl_surf = SDL_CreateRGBSurfaceFrom(icon, w, h, 32, w * 4, 0xFF0000, 0x00FF00, 0x0000FF, 0xFF000000);
- if (!sdl_surf) {
- warning("SDL_CreateRGBSurfaceFrom(icon) failed");
- }
- SDL_WM_SetIcon(sdl_surf, NULL);
- SDL_FreeSurface(sdl_surf);
- free(icon);
-}
-
-
uint32 OSystem_SDL::getMillis(bool skipRecord) {
uint32 millis = SDL_GetTicks();
@@ -572,14 +528,8 @@ bool OSystem_SDL::setGraphicsMode(int mode) {
//
// This is a probably temporary workaround to fix bugs like #3368143
// "SDL/OpenGL: Crash when switching renderer backend".
- const int screenWidth = _graphicsManager->getWidth();
- const int screenHeight = _graphicsManager->getHeight();
- const bool arState = _graphicsManager->getFeatureState(kFeatureAspectRatioCorrection);
- const bool fullscreen = _graphicsManager->getFeatureState(kFeatureFullscreenMode);
- const bool cursorPalette = _graphicsManager->getFeatureState(kFeatureCursorPalette);
-#ifdef USE_RGB_COLOR
- const Graphics::PixelFormat pixelFormat = _graphicsManager->getScreenFormat();
-#endif
+ SdlGraphicsManager *sdlGraphicsManager = dynamic_cast<SdlGraphicsManager *>(_graphicsManager);
+ SdlGraphicsManager::State state = sdlGraphicsManager->getState();
bool switchedManager = false;
@@ -587,16 +537,16 @@ bool OSystem_SDL::setGraphicsMode(int mode) {
// manager, delete and create the new mode graphics manager
if (_graphicsMode >= _firstGLMode && mode < _firstGLMode) {
debug(1, "switching to plain SDL graphics");
- dynamic_cast<SdlGraphicsManager *>(_graphicsManager)->deactivateManager();
+ sdlGraphicsManager->deactivateManager();
delete _graphicsManager;
- _graphicsManager = new SurfaceSdlGraphicsManager(_eventSource);
+ _graphicsManager = sdlGraphicsManager = new SurfaceSdlGraphicsManager(_eventSource, _window);
switchedManager = true;
} else if (_graphicsMode < _firstGLMode && mode >= _firstGLMode) {
debug(1, "switching to OpenGL graphics");
- dynamic_cast<SdlGraphicsManager *>(_graphicsManager)->deactivateManager();
+ sdlGraphicsManager->deactivateManager();
delete _graphicsManager;
- _graphicsManager = new OpenGLSdlGraphicsManager(_desktopWidth, _desktopHeight, _eventSource);
+ _graphicsManager = sdlGraphicsManager = new OpenGLSdlGraphicsManager(_desktopWidth, _desktopHeight, _eventSource, _window);
switchedManager = true;
}
@@ -604,24 +554,10 @@ bool OSystem_SDL::setGraphicsMode(int mode) {
_graphicsMode = mode;
if (switchedManager) {
- dynamic_cast<SdlGraphicsManager *>(_graphicsManager)->activateManager();
+ sdlGraphicsManager->activateManager();
- _graphicsManager->beginGFXTransaction();
-#ifdef USE_RGB_COLOR
- _graphicsManager->initSize(screenWidth, screenHeight, &pixelFormat);
-#else
- _graphicsManager->initSize(screenWidth, screenHeight, 0);
-#endif
- _graphicsManager->setFeatureState(kFeatureAspectRatioCorrection, arState);
- _graphicsManager->setFeatureState(kFeatureFullscreenMode, fullscreen);
- _graphicsManager->setFeatureState(kFeatureCursorPalette, cursorPalette);
-
- // Worst part about this right now, tell the cursor manager to
- // resetup the cursor + cursor palette if necessarily
-
- // First we need to try to setup the old state on the new manager...
- if (_graphicsManager->endGFXTransaction() != kTransactionSuccess) {
- // Oh my god if this failed the client code might just explode.
+ // This failing will probably have bad consequences...
+ if (!sdlGraphicsManager->setState(state)) {
return false;
}
@@ -630,7 +566,7 @@ bool OSystem_SDL::setGraphicsMode(int mode) {
CursorMan.popCursor();
// Next setup cursor palette if needed
- if (cursorPalette) {
+ if (_graphicsManager->getFeatureState(kFeatureCursorPalette)) {
CursorMan.pushCursorPalette(0, 0, 0);
CursorMan.popCursorPalette();
}
@@ -660,7 +596,7 @@ void OSystem_SDL::setupGraphicsModes() {
const OSystem::GraphicsMode *srcMode;
int defaultMode;
- GraphicsManager *manager = new SurfaceSdlGraphicsManager(_eventSource);
+ GraphicsManager *manager = new SurfaceSdlGraphicsManager(_eventSource, _window);
srcMode = manager->getSupportedGraphicsModes();
defaultMode = manager->getDefaultGraphicsMode();
while (srcMode->name) {
@@ -674,7 +610,7 @@ void OSystem_SDL::setupGraphicsModes() {
assert(_defaultSDLMode != -1);
_firstGLMode = _graphicsModes.size();
- manager = new OpenGLSdlGraphicsManager(_desktopWidth, _desktopHeight, _eventSource);
+ manager = new OpenGLSdlGraphicsManager(_desktopWidth, _desktopHeight, _eventSource, _window);
srcMode = manager->getSupportedGraphicsModes();
defaultMode = manager->getDefaultGraphicsMode();
while (srcMode->name) {
@@ -702,5 +638,38 @@ void OSystem_SDL::setupGraphicsModes() {
mode++;
}
}
+#endif
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+int SDL_SetColors(SDL_Surface *surface, SDL_Color *colors, int firstcolor, int ncolors) {
+ if (surface->format->palette) {
+ return !SDL_SetPaletteColors(surface->format->palette, colors, firstcolor, ncolors) ? 1 : 0;
+ } else {
+ return 0;
+ }
+}
+
+int SDL_SetAlpha(SDL_Surface *surface, Uint32 flag, Uint8 alpha) {
+ if (SDL_SetSurfaceAlphaMod(surface, alpha)) {
+ return -1;
+ }
+
+ if (alpha == 255 || !flag) {
+ if (SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_NONE)) {
+ return -1;
+ }
+ } else {
+ if (SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_BLEND)) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+#undef SDL_SetColorKey
+int SDL_SetColorKey_replacement(SDL_Surface *surface, Uint32 flag, Uint32 key) {
+ return SDL_SetColorKey(surface, SDL_TRUE, key) ? -1 : 0;
+}
#endif
+
diff --git a/backends/platform/sdl/sdl.h b/backends/platform/sdl/sdl.h
index 5dcc269e55..5ee56d0568 100644
--- a/backends/platform/sdl/sdl.h
+++ b/backends/platform/sdl/sdl.h
@@ -29,6 +29,7 @@
#include "backends/mixer/sdl/sdl-mixer.h"
#include "backends/events/sdl/sdl-events.h"
#include "backends/log/log.h"
+#include "backends/platform/sdl/sdl-window.h"
#include "common/array.h"
@@ -91,6 +92,11 @@ protected:
*/
SdlEventSource *_eventSource;
+ /**
+ * The SDL output window.
+ */
+ SdlWindow *_window;
+
virtual Common::EventSource *getDefaultEventSource() { return _eventSource; }
/**
@@ -98,11 +104,6 @@ protected:
*/
virtual void initSDL();
- /**
- * Setup the window icon.
- */
- virtual void setupIcon();
-
// Logging
virtual Common::WriteStream *createLogFile() { return 0; }
Backends::Log::Log *_logger;
diff --git a/backends/platform/sdl/win32/win32-main.cpp b/backends/platform/sdl/win32/win32-main.cpp
index e5b26c3ff0..c6c15c00e8 100644
--- a/backends/platform/sdl/win32/win32-main.cpp
+++ b/backends/platform/sdl/win32/win32-main.cpp
@@ -40,7 +40,9 @@
#include "base/main.h"
int __stdcall WinMain(HINSTANCE /*hInst*/, HINSTANCE /*hPrevInst*/, LPSTR /*lpCmdLine*/, int /*iShowCmd*/) {
+#if !SDL_VERSION_ATLEAST(2, 0, 0)
SDL_SetModuleHandle(GetModuleHandle(NULL));
+#endif
return main(__argc, __argv);
}
diff --git a/backends/platform/sdl/win32/win32-window.cpp b/backends/platform/sdl/win32/win32-window.cpp
new file mode 100644
index 0000000000..de10be6b57
--- /dev/null
+++ b/backends/platform/sdl/win32/win32-window.cpp
@@ -0,0 +1,59 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+// Disable symbol overrides so that we can use system headers.
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+#ifdef WIN32
+
+#include "backends/platform/sdl/win32/win32-window.h"
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef ARRAYSIZE // winnt.h defines ARRAYSIZE, but we want our own one...
+
+void SdlWindow_Win32::setupIcon() {
+ HMODULE handle = GetModuleHandle(NULL);
+ HICON ico = LoadIcon(handle, MAKEINTRESOURCE(1001 /* IDI_ICON */));
+ if (ico) {
+ SDL_SysWMinfo wminfo;
+ if (getSDLWMInformation(&wminfo)) {
+ // Replace the handle to the icon associated with the window class by our custom icon
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ SetClassLongPtr(wminfo.info.win.window, GCLP_HICON, (ULONG_PTR)ico);
+#else
+ SetClassLongPtr(wminfo.window, GCLP_HICON, (ULONG_PTR)ico);
+#endif
+
+ // Since there wasn't any default icon, we can't use the return value from SetClassLong
+ // to check for errors (it would be 0 in both cases: error or no previous value for the
+ // icon handle). Instead we check for the last-error code value.
+ if (GetLastError() == ERROR_SUCCESS)
+ return;
+ }
+ }
+
+ // If no icon has been set, fallback to default path
+ SdlWindow::setupIcon();
+}
+
+#endif
diff --git a/engines/zvision/detection.h b/backends/platform/sdl/win32/win32-window.h
index f80cac79ec..3bda697bc7 100644
--- a/engines/zvision/detection.h
+++ b/backends/platform/sdl/win32/win32-window.h
@@ -20,24 +20,18 @@
*
*/
-#ifndef ZVISION_DETECTION_H
-#define ZVISION_DETECTION_H
+#ifndef BACKENDS_PLATFORM_SDL_WIN32_WIN32_WINDOW_H
+#define BACKENDS_PLATFORM_SDL_WIN32_WIN32_WINDOW_H
-#include "engines/advancedDetector.h"
+#ifdef WIN32
-namespace ZVision {
+#include "backends/platform/sdl/sdl-window.h"
-enum ZVisionGameId {
- GID_NONE = 0,
- GID_NEMESIS = 1,
- GID_GRANDINQUISITOR = 2
+class SdlWindow_Win32 : public SdlWindow {
+public:
+ virtual void setupIcon();
};
-struct ZVisionGameDescription {
- ADGameDescription desc;
- ZVisionGameId gameId;
-};
-
-}
+#endif
#endif
diff --git a/backends/platform/sdl/win32/win32.cpp b/backends/platform/sdl/win32/win32.cpp
index 5f860ad32d..0f70c00b40 100644
--- a/backends/platform/sdl/win32/win32.cpp
+++ b/backends/platform/sdl/win32/win32.cpp
@@ -35,9 +35,8 @@
#include "common/error.h"
#include "common/textconsole.h"
-#include <SDL_syswm.h> // For setting the icon
-
#include "backends/platform/sdl/win32/win32.h"
+#include "backends/platform/sdl/win32/win32-window.h"
#include "backends/saves/windows/windows-saves.h"
#include "backends/fs/windows/windows-fs-factory.h"
#include "backends/taskbar/win32/win32-taskbar.h"
@@ -50,9 +49,12 @@ void OSystem_Win32::init() {
// Initialize File System Factory
_fsFactory = new WindowsFilesystemFactory();
+ // Create Win32 specific window
+ _window = new SdlWindow_Win32();
+
#if defined(USE_TASKBAR)
// Initialize taskbar manager
- _taskbarManager = new Win32TaskbarManager();
+ _taskbarManager = new Win32TaskbarManager(_window);
#endif
// Invoke parent implementation of this method
@@ -126,28 +128,6 @@ bool OSystem_Win32::displayLogFile() {
return false;
}
-void OSystem_Win32::setupIcon() {
- HMODULE handle = GetModuleHandle(NULL);
- HICON ico = LoadIcon(handle, MAKEINTRESOURCE(1001 /* IDI_ICON */));
- if (ico) {
- SDL_SysWMinfo wminfo;
- SDL_VERSION(&wminfo.version);
- if (SDL_GetWMInfo(&wminfo)) {
- // Replace the handle to the icon associated with the window class by our custom icon
- SetClassLongPtr(wminfo.window, GCLP_HICON, (ULONG_PTR)ico);
-
- // Since there wasn't any default icon, we can't use the return value from SetClassLong
- // to check for errors (it would be 0 in both cases: error or no previous value for the
- // icon handle). Instead we check for the last-error code value.
- if (GetLastError() == ERROR_SUCCESS)
- return;
- }
- }
-
- // If no icon has been set, fallback to default path
- OSystem_SDL::setupIcon();
-}
-
Common::String OSystem_Win32::getDefaultConfigFileName() {
char configFile[MAXPATHLEN];
diff --git a/backends/platform/sdl/win32/win32.h b/backends/platform/sdl/win32/win32.h
index d72d80bc26..473e78ff0b 100644
--- a/backends/platform/sdl/win32/win32.h
+++ b/backends/platform/sdl/win32/win32.h
@@ -47,7 +47,6 @@ protected:
*/
Common::String _logFilePath;
- virtual void setupIcon();
virtual Common::String getDefaultConfigFileName();
virtual Common::WriteStream *createLogFile();
};
diff --git a/backends/platform/symbian/AdaptAllMMPs.pl b/backends/platform/symbian/AdaptAllMMPs.pl
index 6eed7f0690..6b9f918a51 100644
--- a/backends/platform/symbian/AdaptAllMMPs.pl
+++ b/backends/platform/symbian/AdaptAllMMPs.pl
@@ -48,12 +48,14 @@ chdir("../../../");
"mmp/scummvm_voyeur.mmp",
"mmp/scummvm_wintermute.mmp",
# New engines
+ "mmp/scummvm_access.mmp",
"mmp/scummvm_avalanche.mmp",
"mmp/scummvm_bbvs.mmp",
"mmp/scummvm_cge2.mmp",
"mmp/scummvm_fullpipe.mmp",
"mmp/scummvm_lastexpress.mmp",
"mmp/scummvm_mads.mmp",
+ "mmp/scummvm_prince.mmp",
"mmp/scummvm_sword25.mmp",
"mmp/scummvm_testbed.mmp",
"mmp/scummvm_zvision.mmp",
@@ -103,6 +105,7 @@ my @sections_scumm = ("", "ENABLE_SCUMM_7_8", "ENABLE_HE"); # special sections f
# files excluded from build, case insensitive, will be matched in filename string only
my @excludes_snd = (
"mt32.*",
+ "Analog.cpp",
"fluidsynth.cpp",
"i386.cpp",
"part.*",
@@ -191,6 +194,7 @@ ParseModule("_tucker", "tucker", \@section_empty);
ParseModule("_voyeur" ,"voyeur", \@section_empty);
ParseModule("_wintermute","wintermute", \@section_empty);
##### new engines
+ParseModule("_access" ,"access", \@section_empty);
ParseModule("_avalanche" ,"avalanche", \@section_empty);
ParseModule("_bbvs" ,"bbvs", \@section_empty);
ParseModule("_cge2" ,"cge2", \@section_empty);
@@ -198,6 +202,7 @@ ParseModule("_fullpipe" ,"fullpipe", \@section_empty);
ParseModule("_lastexpress","lastexpress", \@section_empty);
ParseModule("_m4", "m4", \@section_empty);
ParseModule("_mads" ,"mads", \@section_empty);
+ParseModule("_prince" ,"prince", \@section_empty);
ParseModule("_sword25" ,"sword25", \@section_empty);
ParseModule("_testbed" ,"testbed", \@section_empty);
ParseModule("_zvision" ,"zvision", \@section_empty);
diff --git a/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl b/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl
index f9b376d674..8c19631524 100644
--- a/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl
+++ b/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl
@@ -3,32 +3,36 @@
@WorkingEngines = qw(
agos agi cine cge composer cruise draci dreamweb
- drascula hugo gob groovie kyra lastexpress
- lure made mohawk parallaction pegasus queen
- saga sci scumm sky sword1 sword2 teenagent tinsel
- toltecs tony toon touche tsage tucker wintermute
- bbvs fullpipe hopkins mortevielle mads cge2
- neverhood testbed avalanche zvision voyeur
+ drascula hugo gob groovie hopkins kyra lastexpress
+ lure made mohawk mortevielle neverhood parallaction
+ pegasus queen saga sci scumm sky sword1 sword2
+ teenagent tinsel toltecs tony toon touche tsage
+ tucker voyeur wintermute
+ access avalanche bbvs cge2 fullpipe mads prince
+ testbed zvision
);
-#### New engines
-#### sword25
+
+#### sword25 yet not added
+
+#### In progress engines are :
+#### access avalanche bbvs cge2 fullpipe mads prince
+#### testbed zvision
@WorkingEngines_1st = qw(
- cge2 cine composer cruise drascula groovie
- lastexpress made parallaction queen
- saga scumm touche tucker wintermute
- avalanche zvision voyeur
+ cine composer cruise drascula groovie
+ lastexpress made parallaction queen saga
+ scumm touche tucker wintermute voyeur
+ access avalanche cge2 zvision
);
@WorkingEngines_2nd = qw(
- agi agos bbvs cge draci gob hopkins
- hugo kyra lure mohawk pegasus sci
- sky sword1 sword2 teenagent mads
+ agi agos cge draci dreamweb gob hopkins
+ hugo kyra lure mohawk mortevielle neverhood
+ pegasus sci sky sword1 sword2 teenagent
tinsel tsage toltecs tony toon
- dreamweb fullpipe mortevielle
- neverhood testbed
+ bbvs fullpipe mads prince testbed
);
-#### sword25
+#### sword25 yet not added
@TestingEngines = qw(
diff --git a/backends/platform/symbian/README b/backends/platform/symbian/README
index 8a44e9399d..655ec5137a 100644
--- a/backends/platform/symbian/README
+++ b/backends/platform/symbian/README
@@ -1,7 +1,7 @@
ScummVM - ScummVM ported to EPOC/SymbianOS
- Copyright (C) 2008-2014 ScummVM Team
+ Copyright (C) 2008-2015 ScummVM Team
Copyright (C) 2013-2013 Fedor Strizhniou aka zanac
Copyright (C) 2003-2013 Lars 'AnotherGuest' Persson
Copyright (C) 2002-2008 Jurgen 'SumthinWicked' Braam
diff --git a/backends/platform/symbian/S60/ScummVM_S60.mmp.in b/backends/platform/symbian/S60/ScummVM_S60.mmp.in
index ca2ec7f930..c4b0bf49df 100644
--- a/backends/platform/symbian/S60/ScummVM_S60.mmp.in
+++ b/backends/platform/symbian/S60/ScummVM_S60.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2014 The ScummVM Team
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/S60/ScummVM_S60_App.mmp b/backends/platform/symbian/S60/ScummVM_S60_App.mmp
index 2fc39c6838..f9bd30025c 100644
--- a/backends/platform/symbian/S60/ScummVM_S60_App.mmp
+++ b/backends/platform/symbian/S60/ScummVM_S60_App.mmp
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2014 The ScummVM Team
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/S60v3/ScummVM_A0000658_S60v3.mmp.in b/backends/platform/symbian/S60v3/ScummVM_A0000658_S60v3.mmp.in
index 3a08763e64..c9e4769484 100644
--- a/backends/platform/symbian/S60v3/ScummVM_A0000658_S60v3.mmp.in
+++ b/backends/platform/symbian/S60v3/ScummVM_A0000658_S60v3.mmp.in
@@ -3,7 +3,7 @@
* Copyright (C) 2003-2014 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
* Copyright (C) 2013-2014 Fedor Strizhniou Additional library porting, engine support, help files etc
- * Copyright (C) 2005-2014 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/S60v3/ScummVM_S60v3.mmp.in b/backends/platform/symbian/S60v3/ScummVM_S60v3.mmp.in
index f65be1208e..f2d7b51a7a 100644
--- a/backends/platform/symbian/S60v3/ScummVM_S60v3.mmp.in
+++ b/backends/platform/symbian/S60v3/ScummVM_S60v3.mmp.in
@@ -3,7 +3,7 @@
* Copyright (C) 2003-2014 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
* Copyright (C) 2013-2014 Fedor Strizhniou Additional library porting, engine support, help files etc
- * Copyright (C) 2005-2014 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/S80/ScummVM_S80.mmp.in b/backends/platform/symbian/S80/ScummVM_S80.mmp.in
index 34d1979fe5..0a7a755e47 100644
--- a/backends/platform/symbian/S80/ScummVM_S80.mmp.in
+++ b/backends/platform/symbian/S80/ScummVM_S80.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2014 The ScummVM Team
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/S80/ScummVM_S80_App.mmp b/backends/platform/symbian/S80/ScummVM_S80_App.mmp
index de96963d80..a949c10169 100644
--- a/backends/platform/symbian/S80/ScummVM_S80_App.mmp
+++ b/backends/platform/symbian/S80/ScummVM_S80_App.mmp
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2014 The ScummVM Team
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/S90/Scummvm_S90.mmp.in b/backends/platform/symbian/S90/Scummvm_S90.mmp.in
index e65397b145..eaf4673de8 100644
--- a/backends/platform/symbian/S90/Scummvm_S90.mmp.in
+++ b/backends/platform/symbian/S90/Scummvm_S90.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2014 The ScummVM Team
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/S90/Scummvm_S90_App.mmp b/backends/platform/symbian/S90/Scummvm_S90_App.mmp
index 88a3e4d221..e4426a3351 100644
--- a/backends/platform/symbian/S90/Scummvm_S90_App.mmp
+++ b/backends/platform/symbian/S90/Scummvm_S90_App.mmp
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2014 The ScummVM Team
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/UIQ2/ScummVM.rss b/backends/platform/symbian/UIQ2/ScummVM.rss
index 2e02f1da1d..b8b48cd8f7 100644
--- a/backends/platform/symbian/UIQ2/ScummVM.rss
+++ b/backends/platform/symbian/UIQ2/ScummVM.rss
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2014 The ScummVM Team
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/backends/platform/symbian/UIQ3/ScummVM.rss b/backends/platform/symbian/UIQ3/ScummVM.rss
index 11cc767671..612c52e0b2 100644
--- a/backends/platform/symbian/UIQ3/ScummVM.rss
+++ b/backends/platform/symbian/UIQ3/ScummVM.rss
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2014 The ScummVM Team
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/UIQ3/ScummVM_A0000658.rss b/backends/platform/symbian/UIQ3/ScummVM_A0000658.rss
index 11cc767671..612c52e0b2 100644
--- a/backends/platform/symbian/UIQ3/ScummVM_A0000658.rss
+++ b/backends/platform/symbian/UIQ3/ScummVM_A0000658.rss
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2014 The ScummVM Team
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/UIQ3/ScummVM_A0000658_UIQ3.mmp.in b/backends/platform/symbian/UIQ3/ScummVM_A0000658_UIQ3.mmp.in
index 6e84ab7b08..7d580255bc 100644
--- a/backends/platform/symbian/UIQ3/ScummVM_A0000658_UIQ3.mmp.in
+++ b/backends/platform/symbian/UIQ3/ScummVM_A0000658_UIQ3.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2009 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2009 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2014 The ScummVM Team
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/UIQ3/ScummVM_UIQ3.mmp.in b/backends/platform/symbian/UIQ3/ScummVM_UIQ3.mmp.in
index fee0c81e7a..33a2276b0d 100644
--- a/backends/platform/symbian/UIQ3/ScummVM_UIQ3.mmp.in
+++ b/backends/platform/symbian/UIQ3/ScummVM_UIQ3.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2014 The ScummVM Team
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/UIQ3/scummvm_A0000658_loc.rss b/backends/platform/symbian/UIQ3/scummvm_A0000658_loc.rss
index f54bcc24d3..b79beddcb7 100644
--- a/backends/platform/symbian/UIQ3/scummvm_A0000658_loc.rss
+++ b/backends/platform/symbian/UIQ3/scummvm_A0000658_loc.rss
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2014 The ScummVM Team
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/help/ScummVM.rtf b/backends/platform/symbian/help/ScummVM.rtf
index 8e9d37363c..15b2105ecd 100644
--- a/backends/platform/symbian/help/ScummVM.rtf
+++ b/backends/platform/symbian/help/ScummVM.rtf
@@ -51,24 +51,27 @@ Synonyms;}{\*\cs33 \additive \super \sbasedon10 endnote reference;}{\s34\ql \fi-
{\listoverride\listid-125\listoverridecount0\ls12}{\listoverride\listid-120\listoverridecount0\ls13}{\listoverride\listid-129\listoverridecount0\ls14}{\listoverride\listid-119\listoverridecount0\ls15}{\listoverride\listid-125\listoverridecount0\ls16}
{\listoverride\listid-120\listoverridecount0\ls17}{\listoverride\listid-129\listoverridecount0\ls18}{\listoverride\listid-119\listoverridecount0\ls19}{\listoverride\listid-125\listoverridecount0\ls20}{\listoverride\listid-120\listoverridecount0\ls21}
{\listoverride\listid-129\listoverridecount0\ls22}{\listoverride\listid-119\listoverridecount0\ls23}{\listoverride\listid-125\listoverridecount0\ls24}{\listoverride\listid-120\listoverridecount0\ls25}{\listoverride\listid-129\listoverridecount0\ls26}
-{\listoverride\listid-119\listoverridecount0\ls27}{\listoverride\listid-125\listoverridecount0\ls28}{\listoverride\listid-2\listoverridecount1{\lfolevel\listoverrideformat{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1
-\levelold\levelspace0\levelindent283{\leveltext\'01\u-3991 ?;}{\levelnumbers;}\f30\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1\fbias0 \fi-283\li283 }}\ls29}{\listoverride\listid-2\listoverridecount1{\lfolevel\listoverrideformat{\listlevel
-\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelold\levelspace0\levelindent283{\leveltext\'01\u-3991 ?;}{\levelnumbers;}\f30\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1\fbias0 \fi-283\li283 }}\ls30}}{\info{\author Fedor}
-{\operator Fedor}{\creatim\yr2013\mo11\dy30\hr23\min4}{\revtim\yr2014\mo9\dy9\hr19\min22}{\version99}{\edmins93}{\nofpages8}{\nofwords1514}{\nofchars8634}{\*\company DEV}{\nofcharsws0}{\vern8249}}\margl1701\margr850\margt1134\margb1134
-\deftab708\widowctrl\ftnbj\aenddoc\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\hyphcaps0\horzdoc\dghspace120\dgvspace120\dghorigin1701\dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind4\viewscale100\nolnhtadjtbl \fet0{\*\template
-E:\\Documents and Settings\\Administrator\\Application Data\\Microsoft\\\'d8\'e0\'e1\'eb\'ee\'ed\'fb\\cshelp2000.dot}\sectd \linex0\sectdefaultcl {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang
-{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang
-{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain
-\s17\ql \li0\ri0\sa120\widctlpar\nooverflow\faroman\rin0\lin0\itap0 \i\f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\lang1033\langfe1033\langnp1033 Author: Fedor Strizhniou.}{\f28
-\par }{\lang1033\langfe1033\langnp1033 Date: November 2013}{\f28
-\par }{\lang1033\langfe1033\langnp1033 Version: 1.7.0
+{\listoverride\listid-119\listoverridecount0\ls27}{\listoverride\listid-125\listoverridecount0\ls28}{\listoverride\listid-120\listoverridecount0\ls29}{\listoverride\listid-129\listoverridecount0\ls30}{\listoverride\listid-119\listoverridecount0\ls31}
+{\listoverride\listid-125\listoverridecount0\ls32}{\listoverride\listid-120\listoverridecount0\ls33}{\listoverride\listid-129\listoverridecount0\ls34}{\listoverride\listid-119\listoverridecount0\ls35}{\listoverride\listid-125\listoverridecount0\ls36}
+{\listoverride\listid-120\listoverridecount0\ls37}{\listoverride\listid-129\listoverridecount0\ls38}{\listoverride\listid-119\listoverridecount0\ls39}{\listoverride\listid-125\listoverridecount0\ls40}{\listoverride\listid-2\listoverridecount1{\lfolevel
+\listoverrideformat{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelold\levelspace0\levelindent283{\leveltext\'01\u-3991 ?;}{\levelnumbers;}\f30\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1\fbias0 \fi-283\li283
+}}\ls41}{\listoverride\listid-2\listoverridecount1{\lfolevel\listoverrideformat{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelold\levelspace0\levelindent283{\leveltext\'01\u-3991 ?;}{\levelnumbers;}\f30\chbrdr
+\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1\fbias0 \fi-283\li283 }}\ls42}}{\info{\author Fedor}{\operator Fedor}{\creatim\yr2013\mo11\dy30\hr23\min4}{\revtim\yr2014\mo12\dy29\hr22\min52}{\version102}{\edmins95}{\nofpages8}{\nofwords1514}{\nofchars8634}
+{\*\company DEV}{\nofcharsws0}{\vern8249}}\margl1701\margr850\margt1134\margb1134 \deftab708\widowctrl\ftnbj\aenddoc\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\hyphcaps0\horzdoc\dghspace120\dgvspace120\dghorigin1701\dgvorigin1984\dghshow0
+\dgvshow3\jcompress\viewkind4\viewscale100\nolnhtadjtbl \fet0{\*\template E:\\Documents and Settings\\Administrator\\Application Data\\Microsoft\\\'d8\'e0\'e1\'eb\'ee\'ed\'fb\\cshelp2000.dot}\sectd \linex0\sectdefaultcl {\*\pnseclvl1
+\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5
+\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang
+{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \s17\ql \li0\ri0\sa120\widctlpar\nooverflow\faroman\rin0\lin0\itap0 \i\f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {
+\lang1033\langfe1033\langnp1033 Author: Fedor Strizhniou.}{\f28
+\par }{\lang1033\langfe1033\langnp1033 Date: November 2014}{\f28
+\par }{\lang1033\langfe1033\langnp1033 Version: 1.8.0
\par }\pard\plain \s1\ql \li0\ri0\sb360\sa240\keepn\widctlpar\nooverflow\faroman\outlinelevel0\rin0\lin0\itap0 \b\f1\fs32\lang2057\langfe1033\kerning28\cgrid\langnp2057\langfenp1033 {ScummVM Help
\par }\pard\plain \s16\ql \li0\ri0\sb360\sa240\keepn\widctlpar\nooverflow\faroman\rin0\lin0\itap0 \b\f1\fs32\cf9\lang2057\langfe1033\kerning28\cgrid\langnp2057\langfenp1033 {\lang1033\langfe1033\langnp1033 0x100039ce}{\lang1059\langfe1033\langnp1059
\par }\pard\plain \ql \li0\ri0\sa120\widctlpar\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\f28
\par }\pard\plain \s2\ql \li0\ri0\sb120\sa120\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp20 \brdrb\brdrs\brdrw30\brsp20 \tqr\tx9072\nooverflow\faroman\outlinelevel1\rin0\lin0\itap0 \b\f1\fs24\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\b0\f28
About ScummVM Help
-\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls29\pnrnot0
-\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls29\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {About ScummVM Help
+\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls41\pnrnot0
+\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls41\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {About ScummVM Help
\par }\pard\plain \ql \li0\ri0\sa120\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\f28
\par }{
This help file based on ScummVM forum thread with some elaborations(in Anotherguest section) and text correction. If you wish add some text or translate you may download and modify source document from https://sourceforge.net/projects/scummvms60git/ and t
@@ -79,8 +82,8 @@ hen send me to fedor_qd@mail.ru
\par }{\f29
\par }\pard\plain \s2\ql \li0\ri0\sb120\sa120\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp20 \brdrb\brdrs\brdrw30\brsp20 \tqr\tx9072{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\outlinelevel1\rin0\lin0\itap0
\b\f1\fs24\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\b0\f28 1st guide
-\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls29\pnrnot0
-\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls29\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Controls, Virtual keyboard, Shortcuts, ScummVM, Tips, S60, UIQ, UIQ3, S80, s80, S90, s90
+\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls41\pnrnot0
+\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls41\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Controls, Virtual keyboard, Shortcuts, ScummVM, Tips, S60, UIQ, UIQ3, S80, s80, S90, s90
\par }\pard\plain \ql \li0\ri0\sa120\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\f28
\par }{UIQ3 devices: To the top right (holding the phone portrait) you four icons, from the top they are
\par
@@ -126,17 +129,17 @@ through directorylist (one hand use perhaps!?) or save games etc. Keyboard mode
of events that ScummVM receives from SDL.
\par What are these Shrinked, Zoomed and Upscaled modes anyway?
\par
-\par Shrink displays the game on your screen but in a shrinked way, either in Portrait or Landscape mode, so not all the pixels c
-an be seen. Zoom mode uses the maximum resolution of your phone displaying a smaller part of the game zoomed at 1:1 pixels. For scrolling in S60 Zoom mode: 0+Cursor keys to scroll around, 0+Ok button to center view. Upscale tries to fill the larger screen
-s on S80/S90 devices in a better way for low resolution games. Currently it uses a pixel interpolation upscaling routine.
+\par Shrink displays the game on your screen but in a shrinked way, either in Port
+rait or Landscape mode, so not all the pixels can be seen. Zoom mode uses the maximum resolution of your phone displaying a smaller part of the game zoomed at 1:1 pixels. For scrolling in S60 Zoom mode: 0+Cursor keys to scroll around, 0+Ok button to cente
+r view. Upscale tries to fill the larger screens on S80/S90 devices in a better way for low resolution games. Currently it uses a pixel interpolation upscaling routine.
\par
\par You can also use a bluetooth mouse with S60v3 devices to control your game. You need the bluetooth hid library from Hinkka http://koti.mbnet.fi/hinkka/Download.html to get it to work properly.
\par }{\f29
\par
\par }\pard\plain \s2\ql \li0\ri0\sb120\sa120\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp20 \brdrb\brdrs\brdrw30\brsp20 \tqr\tx9072{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\outlinelevel1\rin0\lin0\itap0
\b\f1\fs24\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\b0\f28 2nd guide
-\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls29\pnrnot0
-\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls29\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Controls, Virtual keyboard, Shortcuts, ScummVM, Tips, S60, s60
+\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls41\pnrnot0
+\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls41\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Controls, Virtual keyboard, Shortcuts, ScummVM, Tips, S60, s60
\par }\pard\plain \ql \li0\ri0\sa120\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\f28
\par
\par }{More user-friendly guide for Nokia phones (based on N96 but should apply to most phones)
@@ -161,9 +164,8 @@ s on S80/S90 devices in a better way for low resolution games. Currently it uses
\par }{1 - Change Input.
\par This is the option you'll probably use the most. There are three settings; A,C and J.
\par
-\par A -
- This is the "Text Input" mode. It allows you to type directly into ScummVM as if you were using a keyboard. Type the same way you would when sending a text message off of your phone. Please note that the pointer is disabled when in this mode. Don't forge
-t to exit Configuration Mode before typing!
+\par A - This is the "Text Input" mode. It allows you to type directly into ScummVM as if you were using a keyboard. Type the same way you would when sending a text message o
+ff of your phone. Please note that the pointer is disabled when in this mode. Don't forget to exit Configuration Mode before typing!
\par
\par C - This is the "Cursor" mode. This emulates the arrow keys of the keyboard. Some games require using this instead of the mouse (e.g. the destruction derby section towards the end of Full Throttle).
\par
@@ -178,8 +180,9 @@ t to exit Configuration Mode before typing!
\par Only applies to Landscape mode, simply swaps the screen output between having the phone tilted on its left side or on its right side.
\par
\par 4 - Toggle Zoom On and Off
-\par Zooms in on a portion of the screen. Handy for when you are looking through a screen for items or having trouble reading subtitles. Use the navigation buttons for panning around
- the play area. Don't forget you'll have to exit out of Configuration Mode before you can move the pointer again. Exiting Configuration Mode does not reset the zoom level.
+\par Zooms in on a portion of the screen. Handy for when you are looking through a screen fo
+r items or having trouble reading subtitles. Use the navigation buttons for panning around the play area. Don't forget you'll have to exit out of Configuration Mode before you can move the pointer again. Exiting Configuration Mode does not reset the zoom
+level.
\par }{\f29
\par }{5 & 6 - Unused
\par
@@ -200,12 +203,12 @@ t to exit Configuration Mode before typing!
\par
\par }\pard\plain \s2\ql \li0\ri0\sb120\sa120\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp20 \brdrb\brdrs\brdrw30\brsp20 \tqr\tx9072{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\outlinelevel1\rin0\lin0\itap0
\b\f1\fs24\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\b0\f28 3rd guide
-\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls29\pnrnot0
-\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls29\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Controls, Virtual keyboard, Shortcuts, ScummVM, Tips, S60, s60
+\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls41\pnrnot0
+\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls41\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Controls, Virtual keyboard, Shortcuts, ScummVM, Tips, S60, s60
\par }\pard\plain \ql \li0\ri0\sa120\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\f28
\par
-\par }{ScummVM keys on Nokia e71 (most likely on any other qwerty-device, too), tested on version 0.14.0svn (Feb. 18 2009
- 05:56:07). Number keys are inserted by first pressing fn-key (leftmost key at bottom row on E71) and then pressing correct key (e.g. 5 is fn+g). You don't have to press both keys simultaneously.
+\par }{ScummVM keys on Nokia e71 (most likely on any other qwerty-device, too), tested on version 0.14.0svn (Feb. 18 20
+09 05:56:07). Number keys are inserted by first pressing fn-key (leftmost key at bottom row on E71) and then pressing correct key (e.g. 5 is fn+g). You don't have to press both keys simultaneously.
\par
\par Basic keys:
\par
@@ -255,9 +258,8 @@ t to exit Configuration Mode before typing!
\par p -- punch (hand)
\par
\par AGI games (King's Quest, Police Quest etc.):
-\par The
- games work beautifully on the E71, but there's some stupid bugs (in input). I recall finding some debug keys and "last sentence" / "inventory" -keys in earlier version, but I can't find them any more. Also you can't turn on sirens in Police Quest, which
-kinda makes it unplayable.
+\par The games work beautifully on the E71, but there's some stupid bugs (in input). I recall finding some debug keys and "last sentence" / "inventory" -keys in earlier version, but I can't find them any more. Also you can't turn on sirens in Police Quest, whi
+ch kinda makes it unplayable.
\par
\par There's good side and bad side to each input mode:
\par Keyboard (I use this primarily)
@@ -278,9 +280,10 @@ kinda makes it unplayable.
\par }{\f28
\par }\pard\plain \s2\ql \li0\ri0\sb120\sa120\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp20 \brdrb\brdrs\brdrw30\brsp20 \tqr\tx9072{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\outlinelevel1\rin0\lin0\itap0
\b\f1\fs24\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {ScummVM1 engines list
-\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls30\pnrnot0
-\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls30\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Supported engines
-\par }\pard\plain \ql \li0\ri0\sa120\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {agi
+\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls42\pnrnot0
+\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls42\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Supported engines
+\par }\pard\plain \ql \li0\ri0\sa120\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {access
+\par agi
\par agos
\par \tab AGOS2
\par cge2
@@ -312,8 +315,8 @@ kinda makes it unplayable.
\par
\par }\pard\plain \s2\ql \li0\ri0\sb120\sa120\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp20 \brdrb\brdrs\brdrw30\brsp20 \tqr\tx9072{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\nooverflow\faroman\outlinelevel1\rin0\lin0\itap0
\b\f1\fs24\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {ScummVM2 engines list
-\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls30\pnrnot0
-\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls30\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Supported engines
+\par {\pntext\pard\plain\s26 \f30\fs20\lang2057\langfe1033\langnp2057\langfenp1033 \loch\af30\dbch\af0\hich\f30 \'69\tab}}\pard\plain \s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl0\ls42\pnrnot0
+\pnf30\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls42\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Supported engines
\par }\pard\plain \ql \li0\ri0\sa120\widctlpar\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {avalanche
\par cge
\par composer
@@ -330,6 +333,7 @@ kinda makes it unplayable.
\par \tab RIVEN
\par mortevielle
\par pegasus
+\par prince
\par sci
\par \tab SCI32
\par sky
diff --git a/backends/platform/symbian/mmp/config.mmh b/backends/platform/symbian/mmp/config.mmh
index 075697d99a..f397e5ec64 100644
--- a/backends/platform/symbian/mmp/config.mmh
+++ b/backends/platform/symbian/mmp/config.mmh
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2014 The ScummVM Team
+ * Copyright (C) 2005-2015 The ScummVM Team
* Copyright (C) 2014 Fedor Strizhniou
*
* ScummVM is the legal property of its developers, whose names
diff --git a/backends/platform/symbian/mmp/scummvm_access.mmp.in b/backends/platform/symbian/mmp/scummvm_access.mmp.in
new file mode 100644
index 0000000000..4f8b258ec0
--- /dev/null
+++ b/backends/platform/symbian/mmp/scummvm_access.mmp.in
@@ -0,0 +1,52 @@
+/* ScummVM - Graphic Adventure Engine
+ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
+ * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
+ * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
+ * Copyright (C) 2005-2013 The ScummVM project
+ *
+ * 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.
+ *
+ */
+
+//
+// EPOC MMP makefile project for ScummVM
+//
+
+// *** Definitions
+
+TARGET scummvm_access.lib
+TARGETTYPE lib
+#include "config.mmh"
+
+//START_AUTO_MACROS_SLAVE//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_MACROS_SLAVE//
+
+// *** SOURCE files
+
+SOURCEPATH ..\..\..\..\engines\access
+
+//START_AUTO_OBJECTS_ACCESS_//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_OBJECTS_ACCESS_//
+
diff --git a/backends/platform/symbian/mmp/scummvm_agi.mmp.in b/backends/platform/symbian/mmp/scummvm_agi.mmp.in
index f24e3ef1a9..e4bdae3e2f 100644
--- a/backends/platform/symbian/mmp/scummvm_agi.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_agi.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_agos.mmp.in b/backends/platform/symbian/mmp/scummvm_agos.mmp.in
index ff15c8d5b0..8db7132a96 100644
--- a/backends/platform/symbian/mmp/scummvm_agos.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_agos.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_avalanche.mmp.in b/backends/platform/symbian/mmp/scummvm_avalanche.mmp.in
index 40047bb6b7..49c73222ca 100644
--- a/backends/platform/symbian/mmp/scummvm_avalanche.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_avalanche.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
* Copyright (C) 2013 Strizniou Fedor
*
* ScummVM is the legal property of its developers, whose names
diff --git a/backends/platform/symbian/mmp/scummvm_base.mmp.in b/backends/platform/symbian/mmp/scummvm_base.mmp.in
index 88aa689f5b..559d070452 100644
--- a/backends/platform/symbian/mmp/scummvm_base.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_base.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_bbvs.mmp.in b/backends/platform/symbian/mmp/scummvm_bbvs.mmp.in
index 20d91a910d..8f643377fc 100644
--- a/backends/platform/symbian/mmp/scummvm_bbvs.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_bbvs.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2014 The ScummVM Team
+ * Copyright (C) 2005-2015 The ScummVM Team
* Copyright (C) 2014 Fedor Strizhniou - Epoc project file
*
* ScummVM is the legal property of its developers, whose names
diff --git a/backends/platform/symbian/mmp/scummvm_cge.mmp.in b/backends/platform/symbian/mmp/scummvm_cge.mmp.in
index 29bdad0600..2b11ef94a6 100644
--- a/backends/platform/symbian/mmp/scummvm_cge.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_cge.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_cge2.mmp.in b/backends/platform/symbian/mmp/scummvm_cge2.mmp.in
index f9c97e1d83..1561b0f479 100644
--- a/backends/platform/symbian/mmp/scummvm_cge2.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_cge2.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_cine.mmp.in b/backends/platform/symbian/mmp/scummvm_cine.mmp.in
index f93cd30c9f..d0a9f86808 100644
--- a/backends/platform/symbian/mmp/scummvm_cine.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_cine.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_composer.mmp.in b/backends/platform/symbian/mmp/scummvm_composer.mmp.in
index 72117fbc19..8761718a12 100644
--- a/backends/platform/symbian/mmp/scummvm_composer.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_composer.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_cruise.mmp.in b/backends/platform/symbian/mmp/scummvm_cruise.mmp.in
index ceb5a2124f..a586a67c0d 100644
--- a/backends/platform/symbian/mmp/scummvm_cruise.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_cruise.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_draci.mmp.in b/backends/platform/symbian/mmp/scummvm_draci.mmp.in
index 77750ff696..4101ce680f 100644
--- a/backends/platform/symbian/mmp/scummvm_draci.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_draci.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_drascula.mmp.in b/backends/platform/symbian/mmp/scummvm_drascula.mmp.in
index 7f39126e68..2ac3e6000f 100644
--- a/backends/platform/symbian/mmp/scummvm_drascula.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_drascula.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_dreamweb.mmp.in b/backends/platform/symbian/mmp/scummvm_dreamweb.mmp.in
index 22d5050597..a238904653 100644
--- a/backends/platform/symbian/mmp/scummvm_dreamweb.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_dreamweb.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
* Copyright (C) 2013 Strizniou Fedor
*
* ScummVM is the legal property of its developers, whose names
diff --git a/backends/platform/symbian/mmp/scummvm_fullpipe.mmp.in b/backends/platform/symbian/mmp/scummvm_fullpipe.mmp.in
index dc5d4da6b7..aae44bda97 100644
--- a/backends/platform/symbian/mmp/scummvm_fullpipe.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_fullpipe.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
* Copyright (C) 2013 Strizniou Fedor
*
* ScummVM is the legal property of its developers, whose names
diff --git a/backends/platform/symbian/mmp/scummvm_gob.mmp.in b/backends/platform/symbian/mmp/scummvm_gob.mmp.in
index a46ee9c403..1bb8982a9e 100644
--- a/backends/platform/symbian/mmp/scummvm_gob.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_gob.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_groovie.mmp.in b/backends/platform/symbian/mmp/scummvm_groovie.mmp.in
index a2a3d5c47d..199bb4c4a8 100644
--- a/backends/platform/symbian/mmp/scummvm_groovie.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_groovie.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_hopkins.mmp.in b/backends/platform/symbian/mmp/scummvm_hopkins.mmp.in
index 82728942a7..59adffb1ea 100644
--- a/backends/platform/symbian/mmp/scummvm_hopkins.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_hopkins.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_hugo.mmp.in b/backends/platform/symbian/mmp/scummvm_hugo.mmp.in
index 1f250bda3f..6ccdb2e95e 100644
--- a/backends/platform/symbian/mmp/scummvm_hugo.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_hugo.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_kyra.mmp.in b/backends/platform/symbian/mmp/scummvm_kyra.mmp.in
index f3b30b1318..365c041b27 100644
--- a/backends/platform/symbian/mmp/scummvm_kyra.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_kyra.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_lastexpress.mmp.in b/backends/platform/symbian/mmp/scummvm_lastexpress.mmp.in
index 38d63b4648..4791307aa6 100644
--- a/backends/platform/symbian/mmp/scummvm_lastexpress.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_lastexpress.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_lure.mmp.in b/backends/platform/symbian/mmp/scummvm_lure.mmp.in
index 2922c9df49..1cd46de184 100644
--- a/backends/platform/symbian/mmp/scummvm_lure.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_lure.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_m4.mmp.in b/backends/platform/symbian/mmp/scummvm_m4.mmp.in
index 0b3a0b60e4..e6621d812d 100644
--- a/backends/platform/symbian/mmp/scummvm_m4.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_m4.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_made.mmp.in b/backends/platform/symbian/mmp/scummvm_made.mmp.in
index e240685753..e8835b6428 100644
--- a/backends/platform/symbian/mmp/scummvm_made.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_made.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_mads.mmp.in b/backends/platform/symbian/mmp/scummvm_mads.mmp.in
index e5e990dd2d..eb1d20749e 100644
--- a/backends/platform/symbian/mmp/scummvm_mads.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_mads.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
* Copyright (C) 2014 Fedor Strizhniou - Epoc project file
*
* ScummVM is the legal property of its developers, whose names
diff --git a/backends/platform/symbian/mmp/scummvm_mohawk.mmp.in b/backends/platform/symbian/mmp/scummvm_mohawk.mmp.in
index 19bed823d5..694032ede6 100644
--- a/backends/platform/symbian/mmp/scummvm_mohawk.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_mohawk.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_mortevielle.mmp.in b/backends/platform/symbian/mmp/scummvm_mortevielle.mmp.in
index 06f9333c37..caf8e330f3 100644
--- a/backends/platform/symbian/mmp/scummvm_mortevielle.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_mortevielle.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
* Copyright (C) 2013 Strizniou Fedor
*
* ScummVM is the legal property of its developers, whose names
diff --git a/backends/platform/symbian/mmp/scummvm_neverhood.mmp.in b/backends/platform/symbian/mmp/scummvm_neverhood.mmp.in
index b6deeb2d73..db0f445089 100644
--- a/backends/platform/symbian/mmp/scummvm_neverhood.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_neverhood.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_parallaction.mmp.in b/backends/platform/symbian/mmp/scummvm_parallaction.mmp.in
index c61e40626c..7c5c4c8abd 100644
--- a/backends/platform/symbian/mmp/scummvm_parallaction.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_parallaction.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_pegasus.mmp.in b/backends/platform/symbian/mmp/scummvm_pegasus.mmp.in
index 3ef85bf29d..fa65964f3f 100644
--- a/backends/platform/symbian/mmp/scummvm_pegasus.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_pegasus.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_prince.mmp.in b/backends/platform/symbian/mmp/scummvm_prince.mmp.in
new file mode 100644
index 0000000000..7dfec04f46
--- /dev/null
+++ b/backends/platform/symbian/mmp/scummvm_prince.mmp.in
@@ -0,0 +1,52 @@
+/* ScummVM - Graphic Adventure Engine
+ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
+ * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
+ * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
+ * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2014 Strizniou Fedor
+ *
+ * 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.
+ *
+ */
+
+//
+// EPOC MMP makefile project for ScummVM
+//
+
+// *** Definitions
+
+TARGET scummvm_prince.lib
+TARGETTYPE lib
+#include "config.mmh"
+
+//START_AUTO_MACROS_SLAVE//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_MACROS_SLAVE//
+
+// *** SOURCE files
+
+SOURCEPATH ..\..\..\..\engines\prince
+
+//START_AUTO_OBJECTS_PRINCE_//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_OBJECTS_PRINCE_//
diff --git a/backends/platform/symbian/mmp/scummvm_queen.mmp.in b/backends/platform/symbian/mmp/scummvm_queen.mmp.in
index 3a15fdd0a2..9280b94fea 100644
--- a/backends/platform/symbian/mmp/scummvm_queen.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_queen.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_saga.mmp.in b/backends/platform/symbian/mmp/scummvm_saga.mmp.in
index ce5de459b2..838ee18ccf 100644
--- a/backends/platform/symbian/mmp/scummvm_saga.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_saga.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_sci.mmp.in b/backends/platform/symbian/mmp/scummvm_sci.mmp.in
index 49484b8c7c..daed96856d 100644
--- a/backends/platform/symbian/mmp/scummvm_sci.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_sci.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_scumm.mmp.in b/backends/platform/symbian/mmp/scummvm_scumm.mmp.in
index 60c54697d0..91c6e79fde 100644
--- a/backends/platform/symbian/mmp/scummvm_scumm.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_scumm.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_sky.mmp.in b/backends/platform/symbian/mmp/scummvm_sky.mmp.in
index 5363bb32ef..51054597ef 100644
--- a/backends/platform/symbian/mmp/scummvm_sky.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_sky.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_sword1.mmp.in b/backends/platform/symbian/mmp/scummvm_sword1.mmp.in
index b4b2b91dae..9ce462f517 100644
--- a/backends/platform/symbian/mmp/scummvm_sword1.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_sword1.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_sword2.mmp.in b/backends/platform/symbian/mmp/scummvm_sword2.mmp.in
index a8c963a618..bd4756c903 100644
--- a/backends/platform/symbian/mmp/scummvm_sword2.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_sword2.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_sword25.mmp.in b/backends/platform/symbian/mmp/scummvm_sword25.mmp.in
index 67efc10c45..b395a25799 100644
--- a/backends/platform/symbian/mmp/scummvm_sword25.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_sword25.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
* Copyright (C) 2013 Strizniou Fedor
*
* ScummVM is the legal property of its developers, whose names
diff --git a/backends/platform/symbian/mmp/scummvm_teenagent.mmp.in b/backends/platform/symbian/mmp/scummvm_teenagent.mmp.in
index 9551eda7b6..fa976791c3 100644
--- a/backends/platform/symbian/mmp/scummvm_teenagent.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_teenagent.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_testbed.mmp.in b/backends/platform/symbian/mmp/scummvm_testbed.mmp.in
index 24b87d154c..e15e02fe1c 100644
--- a/backends/platform/symbian/mmp/scummvm_testbed.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_testbed.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
* Copyright (C) 2013 Strizniou Fedor
*
* ScummVM is the legal property of its developers, whose names
diff --git a/backends/platform/symbian/mmp/scummvm_tinsel.mmp.in b/backends/platform/symbian/mmp/scummvm_tinsel.mmp.in
index a5a62ffc15..095e693372 100644
--- a/backends/platform/symbian/mmp/scummvm_tinsel.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_tinsel.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_toltecs.mmp.in b/backends/platform/symbian/mmp/scummvm_toltecs.mmp.in
index 1512dfed06..5f92b2f376 100644
--- a/backends/platform/symbian/mmp/scummvm_toltecs.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_toltecs.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_tony.mmp.in b/backends/platform/symbian/mmp/scummvm_tony.mmp.in
index 18c4f6d3cb..de1d497412 100644
--- a/backends/platform/symbian/mmp/scummvm_tony.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_tony.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_toon.mmp.in b/backends/platform/symbian/mmp/scummvm_toon.mmp.in
index 9c7568cc8b..49f0b0e19d 100644
--- a/backends/platform/symbian/mmp/scummvm_toon.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_toon.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_touche.mmp.in b/backends/platform/symbian/mmp/scummvm_touche.mmp.in
index 73e14ee691..1ff5d66cb5 100644
--- a/backends/platform/symbian/mmp/scummvm_touche.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_touche.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_tsage.mmp.in b/backends/platform/symbian/mmp/scummvm_tsage.mmp.in
index e18db61683..93f278e279 100644
--- a/backends/platform/symbian/mmp/scummvm_tsage.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_tsage.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_tucker.mmp.in b/backends/platform/symbian/mmp/scummvm_tucker.mmp.in
index aef8841cf2..3be99ab47d 100644
--- a/backends/platform/symbian/mmp/scummvm_tucker.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_tucker.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_voyeur.mmp.in b/backends/platform/symbian/mmp/scummvm_voyeur.mmp.in
index 86dc32b3f8..c31d3fcfa2 100644
--- a/backends/platform/symbian/mmp/scummvm_voyeur.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_voyeur.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2014 The ScummVM Team
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
@@ -32,10 +32,7 @@
TARGET scummvm_voyeur.lib
TARGETTYPE lib
-OPTION MSVC /QIfist /Ob1 /Oy /GF // /QIfist disables use of __ftol2 to avoid linker probs with MS libc: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore/html/vcrefQIfistSuppress_ftol.asp
-OPTION GCC -Wno-multichar -Wno-reorder // don't optimize for ARM, platform way too sensitive for that :( just turn off some common warnings
-OPTION GCCE -Wno-multichar -Wno-reorder -Wno-unused -Wno-format -fsigned-char
-ALWAYS_BUILD_AS_ARM
+#include "config.mmh"
//START_AUTO_MACROS_SLAVE//
@@ -52,20 +49,3 @@ SOURCEPATH ..\..\..\..\engines\voyeur
// empty base file, will be updated by Perl build scripts
//STOP_AUTO_OBJECTS_VOYEUR_//
-
-// *** Include paths
-
-USERINCLUDE ..\..\..\..\engines
-USERINCLUDE ..\..\..\.. ..\..\..\..\gui ..\..\..\..\audio ..\src
-
-SYSTEMINCLUDE \epoc32\include\freetype
-SYSTEMINCLUDE \epoc32\include\mpeg2dec
-SYSTEMINCLUDE \epoc32\include\jpeg
-SYSTEMINCLUDE \epoc32\include\png
-SYSTEMINCLUDE \epoc32\include\ESDL
-SYSTEMINCLUDE \epoc32\include\ZLIB // before \epoc32\include because symbian already has older version
-SYSTEMINCLUDE \epoc32\include\libc
-SYSTEMINCLUDE \epoc32\include\theora
-SYSTEMINCLUDE \epoc32\include\tremor
-SYSTEMINCLUDE \epoc32\include
-SYSTEMINCLUDE ..\src // for portdefs.h
diff --git a/backends/platform/symbian/mmp/scummvm_wintermute.mmp.in b/backends/platform/symbian/mmp/scummvm_wintermute.mmp.in
index 716484755f..97fbd6e3ea 100644
--- a/backends/platform/symbian/mmp/scummvm_wintermute.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_wintermute.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_zvision.mmp.in b/backends/platform/symbian/mmp/scummvm_zvision.mmp.in
index e647275dbc..838520799e 100644
--- a/backends/platform/symbian/mmp/scummvm_zvision.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_zvision.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2013 The ScummVM project
+ * Copyright (C) 2005-2015 The ScummVM Team
* Copyright (C) 2013 Strizniou Fedor - Epoc project file
*
* ScummVM is the legal property of its developers, whose names
@@ -33,6 +33,7 @@
TARGET scummvm_zvision.lib
TARGETTYPE lib
+USERINCLUDE ..\..\..\..\engines\zvision\graphics
#include "config.mmh"
//START_AUTO_MACROS_SLAVE//
diff --git a/backends/platform/symbian/res/ScummVmAif.rss b/backends/platform/symbian/res/ScummVmAif.rss
index 2dbf436a8f..8238bdd005 100644
--- a/backends/platform/symbian/res/ScummVmAif.rss
+++ b/backends/platform/symbian/res/ScummVmAif.rss
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2014 The ScummVM Team
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/res/scummvm.rss b/backends/platform/symbian/res/scummvm.rss
index 6a0ab24ff0..ae34e9fbaa 100644
--- a/backends/platform/symbian/res/scummvm.rss
+++ b/backends/platform/symbian/res/scummvm.rss
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2014 The ScummVM Team
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/res/scummvm_A0000658.rss b/backends/platform/symbian/res/scummvm_A0000658.rss
index 562fef54c6..3b31f9f0a0 100644
--- a/backends/platform/symbian/res/scummvm_A0000658.rss
+++ b/backends/platform/symbian/res/scummvm_A0000658.rss
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2014 The ScummVM Team
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/src/ScummVm.hrh b/backends/platform/symbian/src/ScummVm.hrh
index 316e4d08f6..f756912d96 100644
--- a/backends/platform/symbian/src/ScummVm.hrh
+++ b/backends/platform/symbian/src/ScummVm.hrh
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2014 The ScummVM Team
+ * Copyright (C) 2005-2015 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/src/SymbianOS.cpp b/backends/platform/symbian/src/SymbianOS.cpp
index 1fca7f5df5..e28b78900c 100644
--- a/backends/platform/symbian/src/SymbianOS.cpp
+++ b/backends/platform/symbian/src/SymbianOS.cpp
@@ -63,6 +63,8 @@ OSystem_SDL_Symbian::OSystem_SDL_Symbian()
void OSystem_SDL_Symbian::init() {
_RFs = &CEikonEnv::Static()->FsSession();
+ // Use iconless window: it uses the EScummVM.aif file for the icon.
+ _window = new SdlIconlessWindow();
_fsFactory = new SymbianFilesystemFactory();
OSystem_SDL::init();
}
@@ -109,7 +111,7 @@ void OSystem_SDL_Symbian::initBackend() {
_mixerManager->init();
}
if (_graphicsManager == 0)
- _graphicsManager = new SymbianSdlGraphicsManager(_eventSource);
+ _graphicsManager = new SymbianSdlGraphicsManager(_eventSource, _window);
// Call parent implementation of this method
OSystem_SDL::initBackend();
@@ -171,10 +173,6 @@ Common::String OSystem_SDL_Symbian::getDefaultConfigFileName() {
return configFile;
}
-void OSystem_SDL_Symbian::setupIcon() {
- // Don't for Symbian: it uses the EScummVM.aif file for the icon.
-}
-
RFs& OSystem_SDL_Symbian::FsSession() {
return *_RFs;
}
diff --git a/backends/platform/symbian/src/SymbianOS.h b/backends/platform/symbian/src/SymbianOS.h
index 57a471f1a9..617540941d 100644
--- a/backends/platform/symbian/src/SymbianOS.h
+++ b/backends/platform/symbian/src/SymbianOS.h
@@ -39,7 +39,6 @@ public:
virtual void engineDone();
virtual bool setGraphicsMode(const char *name);
virtual Common::String getDefaultConfigFileName();
- virtual void setupIcon();
/**
* Returns reference to File session
diff --git a/backends/platform/wince/wince-sdl.cpp b/backends/platform/wince/wince-sdl.cpp
index 96c9313c5d..c1b0c7f692 100644
--- a/backends/platform/wince/wince-sdl.cpp
+++ b/backends/platform/wince/wince-sdl.cpp
@@ -420,7 +420,7 @@ void OSystem_WINCE3::initBackend() {
}
if (_graphicsManager == 0)
- _graphicsManager = new WINCESdlGraphicsManager(_eventSource);
+ _graphicsManager = new WINCESdlGraphicsManager(_eventSource, _window);
((WINCESdlEventSource *)_eventSource)->init(dynamic_cast<WINCESdlGraphicsManager *>(_graphicsManager));
diff --git a/backends/taskbar/win32/win32-taskbar.cpp b/backends/taskbar/win32/win32-taskbar.cpp
index 5c9105b0eb..d45253c676 100644
--- a/backends/taskbar/win32/win32-taskbar.cpp
+++ b/backends/taskbar/win32/win32-taskbar.cpp
@@ -48,9 +48,6 @@
#include <shlobj.h>
-// For HWND
-#include <SDL_syswm.h>
-
#include "common/scummsys.h"
#include "backends/taskbar/win32/win32-taskbar.h"
@@ -62,7 +59,7 @@
// System.Title property key, values taken from http://msdn.microsoft.com/en-us/library/bb787584.aspx
const PROPERTYKEY PKEY_Title = { /* fmtid = */ { 0xF29F85E0, 0x4FF9, 0x1068, { 0xAB, 0x91, 0x08, 0x00, 0x2B, 0x27, 0xB3, 0xD9 } }, /* propID = */ 2 };
-Win32TaskbarManager::Win32TaskbarManager() : _taskbar(NULL), _count(0), _icon(NULL) {
+Win32TaskbarManager::Win32TaskbarManager(SdlWindow *window) : _window(window), _taskbar(NULL), _count(0), _icon(NULL) {
// Do nothing if not running on Windows 7 or later
if (!isWin7OrLater())
return;
@@ -408,12 +405,15 @@ LPWSTR Win32TaskbarManager::ansiToUnicode(const char *s) {
HWND Win32TaskbarManager::getHwnd() {
SDL_SysWMinfo wmi;
- SDL_VERSION(&wmi.version);
-
- if(!SDL_GetWMInfo(&wmi))
+ if (_window->getSDLWMInformation(&wmi)) {
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ return wmi.info.win.window;
+#else
+ return wmi.window;
+#endif
+ } else {
return NULL;
-
- return wmi.window;
+ }
}
#endif
diff --git a/backends/taskbar/win32/win32-taskbar.h b/backends/taskbar/win32/win32-taskbar.h
index 36415c1c57..a6d1b49213 100644
--- a/backends/taskbar/win32/win32-taskbar.h
+++ b/backends/taskbar/win32/win32-taskbar.h
@@ -25,6 +25,8 @@
#if defined(WIN32) && defined(USE_TASKBAR)
+#include "backends/platform/sdl/sdl-window.h"
+
#include "common/str.h"
#include "common/taskbar.h"
@@ -32,7 +34,7 @@ struct ITaskbarList3;
class Win32TaskbarManager : public Common::TaskbarManager {
public:
- Win32TaskbarManager();
+ Win32TaskbarManager(SdlWindow *window);
virtual ~Win32TaskbarManager();
virtual void setOverlayIcon(const Common::String &name, const Common::String &description);
@@ -44,6 +46,8 @@ public:
virtual void clearError();
private:
+ SdlWindow *_window;
+
ITaskbarList3 *_taskbar;
// Count handling
diff --git a/base/main.cpp b/base/main.cpp
index b5de7d94d2..3ea38b547a 100644
--- a/base/main.cpp
+++ b/base/main.cpp
@@ -523,22 +523,45 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) {
}
#endif
+ // At this point, we usually return to the launcher. However, the
+ // game may have requested that one or more other games be "chained"
+ // to the current one, with optional save slots to start the games
+ // at. At the time of writing, this is used for the Maniac Mansion
+ // easter egg in Day of the Tentacle.
+
+ Common::String chainedGame;
+ int saveSlot = -1;
+
+ ChainedGamesMan.pop(chainedGame, saveSlot);
+
// Discard any command line options. It's unlikely that the user
// wanted to apply them to *all* games ever launched.
ConfMan.getDomain(Common::ConfigManager::kTransientDomain)->clear();
- // Clear the active config domain
- ConfMan.setActiveDomain("");
+ if (!chainedGame.empty()) {
+ if (saveSlot != -1) {
+ ConfMan.setInt("save_slot", saveSlot, Common::ConfigManager::kTransientDomain);
+ }
+ // Start the chained game
+ ConfMan.setActiveDomain(chainedGame);
+ } else {
+ // Clear the active config domain
+ ConfMan.setActiveDomain("");
+ }
PluginManager::instance().loadAllPlugins(); // only for cached manager
-
} else {
GUI::displayErrorDialog(_("Could not find any engine capable of running the selected game"));
+
+ // Clear the active domain
+ ConfMan.setActiveDomain("");
}
// reset the graphics to default
setupGraphics(system);
- launcherDialog();
+ if (0 == ConfMan.getActiveDomain()) {
+ launcherDialog();
+ }
}
PluginManager::instance().unloadAllPlugins();
PluginManager::destroy();
diff --git a/common/dcl.cpp b/common/dcl.cpp
index 2f4cdeda6b..5993c218cb 100644
--- a/common/dcl.cpp
+++ b/common/dcl.cpp
@@ -30,17 +30,15 @@ namespace Common {
class DecompressorDCL {
public:
- bool unpack(ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked);
+ bool unpack(SeekableReadStream *sourceStream, WriteStream *targetStream, uint32 targetSize, bool targetFixedSize);
protected:
/**
* Initialize decompressor.
- * @param src source stream to read from
- * @param dest destination stream to write to
- * @param nPacked size of packed data
- * @param nUnpacked size of unpacked data
+ * @param sourceStream source stream to read from
+ * @param targetStream target memory stream to write to
*/
- void init(ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked);
+ void init(SeekableReadStream *sourceStream, WriteStream *targetStream, uint32 targetSize, bool targetFixedSize);
/**
* Get a number of bits from _src stream, starting with the least
@@ -66,36 +64,38 @@ protected:
int huffman_lookup(const int *tree);
- uint32 _dwBits; ///< bits buffer
- byte _nBits; ///< number of unread bits in _dwBits
- uint32 _szPacked; ///< size of the compressed data
- uint32 _szUnpacked; ///< size of the decompressed data
- uint32 _dwRead; ///< number of bytes read from _src
- uint32 _dwWrote; ///< number of bytes written to _dest
- ReadStream *_src;
- byte *_dest;
+ uint32 _dwBits; ///< bits buffer
+ byte _nBits; ///< number of unread bits in _dwBits
+ uint32 _sourceSize; ///< size of the source stream
+ uint32 _targetSize; ///< size of the target stream (if fixed)
+ bool _targetFixedSize; ///< if target stream is fixed size or dynamic size
+ uint32 _bytesRead; ///< number of bytes read from _sourceStream
+ uint32 _bytesWritten; ///< number of bytes written to _targetStream
+ SeekableReadStream *_sourceStream;
+ WriteStream *_targetStream;
};
-void DecompressorDCL::init(ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked) {
- _src = src;
- _dest = dest;
- _szPacked = nPacked;
- _szUnpacked = nUnpacked;
+void DecompressorDCL::init(SeekableReadStream *sourceStream, WriteStream *targetStream, uint32 targetSize, bool targetFixedSize) {
+ _sourceStream = sourceStream;
+ _targetStream = targetStream;
+ _sourceSize = sourceStream->size();
+ _targetSize = targetSize;
+ _targetFixedSize = targetFixedSize;
_nBits = 0;
- _dwRead = _dwWrote = 0;
+ _bytesRead = _bytesWritten = 0;
_dwBits = 0;
}
void DecompressorDCL::fetchBitsLSB() {
while (_nBits <= 24) {
- _dwBits |= ((uint32)_src->readByte()) << _nBits;
+ _dwBits |= ((uint32)_sourceStream->readByte()) << _nBits;
_nBits += 8;
- _dwRead++;
+ _bytesRead++;
}
}
uint32 DecompressorDCL::getBitsLSB(int n) {
- // fetching more data to buffer if needed
+ // Fetching more data to buffer if needed
if (_nBits < n)
fetchBitsLSB();
uint32 ret = (_dwBits & ~((~0) << n));
@@ -109,7 +109,8 @@ byte DecompressorDCL::getByteLSB() {
}
void DecompressorDCL::putByte(byte b) {
- _dest[_dwWrote++] = b;
+ _targetStream->writeByte(b);
+ _bytesWritten++;
}
#define HUFFMAN_LEAF 0x40000000
@@ -331,97 +332,189 @@ int DecompressorDCL::huffman_lookup(const int *tree) {
#define DCL_BINARY_MODE 0
#define DCL_ASCII_MODE 1
-bool DecompressorDCL::unpack(ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked) {
- init(src, dest, nPacked, nUnpacked);
+#define MIDI_SETUP_BUNDLE_FILE_MAXIMUM_DICTIONARY_SIZE 4096
+bool DecompressorDCL::unpack(SeekableReadStream *sourceStream, WriteStream *targetStream, uint32 targetSize, bool targetFixedSize) {
+ byte dictionary[MIDI_SETUP_BUNDLE_FILE_MAXIMUM_DICTIONARY_SIZE];
+ uint16 dictionaryPos = 0;
+ uint16 dictionarySize = 0;
+ uint16 dictionaryMask = 0;
int value;
- uint32 val_distance, val_length;
+ uint16 tokenOffset = 0;
+ uint16 tokenLength = 0;
- int mode = getByteLSB();
- int length_param = getByteLSB();
+ init(sourceStream, targetStream, targetSize, targetFixedSize);
+
+ byte mode = getByteLSB();
+ byte dictionaryType = getByteLSB();
if (mode != DCL_BINARY_MODE && mode != DCL_ASCII_MODE) {
warning("DCL-INFLATE: Error: Encountered mode %02x, expected 00 or 01", mode);
return false;
}
- if (length_param < 3 || length_param > 6)
- warning("Unexpected length_param value %d (expected in [3,6])", length_param);
+ // TODO: original code supported 3 as well???
+ // Was this an accident or on purpose? And the original code did just give out a warning
+ // and didn't error out at all
+ switch (dictionaryType) {
+ case 4:
+ dictionarySize = 1024;
+ break;
+ case 5:
+ dictionarySize = 2048;
+ break;
+ case 6:
+ dictionarySize = 4096;
+ break;
+ default:
+ warning("DCL-INFLATE: Error: unsupported dictionary type %02x", dictionaryType);
+ return false;
+ }
+ dictionaryMask = dictionarySize - 1;
- while (_dwWrote < _szUnpacked) {
+ while ((!targetFixedSize) || (_bytesWritten < _targetSize)) {
if (getBitsLSB(1)) { // (length,distance) pair
value = huffman_lookup(length_tree);
if (value < 8)
- val_length = value + 2;
+ tokenLength = value + 2;
else
- val_length = 8 + (1 << (value - 7)) + getBitsLSB(value - 7);
+ tokenLength = 8 + (1 << (value - 7)) + getBitsLSB(value - 7);
+
+ if (tokenLength == 519)
+ break; // End of stream signal
debug(8, " | ");
value = huffman_lookup(distance_tree);
- if (val_length == 2)
- val_distance = (value << 2) | getBitsLSB(2);
+ if (tokenLength == 2)
+ tokenOffset = (value << 2) | getBitsLSB(2);
else
- val_distance = (value << length_param) | getBitsLSB(length_param);
- val_distance ++;
+ tokenOffset = (value << dictionaryType) | getBitsLSB(dictionaryType);
+ tokenOffset++;
- debug(8, "\nCOPY(%d from %d)\n", val_length, val_distance);
+ debug(8, "\nCOPY(%d from %d)\n", tokenLength, tokenOffset);
- if (val_length + _dwWrote > _szUnpacked) {
- warning("DCL-INFLATE Error: Write out of bounds while copying %d bytes (declared unpacked size is %d bytes, current is %d + %d bytes)",
- val_length, _szUnpacked, _dwWrote, val_length);
- return false;
+ if (_targetFixedSize) {
+ if (tokenLength + _bytesWritten > _targetSize) {
+ warning("DCL-INFLATE Error: Write out of bounds while copying %d bytes (declared unpacked size is %d bytes, current is %d + %d bytes)",
+ tokenLength, _targetSize, _bytesWritten, tokenLength);
+ return false;
+ }
}
- if (_dwWrote < val_distance) {
+ if (_bytesWritten < tokenOffset) {
warning("DCL-INFLATE Error: Attempt to copy from before beginning of input stream (declared unpacked size is %d bytes, current is %d bytes)",
- _szUnpacked, _dwWrote);
+ _targetSize, _bytesWritten);
return false;
}
- while (val_length) {
- uint32 copy_length = (val_length > val_distance) ? val_distance : val_length;
- assert(val_distance >= copy_length);
- uint32 pos = _dwWrote - val_distance;
- for (uint32 i = 0; i < copy_length; i++)
- putByte(dest[pos + i]);
+ uint16 dictionaryBaseIndex = (dictionaryPos - tokenOffset) & dictionaryMask;
+ uint16 dictionaryIndex = dictionaryBaseIndex;
+ uint16 dictionaryNextIndex = dictionaryPos;
+
+ while (tokenLength) {
+ // Write byte from dictionary
+ putByte(dictionary[dictionaryIndex]);
+ debug(9, "\33[32;31m%02x\33[37;37m ", dictionary[dictionaryIndex]);
+
+ dictionary[dictionaryNextIndex] = dictionary[dictionaryIndex];
- for (uint32 i = 0; i < copy_length; i++)
- debug(9, "\33[32;31m%02x\33[37;37m ", dest[pos + i]);
- debug(9, "\n");
+ dictionaryNextIndex = (dictionaryNextIndex + 1) & dictionaryMask;
+ dictionaryIndex = (dictionaryIndex + 1) & dictionaryMask;
- val_length -= copy_length;
- val_distance += copy_length;
+ if (dictionaryIndex == dictionaryPos)
+ dictionaryIndex = dictionaryBaseIndex;
+ if (dictionaryNextIndex == dictionarySize)
+ dictionaryNextIndex = 0;
+
+ tokenLength--;
}
+ dictionaryPos = dictionaryNextIndex;
+ debug(9, "\n");
} else { // Copy byte verbatim
value = (mode == DCL_ASCII_MODE) ? huffman_lookup(ascii_tree) : getByteLSB();
putByte(value);
+
+ // Also remember it inside dictionary
+ dictionary[dictionaryPos] = value;
+ dictionaryPos++;
+ if (dictionaryPos >= dictionarySize)
+ dictionaryPos = 0;
+
debug(9, "\33[32;31m%02x \33[37;37m", value);
}
}
- return _dwWrote == _szUnpacked;
+ if (_targetFixedSize) {
+ return _bytesWritten == _targetSize;
+ }
+ return true; // For targets featuring dynamic size we always succeed
}
bool decompressDCL(ReadStream *src, byte *dest, uint32 packedSize, uint32 unpackedSize) {
+ bool success = false;
+ DecompressorDCL dcl;
+
if (!src || !dest)
return false;
+ byte *sourceBufferPtr = (byte *)malloc(packedSize);
+ if (!sourceBufferPtr)
+ return false;
+
+ // Read source into memory
+ src->read(sourceBufferPtr, packedSize);
+
+ Common::MemoryReadStream *sourceStream = new MemoryReadStream(sourceBufferPtr, packedSize, DisposeAfterUse::NO);
+ Common::MemoryWriteStream *targetStream = new MemoryWriteStream(dest, unpackedSize);
+
+ success = dcl.unpack(sourceStream, targetStream, unpackedSize, true);
+ delete sourceStream;
+ delete targetStream;
+ return success;
+}
+
+SeekableReadStream *decompressDCL(SeekableReadStream *sourceStream, uint32 packedSize, uint32 unpackedSize) {
+ bool success = false;
+ byte *targetPtr = nullptr;
+ Common::MemoryWriteStream *targetStream;
DecompressorDCL dcl;
- return dcl.unpack(src, dest, packedSize, unpackedSize);
+
+ targetPtr = (byte *)malloc(unpackedSize);
+ if (!targetPtr)
+ return nullptr;
+
+ targetStream = new MemoryWriteStream(targetPtr, unpackedSize);
+
+ success = dcl.unpack(sourceStream, targetStream, unpackedSize, true);
+ delete targetStream;
+
+ if (!success) {
+ free(targetPtr);
+ return nullptr;
+ }
+ return new MemoryReadStream(targetPtr, unpackedSize, DisposeAfterUse::YES);
}
-SeekableReadStream *decompressDCL(ReadStream *src, uint32 packedSize, uint32 unpackedSize) {
- byte *data = (byte *)malloc(unpackedSize);
+// This one figures out the unpacked size by itself
+// Needed for at least Simon 2, because the unpacked size is not stored anywhere
+SeekableReadStream *decompressDCL(SeekableReadStream *sourceStream) {
+ Common::MemoryWriteStreamDynamic *targetStream;
+ DecompressorDCL dcl;
- if (decompressDCL(src, data, packedSize, unpackedSize))
- return new MemoryReadStream(data, unpackedSize, DisposeAfterUse::YES);
+ targetStream = new MemoryWriteStreamDynamic(DisposeAfterUse::NO);
- free(data);
- return 0;
+ if (dcl.unpack(sourceStream, targetStream, 0, false)) {
+ byte *targetPtr = targetStream->getData();
+ uint32 unpackedSize = targetStream->size();
+ delete targetStream;
+ return new MemoryReadStream(targetPtr, unpackedSize, DisposeAfterUse::YES);
+ }
+ delete targetStream;
+ return nullptr;
}
} // End of namespace Common
diff --git a/common/dcl.h b/common/dcl.h
index 0e96f74c07..f90bc23c8d 100644
--- a/common/dcl.h
+++ b/common/dcl.h
@@ -22,7 +22,8 @@
/**
* @file
- * PKWARE DCL ("explode") decompressor used in engines:
+ * PKWARE DCL ("explode") ("PKWARE data compression library") decompressor used in engines:
+ * - agos (exclusively for Simon 2 setup.shr file)
* - mohawk
* - sci
*/
@@ -38,16 +39,22 @@ class ReadStream;
class SeekableReadStream;
/**
- * Try to decompress a PKWARE DCL compressed stream. Returns true if
+ * Try to decompress a PKWARE DCL (PKWARE data compression library) compressed stream. Returns true if
* successful.
*/
-bool decompressDCL(ReadStream *src, byte *dest, uint32 packedSize, uint32 unpackedSize);
+bool decompressDCL(ReadStream *sourceStream, byte *dest, uint32 packedSize, uint32 unpackedSize);
/**
- * Try to decompress a PKWARE DCL compressed stream. Returns a valid pointer
+ * Try to decompress a PKWARE DCL (PKWARE data compression library) compressed stream. Returns a valid pointer
* if successful and 0 otherwise.
*/
-SeekableReadStream *decompressDCL(ReadStream *src, uint32 packedSize, uint32 unpackedSize);
+SeekableReadStream *decompressDCL(SeekableReadStream *sourceStream, uint32 packedSize, uint32 unpackedSize);
+
+/**
+ * Try to decompress a PKWARE DCL (PKWARE data compression library) compressed stream. Returns a valid pointer
+ * if successful and 0 otherwise. This method is meant for cases, where the unpacked size is not known.
+ */
+SeekableReadStream *decompressDCL(SeekableReadStream *sourceStream);
} // End of namespace Common
diff --git a/common/endian.h b/common/endian.h
index 6d6563f802..7278265961 100644
--- a/common/endian.h
+++ b/common/endian.h
@@ -49,6 +49,18 @@
# error No endianness defined
#endif
+#ifdef HAVE_INT64
+#define SWAP_CONSTANT_64(a) \
+ ((uint64)((((a) >> 56) & 0x000000FF) | \
+ (((a) >> 40) & 0x0000FF00) | \
+ (((a) >> 24) & 0x00FF0000) | \
+ (((a) >> 8) & 0xFF000000) | \
+ (((a) & 0xFF000000) << 8) | \
+ (((a) & 0x00FF0000) << 24) | \
+ (((a) & 0x0000FF00) << 40) | \
+ (((a) & 0x000000FF) << 56) ))
+#endif
+
#define SWAP_CONSTANT_32(a) \
((uint32)((((a) >> 24) & 0x00FF) | \
(((a) >> 8) & 0xFF00) | \
@@ -59,6 +71,36 @@
((uint16)((((a) >> 8) & 0x00FF) | \
(((a) << 8) & 0xFF00) ))
+
+
+/**
+ * Swap the bytes in a 16 bit word in order to convert LE encoded data to BE
+ * and vice versa.
+ */
+
+// compilerspecific variants come first, fallback last
+
+// Test for GCC and if the target has the MIPS rel.2 instructions (we know the psp does)
+#if defined(__GNUC__) && (defined(__psp__) || defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2))
+
+ FORCEINLINE uint16 SWAP_BYTES_16(const uint16 a) {
+ if (__builtin_constant_p(a)) {
+ return SWAP_CONSTANT_16(a);
+ } else {
+ uint16 result;
+ __asm__ ("wsbh %0,%1" : "=r" (result) : "r" (a));
+ return result;
+ }
+ }
+#else
+
+ inline uint16 SWAP_BYTES_16(const uint16 a) {
+ return (a >> 8) | (a << 8);
+ }
+#endif
+
+
+
/**
* Swap the bytes in a 32 bit word in order to convert LE encoded data to BE
* and vice versa.
@@ -108,32 +150,60 @@
}
#endif
+#ifdef HAVE_INT64
/**
- * Swap the bytes in a 16 bit word in order to convert LE encoded data to BE
+ * Swap the bytes in a 64 bit word in order to convert LE encoded data to BE
* and vice versa.
*/
-// compilerspecific variants come first, fallback last
+// machine/compiler-specific variants come first, fallback last
// Test for GCC and if the target has the MIPS rel.2 instructions (we know the psp does)
+//
#if defined(__GNUC__) && (defined(__psp__) || defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2))
- FORCEINLINE uint16 SWAP_BYTES_16(const uint16 a) {
+ FORCEINLINE uint64 SWAP_BYTES_64(const uint64 a) {
if (__builtin_constant_p(a)) {
- return SWAP_CONSTANT_16(a);
+ return SWAP_CONSTANT_64(a);
} else {
- uint16 result;
- __asm__ ("wsbh %0,%1" : "=r" (result) : "r" (a));
- return result;
+ uint32 low = (uint32)a, high = (uint32)(a >> 32);
+ low = SWAP_BYTES_32(low);
+ high = SWAP_BYTES_32(high);
+
+ return (((uint64)low) << 32) | high;
}
}
+
+// Test for GCC >= 4.3.0 as this version added the bswap builtin
+#elif GCC_ATLEAST(4, 3)
+
+ FORCEINLINE uint64 SWAP_BYTES_64(uint64 a) {
+ return __builtin_bswap64(a);
+ }
+
+#elif defined(_MSC_VER)
+
+ FORCEINLINE uint64 SWAP_BYTES_64(uint64 a) {
+ return _byteswap_uint64(a);
+ }
+
+// generic fallback
#else
- inline uint16 SWAP_BYTES_16(const uint16 a) {
- return (a >> 8) | (a << 8);
+ inline uint64 SWAP_BYTES_64(uint64 a) {
+ uint32 low = (uint32)a, high = (uint32)(a >> 32);
+ uint16 lowLow = (uint16)low, lowHigh = (uint16)(low >> 16),
+ highLow = (uint16)high, highHigh = (uint16)(high >> 16);
+
+ return ((uint64)(((uint32)(uint16)((lowLow >> 8) | (lowLow << 8)) << 16) |
+ (uint16)((lowHigh >> 8) | (lowHigh << 8))) << 32) |
+ (((uint32)(uint16)((highLow >> 8) | (highLow << 8)) << 16) |
+ (uint16)((highHigh >> 8) | (highHigh << 8)));
}
#endif
+#endif // HAVE_INT64
+
/**
* A wrapper macro used around four character constants, like 'DATA', to
@@ -183,6 +253,18 @@
((Unaligned32 *)ptr)->val = value;
}
+#ifdef HAVE_INT64
+ FORCEINLINE uint64 READ_UINT64(const void *ptr) {
+ struct Unaligned64 { uint64 val; } __attribute__ ((__packed__, __may_alias__));
+ return ((const Unaligned64 *)ptr)->val;
+ }
+
+ FORCEINLINE void WRITE_UINT64(void *ptr, uint64 value) {
+ struct Unaligned64 { uint64 val; } __attribute__((__packed__, __may_alias__));
+ ((Unaligned64 *)ptr)->val = value;
+ }
+#endif
+
#elif !defined(SCUMM_NEED_ALIGNMENT)
FORCEINLINE uint16 READ_UINT16(const void *ptr) {
@@ -201,6 +283,16 @@
*(uint32 *)(ptr) = value;
}
+#ifdef HAVE_INT64
+ FORCEINLINE uint64 READ_UINT64(const void *ptr) {
+ return *(const uint64 *)(ptr);
+ }
+
+ FORCEINLINE void WRITE_UINT64(void *ptr, uint64 value) {
+ *(uint64 *)(ptr) = value;
+ }
+#endif
+
// use software fallback by loading each byte explicitely
#else
@@ -227,6 +319,23 @@
b[2] = (uint8)(value >> 16);
b[3] = (uint8)(value >> 24);
}
+#ifdef HAVE_INT64
+ inline uint64 READ_UINT64(const void *ptr) {
+ const uint8 *b = (const uint8 *)ptr;
+ return ((uint64)b[7] << 56) | ((uint64)b[6] << 48) | ((uint64)b[5] << 40) | ((uint64)b[4] << 32) | ((uint64)b[3] << 24) | ((uint64)b[2] << 16) | ((uint64)b[1] << 8) | ((uint64)b[0]);
+ }
+ inline void WRITE_UINT64(void *ptr, uint64 value) {
+ uint8 *b = (uint8 *)ptr;
+ b[0] = (uint8)(value >> 0);
+ b[1] = (uint8)(value >> 8);
+ b[2] = (uint8)(value >> 16);
+ b[3] = (uint8)(value >> 24);
+ b[4] = (uint8)(value >> 32);
+ b[5] = (uint8)(value >> 40);
+ b[6] = (uint8)(value >> 48);
+ b[7] = (uint8)(value >> 56);
+ }
+#endif
# elif defined(SCUMM_BIG_ENDIAN)
@@ -250,6 +359,23 @@
b[2] = (uint8)(value >> 8);
b[3] = (uint8)(value >> 0);
}
+#ifdef HAVE_INT64
+ inline uint64 READ_UINT64(const void *ptr) {
+ const uint8 *b = (const uint8 *)ptr;
+ return ((uint64)b[0] << 56) | ((uint64)b[1] << 48) | ((uint64)b[2] << 40) | ((uint64)b[3] << 32) | ((uint64)b[4] << 24) | ((uint64)b[5] << 16) | ((uint64)b[6] << 8) | ((uint64)b[7]);
+ }
+ inline void WRITE_UINT64(void *ptr, uint64 value) {
+ uint8 *b = (uint8 *)ptr;
+ b[0] = (uint8)(value >> 56);
+ b[1] = (uint8)(value >> 48);
+ b[2] = (uint8)(value >> 40);
+ b[3] = (uint8)(value >> 32);
+ b[4] = (uint8)(value >> 24);
+ b[5] = (uint8)(value >> 16);
+ b[6] = (uint8)(value >> 8);
+ b[7] = (uint8)(value >> 0);
+ }
+#endif
# endif
@@ -283,6 +409,17 @@
#define CONSTANT_BE_32(a) SWAP_CONSTANT_32(a)
#define CONSTANT_BE_16(a) SWAP_CONSTANT_16(a)
+#ifdef HAVE_INT64
+ #define READ_LE_UINT64(a) READ_UINT64(a)
+ #define WRITE_LE_UINT64(a, v) WRITE_UINT64(a, v)
+ #define FROM_LE_64(a) ((uint64)(a))
+ #define FROM_BE_64(a) SWAP_BYTES_64(a)
+ #define TO_LE_64(a) ((uint64)(a))
+ #define TO_BE_64(a) SWAP_BYTES_64(a)
+ #define CONSTANT_LE_64(a) ((uint64)(a))
+ #define CONSTANT_BE_64(a) SWAP_CONSTANT_64(a)
+#endif
+
// if the unaligned load and the byteswap take alot instructions its better to directly read and invert
# if defined(SCUMM_NEED_ALIGNMENT) && !defined(__mips__)
@@ -306,6 +443,24 @@
b[2] = (uint8)(value >> 8);
b[3] = (uint8)(value >> 0);
}
+#ifdef HAVE_INT64
+ inline uint64 READ_BE_UINT64(const void *ptr) {
+ const uint8 *b = (const uint8 *)ptr;
+ return ((uint64)b[0] << 56) | ((uint64)b[1] << 48) | ((uint64)b[2] << 40) | ((uint64)b[3] << 32) | ((uint64)b[4] << 24) | ((uint64)b[5] << 16) | ((uint64)b[6] << 8) | ((uint64)b[7]);
+ }
+ inline void WRITE_BE_UINT64(void *ptr, uint64 value) {
+ uint8 *b = (uint8 *)ptr;
+ b[0] = (uint8)(value >> 56);
+ b[1] = (uint8)(value >> 48);
+ b[2] = (uint8)(value >> 40);
+ b[3] = (uint8)(value >> 32);
+ b[4] = (uint8)(value >> 24);
+ b[5] = (uint8)(value >> 16);
+ b[6] = (uint8)(value >> 8);
+ b[7] = (uint8)(value >> 0);
+ }
+#endif
+
# else
inline uint16 READ_BE_UINT16(const void *ptr) {
@@ -320,6 +475,14 @@
inline void WRITE_BE_UINT32(void *ptr, uint32 value) {
WRITE_UINT32(ptr, SWAP_BYTES_32(value));
}
+#ifdef HAVE_INT64
+ inline uint64 READ_BE_UINT64(const void *ptr) {
+ return SWAP_BYTES_64(READ_UINT64(ptr));
+ }
+ inline void WRITE_BE_UINT64(void *ptr, uint64 value) {
+ WRITE_UINT64(ptr, SWAP_BYTES_64(value));
+ }
+#endif
# endif // if defined(SCUMM_NEED_ALIGNMENT)
@@ -349,6 +512,17 @@
#define CONSTANT_BE_32(a) ((uint32)(a))
#define CONSTANT_BE_16(a) ((uint16)(a))
+#ifdef HAVE_INT64
+ #define READ_BE_UINT64(a) READ_UINT64(a)
+ #define WRITE_BE_UINT64(a, v) WRITE_UINT64(a, v)
+ #define FROM_LE_64(a) SWAP_BYTES_64(a)
+ #define FROM_BE_64(a) ((uint64)(a))
+ #define TO_LE_64(a) SWAP_BYTES_64(a)
+ #define TO_BE_64(a) ((uint64)(a))
+ #define CONSTANT_LE_64(a) SWAP_CONSTANT_64(a)
+ #define CONSTANT_BE_64(a) ((uint64)(a))
+#endif
+
// if the unaligned load and the byteswap take alot instructions its better to directly read and invert
# if defined(SCUMM_NEED_ALIGNMENT) && !defined(__mips__)
@@ -372,6 +546,25 @@
b[2] = (uint8)(value >> 16);
b[3] = (uint8)(value >> 24);
}
+
+#ifdef HAVE_INT64
+ inline uint64 READ_LE_UINT64(const void *ptr) {
+ const uint8 *b = (const uint8 *)ptr;
+ return ((uint64)b[7] << 56) | ((uint64)b[6] << 48) | ((uint64)b[5] << 40) | ((uint64)b[4] << 32) | ((uint64)b[3] << 24) | ((uint64)b[2] << 16) | ((uint64)b[1] << 8) | ((uint64)b[0]);
+ }
+ inline void WRITE_LE_UINT64(void *ptr, uint64 value) {
+ uint8 *b = (uint8 *)ptr;
+ b[0] = (uint8)(value >> 0);
+ b[1] = (uint8)(value >> 8);
+ b[2] = (uint8)(value >> 16);
+ b[3] = (uint8)(value >> 24);
+ b[4] = (uint8)(value >> 32);
+ b[5] = (uint8)(value >> 40);
+ b[6] = (uint8)(value >> 48);
+ b[7] = (uint8)(value >> 56);
+ }
+#endif
+
# else
inline uint16 READ_LE_UINT16(const void *ptr) {
@@ -386,6 +579,14 @@
inline void WRITE_LE_UINT32(void *ptr, uint32 value) {
WRITE_UINT32(ptr, SWAP_BYTES_32(value));
}
+#ifdef HAVE_INT64
+ inline uint64 READ_LE_UINT64(const void *ptr) {
+ return SWAP_BYTES_64(READ_UINT64(ptr));
+ }
+ inline void WRITE_LE_UINT64(void *ptr, uint64 value) {
+ WRITE_UINT64(ptr, SWAP_BYTES_64(value));
+ }
+#endif
# endif // if defined(SCUMM_NEED_ALIGNMENT)
diff --git a/common/fft.cpp b/common/fft.cpp
index ac7386083f..27a04abb6a 100644
--- a/common/fft.cpp
+++ b/common/fft.cpp
@@ -56,11 +56,19 @@ FFT::FFT(int bits, int inverse) : _bits(bits), _inverse(inverse) {
}
FFT::~FFT() {
+ for (int i = 0; i < ARRAYSIZE(_cosTables); i++) {
+ delete _cosTables[i];
+ }
+
delete[] _revTab;
delete[] _expTab;
delete[] _tmpBuf;
}
+const uint16 *FFT::getRevTab() const {
+ return _revTab;
+}
+
void FFT::permute(Complex *z) {
int np = 1 << _bits;
diff --git a/common/fft.h b/common/fft.h
index 6eb72c3f84..ed66d32b71 100644
--- a/common/fft.h
+++ b/common/fft.h
@@ -47,6 +47,8 @@ public:
FFT(int bits, int inverse);
~FFT();
+ const uint16 *getRevTab() const;
+
/** Do the permutation needed BEFORE calling calc(). */
void permute(Complex *z);
diff --git a/common/stream.h b/common/stream.h
index 2702068cf3..abe5192b70 100644
--- a/common/stream.h
+++ b/common/stream.h
@@ -125,6 +125,13 @@ public:
write(&value, 4);
}
+#ifdef HAVE_INT64
+ void writeUint64LE(uint64 value) {
+ value = TO_LE_64(value);
+ write(&value, 8);
+ }
+#endif
+
void writeUint16BE(uint16 value) {
value = TO_BE_16(value);
write(&value, 2);
@@ -135,6 +142,13 @@ public:
write(&value, 4);
}
+#ifdef HAVE_INT64
+ void writeUint64BE(uint64 value) {
+ value = TO_BE_64(value);
+ write(&value, 8);
+ }
+#endif
+
FORCEINLINE void writeSint16LE(int16 value) {
writeUint16LE((uint16)value);
}
@@ -143,6 +157,12 @@ public:
writeUint32LE((uint32)value);
}
+#ifdef HAVE_INT64
+ FORCEINLINE void writeSint64LE(int64 value) {
+ writeUint64LE((uint64)value);
+ }
+#endif
+
FORCEINLINE void writeSint16BE(int16 value) {
writeUint16BE((uint16)value);
}
@@ -151,6 +171,12 @@ public:
writeUint32BE((uint32)value);
}
+#ifdef HAVE_INT64
+ FORCEINLINE void writeSint64BE(int64 value) {
+ writeUint64BE((uint64)value);
+ }
+#endif
+
/**
* Write the given string to the stream.
* This writes str.size() characters, but no terminating zero byte.
@@ -241,6 +267,21 @@ public:
return FROM_LE_32(val);
}
+#ifdef HAVE_INT64
+ /**
+ * Read an unsigned 64-bit word stored in little endian (LSB first) order
+ * from the stream and return it.
+ * Performs no error checking. The return value is undefined
+ * if a read error occurred (for which client code can check by
+ * calling err() and eos() ).
+ */
+ uint64 readUint64LE() {
+ uint64 val;
+ read(&val, 8);
+ return FROM_LE_64(val);
+ }
+#endif
+
/**
* Read an unsigned 16-bit word stored in big endian (MSB first) order
* from the stream and return it.
@@ -267,6 +308,21 @@ public:
return FROM_BE_32(val);
}
+#ifdef HAVE_INT64
+ /**
+ * Read an unsigned 64-bit word stored in big endian (MSB first) order
+ * from the stream and return it.
+ * Performs no error checking. The return value is undefined
+ * if a read error occurred (for which client code can check by
+ * calling err() and eos() ).
+ */
+ uint64 readUint64BE() {
+ uint64 val;
+ read(&val, 8);
+ return FROM_BE_64(val);
+ }
+#endif
+
/**
* Read a signed 16-bit word stored in little endian (LSB first) order
* from the stream and return it.
@@ -289,6 +345,19 @@ public:
return (int32)readUint32LE();
}
+#ifdef HAVE_INT64
+ /**
+ * Read a signed 64-bit word stored in little endian (LSB first) order
+ * from the stream and return it.
+ * Performs no error checking. The return value is undefined
+ * if a read error occurred (for which client code can check by
+ * calling err() and eos() ).
+ */
+ FORCEINLINE int64 readSint64LE() {
+ return (int64)readUint64LE();
+ }
+#endif
+
/**
* Read a signed 16-bit word stored in big endian (MSB first) order
* from the stream and return it.
@@ -311,6 +380,19 @@ public:
return (int32)readUint32BE();
}
+#ifdef HAVE_INT64
+ /**
+ * Read a signed 64-bit word stored in big endian (MSB first) order
+ * from the stream and return it.
+ * Performs no error checking. The return value is undefined
+ * if a read error occurred (for which client code can check by
+ * calling err() and eos() ).
+ */
+ FORCEINLINE int64 readSint64BE() {
+ return (int64)readUint64BE();
+ }
+#endif
+
/**
* Read the specified amount of data into a malloc'ed buffer
* which then is wrapped into a MemoryReadStream.
@@ -435,6 +517,14 @@ public:
return (_bigEndian) ? TO_BE_32(val) : TO_LE_32(val);
}
+#ifdef HAVE_INT64
+ uint64 readUint64() {
+ uint64 val;
+ read(&val, 8);
+ return (_bigEndian) ? TO_BE_64(val) : TO_LE_64(val);
+ }
+#endif
+
FORCEINLINE int16 readSint16() {
return (int16)readUint16();
}
@@ -442,6 +532,12 @@ public:
FORCEINLINE int32 readSint32() {
return (int32)readUint32();
}
+
+#ifdef HAVE_INT64
+ FORCEINLINE int64 readSint64() {
+ return (int64)readUint64();
+ }
+#endif
};
/**
diff --git a/configure b/configure
index eba1ebcb32..48dfdbda14 100755
--- a/configure
+++ b/configure
@@ -35,6 +35,7 @@ SAVED_CXXFLAGS=$CXXFLAGS
SAVED_CPPFLAGS=$CPPFLAGS
SAVED_ASFLAGS=$ASFLAGS
SAVED_WINDRESFLAGS=$WINDRESFLAGS
+SAVED_SDL_CONFIG=$SDL_CONFIG
# Use environment vars if set
CXXFLAGS="$CXXFLAGS $CPPFLAGS"
@@ -353,7 +354,7 @@ define_in_config_if_yes() {
# TODO: small bit of code to test sdl usability
find_sdlconfig() {
echo_n "Looking for sdl-config... "
- sdlconfigs="$_sdlconfig:sdl-config:sdl11-config:sdl12-config"
+ sdlconfigs="$SDL_CONFIG:$_sdlconfig:sdl-config:sdl11-config:sdl12-config"
_sdlconfig=
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="$SEPARATOR"
@@ -1318,7 +1319,7 @@ ds)
;;
gamecube)
_host_os=gamecube
- _host_cpu=ppc
+ _host_cpu=powerpc
_host_alias=powerpc-eabi
;;
gp2x)
@@ -1386,7 +1387,7 @@ openpandora)
;;
ppc-amigaos)
_host_os=amigaos
- _host_cpu=ppc
+ _host_cpu=powerpc
;;
ps2)
_host_os=ps2
@@ -1398,7 +1399,7 @@ ps2)
;;
ps3)
_host_os=ps3
- _host_cpu=ppc
+ _host_cpu=powerpc
_host_alias=powerpc64-ps3-elf
# The prefix is always the same on PS3 so we hardcode the default
@@ -1444,7 +1445,7 @@ webos)
;;
wii)
_host_os=wii
- _host_cpu=ppc
+ _host_cpu=powerpc
_host_alias=powerpc-eabi
;;
wince)
@@ -2004,7 +2005,7 @@ cc_check_clean tmp_find_type_with_size.cpp
# for the smaller sizes.
echo_n "Alignment required... "
case $_host_cpu in
- i[3-6]86 | amd64 | x86_64 | ppc*)
+ i[3-6]86 | amd64 | x86_64 | powerpc*)
# Unaligned access should work
_need_memalign=no
;;
@@ -2047,7 +2048,7 @@ case $_host_cpu in
echo "MIPS"
DEFINES="$DEFINES -DMIPS_TARGET"
;;
- ppc*)
+ powerpc*)
echo "PowerPC"
DEFINES="$DEFINES -DPPC_TARGET"
;;
@@ -2181,8 +2182,21 @@ case $_host_os in
exit 1
;;
darwin*)
+ # Pass -mlongcall to gcc so that it emits long calls
+ # which will allow for calls larger than 32MB. The linker
+ # will discard the calls if they are not needed, but we
+ # need to ensure the compiler emits them in the first place.
+ case $_host_cpu in
+ powerpc*)
+ CFLAGS="$CFLAGS -mlongcall"
+ CXXFLAGS="$CXXFLAGS -mlongcall"
+ ;;
+ esac
+
DEFINES="$DEFINES -DMACOSX"
LIBS="$LIBS -framework AudioUnit -framework AudioToolbox -framework Carbon -framework CoreMIDI"
+ # SDL2 doesn't seem to add Cocoa for us.
+ LIBS="$LIBS -framework Cocoa"
add_line_to_config_mk 'MACOSX = 1'
# Now we may have MacPorts or Fink installed
@@ -3058,6 +3072,9 @@ case $_backend in
1.3.*)
add_line_to_config_mk "USE_SDL13 = 1"
;;
+ 2.0.*)
+ add_line_to_config_mk "USE_SDL2 = 1"
+ ;;
*)
;;
esac
@@ -3539,7 +3556,7 @@ if test "$_alsa" = yes ; then
LIBS="$LIBS $ALSA_LIBS -lasound"
INCLUDES="$INCLUDES $ALSA_CFLAGS"
fi
-define_in_config_h_if_yes "$_alsa" 'USE_ALSA'
+define_in_config_if_yes "$_alsa" 'USE_ALSA'
echo "$_alsa"
#
@@ -4504,6 +4521,7 @@ $_def_64bit_type_unsigned
#else
$_def_64bit_type_unsigned
#endif
+#define HAVE_INT64
EOF
fi
@@ -4532,6 +4550,8 @@ WIN32PATH=$_win32path
AMIGAOSPATH=$_amigaospath
STATICLIBPATH=$_staticlibpath
+ABI := $ABI
+
BACKEND := $_backend
MODULES += $MODULES
MODULE_DIRS += $MODULE_DIRS
@@ -4567,6 +4587,7 @@ SAVED_CXXFLAGS := $SAVED_CXXFLAGS
SAVED_CPPFLAGS := $SAVED_CPPFLAGS
SAVED_ASFLAGS := $SAVED_ASFLAGS
SAVED_WINDRESFLAGS := $SAVED_WINDRESFLAGS
+SAVED_SDL_CONFIG := $SAVED_SDL_CONFIG
EOF
#
diff --git a/devtools/create_project/create_project.cpp b/devtools/create_project/create_project.cpp
index e71816f575..e4cb67134a 100644
--- a/devtools/create_project/create_project.cpp
+++ b/devtools/create_project/create_project.cpp
@@ -20,7 +20,7 @@
*
*/
-//#define ENABLE_XCODE
+#define ENABLE_XCODE
// HACK to allow building with the SDL backend on MinGW
// see bug #1800764 "TOOLS: MinGW tools building broken"
@@ -125,6 +125,7 @@ int main(int argc, char *argv[]) {
ProjectType projectType = kProjectNone;
int msvcVersion = 9;
+ bool useSDL2 = false;
// Parse command line arguments
using std::cout;
@@ -267,6 +268,8 @@ int main(int argc, char *argv[]) {
setup.devTools = true;
} else if (!std::strcmp(argv[i], "--tests")) {
setup.tests = true;
+ } else if (!std::strcmp(argv[i], "--sdl2")) {
+ useSDL2 = true;
} else {
std::cerr << "ERROR: Unknown parameter \"" << argv[i] << "\"\n";
return -1;
@@ -333,9 +336,20 @@ int main(int argc, char *argv[]) {
setup.defines.splice(setup.defines.begin(), featureDefines);
// Windows only has support for the SDL backend, so we hardcode it here (along with winmm)
- setup.defines.push_back("WIN32");
+ if (projectType != kProjectXcode) {
+ setup.defines.push_back("WIN32");
+ } else {
+ setup.defines.push_back("POSIX");
+ setup.defines.push_back("MACOSX"); // This will break iOS, but allows OS X to catch up on browser_osx.
+ }
setup.defines.push_back("SDL_BACKEND");
- setup.libraries.push_back("sdl");
+ if (!useSDL2) {
+ cout << "\nLinking to SDL 1.2\n\n";
+ setup.libraries.push_back("sdl");
+ } else {
+ cout << "\nLinking to SDL 2.0\n\n";
+ setup.libraries.push_back("sdl2");
+ }
setup.libraries.push_back("winmm");
// Add additional project-specific library
@@ -401,7 +415,6 @@ int main(int argc, char *argv[]) {
globalWarnings.push_back("-Wwrite-strings");
// The following are not warnings at all... We should consider adding them to
// a different list of parameters.
- globalWarnings.push_back("-fno-rtti");
globalWarnings.push_back("-fno-exceptions");
globalWarnings.push_back("-fcheck-new");
@@ -563,7 +576,7 @@ int main(int argc, char *argv[]) {
globalWarnings.push_back("-fno-exceptions");
globalWarnings.push_back("-fcheck-new");
- provider = new CreateProjectTool::XCodeProvider(globalWarnings, projectWarnings);
+ provider = new CreateProjectTool::XcodeProvider(globalWarnings, projectWarnings);
break;
}
@@ -645,6 +658,9 @@ void displayHelp(const char *exe) {
"Optional features settings:\n"
" --enable-<name> enable inclusion of the feature \"name\"\n"
" --disable-<name> disable inclusion of the feature \"name\"\n"
+ "\n"
+ "SDL settings:\n"
+ " --sdl2 link to SDL 2.0, instead of SDL 1.2\n"
"\n"
" There are the following features available:\n"
"\n";
@@ -1027,7 +1043,7 @@ bool producesObjectFile(const std::string &fileName) {
std::string n, ext;
splitFilename(fileName, n, ext);
- if (ext == "cpp" || ext == "c" || ext == "asm")
+ if (ext == "cpp" || ext == "c" || ext == "asm" || ext == "m" || ext == "mm")
return true;
else
return false;
@@ -1267,8 +1283,9 @@ void ProjectProvider::createProject(BuildSetup &setup) {
for (UUIDMap::const_iterator i = _uuidMap.begin(); i != _uuidMap.end(); ++i) {
if (i->first == setup.projectName)
continue;
-
+ // Retain the files between engines if we're creating a single project
in.clear(); ex.clear();
+
const std::string moduleDir = setup.srcDir + targetFolder + i->first;
createModuleList(moduleDir, setup.defines, setup.testDirs, in, ex);
@@ -1278,7 +1295,6 @@ void ProjectProvider::createProject(BuildSetup &setup) {
if (setup.tests) {
// Create the main project file.
in.clear(); ex.clear();
-
createModuleList(setup.srcDir + "/backends", setup.defines, setup.testDirs, in, ex);
createModuleList(setup.srcDir + "/backends/platform/sdl", setup.defines, setup.testDirs, in, ex);
createModuleList(setup.srcDir + "/base", setup.defines, setup.testDirs, in, ex);
@@ -1293,7 +1309,6 @@ void ProjectProvider::createProject(BuildSetup &setup) {
} else if (!setup.devTools) {
// Last but not least create the main project file.
in.clear(); ex.clear();
-
// File list for the Project file
createModuleList(setup.srcDir + "/backends", setup.defines, setup.testDirs, in, ex);
createModuleList(setup.srcDir + "/backends/platform/sdl", setup.defines, setup.testDirs, in, ex);
diff --git a/devtools/create_project/xcode.cpp b/devtools/create_project/xcode.cpp
index d95bf3e9ee..babd530ad7 100644
--- a/devtools/create_project/xcode.cpp
+++ b/devtools/create_project/xcode.cpp
@@ -30,6 +30,14 @@ namespace CreateProjectTool {
#define DEBUG_XCODE_HASH 0
+#ifdef ENABLE_IOS
+#define IOS_TARGET 0
+#define OSX_TARGET 1
+#define SIM_TARGET 2
+#else
+#define OSX_TARGET 0
+#endif
+
#define ADD_DEFINE(defines, name) \
defines.push_back(name);
@@ -54,39 +62,172 @@ namespace CreateProjectTool {
#define REMOVE_SETTING(config, key) \
config.settings.erase(key);
-#define ADD_BUILD_FILE(id, name, comment) { \
+#define ADD_BUILD_FILE(id, name, fileRefId, comment) { \
Object *buildFile = new Object(this, id, name, "PBXBuildFile", "PBXBuildFile", comment); \
- buildFile->addProperty("fileRef", getHash(name), name, SettingsNoValue); \
+ buildFile->addProperty("fileRef", fileRefId, name, SettingsNoValue); \
_buildFile.add(buildFile); \
_buildFile.flags = SettingsSingleItem; \
}
-#define ADD_FILE_REFERENCE(name, properties) { \
- Object *fileRef = new Object(this, name, name, "PBXFileReference", "PBXFileReference", name); \
+#define ADD_FILE_REFERENCE(id, name, properties) { \
+ Object *fileRef = new Object(this, id, name, "PBXFileReference", "PBXFileReference", name); \
if (!properties.fileEncoding.empty()) fileRef->addProperty("fileEncoding", properties.fileEncoding, "", SettingsNoValue); \
- if (!properties.lastKnownFileType.empty()) fileRef->addProperty("lastKnownFileType", properties.lastKnownFileType, "", SettingsNoValue); \
- if (!properties.fileName.empty()) fileRef->addProperty("name", properties.fileName, "", SettingsNoValue); \
- if (!properties.filePath.empty()) fileRef->addProperty("path", properties.filePath, "", SettingsNoValue); \
+ if (!properties.lastKnownFileType.empty()) fileRef->addProperty("lastKnownFileType", properties.lastKnownFileType, "", SettingsNoValue|SettingsQuoteVariable); \
+ if (!properties.fileName.empty()) fileRef->addProperty("name", properties.fileName, "", SettingsNoValue|SettingsQuoteVariable); \
+ if (!properties.filePath.empty()) fileRef->addProperty("path", properties.filePath, "", SettingsNoValue|SettingsQuoteVariable); \
if (!properties.sourceTree.empty()) fileRef->addProperty("sourceTree", properties.sourceTree, "", SettingsNoValue); \
_fileReference.add(fileRef); \
_fileReference.flags = SettingsSingleItem; \
}
-XCodeProvider::XCodeProvider(StringList &global_warnings, std::map<std::string, StringList> &project_warnings, const int version)
+bool producesObjectFileOnOSX(const std::string &fileName) {
+ std::string n, ext;
+ splitFilename(fileName, n, ext);
+
+ // Note that the difference between this and the general producesObjectFile is that
+ // this one adds Objective-C(++), and removes asm-support.
+ if (ext == "cpp" || ext == "c" || ext == "m" || ext == "mm")
+ return true;
+ else
+ return false;
+}
+
+XcodeProvider::Group::Group(XcodeProvider *objectParent, const std::string &groupName, const std::string &uniqueName, const std::string &path) : Object(objectParent, uniqueName, groupName, "PBXGroup", "", groupName) {
+ addProperty("name", name, "", SettingsNoValue|SettingsQuoteVariable);
+ addProperty("sourceTree", "<group>", "", SettingsNoValue|SettingsQuoteVariable);
+
+ if (path != "") {
+ addProperty("path", path, "", SettingsNoValue|SettingsQuoteVariable);
+ }
+ _childOrder = 0;
+ _treeName = uniqueName;
+}
+
+void XcodeProvider::Group::ensureChildExists(const std::string &name) {
+ std::map<std::string, Group*>::iterator it = _childGroups.find(name);
+ if (it == _childGroups.end()) {
+ Group *child = new Group(parent, name, this->_treeName + '/' + name, name);
+ _childGroups[name] = child;
+ addChildGroup(child);
+ parent->_groups.add(child);
+ }
+}
+
+void XcodeProvider::Group::addChildInternal(const std::string &id, const std::string &comment) {
+ if (properties.find("children") == properties.end()) {
+ Property children;
+ children.hasOrder = true;
+ children.flags = SettingsAsList;
+ properties["children"] = children;
+ }
+ properties["children"].settings[id] = Setting("", comment + " in Sources", SettingsNoValue, 0, _childOrder++);
+ if (_childOrder == 1) {
+ // Force children to use () even when there is only 1 child.
+ // Also this enforces the use of "," after the single item, instead of ; (see writeProperty)
+ properties["children"].flags |= SettingsSingleItem;
+ } else {
+ properties["children"].flags ^= SettingsSingleItem;
+ }
+
+}
+
+void XcodeProvider::Group::addChildGroup(const Group* group) {
+ addChildInternal(parent->getHash(group->_treeName), group->_treeName);
+}
+
+void XcodeProvider::Group::addChildFile(const std::string &name) {
+ std::string id = "FileReference_" + _treeName + "/" + name;
+ addChildInternal(parent->getHash(id), name);
+ FileProperty property = FileProperty(name, name, name, "\"<group>\"");
+
+ parent->addFileReference(id, name, property);
+ if (producesObjectFileOnOSX(name)) {
+ parent->addBuildFile(_treeName + "/" + name, name, parent->getHash(id), name + " in Sources");
+ }
+}
+
+void XcodeProvider::Group::addChildByHash(const std::string &hash, const std::string &name) {
+ addChildInternal(hash, name);
+}
+
+XcodeProvider::Group *XcodeProvider::Group::getChildGroup(const std::string &name) {
+ std::map<std::string, Group*>::iterator it = _childGroups.find(name);
+ assert(it != _childGroups.end());
+ return it->second;
+}
+
+XcodeProvider::Group *XcodeProvider::touchGroupsForPath(const std::string &path) {
+ if (_rootSourceGroup == NULL) {
+ assert (path == _projectRoot);
+ _rootSourceGroup = new Group(this, "Sources", path, path);
+ _groups.add(_rootSourceGroup);
+ return _rootSourceGroup;
+ } else {
+ assert(path.find(_projectRoot) == 0);
+ std::string subPath = path.substr(_projectRoot.size() + 1);
+ Group *currentGroup = _rootSourceGroup;
+ size_t firstPathComponent = subPath.find_first_of('/');
+ // We assume here that all paths have trailing '/', otherwise this breaks.
+ while (firstPathComponent != std::string::npos) {
+ currentGroup->ensureChildExists(subPath.substr(0, firstPathComponent));
+ currentGroup = currentGroup->getChildGroup(subPath.substr(0, firstPathComponent));
+ subPath = subPath.substr(firstPathComponent + 1);
+ firstPathComponent = subPath.find_first_of('/');
+ }
+ return currentGroup;
+ }
+}
+
+void XcodeProvider::addFileReference(const std::string &id, const std::string &name, FileProperty properties) {
+ Object *fileRef = new Object(this, id, name, "PBXFileReference", "PBXFileReference", name);
+ if (!properties.fileEncoding.empty()) fileRef->addProperty("fileEncoding", properties.fileEncoding, "", SettingsNoValue);
+ if (!properties.lastKnownFileType.empty()) fileRef->addProperty("lastKnownFileType", properties.lastKnownFileType, "", SettingsNoValue|SettingsQuoteVariable);
+ if (!properties.fileName.empty()) fileRef->addProperty("name", properties.fileName, "", SettingsNoValue|SettingsQuoteVariable);
+ if (!properties.filePath.empty()) fileRef->addProperty("path", properties.filePath, "", SettingsNoValue|SettingsQuoteVariable);
+ if (!properties.sourceTree.empty()) fileRef->addProperty("sourceTree", properties.sourceTree, "", SettingsNoValue);
+ _fileReference.add(fileRef);
+ _fileReference.flags = SettingsSingleItem;
+}
+
+void XcodeProvider::addProductFileReference(const std::string &id, const std::string &name) {
+ Object *fileRef = new Object(this, id, name, "PBXFileReference", "PBXFileReference", name);
+ fileRef->addProperty("explicitFileType", "compiled.mach-o.executable", "", SettingsNoValue|SettingsQuoteVariable);
+ fileRef->addProperty("includeInIndex", "0", "", SettingsNoValue);
+ fileRef->addProperty("path", name, "", SettingsNoValue|SettingsQuoteVariable);
+ fileRef->addProperty("sourceTree", "BUILT_PRODUCTS_DIR", "", SettingsNoValue);
+ _fileReference.add(fileRef);
+ _fileReference.flags = SettingsSingleItem;
+}
+
+void XcodeProvider::addBuildFile(const std::string &id, const std::string &name, const std::string &fileRefId, const std::string &comment) {
+
+ Object *buildFile = new Object(this, id, name, "PBXBuildFile", "PBXBuildFile", comment);
+ buildFile->addProperty("fileRef", fileRefId, name, SettingsNoValue);
+ _buildFile.add(buildFile);
+ _buildFile.flags = SettingsSingleItem;
+}
+
+XcodeProvider::XcodeProvider(StringList &global_warnings, std::map<std::string, StringList> &project_warnings, const int version)
: ProjectProvider(global_warnings, project_warnings, version) {
+ _rootSourceGroup = NULL;
}
-void XCodeProvider::createWorkspace(const BuildSetup &setup) {
+void XcodeProvider::createWorkspace(const BuildSetup &setup) {
// Create project folder
std::string workspace = setup.outputDir + '/' + PROJECT_NAME ".xcodeproj";
createDirectory(workspace);
-
+ _projectRoot = setup.srcDir;
+ touchGroupsForPath(_projectRoot);
+
// Setup global objects
setupDefines(setup);
+#ifdef ENABLE_IOS
_targets.push_back(PROJECT_DESCRIPTION "-iPhone");
+#endif
_targets.push_back(PROJECT_DESCRIPTION "-OS X");
+#ifdef ENABLE_IOS
_targets.push_back(PROJECT_DESCRIPTION "-Simulator");
-
+#endif
setupCopyFilesBuildPhase();
setupFrameworksBuildPhase();
setupNativeTarget();
@@ -97,7 +238,7 @@ void XCodeProvider::createWorkspace(const BuildSetup &setup) {
// We are done with constructing all the object graph and we got through every project, output the main project file
// (this is kind of a hack since other providers use separate project files)
-void XCodeProvider::createOtherBuildFiles(const BuildSetup &setup) {
+void XcodeProvider::createOtherBuildFiles(const BuildSetup &setup) {
// This needs to be done at the end when all build files have been accounted for
setupSourcesBuildPhase();
@@ -105,7 +246,7 @@ void XCodeProvider::createOtherBuildFiles(const BuildSetup &setup) {
}
// Store information about a project here, for use at the end
-void XCodeProvider::createProjectFile(const std::string &, const std::string &, const BuildSetup &setup, const std::string &moduleDir,
+void XcodeProvider::createProjectFile(const std::string &, const std::string &, const BuildSetup &setup, const std::string &moduleDir,
const StringList &includeList, const StringList &excludeList) {
std::string modulePath;
if (!moduleDir.compare(0, setup.srcDir.size(), setup.srcDir)) {
@@ -124,7 +265,7 @@ void XCodeProvider::createProjectFile(const std::string &, const std::string &,
//////////////////////////////////////////////////////////////////////////
// Main Project file
//////////////////////////////////////////////////////////////////////////
-void XCodeProvider::ouputMainProjectFile(const BuildSetup &setup) {
+void XcodeProvider::ouputMainProjectFile(const BuildSetup &setup) {
std::ofstream project((setup.outputDir + '/' + PROJECT_NAME ".xcodeproj" + '/' + "project.pbxproj").c_str());
if (!project)
error("Could not open \"" + setup.outputDir + '/' + PROJECT_NAME ".xcodeproj" + '/' + "project.pbxproj\" for writing");
@@ -164,92 +305,93 @@ void XCodeProvider::ouputMainProjectFile(const BuildSetup &setup) {
//////////////////////////////////////////////////////////////////////////
// Files
//////////////////////////////////////////////////////////////////////////
-void XCodeProvider::writeFileListToProject(const FileNode &dir, std::ofstream &projectFile, const int indentation,
+void XcodeProvider::writeFileListToProject(const FileNode &dir, std::ofstream &projectFile, const int indentation,
const StringList &duplicate, const std::string &objPrefix, const std::string &filePrefix) {
- // Add comments for shared lists
- _buildFile.comment = "PBXBuildFile";
- _fileReference.comment = "PBXFileReference";
-
- // Init root group
- _groups.comment = "PBXGroup";
-
- // Create group
- std::string name = getLastPathComponent(dir.name);
- Object *group = new Object(this, "PBXGroup_" + name , "PBXGroup", "PBXGroup", "", name);
-
- // List of children
- Property children;
- children.hasOrder = true;
- children.flags = SettingsAsList;
-
- group->addProperty("name", name, "", SettingsNoValue|SettingsQuoteVariable);
- group->addProperty("sourceTree", "<group>", "", SettingsNoValue|SettingsQuoteVariable);
-
- int order = 0;
+ // Ensure that top-level groups are generated for i.e. engines/
+ Group *group = touchGroupsForPath(filePrefix);
for (FileNode::NodeList::const_iterator i = dir.children.begin(); i != dir.children.end(); ++i) {
const FileNode *node = *i;
- std::string id = "FileReference_" + node->name;
- FileProperty property = FileProperty(node->name, node->name, node->name, "<group>");
-
- ADD_SETTING_ORDER_NOVALUE(children, getHash(id), node->name, order++);
- ADD_BUILD_FILE(id, node->name, node->name + " in Sources");
- ADD_FILE_REFERENCE(node->name, property);
-
+ // Iff it is a file, then add (build) file references. Since we're using Groups and not File References
+ // for folders, we shouldn't add folders as file references, obviously.
+ if (node->children.empty()) {
+ group->addChildFile(node->name);
+ }
// Process child nodes
if (!node->children.empty())
writeFileListToProject(*node, projectFile, indentation + 1, duplicate, objPrefix + node->name + '_', filePrefix + node->name + '/');
}
-
- group->properties["children"] = children;
-
- _groups.add(group);
}
//////////////////////////////////////////////////////////////////////////
// Setup functions
//////////////////////////////////////////////////////////////////////////
-void XCodeProvider::setupCopyFilesBuildPhase() {
+void XcodeProvider::setupCopyFilesBuildPhase() {
// Nothing to do here
}
+#define DEF_SYSFRAMEWORK(framework) properties[framework".framework"] = FileProperty("wrapper.framework", framework".framework", "System/Library/Frameworks/" framework ".framework", "SDKROOT"); \
+ ADD_SETTING_ORDER_NOVALUE(children, getHash(framework".framework"), framework".framework", fwOrder++);
+
+#define DEF_LOCALLIB_STATIC(lib) properties[lib".a"] = FileProperty("archive.ar", lib".a", "/opt/local/lib/" lib ".a", "\"<group>\""); \
+ ADD_SETTING_ORDER_NOVALUE(children, getHash(lib".a"), lib".a", fwOrder++);
+
/**
* Sets up the frameworks build phase.
*
* (each native target has different build rules)
*/
-void XCodeProvider::setupFrameworksBuildPhase() {
+void XcodeProvider::setupFrameworksBuildPhase() {
_frameworksBuildPhase.comment = "PBXFrameworksBuildPhase";
+ // Just use a hardcoded id for the Frameworks-group
+ Group *frameworksGroup = new Group(this, "Frameworks", "PBXGroup_CustomTemplate_Frameworks_", "");
+
+ Property children;
+ children.hasOrder = true;
+ children.flags = SettingsAsList;
+
// Setup framework file properties
std::map<std::string, FileProperty> properties;
-
+ int fwOrder = 0;
// Frameworks
- properties["ApplicationServices.framework"] = FileProperty("wrapper.framework", "ApplicationServices.framework", "System/Library/Frameworks/ApplicationServices.framework", "SDKROOT");
- properties["AudioToolbox.framework"] = FileProperty("wrapper.framework", "AudioToolbox.framework", "System/Library/Frameworks/AudioToolbox.framework", "SDKROOT");
- properties["AudioUnit.framework"] = FileProperty("wrapper.framework", "AudioUnit.framework", "System/Library/Frameworks/AudioUnit.framework", "SDKROOT");
- properties["Carbon.framework"] = FileProperty("wrapper.framework", "Carbon.framework", "System/Library/Frameworks/Carbon.framework", "SDKROOT");
- properties["Cocoa.framework"] = FileProperty("wrapper.framework", "Cocoa.framework", "System/Library/Frameworks/Cocoa.framework", "SDKROOT");
- properties["CoreAudio.framework"] = FileProperty("wrapper.framework", "CoreAudio.framework", "System/Library/Frameworks/CoreAudio.framework", "SDKROOT");
- properties["CoreFoundation.framework"] = FileProperty("wrapper.framework", "CoreFoundation.framework", "System/Library/Frameworks/CoreFoundation.framework", "SDKROOT");
- properties["CoreMIDI.framework"] = FileProperty("wrapper.framework", "CoreMIDI.framework", "System/Library/Frameworks/CoreMIDI.framework", "SDKROOT");
- properties["Foundation.framework"] = FileProperty("wrapper.framework", "Foundation.framework", "System/Library/Frameworks/Foundation.framework", "SDKROOT");
- properties["IOKit.framework"] = FileProperty("wrapper.framework", "IOKit.framework", "System/Library/Frameworks/IOKit.framework", "SDKROOT");
- properties["OpenGLES.framework"] = FileProperty("wrapper.framework", "OpenGLES.framework", "System/Library/Frameworks/OpenGLES.framework", "SDKROOT");
- properties["QuartzCore.framework"] = FileProperty("wrapper.framework", "QuartzCore.framework", "System/Library/Frameworks/QuartzCore.framework", "SDKROOT");
- properties["QuickTime.framework"] = FileProperty("wrapper.framework", "QuickTime.framework", "System/Library/Frameworks/QuickTime.framework", "SDKROOT");
- properties["UIKit.framework"] = FileProperty("wrapper.framework", "UIKit.framework", "System/Library/Frameworks/UIKit.framework", "SDKROOT");
+ DEF_SYSFRAMEWORK("ApplicationServices");
+ DEF_SYSFRAMEWORK("AudioToolbox");
+ DEF_SYSFRAMEWORK("AudioUnit");
+ DEF_SYSFRAMEWORK("Carbon");
+ DEF_SYSFRAMEWORK("Cocoa");
+ DEF_SYSFRAMEWORK("CoreAudio");
+ DEF_SYSFRAMEWORK("CoreFoundation");
+ DEF_SYSFRAMEWORK("CoreMIDI");
+ DEF_SYSFRAMEWORK("Foundation");
+ DEF_SYSFRAMEWORK("IOKit");
+ DEF_SYSFRAMEWORK("OpenGLES");
+ DEF_SYSFRAMEWORK("QuartzCore");
+ DEF_SYSFRAMEWORK("QuickTime");
+ DEF_SYSFRAMEWORK("UIKit");
+ // Optionals:
+ DEF_SYSFRAMEWORK("OpenGL");
// Local libraries
- properties["libFLAC.a"] = FileProperty("archive.ar", "libFLAC.a", "lib/libFLAC.a", "\"<group>\"");
- properties["libmad.a"] = FileProperty("archive.ar", "libmad.a", "lib/libmad.a", "\"<group>\"");
- //properties["libmpeg2.a"] = FileProperty("archive.ar", "libmpeg2.a", "lib/libmpeg2.a", "\"<group>\"");
- properties["libvorbisidec.a"] = FileProperty("archive.ar", "libvorbisidec.a", "lib/libvorbisidec.a", "\"<group>\"");
+ DEF_LOCALLIB_STATIC("libFLAC");
+ DEF_LOCALLIB_STATIC("libmad");
+ DEF_LOCALLIB_STATIC("libvorbisidec");
+ DEF_LOCALLIB_STATIC("libfreetype");
+// DEF_LOCALLIB_STATIC("libmpeg2");
+
+ frameworksGroup->properties["children"] = children;
+ _groups.add(frameworksGroup);
+ // Force this to be added as a sub-group in the root.
+ _rootSourceGroup->addChildGroup(frameworksGroup);
+
+ // Declare this here, as it's used across the three targets
+ int order = 0;
+#ifdef ENABLE_IOS
//////////////////////////////////////////////////////////////////////////
// iPhone
- Object *framework_iPhone = new Object(this, "PBXFrameworksBuildPhase_" + _targets[0], "PBXFrameworksBuildPhase", "PBXFrameworksBuildPhase", "", "Frameworks");
+ Object *framework_iPhone = new Object(this, "PBXFrameworksBuildPhase_" + _targets[IOS_TARGET], "PBXFrameworksBuildPhase", "PBXFrameworksBuildPhase", "", "Frameworks");
framework_iPhone->addProperty("buildActionMask", "2147483647", "", SettingsNoValue);
framework_iPhone->addProperty("runOnlyForDeploymentPostprocessing", "0", "", SettingsNoValue);
@@ -272,23 +414,22 @@ void XCodeProvider::setupFrameworksBuildPhase() {
frameworks_iPhone.push_back("libvorbisidec.a");
frameworks_iPhone.push_back("OpenGLES.framework");
- int order = 0;
for (ValueList::iterator framework = frameworks_iPhone.begin(); framework != frameworks_iPhone.end(); framework++) {
std::string id = "Frameworks_" + *framework + "_iphone";
std::string comment = *framework + " in Frameworks";
ADD_SETTING_ORDER_NOVALUE(iPhone_files, getHash(id), comment, order++);
- ADD_BUILD_FILE(id, *framework, comment);
- ADD_FILE_REFERENCE(*framework, properties[*framework]);
+ ADD_BUILD_FILE(id, *framework, getHash(*framework), comment);
+ ADD_FILE_REFERENCE(*framework, *framework, properties[*framework]);
}
framework_iPhone->properties["files"] = iPhone_files;
_frameworksBuildPhase.add(framework_iPhone);
-
+#endif
//////////////////////////////////////////////////////////////////////////
// ScummVM-OS X
- Object *framework_OSX = new Object(this, "PBXFrameworksBuildPhase_" + _targets[1], "PBXFrameworksBuildPhase", "PBXFrameworksBuildPhase", "", "Frameworks");
+ Object *framework_OSX = new Object(this, "PBXFrameworksBuildPhase_" + _targets[OSX_TARGET], "PBXFrameworksBuildPhase", "PBXFrameworksBuildPhase", "", "Frameworks");
framework_OSX->addProperty("buildActionMask", "2147483647", "", SettingsNoValue);
framework_OSX->addProperty("runOnlyForDeploymentPostprocessing", "0", "", SettingsNoValue);
@@ -311,6 +452,8 @@ void XCodeProvider::setupFrameworksBuildPhase() {
frameworks_osx.push_back("IOKit.framework");
frameworks_osx.push_back("Cocoa.framework");
frameworks_osx.push_back("AudioUnit.framework");
+ // Optionals:
+ frameworks_osx.push_back("OpenGL.framework");
order = 0;
for (ValueList::iterator framework = frameworks_osx.begin(); framework != frameworks_osx.end(); framework++) {
@@ -318,17 +461,17 @@ void XCodeProvider::setupFrameworksBuildPhase() {
std::string comment = *framework + " in Frameworks";
ADD_SETTING_ORDER_NOVALUE(osx_files, getHash(id), comment, order++);
- ADD_BUILD_FILE(id, *framework, comment);
- ADD_FILE_REFERENCE(*framework, properties[*framework]);
+ ADD_BUILD_FILE(id, *framework, getHash(*framework), comment);
+ ADD_FILE_REFERENCE(*framework, *framework, properties[*framework]);
}
framework_OSX->properties["files"] = osx_files;
_frameworksBuildPhase.add(framework_OSX);
-
+#ifdef ENABLE_IOS
//////////////////////////////////////////////////////////////////////////
// Simulator
- Object *framework_simulator = new Object(this, "PBXFrameworksBuildPhase_" + _targets[2], "PBXFrameworksBuildPhase", "PBXFrameworksBuildPhase", "", "Frameworks");
+ Object *framework_simulator = new Object(this, "PBXFrameworksBuildPhase_" + _targets[SIM_TARGET], "PBXFrameworksBuildPhase", "PBXFrameworksBuildPhase", "", "Frameworks");
framework_simulator->addProperty("buildActionMask", "2147483647", "", SettingsNoValue);
framework_simulator->addProperty("runOnlyForDeploymentPostprocessing", "0", "", SettingsNoValue);
@@ -353,20 +496,28 @@ void XCodeProvider::setupFrameworksBuildPhase() {
std::string comment = *framework + " in Frameworks";
ADD_SETTING_ORDER_NOVALUE(simulator_files, getHash(id), comment, order++);
- ADD_BUILD_FILE(id, *framework, comment);
- ADD_FILE_REFERENCE(*framework, properties[*framework]);
+ ADD_BUILD_FILE(id, *framework, getHash(*framework), comment);
+ ADD_FILE_REFERENCE(*framework, *framework, properties[*framework]);
}
framework_simulator->properties["files"] = simulator_files;
_frameworksBuildPhase.add(framework_simulator);
+#endif
}
-void XCodeProvider::setupNativeTarget() {
+void XcodeProvider::setupNativeTarget() {
_nativeTarget.comment = "PBXNativeTarget";
+ // Just use a hardcoded id for the Products-group
+ Group *productsGroup = new Group(this, "Products", "PBXGroup_CustomTemplate_Products_" , "");
// Output native target section
for (unsigned int i = 0; i < _targets.size(); i++) {
+#ifndef ENABLE_IOS
+ if (i != OSX_TARGET) { // TODO: Fix iOS-targets, for now just disable them.
+ continue;
+ }
+#endif
Object *target = new Object(this, "PBXNativeTarget_" + _targets[i], "PBXNativeTarget", "PBXNativeTarget", "", _targets[i]);
target->addProperty("buildConfigurationList", getHash("XCConfigurationList_" + _targets[i]), "Build configuration list for PBXNativeTarget \"" + _targets[i] + "\"", SettingsNoValue);
@@ -385,14 +536,18 @@ void XCodeProvider::setupNativeTarget() {
target->addProperty("name", _targets[i], "", SettingsNoValue|SettingsQuoteVariable);
target->addProperty("productName", PROJECT_NAME, "", SettingsNoValue);
+ addProductFileReference("PBXFileReference_" PROJECT_DESCRIPTION ".app_" + _targets[i], PROJECT_DESCRIPTION ".app");
+ productsGroup->addChildByHash(getHash("PBXFileReference_" PROJECT_DESCRIPTION ".app_" + _targets[i]), PROJECT_DESCRIPTION ".app");
target->addProperty("productReference", getHash("PBXFileReference_" PROJECT_DESCRIPTION ".app_" + _targets[i]), PROJECT_DESCRIPTION ".app", SettingsNoValue);
target->addProperty("productType", "com.apple.product-type.application", "", SettingsNoValue|SettingsQuoteVariable);
_nativeTarget.add(target);
}
+ _rootSourceGroup->addChildGroup(productsGroup);
+ _groups.add(productsGroup);
}
-void XCodeProvider::setupProject() {
+void XcodeProvider::setupProject() {
_project.comment = "PBXProject";
Object *project = new Object(this, "PBXProject", "PBXProject", "PBXProject", "", "Project object");
@@ -411,22 +566,30 @@ void XCodeProvider::setupProject() {
ADD_SETTING_ORDER_NOVALUE(regions, "German", "", 3);
project->properties["knownRegions"] = regions;
- project->addProperty("mainGroup", getHash("PBXGroup_CustomTemplate"), "CustomTemplate", SettingsNoValue);
- project->addProperty("projectDirPath", "", "", SettingsNoValue|SettingsQuoteVariable);
+ project->addProperty("mainGroup", _rootSourceGroup->getHashRef(), "CustomTemplate", SettingsNoValue);
+ project->addProperty("projectDirPath", _projectRoot, "", SettingsNoValue|SettingsQuoteVariable);
project->addProperty("projectRoot", "", "", SettingsNoValue|SettingsQuoteVariable);
// List of targets
Property targets;
targets.flags = SettingsAsList;
- targets.settings[getHash("PBXNativeTarget_" + _targets[0])] = Setting("", _targets[0], SettingsNoValue, 0, 0);
- targets.settings[getHash("PBXNativeTarget_" + _targets[1])] = Setting("", _targets[1], SettingsNoValue, 0, 1);
- targets.settings[getHash("PBXNativeTarget_" + _targets[2])] = Setting("", _targets[2], SettingsNoValue, 0, 2);
+#ifdef ENABLE_IOS
+ targets.settings[getHash("PBXNativeTarget_" + _targets[IOS_TARGET])] = Setting("", _targets[IOS_TARGET], SettingsNoValue, 0, 0);
+#endif
+ targets.settings[getHash("PBXNativeTarget_" + _targets[OSX_TARGET])] = Setting("", _targets[OSX_TARGET], SettingsNoValue, 0, 1);
+#ifdef ENABLE_IOS
+ targets.settings[getHash("PBXNativeTarget_" + _targets[SIM_TARGET])] = Setting("", _targets[SIM_TARGET], SettingsNoValue, 0, 2);
+#endif
project->properties["targets"] = targets;
+#ifndef ENABLE_IOS
+ // Force list even when there is only a single target
+ project->properties["targets"].flags |= SettingsSingleItem;
+#endif
_project.add(project);
}
-void XCodeProvider::setupResourcesBuildPhase() {
+void XcodeProvider::setupResourcesBuildPhase() {
_resourcesBuildPhase.comment = "PBXResourcesBuildPhase";
// Setup resource file properties
@@ -483,7 +646,7 @@ void XCodeProvider::setupResourcesBuildPhase() {
ADD_SETTING_ORDER_NOVALUE(files, getHash(id), comment, order++);
// TODO Fix crash when adding build file for data
//ADD_BUILD_FILE(id, *file, comment);
- ADD_FILE_REFERENCE(*file, properties[*file]);
+ ADD_FILE_REFERENCE(*file, *file, properties[*file]);
}
// Add custom files depending on the target
@@ -503,12 +666,41 @@ void XCodeProvider::setupResourcesBuildPhase() {
}
}
-void XCodeProvider::setupSourcesBuildPhase() {
- // TODO
+void XcodeProvider::setupSourcesBuildPhase() {
+ _sourcesBuildPhase.comment = "PBXSourcesBuildPhase";
+
+ // Setup source file properties
+ std::map<std::string, FileProperty> properties;
+
+ // Same as for containers: a rule for each native target
+ for (unsigned int i = 0; i < _targets.size(); i++) {
+ Object *source = new Object(this, "PBXSourcesBuildPhase_" + _targets[i], "PBXSourcesBuildPhase", "PBXSourcesBuildPhase", "", "Sources");
+
+ source->addProperty("buildActionMask", "2147483647", "", SettingsNoValue);
+
+ Property files;
+ files.hasOrder = true;
+ files.flags = SettingsAsList;
+
+ int order = 0;
+ for (std::vector<Object*>::iterator file = _buildFile.objects.begin(); file !=_buildFile.objects.end(); ++file) {
+ if (!producesObjectFileOnOSX((*file)->name)) {
+ continue;
+ }
+ std::string comment = (*file)->name + " in Sources";
+ ADD_SETTING_ORDER_NOVALUE(files, getHash((*file)->id), comment, order++);
+ }
+
+ source->properties["files"] = files;
+
+ source->addProperty("runOnlyForDeploymentPostprocessing", "0", "", SettingsNoValue);
+
+ _sourcesBuildPhase.add(source);
+ }
}
// Setup all build configurations
-void XCodeProvider::setupBuildConfiguration() {
+void XcodeProvider::setupBuildConfiguration() {
_buildConfiguration.comment = "XCBuildConfiguration";
_buildConfiguration.flags = SettingsAsList;
@@ -516,9 +708,9 @@ void XCodeProvider::setupBuildConfiguration() {
///****************************************
// * iPhone
// ****************************************/
-
+#ifdef ENABLE_IOS
// Debug
- Object *iPhone_Debug_Object = new Object(this, "XCBuildConfiguration_" PROJECT_DESCRIPTION "-iPhone_Debug", _targets[0] /* ScummVM-iPhone */, "XCBuildConfiguration", "PBXNativeTarget", "Debug");
+ Object *iPhone_Debug_Object = new Object(this, "XCBuildConfiguration_" PROJECT_DESCRIPTION "-iPhone_Debug", _targets[IOS_TARGET] /* ScummVM-iPhone */, "XCBuildConfiguration", "PBXNativeTarget", "Debug");
Property iPhone_Debug;
ADD_SETTING_QUOTE(iPhone_Debug, "ARCHS", "$(ARCHS_UNIVERSAL_IPHONE_OS)");
ADD_SETTING_QUOTE(iPhone_Debug, "CODE_SIGN_IDENTITY", "iPhone Developer");
@@ -539,10 +731,10 @@ void XCodeProvider::setupBuildConfiguration() {
ADD_SETTING(iPhone_Debug, "GCC_THUMB_SUPPORT", "NO");
ADD_SETTING(iPhone_Debug, "GCC_UNROLL_LOOPS", "YES");
ValueList iPhone_HeaderSearchPaths;
- iPhone_HeaderSearchPaths.push_back("../../engines/");
- iPhone_HeaderSearchPaths.push_back("../../");
+ iPhone_HeaderSearchPaths.push_back("$(SRCROOT)/engines/");
+ iPhone_HeaderSearchPaths.push_back("$(SRCROOT)");
iPhone_HeaderSearchPaths.push_back("include/");
- ADD_SETTING_LIST(iPhone_Debug, "HEADER_SEARCH_PATHS", iPhone_HeaderSearchPaths, SettingsAsList|SettingsNoQuote, 5);
+ ADD_SETTING_LIST(iPhone_Debug, "HEADER_SEARCH_PATHS", iPhone_HeaderSearchPaths, SettingsAsList|SettingsQuoteVariable, 5);
ADD_SETTING(iPhone_Debug, "INFOPLIST_FILE", "Info.plist");
ValueList iPhone_LibPaths;
iPhone_LibPaths.push_back("$(inherited)");
@@ -560,7 +752,7 @@ void XCodeProvider::setupBuildConfiguration() {
iPhone_Debug_Object->properties["buildSettings"] = iPhone_Debug;
// Release
- Object *iPhone_Release_Object = new Object(this, "XCBuildConfiguration_" PROJECT_DESCRIPTION "-iPhone_Release", _targets[0] /* ScummVM-iPhone */, "XCBuildConfiguration", "PBXNativeTarget", "Release");
+ Object *iPhone_Release_Object = new Object(this, "XCBuildConfiguration_" PROJECT_DESCRIPTION "-iPhone_Release", _targets[IOS_TARGET] /* ScummVM-iPhone */, "XCBuildConfiguration", "PBXNativeTarget", "Release");
Property iPhone_Release(iPhone_Debug);
ADD_SETTING(iPhone_Release, "GCC_OPTIMIZATION_LEVEL", "3");
ADD_SETTING(iPhone_Release, "COPY_PHASE_STRIP", "YES");
@@ -572,7 +764,7 @@ void XCodeProvider::setupBuildConfiguration() {
_buildConfiguration.add(iPhone_Debug_Object);
_buildConfiguration.add(iPhone_Release_Object);
-
+#endif
/****************************************
* scummvm
****************************************/
@@ -581,13 +773,14 @@ void XCodeProvider::setupBuildConfiguration() {
Object *scummvm_Debug_Object = new Object(this, "XCBuildConfiguration_" PROJECT_NAME "_Debug", PROJECT_NAME, "XCBuildConfiguration", "PBXProject", "Debug");
Property scummvm_Debug;
ADD_SETTING(scummvm_Debug, "ALWAYS_SEARCH_USER_PATHS", "NO");
+ ADD_SETTING_QUOTE(scummvm_Debug, "USER_HEADER_SEARCH_PATHS", "$(SRCROOT) $(SRCROOT)/engines");
ADD_SETTING_QUOTE(scummvm_Debug, "ARCHS", "$(ARCHS_STANDARD_32_BIT)");
ADD_SETTING_QUOTE(scummvm_Debug, "CODE_SIGN_IDENTITY", "Don't Code Sign");
ADD_SETTING_QUOTE_VAR(scummvm_Debug, "CODE_SIGN_IDENTITY[sdk=iphoneos*]", "Don't Code Sign");
ADD_SETTING_QUOTE(scummvm_Debug, "FRAMEWORK_SEARCH_PATHS", "");
ADD_SETTING(scummvm_Debug, "GCC_C_LANGUAGE_STANDARD", "c99");
ADD_SETTING(scummvm_Debug, "GCC_ENABLE_CPP_EXCEPTIONS", "NO");
- ADD_SETTING(scummvm_Debug, "GCC_ENABLE_CPP_RTTI", "NO");
+ ADD_SETTING(scummvm_Debug, "GCC_ENABLE_CPP_RTTI", "YES");
ADD_SETTING(scummvm_Debug, "GCC_INPUT_FILETYPE", "automatic");
ADD_SETTING(scummvm_Debug, "GCC_OPTIMIZATION_LEVEL", "0");
ValueList scummvm_defines(_defines);
@@ -601,15 +794,15 @@ void XCodeProvider::setupBuildConfiguration() {
ADD_SETTING(scummvm_Debug, "GCC_WARN_UNUSED_VARIABLE", "YES");
ValueList scummvm_HeaderPaths;
scummvm_HeaderPaths.push_back("include/");
- scummvm_HeaderPaths.push_back("../../engines/");
- scummvm_HeaderPaths.push_back("../../");
- ADD_SETTING_LIST(scummvm_Debug, "HEADER_SEARCH_PATHS", scummvm_HeaderPaths, SettingsNoQuote|SettingsAsList, 5);
+ scummvm_HeaderPaths.push_back("$(SRCROOT)/engines/");
+ scummvm_HeaderPaths.push_back("$(SRCROOT)");
+ ADD_SETTING_LIST(scummvm_Debug, "HEADER_SEARCH_PATHS", scummvm_HeaderPaths, SettingsQuoteVariable|SettingsAsList, 5);
ADD_SETTING_QUOTE(scummvm_Debug, "LIBRARY_SEARCH_PATHS", "");
ADD_SETTING(scummvm_Debug, "ONLY_ACTIVE_ARCH", "YES");
ADD_SETTING_QUOTE(scummvm_Debug, "OTHER_CFLAGS", "");
ADD_SETTING_QUOTE(scummvm_Debug, "OTHER_LDFLAGS", "-lz");
ADD_SETTING(scummvm_Debug, "PREBINDING", "NO");
- ADD_SETTING(scummvm_Debug, "SDKROOT", "macosx10.6");
+ ADD_SETTING(scummvm_Debug, "SDKROOT", "macosx");
scummvm_Debug_Object->addProperty("name", "Debug", "", SettingsNoValue);
scummvm_Debug_Object->properties["buildSettings"] = scummvm_Debug;
@@ -633,7 +826,7 @@ void XCodeProvider::setupBuildConfiguration() {
****************************************/
// Debug
- Object *scummvmOSX_Debug_Object = new Object(this, "XCBuildConfiguration_" PROJECT_DESCRIPTION "-OSX_Debug", _targets[1] /* ScummVM-OS X */, "XCBuildConfiguration", "PBXNativeTarget", "Debug");
+ Object *scummvmOSX_Debug_Object = new Object(this, "XCBuildConfiguration_" PROJECT_DESCRIPTION "-OSX_Debug", _targets[OSX_TARGET] /* ScummVM-OS X */, "XCBuildConfiguration", "PBXNativeTarget", "Debug");
Property scummvmOSX_Debug;
ADD_SETTING_QUOTE(scummvmOSX_Debug, "ARCHS", "$(NATIVE_ARCH)");
ADD_SETTING(scummvmOSX_Debug, "COMPRESS_PNG_FILES", "NO");
@@ -642,7 +835,7 @@ void XCodeProvider::setupBuildConfiguration() {
ADD_SETTING_QUOTE(scummvmOSX_Debug, "FRAMEWORK_SEARCH_PATHS", "");
ADD_SETTING(scummvmOSX_Debug, "GCC_C_LANGUAGE_STANDARD", "c99");
ADD_SETTING(scummvmOSX_Debug, "GCC_ENABLE_CPP_EXCEPTIONS", "NO");
- ADD_SETTING(scummvmOSX_Debug, "GCC_ENABLE_CPP_RTTI", "NO");
+ ADD_SETTING(scummvmOSX_Debug, "GCC_ENABLE_CPP_RTTI", "YES");
ADD_SETTING(scummvmOSX_Debug, "GCC_DYNAMIC_NO_PIC", "NO");
ADD_SETTING(scummvmOSX_Debug, "GCC_ENABLE_FIX_AND_CONTINUE", "NO");
ADD_SETTING(scummvmOSX_Debug, "GCC_OPTIMIZATION_LEVEL", "0");
@@ -656,11 +849,12 @@ void XCodeProvider::setupBuildConfiguration() {
ValueList scummvmOSX_HeaderPaths;
scummvmOSX_HeaderPaths.push_back("/opt/local/include/SDL");
scummvmOSX_HeaderPaths.push_back("/opt/local/include");
+ scummvmOSX_HeaderPaths.push_back("/opt/local/include/freetype2");
scummvmOSX_HeaderPaths.push_back("include/");
- scummvmOSX_HeaderPaths.push_back("../../engines/");
- scummvmOSX_HeaderPaths.push_back("../../");
- ADD_SETTING_LIST(scummvmOSX_Debug, "HEADER_SEARCH_PATHS", scummvmOSX_HeaderPaths, SettingsNoQuote|SettingsAsList, 5);
- ADD_SETTING_QUOTE(scummvmOSX_Debug, "INFOPLIST_FILE", "$(SRCROOT)/../macosx/Info.plist");
+ scummvmOSX_HeaderPaths.push_back("$(SRCROOT)/engines/");
+ scummvmOSX_HeaderPaths.push_back("$(SRCROOT)");
+ ADD_SETTING_LIST(scummvmOSX_Debug, "HEADER_SEARCH_PATHS", scummvmOSX_HeaderPaths, SettingsQuoteVariable|SettingsAsList, 5);
+ ADD_SETTING_QUOTE(scummvmOSX_Debug, "INFOPLIST_FILE", "$(SRCROOT)/dists/macosx/Info.plist");
ValueList scummvmOSX_LibPaths;
scummvmOSX_LibPaths.push_back("/sw/lib");
scummvmOSX_LibPaths.push_back("/opt/local/lib");
@@ -671,6 +865,10 @@ void XCodeProvider::setupBuildConfiguration() {
ValueList scummvmOSX_LdFlags;
scummvmOSX_LdFlags.push_back("-lSDLmain");
scummvmOSX_LdFlags.push_back("-logg");
+ scummvmOSX_LdFlags.push_back("-lpng");
+ scummvmOSX_LdFlags.push_back("-ljpeg");
+ scummvmOSX_LdFlags.push_back("-ltheora");
+ scummvmOSX_LdFlags.push_back("-lfreetype");
scummvmOSX_LdFlags.push_back("-lvorbisfile");
scummvmOSX_LdFlags.push_back("-lvorbis");
scummvmOSX_LdFlags.push_back("-lmad");
@@ -685,7 +883,7 @@ void XCodeProvider::setupBuildConfiguration() {
scummvmOSX_Debug_Object->properties["buildSettings"] = scummvmOSX_Debug;
// Release
- Object *scummvmOSX_Release_Object = new Object(this, "XCBuildConfiguration_" PROJECT_DESCRIPTION "-OSX_Release", _targets[1] /* ScummVM-OS X */, "XCBuildConfiguration", "PBXNativeTarget", "Release");
+ Object *scummvmOSX_Release_Object = new Object(this, "XCBuildConfiguration_" PROJECT_DESCRIPTION "-OSX_Release", _targets[OSX_TARGET] /* ScummVM-OS X */, "XCBuildConfiguration", "PBXNativeTarget", "Release");
Property scummvmOSX_Release(scummvmOSX_Debug);
ADD_SETTING(scummvmOSX_Release, "COPY_PHASE_STRIP", "YES");
REMOVE_SETTING(scummvmOSX_Release, "GCC_DYNAMIC_NO_PIC");
@@ -697,13 +895,13 @@ void XCodeProvider::setupBuildConfiguration() {
_buildConfiguration.add(scummvmOSX_Debug_Object);
_buildConfiguration.add(scummvmOSX_Release_Object);
-
+#ifdef ENABLE_IOS
/****************************************
* ScummVM-Simulator
****************************************/
// Debug
- Object *scummvmSimulator_Debug_Object = new Object(this, "XCBuildConfiguration_" PROJECT_DESCRIPTION "-Simulator_Debug", _targets[2] /* ScummVM-Simulator */, "XCBuildConfiguration", "PBXNativeTarget", "Debug");
+ Object *scummvmSimulator_Debug_Object = new Object(this, "XCBuildConfiguration_" PROJECT_DESCRIPTION "-Simulator_Debug", _targets[SIM_TARGET] /* ScummVM-Simulator */, "XCBuildConfiguration", "PBXNativeTarget", "Debug");
Property scummvmSimulator_Debug(iPhone_Debug);
ADD_SETTING_QUOTE(scummvmSimulator_Debug, "FRAMEWORK_SEARCH_PATHS", "$(inherited)");
ADD_SETTING_LIST(scummvmSimulator_Debug, "GCC_PREPROCESSOR_DEFINITIONS", scummvm_defines, SettingsNoQuote|SettingsAsList, 5);
@@ -715,7 +913,7 @@ void XCodeProvider::setupBuildConfiguration() {
scummvmSimulator_Debug_Object->properties["buildSettings"] = scummvmSimulator_Debug;
// Release
- Object *scummvmSimulator_Release_Object = new Object(this, "XCBuildConfiguration_" PROJECT_DESCRIPTION "-Simulator_Release", _targets[2] /* ScummVM-Simulator */, "XCBuildConfiguration", "PBXNativeTarget", "Release");
+ Object *scummvmSimulator_Release_Object = new Object(this, "XCBuildConfiguration_" PROJECT_DESCRIPTION "-Simulator_Release", _targets[SIM_TARGET] /* ScummVM-Simulator */, "XCBuildConfiguration", "PBXNativeTarget", "Release");
Property scummvmSimulator_Release(scummvmSimulator_Debug);
ADD_SETTING(scummvmSimulator_Release, "COPY_PHASE_STRIP", "YES");
ADD_SETTING(scummvmSimulator_Release, "GCC_OPTIMIZATION_LEVEL", "3");
@@ -732,7 +930,7 @@ void XCodeProvider::setupBuildConfiguration() {
// Configuration List
_configurationList.comment = "XCConfigurationList";
_configurationList.flags = SettingsAsList;
-
+#endif
// Warning: This assumes we have all configurations with a Debug & Release pair
for (std::vector<Object *>::iterator config = _buildConfiguration.objects.begin(); config != _buildConfiguration.objects.end(); config++) {
@@ -758,7 +956,7 @@ void XCodeProvider::setupBuildConfiguration() {
//////////////////////////////////////////////////////////////////////////
// Setup global defines
-void XCodeProvider::setupDefines(const BuildSetup &setup) {
+void XcodeProvider::setupDefines(const BuildSetup &setup) {
for (StringList::const_iterator i = setup.defines.begin(); i != setup.defines.end(); ++i) {
if (*i == "HAVE_NASM") // Not supported on Mac (TODO: change how it's handled in main class or add it only in MSVC/CodeBlocks providers?)
@@ -772,7 +970,6 @@ void XCodeProvider::setupDefines(const BuildSetup &setup) {
ADD_DEFINE(_defines, "SCUMM_LITTLE_ENDIAN");
ADD_DEFINE(_defines, "UNIX");
ADD_DEFINE(_defines, "SCUMMVM");
- ADD_DEFINE(_defines, "USE_TREMOR");
}
//////////////////////////////////////////////////////////////////////////
@@ -780,7 +977,7 @@ void XCodeProvider::setupDefines(const BuildSetup &setup) {
//////////////////////////////////////////////////////////////////////////
// TODO use md5 to compute a file hash (and fall back to standard key generation if not passed a file)
-std::string XCodeProvider::getHash(std::string key) {
+std::string XcodeProvider::getHash(std::string key) {
#if DEBUG_XCODE_HASH
return key;
@@ -800,7 +997,7 @@ std::string XCodeProvider::getHash(std::string key) {
bool isSeparator (char s) { return (s == '-'); }
-std::string XCodeProvider::newHash() const {
+std::string XcodeProvider::newHash() const {
std::string hash = createUUID();
// Remove { and - from UUID and resize to 96-bits uppercase hex string
@@ -832,7 +1029,7 @@ std::string replace(std::string input, const std::string find, std::string repla
return input;
}
-std::string XCodeProvider::writeProperty(const std::string &variable, Property &prop, int flags) const {
+std::string XcodeProvider::writeProperty(const std::string &variable, Property &prop, int flags) const {
std::string output;
output += (flags & SettingsSingleItem ? "" : "\t\t\t") + variable + " = ";
@@ -847,7 +1044,9 @@ std::string XCodeProvider::writeProperty(const std::string &variable, Property &
output += writeSetting((*setting).first, (*setting).second);
- if ((prop.flags & SettingsAsList) && prop.settings.size() > 1) {
+ // The combination of SettingsAsList, and SettingsSingleItem should use "," and not ";" (i.e children
+ // in PBXGroup, so we special case that case here.
+ if ((prop.flags & SettingsAsList) && (prop.settings.size() > 1 || (prop.flags & SettingsSingleItem))) {
output += (prop.settings.size() > 0) ? ",\n" : "\n";
} else {
output += ";";
@@ -861,13 +1060,13 @@ std::string XCodeProvider::writeProperty(const std::string &variable, Property &
return output;
}
-std::string XCodeProvider::writeSetting(const std::string &variable, std::string value, std::string comment, int flags, int indent) const {
+std::string XcodeProvider::writeSetting(const std::string &variable, std::string value, std::string comment, int flags, int indent) const {
return writeSetting(variable, Setting(value, comment, flags, indent));
}
// Heavily modified (not in a good way) function, imported from the QMake
// XCode project generator pbuilder_pbx.cpp, writeSettings() (under LGPL 2.1)
-std::string XCodeProvider::writeSetting(const std::string &variable, const Setting &setting) const {
+std::string XcodeProvider::writeSetting(const std::string &variable, const Setting &setting) const {
std::string output;
const std::string quote = (setting.flags & SettingsNoQuote) ? "" : "\"";
const std::string escape_quote = quote.empty() ? "" : "\\" + quote;
diff --git a/devtools/create_project/xcode.h b/devtools/create_project/xcode.h
index f86e7c555c..2686d14986 100644
--- a/devtools/create_project/xcode.h
+++ b/devtools/create_project/xcode.h
@@ -30,9 +30,9 @@
namespace CreateProjectTool {
-class XCodeProvider : public ProjectProvider {
+class XcodeProvider : public ProjectProvider {
public:
- XCodeProvider(StringList &global_warnings, std::map<std::string, StringList> &project_warnings, const int version = 0);
+ XcodeProvider(StringList &global_warnings, std::map<std::string, StringList> &project_warnings, const int version = 0);
protected:
@@ -45,7 +45,6 @@ protected:
void writeFileListToProject(const FileNode &dir, std::ofstream &projectFile, const int indentation,
const StringList &duplicate, const std::string &objPrefix, const std::string &filePrefix);
-
private:
enum {
SettingsAsList = 0x01,
@@ -169,7 +168,7 @@ private:
PropertyList properties; // List of object properties, including output configuration
// Constructs an object and add a default type property
- Object(XCodeProvider *objectParent, std::string objectId, std::string objectName, std::string objectType, std::string objectRefType = "", std::string objectComment = "")
+ Object(XcodeProvider *objectParent, std::string objectId, std::string objectName, std::string objectType, std::string objectRefType = "", std::string objectComment = "")
: id(objectId), name(objectName), refType(objectRefType), comment(objectComment), parent(objectParent) {
assert(objectParent);
assert(!objectId.empty());
@@ -210,9 +209,10 @@ private:
return output;
}
+ // Slight hack, to allow Group access to parent.
+ protected:
+ XcodeProvider *parent;
private:
- XCodeProvider *parent;
-
// Returns the type property (should always be the first in the properties map)
std::string getType() {
assert(!properties.empty());
@@ -258,6 +258,36 @@ private:
}
};
+ // A class to maintain a folder-reference group-hierarchy, which together with the functionality below
+ // allows for breaking up sub-paths into a chain of groups. This helps with merging engines into the
+ // overall group-layout.
+ class Group : public Object {
+ int _childOrder;
+ std::map<std::string, Group *> _childGroups;
+ std::string _treeName;
+ void addChildInternal(const std::string &id, const std::string &comment);
+ public:
+ Group(XcodeProvider *objectParent, const std::string &groupName, const std::string &uniqueName, const std::string &path);
+ void addChildFile(const std::string &name);
+ void addChildByHash(const std::string &hash, const std::string &name);
+ // Should be passed the hash for the entry
+ void addChildGroup(const Group* group);
+ void ensureChildExists(const std::string &name);
+ Group *getChildGroup(const std::string &name);
+ std::string getHashRef() const { return parent->getHash(id); }
+ };
+
+ // The path used by the root-source group
+ std::string _projectRoot;
+ // The base source group, currently also re-purposed for containing the various support-groups.
+ Group *_rootSourceGroup;
+ // Helper function to create the chain of groups for the various subfolders. Necessary as
+ // create_project likes to start in engines/
+ Group *touchGroupsForPath(const std::string &path);
+ // Functionality for adding file-refs and build-files, as Group-objects need to be able to do this.
+ void addFileReference(const std::string &id, const std::string &name, FileProperty properties);
+ void addProductFileReference(const std::string &id, const std::string &name);
+ void addBuildFile(const std::string &id, const std::string &name, const std::string &fileRefId, const std::string &comment);
// All objects
std::map<std::string, std::string> _hashDictionnary;
ValueList _defines;
diff --git a/devtools/credits.pl b/devtools/credits.pl
index 1c2ece80ed..41c2d4f162 100755
--- a/devtools/credits.pl
+++ b/devtools/credits.pl
@@ -789,8 +789,10 @@ begin_credits("Credits");
add_person("Tobia Tesan", "t0by", "");
end_section();
- begin_section("ZVision");
+ begin_section("Z-Vision");
add_person("Adrian Astley", "RichieSams", "");
+ add_person("Filippos Karapetis", "[md5]", "");
+ add_person("Anton Yarcev", "Zidane", "");
end_section();
end_section();
@@ -1051,7 +1053,7 @@ begin_credits("Credits");
end_section();
begin_section("German");
add_person("Simon Sawatzki", "SimSaw", "");
- add_person("Lothar Serra Mari", "Lothar93", "(retired)");
+ add_person("Lothar Serra Mari", "rootfather", "");
end_section();
begin_section("Hungarian");
add_person("Alex Bevilacqua", "", "");
@@ -1092,6 +1094,12 @@ begin_credits("Credits");
add_person("V&iacute;ctor Gonz&aacute;lez", "IlDucci", "Soltys Spanish translation");
add_person("Alejandro G&oacute;mez de la Mu&ntilde;oza", "TheFireRed", "Soltys Spanish translation");
end_section();
+ begin_section("CGE2");
+ add_person("Arnaud Boutonn&eacute;", "Strangerke", "Sfinx English translation");
+ add_person("Thierry Crozat", "criezy", "Sfinx English translation");
+ add_person("Peter Bozs&oacute;", "uruk", "Sfinx English translation editor");
+ add_person("Ryan Clark", "", "Sfinx English translation editor");
+ end_section();
begin_section("Drascula");
add_person("Thierry Crozat", "criezy", "Improve French translation");
end_section();
@@ -1125,6 +1133,7 @@ begin_credits("Credits");
add_person("Jeroen Janssen", "japj", "Numerous readability and bugfix patches");
add_person("Keith Kaisershot", "blitter", "Several Pegasus Prime patches");
add_person("Andreas Karlsson", "Sprawl", "Initial port for SymbianOS");
+ add_person("Stefan Kristiansson", "skristiansson", "Initial work on SDL2 support");
add_person("Claudio Matsuoka", "", "Daily Linux builds");
add_person("Thomas Mayer", "", "PSP port contributions");
add_person("Sean Murray", "lightcast", "ScummVM tools GUI application (GSoC 2007 task)");
@@ -1215,7 +1224,7 @@ begin_credits("Credits");
add_person("Jimmi Th&oslash;gersen", "", "For ScummRev, and much obscure code/documentation");
add_person("", "Tristan", "For additional work on the original MT-32 emulator");
add_person("James Woodcock", "", "Soundtrack enhancements");
- add_person("Anton Yartsev", "Zidane", "For the original re-implementation of the ZVision engine");
+ add_person("Anton Yartsev", "Zidane", "For the original re-implementation of the Z-Vision engine");
end_persons();
add_paragraph(
diff --git a/devtools/scumm-md5.txt b/devtools/scumm-md5.txt
index 62925e98fa..ffde276a3d 100644
--- a/devtools/scumm-md5.txt
+++ b/devtools/scumm-md5.txt
@@ -127,6 +127,7 @@ indy3 Indiana Jones and the Last Crusade
66236cd1aec24e1d4aff4c4cc93b7e18 -1 fr DOS EGA EGA ?? v1.3, 25 Aug 89 Andrea Petrucci, Peter Eckerlein
89cfc425566003ff74b7dc7b3e6fd469 -1 fr DOS EGA EGA ?? v1.3, 25 Aug 89 Jorpho
69d70269fafc4445adbb0d223e4f9a3f 5361 en DOS EGA EGA v1.4, 11/07/89 (5.25\") Petr Maruska
+ 56e8c37a0a08c3a7076f82417461a877 -1 en DOS EGA EGA v1.4, 7 Nov 89 (3.5\") Paulo Vicente
6f6ef668c608c7f534fea6e6d3878dde -1 de DOS EGA EGA v1.4 from 19 Oct 89 dhewg, Peter Eckerlein
eb700bb73ca1cc44a1ad5e4b1a4bdeaf 5361 de DOS EGA EGA PC-Spiele a.borque
d62d248c3df6ec177405e2cb23d923b2 -1 it DOS EGA EGA v1.4 from 25 Nov 89 Andrea Petrucci, Peter Eckerlein
@@ -293,12 +294,14 @@ atlantis Indiana Jones and the Fate of Atlantis
035deab53b47bc43abc763560d0f8d4b -1 en DOS Floppy Demo -
98744fe66ff730e8c2b3b1f58803ab0b -1 en DOS Floppy Demo - Simon Krumrein, sev
+ 12cdc256eae5a461bcc9a49975999841 -1 en DOS Floppy Demo - Paulo Vicente
99b6f822b0b2612415407865438697d6 -1 en DOS - Demo non-interactive
28d24a33448fab6795850bc9f159a4a2 11170 jp FM-TOWNS FM-TOWNS Demo non-interactive khalek, Fingolfin
tentacle Day of the Tentacle
acad97ab1c6fc2a5b2d98abf6db4a190 -1 en All? Floppy Floppy Version A ?
2723fea3dae0cb47768c424b145ae0e7 7932 en DOS Floppy Floppy Version B ? Andrej Sinicyn, Andrea Petrucci, Fingolfin
+ f0ccc12a8704bf57706b42a37f877128 -1 en DOS Floppy Floppy 1.6 Paulo Vicente
92b078d9d6d9d751da9c26b8b3075779 -1 fr DOS Floppy Floppy - Nicolas Sauz&egrave;de, Andrea Petrucci
94aaedbb8f26d71ed3ad6dd34490e29e -1 fr DOS Floppy Floppy alt? Nicolas Joly
57b0d89af79befe1cabce3bece869e7f -1 de DOS Floppy Floppy - Andrej Sinicyn, Andrea Petrucci
@@ -311,7 +314,7 @@ tentacle Day of the Tentacle
4fbbe9f64b8bc547503a379a301183ce -1 it All? - CD - Andrea Petrucci
883af4b0af4f77a92f1dcf1d0a283140 -1 es All? - CD - Andrea Petrucci
cc04a076779379524ed4d9c5ee3c6fb1 282467632 en Mac - CD Mac bundle Fingolfin, Joachim Eberhard
- ede149fda3edfc1dbd7347e0737cb583 -1 fr Mac - CD Mac bundle ThierryFR
+ ede149fda3edfc1dbd7347e0737cb583 282830409 fr Mac - CD Mac bundle ThierryFR, Thierry Crozat
f73883f13b5a302749a5bad31d909780 -1 de Mac - CD Mac bundle morrissey
c83079157ec765a28de445aec9768d60 7477 en All - Demo - Fingolfin
@@ -334,7 +337,7 @@ samnmax Sam &amp; Max Hit the Road
4ba7fb331296c283e73d8f5b2096e551 -1 es All? - CD - Andrea Petrucci
d43352a805d78b5f4936c6d7779bf575 -1 ru DOS - CD -
166553538ff320c69edafeee29525419 199195304 en Mac - CD Mac bundle Joachim Eberhard
- 3a5d13675e9a23aedac0bac7730f0ac1 -1 fr Mac - CD Mac bundle ThierryFR
+ 3a5d13675e9a23aedac0bac7730f0ac1 228446581 fr Mac - CD Mac bundle ThierryFR, Thierry Crozat
c3196c5349e53e387aaff1533d95e53a -1 en DOS Floppy Demo -
0e4c5d54a0ad4b26132e78b5ea76642a 6485 en DOS Floppy Demo WIP Fingolfin
@@ -355,6 +358,7 @@ ft Full Throttle
e72bb4c2b613db2cf50f89ff6350e70a -1 es All? - - -
fe381e45117878b1e942cb876b050fd6 513243679 en Mac - - Mac bundle Fingolfin
04401d747f1a2c1c4b388daff71ed378 535405461 de Mac - - Mac bundle Fingolfin
+ 403d2ec4d60d3cdae925e6cbf67716d6 489436643 fr Mac - - Mac bundle Thierry Crozat
32a433dea56b86a55b59e4ff7d755711 -1 en DOS Demo Demo -
9d7b67be003fea60be4dcbd193611936 11164 en Mac Demo Demo - Fingolfin
@@ -623,12 +627,12 @@ airport Let's Explore the Airport with Buzzy
86c9902b7bec1a17926d4dae85beaa45 -1 en Windows HE 71 Demo - khalek
farm Let's Explore the Farm with Buzzy
- fbbbb38a81fc9d6a61d509278390a290 -1 en Mac - - - khalek
a5c5388da9bf0e6662fdca8813a79d13 86962 en Windows - - - George Kormendi
- a85856675429fe88051744f755b72f93 -1 en Windows - - - Kirben
- a2386da005672cbd5136f4f27a626c5f 87061 nl Windows - - - George Kormendi
- eeb606c2d2ec877a712a9f20c10bcdda 87034 nl Mac - - - Ben Castricum
- 5dda73606533d66a4c3f4f9ea6e842af 87061 ru Windows - - - sev
+ fbbbb38a81fc9d6a61d509278390a290 -1 en Mac HE 73 - - khalek
+ a85856675429fe88051744f755b72f93 -1 en Windows HE 73 - - Kirben
+ a2386da005672cbd5136f4f27a626c5f 87061 nl Windows HE 73 - - George Kormendi
+ eeb606c2d2ec877a712a9f20c10bcdda 87034 nl Mac HE 73 - - Ben Castricum
+ 5dda73606533d66a4c3f4f9ea6e842af 87061 ru Windows HE 73 - - sev
39fd6db10d0222d817025c4d3346e3b4 -1 en Mac - Demo - Joachim Eberhard
6c375c2236d99f56e6c2cf540e74e474 34333 nl Windows - Demo - Kirben
@@ -666,6 +670,7 @@ pajama2 Pajama Sam 2: Thunder and Lightning Aren't so Frightening
d4e79c3d8645b8266cd78c325bc35154 60557 us All - - - Kirben
6a60d395b78b205c93a956100b1bf5ae -1 de All HE 98.5 - - EdDammer
513f91a9dbe8d5490b39e56a3ac5bbdf -1 nl All HE 98.5 - - daniel9
+ 2328be0317008ef047eed7912a4b0850 -1 gb Windows HE 98.5 - - Saleck
55f4e9402bec2bded383843123f37c5c -1 de Windows HE 98.5 - - WindlePoons
e5563c8358443c4352fcddf7402a5e0a -1 fr Windows HE 98.5 - - gist974
c6907d44f1166941d982864cd42cdc89 -1 de All HE 99 - - nachbarnebenan
@@ -682,6 +687,7 @@ pajama2 Pajama Sam 2: Thunder and Lightning Aren't so Frightening
pajama3 Pajama Sam 3: You Are What You Eat From Your Head to Your Feet
f7711f9264d4d43c2a1518ec7c10a607 79382 us All - - - Kirben
2e8a1f76ea33bc5e04347646feee173d -1 de All - - - Joachim Eberhard
+ 83e7a9205567dceb456ee35eeaf26ffa -1 it All - - - Saleck
aefa244ea034b7cd2041f0a44be7d9ba -1 en Mac - - - pix_climber
06c3cf4f31daad8b1cd93153491db9e6 79382 nl All - - - daniel9
7410a8ba9795020cd42f171c4320659e -1 fr Windows - - - gist974
@@ -724,6 +730,7 @@ socks Pajama Sam's Sock Works
puttrace Putt-Putt Enters the Race
981e1e1891f2be7e25a01f50ae55a5af -1 us All HE 98 - - Kirben
+ 05d3143827ab4f5d2521a1a47dab8ff2 -1 it All HE 98 - - Saleck
1ed22f601f8b3695804a6583cc3083f1 -1 nl All HE 98.5 - - daniel9
33e989f85da700e2014d00f345cab3d7 -1 fr Windows HE 98.5 - - gist974
b47be81e39a9710f6f595f7b527b60f8 -1 gb Windows HE 99 - - Reckless
@@ -887,6 +894,7 @@ spyfox2 SPY Fox 2: Some Assembly Required
f79e60c17cca601e411f1f75e8ee9b5a 51286 All All - - - Kirben
90e2f0af4f779629695c6394a65bb702 -1 fr All - - - gist974, ThierryFR
bc4700bc0e12879f6d25d14d6be6cfdd -1 de All - - - Joachim Eberhard
+ 3785fd25f7e02b5782bfc5072d8f77c8 -1 it All - - - Saleck
cea91e3dd47f2518ea418e41611aa77f -1 ru All - - - sev
9fd66fb3b04703bd50da4356e4202558 51295 en Mac - - - pix_climber
71fe97c3108678cf604f14abe342341b 51286 nl All - - - adutchguy
diff --git a/dists/android/AndroidManifest.xml b/dists/android/AndroidManifest.xml
index db8a9adc54..ba1046e85c 100644
--- a/dists/android/AndroidManifest.xml
+++ b/dists/android/AndroidManifest.xml
@@ -5,7 +5,6 @@
package="org.scummvm.scummvm"
android:versionCode="@ANDROID_VERSIONCODE@"
android:versionName="1.8.0git"
- android:installLocation="preferExternal"
android:sharedUserId="org.scummvm.scummvm">
<!-- This version works on Android 1.5 (SDK 3) and newer, but we
@@ -13,7 +12,7 @@
<uses-sdk android:minSdkVersion="3"
android:targetSdkVersion="8"/>
- <application android:name=".ScummVMApplication"
+ <application
android:label="@string/app_name"
android:description="@string/app_desc"
android:icon="@drawable/scummvm">
@@ -24,28 +23,12 @@
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
- </intent-filter>
- </activity>
-
- <activity android:name=".Unpacker"
- android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
- android:screenOrientation="landscape"
- android:configChanges="orientation|keyboardHidden">
- <meta-data android:name="org.scummvm.unpacker.nextActivity"
- android:value="org.scummvm.scummvm/.ScummVMActivity"/>
- <intent-filter>
- <action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<category android:name="tv.ouya.intent.category.GAME"/>
</intent-filter>
</activity>
</application>
- <permission android:name="org.scummvm.scummvm.permission.SCUMMVM_PLUGIN"
- android:label="@string/scummvm_perm_plugin_label"
- android:description="@string/scummvm_perm_plugin_desc"
- android:protectionLevel="signature"/>
-
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- Always needs some sort of qwerty keyboard.
diff --git a/dists/android/AndroidManifest.xml.in b/dists/android/AndroidManifest.xml.in
index bf45ffcc0e..d90e282e3d 100644
--- a/dists/android/AndroidManifest.xml.in
+++ b/dists/android/AndroidManifest.xml.in
@@ -5,7 +5,6 @@
package="org.scummvm.scummvm"
android:versionCode="@ANDROID_VERSIONCODE@"
android:versionName="@VERSION@"
- android:installLocation="preferExternal"
android:sharedUserId="org.scummvm.scummvm">
<!-- This version works on Android 1.5 (SDK 3) and newer, but we
@@ -13,7 +12,7 @@
<uses-sdk android:minSdkVersion="3"
android:targetSdkVersion="8"/>
- <application android:name=".ScummVMApplication"
+ <application
android:label="@string/app_name"
android:description="@string/app_desc"
android:icon="@drawable/scummvm">
@@ -24,28 +23,12 @@
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
- </intent-filter>
- </activity>
-
- <activity android:name=".Unpacker"
- android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
- android:screenOrientation="landscape"
- android:configChanges="orientation|keyboardHidden">
- <meta-data android:name="org.scummvm.unpacker.nextActivity"
- android:value="org.scummvm.scummvm/.ScummVMActivity"/>
- <intent-filter>
- <action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<category android:name="tv.ouya.intent.category.GAME"/>
</intent-filter>
</activity>
</application>
- <permission android:name="org.scummvm.scummvm.permission.SCUMMVM_PLUGIN"
- android:label="@string/scummvm_perm_plugin_label"
- android:description="@string/scummvm_perm_plugin_desc"
- android:protectionLevel="signature"/>
-
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- Always needs some sort of qwerty keyboard.
diff --git a/dists/android/custom_rules.xml b/dists/android/custom_rules.xml
new file mode 100644
index 0000000000..5ed81b7273
--- /dev/null
+++ b/dists/android/custom_rules.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="custom_rules">
+ <!-- Override the built-in aapt task, don't compress assets. -->
+ <target name="-package-resources" depends="-crunch">
+ <!-- only package resources if *not* a library project -->
+ <do-only-if-not-library elseText="Library project: do not package resources..." >
+ <aapt executable="${aapt}"
+ command="package"
+ versioncode="${version.code}"
+ versionname="${version.name}"
+ debug="${build.is.packaging.debug}"
+ manifest="${out.manifest.abs.file}"
+ assets="${asset.absolute.dir}"
+ androidjar="${project.target.android.jar}"
+ apkfolder="${out.absolute.dir}"
+ nocrunch="${build.packaging.nocrunch}"
+ resourcefilename="${resource.package.file.name}"
+ resourcefilter="${aapt.resource.filter}"
+ libraryResFolderPathRefid="project.library.res.folder.path"
+ libraryPackagesRefid="project.library.packages"
+ libraryRFileRefid="project.library.bin.r.file.path"
+ previousBuildType="${build.last.target}"
+ buildType="${build.target}"
+ ignoreAssets="${aapt.ignore.assets}">
+ <res path="${out.res.absolute.dir}" />
+ <res path="${resource.absolute.dir}" />
+ <nocompress /> <!-- forces no compression on any files in assets or res/raw -->
+ </aapt>
+ </do-only-if-not-library>
+ </target>
+</project>
diff --git a/dists/android/jni/Android.mk b/dists/android/jni/Android.mk
new file mode 100644
index 0000000000..0b3ee4d22e
--- /dev/null
+++ b/dists/android/jni/Android.mk
@@ -0,0 +1,9 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+APP_ABI := $(ABI)
+LOCAL_MODULE := scummvm
+LOCAL_SRC_FILES := ../libscummvm.so
+
+include $(PREBUILT_SHARED_LIBRARY)
diff --git a/dists/android/mkplugin.sh b/dists/android/mkplugin.sh
deleted file mode 100755
index 30a7ef66d6..0000000000
--- a/dists/android/mkplugin.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/sh
-
-if [ $# -ne 5 ]; then
- echo "usage: $0 configure plugin template versioncode target"
- exit 1
-fi
-
-CONFIGURE=$1
-PLUGIN_NAME=$2
-TEMPLATE=$3
-PLUGIN_VERSION_CODE=$4
-TARGET=$5
-
-PLUGIN_DESC=`sed -n "s/add_engine\s$PLUGIN_NAME\s\"\(.\+\)\"\s.*/\1/p" < $CONFIGURE`
-
-sed "s|@PLUGIN_NAME@|$PLUGIN_NAME|;s|@PLUGIN_VERSION_CODE@|$PLUGIN_VERSION_CODE|;s|@PLUGIN_DESC@|$PLUGIN_DESC|" < $TEMPLATE > $TARGET
diff --git a/dists/android/plugin-manifest.xml b/dists/android/plugin-manifest.xml
deleted file mode 100644
index 040d1ea57c..0000000000
--- a/dists/android/plugin-manifest.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="org.scummvm.scummvm.plugin.@PLUGIN_NAME@"
- android:versionCode="@PLUGIN_VERSION_CODE@"
- android:versionName="1.8.0git"
- android:installLocation="preferExternal"
- android:sharedUserId="org.scummvm.scummvm">
-
- <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="8" />
-
- <application android:label="@string/app_name"
- android:description="@string/app_desc"
- android:icon="@drawable/scummvm">
- <receiver android:name="org.scummvm.scummvm.PluginProvider"
- android:process="org.scummvm.scummvm">
- <intent-filter>
- <action android:name="org.scummvm.scummvm.action.PLUGIN_QUERY"/>
- <category android:name="android.intent.category.INFO"/>
- </intent-filter>
- <meta-data android:name="org.scummvm.scummvm.meta.UNPACK_LIB"
- android:value="mylib/armeabi/lib@PLUGIN_NAME@.so" />
- </receiver>
- </application>
-
- <uses-permission android:name="org.scummvm.scummvm.permission.SCUMMVM_PLUGIN"/>
- <uses-configuration android:reqFiveWayNav="true"
- android:reqKeyboardType="qwerty"/>
-
- <uses-configuration android:reqTouchScreen="finger"
- android:reqKeyboardType="qwerty"/>
-
- <uses-configuration android:reqTouchScreen="stylus"
- android:reqKeyboardType="qwerty"/>
-</manifest>
diff --git a/dists/android/plugin-manifest.xml.in b/dists/android/plugin-manifest.xml.in
deleted file mode 100644
index 4b429097ae..0000000000
--- a/dists/android/plugin-manifest.xml.in
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="org.scummvm.scummvm.plugin.@PLUGIN_NAME@"
- android:versionCode="@PLUGIN_VERSION_CODE@"
- android:versionName="@VERSION@"
- android:installLocation="preferExternal"
- android:sharedUserId="org.scummvm.scummvm">
-
- <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="8" />
-
- <application android:label="@string/app_name"
- android:description="@string/app_desc"
- android:icon="@drawable/scummvm">
- <receiver android:name="org.scummvm.scummvm.PluginProvider"
- android:process="org.scummvm.scummvm">
- <intent-filter>
- <action android:name="org.scummvm.scummvm.action.PLUGIN_QUERY"/>
- <category android:name="android.intent.category.INFO"/>
- </intent-filter>
- <meta-data android:name="org.scummvm.scummvm.meta.UNPACK_LIB"
- android:value="mylib/armeabi/lib@PLUGIN_NAME@.so" />
- </receiver>
- </application>
-
- <uses-permission android:name="org.scummvm.scummvm.permission.SCUMMVM_PLUGIN"/>
- <uses-configuration android:reqFiveWayNav="true"
- android:reqKeyboardType="qwerty"/>
-
- <uses-configuration android:reqTouchScreen="finger"
- android:reqKeyboardType="qwerty"/>
-
- <uses-configuration android:reqTouchScreen="stylus"
- android:reqKeyboardType="qwerty"/>
-</manifest>
diff --git a/dists/android/plugin-strings.xml b/dists/android/plugin-strings.xml
deleted file mode 100644
index ade37e0aca..0000000000
--- a/dists/android/plugin-strings.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<resources>
- <string name="app_name">ScummVM plugin: "@PLUGIN_NAME@"</string>
- <string name="app_desc">Game engine for: @PLUGIN_DESC@</string>
-</resources>
diff --git a/dists/android/project.properties b/dists/android/project.properties
new file mode 100644
index 0000000000..730e911f2f
--- /dev/null
+++ b/dists/android/project.properties
@@ -0,0 +1,11 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system use,
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+
+# Project target.
+target=android-14
diff --git a/dists/android/res/drawable/gradient.xml b/dists/android/res/drawable/gradient.xml
deleted file mode 100644
index dbfd9b5b34..0000000000
--- a/dists/android/res/drawable/gradient.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<shape xmlns:android="http://schemas.android.com/apk/res/android">
- <gradient
- android:startColor="#e9bb8b"
- android:endColor="#d16e09"
- android:angle="315" />
-</shape>
diff --git a/dists/android/res/layout/main.xml b/dists/android/res/layout/main.xml
index 31aa345cc7..8b0d515d62 100644
--- a/dists/android/res/layout/main.xml
+++ b/dists/android/res/layout/main.xml
@@ -9,8 +9,4 @@
android:keepScreenOn="true"
android:focusable="true"
android:focusableInTouchMode="true"
- android:layout_marginTop="@dimen/verticalMargin"
- android:layout_marginLeft="@dimen/horizontalMargin"
- android:layout_marginBottom="@dimen/verticalMargin"
- android:layout_marginRight="@dimen/horizontalMargin"
/>
diff --git a/dists/android/res/layout/splash.xml b/dists/android/res/layout/splash.xml
deleted file mode 100644
index e9fd5f70e7..0000000000
--- a/dists/android/res/layout/splash.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:gravity="center"
- android:background="@drawable/gradient"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:adjustViewBounds="true"
- android:scaleType="fitCenter"
- android:src="@drawable/scummvm_big" />
- <ProgressBar android:id="@+id/progress"
- style="?android:attr/progressBarStyleHorizontal"
- android:layout_width="300dip"
- android:layout_height="wrap_content"
- android:padding="20dip"/>
-</LinearLayout>
diff --git a/dists/codeblocks/readme.txt b/dists/codeblocks/readme.txt
index b0456aee13..1be60262c6 100644
--- a/dists/codeblocks/readme.txt
+++ b/dists/codeblocks/readme.txt
@@ -1,5 +1,5 @@
The Code::Blocks project files can now be created automatically from the GCC
-files using the create_project tool inside the /tools/create_project folder.
+files using the create_project tool inside the /devtools/create_project folder.
To create the default project files, build create_project.exe, copy it inside
this folder and run the create_codeblocks.bat file for a default build. You can
diff --git a/dists/debian/copyright b/dists/debian/copyright
index 1317fc6cee..734ec77039 100644
--- a/dists/debian/copyright
+++ b/dists/debian/copyright
@@ -7,7 +7,7 @@ It was downloaded from <http://www.scummvm.org/>.
Upstream Authors: see `/usr/share/doc/scummvm/AUTHORS'.
-ScummVM is Copyright © 2002-2014 The ScummVM Team
+ScummVM is Copyright © 2002-2015 The ScummVM Team
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
diff --git a/dists/iphone/readme.txt b/dists/iphone/readme.txt
deleted file mode 100644
index b115ed335c..0000000000
--- a/dists/iphone/readme.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-The Xcode project files can now be created automatically from the GCC
-files using the create_project tool inside the /tools/create_project folder.
-
-To create the default project files, build create_project.exe, copy it inside
-this folder and run the create_xcode.bat file for a default build. You can
-run create_project.exe with no parameters to check the possible command-line
-options.
diff --git a/dists/iphone/scummvm.xcodeproj/project.pbxproj b/dists/iphone/scummvm.xcodeproj/project.pbxproj
deleted file mode 100644
index 8f6ba6429d..0000000000
--- a/dists/iphone/scummvm.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,12331 +0,0 @@
-// !$*UTF8*$!
-{
- archiveVersion = 1;
- classes = {
- };
- objectVersion = 45;
- objects = {
-
-/* Begin PBXBuildFile section */
- 8CB5A9C11253FD6900CB6BC7 /* m4_scene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CB5A9B71253FD6800CB6BC7 /* m4_scene.cpp */; };
- 8CB5A9C21253FD6900CB6BC7 /* mads_logic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CB5A9B91253FD6800CB6BC7 /* mads_logic.cpp */; };
- 8CB5A9C31253FD6900CB6BC7 /* mads_player.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CB5A9BB1253FD6800CB6BC7 /* mads_player.cpp */; };
- 8CB5A9C41253FD6900CB6BC7 /* mads_scene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CB5A9BD1253FD6800CB6BC7 /* mads_scene.cpp */; };
- 8CB5A9C51253FD6900CB6BC7 /* mads_views.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CB5A9BF1253FD6900CB6BC7 /* mads_views.cpp */; };
- 8CB5A9C61253FD6900CB6BC7 /* m4_scene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CB5A9B71253FD6800CB6BC7 /* m4_scene.cpp */; };
- 8CB5A9C71253FD6900CB6BC7 /* mads_logic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CB5A9B91253FD6800CB6BC7 /* mads_logic.cpp */; };
- 8CB5A9C81253FD6900CB6BC7 /* mads_player.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CB5A9BB1253FD6800CB6BC7 /* mads_player.cpp */; };
- 8CB5A9C91253FD6900CB6BC7 /* mads_scene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CB5A9BD1253FD6800CB6BC7 /* mads_scene.cpp */; };
- 8CB5A9CA1253FD6900CB6BC7 /* mads_views.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CB5A9BF1253FD6900CB6BC7 /* mads_views.cpp */; };
- 8CB5A9CB1253FD6900CB6BC7 /* m4_scene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CB5A9B71253FD6800CB6BC7 /* m4_scene.cpp */; };
- 8CB5A9CC1253FD6900CB6BC7 /* mads_logic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CB5A9B91253FD6800CB6BC7 /* mads_logic.cpp */; };
- 8CB5A9CD1253FD6900CB6BC7 /* mads_player.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CB5A9BB1253FD6800CB6BC7 /* mads_player.cpp */; };
- 8CB5A9CE1253FD6900CB6BC7 /* mads_scene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CB5A9BD1253FD6800CB6BC7 /* mads_scene.cpp */; };
- 8CB5A9CF1253FD6900CB6BC7 /* mads_views.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CB5A9BF1253FD6900CB6BC7 /* mads_views.cpp */; };
- 8CB5A9D91253FDF500CB6BC7 /* drascula.dat in Resources */ = {isa = PBXBuildFile; fileRef = 8CB5A9D51253FDF400CB6BC7 /* drascula.dat */; };
- 8CB5A9DA1253FDF500CB6BC7 /* hugo.dat in Resources */ = {isa = PBXBuildFile; fileRef = 8CB5A9D61253FDF500CB6BC7 /* hugo.dat */; };
- 8CB5A9DB1253FDF500CB6BC7 /* m4.dat in Resources */ = {isa = PBXBuildFile; fileRef = 8CB5A9D71253FDF500CB6BC7 /* m4.dat */; };
- 8CB5A9DC1253FDF500CB6BC7 /* teenagent.dat in Resources */ = {isa = PBXBuildFile; fileRef = 8CB5A9D81253FDF500CB6BC7 /* teenagent.dat */; };
- 8CB5A9DD1253FDF500CB6BC7 /* drascula.dat in Resources */ = {isa = PBXBuildFile; fileRef = 8CB5A9D51253FDF400CB6BC7 /* drascula.dat */; };
- 8CB5A9DE1253FDF500CB6BC7 /* hugo.dat in Resources */ = {isa = PBXBuildFile; fileRef = 8CB5A9D61253FDF500CB6BC7 /* hugo.dat */; };
- 8CB5A9DF1253FDF500CB6BC7 /* m4.dat in Resources */ = {isa = PBXBuildFile; fileRef = 8CB5A9D71253FDF500CB6BC7 /* m4.dat */; };
- 8CB5A9E01253FDF500CB6BC7 /* teenagent.dat in Resources */ = {isa = PBXBuildFile; fileRef = 8CB5A9D81253FDF500CB6BC7 /* teenagent.dat */; };
- 8CB5A9E11253FDF500CB6BC7 /* drascula.dat in Resources */ = {isa = PBXBuildFile; fileRef = 8CB5A9D51253FDF400CB6BC7 /* drascula.dat */; };
- 8CB5A9E21253FDF500CB6BC7 /* hugo.dat in Resources */ = {isa = PBXBuildFile; fileRef = 8CB5A9D61253FDF500CB6BC7 /* hugo.dat */; };
- 8CB5A9E31253FDF500CB6BC7 /* m4.dat in Resources */ = {isa = PBXBuildFile; fileRef = 8CB5A9D71253FDF500CB6BC7 /* m4.dat */; };
- 8CB5A9E41253FDF500CB6BC7 /* teenagent.dat in Resources */ = {isa = PBXBuildFile; fileRef = 8CB5A9D81253FDF500CB6BC7 /* teenagent.dat */; };
- 8CD1ED0B126202AB00FA198C /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECC6126202AA00FA198C /* detection.cpp */; };
- 8CD1ED0C126202AB00FA198C /* display.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECC7126202AA00FA198C /* display.cpp */; };
- 8CD1ED0E126202AB00FA198C /* file.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECCB126202AA00FA198C /* file.cpp */; };
- 8CD1ED0F126202AB00FA198C /* hugo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECCF126202AA00FA198C /* hugo.cpp */; };
- 8CD1ED10126202AB00FA198C /* intro.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECD1126202AA00FA198C /* intro.cpp */; };
- 8CD1ED11126202AB00FA198C /* inventory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECD3126202AA00FA198C /* inventory.cpp */; };
- 8CD1ED14126202AB00FA198C /* mouse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECD7126202AA00FA198C /* mouse.cpp */; };
- 8CD1ED15126202AB00FA198C /* parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECD9126202AA00FA198C /* parser.cpp */; };
- 8CD1ED16126202AB00FA198C /* route.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECDB126202AA00FA198C /* route.cpp */; };
- 8CD1ED17126202AB00FA198C /* schedule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECDD126202AA00FA198C /* schedule.cpp */; };
- 8CD1ED18126202AB00FA198C /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECDF126202AA00FA198C /* sound.cpp */; };
- 8CD1ED19126202AB00FA198C /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECE1126202AA00FA198C /* util.cpp */; };
- 8CD1ED1A126202AB00FA198C /* anim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECE4126202AA00FA198C /* anim.cpp */; };
- 8CD1ED1B126202AB00FA198C /* audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECE6126202AA00FA198C /* audio.cpp */; };
- 8CD1ED1C126202AB00FA198C /* character.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECE8126202AA00FA198C /* character.cpp */; };
- 8CD1ED1D126202AB00FA198C /* conversation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECEA126202AA00FA198C /* conversation.cpp */; };
- 8CD1ED1E126202AB00FA198C /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECEC126202AA00FA198C /* detection.cpp */; };
- 8CD1ED1F126202AB00FA198C /* drew.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECED126202AA00FA198C /* drew.cpp */; };
- 8CD1ED20126202AB00FA198C /* flux.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECEF126202AA00FA198C /* flux.cpp */; };
- 8CD1ED21126202AB00FA198C /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECF1126202AA00FA198C /* font.cpp */; };
- 8CD1ED22126202AB00FA198C /* hotspot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECF3126202AA00FA198C /* hotspot.cpp */; };
- 8CD1ED25126202AB00FA198C /* movie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECF7126202AA00FA198C /* movie.cpp */; };
- 8CD1ED26126202AB00FA198C /* path.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECF9126202AA00FA198C /* path.cpp */; };
- 8CD1ED27126202AB00FA198C /* picture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECFB126202AA00FA198C /* picture.cpp */; };
- 8CD1ED28126202AB00FA198C /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECFD126202AA00FA198C /* resource.cpp */; };
- 8CD1ED29126202AB00FA198C /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECFF126202AA00FA198C /* script.cpp */; };
- 8CD1ED2A126202AB00FA198C /* script_func.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ED01126202AA00FA198C /* script_func.cpp */; };
- 8CD1ED2B126202AB00FA198C /* state.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ED03126202AA00FA198C /* state.cpp */; };
- 8CD1ED2C126202AB00FA198C /* text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ED05126202AA00FA198C /* text.cpp */; };
- 8CD1ED2D126202AB00FA198C /* tools.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ED07126202AA00FA198C /* tools.cpp */; };
- 8CD1ED2E126202AB00FA198C /* toon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ED09126202AA00FA198C /* toon.cpp */; };
- 8CD1ED2F126202AB00FA198C /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECC6126202AA00FA198C /* detection.cpp */; };
- 8CD1ED30126202AB00FA198C /* display.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECC7126202AA00FA198C /* display.cpp */; };
- 8CD1ED32126202AB00FA198C /* file.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECCB126202AA00FA198C /* file.cpp */; };
- 8CD1ED33126202AB00FA198C /* hugo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECCF126202AA00FA198C /* hugo.cpp */; };
- 8CD1ED34126202AB00FA198C /* intro.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECD1126202AA00FA198C /* intro.cpp */; };
- 8CD1ED35126202AB00FA198C /* inventory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECD3126202AA00FA198C /* inventory.cpp */; };
- 8CD1ED38126202AB00FA198C /* mouse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECD7126202AA00FA198C /* mouse.cpp */; };
- 8CD1ED39126202AB00FA198C /* parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECD9126202AA00FA198C /* parser.cpp */; };
- 8CD1ED3A126202AB00FA198C /* route.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECDB126202AA00FA198C /* route.cpp */; };
- 8CD1ED3B126202AB00FA198C /* schedule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECDD126202AA00FA198C /* schedule.cpp */; };
- 8CD1ED3C126202AB00FA198C /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECDF126202AA00FA198C /* sound.cpp */; };
- 8CD1ED3D126202AB00FA198C /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECE1126202AA00FA198C /* util.cpp */; };
- 8CD1ED3E126202AB00FA198C /* anim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECE4126202AA00FA198C /* anim.cpp */; };
- 8CD1ED3F126202AB00FA198C /* audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECE6126202AA00FA198C /* audio.cpp */; };
- 8CD1ED40126202AB00FA198C /* character.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECE8126202AA00FA198C /* character.cpp */; };
- 8CD1ED41126202AB00FA198C /* conversation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECEA126202AA00FA198C /* conversation.cpp */; };
- 8CD1ED42126202AB00FA198C /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECEC126202AA00FA198C /* detection.cpp */; };
- 8CD1ED43126202AB00FA198C /* drew.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECED126202AA00FA198C /* drew.cpp */; };
- 8CD1ED44126202AB00FA198C /* flux.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECEF126202AA00FA198C /* flux.cpp */; };
- 8CD1ED45126202AB00FA198C /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECF1126202AA00FA198C /* font.cpp */; };
- 8CD1ED46126202AB00FA198C /* hotspot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECF3126202AA00FA198C /* hotspot.cpp */; };
- 8CD1ED49126202AB00FA198C /* movie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECF7126202AA00FA198C /* movie.cpp */; };
- 8CD1ED4A126202AB00FA198C /* path.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECF9126202AA00FA198C /* path.cpp */; };
- 8CD1ED4B126202AB00FA198C /* picture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECFB126202AA00FA198C /* picture.cpp */; };
- 8CD1ED4C126202AB00FA198C /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECFD126202AA00FA198C /* resource.cpp */; };
- 8CD1ED4D126202AB00FA198C /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECFF126202AA00FA198C /* script.cpp */; };
- 8CD1ED4E126202AB00FA198C /* script_func.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ED01126202AA00FA198C /* script_func.cpp */; };
- 8CD1ED4F126202AB00FA198C /* state.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ED03126202AA00FA198C /* state.cpp */; };
- 8CD1ED50126202AB00FA198C /* text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ED05126202AA00FA198C /* text.cpp */; };
- 8CD1ED51126202AB00FA198C /* tools.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ED07126202AA00FA198C /* tools.cpp */; };
- 8CD1ED52126202AB00FA198C /* toon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ED09126202AA00FA198C /* toon.cpp */; };
- 8CD1ED53126202AB00FA198C /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECC6126202AA00FA198C /* detection.cpp */; };
- 8CD1ED54126202AB00FA198C /* display.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECC7126202AA00FA198C /* display.cpp */; };
- 8CD1ED56126202AB00FA198C /* file.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECCB126202AA00FA198C /* file.cpp */; };
- 8CD1ED57126202AB00FA198C /* hugo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECCF126202AA00FA198C /* hugo.cpp */; };
- 8CD1ED58126202AB00FA198C /* intro.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECD1126202AA00FA198C /* intro.cpp */; };
- 8CD1ED59126202AB00FA198C /* inventory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECD3126202AA00FA198C /* inventory.cpp */; };
- 8CD1ED5C126202AB00FA198C /* mouse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECD7126202AA00FA198C /* mouse.cpp */; };
- 8CD1ED5D126202AB00FA198C /* parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECD9126202AA00FA198C /* parser.cpp */; };
- 8CD1ED5E126202AB00FA198C /* route.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECDB126202AA00FA198C /* route.cpp */; };
- 8CD1ED5F126202AB00FA198C /* schedule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECDD126202AA00FA198C /* schedule.cpp */; };
- 8CD1ED60126202AB00FA198C /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECDF126202AA00FA198C /* sound.cpp */; };
- 8CD1ED61126202AB00FA198C /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECE1126202AA00FA198C /* util.cpp */; };
- 8CD1ED62126202AB00FA198C /* anim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECE4126202AA00FA198C /* anim.cpp */; };
- 8CD1ED63126202AB00FA198C /* audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECE6126202AA00FA198C /* audio.cpp */; };
- 8CD1ED64126202AB00FA198C /* character.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECE8126202AA00FA198C /* character.cpp */; };
- 8CD1ED65126202AB00FA198C /* conversation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECEA126202AA00FA198C /* conversation.cpp */; };
- 8CD1ED66126202AB00FA198C /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECEC126202AA00FA198C /* detection.cpp */; };
- 8CD1ED67126202AB00FA198C /* drew.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECED126202AA00FA198C /* drew.cpp */; };
- 8CD1ED68126202AB00FA198C /* flux.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECEF126202AA00FA198C /* flux.cpp */; };
- 8CD1ED69126202AB00FA198C /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECF1126202AA00FA198C /* font.cpp */; };
- 8CD1ED6A126202AB00FA198C /* hotspot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECF3126202AA00FA198C /* hotspot.cpp */; };
- 8CD1ED6D126202AB00FA198C /* movie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECF7126202AA00FA198C /* movie.cpp */; };
- 8CD1ED6E126202AB00FA198C /* path.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECF9126202AA00FA198C /* path.cpp */; };
- 8CD1ED6F126202AB00FA198C /* picture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECFB126202AA00FA198C /* picture.cpp */; };
- 8CD1ED70126202AB00FA198C /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECFD126202AA00FA198C /* resource.cpp */; };
- 8CD1ED71126202AB00FA198C /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ECFF126202AA00FA198C /* script.cpp */; };
- 8CD1ED72126202AB00FA198C /* script_func.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ED01126202AA00FA198C /* script_func.cpp */; };
- 8CD1ED73126202AB00FA198C /* state.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ED03126202AA00FA198C /* state.cpp */; };
- 8CD1ED74126202AB00FA198C /* text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ED05126202AA00FA198C /* text.cpp */; };
- 8CD1ED75126202AB00FA198C /* tools.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ED07126202AA00FA198C /* tools.cpp */; };
- 8CD1ED76126202AB00FA198C /* toon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1ED09126202AA00FA198C /* toon.cpp */; };
- 8CD1ED881262030100FA198C /* toon.dat in Resources */ = {isa = PBXBuildFile; fileRef = 8CD1ED871262030100FA198C /* toon.dat */; };
- 8CD1ED891262030100FA198C /* toon.dat in Resources */ = {isa = PBXBuildFile; fileRef = 8CD1ED871262030100FA198C /* toon.dat */; };
- 8CD1ED8A1262030100FA198C /* toon.dat in Resources */ = {isa = PBXBuildFile; fileRef = 8CD1ED871262030100FA198C /* toon.dat */; };
- 8CD80C8B126271A9001C6C87 /* surface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80C89126271A9001C6C87 /* surface.cpp */; };
- 8CD80C8C126271A9001C6C87 /* surface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80C89126271A9001C6C87 /* surface.cpp */; };
- 8CD80C8D126271A9001C6C87 /* surface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80C89126271A9001C6C87 /* surface.cpp */; };
- 8CD80C91126271BD001C6C87 /* gfx_towns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80C90126271BD001C6C87 /* gfx_towns.cpp */; };
- 8CD80C92126271BD001C6C87 /* gfx_towns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80C90126271BD001C6C87 /* gfx_towns.cpp */; };
- 8CD80C93126271BD001C6C87 /* gfx_towns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80C90126271BD001C6C87 /* gfx_towns.cpp */; };
- 8CD80CE0126272A0001C6C87 /* actor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CBF1262729F001C6C87 /* actor.cpp */; };
- 8CD80CE1126272A0001C6C87 /* animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CC11262729F001C6C87 /* animation.cpp */; };
- 8CD80CE2126272A0001C6C87 /* callbacks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CC31262729F001C6C87 /* callbacks.cpp */; };
- 8CD80CE3126272A0001C6C87 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CC41262729F001C6C87 /* console.cpp */; };
- 8CD80CE4126272A0001C6C87 /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CC61262729F001C6C87 /* detection.cpp */; };
- 8CD80CE5126272A0001C6C87 /* dialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CC71262729F001C6C87 /* dialog.cpp */; };
- 8CD80CE6126272A0001C6C87 /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CC91262729F001C6C87 /* font.cpp */; };
- 8CD80CE7126272A0001C6C87 /* inventory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CCB1262729F001C6C87 /* inventory.cpp */; };
- 8CD80CE9126272A0001C6C87 /* music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CCE1262729F001C6C87 /* music.cpp */; };
- 8CD80CEA126272A0001C6C87 /* objects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CD01262729F001C6C87 /* objects.cpp */; };
- 8CD80CEB126272A0001C6C87 /* pack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CD21262729F001C6C87 /* pack.cpp */; };
- 8CD80CEC126272A0001C6C87 /* resources.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CD4126272A0001C6C87 /* resources.cpp */; };
- 8CD80CED126272A0001C6C87 /* scene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CD6126272A0001C6C87 /* scene.cpp */; };
- 8CD80CEE126272A0001C6C87 /* segment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CD8126272A0001C6C87 /* segment.cpp */; };
- 8CD80CEF126272A0001C6C87 /* surface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CDA126272A0001C6C87 /* surface.cpp */; };
- 8CD80CF0126272A0001C6C87 /* surface_list.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CDC126272A0001C6C87 /* surface_list.cpp */; };
- 8CD80CF1126272A0001C6C87 /* teenagent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CDE126272A0001C6C87 /* teenagent.cpp */; };
- 8CD80CF2126272A0001C6C87 /* actor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CBF1262729F001C6C87 /* actor.cpp */; };
- 8CD80CF3126272A0001C6C87 /* animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CC11262729F001C6C87 /* animation.cpp */; };
- 8CD80CF4126272A0001C6C87 /* callbacks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CC31262729F001C6C87 /* callbacks.cpp */; };
- 8CD80CF5126272A0001C6C87 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CC41262729F001C6C87 /* console.cpp */; };
- 8CD80CF6126272A0001C6C87 /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CC61262729F001C6C87 /* detection.cpp */; };
- 8CD80CF7126272A0001C6C87 /* dialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CC71262729F001C6C87 /* dialog.cpp */; };
- 8CD80CF8126272A0001C6C87 /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CC91262729F001C6C87 /* font.cpp */; };
- 8CD80CF9126272A0001C6C87 /* inventory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CCB1262729F001C6C87 /* inventory.cpp */; };
- 8CD80CFB126272A0001C6C87 /* music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CCE1262729F001C6C87 /* music.cpp */; };
- 8CD80CFC126272A0001C6C87 /* objects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CD01262729F001C6C87 /* objects.cpp */; };
- 8CD80CFD126272A0001C6C87 /* pack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CD21262729F001C6C87 /* pack.cpp */; };
- 8CD80CFE126272A0001C6C87 /* resources.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CD4126272A0001C6C87 /* resources.cpp */; };
- 8CD80CFF126272A0001C6C87 /* scene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CD6126272A0001C6C87 /* scene.cpp */; };
- 8CD80D00126272A0001C6C87 /* segment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CD8126272A0001C6C87 /* segment.cpp */; };
- 8CD80D01126272A0001C6C87 /* surface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CDA126272A0001C6C87 /* surface.cpp */; };
- 8CD80D02126272A0001C6C87 /* surface_list.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CDC126272A0001C6C87 /* surface_list.cpp */; };
- 8CD80D03126272A0001C6C87 /* teenagent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CDE126272A0001C6C87 /* teenagent.cpp */; };
- 8CD80D04126272A0001C6C87 /* actor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CBF1262729F001C6C87 /* actor.cpp */; };
- 8CD80D05126272A0001C6C87 /* animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CC11262729F001C6C87 /* animation.cpp */; };
- 8CD80D06126272A0001C6C87 /* callbacks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CC31262729F001C6C87 /* callbacks.cpp */; };
- 8CD80D07126272A0001C6C87 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CC41262729F001C6C87 /* console.cpp */; };
- 8CD80D08126272A0001C6C87 /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CC61262729F001C6C87 /* detection.cpp */; };
- 8CD80D09126272A0001C6C87 /* dialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CC71262729F001C6C87 /* dialog.cpp */; };
- 8CD80D0A126272A0001C6C87 /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CC91262729F001C6C87 /* font.cpp */; };
- 8CD80D0B126272A0001C6C87 /* inventory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CCB1262729F001C6C87 /* inventory.cpp */; };
- 8CD80D0D126272A0001C6C87 /* music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CCE1262729F001C6C87 /* music.cpp */; };
- 8CD80D0E126272A0001C6C87 /* objects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CD01262729F001C6C87 /* objects.cpp */; };
- 8CD80D0F126272A0001C6C87 /* pack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CD21262729F001C6C87 /* pack.cpp */; };
- 8CD80D10126272A0001C6C87 /* resources.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CD4126272A0001C6C87 /* resources.cpp */; };
- 8CD80D11126272A0001C6C87 /* scene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CD6126272A0001C6C87 /* scene.cpp */; };
- 8CD80D12126272A0001C6C87 /* segment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CD8126272A0001C6C87 /* segment.cpp */; };
- 8CD80D13126272A0001C6C87 /* surface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CDA126272A0001C6C87 /* surface.cpp */; };
- 8CD80D14126272A0001C6C87 /* surface_list.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CDC126272A0001C6C87 /* surface_list.cpp */; };
- 8CD80D15126272A0001C6C87 /* teenagent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD80CDE126272A0001C6C87 /* teenagent.cpp */; };
- DF093E5F0F63CAD4002D821E /* pn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF093E5C0F63CAD4002D821E /* pn.cpp */; };
- DF093E600F63CAD4002D821E /* script_pn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF093E5D0F63CAD4002D821E /* script_pn.cpp */; };
- DF093E610F63CAD4002D821E /* vga_pn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF093E5E0F63CAD4002D821E /* vga_pn.cpp */; };
- DF093E770F63CB26002D821E /* scummclassic.zip in Resources */ = {isa = PBXBuildFile; fileRef = DF2FFBDB0F485E480006E566 /* scummclassic.zip */; };
- DF093E780F63CB26002D821E /* scummmodern.zip in Resources */ = {isa = PBXBuildFile; fileRef = DF7E8C7A0ED601E5001CB19F /* scummmodern.zip */; };
- DF093E7A0F63CB26002D821E /* kyra.dat in Resources */ = {isa = PBXBuildFile; fileRef = DFE47C810D81F86900B6D1FB /* kyra.dat */; };
- DF093E7B0F63CB26002D821E /* lure.dat in Resources */ = {isa = PBXBuildFile; fileRef = DFE47C820D81F86900B6D1FB /* lure.dat */; };
- DF093E7C0F63CB26002D821E /* queen.tbl in Resources */ = {isa = PBXBuildFile; fileRef = DFE47C830D81F86900B6D1FB /* queen.tbl */; };
- DF093E7D0F63CB26002D821E /* sky.cpt in Resources */ = {isa = PBXBuildFile; fileRef = DFE47C850D81F86900B6D1FB /* sky.cpt */; };
- DF093E810F63CB26002D821E /* commandLine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE470C10D81F4BA00B6D1FB /* commandLine.cpp */; };
- DF093E820F63CB26002D821E /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE470C70D81F4BA00B6D1FB /* main.cpp */; };
- DF093E830F63CB26002D821E /* plugins.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE470CA0D81F4BA00B6D1FB /* plugins.cpp */; };
- DF093E840F63CB26002D821E /* version.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE470CC0D81F4BA00B6D1FB /* version.cpp */; };
- DF093E850F63CB26002D821E /* default-events.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE470D80D81F4E700B6D1FB /* default-events.cpp */; };
- DF093E860F63CB26002D821E /* posix-fs-factory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE470F60D81F4E700B6D1FB /* posix-fs-factory.cpp */; };
- DF093E890F63CB26002D821E /* posix-provider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473810D81F4E800B6D1FB /* posix-provider.cpp */; };
- DF093E8A0F63CB26002D821E /* default-saves.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4738E0D81F4E800B6D1FB /* default-saves.cpp */; };
- DF093E8B0F63CB26002D821E /* savefile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473900D81F4E800B6D1FB /* savefile.cpp */; };
- DF093E8C0F63CB26002D821E /* default-timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473930D81F4E800B6D1FB /* default-timer.cpp */; };
- DF093E8D0F63CB26002D821E /* config-file.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4739A0D81F4E800B6D1FB /* config-file.cpp */; };
- DF093E8E0F63CB26002D821E /* config-manager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4739C0D81F4E800B6D1FB /* config-manager.cpp */; };
- DF093E8F0F63CB26002D821E /* file.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473A10D81F4E800B6D1FB /* file.cpp */; };
- DF093E900F63CB26002D821E /* fs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473A40D81F4E800B6D1FB /* fs.cpp */; };
- DF093E910F63CB26002D821E /* hashmap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473A80D81F4E800B6D1FB /* hashmap.cpp */; };
- DF093E920F63CB26002D821E /* md5.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473AD0D81F4E800B6D1FB /* md5.cpp */; };
- DF093E930F63CB26002D821E /* mutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473B00D81F4E800B6D1FB /* mutex.cpp */; };
- DF093E940F63CB26002D821E /* str.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473BA0D81F4E800B6D1FB /* str.cpp */; };
- DF093E950F63CB26002D821E /* stream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473BC0D81F4E800B6D1FB /* stream.cpp */; };
- DF093E960F63CB26002D821E /* system.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473BE0D81F4E800B6D1FB /* system.cpp */; };
- DF093E970F63CB26002D821E /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473C30D81F4E800B6D1FB /* util.cpp */; };
- DF093E980F63CB26002D821E /* zlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473C50D81F4E800B6D1FB /* zlib.cpp */; };
- DF093E990F63CB26002D821E /* cursorman.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477540D81F4E900B6D1FB /* cursorman.cpp */; };
- DF093E9A0F63CB26002D821E /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477580D81F4E900B6D1FB /* font.cpp */; };
- DF093E9B0F63CB26002D821E /* fontman.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4775A0D81F4E900B6D1FB /* fontman.cpp */; };
- DF093E9C0F63CB26002D821E /* consolefont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4775D0D81F4E900B6D1FB /* consolefont.cpp */; };
- DF093E9D0F63CB26002D821E /* newfont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4775E0D81F4E900B6D1FB /* newfont.cpp */; };
- DF093E9E0F63CB26002D821E /* newfont_big.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4775F0D81F4E900B6D1FB /* newfont_big.cpp */; };
- DF093EA00F63CB26002D821E /* iff.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477610D81F4E900B6D1FB /* iff.cpp */; };
- DF093EA10F63CB26002D821E /* imagedec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477630D81F4E900B6D1FB /* imagedec.cpp */; };
- DF093EA20F63CB26002D821E /* primitives.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4776A0D81F4E900B6D1FB /* primitives.cpp */; };
- DF093EA30F63CB26002D821E /* surface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477860D81F4E900B6D1FB /* surface.cpp */; };
- DF093EA40F63CB26002D821E /* about.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477890D81F4E900B6D1FB /* about.cpp */; };
- DF093EA50F63CB26002D821E /* Actions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4778B0D81F4E900B6D1FB /* Actions.cpp */; };
- DF093EA70F63CB26002D821E /* chooser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4778F0D81F4E900B6D1FB /* chooser.cpp */; };
- DF093EA80F63CB26002D821E /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477910D81F4E900B6D1FB /* console.cpp */; };
- DF093EA90F63CB26002D821E /* debugger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477940D81F4E900B6D1FB /* debugger.cpp */; };
- DF093EAA0F63CB26002D821E /* dialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477960D81F4E900B6D1FB /* dialog.cpp */; };
- DF093EAD0F63CB26002D821E /* Key.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4779E0D81F4E900B6D1FB /* Key.cpp */; };
- DF093EAE0F63CB26002D821E /* launcher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477A20D81F4E900B6D1FB /* launcher.cpp */; };
- DF093EB00F63CB26002D821E /* massadd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477A60D81F4E900B6D1FB /* massadd.cpp */; };
- DF093EB10F63CB26002D821E /* message.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477A80D81F4E900B6D1FB /* message.cpp */; };
- DF093EB20F63CB26002D821E /* object.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477AD0D81F4E900B6D1FB /* object.cpp */; };
- DF093EB30F63CB26002D821E /* options.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477AF0D81F4E900B6D1FB /* options.cpp */; };
- DF093EB70F63CB26002D821E /* themebrowser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477BA0D81F4E900B6D1FB /* themebrowser.cpp */; };
- DF093EB80F63CB26002D821E /* widget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477C40D81F4E900B6D1FB /* widget.cpp */; };
- DF093ED60F63CB26002D821E /* memorypool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD511460DF3383500854012 /* memorypool.cpp */; };
- DF093ED70F63CB26002D821E /* seq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD517E10DF33CAC00854012 /* seq.cpp */; };
- DF093ED80F63CB26002D821E /* scaler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD5183B0DF3411800854012 /* scaler.cpp */; };
- DF093ED90F63CB26002D821E /* scalebit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD518A00DF34B2500854012 /* scalebit.cpp */; };
- DF093EDA0F63CB26002D821E /* 2xsai.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD518AA0DF34BA600854012 /* 2xsai.cpp */; };
- DF093EDB0F63CB26002D821E /* aspect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD518AB0DF34BA600854012 /* aspect.cpp */; };
- DF093EDE0F63CB26002D821E /* scale2x.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD518B50DF34BA600854012 /* scale2x.cpp */; };
- DF093EDF0F63CB26002D821E /* scale3x.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD518B80DF34BA600854012 /* scale3x.cpp */; };
- DF093EE20F63CB26002D821E /* agi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF841FF70E7BA6A600F5680E /* agi.cpp */; };
- DF093EE30F63CB26002D821E /* checks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF841FF90E7BA6A600F5680E /* checks.cpp */; };
- DF093EE40F63CB26002D821E /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF841FFA0E7BA6A600F5680E /* console.cpp */; };
- DF093EE50F63CB26002D821E /* cycle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF841FFC0E7BA6A600F5680E /* cycle.cpp */; };
- DF093EE60F63CB26002D821E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF841FFD0E7BA6A600F5680E /* detection.cpp */; };
- DF093EE70F63CB26002D821E /* global.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF841FFF0E7BA6A600F5680E /* global.cpp */; };
- DF093EE80F63CB26002D821E /* graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420000E7BA6A600F5680E /* graphics.cpp */; };
- DF093EE90F63CB26002D821E /* id.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420020E7BA6A600F5680E /* id.cpp */; };
- DF093EEA0F63CB26002D821E /* inv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420030E7BA6A600F5680E /* inv.cpp */; };
- DF093EEB0F63CB26002D821E /* keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420040E7BA6A600F5680E /* keyboard.cpp */; };
- DF093EEC0F63CB26002D821E /* loader_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420060E7BA6A600F5680E /* loader_v2.cpp */; };
- DF093EED0F63CB26002D821E /* loader_v3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420070E7BA6A600F5680E /* loader_v3.cpp */; };
- DF093EEE0F63CB26002D821E /* logic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420080E7BA6A600F5680E /* logic.cpp */; };
- DF093EEF0F63CB26002D821E /* lzw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84200A0E7BA6A600F5680E /* lzw.cpp */; };
- DF093EF00F63CB26002D821E /* menu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84200C0E7BA6A600F5680E /* menu.cpp */; };
- DF093EF10F63CB26002D821E /* motion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84200F0E7BA6A600F5680E /* motion.cpp */; };
- DF093EF20F63CB26002D821E /* objects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420100E7BA6A600F5680E /* objects.cpp */; };
- DF093EF30F63CB26002D821E /* op_cmd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420110E7BA6A600F5680E /* op_cmd.cpp */; };
- DF093EF40F63CB26002D821E /* op_dbg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420120E7BA6A600F5680E /* op_dbg.cpp */; };
- DF093EF50F63CB26002D821E /* op_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420130E7BA6A600F5680E /* op_test.cpp */; };
- DF093EF60F63CB26002D821E /* picture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420150E7BA6A600F5680E /* picture.cpp */; };
- DF093EF70F63CB26002D821E /* preagi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420170E7BA6A600F5680E /* preagi.cpp */; };
- DF093EF80F63CB26002D821E /* preagi_common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420190E7BA6A600F5680E /* preagi_common.cpp */; };
- DF093EF90F63CB26002D821E /* preagi_mickey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84201B0E7BA6A600F5680E /* preagi_mickey.cpp */; };
- DF093EFA0F63CB26002D821E /* preagi_troll.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84201D0E7BA6A600F5680E /* preagi_troll.cpp */; };
- DF093EFB0F63CB26002D821E /* preagi_winnie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84201F0E7BA6A600F5680E /* preagi_winnie.cpp */; };
- DF093EFC0F63CB26002D821E /* predictive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420210E7BA6A600F5680E /* predictive.cpp */; };
- DF093EFD0F63CB26002D821E /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420220E7BA6A600F5680E /* saveload.cpp */; };
- DF093EFE0F63CB26002D821E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420230E7BA6A600F5680E /* sound.cpp */; };
- DF093EFF0F63CB26002D821E /* sprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420250E7BA6A600F5680E /* sprite.cpp */; };
- DF093F000F63CB26002D821E /* text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420270E7BA6A600F5680E /* text.cpp */; };
- DF093F010F63CB26002D821E /* view.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420280E7BA6A600F5680E /* view.cpp */; };
- DF093F020F63CB26002D821E /* wagparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84202A0E7BA6A600F5680E /* wagparser.cpp */; };
- DF093F030F63CB26002D821E /* words.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84202C0E7BA6A600F5680E /* words.cpp */; };
- DF093F040F63CB26002D821E /* agos.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84202E0E7BA6A600F5680E /* agos.cpp */; };
- DF093F050F63CB26002D821E /* animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420300E7BA6A600F5680E /* animation.cpp */; };
- DF093F060F63CB26002D821E /* charset-fontdata.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420320E7BA6A600F5680E /* charset-fontdata.cpp */; };
- DF093F070F63CB26002D821E /* charset.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420330E7BA6A600F5680E /* charset.cpp */; };
- DF093F080F63CB26002D821E /* contain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420340E7BA6A600F5680E /* contain.cpp */; };
- DF093F090F63CB26002D821E /* cursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420350E7BA6A600F5680E /* cursor.cpp */; };
- DF093F0A0F63CB26002D821E /* debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420360E7BA6A600F5680E /* debug.cpp */; };
- DF093F0B0F63CB26002D821E /* debugger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420380E7BA6A600F5680E /* debugger.cpp */; };
- DF093F0C0F63CB26002D821E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84203A0E7BA6A600F5680E /* detection.cpp */; };
- DF093F0D0F63CB26002D821E /* draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84203C0E7BA6A600F5680E /* draw.cpp */; };
- DF093F0E0F63CB26002D821E /* event.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84203D0E7BA6A600F5680E /* event.cpp */; };
- DF093F0F0F63CB26002D821E /* gfx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84203E0E7BA6A600F5680E /* gfx.cpp */; };
- DF093F100F63CB26002D821E /* icons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84203F0E7BA6A600F5680E /* icons.cpp */; };
- DF093F110F63CB26002D821E /* input.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420400E7BA6A600F5680E /* input.cpp */; };
- DF093F120F63CB26002D821E /* items.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420420E7BA6A600F5680E /* items.cpp */; };
- DF093F130F63CB26002D821E /* menus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420430E7BA6A600F5680E /* menus.cpp */; };
- DF093F140F63CB26002D821E /* midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420440E7BA6A600F5680E /* midi.cpp */; };
- DF093F150F63CB26002D821E /* midiparser_s1d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420460E7BA6A600F5680E /* midiparser_s1d.cpp */; };
- DF093F160F63CB26002D821E /* oracle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420480E7BA6A600F5680E /* oracle.cpp */; };
- DF093F170F63CB26002D821E /* res.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420490E7BA6A600F5680E /* res.cpp */; };
- DF093F180F63CB26002D821E /* res_ami.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84204A0E7BA6A600F5680E /* res_ami.cpp */; };
- DF093F190F63CB26002D821E /* res_snd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84204B0E7BA6A600F5680E /* res_snd.cpp */; };
- DF093F1A0F63CB26002D821E /* rooms.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84204C0E7BA6A600F5680E /* rooms.cpp */; };
- DF093F1B0F63CB26002D821E /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84204D0E7BA6A600F5680E /* saveload.cpp */; };
- DF093F1C0F63CB26002D821E /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84204E0E7BA6A600F5680E /* script.cpp */; };
- DF093F1D0F63CB26002D821E /* script_e1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84204F0E7BA6A600F5680E /* script_e1.cpp */; };
- DF093F1E0F63CB26002D821E /* script_e2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420500E7BA6A600F5680E /* script_e2.cpp */; };
- DF093F1F0F63CB26002D821E /* script_ff.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420510E7BA6A600F5680E /* script_ff.cpp */; };
- DF093F200F63CB26002D821E /* script_pp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420520E7BA6A600F5680E /* script_pp.cpp */; };
- DF093F210F63CB26002D821E /* script_s1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420530E7BA6A600F5680E /* script_s1.cpp */; };
- DF093F220F63CB26002D821E /* script_s2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420540E7BA6A600F5680E /* script_s2.cpp */; };
- DF093F230F63CB26002D821E /* script_ww.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420550E7BA6A600F5680E /* script_ww.cpp */; };
- DF093F240F63CB26002D821E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420560E7BA6A600F5680E /* sound.cpp */; };
- DF093F250F63CB26002D821E /* string.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420580E7BA6A600F5680E /* string.cpp */; };
- DF093F260F63CB26002D821E /* subroutine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420590E7BA6A600F5680E /* subroutine.cpp */; };
- DF093F270F63CB26002D821E /* verb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84205A0E7BA6A600F5680E /* verb.cpp */; };
- DF093F280F63CB26002D821E /* vga.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84205B0E7BA6A600F5680E /* vga.cpp */; };
- DF093F290F63CB26002D821E /* vga_e2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84205D0E7BA6A600F5680E /* vga_e2.cpp */; };
- DF093F2A0F63CB26002D821E /* vga_ff.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84205E0E7BA6A600F5680E /* vga_ff.cpp */; };
- DF093F2B0F63CB26002D821E /* vga_s1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84205F0E7BA6A600F5680E /* vga_s1.cpp */; };
- DF093F2C0F63CB26002D821E /* vga_s2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420600E7BA6A600F5680E /* vga_s2.cpp */; };
- DF093F2D0F63CB26002D821E /* vga_ww.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420610E7BA6A600F5680E /* vga_ww.cpp */; };
- DF093F2E0F63CB26002D821E /* window.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420620E7BA6A600F5680E /* window.cpp */; };
- DF093F2F0F63CB26002D821E /* zones.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420630E7BA6A600F5680E /* zones.cpp */; };
- DF093F300F63CB26002D821E /* anim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420650E7BA6A600F5680E /* anim.cpp */; };
- DF093F310F63CB26002D821E /* bg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420670E7BA6A600F5680E /* bg.cpp */; };
- DF093F320F63CB26002D821E /* bg_list.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420690E7BA6A600F5680E /* bg_list.cpp */; };
- DF093F330F63CB26002D821E /* cine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84206B0E7BA6A600F5680E /* cine.cpp */; };
- DF093F340F63CB26002D821E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84206D0E7BA6A600F5680E /* detection.cpp */; };
- DF093F350F63CB26002D821E /* gfx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84206E0E7BA6A600F5680E /* gfx.cpp */; };
- DF093F360F63CB26002D821E /* main_loop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420700E7BA6A600F5680E /* main_loop.cpp */; };
- DF093F370F63CB26002D821E /* msg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420730E7BA6A600F5680E /* msg.cpp */; };
- DF093F380F63CB26002D821E /* object.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420750E7BA6A600F5680E /* object.cpp */; };
- DF093F390F63CB26002D821E /* pal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420770E7BA6A600F5680E /* pal.cpp */; };
- DF093F3A0F63CB26002D821E /* part.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420790E7BA6A600F5680E /* part.cpp */; };
- DF093F3B0F63CB26002D821E /* prc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84207B0E7BA6A600F5680E /* prc.cpp */; };
- DF093F3C0F63CB26002D821E /* rel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84207D0E7BA6A600F5680E /* rel.cpp */; };
- DF093F3D0F63CB26002D821E /* script_fw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420800E7BA6A600F5680E /* script_fw.cpp */; };
- DF093F3E0F63CB26002D821E /* script_os.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420810E7BA6A600F5680E /* script_os.cpp */; };
- DF093F3F0F63CB26002D821E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420820E7BA6A600F5680E /* sound.cpp */; };
- DF093F400F63CB26002D821E /* texte.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420840E7BA6A600F5680E /* texte.cpp */; };
- DF093F410F63CB26002D821E /* unpack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420860E7BA6A600F5680E /* unpack.cpp */; };
- DF093F420F63CB26002D821E /* various.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420880E7BA6A600F5680E /* various.cpp */; };
- DF093F430F63CB26002D821E /* actor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420AB0E7BA6A600F5680E /* actor.cpp */; };
- DF093F440F63CB26002D821E /* background.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420AE0E7BA6A600F5680E /* background.cpp */; };
- DF093F450F63CB26002D821E /* backgroundIncrust.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420B10E7BA6A600F5680E /* backgroundIncrust.cpp */; };
- DF093F460F63CB26002D821E /* cell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420B40E7BA6A600F5680E /* cell.cpp */; };
- DF093F470F63CB26002D821E /* cruise.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420B70E7BA6A600F5680E /* cruise.cpp */; };
- DF093F480F63CB26002D821E /* cruise_main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420BA0E7BA6A700F5680E /* cruise_main.cpp */; };
- DF093F490F63CB26002D821E /* ctp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420BD0E7BA6A700F5680E /* ctp.cpp */; };
- DF093F4A0F63CB26002D821E /* dataLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420C00E7BA6A700F5680E /* dataLoader.cpp */; };
- DF093F4B0F63CB26002D821E /* decompiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420C30E7BA6A700F5680E /* decompiler.cpp */; };
- DF093F4C0F63CB26002D821E /* delphine-unpack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420C50E7BA6A700F5680E /* delphine-unpack.cpp */; };
- DF093F4D0F63CB26002D821E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420C70E7BA6A700F5680E /* detection.cpp */; };
- DF093F4E0F63CB26002D821E /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420C90E7BA6A700F5680E /* font.cpp */; };
- DF093F4F0F63CB26002D821E /* function.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420CF0E7BA6A700F5680E /* function.cpp */; };
- DF093F500F63CB26002D821E /* gfxModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420D20E7BA6A700F5680E /* gfxModule.cpp */; };
- DF093F510F63CB26002D821E /* linker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420D60E7BA6A700F5680E /* linker.cpp */; };
- DF093F520F63CB26002D821E /* mainDraw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420D90E7BA6A700F5680E /* mainDraw.cpp */; };
- DF093F530F63CB26002D821E /* menu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420DC0E7BA6A700F5680E /* menu.cpp */; };
- DF093F540F63CB26002D821E /* mouse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420E00E7BA6A700F5680E /* mouse.cpp */; };
- DF093F550F63CB26002D821E /* object.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420E30E7BA6A700F5680E /* object.cpp */; };
- DF093F560F63CB26002D821E /* overlay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420E60E7BA6A700F5680E /* overlay.cpp */; };
- DF093F570F63CB26002D821E /* perso.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420E90E7BA6A700F5680E /* perso.cpp */; };
- DF093F580F63CB26002D821E /* polys.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420EC0E7BA6A700F5680E /* polys.cpp */; };
- DF093F590F63CB26002D821E /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420EF0E7BA6A700F5680E /* saveload.cpp */; };
- DF093F5A0F63CB26002D821E /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420F20E7BA6A700F5680E /* script.cpp */; };
- DF093F5B0F63CB26002D821E /* stack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420F50E7BA6A700F5680E /* stack.cpp */; };
- DF093F5C0F63CB26002D821E /* various.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420F90E7BA6A700F5680E /* various.cpp */; };
- DF093F5D0F63CB26002D821E /* vars.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420FC0E7BA6A700F5680E /* vars.cpp */; };
- DF093F5E0F63CB26002D821E /* volume.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420FF0E7BA6A700F5680E /* volume.cpp */; };
- DF093F5F0F63CB26002D821E /* dialogs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421020E7BA6A700F5680E /* dialogs.cpp */; };
- DF093F600F63CB26002D821E /* actors.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421050E7BA6A700F5680E /* actors.cpp */; };
- DF093F610F63CB26002D821E /* animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421060E7BA6A700F5680E /* animation.cpp */; };
- DF093F620F63CB26002D821E /* converse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421070E7BA6A700F5680E /* converse.cpp */; };
- DF093F630F63CB26002D821E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421080E7BA6A700F5680E /* detection.cpp */; };
- DF093F640F63CB26002D821E /* drascula.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421090E7BA6A700F5680E /* drascula.cpp */; };
- DF093F650F63CB26002D821E /* graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84210B0E7BA6A700F5680E /* graphics.cpp */; };
- DF093F660F63CB26002D821E /* interface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84210C0E7BA6A700F5680E /* interface.cpp */; };
- DF093F670F63CB26002D821E /* objects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84210E0E7BA6A700F5680E /* objects.cpp */; };
- DF093F680F63CB26002D821E /* palette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84210F0E7BA6A700F5680E /* palette.cpp */; };
- DF093F690F63CB26002D821E /* rooms.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421100E7BA6A700F5680E /* rooms.cpp */; };
- DF093F6A0F63CB26002D821E /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421110E7BA6A700F5680E /* saveload.cpp */; };
- DF093F6B0F63CB26002D821E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421120E7BA6A700F5680E /* sound.cpp */; };
- DF093F6C0F63CB26002D821E /* talk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421130E7BA6A700F5680E /* talk.cpp */; };
- DF093F6D0F63CB26002D821E /* engine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421140E7BA6A700F5680E /* engine.cpp */; };
- DF093F6F0F63CB26002D821E /* dataio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84211B0E7BA6A700F5680E /* dataio.cpp */; };
- DF093F700F63CB26002D821E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84211D0E7BA6A700F5680E /* detection.cpp */; };
- DF093F710F63CB26002D821E /* draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84211E0E7BA6A700F5680E /* draw.cpp */; };
- DF093F720F63CB26002D821E /* draw_bargon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421200E7BA6A700F5680E /* draw_bargon.cpp */; };
- DF093F730F63CB26002D821E /* draw_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421210E7BA6A700F5680E /* draw_v1.cpp */; };
- DF093F740F63CB26002D821E /* draw_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421220E7BA6A700F5680E /* draw_v2.cpp */; };
- DF093F760F63CB26002D821E /* game.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421250E7BA6A700F5680E /* game.cpp */; };
- DF093F790F63CB26002D821E /* global.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421290E7BA6A700F5680E /* global.cpp */; };
- DF093F7A0F63CB26002D821E /* gob.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84212B0E7BA6A700F5680E /* gob.cpp */; };
- DF093F7B0F63CB26002D821E /* goblin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84212D0E7BA6A700F5680E /* goblin.cpp */; };
- DF093F7C0F63CB26002D821E /* goblin_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84212F0E7BA6A700F5680E /* goblin_v1.cpp */; };
- DF093F7D0F63CB26002D821E /* goblin_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421300E7BA6A700F5680E /* goblin_v2.cpp */; };
- DF093F7E0F63CB26002D821E /* goblin_v3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421310E7BA6A700F5680E /* goblin_v3.cpp */; };
- DF093F7F0F63CB26002D821E /* goblin_v4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421320E7BA6A700F5680E /* goblin_v4.cpp */; };
- DF093F800F63CB26002D821E /* init.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421330E7BA6A700F5680E /* init.cpp */; };
- DF093F810F63CB26002D821E /* init_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421350E7BA6A700F5680E /* init_v1.cpp */; };
- DF093F820F63CB26002D821E /* init_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421360E7BA6A700F5680E /* init_v2.cpp */; };
- DF093F830F63CB26002D821E /* init_v3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421370E7BA6A700F5680E /* init_v3.cpp */; };
- DF093F840F63CB26002D821E /* inter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421380E7BA6A700F5680E /* inter.cpp */; };
- DF093F850F63CB26002D821E /* inter_bargon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84213A0E7BA6A700F5680E /* inter_bargon.cpp */; };
- DF093F860F63CB26002D821E /* inter_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84213B0E7BA6A700F5680E /* inter_v1.cpp */; };
- DF093F870F63CB26002D821E /* inter_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84213C0E7BA6A700F5680E /* inter_v2.cpp */; };
- DF093F880F63CB26002D821E /* inter_v3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84213D0E7BA6A700F5680E /* inter_v3.cpp */; };
- DF093F890F63CB26002D821E /* inter_v4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84213E0E7BA6A700F5680E /* inter_v4.cpp */; };
- DF093F8A0F63CB26002D821E /* inter_v5.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84213F0E7BA6A700F5680E /* inter_v5.cpp */; };
- DF093F8B0F63CB26002D821E /* inter_v6.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421400E7BA6A700F5680E /* inter_v6.cpp */; };
- DF093F8C0F63CB26002D821E /* map.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421410E7BA6A700F5680E /* map.cpp */; };
- DF093F8D0F63CB26002D821E /* map_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421430E7BA6A700F5680E /* map_v1.cpp */; };
- DF093F8E0F63CB26002D821E /* map_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421440E7BA6A700F5680E /* map_v2.cpp */; };
- DF093F900F63CB26002D821E /* mult.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421470E7BA6A700F5680E /* mult.cpp */; };
- DF093F910F63CB26002D821E /* mult_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421490E7BA6A700F5680E /* mult_v1.cpp */; };
- DF093F920F63CB26002D821E /* mult_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84214A0E7BA6A700F5680E /* mult_v2.cpp */; };
- DF093F930F63CB26002D821E /* palanim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84214C0E7BA6A700F5680E /* palanim.cpp */; };
- DF093F9B0F63CB26002D821E /* scenery.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421570E7BA6A700F5680E /* scenery.cpp */; };
- DF093F9C0F63CB26002D821E /* scenery_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421590E7BA6A700F5680E /* scenery_v1.cpp */; };
- DF093F9D0F63CB26002D821E /* scenery_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84215A0E7BA6A700F5680E /* scenery_v2.cpp */; };
- DF093F9E0F63CB26002D821E /* adlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84215C0E7BA6A700F5680E /* adlib.cpp */; };
- DF093F9F0F63CB26002D821E /* bgatmosphere.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84215E0E7BA6A700F5680E /* bgatmosphere.cpp */; };
- DF093FA00F63CB26002D821E /* cdrom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421600E7BA6A700F5680E /* cdrom.cpp */; };
- DF093FA10F63CB26002D821E /* infogrames.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421620E7BA6A700F5680E /* infogrames.cpp */; };
- DF093FA20F63CB26002D821E /* pcspeaker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421640E7BA6A700F5680E /* pcspeaker.cpp */; };
- DF093FA30F63CB26002D821E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421660E7BA6A700F5680E /* sound.cpp */; };
- DF093FA40F63CB26002D821E /* soundblaster.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421680E7BA6A700F5680E /* soundblaster.cpp */; };
- DF093FA50F63CB26002D821E /* sounddesc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84216A0E7BA6A700F5680E /* sounddesc.cpp */; };
- DF093FA60F63CB26002D821E /* soundmixer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84216C0E7BA6A700F5680E /* soundmixer.cpp */; };
- DF093FA70F63CB26002D821E /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84216F0E7BA6A700F5680E /* util.cpp */; };
- DF093FA80F63CB26002D821E /* variables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421710E7BA6A700F5680E /* variables.cpp */; };
- DF093FA90F63CB26002D821E /* video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421730E7BA6A700F5680E /* video.cpp */; };
- DF093FAA0F63CB26002D821E /* video_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421750E7BA6A700F5680E /* video_v1.cpp */; };
- DF093FAB0F63CB26002D821E /* video_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421760E7BA6A700F5680E /* video_v2.cpp */; };
- DF093FAC0F63CB26002D821E /* video_v6.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421770E7BA6A700F5680E /* video_v6.cpp */; };
- DF093FAD0F63CB26002D821E /* videoplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421780E7BA6A700F5680E /* videoplayer.cpp */; };
- DF093FD10F63CB26002D821E /* animator_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421A40E7BA6A800F5680E /* animator_hof.cpp */; };
- DF093FD20F63CB26002D821E /* animator_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421A50E7BA6A800F5680E /* animator_lok.cpp */; };
- DF093FD30F63CB26002D821E /* animator_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421A70E7BA6A800F5680E /* animator_mr.cpp */; };
- DF093FD40F63CB26002D821E /* animator_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421A90E7BA6A800F5680E /* animator_v2.cpp */; };
- DF093FD50F63CB26002D821E /* debugger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421AB0E7BA6A800F5680E /* debugger.cpp */; };
- DF093FD60F63CB26002D821E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421AD0E7BA6A800F5680E /* detection.cpp */; };
- DF093FD70F63CB26002D821E /* gui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421AE0E7BA6A800F5680E /* gui.cpp */; };
- DF093FD80F63CB26002D821E /* gui_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421B00E7BA6A800F5680E /* gui_hof.cpp */; };
- DF093FD90F63CB26002D821E /* gui_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421B20E7BA6A800F5680E /* gui_lok.cpp */; };
- DF093FDA0F63CB26002D821E /* gui_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421B40E7BA6A800F5680E /* gui_mr.cpp */; };
- DF093FDB0F63CB26002D821E /* gui_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421B70E7BA6A800F5680E /* gui_v2.cpp */; };
- DF093FDC0F63CB26002D821E /* items_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421BA0E7BA6A800F5680E /* items_hof.cpp */; };
- DF093FDD0F63CB26002D821E /* items_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421BB0E7BA6A800F5680E /* items_lok.cpp */; };
- DF093FDE0F63CB26002D821E /* items_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421BC0E7BA6A800F5680E /* items_mr.cpp */; };
- DF093FDF0F63CB26002D821E /* items_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421BE0E7BA6A800F5680E /* items_v2.cpp */; };
- DF093FE00F63CB26002D821E /* kyra_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421C10E7BA6A800F5680E /* kyra_hof.cpp */; };
- DF093FE10F63CB26002D821E /* kyra_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421C30E7BA6A800F5680E /* kyra_lok.cpp */; };
- DF093FE20F63CB26002D821E /* kyra_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421C50E7BA6A800F5680E /* kyra_mr.cpp */; };
- DF093FE30F63CB26002D821E /* kyra_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421C70E7BA6A800F5680E /* kyra_v1.cpp */; };
- DF093FE40F63CB26002D821E /* kyra_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421C90E7BA6A800F5680E /* kyra_v2.cpp */; };
- DF093FE50F63CB26002D821E /* lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421CC0E7BA6A800F5680E /* lol.cpp */; };
- DF093FE60F63CB26002D821E /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421CF0E7BA6A800F5680E /* resource.cpp */; };
- DF093FE70F63CB26002D821E /* resource_intern.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421D10E7BA6A800F5680E /* resource_intern.cpp */; };
- DF093FE80F63CB26002D821E /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421D30E7BA6A800F5680E /* saveload.cpp */; };
- DF093FE90F63CB26002D821E /* saveload_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421D40E7BA6A800F5680E /* saveload_hof.cpp */; };
- DF093FEA0F63CB26002D821E /* saveload_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421D50E7BA6A800F5680E /* saveload_lok.cpp */; };
- DF093FEB0F63CB26002D821E /* saveload_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421D60E7BA6A800F5680E /* saveload_mr.cpp */; };
- DF093FEC0F63CB26002D821E /* scene_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421DA0E7BA6A800F5680E /* scene_hof.cpp */; };
- DF093FED0F63CB26002D821E /* scene_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421DB0E7BA6A800F5680E /* scene_lok.cpp */; };
- DF093FEE0F63CB26002D821E /* scene_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421DC0E7BA6A800F5680E /* scene_mr.cpp */; };
- DF093FEF0F63CB26002D821E /* scene_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421DD0E7BA6A800F5680E /* scene_v1.cpp */; };
- DF093FF00F63CB26002D821E /* scene_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421DE0E7BA6A800F5680E /* scene_v2.cpp */; };
- DF093FF10F63CB26002D821E /* screen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421E00E7BA6A800F5680E /* screen.cpp */; };
- DF093FF20F63CB26002D821E /* screen_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421E20E7BA6A800F5680E /* screen_hof.cpp */; };
- DF093FF30F63CB26002D821E /* screen_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421E40E7BA6A800F5680E /* screen_lok.cpp */; };
- DF093FF40F63CB26002D821E /* screen_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421E60E7BA6A800F5680E /* screen_lol.cpp */; };
- DF093FF50F63CB26002D821E /* screen_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421E80E7BA6A800F5680E /* screen_mr.cpp */; };
- DF093FF60F63CB26002D821E /* screen_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421EB0E7BA6A800F5680E /* screen_v2.cpp */; };
- DF093FF70F63CB26002D821E /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421EE0E7BA6A800F5680E /* script.cpp */; };
- DF093FF80F63CB26002D821E /* script_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421F00E7BA6A800F5680E /* script_hof.cpp */; };
- DF093FF90F63CB26002D821E /* script_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421F10E7BA6A800F5680E /* script_lok.cpp */; };
- DF093FFA0F63CB26002D821E /* script_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421F20E7BA6A800F5680E /* script_mr.cpp */; };
- DF093FFB0F63CB26002D821E /* script_tim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421F30E7BA6A800F5680E /* script_tim.cpp */; };
- DF093FFC0F63CB26002D821E /* script_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421F50E7BA6A800F5680E /* script_v1.cpp */; };
- DF093FFD0F63CB26002D821E /* script_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421F60E7BA6A800F5680E /* script_v2.cpp */; };
- DF093FFE0F63CB26002D821E /* seqplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421F80E7BA6A800F5680E /* seqplayer.cpp */; };
- DF093FFF0F63CB26002D821E /* sequences_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421FA0E7BA6A800F5680E /* sequences_hof.cpp */; };
- DF0940000F63CB26002D821E /* sequences_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421FB0E7BA6A800F5680E /* sequences_lok.cpp */; };
- DF0940010F63CB26002D821E /* sequences_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421FC0E7BA6A800F5680E /* sequences_mr.cpp */; };
- DF0940020F63CB26002D821E /* sequences_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421FE0E7BA6A800F5680E /* sequences_v2.cpp */; };
- DF0940030F63CB26002D821E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422000E7BA6A800F5680E /* sound.cpp */; };
- DF0940040F63CB26002D821E /* sound_adlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422020E7BA6A800F5680E /* sound_adlib.cpp */; };
- DF0940050F63CB26002D821E /* sound_digital.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422030E7BA6A800F5680E /* sound_digital.cpp */; };
- DF0940060F63CB26002D821E /* sound_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422040E7BA6A800F5680E /* sound_lok.cpp */; };
- DF0940070F63CB26002D821E /* sound_towns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422050E7BA6A800F5680E /* sound_towns.cpp */; };
- DF0940080F63CB26002D821E /* sprites.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422070E7BA6A800F5680E /* sprites.cpp */; };
- DF0940090F63CB26002D821E /* staticres.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422090E7BA6A800F5680E /* staticres.cpp */; };
- DF09400A0F63CB26002D821E /* text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84220A0E7BA6A800F5680E /* text.cpp */; };
- DF09400B0F63CB26002D821E /* text_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84220C0E7BA6A800F5680E /* text_hof.cpp */; };
- DF09400C0F63CB26002D821E /* text_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84220E0E7BA6A800F5680E /* text_lok.cpp */; };
- DF09400D0F63CB26002D821E /* text_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84220F0E7BA6A800F5680E /* text_mr.cpp */; };
- DF09400E0F63CB26002D821E /* timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422140E7BA6A800F5680E /* timer.cpp */; };
- DF09400F0F63CB26002D821E /* timer_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422160E7BA6A800F5680E /* timer_hof.cpp */; };
- DF0940100F63CB26002D821E /* timer_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422170E7BA6A800F5680E /* timer_lok.cpp */; };
- DF0940110F63CB26002D821E /* timer_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422180E7BA6A800F5680E /* timer_mr.cpp */; };
- DF0940120F63CB26002D821E /* vqa.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84221C0E7BA6A800F5680E /* vqa.cpp */; };
- DF0940130F63CB26002D821E /* wsamovie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84221E0E7BA6A800F5680E /* wsamovie.cpp */; };
- DF0940140F63CB26002D821E /* animseq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422210E7BA6A800F5680E /* animseq.cpp */; };
- DF0940150F63CB26002D821E /* debugger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422230E7BA6A800F5680E /* debugger.cpp */; };
- DF0940160F63CB26002D821E /* decode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422250E7BA6A800F5680E /* decode.cpp */; };
- DF0940170F63CB26002D821E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422270E7BA6A800F5680E /* detection.cpp */; };
- DF0940180F63CB26002D821E /* disk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422280E7BA6A800F5680E /* disk.cpp */; };
- DF0940190F63CB26002D821E /* events.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84222A0E7BA6A800F5680E /* events.cpp */; };
- DF09401A0F63CB26002D821E /* fights.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84222C0E7BA6A800F5680E /* fights.cpp */; };
- DF09401B0F63CB26002D821E /* game.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84222E0E7BA6A800F5680E /* game.cpp */; };
- DF09401C0F63CB26002D821E /* hotspots.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422300E7BA6A800F5680E /* hotspots.cpp */; };
- DF09401D0F63CB26002D821E /* intro.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422320E7BA6A800F5680E /* intro.cpp */; };
- DF09401E0F63CB26002D821E /* lure.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422340E7BA6A800F5680E /* lure.cpp */; };
- DF09401F0F63CB26002D821E /* memory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422370E7BA6A800F5680E /* memory.cpp */; };
- DF0940200F63CB26002D821E /* menu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422390E7BA6A800F5680E /* menu.cpp */; };
- DF0940210F63CB26002D821E /* palette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84223C0E7BA6A800F5680E /* palette.cpp */; };
- DF0940220F63CB26002D821E /* res.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84223E0E7BA6A800F5680E /* res.cpp */; };
- DF0940230F63CB26002D821E /* res_struct.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422400E7BA6A800F5680E /* res_struct.cpp */; };
- DF0940240F63CB26002D821E /* room.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422420E7BA6A800F5680E /* room.cpp */; };
- DF0940250F63CB26002D821E /* screen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422440E7BA6A800F5680E /* screen.cpp */; };
- DF0940260F63CB26002D821E /* scripts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422460E7BA6A800F5680E /* scripts.cpp */; };
- DF0940270F63CB26002D821E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422480E7BA6A800F5680E /* sound.cpp */; };
- DF0940280F63CB26002D821E /* strings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84224A0E7BA6A800F5680E /* strings.cpp */; };
- DF0940290F63CB26002D821E /* surface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84224C0E7BA6A800F5680E /* surface.cpp */; };
- DF09402A0F63CB26002D821E /* actor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84226E0E7BA6A800F5680E /* actor.cpp */; };
- DF09402B0F63CB26002D821E /* animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422710E7BA6A800F5680E /* animation.cpp */; };
- DF09402C0F63CB26002D821E /* assets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422740E7BA6A800F5680E /* assets.cpp */; };
- DF09402D0F63CB26002D821E /* compression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422780E7BA6A900F5680E /* compression.cpp */; };
- DF09402E0F63CB26002D821E /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84227B0E7BA6A900F5680E /* console.cpp */; };
- DF09402F0F63CB26002D821E /* converse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84227E0E7BA6A900F5680E /* converse.cpp */; };
- DF0940300F63CB26002D821E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422810E7BA6A900F5680E /* detection.cpp */; };
- DF0940310F63CB26002D821E /* events.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422830E7BA6A900F5680E /* events.cpp */; };
- DF0940320F63CB26002D821E /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422860E7BA6A900F5680E /* font.cpp */; };
- DF0940330F63CB26002D821E /* globals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422890E7BA6A900F5680E /* globals.cpp */; };
- DF0940340F63CB26002D821E /* graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84228C0E7BA6A900F5680E /* graphics.cpp */; };
- DF0940350F63CB26002D821E /* gui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84228F0E7BA6A900F5680E /* gui.cpp */; };
- DF0940360F63CB26002D821E /* hotspot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422920E7BA6A900F5680E /* hotspot.cpp */; };
- DF0940370F63CB26002D821E /* m4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422960E7BA6A900F5680E /* m4.cpp */; };
- DF0940380F63CB26002D821E /* m4_menus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422990E7BA6A900F5680E /* m4_menus.cpp */; };
- DF0940390F63CB26002D821E /* m4_views.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84229C0E7BA6A900F5680E /* m4_views.cpp */; };
- DF09403A0F63CB26002D821E /* mads_anim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84229F0E7BA6A900F5680E /* mads_anim.cpp */; };
- DF09403B0F63CB26002D821E /* mads_menus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422A20E7BA6A900F5680E /* mads_menus.cpp */; };
- DF09403C0F63CB26002D821E /* midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422A50E7BA6A900F5680E /* midi.cpp */; };
- DF09403D0F63CB26002D821E /* rails.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422A90E7BA6A900F5680E /* rails.cpp */; };
- DF09403E0F63CB26002D821E /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422AC0E7BA6A900F5680E /* resource.cpp */; };
- DF09403F0F63CB26002D821E /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422AF0E7BA6A900F5680E /* saveload.cpp */; };
- DF0940400F63CB26002D821E /* scene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422B20E7BA6A900F5680E /* scene.cpp */; };
- DF0940410F63CB26002D821E /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422B50E7BA6A900F5680E /* script.cpp */; };
- DF0940420F63CB26002D821E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422B90E7BA6A900F5680E /* sound.cpp */; };
- DF0940430F63CB26002D821E /* sprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422BC0E7BA6A900F5680E /* sprite.cpp */; };
- DF0940440F63CB26002D821E /* viewmgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422BF0E7BA6A900F5680E /* viewmgr.cpp */; };
- DF0940450F63CB26002D821E /* woodscript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422C20E7BA6A900F5680E /* woodscript.cpp */; };
- DF0940460F63CB26002D821E /* ws_machine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422C50E7BA6A900F5680E /* ws_machine.cpp */; };
- DF0940470F63CB26002D821E /* ws_sequence.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422C70E7BA6A900F5680E /* ws_sequence.cpp */; };
- DF0940480F63CB26002D821E /* database.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422CA0E7BA6A900F5680E /* database.cpp */; };
- DF0940490F63CB26002D821E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422CC0E7BA6A900F5680E /* detection.cpp */; };
- DF09404A0F63CB26002D821E /* graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422CD0E7BA6A900F5680E /* graphics.cpp */; };
- DF09404B0F63CB26002D821E /* made.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422CF0E7BA6A900F5680E /* made.cpp */; };
- DF09404C0F63CB26002D821E /* music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422D20E7BA6A900F5680E /* music.cpp */; };
- DF09404D0F63CB26002D821E /* pmvplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422D40E7BA6A900F5680E /* pmvplayer.cpp */; };
- DF09404E0F63CB26002D821E /* redreader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422D60E7BA6A900F5680E /* redreader.cpp */; };
- DF09404F0F63CB26002D821E /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422D80E7BA6A900F5680E /* resource.cpp */; };
- DF0940500F63CB26002D821E /* screen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422DA0E7BA6A900F5680E /* screen.cpp */; };
- DF0940510F63CB26002D821E /* screenfx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422DC0E7BA6A900F5680E /* screenfx.cpp */; };
- DF0940520F63CB26002D821E /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422DE0E7BA6A900F5680E /* script.cpp */; };
- DF0940530F63CB26002D821E /* scriptfuncs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422E00E7BA6A900F5680E /* scriptfuncs.cpp */; };
- DF0940540F63CB26002D821E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422E20E7BA6A900F5680E /* sound.cpp */; };
- DF0940550F63CB26002D821E /* balloons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422E70E7BA6A900F5680E /* balloons.cpp */; };
- DF0940560F63CB26002D821E /* callables_br.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422E80E7BA6A900F5680E /* callables_br.cpp */; };
- DF0940570F63CB26002D821E /* callables_ns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422E90E7BA6A900F5680E /* callables_ns.cpp */; };
- DF0940580F63CB26002D821E /* debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422EA0E7BA6A900F5680E /* debug.cpp */; };
- DF0940590F63CB26002D821E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422EC0E7BA6A900F5680E /* detection.cpp */; };
- DF09405A0F63CB26002D821E /* dialogue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422ED0E7BA6A900F5680E /* dialogue.cpp */; };
- DF09405B0F63CB26002D821E /* disk_br.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422EF0E7BA6A900F5680E /* disk_br.cpp */; };
- DF09405C0F63CB26002D821E /* disk_ns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422F00E7BA6A900F5680E /* disk_ns.cpp */; };
- DF09405D0F63CB26002D821E /* exec_br.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422F20E7BA6A900F5680E /* exec_br.cpp */; };
- DF09405E0F63CB26002D821E /* exec_ns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422F30E7BA6A900F5680E /* exec_ns.cpp */; };
- DF09405F0F63CB26002D821E /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422F40E7BA6A900F5680E /* font.cpp */; };
- DF0940600F63CB26002D821E /* gfxbase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422F50E7BA6A900F5680E /* gfxbase.cpp */; };
- DF0940610F63CB26002D821E /* graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422F60E7BA6A900F5680E /* graphics.cpp */; };
- DF0940620F63CB26002D821E /* gui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422F80E7BA6A900F5680E /* gui.cpp */; };
- DF0940630F63CB26002D821E /* gui_br.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422FA0E7BA6A900F5680E /* gui_br.cpp */; };
- DF0940640F63CB26002D821E /* gui_ns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422FB0E7BA6A900F5680E /* gui_ns.cpp */; };
- DF0940650F63CB26002D821E /* input.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422FC0E7BA6A900F5680E /* input.cpp */; };
- DF0940660F63CB26002D821E /* inventory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422FE0E7BA6A900F5680E /* inventory.cpp */; };
- DF0940670F63CB26002D821E /* objects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423010E7BA6A900F5680E /* objects.cpp */; };
- DF0940680F63CB26002D821E /* parallaction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423030E7BA6A900F5680E /* parallaction.cpp */; };
- DF0940690F63CB26002D821E /* parallaction_br.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423050E7BA6A900F5680E /* parallaction_br.cpp */; };
- DF09406A0F63CB26002D821E /* parallaction_ns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423060E7BA6A900F5680E /* parallaction_ns.cpp */; };
- DF09406B0F63CB26002D821E /* parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423070E7BA6A900F5680E /* parser.cpp */; };
- DF09406C0F63CB26002D821E /* parser_br.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423090E7BA6A900F5680E /* parser_br.cpp */; };
- DF09406D0F63CB26002D821E /* parser_ns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84230A0E7BA6A900F5680E /* parser_ns.cpp */; };
- DF09406E0F63CB26002D821E /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84230B0E7BA6A900F5680E /* saveload.cpp */; };
- DF0940700F63CB26002D821E /* staticres.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84230F0E7BA6A900F5680E /* staticres.cpp */; };
- DF0940710F63CB26002D821E /* walk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423100E7BA6A900F5680E /* walk.cpp */; };
- DF0940720F63CB26002D821E /* bankman.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423130E7BA6A900F5680E /* bankman.cpp */; };
- DF0940730F63CB26002D821E /* command.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423150E7BA6A900F5680E /* command.cpp */; };
- DF0940740F63CB26002D821E /* credits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423170E7BA6A900F5680E /* credits.cpp */; };
- DF0940750F63CB26002D821E /* cutaway.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423190E7BA6A900F5680E /* cutaway.cpp */; };
- DF0940760F63CB26002D821E /* debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84231B0E7BA6A900F5680E /* debug.cpp */; };
- DF0940770F63CB26002D821E /* display.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84231E0E7BA6A900F5680E /* display.cpp */; };
- DF0940780F63CB26002D821E /* graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423200E7BA6A900F5680E /* graphics.cpp */; };
- DF0940790F63CB26002D821E /* grid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423220E7BA6A900F5680E /* grid.cpp */; };
- DF09407A0F63CB26002D821E /* input.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423240E7BA6A900F5680E /* input.cpp */; };
- DF09407B0F63CB26002D821E /* journal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423260E7BA6A900F5680E /* journal.cpp */; };
- DF09407C0F63CB26002D821E /* logic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423280E7BA6A900F5680E /* logic.cpp */; };
- DF09407D0F63CB26002D821E /* midiadlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84232A0E7BA6A900F5680E /* midiadlib.cpp */; };
- DF09407E0F63CB26002D821E /* music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84232C0E7BA6A900F5680E /* music.cpp */; };
- DF09407F0F63CB26002D821E /* musicdata.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84232E0E7BA6A900F5680E /* musicdata.cpp */; };
- DF0940800F63CB26002D821E /* queen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84232F0E7BA6A900F5680E /* queen.cpp */; };
- DF0940810F63CB26002D821E /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423310E7BA6A900F5680E /* resource.cpp */; };
- DF0940820F63CB26002D821E /* restables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423330E7BA6A900F5680E /* restables.cpp */; };
- DF0940830F63CB26002D821E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423340E7BA6A900F5680E /* sound.cpp */; };
- DF0940840F63CB26002D821E /* state.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423360E7BA6A900F5680E /* state.cpp */; };
- DF0940850F63CB26002D821E /* talk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423390E7BA6A900F5680E /* talk.cpp */; };
- DF0940860F63CB26002D821E /* walk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84233B0E7BA6A900F5680E /* walk.cpp */; };
- DF0940870F63CB26002D821E /* actor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84233F0E7BA6AA00F5680E /* actor.cpp */; };
- DF0940880F63CB26002D821E /* actor_path.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423410E7BA6AA00F5680E /* actor_path.cpp */; };
- DF0940890F63CB26002D821E /* actor_walk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423420E7BA6AA00F5680E /* actor_walk.cpp */; };
- DF09408A0F63CB26002D821E /* animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423430E7BA6AA00F5680E /* animation.cpp */; };
- DF09408B0F63CB26002D821E /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423450E7BA6AA00F5680E /* console.cpp */; };
- DF09408C0F63CB26002D821E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423470E7BA6AA00F5680E /* detection.cpp */; };
- DF09408D0F63CB26002D821E /* events.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84234A0E7BA6AA00F5680E /* events.cpp */; };
- DF09408E0F63CB26002D821E /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84234C0E7BA6AA00F5680E /* font.cpp */; };
- DF09408F0F63CB26002D821E /* font_map.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84234E0E7BA6AA00F5680E /* font_map.cpp */; };
- DF0940900F63CB26002D821E /* gfx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84234F0E7BA6AA00F5680E /* gfx.cpp */; };
- DF0940910F63CB26002D821E /* image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423520E7BA6AA00F5680E /* image.cpp */; };
- DF0940920F63CB26002D821E /* input.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423530E7BA6AA00F5680E /* input.cpp */; };
- DF0940930F63CB26002D821E /* interface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423540E7BA6AA00F5680E /* interface.cpp */; };
- DF0940940F63CB26002D821E /* introproc_ihnm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423560E7BA6AA00F5680E /* introproc_ihnm.cpp */; };
- DF0940950F63CB26002D821E /* introproc_ite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423570E7BA6AA00F5680E /* introproc_ite.cpp */; };
- DF0940960F63CB26002D821E /* isomap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423580E7BA6AA00F5680E /* isomap.cpp */; };
- DF0940970F63CB26002D821E /* itedata.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84235B0E7BA6AA00F5680E /* itedata.cpp */; };
- DF0940980F63CB26002D821E /* music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84235F0E7BA6AA00F5680E /* music.cpp */; };
- DF0940990F63CB26002D821E /* objectmap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423610E7BA6AA00F5680E /* objectmap.cpp */; };
- DF09409A0F63CB26002D821E /* palanim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423630E7BA6AA00F5680E /* palanim.cpp */; };
- DF09409B0F63CB26002D821E /* puzzle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423650E7BA6AA00F5680E /* puzzle.cpp */; };
- DF09409C0F63CB26002D821E /* render.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423670E7BA6AA00F5680E /* render.cpp */; };
- DF09409D0F63CB26002D821E /* saga.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84236B0E7BA6AA00F5680E /* saga.cpp */; };
- DF09409E0F63CB26002D821E /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84236D0E7BA6AA00F5680E /* saveload.cpp */; };
- DF09409F0F63CB26002D821E /* scene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84236E0E7BA6AA00F5680E /* scene.cpp */; };
- DF0940A00F63CB26002D821E /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423700E7BA6AA00F5680E /* script.cpp */; };
- DF0940A10F63CB26002D821E /* sfuncs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423720E7BA6AA00F5680E /* sfuncs.cpp */; };
- DF0940A20F63CB26002D821E /* sndres.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423730E7BA6AA00F5680E /* sndres.cpp */; };
- DF0940A30F63CB26002D821E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423750E7BA6AA00F5680E /* sound.cpp */; };
- DF0940A40F63CB26002D821E /* sprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423770E7BA6AA00F5680E /* sprite.cpp */; };
- DF0940A50F63CB26002D821E /* sthread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423790E7BA6AA00F5680E /* sthread.cpp */; };
- DF0940A60F63CB26002D821E /* actor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84237C0E7BA6AA00F5680E /* actor.cpp */; };
- DF0940A70F63CB26002D821E /* akos.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84237E0E7BA6AA00F5680E /* akos.cpp */; };
- DF0940A80F63CB26002D821E /* base-costume.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423800E7BA6AA00F5680E /* base-costume.cpp */; };
- DF0940A90F63CB26002D821E /* bomp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423820E7BA6AA00F5680E /* bomp.cpp */; };
- DF0940AA0F63CB26002D821E /* boxes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423840E7BA6AA00F5680E /* boxes.cpp */; };
- DF0940AB0F63CB26002D821E /* camera.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423860E7BA6AA00F5680E /* camera.cpp */; };
- DF0940AC0F63CB26002D821E /* charset-fontdata.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423870E7BA6AA00F5680E /* charset-fontdata.cpp */; };
- DF0940AD0F63CB26002D821E /* charset.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423880E7BA6AA00F5680E /* charset.cpp */; };
- DF0940AE0F63CB26002D821E /* costume.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84238A0E7BA6AA00F5680E /* costume.cpp */; };
- DF0940AF0F63CB26002D821E /* cursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84238C0E7BA6AA00F5680E /* cursor.cpp */; };
- DF0940B00F63CB26002D821E /* debugger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84238D0E7BA6AA00F5680E /* debugger.cpp */; };
- DF0940B10F63CB26002D821E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84238F0E7BA6AA00F5680E /* detection.cpp */; };
- DF0940B20F63CB26002D821E /* dialogs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423920E7BA6AA00F5680E /* dialogs.cpp */; };
- DF0940B30F63CB26002D821E /* file.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423940E7BA6AA00F5680E /* file.cpp */; };
- DF0940B40F63CB26002D821E /* file_nes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423960E7BA6AA00F5680E /* file_nes.cpp */; };
- DF0940B50F63CB26002D821E /* gfx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423980E7BA6AA00F5680E /* gfx.cpp */; };
- DF0940B60F63CB26002D821E /* animation_he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84239C0E7BA6AA00F5680E /* animation_he.cpp */; };
- DF0940B70F63CB26002D821E /* cup_player_he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84239E0E7BA6AA00F5680E /* cup_player_he.cpp */; };
- DF0940B80F63CB26002D821E /* floodfill_he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423A00E7BA6AA00F5680E /* floodfill_he.cpp */; };
- DF0940B90F63CB26002D821E /* logic_he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423A30E7BA6AA00F5680E /* logic_he.cpp */; };
- DF0940BA0F63CB26002D821E /* palette_he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423A50E7BA6AA00F5680E /* palette_he.cpp */; };
- DF0940BB0F63CB26002D821E /* resource_he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423A60E7BA6AA00F5680E /* resource_he.cpp */; };
- DF0940BC0F63CB26002D821E /* script_v100he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423A80E7BA6AA00F5680E /* script_v100he.cpp */; };
- DF0940BD0F63CB26002D821E /* script_v60he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423A90E7BA6AA00F5680E /* script_v60he.cpp */; };
- DF0940BE0F63CB26002D821E /* script_v70he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423AA0E7BA6AA00F5680E /* script_v70he.cpp */; };
- DF0940BF0F63CB26002D821E /* script_v71he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423AB0E7BA6AA00F5680E /* script_v71he.cpp */; };
- DF0940C00F63CB26002D821E /* script_v72he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423AC0E7BA6AA00F5680E /* script_v72he.cpp */; };
- DF0940C10F63CB26002D821E /* script_v80he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423AD0E7BA6AA00F5680E /* script_v80he.cpp */; };
- DF0940C20F63CB26002D821E /* script_v90he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423AE0E7BA6AA00F5680E /* script_v90he.cpp */; };
- DF0940C30F63CB26002D821E /* sound_he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423AF0E7BA6AA00F5680E /* sound_he.cpp */; };
- DF0940C40F63CB26002D821E /* sprite_he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423B10E7BA6AA00F5680E /* sprite_he.cpp */; };
- DF0940C50F63CB26002D821E /* wiz_he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423B30E7BA6AA00F5680E /* wiz_he.cpp */; };
- DF0940C60F63CB26002D821E /* help.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423B50E7BA6AA00F5680E /* help.cpp */; };
- DF0940C70F63CB26002D821E /* imuse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423B80E7BA6AA00F5680E /* imuse.cpp */; };
- DF0940C80F63CB26002D821E /* imuse_part.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423BB0E7BA6AA00F5680E /* imuse_part.cpp */; };
- DF0940C90F63CB26002D821E /* imuse_player.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423BC0E7BA6AA00F5680E /* imuse_player.cpp */; };
- DF0940CA0F63CB26002D821E /* instrument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423BD0E7BA6AA00F5680E /* instrument.cpp */; };
- DF0940CB0F63CB26002D821E /* sysex_samnmax.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423C00E7BA6AA00F5680E /* sysex_samnmax.cpp */; };
- DF0940CC0F63CB26002D821E /* sysex_scumm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423C10E7BA6AA00F5680E /* sysex_scumm.cpp */; };
- DF0940CD0F63CB26002D821E /* dimuse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423C30E7BA6AA00F5680E /* dimuse.cpp */; };
- DF0940CE0F63CB26002D821E /* dimuse_bndmgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423C50E7BA6AA00F5680E /* dimuse_bndmgr.cpp */; };
- DF0940CF0F63CB26002D821E /* dimuse_codecs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423C70E7BA6AA00F5680E /* dimuse_codecs.cpp */; };
- DF0940D00F63CB26002D821E /* dimuse_music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423C80E7BA6AA00F5680E /* dimuse_music.cpp */; };
- DF0940D10F63CB26002D821E /* dimuse_script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423C90E7BA6AA00F5680E /* dimuse_script.cpp */; };
- DF0940D20F63CB26002D821E /* dimuse_sndmgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423CA0E7BA6AA00F5680E /* dimuse_sndmgr.cpp */; };
- DF0940D30F63CB26002D821E /* dimuse_tables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423CC0E7BA6AA00F5680E /* dimuse_tables.cpp */; };
- DF0940D40F63CB26002D821E /* dimuse_track.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423CE0E7BA6AA00F5680E /* dimuse_track.cpp */; };
- DF0940D50F63CB26002D821E /* input.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423D00E7BA6AA00F5680E /* input.cpp */; };
- DF0940D60F63CB26002D821E /* insane.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423D20E7BA6AA00F5680E /* insane.cpp */; };
- DF0940D70F63CB26002D821E /* insane_ben.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423D40E7BA6AA00F5680E /* insane_ben.cpp */; };
- DF0940D80F63CB26002D821E /* insane_enemy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423D50E7BA6AA00F5680E /* insane_enemy.cpp */; };
- DF0940D90F63CB26002D821E /* insane_iact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423D60E7BA6AA00F5680E /* insane_iact.cpp */; };
- DF0940DA0F63CB26002D821E /* insane_scenes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423D70E7BA6AA00F5680E /* insane_scenes.cpp */; };
- DF0940DC0F63CB26002D821E /* midiparser_ro.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423DA0E7BA6AA00F5680E /* midiparser_ro.cpp */; };
- DF0940DD0F63CB26002D821E /* nut_renderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423DD0E7BA6AA00F5680E /* nut_renderer.cpp */; };
- DF0940DE0F63CB26002D821E /* object.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423DF0E7BA6AA00F5680E /* object.cpp */; };
- DF0940DF0F63CB26002D821E /* palette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423E10E7BA6AA00F5680E /* palette.cpp */; };
- DF0940E00F63CB26002D821E /* player_mod.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423E20E7BA6AA00F5680E /* player_mod.cpp */; };
- DF0940E10F63CB26002D821E /* player_nes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423E40E7BA6AA00F5680E /* player_nes.cpp */; };
- DF0940E20F63CB26002D821E /* player_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423E60E7BA6AA00F5680E /* player_v1.cpp */; };
- DF0940E30F63CB26002D821E /* player_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423E80E7BA6AA00F5680E /* player_v2.cpp */; };
- DF0940E40F63CB26002D821E /* player_v2a.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423EA0E7BA6AA00F5680E /* player_v2a.cpp */; };
- DF0940E50F63CB26002D821E /* player_v3a.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423EC0E7BA6AA00F5680E /* player_v3a.cpp */; };
- DF0940E60F63CB26002D821E /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423EF0E7BA6AA00F5680E /* resource.cpp */; };
- DF0940E70F63CB26002D821E /* resource_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423F10E7BA6AA00F5680E /* resource_v2.cpp */; };
- DF0940E80F63CB26002D821E /* resource_v3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423F20E7BA6AA00F5680E /* resource_v3.cpp */; };
- DF0940E90F63CB26002D821E /* resource_v4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423F30E7BA6AA00F5680E /* resource_v4.cpp */; };
- DF0940EA0F63CB26002D821E /* room.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423F40E7BA6AA00F5680E /* room.cpp */; };
- DF0940EB0F63CB26002D821E /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423F50E7BA6AA00F5680E /* saveload.cpp */; };
- DF0940EC0F63CB26002D821E /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423F70E7BA6AA00F5680E /* script.cpp */; };
- DF0940ED0F63CB26002D821E /* script_v0.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423F90E7BA6AA00F5680E /* script_v0.cpp */; };
- DF0940EE0F63CB26002D821E /* script_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423FA0E7BA6AA00F5680E /* script_v2.cpp */; };
- DF0940EF0F63CB26002D821E /* script_v5.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423FB0E7BA6AA00F5680E /* script_v5.cpp */; };
- DF0940F00F63CB26002D821E /* script_v6.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423FC0E7BA6AA00F5680E /* script_v6.cpp */; };
- DF0940F10F63CB26002D821E /* script_v8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423FD0E7BA6AA00F5680E /* script_v8.cpp */; };
- DF0940F20F63CB26002D821E /* scumm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423FF0E7BA6AA00F5680E /* scumm.cpp */; };
- DF0940F30F63CB26002D821E /* channel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424020E7BA6AA00F5680E /* channel.cpp */; };
- DF0940F40F63CB26002D821E /* codec1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424060E7BA6AA00F5680E /* codec1.cpp */; };
- DF0940F50F63CB26002D821E /* codec37.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424070E7BA6AA00F5680E /* codec37.cpp */; };
- DF0940F60F63CB26002D821E /* codec47.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424090E7BA6AA00F5680E /* codec47.cpp */; };
- DF0940F70F63CB26002D821E /* imuse_channel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84240D0E7BA6AA00F5680E /* imuse_channel.cpp */; };
- DF0940F80F63CB26002D821E /* saud_channel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84240E0E7BA6AA00F5680E /* saud_channel.cpp */; };
- DF0940F90F63CB26002D821E /* smush_font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84240F0E7BA6AA00F5680E /* smush_font.cpp */; };
- DF0940FA0F63CB26002D821E /* smush_mixer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424110E7BA6AA00F5680E /* smush_mixer.cpp */; };
- DF0940FB0F63CB26002D821E /* smush_player.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424130E7BA6AA00F5680E /* smush_player.cpp */; };
- DF0940FC0F63CB26002D821E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424150E7BA6AB00F5680E /* sound.cpp */; };
- DF0940FD0F63CB26002D821E /* string.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424170E7BA6AB00F5680E /* string.cpp */; };
- DF0940FE0F63CB26002D821E /* usage_bits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424190E7BA6AB00F5680E /* usage_bits.cpp */; };
- DF0940FF0F63CB26002D821E /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84241B0E7BA6AB00F5680E /* util.cpp */; };
- DF0941000F63CB26002D821E /* vars.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84241D0E7BA6AB00F5680E /* vars.cpp */; };
- DF0941010F63CB26002D821E /* verbs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84241E0E7BA6AB00F5680E /* verbs.cpp */; };
- DF0941020F63CB26002D821E /* autoroute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424210E7BA6AB00F5680E /* autoroute.cpp */; };
- DF0941030F63CB26002D821E /* compact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424230E7BA6AB00F5680E /* compact.cpp */; };
- DF0941040F63CB26002D821E /* control.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424250E7BA6AB00F5680E /* control.cpp */; };
- DF0941050F63CB26002D821E /* debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424270E7BA6AB00F5680E /* debug.cpp */; };
- DF0941060F63CB26002D821E /* disk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424290E7BA6AB00F5680E /* disk.cpp */; };
- DF0941070F63CB26002D821E /* grid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84242B0E7BA6AB00F5680E /* grid.cpp */; };
- DF0941080F63CB26002D821E /* hufftext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84242D0E7BA6AB00F5680E /* hufftext.cpp */; };
- DF0941090F63CB26002D821E /* intro.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84242E0E7BA6AB00F5680E /* intro.cpp */; };
- DF09410A0F63CB26002D821E /* logic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424300E7BA6AB00F5680E /* logic.cpp */; };
- DF09410B0F63CB26002D821E /* mouse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424330E7BA6AB00F5680E /* mouse.cpp */; };
- DF09410C0F63CB26002D821E /* adlibchannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424360E7BA6AB00F5680E /* adlibchannel.cpp */; };
- DF09410D0F63CB26002D821E /* adlibmusic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424380E7BA6AB00F5680E /* adlibmusic.cpp */; };
- DF09410E0F63CB26002D821E /* gmchannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84243A0E7BA6AB00F5680E /* gmchannel.cpp */; };
- DF09410F0F63CB26002D821E /* gmmusic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84243C0E7BA6AB00F5680E /* gmmusic.cpp */; };
- DF0941100F63CB26002D821E /* mt32music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84243E0E7BA6AB00F5680E /* mt32music.cpp */; };
- DF0941110F63CB26002D821E /* musicbase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424400E7BA6AB00F5680E /* musicbase.cpp */; };
- DF0941120F63CB26002D821E /* rnc_deco.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424420E7BA6AB00F5680E /* rnc_deco.cpp */; };
- DF0941130F63CB26002D821E /* screen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424440E7BA6AB00F5680E /* screen.cpp */; };
- DF0941140F63CB26002D821E /* sky.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424460E7BA6AB00F5680E /* sky.cpp */; };
- DF0941150F63CB26002D821E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424490E7BA6AB00F5680E /* sound.cpp */; };
- DF0941160F63CB26002D821E /* text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84244C0E7BA6AB00F5680E /* text.cpp */; };
- DF0941170F63CB26002D821E /* animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84244F0E7BA6AB00F5680E /* animation.cpp */; };
- DF0941180F63CB26002D821E /* control.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424520E7BA6AB00F5680E /* control.cpp */; };
- DF0941190F63CB26002D821E /* debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424560E7BA6AB00F5680E /* debug.cpp */; };
- DF09411A0F63CB26002D821E /* eventman.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424580E7BA6AB00F5680E /* eventman.cpp */; };
- DF09411B0F63CB26002D821E /* logic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84245A0E7BA6AB00F5680E /* logic.cpp */; };
- DF09411C0F63CB26002D821E /* memman.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84245C0E7BA6AB00F5680E /* memman.cpp */; };
- DF09411D0F63CB26002D821E /* menu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84245E0E7BA6AB00F5680E /* menu.cpp */; };
- DF09411E0F63CB26002D821E /* mouse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424610E7BA6AB00F5680E /* mouse.cpp */; };
- DF09411F0F63CB26002D821E /* music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424630E7BA6AB00F5680E /* music.cpp */; };
- DF0941200F63CB26002D821E /* objectman.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424660E7BA6AB00F5680E /* objectman.cpp */; };
- DF0941210F63CB26002D821E /* resman.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424680E7BA6AB00F5680E /* resman.cpp */; };
- DF0941220F63CB26002D821E /* router.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84246A0E7BA6AB00F5680E /* router.cpp */; };
- DF0941230F63CB26002D821E /* screen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84246C0E7BA6AB00F5680E /* screen.cpp */; };
- DF0941240F63CB26002D821E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84246E0E7BA6AB00F5680E /* sound.cpp */; };
- DF0941250F63CB26002D821E /* staticres.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424700E7BA6AB00F5680E /* staticres.cpp */; };
- DF0941260F63CB26002D821E /* sword1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424710E7BA6AB00F5680E /* sword1.cpp */; };
- DF0941270F63CB26002D821E /* text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424750E7BA6AB00F5680E /* text.cpp */; };
- DF0941280F63CB26002D821E /* animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424780E7BA6AB00F5680E /* animation.cpp */; };
- DF0941290F63CB26002D821E /* anims.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84247A0E7BA6AB00F5680E /* anims.cpp */; };
- DF09412A0F63CB26002D821E /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84247B0E7BA6AB00F5680E /* console.cpp */; };
- DF09412B0F63CB26002D821E /* controls.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84247D0E7BA6AB00F5680E /* controls.cpp */; };
- DF09412C0F63CB26002D821E /* debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84247F0E7BA6AB00F5680E /* debug.cpp */; };
- DF09412D0F63CB26002D821E /* events.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424820E7BA6AB00F5680E /* events.cpp */; };
- DF09412E0F63CB26002D821E /* function.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424830E7BA6AB00F5680E /* function.cpp */; };
- DF09412F0F63CB26002D821E /* icons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424850E7BA6AB00F5680E /* icons.cpp */; };
- DF0941300F63CB26002D821E /* interpreter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424860E7BA6AB00F5680E /* interpreter.cpp */; };
- DF0941310F63CB26002D821E /* layers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424880E7BA6AB00F5680E /* layers.cpp */; };
- DF0941320F63CB26002D821E /* logic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424890E7BA6AB00F5680E /* logic.cpp */; };
- DF0941330F63CB26002D821E /* maketext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84248B0E7BA6AB00F5680E /* maketext.cpp */; };
- DF0941340F63CB26002D821E /* memory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84248D0E7BA6AB00F5680E /* memory.cpp */; };
- DF0941350F63CB26002D821E /* menu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84248F0E7BA6AB00F5680E /* menu.cpp */; };
- DF0941360F63CB26002D821E /* mouse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424910E7BA6AB00F5680E /* mouse.cpp */; };
- DF0941370F63CB26002D821E /* music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424930E7BA6AB00F5680E /* music.cpp */; };
- DF0941380F63CB26002D821E /* palette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424950E7BA6AB00F5680E /* palette.cpp */; };
- DF0941390F63CB26002D821E /* protocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424960E7BA6AB00F5680E /* protocol.cpp */; };
- DF09413A0F63CB26002D821E /* render.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424970E7BA6AB00F5680E /* render.cpp */; };
- DF09413B0F63CB26002D821E /* resman.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424980E7BA6AB00F5680E /* resman.cpp */; };
- DF09413C0F63CB26002D821E /* router.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84249A0E7BA6AB00F5680E /* router.cpp */; };
- DF09413D0F63CB26002D821E /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84249C0E7BA6AB00F5680E /* saveload.cpp */; };
- DF09413E0F63CB26002D821E /* screen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84249E0E7BA6AB00F5680E /* screen.cpp */; };
- DF09413F0F63CB26002D821E /* scroll.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424A00E7BA6AB00F5680E /* scroll.cpp */; };
- DF0941400F63CB26002D821E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424A10E7BA6AB00F5680E /* sound.cpp */; };
- DF0941410F63CB26002D821E /* speech.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424A30E7BA6AB00F5680E /* speech.cpp */; };
- DF0941420F63CB26002D821E /* sprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424A40E7BA6AB00F5680E /* sprite.cpp */; };
- DF0941430F63CB26002D821E /* startup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424A50E7BA6AB00F5680E /* startup.cpp */; };
- DF0941440F63CB26002D821E /* sword2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424A60E7BA6AB00F5680E /* sword2.cpp */; };
- DF0941450F63CB26002D821E /* sync.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424A80E7BA6AB00F5680E /* sync.cpp */; };
- DF0941460F63CB26002D821E /* walker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424A90E7BA6AB00F5680E /* walker.cpp */; };
- DF0941470F63CB26002D821E /* actors.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424AB0E7BA6AB00F5680E /* actors.cpp */; };
- DF0941480F63CB26002D821E /* anim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424AD0E7BA6AB00F5680E /* anim.cpp */; };
- DF0941490F63CB26002D821E /* background.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424AF0E7BA6AB00F5680E /* background.cpp */; };
- DF09414A0F63CB26002D821E /* bg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424B10E7BA6AB00F5680E /* bg.cpp */; };
- DF09414B0F63CB26002D821E /* cliprect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424B20E7BA6AB00F5680E /* cliprect.cpp */; };
- DF09414C0F63CB26002D821E /* config.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424B40E7BA6AB00F5680E /* config.cpp */; };
- DF09414D0F63CB26002D821E /* cursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424B70E7BA6AB00F5680E /* cursor.cpp */; };
- DF09414E0F63CB26002D821E /* debugger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424B90E7BA6AB00F5680E /* debugger.cpp */; };
- DF09414F0F63CB26002D821E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424BB0E7BA6AB00F5680E /* detection.cpp */; };
- DF0941500F63CB26002D821E /* effect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424BD0E7BA6AB00F5680E /* effect.cpp */; };
- DF0941510F63CB26002D821E /* events.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424BE0E7BA6AB00F5680E /* events.cpp */; };
- DF0941520F63CB26002D821E /* faders.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424C00E7BA6AB00F5680E /* faders.cpp */; };
- DF0941530F63CB26002D821E /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424C30E7BA6AB00F5680E /* font.cpp */; };
- DF0941540F63CB26002D821E /* graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424C50E7BA6AB00F5680E /* graphics.cpp */; };
- DF0941550F63CB26002D821E /* handle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424C70E7BA6AB00F5680E /* handle.cpp */; };
- DF0941560F63CB26002D821E /* heapmem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424C90E7BA6AB00F5680E /* heapmem.cpp */; };
- DF0941570F63CB26002D821E /* mareels.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424CD0E7BA6AB00F5680E /* mareels.cpp */; };
- DF0941580F63CB26002D821E /* move.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424CF0E7BA6AB00F5680E /* move.cpp */; };
- DF0941590F63CB26002D821E /* multiobj.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424D10E7BA6AB00F5680E /* multiobj.cpp */; };
- DF09415A0F63CB26002D821E /* music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424D30E7BA6AB00F5680E /* music.cpp */; };
- DF09415B0F63CB26002D821E /* object.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424D50E7BA6AB00F5680E /* object.cpp */; };
- DF09415C0F63CB26002D821E /* palette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424D70E7BA6AB00F5680E /* palette.cpp */; };
- DF09415D0F63CB26002D821E /* pcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424D90E7BA6AB00F5680E /* pcode.cpp */; };
- DF09415E0F63CB26002D821E /* pdisplay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424DB0E7BA6AB00F5680E /* pdisplay.cpp */; };
- DF09415F0F63CB26002D821E /* play.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424DD0E7BA6AB00F5680E /* play.cpp */; };
- DF0941600F63CB26002D821E /* polygons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424DE0E7BA6AB00F5680E /* polygons.cpp */; };
- DF0941610F63CB26002D821E /* rince.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424E00E7BA6AB00F5680E /* rince.cpp */; };
- DF0941620F63CB26002D821E /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424E20E7BA6AB00F5680E /* saveload.cpp */; };
- DF0941630F63CB26002D821E /* savescn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424E30E7BA6AB00F5680E /* savescn.cpp */; };
- DF0941640F63CB26002D821E /* scene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424E50E7BA6AB00F5680E /* scene.cpp */; };
- DF0941650F63CB26002D821E /* sched.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424E70E7BA6AB00F5680E /* sched.cpp */; };
- DF0941660F63CB26002D821E /* scn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424E90E7BA6AB00F5680E /* scn.cpp */; };
- DF0941670F63CB26002D821E /* scroll.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424EB0E7BA6AB00F5680E /* scroll.cpp */; };
- DF0941680F63CB26002D821E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424EE0E7BA6AB00F5680E /* sound.cpp */; };
- DF0941690F63CB26002D821E /* strres.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424F00E7BA6AB00F5680E /* strres.cpp */; };
- DF09416A0F63CB26002D821E /* text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424F20E7BA6AB00F5680E /* text.cpp */; };
- DF09416B0F63CB26002D821E /* timers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424F40E7BA6AB00F5680E /* timers.cpp */; };
- DF09416C0F63CB26002D821E /* tinlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424F60E7BA6AB00F5680E /* tinlib.cpp */; };
- DF09416D0F63CB26002D821E /* tinsel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424F80E7BA6AB00F5680E /* tinsel.cpp */; };
- DF09416E0F63CB26002D821E /* token.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424FA0E7BA6AB00F5680E /* token.cpp */; };
- DF09416F0F63CB26002D821E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424FD0E7BA6AB00F5680E /* detection.cpp */; };
- DF0941700F63CB26002D821E /* graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424FE0E7BA6AB00F5680E /* graphics.cpp */; };
- DF0941710F63CB26002D821E /* menu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8425000E7BA6AB00F5680E /* menu.cpp */; };
- DF0941720F63CB26002D821E /* midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8425010E7BA6AB00F5680E /* midi.cpp */; };
- DF0941730F63CB26002D821E /* opcodes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8425040E7BA6AB00F5680E /* opcodes.cpp */; };
- DF0941740F63CB26002D821E /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8425050E7BA6AB00F5680E /* resource.cpp */; };
- DF0941750F63CB26002D821E /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8425060E7BA6AB00F5680E /* saveload.cpp */; };
- DF0941760F63CB26002D821E /* staticres.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8425070E7BA6AB00F5680E /* staticres.cpp */; };
- DF0941770F63CB26002D821E /* touche.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8425080E7BA6AB00F5680E /* touche.cpp */; };
- DF0941790F63CB26002D821E /* timidity.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF842A3D0E7BBB5000F5680E /* timidity.cpp */; };
- DF09417A0F63CB26002D821E /* archive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF842A400E7BBBB400F5680E /* archive.cpp */; };
- DF09417B0F63CB26002D821E /* unarj.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF842A450E7BBBB400F5680E /* unarj.cpp */; };
- DF09417C0F63CB26002D821E /* stdiostream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF842A6B0E7BBD5700F5680E /* stdiostream.cpp */; };
- DF09417E0F63CB26002D821E /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8BF00ED5FC77001CB19F /* saveload.cpp */; };
- DF09417F0F63CB26002D821E /* ThemeEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8BF40ED5FC77001CB19F /* ThemeEngine.cpp */; };
- DF0941800F63CB26002D821E /* ThemeEval.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8BF60ED5FC77001CB19F /* ThemeEval.cpp */; };
- DF0941810F63CB26002D821E /* ThemeLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8BF80ED5FC77001CB19F /* ThemeLayout.cpp */; };
- DF0941820F63CB26002D821E /* ThemeParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8BFA0ED5FC77001CB19F /* ThemeParser.cpp */; };
- DF0941830F63CB26002D821E /* thumbnail.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8C050ED5FCAF001CB19F /* thumbnail.cpp */; };
- DF0941840F63CB26002D821E /* VectorRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8C070ED5FCAF001CB19F /* VectorRenderer.cpp */; };
- DF0941850F63CB26002D821E /* VectorRendererSpec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8C090ED5FCAF001CB19F /* VectorRendererSpec.cpp */; };
- DF0941860F63CB26002D821E /* xmlparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8C0F0ED5FCC2001CB19F /* xmlparser.cpp */; };
- DF0941870F63CB26002D821E /* game.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8C510ED60067001CB19F /* game.cpp */; };
- DF0941880F63CB26002D821E /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFAAAFF50F0112AD003E9390 /* saveload.cpp */; };
- DF0941890F63CB26002D821E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFAAAFF80F0112C1003E9390 /* detection.cpp */; };
- DF09418A0F63CB26002D821E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFAAAFFB0F0112DF003E9390 /* detection.cpp */; };
- DF09418B0F63CB26002D821E /* thumbnail_intern.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFAAB0010F011392003E9390 /* thumbnail_intern.cpp */; };
- DF09418C0F63CB26002D821E /* dither.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFB900F485D890006E566 /* dither.cpp */; };
- DF0941920F63CB26002D821E /* debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFBD10F485DFB0006E566 /* debug.cpp */; };
- DF0941940F63CB26002D821E /* posix-saves.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFBF80F4860A60006E566 /* posix-saves.cpp */; };
- DF0941950F63CB26002D821E /* bmv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC1F0F4862520006E566 /* bmv.cpp */; };
- DF0941960F63CB26002D821E /* dialogs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC200F4862520006E566 /* dialogs.cpp */; };
- DF0941970F63CB26002D821E /* drives.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC220F4862520006E566 /* drives.cpp */; };
- DF0941980F63CB26002D821E /* sysvar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC270F4862520006E566 /* sysvar.cpp */; };
- DF0941990F63CB26002D821E /* gui_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC2E0F48628A0006E566 /* gui_lol.cpp */; };
- DF09419A0F63CB26002D821E /* items_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC300F48628A0006E566 /* items_lol.cpp */; };
- DF09419B0F63CB26002D821E /* script_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC310F48628A0006E566 /* script_lol.cpp */; };
- DF09419C0F63CB26002D821E /* sequences_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC320F48628A0006E566 /* sequences_lol.cpp */; };
- DF09419D0F63CB26002D821E /* sound_midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC330F48628A0006E566 /* sound_midi.cpp */; };
- DF09419E0F63CB26002D821E /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC360F48628A0006E566 /* util.cpp */; };
- DF0941A20F63CB26002D821E /* scene_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC490F4863100006E566 /* scene_lol.cpp */; };
- DF0941A30F63CB26002D821E /* advancedDetector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC4C0F4863560006E566 /* advancedDetector.cpp */; };
- DF0941A40F63CB26002D821E /* base-backend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC5B0F4866E70006E566 /* base-backend.cpp */; };
- DF0941A60F63CB26002D821E /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC600F48672D0006E566 /* resource.cpp */; };
- DF0941A70F63CB26002D821E /* resource_hrs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC620F48672D0006E566 /* resource_hrs.cpp */; };
- DF0941A80F63CB26002D821E /* resource_res.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC630F48672D0006E566 /* resource_res.cpp */; };
- DF0941A90F63CB26002D821E /* resource_rsc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC640F48672D0006E566 /* resource_rsc.cpp */; };
- DF0941AA0F63CB26002D821E /* sfuncs_ihnm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC650F48672D0006E566 /* sfuncs_ihnm.cpp */; };
- DF0941AB0F63CB26002D821E /* debugger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC700F4867910006E566 /* debugger.cpp */; };
- DF0941AC0F63CB26002D821E /* staticres.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC720F4867910006E566 /* staticres.cpp */; };
- DF0941AD0F63CB26002D821E /* cell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCBD0F4870690006E566 /* cell.cpp */; };
- DF0941AE0F63CB26002D821E /* cursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCBF0F4870690006E566 /* cursor.cpp */; };
- DF0941AF0F63CB26002D821E /* debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCC10F4870690006E566 /* debug.cpp */; };
- DF0941B00F63CB26002D821E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCC30F4870690006E566 /* detection.cpp */; };
- DF0941B10F63CB26002D821E /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCC40F4870690006E566 /* font.cpp */; };
- DF0941B20F63CB26002D821E /* graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCC60F4870690006E566 /* graphics.cpp */; };
- DF0941B30F63CB26002D821E /* groovie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCC80F4870690006E566 /* groovie.cpp */; };
- DF0941B40F63CB26002D821E /* lzss.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCCA0F4870690006E566 /* lzss.cpp */; };
- DF0941B50F63CB26002D821E /* music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCCD0F4870690006E566 /* music.cpp */; };
- DF0941B60F63CB26002D821E /* player.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCCF0F4870690006E566 /* player.cpp */; };
- DF0941B70F63CB26002D821E /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCD10F4870690006E566 /* resource.cpp */; };
- DF0941B80F63CB26002D821E /* roq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCD30F4870690006E566 /* roq.cpp */; };
- DF0941B90F63CB26002D821E /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCD50F4870690006E566 /* saveload.cpp */; };
- DF0941BA0F63CB26002D821E /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCD70F4870690006E566 /* script.cpp */; };
- DF0941BB0F63CB26002D821E /* vdx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCD90F4870690006E566 /* vdx.cpp */; };
- DF0941BC0F63CB26002D821E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFD050F4870E50006E566 /* detection.cpp */; };
- DF0941BD0F63CB26002D821E /* graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFD060F4870E50006E566 /* graphics.cpp */; };
- DF0941BE0F63CB26002D821E /* locations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFD080F4870E50006E566 /* locations.cpp */; };
- DF0941BF0F63CB26002D821E /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFD0A0F4870E50006E566 /* resource.cpp */; };
- DF0941C00F63CB26002D821E /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFD0B0F4870E50006E566 /* saveload.cpp */; };
- DF0941C10F63CB26002D821E /* sequences.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFD0C0F4870E50006E566 /* sequences.cpp */; };
- DF0941C20F63CB26002D821E /* staticres.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFD0D0F4870E50006E566 /* staticres.cpp */; };
- DF0941C30F63CB26002D821E /* tucker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFD0E0F4870E50006E566 /* tucker.cpp */; };
- DF0941C40F63CB26002D821E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8301A0F48AF18005EF03C /* detection.cpp */; };
- DF0941C60F63CB26002D821E /* gc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8301E0F48AF18005EF03C /* gc.cpp */; };
- DF0941C80F63CB26002D821E /* kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830230F48AF18005EF03C /* kernel.cpp */; };
- DF0941C90F63CB26002D821E /* kevent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830260F48AF18005EF03C /* kevent.cpp */; };
- DF0941CA0F63CB26002D821E /* kfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830270F48AF18005EF03C /* kfile.cpp */; };
- DF0941CB0F63CB26002D821E /* kgraphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830280F48AF18005EF03C /* kgraphics.cpp */; };
- DF0941CC0F63CB26002D821E /* klists.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830290F48AF18005EF03C /* klists.cpp */; };
- DF0941CD0F63CB26002D821E /* kmath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8302A0F48AF18005EF03C /* kmath.cpp */; };
- DF0941CE0F63CB26002D821E /* kmenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8302B0F48AF18005EF03C /* kmenu.cpp */; };
- DF0941CF0F63CB26002D821E /* kmovement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8302C0F48AF18005EF03C /* kmovement.cpp */; };
- DF0941D00F63CB26002D821E /* kpathing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8302D0F48AF18005EF03C /* kpathing.cpp */; };
- DF0941D10F63CB26002D821E /* kscripts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8302E0F48AF18005EF03C /* kscripts.cpp */; };
- DF0941D20F63CB26002D821E /* ksound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8302F0F48AF18005EF03C /* ksound.cpp */; };
- DF0941D30F63CB26002D821E /* kstring.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830300F48AF18005EF03C /* kstring.cpp */; };
- DF0941D40F63CB26002D821E /* message.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830310F48AF18005EF03C /* message.cpp */; };
- DF0941D60F63CB26002D821E /* savegame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830360F48AF18005EF03C /* savegame.cpp */; };
- DF0941D80F63CB26002D821E /* scriptdebug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830390F48AF18005EF03C /* scriptdebug.cpp */; };
- DF0941D90F63CB26002D821E /* seg_manager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8303A0F48AF18005EF03C /* seg_manager.cpp */; };
- DF0941DA0F63CB26002D821E /* vm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8303C0F48AF18005EF03C /* vm.cpp */; };
- DF0941EC0F63CB26002D821E /* sci.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830960F48AF18005EF03C /* sci.cpp */; };
- DF0942020F63CB26002D821E /* unzip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473C10D81F4E800B6D1FB /* unzip.cpp */; };
- DF0942030F63CB26002D821E /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFAAD2390F50120E00C3A4E2 /* console.cpp */; };
- DF0942090F63CB26002D821E /* state.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF573C010F5A81EA00961A72 /* state.cpp */; };
- DF09420C0F63CB26002D821E /* exec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF573CBA0F5A85B300961A72 /* exec.cpp */; };
- DF09420D0F63CB26002D821E /* timer_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF573CBD0F5A85E100961A72 /* timer_lol.cpp */; };
- DF0942100F63CB26002D821E /* sprites_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF89C2870F62D55C00D756B6 /* sprites_lol.cpp */; };
- DF0942110F63CB26002D821E /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF89C2A30F62D79E00D756B6 /* script.cpp */; };
- DF0942150F63CB26002D821E /* pn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF093E5C0F63CAD4002D821E /* pn.cpp */; };
- DF0942160F63CB26002D821E /* script_pn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF093E5D0F63CAD4002D821E /* script_pn.cpp */; };
- DF0942170F63CB26002D821E /* vga_pn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF093E5E0F63CAD4002D821E /* vga_pn.cpp */; };
- DF0942470F63CB9A002D821E /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF0942390F63CB9A002D821E /* main.cpp */; };
- DF09424A0F63CB9A002D821E /* sdl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09423C0F63CB9A002D821E /* sdl.cpp */; };
- DF0943730F63D1DA002D821E /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF842A170E7BB34E00F5680E /* CoreFoundation.framework */; };
- DF0943740F63D1DD002D821E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF842A180E7BB34E00F5680E /* Foundation.framework */; };
- DF0943750F63D1DE002D821E /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF842A270E7BB37500F5680E /* AudioToolbox.framework */; };
- DF0944180F63FA8F002D821E /* QuickTime.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF0944170F63FA8F002D821E /* QuickTime.framework */; };
- DF0944250F63FB2C002D821E /* CoreMIDI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF0944240F63FB2C002D821E /* CoreMIDI.framework */; };
- DF0944290F63FB60002D821E /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF842A160E7BB34E00F5680E /* CoreAudio.framework */; };
- DF09442B0F63FB75002D821E /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF842A2E0E7BB39E00F5680E /* QuartzCore.framework */; };
- DF0944330F63FBB3002D821E /* coreaudio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF0944300F63FBB3002D821E /* coreaudio.cpp */; };
- DF0944340F63FBB3002D821E /* coremidi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF0944310F63FBB3002D821E /* coremidi.cpp */; };
- DF0944380F63FBFE002D821E /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF0944370F63FBFE002D821E /* Carbon.framework */; };
- DF09446F0F63FCCB002D821E /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF09446D0F63FCCB002D821E /* ApplicationServices.framework */; };
- DF0944700F63FCCB002D821E /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF09446E0F63FCCB002D821E /* IOKit.framework */; };
- DF0944780F63FD10002D821E /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF0944770F63FD10002D821E /* Cocoa.framework */; };
- DF0944800F63FD67002D821E /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF09447F0F63FD67002D821E /* AudioUnit.framework */; };
- DF0944B10F6430ED002D821E /* scummvm.icns in Resources */ = {isa = PBXBuildFile; fileRef = DF0944B00F6430ED002D821E /* scummvm.icns */; };
- DF09CC100FAC4E1900A5AFD7 /* batplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC070FAC4E1900A5AFD7 /* batplayer.cpp */; };
- DF09CC110FAC4E1900A5AFD7 /* demoplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC090FAC4E1900A5AFD7 /* demoplayer.cpp */; };
- DF09CC120FAC4E1900A5AFD7 /* scnplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC0B0FAC4E1900A5AFD7 /* scnplayer.cpp */; };
- DF09CC130FAC4E1900A5AFD7 /* draw_fascin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC0D0FAC4E1900A5AFD7 /* draw_fascin.cpp */; };
- DF09CC150FAC4E1900A5AFD7 /* inter_fascin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC0F0FAC4E1900A5AFD7 /* inter_fascin.cpp */; };
- DF09CC160FAC4E1900A5AFD7 /* batplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC070FAC4E1900A5AFD7 /* batplayer.cpp */; };
- DF09CC170FAC4E1900A5AFD7 /* demoplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC090FAC4E1900A5AFD7 /* demoplayer.cpp */; };
- DF09CC180FAC4E1900A5AFD7 /* scnplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC0B0FAC4E1900A5AFD7 /* scnplayer.cpp */; };
- DF09CC190FAC4E1900A5AFD7 /* draw_fascin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC0D0FAC4E1900A5AFD7 /* draw_fascin.cpp */; };
- DF09CC1B0FAC4E1900A5AFD7 /* inter_fascin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC0F0FAC4E1900A5AFD7 /* inter_fascin.cpp */; };
- DF09CC280FAC4EAB00A5AFD7 /* script_v3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC260FAC4EAB00A5AFD7 /* script_v3.cpp */; };
- DF09CC290FAC4EAB00A5AFD7 /* script_v4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC270FAC4EAB00A5AFD7 /* script_v4.cpp */; };
- DF09CC2A0FAC4EAB00A5AFD7 /* script_v3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC260FAC4EAB00A5AFD7 /* script_v3.cpp */; };
- DF09CC2B0FAC4EAB00A5AFD7 /* script_v4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC270FAC4EAB00A5AFD7 /* script_v4.cpp */; };
- DF0E303A1252C5BD0082D593 /* cms.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF0E30391252C5BD0082D593 /* cms.cpp */; };
- DF0E303B1252C5BD0082D593 /* cms.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF0E30391252C5BD0082D593 /* cms.cpp */; };
- DF0E303C1252C5BD0082D593 /* cms.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF0E30391252C5BD0082D593 /* cms.cpp */; };
- DF203F471380C06E0056300A /* gui-manager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F461380C06E0056300A /* gui-manager.cpp */; };
- DF203F481380C06E0056300A /* gui-manager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F461380C06E0056300A /* gui-manager.cpp */; };
- DF203F491380C06E0056300A /* gui-manager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F461380C06E0056300A /* gui-manager.cpp */; };
- DF203F631380C2750056300A /* avi_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F531380C2740056300A /* avi_decoder.cpp */; };
- DF203F641380C2750056300A /* coktel_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F551380C2740056300A /* coktel_decoder.cpp */; };
- DF203F651380C2750056300A /* dxa_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F571380C2740056300A /* dxa_decoder.cpp */; };
- DF203F661380C2750056300A /* flic_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F591380C2740056300A /* flic_decoder.cpp */; };
- DF203F681380C2750056300A /* qt_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F5D1380C2740056300A /* qt_decoder.cpp */; };
- DF203F691380C2750056300A /* smk_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F5F1380C2750056300A /* smk_decoder.cpp */; };
- DF203F6A1380C2750056300A /* video_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F611380C2750056300A /* video_decoder.cpp */; };
- DF203F6B1380C2750056300A /* avi_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F531380C2740056300A /* avi_decoder.cpp */; };
- DF203F6C1380C2750056300A /* coktel_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F551380C2740056300A /* coktel_decoder.cpp */; };
- DF203F6D1380C2750056300A /* dxa_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F571380C2740056300A /* dxa_decoder.cpp */; };
- DF203F6E1380C2750056300A /* flic_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F591380C2740056300A /* flic_decoder.cpp */; };
- DF203F701380C2750056300A /* qt_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F5D1380C2740056300A /* qt_decoder.cpp */; };
- DF203F711380C2750056300A /* smk_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F5F1380C2750056300A /* smk_decoder.cpp */; };
- DF203F721380C2750056300A /* video_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F611380C2750056300A /* video_decoder.cpp */; };
- DF203F731380C2750056300A /* avi_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F531380C2740056300A /* avi_decoder.cpp */; };
- DF203F741380C2750056300A /* coktel_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F551380C2740056300A /* coktel_decoder.cpp */; };
- DF203F751380C2750056300A /* dxa_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F571380C2740056300A /* dxa_decoder.cpp */; };
- DF203F761380C2750056300A /* flic_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F591380C2740056300A /* flic_decoder.cpp */; };
- DF203F781380C2750056300A /* qt_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F5D1380C2740056300A /* qt_decoder.cpp */; };
- DF203F791380C2750056300A /* smk_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F5F1380C2750056300A /* smk_decoder.cpp */; };
- DF203F7A1380C2750056300A /* video_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F611380C2750056300A /* video_decoder.cpp */; };
- DF203F951380C2920056300A /* cdtoons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F7C1380C2920056300A /* cdtoons.cpp */; };
- DF203F961380C2920056300A /* cinepak.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F7E1380C2920056300A /* cinepak.cpp */; };
- DF203F971380C2920056300A /* indeo3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F811380C2920056300A /* indeo3.cpp */; };
- DF203F981380C2920056300A /* mjpeg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F831380C2920056300A /* mjpeg.cpp */; };
- DF203F991380C2920056300A /* msrle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F851380C2920056300A /* msrle.cpp */; };
- DF203F9A1380C2920056300A /* msvideo1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F871380C2920056300A /* msvideo1.cpp */; };
- DF203F9C1380C2920056300A /* qtrle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F8C1380C2920056300A /* qtrle.cpp */; };
- DF203F9D1380C2920056300A /* rpza.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F8E1380C2920056300A /* rpza.cpp */; };
- DF203F9E1380C2920056300A /* smc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F901380C2920056300A /* smc.cpp */; };
- DF203F9F1380C2920056300A /* truemotion1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F921380C2920056300A /* truemotion1.cpp */; };
- DF203FA01380C2920056300A /* cdtoons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F7C1380C2920056300A /* cdtoons.cpp */; };
- DF203FA11380C2920056300A /* cinepak.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F7E1380C2920056300A /* cinepak.cpp */; };
- DF203FA21380C2920056300A /* indeo3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F811380C2920056300A /* indeo3.cpp */; };
- DF203FA31380C2920056300A /* mjpeg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F831380C2920056300A /* mjpeg.cpp */; };
- DF203FA41380C2920056300A /* msrle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F851380C2920056300A /* msrle.cpp */; };
- DF203FA51380C2920056300A /* msvideo1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F871380C2920056300A /* msvideo1.cpp */; };
- DF203FA71380C2920056300A /* qtrle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F8C1380C2920056300A /* qtrle.cpp */; };
- DF203FA81380C2920056300A /* rpza.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F8E1380C2920056300A /* rpza.cpp */; };
- DF203FA91380C2920056300A /* smc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F901380C2920056300A /* smc.cpp */; };
- DF203FAA1380C2920056300A /* truemotion1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F921380C2920056300A /* truemotion1.cpp */; };
- DF203FAB1380C2920056300A /* cdtoons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F7C1380C2920056300A /* cdtoons.cpp */; };
- DF203FAC1380C2920056300A /* cinepak.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F7E1380C2920056300A /* cinepak.cpp */; };
- DF203FAD1380C2920056300A /* indeo3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F811380C2920056300A /* indeo3.cpp */; };
- DF203FAE1380C2920056300A /* mjpeg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F831380C2920056300A /* mjpeg.cpp */; };
- DF203FAF1380C2920056300A /* msrle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F851380C2920056300A /* msrle.cpp */; };
- DF203FB01380C2920056300A /* msvideo1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F871380C2920056300A /* msvideo1.cpp */; };
- DF203FB21380C2920056300A /* qtrle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F8C1380C2920056300A /* qtrle.cpp */; };
- DF203FB31380C2920056300A /* rpza.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F8E1380C2920056300A /* rpza.cpp */; };
- DF203FB41380C2920056300A /* smc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F901380C2920056300A /* smc.cpp */; };
- DF203FB51380C2920056300A /* truemotion1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203F921380C2920056300A /* truemotion1.cpp */; };
- DF203FD51380C3BC0056300A /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FC01380C3BC0056300A /* console.cpp */; };
- DF203FD61380C3BC0056300A /* dialogs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FC21380C3BC0056300A /* dialogs.cpp */; };
- DF203FD71380C3BC0056300A /* file_v1d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FC41380C3BC0056300A /* file_v1d.cpp */; };
- DF203FD81380C3BC0056300A /* file_v1w.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FC51380C3BC0056300A /* file_v1w.cpp */; };
- DF203FD91380C3BC0056300A /* file_v2d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FC61380C3BC0056300A /* file_v2d.cpp */; };
- DF203FDA1380C3BC0056300A /* file_v2w.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FC71380C3BC0056300A /* file_v2w.cpp */; };
- DF203FDB1380C3BC0056300A /* file_v3d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FC81380C3BC0056300A /* file_v3d.cpp */; };
- DF203FDC1380C3BC0056300A /* object_v1d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FC91380C3BC0056300A /* object_v1d.cpp */; };
- DF203FDD1380C3BC0056300A /* object_v1w.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FCA1380C3BC0056300A /* object_v1w.cpp */; };
- DF203FDE1380C3BC0056300A /* object_v2d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FCB1380C3BC0056300A /* object_v2d.cpp */; };
- DF203FDF1380C3BC0056300A /* object_v3d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FCC1380C3BC0056300A /* object_v3d.cpp */; };
- DF203FE01380C3BC0056300A /* object.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FCD1380C3BC0056300A /* object.cpp */; };
- DF203FE11380C3BC0056300A /* parser_v1d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FCF1380C3BC0056300A /* parser_v1d.cpp */; };
- DF203FE21380C3BC0056300A /* parser_v1w.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FD01380C3BC0056300A /* parser_v1w.cpp */; };
- DF203FE31380C3BC0056300A /* parser_v2d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FD11380C3BC0056300A /* parser_v2d.cpp */; };
- DF203FE41380C3BC0056300A /* parser_v3d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FD21380C3BC0056300A /* parser_v3d.cpp */; };
- DF203FE51380C3BC0056300A /* text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FD31380C3BC0056300A /* text.cpp */; };
- DF203FE61380C3BC0056300A /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FC01380C3BC0056300A /* console.cpp */; };
- DF203FE71380C3BC0056300A /* dialogs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FC21380C3BC0056300A /* dialogs.cpp */; };
- DF203FE81380C3BC0056300A /* file_v1d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FC41380C3BC0056300A /* file_v1d.cpp */; };
- DF203FE91380C3BC0056300A /* file_v1w.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FC51380C3BC0056300A /* file_v1w.cpp */; };
- DF203FEA1380C3BC0056300A /* file_v2d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FC61380C3BC0056300A /* file_v2d.cpp */; };
- DF203FEB1380C3BC0056300A /* file_v2w.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FC71380C3BC0056300A /* file_v2w.cpp */; };
- DF203FEC1380C3BC0056300A /* file_v3d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FC81380C3BC0056300A /* file_v3d.cpp */; };
- DF203FED1380C3BC0056300A /* object_v1d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FC91380C3BC0056300A /* object_v1d.cpp */; };
- DF203FEE1380C3BC0056300A /* object_v1w.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FCA1380C3BC0056300A /* object_v1w.cpp */; };
- DF203FEF1380C3BC0056300A /* object_v2d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FCB1380C3BC0056300A /* object_v2d.cpp */; };
- DF203FF01380C3BC0056300A /* object_v3d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FCC1380C3BC0056300A /* object_v3d.cpp */; };
- DF203FF11380C3BC0056300A /* object.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FCD1380C3BC0056300A /* object.cpp */; };
- DF203FF21380C3BC0056300A /* parser_v1d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FCF1380C3BC0056300A /* parser_v1d.cpp */; };
- DF203FF31380C3BC0056300A /* parser_v1w.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FD01380C3BC0056300A /* parser_v1w.cpp */; };
- DF203FF41380C3BC0056300A /* parser_v2d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FD11380C3BC0056300A /* parser_v2d.cpp */; };
- DF203FF51380C3BC0056300A /* parser_v3d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FD21380C3BC0056300A /* parser_v3d.cpp */; };
- DF203FF61380C3BC0056300A /* text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FD31380C3BC0056300A /* text.cpp */; };
- DF203FF71380C3BC0056300A /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FC01380C3BC0056300A /* console.cpp */; };
- DF203FF81380C3BC0056300A /* dialogs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FC21380C3BC0056300A /* dialogs.cpp */; };
- DF203FF91380C3BC0056300A /* file_v1d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FC41380C3BC0056300A /* file_v1d.cpp */; };
- DF203FFA1380C3BC0056300A /* file_v1w.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FC51380C3BC0056300A /* file_v1w.cpp */; };
- DF203FFB1380C3BC0056300A /* file_v2d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FC61380C3BC0056300A /* file_v2d.cpp */; };
- DF203FFC1380C3BC0056300A /* file_v2w.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FC71380C3BC0056300A /* file_v2w.cpp */; };
- DF203FFD1380C3BC0056300A /* file_v3d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FC81380C3BC0056300A /* file_v3d.cpp */; };
- DF203FFE1380C3BC0056300A /* object_v1d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FC91380C3BC0056300A /* object_v1d.cpp */; };
- DF203FFF1380C3BC0056300A /* object_v1w.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FCA1380C3BC0056300A /* object_v1w.cpp */; };
- DF2040001380C3BC0056300A /* object_v2d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FCB1380C3BC0056300A /* object_v2d.cpp */; };
- DF2040011380C3BC0056300A /* object_v3d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FCC1380C3BC0056300A /* object_v3d.cpp */; };
- DF2040021380C3BC0056300A /* object.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FCD1380C3BC0056300A /* object.cpp */; };
- DF2040031380C3BC0056300A /* parser_v1d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FCF1380C3BC0056300A /* parser_v1d.cpp */; };
- DF2040041380C3BC0056300A /* parser_v1w.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FD01380C3BC0056300A /* parser_v1w.cpp */; };
- DF2040051380C3BC0056300A /* parser_v2d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FD11380C3BC0056300A /* parser_v2d.cpp */; };
- DF2040061380C3BC0056300A /* parser_v3d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FD21380C3BC0056300A /* parser_v3d.cpp */; };
- DF2040071380C3BC0056300A /* text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF203FD31380C3BC0056300A /* text.cpp */; };
- DF20402E1380C8B70056300A /* editable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040221380C8B70056300A /* editable.cpp */; };
- DF20402F1380C8B70056300A /* edittext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040241380C8B70056300A /* edittext.cpp */; };
- DF2040301380C8B70056300A /* list.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040261380C8B70056300A /* list.cpp */; };
- DF2040311380C8B70056300A /* popup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040281380C8B70056300A /* popup.cpp */; };
- DF2040321380C8B70056300A /* scrollbar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20402A1380C8B70056300A /* scrollbar.cpp */; };
- DF2040331380C8B70056300A /* tab.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20402C1380C8B70056300A /* tab.cpp */; };
- DF2040341380C8B70056300A /* editable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040221380C8B70056300A /* editable.cpp */; };
- DF2040351380C8B70056300A /* edittext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040241380C8B70056300A /* edittext.cpp */; };
- DF2040361380C8B70056300A /* list.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040261380C8B70056300A /* list.cpp */; };
- DF2040371380C8B70056300A /* popup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040281380C8B70056300A /* popup.cpp */; };
- DF2040381380C8B70056300A /* scrollbar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20402A1380C8B70056300A /* scrollbar.cpp */; };
- DF2040391380C8B70056300A /* tab.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20402C1380C8B70056300A /* tab.cpp */; };
- DF20403A1380C8B70056300A /* editable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040221380C8B70056300A /* editable.cpp */; };
- DF20403B1380C8B70056300A /* edittext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040241380C8B70056300A /* edittext.cpp */; };
- DF20403C1380C8B70056300A /* list.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040261380C8B70056300A /* list.cpp */; };
- DF20403D1380C8B70056300A /* popup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040281380C8B70056300A /* popup.cpp */; };
- DF20403E1380C8B70056300A /* scrollbar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20402A1380C8B70056300A /* scrollbar.cpp */; };
- DF20403F1380C8B70056300A /* tab.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20402C1380C8B70056300A /* tab.cpp */; };
- DF20405E1380CA230056300A /* audiostream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040471380CA230056300A /* audiostream.cpp */; };
- DF20405F1380CA230056300A /* fmopl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040491380CA230056300A /* fmopl.cpp */; };
- DF2040601380CA230056300A /* mididrv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20404B1380CA230056300A /* mididrv.cpp */; };
- DF2040611380CA230056300A /* midiparser_smf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20404D1380CA230056300A /* midiparser_smf.cpp */; };
- DF2040621380CA230056300A /* midiparser_xmidi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20404E1380CA230056300A /* midiparser_xmidi.cpp */; };
- DF2040631380CA230056300A /* midiparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20404F1380CA230056300A /* midiparser.cpp */; };
- DF2040641380CA230056300A /* midiplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040511380CA230056300A /* midiplayer.cpp */; };
- DF2040651380CA230056300A /* mixer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040541380CA230056300A /* mixer.cpp */; };
- DF2040661380CA230056300A /* mpu401.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040561380CA230056300A /* mpu401.cpp */; };
- DF2040671380CA230056300A /* musicplugin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040581380CA230056300A /* musicplugin.cpp */; };
- DF2040681380CA230056300A /* rate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20405A1380CA230056300A /* rate.cpp */; };
- DF2040691380CA230056300A /* timestamp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20405C1380CA230056300A /* timestamp.cpp */; };
- DF20406A1380CA230056300A /* audiostream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040471380CA230056300A /* audiostream.cpp */; };
- DF20406B1380CA230056300A /* fmopl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040491380CA230056300A /* fmopl.cpp */; };
- DF20406C1380CA230056300A /* mididrv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20404B1380CA230056300A /* mididrv.cpp */; };
- DF20406D1380CA230056300A /* midiparser_smf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20404D1380CA230056300A /* midiparser_smf.cpp */; };
- DF20406E1380CA230056300A /* midiparser_xmidi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20404E1380CA230056300A /* midiparser_xmidi.cpp */; };
- DF20406F1380CA230056300A /* midiparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20404F1380CA230056300A /* midiparser.cpp */; };
- DF2040701380CA230056300A /* midiplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040511380CA230056300A /* midiplayer.cpp */; };
- DF2040711380CA230056300A /* mixer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040541380CA230056300A /* mixer.cpp */; };
- DF2040721380CA230056300A /* mpu401.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040561380CA230056300A /* mpu401.cpp */; };
- DF2040731380CA230056300A /* musicplugin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040581380CA230056300A /* musicplugin.cpp */; };
- DF2040741380CA230056300A /* rate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20405A1380CA230056300A /* rate.cpp */; };
- DF2040751380CA230056300A /* timestamp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20405C1380CA230056300A /* timestamp.cpp */; };
- DF2040761380CA230056300A /* audiostream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040471380CA230056300A /* audiostream.cpp */; };
- DF2040771380CA230056300A /* fmopl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040491380CA230056300A /* fmopl.cpp */; };
- DF2040781380CA230056300A /* mididrv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20404B1380CA230056300A /* mididrv.cpp */; };
- DF2040791380CA230056300A /* midiparser_smf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20404D1380CA230056300A /* midiparser_smf.cpp */; };
- DF20407A1380CA230056300A /* midiparser_xmidi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20404E1380CA230056300A /* midiparser_xmidi.cpp */; };
- DF20407B1380CA230056300A /* midiparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20404F1380CA230056300A /* midiparser.cpp */; };
- DF20407C1380CA230056300A /* midiplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040511380CA230056300A /* midiplayer.cpp */; };
- DF20407D1380CA230056300A /* mixer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040541380CA230056300A /* mixer.cpp */; };
- DF20407E1380CA230056300A /* mpu401.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040561380CA230056300A /* mpu401.cpp */; };
- DF20407F1380CA230056300A /* musicplugin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040581380CA230056300A /* musicplugin.cpp */; };
- DF2040801380CA230056300A /* rate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20405A1380CA230056300A /* rate.cpp */; };
- DF2040811380CA230056300A /* timestamp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20405C1380CA230056300A /* timestamp.cpp */; };
- DF20409A1380CA400056300A /* adpcm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040841380CA400056300A /* adpcm.cpp */; };
- DF20409B1380CA400056300A /* aiff.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040861380CA400056300A /* aiff.cpp */; };
- DF20409C1380CA400056300A /* flac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040881380CA400056300A /* flac.cpp */; };
- DF20409D1380CA400056300A /* iff_sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20408A1380CA400056300A /* iff_sound.cpp */; };
- DF20409E1380CA400056300A /* mac_snd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20408C1380CA400056300A /* mac_snd.cpp */; };
- DF20409F1380CA400056300A /* mp3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20408E1380CA400056300A /* mp3.cpp */; };
- DF2040A01380CA400056300A /* raw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040901380CA400056300A /* raw.cpp */; };
- DF2040A11380CA400056300A /* vag.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040921380CA400056300A /* vag.cpp */; };
- DF2040A21380CA400056300A /* voc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040941380CA400056300A /* voc.cpp */; };
- DF2040A31380CA400056300A /* vorbis.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040961380CA400056300A /* vorbis.cpp */; };
- DF2040A41380CA400056300A /* wave.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040981380CA400056300A /* wave.cpp */; };
- DF2040A51380CA400056300A /* adpcm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040841380CA400056300A /* adpcm.cpp */; };
- DF2040A61380CA400056300A /* aiff.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040861380CA400056300A /* aiff.cpp */; };
- DF2040A71380CA400056300A /* flac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040881380CA400056300A /* flac.cpp */; };
- DF2040A81380CA400056300A /* iff_sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20408A1380CA400056300A /* iff_sound.cpp */; };
- DF2040A91380CA400056300A /* mac_snd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20408C1380CA400056300A /* mac_snd.cpp */; };
- DF2040AA1380CA400056300A /* mp3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20408E1380CA400056300A /* mp3.cpp */; };
- DF2040AB1380CA400056300A /* raw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040901380CA400056300A /* raw.cpp */; };
- DF2040AC1380CA400056300A /* vag.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040921380CA400056300A /* vag.cpp */; };
- DF2040AD1380CA400056300A /* voc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040941380CA400056300A /* voc.cpp */; };
- DF2040AE1380CA400056300A /* vorbis.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040961380CA400056300A /* vorbis.cpp */; };
- DF2040AF1380CA400056300A /* wave.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040981380CA400056300A /* wave.cpp */; };
- DF2040B01380CA400056300A /* adpcm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040841380CA400056300A /* adpcm.cpp */; };
- DF2040B11380CA400056300A /* aiff.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040861380CA400056300A /* aiff.cpp */; };
- DF2040B21380CA400056300A /* flac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040881380CA400056300A /* flac.cpp */; };
- DF2040B31380CA400056300A /* iff_sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20408A1380CA400056300A /* iff_sound.cpp */; };
- DF2040B41380CA400056300A /* mac_snd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20408C1380CA400056300A /* mac_snd.cpp */; };
- DF2040B51380CA400056300A /* mp3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF20408E1380CA400056300A /* mp3.cpp */; };
- DF2040B61380CA400056300A /* raw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040901380CA400056300A /* raw.cpp */; };
- DF2040B71380CA400056300A /* vag.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040921380CA400056300A /* vag.cpp */; };
- DF2040B81380CA400056300A /* voc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040941380CA400056300A /* voc.cpp */; };
- DF2040B91380CA400056300A /* vorbis.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040961380CA400056300A /* vorbis.cpp */; };
- DF2040BA1380CA400056300A /* wave.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040981380CA400056300A /* wave.cpp */; };
- DF2040CC1380CA810056300A /* infogrames.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040BC1380CA810056300A /* infogrames.cpp */; };
- DF2040CD1380CA810056300A /* maxtrax.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040BE1380CA810056300A /* maxtrax.cpp */; };
- DF2040CE1380CA810056300A /* module.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040C01380CA810056300A /* module.cpp */; };
- DF2040CF1380CA810056300A /* paula.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040C21380CA810056300A /* paula.cpp */; };
- DF2040D01380CA810056300A /* protracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040C41380CA810056300A /* protracker.cpp */; };
- DF2040D11380CA810056300A /* rjp1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040C61380CA810056300A /* rjp1.cpp */; };
- DF2040D21380CA810056300A /* soundfx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040C81380CA810056300A /* soundfx.cpp */; };
- DF2040D31380CA810056300A /* tfmx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040CA1380CA810056300A /* tfmx.cpp */; };
- DF2040D41380CA810056300A /* infogrames.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040BC1380CA810056300A /* infogrames.cpp */; };
- DF2040D51380CA810056300A /* maxtrax.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040BE1380CA810056300A /* maxtrax.cpp */; };
- DF2040D61380CA810056300A /* module.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040C01380CA810056300A /* module.cpp */; };
- DF2040D71380CA810056300A /* paula.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040C21380CA810056300A /* paula.cpp */; };
- DF2040D81380CA810056300A /* protracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040C41380CA810056300A /* protracker.cpp */; };
- DF2040D91380CA810056300A /* rjp1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040C61380CA810056300A /* rjp1.cpp */; };
- DF2040DA1380CA810056300A /* soundfx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040C81380CA810056300A /* soundfx.cpp */; };
- DF2040DB1380CA810056300A /* tfmx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040CA1380CA810056300A /* tfmx.cpp */; };
- DF2040DC1380CA810056300A /* infogrames.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040BC1380CA810056300A /* infogrames.cpp */; };
- DF2040DD1380CA810056300A /* maxtrax.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040BE1380CA810056300A /* maxtrax.cpp */; };
- DF2040DE1380CA810056300A /* module.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040C01380CA810056300A /* module.cpp */; };
- DF2040DF1380CA810056300A /* paula.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040C21380CA810056300A /* paula.cpp */; };
- DF2040E01380CA810056300A /* protracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040C41380CA810056300A /* protracker.cpp */; };
- DF2040E11380CA810056300A /* rjp1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040C61380CA810056300A /* rjp1.cpp */; };
- DF2040E21380CA810056300A /* soundfx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040C81380CA810056300A /* soundfx.cpp */; };
- DF2040E31380CA810056300A /* tfmx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040CA1380CA810056300A /* tfmx.cpp */; };
- DF2040F41380CAA40056300A /* adlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040E51380CAA40056300A /* adlib.cpp */; };
- DF2040F51380CAA40056300A /* appleiigs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040E61380CAA40056300A /* appleiigs.cpp */; };
- DF2040F61380CAA40056300A /* cms.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040E71380CAA40056300A /* cms.cpp */; };
- DF2040F71380CAA40056300A /* eas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040E91380CAA40056300A /* eas.cpp */; };
- DF2040F81380CAA40056300A /* fluidsynth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040EB1380CAA40056300A /* fluidsynth.cpp */; };
- DF2040F91380CAA40056300A /* mt32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040EC1380CAA40056300A /* mt32.cpp */; };
- DF2040FA1380CAA40056300A /* pcspk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040ED1380CAA40056300A /* pcspk.cpp */; };
- DF2040FB1380CAA40056300A /* sid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040EF1380CAA40056300A /* sid.cpp */; };
- DF2040FC1380CAA40056300A /* wave6581.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040F11380CAA40056300A /* wave6581.cpp */; };
- DF2040FE1380CAA40056300A /* adlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040E51380CAA40056300A /* adlib.cpp */; };
- DF2040FF1380CAA40056300A /* appleiigs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040E61380CAA40056300A /* appleiigs.cpp */; };
- DF2041001380CAA40056300A /* cms.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040E71380CAA40056300A /* cms.cpp */; };
- DF2041011380CAA40056300A /* eas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040E91380CAA40056300A /* eas.cpp */; };
- DF2041021380CAA40056300A /* fluidsynth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040EB1380CAA40056300A /* fluidsynth.cpp */; };
- DF2041031380CAA40056300A /* mt32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040EC1380CAA40056300A /* mt32.cpp */; };
- DF2041041380CAA40056300A /* pcspk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040ED1380CAA40056300A /* pcspk.cpp */; };
- DF2041051380CAA40056300A /* sid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040EF1380CAA40056300A /* sid.cpp */; };
- DF2041061380CAA40056300A /* wave6581.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040F11380CAA40056300A /* wave6581.cpp */; };
- DF2041081380CAA40056300A /* adlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040E51380CAA40056300A /* adlib.cpp */; };
- DF2041091380CAA40056300A /* appleiigs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040E61380CAA40056300A /* appleiigs.cpp */; };
- DF20410A1380CAA40056300A /* cms.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040E71380CAA40056300A /* cms.cpp */; };
- DF20410B1380CAA40056300A /* eas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040E91380CAA40056300A /* eas.cpp */; };
- DF20410C1380CAA40056300A /* fluidsynth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040EB1380CAA40056300A /* fluidsynth.cpp */; };
- DF20410D1380CAA40056300A /* mt32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040EC1380CAA40056300A /* mt32.cpp */; };
- DF20410E1380CAA40056300A /* pcspk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040ED1380CAA40056300A /* pcspk.cpp */; };
- DF20410F1380CAA40056300A /* sid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040EF1380CAA40056300A /* sid.cpp */; };
- DF2041101380CAA40056300A /* wave6581.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2040F11380CAA40056300A /* wave6581.cpp */; };
- DF224E040FB23BC500C8E453 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF224E020FB23BC500C8E453 /* OpenGLES.framework */; };
- DF224E050FB23BC500C8E453 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF224E020FB23BC500C8E453 /* OpenGLES.framework */; };
- DF2EC3E510E6490800765801 /* browser_osx.mm in Sources */ = {isa = PBXBuildFile; fileRef = DF2EC3E410E6490800765801 /* browser_osx.mm */; };
- DF2EC3F810E64C0C00765801 /* dialogs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2EC3F610E64C0C00765801 /* dialogs.cpp */; };
- DF2EC3F910E64C0C00765801 /* dialogs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2EC3F610E64C0C00765801 /* dialogs.cpp */; };
- DF2EC3FA10E64C0C00765801 /* dialogs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2EC3F610E64C0C00765801 /* dialogs.cpp */; };
- DF2EC3FE10E64C4300765801 /* animator_tim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2EC3FD10E64C4300765801 /* animator_tim.cpp */; };
- DF2EC3FF10E64C4300765801 /* animator_tim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2EC3FD10E64C4300765801 /* animator_tim.cpp */; };
- DF2EC40010E64C4300765801 /* animator_tim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2EC3FD10E64C4300765801 /* animator_tim.cpp */; };
- DF2EC40510E64C8000765801 /* event.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2EC40310E64C8000765801 /* event.cpp */; };
- DF2EC40610E64C8000765801 /* event.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2EC40310E64C8000765801 /* event.cpp */; };
- DF2EC40710E64C8000765801 /* event.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2EC40310E64C8000765801 /* event.cpp */; };
- DF2EC50110E64D7C00765801 /* player_pce.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2EC4FD10E64D7C00765801 /* player_pce.cpp */; };
- DF2EC50210E64D7C00765801 /* player_sid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2EC4FF10E64D7C00765801 /* player_sid.cpp */; };
- DF2EC50310E64D7C00765801 /* player_pce.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2EC4FD10E64D7C00765801 /* player_pce.cpp */; };
- DF2EC50410E64D7C00765801 /* player_sid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2EC4FF10E64D7C00765801 /* player_sid.cpp */; };
- DF2EC50510E64D7C00765801 /* player_pce.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2EC4FD10E64D7C00765801 /* player_pce.cpp */; };
- DF2EC50610E64D7C00765801 /* player_sid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2EC4FF10E64D7C00765801 /* player_sid.cpp */; };
- DF2EC50B10E64DB300765801 /* textconsole.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2EC50910E64DB300765801 /* textconsole.cpp */; };
- DF2EC50C10E64DB300765801 /* textconsole.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2EC50910E64DB300765801 /* textconsole.cpp */; };
- DF2EC50D10E64DB300765801 /* textconsole.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2EC50910E64DB300765801 /* textconsole.cpp */; };
- DF2FFB930F485D890006E566 /* dither.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFB900F485D890006E566 /* dither.cpp */; };
- DF2FFBD30F485DFB0006E566 /* debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFBD10F485DFB0006E566 /* debug.cpp */; };
- DF2FFBFC0F4860A60006E566 /* posix-saves.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFBF80F4860A60006E566 /* posix-saves.cpp */; };
- DF2FFC290F4862520006E566 /* bmv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC1F0F4862520006E566 /* bmv.cpp */; };
- DF2FFC2A0F4862520006E566 /* dialogs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC200F4862520006E566 /* dialogs.cpp */; };
- DF2FFC2B0F4862520006E566 /* drives.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC220F4862520006E566 /* drives.cpp */; };
- DF2FFC2C0F4862520006E566 /* sysvar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC270F4862520006E566 /* sysvar.cpp */; };
- DF2FFC380F48628A0006E566 /* gui_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC2E0F48628A0006E566 /* gui_lol.cpp */; };
- DF2FFC390F48628A0006E566 /* items_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC300F48628A0006E566 /* items_lol.cpp */; };
- DF2FFC3A0F48628A0006E566 /* script_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC310F48628A0006E566 /* script_lol.cpp */; };
- DF2FFC3B0F48628A0006E566 /* sequences_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC320F48628A0006E566 /* sequences_lol.cpp */; };
- DF2FFC3C0F48628A0006E566 /* sound_midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC330F48628A0006E566 /* sound_midi.cpp */; };
- DF2FFC3E0F48628A0006E566 /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC360F48628A0006E566 /* util.cpp */; };
- DF2FFC4A0F4863100006E566 /* scene_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC490F4863100006E566 /* scene_lol.cpp */; };
- DF2FFC4E0F4863560006E566 /* advancedDetector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC4C0F4863560006E566 /* advancedDetector.cpp */; };
- DF2FFC5D0F4866E70006E566 /* base-backend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC5B0F4866E70006E566 /* base-backend.cpp */; };
- DF2FFC670F48672D0006E566 /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC600F48672D0006E566 /* resource.cpp */; };
- DF2FFC680F48672D0006E566 /* resource_hrs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC620F48672D0006E566 /* resource_hrs.cpp */; };
- DF2FFC690F48672D0006E566 /* resource_res.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC630F48672D0006E566 /* resource_res.cpp */; };
- DF2FFC6A0F48672D0006E566 /* resource_rsc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC640F48672D0006E566 /* resource_rsc.cpp */; };
- DF2FFC6B0F48672D0006E566 /* sfuncs_ihnm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC650F48672D0006E566 /* sfuncs_ihnm.cpp */; };
- DF2FFC740F4867910006E566 /* debugger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC700F4867910006E566 /* debugger.cpp */; };
- DF2FFC750F4867910006E566 /* staticres.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC720F4867910006E566 /* staticres.cpp */; };
- DF2FFCDB0F4870690006E566 /* cell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCBD0F4870690006E566 /* cell.cpp */; };
- DF2FFCDC0F4870690006E566 /* cursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCBF0F4870690006E566 /* cursor.cpp */; };
- DF2FFCDD0F4870690006E566 /* debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCC10F4870690006E566 /* debug.cpp */; };
- DF2FFCDE0F4870690006E566 /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCC30F4870690006E566 /* detection.cpp */; };
- DF2FFCDF0F4870690006E566 /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCC40F4870690006E566 /* font.cpp */; };
- DF2FFCE00F4870690006E566 /* graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCC60F4870690006E566 /* graphics.cpp */; };
- DF2FFCE10F4870690006E566 /* groovie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCC80F4870690006E566 /* groovie.cpp */; };
- DF2FFCE20F4870690006E566 /* lzss.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCCA0F4870690006E566 /* lzss.cpp */; };
- DF2FFCE40F4870690006E566 /* music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCCD0F4870690006E566 /* music.cpp */; };
- DF2FFCE50F4870690006E566 /* player.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCCF0F4870690006E566 /* player.cpp */; };
- DF2FFCE60F4870690006E566 /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCD10F4870690006E566 /* resource.cpp */; };
- DF2FFCE70F4870690006E566 /* roq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCD30F4870690006E566 /* roq.cpp */; };
- DF2FFCE80F4870690006E566 /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCD50F4870690006E566 /* saveload.cpp */; };
- DF2FFCE90F4870690006E566 /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCD70F4870690006E566 /* script.cpp */; };
- DF2FFCEA0F4870690006E566 /* vdx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCD90F4870690006E566 /* vdx.cpp */; };
- DF2FFD100F4870E50006E566 /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFD050F4870E50006E566 /* detection.cpp */; };
- DF2FFD110F4870E50006E566 /* graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFD060F4870E50006E566 /* graphics.cpp */; };
- DF2FFD120F4870E50006E566 /* locations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFD080F4870E50006E566 /* locations.cpp */; };
- DF2FFD140F4870E50006E566 /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFD0A0F4870E50006E566 /* resource.cpp */; };
- DF2FFD150F4870E50006E566 /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFD0B0F4870E50006E566 /* saveload.cpp */; };
- DF2FFD160F4870E50006E566 /* sequences.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFD0C0F4870E50006E566 /* sequences.cpp */; };
- DF2FFD170F4870E50006E566 /* staticres.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFD0D0F4870E50006E566 /* staticres.cpp */; };
- DF2FFD180F4870E50006E566 /* tucker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFD0E0F4870E50006E566 /* tucker.cpp */; };
- DF2FFD2B0F48717F0006E566 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = DF2FFD290F48717F0006E566 /* Default.png */; };
- DF2FFD2C0F48717F0006E566 /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = DF2FFD2A0F48717F0006E566 /* icon.png */; };
- DF2FFD2D0F48719E0006E566 /* scummclassic.zip in Resources */ = {isa = PBXBuildFile; fileRef = DF2FFBDB0F485E480006E566 /* scummclassic.zip */; };
- DF45B1CA116628A5009B85CC /* animate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B176116628A5009B85CC /* animate.cpp */; };
- DF45B1CB116628A5009B85CC /* cache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B178116628A5009B85CC /* cache.cpp */; };
- DF45B1CC116628A5009B85CC /* compare.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B17A116628A5009B85CC /* compare.cpp */; };
- DF45B1CD116628A5009B85CC /* controls.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B17C116628A5009B85CC /* controls.cpp */; };
- DF45B1CE116628A5009B85CC /* coordadjuster.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B17E116628A5009B85CC /* coordadjuster.cpp */; };
- DF45B1CF116628A5009B85CC /* cursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B180116628A5009B85CC /* cursor.cpp */; };
- DF45B1D0116628A5009B85CC /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B182116628A5009B85CC /* font.cpp */; };
- DF45B1D4116628A5009B85CC /* menu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B18B116628A5009B85CC /* menu.cpp */; };
- DF45B1D5116628A5009B85CC /* paint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B18D116628A5009B85CC /* paint.cpp */; };
- DF45B1D6116628A5009B85CC /* paint16.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B18F116628A5009B85CC /* paint16.cpp */; };
- DF45B1D8116628A5009B85CC /* palette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B193116628A5009B85CC /* palette.cpp */; };
- DF45B1D9116628A5009B85CC /* picture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B195116628A5009B85CC /* picture.cpp */; };
- DF45B1DA116628A5009B85CC /* portrait.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B197116628A5009B85CC /* portrait.cpp */; };
- DF45B1DB116628A5009B85CC /* ports.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B199116628A5009B85CC /* ports.cpp */; };
- DF45B1DD116628A5009B85CC /* screen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B19D116628A5009B85CC /* screen.cpp */; };
- DF45B1DE116628A5009B85CC /* text16.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B19F116628A5009B85CC /* text16.cpp */; };
- DF45B1DF116628A5009B85CC /* transitions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1A1116628A5009B85CC /* transitions.cpp */; };
- DF45B1E0116628A5009B85CC /* view.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1A3116628A5009B85CC /* view.cpp */; };
- DF45B1E1116628A5009B85CC /* grammar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1A6116628A5009B85CC /* grammar.cpp */; };
- DF45B1E2116628A5009B85CC /* said.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1A7116628A5009B85CC /* said.cpp */; };
- DF45B1E4116628A5009B85CC /* vocabulary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1A9116628A5009B85CC /* vocabulary.cpp */; };
- DF45B1E5116628A5009B85CC /* audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1AC116628A5009B85CC /* audio.cpp */; };
- DF45B1E6116628A5009B85CC /* adlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1AF116628A5009B85CC /* adlib.cpp */; };
- DF45B1E8116628A5009B85CC /* fb01.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1B1116628A5009B85CC /* fb01.cpp */; };
- DF45B1E9116628A5009B85CC /* midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1B3116628A5009B85CC /* midi.cpp */; };
- DF45B1EA116628A5009B85CC /* pcjr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1B5116628A5009B85CC /* pcjr.cpp */; };
- DF45B1EF116628A5009B85CC /* midiparser_sci.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1BF116628A5009B85CC /* midiparser_sci.cpp */; };
- DF45B1F0116628A5009B85CC /* music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1C1116628A5009B85CC /* music.cpp */; };
- DF45B1F1116628A5009B85CC /* soundcmd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1C3116628A5009B85CC /* soundcmd.cpp */; };
- DF45B1F2116628A5009B85CC /* seq_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1C6116628A5009B85CC /* seq_decoder.cpp */; };
- DF45B1F4116628A5009B85CC /* animate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B176116628A5009B85CC /* animate.cpp */; };
- DF45B1F5116628A5009B85CC /* cache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B178116628A5009B85CC /* cache.cpp */; };
- DF45B1F6116628A5009B85CC /* compare.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B17A116628A5009B85CC /* compare.cpp */; };
- DF45B1F7116628A5009B85CC /* controls.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B17C116628A5009B85CC /* controls.cpp */; };
- DF45B1F8116628A5009B85CC /* coordadjuster.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B17E116628A5009B85CC /* coordadjuster.cpp */; };
- DF45B1F9116628A5009B85CC /* cursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B180116628A5009B85CC /* cursor.cpp */; };
- DF45B1FA116628A5009B85CC /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B182116628A5009B85CC /* font.cpp */; };
- DF45B1FE116628A5009B85CC /* menu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B18B116628A5009B85CC /* menu.cpp */; };
- DF45B1FF116628A5009B85CC /* paint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B18D116628A5009B85CC /* paint.cpp */; };
- DF45B200116628A5009B85CC /* paint16.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B18F116628A5009B85CC /* paint16.cpp */; };
- DF45B202116628A5009B85CC /* palette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B193116628A5009B85CC /* palette.cpp */; };
- DF45B203116628A5009B85CC /* picture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B195116628A5009B85CC /* picture.cpp */; };
- DF45B204116628A5009B85CC /* portrait.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B197116628A5009B85CC /* portrait.cpp */; };
- DF45B205116628A5009B85CC /* ports.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B199116628A5009B85CC /* ports.cpp */; };
- DF45B207116628A5009B85CC /* screen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B19D116628A5009B85CC /* screen.cpp */; };
- DF45B208116628A5009B85CC /* text16.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B19F116628A5009B85CC /* text16.cpp */; };
- DF45B209116628A5009B85CC /* transitions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1A1116628A5009B85CC /* transitions.cpp */; };
- DF45B20A116628A5009B85CC /* view.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1A3116628A5009B85CC /* view.cpp */; };
- DF45B20B116628A5009B85CC /* grammar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1A6116628A5009B85CC /* grammar.cpp */; };
- DF45B20C116628A5009B85CC /* said.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1A7116628A5009B85CC /* said.cpp */; };
- DF45B20E116628A5009B85CC /* vocabulary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1A9116628A5009B85CC /* vocabulary.cpp */; };
- DF45B20F116628A5009B85CC /* audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1AC116628A5009B85CC /* audio.cpp */; };
- DF45B210116628A5009B85CC /* adlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1AF116628A5009B85CC /* adlib.cpp */; };
- DF45B212116628A5009B85CC /* fb01.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1B1116628A5009B85CC /* fb01.cpp */; };
- DF45B213116628A5009B85CC /* midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1B3116628A5009B85CC /* midi.cpp */; };
- DF45B214116628A5009B85CC /* pcjr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1B5116628A5009B85CC /* pcjr.cpp */; };
- DF45B219116628A5009B85CC /* midiparser_sci.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1BF116628A5009B85CC /* midiparser_sci.cpp */; };
- DF45B21A116628A5009B85CC /* music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1C1116628A5009B85CC /* music.cpp */; };
- DF45B21B116628A5009B85CC /* soundcmd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1C3116628A5009B85CC /* soundcmd.cpp */; };
- DF45B21C116628A5009B85CC /* seq_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1C6116628A5009B85CC /* seq_decoder.cpp */; };
- DF45B21E116628A5009B85CC /* animate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B176116628A5009B85CC /* animate.cpp */; };
- DF45B21F116628A5009B85CC /* cache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B178116628A5009B85CC /* cache.cpp */; };
- DF45B220116628A5009B85CC /* compare.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B17A116628A5009B85CC /* compare.cpp */; };
- DF45B221116628A5009B85CC /* controls.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B17C116628A5009B85CC /* controls.cpp */; };
- DF45B222116628A5009B85CC /* coordadjuster.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B17E116628A5009B85CC /* coordadjuster.cpp */; };
- DF45B223116628A5009B85CC /* cursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B180116628A5009B85CC /* cursor.cpp */; };
- DF45B224116628A5009B85CC /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B182116628A5009B85CC /* font.cpp */; };
- DF45B228116628A5009B85CC /* menu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B18B116628A5009B85CC /* menu.cpp */; };
- DF45B229116628A5009B85CC /* paint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B18D116628A5009B85CC /* paint.cpp */; };
- DF45B22A116628A5009B85CC /* paint16.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B18F116628A5009B85CC /* paint16.cpp */; };
- DF45B22C116628A5009B85CC /* palette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B193116628A5009B85CC /* palette.cpp */; };
- DF45B22D116628A5009B85CC /* picture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B195116628A5009B85CC /* picture.cpp */; };
- DF45B22E116628A5009B85CC /* portrait.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B197116628A5009B85CC /* portrait.cpp */; };
- DF45B22F116628A5009B85CC /* ports.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B199116628A5009B85CC /* ports.cpp */; };
- DF45B231116628A5009B85CC /* screen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B19D116628A5009B85CC /* screen.cpp */; };
- DF45B232116628A5009B85CC /* text16.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B19F116628A5009B85CC /* text16.cpp */; };
- DF45B233116628A5009B85CC /* transitions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1A1116628A5009B85CC /* transitions.cpp */; };
- DF45B234116628A5009B85CC /* view.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1A3116628A5009B85CC /* view.cpp */; };
- DF45B235116628A5009B85CC /* grammar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1A6116628A5009B85CC /* grammar.cpp */; };
- DF45B236116628A5009B85CC /* said.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1A7116628A5009B85CC /* said.cpp */; };
- DF45B238116628A5009B85CC /* vocabulary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1A9116628A5009B85CC /* vocabulary.cpp */; };
- DF45B239116628A5009B85CC /* audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1AC116628A5009B85CC /* audio.cpp */; };
- DF45B23A116628A5009B85CC /* adlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1AF116628A5009B85CC /* adlib.cpp */; };
- DF45B23C116628A5009B85CC /* fb01.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1B1116628A5009B85CC /* fb01.cpp */; };
- DF45B23D116628A5009B85CC /* midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1B3116628A5009B85CC /* midi.cpp */; };
- DF45B23E116628A5009B85CC /* pcjr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1B5116628A5009B85CC /* pcjr.cpp */; };
- DF45B243116628A5009B85CC /* midiparser_sci.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1BF116628A5009B85CC /* midiparser_sci.cpp */; };
- DF45B244116628A5009B85CC /* music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1C1116628A5009B85CC /* music.cpp */; };
- DF45B245116628A5009B85CC /* soundcmd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1C3116628A5009B85CC /* soundcmd.cpp */; };
- DF45B246116628A5009B85CC /* seq_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF45B1C6116628A5009B85CC /* seq_decoder.cpp */; };
- DF46B6F31381E18900D08723 /* coroutine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B6F21381E18900D08723 /* coroutine.cpp */; };
- DF46B6F41381E18900D08723 /* coroutine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B6F21381E18900D08723 /* coroutine.cpp */; };
- DF46B6F51381E18900D08723 /* coroutine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B6F21381E18900D08723 /* coroutine.cpp */; };
- DF46B6FF1381E1FF00D08723 /* towns_audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B6F71381E1FF00D08723 /* towns_audio.cpp */; };
- DF46B7001381E1FF00D08723 /* towns_euphony.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B6F91381E1FF00D08723 /* towns_euphony.cpp */; };
- DF46B7011381E1FF00D08723 /* towns_pc98_driver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B6FB1381E1FF00D08723 /* towns_pc98_driver.cpp */; };
- DF46B7021381E1FF00D08723 /* towns_pc98_fmsynth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B6FD1381E1FF00D08723 /* towns_pc98_fmsynth.cpp */; };
- DF46B7031381E1FF00D08723 /* towns_audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B6F71381E1FF00D08723 /* towns_audio.cpp */; };
- DF46B7041381E1FF00D08723 /* towns_euphony.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B6F91381E1FF00D08723 /* towns_euphony.cpp */; };
- DF46B7051381E1FF00D08723 /* towns_pc98_driver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B6FB1381E1FF00D08723 /* towns_pc98_driver.cpp */; };
- DF46B7061381E1FF00D08723 /* towns_pc98_fmsynth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B6FD1381E1FF00D08723 /* towns_pc98_fmsynth.cpp */; };
- DF46B7071381E1FF00D08723 /* towns_audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B6F71381E1FF00D08723 /* towns_audio.cpp */; };
- DF46B7081381E1FF00D08723 /* towns_euphony.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B6F91381E1FF00D08723 /* towns_euphony.cpp */; };
- DF46B7091381E1FF00D08723 /* towns_pc98_driver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B6FB1381E1FF00D08723 /* towns_pc98_driver.cpp */; };
- DF46B70A1381E1FF00D08723 /* towns_pc98_fmsynth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B6FD1381E1FF00D08723 /* towns_pc98_fmsynth.cpp */; };
- DF46B7191381E27000D08723 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B70F1381E27000D08723 /* console.cpp */; };
- DF46B71A1381E27000D08723 /* databases.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7111381E27000D08723 /* databases.cpp */; };
- DF46B71B1381E27000D08723 /* dbase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7131381E27000D08723 /* dbase.cpp */; };
- DF46B71C1381E27000D08723 /* iniconfig.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7151381E27000D08723 /* iniconfig.cpp */; };
- DF46B71D1381E27000D08723 /* init_v7.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7171381E27000D08723 /* init_v7.cpp */; };
- DF46B71E1381E27000D08723 /* inter_inca2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7181381E27000D08723 /* inter_inca2.cpp */; };
- DF46B71F1381E27000D08723 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B70F1381E27000D08723 /* console.cpp */; };
- DF46B7201381E27000D08723 /* databases.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7111381E27000D08723 /* databases.cpp */; };
- DF46B7211381E27000D08723 /* dbase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7131381E27000D08723 /* dbase.cpp */; };
- DF46B7221381E27000D08723 /* iniconfig.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7151381E27000D08723 /* iniconfig.cpp */; };
- DF46B7231381E27000D08723 /* init_v7.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7171381E27000D08723 /* init_v7.cpp */; };
- DF46B7241381E27000D08723 /* inter_inca2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7181381E27000D08723 /* inter_inca2.cpp */; };
- DF46B7251381E27000D08723 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B70F1381E27000D08723 /* console.cpp */; };
- DF46B7261381E27000D08723 /* databases.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7111381E27000D08723 /* databases.cpp */; };
- DF46B7271381E27000D08723 /* dbase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7131381E27000D08723 /* dbase.cpp */; };
- DF46B7281381E27000D08723 /* iniconfig.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7151381E27000D08723 /* iniconfig.cpp */; };
- DF46B7291381E27000D08723 /* init_v7.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7171381E27000D08723 /* init_v7.cpp */; };
- DF46B72A1381E27000D08723 /* inter_inca2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7181381E27000D08723 /* inter_inca2.cpp */; };
- DF46B7441381E40500D08723 /* log.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7421381E40500D08723 /* log.cpp */; };
- DF46B7451381E40500D08723 /* log.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7421381E40500D08723 /* log.cpp */; };
- DF46B7461381E40500D08723 /* log.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7421381E40500D08723 /* log.cpp */; };
- DF46B7491381E40F00D08723 /* modular-backend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7471381E40F00D08723 /* modular-backend.cpp */; };
- DF46B74A1381E40F00D08723 /* modular-backend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7471381E40F00D08723 /* modular-backend.cpp */; };
- DF46B74B1381E40F00D08723 /* modular-backend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7471381E40F00D08723 /* modular-backend.cpp */; };
- DF46B7541381E46700D08723 /* player_v2base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7511381E46700D08723 /* player_v2base.cpp */; };
- DF46B7551381E46700D08723 /* player_v2base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7511381E46700D08723 /* player_v2base.cpp */; };
- DF46B7561381E46700D08723 /* player_v2base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7511381E46700D08723 /* player_v2base.cpp */; };
- DF46B75E1381E4A400D08723 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B75B1381E4A400D08723 /* console.cpp */; };
- DF46B75F1381E4A400D08723 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B75B1381E4A400D08723 /* console.cpp */; };
- DF46B7601381E4A400D08723 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B75B1381E4A400D08723 /* console.cpp */; };
- DF46B7631381E4D400D08723 /* robot_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7611381E4D400D08723 /* robot_decoder.cpp */; };
- DF46B7641381E4D400D08723 /* robot_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7611381E4D400D08723 /* robot_decoder.cpp */; };
- DF46B7651381E4D400D08723 /* robot_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7611381E4D400D08723 /* robot_decoder.cpp */; };
- DF46B7671381E4E400D08723 /* vm_types.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7661381E4E400D08723 /* vm_types.cpp */; };
- DF46B7681381E4E400D08723 /* vm_types.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7661381E4E400D08723 /* vm_types.cpp */; };
- DF46B7691381E4E400D08723 /* vm_types.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7661381E4E400D08723 /* vm_types.cpp */; };
- DF46B77B1381E54200D08723 /* dcl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B76F1381E54200D08723 /* dcl.cpp */; };
- DF46B77C1381E54200D08723 /* iff_container.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7721381E54200D08723 /* iff_container.cpp */; };
- DF46B77D1381E54200D08723 /* winexe_ne.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7751381E54200D08723 /* winexe_ne.cpp */; };
- DF46B77E1381E54200D08723 /* winexe_pe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7771381E54200D08723 /* winexe_pe.cpp */; };
- DF46B77F1381E54200D08723 /* winexe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7791381E54200D08723 /* winexe.cpp */; };
- DF46B7801381E54200D08723 /* dcl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B76F1381E54200D08723 /* dcl.cpp */; };
- DF46B7811381E54200D08723 /* iff_container.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7721381E54200D08723 /* iff_container.cpp */; };
- DF46B7821381E54200D08723 /* winexe_ne.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7751381E54200D08723 /* winexe_ne.cpp */; };
- DF46B7831381E54200D08723 /* winexe_pe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7771381E54200D08723 /* winexe_pe.cpp */; };
- DF46B7841381E54200D08723 /* winexe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7791381E54200D08723 /* winexe.cpp */; };
- DF46B7851381E54200D08723 /* dcl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B76F1381E54200D08723 /* dcl.cpp */; };
- DF46B7861381E54200D08723 /* iff_container.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7721381E54200D08723 /* iff_container.cpp */; };
- DF46B7871381E54200D08723 /* winexe_ne.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7751381E54200D08723 /* winexe_ne.cpp */; };
- DF46B7881381E54200D08723 /* winexe_pe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7771381E54200D08723 /* winexe_pe.cpp */; };
- DF46B7891381E54200D08723 /* winexe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7791381E54200D08723 /* winexe.cpp */; };
- DF46B7931381E58000D08723 /* png.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B78F1381E58000D08723 /* png.cpp */; };
- DF46B7941381E58000D08723 /* wincursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7911381E58000D08723 /* wincursor.cpp */; };
- DF46B7951381E58000D08723 /* png.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B78F1381E58000D08723 /* png.cpp */; };
- DF46B7961381E58000D08723 /* wincursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7911381E58000D08723 /* wincursor.cpp */; };
- DF46B7971381E58000D08723 /* png.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B78F1381E58000D08723 /* png.cpp */; };
- DF46B7981381E58000D08723 /* wincursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7911381E58000D08723 /* wincursor.cpp */; };
- DF46B79F1381E5B500D08723 /* winfont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B79D1381E5B500D08723 /* winfont.cpp */; };
- DF46B7A01381E5B500D08723 /* winfont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B79D1381E5B500D08723 /* winfont.cpp */; };
- DF46B7A11381E5B500D08723 /* winfont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B79D1381E5B500D08723 /* winfont.cpp */; };
- DF46B7A51381E5D900D08723 /* sdl-timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7A31381E5D900D08723 /* sdl-timer.cpp */; };
- DF46B7A91381E5F100D08723 /* header.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7A81381E5F100D08723 /* header.cpp */; };
- DF46B7AA1381E5F100D08723 /* header.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7A81381E5F100D08723 /* header.cpp */; };
- DF46B7AB1381E5F100D08723 /* header.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7A81381E5F100D08723 /* header.cpp */; };
- DF46B7B41381E67800D08723 /* sdl-mutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7B21381E67800D08723 /* sdl-mutex.cpp */; };
- DF46B7B51381E67800D08723 /* sdl-mutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7B21381E67800D08723 /* sdl-mutex.cpp */; };
- DF46B7B61381E67800D08723 /* sdl-mutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7B21381E67800D08723 /* sdl-mutex.cpp */; };
- DF46B7BD1381E6C000D08723 /* object.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7BB1381E6C000D08723 /* object.cpp */; };
- DF46B7BE1381E6C000D08723 /* object.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7BB1381E6C000D08723 /* object.cpp */; };
- DF46B7BF1381E6C000D08723 /* object.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7BB1381E6C000D08723 /* object.cpp */; };
- DF46B7C81381E72500D08723 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7C61381E72500D08723 /* console.cpp */; };
- DF46B7C91381E72500D08723 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7C61381E72500D08723 /* console.cpp */; };
- DF46B7CA1381E72500D08723 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7C61381E72500D08723 /* console.cpp */; };
- DF46B7CF1381E76300D08723 /* sdl-events.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7CD1381E76300D08723 /* sdl-events.cpp */; };
- DF46B7D61381E7C600D08723 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7D41381E7C600D08723 /* console.cpp */; };
- DF46B7D71381E7C600D08723 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7D41381E7C600D08723 /* console.cpp */; };
- DF46B7D81381E7C600D08723 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B7D41381E7C600D08723 /* console.cpp */; };
- DF46B83C1381F13500D08723 /* saveload_v7.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B83B1381F13500D08723 /* saveload_v7.cpp */; };
- DF46B83D1381F13500D08723 /* saveload_v7.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B83B1381F13500D08723 /* saveload_v7.cpp */; };
- DF46B83E1381F13500D08723 /* saveload_v7.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B83B1381F13500D08723 /* saveload_v7.cpp */; };
- DF46B8441381F35500D08723 /* saveload_inca2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B8431381F35500D08723 /* saveload_inca2.cpp */; };
- DF46B8451381F35500D08723 /* saveload_inca2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B8431381F35500D08723 /* saveload_inca2.cpp */; };
- DF46B8461381F35500D08723 /* saveload_inca2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B8431381F35500D08723 /* saveload_inca2.cpp */; };
- DF46B8481381F38700D08723 /* inter_v7.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B8471381F38700D08723 /* inter_v7.cpp */; };
- DF46B8491381F38700D08723 /* inter_v7.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B8471381F38700D08723 /* inter_v7.cpp */; };
- DF46B84A1381F38700D08723 /* inter_v7.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B8471381F38700D08723 /* inter_v7.cpp */; };
- DF46B84D1381F39E00D08723 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B84B1381F39E00D08723 /* console.cpp */; };
- DF46B84E1381F39E00D08723 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B84B1381F39E00D08723 /* console.cpp */; };
- DF46B84F1381F39E00D08723 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B84B1381F39E00D08723 /* console.cpp */; };
- DF46B8521381F3B400D08723 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B8501381F3B400D08723 /* console.cpp */; };
- DF46B8531381F3B400D08723 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B8501381F3B400D08723 /* console.cpp */; };
- DF46B8541381F3B400D08723 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B8501381F3B400D08723 /* console.cpp */; };
- DF46B8601381F44E00D08723 /* dbopl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B85A1381F44E00D08723 /* dbopl.cpp */; };
- DF46B8611381F44E00D08723 /* dosbox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B85C1381F44E00D08723 /* dosbox.cpp */; };
- DF46B8621381F44E00D08723 /* mame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B85E1381F44E00D08723 /* mame.cpp */; };
- DF46B8631381F44E00D08723 /* dbopl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B85A1381F44E00D08723 /* dbopl.cpp */; };
- DF46B8641381F44E00D08723 /* dosbox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B85C1381F44E00D08723 /* dosbox.cpp */; };
- DF46B8651381F44E00D08723 /* mame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B85E1381F44E00D08723 /* mame.cpp */; };
- DF46B8661381F44E00D08723 /* dbopl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B85A1381F44E00D08723 /* dbopl.cpp */; };
- DF46B8671381F44E00D08723 /* dosbox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B85C1381F44E00D08723 /* dosbox.cpp */; };
- DF46B8681381F44E00D08723 /* mame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B85E1381F44E00D08723 /* mame.cpp */; };
- DF46B8711381F4A200D08723 /* sdl-audiocd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B86F1381F4A200D08723 /* sdl-audiocd.cpp */; };
- DF46B8721381F4A200D08723 /* sdl-audiocd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B86F1381F4A200D08723 /* sdl-audiocd.cpp */; };
- DF46B8731381F4A200D08723 /* sdl-audiocd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B86F1381F4A200D08723 /* sdl-audiocd.cpp */; };
- DF46B87D1381F4F200D08723 /* default-audiocd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B87B1381F4F200D08723 /* default-audiocd.cpp */; };
- DF46B87E1381F4F200D08723 /* default-audiocd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B87B1381F4F200D08723 /* default-audiocd.cpp */; };
- DF46B87F1381F4F200D08723 /* default-audiocd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B87B1381F4F200D08723 /* default-audiocd.cpp */; };
- DF46B8891381F5D800D08723 /* sdl-provider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B8871381F5D800D08723 /* sdl-provider.cpp */; };
- DF46B88A1381F5D800D08723 /* sdl-provider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B8871381F5D800D08723 /* sdl-provider.cpp */; };
- DF46B88B1381F5D800D08723 /* sdl-provider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B8871381F5D800D08723 /* sdl-provider.cpp */; };
- DF46B8921381F62B00D08723 /* adpcm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B8901381F62B00D08723 /* adpcm.cpp */; };
- DF46B8931381F62B00D08723 /* adpcm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B8901381F62B00D08723 /* adpcm.cpp */; };
- DF46B8941381F62B00D08723 /* adpcm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B8901381F62B00D08723 /* adpcm.cpp */; };
- DF46B89B1381F6C400D08723 /* null.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B8991381F6C400D08723 /* null.cpp */; };
- DF46B89C1381F6C400D08723 /* null.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B8991381F6C400D08723 /* null.cpp */; };
- DF46B89D1381F6C400D08723 /* null.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF46B8991381F6C400D08723 /* null.cpp */; };
- DF573C080F5A81EA00961A72 /* state.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF573C010F5A81EA00961A72 /* state.cpp */; };
- DF573CBB0F5A85B300961A72 /* exec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF573CBA0F5A85B300961A72 /* exec.cpp */; };
- DF573CBE0F5A85E100961A72 /* timer_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF573CBD0F5A85E100961A72 /* timer_lol.cpp */; };
- DF5CEB290F75535000DEA624 /* sound_br.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF5CEB260F75535000DEA624 /* sound_br.cpp */; };
- DF5CEB2A0F75535000DEA624 /* sound_ns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF5CEB270F75535000DEA624 /* sound_ns.cpp */; };
- DF5CEB2C0F75535000DEA624 /* sound_br.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF5CEB260F75535000DEA624 /* sound_br.cpp */; };
- DF5CEB2D0F75535000DEA624 /* sound_ns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF5CEB270F75535000DEA624 /* sound_ns.cpp */; };
- DF5CEB310F75538000DEA624 /* protracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF5CEB2F0F75538000DEA624 /* protracker.cpp */; };
- DF5CEB320F75538000DEA624 /* protracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF5CEB2F0F75538000DEA624 /* protracker.cpp */; };
- DF61183C0FE3A8080042AD3F /* kmisc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118380FE3A8080042AD3F /* kmisc.cpp */; };
- DF61183D0FE3A8080042AD3F /* segment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118390FE3A8080042AD3F /* segment.cpp */; };
- DF61183E0FE3A8080042AD3F /* kmisc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118380FE3A8080042AD3F /* kmisc.cpp */; };
- DF61183F0FE3A8080042AD3F /* segment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118390FE3A8080042AD3F /* segment.cpp */; };
- DF6118400FE3A8080042AD3F /* kmisc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118380FE3A8080042AD3F /* kmisc.cpp */; };
- DF6118410FE3A8080042AD3F /* segment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118390FE3A8080042AD3F /* segment.cpp */; };
- DF6118490FE3A8250042AD3F /* decompressor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118430FE3A8250042AD3F /* decompressor.cpp */; };
- DF61184A0FE3A8250042AD3F /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118450FE3A8250042AD3F /* resource.cpp */; };
- DF61184C0FE3A8250042AD3F /* decompressor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118430FE3A8250042AD3F /* decompressor.cpp */; };
- DF61184D0FE3A8250042AD3F /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118450FE3A8250042AD3F /* resource.cpp */; };
- DF61184F0FE3A8250042AD3F /* decompressor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118430FE3A8250042AD3F /* decompressor.cpp */; };
- DF6118500FE3A8250042AD3F /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118450FE3A8250042AD3F /* resource.cpp */; };
- DF6118550FE3A8990042AD3F /* disk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118540FE3A8990042AD3F /* disk.cpp */; };
- DF6118560FE3A8990042AD3F /* disk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118540FE3A8990042AD3F /* disk.cpp */; };
- DF6118570FE3A8990042AD3F /* disk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118540FE3A8990042AD3F /* disk.cpp */; };
- DF6118890FE3A9AA0042AD3F /* saveconverter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118790FE3A9AA0042AD3F /* saveconverter.cpp */; };
- DF61188A0FE3A9AA0042AD3F /* saveconverter_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF61187B0FE3A9AA0042AD3F /* saveconverter_v2.cpp */; };
- DF61188B0FE3A9AA0042AD3F /* saveconverter_v3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF61187C0FE3A9AA0042AD3F /* saveconverter_v3.cpp */; };
- DF61188C0FE3A9AA0042AD3F /* saveconverter_v4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF61187D0FE3A9AA0042AD3F /* saveconverter_v4.cpp */; };
- DF61188E0FE3A9AA0042AD3F /* savefile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF61187F0FE3A9AA0042AD3F /* savefile.cpp */; };
- DF61188F0FE3A9AA0042AD3F /* savehandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118810FE3A9AA0042AD3F /* savehandler.cpp */; };
- DF6118900FE3A9AA0042AD3F /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118830FE3A9AA0042AD3F /* saveload.cpp */; };
- DF6118910FE3A9AA0042AD3F /* saveload_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118850FE3A9AA0042AD3F /* saveload_v2.cpp */; };
- DF6118920FE3A9AA0042AD3F /* saveload_v3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118860FE3A9AA0042AD3F /* saveload_v3.cpp */; };
- DF6118930FE3A9AA0042AD3F /* saveload_v4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118870FE3A9AA0042AD3F /* saveload_v4.cpp */; };
- DF6118940FE3A9AA0042AD3F /* saveload_v6.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118880FE3A9AA0042AD3F /* saveload_v6.cpp */; };
- DF6118950FE3A9AA0042AD3F /* saveconverter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118790FE3A9AA0042AD3F /* saveconverter.cpp */; };
- DF6118960FE3A9AA0042AD3F /* saveconverter_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF61187B0FE3A9AA0042AD3F /* saveconverter_v2.cpp */; };
- DF6118970FE3A9AA0042AD3F /* saveconverter_v3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF61187C0FE3A9AA0042AD3F /* saveconverter_v3.cpp */; };
- DF6118980FE3A9AA0042AD3F /* saveconverter_v4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF61187D0FE3A9AA0042AD3F /* saveconverter_v4.cpp */; };
- DF61189A0FE3A9AA0042AD3F /* savefile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF61187F0FE3A9AA0042AD3F /* savefile.cpp */; };
- DF61189B0FE3A9AA0042AD3F /* savehandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118810FE3A9AA0042AD3F /* savehandler.cpp */; };
- DF61189C0FE3A9AA0042AD3F /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118830FE3A9AA0042AD3F /* saveload.cpp */; };
- DF61189D0FE3A9AA0042AD3F /* saveload_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118850FE3A9AA0042AD3F /* saveload_v2.cpp */; };
- DF61189E0FE3A9AA0042AD3F /* saveload_v3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118860FE3A9AA0042AD3F /* saveload_v3.cpp */; };
- DF61189F0FE3A9AA0042AD3F /* saveload_v4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118870FE3A9AA0042AD3F /* saveload_v4.cpp */; };
- DF6118A00FE3A9AA0042AD3F /* saveload_v6.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118880FE3A9AA0042AD3F /* saveload_v6.cpp */; };
- DF6118A10FE3A9AA0042AD3F /* saveconverter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118790FE3A9AA0042AD3F /* saveconverter.cpp */; };
- DF6118A20FE3A9AA0042AD3F /* saveconverter_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF61187B0FE3A9AA0042AD3F /* saveconverter_v2.cpp */; };
- DF6118A30FE3A9AA0042AD3F /* saveconverter_v3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF61187C0FE3A9AA0042AD3F /* saveconverter_v3.cpp */; };
- DF6118A40FE3A9AA0042AD3F /* saveconverter_v4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF61187D0FE3A9AA0042AD3F /* saveconverter_v4.cpp */; };
- DF6118A60FE3A9AA0042AD3F /* savefile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF61187F0FE3A9AA0042AD3F /* savefile.cpp */; };
- DF6118A70FE3A9AA0042AD3F /* savehandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118810FE3A9AA0042AD3F /* savehandler.cpp */; };
- DF6118A80FE3A9AA0042AD3F /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118830FE3A9AA0042AD3F /* saveload.cpp */; };
- DF6118A90FE3A9AA0042AD3F /* saveload_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118850FE3A9AA0042AD3F /* saveload_v2.cpp */; };
- DF6118AA0FE3A9AA0042AD3F /* saveload_v3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118860FE3A9AA0042AD3F /* saveload_v3.cpp */; };
- DF6118AB0FE3A9AA0042AD3F /* saveload_v4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118870FE3A9AA0042AD3F /* saveload_v4.cpp */; };
- DF6118AC0FE3A9AA0042AD3F /* saveload_v6.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118880FE3A9AA0042AD3F /* saveload_v6.cpp */; };
- DF6118AF0FE3A9EA0042AD3F /* feeble.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118AE0FE3A9EA0042AD3F /* feeble.cpp */; };
- DF6118B00FE3A9EA0042AD3F /* feeble.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118AE0FE3A9EA0042AD3F /* feeble.cpp */; };
- DF6118B10FE3A9EA0042AD3F /* feeble.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118AE0FE3A9EA0042AD3F /* feeble.cpp */; };
- DF6118B80FE3AA280042AD3F /* saveload_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118B30FE3AA280042AD3F /* saveload_lol.cpp */; };
- DF6118B90FE3AA280042AD3F /* sound_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118B40FE3AA280042AD3F /* sound_lol.cpp */; };
- DF6118BA0FE3AA280042AD3F /* sound_pcspk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118B50FE3AA280042AD3F /* sound_pcspk.cpp */; };
- DF6118BB0FE3AA280042AD3F /* text_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118B60FE3AA280042AD3F /* text_lol.cpp */; };
- DF6118BC0FE3AA280042AD3F /* saveload_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118B30FE3AA280042AD3F /* saveload_lol.cpp */; };
- DF6118BD0FE3AA280042AD3F /* sound_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118B40FE3AA280042AD3F /* sound_lol.cpp */; };
- DF6118BE0FE3AA280042AD3F /* sound_pcspk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118B50FE3AA280042AD3F /* sound_pcspk.cpp */; };
- DF6118BF0FE3AA280042AD3F /* text_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118B60FE3AA280042AD3F /* text_lol.cpp */; };
- DF6118C00FE3AA280042AD3F /* saveload_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118B30FE3AA280042AD3F /* saveload_lol.cpp */; };
- DF6118C10FE3AA280042AD3F /* sound_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118B40FE3AA280042AD3F /* sound_lol.cpp */; };
- DF6118C20FE3AA280042AD3F /* sound_pcspk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118B50FE3AA280042AD3F /* sound_pcspk.cpp */; };
- DF6118C30FE3AA280042AD3F /* text_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118B60FE3AA280042AD3F /* text_lol.cpp */; };
- DF6118C70FE3AABD0042AD3F /* player_v2cms.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118C60FE3AABD0042AD3F /* player_v2cms.cpp */; };
- DF6118C80FE3AABD0042AD3F /* player_v2cms.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118C60FE3AABD0042AD3F /* player_v2cms.cpp */; };
- DF6118C90FE3AABD0042AD3F /* player_v2cms.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118C60FE3AABD0042AD3F /* player_v2cms.cpp */; };
- DF6118CC0FE3AAFD0042AD3F /* hardwarekeys.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6118CB0FE3AAFD0042AD3F /* hardwarekeys.cpp */; };
- DF6BF4C410529DA50069811F /* conversion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4C010529DA50069811F /* conversion.cpp */; };
- DF6BF4C510529DA50069811F /* jpeg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4C210529DA50069811F /* jpeg.cpp */; };
- DF6BF4C610529DA50069811F /* conversion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4C010529DA50069811F /* conversion.cpp */; };
- DF6BF4C710529DA50069811F /* jpeg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4C210529DA50069811F /* jpeg.cpp */; };
- DF6BF4C810529DA50069811F /* conversion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4C010529DA50069811F /* conversion.cpp */; };
- DF6BF4C910529DA50069811F /* jpeg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4C210529DA50069811F /* jpeg.cpp */; };
- DF6BF4D810529DE90069811F /* input_pn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4D510529DE90069811F /* input_pn.cpp */; };
- DF6BF4D910529DE90069811F /* string_pn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4D610529DE90069811F /* string_pn.cpp */; };
- DF6BF4DA10529DE90069811F /* verb_pn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4D710529DE90069811F /* verb_pn.cpp */; };
- DF6BF4DB10529DE90069811F /* input_pn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4D510529DE90069811F /* input_pn.cpp */; };
- DF6BF4DC10529DE90069811F /* string_pn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4D610529DE90069811F /* string_pn.cpp */; };
- DF6BF4DD10529DE90069811F /* verb_pn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4D710529DE90069811F /* verb_pn.cpp */; };
- DF6BF4DE10529DE90069811F /* input_pn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4D510529DE90069811F /* input_pn.cpp */; };
- DF6BF4DF10529DE90069811F /* string_pn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4D610529DE90069811F /* string_pn.cpp */; };
- DF6BF4E010529DE90069811F /* verb_pn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4D710529DE90069811F /* verb_pn.cpp */; };
- DF6BF4E410529E260069811F /* sound_amiga.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4E310529E260069811F /* sound_amiga.cpp */; };
- DF6BF4E510529E260069811F /* sound_amiga.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4E310529E260069811F /* sound_amiga.cpp */; };
- DF6BF4E610529E260069811F /* sound_amiga.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4E310529E260069811F /* sound_amiga.cpp */; };
- DF6BF4EA10529E6E0069811F /* init_v4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4E810529E6E0069811F /* init_v4.cpp */; };
- DF6BF4EB10529E6E0069811F /* inter_playtoons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4E910529E6E0069811F /* inter_playtoons.cpp */; };
- DF6BF4EC10529E6E0069811F /* init_v4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4E810529E6E0069811F /* init_v4.cpp */; };
- DF6BF4ED10529E6E0069811F /* inter_playtoons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4E910529E6E0069811F /* inter_playtoons.cpp */; };
- DF6BF4EE10529E6E0069811F /* init_v4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4E810529E6E0069811F /* init_v4.cpp */; };
- DF6BF4EF10529E6E0069811F /* inter_playtoons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4E910529E6E0069811F /* inter_playtoons.cpp */; };
- DF6BF4F310529EE40069811F /* player_v4a.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4F110529EE40069811F /* player_v4a.cpp */; };
- DF6BF4F410529EE40069811F /* player_v4a.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4F110529EE40069811F /* player_v4a.cpp */; };
- DF6BF4F510529EE40069811F /* player_v4a.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4F110529EE40069811F /* player_v4a.cpp */; };
- DF6BF4FC10529F140069811F /* EventDispatcher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4F710529F140069811F /* EventDispatcher.cpp */; };
- DF6BF4FD10529F140069811F /* EventRecorder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4F810529F140069811F /* EventRecorder.cpp */; };
- DF6BF4FE10529F140069811F /* EventDispatcher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4F710529F140069811F /* EventDispatcher.cpp */; };
- DF6BF4FF10529F140069811F /* EventRecorder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4F810529F140069811F /* EventRecorder.cpp */; };
- DF6BF50010529F140069811F /* EventDispatcher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4F710529F140069811F /* EventDispatcher.cpp */; };
- DF6BF50110529F140069811F /* EventRecorder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6BF4F810529F140069811F /* EventRecorder.cpp */; };
- DF7585CE100CB66E00CC3324 /* expression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585C3100CB66E00CC3324 /* expression.cpp */; };
- DF7585CF100CB66E00CC3324 /* hotspots.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585C5100CB66E00CC3324 /* hotspots.cpp */; };
- DF7585D0100CB66E00CC3324 /* init_v6.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585C7100CB66E00CC3324 /* init_v6.cpp */; };
- DF7585D1100CB66E00CC3324 /* resources.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585C8100CB66E00CC3324 /* resources.cpp */; };
- DF7585D2100CB66E00CC3324 /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585CA100CB66E00CC3324 /* script.cpp */; };
- DF7585D3100CB66E00CC3324 /* totfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585CC100CB66E00CC3324 /* totfile.cpp */; };
- DF7585D4100CB66E00CC3324 /* expression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585C3100CB66E00CC3324 /* expression.cpp */; };
- DF7585D5100CB66E00CC3324 /* hotspots.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585C5100CB66E00CC3324 /* hotspots.cpp */; };
- DF7585D6100CB66E00CC3324 /* init_v6.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585C7100CB66E00CC3324 /* init_v6.cpp */; };
- DF7585D7100CB66E00CC3324 /* resources.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585C8100CB66E00CC3324 /* resources.cpp */; };
- DF7585D8100CB66E00CC3324 /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585CA100CB66E00CC3324 /* script.cpp */; };
- DF7585D9100CB66E00CC3324 /* totfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585CC100CB66E00CC3324 /* totfile.cpp */; };
- DF7585DA100CB66E00CC3324 /* expression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585C3100CB66E00CC3324 /* expression.cpp */; };
- DF7585DB100CB66E00CC3324 /* hotspots.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585C5100CB66E00CC3324 /* hotspots.cpp */; };
- DF7585DC100CB66E00CC3324 /* init_v6.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585C7100CB66E00CC3324 /* init_v6.cpp */; };
- DF7585DD100CB66E00CC3324 /* resources.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585C8100CB66E00CC3324 /* resources.cpp */; };
- DF7585DE100CB66E00CC3324 /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585CA100CB66E00CC3324 /* script.cpp */; };
- DF7585DF100CB66E00CC3324 /* totfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585CC100CB66E00CC3324 /* totfile.cpp */; };
- DF7585EC100CB6EA00CC3324 /* sjis.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585EA100CB6EA00CC3324 /* sjis.cpp */; };
- DF7585ED100CB6EA00CC3324 /* sjis.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585EA100CB6EA00CC3324 /* sjis.cpp */; };
- DF7585EE100CB6EA00CC3324 /* sjis.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585EA100CB6EA00CC3324 /* sjis.cpp */; };
- DF7585F1100CB70600CC3324 /* saveload_playtoons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585F0100CB70600CC3324 /* saveload_playtoons.cpp */; };
- DF7585F2100CB70600CC3324 /* saveload_playtoons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585F0100CB70600CC3324 /* saveload_playtoons.cpp */; };
- DF7585F3100CB70600CC3324 /* saveload_playtoons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585F0100CB70600CC3324 /* saveload_playtoons.cpp */; };
- DF7585F7100CB75800CC3324 /* static_selectors.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585F6100CB75800CC3324 /* static_selectors.cpp */; };
- DF7585F8100CB75800CC3324 /* static_selectors.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585F6100CB75800CC3324 /* static_selectors.cpp */; };
- DF7585F9100CB75800CC3324 /* static_selectors.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7585F6100CB75800CC3324 /* static_selectors.cpp */; };
- DF758619100CBA0200CC3324 /* osys_events.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF758614100CBA0200CC3324 /* osys_events.cpp */; };
- DF75861A100CBA0200CC3324 /* osys_main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF758615100CBA0200CC3324 /* osys_main.cpp */; };
- DF75861B100CBA0200CC3324 /* osys_sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF758617100CBA0200CC3324 /* osys_sound.cpp */; };
- DF75861C100CBA0200CC3324 /* osys_video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF758618100CBA0200CC3324 /* osys_video.cpp */; };
- DF75861D100CBA0200CC3324 /* osys_events.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF758614100CBA0200CC3324 /* osys_events.cpp */; };
- DF75861E100CBA0200CC3324 /* osys_main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF758615100CBA0200CC3324 /* osys_main.cpp */; };
- DF75861F100CBA0200CC3324 /* osys_sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF758617100CBA0200CC3324 /* osys_sound.cpp */; };
- DF758620100CBA0200CC3324 /* osys_video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF758618100CBA0200CC3324 /* osys_video.cpp */; };
- DF7E8BFD0ED5FC77001CB19F /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8BF00ED5FC77001CB19F /* saveload.cpp */; };
- DF7E8BFF0ED5FC77001CB19F /* ThemeEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8BF40ED5FC77001CB19F /* ThemeEngine.cpp */; };
- DF7E8C000ED5FC77001CB19F /* ThemeEval.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8BF60ED5FC77001CB19F /* ThemeEval.cpp */; };
- DF7E8C010ED5FC77001CB19F /* ThemeLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8BF80ED5FC77001CB19F /* ThemeLayout.cpp */; };
- DF7E8C020ED5FC77001CB19F /* ThemeParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8BFA0ED5FC77001CB19F /* ThemeParser.cpp */; };
- DF7E8C0C0ED5FCAF001CB19F /* thumbnail.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8C050ED5FCAF001CB19F /* thumbnail.cpp */; };
- DF7E8C0D0ED5FCAF001CB19F /* VectorRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8C070ED5FCAF001CB19F /* VectorRenderer.cpp */; };
- DF7E8C0E0ED5FCAF001CB19F /* VectorRendererSpec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8C090ED5FCAF001CB19F /* VectorRendererSpec.cpp */; };
- DF7E8C110ED5FCC2001CB19F /* xmlparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8C0F0ED5FCC2001CB19F /* xmlparser.cpp */; };
- DF7E8C530ED60067001CB19F /* game.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8C510ED60067001CB19F /* game.cpp */; };
- DF7E8C810ED60271001CB19F /* scummmodern.zip in Resources */ = {isa = PBXBuildFile; fileRef = DF7E8C7A0ED601E5001CB19F /* scummmodern.zip */; };
- DF7F286111FF23D500159131 /* amigamac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F286011FF23D500159131 /* amigamac.cpp */; };
- DF7F286211FF23D500159131 /* amigamac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F286011FF23D500159131 /* amigamac.cpp */; };
- DF7F286311FF23D500159131 /* amigamac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F286011FF23D500159131 /* amigamac.cpp */; };
- DF7F286711FF23EF00159131 /* kvideo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F286411FF23EF00159131 /* kvideo.cpp */; };
- DF7F286811FF23EF00159131 /* workarounds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F286511FF23EF00159131 /* workarounds.cpp */; };
- DF7F286911FF23EF00159131 /* kvideo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F286411FF23EF00159131 /* kvideo.cpp */; };
- DF7F286A11FF23EF00159131 /* workarounds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F286511FF23EF00159131 /* workarounds.cpp */; };
- DF7F286B11FF23EF00159131 /* kvideo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F286411FF23EF00159131 /* kvideo.cpp */; };
- DF7F286C11FF23EF00159131 /* workarounds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F286511FF23EF00159131 /* workarounds.cpp */; };
- DF7F287A11FF243B00159131 /* sound_2gs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F287011FF243A00159131 /* sound_2gs.cpp */; };
- DF7F287B11FF243B00159131 /* sound_coco3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F287211FF243B00159131 /* sound_coco3.cpp */; };
- DF7F287C11FF243B00159131 /* sound_midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F287411FF243B00159131 /* sound_midi.cpp */; };
- DF7F287D11FF243B00159131 /* sound_pcjr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F287611FF243B00159131 /* sound_pcjr.cpp */; };
- DF7F287E11FF243B00159131 /* sound_sarien.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F287811FF243B00159131 /* sound_sarien.cpp */; };
- DF7F287F11FF243B00159131 /* sound_2gs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F287011FF243A00159131 /* sound_2gs.cpp */; };
- DF7F288011FF243B00159131 /* sound_coco3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F287211FF243B00159131 /* sound_coco3.cpp */; };
- DF7F288111FF243B00159131 /* sound_midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F287411FF243B00159131 /* sound_midi.cpp */; };
- DF7F288211FF243B00159131 /* sound_pcjr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F287611FF243B00159131 /* sound_pcjr.cpp */; };
- DF7F288311FF243B00159131 /* sound_sarien.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F287811FF243B00159131 /* sound_sarien.cpp */; };
- DF7F288411FF243B00159131 /* sound_2gs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F287011FF243A00159131 /* sound_2gs.cpp */; };
- DF7F288511FF243B00159131 /* sound_coco3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F287211FF243B00159131 /* sound_coco3.cpp */; };
- DF7F288611FF243B00159131 /* sound_midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F287411FF243B00159131 /* sound_midi.cpp */; };
- DF7F288711FF243B00159131 /* sound_pcjr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F287611FF243B00159131 /* sound_pcjr.cpp */; };
- DF7F288811FF243B00159131 /* sound_sarien.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F287811FF243B00159131 /* sound_sarien.cpp */; };
- DF7F288B11FF244F00159131 /* Tooltip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F288911FF244F00159131 /* Tooltip.cpp */; };
- DF7F288C11FF244F00159131 /* Tooltip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F288911FF244F00159131 /* Tooltip.cpp */; };
- DF7F288D11FF244F00159131 /* Tooltip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F288911FF244F00159131 /* Tooltip.cpp */; };
- DF7F289311FF247300159131 /* translation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F289111FF247300159131 /* translation.cpp */; };
- DF7F289511FF247300159131 /* translation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F289111FF247300159131 /* translation.cpp */; };
- DF7F289711FF247300159131 /* translation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F289111FF247300159131 /* translation.cpp */; };
- DF7F28A511FF24C400159131 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F28A311FF24C400159131 /* console.cpp */; };
- DF7F28A611FF24C400159131 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F28A311FF24C400159131 /* console.cpp */; };
- DF7F28A711FF24C400159131 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7F28A311FF24C400159131 /* console.cpp */; };
- DF841FDD0E7BA61800F5680E /* iphone_keyboard.m in Sources */ = {isa = PBXBuildFile; fileRef = DF841FD90E7BA61800F5680E /* iphone_keyboard.m */; };
- DF841FDE0E7BA61800F5680E /* iphone_video.m in Sources */ = {isa = PBXBuildFile; fileRef = DF841FDB0E7BA61800F5680E /* iphone_video.m */; };
- DF84250A0E7BA6AC00F5680E /* agi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF841FF70E7BA6A600F5680E /* agi.cpp */; };
- DF84250B0E7BA6AC00F5680E /* checks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF841FF90E7BA6A600F5680E /* checks.cpp */; };
- DF84250C0E7BA6AC00F5680E /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF841FFA0E7BA6A600F5680E /* console.cpp */; };
- DF84250D0E7BA6AC00F5680E /* cycle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF841FFC0E7BA6A600F5680E /* cycle.cpp */; };
- DF84250E0E7BA6AC00F5680E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF841FFD0E7BA6A600F5680E /* detection.cpp */; };
- DF84250F0E7BA6AC00F5680E /* global.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF841FFF0E7BA6A600F5680E /* global.cpp */; };
- DF8425100E7BA6AC00F5680E /* graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420000E7BA6A600F5680E /* graphics.cpp */; };
- DF8425110E7BA6AC00F5680E /* id.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420020E7BA6A600F5680E /* id.cpp */; };
- DF8425120E7BA6AC00F5680E /* inv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420030E7BA6A600F5680E /* inv.cpp */; };
- DF8425130E7BA6AC00F5680E /* keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420040E7BA6A600F5680E /* keyboard.cpp */; };
- DF8425140E7BA6AC00F5680E /* loader_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420060E7BA6A600F5680E /* loader_v2.cpp */; };
- DF8425150E7BA6AC00F5680E /* loader_v3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420070E7BA6A600F5680E /* loader_v3.cpp */; };
- DF8425160E7BA6AC00F5680E /* logic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420080E7BA6A600F5680E /* logic.cpp */; };
- DF8425170E7BA6AC00F5680E /* lzw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84200A0E7BA6A600F5680E /* lzw.cpp */; };
- DF8425180E7BA6AC00F5680E /* menu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84200C0E7BA6A600F5680E /* menu.cpp */; };
- DF84251A0E7BA6AC00F5680E /* motion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84200F0E7BA6A600F5680E /* motion.cpp */; };
- DF84251B0E7BA6AC00F5680E /* objects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420100E7BA6A600F5680E /* objects.cpp */; };
- DF84251C0E7BA6AC00F5680E /* op_cmd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420110E7BA6A600F5680E /* op_cmd.cpp */; };
- DF84251D0E7BA6AC00F5680E /* op_dbg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420120E7BA6A600F5680E /* op_dbg.cpp */; };
- DF84251E0E7BA6AC00F5680E /* op_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420130E7BA6A600F5680E /* op_test.cpp */; };
- DF84251F0E7BA6AC00F5680E /* picture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420150E7BA6A600F5680E /* picture.cpp */; };
- DF8425200E7BA6AC00F5680E /* preagi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420170E7BA6A600F5680E /* preagi.cpp */; };
- DF8425210E7BA6AC00F5680E /* preagi_common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420190E7BA6A600F5680E /* preagi_common.cpp */; };
- DF8425220E7BA6AC00F5680E /* preagi_mickey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84201B0E7BA6A600F5680E /* preagi_mickey.cpp */; };
- DF8425230E7BA6AC00F5680E /* preagi_troll.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84201D0E7BA6A600F5680E /* preagi_troll.cpp */; };
- DF8425240E7BA6AC00F5680E /* preagi_winnie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84201F0E7BA6A600F5680E /* preagi_winnie.cpp */; };
- DF8425250E7BA6AC00F5680E /* predictive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420210E7BA6A600F5680E /* predictive.cpp */; };
- DF8425260E7BA6AC00F5680E /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420220E7BA6A600F5680E /* saveload.cpp */; };
- DF8425270E7BA6AC00F5680E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420230E7BA6A600F5680E /* sound.cpp */; };
- DF8425280E7BA6AC00F5680E /* sprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420250E7BA6A600F5680E /* sprite.cpp */; };
- DF8425290E7BA6AC00F5680E /* text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420270E7BA6A600F5680E /* text.cpp */; };
- DF84252A0E7BA6AC00F5680E /* view.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420280E7BA6A600F5680E /* view.cpp */; };
- DF84252B0E7BA6AC00F5680E /* wagparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84202A0E7BA6A600F5680E /* wagparser.cpp */; };
- DF84252C0E7BA6AC00F5680E /* words.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84202C0E7BA6A600F5680E /* words.cpp */; };
- DF84252D0E7BA6AC00F5680E /* agos.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84202E0E7BA6A600F5680E /* agos.cpp */; };
- DF84252E0E7BA6AC00F5680E /* animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420300E7BA6A600F5680E /* animation.cpp */; };
- DF84252F0E7BA6AC00F5680E /* charset-fontdata.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420320E7BA6A600F5680E /* charset-fontdata.cpp */; };
- DF8425300E7BA6AC00F5680E /* charset.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420330E7BA6A600F5680E /* charset.cpp */; };
- DF8425310E7BA6AC00F5680E /* contain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420340E7BA6A600F5680E /* contain.cpp */; };
- DF8425320E7BA6AC00F5680E /* cursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420350E7BA6A600F5680E /* cursor.cpp */; };
- DF8425330E7BA6AC00F5680E /* debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420360E7BA6A600F5680E /* debug.cpp */; };
- DF8425340E7BA6AC00F5680E /* debugger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420380E7BA6A600F5680E /* debugger.cpp */; };
- DF8425350E7BA6AC00F5680E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84203A0E7BA6A600F5680E /* detection.cpp */; };
- DF8425360E7BA6AC00F5680E /* draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84203C0E7BA6A600F5680E /* draw.cpp */; };
- DF8425370E7BA6AC00F5680E /* event.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84203D0E7BA6A600F5680E /* event.cpp */; };
- DF8425380E7BA6AC00F5680E /* gfx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84203E0E7BA6A600F5680E /* gfx.cpp */; };
- DF8425390E7BA6AC00F5680E /* icons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84203F0E7BA6A600F5680E /* icons.cpp */; };
- DF84253A0E7BA6AC00F5680E /* input.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420400E7BA6A600F5680E /* input.cpp */; };
- DF84253B0E7BA6AC00F5680E /* items.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420420E7BA6A600F5680E /* items.cpp */; };
- DF84253C0E7BA6AC00F5680E /* menus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420430E7BA6A600F5680E /* menus.cpp */; };
- DF84253D0E7BA6AC00F5680E /* midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420440E7BA6A600F5680E /* midi.cpp */; };
- DF84253E0E7BA6AC00F5680E /* midiparser_s1d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420460E7BA6A600F5680E /* midiparser_s1d.cpp */; };
- DF8425400E7BA6AC00F5680E /* oracle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420480E7BA6A600F5680E /* oracle.cpp */; };
- DF8425410E7BA6AC00F5680E /* res.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420490E7BA6A600F5680E /* res.cpp */; };
- DF8425420E7BA6AC00F5680E /* res_ami.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84204A0E7BA6A600F5680E /* res_ami.cpp */; };
- DF8425430E7BA6AC00F5680E /* res_snd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84204B0E7BA6A600F5680E /* res_snd.cpp */; };
- DF8425440E7BA6AC00F5680E /* rooms.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84204C0E7BA6A600F5680E /* rooms.cpp */; };
- DF8425450E7BA6AC00F5680E /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84204D0E7BA6A600F5680E /* saveload.cpp */; };
- DF8425460E7BA6AC00F5680E /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84204E0E7BA6A600F5680E /* script.cpp */; };
- DF8425470E7BA6AC00F5680E /* script_e1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84204F0E7BA6A600F5680E /* script_e1.cpp */; };
- DF8425480E7BA6AC00F5680E /* script_e2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420500E7BA6A600F5680E /* script_e2.cpp */; };
- DF8425490E7BA6AC00F5680E /* script_ff.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420510E7BA6A600F5680E /* script_ff.cpp */; };
- DF84254A0E7BA6AC00F5680E /* script_pp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420520E7BA6A600F5680E /* script_pp.cpp */; };
- DF84254B0E7BA6AC00F5680E /* script_s1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420530E7BA6A600F5680E /* script_s1.cpp */; };
- DF84254C0E7BA6AC00F5680E /* script_s2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420540E7BA6A600F5680E /* script_s2.cpp */; };
- DF84254D0E7BA6AC00F5680E /* script_ww.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420550E7BA6A600F5680E /* script_ww.cpp */; };
- DF84254E0E7BA6AC00F5680E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420560E7BA6A600F5680E /* sound.cpp */; };
- DF84254F0E7BA6AC00F5680E /* string.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420580E7BA6A600F5680E /* string.cpp */; };
- DF8425500E7BA6AC00F5680E /* subroutine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420590E7BA6A600F5680E /* subroutine.cpp */; };
- DF8425510E7BA6AC00F5680E /* verb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84205A0E7BA6A600F5680E /* verb.cpp */; };
- DF8425520E7BA6AC00F5680E /* vga.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84205B0E7BA6A600F5680E /* vga.cpp */; };
- DF8425530E7BA6AC00F5680E /* vga_e2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84205D0E7BA6A600F5680E /* vga_e2.cpp */; };
- DF8425540E7BA6AC00F5680E /* vga_ff.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84205E0E7BA6A600F5680E /* vga_ff.cpp */; };
- DF8425550E7BA6AC00F5680E /* vga_s1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84205F0E7BA6A600F5680E /* vga_s1.cpp */; };
- DF8425560E7BA6AC00F5680E /* vga_s2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420600E7BA6A600F5680E /* vga_s2.cpp */; };
- DF8425570E7BA6AC00F5680E /* vga_ww.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420610E7BA6A600F5680E /* vga_ww.cpp */; };
- DF8425580E7BA6AC00F5680E /* window.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420620E7BA6A600F5680E /* window.cpp */; };
- DF8425590E7BA6AC00F5680E /* zones.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420630E7BA6A600F5680E /* zones.cpp */; };
- DF84255A0E7BA6AC00F5680E /* anim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420650E7BA6A600F5680E /* anim.cpp */; };
- DF84255B0E7BA6AC00F5680E /* bg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420670E7BA6A600F5680E /* bg.cpp */; };
- DF84255C0E7BA6AC00F5680E /* bg_list.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420690E7BA6A600F5680E /* bg_list.cpp */; };
- DF84255D0E7BA6AC00F5680E /* cine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84206B0E7BA6A600F5680E /* cine.cpp */; };
- DF84255E0E7BA6AC00F5680E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84206D0E7BA6A600F5680E /* detection.cpp */; };
- DF84255F0E7BA6AC00F5680E /* gfx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84206E0E7BA6A600F5680E /* gfx.cpp */; };
- DF8425600E7BA6AC00F5680E /* main_loop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420700E7BA6A600F5680E /* main_loop.cpp */; };
- DF8425620E7BA6AC00F5680E /* msg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420730E7BA6A600F5680E /* msg.cpp */; };
- DF8425630E7BA6AC00F5680E /* object.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420750E7BA6A600F5680E /* object.cpp */; };
- DF8425640E7BA6AC00F5680E /* pal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420770E7BA6A600F5680E /* pal.cpp */; };
- DF8425650E7BA6AC00F5680E /* part.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420790E7BA6A600F5680E /* part.cpp */; };
- DF8425660E7BA6AC00F5680E /* prc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84207B0E7BA6A600F5680E /* prc.cpp */; };
- DF8425670E7BA6AC00F5680E /* rel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84207D0E7BA6A600F5680E /* rel.cpp */; };
- DF8425680E7BA6AC00F5680E /* script_fw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420800E7BA6A600F5680E /* script_fw.cpp */; };
- DF8425690E7BA6AC00F5680E /* script_os.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420810E7BA6A600F5680E /* script_os.cpp */; };
- DF84256A0E7BA6AC00F5680E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420820E7BA6A600F5680E /* sound.cpp */; };
- DF84256B0E7BA6AC00F5680E /* texte.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420840E7BA6A600F5680E /* texte.cpp */; };
- DF84256C0E7BA6AC00F5680E /* unpack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420860E7BA6A600F5680E /* unpack.cpp */; };
- DF84256D0E7BA6AC00F5680E /* various.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420880E7BA6A600F5680E /* various.cpp */; };
- DF84258D0E7BA6AC00F5680E /* actor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420AB0E7BA6A600F5680E /* actor.cpp */; };
- DF84258F0E7BA6AC00F5680E /* background.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420AE0E7BA6A600F5680E /* background.cpp */; };
- DF8425910E7BA6AC00F5680E /* backgroundIncrust.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420B10E7BA6A600F5680E /* backgroundIncrust.cpp */; };
- DF8425930E7BA6AC00F5680E /* cell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420B40E7BA6A600F5680E /* cell.cpp */; };
- DF8425950E7BA6AC00F5680E /* cruise.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420B70E7BA6A600F5680E /* cruise.cpp */; };
- DF8425970E7BA6AC00F5680E /* cruise_main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420BA0E7BA6A700F5680E /* cruise_main.cpp */; };
- DF8425990E7BA6AC00F5680E /* ctp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420BD0E7BA6A700F5680E /* ctp.cpp */; };
- DF84259B0E7BA6AC00F5680E /* dataLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420C00E7BA6A700F5680E /* dataLoader.cpp */; };
- DF84259D0E7BA6AC00F5680E /* decompiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420C30E7BA6A700F5680E /* decompiler.cpp */; };
- DF84259F0E7BA6AC00F5680E /* delphine-unpack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420C50E7BA6A700F5680E /* delphine-unpack.cpp */; };
- DF8425A10E7BA6AC00F5680E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420C70E7BA6A700F5680E /* detection.cpp */; };
- DF8425A30E7BA6AC00F5680E /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420C90E7BA6A700F5680E /* font.cpp */; };
- DF8425A70E7BA6AC00F5680E /* function.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420CF0E7BA6A700F5680E /* function.cpp */; };
- DF8425A90E7BA6AC00F5680E /* gfxModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420D20E7BA6A700F5680E /* gfxModule.cpp */; };
- DF8425AC0E7BA6AC00F5680E /* linker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420D60E7BA6A700F5680E /* linker.cpp */; };
- DF8425AE0E7BA6AC00F5680E /* mainDraw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420D90E7BA6A700F5680E /* mainDraw.cpp */; };
- DF8425B00E7BA6AC00F5680E /* menu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420DC0E7BA6A700F5680E /* menu.cpp */; };
- DF8425B30E7BA6AC00F5680E /* mouse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420E00E7BA6A700F5680E /* mouse.cpp */; };
- DF8425B50E7BA6AC00F5680E /* object.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420E30E7BA6A700F5680E /* object.cpp */; };
- DF8425B70E7BA6AC00F5680E /* overlay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420E60E7BA6A700F5680E /* overlay.cpp */; };
- DF8425B90E7BA6AC00F5680E /* perso.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420E90E7BA6A700F5680E /* perso.cpp */; };
- DF8425BB0E7BA6AC00F5680E /* polys.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420EC0E7BA6A700F5680E /* polys.cpp */; };
- DF8425BD0E7BA6AC00F5680E /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420EF0E7BA6A700F5680E /* saveload.cpp */; };
- DF8425BF0E7BA6AC00F5680E /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420F20E7BA6A700F5680E /* script.cpp */; };
- DF8425C10E7BA6AC00F5680E /* stack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420F50E7BA6A700F5680E /* stack.cpp */; };
- DF8425C40E7BA6AC00F5680E /* various.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420F90E7BA6A700F5680E /* various.cpp */; };
- DF8425C60E7BA6AC00F5680E /* vars.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420FC0E7BA6A700F5680E /* vars.cpp */; };
- DF8425C80E7BA6AC00F5680E /* volume.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420FF0E7BA6A700F5680E /* volume.cpp */; };
- DF8425CA0E7BA6AC00F5680E /* dialogs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421020E7BA6A700F5680E /* dialogs.cpp */; };
- DF8425CB0E7BA6AC00F5680E /* actors.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421050E7BA6A700F5680E /* actors.cpp */; };
- DF8425CC0E7BA6AC00F5680E /* animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421060E7BA6A700F5680E /* animation.cpp */; };
- DF8425CD0E7BA6AC00F5680E /* converse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421070E7BA6A700F5680E /* converse.cpp */; };
- DF8425CE0E7BA6AC00F5680E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421080E7BA6A700F5680E /* detection.cpp */; };
- DF8425CF0E7BA6AC00F5680E /* drascula.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421090E7BA6A700F5680E /* drascula.cpp */; };
- DF8425D00E7BA6AC00F5680E /* graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84210B0E7BA6A700F5680E /* graphics.cpp */; };
- DF8425D10E7BA6AC00F5680E /* interface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84210C0E7BA6A700F5680E /* interface.cpp */; };
- DF8425D30E7BA6AC00F5680E /* objects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84210E0E7BA6A700F5680E /* objects.cpp */; };
- DF8425D40E7BA6AC00F5680E /* palette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84210F0E7BA6A700F5680E /* palette.cpp */; };
- DF8425D50E7BA6AC00F5680E /* rooms.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421100E7BA6A700F5680E /* rooms.cpp */; };
- DF8425D60E7BA6AC00F5680E /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421110E7BA6A700F5680E /* saveload.cpp */; };
- DF8425D70E7BA6AC00F5680E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421120E7BA6A700F5680E /* sound.cpp */; };
- DF8425D80E7BA6AC00F5680E /* talk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421130E7BA6A700F5680E /* talk.cpp */; };
- DF8425D90E7BA6AC00F5680E /* engine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421140E7BA6A700F5680E /* engine.cpp */; };
- DF8425DD0E7BA6AC00F5680E /* dataio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84211B0E7BA6A700F5680E /* dataio.cpp */; };
- DF8425DE0E7BA6AC00F5680E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84211D0E7BA6A700F5680E /* detection.cpp */; };
- DF8425DF0E7BA6AC00F5680E /* draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84211E0E7BA6A700F5680E /* draw.cpp */; };
- DF8425E00E7BA6AC00F5680E /* draw_bargon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421200E7BA6A700F5680E /* draw_bargon.cpp */; };
- DF8425E10E7BA6AC00F5680E /* draw_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421210E7BA6A700F5680E /* draw_v1.cpp */; };
- DF8425E20E7BA6AC00F5680E /* draw_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421220E7BA6A700F5680E /* draw_v2.cpp */; };
- DF8425E40E7BA6AC00F5680E /* game.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421250E7BA6A700F5680E /* game.cpp */; };
- DF8425E70E7BA6AC00F5680E /* global.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421290E7BA6A700F5680E /* global.cpp */; };
- DF8425E80E7BA6AC00F5680E /* gob.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84212B0E7BA6A700F5680E /* gob.cpp */; };
- DF8425E90E7BA6AC00F5680E /* goblin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84212D0E7BA6A700F5680E /* goblin.cpp */; };
- DF8425EA0E7BA6AC00F5680E /* goblin_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84212F0E7BA6A700F5680E /* goblin_v1.cpp */; };
- DF8425EB0E7BA6AC00F5680E /* goblin_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421300E7BA6A700F5680E /* goblin_v2.cpp */; };
- DF8425EC0E7BA6AC00F5680E /* goblin_v3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421310E7BA6A700F5680E /* goblin_v3.cpp */; };
- DF8425ED0E7BA6AC00F5680E /* goblin_v4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421320E7BA6A700F5680E /* goblin_v4.cpp */; };
- DF8425EE0E7BA6AC00F5680E /* init.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421330E7BA6A700F5680E /* init.cpp */; };
- DF8425EF0E7BA6AC00F5680E /* init_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421350E7BA6A700F5680E /* init_v1.cpp */; };
- DF8425F00E7BA6AC00F5680E /* init_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421360E7BA6A700F5680E /* init_v2.cpp */; };
- DF8425F10E7BA6AC00F5680E /* init_v3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421370E7BA6A700F5680E /* init_v3.cpp */; };
- DF8425F20E7BA6AC00F5680E /* inter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421380E7BA6A700F5680E /* inter.cpp */; };
- DF8425F30E7BA6AC00F5680E /* inter_bargon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84213A0E7BA6A700F5680E /* inter_bargon.cpp */; };
- DF8425F40E7BA6AC00F5680E /* inter_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84213B0E7BA6A700F5680E /* inter_v1.cpp */; };
- DF8425F50E7BA6AC00F5680E /* inter_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84213C0E7BA6A700F5680E /* inter_v2.cpp */; };
- DF8425F60E7BA6AC00F5680E /* inter_v3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84213D0E7BA6A700F5680E /* inter_v3.cpp */; };
- DF8425F70E7BA6AC00F5680E /* inter_v4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84213E0E7BA6A700F5680E /* inter_v4.cpp */; };
- DF8425F80E7BA6AC00F5680E /* inter_v5.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84213F0E7BA6A700F5680E /* inter_v5.cpp */; };
- DF8425F90E7BA6AC00F5680E /* inter_v6.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421400E7BA6A700F5680E /* inter_v6.cpp */; };
- DF8425FA0E7BA6AC00F5680E /* map.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421410E7BA6A700F5680E /* map.cpp */; };
- DF8425FB0E7BA6AC00F5680E /* map_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421430E7BA6A700F5680E /* map_v1.cpp */; };
- DF8425FC0E7BA6AC00F5680E /* map_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421440E7BA6A700F5680E /* map_v2.cpp */; };
- DF8425FF0E7BA6AC00F5680E /* mult.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421470E7BA6A700F5680E /* mult.cpp */; };
- DF8426000E7BA6AC00F5680E /* mult_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421490E7BA6A700F5680E /* mult_v1.cpp */; };
- DF8426010E7BA6AC00F5680E /* mult_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84214A0E7BA6A700F5680E /* mult_v2.cpp */; };
- DF8426030E7BA6AC00F5680E /* palanim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84214C0E7BA6A700F5680E /* palanim.cpp */; };
- DF84260B0E7BA6AC00F5680E /* scenery.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421570E7BA6A700F5680E /* scenery.cpp */; };
- DF84260C0E7BA6AC00F5680E /* scenery_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421590E7BA6A700F5680E /* scenery_v1.cpp */; };
- DF84260D0E7BA6AC00F5680E /* scenery_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84215A0E7BA6A700F5680E /* scenery_v2.cpp */; };
- DF84260E0E7BA6AC00F5680E /* adlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84215C0E7BA6A700F5680E /* adlib.cpp */; };
- DF84260F0E7BA6AC00F5680E /* bgatmosphere.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84215E0E7BA6A700F5680E /* bgatmosphere.cpp */; };
- DF8426100E7BA6AC00F5680E /* cdrom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421600E7BA6A700F5680E /* cdrom.cpp */; };
- DF8426110E7BA6AC00F5680E /* infogrames.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421620E7BA6A700F5680E /* infogrames.cpp */; };
- DF8426120E7BA6AC00F5680E /* pcspeaker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421640E7BA6A700F5680E /* pcspeaker.cpp */; };
- DF8426130E7BA6AC00F5680E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421660E7BA6A700F5680E /* sound.cpp */; };
- DF8426140E7BA6AC00F5680E /* soundblaster.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421680E7BA6A700F5680E /* soundblaster.cpp */; };
- DF8426150E7BA6AC00F5680E /* sounddesc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84216A0E7BA6A700F5680E /* sounddesc.cpp */; };
- DF8426160E7BA6AC00F5680E /* soundmixer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84216C0E7BA6A700F5680E /* soundmixer.cpp */; };
- DF8426180E7BA6AC00F5680E /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84216F0E7BA6A700F5680E /* util.cpp */; };
- DF8426190E7BA6AC00F5680E /* variables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421710E7BA6A700F5680E /* variables.cpp */; };
- DF84261A0E7BA6AC00F5680E /* video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421730E7BA6A700F5680E /* video.cpp */; };
- DF84261B0E7BA6AC00F5680E /* video_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421750E7BA6A700F5680E /* video_v1.cpp */; };
- DF84261C0E7BA6AC00F5680E /* video_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421760E7BA6A700F5680E /* video_v2.cpp */; };
- DF84261D0E7BA6AC00F5680E /* video_v6.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421770E7BA6A700F5680E /* video_v6.cpp */; };
- DF84261E0E7BA6AC00F5680E /* videoplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421780E7BA6A700F5680E /* videoplayer.cpp */; };
- DF8426430E7BA6AC00F5680E /* animator_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421A40E7BA6A800F5680E /* animator_hof.cpp */; };
- DF8426440E7BA6AC00F5680E /* animator_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421A50E7BA6A800F5680E /* animator_lok.cpp */; };
- DF8426450E7BA6AC00F5680E /* animator_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421A70E7BA6A800F5680E /* animator_mr.cpp */; };
- DF8426470E7BA6AC00F5680E /* animator_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421A90E7BA6A800F5680E /* animator_v2.cpp */; };
- DF8426490E7BA6AC00F5680E /* debugger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421AB0E7BA6A800F5680E /* debugger.cpp */; };
- DF84264A0E7BA6AC00F5680E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421AD0E7BA6A800F5680E /* detection.cpp */; };
- DF84264B0E7BA6AC00F5680E /* gui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421AE0E7BA6A800F5680E /* gui.cpp */; };
- DF84264C0E7BA6AC00F5680E /* gui_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421B00E7BA6A800F5680E /* gui_hof.cpp */; };
- DF84264D0E7BA6AC00F5680E /* gui_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421B20E7BA6A800F5680E /* gui_lok.cpp */; };
- DF84264E0E7BA6AC00F5680E /* gui_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421B40E7BA6A800F5680E /* gui_mr.cpp */; };
- DF8426500E7BA6AC00F5680E /* gui_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421B70E7BA6A800F5680E /* gui_v2.cpp */; };
- DF8426520E7BA6AC00F5680E /* items_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421BA0E7BA6A800F5680E /* items_hof.cpp */; };
- DF8426530E7BA6AC00F5680E /* items_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421BB0E7BA6A800F5680E /* items_lok.cpp */; };
- DF8426540E7BA6AC00F5680E /* items_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421BC0E7BA6A800F5680E /* items_mr.cpp */; };
- DF8426560E7BA6AC00F5680E /* items_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421BE0E7BA6A800F5680E /* items_v2.cpp */; };
- DF8426590E7BA6AC00F5680E /* kyra_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421C10E7BA6A800F5680E /* kyra_hof.cpp */; };
- DF84265A0E7BA6AC00F5680E /* kyra_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421C30E7BA6A800F5680E /* kyra_lok.cpp */; };
- DF84265B0E7BA6AC00F5680E /* kyra_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421C50E7BA6A800F5680E /* kyra_mr.cpp */; };
- DF84265C0E7BA6AC00F5680E /* kyra_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421C70E7BA6A800F5680E /* kyra_v1.cpp */; };
- DF84265D0E7BA6AC00F5680E /* kyra_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421C90E7BA6A800F5680E /* kyra_v2.cpp */; };
- DF84265F0E7BA6AC00F5680E /* lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421CC0E7BA6A800F5680E /* lol.cpp */; };
- DF8426610E7BA6AC00F5680E /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421CF0E7BA6A800F5680E /* resource.cpp */; };
- DF8426620E7BA6AC00F5680E /* resource_intern.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421D10E7BA6A800F5680E /* resource_intern.cpp */; };
- DF8426630E7BA6AC00F5680E /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421D30E7BA6A800F5680E /* saveload.cpp */; };
- DF8426640E7BA6AC00F5680E /* saveload_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421D40E7BA6A800F5680E /* saveload_hof.cpp */; };
- DF8426650E7BA6AC00F5680E /* saveload_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421D50E7BA6A800F5680E /* saveload_lok.cpp */; };
- DF8426660E7BA6AC00F5680E /* saveload_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421D60E7BA6A800F5680E /* saveload_mr.cpp */; };
- DF84266A0E7BA6AC00F5680E /* scene_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421DA0E7BA6A800F5680E /* scene_hof.cpp */; };
- DF84266B0E7BA6AC00F5680E /* scene_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421DB0E7BA6A800F5680E /* scene_lok.cpp */; };
- DF84266C0E7BA6AC00F5680E /* scene_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421DC0E7BA6A800F5680E /* scene_mr.cpp */; };
- DF84266D0E7BA6AC00F5680E /* scene_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421DD0E7BA6A800F5680E /* scene_v1.cpp */; };
- DF84266E0E7BA6AC00F5680E /* scene_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421DE0E7BA6A800F5680E /* scene_v2.cpp */; };
- DF8426700E7BA6AC00F5680E /* screen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421E00E7BA6A800F5680E /* screen.cpp */; };
- DF8426710E7BA6AC00F5680E /* screen_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421E20E7BA6A800F5680E /* screen_hof.cpp */; };
- DF8426720E7BA6AC00F5680E /* screen_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421E40E7BA6A800F5680E /* screen_lok.cpp */; };
- DF8426730E7BA6AC00F5680E /* screen_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421E60E7BA6A800F5680E /* screen_lol.cpp */; };
- DF8426740E7BA6AC00F5680E /* screen_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421E80E7BA6A800F5680E /* screen_mr.cpp */; };
- DF8426760E7BA6AC00F5680E /* screen_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421EB0E7BA6A800F5680E /* screen_v2.cpp */; };
- DF8426780E7BA6AC00F5680E /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421EE0E7BA6A800F5680E /* script.cpp */; };
- DF8426790E7BA6AC00F5680E /* script_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421F00E7BA6A800F5680E /* script_hof.cpp */; };
- DF84267A0E7BA6AC00F5680E /* script_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421F10E7BA6A800F5680E /* script_lok.cpp */; };
- DF84267B0E7BA6AC00F5680E /* script_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421F20E7BA6A800F5680E /* script_mr.cpp */; };
- DF84267C0E7BA6AC00F5680E /* script_tim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421F30E7BA6A800F5680E /* script_tim.cpp */; };
- DF84267D0E7BA6AC00F5680E /* script_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421F50E7BA6A800F5680E /* script_v1.cpp */; };
- DF84267E0E7BA6AC00F5680E /* script_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421F60E7BA6A800F5680E /* script_v2.cpp */; };
- DF8426800E7BA6AC00F5680E /* seqplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421F80E7BA6A800F5680E /* seqplayer.cpp */; };
- DF8426810E7BA6AC00F5680E /* sequences_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421FA0E7BA6A800F5680E /* sequences_hof.cpp */; };
- DF8426820E7BA6AC00F5680E /* sequences_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421FB0E7BA6A800F5680E /* sequences_lok.cpp */; };
- DF8426830E7BA6AC00F5680E /* sequences_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421FC0E7BA6A800F5680E /* sequences_mr.cpp */; };
- DF8426850E7BA6AC00F5680E /* sequences_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421FE0E7BA6A800F5680E /* sequences_v2.cpp */; };
- DF8426870E7BA6AC00F5680E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422000E7BA6A800F5680E /* sound.cpp */; };
- DF8426880E7BA6AC00F5680E /* sound_adlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422020E7BA6A800F5680E /* sound_adlib.cpp */; };
- DF8426890E7BA6AC00F5680E /* sound_digital.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422030E7BA6A800F5680E /* sound_digital.cpp */; };
- DF84268A0E7BA6AC00F5680E /* sound_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422040E7BA6A800F5680E /* sound_lok.cpp */; };
- DF84268B0E7BA6AC00F5680E /* sound_towns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422050E7BA6A800F5680E /* sound_towns.cpp */; };
- DF84268D0E7BA6AC00F5680E /* sprites.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422070E7BA6A800F5680E /* sprites.cpp */; };
- DF84268E0E7BA6AC00F5680E /* staticres.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422090E7BA6A800F5680E /* staticres.cpp */; };
- DF84268F0E7BA6AC00F5680E /* text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84220A0E7BA6A800F5680E /* text.cpp */; };
- DF8426900E7BA6AC00F5680E /* text_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84220C0E7BA6A800F5680E /* text_hof.cpp */; };
- DF8426910E7BA6AC00F5680E /* text_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84220E0E7BA6A800F5680E /* text_lok.cpp */; };
- DF8426920E7BA6AC00F5680E /* text_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84220F0E7BA6A800F5680E /* text_mr.cpp */; };
- DF8426960E7BA6AC00F5680E /* timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422140E7BA6A800F5680E /* timer.cpp */; };
- DF8426970E7BA6AC00F5680E /* timer_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422160E7BA6A800F5680E /* timer_hof.cpp */; };
- DF8426980E7BA6AC00F5680E /* timer_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422170E7BA6A800F5680E /* timer_lok.cpp */; };
- DF8426990E7BA6AC00F5680E /* timer_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422180E7BA6A800F5680E /* timer_mr.cpp */; };
- DF84269D0E7BA6AC00F5680E /* vqa.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84221C0E7BA6A800F5680E /* vqa.cpp */; };
- DF84269E0E7BA6AC00F5680E /* wsamovie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84221E0E7BA6A800F5680E /* wsamovie.cpp */; };
- DF84269F0E7BA6AC00F5680E /* animseq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422210E7BA6A800F5680E /* animseq.cpp */; };
- DF8426A00E7BA6AC00F5680E /* debugger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422230E7BA6A800F5680E /* debugger.cpp */; };
- DF8426A10E7BA6AC00F5680E /* decode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422250E7BA6A800F5680E /* decode.cpp */; };
- DF8426A20E7BA6AC00F5680E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422270E7BA6A800F5680E /* detection.cpp */; };
- DF8426A30E7BA6AC00F5680E /* disk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422280E7BA6A800F5680E /* disk.cpp */; };
- DF8426A40E7BA6AC00F5680E /* events.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84222A0E7BA6A800F5680E /* events.cpp */; };
- DF8426A50E7BA6AC00F5680E /* fights.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84222C0E7BA6A800F5680E /* fights.cpp */; };
- DF8426A60E7BA6AC00F5680E /* game.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84222E0E7BA6A800F5680E /* game.cpp */; };
- DF8426A70E7BA6AC00F5680E /* hotspots.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422300E7BA6A800F5680E /* hotspots.cpp */; };
- DF8426A80E7BA6AC00F5680E /* intro.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422320E7BA6A800F5680E /* intro.cpp */; };
- DF8426A90E7BA6AC00F5680E /* lure.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422340E7BA6A800F5680E /* lure.cpp */; };
- DF8426AA0E7BA6AC00F5680E /* memory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422370E7BA6A800F5680E /* memory.cpp */; };
- DF8426AB0E7BA6AC00F5680E /* menu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422390E7BA6A800F5680E /* menu.cpp */; };
- DF8426AD0E7BA6AC00F5680E /* palette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84223C0E7BA6A800F5680E /* palette.cpp */; };
- DF8426AE0E7BA6AC00F5680E /* res.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84223E0E7BA6A800F5680E /* res.cpp */; };
- DF8426AF0E7BA6AC00F5680E /* res_struct.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422400E7BA6A800F5680E /* res_struct.cpp */; };
- DF8426B00E7BA6AC00F5680E /* room.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422420E7BA6A800F5680E /* room.cpp */; };
- DF8426B10E7BA6AC00F5680E /* screen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422440E7BA6A800F5680E /* screen.cpp */; };
- DF8426B20E7BA6AC00F5680E /* scripts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422460E7BA6A800F5680E /* scripts.cpp */; };
- DF8426B30E7BA6AC00F5680E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422480E7BA6A800F5680E /* sound.cpp */; };
- DF8426B40E7BA6AC00F5680E /* strings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84224A0E7BA6A800F5680E /* strings.cpp */; };
- DF8426B50E7BA6AC00F5680E /* surface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84224C0E7BA6A800F5680E /* surface.cpp */; };
- DF8426D40E7BA6AC00F5680E /* actor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84226E0E7BA6A800F5680E /* actor.cpp */; };
- DF8426D60E7BA6AC00F5680E /* animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422710E7BA6A800F5680E /* animation.cpp */; };
- DF8426D80E7BA6AC00F5680E /* assets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422740E7BA6A800F5680E /* assets.cpp */; };
- DF8426DA0E7BA6AC00F5680E /* compression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422780E7BA6A900F5680E /* compression.cpp */; };
- DF8426DC0E7BA6AC00F5680E /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84227B0E7BA6A900F5680E /* console.cpp */; };
- DF8426DE0E7BA6AC00F5680E /* converse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84227E0E7BA6A900F5680E /* converse.cpp */; };
- DF8426E00E7BA6AC00F5680E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422810E7BA6A900F5680E /* detection.cpp */; };
- DF8426E20E7BA6AC00F5680E /* events.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422830E7BA6A900F5680E /* events.cpp */; };
- DF8426E40E7BA6AC00F5680E /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422860E7BA6A900F5680E /* font.cpp */; };
- DF8426E60E7BA6AC00F5680E /* globals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422890E7BA6A900F5680E /* globals.cpp */; };
- DF8426E80E7BA6AC00F5680E /* graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84228C0E7BA6A900F5680E /* graphics.cpp */; };
- DF8426EA0E7BA6AC00F5680E /* gui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84228F0E7BA6A900F5680E /* gui.cpp */; };
- DF8426EC0E7BA6AC00F5680E /* hotspot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422920E7BA6A900F5680E /* hotspot.cpp */; };
- DF8426EF0E7BA6AC00F5680E /* m4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422960E7BA6A900F5680E /* m4.cpp */; };
- DF8426F10E7BA6AC00F5680E /* m4_menus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422990E7BA6A900F5680E /* m4_menus.cpp */; };
- DF8426F30E7BA6AC00F5680E /* m4_views.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84229C0E7BA6A900F5680E /* m4_views.cpp */; };
- DF8426F50E7BA6AC00F5680E /* mads_anim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84229F0E7BA6A900F5680E /* mads_anim.cpp */; };
- DF8426F70E7BA6AC00F5680E /* mads_menus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422A20E7BA6A900F5680E /* mads_menus.cpp */; };
- DF8426F90E7BA6AC00F5680E /* midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422A50E7BA6A900F5680E /* midi.cpp */; };
- DF8426FC0E7BA6AC00F5680E /* rails.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422A90E7BA6A900F5680E /* rails.cpp */; };
- DF8426FE0E7BA6AC00F5680E /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422AC0E7BA6A900F5680E /* resource.cpp */; };
- DF8427000E7BA6AC00F5680E /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422AF0E7BA6A900F5680E /* saveload.cpp */; };
- DF8427020E7BA6AC00F5680E /* scene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422B20E7BA6A900F5680E /* scene.cpp */; };
- DF8427040E7BA6AC00F5680E /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422B50E7BA6A900F5680E /* script.cpp */; };
- DF8427060E7BA6AC00F5680E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422B90E7BA6A900F5680E /* sound.cpp */; };
- DF8427080E7BA6AC00F5680E /* sprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422BC0E7BA6A900F5680E /* sprite.cpp */; };
- DF84270A0E7BA6AC00F5680E /* viewmgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422BF0E7BA6A900F5680E /* viewmgr.cpp */; };
- DF84270C0E7BA6AC00F5680E /* woodscript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422C20E7BA6A900F5680E /* woodscript.cpp */; };
- DF84270E0E7BA6AC00F5680E /* ws_machine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422C50E7BA6A900F5680E /* ws_machine.cpp */; };
- DF8427100E7BA6AC00F5680E /* ws_sequence.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422C70E7BA6A900F5680E /* ws_sequence.cpp */; };
- DF8427120E7BA6AC00F5680E /* database.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422CA0E7BA6A900F5680E /* database.cpp */; };
- DF8427130E7BA6AC00F5680E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422CC0E7BA6A900F5680E /* detection.cpp */; };
- DF8427140E7BA6AC00F5680E /* graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422CD0E7BA6A900F5680E /* graphics.cpp */; };
- DF8427150E7BA6AC00F5680E /* made.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422CF0E7BA6A900F5680E /* made.cpp */; };
- DF8427170E7BA6AC00F5680E /* music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422D20E7BA6A900F5680E /* music.cpp */; };
- DF8427180E7BA6AC00F5680E /* pmvplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422D40E7BA6A900F5680E /* pmvplayer.cpp */; };
- DF8427190E7BA6AC00F5680E /* redreader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422D60E7BA6A900F5680E /* redreader.cpp */; };
- DF84271A0E7BA6AC00F5680E /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422D80E7BA6A900F5680E /* resource.cpp */; };
- DF84271B0E7BA6AC00F5680E /* screen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422DA0E7BA6A900F5680E /* screen.cpp */; };
- DF84271C0E7BA6AC00F5680E /* screenfx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422DC0E7BA6A900F5680E /* screenfx.cpp */; };
- DF84271D0E7BA6AC00F5680E /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422DE0E7BA6A900F5680E /* script.cpp */; };
- DF84271E0E7BA6AC00F5680E /* scriptfuncs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422E00E7BA6A900F5680E /* scriptfuncs.cpp */; };
- DF84271F0E7BA6AC00F5680E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422E20E7BA6A900F5680E /* sound.cpp */; };
- DF8427210E7BA6AC00F5680E /* balloons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422E70E7BA6A900F5680E /* balloons.cpp */; };
- DF8427220E7BA6AC00F5680E /* callables_br.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422E80E7BA6A900F5680E /* callables_br.cpp */; };
- DF8427230E7BA6AC00F5680E /* callables_ns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422E90E7BA6A900F5680E /* callables_ns.cpp */; };
- DF8427240E7BA6AC00F5680E /* debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422EA0E7BA6A900F5680E /* debug.cpp */; };
- DF8427250E7BA6AC00F5680E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422EC0E7BA6A900F5680E /* detection.cpp */; };
- DF8427260E7BA6AC00F5680E /* dialogue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422ED0E7BA6A900F5680E /* dialogue.cpp */; };
- DF8427270E7BA6AC00F5680E /* disk_br.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422EF0E7BA6A900F5680E /* disk_br.cpp */; };
- DF8427280E7BA6AC00F5680E /* disk_ns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422F00E7BA6A900F5680E /* disk_ns.cpp */; };
- DF8427290E7BA6AC00F5680E /* exec_br.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422F20E7BA6A900F5680E /* exec_br.cpp */; };
- DF84272A0E7BA6AC00F5680E /* exec_ns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422F30E7BA6A900F5680E /* exec_ns.cpp */; };
- DF84272B0E7BA6AC00F5680E /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422F40E7BA6A900F5680E /* font.cpp */; };
- DF84272C0E7BA6AC00F5680E /* gfxbase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422F50E7BA6A900F5680E /* gfxbase.cpp */; };
- DF84272D0E7BA6AC00F5680E /* graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422F60E7BA6A900F5680E /* graphics.cpp */; };
- DF84272E0E7BA6AC00F5680E /* gui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422F80E7BA6A900F5680E /* gui.cpp */; };
- DF84272F0E7BA6AC00F5680E /* gui_br.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422FA0E7BA6A900F5680E /* gui_br.cpp */; };
- DF8427300E7BA6AC00F5680E /* gui_ns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422FB0E7BA6A900F5680E /* gui_ns.cpp */; };
- DF8427310E7BA6AC00F5680E /* input.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422FC0E7BA6A900F5680E /* input.cpp */; };
- DF8427320E7BA6AC00F5680E /* inventory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422FE0E7BA6A900F5680E /* inventory.cpp */; };
- DF8427340E7BA6AC00F5680E /* objects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423010E7BA6A900F5680E /* objects.cpp */; };
- DF8427350E7BA6AC00F5680E /* parallaction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423030E7BA6A900F5680E /* parallaction.cpp */; };
- DF8427360E7BA6AC00F5680E /* parallaction_br.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423050E7BA6A900F5680E /* parallaction_br.cpp */; };
- DF8427370E7BA6AC00F5680E /* parallaction_ns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423060E7BA6A900F5680E /* parallaction_ns.cpp */; };
- DF8427380E7BA6AC00F5680E /* parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423070E7BA6A900F5680E /* parser.cpp */; };
- DF8427390E7BA6AC00F5680E /* parser_br.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423090E7BA6A900F5680E /* parser_br.cpp */; };
- DF84273A0E7BA6AC00F5680E /* parser_ns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84230A0E7BA6A900F5680E /* parser_ns.cpp */; };
- DF84273B0E7BA6AC00F5680E /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84230B0E7BA6A900F5680E /* saveload.cpp */; };
- DF84273D0E7BA6AC00F5680E /* staticres.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84230F0E7BA6A900F5680E /* staticres.cpp */; };
- DF84273E0E7BA6AC00F5680E /* walk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423100E7BA6A900F5680E /* walk.cpp */; };
- DF84273F0E7BA6AC00F5680E /* bankman.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423130E7BA6A900F5680E /* bankman.cpp */; };
- DF8427400E7BA6AC00F5680E /* command.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423150E7BA6A900F5680E /* command.cpp */; };
- DF8427410E7BA6AC00F5680E /* credits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423170E7BA6A900F5680E /* credits.cpp */; };
- DF8427420E7BA6AC00F5680E /* cutaway.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423190E7BA6A900F5680E /* cutaway.cpp */; };
- DF8427430E7BA6AC00F5680E /* debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84231B0E7BA6A900F5680E /* debug.cpp */; };
- DF8427440E7BA6AC00F5680E /* display.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84231E0E7BA6A900F5680E /* display.cpp */; };
- DF8427450E7BA6AC00F5680E /* graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423200E7BA6A900F5680E /* graphics.cpp */; };
- DF8427460E7BA6AC00F5680E /* grid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423220E7BA6A900F5680E /* grid.cpp */; };
- DF8427470E7BA6AC00F5680E /* input.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423240E7BA6A900F5680E /* input.cpp */; };
- DF8427480E7BA6AC00F5680E /* journal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423260E7BA6A900F5680E /* journal.cpp */; };
- DF8427490E7BA6AC00F5680E /* logic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423280E7BA6A900F5680E /* logic.cpp */; };
- DF84274A0E7BA6AC00F5680E /* midiadlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84232A0E7BA6A900F5680E /* midiadlib.cpp */; };
- DF84274C0E7BA6AC00F5680E /* music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84232C0E7BA6A900F5680E /* music.cpp */; };
- DF84274D0E7BA6AC00F5680E /* musicdata.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84232E0E7BA6A900F5680E /* musicdata.cpp */; };
- DF84274E0E7BA6AC00F5680E /* queen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84232F0E7BA6A900F5680E /* queen.cpp */; };
- DF84274F0E7BA6AC00F5680E /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423310E7BA6A900F5680E /* resource.cpp */; };
- DF8427500E7BA6AC00F5680E /* restables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423330E7BA6A900F5680E /* restables.cpp */; };
- DF8427510E7BA6AC00F5680E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423340E7BA6A900F5680E /* sound.cpp */; };
- DF8427520E7BA6AC00F5680E /* state.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423360E7BA6A900F5680E /* state.cpp */; };
- DF8427530E7BA6AC00F5680E /* talk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423390E7BA6A900F5680E /* talk.cpp */; };
- DF8427540E7BA6AC00F5680E /* walk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84233B0E7BA6A900F5680E /* walk.cpp */; };
- DF8427560E7BA6AC00F5680E /* actor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84233F0E7BA6AA00F5680E /* actor.cpp */; };
- DF8427570E7BA6AC00F5680E /* actor_path.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423410E7BA6AA00F5680E /* actor_path.cpp */; };
- DF8427580E7BA6AC00F5680E /* actor_walk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423420E7BA6AA00F5680E /* actor_walk.cpp */; };
- DF8427590E7BA6AC00F5680E /* animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423430E7BA6AA00F5680E /* animation.cpp */; };
- DF84275A0E7BA6AC00F5680E /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423450E7BA6AA00F5680E /* console.cpp */; };
- DF84275B0E7BA6AC00F5680E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423470E7BA6AA00F5680E /* detection.cpp */; };
- DF84275C0E7BA6AC00F5680E /* events.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84234A0E7BA6AA00F5680E /* events.cpp */; };
- DF84275D0E7BA6AC00F5680E /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84234C0E7BA6AA00F5680E /* font.cpp */; };
- DF84275E0E7BA6AC00F5680E /* font_map.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84234E0E7BA6AA00F5680E /* font_map.cpp */; };
- DF84275F0E7BA6AC00F5680E /* gfx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84234F0E7BA6AA00F5680E /* gfx.cpp */; };
- DF8427610E7BA6AC00F5680E /* image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423520E7BA6AA00F5680E /* image.cpp */; };
- DF8427620E7BA6AC00F5680E /* input.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423530E7BA6AA00F5680E /* input.cpp */; };
- DF8427630E7BA6AC00F5680E /* interface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423540E7BA6AA00F5680E /* interface.cpp */; };
- DF8427640E7BA6AC00F5680E /* introproc_ihnm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423560E7BA6AA00F5680E /* introproc_ihnm.cpp */; };
- DF8427650E7BA6AC00F5680E /* introproc_ite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423570E7BA6AA00F5680E /* introproc_ite.cpp */; };
- DF8427660E7BA6AC00F5680E /* isomap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423580E7BA6AA00F5680E /* isomap.cpp */; };
- DF8427680E7BA6AC00F5680E /* itedata.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84235B0E7BA6AA00F5680E /* itedata.cpp */; };
- DF84276A0E7BA6AC00F5680E /* music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84235F0E7BA6AA00F5680E /* music.cpp */; };
- DF84276B0E7BA6AC00F5680E /* objectmap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423610E7BA6AA00F5680E /* objectmap.cpp */; };
- DF84276C0E7BA6AC00F5680E /* palanim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423630E7BA6AA00F5680E /* palanim.cpp */; };
- DF84276D0E7BA6AC00F5680E /* puzzle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423650E7BA6AA00F5680E /* puzzle.cpp */; };
- DF84276E0E7BA6AC00F5680E /* render.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423670E7BA6AA00F5680E /* render.cpp */; };
- DF8427700E7BA6AC00F5680E /* saga.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84236B0E7BA6AA00F5680E /* saga.cpp */; };
- DF8427710E7BA6AC00F5680E /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84236D0E7BA6AA00F5680E /* saveload.cpp */; };
- DF8427720E7BA6AC00F5680E /* scene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84236E0E7BA6AA00F5680E /* scene.cpp */; };
- DF8427730E7BA6AC00F5680E /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423700E7BA6AA00F5680E /* script.cpp */; };
- DF8427740E7BA6AC00F5680E /* sfuncs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423720E7BA6AA00F5680E /* sfuncs.cpp */; };
- DF8427750E7BA6AC00F5680E /* sndres.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423730E7BA6AA00F5680E /* sndres.cpp */; };
- DF8427760E7BA6AC00F5680E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423750E7BA6AA00F5680E /* sound.cpp */; };
- DF8427770E7BA6AC00F5680E /* sprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423770E7BA6AA00F5680E /* sprite.cpp */; };
- DF8427780E7BA6AC00F5680E /* sthread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423790E7BA6AA00F5680E /* sthread.cpp */; };
- DF84277A0E7BA6AC00F5680E /* actor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84237C0E7BA6AA00F5680E /* actor.cpp */; };
- DF84277B0E7BA6AC00F5680E /* akos.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84237E0E7BA6AA00F5680E /* akos.cpp */; };
- DF84277C0E7BA6AC00F5680E /* base-costume.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423800E7BA6AA00F5680E /* base-costume.cpp */; };
- DF84277D0E7BA6AC00F5680E /* bomp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423820E7BA6AA00F5680E /* bomp.cpp */; };
- DF84277E0E7BA6AC00F5680E /* boxes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423840E7BA6AA00F5680E /* boxes.cpp */; };
- DF84277F0E7BA6AC00F5680E /* camera.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423860E7BA6AA00F5680E /* camera.cpp */; };
- DF8427800E7BA6AC00F5680E /* charset-fontdata.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423870E7BA6AA00F5680E /* charset-fontdata.cpp */; };
- DF8427810E7BA6AC00F5680E /* charset.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423880E7BA6AA00F5680E /* charset.cpp */; };
- DF8427820E7BA6AC00F5680E /* costume.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84238A0E7BA6AA00F5680E /* costume.cpp */; };
- DF8427830E7BA6AC00F5680E /* cursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84238C0E7BA6AA00F5680E /* cursor.cpp */; };
- DF8427840E7BA6AC00F5680E /* debugger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84238D0E7BA6AA00F5680E /* debugger.cpp */; };
- DF8427850E7BA6AC00F5680E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84238F0E7BA6AA00F5680E /* detection.cpp */; };
- DF8427860E7BA6AC00F5680E /* dialogs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423920E7BA6AA00F5680E /* dialogs.cpp */; };
- DF8427870E7BA6AC00F5680E /* file.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423940E7BA6AA00F5680E /* file.cpp */; };
- DF8427880E7BA6AC00F5680E /* file_nes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423960E7BA6AA00F5680E /* file_nes.cpp */; };
- DF8427890E7BA6AC00F5680E /* gfx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423980E7BA6AA00F5680E /* gfx.cpp */; };
- DF84278B0E7BA6AC00F5680E /* animation_he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84239C0E7BA6AA00F5680E /* animation_he.cpp */; };
- DF84278C0E7BA6AC00F5680E /* cup_player_he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84239E0E7BA6AA00F5680E /* cup_player_he.cpp */; };
- DF84278D0E7BA6AC00F5680E /* floodfill_he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423A00E7BA6AA00F5680E /* floodfill_he.cpp */; };
- DF84278E0E7BA6AC00F5680E /* logic_he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423A30E7BA6AA00F5680E /* logic_he.cpp */; };
- DF84278F0E7BA6AC00F5680E /* palette_he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423A50E7BA6AA00F5680E /* palette_he.cpp */; };
- DF8427900E7BA6AC00F5680E /* resource_he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423A60E7BA6AA00F5680E /* resource_he.cpp */; };
- DF8427910E7BA6AC00F5680E /* script_v100he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423A80E7BA6AA00F5680E /* script_v100he.cpp */; };
- DF8427920E7BA6AC00F5680E /* script_v60he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423A90E7BA6AA00F5680E /* script_v60he.cpp */; };
- DF8427930E7BA6AC00F5680E /* script_v70he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423AA0E7BA6AA00F5680E /* script_v70he.cpp */; };
- DF8427940E7BA6AC00F5680E /* script_v71he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423AB0E7BA6AA00F5680E /* script_v71he.cpp */; };
- DF8427950E7BA6AC00F5680E /* script_v72he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423AC0E7BA6AA00F5680E /* script_v72he.cpp */; };
- DF8427960E7BA6AC00F5680E /* script_v80he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423AD0E7BA6AA00F5680E /* script_v80he.cpp */; };
- DF8427970E7BA6AC00F5680E /* script_v90he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423AE0E7BA6AA00F5680E /* script_v90he.cpp */; };
- DF8427980E7BA6AC00F5680E /* sound_he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423AF0E7BA6AA00F5680E /* sound_he.cpp */; };
- DF8427990E7BA6AC00F5680E /* sprite_he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423B10E7BA6AA00F5680E /* sprite_he.cpp */; };
- DF84279A0E7BA6AC00F5680E /* wiz_he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423B30E7BA6AA00F5680E /* wiz_he.cpp */; };
- DF84279B0E7BA6AC00F5680E /* help.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423B50E7BA6AA00F5680E /* help.cpp */; };
- DF84279C0E7BA6AC00F5680E /* imuse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423B80E7BA6AA00F5680E /* imuse.cpp */; };
- DF84279D0E7BA6AC00F5680E /* imuse_part.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423BB0E7BA6AA00F5680E /* imuse_part.cpp */; };
- DF84279E0E7BA6AC00F5680E /* imuse_player.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423BC0E7BA6AA00F5680E /* imuse_player.cpp */; };
- DF84279F0E7BA6AC00F5680E /* instrument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423BD0E7BA6AA00F5680E /* instrument.cpp */; };
- DF8427A00E7BA6AC00F5680E /* sysex_samnmax.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423C00E7BA6AA00F5680E /* sysex_samnmax.cpp */; };
- DF8427A10E7BA6AC00F5680E /* sysex_scumm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423C10E7BA6AA00F5680E /* sysex_scumm.cpp */; };
- DF8427A20E7BA6AC00F5680E /* dimuse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423C30E7BA6AA00F5680E /* dimuse.cpp */; };
- DF8427A30E7BA6AC00F5680E /* dimuse_bndmgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423C50E7BA6AA00F5680E /* dimuse_bndmgr.cpp */; };
- DF8427A40E7BA6AC00F5680E /* dimuse_codecs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423C70E7BA6AA00F5680E /* dimuse_codecs.cpp */; };
- DF8427A50E7BA6AC00F5680E /* dimuse_music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423C80E7BA6AA00F5680E /* dimuse_music.cpp */; };
- DF8427A60E7BA6AC00F5680E /* dimuse_script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423C90E7BA6AA00F5680E /* dimuse_script.cpp */; };
- DF8427A70E7BA6AC00F5680E /* dimuse_sndmgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423CA0E7BA6AA00F5680E /* dimuse_sndmgr.cpp */; };
- DF8427A80E7BA6AC00F5680E /* dimuse_tables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423CC0E7BA6AA00F5680E /* dimuse_tables.cpp */; };
- DF8427A90E7BA6AC00F5680E /* dimuse_track.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423CE0E7BA6AA00F5680E /* dimuse_track.cpp */; };
- DF8427AA0E7BA6AC00F5680E /* input.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423D00E7BA6AA00F5680E /* input.cpp */; };
- DF8427AB0E7BA6AC00F5680E /* insane.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423D20E7BA6AA00F5680E /* insane.cpp */; };
- DF8427AC0E7BA6AC00F5680E /* insane_ben.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423D40E7BA6AA00F5680E /* insane_ben.cpp */; };
- DF8427AD0E7BA6AC00F5680E /* insane_enemy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423D50E7BA6AA00F5680E /* insane_enemy.cpp */; };
- DF8427AE0E7BA6AC00F5680E /* insane_iact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423D60E7BA6AA00F5680E /* insane_iact.cpp */; };
- DF8427AF0E7BA6AC00F5680E /* insane_scenes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423D70E7BA6AA00F5680E /* insane_scenes.cpp */; };
- DF8427B10E7BA6AC00F5680E /* midiparser_ro.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423DA0E7BA6AA00F5680E /* midiparser_ro.cpp */; };
- DF8427B30E7BA6AC00F5680E /* nut_renderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423DD0E7BA6AA00F5680E /* nut_renderer.cpp */; };
- DF8427B40E7BA6AC00F5680E /* object.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423DF0E7BA6AA00F5680E /* object.cpp */; };
- DF8427B50E7BA6AC00F5680E /* palette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423E10E7BA6AA00F5680E /* palette.cpp */; };
- DF8427B60E7BA6AC00F5680E /* player_mod.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423E20E7BA6AA00F5680E /* player_mod.cpp */; };
- DF8427B70E7BA6AC00F5680E /* player_nes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423E40E7BA6AA00F5680E /* player_nes.cpp */; };
- DF8427B80E7BA6AC00F5680E /* player_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423E60E7BA6AA00F5680E /* player_v1.cpp */; };
- DF8427B90E7BA6AC00F5680E /* player_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423E80E7BA6AA00F5680E /* player_v2.cpp */; };
- DF8427BA0E7BA6AC00F5680E /* player_v2a.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423EA0E7BA6AA00F5680E /* player_v2a.cpp */; };
- DF8427BB0E7BA6AC00F5680E /* player_v3a.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423EC0E7BA6AA00F5680E /* player_v3a.cpp */; };
- DF8427BD0E7BA6AC00F5680E /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423EF0E7BA6AA00F5680E /* resource.cpp */; };
- DF8427BE0E7BA6AC00F5680E /* resource_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423F10E7BA6AA00F5680E /* resource_v2.cpp */; };
- DF8427BF0E7BA6AC00F5680E /* resource_v3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423F20E7BA6AA00F5680E /* resource_v3.cpp */; };
- DF8427C00E7BA6AC00F5680E /* resource_v4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423F30E7BA6AA00F5680E /* resource_v4.cpp */; };
- DF8427C10E7BA6AC00F5680E /* room.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423F40E7BA6AA00F5680E /* room.cpp */; };
- DF8427C20E7BA6AC00F5680E /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423F50E7BA6AA00F5680E /* saveload.cpp */; };
- DF8427C30E7BA6AC00F5680E /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423F70E7BA6AA00F5680E /* script.cpp */; };
- DF8427C40E7BA6AC00F5680E /* script_v0.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423F90E7BA6AA00F5680E /* script_v0.cpp */; };
- DF8427C50E7BA6AC00F5680E /* script_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423FA0E7BA6AA00F5680E /* script_v2.cpp */; };
- DF8427C60E7BA6AC00F5680E /* script_v5.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423FB0E7BA6AA00F5680E /* script_v5.cpp */; };
- DF8427C70E7BA6AC00F5680E /* script_v6.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423FC0E7BA6AA00F5680E /* script_v6.cpp */; };
- DF8427C80E7BA6AC00F5680E /* script_v8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423FD0E7BA6AA00F5680E /* script_v8.cpp */; };
- DF8427C90E7BA6AC00F5680E /* scumm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423FF0E7BA6AA00F5680E /* scumm.cpp */; };
- DF8427CA0E7BA6AC00F5680E /* channel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424020E7BA6AA00F5680E /* channel.cpp */; };
- DF8427CC0E7BA6AC00F5680E /* codec1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424060E7BA6AA00F5680E /* codec1.cpp */; };
- DF8427CD0E7BA6AC00F5680E /* codec37.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424070E7BA6AA00F5680E /* codec37.cpp */; };
- DF8427CE0E7BA6AC00F5680E /* codec47.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424090E7BA6AA00F5680E /* codec47.cpp */; };
- DF8427D10E7BA6AC00F5680E /* imuse_channel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84240D0E7BA6AA00F5680E /* imuse_channel.cpp */; };
- DF8427D20E7BA6AC00F5680E /* saud_channel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84240E0E7BA6AA00F5680E /* saud_channel.cpp */; };
- DF8427D30E7BA6AC00F5680E /* smush_font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84240F0E7BA6AA00F5680E /* smush_font.cpp */; };
- DF8427D40E7BA6AC00F5680E /* smush_mixer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424110E7BA6AA00F5680E /* smush_mixer.cpp */; };
- DF8427D50E7BA6AC00F5680E /* smush_player.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424130E7BA6AA00F5680E /* smush_player.cpp */; };
- DF8427D60E7BA6AC00F5680E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424150E7BA6AB00F5680E /* sound.cpp */; };
- DF8427D70E7BA6AC00F5680E /* string.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424170E7BA6AB00F5680E /* string.cpp */; };
- DF8427D90E7BA6AC00F5680E /* usage_bits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424190E7BA6AB00F5680E /* usage_bits.cpp */; };
- DF8427DA0E7BA6AC00F5680E /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84241B0E7BA6AB00F5680E /* util.cpp */; };
- DF8427DB0E7BA6AC00F5680E /* vars.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84241D0E7BA6AB00F5680E /* vars.cpp */; };
- DF8427DC0E7BA6AC00F5680E /* verbs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84241E0E7BA6AB00F5680E /* verbs.cpp */; };
- DF8427DD0E7BA6AC00F5680E /* autoroute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424210E7BA6AB00F5680E /* autoroute.cpp */; };
- DF8427DE0E7BA6AC00F5680E /* compact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424230E7BA6AB00F5680E /* compact.cpp */; };
- DF8427DF0E7BA6AC00F5680E /* control.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424250E7BA6AB00F5680E /* control.cpp */; };
- DF8427E00E7BA6AC00F5680E /* debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424270E7BA6AB00F5680E /* debug.cpp */; };
- DF8427E10E7BA6AC00F5680E /* disk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424290E7BA6AB00F5680E /* disk.cpp */; };
- DF8427E20E7BA6AC00F5680E /* grid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84242B0E7BA6AB00F5680E /* grid.cpp */; };
- DF8427E30E7BA6AC00F5680E /* hufftext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84242D0E7BA6AB00F5680E /* hufftext.cpp */; };
- DF8427E40E7BA6AC00F5680E /* intro.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84242E0E7BA6AB00F5680E /* intro.cpp */; };
- DF8427E50E7BA6AC00F5680E /* logic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424300E7BA6AB00F5680E /* logic.cpp */; };
- DF8427E70E7BA6AC00F5680E /* mouse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424330E7BA6AB00F5680E /* mouse.cpp */; };
- DF8427E80E7BA6AC00F5680E /* adlibchannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424360E7BA6AB00F5680E /* adlibchannel.cpp */; };
- DF8427E90E7BA6AC00F5680E /* adlibmusic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424380E7BA6AB00F5680E /* adlibmusic.cpp */; };
- DF8427EA0E7BA6AC00F5680E /* gmchannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84243A0E7BA6AB00F5680E /* gmchannel.cpp */; };
- DF8427EB0E7BA6AC00F5680E /* gmmusic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84243C0E7BA6AB00F5680E /* gmmusic.cpp */; };
- DF8427EC0E7BA6AC00F5680E /* mt32music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84243E0E7BA6AB00F5680E /* mt32music.cpp */; };
- DF8427ED0E7BA6AC00F5680E /* musicbase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424400E7BA6AB00F5680E /* musicbase.cpp */; };
- DF8427EE0E7BA6AC00F5680E /* rnc_deco.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424420E7BA6AB00F5680E /* rnc_deco.cpp */; };
- DF8427EF0E7BA6AC00F5680E /* screen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424440E7BA6AB00F5680E /* screen.cpp */; };
- DF8427F00E7BA6AC00F5680E /* sky.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424460E7BA6AB00F5680E /* sky.cpp */; };
- DF8427F10E7BA6AC00F5680E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424490E7BA6AB00F5680E /* sound.cpp */; };
- DF8427F20E7BA6AC00F5680E /* text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84244C0E7BA6AB00F5680E /* text.cpp */; };
- DF8427F30E7BA6AC00F5680E /* animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84244F0E7BA6AB00F5680E /* animation.cpp */; };
- DF8427F40E7BA6AC00F5680E /* control.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424520E7BA6AB00F5680E /* control.cpp */; };
- DF8427F60E7BA6AC00F5680E /* debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424560E7BA6AB00F5680E /* debug.cpp */; };
- DF8427F70E7BA6AC00F5680E /* eventman.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424580E7BA6AB00F5680E /* eventman.cpp */; };
- DF8427F80E7BA6AC00F5680E /* logic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84245A0E7BA6AB00F5680E /* logic.cpp */; };
- DF8427F90E7BA6AC00F5680E /* memman.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84245C0E7BA6AB00F5680E /* memman.cpp */; };
- DF8427FA0E7BA6AC00F5680E /* menu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84245E0E7BA6AB00F5680E /* menu.cpp */; };
- DF8427FC0E7BA6AC00F5680E /* mouse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424610E7BA6AB00F5680E /* mouse.cpp */; };
- DF8427FD0E7BA6AC00F5680E /* music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424630E7BA6AB00F5680E /* music.cpp */; };
- DF8427FE0E7BA6AC00F5680E /* objectman.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424660E7BA6AB00F5680E /* objectman.cpp */; };
- DF8427FF0E7BA6AC00F5680E /* resman.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424680E7BA6AB00F5680E /* resman.cpp */; };
- DF8428000E7BA6AC00F5680E /* router.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84246A0E7BA6AB00F5680E /* router.cpp */; };
- DF8428010E7BA6AC00F5680E /* screen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84246C0E7BA6AB00F5680E /* screen.cpp */; };
- DF8428020E7BA6AC00F5680E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84246E0E7BA6AB00F5680E /* sound.cpp */; };
- DF8428030E7BA6AC00F5680E /* staticres.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424700E7BA6AB00F5680E /* staticres.cpp */; };
- DF8428040E7BA6AC00F5680E /* sword1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424710E7BA6AB00F5680E /* sword1.cpp */; };
- DF8428050E7BA6AC00F5680E /* text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424750E7BA6AB00F5680E /* text.cpp */; };
- DF8428060E7BA6AC00F5680E /* animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424780E7BA6AB00F5680E /* animation.cpp */; };
- DF8428070E7BA6AC00F5680E /* anims.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84247A0E7BA6AB00F5680E /* anims.cpp */; };
- DF8428080E7BA6AC00F5680E /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84247B0E7BA6AB00F5680E /* console.cpp */; };
- DF8428090E7BA6AC00F5680E /* controls.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84247D0E7BA6AB00F5680E /* controls.cpp */; };
- DF84280A0E7BA6AC00F5680E /* debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84247F0E7BA6AB00F5680E /* debug.cpp */; };
- DF84280B0E7BA6AC00F5680E /* events.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424820E7BA6AB00F5680E /* events.cpp */; };
- DF84280C0E7BA6AC00F5680E /* function.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424830E7BA6AB00F5680E /* function.cpp */; };
- DF84280D0E7BA6AC00F5680E /* icons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424850E7BA6AB00F5680E /* icons.cpp */; };
- DF84280E0E7BA6AC00F5680E /* interpreter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424860E7BA6AB00F5680E /* interpreter.cpp */; };
- DF84280F0E7BA6AC00F5680E /* layers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424880E7BA6AB00F5680E /* layers.cpp */; };
- DF8428100E7BA6AC00F5680E /* logic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424890E7BA6AB00F5680E /* logic.cpp */; };
- DF8428110E7BA6AC00F5680E /* maketext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84248B0E7BA6AB00F5680E /* maketext.cpp */; };
- DF8428120E7BA6AC00F5680E /* memory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84248D0E7BA6AB00F5680E /* memory.cpp */; };
- DF8428130E7BA6AC00F5680E /* menu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84248F0E7BA6AB00F5680E /* menu.cpp */; };
- DF8428150E7BA6AC00F5680E /* mouse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424910E7BA6AB00F5680E /* mouse.cpp */; };
- DF8428160E7BA6AC00F5680E /* music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424930E7BA6AB00F5680E /* music.cpp */; };
- DF8428170E7BA6AC00F5680E /* palette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424950E7BA6AB00F5680E /* palette.cpp */; };
- DF8428180E7BA6AC00F5680E /* protocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424960E7BA6AB00F5680E /* protocol.cpp */; };
- DF8428190E7BA6AC00F5680E /* render.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424970E7BA6AB00F5680E /* render.cpp */; };
- DF84281A0E7BA6AC00F5680E /* resman.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424980E7BA6AB00F5680E /* resman.cpp */; };
- DF84281B0E7BA6AC00F5680E /* router.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84249A0E7BA6AB00F5680E /* router.cpp */; };
- DF84281C0E7BA6AC00F5680E /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84249C0E7BA6AB00F5680E /* saveload.cpp */; };
- DF84281D0E7BA6AC00F5680E /* screen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84249E0E7BA6AB00F5680E /* screen.cpp */; };
- DF84281E0E7BA6AC00F5680E /* scroll.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424A00E7BA6AB00F5680E /* scroll.cpp */; };
- DF84281F0E7BA6AC00F5680E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424A10E7BA6AB00F5680E /* sound.cpp */; };
- DF8428200E7BA6AC00F5680E /* speech.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424A30E7BA6AB00F5680E /* speech.cpp */; };
- DF8428210E7BA6AC00F5680E /* sprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424A40E7BA6AB00F5680E /* sprite.cpp */; };
- DF8428220E7BA6AC00F5680E /* startup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424A50E7BA6AB00F5680E /* startup.cpp */; };
- DF8428230E7BA6AC00F5680E /* sword2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424A60E7BA6AB00F5680E /* sword2.cpp */; };
- DF8428240E7BA6AC00F5680E /* sync.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424A80E7BA6AB00F5680E /* sync.cpp */; };
- DF8428250E7BA6AC00F5680E /* walker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424A90E7BA6AB00F5680E /* walker.cpp */; };
- DF8428260E7BA6AC00F5680E /* actors.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424AB0E7BA6AB00F5680E /* actors.cpp */; };
- DF8428270E7BA6AC00F5680E /* anim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424AD0E7BA6AB00F5680E /* anim.cpp */; };
- DF8428280E7BA6AC00F5680E /* background.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424AF0E7BA6AB00F5680E /* background.cpp */; };
- DF8428290E7BA6AC00F5680E /* bg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424B10E7BA6AB00F5680E /* bg.cpp */; };
- DF84282A0E7BA6AC00F5680E /* cliprect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424B20E7BA6AB00F5680E /* cliprect.cpp */; };
- DF84282B0E7BA6AC00F5680E /* config.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424B40E7BA6AB00F5680E /* config.cpp */; };
- DF84282C0E7BA6AC00F5680E /* cursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424B70E7BA6AB00F5680E /* cursor.cpp */; };
- DF84282D0E7BA6AC00F5680E /* debugger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424B90E7BA6AB00F5680E /* debugger.cpp */; };
- DF84282E0E7BA6AC00F5680E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424BB0E7BA6AB00F5680E /* detection.cpp */; };
- DF84282F0E7BA6AC00F5680E /* effect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424BD0E7BA6AB00F5680E /* effect.cpp */; };
- DF8428300E7BA6AC00F5680E /* events.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424BE0E7BA6AB00F5680E /* events.cpp */; };
- DF8428310E7BA6AC00F5680E /* faders.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424C00E7BA6AB00F5680E /* faders.cpp */; };
- DF8428320E7BA6AC00F5680E /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424C30E7BA6AB00F5680E /* font.cpp */; };
- DF8428330E7BA6AC00F5680E /* graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424C50E7BA6AB00F5680E /* graphics.cpp */; };
- DF8428340E7BA6AC00F5680E /* handle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424C70E7BA6AB00F5680E /* handle.cpp */; };
- DF8428350E7BA6AC00F5680E /* heapmem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424C90E7BA6AB00F5680E /* heapmem.cpp */; };
- DF8428370E7BA6AC00F5680E /* mareels.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424CD0E7BA6AB00F5680E /* mareels.cpp */; };
- DF8428390E7BA6AC00F5680E /* move.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424CF0E7BA6AB00F5680E /* move.cpp */; };
- DF84283A0E7BA6AC00F5680E /* multiobj.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424D10E7BA6AB00F5680E /* multiobj.cpp */; };
- DF84283B0E7BA6AC00F5680E /* music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424D30E7BA6AB00F5680E /* music.cpp */; };
- DF84283C0E7BA6AC00F5680E /* object.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424D50E7BA6AB00F5680E /* object.cpp */; };
- DF84283D0E7BA6AC00F5680E /* palette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424D70E7BA6AB00F5680E /* palette.cpp */; };
- DF84283E0E7BA6AC00F5680E /* pcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424D90E7BA6AB00F5680E /* pcode.cpp */; };
- DF84283F0E7BA6AC00F5680E /* pdisplay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424DB0E7BA6AB00F5680E /* pdisplay.cpp */; };
- DF8428400E7BA6AC00F5680E /* play.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424DD0E7BA6AB00F5680E /* play.cpp */; };
- DF8428410E7BA6AC00F5680E /* polygons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424DE0E7BA6AB00F5680E /* polygons.cpp */; };
- DF8428420E7BA6AC00F5680E /* rince.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424E00E7BA6AB00F5680E /* rince.cpp */; };
- DF8428430E7BA6AC00F5680E /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424E20E7BA6AB00F5680E /* saveload.cpp */; };
- DF8428440E7BA6AC00F5680E /* savescn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424E30E7BA6AB00F5680E /* savescn.cpp */; };
- DF8428450E7BA6AC00F5680E /* scene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424E50E7BA6AB00F5680E /* scene.cpp */; };
- DF8428460E7BA6AC00F5680E /* sched.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424E70E7BA6AB00F5680E /* sched.cpp */; };
- DF8428470E7BA6AC00F5680E /* scn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424E90E7BA6AB00F5680E /* scn.cpp */; };
- DF8428480E7BA6AC00F5680E /* scroll.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424EB0E7BA6AB00F5680E /* scroll.cpp */; };
- DF8428490E7BA6AC00F5680E /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424EE0E7BA6AB00F5680E /* sound.cpp */; };
- DF84284A0E7BA6AC00F5680E /* strres.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424F00E7BA6AB00F5680E /* strres.cpp */; };
- DF84284B0E7BA6AC00F5680E /* text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424F20E7BA6AB00F5680E /* text.cpp */; };
- DF84284C0E7BA6AC00F5680E /* timers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424F40E7BA6AB00F5680E /* timers.cpp */; };
- DF84284D0E7BA6AC00F5680E /* tinlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424F60E7BA6AB00F5680E /* tinlib.cpp */; };
- DF84284E0E7BA6AC00F5680E /* tinsel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424F80E7BA6AB00F5680E /* tinsel.cpp */; };
- DF84284F0E7BA6AC00F5680E /* token.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424FA0E7BA6AB00F5680E /* token.cpp */; };
- DF8428500E7BA6AC00F5680E /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424FD0E7BA6AB00F5680E /* detection.cpp */; };
- DF8428510E7BA6AC00F5680E /* graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424FE0E7BA6AB00F5680E /* graphics.cpp */; };
- DF8428520E7BA6AC00F5680E /* menu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8425000E7BA6AB00F5680E /* menu.cpp */; };
- DF8428530E7BA6AC00F5680E /* midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8425010E7BA6AB00F5680E /* midi.cpp */; };
- DF8428550E7BA6AC00F5680E /* opcodes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8425040E7BA6AB00F5680E /* opcodes.cpp */; };
- DF8428560E7BA6AC00F5680E /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8425050E7BA6AB00F5680E /* resource.cpp */; };
- DF8428570E7BA6AC00F5680E /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8425060E7BA6AB00F5680E /* saveload.cpp */; };
- DF8428580E7BA6AC00F5680E /* staticres.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8425070E7BA6AB00F5680E /* staticres.cpp */; };
- DF8428590E7BA6AC00F5680E /* touche.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8425080E7BA6AB00F5680E /* touche.cpp */; };
- DF8428970E7BAAAB00F5680E /* blit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8428960E7BAAAB00F5680E /* blit.cpp */; };
- DF842A1A0E7BB34E00F5680E /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF842A160E7BB34E00F5680E /* CoreAudio.framework */; };
- DF842A1B0E7BB34E00F5680E /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF842A170E7BB34E00F5680E /* CoreFoundation.framework */; };
- DF842A1C0E7BB34E00F5680E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF842A180E7BB34E00F5680E /* Foundation.framework */; };
- DF842A1D0E7BB34E00F5680E /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF842A190E7BB34E00F5680E /* UIKit.framework */; };
- DF842A280E7BB37500F5680E /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF842A270E7BB37500F5680E /* AudioToolbox.framework */; };
- DF842A2F0E7BB39E00F5680E /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF842A2E0E7BB39E00F5680E /* QuartzCore.framework */; };
- DF842A3E0E7BBB5000F5680E /* timidity.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF842A3D0E7BBB5000F5680E /* timidity.cpp */; };
- DF842A470E7BBBB400F5680E /* archive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF842A400E7BBBB400F5680E /* archive.cpp */; };
- DF842A490E7BBBB400F5680E /* unarj.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF842A450E7BBBB400F5680E /* unarj.cpp */; };
- DF842A6D0E7BBD5700F5680E /* stdiostream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF842A6B0E7BBD5700F5680E /* stdiostream.cpp */; };
- DF895C03124C24680077F6E8 /* player_towns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF895C01124C24680077F6E8 /* player_towns.cpp */; };
- DF895C04124C24680077F6E8 /* player_towns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF895C01124C24680077F6E8 /* player_towns.cpp */; };
- DF895C05124C24680077F6E8 /* player_towns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF895C01124C24680077F6E8 /* player_towns.cpp */; };
- DF895C25124C25150077F6E8 /* init_fascin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF895C24124C25150077F6E8 /* init_fascin.cpp */; };
- DF895C26124C25150077F6E8 /* init_fascin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF895C24124C25150077F6E8 /* init_fascin.cpp */; };
- DF895C27124C25150077F6E8 /* init_fascin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF895C24124C25150077F6E8 /* init_fascin.cpp */; };
- DF895C2A124C25350077F6E8 /* script_patches.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF895C29124C25350077F6E8 /* script_patches.cpp */; };
- DF895C2B124C25350077F6E8 /* script_patches.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF895C29124C25350077F6E8 /* script_patches.cpp */; };
- DF895C2C124C25350077F6E8 /* script_patches.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF895C29124C25350077F6E8 /* script_patches.cpp */; };
- DF895C34124C26660077F6E8 /* icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = DF895C33124C26660077F6E8 /* icon-72.png */; };
- DF895C35124C26660077F6E8 /* icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = DF895C33124C26660077F6E8 /* icon-72.png */; };
- DF895C36124C26660077F6E8 /* icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = DF895C33124C26660077F6E8 /* icon-72.png */; };
- DF895C41124C271F0077F6E8 /* icon4.png in Resources */ = {isa = PBXBuildFile; fileRef = DF895C40124C271F0077F6E8 /* icon4.png */; };
- DF895C42124C271F0077F6E8 /* icon4.png in Resources */ = {isa = PBXBuildFile; fileRef = DF895C40124C271F0077F6E8 /* icon4.png */; };
- DF895C43124C271F0077F6E8 /* icon4.png in Resources */ = {isa = PBXBuildFile; fileRef = DF895C40124C271F0077F6E8 /* icon4.png */; };
- DF89C2880F62D55C00D756B6 /* sprites_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF89C2870F62D55C00D756B6 /* sprites_lol.cpp */; };
- DF89C2A40F62D79E00D756B6 /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF89C2A30F62D79E00D756B6 /* script.cpp */; };
- DF90E9BF10AEDA9B00C8F93F /* selector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF90E9BD10AEDA9B00C8F93F /* selector.cpp */; };
- DF90E9C110AEDA9B00C8F93F /* selector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF90E9BD10AEDA9B00C8F93F /* selector.cpp */; };
- DF90E9C310AEDA9B00C8F93F /* selector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF90E9BD10AEDA9B00C8F93F /* selector.cpp */; };
- DF90EAA410B0234300C8F93F /* draw_playtoons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF90EAA310B0234300C8F93F /* draw_playtoons.cpp */; };
- DF90EAA510B0234300C8F93F /* draw_playtoons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF90EAA310B0234300C8F93F /* draw_playtoons.cpp */; };
- DF90EAA610B0234300C8F93F /* draw_playtoons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF90EAA310B0234300C8F93F /* draw_playtoons.cpp */; };
- DF90EAAD10B0236F00C8F93F /* staticres.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF90EAAB10B0236F00C8F93F /* staticres.cpp */; };
- DF90EAAE10B0236F00C8F93F /* staticres.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF90EAAB10B0236F00C8F93F /* staticres.cpp */; };
- DF90EAAF10B0236F00C8F93F /* staticres.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF90EAAB10B0236F00C8F93F /* staticres.cpp */; };
- DF9B9248118E46730069C19D /* error.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF9B9246118E46730069C19D /* error.cpp */; };
- DF9B9249118E46730069C19D /* error.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF9B9246118E46730069C19D /* error.cpp */; };
- DF9B924A118E46730069C19D /* error.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF9B9246118E46730069C19D /* error.cpp */; };
- DF9B9252118E46A00069C19D /* fontsjis.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF9B924F118E46A00069C19D /* fontsjis.cpp */; };
- DF9B9254118E46A00069C19D /* fontsjis.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF9B924F118E46A00069C19D /* fontsjis.cpp */; };
- DF9B9256118E46A00069C19D /* fontsjis.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF9B924F118E46A00069C19D /* fontsjis.cpp */; };
- DF9B9262118E46FE0069C19D /* error.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF9B9261118E46FE0069C19D /* error.cpp */; };
- DF9B9263118E46FE0069C19D /* error.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF9B9261118E46FE0069C19D /* error.cpp */; };
- DF9B9264118E46FE0069C19D /* error.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF9B9261118E46FE0069C19D /* error.cpp */; };
- DFAAAFF70F0112AD003E9390 /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFAAAFF50F0112AD003E9390 /* saveload.cpp */; };
- DFAAAFF90F0112C1003E9390 /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFAAAFF80F0112C1003E9390 /* detection.cpp */; };
- DFAAAFFC0F0112DF003E9390 /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFAAAFFB0F0112DF003E9390 /* detection.cpp */; };
- DFAAB0020F011392003E9390 /* thumbnail_intern.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFAAB0010F011392003E9390 /* thumbnail_intern.cpp */; };
- DFAAD23D0F50120E00C3A4E2 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFAAD2390F50120E00C3A4E2 /* console.cpp */; };
- DFADEBB313820DF500C46364 /* maccursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFADEBB113820DF500C46364 /* maccursor.cpp */; };
- DFADEBB413820DF500C46364 /* maccursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFADEBB113820DF500C46364 /* maccursor.cpp */; };
- DFADEBB513820DF500C46364 /* maccursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFADEBB113820DF500C46364 /* maccursor.cpp */; };
- DFADEBB713820E0C00C46364 /* posix-fs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFADEBB613820E0C00C46364 /* posix-fs.cpp */; };
- DFADEBB813820E0C00C46364 /* posix-fs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFADEBB613820E0C00C46364 /* posix-fs.cpp */; };
- DFADEBB913820E0C00C46364 /* posix-fs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFADEBB613820E0C00C46364 /* posix-fs.cpp */; };
- DFADEC071382140300C46364 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DFADEC061382140300C46364 /* libz.dylib */; };
- DFB0577611B753DA0015AE65 /* rational.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB0577411B753DA0015AE65 /* rational.cpp */; };
- DFB0577711B753DA0015AE65 /* rational.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB0577411B753DA0015AE65 /* rational.cpp */; };
- DFB0577811B753DA0015AE65 /* rational.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB0577411B753DA0015AE65 /* rational.cpp */; };
- DFB0578011B7541F0015AE65 /* resource_audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB0577D11B7541F0015AE65 /* resource_audio.cpp */; };
- DFB0578111B7541F0015AE65 /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB0577E11B7541F0015AE65 /* util.cpp */; };
- DFB0578211B7541F0015AE65 /* resource_audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB0577D11B7541F0015AE65 /* resource_audio.cpp */; };
- DFB0578311B7541F0015AE65 /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB0577E11B7541F0015AE65 /* util.cpp */; };
- DFB0578411B7541F0015AE65 /* resource_audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB0577D11B7541F0015AE65 /* resource_audio.cpp */; };
- DFB0578511B7541F0015AE65 /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB0577E11B7541F0015AE65 /* util.cpp */; };
- DFB0578A11B754570015AE65 /* maciconbar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB0578811B754570015AE65 /* maciconbar.cpp */; };
- DFB0578B11B754570015AE65 /* maciconbar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB0578811B754570015AE65 /* maciconbar.cpp */; };
- DFB0578C11B754570015AE65 /* maciconbar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB0578811B754570015AE65 /* maciconbar.cpp */; };
- DFB0579111B7547D0015AE65 /* pict.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB0578F11B7547D0015AE65 /* pict.cpp */; };
- DFB0579211B7547D0015AE65 /* pict.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB0578F11B7547D0015AE65 /* pict.cpp */; };
- DFB0579311B7547D0015AE65 /* pict.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB0578F11B7547D0015AE65 /* pict.cpp */; };
- DFC831210F48AF19005EF03C /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8301A0F48AF18005EF03C /* detection.cpp */; };
- DFC831240F48AF19005EF03C /* gc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8301E0F48AF18005EF03C /* gc.cpp */; };
- DFC831270F48AF19005EF03C /* kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830230F48AF18005EF03C /* kernel.cpp */; };
- DFC831280F48AF19005EF03C /* kevent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830260F48AF18005EF03C /* kevent.cpp */; };
- DFC831290F48AF19005EF03C /* kfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830270F48AF18005EF03C /* kfile.cpp */; };
- DFC8312A0F48AF19005EF03C /* kgraphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830280F48AF18005EF03C /* kgraphics.cpp */; };
- DFC8312B0F48AF19005EF03C /* klists.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830290F48AF18005EF03C /* klists.cpp */; };
- DFC8312C0F48AF19005EF03C /* kmath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8302A0F48AF18005EF03C /* kmath.cpp */; };
- DFC8312D0F48AF19005EF03C /* kmenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8302B0F48AF18005EF03C /* kmenu.cpp */; };
- DFC8312E0F48AF19005EF03C /* kmovement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8302C0F48AF18005EF03C /* kmovement.cpp */; };
- DFC8312F0F48AF19005EF03C /* kpathing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8302D0F48AF18005EF03C /* kpathing.cpp */; };
- DFC831300F48AF19005EF03C /* kscripts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8302E0F48AF18005EF03C /* kscripts.cpp */; };
- DFC831310F48AF19005EF03C /* ksound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8302F0F48AF18005EF03C /* ksound.cpp */; };
- DFC831320F48AF19005EF03C /* kstring.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830300F48AF18005EF03C /* kstring.cpp */; };
- DFC831330F48AF19005EF03C /* message.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830310F48AF18005EF03C /* message.cpp */; };
- DFC831370F48AF19005EF03C /* savegame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830360F48AF18005EF03C /* savegame.cpp */; };
- DFC831390F48AF19005EF03C /* scriptdebug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830390F48AF18005EF03C /* scriptdebug.cpp */; };
- DFC8313A0F48AF19005EF03C /* seg_manager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8303A0F48AF18005EF03C /* seg_manager.cpp */; };
- DFC8313C0F48AF19005EF03C /* vm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8303C0F48AF18005EF03C /* vm.cpp */; };
- DFC8315C0F48AF19005EF03C /* sci.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830960F48AF18005EF03C /* sci.cpp */; };
- DFCDC6D9116629CE00A7D2A0 /* features.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCDC6D5116629CE00A7D2A0 /* features.cpp */; };
- DFCDC6DA116629CE00A7D2A0 /* kparse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCDC6D7116629CE00A7D2A0 /* kparse.cpp */; };
- DFCDC6DB116629CE00A7D2A0 /* features.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCDC6D5116629CE00A7D2A0 /* features.cpp */; };
- DFCDC6DC116629CE00A7D2A0 /* kparse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCDC6D7116629CE00A7D2A0 /* kparse.cpp */; };
- DFCDC6DD116629CE00A7D2A0 /* features.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCDC6D5116629CE00A7D2A0 /* features.cpp */; };
- DFCDC6DE116629CE00A7D2A0 /* kparse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCDC6D7116629CE00A7D2A0 /* kparse.cpp */; };
- DFCDC6F711662AAB00A7D2A0 /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCDC6F611662AAB00A7D2A0 /* resource.cpp */; };
- DFCDC6F811662AAB00A7D2A0 /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCDC6F611662AAB00A7D2A0 /* resource.cpp */; };
- DFCDC6F911662AAB00A7D2A0 /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCDC6F611662AAB00A7D2A0 /* resource.cpp */; };
- DFCDC70411662B0200A7D2A0 /* saveload_fascin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCDC70311662B0200A7D2A0 /* saveload_fascin.cpp */; };
- DFCDC70511662B0200A7D2A0 /* saveload_fascin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCDC70311662B0200A7D2A0 /* saveload_fascin.cpp */; };
- DFCDC70611662B0200A7D2A0 /* saveload_fascin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCDC70311662B0200A7D2A0 /* saveload_fascin.cpp */; };
- DFCDC70B11662B6B00A7D2A0 /* macresman.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCDC70911662B6B00A7D2A0 /* macresman.cpp */; };
- DFCDC70C11662B6B00A7D2A0 /* macresman.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCDC70911662B6B00A7D2A0 /* macresman.cpp */; };
- DFCDC70D11662B6B00A7D2A0 /* macresman.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCDC70911662B6B00A7D2A0 /* macresman.cpp */; };
- DFD511480DF3383500854012 /* memorypool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD511460DF3383500854012 /* memorypool.cpp */; };
- DFD517E20DF33CAC00854012 /* seq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD517E10DF33CAC00854012 /* seq.cpp */; };
- DFD5183D0DF3411800854012 /* scaler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD5183B0DF3411800854012 /* scaler.cpp */; };
- DFD518A20DF34B2500854012 /* scalebit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD518A00DF34B2500854012 /* scalebit.cpp */; };
- DFD518BC0DF34BA600854012 /* 2xsai.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD518AA0DF34BA600854012 /* 2xsai.cpp */; };
- DFD518BD0DF34BA600854012 /* aspect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD518AB0DF34BA600854012 /* aspect.cpp */; };
- DFD518C50DF34BA600854012 /* scale2x.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD518B50DF34BA600854012 /* scale2x.cpp */; };
- DFD518C70DF34BA600854012 /* scale3x.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD518B80DF34BA600854012 /* scale3x.cpp */; };
- DFD6470C0F495B51008E18EF /* unzip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473C10D81F4E800B6D1FB /* unzip.cpp */; };
- DFE470CE0D81F4BA00B6D1FB /* commandLine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE470C10D81F4BA00B6D1FB /* commandLine.cpp */; };
- DFE470D10D81F4BA00B6D1FB /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE470C70D81F4BA00B6D1FB /* main.cpp */; };
- DFE470D30D81F4BA00B6D1FB /* plugins.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE470CA0D81F4BA00B6D1FB /* plugins.cpp */; };
- DFE470D40D81F4BA00B6D1FB /* version.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE470CC0D81F4BA00B6D1FB /* version.cpp */; };
- DFE4782B0D81F4E900B6D1FB /* default-events.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE470D80D81F4E700B6D1FB /* default-events.cpp */; };
- DFE478380D81F4E900B6D1FB /* posix-fs-factory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE470F60D81F4E700B6D1FB /* posix-fs-factory.cpp */; };
- DFE478C50D81F4E900B6D1FB /* iphone_main.m in Sources */ = {isa = PBXBuildFile; fileRef = DFE471E10D81F4E700B6D1FB /* iphone_main.m */; };
- DFE479B60D81F4E900B6D1FB /* posix-provider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473810D81F4E800B6D1FB /* posix-provider.cpp */; };
- DFE479BA0D81F4E900B6D1FB /* default-saves.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4738E0D81F4E800B6D1FB /* default-saves.cpp */; };
- DFE479BB0D81F4E900B6D1FB /* savefile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473900D81F4E800B6D1FB /* savefile.cpp */; };
- DFE479BC0D81F4E900B6D1FB /* default-timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473930D81F4E800B6D1FB /* default-timer.cpp */; };
- DFE479BE0D81F4E900B6D1FB /* config-file.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4739A0D81F4E800B6D1FB /* config-file.cpp */; };
- DFE479BF0D81F4E900B6D1FB /* config-manager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4739C0D81F4E800B6D1FB /* config-manager.cpp */; };
- DFE479C00D81F4E900B6D1FB /* file.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473A10D81F4E800B6D1FB /* file.cpp */; };
- DFE479C10D81F4E900B6D1FB /* fs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473A40D81F4E800B6D1FB /* fs.cpp */; };
- DFE479C20D81F4E900B6D1FB /* hashmap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473A80D81F4E800B6D1FB /* hashmap.cpp */; };
- DFE479C30D81F4E900B6D1FB /* md5.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473AD0D81F4E800B6D1FB /* md5.cpp */; };
- DFE479C50D81F4E900B6D1FB /* mutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473B00D81F4E800B6D1FB /* mutex.cpp */; };
- DFE479C60D81F4E900B6D1FB /* str.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473BA0D81F4E800B6D1FB /* str.cpp */; };
- DFE479C70D81F4E900B6D1FB /* stream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473BC0D81F4E800B6D1FB /* stream.cpp */; };
- DFE479C80D81F4E900B6D1FB /* system.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473BE0D81F4E800B6D1FB /* system.cpp */; };
- DFE479CA0D81F4E900B6D1FB /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473C30D81F4E800B6D1FB /* util.cpp */; };
- DFE479CB0D81F4E900B6D1FB /* zlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473C50D81F4E800B6D1FB /* zlib.cpp */; };
- DFE47BFB0D81F4E900B6D1FB /* cursorman.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477540D81F4E900B6D1FB /* cursorman.cpp */; };
- DFE47BFD0D81F4E900B6D1FB /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477580D81F4E900B6D1FB /* font.cpp */; };
- DFE47BFE0D81F4E900B6D1FB /* fontman.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4775A0D81F4E900B6D1FB /* fontman.cpp */; };
- DFE47BFF0D81F4E900B6D1FB /* consolefont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4775D0D81F4E900B6D1FB /* consolefont.cpp */; };
- DFE47C000D81F4E900B6D1FB /* newfont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4775E0D81F4E900B6D1FB /* newfont.cpp */; };
- DFE47C010D81F4E900B6D1FB /* newfont_big.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4775F0D81F4E900B6D1FB /* newfont_big.cpp */; };
- DFE47C030D81F4E900B6D1FB /* iff.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477610D81F4E900B6D1FB /* iff.cpp */; };
- DFE47C040D81F4E900B6D1FB /* imagedec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477630D81F4E900B6D1FB /* imagedec.cpp */; };
- DFE47C080D81F4E900B6D1FB /* primitives.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4776A0D81F4E900B6D1FB /* primitives.cpp */; };
- DFE47C1B0D81F4E900B6D1FB /* surface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477860D81F4E900B6D1FB /* surface.cpp */; };
- DFE47C1C0D81F4E900B6D1FB /* about.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477890D81F4E900B6D1FB /* about.cpp */; };
- DFE47C1D0D81F4E900B6D1FB /* Actions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4778B0D81F4E900B6D1FB /* Actions.cpp */; };
- DFE47C1E0D81F4E900B6D1FB /* browser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4778D0D81F4E900B6D1FB /* browser.cpp */; };
- DFE47C1F0D81F4E900B6D1FB /* chooser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4778F0D81F4E900B6D1FB /* chooser.cpp */; };
- DFE47C200D81F4E900B6D1FB /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477910D81F4E900B6D1FB /* console.cpp */; };
- DFE47C210D81F4E900B6D1FB /* debugger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477940D81F4E900B6D1FB /* debugger.cpp */; };
- DFE47C220D81F4E900B6D1FB /* dialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477960D81F4E900B6D1FB /* dialog.cpp */; };
- DFE47C260D81F4E900B6D1FB /* Key.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4779E0D81F4E900B6D1FB /* Key.cpp */; };
- DFE47C280D81F4E900B6D1FB /* launcher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477A20D81F4E900B6D1FB /* launcher.cpp */; };
- DFE47C2A0D81F4E900B6D1FB /* massadd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477A60D81F4E900B6D1FB /* massadd.cpp */; };
- DFE47C2B0D81F4E900B6D1FB /* message.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477A80D81F4E900B6D1FB /* message.cpp */; };
- DFE47C2E0D81F4E900B6D1FB /* object.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477AD0D81F4E900B6D1FB /* object.cpp */; };
- DFE47C2F0D81F4E900B6D1FB /* options.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477AF0D81F4E900B6D1FB /* options.cpp */; };
- DFE47C350D81F4E900B6D1FB /* themebrowser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477BA0D81F4E900B6D1FB /* themebrowser.cpp */; };
- DFE47C3B0D81F4E900B6D1FB /* widget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477C40D81F4E900B6D1FB /* widget.cpp */; };
- DFE47C870D81F86900B6D1FB /* kyra.dat in Resources */ = {isa = PBXBuildFile; fileRef = DFE47C810D81F86900B6D1FB /* kyra.dat */; };
- DFE47C880D81F86900B6D1FB /* lure.dat in Resources */ = {isa = PBXBuildFile; fileRef = DFE47C820D81F86900B6D1FB /* lure.dat */; };
- DFE47C890D81F86900B6D1FB /* queen.tbl in Resources */ = {isa = PBXBuildFile; fileRef = DFE47C830D81F86900B6D1FB /* queen.tbl */; };
- DFE47C8B0D81F86900B6D1FB /* sky.cpt in Resources */ = {isa = PBXBuildFile; fileRef = DFE47C850D81F86900B6D1FB /* sky.cpt */; };
- DFE88C460F874A1100C555C5 /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE88C440F874A1100C555C5 /* sound.cpp */; };
- DFE88C470F874A1100C555C5 /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE88C440F874A1100C555C5 /* sound.cpp */; };
- DFEC5D101166C5CF00C90552 /* random.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFEC5D0A1166C5CF00C90552 /* random.cpp */; };
- DFEC5D111166C5CF00C90552 /* tokenizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFEC5D0D1166C5CF00C90552 /* tokenizer.cpp */; };
- DFEC5D121166C5CF00C90552 /* random.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFEC5D0A1166C5CF00C90552 /* random.cpp */; };
- DFEC5D131166C5CF00C90552 /* tokenizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFEC5D0D1166C5CF00C90552 /* tokenizer.cpp */; };
- DFEC5D141166C5CF00C90552 /* random.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFEC5D0A1166C5CF00C90552 /* random.cpp */; };
- DFEC5D151166C5CF00C90552 /* tokenizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFEC5D0D1166C5CF00C90552 /* tokenizer.cpp */; };
- DFEC5D361166C67300C90552 /* savestate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFEC5D341166C67300C90552 /* savestate.cpp */; };
- DFEC5D371166C67300C90552 /* savestate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFEC5D341166C67300C90552 /* savestate.cpp */; };
- DFEC5D381166C67300C90552 /* savestate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFEC5D341166C67300C90552 /* savestate.cpp */; };
- DFF959050FB22D3000A3EC78 /* libmad.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DFD6476C0F49F7EF008E18EF /* libmad.a */; };
- DFF959060FB22D3100A3EC78 /* libFLAC.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DFD6476B0F49F7EF008E18EF /* libFLAC.a */; };
- DFF959080FB22D3300A3EC78 /* libvorbisidec.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DFD6476F0F49F7EF008E18EF /* libvorbisidec.a */; };
- DFF9590D0FB22D5700A3EC78 /* scummclassic.zip in Resources */ = {isa = PBXBuildFile; fileRef = DF2FFBDB0F485E480006E566 /* scummclassic.zip */; };
- DFF9590E0FB22D5700A3EC78 /* scummmodern.zip in Resources */ = {isa = PBXBuildFile; fileRef = DF7E8C7A0ED601E5001CB19F /* scummmodern.zip */; };
- DFF959100FB22D5700A3EC78 /* kyra.dat in Resources */ = {isa = PBXBuildFile; fileRef = DFE47C810D81F86900B6D1FB /* kyra.dat */; };
- DFF959110FB22D5700A3EC78 /* lure.dat in Resources */ = {isa = PBXBuildFile; fileRef = DFE47C820D81F86900B6D1FB /* lure.dat */; };
- DFF959120FB22D5700A3EC78 /* queen.tbl in Resources */ = {isa = PBXBuildFile; fileRef = DFE47C830D81F86900B6D1FB /* queen.tbl */; };
- DFF959130FB22D5700A3EC78 /* sky.cpt in Resources */ = {isa = PBXBuildFile; fileRef = DFE47C850D81F86900B6D1FB /* sky.cpt */; };
- DFF959140FB22D5700A3EC78 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = DF2FFD290F48717F0006E566 /* Default.png */; };
- DFF959150FB22D5700A3EC78 /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = DF2FFD2A0F48717F0006E566 /* icon.png */; };
- DFF959170FB22D5700A3EC78 /* commandLine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE470C10D81F4BA00B6D1FB /* commandLine.cpp */; };
- DFF959180FB22D5700A3EC78 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE470C70D81F4BA00B6D1FB /* main.cpp */; };
- DFF959190FB22D5700A3EC78 /* plugins.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE470CA0D81F4BA00B6D1FB /* plugins.cpp */; };
- DFF9591A0FB22D5700A3EC78 /* version.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE470CC0D81F4BA00B6D1FB /* version.cpp */; };
- DFF9591B0FB22D5700A3EC78 /* default-events.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE470D80D81F4E700B6D1FB /* default-events.cpp */; };
- DFF9591C0FB22D5700A3EC78 /* posix-fs-factory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE470F60D81F4E700B6D1FB /* posix-fs-factory.cpp */; };
- DFF9591D0FB22D5700A3EC78 /* iphone_main.m in Sources */ = {isa = PBXBuildFile; fileRef = DFE471E10D81F4E700B6D1FB /* iphone_main.m */; };
- DFF9591F0FB22D5700A3EC78 /* posix-provider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473810D81F4E800B6D1FB /* posix-provider.cpp */; };
- DFF959200FB22D5700A3EC78 /* default-saves.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4738E0D81F4E800B6D1FB /* default-saves.cpp */; };
- DFF959210FB22D5700A3EC78 /* savefile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473900D81F4E800B6D1FB /* savefile.cpp */; };
- DFF959220FB22D5700A3EC78 /* default-timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473930D81F4E800B6D1FB /* default-timer.cpp */; };
- DFF959230FB22D5700A3EC78 /* config-file.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4739A0D81F4E800B6D1FB /* config-file.cpp */; };
- DFF959240FB22D5700A3EC78 /* config-manager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4739C0D81F4E800B6D1FB /* config-manager.cpp */; };
- DFF959250FB22D5700A3EC78 /* file.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473A10D81F4E800B6D1FB /* file.cpp */; };
- DFF959260FB22D5700A3EC78 /* fs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473A40D81F4E800B6D1FB /* fs.cpp */; };
- DFF959270FB22D5700A3EC78 /* hashmap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473A80D81F4E800B6D1FB /* hashmap.cpp */; };
- DFF959280FB22D5700A3EC78 /* md5.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473AD0D81F4E800B6D1FB /* md5.cpp */; };
- DFF959290FB22D5700A3EC78 /* mutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473B00D81F4E800B6D1FB /* mutex.cpp */; };
- DFF9592A0FB22D5700A3EC78 /* str.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473BA0D81F4E800B6D1FB /* str.cpp */; };
- DFF9592B0FB22D5700A3EC78 /* stream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473BC0D81F4E800B6D1FB /* stream.cpp */; };
- DFF9592C0FB22D5700A3EC78 /* system.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473BE0D81F4E800B6D1FB /* system.cpp */; };
- DFF9592D0FB22D5700A3EC78 /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473C30D81F4E800B6D1FB /* util.cpp */; };
- DFF9592E0FB22D5700A3EC78 /* zlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473C50D81F4E800B6D1FB /* zlib.cpp */; };
- DFF9592F0FB22D5700A3EC78 /* cursorman.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477540D81F4E900B6D1FB /* cursorman.cpp */; };
- DFF959300FB22D5700A3EC78 /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477580D81F4E900B6D1FB /* font.cpp */; };
- DFF959310FB22D5700A3EC78 /* fontman.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4775A0D81F4E900B6D1FB /* fontman.cpp */; };
- DFF959320FB22D5700A3EC78 /* consolefont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4775D0D81F4E900B6D1FB /* consolefont.cpp */; };
- DFF959330FB22D5700A3EC78 /* newfont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4775E0D81F4E900B6D1FB /* newfont.cpp */; };
- DFF959340FB22D5700A3EC78 /* newfont_big.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4775F0D81F4E900B6D1FB /* newfont_big.cpp */; };
- DFF959360FB22D5700A3EC78 /* iff.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477610D81F4E900B6D1FB /* iff.cpp */; };
- DFF959370FB22D5700A3EC78 /* imagedec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477630D81F4E900B6D1FB /* imagedec.cpp */; };
- DFF959380FB22D5700A3EC78 /* primitives.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4776A0D81F4E900B6D1FB /* primitives.cpp */; };
- DFF959390FB22D5700A3EC78 /* surface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477860D81F4E900B6D1FB /* surface.cpp */; };
- DFF9593A0FB22D5700A3EC78 /* about.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477890D81F4E900B6D1FB /* about.cpp */; };
- DFF9593B0FB22D5700A3EC78 /* Actions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4778B0D81F4E900B6D1FB /* Actions.cpp */; };
- DFF9593C0FB22D5700A3EC78 /* browser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4778D0D81F4E900B6D1FB /* browser.cpp */; };
- DFF9593D0FB22D5700A3EC78 /* chooser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4778F0D81F4E900B6D1FB /* chooser.cpp */; };
- DFF9593E0FB22D5700A3EC78 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477910D81F4E900B6D1FB /* console.cpp */; };
- DFF9593F0FB22D5700A3EC78 /* debugger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477940D81F4E900B6D1FB /* debugger.cpp */; };
- DFF959400FB22D5700A3EC78 /* dialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477960D81F4E900B6D1FB /* dialog.cpp */; };
- DFF959430FB22D5700A3EC78 /* Key.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4779E0D81F4E900B6D1FB /* Key.cpp */; };
- DFF959440FB22D5700A3EC78 /* launcher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477A20D81F4E900B6D1FB /* launcher.cpp */; };
- DFF959460FB22D5700A3EC78 /* massadd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477A60D81F4E900B6D1FB /* massadd.cpp */; };
- DFF959470FB22D5700A3EC78 /* message.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477A80D81F4E900B6D1FB /* message.cpp */; };
- DFF959480FB22D5700A3EC78 /* object.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477AD0D81F4E900B6D1FB /* object.cpp */; };
- DFF959490FB22D5700A3EC78 /* options.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477AF0D81F4E900B6D1FB /* options.cpp */; };
- DFF9594D0FB22D5700A3EC78 /* themebrowser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477BA0D81F4E900B6D1FB /* themebrowser.cpp */; };
- DFF9594E0FB22D5700A3EC78 /* widget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE477C40D81F4E900B6D1FB /* widget.cpp */; };
- DFF9596C0FB22D5700A3EC78 /* memorypool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD511460DF3383500854012 /* memorypool.cpp */; };
- DFF9596D0FB22D5700A3EC78 /* seq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD517E10DF33CAC00854012 /* seq.cpp */; };
- DFF9596E0FB22D5700A3EC78 /* scaler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD5183B0DF3411800854012 /* scaler.cpp */; };
- DFF9596F0FB22D5700A3EC78 /* scalebit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD518A00DF34B2500854012 /* scalebit.cpp */; };
- DFF959700FB22D5700A3EC78 /* 2xsai.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD518AA0DF34BA600854012 /* 2xsai.cpp */; };
- DFF959710FB22D5700A3EC78 /* aspect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD518AB0DF34BA600854012 /* aspect.cpp */; };
- DFF959740FB22D5700A3EC78 /* scale2x.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD518B50DF34BA600854012 /* scale2x.cpp */; };
- DFF959750FB22D5700A3EC78 /* scale3x.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD518B80DF34BA600854012 /* scale3x.cpp */; };
- DFF959760FB22D5700A3EC78 /* iphone_keyboard.m in Sources */ = {isa = PBXBuildFile; fileRef = DF841FD90E7BA61800F5680E /* iphone_keyboard.m */; };
- DFF959770FB22D5700A3EC78 /* iphone_video.m in Sources */ = {isa = PBXBuildFile; fileRef = DF841FDB0E7BA61800F5680E /* iphone_video.m */; };
- DFF959780FB22D5700A3EC78 /* agi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF841FF70E7BA6A600F5680E /* agi.cpp */; };
- DFF959790FB22D5700A3EC78 /* checks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF841FF90E7BA6A600F5680E /* checks.cpp */; };
- DFF9597A0FB22D5700A3EC78 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF841FFA0E7BA6A600F5680E /* console.cpp */; };
- DFF9597B0FB22D5700A3EC78 /* cycle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF841FFC0E7BA6A600F5680E /* cycle.cpp */; };
- DFF9597C0FB22D5700A3EC78 /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF841FFD0E7BA6A600F5680E /* detection.cpp */; };
- DFF9597D0FB22D5700A3EC78 /* global.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF841FFF0E7BA6A600F5680E /* global.cpp */; };
- DFF9597E0FB22D5700A3EC78 /* graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420000E7BA6A600F5680E /* graphics.cpp */; };
- DFF9597F0FB22D5700A3EC78 /* id.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420020E7BA6A600F5680E /* id.cpp */; };
- DFF959800FB22D5700A3EC78 /* inv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420030E7BA6A600F5680E /* inv.cpp */; };
- DFF959810FB22D5700A3EC78 /* keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420040E7BA6A600F5680E /* keyboard.cpp */; };
- DFF959820FB22D5700A3EC78 /* loader_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420060E7BA6A600F5680E /* loader_v2.cpp */; };
- DFF959830FB22D5700A3EC78 /* loader_v3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420070E7BA6A600F5680E /* loader_v3.cpp */; };
- DFF959840FB22D5700A3EC78 /* logic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420080E7BA6A600F5680E /* logic.cpp */; };
- DFF959850FB22D5700A3EC78 /* lzw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84200A0E7BA6A600F5680E /* lzw.cpp */; };
- DFF959860FB22D5700A3EC78 /* menu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84200C0E7BA6A600F5680E /* menu.cpp */; };
- DFF959870FB22D5700A3EC78 /* motion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84200F0E7BA6A600F5680E /* motion.cpp */; };
- DFF959880FB22D5700A3EC78 /* objects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420100E7BA6A600F5680E /* objects.cpp */; };
- DFF959890FB22D5700A3EC78 /* op_cmd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420110E7BA6A600F5680E /* op_cmd.cpp */; };
- DFF9598A0FB22D5700A3EC78 /* op_dbg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420120E7BA6A600F5680E /* op_dbg.cpp */; };
- DFF9598B0FB22D5700A3EC78 /* op_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420130E7BA6A600F5680E /* op_test.cpp */; };
- DFF9598C0FB22D5700A3EC78 /* picture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420150E7BA6A600F5680E /* picture.cpp */; };
- DFF9598D0FB22D5700A3EC78 /* preagi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420170E7BA6A600F5680E /* preagi.cpp */; };
- DFF9598E0FB22D5700A3EC78 /* preagi_common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420190E7BA6A600F5680E /* preagi_common.cpp */; };
- DFF9598F0FB22D5700A3EC78 /* preagi_mickey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84201B0E7BA6A600F5680E /* preagi_mickey.cpp */; };
- DFF959900FB22D5700A3EC78 /* preagi_troll.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84201D0E7BA6A600F5680E /* preagi_troll.cpp */; };
- DFF959910FB22D5700A3EC78 /* preagi_winnie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84201F0E7BA6A600F5680E /* preagi_winnie.cpp */; };
- DFF959920FB22D5700A3EC78 /* predictive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420210E7BA6A600F5680E /* predictive.cpp */; };
- DFF959930FB22D5700A3EC78 /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420220E7BA6A600F5680E /* saveload.cpp */; };
- DFF959940FB22D5700A3EC78 /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420230E7BA6A600F5680E /* sound.cpp */; };
- DFF959950FB22D5700A3EC78 /* sprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420250E7BA6A600F5680E /* sprite.cpp */; };
- DFF959960FB22D5700A3EC78 /* text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420270E7BA6A600F5680E /* text.cpp */; };
- DFF959970FB22D5700A3EC78 /* view.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420280E7BA6A600F5680E /* view.cpp */; };
- DFF959980FB22D5700A3EC78 /* wagparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84202A0E7BA6A600F5680E /* wagparser.cpp */; };
- DFF959990FB22D5700A3EC78 /* words.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84202C0E7BA6A600F5680E /* words.cpp */; };
- DFF9599A0FB22D5700A3EC78 /* agos.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84202E0E7BA6A600F5680E /* agos.cpp */; };
- DFF9599B0FB22D5700A3EC78 /* animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420300E7BA6A600F5680E /* animation.cpp */; };
- DFF9599C0FB22D5700A3EC78 /* charset-fontdata.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420320E7BA6A600F5680E /* charset-fontdata.cpp */; };
- DFF9599D0FB22D5700A3EC78 /* charset.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420330E7BA6A600F5680E /* charset.cpp */; };
- DFF9599E0FB22D5700A3EC78 /* contain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420340E7BA6A600F5680E /* contain.cpp */; };
- DFF9599F0FB22D5700A3EC78 /* cursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420350E7BA6A600F5680E /* cursor.cpp */; };
- DFF959A00FB22D5700A3EC78 /* debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420360E7BA6A600F5680E /* debug.cpp */; };
- DFF959A10FB22D5700A3EC78 /* debugger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420380E7BA6A600F5680E /* debugger.cpp */; };
- DFF959A20FB22D5700A3EC78 /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84203A0E7BA6A600F5680E /* detection.cpp */; };
- DFF959A30FB22D5700A3EC78 /* draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84203C0E7BA6A600F5680E /* draw.cpp */; };
- DFF959A40FB22D5700A3EC78 /* event.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84203D0E7BA6A600F5680E /* event.cpp */; };
- DFF959A50FB22D5700A3EC78 /* gfx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84203E0E7BA6A600F5680E /* gfx.cpp */; };
- DFF959A60FB22D5700A3EC78 /* icons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84203F0E7BA6A600F5680E /* icons.cpp */; };
- DFF959A70FB22D5700A3EC78 /* input.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420400E7BA6A600F5680E /* input.cpp */; };
- DFF959A80FB22D5700A3EC78 /* items.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420420E7BA6A600F5680E /* items.cpp */; };
- DFF959A90FB22D5700A3EC78 /* menus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420430E7BA6A600F5680E /* menus.cpp */; };
- DFF959AA0FB22D5700A3EC78 /* midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420440E7BA6A600F5680E /* midi.cpp */; };
- DFF959AB0FB22D5700A3EC78 /* midiparser_s1d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420460E7BA6A600F5680E /* midiparser_s1d.cpp */; };
- DFF959AC0FB22D5700A3EC78 /* oracle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420480E7BA6A600F5680E /* oracle.cpp */; };
- DFF959AD0FB22D5700A3EC78 /* res.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420490E7BA6A600F5680E /* res.cpp */; };
- DFF959AE0FB22D5700A3EC78 /* res_ami.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84204A0E7BA6A600F5680E /* res_ami.cpp */; };
- DFF959AF0FB22D5700A3EC78 /* res_snd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84204B0E7BA6A600F5680E /* res_snd.cpp */; };
- DFF959B00FB22D5700A3EC78 /* rooms.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84204C0E7BA6A600F5680E /* rooms.cpp */; };
- DFF959B10FB22D5700A3EC78 /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84204D0E7BA6A600F5680E /* saveload.cpp */; };
- DFF959B20FB22D5700A3EC78 /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84204E0E7BA6A600F5680E /* script.cpp */; };
- DFF959B30FB22D5700A3EC78 /* script_e1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84204F0E7BA6A600F5680E /* script_e1.cpp */; };
- DFF959B40FB22D5700A3EC78 /* script_e2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420500E7BA6A600F5680E /* script_e2.cpp */; };
- DFF959B50FB22D5700A3EC78 /* script_ff.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420510E7BA6A600F5680E /* script_ff.cpp */; };
- DFF959B60FB22D5700A3EC78 /* script_pp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420520E7BA6A600F5680E /* script_pp.cpp */; };
- DFF959B70FB22D5700A3EC78 /* script_s1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420530E7BA6A600F5680E /* script_s1.cpp */; };
- DFF959B80FB22D5700A3EC78 /* script_s2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420540E7BA6A600F5680E /* script_s2.cpp */; };
- DFF959B90FB22D5700A3EC78 /* script_ww.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420550E7BA6A600F5680E /* script_ww.cpp */; };
- DFF959BA0FB22D5700A3EC78 /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420560E7BA6A600F5680E /* sound.cpp */; };
- DFF959BB0FB22D5700A3EC78 /* string.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420580E7BA6A600F5680E /* string.cpp */; };
- DFF959BC0FB22D5700A3EC78 /* subroutine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420590E7BA6A600F5680E /* subroutine.cpp */; };
- DFF959BD0FB22D5700A3EC78 /* verb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84205A0E7BA6A600F5680E /* verb.cpp */; };
- DFF959BE0FB22D5700A3EC78 /* vga.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84205B0E7BA6A600F5680E /* vga.cpp */; };
- DFF959BF0FB22D5700A3EC78 /* vga_e2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84205D0E7BA6A600F5680E /* vga_e2.cpp */; };
- DFF959C00FB22D5700A3EC78 /* vga_ff.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84205E0E7BA6A600F5680E /* vga_ff.cpp */; };
- DFF959C10FB22D5700A3EC78 /* vga_s1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84205F0E7BA6A600F5680E /* vga_s1.cpp */; };
- DFF959C20FB22D5700A3EC78 /* vga_s2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420600E7BA6A600F5680E /* vga_s2.cpp */; };
- DFF959C30FB22D5700A3EC78 /* vga_ww.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420610E7BA6A600F5680E /* vga_ww.cpp */; };
- DFF959C40FB22D5700A3EC78 /* window.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420620E7BA6A600F5680E /* window.cpp */; };
- DFF959C50FB22D5700A3EC78 /* zones.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420630E7BA6A600F5680E /* zones.cpp */; };
- DFF959C60FB22D5700A3EC78 /* anim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420650E7BA6A600F5680E /* anim.cpp */; };
- DFF959C70FB22D5700A3EC78 /* bg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420670E7BA6A600F5680E /* bg.cpp */; };
- DFF959C80FB22D5700A3EC78 /* bg_list.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420690E7BA6A600F5680E /* bg_list.cpp */; };
- DFF959C90FB22D5700A3EC78 /* cine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84206B0E7BA6A600F5680E /* cine.cpp */; };
- DFF959CA0FB22D5700A3EC78 /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84206D0E7BA6A600F5680E /* detection.cpp */; };
- DFF959CB0FB22D5700A3EC78 /* gfx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84206E0E7BA6A600F5680E /* gfx.cpp */; };
- DFF959CC0FB22D5700A3EC78 /* main_loop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420700E7BA6A600F5680E /* main_loop.cpp */; };
- DFF959CD0FB22D5700A3EC78 /* msg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420730E7BA6A600F5680E /* msg.cpp */; };
- DFF959CE0FB22D5700A3EC78 /* object.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420750E7BA6A600F5680E /* object.cpp */; };
- DFF959CF0FB22D5700A3EC78 /* pal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420770E7BA6A600F5680E /* pal.cpp */; };
- DFF959D00FB22D5700A3EC78 /* part.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420790E7BA6A600F5680E /* part.cpp */; };
- DFF959D10FB22D5700A3EC78 /* prc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84207B0E7BA6A600F5680E /* prc.cpp */; };
- DFF959D20FB22D5700A3EC78 /* rel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84207D0E7BA6A600F5680E /* rel.cpp */; };
- DFF959D30FB22D5700A3EC78 /* script_fw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420800E7BA6A600F5680E /* script_fw.cpp */; };
- DFF959D40FB22D5700A3EC78 /* script_os.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420810E7BA6A600F5680E /* script_os.cpp */; };
- DFF959D50FB22D5700A3EC78 /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420820E7BA6A600F5680E /* sound.cpp */; };
- DFF959D60FB22D5700A3EC78 /* texte.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420840E7BA6A600F5680E /* texte.cpp */; };
- DFF959D70FB22D5700A3EC78 /* unpack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420860E7BA6A600F5680E /* unpack.cpp */; };
- DFF959D80FB22D5700A3EC78 /* various.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420880E7BA6A600F5680E /* various.cpp */; };
- DFF959D90FB22D5700A3EC78 /* actor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420AB0E7BA6A600F5680E /* actor.cpp */; };
- DFF959DA0FB22D5700A3EC78 /* background.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420AE0E7BA6A600F5680E /* background.cpp */; };
- DFF959DB0FB22D5700A3EC78 /* backgroundIncrust.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420B10E7BA6A600F5680E /* backgroundIncrust.cpp */; };
- DFF959DC0FB22D5700A3EC78 /* cell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420B40E7BA6A600F5680E /* cell.cpp */; };
- DFF959DD0FB22D5700A3EC78 /* cruise.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420B70E7BA6A600F5680E /* cruise.cpp */; };
- DFF959DE0FB22D5700A3EC78 /* cruise_main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420BA0E7BA6A700F5680E /* cruise_main.cpp */; };
- DFF959DF0FB22D5700A3EC78 /* ctp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420BD0E7BA6A700F5680E /* ctp.cpp */; };
- DFF959E00FB22D5700A3EC78 /* dataLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420C00E7BA6A700F5680E /* dataLoader.cpp */; };
- DFF959E10FB22D5700A3EC78 /* decompiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420C30E7BA6A700F5680E /* decompiler.cpp */; };
- DFF959E20FB22D5700A3EC78 /* delphine-unpack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420C50E7BA6A700F5680E /* delphine-unpack.cpp */; };
- DFF959E30FB22D5700A3EC78 /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420C70E7BA6A700F5680E /* detection.cpp */; };
- DFF959E40FB22D5700A3EC78 /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420C90E7BA6A700F5680E /* font.cpp */; };
- DFF959E50FB22D5700A3EC78 /* function.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420CF0E7BA6A700F5680E /* function.cpp */; };
- DFF959E60FB22D5700A3EC78 /* gfxModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420D20E7BA6A700F5680E /* gfxModule.cpp */; };
- DFF959E70FB22D5700A3EC78 /* linker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420D60E7BA6A700F5680E /* linker.cpp */; };
- DFF959E80FB22D5700A3EC78 /* mainDraw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420D90E7BA6A700F5680E /* mainDraw.cpp */; };
- DFF959E90FB22D5700A3EC78 /* menu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420DC0E7BA6A700F5680E /* menu.cpp */; };
- DFF959EA0FB22D5700A3EC78 /* mouse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420E00E7BA6A700F5680E /* mouse.cpp */; };
- DFF959EB0FB22D5700A3EC78 /* object.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420E30E7BA6A700F5680E /* object.cpp */; };
- DFF959EC0FB22D5700A3EC78 /* overlay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420E60E7BA6A700F5680E /* overlay.cpp */; };
- DFF959ED0FB22D5700A3EC78 /* perso.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420E90E7BA6A700F5680E /* perso.cpp */; };
- DFF959EE0FB22D5700A3EC78 /* polys.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420EC0E7BA6A700F5680E /* polys.cpp */; };
- DFF959EF0FB22D5700A3EC78 /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420EF0E7BA6A700F5680E /* saveload.cpp */; };
- DFF959F00FB22D5700A3EC78 /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420F20E7BA6A700F5680E /* script.cpp */; };
- DFF959F10FB22D5700A3EC78 /* stack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420F50E7BA6A700F5680E /* stack.cpp */; };
- DFF959F20FB22D5700A3EC78 /* various.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420F90E7BA6A700F5680E /* various.cpp */; };
- DFF959F30FB22D5700A3EC78 /* vars.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420FC0E7BA6A700F5680E /* vars.cpp */; };
- DFF959F40FB22D5700A3EC78 /* volume.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8420FF0E7BA6A700F5680E /* volume.cpp */; };
- DFF959F50FB22D5700A3EC78 /* dialogs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421020E7BA6A700F5680E /* dialogs.cpp */; };
- DFF959F60FB22D5700A3EC78 /* actors.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421050E7BA6A700F5680E /* actors.cpp */; };
- DFF959F70FB22D5700A3EC78 /* animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421060E7BA6A700F5680E /* animation.cpp */; };
- DFF959F80FB22D5700A3EC78 /* converse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421070E7BA6A700F5680E /* converse.cpp */; };
- DFF959F90FB22D5700A3EC78 /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421080E7BA6A700F5680E /* detection.cpp */; };
- DFF959FA0FB22D5700A3EC78 /* drascula.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421090E7BA6A700F5680E /* drascula.cpp */; };
- DFF959FB0FB22D5700A3EC78 /* graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84210B0E7BA6A700F5680E /* graphics.cpp */; };
- DFF959FC0FB22D5700A3EC78 /* interface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84210C0E7BA6A700F5680E /* interface.cpp */; };
- DFF959FD0FB22D5700A3EC78 /* objects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84210E0E7BA6A700F5680E /* objects.cpp */; };
- DFF959FE0FB22D5700A3EC78 /* palette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84210F0E7BA6A700F5680E /* palette.cpp */; };
- DFF959FF0FB22D5700A3EC78 /* rooms.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421100E7BA6A700F5680E /* rooms.cpp */; };
- DFF95A000FB22D5700A3EC78 /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421110E7BA6A700F5680E /* saveload.cpp */; };
- DFF95A010FB22D5700A3EC78 /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421120E7BA6A700F5680E /* sound.cpp */; };
- DFF95A020FB22D5700A3EC78 /* talk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421130E7BA6A700F5680E /* talk.cpp */; };
- DFF95A030FB22D5700A3EC78 /* engine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421140E7BA6A700F5680E /* engine.cpp */; };
- DFF95A050FB22D5700A3EC78 /* dataio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84211B0E7BA6A700F5680E /* dataio.cpp */; };
- DFF95A060FB22D5700A3EC78 /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84211D0E7BA6A700F5680E /* detection.cpp */; };
- DFF95A070FB22D5700A3EC78 /* draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84211E0E7BA6A700F5680E /* draw.cpp */; };
- DFF95A080FB22D5700A3EC78 /* draw_bargon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421200E7BA6A700F5680E /* draw_bargon.cpp */; };
- DFF95A090FB22D5700A3EC78 /* draw_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421210E7BA6A700F5680E /* draw_v1.cpp */; };
- DFF95A0A0FB22D5700A3EC78 /* draw_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421220E7BA6A700F5680E /* draw_v2.cpp */; };
- DFF95A0C0FB22D5700A3EC78 /* game.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421250E7BA6A700F5680E /* game.cpp */; };
- DFF95A0F0FB22D5700A3EC78 /* global.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421290E7BA6A700F5680E /* global.cpp */; };
- DFF95A100FB22D5700A3EC78 /* gob.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84212B0E7BA6A700F5680E /* gob.cpp */; };
- DFF95A110FB22D5700A3EC78 /* goblin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84212D0E7BA6A700F5680E /* goblin.cpp */; };
- DFF95A120FB22D5700A3EC78 /* goblin_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84212F0E7BA6A700F5680E /* goblin_v1.cpp */; };
- DFF95A130FB22D5700A3EC78 /* goblin_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421300E7BA6A700F5680E /* goblin_v2.cpp */; };
- DFF95A140FB22D5700A3EC78 /* goblin_v3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421310E7BA6A700F5680E /* goblin_v3.cpp */; };
- DFF95A150FB22D5700A3EC78 /* goblin_v4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421320E7BA6A700F5680E /* goblin_v4.cpp */; };
- DFF95A160FB22D5700A3EC78 /* init.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421330E7BA6A700F5680E /* init.cpp */; };
- DFF95A170FB22D5700A3EC78 /* init_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421350E7BA6A700F5680E /* init_v1.cpp */; };
- DFF95A180FB22D5700A3EC78 /* init_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421360E7BA6A700F5680E /* init_v2.cpp */; };
- DFF95A190FB22D5700A3EC78 /* init_v3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421370E7BA6A700F5680E /* init_v3.cpp */; };
- DFF95A1A0FB22D5700A3EC78 /* inter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421380E7BA6A700F5680E /* inter.cpp */; };
- DFF95A1B0FB22D5700A3EC78 /* inter_bargon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84213A0E7BA6A700F5680E /* inter_bargon.cpp */; };
- DFF95A1C0FB22D5700A3EC78 /* inter_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84213B0E7BA6A700F5680E /* inter_v1.cpp */; };
- DFF95A1D0FB22D5700A3EC78 /* inter_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84213C0E7BA6A700F5680E /* inter_v2.cpp */; };
- DFF95A1E0FB22D5700A3EC78 /* inter_v3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84213D0E7BA6A700F5680E /* inter_v3.cpp */; };
- DFF95A1F0FB22D5700A3EC78 /* inter_v4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84213E0E7BA6A700F5680E /* inter_v4.cpp */; };
- DFF95A200FB22D5700A3EC78 /* inter_v5.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84213F0E7BA6A700F5680E /* inter_v5.cpp */; };
- DFF95A210FB22D5700A3EC78 /* inter_v6.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421400E7BA6A700F5680E /* inter_v6.cpp */; };
- DFF95A220FB22D5700A3EC78 /* map.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421410E7BA6A700F5680E /* map.cpp */; };
- DFF95A230FB22D5700A3EC78 /* map_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421430E7BA6A700F5680E /* map_v1.cpp */; };
- DFF95A240FB22D5700A3EC78 /* map_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421440E7BA6A700F5680E /* map_v2.cpp */; };
- DFF95A260FB22D5700A3EC78 /* mult.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421470E7BA6A700F5680E /* mult.cpp */; };
- DFF95A270FB22D5700A3EC78 /* mult_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421490E7BA6A700F5680E /* mult_v1.cpp */; };
- DFF95A280FB22D5700A3EC78 /* mult_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84214A0E7BA6A700F5680E /* mult_v2.cpp */; };
- DFF95A290FB22D5700A3EC78 /* palanim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84214C0E7BA6A700F5680E /* palanim.cpp */; };
- DFF95A310FB22D5700A3EC78 /* scenery.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421570E7BA6A700F5680E /* scenery.cpp */; };
- DFF95A320FB22D5700A3EC78 /* scenery_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421590E7BA6A700F5680E /* scenery_v1.cpp */; };
- DFF95A330FB22D5700A3EC78 /* scenery_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84215A0E7BA6A700F5680E /* scenery_v2.cpp */; };
- DFF95A340FB22D5700A3EC78 /* adlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84215C0E7BA6A700F5680E /* adlib.cpp */; };
- DFF95A350FB22D5700A3EC78 /* bgatmosphere.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84215E0E7BA6A700F5680E /* bgatmosphere.cpp */; };
- DFF95A360FB22D5700A3EC78 /* cdrom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421600E7BA6A700F5680E /* cdrom.cpp */; };
- DFF95A370FB22D5700A3EC78 /* infogrames.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421620E7BA6A700F5680E /* infogrames.cpp */; };
- DFF95A380FB22D5700A3EC78 /* pcspeaker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421640E7BA6A700F5680E /* pcspeaker.cpp */; };
- DFF95A390FB22D5700A3EC78 /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421660E7BA6A700F5680E /* sound.cpp */; };
- DFF95A3A0FB22D5700A3EC78 /* soundblaster.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421680E7BA6A700F5680E /* soundblaster.cpp */; };
- DFF95A3B0FB22D5700A3EC78 /* sounddesc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84216A0E7BA6A700F5680E /* sounddesc.cpp */; };
- DFF95A3C0FB22D5700A3EC78 /* soundmixer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84216C0E7BA6A700F5680E /* soundmixer.cpp */; };
- DFF95A3D0FB22D5700A3EC78 /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84216F0E7BA6A700F5680E /* util.cpp */; };
- DFF95A3E0FB22D5700A3EC78 /* variables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421710E7BA6A700F5680E /* variables.cpp */; };
- DFF95A3F0FB22D5700A3EC78 /* video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421730E7BA6A700F5680E /* video.cpp */; };
- DFF95A400FB22D5700A3EC78 /* video_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421750E7BA6A700F5680E /* video_v1.cpp */; };
- DFF95A410FB22D5700A3EC78 /* video_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421760E7BA6A700F5680E /* video_v2.cpp */; };
- DFF95A420FB22D5700A3EC78 /* video_v6.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421770E7BA6A700F5680E /* video_v6.cpp */; };
- DFF95A430FB22D5700A3EC78 /* videoplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421780E7BA6A700F5680E /* videoplayer.cpp */; };
- DFF95A670FB22D5700A3EC78 /* animator_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421A40E7BA6A800F5680E /* animator_hof.cpp */; };
- DFF95A680FB22D5700A3EC78 /* animator_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421A50E7BA6A800F5680E /* animator_lok.cpp */; };
- DFF95A690FB22D5700A3EC78 /* animator_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421A70E7BA6A800F5680E /* animator_mr.cpp */; };
- DFF95A6A0FB22D5700A3EC78 /* animator_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421A90E7BA6A800F5680E /* animator_v2.cpp */; };
- DFF95A6B0FB22D5700A3EC78 /* debugger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421AB0E7BA6A800F5680E /* debugger.cpp */; };
- DFF95A6C0FB22D5700A3EC78 /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421AD0E7BA6A800F5680E /* detection.cpp */; };
- DFF95A6D0FB22D5700A3EC78 /* gui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421AE0E7BA6A800F5680E /* gui.cpp */; };
- DFF95A6E0FB22D5700A3EC78 /* gui_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421B00E7BA6A800F5680E /* gui_hof.cpp */; };
- DFF95A6F0FB22D5700A3EC78 /* gui_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421B20E7BA6A800F5680E /* gui_lok.cpp */; };
- DFF95A700FB22D5700A3EC78 /* gui_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421B40E7BA6A800F5680E /* gui_mr.cpp */; };
- DFF95A710FB22D5700A3EC78 /* gui_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421B70E7BA6A800F5680E /* gui_v2.cpp */; };
- DFF95A720FB22D5700A3EC78 /* items_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421BA0E7BA6A800F5680E /* items_hof.cpp */; };
- DFF95A730FB22D5700A3EC78 /* items_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421BB0E7BA6A800F5680E /* items_lok.cpp */; };
- DFF95A740FB22D5700A3EC78 /* items_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421BC0E7BA6A800F5680E /* items_mr.cpp */; };
- DFF95A750FB22D5700A3EC78 /* items_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421BE0E7BA6A800F5680E /* items_v2.cpp */; };
- DFF95A760FB22D5700A3EC78 /* kyra_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421C10E7BA6A800F5680E /* kyra_hof.cpp */; };
- DFF95A770FB22D5700A3EC78 /* kyra_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421C30E7BA6A800F5680E /* kyra_lok.cpp */; };
- DFF95A780FB22D5700A3EC78 /* kyra_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421C50E7BA6A800F5680E /* kyra_mr.cpp */; };
- DFF95A790FB22D5700A3EC78 /* kyra_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421C70E7BA6A800F5680E /* kyra_v1.cpp */; };
- DFF95A7A0FB22D5700A3EC78 /* kyra_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421C90E7BA6A800F5680E /* kyra_v2.cpp */; };
- DFF95A7B0FB22D5700A3EC78 /* lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421CC0E7BA6A800F5680E /* lol.cpp */; };
- DFF95A7C0FB22D5700A3EC78 /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421CF0E7BA6A800F5680E /* resource.cpp */; };
- DFF95A7D0FB22D5700A3EC78 /* resource_intern.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421D10E7BA6A800F5680E /* resource_intern.cpp */; };
- DFF95A7E0FB22D5700A3EC78 /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421D30E7BA6A800F5680E /* saveload.cpp */; };
- DFF95A7F0FB22D5700A3EC78 /* saveload_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421D40E7BA6A800F5680E /* saveload_hof.cpp */; };
- DFF95A800FB22D5700A3EC78 /* saveload_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421D50E7BA6A800F5680E /* saveload_lok.cpp */; };
- DFF95A810FB22D5700A3EC78 /* saveload_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421D60E7BA6A800F5680E /* saveload_mr.cpp */; };
- DFF95A820FB22D5700A3EC78 /* scene_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421DA0E7BA6A800F5680E /* scene_hof.cpp */; };
- DFF95A830FB22D5700A3EC78 /* scene_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421DB0E7BA6A800F5680E /* scene_lok.cpp */; };
- DFF95A840FB22D5700A3EC78 /* scene_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421DC0E7BA6A800F5680E /* scene_mr.cpp */; };
- DFF95A850FB22D5700A3EC78 /* scene_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421DD0E7BA6A800F5680E /* scene_v1.cpp */; };
- DFF95A860FB22D5700A3EC78 /* scene_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421DE0E7BA6A800F5680E /* scene_v2.cpp */; };
- DFF95A870FB22D5700A3EC78 /* screen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421E00E7BA6A800F5680E /* screen.cpp */; };
- DFF95A880FB22D5700A3EC78 /* screen_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421E20E7BA6A800F5680E /* screen_hof.cpp */; };
- DFF95A890FB22D5700A3EC78 /* screen_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421E40E7BA6A800F5680E /* screen_lok.cpp */; };
- DFF95A8A0FB22D5700A3EC78 /* screen_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421E60E7BA6A800F5680E /* screen_lol.cpp */; };
- DFF95A8B0FB22D5700A3EC78 /* screen_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421E80E7BA6A800F5680E /* screen_mr.cpp */; };
- DFF95A8C0FB22D5700A3EC78 /* screen_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421EB0E7BA6A800F5680E /* screen_v2.cpp */; };
- DFF95A8D0FB22D5700A3EC78 /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421EE0E7BA6A800F5680E /* script.cpp */; };
- DFF95A8E0FB22D5700A3EC78 /* script_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421F00E7BA6A800F5680E /* script_hof.cpp */; };
- DFF95A8F0FB22D5700A3EC78 /* script_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421F10E7BA6A800F5680E /* script_lok.cpp */; };
- DFF95A900FB22D5700A3EC78 /* script_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421F20E7BA6A800F5680E /* script_mr.cpp */; };
- DFF95A910FB22D5700A3EC78 /* script_tim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421F30E7BA6A800F5680E /* script_tim.cpp */; };
- DFF95A920FB22D5700A3EC78 /* script_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421F50E7BA6A800F5680E /* script_v1.cpp */; };
- DFF95A930FB22D5700A3EC78 /* script_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421F60E7BA6A800F5680E /* script_v2.cpp */; };
- DFF95A940FB22D5700A3EC78 /* seqplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421F80E7BA6A800F5680E /* seqplayer.cpp */; };
- DFF95A950FB22D5700A3EC78 /* sequences_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421FA0E7BA6A800F5680E /* sequences_hof.cpp */; };
- DFF95A960FB22D5700A3EC78 /* sequences_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421FB0E7BA6A800F5680E /* sequences_lok.cpp */; };
- DFF95A970FB22D5700A3EC78 /* sequences_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421FC0E7BA6A800F5680E /* sequences_mr.cpp */; };
- DFF95A980FB22D5700A3EC78 /* sequences_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8421FE0E7BA6A800F5680E /* sequences_v2.cpp */; };
- DFF95A990FB22D5700A3EC78 /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422000E7BA6A800F5680E /* sound.cpp */; };
- DFF95A9A0FB22D5700A3EC78 /* sound_adlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422020E7BA6A800F5680E /* sound_adlib.cpp */; };
- DFF95A9B0FB22D5700A3EC78 /* sound_digital.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422030E7BA6A800F5680E /* sound_digital.cpp */; };
- DFF95A9C0FB22D5700A3EC78 /* sound_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422040E7BA6A800F5680E /* sound_lok.cpp */; };
- DFF95A9D0FB22D5700A3EC78 /* sound_towns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422050E7BA6A800F5680E /* sound_towns.cpp */; };
- DFF95A9E0FB22D5700A3EC78 /* sprites.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422070E7BA6A800F5680E /* sprites.cpp */; };
- DFF95A9F0FB22D5700A3EC78 /* staticres.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422090E7BA6A800F5680E /* staticres.cpp */; };
- DFF95AA00FB22D5700A3EC78 /* text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84220A0E7BA6A800F5680E /* text.cpp */; };
- DFF95AA10FB22D5700A3EC78 /* text_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84220C0E7BA6A800F5680E /* text_hof.cpp */; };
- DFF95AA20FB22D5700A3EC78 /* text_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84220E0E7BA6A800F5680E /* text_lok.cpp */; };
- DFF95AA30FB22D5700A3EC78 /* text_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84220F0E7BA6A800F5680E /* text_mr.cpp */; };
- DFF95AA40FB22D5700A3EC78 /* timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422140E7BA6A800F5680E /* timer.cpp */; };
- DFF95AA50FB22D5700A3EC78 /* timer_hof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422160E7BA6A800F5680E /* timer_hof.cpp */; };
- DFF95AA60FB22D5700A3EC78 /* timer_lok.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422170E7BA6A800F5680E /* timer_lok.cpp */; };
- DFF95AA70FB22D5700A3EC78 /* timer_mr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422180E7BA6A800F5680E /* timer_mr.cpp */; };
- DFF95AA80FB22D5700A3EC78 /* vqa.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84221C0E7BA6A800F5680E /* vqa.cpp */; };
- DFF95AA90FB22D5700A3EC78 /* wsamovie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84221E0E7BA6A800F5680E /* wsamovie.cpp */; };
- DFF95AAA0FB22D5700A3EC78 /* animseq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422210E7BA6A800F5680E /* animseq.cpp */; };
- DFF95AAB0FB22D5700A3EC78 /* debugger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422230E7BA6A800F5680E /* debugger.cpp */; };
- DFF95AAC0FB22D5700A3EC78 /* decode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422250E7BA6A800F5680E /* decode.cpp */; };
- DFF95AAD0FB22D5700A3EC78 /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422270E7BA6A800F5680E /* detection.cpp */; };
- DFF95AAE0FB22D5700A3EC78 /* disk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422280E7BA6A800F5680E /* disk.cpp */; };
- DFF95AAF0FB22D5700A3EC78 /* events.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84222A0E7BA6A800F5680E /* events.cpp */; };
- DFF95AB00FB22D5700A3EC78 /* fights.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84222C0E7BA6A800F5680E /* fights.cpp */; };
- DFF95AB10FB22D5700A3EC78 /* game.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84222E0E7BA6A800F5680E /* game.cpp */; };
- DFF95AB20FB22D5700A3EC78 /* hotspots.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422300E7BA6A800F5680E /* hotspots.cpp */; };
- DFF95AB30FB22D5700A3EC78 /* intro.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422320E7BA6A800F5680E /* intro.cpp */; };
- DFF95AB40FB22D5700A3EC78 /* lure.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422340E7BA6A800F5680E /* lure.cpp */; };
- DFF95AB50FB22D5700A3EC78 /* memory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422370E7BA6A800F5680E /* memory.cpp */; };
- DFF95AB60FB22D5700A3EC78 /* menu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422390E7BA6A800F5680E /* menu.cpp */; };
- DFF95AB70FB22D5700A3EC78 /* palette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84223C0E7BA6A800F5680E /* palette.cpp */; };
- DFF95AB80FB22D5700A3EC78 /* res.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84223E0E7BA6A800F5680E /* res.cpp */; };
- DFF95AB90FB22D5700A3EC78 /* res_struct.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422400E7BA6A800F5680E /* res_struct.cpp */; };
- DFF95ABA0FB22D5700A3EC78 /* room.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422420E7BA6A800F5680E /* room.cpp */; };
- DFF95ABB0FB22D5700A3EC78 /* screen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422440E7BA6A800F5680E /* screen.cpp */; };
- DFF95ABC0FB22D5700A3EC78 /* scripts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422460E7BA6A800F5680E /* scripts.cpp */; };
- DFF95ABD0FB22D5700A3EC78 /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422480E7BA6A800F5680E /* sound.cpp */; };
- DFF95ABE0FB22D5700A3EC78 /* strings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84224A0E7BA6A800F5680E /* strings.cpp */; };
- DFF95ABF0FB22D5700A3EC78 /* surface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84224C0E7BA6A800F5680E /* surface.cpp */; };
- DFF95AC00FB22D5700A3EC78 /* actor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84226E0E7BA6A800F5680E /* actor.cpp */; };
- DFF95AC10FB22D5700A3EC78 /* animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422710E7BA6A800F5680E /* animation.cpp */; };
- DFF95AC20FB22D5700A3EC78 /* assets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422740E7BA6A800F5680E /* assets.cpp */; };
- DFF95AC30FB22D5700A3EC78 /* compression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422780E7BA6A900F5680E /* compression.cpp */; };
- DFF95AC40FB22D5700A3EC78 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84227B0E7BA6A900F5680E /* console.cpp */; };
- DFF95AC50FB22D5700A3EC78 /* converse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84227E0E7BA6A900F5680E /* converse.cpp */; };
- DFF95AC60FB22D5700A3EC78 /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422810E7BA6A900F5680E /* detection.cpp */; };
- DFF95AC70FB22D5700A3EC78 /* events.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422830E7BA6A900F5680E /* events.cpp */; };
- DFF95AC80FB22D5700A3EC78 /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422860E7BA6A900F5680E /* font.cpp */; };
- DFF95AC90FB22D5700A3EC78 /* globals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422890E7BA6A900F5680E /* globals.cpp */; };
- DFF95ACA0FB22D5700A3EC78 /* graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84228C0E7BA6A900F5680E /* graphics.cpp */; };
- DFF95ACB0FB22D5700A3EC78 /* gui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84228F0E7BA6A900F5680E /* gui.cpp */; };
- DFF95ACC0FB22D5700A3EC78 /* hotspot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422920E7BA6A900F5680E /* hotspot.cpp */; };
- DFF95ACD0FB22D5700A3EC78 /* m4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422960E7BA6A900F5680E /* m4.cpp */; };
- DFF95ACE0FB22D5700A3EC78 /* m4_menus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422990E7BA6A900F5680E /* m4_menus.cpp */; };
- DFF95ACF0FB22D5700A3EC78 /* m4_views.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84229C0E7BA6A900F5680E /* m4_views.cpp */; };
- DFF95AD00FB22D5700A3EC78 /* mads_anim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84229F0E7BA6A900F5680E /* mads_anim.cpp */; };
- DFF95AD10FB22D5700A3EC78 /* mads_menus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422A20E7BA6A900F5680E /* mads_menus.cpp */; };
- DFF95AD20FB22D5700A3EC78 /* midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422A50E7BA6A900F5680E /* midi.cpp */; };
- DFF95AD30FB22D5700A3EC78 /* rails.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422A90E7BA6A900F5680E /* rails.cpp */; };
- DFF95AD40FB22D5700A3EC78 /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422AC0E7BA6A900F5680E /* resource.cpp */; };
- DFF95AD50FB22D5700A3EC78 /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422AF0E7BA6A900F5680E /* saveload.cpp */; };
- DFF95AD60FB22D5700A3EC78 /* scene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422B20E7BA6A900F5680E /* scene.cpp */; };
- DFF95AD70FB22D5700A3EC78 /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422B50E7BA6A900F5680E /* script.cpp */; };
- DFF95AD80FB22D5700A3EC78 /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422B90E7BA6A900F5680E /* sound.cpp */; };
- DFF95AD90FB22D5700A3EC78 /* sprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422BC0E7BA6A900F5680E /* sprite.cpp */; };
- DFF95ADA0FB22D5700A3EC78 /* viewmgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422BF0E7BA6A900F5680E /* viewmgr.cpp */; };
- DFF95ADB0FB22D5700A3EC78 /* woodscript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422C20E7BA6A900F5680E /* woodscript.cpp */; };
- DFF95ADC0FB22D5700A3EC78 /* ws_machine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422C50E7BA6A900F5680E /* ws_machine.cpp */; };
- DFF95ADD0FB22D5700A3EC78 /* ws_sequence.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422C70E7BA6A900F5680E /* ws_sequence.cpp */; };
- DFF95ADE0FB22D5700A3EC78 /* database.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422CA0E7BA6A900F5680E /* database.cpp */; };
- DFF95ADF0FB22D5700A3EC78 /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422CC0E7BA6A900F5680E /* detection.cpp */; };
- DFF95AE00FB22D5700A3EC78 /* graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422CD0E7BA6A900F5680E /* graphics.cpp */; };
- DFF95AE10FB22D5700A3EC78 /* made.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422CF0E7BA6A900F5680E /* made.cpp */; };
- DFF95AE20FB22D5700A3EC78 /* music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422D20E7BA6A900F5680E /* music.cpp */; };
- DFF95AE30FB22D5700A3EC78 /* pmvplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422D40E7BA6A900F5680E /* pmvplayer.cpp */; };
- DFF95AE40FB22D5700A3EC78 /* redreader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422D60E7BA6A900F5680E /* redreader.cpp */; };
- DFF95AE50FB22D5700A3EC78 /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422D80E7BA6A900F5680E /* resource.cpp */; };
- DFF95AE60FB22D5700A3EC78 /* screen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422DA0E7BA6A900F5680E /* screen.cpp */; };
- DFF95AE70FB22D5700A3EC78 /* screenfx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422DC0E7BA6A900F5680E /* screenfx.cpp */; };
- DFF95AE80FB22D5700A3EC78 /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422DE0E7BA6A900F5680E /* script.cpp */; };
- DFF95AE90FB22D5700A3EC78 /* scriptfuncs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422E00E7BA6A900F5680E /* scriptfuncs.cpp */; };
- DFF95AEA0FB22D5700A3EC78 /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422E20E7BA6A900F5680E /* sound.cpp */; };
- DFF95AEB0FB22D5700A3EC78 /* balloons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422E70E7BA6A900F5680E /* balloons.cpp */; };
- DFF95AEC0FB22D5700A3EC78 /* callables_br.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422E80E7BA6A900F5680E /* callables_br.cpp */; };
- DFF95AED0FB22D5700A3EC78 /* callables_ns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422E90E7BA6A900F5680E /* callables_ns.cpp */; };
- DFF95AEE0FB22D5700A3EC78 /* debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422EA0E7BA6A900F5680E /* debug.cpp */; };
- DFF95AEF0FB22D5700A3EC78 /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422EC0E7BA6A900F5680E /* detection.cpp */; };
- DFF95AF00FB22D5700A3EC78 /* dialogue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422ED0E7BA6A900F5680E /* dialogue.cpp */; };
- DFF95AF10FB22D5700A3EC78 /* disk_br.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422EF0E7BA6A900F5680E /* disk_br.cpp */; };
- DFF95AF20FB22D5700A3EC78 /* disk_ns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422F00E7BA6A900F5680E /* disk_ns.cpp */; };
- DFF95AF30FB22D5700A3EC78 /* exec_br.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422F20E7BA6A900F5680E /* exec_br.cpp */; };
- DFF95AF40FB22D5700A3EC78 /* exec_ns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422F30E7BA6A900F5680E /* exec_ns.cpp */; };
- DFF95AF50FB22D5700A3EC78 /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422F40E7BA6A900F5680E /* font.cpp */; };
- DFF95AF60FB22D5700A3EC78 /* gfxbase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422F50E7BA6A900F5680E /* gfxbase.cpp */; };
- DFF95AF70FB22D5700A3EC78 /* graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422F60E7BA6A900F5680E /* graphics.cpp */; };
- DFF95AF80FB22D5700A3EC78 /* gui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422F80E7BA6A900F5680E /* gui.cpp */; };
- DFF95AF90FB22D5700A3EC78 /* gui_br.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422FA0E7BA6A900F5680E /* gui_br.cpp */; };
- DFF95AFA0FB22D5700A3EC78 /* gui_ns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422FB0E7BA6A900F5680E /* gui_ns.cpp */; };
- DFF95AFB0FB22D5700A3EC78 /* input.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422FC0E7BA6A900F5680E /* input.cpp */; };
- DFF95AFC0FB22D5700A3EC78 /* inventory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8422FE0E7BA6A900F5680E /* inventory.cpp */; };
- DFF95AFD0FB22D5700A3EC78 /* objects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423010E7BA6A900F5680E /* objects.cpp */; };
- DFF95AFE0FB22D5700A3EC78 /* parallaction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423030E7BA6A900F5680E /* parallaction.cpp */; };
- DFF95AFF0FB22D5700A3EC78 /* parallaction_br.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423050E7BA6A900F5680E /* parallaction_br.cpp */; };
- DFF95B000FB22D5700A3EC78 /* parallaction_ns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423060E7BA6A900F5680E /* parallaction_ns.cpp */; };
- DFF95B010FB22D5700A3EC78 /* parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423070E7BA6A900F5680E /* parser.cpp */; };
- DFF95B020FB22D5700A3EC78 /* parser_br.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423090E7BA6A900F5680E /* parser_br.cpp */; };
- DFF95B030FB22D5700A3EC78 /* parser_ns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84230A0E7BA6A900F5680E /* parser_ns.cpp */; };
- DFF95B040FB22D5700A3EC78 /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84230B0E7BA6A900F5680E /* saveload.cpp */; };
- DFF95B050FB22D5700A3EC78 /* staticres.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84230F0E7BA6A900F5680E /* staticres.cpp */; };
- DFF95B060FB22D5700A3EC78 /* walk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423100E7BA6A900F5680E /* walk.cpp */; };
- DFF95B070FB22D5700A3EC78 /* bankman.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423130E7BA6A900F5680E /* bankman.cpp */; };
- DFF95B080FB22D5700A3EC78 /* command.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423150E7BA6A900F5680E /* command.cpp */; };
- DFF95B090FB22D5700A3EC78 /* credits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423170E7BA6A900F5680E /* credits.cpp */; };
- DFF95B0A0FB22D5700A3EC78 /* cutaway.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423190E7BA6A900F5680E /* cutaway.cpp */; };
- DFF95B0B0FB22D5700A3EC78 /* debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84231B0E7BA6A900F5680E /* debug.cpp */; };
- DFF95B0C0FB22D5700A3EC78 /* display.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84231E0E7BA6A900F5680E /* display.cpp */; };
- DFF95B0D0FB22D5700A3EC78 /* graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423200E7BA6A900F5680E /* graphics.cpp */; };
- DFF95B0E0FB22D5700A3EC78 /* grid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423220E7BA6A900F5680E /* grid.cpp */; };
- DFF95B0F0FB22D5700A3EC78 /* input.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423240E7BA6A900F5680E /* input.cpp */; };
- DFF95B100FB22D5700A3EC78 /* journal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423260E7BA6A900F5680E /* journal.cpp */; };
- DFF95B110FB22D5700A3EC78 /* logic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423280E7BA6A900F5680E /* logic.cpp */; };
- DFF95B120FB22D5700A3EC78 /* midiadlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84232A0E7BA6A900F5680E /* midiadlib.cpp */; };
- DFF95B130FB22D5700A3EC78 /* music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84232C0E7BA6A900F5680E /* music.cpp */; };
- DFF95B140FB22D5700A3EC78 /* musicdata.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84232E0E7BA6A900F5680E /* musicdata.cpp */; };
- DFF95B150FB22D5700A3EC78 /* queen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84232F0E7BA6A900F5680E /* queen.cpp */; };
- DFF95B160FB22D5700A3EC78 /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423310E7BA6A900F5680E /* resource.cpp */; };
- DFF95B170FB22D5700A3EC78 /* restables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423330E7BA6A900F5680E /* restables.cpp */; };
- DFF95B180FB22D5700A3EC78 /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423340E7BA6A900F5680E /* sound.cpp */; };
- DFF95B190FB22D5700A3EC78 /* state.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423360E7BA6A900F5680E /* state.cpp */; };
- DFF95B1A0FB22D5700A3EC78 /* talk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423390E7BA6A900F5680E /* talk.cpp */; };
- DFF95B1B0FB22D5700A3EC78 /* walk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84233B0E7BA6A900F5680E /* walk.cpp */; };
- DFF95B1C0FB22D5700A3EC78 /* actor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84233F0E7BA6AA00F5680E /* actor.cpp */; };
- DFF95B1D0FB22D5700A3EC78 /* actor_path.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423410E7BA6AA00F5680E /* actor_path.cpp */; };
- DFF95B1E0FB22D5700A3EC78 /* actor_walk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423420E7BA6AA00F5680E /* actor_walk.cpp */; };
- DFF95B1F0FB22D5700A3EC78 /* animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423430E7BA6AA00F5680E /* animation.cpp */; };
- DFF95B200FB22D5700A3EC78 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423450E7BA6AA00F5680E /* console.cpp */; };
- DFF95B210FB22D5700A3EC78 /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423470E7BA6AA00F5680E /* detection.cpp */; };
- DFF95B220FB22D5700A3EC78 /* events.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84234A0E7BA6AA00F5680E /* events.cpp */; };
- DFF95B230FB22D5700A3EC78 /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84234C0E7BA6AA00F5680E /* font.cpp */; };
- DFF95B240FB22D5700A3EC78 /* font_map.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84234E0E7BA6AA00F5680E /* font_map.cpp */; };
- DFF95B250FB22D5700A3EC78 /* gfx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84234F0E7BA6AA00F5680E /* gfx.cpp */; };
- DFF95B260FB22D5700A3EC78 /* image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423520E7BA6AA00F5680E /* image.cpp */; };
- DFF95B270FB22D5700A3EC78 /* input.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423530E7BA6AA00F5680E /* input.cpp */; };
- DFF95B280FB22D5700A3EC78 /* interface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423540E7BA6AA00F5680E /* interface.cpp */; };
- DFF95B290FB22D5700A3EC78 /* introproc_ihnm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423560E7BA6AA00F5680E /* introproc_ihnm.cpp */; };
- DFF95B2A0FB22D5700A3EC78 /* introproc_ite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423570E7BA6AA00F5680E /* introproc_ite.cpp */; };
- DFF95B2B0FB22D5700A3EC78 /* isomap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423580E7BA6AA00F5680E /* isomap.cpp */; };
- DFF95B2C0FB22D5700A3EC78 /* itedata.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84235B0E7BA6AA00F5680E /* itedata.cpp */; };
- DFF95B2D0FB22D5700A3EC78 /* music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84235F0E7BA6AA00F5680E /* music.cpp */; };
- DFF95B2E0FB22D5700A3EC78 /* objectmap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423610E7BA6AA00F5680E /* objectmap.cpp */; };
- DFF95B2F0FB22D5700A3EC78 /* palanim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423630E7BA6AA00F5680E /* palanim.cpp */; };
- DFF95B300FB22D5700A3EC78 /* puzzle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423650E7BA6AA00F5680E /* puzzle.cpp */; };
- DFF95B310FB22D5700A3EC78 /* render.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423670E7BA6AA00F5680E /* render.cpp */; };
- DFF95B320FB22D5700A3EC78 /* saga.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84236B0E7BA6AA00F5680E /* saga.cpp */; };
- DFF95B330FB22D5700A3EC78 /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84236D0E7BA6AA00F5680E /* saveload.cpp */; };
- DFF95B340FB22D5700A3EC78 /* scene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84236E0E7BA6AA00F5680E /* scene.cpp */; };
- DFF95B350FB22D5700A3EC78 /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423700E7BA6AA00F5680E /* script.cpp */; };
- DFF95B360FB22D5700A3EC78 /* sfuncs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423720E7BA6AA00F5680E /* sfuncs.cpp */; };
- DFF95B370FB22D5700A3EC78 /* sndres.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423730E7BA6AA00F5680E /* sndres.cpp */; };
- DFF95B380FB22D5700A3EC78 /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423750E7BA6AA00F5680E /* sound.cpp */; };
- DFF95B390FB22D5700A3EC78 /* sprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423770E7BA6AA00F5680E /* sprite.cpp */; };
- DFF95B3A0FB22D5700A3EC78 /* sthread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423790E7BA6AA00F5680E /* sthread.cpp */; };
- DFF95B3B0FB22D5700A3EC78 /* actor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84237C0E7BA6AA00F5680E /* actor.cpp */; };
- DFF95B3C0FB22D5700A3EC78 /* akos.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84237E0E7BA6AA00F5680E /* akos.cpp */; };
- DFF95B3D0FB22D5700A3EC78 /* base-costume.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423800E7BA6AA00F5680E /* base-costume.cpp */; };
- DFF95B3E0FB22D5700A3EC78 /* bomp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423820E7BA6AA00F5680E /* bomp.cpp */; };
- DFF95B3F0FB22D5700A3EC78 /* boxes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423840E7BA6AA00F5680E /* boxes.cpp */; };
- DFF95B400FB22D5700A3EC78 /* camera.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423860E7BA6AA00F5680E /* camera.cpp */; };
- DFF95B410FB22D5700A3EC78 /* charset-fontdata.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423870E7BA6AA00F5680E /* charset-fontdata.cpp */; };
- DFF95B420FB22D5700A3EC78 /* charset.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423880E7BA6AA00F5680E /* charset.cpp */; };
- DFF95B430FB22D5700A3EC78 /* costume.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84238A0E7BA6AA00F5680E /* costume.cpp */; };
- DFF95B440FB22D5700A3EC78 /* cursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84238C0E7BA6AA00F5680E /* cursor.cpp */; };
- DFF95B450FB22D5700A3EC78 /* debugger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84238D0E7BA6AA00F5680E /* debugger.cpp */; };
- DFF95B460FB22D5700A3EC78 /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84238F0E7BA6AA00F5680E /* detection.cpp */; };
- DFF95B470FB22D5700A3EC78 /* dialogs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423920E7BA6AA00F5680E /* dialogs.cpp */; };
- DFF95B480FB22D5700A3EC78 /* file.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423940E7BA6AA00F5680E /* file.cpp */; };
- DFF95B490FB22D5700A3EC78 /* file_nes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423960E7BA6AA00F5680E /* file_nes.cpp */; };
- DFF95B4A0FB22D5700A3EC78 /* gfx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423980E7BA6AA00F5680E /* gfx.cpp */; };
- DFF95B4B0FB22D5700A3EC78 /* animation_he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84239C0E7BA6AA00F5680E /* animation_he.cpp */; };
- DFF95B4C0FB22D5700A3EC78 /* cup_player_he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84239E0E7BA6AA00F5680E /* cup_player_he.cpp */; };
- DFF95B4D0FB22D5700A3EC78 /* floodfill_he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423A00E7BA6AA00F5680E /* floodfill_he.cpp */; };
- DFF95B4E0FB22D5700A3EC78 /* logic_he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423A30E7BA6AA00F5680E /* logic_he.cpp */; };
- DFF95B4F0FB22D5700A3EC78 /* palette_he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423A50E7BA6AA00F5680E /* palette_he.cpp */; };
- DFF95B500FB22D5700A3EC78 /* resource_he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423A60E7BA6AA00F5680E /* resource_he.cpp */; };
- DFF95B510FB22D5700A3EC78 /* script_v100he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423A80E7BA6AA00F5680E /* script_v100he.cpp */; };
- DFF95B520FB22D5700A3EC78 /* script_v60he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423A90E7BA6AA00F5680E /* script_v60he.cpp */; };
- DFF95B530FB22D5700A3EC78 /* script_v70he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423AA0E7BA6AA00F5680E /* script_v70he.cpp */; };
- DFF95B540FB22D5700A3EC78 /* script_v71he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423AB0E7BA6AA00F5680E /* script_v71he.cpp */; };
- DFF95B550FB22D5700A3EC78 /* script_v72he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423AC0E7BA6AA00F5680E /* script_v72he.cpp */; };
- DFF95B560FB22D5700A3EC78 /* script_v80he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423AD0E7BA6AA00F5680E /* script_v80he.cpp */; };
- DFF95B570FB22D5700A3EC78 /* script_v90he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423AE0E7BA6AA00F5680E /* script_v90he.cpp */; };
- DFF95B580FB22D5700A3EC78 /* sound_he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423AF0E7BA6AA00F5680E /* sound_he.cpp */; };
- DFF95B590FB22D5700A3EC78 /* sprite_he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423B10E7BA6AA00F5680E /* sprite_he.cpp */; };
- DFF95B5A0FB22D5700A3EC78 /* wiz_he.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423B30E7BA6AA00F5680E /* wiz_he.cpp */; };
- DFF95B5B0FB22D5700A3EC78 /* help.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423B50E7BA6AA00F5680E /* help.cpp */; };
- DFF95B5C0FB22D5700A3EC78 /* imuse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423B80E7BA6AA00F5680E /* imuse.cpp */; };
- DFF95B5D0FB22D5700A3EC78 /* imuse_part.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423BB0E7BA6AA00F5680E /* imuse_part.cpp */; };
- DFF95B5E0FB22D5700A3EC78 /* imuse_player.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423BC0E7BA6AA00F5680E /* imuse_player.cpp */; };
- DFF95B5F0FB22D5700A3EC78 /* instrument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423BD0E7BA6AA00F5680E /* instrument.cpp */; };
- DFF95B600FB22D5700A3EC78 /* sysex_samnmax.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423C00E7BA6AA00F5680E /* sysex_samnmax.cpp */; };
- DFF95B610FB22D5700A3EC78 /* sysex_scumm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423C10E7BA6AA00F5680E /* sysex_scumm.cpp */; };
- DFF95B620FB22D5700A3EC78 /* dimuse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423C30E7BA6AA00F5680E /* dimuse.cpp */; };
- DFF95B630FB22D5700A3EC78 /* dimuse_bndmgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423C50E7BA6AA00F5680E /* dimuse_bndmgr.cpp */; };
- DFF95B640FB22D5700A3EC78 /* dimuse_codecs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423C70E7BA6AA00F5680E /* dimuse_codecs.cpp */; };
- DFF95B650FB22D5700A3EC78 /* dimuse_music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423C80E7BA6AA00F5680E /* dimuse_music.cpp */; };
- DFF95B660FB22D5700A3EC78 /* dimuse_script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423C90E7BA6AA00F5680E /* dimuse_script.cpp */; };
- DFF95B670FB22D5700A3EC78 /* dimuse_sndmgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423CA0E7BA6AA00F5680E /* dimuse_sndmgr.cpp */; };
- DFF95B680FB22D5700A3EC78 /* dimuse_tables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423CC0E7BA6AA00F5680E /* dimuse_tables.cpp */; };
- DFF95B690FB22D5700A3EC78 /* dimuse_track.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423CE0E7BA6AA00F5680E /* dimuse_track.cpp */; };
- DFF95B6A0FB22D5700A3EC78 /* input.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423D00E7BA6AA00F5680E /* input.cpp */; };
- DFF95B6B0FB22D5700A3EC78 /* insane.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423D20E7BA6AA00F5680E /* insane.cpp */; };
- DFF95B6C0FB22D5700A3EC78 /* insane_ben.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423D40E7BA6AA00F5680E /* insane_ben.cpp */; };
- DFF95B6D0FB22D5700A3EC78 /* insane_enemy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423D50E7BA6AA00F5680E /* insane_enemy.cpp */; };
- DFF95B6E0FB22D5700A3EC78 /* insane_iact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423D60E7BA6AA00F5680E /* insane_iact.cpp */; };
- DFF95B6F0FB22D5700A3EC78 /* insane_scenes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423D70E7BA6AA00F5680E /* insane_scenes.cpp */; };
- DFF95B710FB22D5700A3EC78 /* midiparser_ro.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423DA0E7BA6AA00F5680E /* midiparser_ro.cpp */; };
- DFF95B720FB22D5700A3EC78 /* nut_renderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423DD0E7BA6AA00F5680E /* nut_renderer.cpp */; };
- DFF95B730FB22D5700A3EC78 /* object.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423DF0E7BA6AA00F5680E /* object.cpp */; };
- DFF95B740FB22D5700A3EC78 /* palette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423E10E7BA6AA00F5680E /* palette.cpp */; };
- DFF95B750FB22D5700A3EC78 /* player_mod.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423E20E7BA6AA00F5680E /* player_mod.cpp */; };
- DFF95B760FB22D5700A3EC78 /* player_nes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423E40E7BA6AA00F5680E /* player_nes.cpp */; };
- DFF95B770FB22D5700A3EC78 /* player_v1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423E60E7BA6AA00F5680E /* player_v1.cpp */; };
- DFF95B780FB22D5700A3EC78 /* player_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423E80E7BA6AA00F5680E /* player_v2.cpp */; };
- DFF95B790FB22D5700A3EC78 /* player_v2a.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423EA0E7BA6AA00F5680E /* player_v2a.cpp */; };
- DFF95B7A0FB22D5700A3EC78 /* player_v3a.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423EC0E7BA6AA00F5680E /* player_v3a.cpp */; };
- DFF95B7B0FB22D5700A3EC78 /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423EF0E7BA6AA00F5680E /* resource.cpp */; };
- DFF95B7C0FB22D5700A3EC78 /* resource_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423F10E7BA6AA00F5680E /* resource_v2.cpp */; };
- DFF95B7D0FB22D5700A3EC78 /* resource_v3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423F20E7BA6AA00F5680E /* resource_v3.cpp */; };
- DFF95B7E0FB22D5700A3EC78 /* resource_v4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423F30E7BA6AA00F5680E /* resource_v4.cpp */; };
- DFF95B7F0FB22D5700A3EC78 /* room.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423F40E7BA6AA00F5680E /* room.cpp */; };
- DFF95B800FB22D5700A3EC78 /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423F50E7BA6AA00F5680E /* saveload.cpp */; };
- DFF95B810FB22D5700A3EC78 /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423F70E7BA6AA00F5680E /* script.cpp */; };
- DFF95B820FB22D5700A3EC78 /* script_v0.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423F90E7BA6AA00F5680E /* script_v0.cpp */; };
- DFF95B830FB22D5700A3EC78 /* script_v2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423FA0E7BA6AA00F5680E /* script_v2.cpp */; };
- DFF95B840FB22D5700A3EC78 /* script_v5.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423FB0E7BA6AA00F5680E /* script_v5.cpp */; };
- DFF95B850FB22D5700A3EC78 /* script_v6.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423FC0E7BA6AA00F5680E /* script_v6.cpp */; };
- DFF95B860FB22D5700A3EC78 /* script_v8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423FD0E7BA6AA00F5680E /* script_v8.cpp */; };
- DFF95B870FB22D5700A3EC78 /* scumm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8423FF0E7BA6AA00F5680E /* scumm.cpp */; };
- DFF95B880FB22D5700A3EC78 /* channel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424020E7BA6AA00F5680E /* channel.cpp */; };
- DFF95B890FB22D5700A3EC78 /* codec1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424060E7BA6AA00F5680E /* codec1.cpp */; };
- DFF95B8A0FB22D5700A3EC78 /* codec37.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424070E7BA6AA00F5680E /* codec37.cpp */; };
- DFF95B8B0FB22D5700A3EC78 /* codec47.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424090E7BA6AA00F5680E /* codec47.cpp */; };
- DFF95B8C0FB22D5700A3EC78 /* imuse_channel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84240D0E7BA6AA00F5680E /* imuse_channel.cpp */; };
- DFF95B8D0FB22D5700A3EC78 /* saud_channel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84240E0E7BA6AA00F5680E /* saud_channel.cpp */; };
- DFF95B8E0FB22D5700A3EC78 /* smush_font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84240F0E7BA6AA00F5680E /* smush_font.cpp */; };
- DFF95B8F0FB22D5700A3EC78 /* smush_mixer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424110E7BA6AA00F5680E /* smush_mixer.cpp */; };
- DFF95B900FB22D5700A3EC78 /* smush_player.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424130E7BA6AA00F5680E /* smush_player.cpp */; };
- DFF95B910FB22D5700A3EC78 /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424150E7BA6AB00F5680E /* sound.cpp */; };
- DFF95B920FB22D5700A3EC78 /* string.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424170E7BA6AB00F5680E /* string.cpp */; };
- DFF95B930FB22D5700A3EC78 /* usage_bits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424190E7BA6AB00F5680E /* usage_bits.cpp */; };
- DFF95B940FB22D5700A3EC78 /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84241B0E7BA6AB00F5680E /* util.cpp */; };
- DFF95B950FB22D5700A3EC78 /* vars.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84241D0E7BA6AB00F5680E /* vars.cpp */; };
- DFF95B960FB22D5700A3EC78 /* verbs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84241E0E7BA6AB00F5680E /* verbs.cpp */; };
- DFF95B970FB22D5700A3EC78 /* autoroute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424210E7BA6AB00F5680E /* autoroute.cpp */; };
- DFF95B980FB22D5700A3EC78 /* compact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424230E7BA6AB00F5680E /* compact.cpp */; };
- DFF95B990FB22D5700A3EC78 /* control.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424250E7BA6AB00F5680E /* control.cpp */; };
- DFF95B9A0FB22D5700A3EC78 /* debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424270E7BA6AB00F5680E /* debug.cpp */; };
- DFF95B9B0FB22D5700A3EC78 /* disk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424290E7BA6AB00F5680E /* disk.cpp */; };
- DFF95B9C0FB22D5700A3EC78 /* grid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84242B0E7BA6AB00F5680E /* grid.cpp */; };
- DFF95B9D0FB22D5700A3EC78 /* hufftext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84242D0E7BA6AB00F5680E /* hufftext.cpp */; };
- DFF95B9E0FB22D5700A3EC78 /* intro.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84242E0E7BA6AB00F5680E /* intro.cpp */; };
- DFF95B9F0FB22D5700A3EC78 /* logic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424300E7BA6AB00F5680E /* logic.cpp */; };
- DFF95BA00FB22D5700A3EC78 /* mouse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424330E7BA6AB00F5680E /* mouse.cpp */; };
- DFF95BA10FB22D5700A3EC78 /* adlibchannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424360E7BA6AB00F5680E /* adlibchannel.cpp */; };
- DFF95BA20FB22D5700A3EC78 /* adlibmusic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424380E7BA6AB00F5680E /* adlibmusic.cpp */; };
- DFF95BA30FB22D5700A3EC78 /* gmchannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84243A0E7BA6AB00F5680E /* gmchannel.cpp */; };
- DFF95BA40FB22D5700A3EC78 /* gmmusic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84243C0E7BA6AB00F5680E /* gmmusic.cpp */; };
- DFF95BA50FB22D5700A3EC78 /* mt32music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84243E0E7BA6AB00F5680E /* mt32music.cpp */; };
- DFF95BA60FB22D5700A3EC78 /* musicbase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424400E7BA6AB00F5680E /* musicbase.cpp */; };
- DFF95BA70FB22D5700A3EC78 /* rnc_deco.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424420E7BA6AB00F5680E /* rnc_deco.cpp */; };
- DFF95BA80FB22D5700A3EC78 /* screen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424440E7BA6AB00F5680E /* screen.cpp */; };
- DFF95BA90FB22D5700A3EC78 /* sky.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424460E7BA6AB00F5680E /* sky.cpp */; };
- DFF95BAA0FB22D5700A3EC78 /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424490E7BA6AB00F5680E /* sound.cpp */; };
- DFF95BAB0FB22D5700A3EC78 /* text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84244C0E7BA6AB00F5680E /* text.cpp */; };
- DFF95BAC0FB22D5700A3EC78 /* animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84244F0E7BA6AB00F5680E /* animation.cpp */; };
- DFF95BAD0FB22D5700A3EC78 /* control.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424520E7BA6AB00F5680E /* control.cpp */; };
- DFF95BAE0FB22D5700A3EC78 /* debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424560E7BA6AB00F5680E /* debug.cpp */; };
- DFF95BAF0FB22D5700A3EC78 /* eventman.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424580E7BA6AB00F5680E /* eventman.cpp */; };
- DFF95BB00FB22D5700A3EC78 /* logic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84245A0E7BA6AB00F5680E /* logic.cpp */; };
- DFF95BB10FB22D5700A3EC78 /* memman.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84245C0E7BA6AB00F5680E /* memman.cpp */; };
- DFF95BB20FB22D5700A3EC78 /* menu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84245E0E7BA6AB00F5680E /* menu.cpp */; };
- DFF95BB30FB22D5700A3EC78 /* mouse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424610E7BA6AB00F5680E /* mouse.cpp */; };
- DFF95BB40FB22D5700A3EC78 /* music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424630E7BA6AB00F5680E /* music.cpp */; };
- DFF95BB50FB22D5700A3EC78 /* objectman.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424660E7BA6AB00F5680E /* objectman.cpp */; };
- DFF95BB60FB22D5700A3EC78 /* resman.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424680E7BA6AB00F5680E /* resman.cpp */; };
- DFF95BB70FB22D5700A3EC78 /* router.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84246A0E7BA6AB00F5680E /* router.cpp */; };
- DFF95BB80FB22D5700A3EC78 /* screen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84246C0E7BA6AB00F5680E /* screen.cpp */; };
- DFF95BB90FB22D5700A3EC78 /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84246E0E7BA6AB00F5680E /* sound.cpp */; };
- DFF95BBA0FB22D5700A3EC78 /* staticres.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424700E7BA6AB00F5680E /* staticres.cpp */; };
- DFF95BBB0FB22D5700A3EC78 /* sword1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424710E7BA6AB00F5680E /* sword1.cpp */; };
- DFF95BBC0FB22D5700A3EC78 /* text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424750E7BA6AB00F5680E /* text.cpp */; };
- DFF95BBD0FB22D5700A3EC78 /* animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424780E7BA6AB00F5680E /* animation.cpp */; };
- DFF95BBE0FB22D5700A3EC78 /* anims.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84247A0E7BA6AB00F5680E /* anims.cpp */; };
- DFF95BBF0FB22D5700A3EC78 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84247B0E7BA6AB00F5680E /* console.cpp */; };
- DFF95BC00FB22D5700A3EC78 /* controls.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84247D0E7BA6AB00F5680E /* controls.cpp */; };
- DFF95BC10FB22D5700A3EC78 /* debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84247F0E7BA6AB00F5680E /* debug.cpp */; };
- DFF95BC20FB22D5700A3EC78 /* events.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424820E7BA6AB00F5680E /* events.cpp */; };
- DFF95BC30FB22D5700A3EC78 /* function.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424830E7BA6AB00F5680E /* function.cpp */; };
- DFF95BC40FB22D5700A3EC78 /* icons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424850E7BA6AB00F5680E /* icons.cpp */; };
- DFF95BC50FB22D5700A3EC78 /* interpreter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424860E7BA6AB00F5680E /* interpreter.cpp */; };
- DFF95BC60FB22D5700A3EC78 /* layers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424880E7BA6AB00F5680E /* layers.cpp */; };
- DFF95BC70FB22D5700A3EC78 /* logic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424890E7BA6AB00F5680E /* logic.cpp */; };
- DFF95BC80FB22D5700A3EC78 /* maketext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84248B0E7BA6AB00F5680E /* maketext.cpp */; };
- DFF95BC90FB22D5700A3EC78 /* memory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84248D0E7BA6AB00F5680E /* memory.cpp */; };
- DFF95BCA0FB22D5700A3EC78 /* menu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84248F0E7BA6AB00F5680E /* menu.cpp */; };
- DFF95BCB0FB22D5700A3EC78 /* mouse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424910E7BA6AB00F5680E /* mouse.cpp */; };
- DFF95BCC0FB22D5700A3EC78 /* music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424930E7BA6AB00F5680E /* music.cpp */; };
- DFF95BCD0FB22D5700A3EC78 /* palette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424950E7BA6AB00F5680E /* palette.cpp */; };
- DFF95BCE0FB22D5700A3EC78 /* protocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424960E7BA6AB00F5680E /* protocol.cpp */; };
- DFF95BCF0FB22D5700A3EC78 /* render.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424970E7BA6AB00F5680E /* render.cpp */; };
- DFF95BD00FB22D5700A3EC78 /* resman.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424980E7BA6AB00F5680E /* resman.cpp */; };
- DFF95BD10FB22D5700A3EC78 /* router.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84249A0E7BA6AB00F5680E /* router.cpp */; };
- DFF95BD20FB22D5700A3EC78 /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84249C0E7BA6AB00F5680E /* saveload.cpp */; };
- DFF95BD30FB22D5700A3EC78 /* screen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF84249E0E7BA6AB00F5680E /* screen.cpp */; };
- DFF95BD40FB22D5700A3EC78 /* scroll.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424A00E7BA6AB00F5680E /* scroll.cpp */; };
- DFF95BD50FB22D5700A3EC78 /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424A10E7BA6AB00F5680E /* sound.cpp */; };
- DFF95BD60FB22D5700A3EC78 /* speech.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424A30E7BA6AB00F5680E /* speech.cpp */; };
- DFF95BD70FB22D5700A3EC78 /* sprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424A40E7BA6AB00F5680E /* sprite.cpp */; };
- DFF95BD80FB22D5700A3EC78 /* startup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424A50E7BA6AB00F5680E /* startup.cpp */; };
- DFF95BD90FB22D5700A3EC78 /* sword2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424A60E7BA6AB00F5680E /* sword2.cpp */; };
- DFF95BDA0FB22D5700A3EC78 /* sync.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424A80E7BA6AB00F5680E /* sync.cpp */; };
- DFF95BDB0FB22D5700A3EC78 /* walker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424A90E7BA6AB00F5680E /* walker.cpp */; };
- DFF95BDC0FB22D5700A3EC78 /* actors.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424AB0E7BA6AB00F5680E /* actors.cpp */; };
- DFF95BDD0FB22D5700A3EC78 /* anim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424AD0E7BA6AB00F5680E /* anim.cpp */; };
- DFF95BDE0FB22D5700A3EC78 /* background.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424AF0E7BA6AB00F5680E /* background.cpp */; };
- DFF95BDF0FB22D5700A3EC78 /* bg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424B10E7BA6AB00F5680E /* bg.cpp */; };
- DFF95BE00FB22D5700A3EC78 /* cliprect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424B20E7BA6AB00F5680E /* cliprect.cpp */; };
- DFF95BE10FB22D5700A3EC78 /* config.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424B40E7BA6AB00F5680E /* config.cpp */; };
- DFF95BE20FB22D5700A3EC78 /* cursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424B70E7BA6AB00F5680E /* cursor.cpp */; };
- DFF95BE30FB22D5700A3EC78 /* debugger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424B90E7BA6AB00F5680E /* debugger.cpp */; };
- DFF95BE40FB22D5700A3EC78 /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424BB0E7BA6AB00F5680E /* detection.cpp */; };
- DFF95BE50FB22D5700A3EC78 /* effect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424BD0E7BA6AB00F5680E /* effect.cpp */; };
- DFF95BE60FB22D5700A3EC78 /* events.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424BE0E7BA6AB00F5680E /* events.cpp */; };
- DFF95BE70FB22D5700A3EC78 /* faders.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424C00E7BA6AB00F5680E /* faders.cpp */; };
- DFF95BE80FB22D5700A3EC78 /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424C30E7BA6AB00F5680E /* font.cpp */; };
- DFF95BE90FB22D5700A3EC78 /* graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424C50E7BA6AB00F5680E /* graphics.cpp */; };
- DFF95BEA0FB22D5700A3EC78 /* handle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424C70E7BA6AB00F5680E /* handle.cpp */; };
- DFF95BEB0FB22D5700A3EC78 /* heapmem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424C90E7BA6AB00F5680E /* heapmem.cpp */; };
- DFF95BEC0FB22D5700A3EC78 /* mareels.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424CD0E7BA6AB00F5680E /* mareels.cpp */; };
- DFF95BED0FB22D5700A3EC78 /* move.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424CF0E7BA6AB00F5680E /* move.cpp */; };
- DFF95BEE0FB22D5700A3EC78 /* multiobj.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424D10E7BA6AB00F5680E /* multiobj.cpp */; };
- DFF95BEF0FB22D5700A3EC78 /* music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424D30E7BA6AB00F5680E /* music.cpp */; };
- DFF95BF00FB22D5700A3EC78 /* object.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424D50E7BA6AB00F5680E /* object.cpp */; };
- DFF95BF10FB22D5700A3EC78 /* palette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424D70E7BA6AB00F5680E /* palette.cpp */; };
- DFF95BF20FB22D5700A3EC78 /* pcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424D90E7BA6AB00F5680E /* pcode.cpp */; };
- DFF95BF30FB22D5700A3EC78 /* pdisplay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424DB0E7BA6AB00F5680E /* pdisplay.cpp */; };
- DFF95BF40FB22D5700A3EC78 /* play.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424DD0E7BA6AB00F5680E /* play.cpp */; };
- DFF95BF50FB22D5700A3EC78 /* polygons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424DE0E7BA6AB00F5680E /* polygons.cpp */; };
- DFF95BF60FB22D5700A3EC78 /* rince.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424E00E7BA6AB00F5680E /* rince.cpp */; };
- DFF95BF70FB22D5700A3EC78 /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424E20E7BA6AB00F5680E /* saveload.cpp */; };
- DFF95BF80FB22D5700A3EC78 /* savescn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424E30E7BA6AB00F5680E /* savescn.cpp */; };
- DFF95BF90FB22D5700A3EC78 /* scene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424E50E7BA6AB00F5680E /* scene.cpp */; };
- DFF95BFA0FB22D5700A3EC78 /* sched.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424E70E7BA6AB00F5680E /* sched.cpp */; };
- DFF95BFB0FB22D5700A3EC78 /* scn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424E90E7BA6AB00F5680E /* scn.cpp */; };
- DFF95BFC0FB22D5700A3EC78 /* scroll.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424EB0E7BA6AB00F5680E /* scroll.cpp */; };
- DFF95BFD0FB22D5700A3EC78 /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424EE0E7BA6AB00F5680E /* sound.cpp */; };
- DFF95BFE0FB22D5700A3EC78 /* strres.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424F00E7BA6AB00F5680E /* strres.cpp */; };
- DFF95BFF0FB22D5700A3EC78 /* text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424F20E7BA6AB00F5680E /* text.cpp */; };
- DFF95C000FB22D5700A3EC78 /* timers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424F40E7BA6AB00F5680E /* timers.cpp */; };
- DFF95C010FB22D5700A3EC78 /* tinlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424F60E7BA6AB00F5680E /* tinlib.cpp */; };
- DFF95C020FB22D5700A3EC78 /* tinsel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424F80E7BA6AB00F5680E /* tinsel.cpp */; };
- DFF95C030FB22D5700A3EC78 /* token.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424FA0E7BA6AB00F5680E /* token.cpp */; };
- DFF95C040FB22D5700A3EC78 /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424FD0E7BA6AB00F5680E /* detection.cpp */; };
- DFF95C050FB22D5700A3EC78 /* graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8424FE0E7BA6AB00F5680E /* graphics.cpp */; };
- DFF95C060FB22D5700A3EC78 /* menu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8425000E7BA6AB00F5680E /* menu.cpp */; };
- DFF95C070FB22D5700A3EC78 /* midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8425010E7BA6AB00F5680E /* midi.cpp */; };
- DFF95C080FB22D5700A3EC78 /* opcodes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8425040E7BA6AB00F5680E /* opcodes.cpp */; };
- DFF95C090FB22D5700A3EC78 /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8425050E7BA6AB00F5680E /* resource.cpp */; };
- DFF95C0A0FB22D5700A3EC78 /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8425060E7BA6AB00F5680E /* saveload.cpp */; };
- DFF95C0B0FB22D5700A3EC78 /* staticres.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8425070E7BA6AB00F5680E /* staticres.cpp */; };
- DFF95C0C0FB22D5700A3EC78 /* touche.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8425080E7BA6AB00F5680E /* touche.cpp */; };
- DFF95C0D0FB22D5700A3EC78 /* blit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF8428960E7BAAAB00F5680E /* blit.cpp */; };
- DFF95C0E0FB22D5700A3EC78 /* timidity.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF842A3D0E7BBB5000F5680E /* timidity.cpp */; };
- DFF95C0F0FB22D5700A3EC78 /* archive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF842A400E7BBBB400F5680E /* archive.cpp */; };
- DFF95C100FB22D5700A3EC78 /* unarj.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF842A450E7BBBB400F5680E /* unarj.cpp */; };
- DFF95C110FB22D5700A3EC78 /* stdiostream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF842A6B0E7BBD5700F5680E /* stdiostream.cpp */; };
- DFF95C130FB22D5700A3EC78 /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8BF00ED5FC77001CB19F /* saveload.cpp */; };
- DFF95C140FB22D5700A3EC78 /* ThemeEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8BF40ED5FC77001CB19F /* ThemeEngine.cpp */; };
- DFF95C150FB22D5700A3EC78 /* ThemeEval.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8BF60ED5FC77001CB19F /* ThemeEval.cpp */; };
- DFF95C160FB22D5700A3EC78 /* ThemeLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8BF80ED5FC77001CB19F /* ThemeLayout.cpp */; };
- DFF95C170FB22D5700A3EC78 /* ThemeParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8BFA0ED5FC77001CB19F /* ThemeParser.cpp */; };
- DFF95C180FB22D5700A3EC78 /* thumbnail.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8C050ED5FCAF001CB19F /* thumbnail.cpp */; };
- DFF95C190FB22D5700A3EC78 /* VectorRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8C070ED5FCAF001CB19F /* VectorRenderer.cpp */; };
- DFF95C1A0FB22D5700A3EC78 /* VectorRendererSpec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8C090ED5FCAF001CB19F /* VectorRendererSpec.cpp */; };
- DFF95C1B0FB22D5700A3EC78 /* xmlparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8C0F0ED5FCC2001CB19F /* xmlparser.cpp */; };
- DFF95C1C0FB22D5700A3EC78 /* game.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF7E8C510ED60067001CB19F /* game.cpp */; };
- DFF95C1D0FB22D5700A3EC78 /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFAAAFF50F0112AD003E9390 /* saveload.cpp */; };
- DFF95C1E0FB22D5700A3EC78 /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFAAAFF80F0112C1003E9390 /* detection.cpp */; };
- DFF95C1F0FB22D5700A3EC78 /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFAAAFFB0F0112DF003E9390 /* detection.cpp */; };
- DFF95C200FB22D5700A3EC78 /* thumbnail_intern.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFAAB0010F011392003E9390 /* thumbnail_intern.cpp */; };
- DFF95C210FB22D5700A3EC78 /* dither.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFB900F485D890006E566 /* dither.cpp */; };
- DFF95C270FB22D5700A3EC78 /* debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFBD10F485DFB0006E566 /* debug.cpp */; };
- DFF95C290FB22D5700A3EC78 /* posix-saves.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFBF80F4860A60006E566 /* posix-saves.cpp */; };
- DFF95C2A0FB22D5700A3EC78 /* bmv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC1F0F4862520006E566 /* bmv.cpp */; };
- DFF95C2B0FB22D5700A3EC78 /* dialogs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC200F4862520006E566 /* dialogs.cpp */; };
- DFF95C2C0FB22D5700A3EC78 /* drives.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC220F4862520006E566 /* drives.cpp */; };
- DFF95C2D0FB22D5700A3EC78 /* sysvar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC270F4862520006E566 /* sysvar.cpp */; };
- DFF95C2E0FB22D5700A3EC78 /* gui_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC2E0F48628A0006E566 /* gui_lol.cpp */; };
- DFF95C2F0FB22D5700A3EC78 /* items_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC300F48628A0006E566 /* items_lol.cpp */; };
- DFF95C300FB22D5700A3EC78 /* script_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC310F48628A0006E566 /* script_lol.cpp */; };
- DFF95C310FB22D5700A3EC78 /* sequences_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC320F48628A0006E566 /* sequences_lol.cpp */; };
- DFF95C320FB22D5700A3EC78 /* sound_midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC330F48628A0006E566 /* sound_midi.cpp */; };
- DFF95C330FB22D5700A3EC78 /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC360F48628A0006E566 /* util.cpp */; };
- DFF95C370FB22D5700A3EC78 /* scene_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC490F4863100006E566 /* scene_lol.cpp */; };
- DFF95C380FB22D5700A3EC78 /* advancedDetector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC4C0F4863560006E566 /* advancedDetector.cpp */; };
- DFF95C390FB22D5700A3EC78 /* base-backend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC5B0F4866E70006E566 /* base-backend.cpp */; };
- DFF95C3A0FB22D5700A3EC78 /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC600F48672D0006E566 /* resource.cpp */; };
- DFF95C3B0FB22D5700A3EC78 /* resource_hrs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC620F48672D0006E566 /* resource_hrs.cpp */; };
- DFF95C3C0FB22D5700A3EC78 /* resource_res.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC630F48672D0006E566 /* resource_res.cpp */; };
- DFF95C3D0FB22D5700A3EC78 /* resource_rsc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC640F48672D0006E566 /* resource_rsc.cpp */; };
- DFF95C3E0FB22D5700A3EC78 /* sfuncs_ihnm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC650F48672D0006E566 /* sfuncs_ihnm.cpp */; };
- DFF95C3F0FB22D5700A3EC78 /* debugger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC700F4867910006E566 /* debugger.cpp */; };
- DFF95C400FB22D5700A3EC78 /* staticres.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFC720F4867910006E566 /* staticres.cpp */; };
- DFF95C410FB22D5700A3EC78 /* cell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCBD0F4870690006E566 /* cell.cpp */; };
- DFF95C420FB22D5700A3EC78 /* cursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCBF0F4870690006E566 /* cursor.cpp */; };
- DFF95C430FB22D5700A3EC78 /* debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCC10F4870690006E566 /* debug.cpp */; };
- DFF95C440FB22D5700A3EC78 /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCC30F4870690006E566 /* detection.cpp */; };
- DFF95C450FB22D5700A3EC78 /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCC40F4870690006E566 /* font.cpp */; };
- DFF95C460FB22D5700A3EC78 /* graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCC60F4870690006E566 /* graphics.cpp */; };
- DFF95C470FB22D5700A3EC78 /* groovie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCC80F4870690006E566 /* groovie.cpp */; };
- DFF95C480FB22D5700A3EC78 /* lzss.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCCA0F4870690006E566 /* lzss.cpp */; };
- DFF95C490FB22D5700A3EC78 /* music.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCCD0F4870690006E566 /* music.cpp */; };
- DFF95C4A0FB22D5700A3EC78 /* player.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCCF0F4870690006E566 /* player.cpp */; };
- DFF95C4B0FB22D5700A3EC78 /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCD10F4870690006E566 /* resource.cpp */; };
- DFF95C4C0FB22D5700A3EC78 /* roq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCD30F4870690006E566 /* roq.cpp */; };
- DFF95C4D0FB22D5700A3EC78 /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCD50F4870690006E566 /* saveload.cpp */; };
- DFF95C4E0FB22D5700A3EC78 /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCD70F4870690006E566 /* script.cpp */; };
- DFF95C4F0FB22D5700A3EC78 /* vdx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFCD90F4870690006E566 /* vdx.cpp */; };
- DFF95C500FB22D5700A3EC78 /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFD050F4870E50006E566 /* detection.cpp */; };
- DFF95C510FB22D5700A3EC78 /* graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFD060F4870E50006E566 /* graphics.cpp */; };
- DFF95C520FB22D5700A3EC78 /* locations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFD080F4870E50006E566 /* locations.cpp */; };
- DFF95C530FB22D5700A3EC78 /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFD0A0F4870E50006E566 /* resource.cpp */; };
- DFF95C540FB22D5700A3EC78 /* saveload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFD0B0F4870E50006E566 /* saveload.cpp */; };
- DFF95C550FB22D5700A3EC78 /* sequences.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFD0C0F4870E50006E566 /* sequences.cpp */; };
- DFF95C560FB22D5700A3EC78 /* staticres.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFD0D0F4870E50006E566 /* staticres.cpp */; };
- DFF95C570FB22D5700A3EC78 /* tucker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2FFD0E0F4870E50006E566 /* tucker.cpp */; };
- DFF95C580FB22D5700A3EC78 /* detection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8301A0F48AF18005EF03C /* detection.cpp */; };
- DFF95C5A0FB22D5700A3EC78 /* gc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8301E0F48AF18005EF03C /* gc.cpp */; };
- DFF95C5C0FB22D5700A3EC78 /* kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830230F48AF18005EF03C /* kernel.cpp */; };
- DFF95C5D0FB22D5700A3EC78 /* kevent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830260F48AF18005EF03C /* kevent.cpp */; };
- DFF95C5E0FB22D5700A3EC78 /* kfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830270F48AF18005EF03C /* kfile.cpp */; };
- DFF95C5F0FB22D5700A3EC78 /* kgraphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830280F48AF18005EF03C /* kgraphics.cpp */; };
- DFF95C600FB22D5700A3EC78 /* klists.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830290F48AF18005EF03C /* klists.cpp */; };
- DFF95C610FB22D5700A3EC78 /* kmath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8302A0F48AF18005EF03C /* kmath.cpp */; };
- DFF95C620FB22D5700A3EC78 /* kmenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8302B0F48AF18005EF03C /* kmenu.cpp */; };
- DFF95C630FB22D5700A3EC78 /* kmovement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8302C0F48AF18005EF03C /* kmovement.cpp */; };
- DFF95C640FB22D5700A3EC78 /* kpathing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8302D0F48AF18005EF03C /* kpathing.cpp */; };
- DFF95C650FB22D5700A3EC78 /* kscripts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8302E0F48AF18005EF03C /* kscripts.cpp */; };
- DFF95C660FB22D5700A3EC78 /* ksound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8302F0F48AF18005EF03C /* ksound.cpp */; };
- DFF95C670FB22D5700A3EC78 /* kstring.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830300F48AF18005EF03C /* kstring.cpp */; };
- DFF95C680FB22D5700A3EC78 /* message.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830310F48AF18005EF03C /* message.cpp */; };
- DFF95C6A0FB22D5700A3EC78 /* savegame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830360F48AF18005EF03C /* savegame.cpp */; };
- DFF95C6C0FB22D5700A3EC78 /* scriptdebug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830390F48AF18005EF03C /* scriptdebug.cpp */; };
- DFF95C6D0FB22D5700A3EC78 /* seg_manager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8303A0F48AF18005EF03C /* seg_manager.cpp */; };
- DFF95C6E0FB22D5700A3EC78 /* vm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC8303C0F48AF18005EF03C /* vm.cpp */; };
- DFF95C770FB22D5700A3EC78 /* sci.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC830960F48AF18005EF03C /* sci.cpp */; };
- DFF95C880FB22D5700A3EC78 /* unzip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE473C10D81F4E800B6D1FB /* unzip.cpp */; };
- DFF95C890FB22D5700A3EC78 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFAAD2390F50120E00C3A4E2 /* console.cpp */; };
- DFF95C8E0FB22D5700A3EC78 /* state.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF573C010F5A81EA00961A72 /* state.cpp */; };
- DFF95C910FB22D5700A3EC78 /* exec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF573CBA0F5A85B300961A72 /* exec.cpp */; };
- DFF95C920FB22D5700A3EC78 /* timer_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF573CBD0F5A85E100961A72 /* timer_lol.cpp */; };
- DFF95C940FB22D5700A3EC78 /* sprites_lol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF89C2870F62D55C00D756B6 /* sprites_lol.cpp */; };
- DFF95C950FB22D5700A3EC78 /* script.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF89C2A30F62D79E00D756B6 /* script.cpp */; };
- DFF95C990FB22D5700A3EC78 /* pn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF093E5C0F63CAD4002D821E /* pn.cpp */; };
- DFF95C9A0FB22D5700A3EC78 /* script_pn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF093E5D0F63CAD4002D821E /* script_pn.cpp */; };
- DFF95C9B0FB22D5700A3EC78 /* vga_pn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF093E5E0F63CAD4002D821E /* vga_pn.cpp */; };
- DFF95CA70FB22D5700A3EC78 /* sound_br.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF5CEB260F75535000DEA624 /* sound_br.cpp */; };
- DFF95CA80FB22D5700A3EC78 /* sound_ns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF5CEB270F75535000DEA624 /* sound_ns.cpp */; };
- DFF95CA90FB22D5700A3EC78 /* protracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF5CEB2F0F75538000DEA624 /* protracker.cpp */; };
- DFF95CAC0FB22D5700A3EC78 /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE88C440F874A1100C555C5 /* sound.cpp */; };
- DFF95CAE0FB22D5700A3EC78 /* batplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC070FAC4E1900A5AFD7 /* batplayer.cpp */; };
- DFF95CAF0FB22D5700A3EC78 /* demoplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC090FAC4E1900A5AFD7 /* demoplayer.cpp */; };
- DFF95CB00FB22D5700A3EC78 /* scnplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC0B0FAC4E1900A5AFD7 /* scnplayer.cpp */; };
- DFF95CB10FB22D5700A3EC78 /* draw_fascin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC0D0FAC4E1900A5AFD7 /* draw_fascin.cpp */; };
- DFF95CB30FB22D5700A3EC78 /* inter_fascin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC0F0FAC4E1900A5AFD7 /* inter_fascin.cpp */; };
- DFF95CB40FB22D5700A3EC78 /* script_v3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC260FAC4EAB00A5AFD7 /* script_v3.cpp */; };
- DFF95CB50FB22D5700A3EC78 /* script_v4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF09CC270FAC4EAB00A5AFD7 /* script_v4.cpp */; };
- DFF95CBC0FB22D5700A3EC78 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF842A160E7BB34E00F5680E /* CoreAudio.framework */; };
- DFF95CBD0FB22D5700A3EC78 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF842A170E7BB34E00F5680E /* CoreFoundation.framework */; };
- DFF95CBE0FB22D5700A3EC78 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF842A180E7BB34E00F5680E /* Foundation.framework */; };
- DFF95CBF0FB22D5700A3EC78 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF842A190E7BB34E00F5680E /* UIKit.framework */; };
- DFF95CC00FB22D5700A3EC78 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF842A270E7BB37500F5680E /* AudioToolbox.framework */; };
- DFF95CC10FB22D5700A3EC78 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF842A2E0E7BB39E00F5680E /* QuartzCore.framework */; };
- F92B4DCE139DD428000D1BF1 /* quicktime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F92B4DCC139DD428000D1BF1 /* quicktime.cpp */; };
- F92B4DCF139DD428000D1BF1 /* quicktime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F92B4DCC139DD428000D1BF1 /* quicktime.cpp */; };
- F92B4DD0139DD428000D1BF1 /* quicktime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F92B4DCC139DD428000D1BF1 /* quicktime.cpp */; };
- F92B4DD3139DD449000D1BF1 /* yuv_to_rgb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F92B4DD1139DD449000D1BF1 /* yuv_to_rgb.cpp */; };
- F92B4DD4139DD449000D1BF1 /* yuv_to_rgb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F92B4DD1139DD449000D1BF1 /* yuv_to_rgb.cpp */; };
- F92B4DD5139DD449000D1BF1 /* yuv_to_rgb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F92B4DD1139DD449000D1BF1 /* yuv_to_rgb.cpp */; };
- F92B4DDA139DDC92000D1BF1 /* macosx-main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F92B4DD7139DDC92000D1BF1 /* macosx-main.cpp */; };
- F92B4DDB139DDC92000D1BF1 /* macosx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F92B4DD8139DDC92000D1BF1 /* macosx.cpp */; };
- F9946D90139E1A260072D195 /* cdtoons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946D7A139E1A260072D195 /* cdtoons.cpp */; };
- F9946D91139E1A260072D195 /* cinepak.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946D7C139E1A260072D195 /* cinepak.cpp */; };
- F9946D92139E1A260072D195 /* indeo3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946D7F139E1A260072D195 /* indeo3.cpp */; };
- F9946D93139E1A260072D195 /* mjpeg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946D81139E1A260072D195 /* mjpeg.cpp */; };
- F9946D94139E1A260072D195 /* msrle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946D83139E1A260072D195 /* msrle.cpp */; };
- F9946D95139E1A260072D195 /* msvideo1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946D85139E1A260072D195 /* msvideo1.cpp */; };
- F9946D96139E1A260072D195 /* qtrle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946D87139E1A260072D195 /* qtrle.cpp */; };
- F9946D97139E1A260072D195 /* rpza.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946D89139E1A260072D195 /* rpza.cpp */; };
- F9946D98139E1A260072D195 /* smc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946D8B139E1A260072D195 /* smc.cpp */; };
- F9946D99139E1A260072D195 /* truemotion1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946D8D139E1A260072D195 /* truemotion1.cpp */; };
- F9946D9D139E1A560072D195 /* towns_midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946D9A139E1A560072D195 /* towns_midi.cpp */; };
- F9946D9E139E1A560072D195 /* towns_midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946D9A139E1A560072D195 /* towns_midi.cpp */; };
- F9946D9F139E1A560072D195 /* towns_midi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946D9A139E1A560072D195 /* towns_midi.cpp */; };
- F9946DA0139E1A560072D195 /* towns_pc98_plugins.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946D9C139E1A560072D195 /* towns_pc98_plugins.cpp */; };
- F9946DA1139E1A560072D195 /* towns_pc98_plugins.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946D9C139E1A560072D195 /* towns_pc98_plugins.cpp */; };
- F9946DA2139E1A560072D195 /* towns_pc98_plugins.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946D9C139E1A560072D195 /* towns_pc98_plugins.cpp */; };
- F9946DB5139E1A880072D195 /* freeverb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DA3139E1A880072D195 /* freeverb.cpp */; };
- F9946DB6139E1A880072D195 /* freeverb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DA3139E1A880072D195 /* freeverb.cpp */; };
- F9946DB7139E1A880072D195 /* freeverb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DA3139E1A880072D195 /* freeverb.cpp */; };
- F9946DB8139E1A880072D195 /* i386.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DA5139E1A880072D195 /* i386.cpp */; };
- F9946DB9139E1A880072D195 /* i386.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DA5139E1A880072D195 /* i386.cpp */; };
- F9946DBA139E1A880072D195 /* i386.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DA5139E1A880072D195 /* i386.cpp */; };
- F9946DBB139E1A880072D195 /* mt32_file.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DA7139E1A880072D195 /* mt32_file.cpp */; };
- F9946DBC139E1A880072D195 /* mt32_file.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DA7139E1A880072D195 /* mt32_file.cpp */; };
- F9946DBD139E1A880072D195 /* mt32_file.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DA7139E1A880072D195 /* mt32_file.cpp */; };
- F9946DBE139E1A880072D195 /* part.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DAA139E1A880072D195 /* part.cpp */; };
- F9946DBF139E1A880072D195 /* part.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DAA139E1A880072D195 /* part.cpp */; };
- F9946DC0139E1A880072D195 /* part.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DAA139E1A880072D195 /* part.cpp */; };
- F9946DC1139E1A880072D195 /* partial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DAC139E1A880072D195 /* partial.cpp */; };
- F9946DC2139E1A880072D195 /* partial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DAC139E1A880072D195 /* partial.cpp */; };
- F9946DC3139E1A880072D195 /* partial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DAC139E1A880072D195 /* partial.cpp */; };
- F9946DC4139E1A880072D195 /* partialManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DAE139E1A880072D195 /* partialManager.cpp */; };
- F9946DC5139E1A880072D195 /* partialManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DAE139E1A880072D195 /* partialManager.cpp */; };
- F9946DC6139E1A880072D195 /* partialManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DAE139E1A880072D195 /* partialManager.cpp */; };
- F9946DC7139E1A880072D195 /* synth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DB1139E1A880072D195 /* synth.cpp */; };
- F9946DC8139E1A880072D195 /* synth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DB1139E1A880072D195 /* synth.cpp */; };
- F9946DC9139E1A880072D195 /* synth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DB1139E1A880072D195 /* synth.cpp */; };
- F9946DCA139E1A880072D195 /* tables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DB3139E1A880072D195 /* tables.cpp */; };
- F9946DCB139E1A880072D195 /* tables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DB3139E1A880072D195 /* tables.cpp */; };
- F9946DCC139E1A880072D195 /* tables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DB3139E1A880072D195 /* tables.cpp */; };
- F9946DD6139E1AD30072D195 /* aac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DCE139E1AD30072D195 /* aac.cpp */; };
- F9946DD7139E1AD30072D195 /* aac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DCE139E1AD30072D195 /* aac.cpp */; };
- F9946DD8139E1AD30072D195 /* aac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DCE139E1AD30072D195 /* aac.cpp */; };
- F9946DD9139E1AD30072D195 /* qdm2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DD0139E1AD30072D195 /* qdm2.cpp */; };
- F9946DDA139E1AD30072D195 /* qdm2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DD0139E1AD30072D195 /* qdm2.cpp */; };
- F9946DDB139E1AD30072D195 /* qdm2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DD0139E1AD30072D195 /* qdm2.cpp */; };
- F9946DDC139E1AD30072D195 /* quicktime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DD4139E1AD30072D195 /* quicktime.cpp */; };
- F9946DDD139E1AD30072D195 /* quicktime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DD4139E1AD30072D195 /* quicktime.cpp */; };
- F9946DDE139E1AD30072D195 /* quicktime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DD4139E1AD30072D195 /* quicktime.cpp */; };
- F9946DE3139E1B180072D195 /* posix-main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DE0139E1B180072D195 /* posix-main.cpp */; };
- F9946DE4139E1B180072D195 /* posix-main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DE0139E1B180072D195 /* posix-main.cpp */; };
- F9946DE5139E1B180072D195 /* posix-main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DE0139E1B180072D195 /* posix-main.cpp */; };
- F9946DE6139E1B180072D195 /* posix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DE1139E1B180072D195 /* posix.cpp */; };
- F9946DE7139E1B180072D195 /* posix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DE1139E1B180072D195 /* posix.cpp */; };
- F9946DE8139E1B180072D195 /* posix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DE1139E1B180072D195 /* posix.cpp */; };
- F9946DEC139E1B6F0072D195 /* downscaler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DEA139E1B6F0072D195 /* downscaler.cpp */; };
- F9946DED139E1B6F0072D195 /* downscaler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DEA139E1B6F0072D195 /* downscaler.cpp */; };
- F9946DEE139E1B6F0072D195 /* downscaler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DEA139E1B6F0072D195 /* downscaler.cpp */; };
- F9946DF1139E1BA00072D195 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DEF139E1BA00072D195 /* console.cpp */; };
- F9946DF2139E1BA00072D195 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DEF139E1BA00072D195 /* console.cpp */; };
- F9946DF3139E1BA00072D195 /* console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DEF139E1BA00072D195 /* console.cpp */; };
- F9946DF7139E1BBF0072D195 /* sdl-mixer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DF5139E1BBF0072D195 /* sdl-mixer.cpp */; };
- F9946DF8139E1BBF0072D195 /* sdl-mixer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DF5139E1BBF0072D195 /* sdl-mixer.cpp */; };
- F9946DF9139E1BBF0072D195 /* sdl-mixer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DF5139E1BBF0072D195 /* sdl-mixer.cpp */; };
- F9946DFE139E1BEB0072D195 /* doublebuffersdl-mixer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DFC139E1BEB0072D195 /* doublebuffersdl-mixer.cpp */; };
- F9946DFF139E1BEB0072D195 /* doublebuffersdl-mixer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DFC139E1BEB0072D195 /* doublebuffersdl-mixer.cpp */; };
- F9946E00139E1BEB0072D195 /* doublebuffersdl-mixer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946DFC139E1BEB0072D195 /* doublebuffersdl-mixer.cpp */; };
- F9946E04139E1C390072D195 /* sdl-graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946E02139E1C390072D195 /* sdl-graphics.cpp */; };
- F9946E05139E1C390072D195 /* sdl-graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946E02139E1C390072D195 /* sdl-graphics.cpp */; };
- F9946E06139E1C3A0072D195 /* sdl-graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9946E02139E1C390072D195 /* sdl-graphics.cpp */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXCopyFilesBuildPhase section */
- DF0942260F63CB26002D821E /* CopyFiles */ = {
- isa = PBXCopyFilesBuildPhase;
- buildActionMask = 2147483647;
- dstPath = "";
- dstSubfolderSpec = 7;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- DF573CB30F5A84DF00961A72 /* CopyFiles */ = {
- isa = PBXCopyFilesBuildPhase;
- buildActionMask = 2147483647;
- dstPath = "";
- dstSubfolderSpec = 7;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- DFF95CC60FB22D5700A3EC78 /* CopyFiles */ = {
- isa = PBXCopyFilesBuildPhase;
- buildActionMask = 2147483647;
- dstPath = "";
- dstSubfolderSpec = 7;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXCopyFilesBuildPhase section */
-
-/* Begin PBXFileReference section */
- 1D6058910D05DD3D006BFB54 /* ScummVM.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ScummVM.app; sourceTree = BUILT_PRODUCTS_DIR; };
- 8CB5A9B71253FD6800CB6BC7 /* m4_scene.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = m4_scene.cpp; sourceTree = "<group>"; };
- 8CB5A9B81253FD6800CB6BC7 /* m4_scene.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = m4_scene.h; sourceTree = "<group>"; };
- 8CB5A9B91253FD6800CB6BC7 /* mads_logic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mads_logic.cpp; sourceTree = "<group>"; };
- 8CB5A9BA1253FD6800CB6BC7 /* mads_logic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mads_logic.h; sourceTree = "<group>"; };
- 8CB5A9BB1253FD6800CB6BC7 /* mads_player.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mads_player.cpp; sourceTree = "<group>"; };
- 8CB5A9BC1253FD6800CB6BC7 /* mads_player.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mads_player.h; sourceTree = "<group>"; };
- 8CB5A9BD1253FD6800CB6BC7 /* mads_scene.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mads_scene.cpp; sourceTree = "<group>"; };
- 8CB5A9BE1253FD6800CB6BC7 /* mads_scene.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mads_scene.h; sourceTree = "<group>"; };
- 8CB5A9BF1253FD6900CB6BC7 /* mads_views.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mads_views.cpp; sourceTree = "<group>"; };
- 8CB5A9C01253FD6900CB6BC7 /* mads_views.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mads_views.h; sourceTree = "<group>"; };
- 8CB5A9D51253FDF400CB6BC7 /* drascula.dat */ = {isa = PBXFileReference; lastKnownFileType = file; path = drascula.dat; sourceTree = "<group>"; };
- 8CB5A9D61253FDF500CB6BC7 /* hugo.dat */ = {isa = PBXFileReference; lastKnownFileType = file; path = hugo.dat; sourceTree = "<group>"; };
- 8CB5A9D71253FDF500CB6BC7 /* m4.dat */ = {isa = PBXFileReference; lastKnownFileType = file; path = m4.dat; sourceTree = "<group>"; };
- 8CB5A9D81253FDF500CB6BC7 /* teenagent.dat */ = {isa = PBXFileReference; lastKnownFileType = file; path = teenagent.dat; sourceTree = "<group>"; };
- 8CD1ECC6126202AA00FA198C /* detection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = detection.cpp; sourceTree = "<group>"; };
- 8CD1ECC7126202AA00FA198C /* display.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = display.cpp; sourceTree = "<group>"; };
- 8CD1ECC8126202AA00FA198C /* display.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = display.h; sourceTree = "<group>"; };
- 8CD1ECCB126202AA00FA198C /* file.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = file.cpp; sourceTree = "<group>"; };
- 8CD1ECCC126202AA00FA198C /* file.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = file.h; sourceTree = "<group>"; };
- 8CD1ECCD126202AA00FA198C /* game.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = game.h; sourceTree = "<group>"; };
- 8CD1ECCF126202AA00FA198C /* hugo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hugo.cpp; sourceTree = "<group>"; };
- 8CD1ECD0126202AA00FA198C /* hugo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hugo.h; sourceTree = "<group>"; };
- 8CD1ECD1126202AA00FA198C /* intro.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = intro.cpp; sourceTree = "<group>"; };
- 8CD1ECD2126202AA00FA198C /* intro.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = intro.h; sourceTree = "<group>"; };
- 8CD1ECD3126202AA00FA198C /* inventory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = inventory.cpp; sourceTree = "<group>"; };
- 8CD1ECD4126202AA00FA198C /* inventory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = inventory.h; sourceTree = "<group>"; };
- 8CD1ECD7126202AA00FA198C /* mouse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mouse.cpp; sourceTree = "<group>"; };
- 8CD1ECD8126202AA00FA198C /* mouse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mouse.h; sourceTree = "<group>"; };
- 8CD1ECD9126202AA00FA198C /* parser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parser.cpp; sourceTree = "<group>"; };
- 8CD1ECDA126202AA00FA198C /* parser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = parser.h; sourceTree = "<group>"; };
- 8CD1ECDB126202AA00FA198C /* route.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = route.cpp; sourceTree = "<group>"; };
- 8CD1ECDC126202AA00FA198C /* route.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = route.h; sourceTree = "<group>"; };
- 8CD1ECDD126202AA00FA198C /* schedule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = schedule.cpp; sourceTree = "<group>"; };
- 8CD1ECDE126202AA00FA198C /* schedule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = schedule.h; sourceTree = "<group>"; };
- 8CD1ECDF126202AA00FA198C /* sound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound.cpp; sourceTree = "<group>"; };
- 8CD1ECE0126202AA00FA198C /* sound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound.h; sourceTree = "<group>"; };
- 8CD1ECE1126202AA00FA198C /* util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = util.cpp; sourceTree = "<group>"; };
- 8CD1ECE2126202AA00FA198C /* util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = util.h; sourceTree = "<group>"; };
- 8CD1ECE4126202AA00FA198C /* anim.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = anim.cpp; sourceTree = "<group>"; };
- 8CD1ECE5126202AA00FA198C /* anim.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = anim.h; sourceTree = "<group>"; };
- 8CD1ECE6126202AA00FA198C /* audio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = audio.cpp; sourceTree = "<group>"; };
- 8CD1ECE7126202AA00FA198C /* audio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = audio.h; sourceTree = "<group>"; };
- 8CD1ECE8126202AA00FA198C /* character.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = character.cpp; sourceTree = "<group>"; };
- 8CD1ECE9126202AA00FA198C /* character.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = character.h; sourceTree = "<group>"; };
- 8CD1ECEA126202AA00FA198C /* conversation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = conversation.cpp; sourceTree = "<group>"; };
- 8CD1ECEB126202AA00FA198C /* conversation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = conversation.h; sourceTree = "<group>"; };
- 8CD1ECEC126202AA00FA198C /* detection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = detection.cpp; sourceTree = "<group>"; };
- 8CD1ECED126202AA00FA198C /* drew.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = drew.cpp; sourceTree = "<group>"; };
- 8CD1ECEE126202AA00FA198C /* drew.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = drew.h; sourceTree = "<group>"; };
- 8CD1ECEF126202AA00FA198C /* flux.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = flux.cpp; sourceTree = "<group>"; };
- 8CD1ECF0126202AA00FA198C /* flux.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = flux.h; sourceTree = "<group>"; };
- 8CD1ECF1126202AA00FA198C /* font.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = font.cpp; sourceTree = "<group>"; };
- 8CD1ECF2126202AA00FA198C /* font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = font.h; sourceTree = "<group>"; };
- 8CD1ECF3126202AA00FA198C /* hotspot.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hotspot.cpp; sourceTree = "<group>"; };
- 8CD1ECF4126202AA00FA198C /* hotspot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hotspot.h; sourceTree = "<group>"; };
- 8CD1ECF7126202AA00FA198C /* movie.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = movie.cpp; sourceTree = "<group>"; };
- 8CD1ECF8126202AA00FA198C /* movie.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = movie.h; sourceTree = "<group>"; };
- 8CD1ECF9126202AA00FA198C /* path.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = path.cpp; sourceTree = "<group>"; };
- 8CD1ECFA126202AA00FA198C /* path.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = path.h; sourceTree = "<group>"; };
- 8CD1ECFB126202AA00FA198C /* picture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = picture.cpp; sourceTree = "<group>"; };
- 8CD1ECFC126202AA00FA198C /* picture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = picture.h; sourceTree = "<group>"; };
- 8CD1ECFD126202AA00FA198C /* resource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resource.cpp; sourceTree = "<group>"; };
- 8CD1ECFE126202AA00FA198C /* resource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resource.h; sourceTree = "<group>"; };
- 8CD1ECFF126202AA00FA198C /* script.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script.cpp; sourceTree = "<group>"; };
- 8CD1ED00126202AA00FA198C /* script.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = script.h; sourceTree = "<group>"; };
- 8CD1ED01126202AA00FA198C /* script_func.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_func.cpp; sourceTree = "<group>"; };
- 8CD1ED02126202AA00FA198C /* script_func.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = script_func.h; sourceTree = "<group>"; };
- 8CD1ED03126202AA00FA198C /* state.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = state.cpp; sourceTree = "<group>"; };
- 8CD1ED04126202AA00FA198C /* state.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = state.h; sourceTree = "<group>"; };
- 8CD1ED05126202AA00FA198C /* text.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = text.cpp; sourceTree = "<group>"; };
- 8CD1ED06126202AA00FA198C /* text.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = text.h; sourceTree = "<group>"; };
- 8CD1ED07126202AA00FA198C /* tools.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tools.cpp; sourceTree = "<group>"; };
- 8CD1ED08126202AA00FA198C /* tools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tools.h; sourceTree = "<group>"; };
- 8CD1ED09126202AA00FA198C /* toon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = toon.cpp; sourceTree = "<group>"; };
- 8CD1ED0A126202AA00FA198C /* toon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = toon.h; sourceTree = "<group>"; };
- 8CD1ED871262030100FA198C /* toon.dat */ = {isa = PBXFileReference; lastKnownFileType = file; path = toon.dat; sourceTree = "<group>"; };
- 8CD80C89126271A9001C6C87 /* surface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = surface.cpp; sourceTree = "<group>"; };
- 8CD80C8A126271A9001C6C87 /* surface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = surface.h; sourceTree = "<group>"; };
- 8CD80C90126271BD001C6C87 /* gfx_towns.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gfx_towns.cpp; sourceTree = "<group>"; };
- 8CD80CBF1262729F001C6C87 /* actor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = actor.cpp; sourceTree = "<group>"; };
- 8CD80CC01262729F001C6C87 /* actor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = actor.h; sourceTree = "<group>"; };
- 8CD80CC11262729F001C6C87 /* animation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = animation.cpp; sourceTree = "<group>"; };
- 8CD80CC21262729F001C6C87 /* animation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = animation.h; sourceTree = "<group>"; };
- 8CD80CC31262729F001C6C87 /* callbacks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = callbacks.cpp; sourceTree = "<group>"; };
- 8CD80CC41262729F001C6C87 /* console.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = console.cpp; sourceTree = "<group>"; };
- 8CD80CC51262729F001C6C87 /* console.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = console.h; sourceTree = "<group>"; };
- 8CD80CC61262729F001C6C87 /* detection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = detection.cpp; sourceTree = "<group>"; };
- 8CD80CC71262729F001C6C87 /* dialog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dialog.cpp; sourceTree = "<group>"; };
- 8CD80CC81262729F001C6C87 /* dialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dialog.h; sourceTree = "<group>"; };
- 8CD80CC91262729F001C6C87 /* font.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = font.cpp; sourceTree = "<group>"; };
- 8CD80CCA1262729F001C6C87 /* font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = font.h; sourceTree = "<group>"; };
- 8CD80CCB1262729F001C6C87 /* inventory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = inventory.cpp; sourceTree = "<group>"; };
- 8CD80CCC1262729F001C6C87 /* inventory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = inventory.h; sourceTree = "<group>"; };
- 8CD80CCE1262729F001C6C87 /* music.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = music.cpp; sourceTree = "<group>"; };
- 8CD80CCF1262729F001C6C87 /* music.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = music.h; sourceTree = "<group>"; };
- 8CD80CD01262729F001C6C87 /* objects.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = objects.cpp; sourceTree = "<group>"; };
- 8CD80CD11262729F001C6C87 /* objects.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = objects.h; sourceTree = "<group>"; };
- 8CD80CD21262729F001C6C87 /* pack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pack.cpp; sourceTree = "<group>"; };
- 8CD80CD3126272A0001C6C87 /* pack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pack.h; sourceTree = "<group>"; };
- 8CD80CD4126272A0001C6C87 /* resources.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resources.cpp; sourceTree = "<group>"; };
- 8CD80CD5126272A0001C6C87 /* resources.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resources.h; sourceTree = "<group>"; };
- 8CD80CD6126272A0001C6C87 /* scene.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scene.cpp; sourceTree = "<group>"; };
- 8CD80CD7126272A0001C6C87 /* scene.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scene.h; sourceTree = "<group>"; };
- 8CD80CD8126272A0001C6C87 /* segment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = segment.cpp; sourceTree = "<group>"; };
- 8CD80CD9126272A0001C6C87 /* segment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = segment.h; sourceTree = "<group>"; };
- 8CD80CDA126272A0001C6C87 /* surface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = surface.cpp; sourceTree = "<group>"; };
- 8CD80CDB126272A0001C6C87 /* surface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = surface.h; sourceTree = "<group>"; };
- 8CD80CDC126272A0001C6C87 /* surface_list.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = surface_list.cpp; sourceTree = "<group>"; };
- 8CD80CDD126272A0001C6C87 /* surface_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = surface_list.h; sourceTree = "<group>"; };
- 8CD80CDE126272A0001C6C87 /* teenagent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = teenagent.cpp; sourceTree = "<group>"; };
- 8CD80CDF126272A0001C6C87 /* teenagent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = teenagent.h; sourceTree = "<group>"; };
- 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
- DF093E5C0F63CAD4002D821E /* pn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pn.cpp; sourceTree = "<group>"; };
- DF093E5D0F63CAD4002D821E /* script_pn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_pn.cpp; sourceTree = "<group>"; };
- DF093E5E0F63CAD4002D821E /* vga_pn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vga_pn.cpp; sourceTree = "<group>"; };
- DF09422A0F63CB26002D821E /* ScummVM.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ScummVM.app; sourceTree = BUILT_PRODUCTS_DIR; };
- DF0942390F63CB9A002D821E /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
- DF09423C0F63CB9A002D821E /* sdl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sdl.cpp; sourceTree = "<group>"; };
- DF09423D0F63CB9A002D821E /* sdl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sdl.h; sourceTree = "<group>"; };
- DF0944170F63FA8F002D821E /* QuickTime.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickTime.framework; path = System/Library/Frameworks/QuickTime.framework; sourceTree = SDKROOT; };
- DF0944240F63FB2C002D821E /* CoreMIDI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMIDI.framework; path = System/Library/Frameworks/CoreMIDI.framework; sourceTree = SDKROOT; };
- DF0944300F63FBB3002D821E /* coreaudio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = coreaudio.cpp; sourceTree = "<group>"; };
- DF0944310F63FBB3002D821E /* coremidi.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = coremidi.cpp; sourceTree = "<group>"; };
- DF0944370F63FBFE002D821E /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; };
- DF09446D0F63FCCB002D821E /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = System/Library/Frameworks/ApplicationServices.framework; sourceTree = SDKROOT; };
- DF09446E0F63FCCB002D821E /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
- DF0944770F63FD10002D821E /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
- DF09447F0F63FD67002D821E /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; };
- DF0944B00F6430ED002D821E /* scummvm.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = scummvm.icns; path = ../../icons/scummvm.icns; sourceTree = SOURCE_ROOT; };
- DF09CC070FAC4E1900A5AFD7 /* batplayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = batplayer.cpp; sourceTree = "<group>"; };
- DF09CC080FAC4E1900A5AFD7 /* batplayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = batplayer.h; sourceTree = "<group>"; };
- DF09CC090FAC4E1900A5AFD7 /* demoplayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = demoplayer.cpp; sourceTree = "<group>"; };
- DF09CC0A0FAC4E1900A5AFD7 /* demoplayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = demoplayer.h; sourceTree = "<group>"; };
- DF09CC0B0FAC4E1900A5AFD7 /* scnplayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scnplayer.cpp; sourceTree = "<group>"; };
- DF09CC0C0FAC4E1900A5AFD7 /* scnplayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scnplayer.h; sourceTree = "<group>"; };
- DF09CC0D0FAC4E1900A5AFD7 /* draw_fascin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = draw_fascin.cpp; sourceTree = "<group>"; };
- DF09CC0F0FAC4E1900A5AFD7 /* inter_fascin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = inter_fascin.cpp; sourceTree = "<group>"; };
- DF09CC1D0FAC4E6200A5AFD7 /* scumm_v0.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scumm_v0.h; sourceTree = "<group>"; };
- DF09CC1E0FAC4E6200A5AFD7 /* scumm_v2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scumm_v2.h; sourceTree = "<group>"; };
- DF09CC1F0FAC4E6200A5AFD7 /* scumm_v3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scumm_v3.h; sourceTree = "<group>"; };
- DF09CC200FAC4E6200A5AFD7 /* scumm_v4.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scumm_v4.h; sourceTree = "<group>"; };
- DF09CC210FAC4E6200A5AFD7 /* scumm_v5.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scumm_v5.h; sourceTree = "<group>"; };
- DF09CC220FAC4E6200A5AFD7 /* scumm_v6.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scumm_v6.h; sourceTree = "<group>"; };
- DF09CC230FAC4E6200A5AFD7 /* scumm_v7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scumm_v7.h; sourceTree = "<group>"; };
- DF09CC240FAC4E6200A5AFD7 /* scumm_v8.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scumm_v8.h; sourceTree = "<group>"; };
- DF09CC260FAC4EAB00A5AFD7 /* script_v3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_v3.cpp; sourceTree = "<group>"; };
- DF09CC270FAC4EAB00A5AFD7 /* script_v4.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_v4.cpp; sourceTree = "<group>"; };
- DF0E30391252C5BD0082D593 /* cms.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cms.cpp; sourceTree = "<group>"; };
- DF203F461380C06E0056300A /* gui-manager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "gui-manager.cpp"; sourceTree = "<group>"; };
- DF203F531380C2740056300A /* avi_decoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = avi_decoder.cpp; path = ../../video/avi_decoder.cpp; sourceTree = SOURCE_ROOT; };
- DF203F541380C2740056300A /* avi_decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = avi_decoder.h; path = ../../video/avi_decoder.h; sourceTree = SOURCE_ROOT; };
- DF203F551380C2740056300A /* coktel_decoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = coktel_decoder.cpp; path = ../../video/coktel_decoder.cpp; sourceTree = SOURCE_ROOT; };
- DF203F561380C2740056300A /* coktel_decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = coktel_decoder.h; path = ../../video/coktel_decoder.h; sourceTree = SOURCE_ROOT; };
- DF203F571380C2740056300A /* dxa_decoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dxa_decoder.cpp; path = ../../video/dxa_decoder.cpp; sourceTree = SOURCE_ROOT; };
- DF203F581380C2740056300A /* dxa_decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dxa_decoder.h; path = ../../video/dxa_decoder.h; sourceTree = SOURCE_ROOT; };
- DF203F591380C2740056300A /* flic_decoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = flic_decoder.cpp; path = ../../video/flic_decoder.cpp; sourceTree = SOURCE_ROOT; };
- DF203F5A1380C2740056300A /* flic_decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = flic_decoder.h; path = ../../video/flic_decoder.h; sourceTree = SOURCE_ROOT; };
- DF203F5D1380C2740056300A /* qt_decoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = qt_decoder.cpp; path = ../../video/qt_decoder.cpp; sourceTree = SOURCE_ROOT; };
- DF203F5E1380C2750056300A /* qt_decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = qt_decoder.h; path = ../../video/qt_decoder.h; sourceTree = SOURCE_ROOT; };
- DF203F5F1380C2750056300A /* smk_decoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = smk_decoder.cpp; path = ../../video/smk_decoder.cpp; sourceTree = SOURCE_ROOT; };
- DF203F601380C2750056300A /* smk_decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = smk_decoder.h; path = ../../video/smk_decoder.h; sourceTree = SOURCE_ROOT; };
- DF203F611380C2750056300A /* video_decoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = video_decoder.cpp; path = ../../video/video_decoder.cpp; sourceTree = SOURCE_ROOT; };
- DF203F621380C2750056300A /* video_decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = video_decoder.h; path = ../../video/video_decoder.h; sourceTree = SOURCE_ROOT; };
- DF203F7C1380C2920056300A /* cdtoons.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cdtoons.cpp; path = ../../video/codecs/cdtoons.cpp; sourceTree = SOURCE_ROOT; };
- DF203F7D1380C2920056300A /* cdtoons.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cdtoons.h; path = ../../video/codecs/cdtoons.h; sourceTree = SOURCE_ROOT; };
- DF203F7E1380C2920056300A /* cinepak.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cinepak.cpp; path = ../../video/codecs/cinepak.cpp; sourceTree = SOURCE_ROOT; };
- DF203F7F1380C2920056300A /* cinepak.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cinepak.h; path = ../../video/codecs/cinepak.h; sourceTree = SOURCE_ROOT; };
- DF203F801380C2920056300A /* codec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = codec.h; path = ../../video/codecs/codec.h; sourceTree = SOURCE_ROOT; };
- DF203F811380C2920056300A /* indeo3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = indeo3.cpp; path = ../../video/codecs/indeo3.cpp; sourceTree = SOURCE_ROOT; };
- DF203F821380C2920056300A /* indeo3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = indeo3.h; path = ../../video/codecs/indeo3.h; sourceTree = SOURCE_ROOT; };
- DF203F831380C2920056300A /* mjpeg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mjpeg.cpp; path = ../../video/codecs/mjpeg.cpp; sourceTree = SOURCE_ROOT; };
- DF203F841380C2920056300A /* mjpeg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mjpeg.h; path = ../../video/codecs/mjpeg.h; sourceTree = SOURCE_ROOT; };
- DF203F851380C2920056300A /* msrle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = msrle.cpp; path = ../../video/codecs/msrle.cpp; sourceTree = SOURCE_ROOT; };
- DF203F861380C2920056300A /* msrle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = msrle.h; path = ../../video/codecs/msrle.h; sourceTree = SOURCE_ROOT; };
- DF203F871380C2920056300A /* msvideo1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = msvideo1.cpp; path = ../../video/codecs/msvideo1.cpp; sourceTree = SOURCE_ROOT; };
- DF203F881380C2920056300A /* msvideo1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = msvideo1.h; path = ../../video/codecs/msvideo1.h; sourceTree = SOURCE_ROOT; };
- DF203F8C1380C2920056300A /* qtrle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = qtrle.cpp; path = ../../video/codecs/qtrle.cpp; sourceTree = SOURCE_ROOT; };
- DF203F8D1380C2920056300A /* qtrle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = qtrle.h; path = ../../video/codecs/qtrle.h; sourceTree = SOURCE_ROOT; };
- DF203F8E1380C2920056300A /* rpza.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = rpza.cpp; path = ../../video/codecs/rpza.cpp; sourceTree = SOURCE_ROOT; };
- DF203F8F1380C2920056300A /* rpza.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = rpza.h; path = ../../video/codecs/rpza.h; sourceTree = SOURCE_ROOT; };
- DF203F901380C2920056300A /* smc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = smc.cpp; path = ../../video/codecs/smc.cpp; sourceTree = SOURCE_ROOT; };
- DF203F911380C2920056300A /* smc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = smc.h; path = ../../video/codecs/smc.h; sourceTree = SOURCE_ROOT; };
- DF203F921380C2920056300A /* truemotion1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = truemotion1.cpp; path = ../../video/codecs/truemotion1.cpp; sourceTree = SOURCE_ROOT; };
- DF203F931380C2920056300A /* truemotion1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = truemotion1.h; path = ../../video/codecs/truemotion1.h; sourceTree = SOURCE_ROOT; };
- DF203F941380C2920056300A /* truemotion1data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = truemotion1data.h; path = ../../video/codecs/truemotion1data.h; sourceTree = SOURCE_ROOT; };
- DF203FC01380C3BC0056300A /* console.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = console.cpp; sourceTree = "<group>"; };
- DF203FC11380C3BC0056300A /* console.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = console.h; sourceTree = "<group>"; };
- DF203FC21380C3BC0056300A /* dialogs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dialogs.cpp; sourceTree = "<group>"; };
- DF203FC31380C3BC0056300A /* dialogs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dialogs.h; sourceTree = "<group>"; };
- DF203FC41380C3BC0056300A /* file_v1d.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = file_v1d.cpp; sourceTree = "<group>"; };
- DF203FC51380C3BC0056300A /* file_v1w.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = file_v1w.cpp; sourceTree = "<group>"; };
- DF203FC61380C3BC0056300A /* file_v2d.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = file_v2d.cpp; sourceTree = "<group>"; };
- DF203FC71380C3BC0056300A /* file_v2w.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = file_v2w.cpp; sourceTree = "<group>"; };
- DF203FC81380C3BC0056300A /* file_v3d.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = file_v3d.cpp; sourceTree = "<group>"; };
- DF203FC91380C3BC0056300A /* object_v1d.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = object_v1d.cpp; sourceTree = "<group>"; };
- DF203FCA1380C3BC0056300A /* object_v1w.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = object_v1w.cpp; sourceTree = "<group>"; };
- DF203FCB1380C3BC0056300A /* object_v2d.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = object_v2d.cpp; sourceTree = "<group>"; };
- DF203FCC1380C3BC0056300A /* object_v3d.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = object_v3d.cpp; sourceTree = "<group>"; };
- DF203FCD1380C3BC0056300A /* object.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = object.cpp; sourceTree = "<group>"; };
- DF203FCE1380C3BC0056300A /* object.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = object.h; sourceTree = "<group>"; };
- DF203FCF1380C3BC0056300A /* parser_v1d.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parser_v1d.cpp; sourceTree = "<group>"; };
- DF203FD01380C3BC0056300A /* parser_v1w.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parser_v1w.cpp; sourceTree = "<group>"; };
- DF203FD11380C3BC0056300A /* parser_v2d.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parser_v2d.cpp; sourceTree = "<group>"; };
- DF203FD21380C3BC0056300A /* parser_v3d.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parser_v3d.cpp; sourceTree = "<group>"; };
- DF203FD31380C3BC0056300A /* text.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = text.cpp; sourceTree = "<group>"; };
- DF203FD41380C3BC0056300A /* text.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = text.h; sourceTree = "<group>"; };
- DF2040221380C8B70056300A /* editable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = editable.cpp; path = widgets/editable.cpp; sourceTree = "<group>"; };
- DF2040231380C8B70056300A /* editable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = editable.h; path = widgets/editable.h; sourceTree = "<group>"; };
- DF2040241380C8B70056300A /* edittext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = edittext.cpp; path = widgets/edittext.cpp; sourceTree = "<group>"; };
- DF2040251380C8B70056300A /* edittext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = edittext.h; path = widgets/edittext.h; sourceTree = "<group>"; };
- DF2040261380C8B70056300A /* list.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = list.cpp; path = widgets/list.cpp; sourceTree = "<group>"; };
- DF2040271380C8B70056300A /* list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = list.h; path = widgets/list.h; sourceTree = "<group>"; };
- DF2040281380C8B70056300A /* popup.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = popup.cpp; path = widgets/popup.cpp; sourceTree = "<group>"; };
- DF2040291380C8B70056300A /* popup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = popup.h; path = widgets/popup.h; sourceTree = "<group>"; };
- DF20402A1380C8B70056300A /* scrollbar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = scrollbar.cpp; path = widgets/scrollbar.cpp; sourceTree = "<group>"; };
- DF20402B1380C8B70056300A /* scrollbar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = scrollbar.h; path = widgets/scrollbar.h; sourceTree = "<group>"; };
- DF20402C1380C8B70056300A /* tab.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tab.cpp; path = widgets/tab.cpp; sourceTree = "<group>"; };
- DF20402D1380C8B70056300A /* tab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tab.h; path = widgets/tab.h; sourceTree = "<group>"; };
- DF2040471380CA230056300A /* audiostream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = audiostream.cpp; path = ../../audio/audiostream.cpp; sourceTree = SOURCE_ROOT; };
- DF2040481380CA230056300A /* audiostream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = audiostream.h; path = ../../audio/audiostream.h; sourceTree = SOURCE_ROOT; };
- DF2040491380CA230056300A /* fmopl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = fmopl.cpp; path = ../../audio/fmopl.cpp; sourceTree = SOURCE_ROOT; };
- DF20404A1380CA230056300A /* fmopl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = fmopl.h; path = ../../audio/fmopl.h; sourceTree = SOURCE_ROOT; };
- DF20404B1380CA230056300A /* mididrv.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mididrv.cpp; path = ../../audio/mididrv.cpp; sourceTree = SOURCE_ROOT; };
- DF20404C1380CA230056300A /* mididrv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mididrv.h; path = ../../audio/mididrv.h; sourceTree = SOURCE_ROOT; };
- DF20404D1380CA230056300A /* midiparser_smf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = midiparser_smf.cpp; path = ../../audio/midiparser_smf.cpp; sourceTree = SOURCE_ROOT; };
- DF20404E1380CA230056300A /* midiparser_xmidi.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = midiparser_xmidi.cpp; path = ../../audio/midiparser_xmidi.cpp; sourceTree = SOURCE_ROOT; };
- DF20404F1380CA230056300A /* midiparser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = midiparser.cpp; path = ../../audio/midiparser.cpp; sourceTree = SOURCE_ROOT; };
- DF2040501380CA230056300A /* midiparser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = midiparser.h; path = ../../audio/midiparser.h; sourceTree = SOURCE_ROOT; };
- DF2040511380CA230056300A /* midiplayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = midiplayer.cpp; path = ../../audio/midiplayer.cpp; sourceTree = SOURCE_ROOT; };
- DF2040521380CA230056300A /* midiplayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = midiplayer.h; path = ../../audio/midiplayer.h; sourceTree = SOURCE_ROOT; };
- DF2040531380CA230056300A /* mixer_intern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mixer_intern.h; path = ../../audio/mixer_intern.h; sourceTree = SOURCE_ROOT; };
- DF2040541380CA230056300A /* mixer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mixer.cpp; path = ../../audio/mixer.cpp; sourceTree = SOURCE_ROOT; };
- DF2040551380CA230056300A /* mixer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mixer.h; path = ../../audio/mixer.h; sourceTree = SOURCE_ROOT; };
- DF2040561380CA230056300A /* mpu401.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mpu401.cpp; path = ../../audio/mpu401.cpp; sourceTree = SOURCE_ROOT; };
- DF2040571380CA230056300A /* mpu401.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mpu401.h; path = ../../audio/mpu401.h; sourceTree = SOURCE_ROOT; };
- DF2040581380CA230056300A /* musicplugin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = musicplugin.cpp; path = ../../audio/musicplugin.cpp; sourceTree = SOURCE_ROOT; };
- DF2040591380CA230056300A /* musicplugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = musicplugin.h; path = ../../audio/musicplugin.h; sourceTree = SOURCE_ROOT; };
- DF20405A1380CA230056300A /* rate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = rate.cpp; path = ../../audio/rate.cpp; sourceTree = SOURCE_ROOT; };
- DF20405B1380CA230056300A /* rate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = rate.h; path = ../../audio/rate.h; sourceTree = SOURCE_ROOT; };
- DF20405C1380CA230056300A /* timestamp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = timestamp.cpp; path = ../../audio/timestamp.cpp; sourceTree = SOURCE_ROOT; };
- DF20405D1380CA230056300A /* timestamp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = timestamp.h; path = ../../audio/timestamp.h; sourceTree = SOURCE_ROOT; };
- DF2040831380CA400056300A /* adpcm_intern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = adpcm_intern.h; path = ../../audio/decoders/adpcm_intern.h; sourceTree = SOURCE_ROOT; };
- DF2040841380CA400056300A /* adpcm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = adpcm.cpp; path = ../../audio/decoders/adpcm.cpp; sourceTree = SOURCE_ROOT; };
- DF2040851380CA400056300A /* adpcm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = adpcm.h; path = ../../audio/decoders/adpcm.h; sourceTree = SOURCE_ROOT; };
- DF2040861380CA400056300A /* aiff.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = aiff.cpp; path = ../../audio/decoders/aiff.cpp; sourceTree = SOURCE_ROOT; };
- DF2040871380CA400056300A /* aiff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = aiff.h; path = ../../audio/decoders/aiff.h; sourceTree = SOURCE_ROOT; };
- DF2040881380CA400056300A /* flac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = flac.cpp; path = ../../audio/decoders/flac.cpp; sourceTree = SOURCE_ROOT; };
- DF2040891380CA400056300A /* flac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = flac.h; path = ../../audio/decoders/flac.h; sourceTree = SOURCE_ROOT; };
- DF20408A1380CA400056300A /* iff_sound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = iff_sound.cpp; path = ../../audio/decoders/iff_sound.cpp; sourceTree = SOURCE_ROOT; };
- DF20408B1380CA400056300A /* iff_sound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iff_sound.h; path = ../../audio/decoders/iff_sound.h; sourceTree = SOURCE_ROOT; };
- DF20408C1380CA400056300A /* mac_snd.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mac_snd.cpp; path = ../../audio/decoders/mac_snd.cpp; sourceTree = SOURCE_ROOT; };
- DF20408D1380CA400056300A /* mac_snd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mac_snd.h; path = ../../audio/decoders/mac_snd.h; sourceTree = SOURCE_ROOT; };
- DF20408E1380CA400056300A /* mp3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mp3.cpp; path = ../../audio/decoders/mp3.cpp; sourceTree = SOURCE_ROOT; };
- DF20408F1380CA400056300A /* mp3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mp3.h; path = ../../audio/decoders/mp3.h; sourceTree = SOURCE_ROOT; };
- DF2040901380CA400056300A /* raw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = raw.cpp; path = ../../audio/decoders/raw.cpp; sourceTree = SOURCE_ROOT; };
- DF2040911380CA400056300A /* raw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = raw.h; path = ../../audio/decoders/raw.h; sourceTree = SOURCE_ROOT; };
- DF2040921380CA400056300A /* vag.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = vag.cpp; path = ../../audio/decoders/vag.cpp; sourceTree = SOURCE_ROOT; };
- DF2040931380CA400056300A /* vag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vag.h; path = ../../audio/decoders/vag.h; sourceTree = SOURCE_ROOT; };
- DF2040941380CA400056300A /* voc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = voc.cpp; path = ../../audio/decoders/voc.cpp; sourceTree = SOURCE_ROOT; };
- DF2040951380CA400056300A /* voc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = voc.h; path = ../../audio/decoders/voc.h; sourceTree = SOURCE_ROOT; };
- DF2040961380CA400056300A /* vorbis.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = vorbis.cpp; path = ../../audio/decoders/vorbis.cpp; sourceTree = SOURCE_ROOT; };
- DF2040971380CA400056300A /* vorbis.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vorbis.h; path = ../../audio/decoders/vorbis.h; sourceTree = SOURCE_ROOT; };
- DF2040981380CA400056300A /* wave.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = wave.cpp; path = ../../audio/decoders/wave.cpp; sourceTree = SOURCE_ROOT; };
- DF2040991380CA400056300A /* wave.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = wave.h; path = ../../audio/decoders/wave.h; sourceTree = SOURCE_ROOT; };
- DF2040BC1380CA810056300A /* infogrames.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = infogrames.cpp; path = ../../audio/mods/infogrames.cpp; sourceTree = SOURCE_ROOT; };
- DF2040BD1380CA810056300A /* infogrames.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = infogrames.h; path = ../../audio/mods/infogrames.h; sourceTree = SOURCE_ROOT; };
- DF2040BE1380CA810056300A /* maxtrax.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = maxtrax.cpp; path = ../../audio/mods/maxtrax.cpp; sourceTree = SOURCE_ROOT; };
- DF2040BF1380CA810056300A /* maxtrax.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = maxtrax.h; path = ../../audio/mods/maxtrax.h; sourceTree = SOURCE_ROOT; };
- DF2040C01380CA810056300A /* module.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = module.cpp; path = ../../audio/mods/module.cpp; sourceTree = SOURCE_ROOT; };
- DF2040C11380CA810056300A /* module.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = module.h; path = ../../audio/mods/module.h; sourceTree = SOURCE_ROOT; };
- DF2040C21380CA810056300A /* paula.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = paula.cpp; path = ../../audio/mods/paula.cpp; sourceTree = SOURCE_ROOT; };
- DF2040C31380CA810056300A /* paula.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = paula.h; path = ../../audio/mods/paula.h; sourceTree = SOURCE_ROOT; };
- DF2040C41380CA810056300A /* protracker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = protracker.cpp; path = ../../audio/mods/protracker.cpp; sourceTree = SOURCE_ROOT; };
- DF2040C51380CA810056300A /* protracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = protracker.h; path = ../../audio/mods/protracker.h; sourceTree = SOURCE_ROOT; };
- DF2040C61380CA810056300A /* rjp1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = rjp1.cpp; path = ../../audio/mods/rjp1.cpp; sourceTree = SOURCE_ROOT; };
- DF2040C71380CA810056300A /* rjp1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = rjp1.h; path = ../../audio/mods/rjp1.h; sourceTree = SOURCE_ROOT; };
- DF2040C81380CA810056300A /* soundfx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = soundfx.cpp; path = ../../audio/mods/soundfx.cpp; sourceTree = SOURCE_ROOT; };
- DF2040C91380CA810056300A /* soundfx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = soundfx.h; path = ../../audio/mods/soundfx.h; sourceTree = SOURCE_ROOT; };
- DF2040CA1380CA810056300A /* tfmx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tfmx.cpp; path = ../../audio/mods/tfmx.cpp; sourceTree = SOURCE_ROOT; };
- DF2040CB1380CA810056300A /* tfmx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tfmx.h; path = ../../audio/mods/tfmx.h; sourceTree = SOURCE_ROOT; };
- DF2040E51380CAA40056300A /* adlib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = adlib.cpp; path = ../../audio/softsynth/adlib.cpp; sourceTree = SOURCE_ROOT; };
- DF2040E61380CAA40056300A /* appleiigs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = appleiigs.cpp; path = ../../audio/softsynth/appleiigs.cpp; sourceTree = SOURCE_ROOT; };
- DF2040E71380CAA40056300A /* cms.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cms.cpp; path = ../../audio/softsynth/cms.cpp; sourceTree = SOURCE_ROOT; };
- DF2040E81380CAA40056300A /* cms.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cms.h; path = ../../audio/softsynth/cms.h; sourceTree = SOURCE_ROOT; };
- DF2040E91380CAA40056300A /* eas.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = eas.cpp; path = ../../audio/softsynth/eas.cpp; sourceTree = SOURCE_ROOT; };
- DF2040EA1380CAA40056300A /* emumidi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = emumidi.h; path = ../../audio/softsynth/emumidi.h; sourceTree = SOURCE_ROOT; };
- DF2040EB1380CAA40056300A /* fluidsynth.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = fluidsynth.cpp; path = ../../audio/softsynth/fluidsynth.cpp; sourceTree = SOURCE_ROOT; };
- DF2040EC1380CAA40056300A /* mt32.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mt32.cpp; path = ../../audio/softsynth/mt32.cpp; sourceTree = SOURCE_ROOT; };
- DF2040ED1380CAA40056300A /* pcspk.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pcspk.cpp; path = ../../audio/softsynth/pcspk.cpp; sourceTree = SOURCE_ROOT; };
- DF2040EE1380CAA40056300A /* pcspk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pcspk.h; path = ../../audio/softsynth/pcspk.h; sourceTree = SOURCE_ROOT; };
- DF2040EF1380CAA40056300A /* sid.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = sid.cpp; path = ../../audio/softsynth/sid.cpp; sourceTree = SOURCE_ROOT; };
- DF2040F01380CAA40056300A /* sid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sid.h; path = ../../audio/softsynth/sid.h; sourceTree = SOURCE_ROOT; };
- DF2040F11380CAA40056300A /* wave6581.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = wave6581.cpp; path = ../../audio/softsynth/wave6581.cpp; sourceTree = SOURCE_ROOT; };
- DF224E020FB23BC500C8E453 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
- DF2EC3E410E6490800765801 /* browser_osx.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = browser_osx.mm; sourceTree = "<group>"; };
- DF2EC3F610E64C0C00765801 /* dialogs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dialogs.cpp; sourceTree = "<group>"; };
- DF2EC3F710E64C0C00765801 /* dialogs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dialogs.h; sourceTree = "<group>"; };
- DF2EC3FD10E64C4300765801 /* animator_tim.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = animator_tim.cpp; sourceTree = "<group>"; };
- DF2EC40310E64C8000765801 /* event.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = event.cpp; sourceTree = "<group>"; };
- DF2EC40410E64C8000765801 /* event.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = event.h; sourceTree = "<group>"; };
- DF2EC4FD10E64D7C00765801 /* player_pce.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = player_pce.cpp; sourceTree = "<group>"; };
- DF2EC4FE10E64D7C00765801 /* player_pce.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = player_pce.h; sourceTree = "<group>"; };
- DF2EC4FF10E64D7C00765801 /* player_sid.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = player_sid.cpp; sourceTree = "<group>"; };
- DF2EC50010E64D7C00765801 /* player_sid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = player_sid.h; sourceTree = "<group>"; };
- DF2EC50910E64DB300765801 /* textconsole.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = textconsole.cpp; sourceTree = "<group>"; };
- DF2EC50A10E64DB300765801 /* textconsole.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = textconsole.h; sourceTree = "<group>"; };
- DF2FFB900F485D890006E566 /* dither.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dither.cpp; sourceTree = "<group>"; };
- DF2FFB910F485D890006E566 /* dither.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dither.h; sourceTree = "<group>"; };
- DF2FFB920F485D890006E566 /* pixelformat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pixelformat.h; sourceTree = "<group>"; };
- DF2FFBD10F485DFB0006E566 /* debug.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug.cpp; sourceTree = "<group>"; };
- DF2FFBD20F485DFB0006E566 /* debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug.h; sourceTree = "<group>"; };
- DF2FFBD60F485E360006E566 /* gui-manager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gui-manager.h"; sourceTree = "<group>"; };
- DF2FFBDB0F485E480006E566 /* scummclassic.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = scummclassic.zip; sourceTree = "<group>"; };
- DF2FFBF80F4860A60006E566 /* posix-saves.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "posix-saves.cpp"; sourceTree = "<group>"; };
- DF2FFBF90F4860A60006E566 /* posix-saves.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "posix-saves.h"; sourceTree = "<group>"; };
- DF2FFC1F0F4862520006E566 /* bmv.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bmv.cpp; sourceTree = "<group>"; };
- DF2FFC200F4862520006E566 /* dialogs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dialogs.cpp; sourceTree = "<group>"; };
- DF2FFC210F4862520006E566 /* dialogs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dialogs.h; sourceTree = "<group>"; };
- DF2FFC220F4862520006E566 /* drives.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = drives.cpp; sourceTree = "<group>"; };
- DF2FFC230F4862520006E566 /* drives.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = drives.h; sourceTree = "<group>"; };
- DF2FFC240F4862520006E566 /* mareels.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mareels.h; sourceTree = "<group>"; };
- DF2FFC250F4862520006E566 /* pdisplay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pdisplay.h; sourceTree = "<group>"; };
- DF2FFC260F4862520006E566 /* play.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = play.h; sourceTree = "<group>"; };
- DF2FFC270F4862520006E566 /* sysvar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sysvar.cpp; sourceTree = "<group>"; };
- DF2FFC280F4862520006E566 /* sysvar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sysvar.h; sourceTree = "<group>"; };
- DF2FFC2E0F48628A0006E566 /* gui_lol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gui_lol.cpp; sourceTree = "<group>"; };
- DF2FFC2F0F48628A0006E566 /* gui_lol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gui_lol.h; sourceTree = "<group>"; };
- DF2FFC300F48628A0006E566 /* items_lol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = items_lol.cpp; sourceTree = "<group>"; };
- DF2FFC310F48628A0006E566 /* script_lol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_lol.cpp; sourceTree = "<group>"; };
- DF2FFC320F48628A0006E566 /* sequences_lol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sequences_lol.cpp; sourceTree = "<group>"; };
- DF2FFC330F48628A0006E566 /* sound_midi.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound_midi.cpp; sourceTree = "<group>"; };
- DF2FFC360F48628A0006E566 /* util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = util.cpp; sourceTree = "<group>"; };
- DF2FFC370F48628A0006E566 /* util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = util.h; sourceTree = "<group>"; };
- DF2FFC490F4863100006E566 /* scene_lol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scene_lol.cpp; sourceTree = "<group>"; };
- DF2FFC4C0F4863560006E566 /* advancedDetector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = advancedDetector.cpp; sourceTree = "<group>"; };
- DF2FFC4D0F4863560006E566 /* advancedDetector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = advancedDetector.h; sourceTree = "<group>"; };
- DF2FFC5B0F4866E70006E566 /* base-backend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "base-backend.cpp"; sourceTree = "<group>"; };
- DF2FFC5C0F4866E70006E566 /* base-backend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "base-backend.h"; sourceTree = "<group>"; };
- DF2FFC600F48672D0006E566 /* resource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resource.cpp; sourceTree = "<group>"; };
- DF2FFC610F48672D0006E566 /* resource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resource.h; sourceTree = "<group>"; };
- DF2FFC620F48672D0006E566 /* resource_hrs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resource_hrs.cpp; sourceTree = "<group>"; };
- DF2FFC630F48672D0006E566 /* resource_res.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resource_res.cpp; sourceTree = "<group>"; };
- DF2FFC640F48672D0006E566 /* resource_rsc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resource_rsc.cpp; sourceTree = "<group>"; };
- DF2FFC650F48672D0006E566 /* sfuncs_ihnm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sfuncs_ihnm.cpp; sourceTree = "<group>"; };
- DF2FFC700F4867910006E566 /* debugger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debugger.cpp; sourceTree = "<group>"; };
- DF2FFC710F4867910006E566 /* debugger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debugger.h; sourceTree = "<group>"; };
- DF2FFC720F4867910006E566 /* staticres.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = staticres.cpp; sourceTree = "<group>"; };
- DF2FFC730F4867910006E566 /* staticres.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = staticres.h; sourceTree = "<group>"; };
- DF2FFCBD0F4870690006E566 /* cell.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cell.cpp; sourceTree = "<group>"; };
- DF2FFCBE0F4870690006E566 /* cell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cell.h; sourceTree = "<group>"; };
- DF2FFCBF0F4870690006E566 /* cursor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cursor.cpp; sourceTree = "<group>"; };
- DF2FFCC00F4870690006E566 /* cursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cursor.h; sourceTree = "<group>"; };
- DF2FFCC10F4870690006E566 /* debug.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug.cpp; sourceTree = "<group>"; };
- DF2FFCC20F4870690006E566 /* debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug.h; sourceTree = "<group>"; };
- DF2FFCC30F4870690006E566 /* detection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = detection.cpp; sourceTree = "<group>"; };
- DF2FFCC40F4870690006E566 /* font.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = font.cpp; sourceTree = "<group>"; };
- DF2FFCC50F4870690006E566 /* font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = font.h; sourceTree = "<group>"; };
- DF2FFCC60F4870690006E566 /* graphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = graphics.cpp; sourceTree = "<group>"; };
- DF2FFCC70F4870690006E566 /* graphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = graphics.h; sourceTree = "<group>"; };
- DF2FFCC80F4870690006E566 /* groovie.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = groovie.cpp; sourceTree = "<group>"; };
- DF2FFCC90F4870690006E566 /* groovie.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = groovie.h; sourceTree = "<group>"; };
- DF2FFCCA0F4870690006E566 /* lzss.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lzss.cpp; sourceTree = "<group>"; };
- DF2FFCCB0F4870690006E566 /* lzss.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lzss.h; sourceTree = "<group>"; };
- DF2FFCCD0F4870690006E566 /* music.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = music.cpp; sourceTree = "<group>"; };
- DF2FFCCE0F4870690006E566 /* music.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = music.h; sourceTree = "<group>"; };
- DF2FFCCF0F4870690006E566 /* player.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = player.cpp; sourceTree = "<group>"; };
- DF2FFCD00F4870690006E566 /* player.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = player.h; sourceTree = "<group>"; };
- DF2FFCD10F4870690006E566 /* resource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resource.cpp; sourceTree = "<group>"; };
- DF2FFCD20F4870690006E566 /* resource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resource.h; sourceTree = "<group>"; };
- DF2FFCD30F4870690006E566 /* roq.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = roq.cpp; sourceTree = "<group>"; };
- DF2FFCD40F4870690006E566 /* roq.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = roq.h; sourceTree = "<group>"; };
- DF2FFCD50F4870690006E566 /* saveload.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveload.cpp; sourceTree = "<group>"; };
- DF2FFCD60F4870690006E566 /* saveload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = saveload.h; sourceTree = "<group>"; };
- DF2FFCD70F4870690006E566 /* script.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script.cpp; sourceTree = "<group>"; };
- DF2FFCD80F4870690006E566 /* script.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = script.h; sourceTree = "<group>"; };
- DF2FFCD90F4870690006E566 /* vdx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vdx.cpp; sourceTree = "<group>"; };
- DF2FFCDA0F4870690006E566 /* vdx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vdx.h; sourceTree = "<group>"; };
- DF2FFD050F4870E50006E566 /* detection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = detection.cpp; sourceTree = "<group>"; };
- DF2FFD060F4870E50006E566 /* graphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = graphics.cpp; sourceTree = "<group>"; };
- DF2FFD070F4870E50006E566 /* graphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = graphics.h; sourceTree = "<group>"; };
- DF2FFD080F4870E50006E566 /* locations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = locations.cpp; sourceTree = "<group>"; };
- DF2FFD0A0F4870E50006E566 /* resource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resource.cpp; sourceTree = "<group>"; };
- DF2FFD0B0F4870E50006E566 /* saveload.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveload.cpp; sourceTree = "<group>"; };
- DF2FFD0C0F4870E50006E566 /* sequences.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sequences.cpp; sourceTree = "<group>"; };
- DF2FFD0D0F4870E50006E566 /* staticres.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = staticres.cpp; sourceTree = "<group>"; };
- DF2FFD0E0F4870E50006E566 /* tucker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tucker.cpp; sourceTree = "<group>"; };
- DF2FFD0F0F4870E50006E566 /* tucker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tucker.h; sourceTree = "<group>"; };
- DF2FFD290F48717F0006E566 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = "<group>"; };
- DF2FFD2A0F48717F0006E566 /* icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon.png; sourceTree = "<group>"; };
- DF45B176116628A5009B85CC /* animate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = animate.cpp; sourceTree = "<group>"; };
- DF45B177116628A5009B85CC /* animate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = animate.h; sourceTree = "<group>"; };
- DF45B178116628A5009B85CC /* cache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cache.cpp; sourceTree = "<group>"; };
- DF45B179116628A5009B85CC /* cache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cache.h; sourceTree = "<group>"; };
- DF45B17A116628A5009B85CC /* compare.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = compare.cpp; sourceTree = "<group>"; };
- DF45B17B116628A5009B85CC /* compare.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = compare.h; sourceTree = "<group>"; };
- DF45B17C116628A5009B85CC /* controls.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = controls.cpp; sourceTree = "<group>"; };
- DF45B17D116628A5009B85CC /* controls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = controls.h; sourceTree = "<group>"; };
- DF45B17E116628A5009B85CC /* coordadjuster.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = coordadjuster.cpp; sourceTree = "<group>"; };
- DF45B17F116628A5009B85CC /* coordadjuster.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = coordadjuster.h; sourceTree = "<group>"; };
- DF45B180116628A5009B85CC /* cursor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cursor.cpp; sourceTree = "<group>"; };
- DF45B181116628A5009B85CC /* cursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cursor.h; sourceTree = "<group>"; };
- DF45B182116628A5009B85CC /* font.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = font.cpp; sourceTree = "<group>"; };
- DF45B183116628A5009B85CC /* font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = font.h; sourceTree = "<group>"; };
- DF45B185116628A5009B85CC /* frameout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = frameout.h; sourceTree = "<group>"; };
- DF45B18A116628A5009B85CC /* helpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = helpers.h; sourceTree = "<group>"; };
- DF45B18B116628A5009B85CC /* menu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = menu.cpp; sourceTree = "<group>"; };
- DF45B18C116628A5009B85CC /* menu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = menu.h; sourceTree = "<group>"; };
- DF45B18D116628A5009B85CC /* paint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = paint.cpp; sourceTree = "<group>"; };
- DF45B18E116628A5009B85CC /* paint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = paint.h; sourceTree = "<group>"; };
- DF45B18F116628A5009B85CC /* paint16.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = paint16.cpp; sourceTree = "<group>"; };
- DF45B190116628A5009B85CC /* paint16.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = paint16.h; sourceTree = "<group>"; };
- DF45B191116628A5009B85CC /* paint32.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = paint32.cpp; sourceTree = "<group>"; };
- DF45B192116628A5009B85CC /* paint32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = paint32.h; sourceTree = "<group>"; };
- DF45B193116628A5009B85CC /* palette.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = palette.cpp; sourceTree = "<group>"; };
- DF45B194116628A5009B85CC /* palette.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = palette.h; sourceTree = "<group>"; };
- DF45B195116628A5009B85CC /* picture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = picture.cpp; sourceTree = "<group>"; };
- DF45B196116628A5009B85CC /* picture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = picture.h; sourceTree = "<group>"; };
- DF45B197116628A5009B85CC /* portrait.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = portrait.cpp; sourceTree = "<group>"; };
- DF45B198116628A5009B85CC /* portrait.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = portrait.h; sourceTree = "<group>"; };
- DF45B199116628A5009B85CC /* ports.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ports.cpp; sourceTree = "<group>"; };
- DF45B19A116628A5009B85CC /* ports.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ports.h; sourceTree = "<group>"; };
- DF45B19B116628A5009B85CC /* robot.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = robot.cpp; sourceTree = "<group>"; };
- DF45B19C116628A5009B85CC /* robot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = robot.h; sourceTree = "<group>"; };
- DF45B19D116628A5009B85CC /* screen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = screen.cpp; sourceTree = "<group>"; };
- DF45B19E116628A5009B85CC /* screen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = screen.h; sourceTree = "<group>"; };
- DF45B19F116628A5009B85CC /* text16.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = text16.cpp; sourceTree = "<group>"; };
- DF45B1A0116628A5009B85CC /* text16.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = text16.h; sourceTree = "<group>"; };
- DF45B1A1116628A5009B85CC /* transitions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = transitions.cpp; sourceTree = "<group>"; };
- DF45B1A2116628A5009B85CC /* transitions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = transitions.h; sourceTree = "<group>"; };
- DF45B1A3116628A5009B85CC /* view.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = view.cpp; sourceTree = "<group>"; };
- DF45B1A4116628A5009B85CC /* view.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = view.h; sourceTree = "<group>"; };
- DF45B1A6116628A5009B85CC /* grammar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = grammar.cpp; sourceTree = "<group>"; };
- DF45B1A7116628A5009B85CC /* said.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = said.cpp; sourceTree = "<group>"; };
- DF45B1A9116628A5009B85CC /* vocabulary.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vocabulary.cpp; sourceTree = "<group>"; };
- DF45B1AA116628A5009B85CC /* vocabulary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vocabulary.h; sourceTree = "<group>"; };
- DF45B1AC116628A5009B85CC /* audio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = audio.cpp; sourceTree = "<group>"; };
- DF45B1AD116628A5009B85CC /* audio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = audio.h; sourceTree = "<group>"; };
- DF45B1AF116628A5009B85CC /* adlib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = adlib.cpp; sourceTree = "<group>"; };
- DF45B1B1116628A5009B85CC /* fb01.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fb01.cpp; sourceTree = "<group>"; };
- DF45B1B2116628A5009B85CC /* map-mt32-to-gm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "map-mt32-to-gm.h"; sourceTree = "<group>"; };
- DF45B1B3116628A5009B85CC /* midi.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = midi.cpp; sourceTree = "<group>"; };
- DF45B1B4116628A5009B85CC /* mididriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mididriver.h; sourceTree = "<group>"; };
- DF45B1B5116628A5009B85CC /* pcjr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pcjr.cpp; sourceTree = "<group>"; };
- DF45B1BF116628A5009B85CC /* midiparser_sci.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = midiparser_sci.cpp; sourceTree = "<group>"; };
- DF45B1C0116628A5009B85CC /* midiparser_sci.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = midiparser_sci.h; sourceTree = "<group>"; };
- DF45B1C1116628A5009B85CC /* music.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = music.cpp; sourceTree = "<group>"; };
- DF45B1C2116628A5009B85CC /* music.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = music.h; sourceTree = "<group>"; };
- DF45B1C3116628A5009B85CC /* soundcmd.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = soundcmd.cpp; sourceTree = "<group>"; };
- DF45B1C4116628A5009B85CC /* soundcmd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = soundcmd.h; sourceTree = "<group>"; };
- DF45B1C6116628A5009B85CC /* seq_decoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = seq_decoder.cpp; sourceTree = "<group>"; };
- DF45B1C7116628A5009B85CC /* seq_decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = seq_decoder.h; sourceTree = "<group>"; };
- DF46B6F21381E18900D08723 /* coroutine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = coroutine.cpp; sourceTree = "<group>"; };
- DF46B6F71381E1FF00D08723 /* towns_audio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = towns_audio.cpp; path = ../../audio/softsynth/fmtowns_pc98/towns_audio.cpp; sourceTree = SOURCE_ROOT; };
- DF46B6F81381E1FF00D08723 /* towns_audio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = towns_audio.h; path = ../../audio/softsynth/fmtowns_pc98/towns_audio.h; sourceTree = SOURCE_ROOT; };
- DF46B6F91381E1FF00D08723 /* towns_euphony.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = towns_euphony.cpp; path = ../../audio/softsynth/fmtowns_pc98/towns_euphony.cpp; sourceTree = SOURCE_ROOT; };
- DF46B6FA1381E1FF00D08723 /* towns_euphony.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = towns_euphony.h; path = ../../audio/softsynth/fmtowns_pc98/towns_euphony.h; sourceTree = SOURCE_ROOT; };
- DF46B6FB1381E1FF00D08723 /* towns_pc98_driver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = towns_pc98_driver.cpp; path = ../../audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp; sourceTree = SOURCE_ROOT; };
- DF46B6FC1381E1FF00D08723 /* towns_pc98_driver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = towns_pc98_driver.h; path = ../../audio/softsynth/fmtowns_pc98/towns_pc98_driver.h; sourceTree = SOURCE_ROOT; };
- DF46B6FD1381E1FF00D08723 /* towns_pc98_fmsynth.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = towns_pc98_fmsynth.cpp; path = ../../audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp; sourceTree = SOURCE_ROOT; };
- DF46B6FE1381E1FF00D08723 /* towns_pc98_fmsynth.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = towns_pc98_fmsynth.h; path = ../../audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h; sourceTree = SOURCE_ROOT; };
- DF46B70F1381E27000D08723 /* console.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = console.cpp; sourceTree = "<group>"; };
- DF46B7101381E27000D08723 /* console.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = console.h; sourceTree = "<group>"; };
- DF46B7111381E27000D08723 /* databases.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = databases.cpp; sourceTree = "<group>"; };
- DF46B7121381E27000D08723 /* databases.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = databases.h; sourceTree = "<group>"; };
- DF46B7131381E27000D08723 /* dbase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dbase.cpp; sourceTree = "<group>"; };
- DF46B7141381E27000D08723 /* dbase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dbase.h; sourceTree = "<group>"; };
- DF46B7151381E27000D08723 /* iniconfig.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = iniconfig.cpp; sourceTree = "<group>"; };
- DF46B7161381E27000D08723 /* iniconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iniconfig.h; sourceTree = "<group>"; };
- DF46B7171381E27000D08723 /* init_v7.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = init_v7.cpp; sourceTree = "<group>"; };
- DF46B7181381E27000D08723 /* inter_inca2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = inter_inca2.cpp; sourceTree = "<group>"; };
- DF46B7421381E40500D08723 /* log.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = log.cpp; path = log/log.cpp; sourceTree = "<group>"; };
- DF46B7431381E40500D08723 /* log.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = log.h; path = log/log.h; sourceTree = "<group>"; };
- DF46B7471381E40F00D08723 /* modular-backend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "modular-backend.cpp"; sourceTree = "<group>"; };
- DF46B7481381E40F00D08723 /* modular-backend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "modular-backend.h"; sourceTree = "<group>"; };
- DF46B7501381E46700D08723 /* actor_he.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = actor_he.h; sourceTree = "<group>"; };
- DF46B7511381E46700D08723 /* player_v2base.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = player_v2base.cpp; sourceTree = "<group>"; };
- DF46B7521381E46700D08723 /* player_v2base.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = player_v2base.h; sourceTree = "<group>"; };
- DF46B7531381E46700D08723 /* player_v2cms.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = player_v2cms.h; sourceTree = "<group>"; };
- DF46B75B1381E4A400D08723 /* console.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = console.cpp; sourceTree = "<group>"; };
- DF46B75C1381E4A400D08723 /* console.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = console.h; sourceTree = "<group>"; };
- DF46B75D1381E4A400D08723 /* detection_tables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = detection_tables.h; sourceTree = "<group>"; };
- DF46B7611381E4D400D08723 /* robot_decoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = robot_decoder.cpp; sourceTree = "<group>"; };
- DF46B7621381E4D400D08723 /* robot_decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = robot_decoder.h; sourceTree = "<group>"; };
- DF46B7661381E4E400D08723 /* vm_types.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vm_types.cpp; sourceTree = "<group>"; };
- DF46B76E1381E54200D08723 /* bufferedstream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bufferedstream.h; sourceTree = "<group>"; };
- DF46B76F1381E54200D08723 /* dcl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dcl.cpp; sourceTree = "<group>"; };
- DF46B7701381E54200D08723 /* dcl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dcl.h; sourceTree = "<group>"; };
- DF46B7711381E54200D08723 /* forbidden.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = forbidden.h; sourceTree = "<group>"; };
- DF46B7721381E54200D08723 /* iff_container.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = iff_container.cpp; sourceTree = "<group>"; };
- DF46B7731381E54200D08723 /* substream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = substream.h; sourceTree = "<group>"; };
- DF46B7741381E54200D08723 /* translation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = translation.h; sourceTree = "<group>"; };
- DF46B7751381E54200D08723 /* winexe_ne.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = winexe_ne.cpp; sourceTree = "<group>"; };
- DF46B7761381E54200D08723 /* winexe_ne.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = winexe_ne.h; sourceTree = "<group>"; };
- DF46B7771381E54200D08723 /* winexe_pe.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = winexe_pe.cpp; sourceTree = "<group>"; };
- DF46B7781381E54200D08723 /* winexe_pe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = winexe_pe.h; sourceTree = "<group>"; };
- DF46B7791381E54200D08723 /* winexe.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = winexe.cpp; sourceTree = "<group>"; };
- DF46B77A1381E54200D08723 /* winexe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = winexe.h; sourceTree = "<group>"; };
- DF46B78E1381E58000D08723 /* palette.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = palette.h; sourceTree = "<group>"; };
- DF46B78F1381E58000D08723 /* png.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = png.cpp; sourceTree = "<group>"; };
- DF46B7901381E58000D08723 /* png.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = png.h; sourceTree = "<group>"; };
- DF46B7911381E58000D08723 /* wincursor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wincursor.cpp; sourceTree = "<group>"; };
- DF46B7921381E58000D08723 /* wincursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wincursor.h; sourceTree = "<group>"; };
- DF46B79D1381E5B500D08723 /* winfont.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = winfont.cpp; sourceTree = "<group>"; };
- DF46B79E1381E5B500D08723 /* winfont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = winfont.h; sourceTree = "<group>"; };
- DF46B7A31381E5D900D08723 /* sdl-timer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "sdl-timer.cpp"; path = "sdl/sdl-timer.cpp"; sourceTree = "<group>"; };
- DF46B7A41381E5D900D08723 /* sdl-timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "sdl-timer.h"; path = "sdl/sdl-timer.h"; sourceTree = "<group>"; };
- DF46B7A81381E5F100D08723 /* header.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = header.cpp; sourceTree = "<group>"; };
- DF46B7B21381E67800D08723 /* sdl-mutex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "sdl-mutex.cpp"; path = "mutex/sdl/sdl-mutex.cpp"; sourceTree = "<group>"; };
- DF46B7B31381E67800D08723 /* sdl-mutex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "sdl-mutex.h"; path = "mutex/sdl/sdl-mutex.h"; sourceTree = "<group>"; };
- DF46B7BB1381E6C000D08723 /* object.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = object.cpp; sourceTree = "<group>"; };
- DF46B7BC1381E6C000D08723 /* object.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = object.h; sourceTree = "<group>"; };
- DF46B7C61381E72500D08723 /* console.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = console.cpp; sourceTree = "<group>"; };
- DF46B7C71381E72500D08723 /* console.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = console.h; sourceTree = "<group>"; };
- DF46B7CD1381E76300D08723 /* sdl-events.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "sdl-events.cpp"; path = "events/sdl/sdl-events.cpp"; sourceTree = "<group>"; };
- DF46B7CE1381E76300D08723 /* sdl-events.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "sdl-events.h"; path = "events/sdl/sdl-events.h"; sourceTree = "<group>"; };
- DF46B7D41381E7C600D08723 /* console.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = console.cpp; sourceTree = "<group>"; };
- DF46B7D51381E7C600D08723 /* console.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = console.h; sourceTree = "<group>"; };
- DF46B83B1381F13500D08723 /* saveload_v7.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveload_v7.cpp; sourceTree = "<group>"; };
- DF46B8431381F35500D08723 /* saveload_inca2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveload_inca2.cpp; sourceTree = "<group>"; };
- DF46B8471381F38700D08723 /* inter_v7.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = inter_v7.cpp; sourceTree = "<group>"; };
- DF46B84B1381F39E00D08723 /* console.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = console.cpp; sourceTree = "<group>"; };
- DF46B84C1381F39E00D08723 /* console.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = console.h; sourceTree = "<group>"; };
- DF46B8501381F3B400D08723 /* console.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = console.cpp; sourceTree = "<group>"; };
- DF46B8511381F3B400D08723 /* console.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = console.h; sourceTree = "<group>"; };
- DF46B85A1381F44E00D08723 /* dbopl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dbopl.cpp; path = ../../audio/softsynth/opl/dbopl.cpp; sourceTree = SOURCE_ROOT; };
- DF46B85B1381F44E00D08723 /* dbopl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dbopl.h; path = ../../audio/softsynth/opl/dbopl.h; sourceTree = SOURCE_ROOT; };
- DF46B85C1381F44E00D08723 /* dosbox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dosbox.cpp; path = ../../audio/softsynth/opl/dosbox.cpp; sourceTree = SOURCE_ROOT; };
- DF46B85D1381F44E00D08723 /* dosbox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dosbox.h; path = ../../audio/softsynth/opl/dosbox.h; sourceTree = SOURCE_ROOT; };
- DF46B85E1381F44E00D08723 /* mame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mame.cpp; path = ../../audio/softsynth/opl/mame.cpp; sourceTree = SOURCE_ROOT; };
- DF46B85F1381F44E00D08723 /* mame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mame.h; path = ../../audio/softsynth/opl/mame.h; sourceTree = SOURCE_ROOT; };
- DF46B86F1381F4A200D08723 /* sdl-audiocd.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "sdl-audiocd.cpp"; path = "audiocd/sdl/sdl-audiocd.cpp"; sourceTree = "<group>"; };
- DF46B8701381F4A200D08723 /* sdl-audiocd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "sdl-audiocd.h"; path = "audiocd/sdl/sdl-audiocd.h"; sourceTree = "<group>"; };
- DF46B87B1381F4F200D08723 /* default-audiocd.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "default-audiocd.cpp"; path = "audiocd/default/default-audiocd.cpp"; sourceTree = "<group>"; };
- DF46B87C1381F4F200D08723 /* default-audiocd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "default-audiocd.h"; path = "audiocd/default/default-audiocd.h"; sourceTree = "<group>"; };
- DF46B8801381F4FF00D08723 /* audiocd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = audiocd.h; path = audiocd/audiocd.h; sourceTree = "<group>"; };
- DF46B8851381F56400D08723 /* util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = util.h; sourceTree = "<group>"; };
- DF46B8871381F5D800D08723 /* sdl-provider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "sdl-provider.cpp"; path = "sdl/sdl-provider.cpp"; sourceTree = "<group>"; };
- DF46B8881381F5D800D08723 /* sdl-provider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "sdl-provider.h"; path = "sdl/sdl-provider.h"; sourceTree = "<group>"; };
- DF46B8901381F62B00D08723 /* adpcm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = adpcm.cpp; sourceTree = "<group>"; };
- DF46B8911381F62B00D08723 /* adpcm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = adpcm.h; sourceTree = "<group>"; };
- DF46B8991381F6C400D08723 /* null.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = null.cpp; path = ../../audio/null.cpp; sourceTree = SOURCE_ROOT; };
- DF46B89A1381F6C400D08723 /* null.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = null.h; path = ../../audio/null.h; sourceTree = SOURCE_ROOT; };
- DF573BFE0F5A81EA00961A72 /* kernel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kernel.h; sourceTree = "<group>"; };
- DF573BFF0F5A81EA00961A72 /* script.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = script.h; sourceTree = "<group>"; };
- DF573C000F5A81EA00961A72 /* seg_manager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = seg_manager.h; sourceTree = "<group>"; };
- DF573C010F5A81EA00961A72 /* state.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = state.cpp; sourceTree = "<group>"; };
- DF573C020F5A81EA00961A72 /* state.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = state.h; sourceTree = "<group>"; };
- DF573C030F5A81EA00961A72 /* vm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vm.h; sourceTree = "<group>"; };
- DF573C040F5A81EA00961A72 /* vm_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vm_types.h; sourceTree = "<group>"; };
- DF573CBA0F5A85B300961A72 /* exec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = exec.cpp; sourceTree = "<group>"; };
- DF573CBD0F5A85E100961A72 /* timer_lol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = timer_lol.cpp; sourceTree = "<group>"; };
- DF5CEB260F75535000DEA624 /* sound_br.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound_br.cpp; sourceTree = "<group>"; };
- DF5CEB270F75535000DEA624 /* sound_ns.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound_ns.cpp; sourceTree = "<group>"; };
- DF5CEB2F0F75538000DEA624 /* protracker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = protracker.cpp; sourceTree = "<group>"; };
- DF5CEB300F75538000DEA624 /* protracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = protracker.h; sourceTree = "<group>"; };
- DF6118380FE3A8080042AD3F /* kmisc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kmisc.cpp; sourceTree = "<group>"; };
- DF6118390FE3A8080042AD3F /* segment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = segment.cpp; sourceTree = "<group>"; };
- DF61183A0FE3A8080042AD3F /* segment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = segment.h; sourceTree = "<group>"; };
- DF61183B0FE3A8080042AD3F /* savegame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = savegame.h; sourceTree = "<group>"; };
- DF6118420FE3A8250042AD3F /* debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug.h; sourceTree = "<group>"; };
- DF6118430FE3A8250042AD3F /* decompressor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = decompressor.cpp; sourceTree = "<group>"; };
- DF6118440FE3A8250042AD3F /* decompressor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = decompressor.h; sourceTree = "<group>"; };
- DF6118450FE3A8250042AD3F /* resource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resource.cpp; sourceTree = "<group>"; };
- DF6118460FE3A8250042AD3F /* resource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resource.h; sourceTree = "<group>"; };
- DF6118540FE3A8990042AD3F /* disk.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = disk.cpp; sourceTree = "<group>"; };
- DF6118790FE3A9AA0042AD3F /* saveconverter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveconverter.cpp; sourceTree = "<group>"; };
- DF61187A0FE3A9AA0042AD3F /* saveconverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = saveconverter.h; sourceTree = "<group>"; };
- DF61187B0FE3A9AA0042AD3F /* saveconverter_v2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveconverter_v2.cpp; sourceTree = "<group>"; };
- DF61187C0FE3A9AA0042AD3F /* saveconverter_v3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveconverter_v3.cpp; sourceTree = "<group>"; };
- DF61187D0FE3A9AA0042AD3F /* saveconverter_v4.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveconverter_v4.cpp; sourceTree = "<group>"; };
- DF61187F0FE3A9AA0042AD3F /* savefile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = savefile.cpp; sourceTree = "<group>"; };
- DF6118800FE3A9AA0042AD3F /* savefile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = savefile.h; sourceTree = "<group>"; };
- DF6118810FE3A9AA0042AD3F /* savehandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = savehandler.cpp; sourceTree = "<group>"; };
- DF6118820FE3A9AA0042AD3F /* savehandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = savehandler.h; sourceTree = "<group>"; };
- DF6118830FE3A9AA0042AD3F /* saveload.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveload.cpp; sourceTree = "<group>"; };
- DF6118840FE3A9AA0042AD3F /* saveload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = saveload.h; sourceTree = "<group>"; };
- DF6118850FE3A9AA0042AD3F /* saveload_v2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveload_v2.cpp; sourceTree = "<group>"; };
- DF6118860FE3A9AA0042AD3F /* saveload_v3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveload_v3.cpp; sourceTree = "<group>"; };
- DF6118870FE3A9AA0042AD3F /* saveload_v4.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveload_v4.cpp; sourceTree = "<group>"; };
- DF6118880FE3A9AA0042AD3F /* saveload_v6.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveload_v6.cpp; sourceTree = "<group>"; };
- DF6118AE0FE3A9EA0042AD3F /* feeble.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = feeble.cpp; sourceTree = "<group>"; };
- DF6118B30FE3AA280042AD3F /* saveload_lol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveload_lol.cpp; sourceTree = "<group>"; };
- DF6118B40FE3AA280042AD3F /* sound_lol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound_lol.cpp; sourceTree = "<group>"; };
- DF6118B50FE3AA280042AD3F /* sound_pcspk.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound_pcspk.cpp; sourceTree = "<group>"; };
- DF6118B60FE3AA280042AD3F /* text_lol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = text_lol.cpp; sourceTree = "<group>"; };
- DF6118B70FE3AA280042AD3F /* text_lol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = text_lol.h; sourceTree = "<group>"; };
- DF6118C60FE3AABD0042AD3F /* player_v2cms.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = player_v2cms.cpp; sourceTree = "<group>"; };
- DF6118CB0FE3AAFD0042AD3F /* hardwarekeys.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hardwarekeys.cpp; sourceTree = "<group>"; };
- DF6BF4C010529DA50069811F /* conversion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = conversion.cpp; sourceTree = "<group>"; };
- DF6BF4C110529DA50069811F /* conversion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = conversion.h; sourceTree = "<group>"; };
- DF6BF4C210529DA50069811F /* jpeg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = jpeg.cpp; sourceTree = "<group>"; };
- DF6BF4C310529DA50069811F /* jpeg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = jpeg.h; sourceTree = "<group>"; };
- DF6BF4D510529DE90069811F /* input_pn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = input_pn.cpp; sourceTree = "<group>"; };
- DF6BF4D610529DE90069811F /* string_pn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = string_pn.cpp; sourceTree = "<group>"; };
- DF6BF4D710529DE90069811F /* verb_pn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = verb_pn.cpp; sourceTree = "<group>"; };
- DF6BF4E210529E260069811F /* sound_adlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound_adlib.h; sourceTree = "<group>"; };
- DF6BF4E310529E260069811F /* sound_amiga.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound_amiga.cpp; sourceTree = "<group>"; };
- DF6BF4E810529E6E0069811F /* init_v4.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = init_v4.cpp; sourceTree = "<group>"; };
- DF6BF4E910529E6E0069811F /* inter_playtoons.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = inter_playtoons.cpp; sourceTree = "<group>"; };
- DF6BF4F110529EE40069811F /* player_v4a.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = player_v4a.cpp; sourceTree = "<group>"; };
- DF6BF4F210529EE40069811F /* player_v4a.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = player_v4a.h; sourceTree = "<group>"; };
- DF6BF4F710529F140069811F /* EventDispatcher.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventDispatcher.cpp; sourceTree = "<group>"; };
- DF6BF4F810529F140069811F /* EventRecorder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventRecorder.cpp; sourceTree = "<group>"; };
- DF6BF4F910529F140069811F /* EventRecorder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventRecorder.h; sourceTree = "<group>"; };
- DF6BF4FA10529F140069811F /* list_intern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = list_intern.h; sourceTree = "<group>"; };
- DF6BF4FB10529F140069811F /* serializer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = serializer.h; sourceTree = "<group>"; };
- DF7585C3100CB66E00CC3324 /* expression.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = expression.cpp; sourceTree = "<group>"; };
- DF7585C4100CB66E00CC3324 /* expression.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = expression.h; sourceTree = "<group>"; };
- DF7585C5100CB66E00CC3324 /* hotspots.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hotspots.cpp; sourceTree = "<group>"; };
- DF7585C6100CB66E00CC3324 /* hotspots.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hotspots.h; sourceTree = "<group>"; };
- DF7585C7100CB66E00CC3324 /* init_v6.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = init_v6.cpp; sourceTree = "<group>"; };
- DF7585C8100CB66E00CC3324 /* resources.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resources.cpp; sourceTree = "<group>"; };
- DF7585C9100CB66E00CC3324 /* resources.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resources.h; sourceTree = "<group>"; };
- DF7585CA100CB66E00CC3324 /* script.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script.cpp; sourceTree = "<group>"; };
- DF7585CB100CB66E00CC3324 /* script.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = script.h; sourceTree = "<group>"; };
- DF7585CC100CB66E00CC3324 /* totfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = totfile.cpp; sourceTree = "<group>"; };
- DF7585CD100CB66E00CC3324 /* totfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = totfile.h; sourceTree = "<group>"; };
- DF7585EA100CB6EA00CC3324 /* sjis.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sjis.cpp; sourceTree = "<group>"; };
- DF7585EB100CB6EA00CC3324 /* sjis.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sjis.h; sourceTree = "<group>"; };
- DF7585F0100CB70600CC3324 /* saveload_playtoons.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveload_playtoons.cpp; sourceTree = "<group>"; };
- DF7585F6100CB75800CC3324 /* static_selectors.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = static_selectors.cpp; sourceTree = "<group>"; };
- DF758614100CBA0200CC3324 /* osys_events.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = osys_events.cpp; sourceTree = "<group>"; };
- DF758615100CBA0200CC3324 /* osys_main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = osys_main.cpp; sourceTree = "<group>"; };
- DF758616100CBA0200CC3324 /* osys_main.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = osys_main.h; sourceTree = "<group>"; };
- DF758617100CBA0200CC3324 /* osys_sound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = osys_sound.cpp; sourceTree = "<group>"; };
- DF758618100CBA0200CC3324 /* osys_video.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = osys_video.cpp; sourceTree = "<group>"; };
- DF7E8BF00ED5FC77001CB19F /* saveload.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveload.cpp; sourceTree = "<group>"; };
- DF7E8BF10ED5FC77001CB19F /* saveload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = saveload.h; sourceTree = "<group>"; };
- DF7E8BF40ED5FC77001CB19F /* ThemeEngine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThemeEngine.cpp; sourceTree = "<group>"; };
- DF7E8BF50ED5FC77001CB19F /* ThemeEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThemeEngine.h; sourceTree = "<group>"; };
- DF7E8BF60ED5FC77001CB19F /* ThemeEval.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThemeEval.cpp; sourceTree = "<group>"; };
- DF7E8BF70ED5FC77001CB19F /* ThemeEval.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThemeEval.h; sourceTree = "<group>"; };
- DF7E8BF80ED5FC77001CB19F /* ThemeLayout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThemeLayout.cpp; sourceTree = "<group>"; };
- DF7E8BF90ED5FC77001CB19F /* ThemeLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThemeLayout.h; sourceTree = "<group>"; };
- DF7E8BFA0ED5FC77001CB19F /* ThemeParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThemeParser.cpp; sourceTree = "<group>"; };
- DF7E8BFB0ED5FC77001CB19F /* ThemeParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThemeParser.h; sourceTree = "<group>"; };
- DF7E8C050ED5FCAF001CB19F /* thumbnail.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = thumbnail.cpp; sourceTree = "<group>"; };
- DF7E8C060ED5FCAF001CB19F /* thumbnail.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = thumbnail.h; sourceTree = "<group>"; };
- DF7E8C070ED5FCAF001CB19F /* VectorRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VectorRenderer.cpp; sourceTree = "<group>"; };
- DF7E8C080ED5FCAF001CB19F /* VectorRenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VectorRenderer.h; sourceTree = "<group>"; };
- DF7E8C090ED5FCAF001CB19F /* VectorRendererSpec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VectorRendererSpec.cpp; sourceTree = "<group>"; };
- DF7E8C0A0ED5FCAF001CB19F /* VectorRendererSpec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VectorRendererSpec.h; sourceTree = "<group>"; };
- DF7E8C0F0ED5FCC2001CB19F /* xmlparser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xmlparser.cpp; sourceTree = "<group>"; };
- DF7E8C100ED5FCC2001CB19F /* xmlparser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xmlparser.h; sourceTree = "<group>"; };
- DF7E8C510ED60067001CB19F /* game.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = game.cpp; sourceTree = "<group>"; };
- DF7E8C520ED60067001CB19F /* game.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = game.h; sourceTree = "<group>"; };
- DF7E8C7A0ED601E5001CB19F /* scummmodern.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = scummmodern.zip; sourceTree = "<group>"; };
- DF7F285C11FF23B700159131 /* frameout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = frameout.cpp; sourceTree = "<group>"; };
- DF7F286011FF23D500159131 /* amigamac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = amigamac.cpp; sourceTree = "<group>"; };
- DF7F286411FF23EF00159131 /* kvideo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kvideo.cpp; sourceTree = "<group>"; };
- DF7F286511FF23EF00159131 /* workarounds.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = workarounds.cpp; sourceTree = "<group>"; };
- DF7F286611FF23EF00159131 /* workarounds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = workarounds.h; sourceTree = "<group>"; };
- DF7F286F11FF243A00159131 /* detection_tables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = detection_tables.h; sourceTree = "<group>"; };
- DF7F287011FF243A00159131 /* sound_2gs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound_2gs.cpp; sourceTree = "<group>"; };
- DF7F287111FF243A00159131 /* sound_2gs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound_2gs.h; sourceTree = "<group>"; };
- DF7F287211FF243B00159131 /* sound_coco3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound_coco3.cpp; sourceTree = "<group>"; };
- DF7F287311FF243B00159131 /* sound_coco3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound_coco3.h; sourceTree = "<group>"; };
- DF7F287411FF243B00159131 /* sound_midi.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound_midi.cpp; sourceTree = "<group>"; };
- DF7F287511FF243B00159131 /* sound_midi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound_midi.h; sourceTree = "<group>"; };
- DF7F287611FF243B00159131 /* sound_pcjr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound_pcjr.cpp; sourceTree = "<group>"; };
- DF7F287711FF243B00159131 /* sound_pcjr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound_pcjr.h; sourceTree = "<group>"; };
- DF7F287811FF243B00159131 /* sound_sarien.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound_sarien.cpp; sourceTree = "<group>"; };
- DF7F287911FF243B00159131 /* sound_sarien.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound_sarien.h; sourceTree = "<group>"; };
- DF7F288911FF244F00159131 /* Tooltip.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Tooltip.cpp; sourceTree = "<group>"; };
- DF7F288A11FF244F00159131 /* Tooltip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Tooltip.h; sourceTree = "<group>"; };
- DF7F289111FF247300159131 /* translation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = translation.cpp; sourceTree = "<group>"; };
- DF7F28A311FF24C400159131 /* console.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = console.cpp; sourceTree = "<group>"; };
- DF7F28A411FF24C400159131 /* console.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = console.h; sourceTree = "<group>"; };
- DF841FD90E7BA61800F5680E /* iphone_keyboard.m */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; path = iphone_keyboard.m; sourceTree = "<group>"; };
- DF841FDA0E7BA61800F5680E /* iphone_video.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iphone_video.h; sourceTree = "<group>"; };
- DF841FDB0E7BA61800F5680E /* iphone_video.m */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; path = iphone_video.m; sourceTree = "<group>"; };
- DF841FF70E7BA6A600F5680E /* agi.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = agi.cpp; sourceTree = "<group>"; };
- DF841FF80E7BA6A600F5680E /* agi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = agi.h; sourceTree = "<group>"; };
- DF841FF90E7BA6A600F5680E /* checks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = checks.cpp; sourceTree = "<group>"; };
- DF841FFA0E7BA6A600F5680E /* console.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = console.cpp; sourceTree = "<group>"; };
- DF841FFB0E7BA6A600F5680E /* console.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = console.h; sourceTree = "<group>"; };
- DF841FFC0E7BA6A600F5680E /* cycle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cycle.cpp; sourceTree = "<group>"; };
- DF841FFD0E7BA6A600F5680E /* detection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = detection.cpp; sourceTree = "<group>"; };
- DF841FFE0E7BA6A600F5680E /* font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = font.h; sourceTree = "<group>"; };
- DF841FFF0E7BA6A600F5680E /* global.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = global.cpp; sourceTree = "<group>"; };
- DF8420000E7BA6A600F5680E /* graphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = graphics.cpp; sourceTree = "<group>"; };
- DF8420010E7BA6A600F5680E /* graphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = graphics.h; sourceTree = "<group>"; };
- DF8420020E7BA6A600F5680E /* id.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = id.cpp; sourceTree = "<group>"; };
- DF8420030E7BA6A600F5680E /* inv.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = inv.cpp; sourceTree = "<group>"; };
- DF8420040E7BA6A600F5680E /* keyboard.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = keyboard.cpp; sourceTree = "<group>"; };
- DF8420050E7BA6A600F5680E /* keyboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = keyboard.h; sourceTree = "<group>"; };
- DF8420060E7BA6A600F5680E /* loader_v2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = loader_v2.cpp; sourceTree = "<group>"; };
- DF8420070E7BA6A600F5680E /* loader_v3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = loader_v3.cpp; sourceTree = "<group>"; };
- DF8420080E7BA6A600F5680E /* logic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = logic.cpp; sourceTree = "<group>"; };
- DF8420090E7BA6A600F5680E /* logic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = logic.h; sourceTree = "<group>"; };
- DF84200A0E7BA6A600F5680E /* lzw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lzw.cpp; sourceTree = "<group>"; };
- DF84200B0E7BA6A600F5680E /* lzw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lzw.h; sourceTree = "<group>"; };
- DF84200C0E7BA6A600F5680E /* menu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = menu.cpp; sourceTree = "<group>"; };
- DF84200D0E7BA6A600F5680E /* menu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = menu.h; sourceTree = "<group>"; };
- DF84200F0E7BA6A600F5680E /* motion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = motion.cpp; sourceTree = "<group>"; };
- DF8420100E7BA6A600F5680E /* objects.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = objects.cpp; sourceTree = "<group>"; };
- DF8420110E7BA6A600F5680E /* op_cmd.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = op_cmd.cpp; sourceTree = "<group>"; };
- DF8420120E7BA6A600F5680E /* op_dbg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = op_dbg.cpp; sourceTree = "<group>"; };
- DF8420130E7BA6A600F5680E /* op_test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = op_test.cpp; sourceTree = "<group>"; };
- DF8420140E7BA6A600F5680E /* opcodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = opcodes.h; sourceTree = "<group>"; };
- DF8420150E7BA6A600F5680E /* picture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = picture.cpp; sourceTree = "<group>"; };
- DF8420160E7BA6A600F5680E /* picture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = picture.h; sourceTree = "<group>"; };
- DF8420170E7BA6A600F5680E /* preagi.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = preagi.cpp; sourceTree = "<group>"; };
- DF8420180E7BA6A600F5680E /* preagi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = preagi.h; sourceTree = "<group>"; };
- DF8420190E7BA6A600F5680E /* preagi_common.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = preagi_common.cpp; sourceTree = "<group>"; };
- DF84201A0E7BA6A600F5680E /* preagi_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = preagi_common.h; sourceTree = "<group>"; };
- DF84201B0E7BA6A600F5680E /* preagi_mickey.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = preagi_mickey.cpp; sourceTree = "<group>"; };
- DF84201C0E7BA6A600F5680E /* preagi_mickey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = preagi_mickey.h; sourceTree = "<group>"; };
- DF84201D0E7BA6A600F5680E /* preagi_troll.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = preagi_troll.cpp; sourceTree = "<group>"; };
- DF84201E0E7BA6A600F5680E /* preagi_troll.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = preagi_troll.h; sourceTree = "<group>"; };
- DF84201F0E7BA6A600F5680E /* preagi_winnie.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = preagi_winnie.cpp; sourceTree = "<group>"; };
- DF8420200E7BA6A600F5680E /* preagi_winnie.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = preagi_winnie.h; sourceTree = "<group>"; };
- DF8420210E7BA6A600F5680E /* predictive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = predictive.cpp; sourceTree = "<group>"; };
- DF8420220E7BA6A600F5680E /* saveload.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveload.cpp; sourceTree = "<group>"; };
- DF8420230E7BA6A600F5680E /* sound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound.cpp; sourceTree = "<group>"; };
- DF8420240E7BA6A600F5680E /* sound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound.h; sourceTree = "<group>"; };
- DF8420250E7BA6A600F5680E /* sprite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sprite.cpp; sourceTree = "<group>"; };
- DF8420260E7BA6A600F5680E /* sprite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sprite.h; sourceTree = "<group>"; };
- DF8420270E7BA6A600F5680E /* text.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = text.cpp; sourceTree = "<group>"; };
- DF8420280E7BA6A600F5680E /* view.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = view.cpp; sourceTree = "<group>"; };
- DF8420290E7BA6A600F5680E /* view.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = view.h; sourceTree = "<group>"; };
- DF84202A0E7BA6A600F5680E /* wagparser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wagparser.cpp; sourceTree = "<group>"; };
- DF84202B0E7BA6A600F5680E /* wagparser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wagparser.h; sourceTree = "<group>"; };
- DF84202C0E7BA6A600F5680E /* words.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = words.cpp; sourceTree = "<group>"; };
- DF84202E0E7BA6A600F5680E /* agos.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = agos.cpp; sourceTree = "<group>"; };
- DF84202F0E7BA6A600F5680E /* agos.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = agos.h; sourceTree = "<group>"; };
- DF8420300E7BA6A600F5680E /* animation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = animation.cpp; sourceTree = "<group>"; };
- DF8420310E7BA6A600F5680E /* animation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = animation.h; sourceTree = "<group>"; };
- DF8420320E7BA6A600F5680E /* charset-fontdata.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "charset-fontdata.cpp"; sourceTree = "<group>"; };
- DF8420330E7BA6A600F5680E /* charset.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = charset.cpp; sourceTree = "<group>"; };
- DF8420340E7BA6A600F5680E /* contain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = contain.cpp; sourceTree = "<group>"; };
- DF8420350E7BA6A600F5680E /* cursor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cursor.cpp; sourceTree = "<group>"; };
- DF8420360E7BA6A600F5680E /* debug.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug.cpp; sourceTree = "<group>"; };
- DF8420370E7BA6A600F5680E /* debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug.h; sourceTree = "<group>"; };
- DF8420380E7BA6A600F5680E /* debugger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debugger.cpp; sourceTree = "<group>"; };
- DF8420390E7BA6A600F5680E /* debugger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debugger.h; sourceTree = "<group>"; };
- DF84203A0E7BA6A600F5680E /* detection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = detection.cpp; sourceTree = "<group>"; };
- DF84203B0E7BA6A600F5680E /* detection_tables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = detection_tables.h; sourceTree = "<group>"; };
- DF84203C0E7BA6A600F5680E /* draw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = draw.cpp; sourceTree = "<group>"; };
- DF84203D0E7BA6A600F5680E /* event.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = event.cpp; sourceTree = "<group>"; };
- DF84203E0E7BA6A600F5680E /* gfx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gfx.cpp; sourceTree = "<group>"; };
- DF84203F0E7BA6A600F5680E /* icons.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = icons.cpp; sourceTree = "<group>"; };
- DF8420400E7BA6A600F5680E /* input.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = input.cpp; sourceTree = "<group>"; };
- DF8420410E7BA6A600F5680E /* intern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = intern.h; sourceTree = "<group>"; };
- DF8420420E7BA6A600F5680E /* items.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = items.cpp; sourceTree = "<group>"; };
- DF8420430E7BA6A600F5680E /* menus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = menus.cpp; sourceTree = "<group>"; };
- DF8420440E7BA6A600F5680E /* midi.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = midi.cpp; sourceTree = "<group>"; };
- DF8420450E7BA6A600F5680E /* midi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = midi.h; sourceTree = "<group>"; };
- DF8420460E7BA6A600F5680E /* midiparser_s1d.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = midiparser_s1d.cpp; sourceTree = "<group>"; };
- DF8420480E7BA6A600F5680E /* oracle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = oracle.cpp; sourceTree = "<group>"; };
- DF8420490E7BA6A600F5680E /* res.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = res.cpp; sourceTree = "<group>"; };
- DF84204A0E7BA6A600F5680E /* res_ami.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = res_ami.cpp; sourceTree = "<group>"; };
- DF84204B0E7BA6A600F5680E /* res_snd.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = res_snd.cpp; sourceTree = "<group>"; };
- DF84204C0E7BA6A600F5680E /* rooms.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rooms.cpp; sourceTree = "<group>"; };
- DF84204D0E7BA6A600F5680E /* saveload.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveload.cpp; sourceTree = "<group>"; };
- DF84204E0E7BA6A600F5680E /* script.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script.cpp; sourceTree = "<group>"; };
- DF84204F0E7BA6A600F5680E /* script_e1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_e1.cpp; sourceTree = "<group>"; };
- DF8420500E7BA6A600F5680E /* script_e2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_e2.cpp; sourceTree = "<group>"; };
- DF8420510E7BA6A600F5680E /* script_ff.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_ff.cpp; sourceTree = "<group>"; };
- DF8420520E7BA6A600F5680E /* script_pp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_pp.cpp; sourceTree = "<group>"; };
- DF8420530E7BA6A600F5680E /* script_s1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_s1.cpp; sourceTree = "<group>"; };
- DF8420540E7BA6A600F5680E /* script_s2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_s2.cpp; sourceTree = "<group>"; };
- DF8420550E7BA6A600F5680E /* script_ww.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_ww.cpp; sourceTree = "<group>"; };
- DF8420560E7BA6A600F5680E /* sound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound.cpp; sourceTree = "<group>"; };
- DF8420570E7BA6A600F5680E /* sound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound.h; sourceTree = "<group>"; };
- DF8420580E7BA6A600F5680E /* string.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = string.cpp; sourceTree = "<group>"; };
- DF8420590E7BA6A600F5680E /* subroutine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = subroutine.cpp; sourceTree = "<group>"; };
- DF84205A0E7BA6A600F5680E /* verb.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = verb.cpp; sourceTree = "<group>"; };
- DF84205B0E7BA6A600F5680E /* vga.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vga.cpp; sourceTree = "<group>"; };
- DF84205C0E7BA6A600F5680E /* vga.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vga.h; sourceTree = "<group>"; };
- DF84205D0E7BA6A600F5680E /* vga_e2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vga_e2.cpp; sourceTree = "<group>"; };
- DF84205E0E7BA6A600F5680E /* vga_ff.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vga_ff.cpp; sourceTree = "<group>"; };
- DF84205F0E7BA6A600F5680E /* vga_s1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vga_s1.cpp; sourceTree = "<group>"; };
- DF8420600E7BA6A600F5680E /* vga_s2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vga_s2.cpp; sourceTree = "<group>"; };
- DF8420610E7BA6A600F5680E /* vga_ww.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vga_ww.cpp; sourceTree = "<group>"; };
- DF8420620E7BA6A600F5680E /* window.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = window.cpp; sourceTree = "<group>"; };
- DF8420630E7BA6A600F5680E /* zones.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = zones.cpp; sourceTree = "<group>"; };
- DF8420650E7BA6A600F5680E /* anim.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = anim.cpp; sourceTree = "<group>"; };
- DF8420660E7BA6A600F5680E /* anim.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = anim.h; sourceTree = "<group>"; };
- DF8420670E7BA6A600F5680E /* bg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bg.cpp; sourceTree = "<group>"; };
- DF8420680E7BA6A600F5680E /* bg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bg.h; sourceTree = "<group>"; };
- DF8420690E7BA6A600F5680E /* bg_list.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bg_list.cpp; sourceTree = "<group>"; };
- DF84206A0E7BA6A600F5680E /* bg_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bg_list.h; sourceTree = "<group>"; };
- DF84206B0E7BA6A600F5680E /* cine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cine.cpp; sourceTree = "<group>"; };
- DF84206C0E7BA6A600F5680E /* cine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cine.h; sourceTree = "<group>"; };
- DF84206D0E7BA6A600F5680E /* detection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = detection.cpp; sourceTree = "<group>"; };
- DF84206E0E7BA6A600F5680E /* gfx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gfx.cpp; sourceTree = "<group>"; };
- DF84206F0E7BA6A600F5680E /* gfx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gfx.h; sourceTree = "<group>"; };
- DF8420700E7BA6A600F5680E /* main_loop.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main_loop.cpp; sourceTree = "<group>"; };
- DF8420710E7BA6A600F5680E /* main_loop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = main_loop.h; sourceTree = "<group>"; };
- DF8420730E7BA6A600F5680E /* msg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = msg.cpp; sourceTree = "<group>"; };
- DF8420740E7BA6A600F5680E /* msg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = msg.h; sourceTree = "<group>"; };
- DF8420750E7BA6A600F5680E /* object.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = object.cpp; sourceTree = "<group>"; };
- DF8420760E7BA6A600F5680E /* object.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = object.h; sourceTree = "<group>"; };
- DF8420770E7BA6A600F5680E /* pal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pal.cpp; sourceTree = "<group>"; };
- DF8420780E7BA6A600F5680E /* pal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pal.h; sourceTree = "<group>"; };
- DF8420790E7BA6A600F5680E /* part.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = part.cpp; sourceTree = "<group>"; };
- DF84207A0E7BA6A600F5680E /* part.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = part.h; sourceTree = "<group>"; };
- DF84207B0E7BA6A600F5680E /* prc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = prc.cpp; sourceTree = "<group>"; };
- DF84207C0E7BA6A600F5680E /* prc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = prc.h; sourceTree = "<group>"; };
- DF84207D0E7BA6A600F5680E /* rel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rel.cpp; sourceTree = "<group>"; };
- DF84207E0E7BA6A600F5680E /* rel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rel.h; sourceTree = "<group>"; };
- DF84207F0E7BA6A600F5680E /* script.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = script.h; sourceTree = "<group>"; };
- DF8420800E7BA6A600F5680E /* script_fw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_fw.cpp; sourceTree = "<group>"; };
- DF8420810E7BA6A600F5680E /* script_os.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_os.cpp; sourceTree = "<group>"; };
- DF8420820E7BA6A600F5680E /* sound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound.cpp; sourceTree = "<group>"; };
- DF8420830E7BA6A600F5680E /* sound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound.h; sourceTree = "<group>"; };
- DF8420840E7BA6A600F5680E /* texte.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = texte.cpp; sourceTree = "<group>"; };
- DF8420850E7BA6A600F5680E /* texte.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = texte.h; sourceTree = "<group>"; };
- DF8420860E7BA6A600F5680E /* unpack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = unpack.cpp; sourceTree = "<group>"; };
- DF8420870E7BA6A600F5680E /* unpack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unpack.h; sourceTree = "<group>"; };
- DF8420880E7BA6A600F5680E /* various.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = various.cpp; sourceTree = "<group>"; };
- DF8420890E7BA6A600F5680E /* various.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = various.h; sourceTree = "<group>"; };
- DF8420AB0E7BA6A600F5680E /* actor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = actor.cpp; sourceTree = "<group>"; };
- DF8420AC0E7BA6A600F5680E /* actor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = actor.h; sourceTree = "<group>"; };
- DF8420AE0E7BA6A600F5680E /* background.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = background.cpp; sourceTree = "<group>"; };
- DF8420AF0E7BA6A600F5680E /* background.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = background.h; sourceTree = "<group>"; };
- DF8420B10E7BA6A600F5680E /* backgroundIncrust.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = backgroundIncrust.cpp; sourceTree = "<group>"; };
- DF8420B20E7BA6A600F5680E /* backgroundIncrust.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = backgroundIncrust.h; sourceTree = "<group>"; };
- DF8420B40E7BA6A600F5680E /* cell.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cell.cpp; sourceTree = "<group>"; };
- DF8420B50E7BA6A600F5680E /* cell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cell.h; sourceTree = "<group>"; };
- DF8420B70E7BA6A600F5680E /* cruise.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cruise.cpp; sourceTree = "<group>"; };
- DF8420B80E7BA6A700F5680E /* cruise.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cruise.h; sourceTree = "<group>"; };
- DF8420BA0E7BA6A700F5680E /* cruise_main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cruise_main.cpp; sourceTree = "<group>"; };
- DF8420BB0E7BA6A700F5680E /* cruise_main.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cruise_main.h; sourceTree = "<group>"; };
- DF8420BD0E7BA6A700F5680E /* ctp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ctp.cpp; sourceTree = "<group>"; };
- DF8420BE0E7BA6A700F5680E /* ctp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ctp.h; sourceTree = "<group>"; };
- DF8420C00E7BA6A700F5680E /* dataLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dataLoader.cpp; sourceTree = "<group>"; };
- DF8420C10E7BA6A700F5680E /* dataLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dataLoader.h; sourceTree = "<group>"; };
- DF8420C30E7BA6A700F5680E /* decompiler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = decompiler.cpp; sourceTree = "<group>"; };
- DF8420C50E7BA6A700F5680E /* delphine-unpack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "delphine-unpack.cpp"; sourceTree = "<group>"; };
- DF8420C70E7BA6A700F5680E /* detection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = detection.cpp; sourceTree = "<group>"; };
- DF8420C90E7BA6A700F5680E /* font.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = font.cpp; sourceTree = "<group>"; };
- DF8420CA0E7BA6A700F5680E /* font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = font.h; sourceTree = "<group>"; };
- DF8420CF0E7BA6A700F5680E /* function.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = function.cpp; sourceTree = "<group>"; };
- DF8420D00E7BA6A700F5680E /* function.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = function.h; sourceTree = "<group>"; };
- DF8420D20E7BA6A700F5680E /* gfxModule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gfxModule.cpp; sourceTree = "<group>"; };
- DF8420D30E7BA6A700F5680E /* gfxModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gfxModule.h; sourceTree = "<group>"; };
- DF8420D60E7BA6A700F5680E /* linker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = linker.cpp; sourceTree = "<group>"; };
- DF8420D70E7BA6A700F5680E /* linker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = linker.h; sourceTree = "<group>"; };
- DF8420D90E7BA6A700F5680E /* mainDraw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mainDraw.cpp; sourceTree = "<group>"; };
- DF8420DA0E7BA6A700F5680E /* mainDraw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mainDraw.h; sourceTree = "<group>"; };
- DF8420DC0E7BA6A700F5680E /* menu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = menu.cpp; sourceTree = "<group>"; };
- DF8420DD0E7BA6A700F5680E /* menu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = menu.h; sourceTree = "<group>"; };
- DF8420E00E7BA6A700F5680E /* mouse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mouse.cpp; sourceTree = "<group>"; };
- DF8420E10E7BA6A700F5680E /* mouse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mouse.h; sourceTree = "<group>"; };
- DF8420E30E7BA6A700F5680E /* object.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = object.cpp; sourceTree = "<group>"; };
- DF8420E40E7BA6A700F5680E /* object.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = object.h; sourceTree = "<group>"; };
- DF8420E60E7BA6A700F5680E /* overlay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = overlay.cpp; sourceTree = "<group>"; };
- DF8420E70E7BA6A700F5680E /* overlay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = overlay.h; sourceTree = "<group>"; };
- DF8420E90E7BA6A700F5680E /* perso.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = perso.cpp; sourceTree = "<group>"; };
- DF8420EA0E7BA6A700F5680E /* perso.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = perso.h; sourceTree = "<group>"; };
- DF8420EC0E7BA6A700F5680E /* polys.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = polys.cpp; sourceTree = "<group>"; };
- DF8420ED0E7BA6A700F5680E /* polys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = polys.h; sourceTree = "<group>"; };
- DF8420EF0E7BA6A700F5680E /* saveload.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveload.cpp; sourceTree = "<group>"; };
- DF8420F00E7BA6A700F5680E /* saveload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = saveload.h; sourceTree = "<group>"; };
- DF8420F20E7BA6A700F5680E /* script.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script.cpp; sourceTree = "<group>"; };
- DF8420F30E7BA6A700F5680E /* script.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = script.h; sourceTree = "<group>"; };
- DF8420F50E7BA6A700F5680E /* stack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stack.cpp; sourceTree = "<group>"; };
- DF8420F60E7BA6A700F5680E /* stack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stack.h; sourceTree = "<group>"; };
- DF8420F90E7BA6A700F5680E /* various.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = various.cpp; sourceTree = "<group>"; };
- DF8420FA0E7BA6A700F5680E /* various.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = various.h; sourceTree = "<group>"; };
- DF8420FC0E7BA6A700F5680E /* vars.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vars.cpp; sourceTree = "<group>"; };
- DF8420FD0E7BA6A700F5680E /* vars.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vars.h; sourceTree = "<group>"; };
- DF8420FF0E7BA6A700F5680E /* volume.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = volume.cpp; sourceTree = "<group>"; };
- DF8421000E7BA6A700F5680E /* volume.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = volume.h; sourceTree = "<group>"; };
- DF8421020E7BA6A700F5680E /* dialogs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dialogs.cpp; sourceTree = "<group>"; };
- DF8421030E7BA6A700F5680E /* dialogs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dialogs.h; sourceTree = "<group>"; };
- DF8421050E7BA6A700F5680E /* actors.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = actors.cpp; sourceTree = "<group>"; };
- DF8421060E7BA6A700F5680E /* animation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = animation.cpp; sourceTree = "<group>"; };
- DF8421070E7BA6A700F5680E /* converse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = converse.cpp; sourceTree = "<group>"; };
- DF8421080E7BA6A700F5680E /* detection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = detection.cpp; sourceTree = "<group>"; };
- DF8421090E7BA6A700F5680E /* drascula.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = drascula.cpp; sourceTree = "<group>"; };
- DF84210A0E7BA6A700F5680E /* drascula.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = drascula.h; sourceTree = "<group>"; };
- DF84210B0E7BA6A700F5680E /* graphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = graphics.cpp; sourceTree = "<group>"; };
- DF84210C0E7BA6A700F5680E /* interface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = interface.cpp; sourceTree = "<group>"; };
- DF84210E0E7BA6A700F5680E /* objects.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = objects.cpp; sourceTree = "<group>"; };
- DF84210F0E7BA6A700F5680E /* palette.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = palette.cpp; sourceTree = "<group>"; };
- DF8421100E7BA6A700F5680E /* rooms.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rooms.cpp; sourceTree = "<group>"; };
- DF8421110E7BA6A700F5680E /* saveload.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveload.cpp; sourceTree = "<group>"; };
- DF8421120E7BA6A700F5680E /* sound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound.cpp; sourceTree = "<group>"; };
- DF8421130E7BA6A700F5680E /* talk.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = talk.cpp; sourceTree = "<group>"; };
- DF8421140E7BA6A700F5680E /* engine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = engine.cpp; sourceTree = "<group>"; };
- DF8421150E7BA6A700F5680E /* engine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = engine.h; sourceTree = "<group>"; };
- DF84211B0E7BA6A700F5680E /* dataio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dataio.cpp; sourceTree = "<group>"; };
- DF84211C0E7BA6A700F5680E /* dataio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dataio.h; sourceTree = "<group>"; };
- DF84211D0E7BA6A700F5680E /* detection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = detection.cpp; sourceTree = "<group>"; };
- DF84211E0E7BA6A700F5680E /* draw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = draw.cpp; sourceTree = "<group>"; };
- DF84211F0E7BA6A700F5680E /* draw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = draw.h; sourceTree = "<group>"; };
- DF8421200E7BA6A700F5680E /* draw_bargon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = draw_bargon.cpp; sourceTree = "<group>"; };
- DF8421210E7BA6A700F5680E /* draw_v1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = draw_v1.cpp; sourceTree = "<group>"; };
- DF8421220E7BA6A700F5680E /* draw_v2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = draw_v2.cpp; sourceTree = "<group>"; };
- DF8421250E7BA6A700F5680E /* game.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = game.cpp; sourceTree = "<group>"; };
- DF8421260E7BA6A700F5680E /* game.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = game.h; sourceTree = "<group>"; };
- DF8421290E7BA6A700F5680E /* global.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = global.cpp; sourceTree = "<group>"; };
- DF84212A0E7BA6A700F5680E /* global.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = global.h; sourceTree = "<group>"; };
- DF84212B0E7BA6A700F5680E /* gob.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gob.cpp; sourceTree = "<group>"; };
- DF84212C0E7BA6A700F5680E /* gob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gob.h; sourceTree = "<group>"; };
- DF84212D0E7BA6A700F5680E /* goblin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = goblin.cpp; sourceTree = "<group>"; };
- DF84212E0E7BA6A700F5680E /* goblin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = goblin.h; sourceTree = "<group>"; };
- DF84212F0E7BA6A700F5680E /* goblin_v1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = goblin_v1.cpp; sourceTree = "<group>"; };
- DF8421300E7BA6A700F5680E /* goblin_v2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = goblin_v2.cpp; sourceTree = "<group>"; };
- DF8421310E7BA6A700F5680E /* goblin_v3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = goblin_v3.cpp; sourceTree = "<group>"; };
- DF8421320E7BA6A700F5680E /* goblin_v4.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = goblin_v4.cpp; sourceTree = "<group>"; };
- DF8421330E7BA6A700F5680E /* init.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = init.cpp; sourceTree = "<group>"; };
- DF8421340E7BA6A700F5680E /* init.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = init.h; sourceTree = "<group>"; };
- DF8421350E7BA6A700F5680E /* init_v1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = init_v1.cpp; sourceTree = "<group>"; };
- DF8421360E7BA6A700F5680E /* init_v2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = init_v2.cpp; sourceTree = "<group>"; };
- DF8421370E7BA6A700F5680E /* init_v3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = init_v3.cpp; sourceTree = "<group>"; };
- DF8421380E7BA6A700F5680E /* inter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = inter.cpp; sourceTree = "<group>"; };
- DF8421390E7BA6A700F5680E /* inter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = inter.h; sourceTree = "<group>"; };
- DF84213A0E7BA6A700F5680E /* inter_bargon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = inter_bargon.cpp; sourceTree = "<group>"; };
- DF84213B0E7BA6A700F5680E /* inter_v1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = inter_v1.cpp; sourceTree = "<group>"; };
- DF84213C0E7BA6A700F5680E /* inter_v2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = inter_v2.cpp; sourceTree = "<group>"; };
- DF84213D0E7BA6A700F5680E /* inter_v3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = inter_v3.cpp; sourceTree = "<group>"; };
- DF84213E0E7BA6A700F5680E /* inter_v4.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = inter_v4.cpp; sourceTree = "<group>"; };
- DF84213F0E7BA6A700F5680E /* inter_v5.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = inter_v5.cpp; sourceTree = "<group>"; };
- DF8421400E7BA6A700F5680E /* inter_v6.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = inter_v6.cpp; sourceTree = "<group>"; };
- DF8421410E7BA6A700F5680E /* map.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = map.cpp; sourceTree = "<group>"; };
- DF8421420E7BA6A700F5680E /* map.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = map.h; sourceTree = "<group>"; };
- DF8421430E7BA6A700F5680E /* map_v1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = map_v1.cpp; sourceTree = "<group>"; };
- DF8421440E7BA6A700F5680E /* map_v2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = map_v2.cpp; sourceTree = "<group>"; };
- DF8421470E7BA6A700F5680E /* mult.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mult.cpp; sourceTree = "<group>"; };
- DF8421480E7BA6A700F5680E /* mult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mult.h; sourceTree = "<group>"; };
- DF8421490E7BA6A700F5680E /* mult_v1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mult_v1.cpp; sourceTree = "<group>"; };
- DF84214A0E7BA6A700F5680E /* mult_v2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mult_v2.cpp; sourceTree = "<group>"; };
- DF84214C0E7BA6A700F5680E /* palanim.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = palanim.cpp; sourceTree = "<group>"; };
- DF84214D0E7BA6A700F5680E /* palanim.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = palanim.h; sourceTree = "<group>"; };
- DF8421570E7BA6A700F5680E /* scenery.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scenery.cpp; sourceTree = "<group>"; };
- DF8421580E7BA6A700F5680E /* scenery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scenery.h; sourceTree = "<group>"; };
- DF8421590E7BA6A700F5680E /* scenery_v1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scenery_v1.cpp; sourceTree = "<group>"; };
- DF84215A0E7BA6A700F5680E /* scenery_v2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scenery_v2.cpp; sourceTree = "<group>"; };
- DF84215C0E7BA6A700F5680E /* adlib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = adlib.cpp; sourceTree = "<group>"; };
- DF84215D0E7BA6A700F5680E /* adlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = adlib.h; sourceTree = "<group>"; };
- DF84215E0E7BA6A700F5680E /* bgatmosphere.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bgatmosphere.cpp; sourceTree = "<group>"; };
- DF84215F0E7BA6A700F5680E /* bgatmosphere.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bgatmosphere.h; sourceTree = "<group>"; };
- DF8421600E7BA6A700F5680E /* cdrom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cdrom.cpp; sourceTree = "<group>"; };
- DF8421610E7BA6A700F5680E /* cdrom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cdrom.h; sourceTree = "<group>"; };
- DF8421620E7BA6A700F5680E /* infogrames.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = infogrames.cpp; sourceTree = "<group>"; };
- DF8421630E7BA6A700F5680E /* infogrames.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = infogrames.h; sourceTree = "<group>"; };
- DF8421640E7BA6A700F5680E /* pcspeaker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pcspeaker.cpp; sourceTree = "<group>"; };
- DF8421650E7BA6A700F5680E /* pcspeaker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pcspeaker.h; sourceTree = "<group>"; };
- DF8421660E7BA6A700F5680E /* sound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound.cpp; sourceTree = "<group>"; };
- DF8421670E7BA6A700F5680E /* sound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound.h; sourceTree = "<group>"; };
- DF8421680E7BA6A700F5680E /* soundblaster.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = soundblaster.cpp; sourceTree = "<group>"; };
- DF8421690E7BA6A700F5680E /* soundblaster.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = soundblaster.h; sourceTree = "<group>"; };
- DF84216A0E7BA6A700F5680E /* sounddesc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sounddesc.cpp; sourceTree = "<group>"; };
- DF84216B0E7BA6A700F5680E /* sounddesc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sounddesc.h; sourceTree = "<group>"; };
- DF84216C0E7BA6A700F5680E /* soundmixer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = soundmixer.cpp; sourceTree = "<group>"; };
- DF84216D0E7BA6A700F5680E /* soundmixer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = soundmixer.h; sourceTree = "<group>"; };
- DF84216F0E7BA6A700F5680E /* util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = util.cpp; sourceTree = "<group>"; };
- DF8421700E7BA6A700F5680E /* util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = util.h; sourceTree = "<group>"; };
- DF8421710E7BA6A700F5680E /* variables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = variables.cpp; sourceTree = "<group>"; };
- DF8421720E7BA6A700F5680E /* variables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = variables.h; sourceTree = "<group>"; };
- DF8421730E7BA6A700F5680E /* video.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = video.cpp; sourceTree = "<group>"; };
- DF8421740E7BA6A700F5680E /* video.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = video.h; sourceTree = "<group>"; };
- DF8421750E7BA6A700F5680E /* video_v1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = video_v1.cpp; sourceTree = "<group>"; };
- DF8421760E7BA6A700F5680E /* video_v2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = video_v2.cpp; sourceTree = "<group>"; };
- DF8421770E7BA6A700F5680E /* video_v6.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = video_v6.cpp; sourceTree = "<group>"; };
- DF8421780E7BA6A700F5680E /* videoplayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = videoplayer.cpp; sourceTree = "<group>"; };
- DF8421790E7BA6A700F5680E /* videoplayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = videoplayer.h; sourceTree = "<group>"; };
- DF8421A40E7BA6A800F5680E /* animator_hof.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = animator_hof.cpp; sourceTree = "<group>"; };
- DF8421A50E7BA6A800F5680E /* animator_lok.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = animator_lok.cpp; sourceTree = "<group>"; };
- DF8421A60E7BA6A800F5680E /* animator_lok.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = animator_lok.h; sourceTree = "<group>"; };
- DF8421A70E7BA6A800F5680E /* animator_mr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = animator_mr.cpp; sourceTree = "<group>"; };
- DF8421A90E7BA6A800F5680E /* animator_v2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = animator_v2.cpp; sourceTree = "<group>"; };
- DF8421AB0E7BA6A800F5680E /* debugger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debugger.cpp; sourceTree = "<group>"; };
- DF8421AC0E7BA6A800F5680E /* debugger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debugger.h; sourceTree = "<group>"; };
- DF8421AD0E7BA6A800F5680E /* detection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = detection.cpp; sourceTree = "<group>"; };
- DF8421AE0E7BA6A800F5680E /* gui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gui.cpp; sourceTree = "<group>"; };
- DF8421AF0E7BA6A800F5680E /* gui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gui.h; sourceTree = "<group>"; };
- DF8421B00E7BA6A800F5680E /* gui_hof.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gui_hof.cpp; sourceTree = "<group>"; };
- DF8421B10E7BA6A800F5680E /* gui_hof.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gui_hof.h; sourceTree = "<group>"; };
- DF8421B20E7BA6A800F5680E /* gui_lok.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gui_lok.cpp; sourceTree = "<group>"; };
- DF8421B30E7BA6A800F5680E /* gui_lok.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gui_lok.h; sourceTree = "<group>"; };
- DF8421B40E7BA6A800F5680E /* gui_mr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gui_mr.cpp; sourceTree = "<group>"; };
- DF8421B50E7BA6A800F5680E /* gui_mr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gui_mr.h; sourceTree = "<group>"; };
- DF8421B70E7BA6A800F5680E /* gui_v2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gui_v2.cpp; sourceTree = "<group>"; };
- DF8421B80E7BA6A800F5680E /* gui_v2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gui_v2.h; sourceTree = "<group>"; };
- DF8421BA0E7BA6A800F5680E /* items_hof.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = items_hof.cpp; sourceTree = "<group>"; };
- DF8421BB0E7BA6A800F5680E /* items_lok.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = items_lok.cpp; sourceTree = "<group>"; };
- DF8421BC0E7BA6A800F5680E /* items_mr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = items_mr.cpp; sourceTree = "<group>"; };
- DF8421BE0E7BA6A800F5680E /* items_v2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = items_v2.cpp; sourceTree = "<group>"; };
- DF8421C10E7BA6A800F5680E /* kyra_hof.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kyra_hof.cpp; sourceTree = "<group>"; };
- DF8421C20E7BA6A800F5680E /* kyra_hof.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kyra_hof.h; sourceTree = "<group>"; };
- DF8421C30E7BA6A800F5680E /* kyra_lok.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kyra_lok.cpp; sourceTree = "<group>"; };
- DF8421C40E7BA6A800F5680E /* kyra_lok.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kyra_lok.h; sourceTree = "<group>"; };
- DF8421C50E7BA6A800F5680E /* kyra_mr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kyra_mr.cpp; sourceTree = "<group>"; };
- DF8421C60E7BA6A800F5680E /* kyra_mr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kyra_mr.h; sourceTree = "<group>"; };
- DF8421C70E7BA6A800F5680E /* kyra_v1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kyra_v1.cpp; sourceTree = "<group>"; };
- DF8421C80E7BA6A800F5680E /* kyra_v1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kyra_v1.h; sourceTree = "<group>"; };
- DF8421C90E7BA6A800F5680E /* kyra_v2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kyra_v2.cpp; sourceTree = "<group>"; };
- DF8421CA0E7BA6A800F5680E /* kyra_v2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kyra_v2.h; sourceTree = "<group>"; };
- DF8421CC0E7BA6A800F5680E /* lol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lol.cpp; sourceTree = "<group>"; };
- DF8421CD0E7BA6A800F5680E /* lol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lol.h; sourceTree = "<group>"; };
- DF8421CF0E7BA6A800F5680E /* resource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resource.cpp; sourceTree = "<group>"; };
- DF8421D00E7BA6A800F5680E /* resource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resource.h; sourceTree = "<group>"; };
- DF8421D10E7BA6A800F5680E /* resource_intern.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resource_intern.cpp; sourceTree = "<group>"; };
- DF8421D20E7BA6A800F5680E /* resource_intern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resource_intern.h; sourceTree = "<group>"; };
- DF8421D30E7BA6A800F5680E /* saveload.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveload.cpp; sourceTree = "<group>"; };
- DF8421D40E7BA6A800F5680E /* saveload_hof.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveload_hof.cpp; sourceTree = "<group>"; };
- DF8421D50E7BA6A800F5680E /* saveload_lok.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveload_lok.cpp; sourceTree = "<group>"; };
- DF8421D60E7BA6A800F5680E /* saveload_mr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveload_mr.cpp; sourceTree = "<group>"; };
- DF8421DA0E7BA6A800F5680E /* scene_hof.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scene_hof.cpp; sourceTree = "<group>"; };
- DF8421DB0E7BA6A800F5680E /* scene_lok.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scene_lok.cpp; sourceTree = "<group>"; };
- DF8421DC0E7BA6A800F5680E /* scene_mr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scene_mr.cpp; sourceTree = "<group>"; };
- DF8421DD0E7BA6A800F5680E /* scene_v1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scene_v1.cpp; sourceTree = "<group>"; };
- DF8421DE0E7BA6A800F5680E /* scene_v2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scene_v2.cpp; sourceTree = "<group>"; };
- DF8421E00E7BA6A800F5680E /* screen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = screen.cpp; sourceTree = "<group>"; };
- DF8421E10E7BA6A800F5680E /* screen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = screen.h; sourceTree = "<group>"; };
- DF8421E20E7BA6A800F5680E /* screen_hof.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = screen_hof.cpp; sourceTree = "<group>"; };
- DF8421E30E7BA6A800F5680E /* screen_hof.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = screen_hof.h; sourceTree = "<group>"; };
- DF8421E40E7BA6A800F5680E /* screen_lok.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = screen_lok.cpp; sourceTree = "<group>"; };
- DF8421E50E7BA6A800F5680E /* screen_lok.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = screen_lok.h; sourceTree = "<group>"; };
- DF8421E60E7BA6A800F5680E /* screen_lol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = screen_lol.cpp; sourceTree = "<group>"; };
- DF8421E70E7BA6A800F5680E /* screen_lol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = screen_lol.h; sourceTree = "<group>"; };
- DF8421E80E7BA6A800F5680E /* screen_mr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = screen_mr.cpp; sourceTree = "<group>"; };
- DF8421E90E7BA6A800F5680E /* screen_mr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = screen_mr.h; sourceTree = "<group>"; };
- DF8421EB0E7BA6A800F5680E /* screen_v2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = screen_v2.cpp; sourceTree = "<group>"; };
- DF8421EC0E7BA6A800F5680E /* screen_v2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = screen_v2.h; sourceTree = "<group>"; };
- DF8421EE0E7BA6A800F5680E /* script.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script.cpp; sourceTree = "<group>"; };
- DF8421EF0E7BA6A800F5680E /* script.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = script.h; sourceTree = "<group>"; };
- DF8421F00E7BA6A800F5680E /* script_hof.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_hof.cpp; sourceTree = "<group>"; };
- DF8421F10E7BA6A800F5680E /* script_lok.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_lok.cpp; sourceTree = "<group>"; };
- DF8421F20E7BA6A800F5680E /* script_mr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_mr.cpp; sourceTree = "<group>"; };
- DF8421F30E7BA6A800F5680E /* script_tim.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_tim.cpp; sourceTree = "<group>"; };
- DF8421F40E7BA6A800F5680E /* script_tim.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = script_tim.h; sourceTree = "<group>"; };
- DF8421F50E7BA6A800F5680E /* script_v1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_v1.cpp; sourceTree = "<group>"; };
- DF8421F60E7BA6A800F5680E /* script_v2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_v2.cpp; sourceTree = "<group>"; };
- DF8421F80E7BA6A800F5680E /* seqplayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = seqplayer.cpp; sourceTree = "<group>"; };
- DF8421F90E7BA6A800F5680E /* seqplayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = seqplayer.h; sourceTree = "<group>"; };
- DF8421FA0E7BA6A800F5680E /* sequences_hof.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sequences_hof.cpp; sourceTree = "<group>"; };
- DF8421FB0E7BA6A800F5680E /* sequences_lok.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sequences_lok.cpp; sourceTree = "<group>"; };
- DF8421FC0E7BA6A800F5680E /* sequences_mr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sequences_mr.cpp; sourceTree = "<group>"; };
- DF8421FE0E7BA6A800F5680E /* sequences_v2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sequences_v2.cpp; sourceTree = "<group>"; };
- DF8422000E7BA6A800F5680E /* sound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound.cpp; sourceTree = "<group>"; };
- DF8422010E7BA6A800F5680E /* sound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound.h; sourceTree = "<group>"; };
- DF8422020E7BA6A800F5680E /* sound_adlib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound_adlib.cpp; sourceTree = "<group>"; };
- DF8422030E7BA6A800F5680E /* sound_digital.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound_digital.cpp; sourceTree = "<group>"; };
- DF8422040E7BA6A800F5680E /* sound_lok.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound_lok.cpp; sourceTree = "<group>"; };
- DF8422050E7BA6A800F5680E /* sound_towns.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound_towns.cpp; sourceTree = "<group>"; };
- DF8422070E7BA6A800F5680E /* sprites.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sprites.cpp; sourceTree = "<group>"; };
- DF8422080E7BA6A800F5680E /* sprites.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sprites.h; sourceTree = "<group>"; };
- DF8422090E7BA6A800F5680E /* staticres.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = staticres.cpp; sourceTree = "<group>"; };
- DF84220A0E7BA6A800F5680E /* text.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = text.cpp; sourceTree = "<group>"; };
- DF84220B0E7BA6A800F5680E /* text.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = text.h; sourceTree = "<group>"; };
- DF84220C0E7BA6A800F5680E /* text_hof.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = text_hof.cpp; sourceTree = "<group>"; };
- DF84220D0E7BA6A800F5680E /* text_hof.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = text_hof.h; sourceTree = "<group>"; };
- DF84220E0E7BA6A800F5680E /* text_lok.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = text_lok.cpp; sourceTree = "<group>"; };
- DF84220F0E7BA6A800F5680E /* text_mr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = text_mr.cpp; sourceTree = "<group>"; };
- DF8422100E7BA6A800F5680E /* text_mr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = text_mr.h; sourceTree = "<group>"; };
- DF8422140E7BA6A800F5680E /* timer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = timer.cpp; sourceTree = "<group>"; };
- DF8422150E7BA6A800F5680E /* timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = timer.h; sourceTree = "<group>"; };
- DF8422160E7BA6A800F5680E /* timer_hof.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = timer_hof.cpp; sourceTree = "<group>"; };
- DF8422170E7BA6A800F5680E /* timer_lok.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = timer_lok.cpp; sourceTree = "<group>"; };
- DF8422180E7BA6A800F5680E /* timer_mr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = timer_mr.cpp; sourceTree = "<group>"; };
- DF84221C0E7BA6A800F5680E /* vqa.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vqa.cpp; sourceTree = "<group>"; };
- DF84221D0E7BA6A800F5680E /* vqa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vqa.h; sourceTree = "<group>"; };
- DF84221E0E7BA6A800F5680E /* wsamovie.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wsamovie.cpp; sourceTree = "<group>"; };
- DF84221F0E7BA6A800F5680E /* wsamovie.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wsamovie.h; sourceTree = "<group>"; };
- DF8422210E7BA6A800F5680E /* animseq.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = animseq.cpp; sourceTree = "<group>"; };
- DF8422220E7BA6A800F5680E /* animseq.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = animseq.h; sourceTree = "<group>"; };
- DF8422230E7BA6A800F5680E /* debugger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debugger.cpp; sourceTree = "<group>"; };
- DF8422240E7BA6A800F5680E /* debugger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debugger.h; sourceTree = "<group>"; };
- DF8422250E7BA6A800F5680E /* decode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = decode.cpp; sourceTree = "<group>"; };
- DF8422260E7BA6A800F5680E /* decode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = decode.h; sourceTree = "<group>"; };
- DF8422270E7BA6A800F5680E /* detection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = detection.cpp; sourceTree = "<group>"; };
- DF8422280E7BA6A800F5680E /* disk.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = disk.cpp; sourceTree = "<group>"; };
- DF8422290E7BA6A800F5680E /* disk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = disk.h; sourceTree = "<group>"; };
- DF84222A0E7BA6A800F5680E /* events.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = events.cpp; sourceTree = "<group>"; };
- DF84222B0E7BA6A800F5680E /* events.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = events.h; sourceTree = "<group>"; };
- DF84222C0E7BA6A800F5680E /* fights.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fights.cpp; sourceTree = "<group>"; };
- DF84222D0E7BA6A800F5680E /* fights.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fights.h; sourceTree = "<group>"; };
- DF84222E0E7BA6A800F5680E /* game.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = game.cpp; sourceTree = "<group>"; };
- DF84222F0E7BA6A800F5680E /* game.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = game.h; sourceTree = "<group>"; };
- DF8422300E7BA6A800F5680E /* hotspots.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hotspots.cpp; sourceTree = "<group>"; };
- DF8422310E7BA6A800F5680E /* hotspots.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hotspots.h; sourceTree = "<group>"; };
- DF8422320E7BA6A800F5680E /* intro.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = intro.cpp; sourceTree = "<group>"; };
- DF8422330E7BA6A800F5680E /* intro.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = intro.h; sourceTree = "<group>"; };
- DF8422340E7BA6A800F5680E /* lure.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lure.cpp; sourceTree = "<group>"; };
- DF8422350E7BA6A800F5680E /* lure.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lure.h; sourceTree = "<group>"; };
- DF8422360E7BA6A800F5680E /* luredefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = luredefs.h; sourceTree = "<group>"; };
- DF8422370E7BA6A800F5680E /* memory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = memory.cpp; sourceTree = "<group>"; };
- DF8422380E7BA6A800F5680E /* memory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = memory.h; sourceTree = "<group>"; };
- DF8422390E7BA6A800F5680E /* menu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = menu.cpp; sourceTree = "<group>"; };
- DF84223A0E7BA6A800F5680E /* menu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = menu.h; sourceTree = "<group>"; };
- DF84223C0E7BA6A800F5680E /* palette.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = palette.cpp; sourceTree = "<group>"; };
- DF84223D0E7BA6A800F5680E /* palette.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = palette.h; sourceTree = "<group>"; };
- DF84223E0E7BA6A800F5680E /* res.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = res.cpp; sourceTree = "<group>"; };
- DF84223F0E7BA6A800F5680E /* res.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = res.h; sourceTree = "<group>"; };
- DF8422400E7BA6A800F5680E /* res_struct.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = res_struct.cpp; sourceTree = "<group>"; };
- DF8422410E7BA6A800F5680E /* res_struct.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = res_struct.h; sourceTree = "<group>"; };
- DF8422420E7BA6A800F5680E /* room.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = room.cpp; sourceTree = "<group>"; };
- DF8422430E7BA6A800F5680E /* room.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = room.h; sourceTree = "<group>"; };
- DF8422440E7BA6A800F5680E /* screen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = screen.cpp; sourceTree = "<group>"; };
- DF8422450E7BA6A800F5680E /* screen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = screen.h; sourceTree = "<group>"; };
- DF8422460E7BA6A800F5680E /* scripts.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scripts.cpp; sourceTree = "<group>"; };
- DF8422470E7BA6A800F5680E /* scripts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scripts.h; sourceTree = "<group>"; };
- DF8422480E7BA6A800F5680E /* sound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound.cpp; sourceTree = "<group>"; };
- DF8422490E7BA6A800F5680E /* sound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound.h; sourceTree = "<group>"; };
- DF84224A0E7BA6A800F5680E /* strings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = strings.cpp; sourceTree = "<group>"; };
- DF84224B0E7BA6A800F5680E /* strings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = strings.h; sourceTree = "<group>"; };
- DF84224C0E7BA6A800F5680E /* surface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = surface.cpp; sourceTree = "<group>"; };
- DF84224D0E7BA6A800F5680E /* surface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = surface.h; sourceTree = "<group>"; };
- DF84226E0E7BA6A800F5680E /* actor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = actor.cpp; sourceTree = "<group>"; };
- DF84226F0E7BA6A800F5680E /* actor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = actor.h; sourceTree = "<group>"; };
- DF8422710E7BA6A800F5680E /* animation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = animation.cpp; sourceTree = "<group>"; };
- DF8422720E7BA6A800F5680E /* animation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = animation.h; sourceTree = "<group>"; };
- DF8422740E7BA6A800F5680E /* assets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = assets.cpp; sourceTree = "<group>"; };
- DF8422750E7BA6A800F5680E /* assets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = assets.h; sourceTree = "<group>"; };
- DF8422770E7BA6A900F5680E /* burger_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = burger_data.h; sourceTree = "<group>"; };
- DF8422780E7BA6A900F5680E /* compression.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = compression.cpp; sourceTree = "<group>"; };
- DF8422790E7BA6A900F5680E /* compression.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = compression.h; sourceTree = "<group>"; };
- DF84227B0E7BA6A900F5680E /* console.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = console.cpp; sourceTree = "<group>"; };
- DF84227C0E7BA6A900F5680E /* console.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = console.h; sourceTree = "<group>"; };
- DF84227E0E7BA6A900F5680E /* converse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = converse.cpp; sourceTree = "<group>"; };
- DF84227F0E7BA6A900F5680E /* converse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = converse.h; sourceTree = "<group>"; };
- DF8422810E7BA6A900F5680E /* detection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = detection.cpp; sourceTree = "<group>"; };
- DF8422830E7BA6A900F5680E /* events.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = events.cpp; sourceTree = "<group>"; };
- DF8422840E7BA6A900F5680E /* events.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = events.h; sourceTree = "<group>"; };
- DF8422860E7BA6A900F5680E /* font.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = font.cpp; sourceTree = "<group>"; };
- DF8422870E7BA6A900F5680E /* font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = font.h; sourceTree = "<group>"; };
- DF8422890E7BA6A900F5680E /* globals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = globals.cpp; sourceTree = "<group>"; };
- DF84228A0E7BA6A900F5680E /* globals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = globals.h; sourceTree = "<group>"; };
- DF84228C0E7BA6A900F5680E /* graphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = graphics.cpp; sourceTree = "<group>"; };
- DF84228D0E7BA6A900F5680E /* graphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = graphics.h; sourceTree = "<group>"; };
- DF84228F0E7BA6A900F5680E /* gui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gui.cpp; sourceTree = "<group>"; };
- DF8422900E7BA6A900F5680E /* gui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gui.h; sourceTree = "<group>"; };
- DF8422920E7BA6A900F5680E /* hotspot.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hotspot.cpp; sourceTree = "<group>"; };
- DF8422930E7BA6A900F5680E /* hotspot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hotspot.h; sourceTree = "<group>"; };
- DF8422960E7BA6A900F5680E /* m4.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = m4.cpp; sourceTree = "<group>"; };
- DF8422970E7BA6A900F5680E /* m4.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = m4.h; sourceTree = "<group>"; };
- DF8422990E7BA6A900F5680E /* m4_menus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = m4_menus.cpp; sourceTree = "<group>"; };
- DF84229A0E7BA6A900F5680E /* m4_menus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = m4_menus.h; sourceTree = "<group>"; };
- DF84229C0E7BA6A900F5680E /* m4_views.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = m4_views.cpp; sourceTree = "<group>"; };
- DF84229D0E7BA6A900F5680E /* m4_views.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = m4_views.h; sourceTree = "<group>"; };
- DF84229F0E7BA6A900F5680E /* mads_anim.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mads_anim.cpp; sourceTree = "<group>"; };
- DF8422A00E7BA6A900F5680E /* mads_anim.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mads_anim.h; sourceTree = "<group>"; };
- DF8422A20E7BA6A900F5680E /* mads_menus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mads_menus.cpp; sourceTree = "<group>"; };
- DF8422A30E7BA6A900F5680E /* mads_menus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mads_menus.h; sourceTree = "<group>"; };
- DF8422A50E7BA6A900F5680E /* midi.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = midi.cpp; sourceTree = "<group>"; };
- DF8422A60E7BA6A900F5680E /* midi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = midi.h; sourceTree = "<group>"; };
- DF8422A90E7BA6A900F5680E /* rails.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rails.cpp; sourceTree = "<group>"; };
- DF8422AA0E7BA6A900F5680E /* rails.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rails.h; sourceTree = "<group>"; };
- DF8422AC0E7BA6A900F5680E /* resource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resource.cpp; sourceTree = "<group>"; };
- DF8422AD0E7BA6A900F5680E /* resource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resource.h; sourceTree = "<group>"; };
- DF8422AF0E7BA6A900F5680E /* saveload.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveload.cpp; sourceTree = "<group>"; };
- DF8422B00E7BA6A900F5680E /* saveload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = saveload.h; sourceTree = "<group>"; };
- DF8422B20E7BA6A900F5680E /* scene.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scene.cpp; sourceTree = "<group>"; };
- DF8422B30E7BA6A900F5680E /* scene.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scene.h; sourceTree = "<group>"; };
- DF8422B50E7BA6A900F5680E /* script.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script.cpp; sourceTree = "<group>"; };
- DF8422B60E7BA6A900F5680E /* script.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = script.h; sourceTree = "<group>"; };
- DF8422B80E7BA6A900F5680E /* scripttab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scripttab.h; sourceTree = "<group>"; };
- DF8422B90E7BA6A900F5680E /* sound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound.cpp; sourceTree = "<group>"; };
- DF8422BA0E7BA6A900F5680E /* sound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound.h; sourceTree = "<group>"; };
- DF8422BC0E7BA6A900F5680E /* sprite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sprite.cpp; sourceTree = "<group>"; };
- DF8422BD0E7BA6A900F5680E /* sprite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sprite.h; sourceTree = "<group>"; };
- DF8422BF0E7BA6A900F5680E /* viewmgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = viewmgr.cpp; sourceTree = "<group>"; };
- DF8422C00E7BA6A900F5680E /* viewmgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = viewmgr.h; sourceTree = "<group>"; };
- DF8422C20E7BA6A900F5680E /* woodscript.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = woodscript.cpp; sourceTree = "<group>"; };
- DF8422C30E7BA6A900F5680E /* woodscript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = woodscript.h; sourceTree = "<group>"; };
- DF8422C50E7BA6A900F5680E /* ws_machine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ws_machine.cpp; sourceTree = "<group>"; };
- DF8422C70E7BA6A900F5680E /* ws_sequence.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ws_sequence.cpp; sourceTree = "<group>"; };
- DF8422CA0E7BA6A900F5680E /* database.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = database.cpp; sourceTree = "<group>"; };
- DF8422CB0E7BA6A900F5680E /* database.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = database.h; sourceTree = "<group>"; };
- DF8422CC0E7BA6A900F5680E /* detection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = detection.cpp; sourceTree = "<group>"; };
- DF8422CD0E7BA6A900F5680E /* graphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = graphics.cpp; sourceTree = "<group>"; };
- DF8422CE0E7BA6A900F5680E /* graphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = graphics.h; sourceTree = "<group>"; };
- DF8422CF0E7BA6A900F5680E /* made.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = made.cpp; sourceTree = "<group>"; };
- DF8422D00E7BA6A900F5680E /* made.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = made.h; sourceTree = "<group>"; };
- DF8422D20E7BA6A900F5680E /* music.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = music.cpp; sourceTree = "<group>"; };
- DF8422D30E7BA6A900F5680E /* music.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = music.h; sourceTree = "<group>"; };
- DF8422D40E7BA6A900F5680E /* pmvplayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pmvplayer.cpp; sourceTree = "<group>"; };
- DF8422D50E7BA6A900F5680E /* pmvplayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pmvplayer.h; sourceTree = "<group>"; };
- DF8422D60E7BA6A900F5680E /* redreader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = redreader.cpp; sourceTree = "<group>"; };
- DF8422D70E7BA6A900F5680E /* redreader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = redreader.h; sourceTree = "<group>"; };
- DF8422D80E7BA6A900F5680E /* resource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resource.cpp; sourceTree = "<group>"; };
- DF8422D90E7BA6A900F5680E /* resource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resource.h; sourceTree = "<group>"; };
- DF8422DA0E7BA6A900F5680E /* screen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = screen.cpp; sourceTree = "<group>"; };
- DF8422DB0E7BA6A900F5680E /* screen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = screen.h; sourceTree = "<group>"; };
- DF8422DC0E7BA6A900F5680E /* screenfx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = screenfx.cpp; sourceTree = "<group>"; };
- DF8422DD0E7BA6A900F5680E /* screenfx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = screenfx.h; sourceTree = "<group>"; };
- DF8422DE0E7BA6A900F5680E /* script.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script.cpp; sourceTree = "<group>"; };
- DF8422DF0E7BA6A900F5680E /* script.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = script.h; sourceTree = "<group>"; };
- DF8422E00E7BA6A900F5680E /* scriptfuncs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scriptfuncs.cpp; sourceTree = "<group>"; };
- DF8422E10E7BA6A900F5680E /* scriptfuncs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scriptfuncs.h; sourceTree = "<group>"; };
- DF8422E20E7BA6A900F5680E /* sound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound.cpp; sourceTree = "<group>"; };
- DF8422E30E7BA6A900F5680E /* sound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound.h; sourceTree = "<group>"; };
- DF8422E40E7BA6A900F5680E /* metaengine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = metaengine.h; sourceTree = "<group>"; };
- DF8422E70E7BA6A900F5680E /* balloons.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = balloons.cpp; sourceTree = "<group>"; };
- DF8422E80E7BA6A900F5680E /* callables_br.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = callables_br.cpp; sourceTree = "<group>"; };
- DF8422E90E7BA6A900F5680E /* callables_ns.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = callables_ns.cpp; sourceTree = "<group>"; };
- DF8422EA0E7BA6A900F5680E /* debug.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug.cpp; sourceTree = "<group>"; };
- DF8422EB0E7BA6A900F5680E /* debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug.h; sourceTree = "<group>"; };
- DF8422EC0E7BA6A900F5680E /* detection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = detection.cpp; sourceTree = "<group>"; };
- DF8422ED0E7BA6A900F5680E /* dialogue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dialogue.cpp; sourceTree = "<group>"; };
- DF8422EE0E7BA6A900F5680E /* disk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = disk.h; sourceTree = "<group>"; };
- DF8422EF0E7BA6A900F5680E /* disk_br.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = disk_br.cpp; sourceTree = "<group>"; };
- DF8422F00E7BA6A900F5680E /* disk_ns.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = disk_ns.cpp; sourceTree = "<group>"; };
- DF8422F10E7BA6A900F5680E /* exec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = exec.h; sourceTree = "<group>"; };
- DF8422F20E7BA6A900F5680E /* exec_br.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = exec_br.cpp; sourceTree = "<group>"; };
- DF8422F30E7BA6A900F5680E /* exec_ns.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = exec_ns.cpp; sourceTree = "<group>"; };
- DF8422F40E7BA6A900F5680E /* font.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = font.cpp; sourceTree = "<group>"; };
- DF8422F50E7BA6A900F5680E /* gfxbase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gfxbase.cpp; sourceTree = "<group>"; };
- DF8422F60E7BA6A900F5680E /* graphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = graphics.cpp; sourceTree = "<group>"; };
- DF8422F70E7BA6A900F5680E /* graphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = graphics.h; sourceTree = "<group>"; };
- DF8422F80E7BA6A900F5680E /* gui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gui.cpp; sourceTree = "<group>"; };
- DF8422F90E7BA6A900F5680E /* gui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gui.h; sourceTree = "<group>"; };
- DF8422FA0E7BA6A900F5680E /* gui_br.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gui_br.cpp; sourceTree = "<group>"; };
- DF8422FB0E7BA6A900F5680E /* gui_ns.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gui_ns.cpp; sourceTree = "<group>"; };
- DF8422FC0E7BA6A900F5680E /* input.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = input.cpp; sourceTree = "<group>"; };
- DF8422FD0E7BA6A900F5680E /* input.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = input.h; sourceTree = "<group>"; };
- DF8422FE0E7BA6A900F5680E /* inventory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = inventory.cpp; sourceTree = "<group>"; };
- DF8422FF0E7BA6A900F5680E /* inventory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = inventory.h; sourceTree = "<group>"; };
- DF8423010E7BA6A900F5680E /* objects.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = objects.cpp; sourceTree = "<group>"; };
- DF8423020E7BA6A900F5680E /* objects.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = objects.h; sourceTree = "<group>"; };
- DF8423030E7BA6A900F5680E /* parallaction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parallaction.cpp; sourceTree = "<group>"; };
- DF8423040E7BA6A900F5680E /* parallaction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = parallaction.h; sourceTree = "<group>"; };
- DF8423050E7BA6A900F5680E /* parallaction_br.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parallaction_br.cpp; sourceTree = "<group>"; };
- DF8423060E7BA6A900F5680E /* parallaction_ns.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parallaction_ns.cpp; sourceTree = "<group>"; };
- DF8423070E7BA6A900F5680E /* parser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parser.cpp; sourceTree = "<group>"; };
- DF8423080E7BA6A900F5680E /* parser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = parser.h; sourceTree = "<group>"; };
- DF8423090E7BA6A900F5680E /* parser_br.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parser_br.cpp; sourceTree = "<group>"; };
- DF84230A0E7BA6A900F5680E /* parser_ns.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parser_ns.cpp; sourceTree = "<group>"; };
- DF84230B0E7BA6A900F5680E /* saveload.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveload.cpp; sourceTree = "<group>"; };
- DF84230C0E7BA6A900F5680E /* saveload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = saveload.h; sourceTree = "<group>"; };
- DF84230E0E7BA6A900F5680E /* sound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound.h; sourceTree = "<group>"; };
- DF84230F0E7BA6A900F5680E /* staticres.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = staticres.cpp; sourceTree = "<group>"; };
- DF8423100E7BA6A900F5680E /* walk.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = walk.cpp; sourceTree = "<group>"; };
- DF8423110E7BA6A900F5680E /* walk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = walk.h; sourceTree = "<group>"; };
- DF8423130E7BA6A900F5680E /* bankman.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bankman.cpp; sourceTree = "<group>"; };
- DF8423140E7BA6A900F5680E /* bankman.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bankman.h; sourceTree = "<group>"; };
- DF8423150E7BA6A900F5680E /* command.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = command.cpp; sourceTree = "<group>"; };
- DF8423160E7BA6A900F5680E /* command.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = command.h; sourceTree = "<group>"; };
- DF8423170E7BA6A900F5680E /* credits.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = credits.cpp; sourceTree = "<group>"; };
- DF8423180E7BA6A900F5680E /* credits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = credits.h; sourceTree = "<group>"; };
- DF8423190E7BA6A900F5680E /* cutaway.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cutaway.cpp; sourceTree = "<group>"; };
- DF84231A0E7BA6A900F5680E /* cutaway.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cutaway.h; sourceTree = "<group>"; };
- DF84231B0E7BA6A900F5680E /* debug.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug.cpp; sourceTree = "<group>"; };
- DF84231C0E7BA6A900F5680E /* debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug.h; sourceTree = "<group>"; };
- DF84231D0E7BA6A900F5680E /* defs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = defs.h; sourceTree = "<group>"; };
- DF84231E0E7BA6A900F5680E /* display.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = display.cpp; sourceTree = "<group>"; };
- DF84231F0E7BA6A900F5680E /* display.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = display.h; sourceTree = "<group>"; };
- DF8423200E7BA6A900F5680E /* graphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = graphics.cpp; sourceTree = "<group>"; };
- DF8423210E7BA6A900F5680E /* graphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = graphics.h; sourceTree = "<group>"; };
- DF8423220E7BA6A900F5680E /* grid.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = grid.cpp; sourceTree = "<group>"; };
- DF8423230E7BA6A900F5680E /* grid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = grid.h; sourceTree = "<group>"; };
- DF8423240E7BA6A900F5680E /* input.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = input.cpp; sourceTree = "<group>"; };
- DF8423250E7BA6A900F5680E /* input.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = input.h; sourceTree = "<group>"; };
- DF8423260E7BA6A900F5680E /* journal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = journal.cpp; sourceTree = "<group>"; };
- DF8423270E7BA6A900F5680E /* journal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = journal.h; sourceTree = "<group>"; };
- DF8423280E7BA6A900F5680E /* logic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = logic.cpp; sourceTree = "<group>"; };
- DF8423290E7BA6A900F5680E /* logic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = logic.h; sourceTree = "<group>"; };
- DF84232A0E7BA6A900F5680E /* midiadlib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = midiadlib.cpp; sourceTree = "<group>"; };
- DF84232C0E7BA6A900F5680E /* music.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = music.cpp; sourceTree = "<group>"; };
- DF84232D0E7BA6A900F5680E /* music.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = music.h; sourceTree = "<group>"; };
- DF84232E0E7BA6A900F5680E /* musicdata.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = musicdata.cpp; sourceTree = "<group>"; };
- DF84232F0E7BA6A900F5680E /* queen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = queen.cpp; sourceTree = "<group>"; };
- DF8423300E7BA6A900F5680E /* queen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = queen.h; sourceTree = "<group>"; };
- DF8423310E7BA6A900F5680E /* resource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resource.cpp; sourceTree = "<group>"; };
- DF8423320E7BA6A900F5680E /* resource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resource.h; sourceTree = "<group>"; };
- DF8423330E7BA6A900F5680E /* restables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = restables.cpp; sourceTree = "<group>"; };
- DF8423340E7BA6A900F5680E /* sound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound.cpp; sourceTree = "<group>"; };
- DF8423350E7BA6A900F5680E /* sound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound.h; sourceTree = "<group>"; };
- DF8423360E7BA6A900F5680E /* state.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = state.cpp; sourceTree = "<group>"; };
- DF8423370E7BA6A900F5680E /* state.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = state.h; sourceTree = "<group>"; };
- DF8423380E7BA6A900F5680E /* structs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = structs.h; sourceTree = "<group>"; };
- DF8423390E7BA6A900F5680E /* talk.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = talk.cpp; sourceTree = "<group>"; };
- DF84233A0E7BA6A900F5680E /* talk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = talk.h; sourceTree = "<group>"; };
- DF84233B0E7BA6A900F5680E /* walk.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = walk.cpp; sourceTree = "<group>"; };
- DF84233C0E7BA6A900F5680E /* walk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = walk.h; sourceTree = "<group>"; };
- DF84233F0E7BA6AA00F5680E /* actor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = actor.cpp; sourceTree = "<group>"; };
- DF8423400E7BA6AA00F5680E /* actor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = actor.h; sourceTree = "<group>"; };
- DF8423410E7BA6AA00F5680E /* actor_path.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = actor_path.cpp; sourceTree = "<group>"; };
- DF8423420E7BA6AA00F5680E /* actor_walk.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = actor_walk.cpp; sourceTree = "<group>"; };
- DF8423430E7BA6AA00F5680E /* animation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = animation.cpp; sourceTree = "<group>"; };
- DF8423440E7BA6AA00F5680E /* animation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = animation.h; sourceTree = "<group>"; };
- DF8423450E7BA6AA00F5680E /* console.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = console.cpp; sourceTree = "<group>"; };
- DF8423460E7BA6AA00F5680E /* console.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = console.h; sourceTree = "<group>"; };
- DF8423470E7BA6AA00F5680E /* detection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = detection.cpp; sourceTree = "<group>"; };
- DF8423480E7BA6AA00F5680E /* detection_tables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = detection_tables.h; sourceTree = "<group>"; };
- DF8423490E7BA6AA00F5680E /* displayinfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = displayinfo.h; sourceTree = "<group>"; };
- DF84234A0E7BA6AA00F5680E /* events.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = events.cpp; sourceTree = "<group>"; };
- DF84234B0E7BA6AA00F5680E /* events.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = events.h; sourceTree = "<group>"; };
- DF84234C0E7BA6AA00F5680E /* font.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = font.cpp; sourceTree = "<group>"; };
- DF84234D0E7BA6AA00F5680E /* font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = font.h; sourceTree = "<group>"; };
- DF84234E0E7BA6AA00F5680E /* font_map.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = font_map.cpp; sourceTree = "<group>"; };
- DF84234F0E7BA6AA00F5680E /* gfx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gfx.cpp; sourceTree = "<group>"; };
- DF8423500E7BA6AA00F5680E /* gfx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gfx.h; sourceTree = "<group>"; };
- DF8423520E7BA6AA00F5680E /* image.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = image.cpp; sourceTree = "<group>"; };
- DF8423530E7BA6AA00F5680E /* input.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = input.cpp; sourceTree = "<group>"; };
- DF8423540E7BA6AA00F5680E /* interface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = interface.cpp; sourceTree = "<group>"; };
- DF8423550E7BA6AA00F5680E /* interface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = interface.h; sourceTree = "<group>"; };
- DF8423560E7BA6AA00F5680E /* introproc_ihnm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = introproc_ihnm.cpp; sourceTree = "<group>"; };
- DF8423570E7BA6AA00F5680E /* introproc_ite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = introproc_ite.cpp; sourceTree = "<group>"; };
- DF8423580E7BA6AA00F5680E /* isomap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = isomap.cpp; sourceTree = "<group>"; };
- DF8423590E7BA6AA00F5680E /* isomap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = isomap.h; sourceTree = "<group>"; };
- DF84235B0E7BA6AA00F5680E /* itedata.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = itedata.cpp; sourceTree = "<group>"; };
- DF84235C0E7BA6AA00F5680E /* itedata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = itedata.h; sourceTree = "<group>"; };
- DF84235F0E7BA6AA00F5680E /* music.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = music.cpp; sourceTree = "<group>"; };
- DF8423600E7BA6AA00F5680E /* music.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = music.h; sourceTree = "<group>"; };
- DF8423610E7BA6AA00F5680E /* objectmap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = objectmap.cpp; sourceTree = "<group>"; };
- DF8423620E7BA6AA00F5680E /* objectmap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = objectmap.h; sourceTree = "<group>"; };
- DF8423630E7BA6AA00F5680E /* palanim.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = palanim.cpp; sourceTree = "<group>"; };
- DF8423640E7BA6AA00F5680E /* palanim.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = palanim.h; sourceTree = "<group>"; };
- DF8423650E7BA6AA00F5680E /* puzzle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = puzzle.cpp; sourceTree = "<group>"; };
- DF8423660E7BA6AA00F5680E /* puzzle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = puzzle.h; sourceTree = "<group>"; };
- DF8423670E7BA6AA00F5680E /* render.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = render.cpp; sourceTree = "<group>"; };
- DF8423680E7BA6AA00F5680E /* render.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = render.h; sourceTree = "<group>"; };
- DF84236B0E7BA6AA00F5680E /* saga.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saga.cpp; sourceTree = "<group>"; };
- DF84236C0E7BA6AA00F5680E /* saga.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = saga.h; sourceTree = "<group>"; };
- DF84236D0E7BA6AA00F5680E /* saveload.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveload.cpp; sourceTree = "<group>"; };
- DF84236E0E7BA6AA00F5680E /* scene.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scene.cpp; sourceTree = "<group>"; };
- DF84236F0E7BA6AA00F5680E /* scene.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scene.h; sourceTree = "<group>"; };
- DF8423700E7BA6AA00F5680E /* script.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script.cpp; sourceTree = "<group>"; };
- DF8423710E7BA6AA00F5680E /* script.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = script.h; sourceTree = "<group>"; };
- DF8423720E7BA6AA00F5680E /* sfuncs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sfuncs.cpp; sourceTree = "<group>"; };
- DF8423730E7BA6AA00F5680E /* sndres.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sndres.cpp; sourceTree = "<group>"; };
- DF8423740E7BA6AA00F5680E /* sndres.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sndres.h; sourceTree = "<group>"; };
- DF8423750E7BA6AA00F5680E /* sound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound.cpp; sourceTree = "<group>"; };
- DF8423760E7BA6AA00F5680E /* sound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound.h; sourceTree = "<group>"; };
- DF8423770E7BA6AA00F5680E /* sprite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sprite.cpp; sourceTree = "<group>"; };
- DF8423780E7BA6AA00F5680E /* sprite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sprite.h; sourceTree = "<group>"; };
- DF8423790E7BA6AA00F5680E /* sthread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sthread.cpp; sourceTree = "<group>"; };
- DF84237C0E7BA6AA00F5680E /* actor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = actor.cpp; sourceTree = "<group>"; };
- DF84237D0E7BA6AA00F5680E /* actor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = actor.h; sourceTree = "<group>"; };
- DF84237E0E7BA6AA00F5680E /* akos.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = akos.cpp; sourceTree = "<group>"; };
- DF84237F0E7BA6AA00F5680E /* akos.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = akos.h; sourceTree = "<group>"; };
- DF8423800E7BA6AA00F5680E /* base-costume.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "base-costume.cpp"; sourceTree = "<group>"; };
- DF8423810E7BA6AA00F5680E /* base-costume.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "base-costume.h"; sourceTree = "<group>"; };
- DF8423820E7BA6AA00F5680E /* bomp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bomp.cpp; sourceTree = "<group>"; };
- DF8423830E7BA6AA00F5680E /* bomp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bomp.h; sourceTree = "<group>"; };
- DF8423840E7BA6AA00F5680E /* boxes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = boxes.cpp; sourceTree = "<group>"; };
- DF8423850E7BA6AA00F5680E /* boxes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = boxes.h; sourceTree = "<group>"; };
- DF8423860E7BA6AA00F5680E /* camera.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = camera.cpp; sourceTree = "<group>"; };
- DF8423870E7BA6AA00F5680E /* charset-fontdata.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "charset-fontdata.cpp"; sourceTree = "<group>"; };
- DF8423880E7BA6AA00F5680E /* charset.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = charset.cpp; sourceTree = "<group>"; };
- DF8423890E7BA6AA00F5680E /* charset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = charset.h; sourceTree = "<group>"; };
- DF84238A0E7BA6AA00F5680E /* costume.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = costume.cpp; sourceTree = "<group>"; };
- DF84238B0E7BA6AA00F5680E /* costume.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = costume.h; sourceTree = "<group>"; };
- DF84238C0E7BA6AA00F5680E /* cursor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cursor.cpp; sourceTree = "<group>"; };
- DF84238D0E7BA6AA00F5680E /* debugger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debugger.cpp; sourceTree = "<group>"; };
- DF84238E0E7BA6AA00F5680E /* debugger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debugger.h; sourceTree = "<group>"; };
- DF84238F0E7BA6AA00F5680E /* detection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = detection.cpp; sourceTree = "<group>"; };
- DF8423900E7BA6AA00F5680E /* detection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = detection.h; sourceTree = "<group>"; };
- DF8423910E7BA6AA00F5680E /* detection_tables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = detection_tables.h; sourceTree = "<group>"; };
- DF8423920E7BA6AA00F5680E /* dialogs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dialogs.cpp; sourceTree = "<group>"; };
- DF8423930E7BA6AA00F5680E /* dialogs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dialogs.h; sourceTree = "<group>"; };
- DF8423940E7BA6AA00F5680E /* file.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = file.cpp; sourceTree = "<group>"; };
- DF8423950E7BA6AA00F5680E /* file.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = file.h; sourceTree = "<group>"; };
- DF8423960E7BA6AA00F5680E /* file_nes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = file_nes.cpp; sourceTree = "<group>"; };
- DF8423970E7BA6AA00F5680E /* file_nes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = file_nes.h; sourceTree = "<group>"; };
- DF8423980E7BA6AA00F5680E /* gfx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gfx.cpp; sourceTree = "<group>"; };
- DF8423990E7BA6AA00F5680E /* gfx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gfx.h; sourceTree = "<group>"; };
- DF84239C0E7BA6AA00F5680E /* animation_he.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = animation_he.cpp; sourceTree = "<group>"; };
- DF84239D0E7BA6AA00F5680E /* animation_he.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = animation_he.h; sourceTree = "<group>"; };
- DF84239E0E7BA6AA00F5680E /* cup_player_he.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cup_player_he.cpp; sourceTree = "<group>"; };
- DF84239F0E7BA6AA00F5680E /* cup_player_he.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cup_player_he.h; sourceTree = "<group>"; };
- DF8423A00E7BA6AA00F5680E /* floodfill_he.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = floodfill_he.cpp; sourceTree = "<group>"; };
- DF8423A10E7BA6AA00F5680E /* floodfill_he.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = floodfill_he.h; sourceTree = "<group>"; };
- DF8423A20E7BA6AA00F5680E /* intern_he.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = intern_he.h; sourceTree = "<group>"; };
- DF8423A30E7BA6AA00F5680E /* logic_he.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = logic_he.cpp; sourceTree = "<group>"; };
- DF8423A40E7BA6AA00F5680E /* logic_he.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = logic_he.h; sourceTree = "<group>"; };
- DF8423A50E7BA6AA00F5680E /* palette_he.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = palette_he.cpp; sourceTree = "<group>"; };
- DF8423A60E7BA6AA00F5680E /* resource_he.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resource_he.cpp; sourceTree = "<group>"; };
- DF8423A70E7BA6AA00F5680E /* resource_he.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resource_he.h; sourceTree = "<group>"; };
- DF8423A80E7BA6AA00F5680E /* script_v100he.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_v100he.cpp; sourceTree = "<group>"; };
- DF8423A90E7BA6AA00F5680E /* script_v60he.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_v60he.cpp; sourceTree = "<group>"; };
- DF8423AA0E7BA6AA00F5680E /* script_v70he.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_v70he.cpp; sourceTree = "<group>"; };
- DF8423AB0E7BA6AA00F5680E /* script_v71he.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_v71he.cpp; sourceTree = "<group>"; };
- DF8423AC0E7BA6AA00F5680E /* script_v72he.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_v72he.cpp; sourceTree = "<group>"; };
- DF8423AD0E7BA6AA00F5680E /* script_v80he.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_v80he.cpp; sourceTree = "<group>"; };
- DF8423AE0E7BA6AA00F5680E /* script_v90he.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_v90he.cpp; sourceTree = "<group>"; };
- DF8423AF0E7BA6AA00F5680E /* sound_he.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound_he.cpp; sourceTree = "<group>"; };
- DF8423B00E7BA6AA00F5680E /* sound_he.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound_he.h; sourceTree = "<group>"; };
- DF8423B10E7BA6AA00F5680E /* sprite_he.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sprite_he.cpp; sourceTree = "<group>"; };
- DF8423B20E7BA6AA00F5680E /* sprite_he.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sprite_he.h; sourceTree = "<group>"; };
- DF8423B30E7BA6AA00F5680E /* wiz_he.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wiz_he.cpp; sourceTree = "<group>"; };
- DF8423B40E7BA6AA00F5680E /* wiz_he.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wiz_he.h; sourceTree = "<group>"; };
- DF8423B50E7BA6AA00F5680E /* help.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = help.cpp; sourceTree = "<group>"; };
- DF8423B60E7BA6AA00F5680E /* help.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = help.h; sourceTree = "<group>"; };
- DF8423B80E7BA6AA00F5680E /* imuse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imuse.cpp; sourceTree = "<group>"; };
- DF8423B90E7BA6AA00F5680E /* imuse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imuse.h; sourceTree = "<group>"; };
- DF8423BA0E7BA6AA00F5680E /* imuse_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imuse_internal.h; sourceTree = "<group>"; };
- DF8423BB0E7BA6AA00F5680E /* imuse_part.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imuse_part.cpp; sourceTree = "<group>"; };
- DF8423BC0E7BA6AA00F5680E /* imuse_player.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imuse_player.cpp; sourceTree = "<group>"; };
- DF8423BD0E7BA6AA00F5680E /* instrument.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = instrument.cpp; sourceTree = "<group>"; };
- DF8423BE0E7BA6AA00F5680E /* instrument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = instrument.h; sourceTree = "<group>"; };
- DF8423BF0E7BA6AA00F5680E /* sysex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sysex.h; sourceTree = "<group>"; };
- DF8423C00E7BA6AA00F5680E /* sysex_samnmax.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sysex_samnmax.cpp; sourceTree = "<group>"; };
- DF8423C10E7BA6AA00F5680E /* sysex_scumm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sysex_scumm.cpp; sourceTree = "<group>"; };
- DF8423C30E7BA6AA00F5680E /* dimuse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dimuse.cpp; sourceTree = "<group>"; };
- DF8423C40E7BA6AA00F5680E /* dimuse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dimuse.h; sourceTree = "<group>"; };
- DF8423C50E7BA6AA00F5680E /* dimuse_bndmgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dimuse_bndmgr.cpp; sourceTree = "<group>"; };
- DF8423C60E7BA6AA00F5680E /* dimuse_bndmgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dimuse_bndmgr.h; sourceTree = "<group>"; };
- DF8423C70E7BA6AA00F5680E /* dimuse_codecs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dimuse_codecs.cpp; sourceTree = "<group>"; };
- DF8423C80E7BA6AA00F5680E /* dimuse_music.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dimuse_music.cpp; sourceTree = "<group>"; };
- DF8423C90E7BA6AA00F5680E /* dimuse_script.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dimuse_script.cpp; sourceTree = "<group>"; };
- DF8423CA0E7BA6AA00F5680E /* dimuse_sndmgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dimuse_sndmgr.cpp; sourceTree = "<group>"; };
- DF8423CB0E7BA6AA00F5680E /* dimuse_sndmgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dimuse_sndmgr.h; sourceTree = "<group>"; };
- DF8423CC0E7BA6AA00F5680E /* dimuse_tables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dimuse_tables.cpp; sourceTree = "<group>"; };
- DF8423CD0E7BA6AA00F5680E /* dimuse_tables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dimuse_tables.h; sourceTree = "<group>"; };
- DF8423CE0E7BA6AA00F5680E /* dimuse_track.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dimuse_track.cpp; sourceTree = "<group>"; };
- DF8423CF0E7BA6AA00F5680E /* dimuse_track.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dimuse_track.h; sourceTree = "<group>"; };
- DF8423D00E7BA6AA00F5680E /* input.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = input.cpp; sourceTree = "<group>"; };
- DF8423D20E7BA6AA00F5680E /* insane.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = insane.cpp; sourceTree = "<group>"; };
- DF8423D30E7BA6AA00F5680E /* insane.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = insane.h; sourceTree = "<group>"; };
- DF8423D40E7BA6AA00F5680E /* insane_ben.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = insane_ben.cpp; sourceTree = "<group>"; };
- DF8423D50E7BA6AA00F5680E /* insane_enemy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = insane_enemy.cpp; sourceTree = "<group>"; };
- DF8423D60E7BA6AA00F5680E /* insane_iact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = insane_iact.cpp; sourceTree = "<group>"; };
- DF8423D70E7BA6AA00F5680E /* insane_scenes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = insane_scenes.cpp; sourceTree = "<group>"; };
- DF8423DA0E7BA6AA00F5680E /* midiparser_ro.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = midiparser_ro.cpp; sourceTree = "<group>"; };
- DF8423DC0E7BA6AA00F5680E /* music.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = music.h; sourceTree = "<group>"; };
- DF8423DD0E7BA6AA00F5680E /* nut_renderer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = nut_renderer.cpp; sourceTree = "<group>"; };
- DF8423DE0E7BA6AA00F5680E /* nut_renderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nut_renderer.h; sourceTree = "<group>"; };
- DF8423DF0E7BA6AA00F5680E /* object.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = object.cpp; sourceTree = "<group>"; };
- DF8423E00E7BA6AA00F5680E /* object.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = object.h; sourceTree = "<group>"; };
- DF8423E10E7BA6AA00F5680E /* palette.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = palette.cpp; sourceTree = "<group>"; };
- DF8423E20E7BA6AA00F5680E /* player_mod.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = player_mod.cpp; sourceTree = "<group>"; };
- DF8423E30E7BA6AA00F5680E /* player_mod.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = player_mod.h; sourceTree = "<group>"; };
- DF8423E40E7BA6AA00F5680E /* player_nes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = player_nes.cpp; sourceTree = "<group>"; };
- DF8423E50E7BA6AA00F5680E /* player_nes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = player_nes.h; sourceTree = "<group>"; };
- DF8423E60E7BA6AA00F5680E /* player_v1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = player_v1.cpp; sourceTree = "<group>"; };
- DF8423E70E7BA6AA00F5680E /* player_v1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = player_v1.h; sourceTree = "<group>"; };
- DF8423E80E7BA6AA00F5680E /* player_v2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = player_v2.cpp; sourceTree = "<group>"; };
- DF8423E90E7BA6AA00F5680E /* player_v2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = player_v2.h; sourceTree = "<group>"; };
- DF8423EA0E7BA6AA00F5680E /* player_v2a.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = player_v2a.cpp; sourceTree = "<group>"; };
- DF8423EB0E7BA6AA00F5680E /* player_v2a.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = player_v2a.h; sourceTree = "<group>"; };
- DF8423EC0E7BA6AA00F5680E /* player_v3a.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = player_v3a.cpp; sourceTree = "<group>"; };
- DF8423ED0E7BA6AA00F5680E /* player_v3a.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = player_v3a.h; sourceTree = "<group>"; };
- DF8423EF0E7BA6AA00F5680E /* resource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resource.cpp; sourceTree = "<group>"; };
- DF8423F00E7BA6AA00F5680E /* resource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resource.h; sourceTree = "<group>"; };
- DF8423F10E7BA6AA00F5680E /* resource_v2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resource_v2.cpp; sourceTree = "<group>"; };
- DF8423F20E7BA6AA00F5680E /* resource_v3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resource_v3.cpp; sourceTree = "<group>"; };
- DF8423F30E7BA6AA00F5680E /* resource_v4.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resource_v4.cpp; sourceTree = "<group>"; };
- DF8423F40E7BA6AA00F5680E /* room.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = room.cpp; sourceTree = "<group>"; };
- DF8423F50E7BA6AA00F5680E /* saveload.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveload.cpp; sourceTree = "<group>"; };
- DF8423F60E7BA6AA00F5680E /* saveload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = saveload.h; sourceTree = "<group>"; };
- DF8423F70E7BA6AA00F5680E /* script.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script.cpp; sourceTree = "<group>"; };
- DF8423F80E7BA6AA00F5680E /* script.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = script.h; sourceTree = "<group>"; };
- DF8423F90E7BA6AA00F5680E /* script_v0.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_v0.cpp; sourceTree = "<group>"; };
- DF8423FA0E7BA6AA00F5680E /* script_v2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_v2.cpp; sourceTree = "<group>"; };
- DF8423FB0E7BA6AA00F5680E /* script_v5.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_v5.cpp; sourceTree = "<group>"; };
- DF8423FC0E7BA6AA00F5680E /* script_v6.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_v6.cpp; sourceTree = "<group>"; };
- DF8423FD0E7BA6AA00F5680E /* script_v8.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_v8.cpp; sourceTree = "<group>"; };
- DF8423FE0E7BA6AA00F5680E /* scumm-md5.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "scumm-md5.h"; sourceTree = "<group>"; };
- DF8423FF0E7BA6AA00F5680E /* scumm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scumm.cpp; sourceTree = "<group>"; };
- DF8424000E7BA6AA00F5680E /* scumm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scumm.h; sourceTree = "<group>"; };
- DF8424020E7BA6AA00F5680E /* channel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = channel.cpp; sourceTree = "<group>"; };
- DF8424030E7BA6AA00F5680E /* channel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = channel.h; sourceTree = "<group>"; };
- DF8424060E7BA6AA00F5680E /* codec1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = codec1.cpp; sourceTree = "<group>"; };
- DF8424070E7BA6AA00F5680E /* codec37.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = codec37.cpp; sourceTree = "<group>"; };
- DF8424080E7BA6AA00F5680E /* codec37.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = codec37.h; sourceTree = "<group>"; };
- DF8424090E7BA6AA00F5680E /* codec47.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = codec47.cpp; sourceTree = "<group>"; };
- DF84240A0E7BA6AA00F5680E /* codec47.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = codec47.h; sourceTree = "<group>"; };
- DF84240D0E7BA6AA00F5680E /* imuse_channel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imuse_channel.cpp; sourceTree = "<group>"; };
- DF84240E0E7BA6AA00F5680E /* saud_channel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saud_channel.cpp; sourceTree = "<group>"; };
- DF84240F0E7BA6AA00F5680E /* smush_font.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = smush_font.cpp; sourceTree = "<group>"; };
- DF8424100E7BA6AA00F5680E /* smush_font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = smush_font.h; sourceTree = "<group>"; };
- DF8424110E7BA6AA00F5680E /* smush_mixer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = smush_mixer.cpp; sourceTree = "<group>"; };
- DF8424120E7BA6AA00F5680E /* smush_mixer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = smush_mixer.h; sourceTree = "<group>"; };
- DF8424130E7BA6AA00F5680E /* smush_player.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = smush_player.cpp; sourceTree = "<group>"; };
- DF8424140E7BA6AB00F5680E /* smush_player.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = smush_player.h; sourceTree = "<group>"; };
- DF8424150E7BA6AB00F5680E /* sound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound.cpp; sourceTree = "<group>"; };
- DF8424160E7BA6AB00F5680E /* sound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound.h; sourceTree = "<group>"; };
- DF8424170E7BA6AB00F5680E /* string.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = string.cpp; sourceTree = "<group>"; };
- DF8424190E7BA6AB00F5680E /* usage_bits.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = usage_bits.cpp; sourceTree = "<group>"; };
- DF84241A0E7BA6AB00F5680E /* usage_bits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = usage_bits.h; sourceTree = "<group>"; };
- DF84241B0E7BA6AB00F5680E /* util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = util.cpp; sourceTree = "<group>"; };
- DF84241C0E7BA6AB00F5680E /* util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = util.h; sourceTree = "<group>"; };
- DF84241D0E7BA6AB00F5680E /* vars.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vars.cpp; sourceTree = "<group>"; };
- DF84241E0E7BA6AB00F5680E /* verbs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = verbs.cpp; sourceTree = "<group>"; };
- DF84241F0E7BA6AB00F5680E /* verbs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = verbs.h; sourceTree = "<group>"; };
- DF8424210E7BA6AB00F5680E /* autoroute.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = autoroute.cpp; sourceTree = "<group>"; };
- DF8424220E7BA6AB00F5680E /* autoroute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = autoroute.h; sourceTree = "<group>"; };
- DF8424230E7BA6AB00F5680E /* compact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = compact.cpp; sourceTree = "<group>"; };
- DF8424240E7BA6AB00F5680E /* compact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = compact.h; sourceTree = "<group>"; };
- DF8424250E7BA6AB00F5680E /* control.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = control.cpp; sourceTree = "<group>"; };
- DF8424260E7BA6AB00F5680E /* control.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = control.h; sourceTree = "<group>"; };
- DF8424270E7BA6AB00F5680E /* debug.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug.cpp; sourceTree = "<group>"; };
- DF8424280E7BA6AB00F5680E /* debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug.h; sourceTree = "<group>"; };
- DF8424290E7BA6AB00F5680E /* disk.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = disk.cpp; sourceTree = "<group>"; };
- DF84242A0E7BA6AB00F5680E /* disk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = disk.h; sourceTree = "<group>"; };
- DF84242B0E7BA6AB00F5680E /* grid.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = grid.cpp; sourceTree = "<group>"; };
- DF84242C0E7BA6AB00F5680E /* grid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = grid.h; sourceTree = "<group>"; };
- DF84242D0E7BA6AB00F5680E /* hufftext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hufftext.cpp; sourceTree = "<group>"; };
- DF84242E0E7BA6AB00F5680E /* intro.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = intro.cpp; sourceTree = "<group>"; };
- DF84242F0E7BA6AB00F5680E /* intro.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = intro.h; sourceTree = "<group>"; };
- DF8424300E7BA6AB00F5680E /* logic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = logic.cpp; sourceTree = "<group>"; };
- DF8424310E7BA6AB00F5680E /* logic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = logic.h; sourceTree = "<group>"; };
- DF8424330E7BA6AB00F5680E /* mouse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mouse.cpp; sourceTree = "<group>"; };
- DF8424340E7BA6AB00F5680E /* mouse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mouse.h; sourceTree = "<group>"; };
- DF8424360E7BA6AB00F5680E /* adlibchannel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = adlibchannel.cpp; sourceTree = "<group>"; };
- DF8424370E7BA6AB00F5680E /* adlibchannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = adlibchannel.h; sourceTree = "<group>"; };
- DF8424380E7BA6AB00F5680E /* adlibmusic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = adlibmusic.cpp; sourceTree = "<group>"; };
- DF8424390E7BA6AB00F5680E /* adlibmusic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = adlibmusic.h; sourceTree = "<group>"; };
- DF84243A0E7BA6AB00F5680E /* gmchannel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gmchannel.cpp; sourceTree = "<group>"; };
- DF84243B0E7BA6AB00F5680E /* gmchannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gmchannel.h; sourceTree = "<group>"; };
- DF84243C0E7BA6AB00F5680E /* gmmusic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gmmusic.cpp; sourceTree = "<group>"; };
- DF84243D0E7BA6AB00F5680E /* gmmusic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gmmusic.h; sourceTree = "<group>"; };
- DF84243E0E7BA6AB00F5680E /* mt32music.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mt32music.cpp; sourceTree = "<group>"; };
- DF84243F0E7BA6AB00F5680E /* mt32music.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mt32music.h; sourceTree = "<group>"; };
- DF8424400E7BA6AB00F5680E /* musicbase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = musicbase.cpp; sourceTree = "<group>"; };
- DF8424410E7BA6AB00F5680E /* musicbase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = musicbase.h; sourceTree = "<group>"; };
- DF8424420E7BA6AB00F5680E /* rnc_deco.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rnc_deco.cpp; sourceTree = "<group>"; };
- DF8424430E7BA6AB00F5680E /* rnc_deco.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rnc_deco.h; sourceTree = "<group>"; };
- DF8424440E7BA6AB00F5680E /* screen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = screen.cpp; sourceTree = "<group>"; };
- DF8424450E7BA6AB00F5680E /* screen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = screen.h; sourceTree = "<group>"; };
- DF8424460E7BA6AB00F5680E /* sky.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sky.cpp; sourceTree = "<group>"; };
- DF8424470E7BA6AB00F5680E /* sky.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sky.h; sourceTree = "<group>"; };
- DF8424480E7BA6AB00F5680E /* skydefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = skydefs.h; sourceTree = "<group>"; };
- DF8424490E7BA6AB00F5680E /* sound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound.cpp; sourceTree = "<group>"; };
- DF84244A0E7BA6AB00F5680E /* sound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound.h; sourceTree = "<group>"; };
- DF84244B0E7BA6AB00F5680E /* struc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = struc.h; sourceTree = "<group>"; };
- DF84244C0E7BA6AB00F5680E /* text.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = text.cpp; sourceTree = "<group>"; };
- DF84244D0E7BA6AB00F5680E /* text.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = text.h; sourceTree = "<group>"; };
- DF84244F0E7BA6AB00F5680E /* animation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = animation.cpp; sourceTree = "<group>"; };
- DF8424500E7BA6AB00F5680E /* animation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = animation.h; sourceTree = "<group>"; };
- DF8424510E7BA6AB00F5680E /* collision.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = collision.h; sourceTree = "<group>"; };
- DF8424520E7BA6AB00F5680E /* control.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = control.cpp; sourceTree = "<group>"; };
- DF8424530E7BA6AB00F5680E /* control.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = control.h; sourceTree = "<group>"; };
- DF8424560E7BA6AB00F5680E /* debug.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug.cpp; sourceTree = "<group>"; };
- DF8424570E7BA6AB00F5680E /* debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug.h; sourceTree = "<group>"; };
- DF8424580E7BA6AB00F5680E /* eventman.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = eventman.cpp; sourceTree = "<group>"; };
- DF8424590E7BA6AB00F5680E /* eventman.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = eventman.h; sourceTree = "<group>"; };
- DF84245A0E7BA6AB00F5680E /* logic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = logic.cpp; sourceTree = "<group>"; };
- DF84245B0E7BA6AB00F5680E /* logic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = logic.h; sourceTree = "<group>"; };
- DF84245C0E7BA6AB00F5680E /* memman.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = memman.cpp; sourceTree = "<group>"; };
- DF84245D0E7BA6AB00F5680E /* memman.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = memman.h; sourceTree = "<group>"; };
- DF84245E0E7BA6AB00F5680E /* menu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = menu.cpp; sourceTree = "<group>"; };
- DF84245F0E7BA6AB00F5680E /* menu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = menu.h; sourceTree = "<group>"; };
- DF8424610E7BA6AB00F5680E /* mouse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mouse.cpp; sourceTree = "<group>"; };
- DF8424620E7BA6AB00F5680E /* mouse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mouse.h; sourceTree = "<group>"; };
- DF8424630E7BA6AB00F5680E /* music.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = music.cpp; sourceTree = "<group>"; };
- DF8424640E7BA6AB00F5680E /* music.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = music.h; sourceTree = "<group>"; };
- DF8424650E7BA6AB00F5680E /* object.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = object.h; sourceTree = "<group>"; };
- DF8424660E7BA6AB00F5680E /* objectman.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = objectman.cpp; sourceTree = "<group>"; };
- DF8424670E7BA6AB00F5680E /* objectman.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = objectman.h; sourceTree = "<group>"; };
- DF8424680E7BA6AB00F5680E /* resman.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resman.cpp; sourceTree = "<group>"; };
- DF8424690E7BA6AB00F5680E /* resman.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resman.h; sourceTree = "<group>"; };
- DF84246A0E7BA6AB00F5680E /* router.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = router.cpp; sourceTree = "<group>"; };
- DF84246B0E7BA6AB00F5680E /* router.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = router.h; sourceTree = "<group>"; };
- DF84246C0E7BA6AB00F5680E /* screen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = screen.cpp; sourceTree = "<group>"; };
- DF84246D0E7BA6AB00F5680E /* screen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = screen.h; sourceTree = "<group>"; };
- DF84246E0E7BA6AB00F5680E /* sound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound.cpp; sourceTree = "<group>"; };
- DF84246F0E7BA6AB00F5680E /* sound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound.h; sourceTree = "<group>"; };
- DF8424700E7BA6AB00F5680E /* staticres.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = staticres.cpp; sourceTree = "<group>"; };
- DF8424710E7BA6AB00F5680E /* sword1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sword1.cpp; sourceTree = "<group>"; };
- DF8424720E7BA6AB00F5680E /* sword1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sword1.h; sourceTree = "<group>"; };
- DF8424730E7BA6AB00F5680E /* sworddefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sworddefs.h; sourceTree = "<group>"; };
- DF8424740E7BA6AB00F5680E /* swordres.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = swordres.h; sourceTree = "<group>"; };
- DF8424750E7BA6AB00F5680E /* text.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = text.cpp; sourceTree = "<group>"; };
- DF8424760E7BA6AB00F5680E /* text.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = text.h; sourceTree = "<group>"; };
- DF8424780E7BA6AB00F5680E /* animation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = animation.cpp; sourceTree = "<group>"; };
- DF8424790E7BA6AB00F5680E /* animation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = animation.h; sourceTree = "<group>"; };
- DF84247A0E7BA6AB00F5680E /* anims.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = anims.cpp; sourceTree = "<group>"; };
- DF84247B0E7BA6AB00F5680E /* console.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = console.cpp; sourceTree = "<group>"; };
- DF84247C0E7BA6AB00F5680E /* console.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = console.h; sourceTree = "<group>"; };
- DF84247D0E7BA6AB00F5680E /* controls.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = controls.cpp; sourceTree = "<group>"; };
- DF84247E0E7BA6AB00F5680E /* controls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = controls.h; sourceTree = "<group>"; };
- DF84247F0E7BA6AB00F5680E /* debug.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug.cpp; sourceTree = "<group>"; };
- DF8424800E7BA6AB00F5680E /* debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug.h; sourceTree = "<group>"; };
- DF8424810E7BA6AB00F5680E /* defs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = defs.h; sourceTree = "<group>"; };
- DF8424820E7BA6AB00F5680E /* events.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = events.cpp; sourceTree = "<group>"; };
- DF8424830E7BA6AB00F5680E /* function.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = function.cpp; sourceTree = "<group>"; };
- DF8424840E7BA6AB00F5680E /* header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = header.h; sourceTree = "<group>"; };
- DF8424850E7BA6AB00F5680E /* icons.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = icons.cpp; sourceTree = "<group>"; };
- DF8424860E7BA6AB00F5680E /* interpreter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = interpreter.cpp; sourceTree = "<group>"; };
- DF8424870E7BA6AB00F5680E /* interpreter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = interpreter.h; sourceTree = "<group>"; };
- DF8424880E7BA6AB00F5680E /* layers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = layers.cpp; sourceTree = "<group>"; };
- DF8424890E7BA6AB00F5680E /* logic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = logic.cpp; sourceTree = "<group>"; };
- DF84248A0E7BA6AB00F5680E /* logic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = logic.h; sourceTree = "<group>"; };
- DF84248B0E7BA6AB00F5680E /* maketext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = maketext.cpp; sourceTree = "<group>"; };
- DF84248C0E7BA6AB00F5680E /* maketext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = maketext.h; sourceTree = "<group>"; };
- DF84248D0E7BA6AB00F5680E /* memory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = memory.cpp; sourceTree = "<group>"; };
- DF84248E0E7BA6AB00F5680E /* memory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = memory.h; sourceTree = "<group>"; };
- DF84248F0E7BA6AB00F5680E /* menu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = menu.cpp; sourceTree = "<group>"; };
- DF8424910E7BA6AB00F5680E /* mouse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mouse.cpp; sourceTree = "<group>"; };
- DF8424920E7BA6AB00F5680E /* mouse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mouse.h; sourceTree = "<group>"; };
- DF8424930E7BA6AB00F5680E /* music.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = music.cpp; sourceTree = "<group>"; };
- DF8424940E7BA6AB00F5680E /* object.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = object.h; sourceTree = "<group>"; };
- DF8424950E7BA6AB00F5680E /* palette.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = palette.cpp; sourceTree = "<group>"; };
- DF8424960E7BA6AB00F5680E /* protocol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = protocol.cpp; sourceTree = "<group>"; };
- DF8424970E7BA6AB00F5680E /* render.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = render.cpp; sourceTree = "<group>"; };
- DF8424980E7BA6AB00F5680E /* resman.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resman.cpp; sourceTree = "<group>"; };
- DF8424990E7BA6AB00F5680E /* resman.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resman.h; sourceTree = "<group>"; };
- DF84249A0E7BA6AB00F5680E /* router.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = router.cpp; sourceTree = "<group>"; };
- DF84249B0E7BA6AB00F5680E /* router.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = router.h; sourceTree = "<group>"; };
- DF84249C0E7BA6AB00F5680E /* saveload.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveload.cpp; sourceTree = "<group>"; };
- DF84249D0E7BA6AB00F5680E /* saveload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = saveload.h; sourceTree = "<group>"; };
- DF84249E0E7BA6AB00F5680E /* screen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = screen.cpp; sourceTree = "<group>"; };
- DF84249F0E7BA6AB00F5680E /* screen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = screen.h; sourceTree = "<group>"; };
- DF8424A00E7BA6AB00F5680E /* scroll.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scroll.cpp; sourceTree = "<group>"; };
- DF8424A10E7BA6AB00F5680E /* sound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound.cpp; sourceTree = "<group>"; };
- DF8424A20E7BA6AB00F5680E /* sound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound.h; sourceTree = "<group>"; };
- DF8424A30E7BA6AB00F5680E /* speech.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = speech.cpp; sourceTree = "<group>"; };
- DF8424A40E7BA6AB00F5680E /* sprite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sprite.cpp; sourceTree = "<group>"; };
- DF8424A50E7BA6AB00F5680E /* startup.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = startup.cpp; sourceTree = "<group>"; };
- DF8424A60E7BA6AB00F5680E /* sword2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sword2.cpp; sourceTree = "<group>"; };
- DF8424A70E7BA6AB00F5680E /* sword2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sword2.h; sourceTree = "<group>"; };
- DF8424A80E7BA6AB00F5680E /* sync.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sync.cpp; sourceTree = "<group>"; };
- DF8424A90E7BA6AB00F5680E /* walker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = walker.cpp; sourceTree = "<group>"; };
- DF8424AB0E7BA6AB00F5680E /* actors.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = actors.cpp; sourceTree = "<group>"; };
- DF8424AC0E7BA6AB00F5680E /* actors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = actors.h; sourceTree = "<group>"; };
- DF8424AD0E7BA6AB00F5680E /* anim.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = anim.cpp; sourceTree = "<group>"; };
- DF8424AE0E7BA6AB00F5680E /* anim.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = anim.h; sourceTree = "<group>"; };
- DF8424AF0E7BA6AB00F5680E /* background.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = background.cpp; sourceTree = "<group>"; };
- DF8424B00E7BA6AB00F5680E /* background.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = background.h; sourceTree = "<group>"; };
- DF8424B10E7BA6AB00F5680E /* bg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bg.cpp; sourceTree = "<group>"; };
- DF8424B20E7BA6AB00F5680E /* cliprect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cliprect.cpp; sourceTree = "<group>"; };
- DF8424B30E7BA6AB00F5680E /* cliprect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cliprect.h; sourceTree = "<group>"; };
- DF8424B40E7BA6AB00F5680E /* config.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = config.cpp; sourceTree = "<group>"; };
- DF8424B50E7BA6AB00F5680E /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = "<group>"; };
- DF8424B60E7BA6AB00F5680E /* coroutine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = coroutine.h; sourceTree = "<group>"; };
- DF8424B70E7BA6AB00F5680E /* cursor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cursor.cpp; sourceTree = "<group>"; };
- DF8424B80E7BA6AB00F5680E /* cursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cursor.h; sourceTree = "<group>"; };
- DF8424B90E7BA6AB00F5680E /* debugger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debugger.cpp; sourceTree = "<group>"; };
- DF8424BA0E7BA6AB00F5680E /* debugger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debugger.h; sourceTree = "<group>"; };
- DF8424BB0E7BA6AB00F5680E /* detection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = detection.cpp; sourceTree = "<group>"; };
- DF8424BC0E7BA6AB00F5680E /* dw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dw.h; sourceTree = "<group>"; };
- DF8424BD0E7BA6AB00F5680E /* effect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = effect.cpp; sourceTree = "<group>"; };
- DF8424BE0E7BA6AB00F5680E /* events.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = events.cpp; sourceTree = "<group>"; };
- DF8424BF0E7BA6AB00F5680E /* events.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = events.h; sourceTree = "<group>"; };
- DF8424C00E7BA6AB00F5680E /* faders.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = faders.cpp; sourceTree = "<group>"; };
- DF8424C10E7BA6AB00F5680E /* faders.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = faders.h; sourceTree = "<group>"; };
- DF8424C20E7BA6AB00F5680E /* film.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = film.h; sourceTree = "<group>"; };
- DF8424C30E7BA6AB00F5680E /* font.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = font.cpp; sourceTree = "<group>"; };
- DF8424C40E7BA6AB00F5680E /* font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = font.h; sourceTree = "<group>"; };
- DF8424C50E7BA6AB00F5680E /* graphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = graphics.cpp; sourceTree = "<group>"; };
- DF8424C60E7BA6AB00F5680E /* graphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = graphics.h; sourceTree = "<group>"; };
- DF8424C70E7BA6AB00F5680E /* handle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = handle.cpp; sourceTree = "<group>"; };
- DF8424C80E7BA6AB00F5680E /* handle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = handle.h; sourceTree = "<group>"; };
- DF8424C90E7BA6AB00F5680E /* heapmem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = heapmem.cpp; sourceTree = "<group>"; };
- DF8424CA0E7BA6AB00F5680E /* heapmem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = heapmem.h; sourceTree = "<group>"; };
- DF8424CD0E7BA6AB00F5680E /* mareels.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mareels.cpp; sourceTree = "<group>"; };
- DF8424CF0E7BA6AB00F5680E /* move.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = move.cpp; sourceTree = "<group>"; };
- DF8424D00E7BA6AB00F5680E /* move.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = move.h; sourceTree = "<group>"; };
- DF8424D10E7BA6AB00F5680E /* multiobj.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = multiobj.cpp; sourceTree = "<group>"; };
- DF8424D20E7BA6AB00F5680E /* multiobj.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = multiobj.h; sourceTree = "<group>"; };
- DF8424D30E7BA6AB00F5680E /* music.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = music.cpp; sourceTree = "<group>"; };
- DF8424D40E7BA6AB00F5680E /* music.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = music.h; sourceTree = "<group>"; };
- DF8424D50E7BA6AB00F5680E /* object.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = object.cpp; sourceTree = "<group>"; };
- DF8424D60E7BA6AB00F5680E /* object.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = object.h; sourceTree = "<group>"; };
- DF8424D70E7BA6AB00F5680E /* palette.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = palette.cpp; sourceTree = "<group>"; };
- DF8424D80E7BA6AB00F5680E /* palette.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = palette.h; sourceTree = "<group>"; };
- DF8424D90E7BA6AB00F5680E /* pcode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pcode.cpp; sourceTree = "<group>"; };
- DF8424DA0E7BA6AB00F5680E /* pcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pcode.h; sourceTree = "<group>"; };
- DF8424DB0E7BA6AB00F5680E /* pdisplay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pdisplay.cpp; sourceTree = "<group>"; };
- DF8424DC0E7BA6AB00F5680E /* pid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pid.h; sourceTree = "<group>"; };
- DF8424DD0E7BA6AB00F5680E /* play.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = play.cpp; sourceTree = "<group>"; };
- DF8424DE0E7BA6AB00F5680E /* polygons.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = polygons.cpp; sourceTree = "<group>"; };
- DF8424DF0E7BA6AB00F5680E /* polygons.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = polygons.h; sourceTree = "<group>"; };
- DF8424E00E7BA6AB00F5680E /* rince.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rince.cpp; sourceTree = "<group>"; };
- DF8424E10E7BA6AB00F5680E /* rince.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rince.h; sourceTree = "<group>"; };
- DF8424E20E7BA6AB00F5680E /* saveload.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveload.cpp; sourceTree = "<group>"; };
- DF8424E30E7BA6AB00F5680E /* savescn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = savescn.cpp; sourceTree = "<group>"; };
- DF8424E40E7BA6AB00F5680E /* savescn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = savescn.h; sourceTree = "<group>"; };
- DF8424E50E7BA6AB00F5680E /* scene.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scene.cpp; sourceTree = "<group>"; };
- DF8424E60E7BA6AB00F5680E /* scene.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scene.h; sourceTree = "<group>"; };
- DF8424E70E7BA6AB00F5680E /* sched.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sched.cpp; sourceTree = "<group>"; };
- DF8424E80E7BA6AB00F5680E /* sched.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sched.h; sourceTree = "<group>"; };
- DF8424E90E7BA6AB00F5680E /* scn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scn.cpp; sourceTree = "<group>"; };
- DF8424EA0E7BA6AB00F5680E /* scn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scn.h; sourceTree = "<group>"; };
- DF8424EB0E7BA6AB00F5680E /* scroll.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scroll.cpp; sourceTree = "<group>"; };
- DF8424EC0E7BA6AB00F5680E /* scroll.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scroll.h; sourceTree = "<group>"; };
- DF8424EE0E7BA6AB00F5680E /* sound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound.cpp; sourceTree = "<group>"; };
- DF8424EF0E7BA6AB00F5680E /* sound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound.h; sourceTree = "<group>"; };
- DF8424F00E7BA6AB00F5680E /* strres.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = strres.cpp; sourceTree = "<group>"; };
- DF8424F10E7BA6AB00F5680E /* strres.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = strres.h; sourceTree = "<group>"; };
- DF8424F20E7BA6AB00F5680E /* text.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = text.cpp; sourceTree = "<group>"; };
- DF8424F30E7BA6AB00F5680E /* text.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = text.h; sourceTree = "<group>"; };
- DF8424F40E7BA6AB00F5680E /* timers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = timers.cpp; sourceTree = "<group>"; };
- DF8424F50E7BA6AB00F5680E /* timers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = timers.h; sourceTree = "<group>"; };
- DF8424F60E7BA6AB00F5680E /* tinlib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinlib.cpp; sourceTree = "<group>"; };
- DF8424F70E7BA6AB00F5680E /* tinlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tinlib.h; sourceTree = "<group>"; };
- DF8424F80E7BA6AB00F5680E /* tinsel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinsel.cpp; sourceTree = "<group>"; };
- DF8424F90E7BA6AB00F5680E /* tinsel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tinsel.h; sourceTree = "<group>"; };
- DF8424FA0E7BA6AB00F5680E /* token.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = token.cpp; sourceTree = "<group>"; };
- DF8424FB0E7BA6AB00F5680E /* token.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = token.h; sourceTree = "<group>"; };
- DF8424FD0E7BA6AB00F5680E /* detection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = detection.cpp; sourceTree = "<group>"; };
- DF8424FE0E7BA6AB00F5680E /* graphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = graphics.cpp; sourceTree = "<group>"; };
- DF8424FF0E7BA6AB00F5680E /* graphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = graphics.h; sourceTree = "<group>"; };
- DF8425000E7BA6AB00F5680E /* menu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = menu.cpp; sourceTree = "<group>"; };
- DF8425010E7BA6AB00F5680E /* midi.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = midi.cpp; sourceTree = "<group>"; };
- DF8425020E7BA6AB00F5680E /* midi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = midi.h; sourceTree = "<group>"; };
- DF8425040E7BA6AB00F5680E /* opcodes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = opcodes.cpp; sourceTree = "<group>"; };
- DF8425050E7BA6AB00F5680E /* resource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resource.cpp; sourceTree = "<group>"; };
- DF8425060E7BA6AB00F5680E /* saveload.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveload.cpp; sourceTree = "<group>"; };
- DF8425070E7BA6AB00F5680E /* staticres.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = staticres.cpp; sourceTree = "<group>"; };
- DF8425080E7BA6AB00F5680E /* touche.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = touche.cpp; sourceTree = "<group>"; };
- DF8425090E7BA6AB00F5680E /* touche.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = touche.h; sourceTree = "<group>"; };
- DF8428960E7BAAAB00F5680E /* blit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = blit.cpp; sourceTree = "<group>"; };
- DF842A160E7BB34E00F5680E /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
- DF842A170E7BB34E00F5680E /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
- DF842A180E7BB34E00F5680E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
- DF842A190E7BB34E00F5680E /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
- DF842A270E7BB37500F5680E /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
- DF842A2E0E7BB39E00F5680E /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
- DF842A3D0E7BBB5000F5680E /* timidity.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = timidity.cpp; sourceTree = "<group>"; };
- DF842A400E7BBBB400F5680E /* archive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = archive.cpp; sourceTree = "<group>"; };
- DF842A410E7BBBB400F5680E /* archive.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = archive.h; sourceTree = "<group>"; };
- DF842A430E7BBBB400F5680E /* ptr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ptr.h; sourceTree = "<group>"; };
- DF842A440E7BBBB400F5680E /* queue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = queue.h; sourceTree = "<group>"; };
- DF842A450E7BBBB400F5680E /* unarj.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = unarj.cpp; sourceTree = "<group>"; };
- DF842A460E7BBBB400F5680E /* unarj.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unarj.h; sourceTree = "<group>"; };
- DF842A4C0E7BBBEB00F5680E /* posix-fs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "posix-fs.h"; sourceTree = "<group>"; };
- DF842A6B0E7BBD5700F5680E /* stdiostream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stdiostream.cpp; sourceTree = "<group>"; };
- DF842A6C0E7BBD5700F5680E /* stdiostream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stdiostream.h; sourceTree = "<group>"; };
- DF895C01124C24680077F6E8 /* player_towns.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = player_towns.cpp; sourceTree = "<group>"; };
- DF895C02124C24680077F6E8 /* player_towns.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = player_towns.h; sourceTree = "<group>"; };
- DF895C23124C25150077F6E8 /* detection_tables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = detection_tables.h; sourceTree = "<group>"; };
- DF895C24124C25150077F6E8 /* init_fascin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = init_fascin.cpp; sourceTree = "<group>"; };
- DF895C28124C25350077F6E8 /* kernel_tables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kernel_tables.h; sourceTree = "<group>"; };
- DF895C29124C25350077F6E8 /* script_patches.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script_patches.cpp; sourceTree = "<group>"; };
- DF895C33124C26660077F6E8 /* icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-72.png"; sourceTree = "<group>"; };
- DF895C40124C271F0077F6E8 /* icon4.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon4.png; sourceTree = "<group>"; };
- DF89C2870F62D55C00D756B6 /* sprites_lol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sprites_lol.cpp; sourceTree = "<group>"; };
- DF89C2A30F62D79E00D756B6 /* script.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = script.cpp; sourceTree = "<group>"; };
- DF90E9B410AEDA5300C8F93F /* detection_tables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = detection_tables.h; sourceTree = "<group>"; };
- DF90E9BD10AEDA9B00C8F93F /* selector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = selector.cpp; sourceTree = "<group>"; };
- DF90EAA310B0234300C8F93F /* draw_playtoons.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = draw_playtoons.cpp; sourceTree = "<group>"; };
- DF90EAAB10B0236F00C8F93F /* staticres.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = staticres.cpp; sourceTree = "<group>"; };
- DF90EAAC10B0236F00C8F93F /* staticres.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = staticres.h; sourceTree = "<group>"; };
- DF9B9246118E46730069C19D /* error.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = error.cpp; sourceTree = "<group>"; };
- DF9B9247118E46730069C19D /* error.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = error.h; sourceTree = "<group>"; };
- DF9B924F118E46A00069C19D /* fontsjis.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fontsjis.cpp; sourceTree = "<group>"; };
- DF9B9250118E46A00069C19D /* fontsjis.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fontsjis.h; sourceTree = "<group>"; };
- DF9B9261118E46FE0069C19D /* error.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = error.cpp; sourceTree = "<group>"; };
- DFAAAFF50F0112AD003E9390 /* saveload.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveload.cpp; sourceTree = "<group>"; };
- DFAAAFF60F0112AD003E9390 /* saveload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = saveload.h; sourceTree = "<group>"; };
- DFAAAFF80F0112C1003E9390 /* detection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = detection.cpp; sourceTree = "<group>"; };
- DFAAAFFB0F0112DF003E9390 /* detection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = detection.cpp; sourceTree = "<group>"; };
- DFAAB0010F011392003E9390 /* thumbnail_intern.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = thumbnail_intern.cpp; sourceTree = "<group>"; };
- DFAAD2390F50120E00C3A4E2 /* console.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = console.cpp; sourceTree = "<group>"; };
- DFAAD23A0F50120E00C3A4E2 /* console.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = console.h; sourceTree = "<group>"; };
- DFADEBB113820DF500C46364 /* maccursor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = maccursor.cpp; sourceTree = "<group>"; };
- DFADEBB213820DF500C46364 /* maccursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = maccursor.h; sourceTree = "<group>"; };
- DFADEBB613820E0C00C46364 /* posix-fs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "posix-fs.cpp"; sourceTree = "<group>"; };
- DFADEC061382140300C46364 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
- DFB0577311B753DA0015AE65 /* debug-channels.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "debug-channels.h"; sourceTree = "<group>"; };
- DFB0577411B753DA0015AE65 /* rational.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rational.cpp; sourceTree = "<group>"; };
- DFB0577511B753DA0015AE65 /* rational.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rational.h; sourceTree = "<group>"; };
- DFB0577D11B7541F0015AE65 /* resource_audio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resource_audio.cpp; sourceTree = "<group>"; };
- DFB0577E11B7541F0015AE65 /* util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = util.cpp; sourceTree = "<group>"; };
- DFB0577F11B7541F0015AE65 /* util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = util.h; sourceTree = "<group>"; };
- DFB0578811B754570015AE65 /* maciconbar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = maciconbar.cpp; sourceTree = "<group>"; };
- DFB0578911B754570015AE65 /* maciconbar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = maciconbar.h; sourceTree = "<group>"; };
- DFB0578F11B7547D0015AE65 /* pict.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pict.cpp; sourceTree = "<group>"; };
- DFB0579011B7547D0015AE65 /* pict.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pict.h; sourceTree = "<group>"; };
- DFC8301A0F48AF18005EF03C /* detection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = detection.cpp; sourceTree = "<group>"; };
- DFC8301E0F48AF18005EF03C /* gc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gc.cpp; sourceTree = "<group>"; };
- DFC8301F0F48AF18005EF03C /* gc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gc.h; sourceTree = "<group>"; };
- DFC830230F48AF18005EF03C /* kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kernel.cpp; sourceTree = "<group>"; };
- DFC830260F48AF18005EF03C /* kevent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kevent.cpp; sourceTree = "<group>"; };
- DFC830270F48AF18005EF03C /* kfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kfile.cpp; sourceTree = "<group>"; };
- DFC830280F48AF18005EF03C /* kgraphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kgraphics.cpp; sourceTree = "<group>"; };
- DFC830290F48AF18005EF03C /* klists.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = klists.cpp; sourceTree = "<group>"; };
- DFC8302A0F48AF18005EF03C /* kmath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kmath.cpp; sourceTree = "<group>"; };
- DFC8302B0F48AF18005EF03C /* kmenu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kmenu.cpp; sourceTree = "<group>"; };
- DFC8302C0F48AF18005EF03C /* kmovement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kmovement.cpp; sourceTree = "<group>"; };
- DFC8302D0F48AF18005EF03C /* kpathing.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kpathing.cpp; sourceTree = "<group>"; };
- DFC8302E0F48AF18005EF03C /* kscripts.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kscripts.cpp; sourceTree = "<group>"; };
- DFC8302F0F48AF18005EF03C /* ksound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ksound.cpp; sourceTree = "<group>"; };
- DFC830300F48AF18005EF03C /* kstring.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kstring.cpp; sourceTree = "<group>"; };
- DFC830310F48AF18005EF03C /* message.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = message.cpp; sourceTree = "<group>"; };
- DFC830320F48AF18005EF03C /* message.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = message.h; sourceTree = "<group>"; };
- DFC830360F48AF18005EF03C /* savegame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = savegame.cpp; sourceTree = "<group>"; };
- DFC830390F48AF18005EF03C /* scriptdebug.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scriptdebug.cpp; sourceTree = "<group>"; };
- DFC8303A0F48AF18005EF03C /* seg_manager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = seg_manager.cpp; sourceTree = "<group>"; };
- DFC8303C0F48AF18005EF03C /* vm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vm.cpp; sourceTree = "<group>"; };
- DFC830960F48AF18005EF03C /* sci.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sci.cpp; sourceTree = "<group>"; };
- DFC830970F48AF18005EF03C /* sci.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sci.h; sourceTree = "<group>"; };
- DFCDC6D5116629CE00A7D2A0 /* features.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = features.cpp; sourceTree = "<group>"; };
- DFCDC6D6116629CE00A7D2A0 /* features.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = features.h; sourceTree = "<group>"; };
- DFCDC6D7116629CE00A7D2A0 /* kparse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kparse.cpp; sourceTree = "<group>"; };
- DFCDC6D8116629CE00A7D2A0 /* selector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = selector.h; sourceTree = "<group>"; };
- DFCDC6F611662AAB00A7D2A0 /* resource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resource.cpp; sourceTree = "<group>"; };
- DFCDC70311662B0200A7D2A0 /* saveload_fascin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = saveload_fascin.cpp; sourceTree = "<group>"; };
- DFCDC70911662B6B00A7D2A0 /* macresman.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = macresman.cpp; sourceTree = "<group>"; };
- DFCDC70A11662B6B00A7D2A0 /* macresman.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = macresman.h; sourceTree = "<group>"; };
- DFD511460DF3383500854012 /* memorypool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = memorypool.cpp; sourceTree = "<group>"; };
- DFD511470DF3383500854012 /* memorypool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = memorypool.h; sourceTree = "<group>"; };
- DFD517E10DF33CAC00854012 /* seq.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = seq.cpp; sourceTree = "<group>"; };
- DFD5183B0DF3411800854012 /* scaler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scaler.cpp; sourceTree = "<group>"; };
- DFD5183C0DF3411800854012 /* scaler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scaler.h; sourceTree = "<group>"; };
- DFD5189E0DF34AD700854012 /* intern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = intern.h; sourceTree = "<group>"; };
- DFD518A00DF34B2500854012 /* scalebit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scalebit.cpp; sourceTree = "<group>"; };
- DFD518A10DF34B2500854012 /* scalebit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scalebit.h; sourceTree = "<group>"; };
- DFD518AA0DF34BA600854012 /* 2xsai.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = 2xsai.cpp; sourceTree = "<group>"; };
- DFD518AB0DF34BA600854012 /* aspect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = aspect.cpp; sourceTree = "<group>"; };
- DFD518B50DF34BA600854012 /* scale2x.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scale2x.cpp; sourceTree = "<group>"; };
- DFD518B60DF34BA600854012 /* scale2x.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scale2x.h; sourceTree = "<group>"; };
- DFD518B80DF34BA600854012 /* scale3x.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scale3x.cpp; sourceTree = "<group>"; };
- DFD518B90DF34BA600854012 /* scale3x.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scale3x.h; sourceTree = "<group>"; };
- DFD6476B0F49F7EF008E18EF /* libFLAC.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libFLAC.a; path = lib/libFLAC.a; sourceTree = "<group>"; };
- DFD6476C0F49F7EF008E18EF /* libmad.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmad.a; path = lib/libmad.a; sourceTree = "<group>"; };
- DFD6476F0F49F7EF008E18EF /* libvorbisidec.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbisidec.a; path = lib/libvorbisidec.a; sourceTree = "<group>"; };
- DFE470C10D81F4BA00B6D1FB /* commandLine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = commandLine.cpp; sourceTree = "<group>"; };
- DFE470C20D81F4BA00B6D1FB /* commandLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = commandLine.h; sourceTree = "<group>"; };
- DFE470C70D81F4BA00B6D1FB /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
- DFE470C80D81F4BA00B6D1FB /* main.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = main.h; sourceTree = "<group>"; };
- DFE470CA0D81F4BA00B6D1FB /* plugins.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = plugins.cpp; sourceTree = "<group>"; };
- DFE470CB0D81F4BA00B6D1FB /* plugins.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = plugins.h; sourceTree = "<group>"; };
- DFE470CC0D81F4BA00B6D1FB /* version.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = version.cpp; sourceTree = "<group>"; };
- DFE470CD0D81F4BA00B6D1FB /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = version.h; sourceTree = "<group>"; };
- DFE470D80D81F4E700B6D1FB /* default-events.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "default-events.cpp"; sourceTree = "<group>"; };
- DFE470D90D81F4E700B6D1FB /* default-events.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "default-events.h"; sourceTree = "<group>"; };
- DFE470DE0D81F4E700B6D1FB /* abstract-fs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "abstract-fs.h"; sourceTree = "<group>"; };
- DFE470E80D81F4E700B6D1FB /* fs-factory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "fs-factory.h"; sourceTree = "<group>"; };
- DFE470F60D81F4E700B6D1FB /* posix-fs-factory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "posix-fs-factory.cpp"; sourceTree = "<group>"; };
- DFE470F70D81F4E700B6D1FB /* posix-fs-factory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "posix-fs-factory.h"; sourceTree = "<group>"; };
- DFE471DC0D81F4E700B6D1FB /* blit_arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = blit_arm.h; sourceTree = "<group>"; };
- DFE471DE0D81F4E700B6D1FB /* iphone_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iphone_common.h; sourceTree = "<group>"; };
- DFE471DF0D81F4E700B6D1FB /* iphone_keyboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iphone_keyboard.h; sourceTree = "<group>"; };
- DFE471E10D81F4E700B6D1FB /* iphone_main.m */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; path = iphone_main.m; sourceTree = "<group>"; };
- DFE4737F0D81F4E800B6D1FB /* dynamic-plugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "dynamic-plugin.h"; sourceTree = "<group>"; };
- DFE473810D81F4E800B6D1FB /* posix-provider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "posix-provider.cpp"; sourceTree = "<group>"; };
- DFE473820D81F4E800B6D1FB /* posix-provider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "posix-provider.h"; sourceTree = "<group>"; };
- DFE4738E0D81F4E800B6D1FB /* default-saves.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "default-saves.cpp"; sourceTree = "<group>"; };
- DFE4738F0D81F4E800B6D1FB /* default-saves.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "default-saves.h"; sourceTree = "<group>"; };
- DFE473900D81F4E800B6D1FB /* savefile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = savefile.cpp; sourceTree = "<group>"; };
- DFE473930D81F4E800B6D1FB /* default-timer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "default-timer.cpp"; sourceTree = "<group>"; };
- DFE473940D81F4E800B6D1FB /* default-timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "default-timer.h"; sourceTree = "<group>"; };
- DFE473980D81F4E800B6D1FB /* algorithm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = algorithm.h; sourceTree = "<group>"; };
- DFE473990D81F4E800B6D1FB /* array.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = array.h; sourceTree = "<group>"; };
- DFE4739A0D81F4E800B6D1FB /* config-file.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "config-file.cpp"; sourceTree = "<group>"; };
- DFE4739B0D81F4E800B6D1FB /* config-file.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "config-file.h"; sourceTree = "<group>"; };
- DFE4739C0D81F4E800B6D1FB /* config-manager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "config-manager.cpp"; sourceTree = "<group>"; };
- DFE4739D0D81F4E800B6D1FB /* config-manager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "config-manager.h"; sourceTree = "<group>"; };
- DFE4739E0D81F4E800B6D1FB /* endian.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = endian.h; sourceTree = "<group>"; };
- DFE4739F0D81F4E800B6D1FB /* error.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = error.h; sourceTree = "<group>"; };
- DFE473A00D81F4E800B6D1FB /* events.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = events.h; sourceTree = "<group>"; };
- DFE473A10D81F4E800B6D1FB /* file.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = file.cpp; sourceTree = "<group>"; };
- DFE473A20D81F4E800B6D1FB /* file.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = file.h; sourceTree = "<group>"; };
- DFE473A30D81F4E800B6D1FB /* frac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = frac.h; sourceTree = "<group>"; };
- DFE473A40D81F4E800B6D1FB /* fs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fs.cpp; sourceTree = "<group>"; };
- DFE473A50D81F4E800B6D1FB /* fs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fs.h; sourceTree = "<group>"; };
- DFE473A60D81F4E800B6D1FB /* func.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = func.h; sourceTree = "<group>"; };
- DFE473A70D81F4E800B6D1FB /* hash-str.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "hash-str.h"; sourceTree = "<group>"; };
- DFE473A80D81F4E800B6D1FB /* hashmap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hashmap.cpp; sourceTree = "<group>"; };
- DFE473A90D81F4E800B6D1FB /* hashmap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hashmap.h; sourceTree = "<group>"; };
- DFE473AA0D81F4E800B6D1FB /* iff_container.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iff_container.h; sourceTree = "<group>"; };
- DFE473AB0D81F4E800B6D1FB /* keyboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = keyboard.h; sourceTree = "<group>"; };
- DFE473AC0D81F4E800B6D1FB /* list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = list.h; sourceTree = "<group>"; };
- DFE473AD0D81F4E800B6D1FB /* md5.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = md5.cpp; sourceTree = "<group>"; };
- DFE473AE0D81F4E800B6D1FB /* md5.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = md5.h; sourceTree = "<group>"; };
- DFE473B00D81F4E800B6D1FB /* mutex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mutex.cpp; sourceTree = "<group>"; };
- DFE473B10D81F4E800B6D1FB /* mutex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mutex.h; sourceTree = "<group>"; };
- DFE473B20D81F4E800B6D1FB /* noncopyable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = noncopyable.h; sourceTree = "<group>"; };
- DFE473B30D81F4E800B6D1FB /* pack-end.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "pack-end.h"; sourceTree = "<group>"; };
- DFE473B40D81F4E800B6D1FB /* pack-start.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "pack-start.h"; sourceTree = "<group>"; };
- DFE473B50D81F4E800B6D1FB /* rect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rect.h; sourceTree = "<group>"; };
- DFE473B60D81F4E800B6D1FB /* savefile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = savefile.h; sourceTree = "<group>"; };
- DFE473B70D81F4E800B6D1FB /* scummsys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scummsys.h; sourceTree = "<group>"; };
- DFE473B80D81F4E800B6D1FB /* singleton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = singleton.h; sourceTree = "<group>"; };
- DFE473B90D81F4E800B6D1FB /* stack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stack.h; sourceTree = "<group>"; };
- DFE473BA0D81F4E800B6D1FB /* str.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = str.cpp; sourceTree = "<group>"; };
- DFE473BB0D81F4E800B6D1FB /* str.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = str.h; sourceTree = "<group>"; };
- DFE473BC0D81F4E800B6D1FB /* stream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stream.cpp; sourceTree = "<group>"; };
- DFE473BD0D81F4E800B6D1FB /* stream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stream.h; sourceTree = "<group>"; };
- DFE473BE0D81F4E800B6D1FB /* system.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = system.cpp; sourceTree = "<group>"; };
- DFE473BF0D81F4E800B6D1FB /* system.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = system.h; sourceTree = "<group>"; };
- DFE473C00D81F4E800B6D1FB /* timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = timer.h; sourceTree = "<group>"; };
- DFE473C10D81F4E800B6D1FB /* unzip.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = unzip.cpp; sourceTree = "<group>"; };
- DFE473C20D81F4E800B6D1FB /* unzip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unzip.h; sourceTree = "<group>"; };
- DFE473C30D81F4E800B6D1FB /* util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = util.cpp; sourceTree = "<group>"; };
- DFE473C40D81F4E800B6D1FB /* util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = util.h; sourceTree = "<group>"; };
- DFE473C50D81F4E800B6D1FB /* zlib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = zlib.cpp; sourceTree = "<group>"; };
- DFE473C60D81F4E800B6D1FB /* zlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = zlib.h; sourceTree = "<group>"; };
- DFE477530D81F4E900B6D1FB /* colormasks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = colormasks.h; sourceTree = "<group>"; };
- DFE477540D81F4E900B6D1FB /* cursorman.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cursorman.cpp; sourceTree = "<group>"; };
- DFE477550D81F4E900B6D1FB /* cursorman.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cursorman.h; sourceTree = "<group>"; };
- DFE477580D81F4E900B6D1FB /* font.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = font.cpp; sourceTree = "<group>"; };
- DFE477590D81F4E900B6D1FB /* font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = font.h; sourceTree = "<group>"; };
- DFE4775A0D81F4E900B6D1FB /* fontman.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fontman.cpp; sourceTree = "<group>"; };
- DFE4775B0D81F4E900B6D1FB /* fontman.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fontman.h; sourceTree = "<group>"; };
- DFE4775D0D81F4E900B6D1FB /* consolefont.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = consolefont.cpp; sourceTree = "<group>"; };
- DFE4775E0D81F4E900B6D1FB /* newfont.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = newfont.cpp; sourceTree = "<group>"; };
- DFE4775F0D81F4E900B6D1FB /* newfont_big.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = newfont_big.cpp; sourceTree = "<group>"; };
- DFE477610D81F4E900B6D1FB /* iff.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = iff.cpp; sourceTree = "<group>"; };
- DFE477620D81F4E900B6D1FB /* iff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iff.h; sourceTree = "<group>"; };
- DFE477630D81F4E900B6D1FB /* imagedec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imagedec.cpp; sourceTree = "<group>"; };
- DFE477640D81F4E900B6D1FB /* imagedec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imagedec.h; sourceTree = "<group>"; };
- DFE4776A0D81F4E900B6D1FB /* primitives.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = primitives.cpp; sourceTree = "<group>"; };
- DFE4776B0D81F4E900B6D1FB /* primitives.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = primitives.h; sourceTree = "<group>"; };
- DFE477860D81F4E900B6D1FB /* surface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = surface.cpp; sourceTree = "<group>"; };
- DFE477870D81F4E900B6D1FB /* surface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = surface.h; sourceTree = "<group>"; };
- DFE477890D81F4E900B6D1FB /* about.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = about.cpp; sourceTree = "<group>"; };
- DFE4778A0D81F4E900B6D1FB /* about.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = about.h; sourceTree = "<group>"; };
- DFE4778B0D81F4E900B6D1FB /* Actions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Actions.cpp; sourceTree = "<group>"; };
- DFE4778C0D81F4E900B6D1FB /* Actions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Actions.h; sourceTree = "<group>"; };
- DFE4778D0D81F4E900B6D1FB /* browser.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; path = browser.cpp; sourceTree = "<group>"; };
- DFE4778E0D81F4E900B6D1FB /* browser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = browser.h; sourceTree = "<group>"; };
- DFE4778F0D81F4E900B6D1FB /* chooser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = chooser.cpp; sourceTree = "<group>"; };
- DFE477900D81F4E900B6D1FB /* chooser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = chooser.h; sourceTree = "<group>"; };
- DFE477910D81F4E900B6D1FB /* console.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = console.cpp; sourceTree = "<group>"; };
- DFE477920D81F4E900B6D1FB /* console.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = console.h; sourceTree = "<group>"; };
- DFE477930D81F4E900B6D1FB /* credits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = credits.h; sourceTree = "<group>"; };
- DFE477940D81F4E900B6D1FB /* debugger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debugger.cpp; sourceTree = "<group>"; };
- DFE477950D81F4E900B6D1FB /* debugger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debugger.h; sourceTree = "<group>"; };
- DFE477960D81F4E900B6D1FB /* dialog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dialog.cpp; sourceTree = "<group>"; };
- DFE477970D81F4E900B6D1FB /* dialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dialog.h; sourceTree = "<group>"; };
- DFE4779E0D81F4E900B6D1FB /* Key.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Key.cpp; sourceTree = "<group>"; };
- DFE4779F0D81F4E900B6D1FB /* Key.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Key.h; sourceTree = "<group>"; };
- DFE477A20D81F4E900B6D1FB /* launcher.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = launcher.cpp; sourceTree = "<group>"; };
- DFE477A30D81F4E900B6D1FB /* launcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = launcher.h; sourceTree = "<group>"; };
- DFE477A60D81F4E900B6D1FB /* massadd.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = massadd.cpp; sourceTree = "<group>"; };
- DFE477A70D81F4E900B6D1FB /* massadd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = massadd.h; sourceTree = "<group>"; };
- DFE477A80D81F4E900B6D1FB /* message.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = message.cpp; sourceTree = "<group>"; };
- DFE477A90D81F4E900B6D1FB /* message.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = message.h; sourceTree = "<group>"; };
- DFE477AD0D81F4E900B6D1FB /* object.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = object.cpp; sourceTree = "<group>"; };
- DFE477AE0D81F4E900B6D1FB /* object.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = object.h; sourceTree = "<group>"; };
- DFE477AF0D81F4E900B6D1FB /* options.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = options.cpp; sourceTree = "<group>"; };
- DFE477B00D81F4E900B6D1FB /* options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = options.h; sourceTree = "<group>"; };
- DFE477BA0D81F4E900B6D1FB /* themebrowser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = themebrowser.cpp; sourceTree = "<group>"; };
- DFE477BB0D81F4E900B6D1FB /* themebrowser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = themebrowser.h; sourceTree = "<group>"; };
- DFE477C40D81F4E900B6D1FB /* widget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = widget.cpp; sourceTree = "<group>"; };
- DFE477C50D81F4E900B6D1FB /* widget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = widget.h; sourceTree = "<group>"; };
- DFE47C810D81F86900B6D1FB /* kyra.dat */ = {isa = PBXFileReference; lastKnownFileType = file; path = kyra.dat; sourceTree = "<group>"; };
- DFE47C820D81F86900B6D1FB /* lure.dat */ = {isa = PBXFileReference; lastKnownFileType = file; path = lure.dat; sourceTree = "<group>"; };
- DFE47C830D81F86900B6D1FB /* queen.tbl */ = {isa = PBXFileReference; lastKnownFileType = file; path = queen.tbl; sourceTree = "<group>"; };
- DFE47C850D81F86900B6D1FB /* sky.cpt */ = {isa = PBXFileReference; lastKnownFileType = file; path = sky.cpt; sourceTree = "<group>"; };
- DFE88C440F874A1100C555C5 /* sound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound.cpp; sourceTree = "<group>"; };
- DFE88C450F874A1100C555C5 /* sound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound.h; sourceTree = "<group>"; };
- DFEC5D0A1166C5CF00C90552 /* random.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = random.cpp; sourceTree = "<group>"; };
- DFEC5D0B1166C5CF00C90552 /* random.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = random.h; sourceTree = "<group>"; };
- DFEC5D0C1166C5CF00C90552 /* str-array.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "str-array.h"; sourceTree = "<group>"; };
- DFEC5D0D1166C5CF00C90552 /* tokenizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tokenizer.cpp; sourceTree = "<group>"; };
- DFEC5D0E1166C5CF00C90552 /* tokenizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tokenizer.h; sourceTree = "<group>"; };
- DFEC5D0F1166C5CF00C90552 /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = types.h; sourceTree = "<group>"; };
- DFEC5D341166C67300C90552 /* savestate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = savestate.cpp; sourceTree = "<group>"; };
- DFEC5D351166C67300C90552 /* savestate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = savestate.h; sourceTree = "<group>"; };
- DFF4DFFC0F4B449F00C50BC7 /* Info.plist.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Info.plist.in; sourceTree = "<group>"; };
- DFF95CCA0FB22D5700A3EC78 /* ScummVM.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ScummVM.app; sourceTree = BUILT_PRODUCTS_DIR; };
- F92B4DCB139DD428000D1BF1 /* memstream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = memstream.h; sourceTree = "<group>"; };
- F92B4DCC139DD428000D1BF1 /* quicktime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = quicktime.cpp; sourceTree = "<group>"; };
- F92B4DCD139DD428000D1BF1 /* quicktime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = quicktime.h; sourceTree = "<group>"; };
- F92B4DD1139DD449000D1BF1 /* yuv_to_rgb.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = yuv_to_rgb.cpp; sourceTree = "<group>"; };
- F92B4DD2139DD449000D1BF1 /* yuv_to_rgb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = yuv_to_rgb.h; sourceTree = "<group>"; };
- F92B4DD6139DDC7A000D1BF1 /* sdl-sys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "sdl-sys.h"; sourceTree = "<group>"; };
- F92B4DD7139DDC92000D1BF1 /* macosx-main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "macosx-main.cpp"; path = "sdl/macosx/macosx-main.cpp"; sourceTree = "<group>"; };
- F92B4DD8139DDC92000D1BF1 /* macosx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = macosx.cpp; path = sdl/macosx/macosx.cpp; sourceTree = "<group>"; };
- F92B4DD9139DDC92000D1BF1 /* macosx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = macosx.h; path = sdl/macosx/macosx.h; sourceTree = "<group>"; };
- F9946D7A139E1A260072D195 /* cdtoons.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cdtoons.cpp; sourceTree = "<group>"; };
- F9946D7B139E1A260072D195 /* cdtoons.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cdtoons.h; sourceTree = "<group>"; };
- F9946D7C139E1A260072D195 /* cinepak.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cinepak.cpp; sourceTree = "<group>"; };
- F9946D7D139E1A260072D195 /* cinepak.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cinepak.h; sourceTree = "<group>"; };
- F9946D7E139E1A260072D195 /* codec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = codec.h; sourceTree = "<group>"; };
- F9946D7F139E1A260072D195 /* indeo3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = indeo3.cpp; sourceTree = "<group>"; };
- F9946D80139E1A260072D195 /* indeo3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = indeo3.h; sourceTree = "<group>"; };
- F9946D81139E1A260072D195 /* mjpeg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mjpeg.cpp; sourceTree = "<group>"; };
- F9946D82139E1A260072D195 /* mjpeg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mjpeg.h; sourceTree = "<group>"; };
- F9946D83139E1A260072D195 /* msrle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = msrle.cpp; sourceTree = "<group>"; };
- F9946D84139E1A260072D195 /* msrle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = msrle.h; sourceTree = "<group>"; };
- F9946D85139E1A260072D195 /* msvideo1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = msvideo1.cpp; sourceTree = "<group>"; };
- F9946D86139E1A260072D195 /* msvideo1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = msvideo1.h; sourceTree = "<group>"; };
- F9946D87139E1A260072D195 /* qtrle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = qtrle.cpp; sourceTree = "<group>"; };
- F9946D88139E1A260072D195 /* qtrle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = qtrle.h; sourceTree = "<group>"; };
- F9946D89139E1A260072D195 /* rpza.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rpza.cpp; sourceTree = "<group>"; };
- F9946D8A139E1A260072D195 /* rpza.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rpza.h; sourceTree = "<group>"; };
- F9946D8B139E1A260072D195 /* smc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = smc.cpp; sourceTree = "<group>"; };
- F9946D8C139E1A260072D195 /* smc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = smc.h; sourceTree = "<group>"; };
- F9946D8D139E1A260072D195 /* truemotion1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = truemotion1.cpp; sourceTree = "<group>"; };
- F9946D8E139E1A260072D195 /* truemotion1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = truemotion1.h; sourceTree = "<group>"; };
- F9946D8F139E1A260072D195 /* truemotion1data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = truemotion1data.h; sourceTree = "<group>"; };
- F9946D9A139E1A560072D195 /* towns_midi.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = towns_midi.cpp; path = ../../audio/softsynth/fmtowns_pc98/towns_midi.cpp; sourceTree = "<group>"; };
- F9946D9B139E1A560072D195 /* towns_midi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = towns_midi.h; path = ../../audio/softsynth/fmtowns_pc98/towns_midi.h; sourceTree = "<group>"; };
- F9946D9C139E1A560072D195 /* towns_pc98_plugins.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = towns_pc98_plugins.cpp; path = ../../audio/softsynth/fmtowns_pc98/towns_pc98_plugins.cpp; sourceTree = "<group>"; };
- F9946DA3139E1A880072D195 /* freeverb.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = freeverb.cpp; path = ../../audio/softsynth/mt32/freeverb.cpp; sourceTree = "<group>"; };
- F9946DA4139E1A880072D195 /* freeverb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = freeverb.h; path = ../../audio/softsynth/mt32/freeverb.h; sourceTree = "<group>"; };
- F9946DA5139E1A880072D195 /* i386.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = i386.cpp; path = ../../audio/softsynth/mt32/i386.cpp; sourceTree = "<group>"; };
- F9946DA6139E1A880072D195 /* i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = i386.h; path = ../../audio/softsynth/mt32/i386.h; sourceTree = "<group>"; };
- F9946DA7139E1A880072D195 /* mt32_file.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mt32_file.cpp; path = ../../audio/softsynth/mt32/mt32_file.cpp; sourceTree = "<group>"; };
- F9946DA8139E1A880072D195 /* mt32_file.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mt32_file.h; path = ../../audio/softsynth/mt32/mt32_file.h; sourceTree = "<group>"; };
- F9946DA9139E1A880072D195 /* mt32emu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mt32emu.h; path = ../../audio/softsynth/mt32/mt32emu.h; sourceTree = "<group>"; };
- F9946DAA139E1A880072D195 /* part.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = part.cpp; path = ../../audio/softsynth/mt32/part.cpp; sourceTree = "<group>"; };
- F9946DAB139E1A880072D195 /* part.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = part.h; path = ../../audio/softsynth/mt32/part.h; sourceTree = "<group>"; };
- F9946DAC139E1A880072D195 /* partial.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = partial.cpp; path = ../../audio/softsynth/mt32/partial.cpp; sourceTree = "<group>"; };
- F9946DAD139E1A880072D195 /* partial.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = partial.h; path = ../../audio/softsynth/mt32/partial.h; sourceTree = "<group>"; };
- F9946DAE139E1A880072D195 /* partialManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = partialManager.cpp; path = ../../audio/softsynth/mt32/partialManager.cpp; sourceTree = "<group>"; };
- F9946DAF139E1A880072D195 /* partialManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = partialManager.h; path = ../../audio/softsynth/mt32/partialManager.h; sourceTree = "<group>"; };
- F9946DB0139E1A880072D195 /* structures.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = structures.h; path = ../../audio/softsynth/mt32/structures.h; sourceTree = "<group>"; };
- F9946DB1139E1A880072D195 /* synth.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = synth.cpp; path = ../../audio/softsynth/mt32/synth.cpp; sourceTree = "<group>"; };
- F9946DB2139E1A880072D195 /* synth.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = synth.h; path = ../../audio/softsynth/mt32/synth.h; sourceTree = "<group>"; };
- F9946DB3139E1A880072D195 /* tables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tables.cpp; path = ../../audio/softsynth/mt32/tables.cpp; sourceTree = "<group>"; };
- F9946DB4139E1A880072D195 /* tables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tables.h; path = ../../audio/softsynth/mt32/tables.h; sourceTree = "<group>"; };
- F9946DCE139E1AD30072D195 /* aac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = aac.cpp; path = ../../audio/decoders/aac.cpp; sourceTree = "<group>"; };
- F9946DCF139E1AD30072D195 /* aac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = aac.h; path = ../../audio/decoders/aac.h; sourceTree = "<group>"; };
- F9946DD0139E1AD30072D195 /* qdm2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = qdm2.cpp; path = ../../audio/decoders/qdm2.cpp; sourceTree = "<group>"; };
- F9946DD1139E1AD30072D195 /* qdm2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = qdm2.h; path = ../../audio/decoders/qdm2.h; sourceTree = "<group>"; };
- F9946DD2139E1AD30072D195 /* qdm2data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = qdm2data.h; path = ../../audio/decoders/qdm2data.h; sourceTree = "<group>"; };
- F9946DD3139E1AD30072D195 /* quicktime_intern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = quicktime_intern.h; path = ../../audio/decoders/quicktime_intern.h; sourceTree = "<group>"; };
- F9946DD4139E1AD30072D195 /* quicktime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = quicktime.cpp; path = ../../audio/decoders/quicktime.cpp; sourceTree = "<group>"; };
- F9946DD5139E1AD30072D195 /* quicktime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = quicktime.h; path = ../../audio/decoders/quicktime.h; sourceTree = "<group>"; };
- F9946DE0139E1B180072D195 /* posix-main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "posix-main.cpp"; sourceTree = "<group>"; };
- F9946DE1139E1B180072D195 /* posix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = posix.cpp; sourceTree = "<group>"; };
- F9946DE2139E1B180072D195 /* posix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = posix.h; sourceTree = "<group>"; };
- F9946DE9139E1B6F0072D195 /* aspect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aspect.h; sourceTree = "<group>"; };
- F9946DEA139E1B6F0072D195 /* downscaler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = downscaler.cpp; sourceTree = "<group>"; };
- F9946DEB139E1B6F0072D195 /* downscaler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = downscaler.h; sourceTree = "<group>"; };
- F9946DEF139E1BA00072D195 /* console.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = console.cpp; sourceTree = "<group>"; };
- F9946DF0139E1BA00072D195 /* console.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = console.h; sourceTree = "<group>"; };
- F9946DF5139E1BBF0072D195 /* sdl-mixer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "sdl-mixer.cpp"; sourceTree = "<group>"; };
- F9946DF6139E1BBF0072D195 /* sdl-mixer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "sdl-mixer.h"; sourceTree = "<group>"; };
- F9946DFC139E1BEB0072D195 /* doublebuffersdl-mixer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "doublebuffersdl-mixer.cpp"; sourceTree = "<group>"; };
- F9946DFD139E1BEB0072D195 /* doublebuffersdl-mixer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "doublebuffersdl-mixer.h"; sourceTree = "<group>"; };
- F9946E02139E1C390072D195 /* sdl-graphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "sdl-graphics.cpp"; sourceTree = "<group>"; };
- F9946E03139E1C390072D195 /* sdl-graphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "sdl-graphics.h"; sourceTree = "<group>"; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
- 1D60588F0D05DD3D006BFB54 /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- DF842A1A0E7BB34E00F5680E /* CoreAudio.framework in Frameworks */,
- DF842A1B0E7BB34E00F5680E /* CoreFoundation.framework in Frameworks */,
- DF842A1C0E7BB34E00F5680E /* Foundation.framework in Frameworks */,
- DF842A1D0E7BB34E00F5680E /* UIKit.framework in Frameworks */,
- DF842A280E7BB37500F5680E /* AudioToolbox.framework in Frameworks */,
- DF842A2F0E7BB39E00F5680E /* QuartzCore.framework in Frameworks */,
- DFF959050FB22D3000A3EC78 /* libmad.a in Frameworks */,
- DFF959060FB22D3100A3EC78 /* libFLAC.a in Frameworks */,
- DFF959080FB22D3300A3EC78 /* libvorbisidec.a in Frameworks */,
- DF224E040FB23BC500C8E453 /* OpenGLES.framework in Frameworks */,
- DFADEC071382140300C46364 /* libz.dylib in Frameworks */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- DF0942180F63CB26002D821E /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- DF0943730F63D1DA002D821E /* CoreFoundation.framework in Frameworks */,
- DF0943740F63D1DD002D821E /* Foundation.framework in Frameworks */,
- DF0943750F63D1DE002D821E /* AudioToolbox.framework in Frameworks */,
- DF0944180F63FA8F002D821E /* QuickTime.framework in Frameworks */,
- DF0944250F63FB2C002D821E /* CoreMIDI.framework in Frameworks */,
- DF0944290F63FB60002D821E /* CoreAudio.framework in Frameworks */,
- DF09442B0F63FB75002D821E /* QuartzCore.framework in Frameworks */,
- DF0944380F63FBFE002D821E /* Carbon.framework in Frameworks */,
- DF09446F0F63FCCB002D821E /* ApplicationServices.framework in Frameworks */,
- DF0944700F63FCCB002D821E /* IOKit.framework in Frameworks */,
- DF0944780F63FD10002D821E /* Cocoa.framework in Frameworks */,
- DF0944800F63FD67002D821E /* AudioUnit.framework in Frameworks */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- DFF95CBB0FB22D5700A3EC78 /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- DFF95CBC0FB22D5700A3EC78 /* CoreAudio.framework in Frameworks */,
- DFF95CBD0FB22D5700A3EC78 /* CoreFoundation.framework in Frameworks */,
- DFF95CBE0FB22D5700A3EC78 /* Foundation.framework in Frameworks */,
- DFF95CBF0FB22D5700A3EC78 /* UIKit.framework in Frameworks */,
- DFF95CC00FB22D5700A3EC78 /* AudioToolbox.framework in Frameworks */,
- DFF95CC10FB22D5700A3EC78 /* QuartzCore.framework in Frameworks */,
- DF224E050FB23BC500C8E453 /* OpenGLES.framework in Frameworks */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
- 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = {
- isa = PBXGroup;
- children = (
- DF224E020FB23BC500C8E453 /* OpenGLES.framework */,
- DF09447F0F63FD67002D821E /* AudioUnit.framework */,
- DF0944770F63FD10002D821E /* Cocoa.framework */,
- DF09446D0F63FCCB002D821E /* ApplicationServices.framework */,
- DF09446E0F63FCCB002D821E /* IOKit.framework */,
- DF0944370F63FBFE002D821E /* Carbon.framework */,
- DF0944240F63FB2C002D821E /* CoreMIDI.framework */,
- DF0944170F63FA8F002D821E /* QuickTime.framework */,
- DF842A2E0E7BB39E00F5680E /* QuartzCore.framework */,
- DF842A270E7BB37500F5680E /* AudioToolbox.framework */,
- DF842A160E7BB34E00F5680E /* CoreAudio.framework */,
- DF842A170E7BB34E00F5680E /* CoreFoundation.framework */,
- DF842A180E7BB34E00F5680E /* Foundation.framework */,
- DF842A190E7BB34E00F5680E /* UIKit.framework */,
- DFADEC061382140300C46364 /* libz.dylib */,
- );
- name = "Linked Frameworks";
- sourceTree = "<group>";
- };
- 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = {
- isa = PBXGroup;
- children = (
- );
- name = "Other Frameworks";
- sourceTree = "<group>";
- };
- 19C28FACFE9D520D11CA2CBB /* Products */ = {
- isa = PBXGroup;
- children = (
- 1D6058910D05DD3D006BFB54 /* ScummVM.app */,
- DF09422A0F63CB26002D821E /* ScummVM.app */,
- DFF95CCA0FB22D5700A3EC78 /* ScummVM.app */,
- );
- name = Products;
- sourceTree = "<group>";
- };
- 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = {
- isa = PBXGroup;
- children = (
- DF2040461380C9ED0056300A /* audio */,
- DF203F521380C2470056300A /* video */,
- DF9B9277118E475D0069C19D /* games */,
- DFD6476A0F49F7D2008E18EF /* libs */,
- DF841FF50E7BA6A600F5680E /* engines */,
- DFE470D50D81F4E700B6D1FB /* backends */,
- DFE470C00D81F4BA00B6D1FB /* base */,
- DFE473950D81F4E800B6D1FB /* common */,
- DFE477520D81F4E900B6D1FB /* graphics */,
- DFE477880D81F4E900B6D1FB /* gui */,
- 29B97317FDCFA39411CA2CEA /* Resources */,
- DFA2A57A118E433A00344DFD /* Resources-iPad */,
- 29B97323FDCFA39411CA2CEA /* Frameworks */,
- 19C28FACFE9D520D11CA2CBB /* Products */,
- );
- name = CustomTemplate;
- sourceTree = "<group>";
- };
- 29B97317FDCFA39411CA2CEA /* Resources */ = {
- isa = PBXGroup;
- children = (
- 8CB5A9D21253FD9100CB6BC7 /* engine-data */,
- DF895C40124C271F0077F6E8 /* icon4.png */,
- DF895C33124C26660077F6E8 /* icon-72.png */,
- DF0944B00F6430ED002D821E /* scummvm.icns */,
- DFF4DFFC0F4B449F00C50BC7 /* Info.plist.in */,
- DF2FFD290F48717F0006E566 /* Default.png */,
- DF2FFD2A0F48717F0006E566 /* icon.png */,
- 8D1107310486CEB800E47090 /* Info.plist */,
- );
- name = Resources;
- sourceTree = "<group>";
- };
- 29B97323FDCFA39411CA2CEA /* Frameworks */ = {
- isa = PBXGroup;
- children = (
- 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */,
- 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */,
- );
- name = Frameworks;
- sourceTree = "<group>";
- };
- 8CB5A9D21253FD9100CB6BC7 /* engine-data */ = {
- isa = PBXGroup;
- children = (
- 8CB5A9D51253FDF400CB6BC7 /* drascula.dat */,
- 8CB5A9D61253FDF500CB6BC7 /* hugo.dat */,
- DFE47C810D81F86900B6D1FB /* kyra.dat */,
- DFE47C820D81F86900B6D1FB /* lure.dat */,
- 8CB5A9D71253FDF500CB6BC7 /* m4.dat */,
- DFE47C830D81F86900B6D1FB /* queen.tbl */,
- DFE47C850D81F86900B6D1FB /* sky.cpt */,
- 8CB5A9D81253FDF500CB6BC7 /* teenagent.dat */,
- 8CD1ED871262030100FA198C /* toon.dat */,
- );
- name = "engine-data";
- path = "../engine-data";
- sourceTree = "<group>";
- };
- 8CD1ECC5126202AA00FA198C /* hugo */ = {
- isa = PBXGroup;
- children = (
- DF203FC01380C3BC0056300A /* console.cpp */,
- DF203FC11380C3BC0056300A /* console.h */,
- DF203FC21380C3BC0056300A /* dialogs.cpp */,
- DF203FC31380C3BC0056300A /* dialogs.h */,
- DF203FC41380C3BC0056300A /* file_v1d.cpp */,
- DF203FC51380C3BC0056300A /* file_v1w.cpp */,
- DF203FC61380C3BC0056300A /* file_v2d.cpp */,
- DF203FC71380C3BC0056300A /* file_v2w.cpp */,
- DF203FC81380C3BC0056300A /* file_v3d.cpp */,
- DF203FC91380C3BC0056300A /* object_v1d.cpp */,
- DF203FCA1380C3BC0056300A /* object_v1w.cpp */,
- DF203FCB1380C3BC0056300A /* object_v2d.cpp */,
- DF203FCC1380C3BC0056300A /* object_v3d.cpp */,
- DF203FCD1380C3BC0056300A /* object.cpp */,
- DF203FCE1380C3BC0056300A /* object.h */,
- DF203FCF1380C3BC0056300A /* parser_v1d.cpp */,
- DF203FD01380C3BC0056300A /* parser_v1w.cpp */,
- DF203FD11380C3BC0056300A /* parser_v2d.cpp */,
- DF203FD21380C3BC0056300A /* parser_v3d.cpp */,
- DF203FD31380C3BC0056300A /* text.cpp */,
- DF203FD41380C3BC0056300A /* text.h */,
- 8CD1ECC6126202AA00FA198C /* detection.cpp */,
- 8CD1ECC7126202AA00FA198C /* display.cpp */,
- 8CD1ECC8126202AA00FA198C /* display.h */,
- 8CD1ECCB126202AA00FA198C /* file.cpp */,
- 8CD1ECCC126202AA00FA198C /* file.h */,
- 8CD1ECCD126202AA00FA198C /* game.h */,
- 8CD1ECCF126202AA00FA198C /* hugo.cpp */,
- 8CD1ECD0126202AA00FA198C /* hugo.h */,
- 8CD1ECD1126202AA00FA198C /* intro.cpp */,
- 8CD1ECD2126202AA00FA198C /* intro.h */,
- 8CD1ECD3126202AA00FA198C /* inventory.cpp */,
- 8CD1ECD4126202AA00FA198C /* inventory.h */,
- 8CD1ECD7126202AA00FA198C /* mouse.cpp */,
- 8CD1ECD8126202AA00FA198C /* mouse.h */,
- 8CD1ECD9126202AA00FA198C /* parser.cpp */,
- 8CD1ECDA126202AA00FA198C /* parser.h */,
- 8CD1ECDB126202AA00FA198C /* route.cpp */,
- 8CD1ECDC126202AA00FA198C /* route.h */,
- 8CD1ECDD126202AA00FA198C /* schedule.cpp */,
- 8CD1ECDE126202AA00FA198C /* schedule.h */,
- 8CD1ECDF126202AA00FA198C /* sound.cpp */,
- 8CD1ECE0126202AA00FA198C /* sound.h */,
- 8CD1ECE1126202AA00FA198C /* util.cpp */,
- 8CD1ECE2126202AA00FA198C /* util.h */,
- );
- path = hugo;
- sourceTree = "<group>";
- };
- 8CD1ECE3126202AA00FA198C /* toon */ = {
- isa = PBXGroup;
- children = (
- F9946DEF139E1BA00072D195 /* console.cpp */,
- F9946DF0139E1BA00072D195 /* console.h */,
- 8CD1ECE4126202AA00FA198C /* anim.cpp */,
- 8CD1ECE5126202AA00FA198C /* anim.h */,
- 8CD1ECE6126202AA00FA198C /* audio.cpp */,
- 8CD1ECE7126202AA00FA198C /* audio.h */,
- 8CD1ECE8126202AA00FA198C /* character.cpp */,
- 8CD1ECE9126202AA00FA198C /* character.h */,
- 8CD1ECEA126202AA00FA198C /* conversation.cpp */,
- 8CD1ECEB126202AA00FA198C /* conversation.h */,
- 8CD1ECEC126202AA00FA198C /* detection.cpp */,
- 8CD1ECED126202AA00FA198C /* drew.cpp */,
- 8CD1ECEE126202AA00FA198C /* drew.h */,
- 8CD1ECEF126202AA00FA198C /* flux.cpp */,
- 8CD1ECF0126202AA00FA198C /* flux.h */,
- 8CD1ECF1126202AA00FA198C /* font.cpp */,
- 8CD1ECF2126202AA00FA198C /* font.h */,
- 8CD1ECF3126202AA00FA198C /* hotspot.cpp */,
- 8CD1ECF4126202AA00FA198C /* hotspot.h */,
- 8CD1ECF7126202AA00FA198C /* movie.cpp */,
- 8CD1ECF8126202AA00FA198C /* movie.h */,
- 8CD1ECF9126202AA00FA198C /* path.cpp */,
- 8CD1ECFA126202AA00FA198C /* path.h */,
- 8CD1ECFB126202AA00FA198C /* picture.cpp */,
- 8CD1ECFC126202AA00FA198C /* picture.h */,
- 8CD1ECFD126202AA00FA198C /* resource.cpp */,
- 8CD1ECFE126202AA00FA198C /* resource.h */,
- 8CD1ECFF126202AA00FA198C /* script.cpp */,
- 8CD1ED00126202AA00FA198C /* script.h */,
- 8CD1ED01126202AA00FA198C /* script_func.cpp */,
- 8CD1ED02126202AA00FA198C /* script_func.h */,
- 8CD1ED03126202AA00FA198C /* state.cpp */,
- 8CD1ED04126202AA00FA198C /* state.h */,
- 8CD1ED05126202AA00FA198C /* text.cpp */,
- 8CD1ED06126202AA00FA198C /* text.h */,
- 8CD1ED07126202AA00FA198C /* tools.cpp */,
- 8CD1ED08126202AA00FA198C /* tools.h */,
- 8CD1ED09126202AA00FA198C /* toon.cpp */,
- 8CD1ED0A126202AA00FA198C /* toon.h */,
- );
- path = toon;
- sourceTree = "<group>";
- };
- 8CD80CBE1262729F001C6C87 /* teenagent */ = {
- isa = PBXGroup;
- children = (
- 8CD80CBF1262729F001C6C87 /* actor.cpp */,
- 8CD80CC01262729F001C6C87 /* actor.h */,
- 8CD80CC11262729F001C6C87 /* animation.cpp */,
- 8CD80CC21262729F001C6C87 /* animation.h */,
- 8CD80CC31262729F001C6C87 /* callbacks.cpp */,
- 8CD80CC41262729F001C6C87 /* console.cpp */,
- 8CD80CC51262729F001C6C87 /* console.h */,
- 8CD80CC61262729F001C6C87 /* detection.cpp */,
- 8CD80CC71262729F001C6C87 /* dialog.cpp */,
- 8CD80CC81262729F001C6C87 /* dialog.h */,
- 8CD80CC91262729F001C6C87 /* font.cpp */,
- 8CD80CCA1262729F001C6C87 /* font.h */,
- 8CD80CCB1262729F001C6C87 /* inventory.cpp */,
- 8CD80CCC1262729F001C6C87 /* inventory.h */,
- 8CD80CCE1262729F001C6C87 /* music.cpp */,
- 8CD80CCF1262729F001C6C87 /* music.h */,
- 8CD80CD01262729F001C6C87 /* objects.cpp */,
- 8CD80CD11262729F001C6C87 /* objects.h */,
- 8CD80CD21262729F001C6C87 /* pack.cpp */,
- 8CD80CD3126272A0001C6C87 /* pack.h */,
- 8CD80CD4126272A0001C6C87 /* resources.cpp */,
- 8CD80CD5126272A0001C6C87 /* resources.h */,
- 8CD80CD6126272A0001C6C87 /* scene.cpp */,
- 8CD80CD7126272A0001C6C87 /* scene.h */,
- 8CD80CD8126272A0001C6C87 /* segment.cpp */,
- 8CD80CD9126272A0001C6C87 /* segment.h */,
- 8CD80CDA126272A0001C6C87 /* surface.cpp */,
- 8CD80CDB126272A0001C6C87 /* surface.h */,
- 8CD80CDC126272A0001C6C87 /* surface_list.cpp */,
- 8CD80CDD126272A0001C6C87 /* surface_list.h */,
- 8CD80CDE126272A0001C6C87 /* teenagent.cpp */,
- 8CD80CDF126272A0001C6C87 /* teenagent.h */,
- );
- path = teenagent;
- sourceTree = "<group>";
- };
- DF09422F0F63CB9A002D821E /* sdl */ = {
- isa = PBXGroup;
- children = (
- F9946DDF139E1B180072D195 /* posix */,
- F92B4DD6139DDC7A000D1BF1 /* sdl-sys.h */,
- DF6118CB0FE3AAFD0042AD3F /* hardwarekeys.cpp */,
- DF0942390F63CB9A002D821E /* main.cpp */,
- DF09423C0F63CB9A002D821E /* sdl.cpp */,
- DF09423D0F63CB9A002D821E /* sdl.h */,
- );
- path = sdl;
- sourceTree = "<group>";
- };
- DF09CC060FAC4E1900A5AFD7 /* demos */ = {
- isa = PBXGroup;
- children = (
- DF09CC070FAC4E1900A5AFD7 /* batplayer.cpp */,
- DF09CC080FAC4E1900A5AFD7 /* batplayer.h */,
- DF09CC090FAC4E1900A5AFD7 /* demoplayer.cpp */,
- DF09CC0A0FAC4E1900A5AFD7 /* demoplayer.h */,
- DF09CC0B0FAC4E1900A5AFD7 /* scnplayer.cpp */,
- DF09CC0C0FAC4E1900A5AFD7 /* scnplayer.h */,
- );
- path = demos;
- sourceTree = "<group>";
- };
- DF203F521380C2470056300A /* video */ = {
- isa = PBXGroup;
- children = (
- DF203F7B1380C27A0056300A /* codecs */,
- DF203F531380C2740056300A /* avi_decoder.cpp */,
- DF203F541380C2740056300A /* avi_decoder.h */,
- DF203F551380C2740056300A /* coktel_decoder.cpp */,
- DF203F561380C2740056300A /* coktel_decoder.h */,
- DF203F571380C2740056300A /* dxa_decoder.cpp */,
- DF203F581380C2740056300A /* dxa_decoder.h */,
- DF203F591380C2740056300A /* flic_decoder.cpp */,
- DF203F5A1380C2740056300A /* flic_decoder.h */,
- DF203F5D1380C2740056300A /* qt_decoder.cpp */,
- DF203F5E1380C2750056300A /* qt_decoder.h */,
- DF203F5F1380C2750056300A /* smk_decoder.cpp */,
- DF203F601380C2750056300A /* smk_decoder.h */,
- DF203F611380C2750056300A /* video_decoder.cpp */,
- DF203F621380C2750056300A /* video_decoder.h */,
- );
- name = video;
- sourceTree = "<group>";
- };
- DF203F7B1380C27A0056300A /* codecs */ = {
- isa = PBXGroup;
- children = (
- DF203F7C1380C2920056300A /* cdtoons.cpp */,
- DF203F7D1380C2920056300A /* cdtoons.h */,
- DF203F7E1380C2920056300A /* cinepak.cpp */,
- DF203F7F1380C2920056300A /* cinepak.h */,
- DF203F801380C2920056300A /* codec.h */,
- DF203F811380C2920056300A /* indeo3.cpp */,
- DF203F821380C2920056300A /* indeo3.h */,
- DF203F831380C2920056300A /* mjpeg.cpp */,
- DF203F841380C2920056300A /* mjpeg.h */,
- DF203F851380C2920056300A /* msrle.cpp */,
- DF203F861380C2920056300A /* msrle.h */,
- DF203F871380C2920056300A /* msvideo1.cpp */,
- DF203F881380C2920056300A /* msvideo1.h */,
- DF203F8C1380C2920056300A /* qtrle.cpp */,
- DF203F8D1380C2920056300A /* qtrle.h */,
- DF203F8E1380C2920056300A /* rpza.cpp */,
- DF203F8F1380C2920056300A /* rpza.h */,
- DF203F901380C2920056300A /* smc.cpp */,
- DF203F911380C2920056300A /* smc.h */,
- DF203F921380C2920056300A /* truemotion1.cpp */,
- DF203F931380C2920056300A /* truemotion1.h */,
- DF203F941380C2920056300A /* truemotion1data.h */,
- );
- name = codecs;
- sourceTree = "<group>";
- };
- DF2040211380C8A60056300A /* widgets */ = {
- isa = PBXGroup;
- children = (
- DF2040221380C8B70056300A /* editable.cpp */,
- DF2040231380C8B70056300A /* editable.h */,
- DF2040241380C8B70056300A /* edittext.cpp */,
- DF2040251380C8B70056300A /* edittext.h */,
- DF2040261380C8B70056300A /* list.cpp */,
- DF2040271380C8B70056300A /* list.h */,
- DF2040281380C8B70056300A /* popup.cpp */,
- DF2040291380C8B70056300A /* popup.h */,
- DF20402A1380C8B70056300A /* scrollbar.cpp */,
- DF20402B1380C8B70056300A /* scrollbar.h */,
- DF20402C1380C8B70056300A /* tab.cpp */,
- DF20402D1380C8B70056300A /* tab.h */,
- );
- name = widgets;
- sourceTree = "<group>";
- };
- DF2040461380C9ED0056300A /* audio */ = {
- isa = PBXGroup;
- children = (
- F9946D79139E1A260072D195 /* codecs */,
- DF46B8991381F6C400D08723 /* null.cpp */,
- DF46B89A1381F6C400D08723 /* null.h */,
- DF2040E41380CA8C0056300A /* softsynth */,
- DF2040BB1380CA5C0056300A /* mods */,
- DF2040821380CA280056300A /* decoders */,
- DF2040471380CA230056300A /* audiostream.cpp */,
- DF2040481380CA230056300A /* audiostream.h */,
- DF2040491380CA230056300A /* fmopl.cpp */,
- DF20404A1380CA230056300A /* fmopl.h */,
- DF20404B1380CA230056300A /* mididrv.cpp */,
- DF20404C1380CA230056300A /* mididrv.h */,
- DF20404D1380CA230056300A /* midiparser_smf.cpp */,
- DF20404E1380CA230056300A /* midiparser_xmidi.cpp */,
- DF20404F1380CA230056300A /* midiparser.cpp */,
- DF2040501380CA230056300A /* midiparser.h */,
- DF2040511380CA230056300A /* midiplayer.cpp */,
- DF2040521380CA230056300A /* midiplayer.h */,
- DF2040531380CA230056300A /* mixer_intern.h */,
- DF2040541380CA230056300A /* mixer.cpp */,
- DF2040551380CA230056300A /* mixer.h */,
- DF2040561380CA230056300A /* mpu401.cpp */,
- DF2040571380CA230056300A /* mpu401.h */,
- DF2040581380CA230056300A /* musicplugin.cpp */,
- DF2040591380CA230056300A /* musicplugin.h */,
- DF20405A1380CA230056300A /* rate.cpp */,
- DF20405B1380CA230056300A /* rate.h */,
- DF20405C1380CA230056300A /* timestamp.cpp */,
- DF20405D1380CA230056300A /* timestamp.h */,
- );
- name = audio;
- sourceTree = "<group>";
- };
- DF2040821380CA280056300A /* decoders */ = {
- isa = PBXGroup;
- children = (
- F9946DCE139E1AD30072D195 /* aac.cpp */,
- F9946DCF139E1AD30072D195 /* aac.h */,
- F9946DD0139E1AD30072D195 /* qdm2.cpp */,
- F9946DD1139E1AD30072D195 /* qdm2.h */,
- F9946DD2139E1AD30072D195 /* qdm2data.h */,
- F9946DD3139E1AD30072D195 /* quicktime_intern.h */,
- F9946DD4139E1AD30072D195 /* quicktime.cpp */,
- F9946DD5139E1AD30072D195 /* quicktime.h */,
- DF2040831380CA400056300A /* adpcm_intern.h */,
- DF2040841380CA400056300A /* adpcm.cpp */,
- DF2040851380CA400056300A /* adpcm.h */,
- DF2040861380CA400056300A /* aiff.cpp */,
- DF2040871380CA400056300A /* aiff.h */,
- DF2040881380CA400056300A /* flac.cpp */,
- DF2040891380CA400056300A /* flac.h */,
- DF20408A1380CA400056300A /* iff_sound.cpp */,
- DF20408B1380CA400056300A /* iff_sound.h */,
- DF20408C1380CA400056300A /* mac_snd.cpp */,
- DF20408D1380CA400056300A /* mac_snd.h */,
- DF20408E1380CA400056300A /* mp3.cpp */,
- DF20408F1380CA400056300A /* mp3.h */,
- DF2040901380CA400056300A /* raw.cpp */,
- DF2040911380CA400056300A /* raw.h */,
- DF2040921380CA400056300A /* vag.cpp */,
- DF2040931380CA400056300A /* vag.h */,
- DF2040941380CA400056300A /* voc.cpp */,
- DF2040951380CA400056300A /* voc.h */,
- DF2040961380CA400056300A /* vorbis.cpp */,
- DF2040971380CA400056300A /* vorbis.h */,
- DF2040981380CA400056300A /* wave.cpp */,
- DF2040991380CA400056300A /* wave.h */,
- );
- name = decoders;
- sourceTree = "<group>";
- };
- DF2040BB1380CA5C0056300A /* mods */ = {
- isa = PBXGroup;
- children = (
- DF2040BC1380CA810056300A /* infogrames.cpp */,
- DF2040BD1380CA810056300A /* infogrames.h */,
- DF2040BE1380CA810056300A /* maxtrax.cpp */,
- DF2040BF1380CA810056300A /* maxtrax.h */,
- DF2040C01380CA810056300A /* module.cpp */,
- DF2040C11380CA810056300A /* module.h */,
- DF2040C21380CA810056300A /* paula.cpp */,
- DF2040C31380CA810056300A /* paula.h */,
- DF2040C41380CA810056300A /* protracker.cpp */,
- DF2040C51380CA810056300A /* protracker.h */,
- DF2040C61380CA810056300A /* rjp1.cpp */,
- DF2040C71380CA810056300A /* rjp1.h */,
- DF2040C81380CA810056300A /* soundfx.cpp */,
- DF2040C91380CA810056300A /* soundfx.h */,
- DF2040CA1380CA810056300A /* tfmx.cpp */,
- DF2040CB1380CA810056300A /* tfmx.h */,
- );
- name = mods;
- sourceTree = "<group>";
- };
- DF2040E41380CA8C0056300A /* softsynth */ = {
- isa = PBXGroup;
- children = (
- F9946DCD139E1A9A0072D195 /* mt32 */,
- DF46B8591381F43100D08723 /* opl */,
- DF46B6F61381E1D100D08723 /* fmtowns_pc98 */,
- DF2040E51380CAA40056300A /* adlib.cpp */,
- DF2040E61380CAA40056300A /* appleiigs.cpp */,
- DF2040E71380CAA40056300A /* cms.cpp */,
- DF2040E81380CAA40056300A /* cms.h */,
- DF2040E91380CAA40056300A /* eas.cpp */,
- DF2040EA1380CAA40056300A /* emumidi.h */,
- DF2040EB1380CAA40056300A /* fluidsynth.cpp */,
- DF2040EC1380CAA40056300A /* mt32.cpp */,
- DF2040ED1380CAA40056300A /* pcspk.cpp */,
- DF2040EE1380CAA40056300A /* pcspk.h */,
- DF2040EF1380CAA40056300A /* sid.cpp */,
- DF2040F01380CAA40056300A /* sid.h */,
- DF2040F11380CAA40056300A /* wave6581.cpp */,
- );
- name = softsynth;
- sourceTree = "<group>";
- };
- DF2FFBF50F4860A60006E566 /* posix */ = {
- isa = PBXGroup;
- children = (
- DF2FFBF80F4860A60006E566 /* posix-saves.cpp */,
- DF2FFBF90F4860A60006E566 /* posix-saves.h */,
- );
- path = posix;
- sourceTree = "<group>";
- };
- DF2FFCBC0F4870690006E566 /* groovie */ = {
- isa = PBXGroup;
- children = (
- DF2FFCBD0F4870690006E566 /* cell.cpp */,
- DF2FFCBE0F4870690006E566 /* cell.h */,
- DF2FFCBF0F4870690006E566 /* cursor.cpp */,
- DF2FFCC00F4870690006E566 /* cursor.h */,
- DF2FFCC10F4870690006E566 /* debug.cpp */,
- DF2FFCC20F4870690006E566 /* debug.h */,
- DF2FFCC30F4870690006E566 /* detection.cpp */,
- DF2FFCC40F4870690006E566 /* font.cpp */,
- DF2FFCC50F4870690006E566 /* font.h */,
- DF2FFCC60F4870690006E566 /* graphics.cpp */,
- DF2FFCC70F4870690006E566 /* graphics.h */,
- DF2FFCC80F4870690006E566 /* groovie.cpp */,
- DF2FFCC90F4870690006E566 /* groovie.h */,
- DF2FFCCA0F4870690006E566 /* lzss.cpp */,
- DF2FFCCB0F4870690006E566 /* lzss.h */,
- DF2FFCCD0F4870690006E566 /* music.cpp */,
- DF2FFCCE0F4870690006E566 /* music.h */,
- DF2FFCCF0F4870690006E566 /* player.cpp */,
- DF2FFCD00F4870690006E566 /* player.h */,
- DF2FFCD10F4870690006E566 /* resource.cpp */,
- DF2FFCD20F4870690006E566 /* resource.h */,
- DF2FFCD30F4870690006E566 /* roq.cpp */,
- DF2FFCD40F4870690006E566 /* roq.h */,
- DF2FFCD50F4870690006E566 /* saveload.cpp */,
- DF2FFCD60F4870690006E566 /* saveload.h */,
- DF2FFCD70F4870690006E566 /* script.cpp */,
- DF2FFCD80F4870690006E566 /* script.h */,
- DF2FFCD90F4870690006E566 /* vdx.cpp */,
- DF2FFCDA0F4870690006E566 /* vdx.h */,
- );
- path = groovie;
- sourceTree = "<group>";
- };
- DF2FFD040F4870E50006E566 /* tucker */ = {
- isa = PBXGroup;
- children = (
- DF46B7D41381E7C600D08723 /* console.cpp */,
- DF46B7D51381E7C600D08723 /* console.h */,
- DF2FFD050F4870E50006E566 /* detection.cpp */,
- DF2FFD060F4870E50006E566 /* graphics.cpp */,
- DF2FFD070F4870E50006E566 /* graphics.h */,
- DF2FFD080F4870E50006E566 /* locations.cpp */,
- DF2FFD0A0F4870E50006E566 /* resource.cpp */,
- DF2FFD0B0F4870E50006E566 /* saveload.cpp */,
- DF2FFD0C0F4870E50006E566 /* sequences.cpp */,
- DF2FFD0D0F4870E50006E566 /* staticres.cpp */,
- DF2FFD0E0F4870E50006E566 /* tucker.cpp */,
- DF2FFD0F0F4870E50006E566 /* tucker.h */,
- );
- path = tucker;
- sourceTree = "<group>";
- };
- DF45B175116628A5009B85CC /* graphics */ = {
- isa = PBXGroup;
- children = (
- DF45B176116628A5009B85CC /* animate.cpp */,
- DF45B177116628A5009B85CC /* animate.h */,
- DF45B178116628A5009B85CC /* cache.cpp */,
- DF45B179116628A5009B85CC /* cache.h */,
- DF45B17A116628A5009B85CC /* compare.cpp */,
- DF45B17B116628A5009B85CC /* compare.h */,
- DF45B17C116628A5009B85CC /* controls.cpp */,
- DF45B17D116628A5009B85CC /* controls.h */,
- DF45B17E116628A5009B85CC /* coordadjuster.cpp */,
- DF45B17F116628A5009B85CC /* coordadjuster.h */,
- DF45B180116628A5009B85CC /* cursor.cpp */,
- DF45B181116628A5009B85CC /* cursor.h */,
- DF45B182116628A5009B85CC /* font.cpp */,
- DF45B183116628A5009B85CC /* font.h */,
- DF9B924F118E46A00069C19D /* fontsjis.cpp */,
- DF9B9250118E46A00069C19D /* fontsjis.h */,
- DF7F285C11FF23B700159131 /* frameout.cpp */,
- DF45B185116628A5009B85CC /* frameout.h */,
- DF45B18A116628A5009B85CC /* helpers.h */,
- DFB0578811B754570015AE65 /* maciconbar.cpp */,
- DFB0578911B754570015AE65 /* maciconbar.h */,
- DF45B18B116628A5009B85CC /* menu.cpp */,
- DF45B18C116628A5009B85CC /* menu.h */,
- DF45B18D116628A5009B85CC /* paint.cpp */,
- DF45B18E116628A5009B85CC /* paint.h */,
- DF45B18F116628A5009B85CC /* paint16.cpp */,
- DF45B190116628A5009B85CC /* paint16.h */,
- DF45B191116628A5009B85CC /* paint32.cpp */,
- DF45B192116628A5009B85CC /* paint32.h */,
- DF45B193116628A5009B85CC /* palette.cpp */,
- DF45B194116628A5009B85CC /* palette.h */,
- DF45B195116628A5009B85CC /* picture.cpp */,
- DF45B196116628A5009B85CC /* picture.h */,
- DF45B197116628A5009B85CC /* portrait.cpp */,
- DF45B198116628A5009B85CC /* portrait.h */,
- DF45B199116628A5009B85CC /* ports.cpp */,
- DF45B19A116628A5009B85CC /* ports.h */,
- DF45B19B116628A5009B85CC /* robot.cpp */,
- DF45B19C116628A5009B85CC /* robot.h */,
- DF45B19D116628A5009B85CC /* screen.cpp */,
- DF45B19E116628A5009B85CC /* screen.h */,
- DF45B19F116628A5009B85CC /* text16.cpp */,
- DF45B1A0116628A5009B85CC /* text16.h */,
- DF45B1A1116628A5009B85CC /* transitions.cpp */,
- DF45B1A2116628A5009B85CC /* transitions.h */,
- DF45B1A3116628A5009B85CC /* view.cpp */,
- DF45B1A4116628A5009B85CC /* view.h */,
- );
- path = graphics;
- sourceTree = "<group>";
- };
- DF45B1A5116628A5009B85CC /* parser */ = {
- isa = PBXGroup;
- children = (
- DF45B1A6116628A5009B85CC /* grammar.cpp */,
- DF45B1A7116628A5009B85CC /* said.cpp */,
- DF45B1A9116628A5009B85CC /* vocabulary.cpp */,
- DF45B1AA116628A5009B85CC /* vocabulary.h */,
- );
- path = parser;
- sourceTree = "<group>";
- };
- DF45B1AB116628A5009B85CC /* sound */ = {
- isa = PBXGroup;
- children = (
- DF45B1AC116628A5009B85CC /* audio.cpp */,
- DF45B1AD116628A5009B85CC /* audio.h */,
- DF45B1AE116628A5009B85CC /* drivers */,
- DF45B1BF116628A5009B85CC /* midiparser_sci.cpp */,
- DF45B1C0116628A5009B85CC /* midiparser_sci.h */,
- DF45B1C1116628A5009B85CC /* music.cpp */,
- DF45B1C2116628A5009B85CC /* music.h */,
- DF45B1C3116628A5009B85CC /* soundcmd.cpp */,
- DF45B1C4116628A5009B85CC /* soundcmd.h */,
- );
- path = sound;
- sourceTree = "<group>";
- };
- DF45B1AE116628A5009B85CC /* drivers */ = {
- isa = PBXGroup;
- children = (
- DF0E30391252C5BD0082D593 /* cms.cpp */,
- DF7F286011FF23D500159131 /* amigamac.cpp */,
- DF45B1AF116628A5009B85CC /* adlib.cpp */,
- DF45B1B1116628A5009B85CC /* fb01.cpp */,
- DF45B1B2116628A5009B85CC /* map-mt32-to-gm.h */,
- DF45B1B3116628A5009B85CC /* midi.cpp */,
- DF45B1B4116628A5009B85CC /* mididriver.h */,
- DF45B1B5116628A5009B85CC /* pcjr.cpp */,
- );
- path = drivers;
- sourceTree = "<group>";
- };
- DF45B1C5116628A5009B85CC /* video */ = {
- isa = PBXGroup;
- children = (
- DF46B7611381E4D400D08723 /* robot_decoder.cpp */,
- DF46B7621381E4D400D08723 /* robot_decoder.h */,
- DF45B1C6116628A5009B85CC /* seq_decoder.cpp */,
- DF45B1C7116628A5009B85CC /* seq_decoder.h */,
- );
- path = video;
- sourceTree = "<group>";
- };
- DF46B6F61381E1D100D08723 /* fmtowns_pc98 */ = {
- isa = PBXGroup;
- children = (
- F9946D9A139E1A560072D195 /* towns_midi.cpp */,
- F9946D9B139E1A560072D195 /* towns_midi.h */,
- F9946D9C139E1A560072D195 /* towns_pc98_plugins.cpp */,
- DF46B6F71381E1FF00D08723 /* towns_audio.cpp */,
- DF46B6F81381E1FF00D08723 /* towns_audio.h */,
- DF46B6F91381E1FF00D08723 /* towns_euphony.cpp */,
- DF46B6FA1381E1FF00D08723 /* towns_euphony.h */,
- DF46B6FB1381E1FF00D08723 /* towns_pc98_driver.cpp */,
- DF46B6FC1381E1FF00D08723 /* towns_pc98_driver.h */,
- DF46B6FD1381E1FF00D08723 /* towns_pc98_fmsynth.cpp */,
- DF46B6FE1381E1FF00D08723 /* towns_pc98_fmsynth.h */,
- );
- name = fmtowns_pc98;
- sourceTree = "<group>";
- };
- DF46B7411381E3F200D08723 /* log */ = {
- isa = PBXGroup;
- children = (
- DF46B7421381E40500D08723 /* log.cpp */,
- DF46B7431381E40500D08723 /* log.h */,
- );
- name = log;
- sourceTree = "<group>";
- };
- DF46B7A21381E5CC00D08723 /* sdl */ = {
- isa = PBXGroup;
- children = (
- DF46B7A31381E5D900D08723 /* sdl-timer.cpp */,
- DF46B7A41381E5D900D08723 /* sdl-timer.h */,
- );
- name = sdl;
- sourceTree = "<group>";
- };
- DF46B7B01381E64E00D08723 /* mutex */ = {
- isa = PBXGroup;
- children = (
- DF46B7B11381E66000D08723 /* sdl */,
- );
- name = mutex;
- sourceTree = "<group>";
- };
- DF46B7B11381E66000D08723 /* sdl */ = {
- isa = PBXGroup;
- children = (
- DF46B7B21381E67800D08723 /* sdl-mutex.cpp */,
- DF46B7B31381E67800D08723 /* sdl-mutex.h */,
- );
- name = sdl;
- sourceTree = "<group>";
- };
- DF46B7CC1381E74D00D08723 /* sdl */ = {
- isa = PBXGroup;
- children = (
- DF46B7CD1381E76300D08723 /* sdl-events.cpp */,
- DF46B7CE1381E76300D08723 /* sdl-events.h */,
- );
- name = sdl;
- path = ..;
- sourceTree = "<group>";
- };
- DF46B8591381F43100D08723 /* opl */ = {
- isa = PBXGroup;
- children = (
- DF46B85A1381F44E00D08723 /* dbopl.cpp */,
- DF46B85B1381F44E00D08723 /* dbopl.h */,
- DF46B85C1381F44E00D08723 /* dosbox.cpp */,
- DF46B85D1381F44E00D08723 /* dosbox.h */,
- DF46B85E1381F44E00D08723 /* mame.cpp */,
- DF46B85F1381F44E00D08723 /* mame.h */,
- );
- name = opl;
- sourceTree = "<group>";
- };
- DF46B86D1381F47B00D08723 /* audiocd */ = {
- isa = PBXGroup;
- children = (
- DF46B8801381F4FF00D08723 /* audiocd.h */,
- DF46B8781381F4C500D08723 /* default */,
- DF46B86E1381F48D00D08723 /* sdl */,
- );
- name = audiocd;
- sourceTree = "<group>";
- };
- DF46B86E1381F48D00D08723 /* sdl */ = {
- isa = PBXGroup;
- children = (
- DF46B86F1381F4A200D08723 /* sdl-audiocd.cpp */,
- DF46B8701381F4A200D08723 /* sdl-audiocd.h */,
- );
- name = sdl;
- sourceTree = "<group>";
- };
- DF46B8781381F4C500D08723 /* default */ = {
- isa = PBXGroup;
- children = (
- DF46B87B1381F4F200D08723 /* default-audiocd.cpp */,
- DF46B87C1381F4F200D08723 /* default-audiocd.h */,
- );
- name = default;
- sourceTree = "<group>";
- };
- DF46B8861381F5C600D08723 /* sdl */ = {
- isa = PBXGroup;
- children = (
- DF46B8871381F5D800D08723 /* sdl-provider.cpp */,
- DF46B8881381F5D800D08723 /* sdl-provider.h */,
- );
- name = sdl;
- sourceTree = "<group>";
- };
- DF6118780FE3A9AA0042AD3F /* save */ = {
- isa = PBXGroup;
- children = (
- DF46B8431381F35500D08723 /* saveload_inca2.cpp */,
- DF46B83B1381F13500D08723 /* saveload_v7.cpp */,
- DFCDC70311662B0200A7D2A0 /* saveload_fascin.cpp */,
- DF7585F0100CB70600CC3324 /* saveload_playtoons.cpp */,
- DF6118790FE3A9AA0042AD3F /* saveconverter.cpp */,
- DF61187A0FE3A9AA0042AD3F /* saveconverter.h */,
- DF61187B0FE3A9AA0042AD3F /* saveconverter_v2.cpp */,
- DF61187C0FE3A9AA0042AD3F /* saveconverter_v3.cpp */,
- DF61187D0FE3A9AA0042AD3F /* saveconverter_v4.cpp */,
- DF61187F0FE3A9AA0042AD3F /* savefile.cpp */,
- DF6118800FE3A9AA0042AD3F /* savefile.h */,
- DF6118810FE3A9AA0042AD3F /* savehandler.cpp */,
- DF6118820FE3A9AA0042AD3F /* savehandler.h */,
- DF6118830FE3A9AA0042AD3F /* saveload.cpp */,
- DF6118840FE3A9AA0042AD3F /* saveload.h */,
- DF6118850FE3A9AA0042AD3F /* saveload_v2.cpp */,
- DF6118860FE3A9AA0042AD3F /* saveload_v3.cpp */,
- DF6118870FE3A9AA0042AD3F /* saveload_v4.cpp */,
- DF6118880FE3A9AA0042AD3F /* saveload_v6.cpp */,
- );
- path = save;
- sourceTree = "<group>";
- };
- DF841FF50E7BA6A600F5680E /* engines */ = {
- isa = PBXGroup;
- children = (
- DF46B8851381F56400D08723 /* util.h */,
- DF2FFC4C0F4863560006E566 /* advancedDetector.cpp */,
- DF2FFC4D0F4863560006E566 /* advancedDetector.h */,
- DF841FF60E7BA6A600F5680E /* agi */,
- DF84202D0E7BA6A600F5680E /* agos */,
- DF8420640E7BA6A600F5680E /* cine */,
- DF84208B0E7BA6A600F5680E /* cruise */,
- DF8421020E7BA6A700F5680E /* dialogs.cpp */,
- DF8421030E7BA6A700F5680E /* dialogs.h */,
- DF8421040E7BA6A700F5680E /* drascula */,
- DF8421140E7BA6A700F5680E /* engine.cpp */,
- DF8421150E7BA6A700F5680E /* engine.h */,
- DF7E8C510ED60067001CB19F /* game.cpp */,
- DF7E8C520ED60067001CB19F /* game.h */,
- DF8421170E7BA6A700F5680E /* gob */,
- DF2FFCBC0F4870690006E566 /* groovie */,
- 8CD1ECC5126202AA00FA198C /* hugo */,
- DF8421A30E7BA6A800F5680E /* kyra */,
- DF8422200E7BA6A800F5680E /* lure */,
- DF84224E0E7BA6A800F5680E /* m4 */,
- DF8422C90E7BA6A900F5680E /* made */,
- DF8422E40E7BA6A900F5680E /* metaengine.h */,
- DF8422E60E7BA6A900F5680E /* parallaction */,
- DF8423120E7BA6A900F5680E /* queen */,
- DF84233E0E7BA6AA00F5680E /* saga */,
- DFEC5D341166C67300C90552 /* savestate.cpp */,
- DFEC5D351166C67300C90552 /* savestate.h */,
- DFC830190F48AF18005EF03C /* sci */,
- DF84237B0E7BA6AA00F5680E /* scumm */,
- DF8424200E7BA6AB00F5680E /* sky */,
- DF84244E0E7BA6AB00F5680E /* sword1 */,
- DF8424770E7BA6AB00F5680E /* sword2 */,
- 8CD80CBE1262729F001C6C87 /* teenagent */,
- DF8424AA0E7BA6AB00F5680E /* tinsel */,
- 8CD1ECE3126202AA00FA198C /* toon */,
- DF8424FC0E7BA6AB00F5680E /* touche */,
- DF2FFD040F4870E50006E566 /* tucker */,
- );
- name = engines;
- path = ../../engines;
- sourceTree = SOURCE_ROOT;
- };
- DF841FF60E7BA6A600F5680E /* agi */ = {
- isa = PBXGroup;
- children = (
- DF841FF70E7BA6A600F5680E /* agi.cpp */,
- DF841FF80E7BA6A600F5680E /* agi.h */,
- DF841FF90E7BA6A600F5680E /* checks.cpp */,
- DF841FFA0E7BA6A600F5680E /* console.cpp */,
- DF841FFB0E7BA6A600F5680E /* console.h */,
- DF841FFC0E7BA6A600F5680E /* cycle.cpp */,
- DF841FFD0E7BA6A600F5680E /* detection.cpp */,
- DF7F286F11FF243A00159131 /* detection_tables.h */,
- DF841FFE0E7BA6A600F5680E /* font.h */,
- DF841FFF0E7BA6A600F5680E /* global.cpp */,
- DF8420000E7BA6A600F5680E /* graphics.cpp */,
- DF8420010E7BA6A600F5680E /* graphics.h */,
- DF8420020E7BA6A600F5680E /* id.cpp */,
- DF8420030E7BA6A600F5680E /* inv.cpp */,
- DF8420040E7BA6A600F5680E /* keyboard.cpp */,
- DF8420050E7BA6A600F5680E /* keyboard.h */,
- DF8420060E7BA6A600F5680E /* loader_v2.cpp */,
- DF8420070E7BA6A600F5680E /* loader_v3.cpp */,
- DF8420080E7BA6A600F5680E /* logic.cpp */,
- DF8420090E7BA6A600F5680E /* logic.h */,
- DF84200A0E7BA6A600F5680E /* lzw.cpp */,
- DF84200B0E7BA6A600F5680E /* lzw.h */,
- DF84200C0E7BA6A600F5680E /* menu.cpp */,
- DF84200D0E7BA6A600F5680E /* menu.h */,
- DF84200F0E7BA6A600F5680E /* motion.cpp */,
- DF8420100E7BA6A600F5680E /* objects.cpp */,
- DF8420110E7BA6A600F5680E /* op_cmd.cpp */,
- DF8420120E7BA6A600F5680E /* op_dbg.cpp */,
- DF8420130E7BA6A600F5680E /* op_test.cpp */,
- DF8420140E7BA6A600F5680E /* opcodes.h */,
- DF8420150E7BA6A600F5680E /* picture.cpp */,
- DF8420160E7BA6A600F5680E /* picture.h */,
- DF8420170E7BA6A600F5680E /* preagi.cpp */,
- DF8420180E7BA6A600F5680E /* preagi.h */,
- DF8420190E7BA6A600F5680E /* preagi_common.cpp */,
- DF84201A0E7BA6A600F5680E /* preagi_common.h */,
- DF84201B0E7BA6A600F5680E /* preagi_mickey.cpp */,
- DF84201C0E7BA6A600F5680E /* preagi_mickey.h */,
- DF84201D0E7BA6A600F5680E /* preagi_troll.cpp */,
- DF84201E0E7BA6A600F5680E /* preagi_troll.h */,
- DF84201F0E7BA6A600F5680E /* preagi_winnie.cpp */,
- DF8420200E7BA6A600F5680E /* preagi_winnie.h */,
- DF8420210E7BA6A600F5680E /* predictive.cpp */,
- DF8420220E7BA6A600F5680E /* saveload.cpp */,
- DF8420230E7BA6A600F5680E /* sound.cpp */,
- DF8420240E7BA6A600F5680E /* sound.h */,
- DF7F287011FF243A00159131 /* sound_2gs.cpp */,
- DF7F287111FF243A00159131 /* sound_2gs.h */,
- DF7F287211FF243B00159131 /* sound_coco3.cpp */,
- DF7F287311FF243B00159131 /* sound_coco3.h */,
- DF7F287411FF243B00159131 /* sound_midi.cpp */,
- DF7F287511FF243B00159131 /* sound_midi.h */,
- DF7F287611FF243B00159131 /* sound_pcjr.cpp */,
- DF7F287711FF243B00159131 /* sound_pcjr.h */,
- DF7F287811FF243B00159131 /* sound_sarien.cpp */,
- DF7F287911FF243B00159131 /* sound_sarien.h */,
- DF8420250E7BA6A600F5680E /* sprite.cpp */,
- DF8420260E7BA6A600F5680E /* sprite.h */,
- DF8420270E7BA6A600F5680E /* text.cpp */,
- DF8420280E7BA6A600F5680E /* view.cpp */,
- DF8420290E7BA6A600F5680E /* view.h */,
- DF84202A0E7BA6A600F5680E /* wagparser.cpp */,
- DF84202B0E7BA6A600F5680E /* wagparser.h */,
- DF84202C0E7BA6A600F5680E /* words.cpp */,
- );
- path = agi;
- sourceTree = "<group>";
- };
- DF84202D0E7BA6A600F5680E /* agos */ = {
- isa = PBXGroup;
- children = (
- DF84202E0E7BA6A600F5680E /* agos.cpp */,
- DF84202F0E7BA6A600F5680E /* agos.h */,
- DF8420300E7BA6A600F5680E /* animation.cpp */,
- DF8420310E7BA6A600F5680E /* animation.h */,
- DF8420320E7BA6A600F5680E /* charset-fontdata.cpp */,
- DF8420330E7BA6A600F5680E /* charset.cpp */,
- DF8420340E7BA6A600F5680E /* contain.cpp */,
- DF8420350E7BA6A600F5680E /* cursor.cpp */,
- DF8420360E7BA6A600F5680E /* debug.cpp */,
- DF8420370E7BA6A600F5680E /* debug.h */,
- DF8420380E7BA6A600F5680E /* debugger.cpp */,
- DF8420390E7BA6A600F5680E /* debugger.h */,
- DF84203A0E7BA6A600F5680E /* detection.cpp */,
- DF84203B0E7BA6A600F5680E /* detection_tables.h */,
- DF84203C0E7BA6A600F5680E /* draw.cpp */,
- DF84203D0E7BA6A600F5680E /* event.cpp */,
- DF6118AE0FE3A9EA0042AD3F /* feeble.cpp */,
- DF84203E0E7BA6A600F5680E /* gfx.cpp */,
- DF84203F0E7BA6A600F5680E /* icons.cpp */,
- DF8420400E7BA6A600F5680E /* input.cpp */,
- DF6BF4D510529DE90069811F /* input_pn.cpp */,
- DF8420410E7BA6A600F5680E /* intern.h */,
- DF8420420E7BA6A600F5680E /* items.cpp */,
- DF8420430E7BA6A600F5680E /* menus.cpp */,
- DF8420440E7BA6A600F5680E /* midi.cpp */,
- DF8420450E7BA6A600F5680E /* midi.h */,
- DF8420460E7BA6A600F5680E /* midiparser_s1d.cpp */,
- DF8420480E7BA6A600F5680E /* oracle.cpp */,
- DF093E5C0F63CAD4002D821E /* pn.cpp */,
- DF8420490E7BA6A600F5680E /* res.cpp */,
- DF84204A0E7BA6A600F5680E /* res_ami.cpp */,
- DF84204B0E7BA6A600F5680E /* res_snd.cpp */,
- DF84204C0E7BA6A600F5680E /* rooms.cpp */,
- DF84204D0E7BA6A600F5680E /* saveload.cpp */,
- DF84204E0E7BA6A600F5680E /* script.cpp */,
- DF84204F0E7BA6A600F5680E /* script_e1.cpp */,
- DF8420500E7BA6A600F5680E /* script_e2.cpp */,
- DF8420510E7BA6A600F5680E /* script_ff.cpp */,
- DF093E5D0F63CAD4002D821E /* script_pn.cpp */,
- DF8420520E7BA6A600F5680E /* script_pp.cpp */,
- DF8420530E7BA6A600F5680E /* script_s1.cpp */,
- DF8420540E7BA6A600F5680E /* script_s2.cpp */,
- DF8420550E7BA6A600F5680E /* script_ww.cpp */,
- DF8420560E7BA6A600F5680E /* sound.cpp */,
- DF8420570E7BA6A600F5680E /* sound.h */,
- DF8420580E7BA6A600F5680E /* string.cpp */,
- DF6BF4D610529DE90069811F /* string_pn.cpp */,
- DF8420590E7BA6A600F5680E /* subroutine.cpp */,
- DF84205A0E7BA6A600F5680E /* verb.cpp */,
- DF6BF4D710529DE90069811F /* verb_pn.cpp */,
- DF84205B0E7BA6A600F5680E /* vga.cpp */,
- DF84205C0E7BA6A600F5680E /* vga.h */,
- DF84205D0E7BA6A600F5680E /* vga_e2.cpp */,
- DF84205E0E7BA6A600F5680E /* vga_ff.cpp */,
- DF093E5E0F63CAD4002D821E /* vga_pn.cpp */,
- DF84205F0E7BA6A600F5680E /* vga_s1.cpp */,
- DF8420600E7BA6A600F5680E /* vga_s2.cpp */,
- DF8420610E7BA6A600F5680E /* vga_ww.cpp */,
- DF8420620E7BA6A600F5680E /* window.cpp */,
- DF8420630E7BA6A600F5680E /* zones.cpp */,
- );
- path = agos;
- sourceTree = "<group>";
- };
- DF8420640E7BA6A600F5680E /* cine */ = {
- isa = PBXGroup;
- children = (
- DF46B75B1381E4A400D08723 /* console.cpp */,
- DF46B75C1381E4A400D08723 /* console.h */,
- DF46B75D1381E4A400D08723 /* detection_tables.h */,
- DF8420650E7BA6A600F5680E /* anim.cpp */,
- DF8420660E7BA6A600F5680E /* anim.h */,
- DF8420670E7BA6A600F5680E /* bg.cpp */,
- DF8420680E7BA6A600F5680E /* bg.h */,
- DF8420690E7BA6A600F5680E /* bg_list.cpp */,
- DF84206A0E7BA6A600F5680E /* bg_list.h */,
- DF84206B0E7BA6A600F5680E /* cine.cpp */,
- DF84206C0E7BA6A600F5680E /* cine.h */,
- DF84206D0E7BA6A600F5680E /* detection.cpp */,
- DF84206E0E7BA6A600F5680E /* gfx.cpp */,
- DF84206F0E7BA6A600F5680E /* gfx.h */,
- DF8420700E7BA6A600F5680E /* main_loop.cpp */,
- DF8420710E7BA6A600F5680E /* main_loop.h */,
- DF8420730E7BA6A600F5680E /* msg.cpp */,
- DF8420740E7BA6A600F5680E /* msg.h */,
- DF8420750E7BA6A600F5680E /* object.cpp */,
- DF8420760E7BA6A600F5680E /* object.h */,
- DF8420770E7BA6A600F5680E /* pal.cpp */,
- DF8420780E7BA6A600F5680E /* pal.h */,
- DF8420790E7BA6A600F5680E /* part.cpp */,
- DF84207A0E7BA6A600F5680E /* part.h */,
- DF84207B0E7BA6A600F5680E /* prc.cpp */,
- DF84207C0E7BA6A600F5680E /* prc.h */,
- DF84207D0E7BA6A600F5680E /* rel.cpp */,
- DF84207E0E7BA6A600F5680E /* rel.h */,
- DFAAAFF50F0112AD003E9390 /* saveload.cpp */,
- DFAAAFF60F0112AD003E9390 /* saveload.h */,
- DF84207F0E7BA6A600F5680E /* script.h */,
- DF8420800E7BA6A600F5680E /* script_fw.cpp */,
- DF8420810E7BA6A600F5680E /* script_os.cpp */,
- DF8420820E7BA6A600F5680E /* sound.cpp */,
- DF8420830E7BA6A600F5680E /* sound.h */,
- DF8420840E7BA6A600F5680E /* texte.cpp */,
- DF8420850E7BA6A600F5680E /* texte.h */,
- DF8420860E7BA6A600F5680E /* unpack.cpp */,
- DF8420870E7BA6A600F5680E /* unpack.h */,
- DF8420880E7BA6A600F5680E /* various.cpp */,
- DF8420890E7BA6A600F5680E /* various.h */,
- );
- path = cine;
- sourceTree = "<group>";
- };
- DF84208B0E7BA6A600F5680E /* cruise */ = {
- isa = PBXGroup;
- children = (
- DF8420AB0E7BA6A600F5680E /* actor.cpp */,
- DF8420AC0E7BA6A600F5680E /* actor.h */,
- DF8420AE0E7BA6A600F5680E /* background.cpp */,
- DF8420AF0E7BA6A600F5680E /* background.h */,
- DF8420B10E7BA6A600F5680E /* backgroundIncrust.cpp */,
- DF8420B20E7BA6A600F5680E /* backgroundIncrust.h */,
- DF8420B40E7BA6A600F5680E /* cell.cpp */,
- DF8420B50E7BA6A600F5680E /* cell.h */,
- DF8420B70E7BA6A600F5680E /* cruise.cpp */,
- DF8420B80E7BA6A700F5680E /* cruise.h */,
- DF8420BA0E7BA6A700F5680E /* cruise_main.cpp */,
- DF8420BB0E7BA6A700F5680E /* cruise_main.h */,
- DF8420BD0E7BA6A700F5680E /* ctp.cpp */,
- DF8420BE0E7BA6A700F5680E /* ctp.h */,
- DF8420C00E7BA6A700F5680E /* dataLoader.cpp */,
- DF8420C10E7BA6A700F5680E /* dataLoader.h */,
- DF2FFC700F4867910006E566 /* debugger.cpp */,
- DF2FFC710F4867910006E566 /* debugger.h */,
- DF8420C30E7BA6A700F5680E /* decompiler.cpp */,
- DF8420C50E7BA6A700F5680E /* delphine-unpack.cpp */,
- DF8420C70E7BA6A700F5680E /* detection.cpp */,
- DF8420C90E7BA6A700F5680E /* font.cpp */,
- DF8420CA0E7BA6A700F5680E /* font.h */,
- DF8420CF0E7BA6A700F5680E /* function.cpp */,
- DF8420D00E7BA6A700F5680E /* function.h */,
- DF8420D20E7BA6A700F5680E /* gfxModule.cpp */,
- DF8420D30E7BA6A700F5680E /* gfxModule.h */,
- DF8420D60E7BA6A700F5680E /* linker.cpp */,
- DF8420D70E7BA6A700F5680E /* linker.h */,
- DF8420D90E7BA6A700F5680E /* mainDraw.cpp */,
- DF8420DA0E7BA6A700F5680E /* mainDraw.h */,
- DF8420DC0E7BA6A700F5680E /* menu.cpp */,
- DF8420DD0E7BA6A700F5680E /* menu.h */,
- DF8420E00E7BA6A700F5680E /* mouse.cpp */,
- DF8420E10E7BA6A700F5680E /* mouse.h */,
- DF8420E30E7BA6A700F5680E /* object.cpp */,
- DF8420E40E7BA6A700F5680E /* object.h */,
- DF8420E60E7BA6A700F5680E /* overlay.cpp */,
- DF8420E70E7BA6A700F5680E /* overlay.h */,
- DF8420E90E7BA6A700F5680E /* perso.cpp */,
- DF8420EA0E7BA6A700F5680E /* perso.h */,
- DF8420EC0E7BA6A700F5680E /* polys.cpp */,
- DF8420ED0E7BA6A700F5680E /* polys.h */,
- DF8420EF0E7BA6A700F5680E /* saveload.cpp */,
- DF8420F00E7BA6A700F5680E /* saveload.h */,
- DF8420F20E7BA6A700F5680E /* script.cpp */,
- DF8420F30E7BA6A700F5680E /* script.h */,
- DFE88C440F874A1100C555C5 /* sound.cpp */,
- DFE88C450F874A1100C555C5 /* sound.h */,
- DF8420F50E7BA6A700F5680E /* stack.cpp */,
- DF8420F60E7BA6A700F5680E /* stack.h */,
- DF2FFC720F4867910006E566 /* staticres.cpp */,
- DF2FFC730F4867910006E566 /* staticres.h */,
- DF8420F90E7BA6A700F5680E /* various.cpp */,
- DF8420FA0E7BA6A700F5680E /* various.h */,
- DF8420FC0E7BA6A700F5680E /* vars.cpp */,
- DF8420FD0E7BA6A700F5680E /* vars.h */,
- DF8420FF0E7BA6A700F5680E /* volume.cpp */,
- DF8421000E7BA6A700F5680E /* volume.h */,
- );
- path = cruise;
- sourceTree = "<group>";
- };
- DF8421040E7BA6A700F5680E /* drascula */ = {
- isa = PBXGroup;
- children = (
- DF8421050E7BA6A700F5680E /* actors.cpp */,
- DF8421060E7BA6A700F5680E /* animation.cpp */,
- DF7F28A311FF24C400159131 /* console.cpp */,
- DF7F28A411FF24C400159131 /* console.h */,
- DF8421070E7BA6A700F5680E /* converse.cpp */,
- DF8421080E7BA6A700F5680E /* detection.cpp */,
- DF8421090E7BA6A700F5680E /* drascula.cpp */,
- DF84210A0E7BA6A700F5680E /* drascula.h */,
- DF84210B0E7BA6A700F5680E /* graphics.cpp */,
- DF84210C0E7BA6A700F5680E /* interface.cpp */,
- DF84210E0E7BA6A700F5680E /* objects.cpp */,
- DF84210F0E7BA6A700F5680E /* palette.cpp */,
- DFCDC6F611662AAB00A7D2A0 /* resource.cpp */,
- DF8421100E7BA6A700F5680E /* rooms.cpp */,
- DF8421110E7BA6A700F5680E /* saveload.cpp */,
- DF8421120E7BA6A700F5680E /* sound.cpp */,
- DF8421130E7BA6A700F5680E /* talk.cpp */,
- );
- path = drascula;
- sourceTree = "<group>";
- };
- DF8421170E7BA6A700F5680E /* gob */ = {
- isa = PBXGroup;
- children = (
- DF46B8471381F38700D08723 /* inter_v7.cpp */,
- DF46B70F1381E27000D08723 /* console.cpp */,
- DF46B7101381E27000D08723 /* console.h */,
- DF46B7111381E27000D08723 /* databases.cpp */,
- DF46B7121381E27000D08723 /* databases.h */,
- DF46B7131381E27000D08723 /* dbase.cpp */,
- DF46B7141381E27000D08723 /* dbase.h */,
- DF46B7151381E27000D08723 /* iniconfig.cpp */,
- DF46B7161381E27000D08723 /* iniconfig.h */,
- DF46B7171381E27000D08723 /* init_v7.cpp */,
- DF46B7181381E27000D08723 /* inter_inca2.cpp */,
- DF84211B0E7BA6A700F5680E /* dataio.cpp */,
- DF84211C0E7BA6A700F5680E /* dataio.h */,
- DF09CC060FAC4E1900A5AFD7 /* demos */,
- DF84211D0E7BA6A700F5680E /* detection.cpp */,
- DF895C23124C25150077F6E8 /* detection_tables.h */,
- DF84211E0E7BA6A700F5680E /* draw.cpp */,
- DF84211F0E7BA6A700F5680E /* draw.h */,
- DF8421200E7BA6A700F5680E /* draw_bargon.cpp */,
- DF09CC0D0FAC4E1900A5AFD7 /* draw_fascin.cpp */,
- DF90EAA310B0234300C8F93F /* draw_playtoons.cpp */,
- DF8421210E7BA6A700F5680E /* draw_v1.cpp */,
- DF8421220E7BA6A700F5680E /* draw_v2.cpp */,
- DF7585C3100CB66E00CC3324 /* expression.cpp */,
- DF7585C4100CB66E00CC3324 /* expression.h */,
- DF8421250E7BA6A700F5680E /* game.cpp */,
- DF8421260E7BA6A700F5680E /* game.h */,
- DF8421290E7BA6A700F5680E /* global.cpp */,
- DF84212A0E7BA6A700F5680E /* global.h */,
- DF84212B0E7BA6A700F5680E /* gob.cpp */,
- DF84212C0E7BA6A700F5680E /* gob.h */,
- DF84212D0E7BA6A700F5680E /* goblin.cpp */,
- DF84212E0E7BA6A700F5680E /* goblin.h */,
- DF84212F0E7BA6A700F5680E /* goblin_v1.cpp */,
- DF8421300E7BA6A700F5680E /* goblin_v2.cpp */,
- DF8421310E7BA6A700F5680E /* goblin_v3.cpp */,
- DF8421320E7BA6A700F5680E /* goblin_v4.cpp */,
- DF7585C5100CB66E00CC3324 /* hotspots.cpp */,
- DF7585C6100CB66E00CC3324 /* hotspots.h */,
- DF8421330E7BA6A700F5680E /* init.cpp */,
- DF8421340E7BA6A700F5680E /* init.h */,
- DF895C24124C25150077F6E8 /* init_fascin.cpp */,
- DF8421350E7BA6A700F5680E /* init_v1.cpp */,
- DF8421360E7BA6A700F5680E /* init_v2.cpp */,
- DF8421370E7BA6A700F5680E /* init_v3.cpp */,
- DF6BF4E810529E6E0069811F /* init_v4.cpp */,
- DF7585C7100CB66E00CC3324 /* init_v6.cpp */,
- DF8421380E7BA6A700F5680E /* inter.cpp */,
- DF8421390E7BA6A700F5680E /* inter.h */,
- DF84213A0E7BA6A700F5680E /* inter_bargon.cpp */,
- DF09CC0F0FAC4E1900A5AFD7 /* inter_fascin.cpp */,
- DF6BF4E910529E6E0069811F /* inter_playtoons.cpp */,
- DF84213B0E7BA6A700F5680E /* inter_v1.cpp */,
- DF84213C0E7BA6A700F5680E /* inter_v2.cpp */,
- DF84213D0E7BA6A700F5680E /* inter_v3.cpp */,
- DF84213E0E7BA6A700F5680E /* inter_v4.cpp */,
- DF84213F0E7BA6A700F5680E /* inter_v5.cpp */,
- DF8421400E7BA6A700F5680E /* inter_v6.cpp */,
- DF8421410E7BA6A700F5680E /* map.cpp */,
- DF8421420E7BA6A700F5680E /* map.h */,
- DF8421430E7BA6A700F5680E /* map_v1.cpp */,
- DF8421440E7BA6A700F5680E /* map_v2.cpp */,
- DF8421470E7BA6A700F5680E /* mult.cpp */,
- DF8421480E7BA6A700F5680E /* mult.h */,
- DF8421490E7BA6A700F5680E /* mult_v1.cpp */,
- DF84214A0E7BA6A700F5680E /* mult_v2.cpp */,
- DF84214C0E7BA6A700F5680E /* palanim.cpp */,
- DF84214D0E7BA6A700F5680E /* palanim.h */,
- DF7585C8100CB66E00CC3324 /* resources.cpp */,
- DF7585C9100CB66E00CC3324 /* resources.h */,
- DF6118780FE3A9AA0042AD3F /* save */,
- DF8421570E7BA6A700F5680E /* scenery.cpp */,
- DF8421580E7BA6A700F5680E /* scenery.h */,
- DF8421590E7BA6A700F5680E /* scenery_v1.cpp */,
- DF84215A0E7BA6A700F5680E /* scenery_v2.cpp */,
- DF7585CA100CB66E00CC3324 /* script.cpp */,
- DF7585CB100CB66E00CC3324 /* script.h */,
- DF84215B0E7BA6A700F5680E /* sound */,
- 8CD80C89126271A9001C6C87 /* surface.cpp */,
- 8CD80C8A126271A9001C6C87 /* surface.h */,
- DF7585CC100CB66E00CC3324 /* totfile.cpp */,
- DF7585CD100CB66E00CC3324 /* totfile.h */,
- DF84216F0E7BA6A700F5680E /* util.cpp */,
- DF8421700E7BA6A700F5680E /* util.h */,
- DF8421710E7BA6A700F5680E /* variables.cpp */,
- DF8421720E7BA6A700F5680E /* variables.h */,
- DF8421730E7BA6A700F5680E /* video.cpp */,
- DF8421740E7BA6A700F5680E /* video.h */,
- DF8421750E7BA6A700F5680E /* video_v1.cpp */,
- DF8421760E7BA6A700F5680E /* video_v2.cpp */,
- DF8421770E7BA6A700F5680E /* video_v6.cpp */,
- DF8421780E7BA6A700F5680E /* videoplayer.cpp */,
- DF8421790E7BA6A700F5680E /* videoplayer.h */,
- );
- path = gob;
- sourceTree = "<group>";
- };
- DF84215B0E7BA6A700F5680E /* sound */ = {
- isa = PBXGroup;
- children = (
- DF5CEB2F0F75538000DEA624 /* protracker.cpp */,
- DF5CEB300F75538000DEA624 /* protracker.h */,
- DF84215C0E7BA6A700F5680E /* adlib.cpp */,
- DF84215D0E7BA6A700F5680E /* adlib.h */,
- DF84215E0E7BA6A700F5680E /* bgatmosphere.cpp */,
- DF84215F0E7BA6A700F5680E /* bgatmosphere.h */,
- DF8421600E7BA6A700F5680E /* cdrom.cpp */,
- DF8421610E7BA6A700F5680E /* cdrom.h */,
- DF8421620E7BA6A700F5680E /* infogrames.cpp */,
- DF8421630E7BA6A700F5680E /* infogrames.h */,
- DF8421640E7BA6A700F5680E /* pcspeaker.cpp */,
- DF8421650E7BA6A700F5680E /* pcspeaker.h */,
- DF8421660E7BA6A700F5680E /* sound.cpp */,
- DF8421670E7BA6A700F5680E /* sound.h */,
- DF8421680E7BA6A700F5680E /* soundblaster.cpp */,
- DF8421690E7BA6A700F5680E /* soundblaster.h */,
- DF84216A0E7BA6A700F5680E /* sounddesc.cpp */,
- DF84216B0E7BA6A700F5680E /* sounddesc.h */,
- DF84216C0E7BA6A700F5680E /* soundmixer.cpp */,
- DF84216D0E7BA6A700F5680E /* soundmixer.h */,
- );
- path = sound;
- sourceTree = "<group>";
- };
- DF8421A30E7BA6A800F5680E /* kyra */ = {
- isa = PBXGroup;
- children = (
- DF8421A40E7BA6A800F5680E /* animator_hof.cpp */,
- DF8421A50E7BA6A800F5680E /* animator_lok.cpp */,
- DF8421A60E7BA6A800F5680E /* animator_lok.h */,
- DF8421A70E7BA6A800F5680E /* animator_mr.cpp */,
- DF2EC3FD10E64C4300765801 /* animator_tim.cpp */,
- DF8421A90E7BA6A800F5680E /* animator_v2.cpp */,
- DF8421AB0E7BA6A800F5680E /* debugger.cpp */,
- DF8421AC0E7BA6A800F5680E /* debugger.h */,
- DF8421AD0E7BA6A800F5680E /* detection.cpp */,
- DF8421AE0E7BA6A800F5680E /* gui.cpp */,
- DF8421AF0E7BA6A800F5680E /* gui.h */,
- DF8421B00E7BA6A800F5680E /* gui_hof.cpp */,
- DF8421B10E7BA6A800F5680E /* gui_hof.h */,
- DF8421B20E7BA6A800F5680E /* gui_lok.cpp */,
- DF8421B30E7BA6A800F5680E /* gui_lok.h */,
- DF2FFC2E0F48628A0006E566 /* gui_lol.cpp */,
- DF2FFC2F0F48628A0006E566 /* gui_lol.h */,
- DF8421B40E7BA6A800F5680E /* gui_mr.cpp */,
- DF8421B50E7BA6A800F5680E /* gui_mr.h */,
- DF8421B70E7BA6A800F5680E /* gui_v2.cpp */,
- DF8421B80E7BA6A800F5680E /* gui_v2.h */,
- DF8421BA0E7BA6A800F5680E /* items_hof.cpp */,
- DF8421BB0E7BA6A800F5680E /* items_lok.cpp */,
- DF2FFC300F48628A0006E566 /* items_lol.cpp */,
- DF8421BC0E7BA6A800F5680E /* items_mr.cpp */,
- DF8421BE0E7BA6A800F5680E /* items_v2.cpp */,
- DF8421C10E7BA6A800F5680E /* kyra_hof.cpp */,
- DF8421C20E7BA6A800F5680E /* kyra_hof.h */,
- DF8421C30E7BA6A800F5680E /* kyra_lok.cpp */,
- DF8421C40E7BA6A800F5680E /* kyra_lok.h */,
- DF8421C50E7BA6A800F5680E /* kyra_mr.cpp */,
- DF8421C60E7BA6A800F5680E /* kyra_mr.h */,
- DF8421C70E7BA6A800F5680E /* kyra_v1.cpp */,
- DF8421C80E7BA6A800F5680E /* kyra_v1.h */,
- DF8421C90E7BA6A800F5680E /* kyra_v2.cpp */,
- DF8421CA0E7BA6A800F5680E /* kyra_v2.h */,
- DF8421CC0E7BA6A800F5680E /* lol.cpp */,
- DF8421CD0E7BA6A800F5680E /* lol.h */,
- DF8421CF0E7BA6A800F5680E /* resource.cpp */,
- DF8421D00E7BA6A800F5680E /* resource.h */,
- DF8421D10E7BA6A800F5680E /* resource_intern.cpp */,
- DF8421D20E7BA6A800F5680E /* resource_intern.h */,
- DF8421D30E7BA6A800F5680E /* saveload.cpp */,
- DF8421D40E7BA6A800F5680E /* saveload_hof.cpp */,
- DF8421D50E7BA6A800F5680E /* saveload_lok.cpp */,
- DF6118B30FE3AA280042AD3F /* saveload_lol.cpp */,
- DF8421D60E7BA6A800F5680E /* saveload_mr.cpp */,
- DF8421DA0E7BA6A800F5680E /* scene_hof.cpp */,
- DF8421DB0E7BA6A800F5680E /* scene_lok.cpp */,
- DF2FFC490F4863100006E566 /* scene_lol.cpp */,
- DF8421DC0E7BA6A800F5680E /* scene_mr.cpp */,
- DF8421DD0E7BA6A800F5680E /* scene_v1.cpp */,
- DF8421DE0E7BA6A800F5680E /* scene_v2.cpp */,
- DF8421E00E7BA6A800F5680E /* screen.cpp */,
- DF8421E10E7BA6A800F5680E /* screen.h */,
- DF8421E20E7BA6A800F5680E /* screen_hof.cpp */,
- DF8421E30E7BA6A800F5680E /* screen_hof.h */,
- DF8421E40E7BA6A800F5680E /* screen_lok.cpp */,
- DF8421E50E7BA6A800F5680E /* screen_lok.h */,
- DF8421E60E7BA6A800F5680E /* screen_lol.cpp */,
- DF8421E70E7BA6A800F5680E /* screen_lol.h */,
- DF8421E80E7BA6A800F5680E /* screen_mr.cpp */,
- DF8421E90E7BA6A800F5680E /* screen_mr.h */,
- DF8421EB0E7BA6A800F5680E /* screen_v2.cpp */,
- DF8421EC0E7BA6A800F5680E /* screen_v2.h */,
- DF8421EE0E7BA6A800F5680E /* script.cpp */,
- DF8421EF0E7BA6A800F5680E /* script.h */,
- DF8421F00E7BA6A800F5680E /* script_hof.cpp */,
- DF8421F10E7BA6A800F5680E /* script_lok.cpp */,
- DF2FFC310F48628A0006E566 /* script_lol.cpp */,
- DF8421F20E7BA6A800F5680E /* script_mr.cpp */,
- DF8421F30E7BA6A800F5680E /* script_tim.cpp */,
- DF8421F40E7BA6A800F5680E /* script_tim.h */,
- DF8421F50E7BA6A800F5680E /* script_v1.cpp */,
- DF8421F60E7BA6A800F5680E /* script_v2.cpp */,
- DF8421F80E7BA6A800F5680E /* seqplayer.cpp */,
- DF8421F90E7BA6A800F5680E /* seqplayer.h */,
- DF8421FA0E7BA6A800F5680E /* sequences_hof.cpp */,
- DF8421FB0E7BA6A800F5680E /* sequences_lok.cpp */,
- DF2FFC320F48628A0006E566 /* sequences_lol.cpp */,
- DF8421FC0E7BA6A800F5680E /* sequences_mr.cpp */,
- DF8421FE0E7BA6A800F5680E /* sequences_v2.cpp */,
- DF8422000E7BA6A800F5680E /* sound.cpp */,
- DF8422010E7BA6A800F5680E /* sound.h */,
- DF8422020E7BA6A800F5680E /* sound_adlib.cpp */,
- DF6BF4E210529E260069811F /* sound_adlib.h */,
- DF6BF4E310529E260069811F /* sound_amiga.cpp */,
- DF8422030E7BA6A800F5680E /* sound_digital.cpp */,
- DF8422040E7BA6A800F5680E /* sound_lok.cpp */,
- DF6118B40FE3AA280042AD3F /* sound_lol.cpp */,
- DF2FFC330F48628A0006E566 /* sound_midi.cpp */,
- DF6118B50FE3AA280042AD3F /* sound_pcspk.cpp */,
- DF8422050E7BA6A800F5680E /* sound_towns.cpp */,
- DF8422070E7BA6A800F5680E /* sprites.cpp */,
- DF8422080E7BA6A800F5680E /* sprites.h */,
- DF89C2870F62D55C00D756B6 /* sprites_lol.cpp */,
- DF8422090E7BA6A800F5680E /* staticres.cpp */,
- DF84220A0E7BA6A800F5680E /* text.cpp */,
- DF84220B0E7BA6A800F5680E /* text.h */,
- DF84220C0E7BA6A800F5680E /* text_hof.cpp */,
- DF84220D0E7BA6A800F5680E /* text_hof.h */,
- DF84220E0E7BA6A800F5680E /* text_lok.cpp */,
- DF6118B60FE3AA280042AD3F /* text_lol.cpp */,
- DF6118B70FE3AA280042AD3F /* text_lol.h */,
- DF84220F0E7BA6A800F5680E /* text_mr.cpp */,
- DF8422100E7BA6A800F5680E /* text_mr.h */,
- DF8422140E7BA6A800F5680E /* timer.cpp */,
- DF8422150E7BA6A800F5680E /* timer.h */,
- DF8422160E7BA6A800F5680E /* timer_hof.cpp */,
- DF8422170E7BA6A800F5680E /* timer_lok.cpp */,
- DF573CBD0F5A85E100961A72 /* timer_lol.cpp */,
- DF8422180E7BA6A800F5680E /* timer_mr.cpp */,
- DF2FFC360F48628A0006E566 /* util.cpp */,
- DF2FFC370F48628A0006E566 /* util.h */,
- DF84221C0E7BA6A800F5680E /* vqa.cpp */,
- DF84221D0E7BA6A800F5680E /* vqa.h */,
- DF84221E0E7BA6A800F5680E /* wsamovie.cpp */,
- DF84221F0E7BA6A800F5680E /* wsamovie.h */,
- );
- path = kyra;
- sourceTree = "<group>";
- };
- DF8422200E7BA6A800F5680E /* lure */ = {
- isa = PBXGroup;
- children = (
- DF8422210E7BA6A800F5680E /* animseq.cpp */,
- DF8422220E7BA6A800F5680E /* animseq.h */,
- DF8422230E7BA6A800F5680E /* debugger.cpp */,
- DF8422240E7BA6A800F5680E /* debugger.h */,
- DF8422250E7BA6A800F5680E /* decode.cpp */,
- DF8422260E7BA6A800F5680E /* decode.h */,
- DF8422270E7BA6A800F5680E /* detection.cpp */,
- DF8422280E7BA6A800F5680E /* disk.cpp */,
- DF8422290E7BA6A800F5680E /* disk.h */,
- DF84222A0E7BA6A800F5680E /* events.cpp */,
- DF84222B0E7BA6A800F5680E /* events.h */,
- DF84222C0E7BA6A800F5680E /* fights.cpp */,
- DF84222D0E7BA6A800F5680E /* fights.h */,
- DF84222E0E7BA6A800F5680E /* game.cpp */,
- DF84222F0E7BA6A800F5680E /* game.h */,
- DF8422300E7BA6A800F5680E /* hotspots.cpp */,
- DF8422310E7BA6A800F5680E /* hotspots.h */,
- DF8422320E7BA6A800F5680E /* intro.cpp */,
- DF8422330E7BA6A800F5680E /* intro.h */,
- DF8422340E7BA6A800F5680E /* lure.cpp */,
- DF8422350E7BA6A800F5680E /* lure.h */,
- DF8422360E7BA6A800F5680E /* luredefs.h */,
- DF8422370E7BA6A800F5680E /* memory.cpp */,
- DF8422380E7BA6A800F5680E /* memory.h */,
- DF8422390E7BA6A800F5680E /* menu.cpp */,
- DF84223A0E7BA6A800F5680E /* menu.h */,
- DF84223C0E7BA6A800F5680E /* palette.cpp */,
- DF84223D0E7BA6A800F5680E /* palette.h */,
- DF84223E0E7BA6A800F5680E /* res.cpp */,
- DF84223F0E7BA6A800F5680E /* res.h */,
- DF8422400E7BA6A800F5680E /* res_struct.cpp */,
- DF8422410E7BA6A800F5680E /* res_struct.h */,
- DF8422420E7BA6A800F5680E /* room.cpp */,
- DF8422430E7BA6A800F5680E /* room.h */,
- DF8422440E7BA6A800F5680E /* screen.cpp */,
- DF8422450E7BA6A800F5680E /* screen.h */,
- DF8422460E7BA6A800F5680E /* scripts.cpp */,
- DF8422470E7BA6A800F5680E /* scripts.h */,
- DF8422480E7BA6A800F5680E /* sound.cpp */,
- DF8422490E7BA6A800F5680E /* sound.h */,
- DF84224A0E7BA6A800F5680E /* strings.cpp */,
- DF84224B0E7BA6A800F5680E /* strings.h */,
- DF84224C0E7BA6A800F5680E /* surface.cpp */,
- DF84224D0E7BA6A800F5680E /* surface.h */,
- );
- path = lure;
- sourceTree = "<group>";
- };
- DF84224E0E7BA6A800F5680E /* m4 */ = {
- isa = PBXGroup;
- children = (
- DF84226E0E7BA6A800F5680E /* actor.cpp */,
- DF84226F0E7BA6A800F5680E /* actor.h */,
- DF8422710E7BA6A800F5680E /* animation.cpp */,
- DF8422720E7BA6A800F5680E /* animation.h */,
- DF8422740E7BA6A800F5680E /* assets.cpp */,
- DF8422750E7BA6A800F5680E /* assets.h */,
- DF8422770E7BA6A900F5680E /* burger_data.h */,
- DF8422780E7BA6A900F5680E /* compression.cpp */,
- DF8422790E7BA6A900F5680E /* compression.h */,
- DF84227B0E7BA6A900F5680E /* console.cpp */,
- DF84227C0E7BA6A900F5680E /* console.h */,
- DF84227E0E7BA6A900F5680E /* converse.cpp */,
- DF84227F0E7BA6A900F5680E /* converse.h */,
- DF8422810E7BA6A900F5680E /* detection.cpp */,
- DF2EC3F610E64C0C00765801 /* dialogs.cpp */,
- DF2EC3F710E64C0C00765801 /* dialogs.h */,
- DF8422830E7BA6A900F5680E /* events.cpp */,
- DF8422840E7BA6A900F5680E /* events.h */,
- DF8422860E7BA6A900F5680E /* font.cpp */,
- DF8422870E7BA6A900F5680E /* font.h */,
- DF8422890E7BA6A900F5680E /* globals.cpp */,
- DF84228A0E7BA6A900F5680E /* globals.h */,
- DF84228C0E7BA6A900F5680E /* graphics.cpp */,
- DF84228D0E7BA6A900F5680E /* graphics.h */,
- DF84228F0E7BA6A900F5680E /* gui.cpp */,
- DF8422900E7BA6A900F5680E /* gui.h */,
- DF8422920E7BA6A900F5680E /* hotspot.cpp */,
- DF8422930E7BA6A900F5680E /* hotspot.h */,
- DF8422960E7BA6A900F5680E /* m4.cpp */,
- DF8422970E7BA6A900F5680E /* m4.h */,
- DF8422990E7BA6A900F5680E /* m4_menus.cpp */,
- DF84229A0E7BA6A900F5680E /* m4_menus.h */,
- 8CB5A9B71253FD6800CB6BC7 /* m4_scene.cpp */,
- 8CB5A9B81253FD6800CB6BC7 /* m4_scene.h */,
- DF84229C0E7BA6A900F5680E /* m4_views.cpp */,
- DF84229D0E7BA6A900F5680E /* m4_views.h */,
- DF84229F0E7BA6A900F5680E /* mads_anim.cpp */,
- DF8422A00E7BA6A900F5680E /* mads_anim.h */,
- 8CB5A9B91253FD6800CB6BC7 /* mads_logic.cpp */,
- 8CB5A9BA1253FD6800CB6BC7 /* mads_logic.h */,
- DF8422A20E7BA6A900F5680E /* mads_menus.cpp */,
- DF8422A30E7BA6A900F5680E /* mads_menus.h */,
- 8CB5A9BB1253FD6800CB6BC7 /* mads_player.cpp */,
- 8CB5A9BC1253FD6800CB6BC7 /* mads_player.h */,
- 8CB5A9BD1253FD6800CB6BC7 /* mads_scene.cpp */,
- 8CB5A9BE1253FD6800CB6BC7 /* mads_scene.h */,
- 8CB5A9BF1253FD6900CB6BC7 /* mads_views.cpp */,
- 8CB5A9C01253FD6900CB6BC7 /* mads_views.h */,
- DF8422A50E7BA6A900F5680E /* midi.cpp */,
- DF8422A60E7BA6A900F5680E /* midi.h */,
- DF8422A90E7BA6A900F5680E /* rails.cpp */,
- DF8422AA0E7BA6A900F5680E /* rails.h */,
- DF8422AC0E7BA6A900F5680E /* resource.cpp */,
- DF8422AD0E7BA6A900F5680E /* resource.h */,
- DF8422AF0E7BA6A900F5680E /* saveload.cpp */,
- DF8422B00E7BA6A900F5680E /* saveload.h */,
- DF8422B20E7BA6A900F5680E /* scene.cpp */,
- DF8422B30E7BA6A900F5680E /* scene.h */,
- DF8422B50E7BA6A900F5680E /* script.cpp */,
- DF8422B60E7BA6A900F5680E /* script.h */,
- DF8422B80E7BA6A900F5680E /* scripttab.h */,
- DF8422B90E7BA6A900F5680E /* sound.cpp */,
- DF8422BA0E7BA6A900F5680E /* sound.h */,
- DF8422BC0E7BA6A900F5680E /* sprite.cpp */,
- DF8422BD0E7BA6A900F5680E /* sprite.h */,
- DF90EAAB10B0236F00C8F93F /* staticres.cpp */,
- DF90EAAC10B0236F00C8F93F /* staticres.h */,
- DF8422BF0E7BA6A900F5680E /* viewmgr.cpp */,
- DF8422C00E7BA6A900F5680E /* viewmgr.h */,
- DF8422C20E7BA6A900F5680E /* woodscript.cpp */,
- DF8422C30E7BA6A900F5680E /* woodscript.h */,
- DF8422C50E7BA6A900F5680E /* ws_machine.cpp */,
- DF8422C70E7BA6A900F5680E /* ws_sequence.cpp */,
- );
- path = m4;
- sourceTree = "<group>";
- };
- DF8422C90E7BA6A900F5680E /* made */ = {
- isa = PBXGroup;
- children = (
- DF46B8501381F3B400D08723 /* console.cpp */,
- DF46B8511381F3B400D08723 /* console.h */,
- DF8422CA0E7BA6A900F5680E /* database.cpp */,
- DF8422CB0E7BA6A900F5680E /* database.h */,
- DF8422CC0E7BA6A900F5680E /* detection.cpp */,
- DF8422CD0E7BA6A900F5680E /* graphics.cpp */,
- DF8422CE0E7BA6A900F5680E /* graphics.h */,
- DF8422CF0E7BA6A900F5680E /* made.cpp */,
- DF8422D00E7BA6A900F5680E /* made.h */,
- DF8422D20E7BA6A900F5680E /* music.cpp */,
- DF8422D30E7BA6A900F5680E /* music.h */,
- DF8422D40E7BA6A900F5680E /* pmvplayer.cpp */,
- DF8422D50E7BA6A900F5680E /* pmvplayer.h */,
- DF8422D60E7BA6A900F5680E /* redreader.cpp */,
- DF8422D70E7BA6A900F5680E /* redreader.h */,
- DF8422D80E7BA6A900F5680E /* resource.cpp */,
- DF8422D90E7BA6A900F5680E /* resource.h */,
- DF8422DA0E7BA6A900F5680E /* screen.cpp */,
- DF8422DB0E7BA6A900F5680E /* screen.h */,
- DF8422DC0E7BA6A900F5680E /* screenfx.cpp */,
- DF8422DD0E7BA6A900F5680E /* screenfx.h */,
- DF8422DE0E7BA6A900F5680E /* script.cpp */,
- DF8422DF0E7BA6A900F5680E /* script.h */,
- DF8422E00E7BA6A900F5680E /* scriptfuncs.cpp */,
- DF8422E10E7BA6A900F5680E /* scriptfuncs.h */,
- DF8422E20E7BA6A900F5680E /* sound.cpp */,
- DF8422E30E7BA6A900F5680E /* sound.h */,
- );
- path = made;
- sourceTree = "<group>";
- };
- DF8422E60E7BA6A900F5680E /* parallaction */ = {
- isa = PBXGroup;
- children = (
- DF8422E70E7BA6A900F5680E /* balloons.cpp */,
- DF8422E80E7BA6A900F5680E /* callables_br.cpp */,
- DF8422E90E7BA6A900F5680E /* callables_ns.cpp */,
- DF8422EA0E7BA6A900F5680E /* debug.cpp */,
- DF8422EB0E7BA6A900F5680E /* debug.h */,
- DF8422EC0E7BA6A900F5680E /* detection.cpp */,
- DF8422ED0E7BA6A900F5680E /* dialogue.cpp */,
- DF6118540FE3A8990042AD3F /* disk.cpp */,
- DF8422EE0E7BA6A900F5680E /* disk.h */,
- DF8422EF0E7BA6A900F5680E /* disk_br.cpp */,
- DF8422F00E7BA6A900F5680E /* disk_ns.cpp */,
- DF573CBA0F5A85B300961A72 /* exec.cpp */,
- DF8422F10E7BA6A900F5680E /* exec.h */,
- DF8422F20E7BA6A900F5680E /* exec_br.cpp */,
- DF8422F30E7BA6A900F5680E /* exec_ns.cpp */,
- DF8422F40E7BA6A900F5680E /* font.cpp */,
- DF8422F50E7BA6A900F5680E /* gfxbase.cpp */,
- DF8422F60E7BA6A900F5680E /* graphics.cpp */,
- DF8422F70E7BA6A900F5680E /* graphics.h */,
- DF8422F80E7BA6A900F5680E /* gui.cpp */,
- DF8422F90E7BA6A900F5680E /* gui.h */,
- DF8422FA0E7BA6A900F5680E /* gui_br.cpp */,
- DF8422FB0E7BA6A900F5680E /* gui_ns.cpp */,
- DF8422FC0E7BA6A900F5680E /* input.cpp */,
- DF8422FD0E7BA6A900F5680E /* input.h */,
- DF8422FE0E7BA6A900F5680E /* inventory.cpp */,
- DF8422FF0E7BA6A900F5680E /* inventory.h */,
- DF8423010E7BA6A900F5680E /* objects.cpp */,
- DF8423020E7BA6A900F5680E /* objects.h */,
- DF8423030E7BA6A900F5680E /* parallaction.cpp */,
- DF8423040E7BA6A900F5680E /* parallaction.h */,
- DF8423050E7BA6A900F5680E /* parallaction_br.cpp */,
- DF8423060E7BA6A900F5680E /* parallaction_ns.cpp */,
- DF8423070E7BA6A900F5680E /* parser.cpp */,
- DF8423080E7BA6A900F5680E /* parser.h */,
- DF8423090E7BA6A900F5680E /* parser_br.cpp */,
- DF84230A0E7BA6A900F5680E /* parser_ns.cpp */,
- DF84230B0E7BA6A900F5680E /* saveload.cpp */,
- DF84230C0E7BA6A900F5680E /* saveload.h */,
- DF84230E0E7BA6A900F5680E /* sound.h */,
- DF5CEB260F75535000DEA624 /* sound_br.cpp */,
- DF5CEB270F75535000DEA624 /* sound_ns.cpp */,
- DF84230F0E7BA6A900F5680E /* staticres.cpp */,
- DF8423100E7BA6A900F5680E /* walk.cpp */,
- DF8423110E7BA6A900F5680E /* walk.h */,
- );
- path = parallaction;
- sourceTree = "<group>";
- };
- DF8423120E7BA6A900F5680E /* queen */ = {
- isa = PBXGroup;
- children = (
- DF8423130E7BA6A900F5680E /* bankman.cpp */,
- DF8423140E7BA6A900F5680E /* bankman.h */,
- DF8423150E7BA6A900F5680E /* command.cpp */,
- DF8423160E7BA6A900F5680E /* command.h */,
- DF8423170E7BA6A900F5680E /* credits.cpp */,
- DF8423180E7BA6A900F5680E /* credits.h */,
- DF8423190E7BA6A900F5680E /* cutaway.cpp */,
- DF84231A0E7BA6A900F5680E /* cutaway.h */,
- DF84231B0E7BA6A900F5680E /* debug.cpp */,
- DF84231C0E7BA6A900F5680E /* debug.h */,
- DF84231D0E7BA6A900F5680E /* defs.h */,
- DF84231E0E7BA6A900F5680E /* display.cpp */,
- DF84231F0E7BA6A900F5680E /* display.h */,
- DF8423200E7BA6A900F5680E /* graphics.cpp */,
- DF8423210E7BA6A900F5680E /* graphics.h */,
- DF8423220E7BA6A900F5680E /* grid.cpp */,
- DF8423230E7BA6A900F5680E /* grid.h */,
- DF8423240E7BA6A900F5680E /* input.cpp */,
- DF8423250E7BA6A900F5680E /* input.h */,
- DF8423260E7BA6A900F5680E /* journal.cpp */,
- DF8423270E7BA6A900F5680E /* journal.h */,
- DF8423280E7BA6A900F5680E /* logic.cpp */,
- DF8423290E7BA6A900F5680E /* logic.h */,
- DF84232A0E7BA6A900F5680E /* midiadlib.cpp */,
- DF84232C0E7BA6A900F5680E /* music.cpp */,
- DF84232D0E7BA6A900F5680E /* music.h */,
- DF84232E0E7BA6A900F5680E /* musicdata.cpp */,
- DF84232F0E7BA6A900F5680E /* queen.cpp */,
- DF8423300E7BA6A900F5680E /* queen.h */,
- DF8423310E7BA6A900F5680E /* resource.cpp */,
- DF8423320E7BA6A900F5680E /* resource.h */,
- DF8423330E7BA6A900F5680E /* restables.cpp */,
- DF8423340E7BA6A900F5680E /* sound.cpp */,
- DF8423350E7BA6A900F5680E /* sound.h */,
- DF8423360E7BA6A900F5680E /* state.cpp */,
- DF8423370E7BA6A900F5680E /* state.h */,
- DF8423380E7BA6A900F5680E /* structs.h */,
- DF8423390E7BA6A900F5680E /* talk.cpp */,
- DF84233A0E7BA6A900F5680E /* talk.h */,
- DF84233B0E7BA6A900F5680E /* walk.cpp */,
- DF84233C0E7BA6A900F5680E /* walk.h */,
- );
- path = queen;
- sourceTree = "<group>";
- };
- DF84233E0E7BA6AA00F5680E /* saga */ = {
- isa = PBXGroup;
- children = (
- DF84233F0E7BA6AA00F5680E /* actor.cpp */,
- DF8423400E7BA6AA00F5680E /* actor.h */,
- DF8423410E7BA6AA00F5680E /* actor_path.cpp */,
- DF8423420E7BA6AA00F5680E /* actor_walk.cpp */,
- DF8423430E7BA6AA00F5680E /* animation.cpp */,
- DF8423440E7BA6AA00F5680E /* animation.h */,
- DF8423450E7BA6AA00F5680E /* console.cpp */,
- DF8423460E7BA6AA00F5680E /* console.h */,
- DF8423470E7BA6AA00F5680E /* detection.cpp */,
- DF8423480E7BA6AA00F5680E /* detection_tables.h */,
- DF8423490E7BA6AA00F5680E /* displayinfo.h */,
- DF84234A0E7BA6AA00F5680E /* events.cpp */,
- DF84234B0E7BA6AA00F5680E /* events.h */,
- DF84234C0E7BA6AA00F5680E /* font.cpp */,
- DF84234D0E7BA6AA00F5680E /* font.h */,
- DF84234E0E7BA6AA00F5680E /* font_map.cpp */,
- DF84234F0E7BA6AA00F5680E /* gfx.cpp */,
- DF8423500E7BA6AA00F5680E /* gfx.h */,
- DF8423520E7BA6AA00F5680E /* image.cpp */,
- DF8423530E7BA6AA00F5680E /* input.cpp */,
- DF8423540E7BA6AA00F5680E /* interface.cpp */,
- DF8423550E7BA6AA00F5680E /* interface.h */,
- DF8423560E7BA6AA00F5680E /* introproc_ihnm.cpp */,
- DF8423570E7BA6AA00F5680E /* introproc_ite.cpp */,
- DF8423580E7BA6AA00F5680E /* isomap.cpp */,
- DF8423590E7BA6AA00F5680E /* isomap.h */,
- DF84235B0E7BA6AA00F5680E /* itedata.cpp */,
- DF84235C0E7BA6AA00F5680E /* itedata.h */,
- DF84235F0E7BA6AA00F5680E /* music.cpp */,
- DF8423600E7BA6AA00F5680E /* music.h */,
- DF8423610E7BA6AA00F5680E /* objectmap.cpp */,
- DF8423620E7BA6AA00F5680E /* objectmap.h */,
- DF8423630E7BA6AA00F5680E /* palanim.cpp */,
- DF8423640E7BA6AA00F5680E /* palanim.h */,
- DF8423650E7BA6AA00F5680E /* puzzle.cpp */,
- DF8423660E7BA6AA00F5680E /* puzzle.h */,
- DF8423670E7BA6AA00F5680E /* render.cpp */,
- DF8423680E7BA6AA00F5680E /* render.h */,
- DF2FFC600F48672D0006E566 /* resource.cpp */,
- DF2FFC610F48672D0006E566 /* resource.h */,
- DF2FFC620F48672D0006E566 /* resource_hrs.cpp */,
- DF2FFC630F48672D0006E566 /* resource_res.cpp */,
- DF2FFC640F48672D0006E566 /* resource_rsc.cpp */,
- DF84236B0E7BA6AA00F5680E /* saga.cpp */,
- DF84236C0E7BA6AA00F5680E /* saga.h */,
- DF84236D0E7BA6AA00F5680E /* saveload.cpp */,
- DF84236E0E7BA6AA00F5680E /* scene.cpp */,
- DF84236F0E7BA6AA00F5680E /* scene.h */,
- DF8423700E7BA6AA00F5680E /* script.cpp */,
- DF8423710E7BA6AA00F5680E /* script.h */,
- DF8423720E7BA6AA00F5680E /* sfuncs.cpp */,
- DF2FFC650F48672D0006E566 /* sfuncs_ihnm.cpp */,
- DF8423730E7BA6AA00F5680E /* sndres.cpp */,
- DF8423740E7BA6AA00F5680E /* sndres.h */,
- DF8423750E7BA6AA00F5680E /* sound.cpp */,
- DF8423760E7BA6AA00F5680E /* sound.h */,
- DF8423770E7BA6AA00F5680E /* sprite.cpp */,
- DF8423780E7BA6AA00F5680E /* sprite.h */,
- DF8423790E7BA6AA00F5680E /* sthread.cpp */,
- );
- path = saga;
- sourceTree = "<group>";
- };
- DF84237B0E7BA6AA00F5680E /* scumm */ = {
- isa = PBXGroup;
- children = (
- DF46B7501381E46700D08723 /* actor_he.h */,
- DF46B7511381E46700D08723 /* player_v2base.cpp */,
- DF46B7521381E46700D08723 /* player_v2base.h */,
- DF46B7531381E46700D08723 /* player_v2cms.h */,
- DF84237C0E7BA6AA00F5680E /* actor.cpp */,
- DF84237D0E7BA6AA00F5680E /* actor.h */,
- DF84237E0E7BA6AA00F5680E /* akos.cpp */,
- DF84237F0E7BA6AA00F5680E /* akos.h */,
- DF8423800E7BA6AA00F5680E /* base-costume.cpp */,
- DF8423810E7BA6AA00F5680E /* base-costume.h */,
- DF8423820E7BA6AA00F5680E /* bomp.cpp */,
- DF8423830E7BA6AA00F5680E /* bomp.h */,
- DF8423840E7BA6AA00F5680E /* boxes.cpp */,
- DF8423850E7BA6AA00F5680E /* boxes.h */,
- DF8423860E7BA6AA00F5680E /* camera.cpp */,
- DF8423870E7BA6AA00F5680E /* charset-fontdata.cpp */,
- DF8423880E7BA6AA00F5680E /* charset.cpp */,
- DF8423890E7BA6AA00F5680E /* charset.h */,
- DF84238A0E7BA6AA00F5680E /* costume.cpp */,
- DF84238B0E7BA6AA00F5680E /* costume.h */,
- DF84238C0E7BA6AA00F5680E /* cursor.cpp */,
- DF84238D0E7BA6AA00F5680E /* debugger.cpp */,
- DF84238E0E7BA6AA00F5680E /* debugger.h */,
- DF84238F0E7BA6AA00F5680E /* detection.cpp */,
- DF8423900E7BA6AA00F5680E /* detection.h */,
- DF8423910E7BA6AA00F5680E /* detection_tables.h */,
- DF8423920E7BA6AA00F5680E /* dialogs.cpp */,
- DF8423930E7BA6AA00F5680E /* dialogs.h */,
- DF8423940E7BA6AA00F5680E /* file.cpp */,
- DF8423950E7BA6AA00F5680E /* file.h */,
- DF8423960E7BA6AA00F5680E /* file_nes.cpp */,
- DF8423970E7BA6AA00F5680E /* file_nes.h */,
- DF8423980E7BA6AA00F5680E /* gfx.cpp */,
- DF8423990E7BA6AA00F5680E /* gfx.h */,
- 8CD80C90126271BD001C6C87 /* gfx_towns.cpp */,
- DF84239B0E7BA6AA00F5680E /* he */,
- DF8423B50E7BA6AA00F5680E /* help.cpp */,
- DF8423B60E7BA6AA00F5680E /* help.h */,
- DF8423B70E7BA6AA00F5680E /* imuse */,
- DF8423C20E7BA6AA00F5680E /* imuse_digi */,
- DF8423D00E7BA6AA00F5680E /* input.cpp */,
- DF8423D10E7BA6AA00F5680E /* insane */,
- DF8423DA0E7BA6AA00F5680E /* midiparser_ro.cpp */,
- DF8423DC0E7BA6AA00F5680E /* music.h */,
- DF8423DD0E7BA6AA00F5680E /* nut_renderer.cpp */,
- DF8423DE0E7BA6AA00F5680E /* nut_renderer.h */,
- DF8423DF0E7BA6AA00F5680E /* object.cpp */,
- DF8423E00E7BA6AA00F5680E /* object.h */,
- DF8423E10E7BA6AA00F5680E /* palette.cpp */,
- DF8423E20E7BA6AA00F5680E /* player_mod.cpp */,
- DF8423E30E7BA6AA00F5680E /* player_mod.h */,
- DF8423E40E7BA6AA00F5680E /* player_nes.cpp */,
- DF8423E50E7BA6AA00F5680E /* player_nes.h */,
- DF2EC4FD10E64D7C00765801 /* player_pce.cpp */,
- DF2EC4FE10E64D7C00765801 /* player_pce.h */,
- DF2EC4FF10E64D7C00765801 /* player_sid.cpp */,
- DF2EC50010E64D7C00765801 /* player_sid.h */,
- DF895C01124C24680077F6E8 /* player_towns.cpp */,
- DF895C02124C24680077F6E8 /* player_towns.h */,
- DF8423E60E7BA6AA00F5680E /* player_v1.cpp */,
- DF8423E70E7BA6AA00F5680E /* player_v1.h */,
- DF8423E80E7BA6AA00F5680E /* player_v2.cpp */,
- DF8423E90E7BA6AA00F5680E /* player_v2.h */,
- DF8423EA0E7BA6AA00F5680E /* player_v2a.cpp */,
- DF8423EB0E7BA6AA00F5680E /* player_v2a.h */,
- DF6118C60FE3AABD0042AD3F /* player_v2cms.cpp */,
- DF8423EC0E7BA6AA00F5680E /* player_v3a.cpp */,
- DF8423ED0E7BA6AA00F5680E /* player_v3a.h */,
- DF6BF4F110529EE40069811F /* player_v4a.cpp */,
- DF6BF4F210529EE40069811F /* player_v4a.h */,
- DF8423EF0E7BA6AA00F5680E /* resource.cpp */,
- DF8423F00E7BA6AA00F5680E /* resource.h */,
- DF8423F10E7BA6AA00F5680E /* resource_v2.cpp */,
- DF8423F20E7BA6AA00F5680E /* resource_v3.cpp */,
- DF8423F30E7BA6AA00F5680E /* resource_v4.cpp */,
- DF8423F40E7BA6AA00F5680E /* room.cpp */,
- DF8423F50E7BA6AA00F5680E /* saveload.cpp */,
- DF8423F60E7BA6AA00F5680E /* saveload.h */,
- DF8423F70E7BA6AA00F5680E /* script.cpp */,
- DF8423F80E7BA6AA00F5680E /* script.h */,
- DF8423F90E7BA6AA00F5680E /* script_v0.cpp */,
- DF8423FA0E7BA6AA00F5680E /* script_v2.cpp */,
- DF09CC260FAC4EAB00A5AFD7 /* script_v3.cpp */,
- DF09CC270FAC4EAB00A5AFD7 /* script_v4.cpp */,
- DF8423FB0E7BA6AA00F5680E /* script_v5.cpp */,
- DF8423FC0E7BA6AA00F5680E /* script_v6.cpp */,
- DF8423FD0E7BA6AA00F5680E /* script_v8.cpp */,
- DF8423FE0E7BA6AA00F5680E /* scumm-md5.h */,
- DF8423FF0E7BA6AA00F5680E /* scumm.cpp */,
- DF8424000E7BA6AA00F5680E /* scumm.h */,
- DF09CC1D0FAC4E6200A5AFD7 /* scumm_v0.h */,
- DF09CC1E0FAC4E6200A5AFD7 /* scumm_v2.h */,
- DF09CC1F0FAC4E6200A5AFD7 /* scumm_v3.h */,
- DF09CC200FAC4E6200A5AFD7 /* scumm_v4.h */,
- DF09CC210FAC4E6200A5AFD7 /* scumm_v5.h */,
- DF09CC220FAC4E6200A5AFD7 /* scumm_v6.h */,
- DF09CC230FAC4E6200A5AFD7 /* scumm_v7.h */,
- DF09CC240FAC4E6200A5AFD7 /* scumm_v8.h */,
- DF8424010E7BA6AA00F5680E /* smush */,
- DF8424150E7BA6AB00F5680E /* sound.cpp */,
- DF8424160E7BA6AB00F5680E /* sound.h */,
- DF8424170E7BA6AB00F5680E /* string.cpp */,
- DF8424190E7BA6AB00F5680E /* usage_bits.cpp */,
- DF84241A0E7BA6AB00F5680E /* usage_bits.h */,
- DF84241B0E7BA6AB00F5680E /* util.cpp */,
- DF84241C0E7BA6AB00F5680E /* util.h */,
- DF84241D0E7BA6AB00F5680E /* vars.cpp */,
- DF84241E0E7BA6AB00F5680E /* verbs.cpp */,
- DF84241F0E7BA6AB00F5680E /* verbs.h */,
- );
- path = scumm;
- sourceTree = "<group>";
- };
- DF84239B0E7BA6AA00F5680E /* he */ = {
- isa = PBXGroup;
- children = (
- DF84239C0E7BA6AA00F5680E /* animation_he.cpp */,
- DF84239D0E7BA6AA00F5680E /* animation_he.h */,
- DF84239E0E7BA6AA00F5680E /* cup_player_he.cpp */,
- DF84239F0E7BA6AA00F5680E /* cup_player_he.h */,
- DF8423A00E7BA6AA00F5680E /* floodfill_he.cpp */,
- DF8423A10E7BA6AA00F5680E /* floodfill_he.h */,
- DF8423A20E7BA6AA00F5680E /* intern_he.h */,
- DF8423A30E7BA6AA00F5680E /* logic_he.cpp */,
- DF8423A40E7BA6AA00F5680E /* logic_he.h */,
- DF8423A50E7BA6AA00F5680E /* palette_he.cpp */,
- DF8423A60E7BA6AA00F5680E /* resource_he.cpp */,
- DF8423A70E7BA6AA00F5680E /* resource_he.h */,
- DF8423A80E7BA6AA00F5680E /* script_v100he.cpp */,
- DF8423A90E7BA6AA00F5680E /* script_v60he.cpp */,
- DF8423AA0E7BA6AA00F5680E /* script_v70he.cpp */,
- DF8423AB0E7BA6AA00F5680E /* script_v71he.cpp */,
- DF8423AC0E7BA6AA00F5680E /* script_v72he.cpp */,
- DF8423AD0E7BA6AA00F5680E /* script_v80he.cpp */,
- DF8423AE0E7BA6AA00F5680E /* script_v90he.cpp */,
- DF8423AF0E7BA6AA00F5680E /* sound_he.cpp */,
- DF8423B00E7BA6AA00F5680E /* sound_he.h */,
- DF8423B10E7BA6AA00F5680E /* sprite_he.cpp */,
- DF8423B20E7BA6AA00F5680E /* sprite_he.h */,
- DF8423B30E7BA6AA00F5680E /* wiz_he.cpp */,
- DF8423B40E7BA6AA00F5680E /* wiz_he.h */,
- );
- path = he;
- sourceTree = "<group>";
- };
- DF8423B70E7BA6AA00F5680E /* imuse */ = {
- isa = PBXGroup;
- children = (
- DF8423B80E7BA6AA00F5680E /* imuse.cpp */,
- DF8423B90E7BA6AA00F5680E /* imuse.h */,
- DF8423BA0E7BA6AA00F5680E /* imuse_internal.h */,
- DF8423BB0E7BA6AA00F5680E /* imuse_part.cpp */,
- DF8423BC0E7BA6AA00F5680E /* imuse_player.cpp */,
- DF8423BD0E7BA6AA00F5680E /* instrument.cpp */,
- DF8423BE0E7BA6AA00F5680E /* instrument.h */,
- DF8423BF0E7BA6AA00F5680E /* sysex.h */,
- DF8423C00E7BA6AA00F5680E /* sysex_samnmax.cpp */,
- DF8423C10E7BA6AA00F5680E /* sysex_scumm.cpp */,
- );
- path = imuse;
- sourceTree = "<group>";
- };
- DF8423C20E7BA6AA00F5680E /* imuse_digi */ = {
- isa = PBXGroup;
- children = (
- DF8423C30E7BA6AA00F5680E /* dimuse.cpp */,
- DF8423C40E7BA6AA00F5680E /* dimuse.h */,
- DF8423C50E7BA6AA00F5680E /* dimuse_bndmgr.cpp */,
- DF8423C60E7BA6AA00F5680E /* dimuse_bndmgr.h */,
- DF8423C70E7BA6AA00F5680E /* dimuse_codecs.cpp */,
- DF8423C80E7BA6AA00F5680E /* dimuse_music.cpp */,
- DF8423C90E7BA6AA00F5680E /* dimuse_script.cpp */,
- DF8423CA0E7BA6AA00F5680E /* dimuse_sndmgr.cpp */,
- DF8423CB0E7BA6AA00F5680E /* dimuse_sndmgr.h */,
- DF8423CC0E7BA6AA00F5680E /* dimuse_tables.cpp */,
- DF8423CD0E7BA6AA00F5680E /* dimuse_tables.h */,
- DF8423CE0E7BA6AA00F5680E /* dimuse_track.cpp */,
- DF8423CF0E7BA6AA00F5680E /* dimuse_track.h */,
- );
- path = imuse_digi;
- sourceTree = "<group>";
- };
- DF8423D10E7BA6AA00F5680E /* insane */ = {
- isa = PBXGroup;
- children = (
- DF8423D20E7BA6AA00F5680E /* insane.cpp */,
- DF8423D30E7BA6AA00F5680E /* insane.h */,
- DF8423D40E7BA6AA00F5680E /* insane_ben.cpp */,
- DF8423D50E7BA6AA00F5680E /* insane_enemy.cpp */,
- DF8423D60E7BA6AA00F5680E /* insane_iact.cpp */,
- DF8423D70E7BA6AA00F5680E /* insane_scenes.cpp */,
- );
- path = insane;
- sourceTree = "<group>";
- };
- DF8424010E7BA6AA00F5680E /* smush */ = {
- isa = PBXGroup;
- children = (
- DF8424020E7BA6AA00F5680E /* channel.cpp */,
- DF8424030E7BA6AA00F5680E /* channel.h */,
- DF8424060E7BA6AA00F5680E /* codec1.cpp */,
- DF8424070E7BA6AA00F5680E /* codec37.cpp */,
- DF8424080E7BA6AA00F5680E /* codec37.h */,
- DF8424090E7BA6AA00F5680E /* codec47.cpp */,
- DF84240A0E7BA6AA00F5680E /* codec47.h */,
- DF84240D0E7BA6AA00F5680E /* imuse_channel.cpp */,
- DF84240E0E7BA6AA00F5680E /* saud_channel.cpp */,
- DF84240F0E7BA6AA00F5680E /* smush_font.cpp */,
- DF8424100E7BA6AA00F5680E /* smush_font.h */,
- DF8424110E7BA6AA00F5680E /* smush_mixer.cpp */,
- DF8424120E7BA6AA00F5680E /* smush_mixer.h */,
- DF8424130E7BA6AA00F5680E /* smush_player.cpp */,
- DF8424140E7BA6AB00F5680E /* smush_player.h */,
- );
- path = smush;
- sourceTree = "<group>";
- };
- DF8424200E7BA6AB00F5680E /* sky */ = {
- isa = PBXGroup;
- children = (
- DF8424210E7BA6AB00F5680E /* autoroute.cpp */,
- DF8424220E7BA6AB00F5680E /* autoroute.h */,
- DF8424230E7BA6AB00F5680E /* compact.cpp */,
- DF8424240E7BA6AB00F5680E /* compact.h */,
- DF8424250E7BA6AB00F5680E /* control.cpp */,
- DF8424260E7BA6AB00F5680E /* control.h */,
- DF8424270E7BA6AB00F5680E /* debug.cpp */,
- DF8424280E7BA6AB00F5680E /* debug.h */,
- DFAAAFF80F0112C1003E9390 /* detection.cpp */,
- DF8424290E7BA6AB00F5680E /* disk.cpp */,
- DF84242A0E7BA6AB00F5680E /* disk.h */,
- DF84242B0E7BA6AB00F5680E /* grid.cpp */,
- DF84242C0E7BA6AB00F5680E /* grid.h */,
- DF84242D0E7BA6AB00F5680E /* hufftext.cpp */,
- DF84242E0E7BA6AB00F5680E /* intro.cpp */,
- DF84242F0E7BA6AB00F5680E /* intro.h */,
- DF8424300E7BA6AB00F5680E /* logic.cpp */,
- DF8424310E7BA6AB00F5680E /* logic.h */,
- DF8424330E7BA6AB00F5680E /* mouse.cpp */,
- DF8424340E7BA6AB00F5680E /* mouse.h */,
- DF8424350E7BA6AB00F5680E /* music */,
- DF8424420E7BA6AB00F5680E /* rnc_deco.cpp */,
- DF8424430E7BA6AB00F5680E /* rnc_deco.h */,
- DF8424440E7BA6AB00F5680E /* screen.cpp */,
- DF8424450E7BA6AB00F5680E /* screen.h */,
- DF8424460E7BA6AB00F5680E /* sky.cpp */,
- DF8424470E7BA6AB00F5680E /* sky.h */,
- DF8424480E7BA6AB00F5680E /* skydefs.h */,
- DF8424490E7BA6AB00F5680E /* sound.cpp */,
- DF84244A0E7BA6AB00F5680E /* sound.h */,
- DF84244B0E7BA6AB00F5680E /* struc.h */,
- DF84244C0E7BA6AB00F5680E /* text.cpp */,
- DF84244D0E7BA6AB00F5680E /* text.h */,
- );
- path = sky;
- sourceTree = "<group>";
- };
- DF8424350E7BA6AB00F5680E /* music */ = {
- isa = PBXGroup;
- children = (
- DF8424360E7BA6AB00F5680E /* adlibchannel.cpp */,
- DF8424370E7BA6AB00F5680E /* adlibchannel.h */,
- DF8424380E7BA6AB00F5680E /* adlibmusic.cpp */,
- DF8424390E7BA6AB00F5680E /* adlibmusic.h */,
- DF84243A0E7BA6AB00F5680E /* gmchannel.cpp */,
- DF84243B0E7BA6AB00F5680E /* gmchannel.h */,
- DF84243C0E7BA6AB00F5680E /* gmmusic.cpp */,
- DF84243D0E7BA6AB00F5680E /* gmmusic.h */,
- DF84243E0E7BA6AB00F5680E /* mt32music.cpp */,
- DF84243F0E7BA6AB00F5680E /* mt32music.h */,
- DF8424400E7BA6AB00F5680E /* musicbase.cpp */,
- DF8424410E7BA6AB00F5680E /* musicbase.h */,
- );
- path = music;
- sourceTree = "<group>";
- };
- DF84244E0E7BA6AB00F5680E /* sword1 */ = {
- isa = PBXGroup;
- children = (
- DF46B7C61381E72500D08723 /* console.cpp */,
- DF46B7C71381E72500D08723 /* console.h */,
- DF84244F0E7BA6AB00F5680E /* animation.cpp */,
- DF8424500E7BA6AB00F5680E /* animation.h */,
- DF8424510E7BA6AB00F5680E /* collision.h */,
- DF8424520E7BA6AB00F5680E /* control.cpp */,
- DF8424530E7BA6AB00F5680E /* control.h */,
- DF8424560E7BA6AB00F5680E /* debug.cpp */,
- DF8424570E7BA6AB00F5680E /* debug.h */,
- DFAAAFFB0F0112DF003E9390 /* detection.cpp */,
- DF8424580E7BA6AB00F5680E /* eventman.cpp */,
- DF8424590E7BA6AB00F5680E /* eventman.h */,
- DF84245A0E7BA6AB00F5680E /* logic.cpp */,
- DF84245B0E7BA6AB00F5680E /* logic.h */,
- DF84245C0E7BA6AB00F5680E /* memman.cpp */,
- DF84245D0E7BA6AB00F5680E /* memman.h */,
- DF84245E0E7BA6AB00F5680E /* menu.cpp */,
- DF84245F0E7BA6AB00F5680E /* menu.h */,
- DF8424610E7BA6AB00F5680E /* mouse.cpp */,
- DF8424620E7BA6AB00F5680E /* mouse.h */,
- DF8424630E7BA6AB00F5680E /* music.cpp */,
- DF8424640E7BA6AB00F5680E /* music.h */,
- DF8424650E7BA6AB00F5680E /* object.h */,
- DF8424660E7BA6AB00F5680E /* objectman.cpp */,
- DF8424670E7BA6AB00F5680E /* objectman.h */,
- DF8424680E7BA6AB00F5680E /* resman.cpp */,
- DF8424690E7BA6AB00F5680E /* resman.h */,
- DF84246A0E7BA6AB00F5680E /* router.cpp */,
- DF84246B0E7BA6AB00F5680E /* router.h */,
- DF84246C0E7BA6AB00F5680E /* screen.cpp */,
- DF84246D0E7BA6AB00F5680E /* screen.h */,
- DF84246E0E7BA6AB00F5680E /* sound.cpp */,
- DF84246F0E7BA6AB00F5680E /* sound.h */,
- DF8424700E7BA6AB00F5680E /* staticres.cpp */,
- DF8424710E7BA6AB00F5680E /* sword1.cpp */,
- DF8424720E7BA6AB00F5680E /* sword1.h */,
- DF8424730E7BA6AB00F5680E /* sworddefs.h */,
- DF8424740E7BA6AB00F5680E /* swordres.h */,
- DF8424750E7BA6AB00F5680E /* text.cpp */,
- DF8424760E7BA6AB00F5680E /* text.h */,
- );
- path = sword1;
- sourceTree = "<group>";
- };
- DF8424770E7BA6AB00F5680E /* sword2 */ = {
- isa = PBXGroup;
- children = (
- DF46B7A81381E5F100D08723 /* header.cpp */,
- DF8424780E7BA6AB00F5680E /* animation.cpp */,
- DF8424790E7BA6AB00F5680E /* animation.h */,
- DF84247A0E7BA6AB00F5680E /* anims.cpp */,
- DF84247B0E7BA6AB00F5680E /* console.cpp */,
- DF84247C0E7BA6AB00F5680E /* console.h */,
- DF84247D0E7BA6AB00F5680E /* controls.cpp */,
- DF84247E0E7BA6AB00F5680E /* controls.h */,
- DF84247F0E7BA6AB00F5680E /* debug.cpp */,
- DF8424800E7BA6AB00F5680E /* debug.h */,
- DF8424810E7BA6AB00F5680E /* defs.h */,
- DF8424820E7BA6AB00F5680E /* events.cpp */,
- DF8424830E7BA6AB00F5680E /* function.cpp */,
- DF8424840E7BA6AB00F5680E /* header.h */,
- DF8424850E7BA6AB00F5680E /* icons.cpp */,
- DF8424860E7BA6AB00F5680E /* interpreter.cpp */,
- DF8424870E7BA6AB00F5680E /* interpreter.h */,
- DF8424880E7BA6AB00F5680E /* layers.cpp */,
- DF8424890E7BA6AB00F5680E /* logic.cpp */,
- DF84248A0E7BA6AB00F5680E /* logic.h */,
- DF84248B0E7BA6AB00F5680E /* maketext.cpp */,
- DF84248C0E7BA6AB00F5680E /* maketext.h */,
- DF84248D0E7BA6AB00F5680E /* memory.cpp */,
- DF84248E0E7BA6AB00F5680E /* memory.h */,
- DF84248F0E7BA6AB00F5680E /* menu.cpp */,
- DF8424910E7BA6AB00F5680E /* mouse.cpp */,
- DF8424920E7BA6AB00F5680E /* mouse.h */,
- DF8424930E7BA6AB00F5680E /* music.cpp */,
- DF8424940E7BA6AB00F5680E /* object.h */,
- DF8424950E7BA6AB00F5680E /* palette.cpp */,
- DF8424960E7BA6AB00F5680E /* protocol.cpp */,
- DF8424970E7BA6AB00F5680E /* render.cpp */,
- DF8424980E7BA6AB00F5680E /* resman.cpp */,
- DF8424990E7BA6AB00F5680E /* resman.h */,
- DF84249A0E7BA6AB00F5680E /* router.cpp */,
- DF84249B0E7BA6AB00F5680E /* router.h */,
- DF84249C0E7BA6AB00F5680E /* saveload.cpp */,
- DF84249D0E7BA6AB00F5680E /* saveload.h */,
- DF84249E0E7BA6AB00F5680E /* screen.cpp */,
- DF84249F0E7BA6AB00F5680E /* screen.h */,
- DF8424A00E7BA6AB00F5680E /* scroll.cpp */,
- DF8424A10E7BA6AB00F5680E /* sound.cpp */,
- DF8424A20E7BA6AB00F5680E /* sound.h */,
- DF8424A30E7BA6AB00F5680E /* speech.cpp */,
- DF8424A40E7BA6AB00F5680E /* sprite.cpp */,
- DF8424A50E7BA6AB00F5680E /* startup.cpp */,
- DF8424A60E7BA6AB00F5680E /* sword2.cpp */,
- DF8424A70E7BA6AB00F5680E /* sword2.h */,
- DF8424A80E7BA6AB00F5680E /* sync.cpp */,
- DF8424A90E7BA6AB00F5680E /* walker.cpp */,
- );
- path = sword2;
- sourceTree = "<group>";
- };
- DF8424AA0E7BA6AB00F5680E /* tinsel */ = {
- isa = PBXGroup;
- children = (
- DF46B8901381F62B00D08723 /* adpcm.cpp */,
- DF46B8911381F62B00D08723 /* adpcm.h */,
- DF46B6F21381E18900D08723 /* coroutine.cpp */,
- DF8424AB0E7BA6AB00F5680E /* actors.cpp */,
- DF8424AC0E7BA6AB00F5680E /* actors.h */,
- DF8424AD0E7BA6AB00F5680E /* anim.cpp */,
- DF8424AE0E7BA6AB00F5680E /* anim.h */,
- DF8424AF0E7BA6AB00F5680E /* background.cpp */,
- DF8424B00E7BA6AB00F5680E /* background.h */,
- DF8424B10E7BA6AB00F5680E /* bg.cpp */,
- DF2FFC1F0F4862520006E566 /* bmv.cpp */,
- DF8424B20E7BA6AB00F5680E /* cliprect.cpp */,
- DF8424B30E7BA6AB00F5680E /* cliprect.h */,
- DF8424B40E7BA6AB00F5680E /* config.cpp */,
- DF8424B50E7BA6AB00F5680E /* config.h */,
- DF8424B60E7BA6AB00F5680E /* coroutine.h */,
- DF8424B70E7BA6AB00F5680E /* cursor.cpp */,
- DF8424B80E7BA6AB00F5680E /* cursor.h */,
- DF8424B90E7BA6AB00F5680E /* debugger.cpp */,
- DF8424BA0E7BA6AB00F5680E /* debugger.h */,
- DF8424BB0E7BA6AB00F5680E /* detection.cpp */,
- DF2FFC200F4862520006E566 /* dialogs.cpp */,
- DF2FFC210F4862520006E566 /* dialogs.h */,
- DF2FFC220F4862520006E566 /* drives.cpp */,
- DF2FFC230F4862520006E566 /* drives.h */,
- DF8424BC0E7BA6AB00F5680E /* dw.h */,
- DF8424BD0E7BA6AB00F5680E /* effect.cpp */,
- DF8424BE0E7BA6AB00F5680E /* events.cpp */,
- DF8424BF0E7BA6AB00F5680E /* events.h */,
- DF8424C00E7BA6AB00F5680E /* faders.cpp */,
- DF8424C10E7BA6AB00F5680E /* faders.h */,
- DF8424C20E7BA6AB00F5680E /* film.h */,
- DF8424C30E7BA6AB00F5680E /* font.cpp */,
- DF8424C40E7BA6AB00F5680E /* font.h */,
- DF8424C50E7BA6AB00F5680E /* graphics.cpp */,
- DF8424C60E7BA6AB00F5680E /* graphics.h */,
- DF8424C70E7BA6AB00F5680E /* handle.cpp */,
- DF8424C80E7BA6AB00F5680E /* handle.h */,
- DF8424C90E7BA6AB00F5680E /* heapmem.cpp */,
- DF8424CA0E7BA6AB00F5680E /* heapmem.h */,
- DF8424CD0E7BA6AB00F5680E /* mareels.cpp */,
- DF2FFC240F4862520006E566 /* mareels.h */,
- DF8424CF0E7BA6AB00F5680E /* move.cpp */,
- DF8424D00E7BA6AB00F5680E /* move.h */,
- DF8424D10E7BA6AB00F5680E /* multiobj.cpp */,
- DF8424D20E7BA6AB00F5680E /* multiobj.h */,
- DF8424D30E7BA6AB00F5680E /* music.cpp */,
- DF8424D40E7BA6AB00F5680E /* music.h */,
- DF8424D50E7BA6AB00F5680E /* object.cpp */,
- DF8424D60E7BA6AB00F5680E /* object.h */,
- DF8424D70E7BA6AB00F5680E /* palette.cpp */,
- DF8424D80E7BA6AB00F5680E /* palette.h */,
- DF8424D90E7BA6AB00F5680E /* pcode.cpp */,
- DF8424DA0E7BA6AB00F5680E /* pcode.h */,
- DF8424DB0E7BA6AB00F5680E /* pdisplay.cpp */,
- DF2FFC250F4862520006E566 /* pdisplay.h */,
- DF8424DC0E7BA6AB00F5680E /* pid.h */,
- DF8424DD0E7BA6AB00F5680E /* play.cpp */,
- DF2FFC260F4862520006E566 /* play.h */,
- DF8424DE0E7BA6AB00F5680E /* polygons.cpp */,
- DF8424DF0E7BA6AB00F5680E /* polygons.h */,
- DF8424E00E7BA6AB00F5680E /* rince.cpp */,
- DF8424E10E7BA6AB00F5680E /* rince.h */,
- DF8424E20E7BA6AB00F5680E /* saveload.cpp */,
- DF8424E30E7BA6AB00F5680E /* savescn.cpp */,
- DF8424E40E7BA6AB00F5680E /* savescn.h */,
- DF8424E50E7BA6AB00F5680E /* scene.cpp */,
- DF8424E60E7BA6AB00F5680E /* scene.h */,
- DF8424E70E7BA6AB00F5680E /* sched.cpp */,
- DF8424E80E7BA6AB00F5680E /* sched.h */,
- DF8424E90E7BA6AB00F5680E /* scn.cpp */,
- DF8424EA0E7BA6AB00F5680E /* scn.h */,
- DF8424EB0E7BA6AB00F5680E /* scroll.cpp */,
- DF8424EC0E7BA6AB00F5680E /* scroll.h */,
- DF8424EE0E7BA6AB00F5680E /* sound.cpp */,
- DF8424EF0E7BA6AB00F5680E /* sound.h */,
- DF8424F00E7BA6AB00F5680E /* strres.cpp */,
- DF8424F10E7BA6AB00F5680E /* strres.h */,
- DF2FFC270F4862520006E566 /* sysvar.cpp */,
- DF2FFC280F4862520006E566 /* sysvar.h */,
- DF8424F20E7BA6AB00F5680E /* text.cpp */,
- DF8424F30E7BA6AB00F5680E /* text.h */,
- DF8424F40E7BA6AB00F5680E /* timers.cpp */,
- DF8424F50E7BA6AB00F5680E /* timers.h */,
- DF8424F60E7BA6AB00F5680E /* tinlib.cpp */,
- DF8424F70E7BA6AB00F5680E /* tinlib.h */,
- DF8424F80E7BA6AB00F5680E /* tinsel.cpp */,
- DF8424F90E7BA6AB00F5680E /* tinsel.h */,
- DF8424FA0E7BA6AB00F5680E /* token.cpp */,
- DF8424FB0E7BA6AB00F5680E /* token.h */,
- );
- path = tinsel;
- sourceTree = "<group>";
- };
- DF8424FC0E7BA6AB00F5680E /* touche */ = {
- isa = PBXGroup;
- children = (
- DF46B84B1381F39E00D08723 /* console.cpp */,
- DF46B84C1381F39E00D08723 /* console.h */,
- DF8424FD0E7BA6AB00F5680E /* detection.cpp */,
- DF8424FE0E7BA6AB00F5680E /* graphics.cpp */,
- DF8424FF0E7BA6AB00F5680E /* graphics.h */,
- DF8425000E7BA6AB00F5680E /* menu.cpp */,
- DF8425010E7BA6AB00F5680E /* midi.cpp */,
- DF8425020E7BA6AB00F5680E /* midi.h */,
- DF8425040E7BA6AB00F5680E /* opcodes.cpp */,
- DF8425050E7BA6AB00F5680E /* resource.cpp */,
- DF8425060E7BA6AB00F5680E /* saveload.cpp */,
- DF8425070E7BA6AB00F5680E /* staticres.cpp */,
- DF8425080E7BA6AB00F5680E /* touche.cpp */,
- DF8425090E7BA6AB00F5680E /* touche.h */,
- );
- path = touche;
- sourceTree = "<group>";
- };
- DF9B9277118E475D0069C19D /* games */ = {
- isa = PBXGroup;
- children = (
- );
- name = games;
- sourceTree = "<group>";
- };
- DFA2A57A118E433A00344DFD /* Resources-iPad */ = {
- isa = PBXGroup;
- children = (
- );
- name = "Resources-iPad";
- sourceTree = "<group>";
- };
- DFC830190F48AF18005EF03C /* sci */ = {
- isa = PBXGroup;
- children = (
- DFAAD2390F50120E00C3A4E2 /* console.cpp */,
- DFAAD23A0F50120E00C3A4E2 /* console.h */,
- DF6118420FE3A8250042AD3F /* debug.h */,
- DF6118430FE3A8250042AD3F /* decompressor.cpp */,
- DF6118440FE3A8250042AD3F /* decompressor.h */,
- DFC8301A0F48AF18005EF03C /* detection.cpp */,
- DF90E9B410AEDA5300C8F93F /* detection_tables.h */,
- DFC8301B0F48AF18005EF03C /* engine */,
- DF2EC40310E64C8000765801 /* event.cpp */,
- DF2EC40410E64C8000765801 /* event.h */,
- DF45B175116628A5009B85CC /* graphics */,
- DF45B1A5116628A5009B85CC /* parser */,
- DF6118450FE3A8250042AD3F /* resource.cpp */,
- DF6118460FE3A8250042AD3F /* resource.h */,
- DFB0577D11B7541F0015AE65 /* resource_audio.cpp */,
- DFC830960F48AF18005EF03C /* sci.cpp */,
- DFC830970F48AF18005EF03C /* sci.h */,
- DF45B1AB116628A5009B85CC /* sound */,
- DFB0577E11B7541F0015AE65 /* util.cpp */,
- DFB0577F11B7541F0015AE65 /* util.h */,
- DF45B1C5116628A5009B85CC /* video */,
- );
- path = sci;
- sourceTree = "<group>";
- };
- DFC8301B0F48AF18005EF03C /* engine */ = {
- isa = PBXGroup;
- children = (
- DF46B7BB1381E6C000D08723 /* object.cpp */,
- DF46B7BC1381E6C000D08723 /* object.h */,
- DF46B7661381E4E400D08723 /* vm_types.cpp */,
- DFCDC6D5116629CE00A7D2A0 /* features.cpp */,
- DFCDC6D6116629CE00A7D2A0 /* features.h */,
- DFC8301E0F48AF18005EF03C /* gc.cpp */,
- DFC8301F0F48AF18005EF03C /* gc.h */,
- DFC830230F48AF18005EF03C /* kernel.cpp */,
- DF573BFE0F5A81EA00961A72 /* kernel.h */,
- DF895C28124C25350077F6E8 /* kernel_tables.h */,
- DFC830260F48AF18005EF03C /* kevent.cpp */,
- DFC830270F48AF18005EF03C /* kfile.cpp */,
- DFC830280F48AF18005EF03C /* kgraphics.cpp */,
- DFC830290F48AF18005EF03C /* klists.cpp */,
- DFC8302A0F48AF18005EF03C /* kmath.cpp */,
- DFC8302B0F48AF18005EF03C /* kmenu.cpp */,
- DF6118380FE3A8080042AD3F /* kmisc.cpp */,
- DFC8302C0F48AF18005EF03C /* kmovement.cpp */,
- DFCDC6D7116629CE00A7D2A0 /* kparse.cpp */,
- DFC8302D0F48AF18005EF03C /* kpathing.cpp */,
- DFC8302E0F48AF18005EF03C /* kscripts.cpp */,
- DFC8302F0F48AF18005EF03C /* ksound.cpp */,
- DFC830300F48AF18005EF03C /* kstring.cpp */,
- DF7F286411FF23EF00159131 /* kvideo.cpp */,
- DFC830310F48AF18005EF03C /* message.cpp */,
- DFC830320F48AF18005EF03C /* message.h */,
- DFC830360F48AF18005EF03C /* savegame.cpp */,
- DF61183B0FE3A8080042AD3F /* savegame.h */,
- DF89C2A30F62D79E00D756B6 /* script.cpp */,
- DF573BFF0F5A81EA00961A72 /* script.h */,
- DF895C29124C25350077F6E8 /* script_patches.cpp */,
- DFC830390F48AF18005EF03C /* scriptdebug.cpp */,
- DFC8303A0F48AF18005EF03C /* seg_manager.cpp */,
- DF573C000F5A81EA00961A72 /* seg_manager.h */,
- DF6118390FE3A8080042AD3F /* segment.cpp */,
- DF61183A0FE3A8080042AD3F /* segment.h */,
- DF90E9BD10AEDA9B00C8F93F /* selector.cpp */,
- DFCDC6D8116629CE00A7D2A0 /* selector.h */,
- DF573C010F5A81EA00961A72 /* state.cpp */,
- DF573C020F5A81EA00961A72 /* state.h */,
- DF7585F6100CB75800CC3324 /* static_selectors.cpp */,
- DFC8303C0F48AF18005EF03C /* vm.cpp */,
- DF573C030F5A81EA00961A72 /* vm.h */,
- DF573C040F5A81EA00961A72 /* vm_types.h */,
- DF7F286511FF23EF00159131 /* workarounds.cpp */,
- DF7F286611FF23EF00159131 /* workarounds.h */,
- );
- path = engine;
- sourceTree = "<group>";
- };
- DFD5184C0DF3420D00854012 /* scaler */ = {
- isa = PBXGroup;
- children = (
- F9946DE9139E1B6F0072D195 /* aspect.h */,
- F9946DEA139E1B6F0072D195 /* downscaler.cpp */,
- F9946DEB139E1B6F0072D195 /* downscaler.h */,
- DFD518AA0DF34BA600854012 /* 2xsai.cpp */,
- DFD518AB0DF34BA600854012 /* aspect.cpp */,
- DFD5189E0DF34AD700854012 /* intern.h */,
- DFD518B50DF34BA600854012 /* scale2x.cpp */,
- DFD518B60DF34BA600854012 /* scale2x.h */,
- DFD518B80DF34BA600854012 /* scale3x.cpp */,
- DFD518B90DF34BA600854012 /* scale3x.h */,
- DFD518A00DF34B2500854012 /* scalebit.cpp */,
- DFD518A10DF34B2500854012 /* scalebit.h */,
- DFAAB0010F011392003E9390 /* thumbnail_intern.cpp */,
- );
- path = scaler;
- sourceTree = "<group>";
- };
- DFD6476A0F49F7D2008E18EF /* libs */ = {
- isa = PBXGroup;
- children = (
- DFD6476B0F49F7EF008E18EF /* libFLAC.a */,
- DFD6476C0F49F7EF008E18EF /* libmad.a */,
- DFD6476F0F49F7EF008E18EF /* libvorbisidec.a */,
- );
- name = libs;
- sourceTree = "<group>";
- };
- DFE470C00D81F4BA00B6D1FB /* base */ = {
- isa = PBXGroup;
- children = (
- DFE470C10D81F4BA00B6D1FB /* commandLine.cpp */,
- DFE470C20D81F4BA00B6D1FB /* commandLine.h */,
- DFE470C70D81F4BA00B6D1FB /* main.cpp */,
- DFE470C80D81F4BA00B6D1FB /* main.h */,
- DFE470CA0D81F4BA00B6D1FB /* plugins.cpp */,
- DFE470CB0D81F4BA00B6D1FB /* plugins.h */,
- DFE470CC0D81F4BA00B6D1FB /* version.cpp */,
- DFE470CD0D81F4BA00B6D1FB /* version.h */,
- );
- name = base;
- path = ../../base;
- sourceTree = SOURCE_ROOT;
- };
- DFE470D50D81F4E700B6D1FB /* backends */ = {
- isa = PBXGroup;
- children = (
- F9946E07139E1C3E0072D195 /* graphics */,
- F9946DFA139E1BCB0072D195 /* mixer */,
- DF46B86D1381F47B00D08723 /* audiocd */,
- DF46B7B01381E64E00D08723 /* mutex */,
- DF46B7471381E40F00D08723 /* modular-backend.cpp */,
- DF46B7481381E40F00D08723 /* modular-backend.h */,
- DF46B7411381E3F200D08723 /* log */,
- DF2FFC5B0F4866E70006E566 /* base-backend.cpp */,
- DF2FFC5C0F4866E70006E566 /* base-backend.h */,
- DFE470D60D81F4E700B6D1FB /* events */,
- DFE470DA0D81F4E700B6D1FB /* fs */,
- DFE471090D81F4E700B6D1FB /* midi */,
- DFE471170D81F4E700B6D1FB /* platform */,
- DFE4737B0D81F4E800B6D1FB /* plugins */,
- DFE473890D81F4E800B6D1FB /* saves */,
- DFE473910D81F4E800B6D1FB /* timer */,
- );
- name = backends;
- path = ../../backends;
- sourceTree = SOURCE_ROOT;
- };
- DFE470D60D81F4E700B6D1FB /* events */ = {
- isa = PBXGroup;
- children = (
- DF46B7CC1381E74D00D08723 /* sdl */,
- DFE470D70D81F4E700B6D1FB /* default */,
- );
- path = events;
- sourceTree = "<group>";
- };
- DFE470D70D81F4E700B6D1FB /* default */ = {
- isa = PBXGroup;
- children = (
- DFE470D80D81F4E700B6D1FB /* default-events.cpp */,
- DFE470D90D81F4E700B6D1FB /* default-events.h */,
- );
- path = default;
- sourceTree = "<group>";
- };
- DFE470DA0D81F4E700B6D1FB /* fs */ = {
- isa = PBXGroup;
- children = (
- DF842A6B0E7BBD5700F5680E /* stdiostream.cpp */,
- DF842A6C0E7BBD5700F5680E /* stdiostream.h */,
- DFE470DE0D81F4E700B6D1FB /* abstract-fs.h */,
- DFE470E80D81F4E700B6D1FB /* fs-factory.h */,
- DFE470F50D81F4E700B6D1FB /* posix */,
- );
- path = fs;
- sourceTree = "<group>";
- };
- DFE470F50D81F4E700B6D1FB /* posix */ = {
- isa = PBXGroup;
- children = (
- DFADEBB613820E0C00C46364 /* posix-fs.cpp */,
- DF842A4C0E7BBBEB00F5680E /* posix-fs.h */,
- DFE470F60D81F4E700B6D1FB /* posix-fs-factory.cpp */,
- DFE470F70D81F4E700B6D1FB /* posix-fs-factory.h */,
- );
- path = posix;
- sourceTree = "<group>";
- };
- DFE471090D81F4E700B6D1FB /* midi */ = {
- isa = PBXGroup;
- children = (
- DF0944300F63FBB3002D821E /* coreaudio.cpp */,
- DF0944310F63FBB3002D821E /* coremidi.cpp */,
- DF842A3D0E7BBB5000F5680E /* timidity.cpp */,
- DFD517E10DF33CAC00854012 /* seq.cpp */,
- );
- path = midi;
- sourceTree = "<group>";
- };
- DFE471170D81F4E700B6D1FB /* platform */ = {
- isa = PBXGroup;
- children = (
- F92B4DDC139DDC9E000D1BF1 /* macosx */,
- DF09422F0F63CB9A002D821E /* sdl */,
- DFE471D70D81F4E700B6D1FB /* iphone */,
- );
- path = platform;
- sourceTree = "<group>";
- };
- DFE471D70D81F4E700B6D1FB /* iphone */ = {
- isa = PBXGroup;
- children = (
- DF758614100CBA0200CC3324 /* osys_events.cpp */,
- DF758615100CBA0200CC3324 /* osys_main.cpp */,
- DF758616100CBA0200CC3324 /* osys_main.h */,
- DF758617100CBA0200CC3324 /* osys_sound.cpp */,
- DF758618100CBA0200CC3324 /* osys_video.cpp */,
- DF8428960E7BAAAB00F5680E /* blit.cpp */,
- DF841FD90E7BA61800F5680E /* iphone_keyboard.m */,
- DF841FDA0E7BA61800F5680E /* iphone_video.h */,
- DF841FDB0E7BA61800F5680E /* iphone_video.m */,
- DFE471DC0D81F4E700B6D1FB /* blit_arm.h */,
- DFE471DE0D81F4E700B6D1FB /* iphone_common.h */,
- DFE471DF0D81F4E700B6D1FB /* iphone_keyboard.h */,
- DFE471E10D81F4E700B6D1FB /* iphone_main.m */,
- );
- path = iphone;
- sourceTree = "<group>";
- };
- DFE4737B0D81F4E800B6D1FB /* plugins */ = {
- isa = PBXGroup;
- children = (
- DF46B8861381F5C600D08723 /* sdl */,
- DFE4737F0D81F4E800B6D1FB /* dynamic-plugin.h */,
- DFE473800D81F4E800B6D1FB /* posix */,
- );
- path = plugins;
- sourceTree = "<group>";
- };
- DFE473800D81F4E800B6D1FB /* posix */ = {
- isa = PBXGroup;
- children = (
- DFE473810D81F4E800B6D1FB /* posix-provider.cpp */,
- DFE473820D81F4E800B6D1FB /* posix-provider.h */,
- );
- path = posix;
- sourceTree = "<group>";
- };
- DFE473890D81F4E800B6D1FB /* saves */ = {
- isa = PBXGroup;
- children = (
- DF2FFBF50F4860A60006E566 /* posix */,
- DFE4738D0D81F4E800B6D1FB /* default */,
- DFE473900D81F4E800B6D1FB /* savefile.cpp */,
- );
- path = saves;
- sourceTree = "<group>";
- };
- DFE4738D0D81F4E800B6D1FB /* default */ = {
- isa = PBXGroup;
- children = (
- DFE4738E0D81F4E800B6D1FB /* default-saves.cpp */,
- DFE4738F0D81F4E800B6D1FB /* default-saves.h */,
- );
- path = default;
- sourceTree = "<group>";
- };
- DFE473910D81F4E800B6D1FB /* timer */ = {
- isa = PBXGroup;
- children = (
- DF46B7A21381E5CC00D08723 /* sdl */,
- DFE473920D81F4E800B6D1FB /* default */,
- );
- path = timer;
- sourceTree = "<group>";
- };
- DFE473920D81F4E800B6D1FB /* default */ = {
- isa = PBXGroup;
- children = (
- DFE473930D81F4E800B6D1FB /* default-timer.cpp */,
- DFE473940D81F4E800B6D1FB /* default-timer.h */,
- );
- path = default;
- sourceTree = "<group>";
- };
- DFE473950D81F4E800B6D1FB /* common */ = {
- isa = PBXGroup;
- children = (
- F92B4DCB139DD428000D1BF1 /* memstream.h */,
- F92B4DCC139DD428000D1BF1 /* quicktime.cpp */,
- F92B4DCD139DD428000D1BF1 /* quicktime.h */,
- DF46B76E1381E54200D08723 /* bufferedstream.h */,
- DF46B76F1381E54200D08723 /* dcl.cpp */,
- DF46B7701381E54200D08723 /* dcl.h */,
- DF46B7711381E54200D08723 /* forbidden.h */,
- DF46B7721381E54200D08723 /* iff_container.cpp */,
- DF46B7731381E54200D08723 /* substream.h */,
- DF46B7741381E54200D08723 /* translation.h */,
- DF46B7751381E54200D08723 /* winexe_ne.cpp */,
- DF46B7761381E54200D08723 /* winexe_ne.h */,
- DF46B7771381E54200D08723 /* winexe_pe.cpp */,
- DF46B7781381E54200D08723 /* winexe_pe.h */,
- DF46B7791381E54200D08723 /* winexe.cpp */,
- DF46B77A1381E54200D08723 /* winexe.h */,
- DFE473980D81F4E800B6D1FB /* algorithm.h */,
- DF842A400E7BBBB400F5680E /* archive.cpp */,
- DF842A410E7BBBB400F5680E /* archive.h */,
- DFE473990D81F4E800B6D1FB /* array.h */,
- DFE4739A0D81F4E800B6D1FB /* config-file.cpp */,
- DFE4739B0D81F4E800B6D1FB /* config-file.h */,
- DFE4739C0D81F4E800B6D1FB /* config-manager.cpp */,
- DFE4739D0D81F4E800B6D1FB /* config-manager.h */,
- DFB0577311B753DA0015AE65 /* debug-channels.h */,
- DF2FFBD10F485DFB0006E566 /* debug.cpp */,
- DF2FFBD20F485DFB0006E566 /* debug.h */,
- DFE4739E0D81F4E800B6D1FB /* endian.h */,
- DF9B9261118E46FE0069C19D /* error.cpp */,
- DFE4739F0D81F4E800B6D1FB /* error.h */,
- DF6BF4F710529F140069811F /* EventDispatcher.cpp */,
- DF6BF4F810529F140069811F /* EventRecorder.cpp */,
- DF6BF4F910529F140069811F /* EventRecorder.h */,
- DFE473A00D81F4E800B6D1FB /* events.h */,
- DFE473A10D81F4E800B6D1FB /* file.cpp */,
- DFE473A20D81F4E800B6D1FB /* file.h */,
- DFE473A30D81F4E800B6D1FB /* frac.h */,
- DFE473A40D81F4E800B6D1FB /* fs.cpp */,
- DFE473A50D81F4E800B6D1FB /* fs.h */,
- DFE473A60D81F4E800B6D1FB /* func.h */,
- DFE473A70D81F4E800B6D1FB /* hash-str.h */,
- DFE473A80D81F4E800B6D1FB /* hashmap.cpp */,
- DFE473A90D81F4E800B6D1FB /* hashmap.h */,
- DFE473AA0D81F4E800B6D1FB /* iff_container.h */,
- DFE473AB0D81F4E800B6D1FB /* keyboard.h */,
- DFE473AC0D81F4E800B6D1FB /* list.h */,
- DF6BF4FA10529F140069811F /* list_intern.h */,
- DFCDC70911662B6B00A7D2A0 /* macresman.cpp */,
- DFCDC70A11662B6B00A7D2A0 /* macresman.h */,
- DFE473AD0D81F4E800B6D1FB /* md5.cpp */,
- DFE473AE0D81F4E800B6D1FB /* md5.h */,
- DFD511460DF3383500854012 /* memorypool.cpp */,
- DFD511470DF3383500854012 /* memorypool.h */,
- DFE473B00D81F4E800B6D1FB /* mutex.cpp */,
- DFE473B10D81F4E800B6D1FB /* mutex.h */,
- DFE473B20D81F4E800B6D1FB /* noncopyable.h */,
- DFE473B30D81F4E800B6D1FB /* pack-end.h */,
- DFE473B40D81F4E800B6D1FB /* pack-start.h */,
- DF842A430E7BBBB400F5680E /* ptr.h */,
- DF842A440E7BBBB400F5680E /* queue.h */,
- DFEC5D0A1166C5CF00C90552 /* random.cpp */,
- DFEC5D0B1166C5CF00C90552 /* random.h */,
- DFB0577411B753DA0015AE65 /* rational.cpp */,
- DFB0577511B753DA0015AE65 /* rational.h */,
- DFE473B50D81F4E800B6D1FB /* rect.h */,
- DFE473B60D81F4E800B6D1FB /* savefile.h */,
- DFE473B70D81F4E800B6D1FB /* scummsys.h */,
- DF6BF4FB10529F140069811F /* serializer.h */,
- DFE473B80D81F4E800B6D1FB /* singleton.h */,
- DFE473B90D81F4E800B6D1FB /* stack.h */,
- DFEC5D0C1166C5CF00C90552 /* str-array.h */,
- DFE473BA0D81F4E800B6D1FB /* str.cpp */,
- DFE473BB0D81F4E800B6D1FB /* str.h */,
- DFE473BC0D81F4E800B6D1FB /* stream.cpp */,
- DFE473BD0D81F4E800B6D1FB /* stream.h */,
- DFE473BE0D81F4E800B6D1FB /* system.cpp */,
- DFE473BF0D81F4E800B6D1FB /* system.h */,
- DF2EC50910E64DB300765801 /* textconsole.cpp */,
- DF2EC50A10E64DB300765801 /* textconsole.h */,
- DFE473C00D81F4E800B6D1FB /* timer.h */,
- DFEC5D0D1166C5CF00C90552 /* tokenizer.cpp */,
- DFEC5D0E1166C5CF00C90552 /* tokenizer.h */,
- DF7F289111FF247300159131 /* translation.cpp */,
- DFEC5D0F1166C5CF00C90552 /* types.h */,
- DF842A450E7BBBB400F5680E /* unarj.cpp */,
- DF842A460E7BBBB400F5680E /* unarj.h */,
- DFE473C10D81F4E800B6D1FB /* unzip.cpp */,
- DFE473C20D81F4E800B6D1FB /* unzip.h */,
- DFE473C30D81F4E800B6D1FB /* util.cpp */,
- DFE473C40D81F4E800B6D1FB /* util.h */,
- DF7E8C0F0ED5FCC2001CB19F /* xmlparser.cpp */,
- DF7E8C100ED5FCC2001CB19F /* xmlparser.h */,
- DFE473C50D81F4E800B6D1FB /* zlib.cpp */,
- DFE473C60D81F4E800B6D1FB /* zlib.h */,
- );
- name = common;
- path = ../../common;
- sourceTree = SOURCE_ROOT;
- };
- DFE477520D81F4E900B6D1FB /* graphics */ = {
- isa = PBXGroup;
- children = (
- F92B4DD1139DD449000D1BF1 /* yuv_to_rgb.cpp */,
- F92B4DD2139DD449000D1BF1 /* yuv_to_rgb.h */,
- DFADEBB113820DF500C46364 /* maccursor.cpp */,
- DFADEBB213820DF500C46364 /* maccursor.h */,
- DF46B78E1381E58000D08723 /* palette.h */,
- DF46B78F1381E58000D08723 /* png.cpp */,
- DF46B7901381E58000D08723 /* png.h */,
- DF46B7911381E58000D08723 /* wincursor.cpp */,
- DF46B7921381E58000D08723 /* wincursor.h */,
- DFE477530D81F4E900B6D1FB /* colormasks.h */,
- DF6BF4C010529DA50069811F /* conversion.cpp */,
- DF6BF4C110529DA50069811F /* conversion.h */,
- DFE477540D81F4E900B6D1FB /* cursorman.cpp */,
- DFE477550D81F4E900B6D1FB /* cursorman.h */,
- DF2FFB900F485D890006E566 /* dither.cpp */,
- DF2FFB910F485D890006E566 /* dither.h */,
- DFE477580D81F4E900B6D1FB /* font.cpp */,
- DFE477590D81F4E900B6D1FB /* font.h */,
- DFE4775A0D81F4E900B6D1FB /* fontman.cpp */,
- DFE4775B0D81F4E900B6D1FB /* fontman.h */,
- DFE4775C0D81F4E900B6D1FB /* fonts */,
- DFE477610D81F4E900B6D1FB /* iff.cpp */,
- DFE477620D81F4E900B6D1FB /* iff.h */,
- DFE477630D81F4E900B6D1FB /* imagedec.cpp */,
- DFE477640D81F4E900B6D1FB /* imagedec.h */,
- DF6BF4C210529DA50069811F /* jpeg.cpp */,
- DF6BF4C310529DA50069811F /* jpeg.h */,
- DFB0578F11B7547D0015AE65 /* pict.cpp */,
- DFB0579011B7547D0015AE65 /* pict.h */,
- DF2FFB920F485D890006E566 /* pixelformat.h */,
- DFE4776A0D81F4E900B6D1FB /* primitives.cpp */,
- DFE4776B0D81F4E900B6D1FB /* primitives.h */,
- DFD5184C0DF3420D00854012 /* scaler */,
- DFD5183B0DF3411800854012 /* scaler.cpp */,
- DFD5183C0DF3411800854012 /* scaler.h */,
- DF7585EA100CB6EA00CC3324 /* sjis.cpp */,
- DF7585EB100CB6EA00CC3324 /* sjis.h */,
- DFE477860D81F4E900B6D1FB /* surface.cpp */,
- DFE477870D81F4E900B6D1FB /* surface.h */,
- DF7E8C050ED5FCAF001CB19F /* thumbnail.cpp */,
- DF7E8C060ED5FCAF001CB19F /* thumbnail.h */,
- DF7E8C070ED5FCAF001CB19F /* VectorRenderer.cpp */,
- DF7E8C080ED5FCAF001CB19F /* VectorRenderer.h */,
- DF7E8C090ED5FCAF001CB19F /* VectorRendererSpec.cpp */,
- DF7E8C0A0ED5FCAF001CB19F /* VectorRendererSpec.h */,
- );
- name = graphics;
- path = ../../graphics;
- sourceTree = SOURCE_ROOT;
- };
- DFE4775C0D81F4E900B6D1FB /* fonts */ = {
- isa = PBXGroup;
- children = (
- DF46B79D1381E5B500D08723 /* winfont.cpp */,
- DF46B79E1381E5B500D08723 /* winfont.h */,
- DFE4775D0D81F4E900B6D1FB /* consolefont.cpp */,
- DFE4775E0D81F4E900B6D1FB /* newfont.cpp */,
- DFE4775F0D81F4E900B6D1FB /* newfont_big.cpp */,
- );
- path = fonts;
- sourceTree = "<group>";
- };
- DFE477880D81F4E900B6D1FB /* gui */ = {
- isa = PBXGroup;
- children = (
- DF2040211380C8A60056300A /* widgets */,
- DF203F461380C06E0056300A /* gui-manager.cpp */,
- DFE477890D81F4E900B6D1FB /* about.cpp */,
- DFE4778A0D81F4E900B6D1FB /* about.h */,
- DFE4778B0D81F4E900B6D1FB /* Actions.cpp */,
- DFE4778C0D81F4E900B6D1FB /* Actions.h */,
- DFE4778D0D81F4E900B6D1FB /* browser.cpp */,
- DFE4778E0D81F4E900B6D1FB /* browser.h */,
- DF2EC3E410E6490800765801 /* browser_osx.mm */,
- DFE4778F0D81F4E900B6D1FB /* chooser.cpp */,
- DFE477900D81F4E900B6D1FB /* chooser.h */,
- DFE477910D81F4E900B6D1FB /* console.cpp */,
- DFE477920D81F4E900B6D1FB /* console.h */,
- DFE477930D81F4E900B6D1FB /* credits.h */,
- DFE477940D81F4E900B6D1FB /* debugger.cpp */,
- DFE477950D81F4E900B6D1FB /* debugger.h */,
- DFE477960D81F4E900B6D1FB /* dialog.cpp */,
- DFE477970D81F4E900B6D1FB /* dialog.h */,
- DF9B9246118E46730069C19D /* error.cpp */,
- DF9B9247118E46730069C19D /* error.h */,
- DF2FFBD60F485E360006E566 /* gui-manager.h */,
- DFE4779E0D81F4E900B6D1FB /* Key.cpp */,
- DFE4779F0D81F4E900B6D1FB /* Key.h */,
- DFE477A20D81F4E900B6D1FB /* launcher.cpp */,
- DFE477A30D81F4E900B6D1FB /* launcher.h */,
- DFE477A60D81F4E900B6D1FB /* massadd.cpp */,
- DFE477A70D81F4E900B6D1FB /* massadd.h */,
- DFE477A80D81F4E900B6D1FB /* message.cpp */,
- DFE477A90D81F4E900B6D1FB /* message.h */,
- DFE477AD0D81F4E900B6D1FB /* object.cpp */,
- DFE477AE0D81F4E900B6D1FB /* object.h */,
- DFE477AF0D81F4E900B6D1FB /* options.cpp */,
- DFE477B00D81F4E900B6D1FB /* options.h */,
- DF7E8BF00ED5FC77001CB19F /* saveload.cpp */,
- DF7E8BF10ED5FC77001CB19F /* saveload.h */,
- DFE477BA0D81F4E900B6D1FB /* themebrowser.cpp */,
- DFE477BB0D81F4E900B6D1FB /* themebrowser.h */,
- DF7E8BF40ED5FC77001CB19F /* ThemeEngine.cpp */,
- DF7E8BF50ED5FC77001CB19F /* ThemeEngine.h */,
- DF7E8BF60ED5FC77001CB19F /* ThemeEval.cpp */,
- DF7E8BF70ED5FC77001CB19F /* ThemeEval.h */,
- DF7E8BF80ED5FC77001CB19F /* ThemeLayout.cpp */,
- DF7E8BF90ED5FC77001CB19F /* ThemeLayout.h */,
- DF7E8BFA0ED5FC77001CB19F /* ThemeParser.cpp */,
- DF7E8BFB0ED5FC77001CB19F /* ThemeParser.h */,
- DFE477C00D81F4E900B6D1FB /* themes */,
- DF7F288911FF244F00159131 /* Tooltip.cpp */,
- DF7F288A11FF244F00159131 /* Tooltip.h */,
- DFE477C40D81F4E900B6D1FB /* widget.cpp */,
- DFE477C50D81F4E900B6D1FB /* widget.h */,
- );
- name = gui;
- path = ../../gui;
- sourceTree = SOURCE_ROOT;
- };
- DFE477C00D81F4E900B6D1FB /* themes */ = {
- isa = PBXGroup;
- children = (
- DF2FFBDB0F485E480006E566 /* scummclassic.zip */,
- DF7E8C7A0ED601E5001CB19F /* scummmodern.zip */,
- );
- path = themes;
- sourceTree = "<group>";
- };
- F92B4DDC139DDC9E000D1BF1 /* macosx */ = {
- isa = PBXGroup;
- children = (
- F92B4DD7139DDC92000D1BF1 /* macosx-main.cpp */,
- F92B4DD8139DDC92000D1BF1 /* macosx.cpp */,
- F92B4DD9139DDC92000D1BF1 /* macosx.h */,
- );
- name = macosx;
- sourceTree = "<group>";
- };
- F9946D79139E1A260072D195 /* codecs */ = {
- isa = PBXGroup;
- children = (
- F9946D7A139E1A260072D195 /* cdtoons.cpp */,
- F9946D7B139E1A260072D195 /* cdtoons.h */,
- F9946D7C139E1A260072D195 /* cinepak.cpp */,
- F9946D7D139E1A260072D195 /* cinepak.h */,
- F9946D7E139E1A260072D195 /* codec.h */,
- F9946D7F139E1A260072D195 /* indeo3.cpp */,
- F9946D80139E1A260072D195 /* indeo3.h */,
- F9946D81139E1A260072D195 /* mjpeg.cpp */,
- F9946D82139E1A260072D195 /* mjpeg.h */,
- F9946D83139E1A260072D195 /* msrle.cpp */,
- F9946D84139E1A260072D195 /* msrle.h */,
- F9946D85139E1A260072D195 /* msvideo1.cpp */,
- F9946D86139E1A260072D195 /* msvideo1.h */,
- F9946D87139E1A260072D195 /* qtrle.cpp */,
- F9946D88139E1A260072D195 /* qtrle.h */,
- F9946D89139E1A260072D195 /* rpza.cpp */,
- F9946D8A139E1A260072D195 /* rpza.h */,
- F9946D8B139E1A260072D195 /* smc.cpp */,
- F9946D8C139E1A260072D195 /* smc.h */,
- F9946D8D139E1A260072D195 /* truemotion1.cpp */,
- F9946D8E139E1A260072D195 /* truemotion1.h */,
- F9946D8F139E1A260072D195 /* truemotion1data.h */,
- );
- name = codecs;
- path = ../../video/codecs;
- sourceTree = "<group>";
- };
- F9946DCD139E1A9A0072D195 /* mt32 */ = {
- isa = PBXGroup;
- children = (
- F9946DA3139E1A880072D195 /* freeverb.cpp */,
- F9946DA4139E1A880072D195 /* freeverb.h */,
- F9946DA5139E1A880072D195 /* i386.cpp */,
- F9946DA6139E1A880072D195 /* i386.h */,
- F9946DA7139E1A880072D195 /* mt32_file.cpp */,
- F9946DA8139E1A880072D195 /* mt32_file.h */,
- F9946DA9139E1A880072D195 /* mt32emu.h */,
- F9946DAA139E1A880072D195 /* part.cpp */,
- F9946DAB139E1A880072D195 /* part.h */,
- F9946DAC139E1A880072D195 /* partial.cpp */,
- F9946DAD139E1A880072D195 /* partial.h */,
- F9946DAE139E1A880072D195 /* partialManager.cpp */,
- F9946DAF139E1A880072D195 /* partialManager.h */,
- F9946DB0139E1A880072D195 /* structures.h */,
- F9946DB1139E1A880072D195 /* synth.cpp */,
- F9946DB2139E1A880072D195 /* synth.h */,
- F9946DB3139E1A880072D195 /* tables.cpp */,
- F9946DB4139E1A880072D195 /* tables.h */,
- );
- name = mt32;
- sourceTree = "<group>";
- };
- F9946DDF139E1B180072D195 /* posix */ = {
- isa = PBXGroup;
- children = (
- F9946DE0139E1B180072D195 /* posix-main.cpp */,
- F9946DE1139E1B180072D195 /* posix.cpp */,
- F9946DE2139E1B180072D195 /* posix.h */,
- );
- path = posix;
- sourceTree = "<group>";
- };
- F9946DF4139E1BBF0072D195 /* sdl */ = {
- isa = PBXGroup;
- children = (
- F9946DF5139E1BBF0072D195 /* sdl-mixer.cpp */,
- F9946DF6139E1BBF0072D195 /* sdl-mixer.h */,
- );
- name = sdl;
- path = mixer/sdl;
- sourceTree = "<group>";
- };
- F9946DFA139E1BCB0072D195 /* mixer */ = {
- isa = PBXGroup;
- children = (
- F9946DFB139E1BEB0072D195 /* doublebuffersdl */,
- F9946DF4139E1BBF0072D195 /* sdl */,
- );
- name = mixer;
- sourceTree = "<group>";
- };
- F9946DFB139E1BEB0072D195 /* doublebuffersdl */ = {
- isa = PBXGroup;
- children = (
- F9946DFC139E1BEB0072D195 /* doublebuffersdl-mixer.cpp */,
- F9946DFD139E1BEB0072D195 /* doublebuffersdl-mixer.h */,
- );
- name = doublebuffersdl;
- path = mixer/doublebuffersdl;
- sourceTree = "<group>";
- };
- F9946E01139E1C390072D195 /* sdl */ = {
- isa = PBXGroup;
- children = (
- F9946E02139E1C390072D195 /* sdl-graphics.cpp */,
- F9946E03139E1C390072D195 /* sdl-graphics.h */,
- );
- name = sdl;
- path = graphics/sdl;
- sourceTree = "<group>";
- };
- F9946E07139E1C3E0072D195 /* graphics */ = {
- isa = PBXGroup;
- children = (
- F9946E01139E1C390072D195 /* sdl */,
- );
- name = graphics;
- sourceTree = "<group>";
- };
-/* End PBXGroup section */
-
-/* Begin PBXNativeTarget section */
- 1D6058900D05DD3D006BFB54 /* ScummVM-iPhone */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "ScummVM-iPhone" */;
- buildPhases = (
- 1D60588D0D05DD3D006BFB54 /* Resources */,
- 1D60588E0D05DD3D006BFB54 /* Sources */,
- 1D60588F0D05DD3D006BFB54 /* Frameworks */,
- DF573CB30F5A84DF00961A72 /* CopyFiles */,
- );
- buildRules = (
- );
- dependencies = (
- );
- name = "ScummVM-iPhone";
- productName = scummvm;
- productReference = 1D6058910D05DD3D006BFB54 /* ScummVM.app */;
- productType = "com.apple.product-type.application";
- };
- DF093E730F63CB26002D821E /* ScummVM-OS X */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = DF0942270F63CB26002D821E /* Build configuration list for PBXNativeTarget "ScummVM-OS X" */;
- buildPhases = (
- DF093E760F63CB26002D821E /* Resources */,
- DF093E800F63CB26002D821E /* Sources */,
- DF0942180F63CB26002D821E /* Frameworks */,
- DF0942260F63CB26002D821E /* CopyFiles */,
- );
- buildRules = (
- );
- dependencies = (
- );
- name = "ScummVM-OS X";
- productName = scummvm;
- productReference = DF09422A0F63CB26002D821E /* ScummVM.app */;
- productType = "com.apple.product-type.application";
- };
- DFF959090FB22D5700A3EC78 /* ScummVM-Simulator */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = DFF95CC70FB22D5700A3EC78 /* Build configuration list for PBXNativeTarget "ScummVM-Simulator" */;
- buildPhases = (
- DFF9590C0FB22D5700A3EC78 /* Resources */,
- DFF959160FB22D5700A3EC78 /* Sources */,
- DFF95CBB0FB22D5700A3EC78 /* Frameworks */,
- DFF95CC60FB22D5700A3EC78 /* CopyFiles */,
- );
- buildRules = (
- );
- dependencies = (
- );
- name = "ScummVM-Simulator";
- productName = scummvm;
- productReference = DFF95CCA0FB22D5700A3EC78 /* ScummVM.app */;
- productType = "com.apple.product-type.application";
- };
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
- 29B97313FDCFA39411CA2CEA /* Project object */ = {
- isa = PBXProject;
- buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "scummvm" */;
- compatibilityVersion = "Xcode 3.1";
- developmentRegion = English;
- hasScannedForEncodings = 1;
- knownRegions = (
- English,
- Japanese,
- French,
- German,
- );
- mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */;
- projectDirPath = "";
- projectRoot = "";
- targets = (
- 1D6058900D05DD3D006BFB54 /* ScummVM-iPhone */,
- DF093E730F63CB26002D821E /* ScummVM-OS X */,
- DFF959090FB22D5700A3EC78 /* ScummVM-Simulator */,
- );
- };
-/* End PBXProject section */
-
-/* Begin PBXResourcesBuildPhase section */
- 1D60588D0D05DD3D006BFB54 /* Resources */ = {
- isa = PBXResourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- DF2FFD2D0F48719E0006E566 /* scummclassic.zip in Resources */,
- DF7E8C810ED60271001CB19F /* scummmodern.zip in Resources */,
- DFE47C870D81F86900B6D1FB /* kyra.dat in Resources */,
- DFE47C880D81F86900B6D1FB /* lure.dat in Resources */,
- DFE47C890D81F86900B6D1FB /* queen.tbl in Resources */,
- DFE47C8B0D81F86900B6D1FB /* sky.cpt in Resources */,
- DF2FFD2B0F48717F0006E566 /* Default.png in Resources */,
- DF2FFD2C0F48717F0006E566 /* icon.png in Resources */,
- DF895C34124C26660077F6E8 /* icon-72.png in Resources */,
- DF895C41124C271F0077F6E8 /* icon4.png in Resources */,
- 8CB5A9E11253FDF500CB6BC7 /* drascula.dat in Resources */,
- 8CB5A9E21253FDF500CB6BC7 /* hugo.dat in Resources */,
- 8CB5A9E31253FDF500CB6BC7 /* m4.dat in Resources */,
- 8CB5A9E41253FDF500CB6BC7 /* teenagent.dat in Resources */,
- 8CD1ED8A1262030100FA198C /* toon.dat in Resources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- DF093E760F63CB26002D821E /* Resources */ = {
- isa = PBXResourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- DF093E770F63CB26002D821E /* scummclassic.zip in Resources */,
- DF093E780F63CB26002D821E /* scummmodern.zip in Resources */,
- DF093E7A0F63CB26002D821E /* kyra.dat in Resources */,
- DF093E7B0F63CB26002D821E /* lure.dat in Resources */,
- DF093E7C0F63CB26002D821E /* queen.tbl in Resources */,
- DF093E7D0F63CB26002D821E /* sky.cpt in Resources */,
- DF0944B10F6430ED002D821E /* scummvm.icns in Resources */,
- DF895C35124C26660077F6E8 /* icon-72.png in Resources */,
- DF895C42124C271F0077F6E8 /* icon4.png in Resources */,
- 8CB5A9DD1253FDF500CB6BC7 /* drascula.dat in Resources */,
- 8CB5A9DE1253FDF500CB6BC7 /* hugo.dat in Resources */,
- 8CB5A9DF1253FDF500CB6BC7 /* m4.dat in Resources */,
- 8CB5A9E01253FDF500CB6BC7 /* teenagent.dat in Resources */,
- 8CD1ED891262030100FA198C /* toon.dat in Resources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- DFF9590C0FB22D5700A3EC78 /* Resources */ = {
- isa = PBXResourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- DFF9590D0FB22D5700A3EC78 /* scummclassic.zip in Resources */,
- DFF9590E0FB22D5700A3EC78 /* scummmodern.zip in Resources */,
- DFF959100FB22D5700A3EC78 /* kyra.dat in Resources */,
- DFF959110FB22D5700A3EC78 /* lure.dat in Resources */,
- DFF959120FB22D5700A3EC78 /* queen.tbl in Resources */,
- DFF959130FB22D5700A3EC78 /* sky.cpt in Resources */,
- DFF959140FB22D5700A3EC78 /* Default.png in Resources */,
- DFF959150FB22D5700A3EC78 /* icon.png in Resources */,
- DF895C36124C26660077F6E8 /* icon-72.png in Resources */,
- DF895C43124C271F0077F6E8 /* icon4.png in Resources */,
- 8CB5A9D91253FDF500CB6BC7 /* drascula.dat in Resources */,
- 8CB5A9DA1253FDF500CB6BC7 /* hugo.dat in Resources */,
- 8CB5A9DB1253FDF500CB6BC7 /* m4.dat in Resources */,
- 8CB5A9DC1253FDF500CB6BC7 /* teenagent.dat in Resources */,
- 8CD1ED881262030100FA198C /* toon.dat in Resources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXResourcesBuildPhase section */
-
-/* Begin PBXSourcesBuildPhase section */
- 1D60588E0D05DD3D006BFB54 /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- DFE470CE0D81F4BA00B6D1FB /* commandLine.cpp in Sources */,
- DFE470D10D81F4BA00B6D1FB /* main.cpp in Sources */,
- DFE470D30D81F4BA00B6D1FB /* plugins.cpp in Sources */,
- DFE470D40D81F4BA00B6D1FB /* version.cpp in Sources */,
- DFE4782B0D81F4E900B6D1FB /* default-events.cpp in Sources */,
- DFE478380D81F4E900B6D1FB /* posix-fs-factory.cpp in Sources */,
- DFE478C50D81F4E900B6D1FB /* iphone_main.m in Sources */,
- DFE479B60D81F4E900B6D1FB /* posix-provider.cpp in Sources */,
- DFE479BA0D81F4E900B6D1FB /* default-saves.cpp in Sources */,
- DFE479BB0D81F4E900B6D1FB /* savefile.cpp in Sources */,
- DFE479BC0D81F4E900B6D1FB /* default-timer.cpp in Sources */,
- DFE479BE0D81F4E900B6D1FB /* config-file.cpp in Sources */,
- DFE479BF0D81F4E900B6D1FB /* config-manager.cpp in Sources */,
- DFE479C00D81F4E900B6D1FB /* file.cpp in Sources */,
- DFE479C10D81F4E900B6D1FB /* fs.cpp in Sources */,
- DFE479C20D81F4E900B6D1FB /* hashmap.cpp in Sources */,
- DFE479C30D81F4E900B6D1FB /* md5.cpp in Sources */,
- DFE479C50D81F4E900B6D1FB /* mutex.cpp in Sources */,
- DFE479C60D81F4E900B6D1FB /* str.cpp in Sources */,
- DFE479C70D81F4E900B6D1FB /* stream.cpp in Sources */,
- DFE479C80D81F4E900B6D1FB /* system.cpp in Sources */,
- DFE479CA0D81F4E900B6D1FB /* util.cpp in Sources */,
- DFE479CB0D81F4E900B6D1FB /* zlib.cpp in Sources */,
- DFE47BFB0D81F4E900B6D1FB /* cursorman.cpp in Sources */,
- DFE47BFD0D81F4E900B6D1FB /* font.cpp in Sources */,
- DFE47BFE0D81F4E900B6D1FB /* fontman.cpp in Sources */,
- DFE47BFF0D81F4E900B6D1FB /* consolefont.cpp in Sources */,
- DFE47C000D81F4E900B6D1FB /* newfont.cpp in Sources */,
- DFE47C010D81F4E900B6D1FB /* newfont_big.cpp in Sources */,
- DFE47C030D81F4E900B6D1FB /* iff.cpp in Sources */,
- DFE47C040D81F4E900B6D1FB /* imagedec.cpp in Sources */,
- DFE47C080D81F4E900B6D1FB /* primitives.cpp in Sources */,
- DFE47C1B0D81F4E900B6D1FB /* surface.cpp in Sources */,
- DFE47C1C0D81F4E900B6D1FB /* about.cpp in Sources */,
- DFE47C1D0D81F4E900B6D1FB /* Actions.cpp in Sources */,
- DFE47C1E0D81F4E900B6D1FB /* browser.cpp in Sources */,
- DFE47C1F0D81F4E900B6D1FB /* chooser.cpp in Sources */,
- DFE47C200D81F4E900B6D1FB /* console.cpp in Sources */,
- DFE47C210D81F4E900B6D1FB /* debugger.cpp in Sources */,
- DFE47C220D81F4E900B6D1FB /* dialog.cpp in Sources */,
- DFE47C260D81F4E900B6D1FB /* Key.cpp in Sources */,
- DFE47C280D81F4E900B6D1FB /* launcher.cpp in Sources */,
- DFE47C2A0D81F4E900B6D1FB /* massadd.cpp in Sources */,
- DFE47C2B0D81F4E900B6D1FB /* message.cpp in Sources */,
- DFE47C2E0D81F4E900B6D1FB /* object.cpp in Sources */,
- DFE47C2F0D81F4E900B6D1FB /* options.cpp in Sources */,
- DFE47C350D81F4E900B6D1FB /* themebrowser.cpp in Sources */,
- DFE47C3B0D81F4E900B6D1FB /* widget.cpp in Sources */,
- DFD511480DF3383500854012 /* memorypool.cpp in Sources */,
- DFD517E20DF33CAC00854012 /* seq.cpp in Sources */,
- DFD5183D0DF3411800854012 /* scaler.cpp in Sources */,
- DFD518A20DF34B2500854012 /* scalebit.cpp in Sources */,
- DFD518BC0DF34BA600854012 /* 2xsai.cpp in Sources */,
- DFD518BD0DF34BA600854012 /* aspect.cpp in Sources */,
- DFD518C50DF34BA600854012 /* scale2x.cpp in Sources */,
- DFD518C70DF34BA600854012 /* scale3x.cpp in Sources */,
- DF841FDD0E7BA61800F5680E /* iphone_keyboard.m in Sources */,
- DF841FDE0E7BA61800F5680E /* iphone_video.m in Sources */,
- DF84250A0E7BA6AC00F5680E /* agi.cpp in Sources */,
- DF84250B0E7BA6AC00F5680E /* checks.cpp in Sources */,
- DF84250C0E7BA6AC00F5680E /* console.cpp in Sources */,
- DF84250D0E7BA6AC00F5680E /* cycle.cpp in Sources */,
- DF84250E0E7BA6AC00F5680E /* detection.cpp in Sources */,
- DF84250F0E7BA6AC00F5680E /* global.cpp in Sources */,
- DF8425100E7BA6AC00F5680E /* graphics.cpp in Sources */,
- DF8425110E7BA6AC00F5680E /* id.cpp in Sources */,
- DF8425120E7BA6AC00F5680E /* inv.cpp in Sources */,
- DF8425130E7BA6AC00F5680E /* keyboard.cpp in Sources */,
- DF8425140E7BA6AC00F5680E /* loader_v2.cpp in Sources */,
- DF8425150E7BA6AC00F5680E /* loader_v3.cpp in Sources */,
- DF8425160E7BA6AC00F5680E /* logic.cpp in Sources */,
- DF8425170E7BA6AC00F5680E /* lzw.cpp in Sources */,
- DF8425180E7BA6AC00F5680E /* menu.cpp in Sources */,
- DF84251A0E7BA6AC00F5680E /* motion.cpp in Sources */,
- DF84251B0E7BA6AC00F5680E /* objects.cpp in Sources */,
- DF84251C0E7BA6AC00F5680E /* op_cmd.cpp in Sources */,
- DF84251D0E7BA6AC00F5680E /* op_dbg.cpp in Sources */,
- DF84251E0E7BA6AC00F5680E /* op_test.cpp in Sources */,
- DF84251F0E7BA6AC00F5680E /* picture.cpp in Sources */,
- DF8425200E7BA6AC00F5680E /* preagi.cpp in Sources */,
- DF8425210E7BA6AC00F5680E /* preagi_common.cpp in Sources */,
- DF8425220E7BA6AC00F5680E /* preagi_mickey.cpp in Sources */,
- DF8425230E7BA6AC00F5680E /* preagi_troll.cpp in Sources */,
- DF8425240E7BA6AC00F5680E /* preagi_winnie.cpp in Sources */,
- DF8425250E7BA6AC00F5680E /* predictive.cpp in Sources */,
- DF8425260E7BA6AC00F5680E /* saveload.cpp in Sources */,
- DF8425270E7BA6AC00F5680E /* sound.cpp in Sources */,
- DF8425280E7BA6AC00F5680E /* sprite.cpp in Sources */,
- DF8425290E7BA6AC00F5680E /* text.cpp in Sources */,
- DF84252A0E7BA6AC00F5680E /* view.cpp in Sources */,
- DF84252B0E7BA6AC00F5680E /* wagparser.cpp in Sources */,
- DF84252C0E7BA6AC00F5680E /* words.cpp in Sources */,
- DF84252D0E7BA6AC00F5680E /* agos.cpp in Sources */,
- DF84252E0E7BA6AC00F5680E /* animation.cpp in Sources */,
- DF84252F0E7BA6AC00F5680E /* charset-fontdata.cpp in Sources */,
- DF8425300E7BA6AC00F5680E /* charset.cpp in Sources */,
- DF8425310E7BA6AC00F5680E /* contain.cpp in Sources */,
- DF8425320E7BA6AC00F5680E /* cursor.cpp in Sources */,
- DF8425330E7BA6AC00F5680E /* debug.cpp in Sources */,
- DF8425340E7BA6AC00F5680E /* debugger.cpp in Sources */,
- DF8425350E7BA6AC00F5680E /* detection.cpp in Sources */,
- DF8425360E7BA6AC00F5680E /* draw.cpp in Sources */,
- DF8425370E7BA6AC00F5680E /* event.cpp in Sources */,
- DF8425380E7BA6AC00F5680E /* gfx.cpp in Sources */,
- DF8425390E7BA6AC00F5680E /* icons.cpp in Sources */,
- DF84253A0E7BA6AC00F5680E /* input.cpp in Sources */,
- DF84253B0E7BA6AC00F5680E /* items.cpp in Sources */,
- DF84253C0E7BA6AC00F5680E /* menus.cpp in Sources */,
- DF84253D0E7BA6AC00F5680E /* midi.cpp in Sources */,
- DF84253E0E7BA6AC00F5680E /* midiparser_s1d.cpp in Sources */,
- DF8425400E7BA6AC00F5680E /* oracle.cpp in Sources */,
- DF8425410E7BA6AC00F5680E /* res.cpp in Sources */,
- DF8425420E7BA6AC00F5680E /* res_ami.cpp in Sources */,
- DF8425430E7BA6AC00F5680E /* res_snd.cpp in Sources */,
- DF8425440E7BA6AC00F5680E /* rooms.cpp in Sources */,
- DF8425450E7BA6AC00F5680E /* saveload.cpp in Sources */,
- DF8425460E7BA6AC00F5680E /* script.cpp in Sources */,
- DF8425470E7BA6AC00F5680E /* script_e1.cpp in Sources */,
- DF8425480E7BA6AC00F5680E /* script_e2.cpp in Sources */,
- DF8425490E7BA6AC00F5680E /* script_ff.cpp in Sources */,
- DF84254A0E7BA6AC00F5680E /* script_pp.cpp in Sources */,
- DF84254B0E7BA6AC00F5680E /* script_s1.cpp in Sources */,
- DF84254C0E7BA6AC00F5680E /* script_s2.cpp in Sources */,
- DF84254D0E7BA6AC00F5680E /* script_ww.cpp in Sources */,
- DF84254E0E7BA6AC00F5680E /* sound.cpp in Sources */,
- DF84254F0E7BA6AC00F5680E /* string.cpp in Sources */,
- DF8425500E7BA6AC00F5680E /* subroutine.cpp in Sources */,
- DF8425510E7BA6AC00F5680E /* verb.cpp in Sources */,
- DF8425520E7BA6AC00F5680E /* vga.cpp in Sources */,
- DF8425530E7BA6AC00F5680E /* vga_e2.cpp in Sources */,
- DF8425540E7BA6AC00F5680E /* vga_ff.cpp in Sources */,
- DF8425550E7BA6AC00F5680E /* vga_s1.cpp in Sources */,
- DF8425560E7BA6AC00F5680E /* vga_s2.cpp in Sources */,
- DF8425570E7BA6AC00F5680E /* vga_ww.cpp in Sources */,
- DF8425580E7BA6AC00F5680E /* window.cpp in Sources */,
- DF8425590E7BA6AC00F5680E /* zones.cpp in Sources */,
- DF84255A0E7BA6AC00F5680E /* anim.cpp in Sources */,
- DF84255B0E7BA6AC00F5680E /* bg.cpp in Sources */,
- DF84255C0E7BA6AC00F5680E /* bg_list.cpp in Sources */,
- DF84255D0E7BA6AC00F5680E /* cine.cpp in Sources */,
- DF84255E0E7BA6AC00F5680E /* detection.cpp in Sources */,
- DF84255F0E7BA6AC00F5680E /* gfx.cpp in Sources */,
- DF8425600E7BA6AC00F5680E /* main_loop.cpp in Sources */,
- DF8425620E7BA6AC00F5680E /* msg.cpp in Sources */,
- DF8425630E7BA6AC00F5680E /* object.cpp in Sources */,
- DF8425640E7BA6AC00F5680E /* pal.cpp in Sources */,
- DF8425650E7BA6AC00F5680E /* part.cpp in Sources */,
- DF8425660E7BA6AC00F5680E /* prc.cpp in Sources */,
- DF8425670E7BA6AC00F5680E /* rel.cpp in Sources */,
- DF8425680E7BA6AC00F5680E /* script_fw.cpp in Sources */,
- DF8425690E7BA6AC00F5680E /* script_os.cpp in Sources */,
- DF84256A0E7BA6AC00F5680E /* sound.cpp in Sources */,
- DF84256B0E7BA6AC00F5680E /* texte.cpp in Sources */,
- DF84256C0E7BA6AC00F5680E /* unpack.cpp in Sources */,
- DF84256D0E7BA6AC00F5680E /* various.cpp in Sources */,
- DF84258D0E7BA6AC00F5680E /* actor.cpp in Sources */,
- DF84258F0E7BA6AC00F5680E /* background.cpp in Sources */,
- DF8425910E7BA6AC00F5680E /* backgroundIncrust.cpp in Sources */,
- DF8425930E7BA6AC00F5680E /* cell.cpp in Sources */,
- DF8425950E7BA6AC00F5680E /* cruise.cpp in Sources */,
- DF8425970E7BA6AC00F5680E /* cruise_main.cpp in Sources */,
- DF8425990E7BA6AC00F5680E /* ctp.cpp in Sources */,
- DF84259B0E7BA6AC00F5680E /* dataLoader.cpp in Sources */,
- DF84259D0E7BA6AC00F5680E /* decompiler.cpp in Sources */,
- DF84259F0E7BA6AC00F5680E /* delphine-unpack.cpp in Sources */,
- DF8425A10E7BA6AC00F5680E /* detection.cpp in Sources */,
- DF8425A30E7BA6AC00F5680E /* font.cpp in Sources */,
- DF8425A70E7BA6AC00F5680E /* function.cpp in Sources */,
- DF8425A90E7BA6AC00F5680E /* gfxModule.cpp in Sources */,
- DF8425AC0E7BA6AC00F5680E /* linker.cpp in Sources */,
- DF8425AE0E7BA6AC00F5680E /* mainDraw.cpp in Sources */,
- DF8425B00E7BA6AC00F5680E /* menu.cpp in Sources */,
- DF8425B30E7BA6AC00F5680E /* mouse.cpp in Sources */,
- DF8425B50E7BA6AC00F5680E /* object.cpp in Sources */,
- DF8425B70E7BA6AC00F5680E /* overlay.cpp in Sources */,
- DF8425B90E7BA6AC00F5680E /* perso.cpp in Sources */,
- DF8425BB0E7BA6AC00F5680E /* polys.cpp in Sources */,
- DF8425BD0E7BA6AC00F5680E /* saveload.cpp in Sources */,
- DF8425BF0E7BA6AC00F5680E /* script.cpp in Sources */,
- DF8425C10E7BA6AC00F5680E /* stack.cpp in Sources */,
- DF8425C40E7BA6AC00F5680E /* various.cpp in Sources */,
- DF8425C60E7BA6AC00F5680E /* vars.cpp in Sources */,
- DF8425C80E7BA6AC00F5680E /* volume.cpp in Sources */,
- DF8425CA0E7BA6AC00F5680E /* dialogs.cpp in Sources */,
- DF8425CB0E7BA6AC00F5680E /* actors.cpp in Sources */,
- DF8425CC0E7BA6AC00F5680E /* animation.cpp in Sources */,
- DF8425CD0E7BA6AC00F5680E /* converse.cpp in Sources */,
- DF8425CE0E7BA6AC00F5680E /* detection.cpp in Sources */,
- DF8425CF0E7BA6AC00F5680E /* drascula.cpp in Sources */,
- DF8425D00E7BA6AC00F5680E /* graphics.cpp in Sources */,
- DF8425D10E7BA6AC00F5680E /* interface.cpp in Sources */,
- DF8425D30E7BA6AC00F5680E /* objects.cpp in Sources */,
- DF8425D40E7BA6AC00F5680E /* palette.cpp in Sources */,
- DF8425D50E7BA6AC00F5680E /* rooms.cpp in Sources */,
- DF8425D60E7BA6AC00F5680E /* saveload.cpp in Sources */,
- DF8425D70E7BA6AC00F5680E /* sound.cpp in Sources */,
- DF8425D80E7BA6AC00F5680E /* talk.cpp in Sources */,
- DF8425D90E7BA6AC00F5680E /* engine.cpp in Sources */,
- DF8425DD0E7BA6AC00F5680E /* dataio.cpp in Sources */,
- DF8425DE0E7BA6AC00F5680E /* detection.cpp in Sources */,
- DF8425DF0E7BA6AC00F5680E /* draw.cpp in Sources */,
- DF8425E00E7BA6AC00F5680E /* draw_bargon.cpp in Sources */,
- DF8425E10E7BA6AC00F5680E /* draw_v1.cpp in Sources */,
- DF8425E20E7BA6AC00F5680E /* draw_v2.cpp in Sources */,
- DF8425E40E7BA6AC00F5680E /* game.cpp in Sources */,
- DF8425E70E7BA6AC00F5680E /* global.cpp in Sources */,
- DF8425E80E7BA6AC00F5680E /* gob.cpp in Sources */,
- DF8425E90E7BA6AC00F5680E /* goblin.cpp in Sources */,
- DF8425EA0E7BA6AC00F5680E /* goblin_v1.cpp in Sources */,
- DF8425EB0E7BA6AC00F5680E /* goblin_v2.cpp in Sources */,
- DF8425EC0E7BA6AC00F5680E /* goblin_v3.cpp in Sources */,
- DF8425ED0E7BA6AC00F5680E /* goblin_v4.cpp in Sources */,
- DF8425EE0E7BA6AC00F5680E /* init.cpp in Sources */,
- DF8425EF0E7BA6AC00F5680E /* init_v1.cpp in Sources */,
- DF8425F00E7BA6AC00F5680E /* init_v2.cpp in Sources */,
- DF8425F10E7BA6AC00F5680E /* init_v3.cpp in Sources */,
- DF8425F20E7BA6AC00F5680E /* inter.cpp in Sources */,
- DF8425F30E7BA6AC00F5680E /* inter_bargon.cpp in Sources */,
- DF8425F40E7BA6AC00F5680E /* inter_v1.cpp in Sources */,
- DF8425F50E7BA6AC00F5680E /* inter_v2.cpp in Sources */,
- DF8425F60E7BA6AC00F5680E /* inter_v3.cpp in Sources */,
- DF8425F70E7BA6AC00F5680E /* inter_v4.cpp in Sources */,
- DF8425F80E7BA6AC00F5680E /* inter_v5.cpp in Sources */,
- DF8425F90E7BA6AC00F5680E /* inter_v6.cpp in Sources */,
- DF8425FA0E7BA6AC00F5680E /* map.cpp in Sources */,
- DF8425FB0E7BA6AC00F5680E /* map_v1.cpp in Sources */,
- DF8425FC0E7BA6AC00F5680E /* map_v2.cpp in Sources */,
- DF8425FF0E7BA6AC00F5680E /* mult.cpp in Sources */,
- DF8426000E7BA6AC00F5680E /* mult_v1.cpp in Sources */,
- DF8426010E7BA6AC00F5680E /* mult_v2.cpp in Sources */,
- DF8426030E7BA6AC00F5680E /* palanim.cpp in Sources */,
- DF84260B0E7BA6AC00F5680E /* scenery.cpp in Sources */,
- DF84260C0E7BA6AC00F5680E /* scenery_v1.cpp in Sources */,
- DF84260D0E7BA6AC00F5680E /* scenery_v2.cpp in Sources */,
- DF84260E0E7BA6AC00F5680E /* adlib.cpp in Sources */,
- DF84260F0E7BA6AC00F5680E /* bgatmosphere.cpp in Sources */,
- DF8426100E7BA6AC00F5680E /* cdrom.cpp in Sources */,
- DF8426110E7BA6AC00F5680E /* infogrames.cpp in Sources */,
- DF8426120E7BA6AC00F5680E /* pcspeaker.cpp in Sources */,
- DF8426130E7BA6AC00F5680E /* sound.cpp in Sources */,
- DF8426140E7BA6AC00F5680E /* soundblaster.cpp in Sources */,
- DF8426150E7BA6AC00F5680E /* sounddesc.cpp in Sources */,
- DF8426160E7BA6AC00F5680E /* soundmixer.cpp in Sources */,
- DF8426180E7BA6AC00F5680E /* util.cpp in Sources */,
- DF8426190E7BA6AC00F5680E /* variables.cpp in Sources */,
- DF84261A0E7BA6AC00F5680E /* video.cpp in Sources */,
- DF84261B0E7BA6AC00F5680E /* video_v1.cpp in Sources */,
- DF84261C0E7BA6AC00F5680E /* video_v2.cpp in Sources */,
- DF84261D0E7BA6AC00F5680E /* video_v6.cpp in Sources */,
- DF84261E0E7BA6AC00F5680E /* videoplayer.cpp in Sources */,
- DF8426430E7BA6AC00F5680E /* animator_hof.cpp in Sources */,
- DF8426440E7BA6AC00F5680E /* animator_lok.cpp in Sources */,
- DF8426450E7BA6AC00F5680E /* animator_mr.cpp in Sources */,
- DF8426470E7BA6AC00F5680E /* animator_v2.cpp in Sources */,
- DF8426490E7BA6AC00F5680E /* debugger.cpp in Sources */,
- DF84264A0E7BA6AC00F5680E /* detection.cpp in Sources */,
- DF84264B0E7BA6AC00F5680E /* gui.cpp in Sources */,
- DF84264C0E7BA6AC00F5680E /* gui_hof.cpp in Sources */,
- DF84264D0E7BA6AC00F5680E /* gui_lok.cpp in Sources */,
- DF84264E0E7BA6AC00F5680E /* gui_mr.cpp in Sources */,
- DF8426500E7BA6AC00F5680E /* gui_v2.cpp in Sources */,
- DF8426520E7BA6AC00F5680E /* items_hof.cpp in Sources */,
- DF8426530E7BA6AC00F5680E /* items_lok.cpp in Sources */,
- DF8426540E7BA6AC00F5680E /* items_mr.cpp in Sources */,
- DF8426560E7BA6AC00F5680E /* items_v2.cpp in Sources */,
- DF8426590E7BA6AC00F5680E /* kyra_hof.cpp in Sources */,
- DF84265A0E7BA6AC00F5680E /* kyra_lok.cpp in Sources */,
- DF84265B0E7BA6AC00F5680E /* kyra_mr.cpp in Sources */,
- DF84265C0E7BA6AC00F5680E /* kyra_v1.cpp in Sources */,
- DF84265D0E7BA6AC00F5680E /* kyra_v2.cpp in Sources */,
- DF84265F0E7BA6AC00F5680E /* lol.cpp in Sources */,
- DF8426610E7BA6AC00F5680E /* resource.cpp in Sources */,
- DF8426620E7BA6AC00F5680E /* resource_intern.cpp in Sources */,
- DF8426630E7BA6AC00F5680E /* saveload.cpp in Sources */,
- DF8426640E7BA6AC00F5680E /* saveload_hof.cpp in Sources */,
- DF8426650E7BA6AC00F5680E /* saveload_lok.cpp in Sources */,
- DF8426660E7BA6AC00F5680E /* saveload_mr.cpp in Sources */,
- DF84266A0E7BA6AC00F5680E /* scene_hof.cpp in Sources */,
- DF84266B0E7BA6AC00F5680E /* scene_lok.cpp in Sources */,
- DF84266C0E7BA6AC00F5680E /* scene_mr.cpp in Sources */,
- DF84266D0E7BA6AC00F5680E /* scene_v1.cpp in Sources */,
- DF84266E0E7BA6AC00F5680E /* scene_v2.cpp in Sources */,
- DF8426700E7BA6AC00F5680E /* screen.cpp in Sources */,
- DF8426710E7BA6AC00F5680E /* screen_hof.cpp in Sources */,
- DF8426720E7BA6AC00F5680E /* screen_lok.cpp in Sources */,
- DF8426730E7BA6AC00F5680E /* screen_lol.cpp in Sources */,
- DF8426740E7BA6AC00F5680E /* screen_mr.cpp in Sources */,
- DF8426760E7BA6AC00F5680E /* screen_v2.cpp in Sources */,
- DF8426780E7BA6AC00F5680E /* script.cpp in Sources */,
- DF8426790E7BA6AC00F5680E /* script_hof.cpp in Sources */,
- DF84267A0E7BA6AC00F5680E /* script_lok.cpp in Sources */,
- DF84267B0E7BA6AC00F5680E /* script_mr.cpp in Sources */,
- DF84267C0E7BA6AC00F5680E /* script_tim.cpp in Sources */,
- DF84267D0E7BA6AC00F5680E /* script_v1.cpp in Sources */,
- DF84267E0E7BA6AC00F5680E /* script_v2.cpp in Sources */,
- DF8426800E7BA6AC00F5680E /* seqplayer.cpp in Sources */,
- DF8426810E7BA6AC00F5680E /* sequences_hof.cpp in Sources */,
- DF8426820E7BA6AC00F5680E /* sequences_lok.cpp in Sources */,
- DF8426830E7BA6AC00F5680E /* sequences_mr.cpp in Sources */,
- DF8426850E7BA6AC00F5680E /* sequences_v2.cpp in Sources */,
- DF8426870E7BA6AC00F5680E /* sound.cpp in Sources */,
- DF8426880E7BA6AC00F5680E /* sound_adlib.cpp in Sources */,
- DF8426890E7BA6AC00F5680E /* sound_digital.cpp in Sources */,
- DF84268A0E7BA6AC00F5680E /* sound_lok.cpp in Sources */,
- DF84268B0E7BA6AC00F5680E /* sound_towns.cpp in Sources */,
- DF84268D0E7BA6AC00F5680E /* sprites.cpp in Sources */,
- DF84268E0E7BA6AC00F5680E /* staticres.cpp in Sources */,
- DF84268F0E7BA6AC00F5680E /* text.cpp in Sources */,
- DF8426900E7BA6AC00F5680E /* text_hof.cpp in Sources */,
- DF8426910E7BA6AC00F5680E /* text_lok.cpp in Sources */,
- DF8426920E7BA6AC00F5680E /* text_mr.cpp in Sources */,
- DF8426960E7BA6AC00F5680E /* timer.cpp in Sources */,
- DF8426970E7BA6AC00F5680E /* timer_hof.cpp in Sources */,
- DF8426980E7BA6AC00F5680E /* timer_lok.cpp in Sources */,
- DF8426990E7BA6AC00F5680E /* timer_mr.cpp in Sources */,
- DF84269D0E7BA6AC00F5680E /* vqa.cpp in Sources */,
- DF84269E0E7BA6AC00F5680E /* wsamovie.cpp in Sources */,
- DF84269F0E7BA6AC00F5680E /* animseq.cpp in Sources */,
- DF8426A00E7BA6AC00F5680E /* debugger.cpp in Sources */,
- DF8426A10E7BA6AC00F5680E /* decode.cpp in Sources */,
- DF8426A20E7BA6AC00F5680E /* detection.cpp in Sources */,
- DF8426A30E7BA6AC00F5680E /* disk.cpp in Sources */,
- DF8426A40E7BA6AC00F5680E /* events.cpp in Sources */,
- DF8426A50E7BA6AC00F5680E /* fights.cpp in Sources */,
- DF8426A60E7BA6AC00F5680E /* game.cpp in Sources */,
- DF8426A70E7BA6AC00F5680E /* hotspots.cpp in Sources */,
- DF8426A80E7BA6AC00F5680E /* intro.cpp in Sources */,
- DF8426A90E7BA6AC00F5680E /* lure.cpp in Sources */,
- DF8426AA0E7BA6AC00F5680E /* memory.cpp in Sources */,
- DF8426AB0E7BA6AC00F5680E /* menu.cpp in Sources */,
- DF8426AD0E7BA6AC00F5680E /* palette.cpp in Sources */,
- DF8426AE0E7BA6AC00F5680E /* res.cpp in Sources */,
- DF8426AF0E7BA6AC00F5680E /* res_struct.cpp in Sources */,
- DF8426B00E7BA6AC00F5680E /* room.cpp in Sources */,
- DF8426B10E7BA6AC00F5680E /* screen.cpp in Sources */,
- DF8426B20E7BA6AC00F5680E /* scripts.cpp in Sources */,
- DF8426B30E7BA6AC00F5680E /* sound.cpp in Sources */,
- DF8426B40E7BA6AC00F5680E /* strings.cpp in Sources */,
- DF8426B50E7BA6AC00F5680E /* surface.cpp in Sources */,
- DF8426D40E7BA6AC00F5680E /* actor.cpp in Sources */,
- DF8426D60E7BA6AC00F5680E /* animation.cpp in Sources */,
- DF8426D80E7BA6AC00F5680E /* assets.cpp in Sources */,
- DF8426DA0E7BA6AC00F5680E /* compression.cpp in Sources */,
- DF8426DC0E7BA6AC00F5680E /* console.cpp in Sources */,
- DF8426DE0E7BA6AC00F5680E /* converse.cpp in Sources */,
- DF8426E00E7BA6AC00F5680E /* detection.cpp in Sources */,
- DF8426E20E7BA6AC00F5680E /* events.cpp in Sources */,
- DF8426E40E7BA6AC00F5680E /* font.cpp in Sources */,
- DF8426E60E7BA6AC00F5680E /* globals.cpp in Sources */,
- DF8426E80E7BA6AC00F5680E /* graphics.cpp in Sources */,
- DF8426EA0E7BA6AC00F5680E /* gui.cpp in Sources */,
- DF8426EC0E7BA6AC00F5680E /* hotspot.cpp in Sources */,
- DF8426EF0E7BA6AC00F5680E /* m4.cpp in Sources */,
- DF8426F10E7BA6AC00F5680E /* m4_menus.cpp in Sources */,
- DF8426F30E7BA6AC00F5680E /* m4_views.cpp in Sources */,
- DF8426F50E7BA6AC00F5680E /* mads_anim.cpp in Sources */,
- DF8426F70E7BA6AC00F5680E /* mads_menus.cpp in Sources */,
- DF8426F90E7BA6AC00F5680E /* midi.cpp in Sources */,
- DF8426FC0E7BA6AC00F5680E /* rails.cpp in Sources */,
- DF8426FE0E7BA6AC00F5680E /* resource.cpp in Sources */,
- DF8427000E7BA6AC00F5680E /* saveload.cpp in Sources */,
- DF8427020E7BA6AC00F5680E /* scene.cpp in Sources */,
- DF8427040E7BA6AC00F5680E /* script.cpp in Sources */,
- DF8427060E7BA6AC00F5680E /* sound.cpp in Sources */,
- DF8427080E7BA6AC00F5680E /* sprite.cpp in Sources */,
- DF84270A0E7BA6AC00F5680E /* viewmgr.cpp in Sources */,
- DF84270C0E7BA6AC00F5680E /* woodscript.cpp in Sources */,
- DF84270E0E7BA6AC00F5680E /* ws_machine.cpp in Sources */,
- DF8427100E7BA6AC00F5680E /* ws_sequence.cpp in Sources */,
- DF8427120E7BA6AC00F5680E /* database.cpp in Sources */,
- DF8427130E7BA6AC00F5680E /* detection.cpp in Sources */,
- DF8427140E7BA6AC00F5680E /* graphics.cpp in Sources */,
- DF8427150E7BA6AC00F5680E /* made.cpp in Sources */,
- DF8427170E7BA6AC00F5680E /* music.cpp in Sources */,
- DF8427180E7BA6AC00F5680E /* pmvplayer.cpp in Sources */,
- DF8427190E7BA6AC00F5680E /* redreader.cpp in Sources */,
- DF84271A0E7BA6AC00F5680E /* resource.cpp in Sources */,
- DF84271B0E7BA6AC00F5680E /* screen.cpp in Sources */,
- DF84271C0E7BA6AC00F5680E /* screenfx.cpp in Sources */,
- DF84271D0E7BA6AC00F5680E /* script.cpp in Sources */,
- DF84271E0E7BA6AC00F5680E /* scriptfuncs.cpp in Sources */,
- DF84271F0E7BA6AC00F5680E /* sound.cpp in Sources */,
- DF8427210E7BA6AC00F5680E /* balloons.cpp in Sources */,
- DF8427220E7BA6AC00F5680E /* callables_br.cpp in Sources */,
- DF8427230E7BA6AC00F5680E /* callables_ns.cpp in Sources */,
- DF8427240E7BA6AC00F5680E /* debug.cpp in Sources */,
- DF8427250E7BA6AC00F5680E /* detection.cpp in Sources */,
- DF8427260E7BA6AC00F5680E /* dialogue.cpp in Sources */,
- DF8427270E7BA6AC00F5680E /* disk_br.cpp in Sources */,
- DF8427280E7BA6AC00F5680E /* disk_ns.cpp in Sources */,
- DF8427290E7BA6AC00F5680E /* exec_br.cpp in Sources */,
- DF84272A0E7BA6AC00F5680E /* exec_ns.cpp in Sources */,
- DF84272B0E7BA6AC00F5680E /* font.cpp in Sources */,
- DF84272C0E7BA6AC00F5680E /* gfxbase.cpp in Sources */,
- DF84272D0E7BA6AC00F5680E /* graphics.cpp in Sources */,
- DF84272E0E7BA6AC00F5680E /* gui.cpp in Sources */,
- DF84272F0E7BA6AC00F5680E /* gui_br.cpp in Sources */,
- DF8427300E7BA6AC00F5680E /* gui_ns.cpp in Sources */,
- DF8427310E7BA6AC00F5680E /* input.cpp in Sources */,
- DF8427320E7BA6AC00F5680E /* inventory.cpp in Sources */,
- DF8427340E7BA6AC00F5680E /* objects.cpp in Sources */,
- DF8427350E7BA6AC00F5680E /* parallaction.cpp in Sources */,
- DF8427360E7BA6AC00F5680E /* parallaction_br.cpp in Sources */,
- DF8427370E7BA6AC00F5680E /* parallaction_ns.cpp in Sources */,
- DF8427380E7BA6AC00F5680E /* parser.cpp in Sources */,
- DF8427390E7BA6AC00F5680E /* parser_br.cpp in Sources */,
- DF84273A0E7BA6AC00F5680E /* parser_ns.cpp in Sources */,
- DF84273B0E7BA6AC00F5680E /* saveload.cpp in Sources */,
- DF84273D0E7BA6AC00F5680E /* staticres.cpp in Sources */,
- DF84273E0E7BA6AC00F5680E /* walk.cpp in Sources */,
- DF84273F0E7BA6AC00F5680E /* bankman.cpp in Sources */,
- DF8427400E7BA6AC00F5680E /* command.cpp in Sources */,
- DF8427410E7BA6AC00F5680E /* credits.cpp in Sources */,
- DF8427420E7BA6AC00F5680E /* cutaway.cpp in Sources */,
- DF8427430E7BA6AC00F5680E /* debug.cpp in Sources */,
- DF8427440E7BA6AC00F5680E /* display.cpp in Sources */,
- DF8427450E7BA6AC00F5680E /* graphics.cpp in Sources */,
- DF8427460E7BA6AC00F5680E /* grid.cpp in Sources */,
- DF8427470E7BA6AC00F5680E /* input.cpp in Sources */,
- DF8427480E7BA6AC00F5680E /* journal.cpp in Sources */,
- DF8427490E7BA6AC00F5680E /* logic.cpp in Sources */,
- DF84274A0E7BA6AC00F5680E /* midiadlib.cpp in Sources */,
- DF84274C0E7BA6AC00F5680E /* music.cpp in Sources */,
- DF84274D0E7BA6AC00F5680E /* musicdata.cpp in Sources */,
- DF84274E0E7BA6AC00F5680E /* queen.cpp in Sources */,
- DF84274F0E7BA6AC00F5680E /* resource.cpp in Sources */,
- DF8427500E7BA6AC00F5680E /* restables.cpp in Sources */,
- DF8427510E7BA6AC00F5680E /* sound.cpp in Sources */,
- DF8427520E7BA6AC00F5680E /* state.cpp in Sources */,
- DF8427530E7BA6AC00F5680E /* talk.cpp in Sources */,
- DF8427540E7BA6AC00F5680E /* walk.cpp in Sources */,
- DF8427560E7BA6AC00F5680E /* actor.cpp in Sources */,
- DF8427570E7BA6AC00F5680E /* actor_path.cpp in Sources */,
- DF8427580E7BA6AC00F5680E /* actor_walk.cpp in Sources */,
- DF8427590E7BA6AC00F5680E /* animation.cpp in Sources */,
- DF84275A0E7BA6AC00F5680E /* console.cpp in Sources */,
- DF84275B0E7BA6AC00F5680E /* detection.cpp in Sources */,
- DF84275C0E7BA6AC00F5680E /* events.cpp in Sources */,
- DF84275D0E7BA6AC00F5680E /* font.cpp in Sources */,
- DF84275E0E7BA6AC00F5680E /* font_map.cpp in Sources */,
- DF84275F0E7BA6AC00F5680E /* gfx.cpp in Sources */,
- DF8427610E7BA6AC00F5680E /* image.cpp in Sources */,
- DF8427620E7BA6AC00F5680E /* input.cpp in Sources */,
- DF8427630E7BA6AC00F5680E /* interface.cpp in Sources */,
- DF8427640E7BA6AC00F5680E /* introproc_ihnm.cpp in Sources */,
- DF8427650E7BA6AC00F5680E /* introproc_ite.cpp in Sources */,
- DF8427660E7BA6AC00F5680E /* isomap.cpp in Sources */,
- DF8427680E7BA6AC00F5680E /* itedata.cpp in Sources */,
- DF84276A0E7BA6AC00F5680E /* music.cpp in Sources */,
- DF84276B0E7BA6AC00F5680E /* objectmap.cpp in Sources */,
- DF84276C0E7BA6AC00F5680E /* palanim.cpp in Sources */,
- DF84276D0E7BA6AC00F5680E /* puzzle.cpp in Sources */,
- DF84276E0E7BA6AC00F5680E /* render.cpp in Sources */,
- DF8427700E7BA6AC00F5680E /* saga.cpp in Sources */,
- DF8427710E7BA6AC00F5680E /* saveload.cpp in Sources */,
- DF8427720E7BA6AC00F5680E /* scene.cpp in Sources */,
- DF8427730E7BA6AC00F5680E /* script.cpp in Sources */,
- DF8427740E7BA6AC00F5680E /* sfuncs.cpp in Sources */,
- DF8427750E7BA6AC00F5680E /* sndres.cpp in Sources */,
- DF8427760E7BA6AC00F5680E /* sound.cpp in Sources */,
- DF8427770E7BA6AC00F5680E /* sprite.cpp in Sources */,
- DF8427780E7BA6AC00F5680E /* sthread.cpp in Sources */,
- DF84277A0E7BA6AC00F5680E /* actor.cpp in Sources */,
- DF84277B0E7BA6AC00F5680E /* akos.cpp in Sources */,
- DF84277C0E7BA6AC00F5680E /* base-costume.cpp in Sources */,
- DF84277D0E7BA6AC00F5680E /* bomp.cpp in Sources */,
- DF84277E0E7BA6AC00F5680E /* boxes.cpp in Sources */,
- DF84277F0E7BA6AC00F5680E /* camera.cpp in Sources */,
- DF8427800E7BA6AC00F5680E /* charset-fontdata.cpp in Sources */,
- DF8427810E7BA6AC00F5680E /* charset.cpp in Sources */,
- DF8427820E7BA6AC00F5680E /* costume.cpp in Sources */,
- DF8427830E7BA6AC00F5680E /* cursor.cpp in Sources */,
- DF8427840E7BA6AC00F5680E /* debugger.cpp in Sources */,
- DF8427850E7BA6AC00F5680E /* detection.cpp in Sources */,
- DF8427860E7BA6AC00F5680E /* dialogs.cpp in Sources */,
- DF8427870E7BA6AC00F5680E /* file.cpp in Sources */,
- DF8427880E7BA6AC00F5680E /* file_nes.cpp in Sources */,
- DF8427890E7BA6AC00F5680E /* gfx.cpp in Sources */,
- DF84278B0E7BA6AC00F5680E /* animation_he.cpp in Sources */,
- DF84278C0E7BA6AC00F5680E /* cup_player_he.cpp in Sources */,
- DF84278D0E7BA6AC00F5680E /* floodfill_he.cpp in Sources */,
- DF84278E0E7BA6AC00F5680E /* logic_he.cpp in Sources */,
- DF84278F0E7BA6AC00F5680E /* palette_he.cpp in Sources */,
- DF8427900E7BA6AC00F5680E /* resource_he.cpp in Sources */,
- DF8427910E7BA6AC00F5680E /* script_v100he.cpp in Sources */,
- DF8427920E7BA6AC00F5680E /* script_v60he.cpp in Sources */,
- DF8427930E7BA6AC00F5680E /* script_v70he.cpp in Sources */,
- DF8427940E7BA6AC00F5680E /* script_v71he.cpp in Sources */,
- DF8427950E7BA6AC00F5680E /* script_v72he.cpp in Sources */,
- DF8427960E7BA6AC00F5680E /* script_v80he.cpp in Sources */,
- DF8427970E7BA6AC00F5680E /* script_v90he.cpp in Sources */,
- DF8427980E7BA6AC00F5680E /* sound_he.cpp in Sources */,
- DF8427990E7BA6AC00F5680E /* sprite_he.cpp in Sources */,
- DF84279A0E7BA6AC00F5680E /* wiz_he.cpp in Sources */,
- DF84279B0E7BA6AC00F5680E /* help.cpp in Sources */,
- DF84279C0E7BA6AC00F5680E /* imuse.cpp in Sources */,
- DF84279D0E7BA6AC00F5680E /* imuse_part.cpp in Sources */,
- DF84279E0E7BA6AC00F5680E /* imuse_player.cpp in Sources */,
- DF84279F0E7BA6AC00F5680E /* instrument.cpp in Sources */,
- DF8427A00E7BA6AC00F5680E /* sysex_samnmax.cpp in Sources */,
- DF8427A10E7BA6AC00F5680E /* sysex_scumm.cpp in Sources */,
- DF8427A20E7BA6AC00F5680E /* dimuse.cpp in Sources */,
- DF8427A30E7BA6AC00F5680E /* dimuse_bndmgr.cpp in Sources */,
- DF8427A40E7BA6AC00F5680E /* dimuse_codecs.cpp in Sources */,
- DF8427A50E7BA6AC00F5680E /* dimuse_music.cpp in Sources */,
- DF8427A60E7BA6AC00F5680E /* dimuse_script.cpp in Sources */,
- DF8427A70E7BA6AC00F5680E /* dimuse_sndmgr.cpp in Sources */,
- DF8427A80E7BA6AC00F5680E /* dimuse_tables.cpp in Sources */,
- DF8427A90E7BA6AC00F5680E /* dimuse_track.cpp in Sources */,
- DF8427AA0E7BA6AC00F5680E /* input.cpp in Sources */,
- DF8427AB0E7BA6AC00F5680E /* insane.cpp in Sources */,
- DF8427AC0E7BA6AC00F5680E /* insane_ben.cpp in Sources */,
- DF8427AD0E7BA6AC00F5680E /* insane_enemy.cpp in Sources */,
- DF8427AE0E7BA6AC00F5680E /* insane_iact.cpp in Sources */,
- DF8427AF0E7BA6AC00F5680E /* insane_scenes.cpp in Sources */,
- DF8427B10E7BA6AC00F5680E /* midiparser_ro.cpp in Sources */,
- DF8427B30E7BA6AC00F5680E /* nut_renderer.cpp in Sources */,
- DF8427B40E7BA6AC00F5680E /* object.cpp in Sources */,
- DF8427B50E7BA6AC00F5680E /* palette.cpp in Sources */,
- DF8427B60E7BA6AC00F5680E /* player_mod.cpp in Sources */,
- DF8427B70E7BA6AC00F5680E /* player_nes.cpp in Sources */,
- DF8427B80E7BA6AC00F5680E /* player_v1.cpp in Sources */,
- DF8427B90E7BA6AC00F5680E /* player_v2.cpp in Sources */,
- DF8427BA0E7BA6AC00F5680E /* player_v2a.cpp in Sources */,
- DF8427BB0E7BA6AC00F5680E /* player_v3a.cpp in Sources */,
- DF8427BD0E7BA6AC00F5680E /* resource.cpp in Sources */,
- DF8427BE0E7BA6AC00F5680E /* resource_v2.cpp in Sources */,
- DF8427BF0E7BA6AC00F5680E /* resource_v3.cpp in Sources */,
- DF8427C00E7BA6AC00F5680E /* resource_v4.cpp in Sources */,
- DF8427C10E7BA6AC00F5680E /* room.cpp in Sources */,
- DF8427C20E7BA6AC00F5680E /* saveload.cpp in Sources */,
- DF8427C30E7BA6AC00F5680E /* script.cpp in Sources */,
- DF8427C40E7BA6AC00F5680E /* script_v0.cpp in Sources */,
- DF8427C50E7BA6AC00F5680E /* script_v2.cpp in Sources */,
- DF8427C60E7BA6AC00F5680E /* script_v5.cpp in Sources */,
- DF8427C70E7BA6AC00F5680E /* script_v6.cpp in Sources */,
- DF8427C80E7BA6AC00F5680E /* script_v8.cpp in Sources */,
- DF8427C90E7BA6AC00F5680E /* scumm.cpp in Sources */,
- DF8427CA0E7BA6AC00F5680E /* channel.cpp in Sources */,
- DF8427CC0E7BA6AC00F5680E /* codec1.cpp in Sources */,
- DF8427CD0E7BA6AC00F5680E /* codec37.cpp in Sources */,
- DF8427CE0E7BA6AC00F5680E /* codec47.cpp in Sources */,
- DF8427D10E7BA6AC00F5680E /* imuse_channel.cpp in Sources */,
- DF8427D20E7BA6AC00F5680E /* saud_channel.cpp in Sources */,
- DF8427D30E7BA6AC00F5680E /* smush_font.cpp in Sources */,
- DF8427D40E7BA6AC00F5680E /* smush_mixer.cpp in Sources */,
- DF8427D50E7BA6AC00F5680E /* smush_player.cpp in Sources */,
- DF8427D60E7BA6AC00F5680E /* sound.cpp in Sources */,
- DF8427D70E7BA6AC00F5680E /* string.cpp in Sources */,
- DF8427D90E7BA6AC00F5680E /* usage_bits.cpp in Sources */,
- DF8427DA0E7BA6AC00F5680E /* util.cpp in Sources */,
- DF8427DB0E7BA6AC00F5680E /* vars.cpp in Sources */,
- DF8427DC0E7BA6AC00F5680E /* verbs.cpp in Sources */,
- DF8427DD0E7BA6AC00F5680E /* autoroute.cpp in Sources */,
- DF8427DE0E7BA6AC00F5680E /* compact.cpp in Sources */,
- DF8427DF0E7BA6AC00F5680E /* control.cpp in Sources */,
- DF8427E00E7BA6AC00F5680E /* debug.cpp in Sources */,
- DF8427E10E7BA6AC00F5680E /* disk.cpp in Sources */,
- DF8427E20E7BA6AC00F5680E /* grid.cpp in Sources */,
- DF8427E30E7BA6AC00F5680E /* hufftext.cpp in Sources */,
- DF8427E40E7BA6AC00F5680E /* intro.cpp in Sources */,
- DF8427E50E7BA6AC00F5680E /* logic.cpp in Sources */,
- DF8427E70E7BA6AC00F5680E /* mouse.cpp in Sources */,
- DF8427E80E7BA6AC00F5680E /* adlibchannel.cpp in Sources */,
- DF8427E90E7BA6AC00F5680E /* adlibmusic.cpp in Sources */,
- DF8427EA0E7BA6AC00F5680E /* gmchannel.cpp in Sources */,
- DF8427EB0E7BA6AC00F5680E /* gmmusic.cpp in Sources */,
- DF8427EC0E7BA6AC00F5680E /* mt32music.cpp in Sources */,
- DF8427ED0E7BA6AC00F5680E /* musicbase.cpp in Sources */,
- DF8427EE0E7BA6AC00F5680E /* rnc_deco.cpp in Sources */,
- DF8427EF0E7BA6AC00F5680E /* screen.cpp in Sources */,
- DF8427F00E7BA6AC00F5680E /* sky.cpp in Sources */,
- DF8427F10E7BA6AC00F5680E /* sound.cpp in Sources */,
- DF8427F20E7BA6AC00F5680E /* text.cpp in Sources */,
- DF8427F30E7BA6AC00F5680E /* animation.cpp in Sources */,
- DF8427F40E7BA6AC00F5680E /* control.cpp in Sources */,
- DF8427F60E7BA6AC00F5680E /* debug.cpp in Sources */,
- DF8427F70E7BA6AC00F5680E /* eventman.cpp in Sources */,
- DF8427F80E7BA6AC00F5680E /* logic.cpp in Sources */,
- DF8427F90E7BA6AC00F5680E /* memman.cpp in Sources */,
- DF8427FA0E7BA6AC00F5680E /* menu.cpp in Sources */,
- DF8427FC0E7BA6AC00F5680E /* mouse.cpp in Sources */,
- DF8427FD0E7BA6AC00F5680E /* music.cpp in Sources */,
- DF8427FE0E7BA6AC00F5680E /* objectman.cpp in Sources */,
- DF8427FF0E7BA6AC00F5680E /* resman.cpp in Sources */,
- DF8428000E7BA6AC00F5680E /* router.cpp in Sources */,
- DF8428010E7BA6AC00F5680E /* screen.cpp in Sources */,
- DF8428020E7BA6AC00F5680E /* sound.cpp in Sources */,
- DF8428030E7BA6AC00F5680E /* staticres.cpp in Sources */,
- DF8428040E7BA6AC00F5680E /* sword1.cpp in Sources */,
- DF8428050E7BA6AC00F5680E /* text.cpp in Sources */,
- DF8428060E7BA6AC00F5680E /* animation.cpp in Sources */,
- DF8428070E7BA6AC00F5680E /* anims.cpp in Sources */,
- DF8428080E7BA6AC00F5680E /* console.cpp in Sources */,
- DF8428090E7BA6AC00F5680E /* controls.cpp in Sources */,
- DF84280A0E7BA6AC00F5680E /* debug.cpp in Sources */,
- DF84280B0E7BA6AC00F5680E /* events.cpp in Sources */,
- DF84280C0E7BA6AC00F5680E /* function.cpp in Sources */,
- DF84280D0E7BA6AC00F5680E /* icons.cpp in Sources */,
- DF84280E0E7BA6AC00F5680E /* interpreter.cpp in Sources */,
- DF84280F0E7BA6AC00F5680E /* layers.cpp in Sources */,
- DF8428100E7BA6AC00F5680E /* logic.cpp in Sources */,
- DF8428110E7BA6AC00F5680E /* maketext.cpp in Sources */,
- DF8428120E7BA6AC00F5680E /* memory.cpp in Sources */,
- DF8428130E7BA6AC00F5680E /* menu.cpp in Sources */,
- DF8428150E7BA6AC00F5680E /* mouse.cpp in Sources */,
- DF8428160E7BA6AC00F5680E /* music.cpp in Sources */,
- DF8428170E7BA6AC00F5680E /* palette.cpp in Sources */,
- DF8428180E7BA6AC00F5680E /* protocol.cpp in Sources */,
- DF8428190E7BA6AC00F5680E /* render.cpp in Sources */,
- DF84281A0E7BA6AC00F5680E /* resman.cpp in Sources */,
- DF84281B0E7BA6AC00F5680E /* router.cpp in Sources */,
- DF84281C0E7BA6AC00F5680E /* saveload.cpp in Sources */,
- DF84281D0E7BA6AC00F5680E /* screen.cpp in Sources */,
- DF84281E0E7BA6AC00F5680E /* scroll.cpp in Sources */,
- DF84281F0E7BA6AC00F5680E /* sound.cpp in Sources */,
- DF8428200E7BA6AC00F5680E /* speech.cpp in Sources */,
- DF8428210E7BA6AC00F5680E /* sprite.cpp in Sources */,
- DF8428220E7BA6AC00F5680E /* startup.cpp in Sources */,
- DF8428230E7BA6AC00F5680E /* sword2.cpp in Sources */,
- DF8428240E7BA6AC00F5680E /* sync.cpp in Sources */,
- DF8428250E7BA6AC00F5680E /* walker.cpp in Sources */,
- DF8428260E7BA6AC00F5680E /* actors.cpp in Sources */,
- DF8428270E7BA6AC00F5680E /* anim.cpp in Sources */,
- DF8428280E7BA6AC00F5680E /* background.cpp in Sources */,
- DF8428290E7BA6AC00F5680E /* bg.cpp in Sources */,
- DF84282A0E7BA6AC00F5680E /* cliprect.cpp in Sources */,
- DF84282B0E7BA6AC00F5680E /* config.cpp in Sources */,
- DF84282C0E7BA6AC00F5680E /* cursor.cpp in Sources */,
- DF84282D0E7BA6AC00F5680E /* debugger.cpp in Sources */,
- DF84282E0E7BA6AC00F5680E /* detection.cpp in Sources */,
- DF84282F0E7BA6AC00F5680E /* effect.cpp in Sources */,
- DF8428300E7BA6AC00F5680E /* events.cpp in Sources */,
- DF8428310E7BA6AC00F5680E /* faders.cpp in Sources */,
- DF8428320E7BA6AC00F5680E /* font.cpp in Sources */,
- DF8428330E7BA6AC00F5680E /* graphics.cpp in Sources */,
- DF8428340E7BA6AC00F5680E /* handle.cpp in Sources */,
- DF8428350E7BA6AC00F5680E /* heapmem.cpp in Sources */,
- DF8428370E7BA6AC00F5680E /* mareels.cpp in Sources */,
- DF8428390E7BA6AC00F5680E /* move.cpp in Sources */,
- DF84283A0E7BA6AC00F5680E /* multiobj.cpp in Sources */,
- DF84283B0E7BA6AC00F5680E /* music.cpp in Sources */,
- DF84283C0E7BA6AC00F5680E /* object.cpp in Sources */,
- DF84283D0E7BA6AC00F5680E /* palette.cpp in Sources */,
- DF84283E0E7BA6AC00F5680E /* pcode.cpp in Sources */,
- DF84283F0E7BA6AC00F5680E /* pdisplay.cpp in Sources */,
- DF8428400E7BA6AC00F5680E /* play.cpp in Sources */,
- DF8428410E7BA6AC00F5680E /* polygons.cpp in Sources */,
- DF8428420E7BA6AC00F5680E /* rince.cpp in Sources */,
- DF8428430E7BA6AC00F5680E /* saveload.cpp in Sources */,
- DF8428440E7BA6AC00F5680E /* savescn.cpp in Sources */,
- DF8428450E7BA6AC00F5680E /* scene.cpp in Sources */,
- DF8428460E7BA6AC00F5680E /* sched.cpp in Sources */,
- DF8428470E7BA6AC00F5680E /* scn.cpp in Sources */,
- DF8428480E7BA6AC00F5680E /* scroll.cpp in Sources */,
- DF8428490E7BA6AC00F5680E /* sound.cpp in Sources */,
- DF84284A0E7BA6AC00F5680E /* strres.cpp in Sources */,
- DF84284B0E7BA6AC00F5680E /* text.cpp in Sources */,
- DF84284C0E7BA6AC00F5680E /* timers.cpp in Sources */,
- DF84284D0E7BA6AC00F5680E /* tinlib.cpp in Sources */,
- DF84284E0E7BA6AC00F5680E /* tinsel.cpp in Sources */,
- DF84284F0E7BA6AC00F5680E /* token.cpp in Sources */,
- DF8428500E7BA6AC00F5680E /* detection.cpp in Sources */,
- DF8428510E7BA6AC00F5680E /* graphics.cpp in Sources */,
- DF8428520E7BA6AC00F5680E /* menu.cpp in Sources */,
- DF8428530E7BA6AC00F5680E /* midi.cpp in Sources */,
- DF8428550E7BA6AC00F5680E /* opcodes.cpp in Sources */,
- DF8428560E7BA6AC00F5680E /* resource.cpp in Sources */,
- DF8428570E7BA6AC00F5680E /* saveload.cpp in Sources */,
- DF8428580E7BA6AC00F5680E /* staticres.cpp in Sources */,
- DF8428590E7BA6AC00F5680E /* touche.cpp in Sources */,
- DF8428970E7BAAAB00F5680E /* blit.cpp in Sources */,
- DF842A3E0E7BBB5000F5680E /* timidity.cpp in Sources */,
- DF842A470E7BBBB400F5680E /* archive.cpp in Sources */,
- DF842A490E7BBBB400F5680E /* unarj.cpp in Sources */,
- DF842A6D0E7BBD5700F5680E /* stdiostream.cpp in Sources */,
- DF7E8BFD0ED5FC77001CB19F /* saveload.cpp in Sources */,
- DF7E8BFF0ED5FC77001CB19F /* ThemeEngine.cpp in Sources */,
- DF7E8C000ED5FC77001CB19F /* ThemeEval.cpp in Sources */,
- DF7E8C010ED5FC77001CB19F /* ThemeLayout.cpp in Sources */,
- DF7E8C020ED5FC77001CB19F /* ThemeParser.cpp in Sources */,
- DF7E8C0C0ED5FCAF001CB19F /* thumbnail.cpp in Sources */,
- DF7E8C0D0ED5FCAF001CB19F /* VectorRenderer.cpp in Sources */,
- DF7E8C0E0ED5FCAF001CB19F /* VectorRendererSpec.cpp in Sources */,
- DF7E8C110ED5FCC2001CB19F /* xmlparser.cpp in Sources */,
- DF7E8C530ED60067001CB19F /* game.cpp in Sources */,
- DFAAAFF70F0112AD003E9390 /* saveload.cpp in Sources */,
- DFAAAFF90F0112C1003E9390 /* detection.cpp in Sources */,
- DFAAAFFC0F0112DF003E9390 /* detection.cpp in Sources */,
- DFAAB0020F011392003E9390 /* thumbnail_intern.cpp in Sources */,
- DF2FFB930F485D890006E566 /* dither.cpp in Sources */,
- DF2FFBD30F485DFB0006E566 /* debug.cpp in Sources */,
- DF2FFBFC0F4860A60006E566 /* posix-saves.cpp in Sources */,
- DF2FFC290F4862520006E566 /* bmv.cpp in Sources */,
- DF2FFC2A0F4862520006E566 /* dialogs.cpp in Sources */,
- DF2FFC2B0F4862520006E566 /* drives.cpp in Sources */,
- DF2FFC2C0F4862520006E566 /* sysvar.cpp in Sources */,
- DF2FFC380F48628A0006E566 /* gui_lol.cpp in Sources */,
- DF2FFC390F48628A0006E566 /* items_lol.cpp in Sources */,
- DF2FFC3A0F48628A0006E566 /* script_lol.cpp in Sources */,
- DF2FFC3B0F48628A0006E566 /* sequences_lol.cpp in Sources */,
- DF2FFC3C0F48628A0006E566 /* sound_midi.cpp in Sources */,
- DF2FFC3E0F48628A0006E566 /* util.cpp in Sources */,
- DF2FFC4A0F4863100006E566 /* scene_lol.cpp in Sources */,
- DF2FFC4E0F4863560006E566 /* advancedDetector.cpp in Sources */,
- DF2FFC5D0F4866E70006E566 /* base-backend.cpp in Sources */,
- DF2FFC670F48672D0006E566 /* resource.cpp in Sources */,
- DF2FFC680F48672D0006E566 /* resource_hrs.cpp in Sources */,
- DF2FFC690F48672D0006E566 /* resource_res.cpp in Sources */,
- DF2FFC6A0F48672D0006E566 /* resource_rsc.cpp in Sources */,
- DF2FFC6B0F48672D0006E566 /* sfuncs_ihnm.cpp in Sources */,
- DF2FFC740F4867910006E566 /* debugger.cpp in Sources */,
- DF2FFC750F4867910006E566 /* staticres.cpp in Sources */,
- DF2FFCDB0F4870690006E566 /* cell.cpp in Sources */,
- DF2FFCDC0F4870690006E566 /* cursor.cpp in Sources */,
- DF2FFCDD0F4870690006E566 /* debug.cpp in Sources */,
- DF2FFCDE0F4870690006E566 /* detection.cpp in Sources */,
- DF2FFCDF0F4870690006E566 /* font.cpp in Sources */,
- DF2FFCE00F4870690006E566 /* graphics.cpp in Sources */,
- DF2FFCE10F4870690006E566 /* groovie.cpp in Sources */,
- DF2FFCE20F4870690006E566 /* lzss.cpp in Sources */,
- DF2FFCE40F4870690006E566 /* music.cpp in Sources */,
- DF2FFCE50F4870690006E566 /* player.cpp in Sources */,
- DF2FFCE60F4870690006E566 /* resource.cpp in Sources */,
- DF2FFCE70F4870690006E566 /* roq.cpp in Sources */,
- DF2FFCE80F4870690006E566 /* saveload.cpp in Sources */,
- DF2FFCE90F4870690006E566 /* script.cpp in Sources */,
- DF2FFCEA0F4870690006E566 /* vdx.cpp in Sources */,
- DF2FFD100F4870E50006E566 /* detection.cpp in Sources */,
- DF2FFD110F4870E50006E566 /* graphics.cpp in Sources */,
- DF2FFD120F4870E50006E566 /* locations.cpp in Sources */,
- DF2FFD140F4870E50006E566 /* resource.cpp in Sources */,
- DF2FFD150F4870E50006E566 /* saveload.cpp in Sources */,
- DF2FFD160F4870E50006E566 /* sequences.cpp in Sources */,
- DF2FFD170F4870E50006E566 /* staticres.cpp in Sources */,
- DF2FFD180F4870E50006E566 /* tucker.cpp in Sources */,
- DFC831210F48AF19005EF03C /* detection.cpp in Sources */,
- DFC831240F48AF19005EF03C /* gc.cpp in Sources */,
- DFC831270F48AF19005EF03C /* kernel.cpp in Sources */,
- DFC831280F48AF19005EF03C /* kevent.cpp in Sources */,
- DFC831290F48AF19005EF03C /* kfile.cpp in Sources */,
- DFC8312A0F48AF19005EF03C /* kgraphics.cpp in Sources */,
- DFC8312B0F48AF19005EF03C /* klists.cpp in Sources */,
- DFC8312C0F48AF19005EF03C /* kmath.cpp in Sources */,
- DFC8312D0F48AF19005EF03C /* kmenu.cpp in Sources */,
- DFC8312E0F48AF19005EF03C /* kmovement.cpp in Sources */,
- DFC8312F0F48AF19005EF03C /* kpathing.cpp in Sources */,
- DFC831300F48AF19005EF03C /* kscripts.cpp in Sources */,
- DFC831310F48AF19005EF03C /* ksound.cpp in Sources */,
- DFC831320F48AF19005EF03C /* kstring.cpp in Sources */,
- DFC831330F48AF19005EF03C /* message.cpp in Sources */,
- DFC831370F48AF19005EF03C /* savegame.cpp in Sources */,
- DFC831390F48AF19005EF03C /* scriptdebug.cpp in Sources */,
- DFC8313A0F48AF19005EF03C /* seg_manager.cpp in Sources */,
- DFC8313C0F48AF19005EF03C /* vm.cpp in Sources */,
- DFC8315C0F48AF19005EF03C /* sci.cpp in Sources */,
- DFD6470C0F495B51008E18EF /* unzip.cpp in Sources */,
- DFAAD23D0F50120E00C3A4E2 /* console.cpp in Sources */,
- DF573C080F5A81EA00961A72 /* state.cpp in Sources */,
- DF573CBB0F5A85B300961A72 /* exec.cpp in Sources */,
- DF573CBE0F5A85E100961A72 /* timer_lol.cpp in Sources */,
- DF89C2880F62D55C00D756B6 /* sprites_lol.cpp in Sources */,
- DF89C2A40F62D79E00D756B6 /* script.cpp in Sources */,
- DF093E5F0F63CAD4002D821E /* pn.cpp in Sources */,
- DF093E600F63CAD4002D821E /* script_pn.cpp in Sources */,
- DF093E610F63CAD4002D821E /* vga_pn.cpp in Sources */,
- DF5CEB2C0F75535000DEA624 /* sound_br.cpp in Sources */,
- DF5CEB2D0F75535000DEA624 /* sound_ns.cpp in Sources */,
- DF5CEB320F75538000DEA624 /* protracker.cpp in Sources */,
- DFE88C470F874A1100C555C5 /* sound.cpp in Sources */,
- DF09CC160FAC4E1900A5AFD7 /* batplayer.cpp in Sources */,
- DF09CC170FAC4E1900A5AFD7 /* demoplayer.cpp in Sources */,
- DF09CC180FAC4E1900A5AFD7 /* scnplayer.cpp in Sources */,
- DF09CC190FAC4E1900A5AFD7 /* draw_fascin.cpp in Sources */,
- DF09CC1B0FAC4E1900A5AFD7 /* inter_fascin.cpp in Sources */,
- DF09CC2A0FAC4EAB00A5AFD7 /* script_v3.cpp in Sources */,
- DF09CC2B0FAC4EAB00A5AFD7 /* script_v4.cpp in Sources */,
- DF61183E0FE3A8080042AD3F /* kmisc.cpp in Sources */,
- DF61183F0FE3A8080042AD3F /* segment.cpp in Sources */,
- DF61184C0FE3A8250042AD3F /* decompressor.cpp in Sources */,
- DF61184D0FE3A8250042AD3F /* resource.cpp in Sources */,
- DF6118560FE3A8990042AD3F /* disk.cpp in Sources */,
- DF6118950FE3A9AA0042AD3F /* saveconverter.cpp in Sources */,
- DF6118960FE3A9AA0042AD3F /* saveconverter_v2.cpp in Sources */,
- DF6118970FE3A9AA0042AD3F /* saveconverter_v3.cpp in Sources */,
- DF6118980FE3A9AA0042AD3F /* saveconverter_v4.cpp in Sources */,
- DF61189A0FE3A9AA0042AD3F /* savefile.cpp in Sources */,
- DF61189B0FE3A9AA0042AD3F /* savehandler.cpp in Sources */,
- DF61189C0FE3A9AA0042AD3F /* saveload.cpp in Sources */,
- DF61189D0FE3A9AA0042AD3F /* saveload_v2.cpp in Sources */,
- DF61189E0FE3A9AA0042AD3F /* saveload_v3.cpp in Sources */,
- DF61189F0FE3A9AA0042AD3F /* saveload_v4.cpp in Sources */,
- DF6118A00FE3A9AA0042AD3F /* saveload_v6.cpp in Sources */,
- DF6118B00FE3A9EA0042AD3F /* feeble.cpp in Sources */,
- DF6118BC0FE3AA280042AD3F /* saveload_lol.cpp in Sources */,
- DF6118BD0FE3AA280042AD3F /* sound_lol.cpp in Sources */,
- DF6118BE0FE3AA280042AD3F /* sound_pcspk.cpp in Sources */,
- DF6118BF0FE3AA280042AD3F /* text_lol.cpp in Sources */,
- DF6118C80FE3AABD0042AD3F /* player_v2cms.cpp in Sources */,
- DF7585DA100CB66E00CC3324 /* expression.cpp in Sources */,
- DF7585DB100CB66E00CC3324 /* hotspots.cpp in Sources */,
- DF7585DC100CB66E00CC3324 /* init_v6.cpp in Sources */,
- DF7585DD100CB66E00CC3324 /* resources.cpp in Sources */,
- DF7585DE100CB66E00CC3324 /* script.cpp in Sources */,
- DF7585DF100CB66E00CC3324 /* totfile.cpp in Sources */,
- DF7585EE100CB6EA00CC3324 /* sjis.cpp in Sources */,
- DF7585F3100CB70600CC3324 /* saveload_playtoons.cpp in Sources */,
- DF7585F9100CB75800CC3324 /* static_selectors.cpp in Sources */,
- DF75861D100CBA0200CC3324 /* osys_events.cpp in Sources */,
- DF75861E100CBA0200CC3324 /* osys_main.cpp in Sources */,
- DF75861F100CBA0200CC3324 /* osys_sound.cpp in Sources */,
- DF758620100CBA0200CC3324 /* osys_video.cpp in Sources */,
- DF6BF4C610529DA50069811F /* conversion.cpp in Sources */,
- DF6BF4C710529DA50069811F /* jpeg.cpp in Sources */,
- DF6BF4DB10529DE90069811F /* input_pn.cpp in Sources */,
- DF6BF4DC10529DE90069811F /* string_pn.cpp in Sources */,
- DF6BF4DD10529DE90069811F /* verb_pn.cpp in Sources */,
- DF6BF4E510529E260069811F /* sound_amiga.cpp in Sources */,
- DF6BF4EC10529E6E0069811F /* init_v4.cpp in Sources */,
- DF6BF4ED10529E6E0069811F /* inter_playtoons.cpp in Sources */,
- DF6BF4F410529EE40069811F /* player_v4a.cpp in Sources */,
- DF6BF4FE10529F140069811F /* EventDispatcher.cpp in Sources */,
- DF6BF4FF10529F140069811F /* EventRecorder.cpp in Sources */,
- DF90E9C310AEDA9B00C8F93F /* selector.cpp in Sources */,
- DF90EAA610B0234300C8F93F /* draw_playtoons.cpp in Sources */,
- DF90EAAF10B0236F00C8F93F /* staticres.cpp in Sources */,
- DF2EC3F910E64C0C00765801 /* dialogs.cpp in Sources */,
- DF2EC3FF10E64C4300765801 /* animator_tim.cpp in Sources */,
- DF2EC40610E64C8000765801 /* event.cpp in Sources */,
- DF2EC50310E64D7C00765801 /* player_pce.cpp in Sources */,
- DF2EC50410E64D7C00765801 /* player_sid.cpp in Sources */,
- DF2EC50C10E64DB300765801 /* textconsole.cpp in Sources */,
- DF45B1CA116628A5009B85CC /* animate.cpp in Sources */,
- DF45B1CB116628A5009B85CC /* cache.cpp in Sources */,
- DF45B1CC116628A5009B85CC /* compare.cpp in Sources */,
- DF45B1CD116628A5009B85CC /* controls.cpp in Sources */,
- DF45B1CE116628A5009B85CC /* coordadjuster.cpp in Sources */,
- DF45B1CF116628A5009B85CC /* cursor.cpp in Sources */,
- DF45B1D0116628A5009B85CC /* font.cpp in Sources */,
- DF45B1D4116628A5009B85CC /* menu.cpp in Sources */,
- DF45B1D5116628A5009B85CC /* paint.cpp in Sources */,
- DF45B1D6116628A5009B85CC /* paint16.cpp in Sources */,
- DF45B1D8116628A5009B85CC /* palette.cpp in Sources */,
- DF45B1D9116628A5009B85CC /* picture.cpp in Sources */,
- DF45B1DA116628A5009B85CC /* portrait.cpp in Sources */,
- DF45B1DB116628A5009B85CC /* ports.cpp in Sources */,
- DF45B1DD116628A5009B85CC /* screen.cpp in Sources */,
- DF45B1DE116628A5009B85CC /* text16.cpp in Sources */,
- DF45B1DF116628A5009B85CC /* transitions.cpp in Sources */,
- DF45B1E0116628A5009B85CC /* view.cpp in Sources */,
- DF45B1E1116628A5009B85CC /* grammar.cpp in Sources */,
- DF45B1E2116628A5009B85CC /* said.cpp in Sources */,
- DF45B1E4116628A5009B85CC /* vocabulary.cpp in Sources */,
- DF45B1E5116628A5009B85CC /* audio.cpp in Sources */,
- DF45B1E6116628A5009B85CC /* adlib.cpp in Sources */,
- DF45B1E8116628A5009B85CC /* fb01.cpp in Sources */,
- DF45B1E9116628A5009B85CC /* midi.cpp in Sources */,
- DF45B1EA116628A5009B85CC /* pcjr.cpp in Sources */,
- DF45B1EF116628A5009B85CC /* midiparser_sci.cpp in Sources */,
- DF45B1F0116628A5009B85CC /* music.cpp in Sources */,
- DF45B1F1116628A5009B85CC /* soundcmd.cpp in Sources */,
- DF45B1F2116628A5009B85CC /* seq_decoder.cpp in Sources */,
- DFCDC6D9116629CE00A7D2A0 /* features.cpp in Sources */,
- DFCDC6DA116629CE00A7D2A0 /* kparse.cpp in Sources */,
- DFCDC6F711662AAB00A7D2A0 /* resource.cpp in Sources */,
- DFCDC70411662B0200A7D2A0 /* saveload_fascin.cpp in Sources */,
- DFCDC70B11662B6B00A7D2A0 /* macresman.cpp in Sources */,
- DFEC5D121166C5CF00C90552 /* random.cpp in Sources */,
- DFEC5D131166C5CF00C90552 /* tokenizer.cpp in Sources */,
- DFEC5D371166C67300C90552 /* savestate.cpp in Sources */,
- DF9B9249118E46730069C19D /* error.cpp in Sources */,
- DF9B9254118E46A00069C19D /* fontsjis.cpp in Sources */,
- DF9B9263118E46FE0069C19D /* error.cpp in Sources */,
- DFB0577711B753DA0015AE65 /* rational.cpp in Sources */,
- DFB0578211B7541F0015AE65 /* resource_audio.cpp in Sources */,
- DFB0578311B7541F0015AE65 /* util.cpp in Sources */,
- DFB0578B11B754570015AE65 /* maciconbar.cpp in Sources */,
- DFB0579211B7547D0015AE65 /* pict.cpp in Sources */,
- DF7F286211FF23D500159131 /* amigamac.cpp in Sources */,
- DF7F286911FF23EF00159131 /* kvideo.cpp in Sources */,
- DF7F286A11FF23EF00159131 /* workarounds.cpp in Sources */,
- DF7F287F11FF243B00159131 /* sound_2gs.cpp in Sources */,
- DF7F288011FF243B00159131 /* sound_coco3.cpp in Sources */,
- DF7F288111FF243B00159131 /* sound_midi.cpp in Sources */,
- DF7F288211FF243B00159131 /* sound_pcjr.cpp in Sources */,
- DF7F288311FF243B00159131 /* sound_sarien.cpp in Sources */,
- DF7F288C11FF244F00159131 /* Tooltip.cpp in Sources */,
- DF7F289511FF247300159131 /* translation.cpp in Sources */,
- DF7F28A611FF24C400159131 /* console.cpp in Sources */,
- DF895C03124C24680077F6E8 /* player_towns.cpp in Sources */,
- DF895C25124C25150077F6E8 /* init_fascin.cpp in Sources */,
- DF895C2A124C25350077F6E8 /* script_patches.cpp in Sources */,
- DF0E303B1252C5BD0082D593 /* cms.cpp in Sources */,
- 8CB5A9CB1253FD6900CB6BC7 /* m4_scene.cpp in Sources */,
- 8CB5A9CC1253FD6900CB6BC7 /* mads_logic.cpp in Sources */,
- 8CB5A9CD1253FD6900CB6BC7 /* mads_player.cpp in Sources */,
- 8CB5A9CE1253FD6900CB6BC7 /* mads_scene.cpp in Sources */,
- 8CB5A9CF1253FD6900CB6BC7 /* mads_views.cpp in Sources */,
- 8CD1ED53126202AB00FA198C /* detection.cpp in Sources */,
- 8CD1ED54126202AB00FA198C /* display.cpp in Sources */,
- 8CD1ED56126202AB00FA198C /* file.cpp in Sources */,
- 8CD1ED57126202AB00FA198C /* hugo.cpp in Sources */,
- 8CD1ED58126202AB00FA198C /* intro.cpp in Sources */,
- 8CD1ED59126202AB00FA198C /* inventory.cpp in Sources */,
- 8CD1ED5C126202AB00FA198C /* mouse.cpp in Sources */,
- 8CD1ED5D126202AB00FA198C /* parser.cpp in Sources */,
- 8CD1ED5E126202AB00FA198C /* route.cpp in Sources */,
- 8CD1ED5F126202AB00FA198C /* schedule.cpp in Sources */,
- 8CD1ED60126202AB00FA198C /* sound.cpp in Sources */,
- 8CD1ED61126202AB00FA198C /* util.cpp in Sources */,
- 8CD1ED62126202AB00FA198C /* anim.cpp in Sources */,
- 8CD1ED63126202AB00FA198C /* audio.cpp in Sources */,
- 8CD1ED64126202AB00FA198C /* character.cpp in Sources */,
- 8CD1ED65126202AB00FA198C /* conversation.cpp in Sources */,
- 8CD1ED66126202AB00FA198C /* detection.cpp in Sources */,
- 8CD1ED67126202AB00FA198C /* drew.cpp in Sources */,
- 8CD1ED68126202AB00FA198C /* flux.cpp in Sources */,
- 8CD1ED69126202AB00FA198C /* font.cpp in Sources */,
- 8CD1ED6A126202AB00FA198C /* hotspot.cpp in Sources */,
- 8CD1ED6D126202AB00FA198C /* movie.cpp in Sources */,
- 8CD1ED6E126202AB00FA198C /* path.cpp in Sources */,
- 8CD1ED6F126202AB00FA198C /* picture.cpp in Sources */,
- 8CD1ED70126202AB00FA198C /* resource.cpp in Sources */,
- 8CD1ED71126202AB00FA198C /* script.cpp in Sources */,
- 8CD1ED72126202AB00FA198C /* script_func.cpp in Sources */,
- 8CD1ED73126202AB00FA198C /* state.cpp in Sources */,
- 8CD1ED74126202AB00FA198C /* text.cpp in Sources */,
- 8CD1ED75126202AB00FA198C /* tools.cpp in Sources */,
- 8CD1ED76126202AB00FA198C /* toon.cpp in Sources */,
- 8CD80C8D126271A9001C6C87 /* surface.cpp in Sources */,
- 8CD80C93126271BD001C6C87 /* gfx_towns.cpp in Sources */,
- 8CD80D04126272A0001C6C87 /* actor.cpp in Sources */,
- 8CD80D05126272A0001C6C87 /* animation.cpp in Sources */,
- 8CD80D06126272A0001C6C87 /* callbacks.cpp in Sources */,
- 8CD80D07126272A0001C6C87 /* console.cpp in Sources */,
- 8CD80D08126272A0001C6C87 /* detection.cpp in Sources */,
- 8CD80D09126272A0001C6C87 /* dialog.cpp in Sources */,
- 8CD80D0A126272A0001C6C87 /* font.cpp in Sources */,
- 8CD80D0B126272A0001C6C87 /* inventory.cpp in Sources */,
- 8CD80D0D126272A0001C6C87 /* music.cpp in Sources */,
- 8CD80D0E126272A0001C6C87 /* objects.cpp in Sources */,
- 8CD80D0F126272A0001C6C87 /* pack.cpp in Sources */,
- 8CD80D10126272A0001C6C87 /* resources.cpp in Sources */,
- 8CD80D11126272A0001C6C87 /* scene.cpp in Sources */,
- 8CD80D12126272A0001C6C87 /* segment.cpp in Sources */,
- 8CD80D13126272A0001C6C87 /* surface.cpp in Sources */,
- 8CD80D14126272A0001C6C87 /* surface_list.cpp in Sources */,
- 8CD80D15126272A0001C6C87 /* teenagent.cpp in Sources */,
- DF203F481380C06E0056300A /* gui-manager.cpp in Sources */,
- DF203F6B1380C2750056300A /* avi_decoder.cpp in Sources */,
- DF203F6C1380C2750056300A /* coktel_decoder.cpp in Sources */,
- DF203F6D1380C2750056300A /* dxa_decoder.cpp in Sources */,
- DF203F6E1380C2750056300A /* flic_decoder.cpp in Sources */,
- DF203F701380C2750056300A /* qt_decoder.cpp in Sources */,
- DF203F711380C2750056300A /* smk_decoder.cpp in Sources */,
- DF203F721380C2750056300A /* video_decoder.cpp in Sources */,
- DF203FA01380C2920056300A /* cdtoons.cpp in Sources */,
- DF203FA11380C2920056300A /* cinepak.cpp in Sources */,
- DF203FA21380C2920056300A /* indeo3.cpp in Sources */,
- DF203FA31380C2920056300A /* mjpeg.cpp in Sources */,
- DF203FA41380C2920056300A /* msrle.cpp in Sources */,
- DF203FA51380C2920056300A /* msvideo1.cpp in Sources */,
- DF203FA71380C2920056300A /* qtrle.cpp in Sources */,
- DF203FA81380C2920056300A /* rpza.cpp in Sources */,
- DF203FA91380C2920056300A /* smc.cpp in Sources */,
- DF203FAA1380C2920056300A /* truemotion1.cpp in Sources */,
- DF203FE61380C3BC0056300A /* console.cpp in Sources */,
- DF203FE71380C3BC0056300A /* dialogs.cpp in Sources */,
- DF203FE81380C3BC0056300A /* file_v1d.cpp in Sources */,
- DF203FE91380C3BC0056300A /* file_v1w.cpp in Sources */,
- DF203FEA1380C3BC0056300A /* file_v2d.cpp in Sources */,
- DF203FEB1380C3BC0056300A /* file_v2w.cpp in Sources */,
- DF203FEC1380C3BC0056300A /* file_v3d.cpp in Sources */,
- DF203FED1380C3BC0056300A /* object_v1d.cpp in Sources */,
- DF203FEE1380C3BC0056300A /* object_v1w.cpp in Sources */,
- DF203FEF1380C3BC0056300A /* object_v2d.cpp in Sources */,
- DF203FF01380C3BC0056300A /* object_v3d.cpp in Sources */,
- DF203FF11380C3BC0056300A /* object.cpp in Sources */,
- DF203FF21380C3BC0056300A /* parser_v1d.cpp in Sources */,
- DF203FF31380C3BC0056300A /* parser_v1w.cpp in Sources */,
- DF203FF41380C3BC0056300A /* parser_v2d.cpp in Sources */,
- DF203FF51380C3BC0056300A /* parser_v3d.cpp in Sources */,
- DF203FF61380C3BC0056300A /* text.cpp in Sources */,
- DF2040341380C8B70056300A /* editable.cpp in Sources */,
- DF2040351380C8B70056300A /* edittext.cpp in Sources */,
- DF2040361380C8B70056300A /* list.cpp in Sources */,
- DF2040371380C8B70056300A /* popup.cpp in Sources */,
- DF2040381380C8B70056300A /* scrollbar.cpp in Sources */,
- DF2040391380C8B70056300A /* tab.cpp in Sources */,
- DF20406A1380CA230056300A /* audiostream.cpp in Sources */,
- DF20406B1380CA230056300A /* fmopl.cpp in Sources */,
- DF20406C1380CA230056300A /* mididrv.cpp in Sources */,
- DF20406D1380CA230056300A /* midiparser_smf.cpp in Sources */,
- DF20406E1380CA230056300A /* midiparser_xmidi.cpp in Sources */,
- DF20406F1380CA230056300A /* midiparser.cpp in Sources */,
- DF2040701380CA230056300A /* midiplayer.cpp in Sources */,
- DF2040711380CA230056300A /* mixer.cpp in Sources */,
- DF2040721380CA230056300A /* mpu401.cpp in Sources */,
- DF2040731380CA230056300A /* musicplugin.cpp in Sources */,
- DF2040741380CA230056300A /* rate.cpp in Sources */,
- DF2040751380CA230056300A /* timestamp.cpp in Sources */,
- DF2040A51380CA400056300A /* adpcm.cpp in Sources */,
- DF2040A61380CA400056300A /* aiff.cpp in Sources */,
- DF2040A71380CA400056300A /* flac.cpp in Sources */,
- DF2040A81380CA400056300A /* iff_sound.cpp in Sources */,
- DF2040A91380CA400056300A /* mac_snd.cpp in Sources */,
- DF2040AA1380CA400056300A /* mp3.cpp in Sources */,
- DF2040AB1380CA400056300A /* raw.cpp in Sources */,
- DF2040AC1380CA400056300A /* vag.cpp in Sources */,
- DF2040AD1380CA400056300A /* voc.cpp in Sources */,
- DF2040AE1380CA400056300A /* vorbis.cpp in Sources */,
- DF2040AF1380CA400056300A /* wave.cpp in Sources */,
- DF2040D41380CA810056300A /* infogrames.cpp in Sources */,
- DF2040D51380CA810056300A /* maxtrax.cpp in Sources */,
- DF2040D61380CA810056300A /* module.cpp in Sources */,
- DF2040D71380CA810056300A /* paula.cpp in Sources */,
- DF2040D81380CA810056300A /* protracker.cpp in Sources */,
- DF2040D91380CA810056300A /* rjp1.cpp in Sources */,
- DF2040DA1380CA810056300A /* soundfx.cpp in Sources */,
- DF2040DB1380CA810056300A /* tfmx.cpp in Sources */,
- DF2040FE1380CAA40056300A /* adlib.cpp in Sources */,
- DF2040FF1380CAA40056300A /* appleiigs.cpp in Sources */,
- DF2041001380CAA40056300A /* cms.cpp in Sources */,
- DF2041011380CAA40056300A /* eas.cpp in Sources */,
- DF2041021380CAA40056300A /* fluidsynth.cpp in Sources */,
- DF2041031380CAA40056300A /* mt32.cpp in Sources */,
- DF2041041380CAA40056300A /* pcspk.cpp in Sources */,
- DF2041051380CAA40056300A /* sid.cpp in Sources */,
- DF2041061380CAA40056300A /* wave6581.cpp in Sources */,
- DF46B6F41381E18900D08723 /* coroutine.cpp in Sources */,
- DF46B7031381E1FF00D08723 /* towns_audio.cpp in Sources */,
- DF46B7041381E1FF00D08723 /* towns_euphony.cpp in Sources */,
- DF46B7051381E1FF00D08723 /* towns_pc98_driver.cpp in Sources */,
- DF46B7061381E1FF00D08723 /* towns_pc98_fmsynth.cpp in Sources */,
- DF46B71F1381E27000D08723 /* console.cpp in Sources */,
- DF46B7201381E27000D08723 /* databases.cpp in Sources */,
- DF46B7211381E27000D08723 /* dbase.cpp in Sources */,
- DF46B7221381E27000D08723 /* iniconfig.cpp in Sources */,
- DF46B7231381E27000D08723 /* init_v7.cpp in Sources */,
- DF46B7241381E27000D08723 /* inter_inca2.cpp in Sources */,
- DF46B7451381E40500D08723 /* log.cpp in Sources */,
- DF46B74A1381E40F00D08723 /* modular-backend.cpp in Sources */,
- DF46B7551381E46700D08723 /* player_v2base.cpp in Sources */,
- DF46B75F1381E4A400D08723 /* console.cpp in Sources */,
- DF46B7641381E4D400D08723 /* robot_decoder.cpp in Sources */,
- DF46B7681381E4E400D08723 /* vm_types.cpp in Sources */,
- DF46B7801381E54200D08723 /* dcl.cpp in Sources */,
- DF46B7811381E54200D08723 /* iff_container.cpp in Sources */,
- DF46B7821381E54200D08723 /* winexe_ne.cpp in Sources */,
- DF46B7831381E54200D08723 /* winexe_pe.cpp in Sources */,
- DF46B7841381E54200D08723 /* winexe.cpp in Sources */,
- DF46B7951381E58000D08723 /* png.cpp in Sources */,
- DF46B7961381E58000D08723 /* wincursor.cpp in Sources */,
- DF46B7A01381E5B500D08723 /* winfont.cpp in Sources */,
- DF46B7AA1381E5F100D08723 /* header.cpp in Sources */,
- DF46B7B51381E67800D08723 /* sdl-mutex.cpp in Sources */,
- DF46B7BE1381E6C000D08723 /* object.cpp in Sources */,
- DF46B7C91381E72500D08723 /* console.cpp in Sources */,
- DF46B7D71381E7C600D08723 /* console.cpp in Sources */,
- DF46B83D1381F13500D08723 /* saveload_v7.cpp in Sources */,
- DF46B8451381F35500D08723 /* saveload_inca2.cpp in Sources */,
- DF46B8491381F38700D08723 /* inter_v7.cpp in Sources */,
- DF46B84E1381F39E00D08723 /* console.cpp in Sources */,
- DF46B8531381F3B400D08723 /* console.cpp in Sources */,
- DF46B8631381F44E00D08723 /* dbopl.cpp in Sources */,
- DF46B8641381F44E00D08723 /* dosbox.cpp in Sources */,
- DF46B8651381F44E00D08723 /* mame.cpp in Sources */,
- DF46B8721381F4A200D08723 /* sdl-audiocd.cpp in Sources */,
- DF46B87E1381F4F200D08723 /* default-audiocd.cpp in Sources */,
- DF46B88A1381F5D800D08723 /* sdl-provider.cpp in Sources */,
- DF46B8931381F62B00D08723 /* adpcm.cpp in Sources */,
- DF46B89C1381F6C400D08723 /* null.cpp in Sources */,
- DFADEBB413820DF500C46364 /* maccursor.cpp in Sources */,
- DFADEBB813820E0C00C46364 /* posix-fs.cpp in Sources */,
- F92B4DCE139DD428000D1BF1 /* quicktime.cpp in Sources */,
- F92B4DD3139DD449000D1BF1 /* yuv_to_rgb.cpp in Sources */,
- F9946D90139E1A260072D195 /* cdtoons.cpp in Sources */,
- F9946D91139E1A260072D195 /* cinepak.cpp in Sources */,
- F9946D92139E1A260072D195 /* indeo3.cpp in Sources */,
- F9946D93139E1A260072D195 /* mjpeg.cpp in Sources */,
- F9946D94139E1A260072D195 /* msrle.cpp in Sources */,
- F9946D95139E1A260072D195 /* msvideo1.cpp in Sources */,
- F9946D96139E1A260072D195 /* qtrle.cpp in Sources */,
- F9946D97139E1A260072D195 /* rpza.cpp in Sources */,
- F9946D98139E1A260072D195 /* smc.cpp in Sources */,
- F9946D99139E1A260072D195 /* truemotion1.cpp in Sources */,
- F9946D9D139E1A560072D195 /* towns_midi.cpp in Sources */,
- F9946DA0139E1A560072D195 /* towns_pc98_plugins.cpp in Sources */,
- F9946DB5139E1A880072D195 /* freeverb.cpp in Sources */,
- F9946DB8139E1A880072D195 /* i386.cpp in Sources */,
- F9946DBB139E1A880072D195 /* mt32_file.cpp in Sources */,
- F9946DBE139E1A880072D195 /* part.cpp in Sources */,
- F9946DC1139E1A880072D195 /* partial.cpp in Sources */,
- F9946DC4139E1A880072D195 /* partialManager.cpp in Sources */,
- F9946DC7139E1A880072D195 /* synth.cpp in Sources */,
- F9946DCA139E1A880072D195 /* tables.cpp in Sources */,
- F9946DD6139E1AD30072D195 /* aac.cpp in Sources */,
- F9946DD9139E1AD30072D195 /* qdm2.cpp in Sources */,
- F9946DDC139E1AD30072D195 /* quicktime.cpp in Sources */,
- F9946DE3139E1B180072D195 /* posix-main.cpp in Sources */,
- F9946DE6139E1B180072D195 /* posix.cpp in Sources */,
- F9946DEC139E1B6F0072D195 /* downscaler.cpp in Sources */,
- F9946DF1139E1BA00072D195 /* console.cpp in Sources */,
- F9946DF7139E1BBF0072D195 /* sdl-mixer.cpp in Sources */,
- F9946DFE139E1BEB0072D195 /* doublebuffersdl-mixer.cpp in Sources */,
- F9946E04139E1C390072D195 /* sdl-graphics.cpp in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- DF093E800F63CB26002D821E /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- DF093E810F63CB26002D821E /* commandLine.cpp in Sources */,
- DF093E820F63CB26002D821E /* main.cpp in Sources */,
- DF093E830F63CB26002D821E /* plugins.cpp in Sources */,
- DF093E840F63CB26002D821E /* version.cpp in Sources */,
- DF093E850F63CB26002D821E /* default-events.cpp in Sources */,
- DF093E860F63CB26002D821E /* posix-fs-factory.cpp in Sources */,
- DF093E890F63CB26002D821E /* posix-provider.cpp in Sources */,
- DF093E8A0F63CB26002D821E /* default-saves.cpp in Sources */,
- DF093E8B0F63CB26002D821E /* savefile.cpp in Sources */,
- DF093E8C0F63CB26002D821E /* default-timer.cpp in Sources */,
- DF093E8D0F63CB26002D821E /* config-file.cpp in Sources */,
- DF093E8E0F63CB26002D821E /* config-manager.cpp in Sources */,
- DF093E8F0F63CB26002D821E /* file.cpp in Sources */,
- DF093E900F63CB26002D821E /* fs.cpp in Sources */,
- DF093E910F63CB26002D821E /* hashmap.cpp in Sources */,
- DF093E920F63CB26002D821E /* md5.cpp in Sources */,
- DF093E930F63CB26002D821E /* mutex.cpp in Sources */,
- DF093E940F63CB26002D821E /* str.cpp in Sources */,
- DF093E950F63CB26002D821E /* stream.cpp in Sources */,
- DF093E960F63CB26002D821E /* system.cpp in Sources */,
- DF093E970F63CB26002D821E /* util.cpp in Sources */,
- DF093E980F63CB26002D821E /* zlib.cpp in Sources */,
- DF093E990F63CB26002D821E /* cursorman.cpp in Sources */,
- DF093E9A0F63CB26002D821E /* font.cpp in Sources */,
- DF093E9B0F63CB26002D821E /* fontman.cpp in Sources */,
- DF093E9C0F63CB26002D821E /* consolefont.cpp in Sources */,
- DF093E9D0F63CB26002D821E /* newfont.cpp in Sources */,
- DF093E9E0F63CB26002D821E /* newfont_big.cpp in Sources */,
- DF093EA00F63CB26002D821E /* iff.cpp in Sources */,
- DF093EA10F63CB26002D821E /* imagedec.cpp in Sources */,
- DF093EA20F63CB26002D821E /* primitives.cpp in Sources */,
- DF093EA30F63CB26002D821E /* surface.cpp in Sources */,
- DF093EA40F63CB26002D821E /* about.cpp in Sources */,
- DF093EA50F63CB26002D821E /* Actions.cpp in Sources */,
- DF093EA70F63CB26002D821E /* chooser.cpp in Sources */,
- DF093EA80F63CB26002D821E /* console.cpp in Sources */,
- DF093EA90F63CB26002D821E /* debugger.cpp in Sources */,
- DF093EAA0F63CB26002D821E /* dialog.cpp in Sources */,
- DF093EAD0F63CB26002D821E /* Key.cpp in Sources */,
- DF093EAE0F63CB26002D821E /* launcher.cpp in Sources */,
- DF093EB00F63CB26002D821E /* massadd.cpp in Sources */,
- DF093EB10F63CB26002D821E /* message.cpp in Sources */,
- DF093EB20F63CB26002D821E /* object.cpp in Sources */,
- DF093EB30F63CB26002D821E /* options.cpp in Sources */,
- DF093EB70F63CB26002D821E /* themebrowser.cpp in Sources */,
- DF093EB80F63CB26002D821E /* widget.cpp in Sources */,
- DF093ED60F63CB26002D821E /* memorypool.cpp in Sources */,
- DF093ED70F63CB26002D821E /* seq.cpp in Sources */,
- DF093ED80F63CB26002D821E /* scaler.cpp in Sources */,
- DF093ED90F63CB26002D821E /* scalebit.cpp in Sources */,
- DF093EDA0F63CB26002D821E /* 2xsai.cpp in Sources */,
- DF093EDB0F63CB26002D821E /* aspect.cpp in Sources */,
- DF093EDE0F63CB26002D821E /* scale2x.cpp in Sources */,
- DF093EDF0F63CB26002D821E /* scale3x.cpp in Sources */,
- DF093EE20F63CB26002D821E /* agi.cpp in Sources */,
- DF093EE30F63CB26002D821E /* checks.cpp in Sources */,
- DF093EE40F63CB26002D821E /* console.cpp in Sources */,
- DF093EE50F63CB26002D821E /* cycle.cpp in Sources */,
- DF093EE60F63CB26002D821E /* detection.cpp in Sources */,
- DF093EE70F63CB26002D821E /* global.cpp in Sources */,
- DF093EE80F63CB26002D821E /* graphics.cpp in Sources */,
- DF093EE90F63CB26002D821E /* id.cpp in Sources */,
- DF093EEA0F63CB26002D821E /* inv.cpp in Sources */,
- DF093EEB0F63CB26002D821E /* keyboard.cpp in Sources */,
- DF093EEC0F63CB26002D821E /* loader_v2.cpp in Sources */,
- DF093EED0F63CB26002D821E /* loader_v3.cpp in Sources */,
- DF093EEE0F63CB26002D821E /* logic.cpp in Sources */,
- DF093EEF0F63CB26002D821E /* lzw.cpp in Sources */,
- DF093EF00F63CB26002D821E /* menu.cpp in Sources */,
- DF093EF10F63CB26002D821E /* motion.cpp in Sources */,
- DF093EF20F63CB26002D821E /* objects.cpp in Sources */,
- DF093EF30F63CB26002D821E /* op_cmd.cpp in Sources */,
- DF093EF40F63CB26002D821E /* op_dbg.cpp in Sources */,
- DF093EF50F63CB26002D821E /* op_test.cpp in Sources */,
- DF093EF60F63CB26002D821E /* picture.cpp in Sources */,
- DF093EF70F63CB26002D821E /* preagi.cpp in Sources */,
- DF093EF80F63CB26002D821E /* preagi_common.cpp in Sources */,
- DF093EF90F63CB26002D821E /* preagi_mickey.cpp in Sources */,
- DF093EFA0F63CB26002D821E /* preagi_troll.cpp in Sources */,
- DF093EFB0F63CB26002D821E /* preagi_winnie.cpp in Sources */,
- DF093EFC0F63CB26002D821E /* predictive.cpp in Sources */,
- DF093EFD0F63CB26002D821E /* saveload.cpp in Sources */,
- DF093EFE0F63CB26002D821E /* sound.cpp in Sources */,
- DF093EFF0F63CB26002D821E /* sprite.cpp in Sources */,
- DF093F000F63CB26002D821E /* text.cpp in Sources */,
- DF093F010F63CB26002D821E /* view.cpp in Sources */,
- DF093F020F63CB26002D821E /* wagparser.cpp in Sources */,
- DF093F030F63CB26002D821E /* words.cpp in Sources */,
- DF093F040F63CB26002D821E /* agos.cpp in Sources */,
- DF093F050F63CB26002D821E /* animation.cpp in Sources */,
- DF093F060F63CB26002D821E /* charset-fontdata.cpp in Sources */,
- DF093F070F63CB26002D821E /* charset.cpp in Sources */,
- DF093F080F63CB26002D821E /* contain.cpp in Sources */,
- DF093F090F63CB26002D821E /* cursor.cpp in Sources */,
- DF093F0A0F63CB26002D821E /* debug.cpp in Sources */,
- DF093F0B0F63CB26002D821E /* debugger.cpp in Sources */,
- DF093F0C0F63CB26002D821E /* detection.cpp in Sources */,
- DF093F0D0F63CB26002D821E /* draw.cpp in Sources */,
- DF093F0E0F63CB26002D821E /* event.cpp in Sources */,
- DF093F0F0F63CB26002D821E /* gfx.cpp in Sources */,
- DF093F100F63CB26002D821E /* icons.cpp in Sources */,
- DF093F110F63CB26002D821E /* input.cpp in Sources */,
- DF093F120F63CB26002D821E /* items.cpp in Sources */,
- DF093F130F63CB26002D821E /* menus.cpp in Sources */,
- DF093F140F63CB26002D821E /* midi.cpp in Sources */,
- DF093F150F63CB26002D821E /* midiparser_s1d.cpp in Sources */,
- DF093F160F63CB26002D821E /* oracle.cpp in Sources */,
- DF093F170F63CB26002D821E /* res.cpp in Sources */,
- DF093F180F63CB26002D821E /* res_ami.cpp in Sources */,
- DF093F190F63CB26002D821E /* res_snd.cpp in Sources */,
- DF093F1A0F63CB26002D821E /* rooms.cpp in Sources */,
- DF093F1B0F63CB26002D821E /* saveload.cpp in Sources */,
- DF093F1C0F63CB26002D821E /* script.cpp in Sources */,
- DF093F1D0F63CB26002D821E /* script_e1.cpp in Sources */,
- DF093F1E0F63CB26002D821E /* script_e2.cpp in Sources */,
- DF093F1F0F63CB26002D821E /* script_ff.cpp in Sources */,
- DF093F200F63CB26002D821E /* script_pp.cpp in Sources */,
- DF093F210F63CB26002D821E /* script_s1.cpp in Sources */,
- DF093F220F63CB26002D821E /* script_s2.cpp in Sources */,
- DF093F230F63CB26002D821E /* script_ww.cpp in Sources */,
- DF093F240F63CB26002D821E /* sound.cpp in Sources */,
- DF093F250F63CB26002D821E /* string.cpp in Sources */,
- DF093F260F63CB26002D821E /* subroutine.cpp in Sources */,
- DF093F270F63CB26002D821E /* verb.cpp in Sources */,
- DF093F280F63CB26002D821E /* vga.cpp in Sources */,
- DF093F290F63CB26002D821E /* vga_e2.cpp in Sources */,
- DF093F2A0F63CB26002D821E /* vga_ff.cpp in Sources */,
- DF093F2B0F63CB26002D821E /* vga_s1.cpp in Sources */,
- DF093F2C0F63CB26002D821E /* vga_s2.cpp in Sources */,
- DF093F2D0F63CB26002D821E /* vga_ww.cpp in Sources */,
- DF093F2E0F63CB26002D821E /* window.cpp in Sources */,
- DF093F2F0F63CB26002D821E /* zones.cpp in Sources */,
- DF093F300F63CB26002D821E /* anim.cpp in Sources */,
- DF093F310F63CB26002D821E /* bg.cpp in Sources */,
- DF093F320F63CB26002D821E /* bg_list.cpp in Sources */,
- DF093F330F63CB26002D821E /* cine.cpp in Sources */,
- DF093F340F63CB26002D821E /* detection.cpp in Sources */,
- DF093F350F63CB26002D821E /* gfx.cpp in Sources */,
- DF093F360F63CB26002D821E /* main_loop.cpp in Sources */,
- DF093F370F63CB26002D821E /* msg.cpp in Sources */,
- DF093F380F63CB26002D821E /* object.cpp in Sources */,
- DF093F390F63CB26002D821E /* pal.cpp in Sources */,
- DF093F3A0F63CB26002D821E /* part.cpp in Sources */,
- DF093F3B0F63CB26002D821E /* prc.cpp in Sources */,
- DF093F3C0F63CB26002D821E /* rel.cpp in Sources */,
- DF093F3D0F63CB26002D821E /* script_fw.cpp in Sources */,
- DF093F3E0F63CB26002D821E /* script_os.cpp in Sources */,
- DF093F3F0F63CB26002D821E /* sound.cpp in Sources */,
- DF093F400F63CB26002D821E /* texte.cpp in Sources */,
- DF093F410F63CB26002D821E /* unpack.cpp in Sources */,
- DF093F420F63CB26002D821E /* various.cpp in Sources */,
- DF093F430F63CB26002D821E /* actor.cpp in Sources */,
- DF093F440F63CB26002D821E /* background.cpp in Sources */,
- DF093F450F63CB26002D821E /* backgroundIncrust.cpp in Sources */,
- DF093F460F63CB26002D821E /* cell.cpp in Sources */,
- DF093F470F63CB26002D821E /* cruise.cpp in Sources */,
- DF093F480F63CB26002D821E /* cruise_main.cpp in Sources */,
- DF093F490F63CB26002D821E /* ctp.cpp in Sources */,
- DF093F4A0F63CB26002D821E /* dataLoader.cpp in Sources */,
- DF093F4B0F63CB26002D821E /* decompiler.cpp in Sources */,
- DF093F4C0F63CB26002D821E /* delphine-unpack.cpp in Sources */,
- DF093F4D0F63CB26002D821E /* detection.cpp in Sources */,
- DF093F4E0F63CB26002D821E /* font.cpp in Sources */,
- DF093F4F0F63CB26002D821E /* function.cpp in Sources */,
- DF093F500F63CB26002D821E /* gfxModule.cpp in Sources */,
- DF093F510F63CB26002D821E /* linker.cpp in Sources */,
- DF093F520F63CB26002D821E /* mainDraw.cpp in Sources */,
- DF093F530F63CB26002D821E /* menu.cpp in Sources */,
- DF093F540F63CB26002D821E /* mouse.cpp in Sources */,
- DF093F550F63CB26002D821E /* object.cpp in Sources */,
- DF093F560F63CB26002D821E /* overlay.cpp in Sources */,
- DF093F570F63CB26002D821E /* perso.cpp in Sources */,
- DF093F580F63CB26002D821E /* polys.cpp in Sources */,
- DF093F590F63CB26002D821E /* saveload.cpp in Sources */,
- DF093F5A0F63CB26002D821E /* script.cpp in Sources */,
- DF093F5B0F63CB26002D821E /* stack.cpp in Sources */,
- DF093F5C0F63CB26002D821E /* various.cpp in Sources */,
- DF093F5D0F63CB26002D821E /* vars.cpp in Sources */,
- DF093F5E0F63CB26002D821E /* volume.cpp in Sources */,
- DF093F5F0F63CB26002D821E /* dialogs.cpp in Sources */,
- DF093F600F63CB26002D821E /* actors.cpp in Sources */,
- DF093F610F63CB26002D821E /* animation.cpp in Sources */,
- DF093F620F63CB26002D821E /* converse.cpp in Sources */,
- DF093F630F63CB26002D821E /* detection.cpp in Sources */,
- DF093F640F63CB26002D821E /* drascula.cpp in Sources */,
- DF093F650F63CB26002D821E /* graphics.cpp in Sources */,
- DF093F660F63CB26002D821E /* interface.cpp in Sources */,
- DF093F670F63CB26002D821E /* objects.cpp in Sources */,
- DF093F680F63CB26002D821E /* palette.cpp in Sources */,
- DF093F690F63CB26002D821E /* rooms.cpp in Sources */,
- DF093F6A0F63CB26002D821E /* saveload.cpp in Sources */,
- DF093F6B0F63CB26002D821E /* sound.cpp in Sources */,
- DF093F6C0F63CB26002D821E /* talk.cpp in Sources */,
- DF093F6D0F63CB26002D821E /* engine.cpp in Sources */,
- DF093F6F0F63CB26002D821E /* dataio.cpp in Sources */,
- DF093F700F63CB26002D821E /* detection.cpp in Sources */,
- DF093F710F63CB26002D821E /* draw.cpp in Sources */,
- DF093F720F63CB26002D821E /* draw_bargon.cpp in Sources */,
- DF093F730F63CB26002D821E /* draw_v1.cpp in Sources */,
- DF093F740F63CB26002D821E /* draw_v2.cpp in Sources */,
- DF093F760F63CB26002D821E /* game.cpp in Sources */,
- DF093F790F63CB26002D821E /* global.cpp in Sources */,
- DF093F7A0F63CB26002D821E /* gob.cpp in Sources */,
- DF093F7B0F63CB26002D821E /* goblin.cpp in Sources */,
- DF093F7C0F63CB26002D821E /* goblin_v1.cpp in Sources */,
- DF093F7D0F63CB26002D821E /* goblin_v2.cpp in Sources */,
- DF093F7E0F63CB26002D821E /* goblin_v3.cpp in Sources */,
- DF093F7F0F63CB26002D821E /* goblin_v4.cpp in Sources */,
- DF093F800F63CB26002D821E /* init.cpp in Sources */,
- DF093F810F63CB26002D821E /* init_v1.cpp in Sources */,
- DF093F820F63CB26002D821E /* init_v2.cpp in Sources */,
- DF093F830F63CB26002D821E /* init_v3.cpp in Sources */,
- DF093F840F63CB26002D821E /* inter.cpp in Sources */,
- DF093F850F63CB26002D821E /* inter_bargon.cpp in Sources */,
- DF093F860F63CB26002D821E /* inter_v1.cpp in Sources */,
- DF093F870F63CB26002D821E /* inter_v2.cpp in Sources */,
- DF093F880F63CB26002D821E /* inter_v3.cpp in Sources */,
- DF093F890F63CB26002D821E /* inter_v4.cpp in Sources */,
- DF093F8A0F63CB26002D821E /* inter_v5.cpp in Sources */,
- DF093F8B0F63CB26002D821E /* inter_v6.cpp in Sources */,
- DF093F8C0F63CB26002D821E /* map.cpp in Sources */,
- DF093F8D0F63CB26002D821E /* map_v1.cpp in Sources */,
- DF093F8E0F63CB26002D821E /* map_v2.cpp in Sources */,
- DF093F900F63CB26002D821E /* mult.cpp in Sources */,
- DF093F910F63CB26002D821E /* mult_v1.cpp in Sources */,
- DF093F920F63CB26002D821E /* mult_v2.cpp in Sources */,
- DF093F930F63CB26002D821E /* palanim.cpp in Sources */,
- DF093F9B0F63CB26002D821E /* scenery.cpp in Sources */,
- DF093F9C0F63CB26002D821E /* scenery_v1.cpp in Sources */,
- DF093F9D0F63CB26002D821E /* scenery_v2.cpp in Sources */,
- DF093F9E0F63CB26002D821E /* adlib.cpp in Sources */,
- DF093F9F0F63CB26002D821E /* bgatmosphere.cpp in Sources */,
- DF093FA00F63CB26002D821E /* cdrom.cpp in Sources */,
- DF093FA10F63CB26002D821E /* infogrames.cpp in Sources */,
- DF093FA20F63CB26002D821E /* pcspeaker.cpp in Sources */,
- DF093FA30F63CB26002D821E /* sound.cpp in Sources */,
- DF093FA40F63CB26002D821E /* soundblaster.cpp in Sources */,
- DF093FA50F63CB26002D821E /* sounddesc.cpp in Sources */,
- DF093FA60F63CB26002D821E /* soundmixer.cpp in Sources */,
- DF093FA70F63CB26002D821E /* util.cpp in Sources */,
- DF093FA80F63CB26002D821E /* variables.cpp in Sources */,
- DF093FA90F63CB26002D821E /* video.cpp in Sources */,
- DF093FAA0F63CB26002D821E /* video_v1.cpp in Sources */,
- DF093FAB0F63CB26002D821E /* video_v2.cpp in Sources */,
- DF093FAC0F63CB26002D821E /* video_v6.cpp in Sources */,
- DF093FAD0F63CB26002D821E /* videoplayer.cpp in Sources */,
- DF093FD10F63CB26002D821E /* animator_hof.cpp in Sources */,
- DF093FD20F63CB26002D821E /* animator_lok.cpp in Sources */,
- DF093FD30F63CB26002D821E /* animator_mr.cpp in Sources */,
- DF093FD40F63CB26002D821E /* animator_v2.cpp in Sources */,
- DF093FD50F63CB26002D821E /* debugger.cpp in Sources */,
- DF093FD60F63CB26002D821E /* detection.cpp in Sources */,
- DF093FD70F63CB26002D821E /* gui.cpp in Sources */,
- DF093FD80F63CB26002D821E /* gui_hof.cpp in Sources */,
- DF093FD90F63CB26002D821E /* gui_lok.cpp in Sources */,
- DF093FDA0F63CB26002D821E /* gui_mr.cpp in Sources */,
- DF093FDB0F63CB26002D821E /* gui_v2.cpp in Sources */,
- DF093FDC0F63CB26002D821E /* items_hof.cpp in Sources */,
- DF093FDD0F63CB26002D821E /* items_lok.cpp in Sources */,
- DF093FDE0F63CB26002D821E /* items_mr.cpp in Sources */,
- DF093FDF0F63CB26002D821E /* items_v2.cpp in Sources */,
- DF093FE00F63CB26002D821E /* kyra_hof.cpp in Sources */,
- DF093FE10F63CB26002D821E /* kyra_lok.cpp in Sources */,
- DF093FE20F63CB26002D821E /* kyra_mr.cpp in Sources */,
- DF093FE30F63CB26002D821E /* kyra_v1.cpp in Sources */,
- DF093FE40F63CB26002D821E /* kyra_v2.cpp in Sources */,
- DF093FE50F63CB26002D821E /* lol.cpp in Sources */,
- DF093FE60F63CB26002D821E /* resource.cpp in Sources */,
- DF093FE70F63CB26002D821E /* resource_intern.cpp in Sources */,
- DF093FE80F63CB26002D821E /* saveload.cpp in Sources */,
- DF093FE90F63CB26002D821E /* saveload_hof.cpp in Sources */,
- DF093FEA0F63CB26002D821E /* saveload_lok.cpp in Sources */,
- DF093FEB0F63CB26002D821E /* saveload_mr.cpp in Sources */,
- DF093FEC0F63CB26002D821E /* scene_hof.cpp in Sources */,
- DF093FED0F63CB26002D821E /* scene_lok.cpp in Sources */,
- DF093FEE0F63CB26002D821E /* scene_mr.cpp in Sources */,
- DF093FEF0F63CB26002D821E /* scene_v1.cpp in Sources */,
- DF093FF00F63CB26002D821E /* scene_v2.cpp in Sources */,
- DF093FF10F63CB26002D821E /* screen.cpp in Sources */,
- DF093FF20F63CB26002D821E /* screen_hof.cpp in Sources */,
- DF093FF30F63CB26002D821E /* screen_lok.cpp in Sources */,
- DF093FF40F63CB26002D821E /* screen_lol.cpp in Sources */,
- DF093FF50F63CB26002D821E /* screen_mr.cpp in Sources */,
- DF093FF60F63CB26002D821E /* screen_v2.cpp in Sources */,
- DF093FF70F63CB26002D821E /* script.cpp in Sources */,
- DF093FF80F63CB26002D821E /* script_hof.cpp in Sources */,
- DF093FF90F63CB26002D821E /* script_lok.cpp in Sources */,
- DF093FFA0F63CB26002D821E /* script_mr.cpp in Sources */,
- DF093FFB0F63CB26002D821E /* script_tim.cpp in Sources */,
- DF093FFC0F63CB26002D821E /* script_v1.cpp in Sources */,
- DF093FFD0F63CB26002D821E /* script_v2.cpp in Sources */,
- DF093FFE0F63CB26002D821E /* seqplayer.cpp in Sources */,
- DF093FFF0F63CB26002D821E /* sequences_hof.cpp in Sources */,
- DF0940000F63CB26002D821E /* sequences_lok.cpp in Sources */,
- DF0940010F63CB26002D821E /* sequences_mr.cpp in Sources */,
- DF0940020F63CB26002D821E /* sequences_v2.cpp in Sources */,
- DF0940030F63CB26002D821E /* sound.cpp in Sources */,
- DF0940040F63CB26002D821E /* sound_adlib.cpp in Sources */,
- DF0940050F63CB26002D821E /* sound_digital.cpp in Sources */,
- DF0940060F63CB26002D821E /* sound_lok.cpp in Sources */,
- DF0940070F63CB26002D821E /* sound_towns.cpp in Sources */,
- DF0940080F63CB26002D821E /* sprites.cpp in Sources */,
- DF0940090F63CB26002D821E /* staticres.cpp in Sources */,
- DF09400A0F63CB26002D821E /* text.cpp in Sources */,
- DF09400B0F63CB26002D821E /* text_hof.cpp in Sources */,
- DF09400C0F63CB26002D821E /* text_lok.cpp in Sources */,
- DF09400D0F63CB26002D821E /* text_mr.cpp in Sources */,
- DF09400E0F63CB26002D821E /* timer.cpp in Sources */,
- DF09400F0F63CB26002D821E /* timer_hof.cpp in Sources */,
- DF0940100F63CB26002D821E /* timer_lok.cpp in Sources */,
- DF0940110F63CB26002D821E /* timer_mr.cpp in Sources */,
- DF0940120F63CB26002D821E /* vqa.cpp in Sources */,
- DF0940130F63CB26002D821E /* wsamovie.cpp in Sources */,
- DF0940140F63CB26002D821E /* animseq.cpp in Sources */,
- DF0940150F63CB26002D821E /* debugger.cpp in Sources */,
- DF0940160F63CB26002D821E /* decode.cpp in Sources */,
- DF0940170F63CB26002D821E /* detection.cpp in Sources */,
- DF0940180F63CB26002D821E /* disk.cpp in Sources */,
- DF0940190F63CB26002D821E /* events.cpp in Sources */,
- DF09401A0F63CB26002D821E /* fights.cpp in Sources */,
- DF09401B0F63CB26002D821E /* game.cpp in Sources */,
- DF09401C0F63CB26002D821E /* hotspots.cpp in Sources */,
- DF09401D0F63CB26002D821E /* intro.cpp in Sources */,
- DF09401E0F63CB26002D821E /* lure.cpp in Sources */,
- DF09401F0F63CB26002D821E /* memory.cpp in Sources */,
- DF0940200F63CB26002D821E /* menu.cpp in Sources */,
- DF0940210F63CB26002D821E /* palette.cpp in Sources */,
- DF0940220F63CB26002D821E /* res.cpp in Sources */,
- DF0940230F63CB26002D821E /* res_struct.cpp in Sources */,
- DF0940240F63CB26002D821E /* room.cpp in Sources */,
- DF0940250F63CB26002D821E /* screen.cpp in Sources */,
- DF0940260F63CB26002D821E /* scripts.cpp in Sources */,
- DF0940270F63CB26002D821E /* sound.cpp in Sources */,
- DF0940280F63CB26002D821E /* strings.cpp in Sources */,
- DF0940290F63CB26002D821E /* surface.cpp in Sources */,
- DF09402A0F63CB26002D821E /* actor.cpp in Sources */,
- DF09402B0F63CB26002D821E /* animation.cpp in Sources */,
- DF09402C0F63CB26002D821E /* assets.cpp in Sources */,
- DF09402D0F63CB26002D821E /* compression.cpp in Sources */,
- DF09402E0F63CB26002D821E /* console.cpp in Sources */,
- DF09402F0F63CB26002D821E /* converse.cpp in Sources */,
- DF0940300F63CB26002D821E /* detection.cpp in Sources */,
- DF0940310F63CB26002D821E /* events.cpp in Sources */,
- DF0940320F63CB26002D821E /* font.cpp in Sources */,
- DF0940330F63CB26002D821E /* globals.cpp in Sources */,
- DF0940340F63CB26002D821E /* graphics.cpp in Sources */,
- DF0940350F63CB26002D821E /* gui.cpp in Sources */,
- DF0940360F63CB26002D821E /* hotspot.cpp in Sources */,
- DF0940370F63CB26002D821E /* m4.cpp in Sources */,
- DF0940380F63CB26002D821E /* m4_menus.cpp in Sources */,
- DF0940390F63CB26002D821E /* m4_views.cpp in Sources */,
- DF09403A0F63CB26002D821E /* mads_anim.cpp in Sources */,
- DF09403B0F63CB26002D821E /* mads_menus.cpp in Sources */,
- DF09403C0F63CB26002D821E /* midi.cpp in Sources */,
- DF09403D0F63CB26002D821E /* rails.cpp in Sources */,
- DF09403E0F63CB26002D821E /* resource.cpp in Sources */,
- DF09403F0F63CB26002D821E /* saveload.cpp in Sources */,
- DF0940400F63CB26002D821E /* scene.cpp in Sources */,
- DF0940410F63CB26002D821E /* script.cpp in Sources */,
- DF0940420F63CB26002D821E /* sound.cpp in Sources */,
- DF0940430F63CB26002D821E /* sprite.cpp in Sources */,
- DF0940440F63CB26002D821E /* viewmgr.cpp in Sources */,
- DF0940450F63CB26002D821E /* woodscript.cpp in Sources */,
- DF0940460F63CB26002D821E /* ws_machine.cpp in Sources */,
- DF0940470F63CB26002D821E /* ws_sequence.cpp in Sources */,
- DF0940480F63CB26002D821E /* database.cpp in Sources */,
- DF0940490F63CB26002D821E /* detection.cpp in Sources */,
- DF09404A0F63CB26002D821E /* graphics.cpp in Sources */,
- DF09404B0F63CB26002D821E /* made.cpp in Sources */,
- DF09404C0F63CB26002D821E /* music.cpp in Sources */,
- DF09404D0F63CB26002D821E /* pmvplayer.cpp in Sources */,
- DF09404E0F63CB26002D821E /* redreader.cpp in Sources */,
- DF09404F0F63CB26002D821E /* resource.cpp in Sources */,
- DF0940500F63CB26002D821E /* screen.cpp in Sources */,
- DF0940510F63CB26002D821E /* screenfx.cpp in Sources */,
- DF0940520F63CB26002D821E /* script.cpp in Sources */,
- DF0940530F63CB26002D821E /* scriptfuncs.cpp in Sources */,
- DF0940540F63CB26002D821E /* sound.cpp in Sources */,
- DF0940550F63CB26002D821E /* balloons.cpp in Sources */,
- DF0940560F63CB26002D821E /* callables_br.cpp in Sources */,
- DF0940570F63CB26002D821E /* callables_ns.cpp in Sources */,
- DF0940580F63CB26002D821E /* debug.cpp in Sources */,
- DF0940590F63CB26002D821E /* detection.cpp in Sources */,
- DF09405A0F63CB26002D821E /* dialogue.cpp in Sources */,
- DF09405B0F63CB26002D821E /* disk_br.cpp in Sources */,
- DF09405C0F63CB26002D821E /* disk_ns.cpp in Sources */,
- DF09405D0F63CB26002D821E /* exec_br.cpp in Sources */,
- DF09405E0F63CB26002D821E /* exec_ns.cpp in Sources */,
- DF09405F0F63CB26002D821E /* font.cpp in Sources */,
- DF0940600F63CB26002D821E /* gfxbase.cpp in Sources */,
- DF0940610F63CB26002D821E /* graphics.cpp in Sources */,
- DF0940620F63CB26002D821E /* gui.cpp in Sources */,
- DF0940630F63CB26002D821E /* gui_br.cpp in Sources */,
- DF0940640F63CB26002D821E /* gui_ns.cpp in Sources */,
- DF0940650F63CB26002D821E /* input.cpp in Sources */,
- DF0940660F63CB26002D821E /* inventory.cpp in Sources */,
- DF0940670F63CB26002D821E /* objects.cpp in Sources */,
- DF0940680F63CB26002D821E /* parallaction.cpp in Sources */,
- DF0940690F63CB26002D821E /* parallaction_br.cpp in Sources */,
- DF09406A0F63CB26002D821E /* parallaction_ns.cpp in Sources */,
- DF09406B0F63CB26002D821E /* parser.cpp in Sources */,
- DF09406C0F63CB26002D821E /* parser_br.cpp in Sources */,
- DF09406D0F63CB26002D821E /* parser_ns.cpp in Sources */,
- DF09406E0F63CB26002D821E /* saveload.cpp in Sources */,
- DF0940700F63CB26002D821E /* staticres.cpp in Sources */,
- DF0940710F63CB26002D821E /* walk.cpp in Sources */,
- DF0940720F63CB26002D821E /* bankman.cpp in Sources */,
- DF0940730F63CB26002D821E /* command.cpp in Sources */,
- DF0940740F63CB26002D821E /* credits.cpp in Sources */,
- DF0940750F63CB26002D821E /* cutaway.cpp in Sources */,
- DF0940760F63CB26002D821E /* debug.cpp in Sources */,
- DF0940770F63CB26002D821E /* display.cpp in Sources */,
- DF0940780F63CB26002D821E /* graphics.cpp in Sources */,
- DF0940790F63CB26002D821E /* grid.cpp in Sources */,
- DF09407A0F63CB26002D821E /* input.cpp in Sources */,
- DF09407B0F63CB26002D821E /* journal.cpp in Sources */,
- DF09407C0F63CB26002D821E /* logic.cpp in Sources */,
- DF09407D0F63CB26002D821E /* midiadlib.cpp in Sources */,
- DF09407E0F63CB26002D821E /* music.cpp in Sources */,
- DF09407F0F63CB26002D821E /* musicdata.cpp in Sources */,
- DF0940800F63CB26002D821E /* queen.cpp in Sources */,
- DF0940810F63CB26002D821E /* resource.cpp in Sources */,
- DF0940820F63CB26002D821E /* restables.cpp in Sources */,
- DF0940830F63CB26002D821E /* sound.cpp in Sources */,
- DF0940840F63CB26002D821E /* state.cpp in Sources */,
- DF0940850F63CB26002D821E /* talk.cpp in Sources */,
- DF0940860F63CB26002D821E /* walk.cpp in Sources */,
- DF0940870F63CB26002D821E /* actor.cpp in Sources */,
- DF0940880F63CB26002D821E /* actor_path.cpp in Sources */,
- DF0940890F63CB26002D821E /* actor_walk.cpp in Sources */,
- DF09408A0F63CB26002D821E /* animation.cpp in Sources */,
- DF09408B0F63CB26002D821E /* console.cpp in Sources */,
- DF09408C0F63CB26002D821E /* detection.cpp in Sources */,
- DF09408D0F63CB26002D821E /* events.cpp in Sources */,
- DF09408E0F63CB26002D821E /* font.cpp in Sources */,
- DF09408F0F63CB26002D821E /* font_map.cpp in Sources */,
- DF0940900F63CB26002D821E /* gfx.cpp in Sources */,
- DF0940910F63CB26002D821E /* image.cpp in Sources */,
- DF0940920F63CB26002D821E /* input.cpp in Sources */,
- DF0940930F63CB26002D821E /* interface.cpp in Sources */,
- DF0940940F63CB26002D821E /* introproc_ihnm.cpp in Sources */,
- DF0940950F63CB26002D821E /* introproc_ite.cpp in Sources */,
- DF0940960F63CB26002D821E /* isomap.cpp in Sources */,
- DF0940970F63CB26002D821E /* itedata.cpp in Sources */,
- DF0940980F63CB26002D821E /* music.cpp in Sources */,
- DF0940990F63CB26002D821E /* objectmap.cpp in Sources */,
- DF09409A0F63CB26002D821E /* palanim.cpp in Sources */,
- DF09409B0F63CB26002D821E /* puzzle.cpp in Sources */,
- DF09409C0F63CB26002D821E /* render.cpp in Sources */,
- DF09409D0F63CB26002D821E /* saga.cpp in Sources */,
- DF09409E0F63CB26002D821E /* saveload.cpp in Sources */,
- DF09409F0F63CB26002D821E /* scene.cpp in Sources */,
- DF0940A00F63CB26002D821E /* script.cpp in Sources */,
- DF0940A10F63CB26002D821E /* sfuncs.cpp in Sources */,
- DF0940A20F63CB26002D821E /* sndres.cpp in Sources */,
- DF0940A30F63CB26002D821E /* sound.cpp in Sources */,
- DF0940A40F63CB26002D821E /* sprite.cpp in Sources */,
- DF0940A50F63CB26002D821E /* sthread.cpp in Sources */,
- DF0940A60F63CB26002D821E /* actor.cpp in Sources */,
- DF0940A70F63CB26002D821E /* akos.cpp in Sources */,
- DF0940A80F63CB26002D821E /* base-costume.cpp in Sources */,
- DF0940A90F63CB26002D821E /* bomp.cpp in Sources */,
- DF0940AA0F63CB26002D821E /* boxes.cpp in Sources */,
- DF0940AB0F63CB26002D821E /* camera.cpp in Sources */,
- DF0940AC0F63CB26002D821E /* charset-fontdata.cpp in Sources */,
- DF0940AD0F63CB26002D821E /* charset.cpp in Sources */,
- DF0940AE0F63CB26002D821E /* costume.cpp in Sources */,
- DF0940AF0F63CB26002D821E /* cursor.cpp in Sources */,
- DF0940B00F63CB26002D821E /* debugger.cpp in Sources */,
- DF0940B10F63CB26002D821E /* detection.cpp in Sources */,
- DF0940B20F63CB26002D821E /* dialogs.cpp in Sources */,
- DF0940B30F63CB26002D821E /* file.cpp in Sources */,
- DF0940B40F63CB26002D821E /* file_nes.cpp in Sources */,
- DF0940B50F63CB26002D821E /* gfx.cpp in Sources */,
- DF0940B60F63CB26002D821E /* animation_he.cpp in Sources */,
- DF0940B70F63CB26002D821E /* cup_player_he.cpp in Sources */,
- DF0940B80F63CB26002D821E /* floodfill_he.cpp in Sources */,
- DF0940B90F63CB26002D821E /* logic_he.cpp in Sources */,
- DF0940BA0F63CB26002D821E /* palette_he.cpp in Sources */,
- DF0940BB0F63CB26002D821E /* resource_he.cpp in Sources */,
- DF0940BC0F63CB26002D821E /* script_v100he.cpp in Sources */,
- DF0940BD0F63CB26002D821E /* script_v60he.cpp in Sources */,
- DF0940BE0F63CB26002D821E /* script_v70he.cpp in Sources */,
- DF0940BF0F63CB26002D821E /* script_v71he.cpp in Sources */,
- DF0940C00F63CB26002D821E /* script_v72he.cpp in Sources */,
- DF0940C10F63CB26002D821E /* script_v80he.cpp in Sources */,
- DF0940C20F63CB26002D821E /* script_v90he.cpp in Sources */,
- DF0940C30F63CB26002D821E /* sound_he.cpp in Sources */,
- DF0940C40F63CB26002D821E /* sprite_he.cpp in Sources */,
- DF0940C50F63CB26002D821E /* wiz_he.cpp in Sources */,
- DF0940C60F63CB26002D821E /* help.cpp in Sources */,
- DF0940C70F63CB26002D821E /* imuse.cpp in Sources */,
- DF0940C80F63CB26002D821E /* imuse_part.cpp in Sources */,
- DF0940C90F63CB26002D821E /* imuse_player.cpp in Sources */,
- DF0940CA0F63CB26002D821E /* instrument.cpp in Sources */,
- DF0940CB0F63CB26002D821E /* sysex_samnmax.cpp in Sources */,
- DF0940CC0F63CB26002D821E /* sysex_scumm.cpp in Sources */,
- DF0940CD0F63CB26002D821E /* dimuse.cpp in Sources */,
- DF0940CE0F63CB26002D821E /* dimuse_bndmgr.cpp in Sources */,
- DF0940CF0F63CB26002D821E /* dimuse_codecs.cpp in Sources */,
- DF0940D00F63CB26002D821E /* dimuse_music.cpp in Sources */,
- DF0940D10F63CB26002D821E /* dimuse_script.cpp in Sources */,
- DF0940D20F63CB26002D821E /* dimuse_sndmgr.cpp in Sources */,
- DF0940D30F63CB26002D821E /* dimuse_tables.cpp in Sources */,
- DF0940D40F63CB26002D821E /* dimuse_track.cpp in Sources */,
- DF0940D50F63CB26002D821E /* input.cpp in Sources */,
- DF0940D60F63CB26002D821E /* insane.cpp in Sources */,
- DF0940D70F63CB26002D821E /* insane_ben.cpp in Sources */,
- DF0940D80F63CB26002D821E /* insane_enemy.cpp in Sources */,
- DF0940D90F63CB26002D821E /* insane_iact.cpp in Sources */,
- DF0940DA0F63CB26002D821E /* insane_scenes.cpp in Sources */,
- DF0940DC0F63CB26002D821E /* midiparser_ro.cpp in Sources */,
- DF0940DD0F63CB26002D821E /* nut_renderer.cpp in Sources */,
- DF0940DE0F63CB26002D821E /* object.cpp in Sources */,
- DF0940DF0F63CB26002D821E /* palette.cpp in Sources */,
- DF0940E00F63CB26002D821E /* player_mod.cpp in Sources */,
- DF0940E10F63CB26002D821E /* player_nes.cpp in Sources */,
- DF0940E20F63CB26002D821E /* player_v1.cpp in Sources */,
- DF0940E30F63CB26002D821E /* player_v2.cpp in Sources */,
- DF0940E40F63CB26002D821E /* player_v2a.cpp in Sources */,
- DF0940E50F63CB26002D821E /* player_v3a.cpp in Sources */,
- DF0940E60F63CB26002D821E /* resource.cpp in Sources */,
- DF0940E70F63CB26002D821E /* resource_v2.cpp in Sources */,
- DF0940E80F63CB26002D821E /* resource_v3.cpp in Sources */,
- DF0940E90F63CB26002D821E /* resource_v4.cpp in Sources */,
- DF0940EA0F63CB26002D821E /* room.cpp in Sources */,
- DF0940EB0F63CB26002D821E /* saveload.cpp in Sources */,
- DF0940EC0F63CB26002D821E /* script.cpp in Sources */,
- DF0940ED0F63CB26002D821E /* script_v0.cpp in Sources */,
- DF0940EE0F63CB26002D821E /* script_v2.cpp in Sources */,
- DF0940EF0F63CB26002D821E /* script_v5.cpp in Sources */,
- DF0940F00F63CB26002D821E /* script_v6.cpp in Sources */,
- DF0940F10F63CB26002D821E /* script_v8.cpp in Sources */,
- DF0940F20F63CB26002D821E /* scumm.cpp in Sources */,
- DF0940F30F63CB26002D821E /* channel.cpp in Sources */,
- DF0940F40F63CB26002D821E /* codec1.cpp in Sources */,
- DF0940F50F63CB26002D821E /* codec37.cpp in Sources */,
- DF0940F60F63CB26002D821E /* codec47.cpp in Sources */,
- DF0940F70F63CB26002D821E /* imuse_channel.cpp in Sources */,
- DF0940F80F63CB26002D821E /* saud_channel.cpp in Sources */,
- DF0940F90F63CB26002D821E /* smush_font.cpp in Sources */,
- DF0940FA0F63CB26002D821E /* smush_mixer.cpp in Sources */,
- DF0940FB0F63CB26002D821E /* smush_player.cpp in Sources */,
- DF0940FC0F63CB26002D821E /* sound.cpp in Sources */,
- DF0940FD0F63CB26002D821E /* string.cpp in Sources */,
- DF0940FE0F63CB26002D821E /* usage_bits.cpp in Sources */,
- DF0940FF0F63CB26002D821E /* util.cpp in Sources */,
- DF0941000F63CB26002D821E /* vars.cpp in Sources */,
- DF0941010F63CB26002D821E /* verbs.cpp in Sources */,
- DF0941020F63CB26002D821E /* autoroute.cpp in Sources */,
- DF0941030F63CB26002D821E /* compact.cpp in Sources */,
- DF0941040F63CB26002D821E /* control.cpp in Sources */,
- DF0941050F63CB26002D821E /* debug.cpp in Sources */,
- DF0941060F63CB26002D821E /* disk.cpp in Sources */,
- DF0941070F63CB26002D821E /* grid.cpp in Sources */,
- DF0941080F63CB26002D821E /* hufftext.cpp in Sources */,
- DF0941090F63CB26002D821E /* intro.cpp in Sources */,
- DF09410A0F63CB26002D821E /* logic.cpp in Sources */,
- DF09410B0F63CB26002D821E /* mouse.cpp in Sources */,
- DF09410C0F63CB26002D821E /* adlibchannel.cpp in Sources */,
- DF09410D0F63CB26002D821E /* adlibmusic.cpp in Sources */,
- DF09410E0F63CB26002D821E /* gmchannel.cpp in Sources */,
- DF09410F0F63CB26002D821E /* gmmusic.cpp in Sources */,
- DF0941100F63CB26002D821E /* mt32music.cpp in Sources */,
- DF0941110F63CB26002D821E /* musicbase.cpp in Sources */,
- DF0941120F63CB26002D821E /* rnc_deco.cpp in Sources */,
- DF0941130F63CB26002D821E /* screen.cpp in Sources */,
- DF0941140F63CB26002D821E /* sky.cpp in Sources */,
- DF0941150F63CB26002D821E /* sound.cpp in Sources */,
- DF0941160F63CB26002D821E /* text.cpp in Sources */,
- DF0941170F63CB26002D821E /* animation.cpp in Sources */,
- DF0941180F63CB26002D821E /* control.cpp in Sources */,
- DF0941190F63CB26002D821E /* debug.cpp in Sources */,
- DF09411A0F63CB26002D821E /* eventman.cpp in Sources */,
- DF09411B0F63CB26002D821E /* logic.cpp in Sources */,
- DF09411C0F63CB26002D821E /* memman.cpp in Sources */,
- DF09411D0F63CB26002D821E /* menu.cpp in Sources */,
- DF09411E0F63CB26002D821E /* mouse.cpp in Sources */,
- DF09411F0F63CB26002D821E /* music.cpp in Sources */,
- DF0941200F63CB26002D821E /* objectman.cpp in Sources */,
- DF0941210F63CB26002D821E /* resman.cpp in Sources */,
- DF0941220F63CB26002D821E /* router.cpp in Sources */,
- DF0941230F63CB26002D821E /* screen.cpp in Sources */,
- DF0941240F63CB26002D821E /* sound.cpp in Sources */,
- DF0941250F63CB26002D821E /* staticres.cpp in Sources */,
- DF0941260F63CB26002D821E /* sword1.cpp in Sources */,
- DF0941270F63CB26002D821E /* text.cpp in Sources */,
- DF0941280F63CB26002D821E /* animation.cpp in Sources */,
- DF0941290F63CB26002D821E /* anims.cpp in Sources */,
- DF09412A0F63CB26002D821E /* console.cpp in Sources */,
- DF09412B0F63CB26002D821E /* controls.cpp in Sources */,
- DF09412C0F63CB26002D821E /* debug.cpp in Sources */,
- DF09412D0F63CB26002D821E /* events.cpp in Sources */,
- DF09412E0F63CB26002D821E /* function.cpp in Sources */,
- DF09412F0F63CB26002D821E /* icons.cpp in Sources */,
- DF0941300F63CB26002D821E /* interpreter.cpp in Sources */,
- DF0941310F63CB26002D821E /* layers.cpp in Sources */,
- DF0941320F63CB26002D821E /* logic.cpp in Sources */,
- DF0941330F63CB26002D821E /* maketext.cpp in Sources */,
- DF0941340F63CB26002D821E /* memory.cpp in Sources */,
- DF0941350F63CB26002D821E /* menu.cpp in Sources */,
- DF0941360F63CB26002D821E /* mouse.cpp in Sources */,
- DF0941370F63CB26002D821E /* music.cpp in Sources */,
- DF0941380F63CB26002D821E /* palette.cpp in Sources */,
- DF0941390F63CB26002D821E /* protocol.cpp in Sources */,
- DF09413A0F63CB26002D821E /* render.cpp in Sources */,
- DF09413B0F63CB26002D821E /* resman.cpp in Sources */,
- DF09413C0F63CB26002D821E /* router.cpp in Sources */,
- DF09413D0F63CB26002D821E /* saveload.cpp in Sources */,
- DF09413E0F63CB26002D821E /* screen.cpp in Sources */,
- DF09413F0F63CB26002D821E /* scroll.cpp in Sources */,
- DF0941400F63CB26002D821E /* sound.cpp in Sources */,
- DF0941410F63CB26002D821E /* speech.cpp in Sources */,
- DF0941420F63CB26002D821E /* sprite.cpp in Sources */,
- DF0941430F63CB26002D821E /* startup.cpp in Sources */,
- DF0941440F63CB26002D821E /* sword2.cpp in Sources */,
- DF0941450F63CB26002D821E /* sync.cpp in Sources */,
- DF0941460F63CB26002D821E /* walker.cpp in Sources */,
- DF0941470F63CB26002D821E /* actors.cpp in Sources */,
- DF0941480F63CB26002D821E /* anim.cpp in Sources */,
- DF0941490F63CB26002D821E /* background.cpp in Sources */,
- DF09414A0F63CB26002D821E /* bg.cpp in Sources */,
- DF09414B0F63CB26002D821E /* cliprect.cpp in Sources */,
- DF09414C0F63CB26002D821E /* config.cpp in Sources */,
- DF09414D0F63CB26002D821E /* cursor.cpp in Sources */,
- DF09414E0F63CB26002D821E /* debugger.cpp in Sources */,
- DF09414F0F63CB26002D821E /* detection.cpp in Sources */,
- DF0941500F63CB26002D821E /* effect.cpp in Sources */,
- DF0941510F63CB26002D821E /* events.cpp in Sources */,
- DF0941520F63CB26002D821E /* faders.cpp in Sources */,
- DF0941530F63CB26002D821E /* font.cpp in Sources */,
- DF0941540F63CB26002D821E /* graphics.cpp in Sources */,
- DF0941550F63CB26002D821E /* handle.cpp in Sources */,
- DF0941560F63CB26002D821E /* heapmem.cpp in Sources */,
- DF0941570F63CB26002D821E /* mareels.cpp in Sources */,
- DF0941580F63CB26002D821E /* move.cpp in Sources */,
- DF0941590F63CB26002D821E /* multiobj.cpp in Sources */,
- DF09415A0F63CB26002D821E /* music.cpp in Sources */,
- DF09415B0F63CB26002D821E /* object.cpp in Sources */,
- DF09415C0F63CB26002D821E /* palette.cpp in Sources */,
- DF09415D0F63CB26002D821E /* pcode.cpp in Sources */,
- DF09415E0F63CB26002D821E /* pdisplay.cpp in Sources */,
- DF09415F0F63CB26002D821E /* play.cpp in Sources */,
- DF0941600F63CB26002D821E /* polygons.cpp in Sources */,
- DF0941610F63CB26002D821E /* rince.cpp in Sources */,
- DF0941620F63CB26002D821E /* saveload.cpp in Sources */,
- DF0941630F63CB26002D821E /* savescn.cpp in Sources */,
- DF0941640F63CB26002D821E /* scene.cpp in Sources */,
- DF0941650F63CB26002D821E /* sched.cpp in Sources */,
- DF0941660F63CB26002D821E /* scn.cpp in Sources */,
- DF0941670F63CB26002D821E /* scroll.cpp in Sources */,
- DF0941680F63CB26002D821E /* sound.cpp in Sources */,
- DF0941690F63CB26002D821E /* strres.cpp in Sources */,
- DF09416A0F63CB26002D821E /* text.cpp in Sources */,
- DF09416B0F63CB26002D821E /* timers.cpp in Sources */,
- DF09416C0F63CB26002D821E /* tinlib.cpp in Sources */,
- DF09416D0F63CB26002D821E /* tinsel.cpp in Sources */,
- DF09416E0F63CB26002D821E /* token.cpp in Sources */,
- DF09416F0F63CB26002D821E /* detection.cpp in Sources */,
- DF0941700F63CB26002D821E /* graphics.cpp in Sources */,
- DF0941710F63CB26002D821E /* menu.cpp in Sources */,
- DF0941720F63CB26002D821E /* midi.cpp in Sources */,
- DF0941730F63CB26002D821E /* opcodes.cpp in Sources */,
- DF0941740F63CB26002D821E /* resource.cpp in Sources */,
- DF0941750F63CB26002D821E /* saveload.cpp in Sources */,
- DF0941760F63CB26002D821E /* staticres.cpp in Sources */,
- DF0941770F63CB26002D821E /* touche.cpp in Sources */,
- DF0941790F63CB26002D821E /* timidity.cpp in Sources */,
- DF09417A0F63CB26002D821E /* archive.cpp in Sources */,
- DF09417B0F63CB26002D821E /* unarj.cpp in Sources */,
- DF09417C0F63CB26002D821E /* stdiostream.cpp in Sources */,
- DF09417E0F63CB26002D821E /* saveload.cpp in Sources */,
- DF09417F0F63CB26002D821E /* ThemeEngine.cpp in Sources */,
- DF0941800F63CB26002D821E /* ThemeEval.cpp in Sources */,
- DF0941810F63CB26002D821E /* ThemeLayout.cpp in Sources */,
- DF0941820F63CB26002D821E /* ThemeParser.cpp in Sources */,
- DF0941830F63CB26002D821E /* thumbnail.cpp in Sources */,
- DF0941840F63CB26002D821E /* VectorRenderer.cpp in Sources */,
- DF0941850F63CB26002D821E /* VectorRendererSpec.cpp in Sources */,
- DF0941860F63CB26002D821E /* xmlparser.cpp in Sources */,
- DF0941870F63CB26002D821E /* game.cpp in Sources */,
- DF0941880F63CB26002D821E /* saveload.cpp in Sources */,
- DF0941890F63CB26002D821E /* detection.cpp in Sources */,
- DF09418A0F63CB26002D821E /* detection.cpp in Sources */,
- DF09418B0F63CB26002D821E /* thumbnail_intern.cpp in Sources */,
- DF09418C0F63CB26002D821E /* dither.cpp in Sources */,
- DF0941920F63CB26002D821E /* debug.cpp in Sources */,
- DF0941940F63CB26002D821E /* posix-saves.cpp in Sources */,
- DF0941950F63CB26002D821E /* bmv.cpp in Sources */,
- DF0941960F63CB26002D821E /* dialogs.cpp in Sources */,
- DF0941970F63CB26002D821E /* drives.cpp in Sources */,
- DF0941980F63CB26002D821E /* sysvar.cpp in Sources */,
- DF0941990F63CB26002D821E /* gui_lol.cpp in Sources */,
- DF09419A0F63CB26002D821E /* items_lol.cpp in Sources */,
- DF09419B0F63CB26002D821E /* script_lol.cpp in Sources */,
- DF09419C0F63CB26002D821E /* sequences_lol.cpp in Sources */,
- DF09419D0F63CB26002D821E /* sound_midi.cpp in Sources */,
- DF09419E0F63CB26002D821E /* util.cpp in Sources */,
- DF0941A20F63CB26002D821E /* scene_lol.cpp in Sources */,
- DF0941A30F63CB26002D821E /* advancedDetector.cpp in Sources */,
- DF0941A40F63CB26002D821E /* base-backend.cpp in Sources */,
- DF0941A60F63CB26002D821E /* resource.cpp in Sources */,
- DF0941A70F63CB26002D821E /* resource_hrs.cpp in Sources */,
- DF0941A80F63CB26002D821E /* resource_res.cpp in Sources */,
- DF0941A90F63CB26002D821E /* resource_rsc.cpp in Sources */,
- DF0941AA0F63CB26002D821E /* sfuncs_ihnm.cpp in Sources */,
- DF0941AB0F63CB26002D821E /* debugger.cpp in Sources */,
- DF0941AC0F63CB26002D821E /* staticres.cpp in Sources */,
- DF0941AD0F63CB26002D821E /* cell.cpp in Sources */,
- DF0941AE0F63CB26002D821E /* cursor.cpp in Sources */,
- DF0941AF0F63CB26002D821E /* debug.cpp in Sources */,
- DF0941B00F63CB26002D821E /* detection.cpp in Sources */,
- DF0941B10F63CB26002D821E /* font.cpp in Sources */,
- DF0941B20F63CB26002D821E /* graphics.cpp in Sources */,
- DF0941B30F63CB26002D821E /* groovie.cpp in Sources */,
- DF0941B40F63CB26002D821E /* lzss.cpp in Sources */,
- DF0941B50F63CB26002D821E /* music.cpp in Sources */,
- DF0941B60F63CB26002D821E /* player.cpp in Sources */,
- DF0941B70F63CB26002D821E /* resource.cpp in Sources */,
- DF0941B80F63CB26002D821E /* roq.cpp in Sources */,
- DF0941B90F63CB26002D821E /* saveload.cpp in Sources */,
- DF0941BA0F63CB26002D821E /* script.cpp in Sources */,
- DF0941BB0F63CB26002D821E /* vdx.cpp in Sources */,
- DF0941BC0F63CB26002D821E /* detection.cpp in Sources */,
- DF0941BD0F63CB26002D821E /* graphics.cpp in Sources */,
- DF0941BE0F63CB26002D821E /* locations.cpp in Sources */,
- DF0941BF0F63CB26002D821E /* resource.cpp in Sources */,
- DF0941C00F63CB26002D821E /* saveload.cpp in Sources */,
- DF0941C10F63CB26002D821E /* sequences.cpp in Sources */,
- DF0941C20F63CB26002D821E /* staticres.cpp in Sources */,
- DF0941C30F63CB26002D821E /* tucker.cpp in Sources */,
- DF0941C40F63CB26002D821E /* detection.cpp in Sources */,
- DF0941C60F63CB26002D821E /* gc.cpp in Sources */,
- DF0941C80F63CB26002D821E /* kernel.cpp in Sources */,
- DF0941C90F63CB26002D821E /* kevent.cpp in Sources */,
- DF0941CA0F63CB26002D821E /* kfile.cpp in Sources */,
- DF0941CB0F63CB26002D821E /* kgraphics.cpp in Sources */,
- DF0941CC0F63CB26002D821E /* klists.cpp in Sources */,
- DF0941CD0F63CB26002D821E /* kmath.cpp in Sources */,
- DF0941CE0F63CB26002D821E /* kmenu.cpp in Sources */,
- DF0941CF0F63CB26002D821E /* kmovement.cpp in Sources */,
- DF0941D00F63CB26002D821E /* kpathing.cpp in Sources */,
- DF0941D10F63CB26002D821E /* kscripts.cpp in Sources */,
- DF0941D20F63CB26002D821E /* ksound.cpp in Sources */,
- DF0941D30F63CB26002D821E /* kstring.cpp in Sources */,
- DF0941D40F63CB26002D821E /* message.cpp in Sources */,
- DF0941D60F63CB26002D821E /* savegame.cpp in Sources */,
- DF0941D80F63CB26002D821E /* scriptdebug.cpp in Sources */,
- DF0941D90F63CB26002D821E /* seg_manager.cpp in Sources */,
- DF0941DA0F63CB26002D821E /* vm.cpp in Sources */,
- DF0941EC0F63CB26002D821E /* sci.cpp in Sources */,
- DF0942020F63CB26002D821E /* unzip.cpp in Sources */,
- DF0942030F63CB26002D821E /* console.cpp in Sources */,
- DF0942090F63CB26002D821E /* state.cpp in Sources */,
- DF09420C0F63CB26002D821E /* exec.cpp in Sources */,
- DF09420D0F63CB26002D821E /* timer_lol.cpp in Sources */,
- DF0942100F63CB26002D821E /* sprites_lol.cpp in Sources */,
- DF0942110F63CB26002D821E /* script.cpp in Sources */,
- DF0942150F63CB26002D821E /* pn.cpp in Sources */,
- DF0942160F63CB26002D821E /* script_pn.cpp in Sources */,
- DF0942170F63CB26002D821E /* vga_pn.cpp in Sources */,
- DF0942470F63CB9A002D821E /* main.cpp in Sources */,
- DF09424A0F63CB9A002D821E /* sdl.cpp in Sources */,
- DF0944330F63FBB3002D821E /* coreaudio.cpp in Sources */,
- DF0944340F63FBB3002D821E /* coremidi.cpp in Sources */,
- DF5CEB290F75535000DEA624 /* sound_br.cpp in Sources */,
- DF5CEB2A0F75535000DEA624 /* sound_ns.cpp in Sources */,
- DF5CEB310F75538000DEA624 /* protracker.cpp in Sources */,
- DFE88C460F874A1100C555C5 /* sound.cpp in Sources */,
- DF09CC100FAC4E1900A5AFD7 /* batplayer.cpp in Sources */,
- DF09CC110FAC4E1900A5AFD7 /* demoplayer.cpp in Sources */,
- DF09CC120FAC4E1900A5AFD7 /* scnplayer.cpp in Sources */,
- DF09CC130FAC4E1900A5AFD7 /* draw_fascin.cpp in Sources */,
- DF09CC150FAC4E1900A5AFD7 /* inter_fascin.cpp in Sources */,
- DF09CC280FAC4EAB00A5AFD7 /* script_v3.cpp in Sources */,
- DF09CC290FAC4EAB00A5AFD7 /* script_v4.cpp in Sources */,
- DF61183C0FE3A8080042AD3F /* kmisc.cpp in Sources */,
- DF61183D0FE3A8080042AD3F /* segment.cpp in Sources */,
- DF6118490FE3A8250042AD3F /* decompressor.cpp in Sources */,
- DF61184A0FE3A8250042AD3F /* resource.cpp in Sources */,
- DF6118550FE3A8990042AD3F /* disk.cpp in Sources */,
- DF6118890FE3A9AA0042AD3F /* saveconverter.cpp in Sources */,
- DF61188A0FE3A9AA0042AD3F /* saveconverter_v2.cpp in Sources */,
- DF61188B0FE3A9AA0042AD3F /* saveconverter_v3.cpp in Sources */,
- DF61188C0FE3A9AA0042AD3F /* saveconverter_v4.cpp in Sources */,
- DF61188E0FE3A9AA0042AD3F /* savefile.cpp in Sources */,
- DF61188F0FE3A9AA0042AD3F /* savehandler.cpp in Sources */,
- DF6118900FE3A9AA0042AD3F /* saveload.cpp in Sources */,
- DF6118910FE3A9AA0042AD3F /* saveload_v2.cpp in Sources */,
- DF6118920FE3A9AA0042AD3F /* saveload_v3.cpp in Sources */,
- DF6118930FE3A9AA0042AD3F /* saveload_v4.cpp in Sources */,
- DF6118940FE3A9AA0042AD3F /* saveload_v6.cpp in Sources */,
- DF6118AF0FE3A9EA0042AD3F /* feeble.cpp in Sources */,
- DF6118B80FE3AA280042AD3F /* saveload_lol.cpp in Sources */,
- DF6118B90FE3AA280042AD3F /* sound_lol.cpp in Sources */,
- DF6118BA0FE3AA280042AD3F /* sound_pcspk.cpp in Sources */,
- DF6118BB0FE3AA280042AD3F /* text_lol.cpp in Sources */,
- DF6118C70FE3AABD0042AD3F /* player_v2cms.cpp in Sources */,
- DF6118CC0FE3AAFD0042AD3F /* hardwarekeys.cpp in Sources */,
- DF7585CE100CB66E00CC3324 /* expression.cpp in Sources */,
- DF7585CF100CB66E00CC3324 /* hotspots.cpp in Sources */,
- DF7585D0100CB66E00CC3324 /* init_v6.cpp in Sources */,
- DF7585D1100CB66E00CC3324 /* resources.cpp in Sources */,
- DF7585D2100CB66E00CC3324 /* script.cpp in Sources */,
- DF7585D3100CB66E00CC3324 /* totfile.cpp in Sources */,
- DF7585EC100CB6EA00CC3324 /* sjis.cpp in Sources */,
- DF7585F1100CB70600CC3324 /* saveload_playtoons.cpp in Sources */,
- DF7585F7100CB75800CC3324 /* static_selectors.cpp in Sources */,
- DF6BF4C810529DA50069811F /* conversion.cpp in Sources */,
- DF6BF4C910529DA50069811F /* jpeg.cpp in Sources */,
- DF6BF4DE10529DE90069811F /* input_pn.cpp in Sources */,
- DF6BF4DF10529DE90069811F /* string_pn.cpp in Sources */,
- DF6BF4E010529DE90069811F /* verb_pn.cpp in Sources */,
- DF6BF4E610529E260069811F /* sound_amiga.cpp in Sources */,
- DF6BF4EE10529E6E0069811F /* init_v4.cpp in Sources */,
- DF6BF4EF10529E6E0069811F /* inter_playtoons.cpp in Sources */,
- DF6BF4F510529EE40069811F /* player_v4a.cpp in Sources */,
- DF6BF50010529F140069811F /* EventDispatcher.cpp in Sources */,
- DF6BF50110529F140069811F /* EventRecorder.cpp in Sources */,
- DF90E9BF10AEDA9B00C8F93F /* selector.cpp in Sources */,
- DF90EAA410B0234300C8F93F /* draw_playtoons.cpp in Sources */,
- DF90EAAD10B0236F00C8F93F /* staticres.cpp in Sources */,
- DF2EC3E510E6490800765801 /* browser_osx.mm in Sources */,
- DF2EC3F810E64C0C00765801 /* dialogs.cpp in Sources */,
- DF2EC3FE10E64C4300765801 /* animator_tim.cpp in Sources */,
- DF2EC40510E64C8000765801 /* event.cpp in Sources */,
- DF2EC50110E64D7C00765801 /* player_pce.cpp in Sources */,
- DF2EC50210E64D7C00765801 /* player_sid.cpp in Sources */,
- DF2EC50B10E64DB300765801 /* textconsole.cpp in Sources */,
- DF45B1F4116628A5009B85CC /* animate.cpp in Sources */,
- DF45B1F5116628A5009B85CC /* cache.cpp in Sources */,
- DF45B1F6116628A5009B85CC /* compare.cpp in Sources */,
- DF45B1F7116628A5009B85CC /* controls.cpp in Sources */,
- DF45B1F8116628A5009B85CC /* coordadjuster.cpp in Sources */,
- DF45B1F9116628A5009B85CC /* cursor.cpp in Sources */,
- DF45B1FA116628A5009B85CC /* font.cpp in Sources */,
- DF45B1FE116628A5009B85CC /* menu.cpp in Sources */,
- DF45B1FF116628A5009B85CC /* paint.cpp in Sources */,
- DF45B200116628A5009B85CC /* paint16.cpp in Sources */,
- DF45B202116628A5009B85CC /* palette.cpp in Sources */,
- DF45B203116628A5009B85CC /* picture.cpp in Sources */,
- DF45B204116628A5009B85CC /* portrait.cpp in Sources */,
- DF45B205116628A5009B85CC /* ports.cpp in Sources */,
- DF45B207116628A5009B85CC /* screen.cpp in Sources */,
- DF45B208116628A5009B85CC /* text16.cpp in Sources */,
- DF45B209116628A5009B85CC /* transitions.cpp in Sources */,
- DF45B20A116628A5009B85CC /* view.cpp in Sources */,
- DF45B20B116628A5009B85CC /* grammar.cpp in Sources */,
- DF45B20C116628A5009B85CC /* said.cpp in Sources */,
- DF45B20E116628A5009B85CC /* vocabulary.cpp in Sources */,
- DF45B20F116628A5009B85CC /* audio.cpp in Sources */,
- DF45B210116628A5009B85CC /* adlib.cpp in Sources */,
- DF45B212116628A5009B85CC /* fb01.cpp in Sources */,
- DF45B213116628A5009B85CC /* midi.cpp in Sources */,
- DF45B214116628A5009B85CC /* pcjr.cpp in Sources */,
- DF45B219116628A5009B85CC /* midiparser_sci.cpp in Sources */,
- DF45B21A116628A5009B85CC /* music.cpp in Sources */,
- DF45B21B116628A5009B85CC /* soundcmd.cpp in Sources */,
- DF45B21C116628A5009B85CC /* seq_decoder.cpp in Sources */,
- DFCDC6DB116629CE00A7D2A0 /* features.cpp in Sources */,
- DFCDC6DC116629CE00A7D2A0 /* kparse.cpp in Sources */,
- DFCDC6F811662AAB00A7D2A0 /* resource.cpp in Sources */,
- DFCDC70511662B0200A7D2A0 /* saveload_fascin.cpp in Sources */,
- DFCDC70C11662B6B00A7D2A0 /* macresman.cpp in Sources */,
- DFEC5D141166C5CF00C90552 /* random.cpp in Sources */,
- DFEC5D151166C5CF00C90552 /* tokenizer.cpp in Sources */,
- DFEC5D381166C67300C90552 /* savestate.cpp in Sources */,
- DF9B924A118E46730069C19D /* error.cpp in Sources */,
- DF9B9256118E46A00069C19D /* fontsjis.cpp in Sources */,
- DF9B9264118E46FE0069C19D /* error.cpp in Sources */,
- DFB0577811B753DA0015AE65 /* rational.cpp in Sources */,
- DFB0578411B7541F0015AE65 /* resource_audio.cpp in Sources */,
- DFB0578511B7541F0015AE65 /* util.cpp in Sources */,
- DFB0578C11B754570015AE65 /* maciconbar.cpp in Sources */,
- DFB0579311B7547D0015AE65 /* pict.cpp in Sources */,
- DF7F286311FF23D500159131 /* amigamac.cpp in Sources */,
- DF7F286B11FF23EF00159131 /* kvideo.cpp in Sources */,
- DF7F286C11FF23EF00159131 /* workarounds.cpp in Sources */,
- DF7F288411FF243B00159131 /* sound_2gs.cpp in Sources */,
- DF7F288511FF243B00159131 /* sound_coco3.cpp in Sources */,
- DF7F288611FF243B00159131 /* sound_midi.cpp in Sources */,
- DF7F288711FF243B00159131 /* sound_pcjr.cpp in Sources */,
- DF7F288811FF243B00159131 /* sound_sarien.cpp in Sources */,
- DF7F288D11FF244F00159131 /* Tooltip.cpp in Sources */,
- DF7F289711FF247300159131 /* translation.cpp in Sources */,
- DF7F28A711FF24C400159131 /* console.cpp in Sources */,
- DF895C04124C24680077F6E8 /* player_towns.cpp in Sources */,
- DF895C26124C25150077F6E8 /* init_fascin.cpp in Sources */,
- DF895C2B124C25350077F6E8 /* script_patches.cpp in Sources */,
- DF0E303C1252C5BD0082D593 /* cms.cpp in Sources */,
- 8CB5A9C61253FD6900CB6BC7 /* m4_scene.cpp in Sources */,
- 8CB5A9C71253FD6900CB6BC7 /* mads_logic.cpp in Sources */,
- 8CB5A9C81253FD6900CB6BC7 /* mads_player.cpp in Sources */,
- 8CB5A9C91253FD6900CB6BC7 /* mads_scene.cpp in Sources */,
- 8CB5A9CA1253FD6900CB6BC7 /* mads_views.cpp in Sources */,
- 8CD1ED2F126202AB00FA198C /* detection.cpp in Sources */,
- 8CD1ED30126202AB00FA198C /* display.cpp in Sources */,
- 8CD1ED32126202AB00FA198C /* file.cpp in Sources */,
- 8CD1ED33126202AB00FA198C /* hugo.cpp in Sources */,
- 8CD1ED34126202AB00FA198C /* intro.cpp in Sources */,
- 8CD1ED35126202AB00FA198C /* inventory.cpp in Sources */,
- 8CD1ED38126202AB00FA198C /* mouse.cpp in Sources */,
- 8CD1ED39126202AB00FA198C /* parser.cpp in Sources */,
- 8CD1ED3A126202AB00FA198C /* route.cpp in Sources */,
- 8CD1ED3B126202AB00FA198C /* schedule.cpp in Sources */,
- 8CD1ED3C126202AB00FA198C /* sound.cpp in Sources */,
- 8CD1ED3D126202AB00FA198C /* util.cpp in Sources */,
- 8CD1ED3E126202AB00FA198C /* anim.cpp in Sources */,
- 8CD1ED3F126202AB00FA198C /* audio.cpp in Sources */,
- 8CD1ED40126202AB00FA198C /* character.cpp in Sources */,
- 8CD1ED41126202AB00FA198C /* conversation.cpp in Sources */,
- 8CD1ED42126202AB00FA198C /* detection.cpp in Sources */,
- 8CD1ED43126202AB00FA198C /* drew.cpp in Sources */,
- 8CD1ED44126202AB00FA198C /* flux.cpp in Sources */,
- 8CD1ED45126202AB00FA198C /* font.cpp in Sources */,
- 8CD1ED46126202AB00FA198C /* hotspot.cpp in Sources */,
- 8CD1ED49126202AB00FA198C /* movie.cpp in Sources */,
- 8CD1ED4A126202AB00FA198C /* path.cpp in Sources */,
- 8CD1ED4B126202AB00FA198C /* picture.cpp in Sources */,
- 8CD1ED4C126202AB00FA198C /* resource.cpp in Sources */,
- 8CD1ED4D126202AB00FA198C /* script.cpp in Sources */,
- 8CD1ED4E126202AB00FA198C /* script_func.cpp in Sources */,
- 8CD1ED4F126202AB00FA198C /* state.cpp in Sources */,
- 8CD1ED50126202AB00FA198C /* text.cpp in Sources */,
- 8CD1ED51126202AB00FA198C /* tools.cpp in Sources */,
- 8CD1ED52126202AB00FA198C /* toon.cpp in Sources */,
- 8CD80C8C126271A9001C6C87 /* surface.cpp in Sources */,
- 8CD80C92126271BD001C6C87 /* gfx_towns.cpp in Sources */,
- 8CD80CF2126272A0001C6C87 /* actor.cpp in Sources */,
- 8CD80CF3126272A0001C6C87 /* animation.cpp in Sources */,
- 8CD80CF4126272A0001C6C87 /* callbacks.cpp in Sources */,
- 8CD80CF5126272A0001C6C87 /* console.cpp in Sources */,
- 8CD80CF6126272A0001C6C87 /* detection.cpp in Sources */,
- 8CD80CF7126272A0001C6C87 /* dialog.cpp in Sources */,
- 8CD80CF8126272A0001C6C87 /* font.cpp in Sources */,
- 8CD80CF9126272A0001C6C87 /* inventory.cpp in Sources */,
- 8CD80CFB126272A0001C6C87 /* music.cpp in Sources */,
- 8CD80CFC126272A0001C6C87 /* objects.cpp in Sources */,
- 8CD80CFD126272A0001C6C87 /* pack.cpp in Sources */,
- 8CD80CFE126272A0001C6C87 /* resources.cpp in Sources */,
- 8CD80CFF126272A0001C6C87 /* scene.cpp in Sources */,
- 8CD80D00126272A0001C6C87 /* segment.cpp in Sources */,
- 8CD80D01126272A0001C6C87 /* surface.cpp in Sources */,
- 8CD80D02126272A0001C6C87 /* surface_list.cpp in Sources */,
- 8CD80D03126272A0001C6C87 /* teenagent.cpp in Sources */,
- DF203F471380C06E0056300A /* gui-manager.cpp in Sources */,
- DF203F631380C2750056300A /* avi_decoder.cpp in Sources */,
- DF203F641380C2750056300A /* coktel_decoder.cpp in Sources */,
- DF203F651380C2750056300A /* dxa_decoder.cpp in Sources */,
- DF203F661380C2750056300A /* flic_decoder.cpp in Sources */,
- DF203F681380C2750056300A /* qt_decoder.cpp in Sources */,
- DF203F691380C2750056300A /* smk_decoder.cpp in Sources */,
- DF203F6A1380C2750056300A /* video_decoder.cpp in Sources */,
- DF203F951380C2920056300A /* cdtoons.cpp in Sources */,
- DF203F961380C2920056300A /* cinepak.cpp in Sources */,
- DF203F971380C2920056300A /* indeo3.cpp in Sources */,
- DF203F981380C2920056300A /* mjpeg.cpp in Sources */,
- DF203F991380C2920056300A /* msrle.cpp in Sources */,
- DF203F9A1380C2920056300A /* msvideo1.cpp in Sources */,
- DF203F9C1380C2920056300A /* qtrle.cpp in Sources */,
- DF203F9D1380C2920056300A /* rpza.cpp in Sources */,
- DF203F9E1380C2920056300A /* smc.cpp in Sources */,
- DF203F9F1380C2920056300A /* truemotion1.cpp in Sources */,
- DF203FD51380C3BC0056300A /* console.cpp in Sources */,
- DF203FD61380C3BC0056300A /* dialogs.cpp in Sources */,
- DF203FD71380C3BC0056300A /* file_v1d.cpp in Sources */,
- DF203FD81380C3BC0056300A /* file_v1w.cpp in Sources */,
- DF203FD91380C3BC0056300A /* file_v2d.cpp in Sources */,
- DF203FDA1380C3BC0056300A /* file_v2w.cpp in Sources */,
- DF203FDB1380C3BC0056300A /* file_v3d.cpp in Sources */,
- DF203FDC1380C3BC0056300A /* object_v1d.cpp in Sources */,
- DF203FDD1380C3BC0056300A /* object_v1w.cpp in Sources */,
- DF203FDE1380C3BC0056300A /* object_v2d.cpp in Sources */,
- DF203FDF1380C3BC0056300A /* object_v3d.cpp in Sources */,
- DF203FE01380C3BC0056300A /* object.cpp in Sources */,
- DF203FE11380C3BC0056300A /* parser_v1d.cpp in Sources */,
- DF203FE21380C3BC0056300A /* parser_v1w.cpp in Sources */,
- DF203FE31380C3BC0056300A /* parser_v2d.cpp in Sources */,
- DF203FE41380C3BC0056300A /* parser_v3d.cpp in Sources */,
- DF203FE51380C3BC0056300A /* text.cpp in Sources */,
- DF20402E1380C8B70056300A /* editable.cpp in Sources */,
- DF20402F1380C8B70056300A /* edittext.cpp in Sources */,
- DF2040301380C8B70056300A /* list.cpp in Sources */,
- DF2040311380C8B70056300A /* popup.cpp in Sources */,
- DF2040321380C8B70056300A /* scrollbar.cpp in Sources */,
- DF2040331380C8B70056300A /* tab.cpp in Sources */,
- DF20405E1380CA230056300A /* audiostream.cpp in Sources */,
- DF20405F1380CA230056300A /* fmopl.cpp in Sources */,
- DF2040601380CA230056300A /* mididrv.cpp in Sources */,
- DF2040611380CA230056300A /* midiparser_smf.cpp in Sources */,
- DF2040621380CA230056300A /* midiparser_xmidi.cpp in Sources */,
- DF2040631380CA230056300A /* midiparser.cpp in Sources */,
- DF2040641380CA230056300A /* midiplayer.cpp in Sources */,
- DF2040651380CA230056300A /* mixer.cpp in Sources */,
- DF2040661380CA230056300A /* mpu401.cpp in Sources */,
- DF2040671380CA230056300A /* musicplugin.cpp in Sources */,
- DF2040681380CA230056300A /* rate.cpp in Sources */,
- DF2040691380CA230056300A /* timestamp.cpp in Sources */,
- DF20409A1380CA400056300A /* adpcm.cpp in Sources */,
- DF20409B1380CA400056300A /* aiff.cpp in Sources */,
- DF20409C1380CA400056300A /* flac.cpp in Sources */,
- DF20409D1380CA400056300A /* iff_sound.cpp in Sources */,
- DF20409E1380CA400056300A /* mac_snd.cpp in Sources */,
- DF20409F1380CA400056300A /* mp3.cpp in Sources */,
- DF2040A01380CA400056300A /* raw.cpp in Sources */,
- DF2040A11380CA400056300A /* vag.cpp in Sources */,
- DF2040A21380CA400056300A /* voc.cpp in Sources */,
- DF2040A31380CA400056300A /* vorbis.cpp in Sources */,
- DF2040A41380CA400056300A /* wave.cpp in Sources */,
- DF2040CC1380CA810056300A /* infogrames.cpp in Sources */,
- DF2040CD1380CA810056300A /* maxtrax.cpp in Sources */,
- DF2040CE1380CA810056300A /* module.cpp in Sources */,
- DF2040CF1380CA810056300A /* paula.cpp in Sources */,
- DF2040D01380CA810056300A /* protracker.cpp in Sources */,
- DF2040D11380CA810056300A /* rjp1.cpp in Sources */,
- DF2040D21380CA810056300A /* soundfx.cpp in Sources */,
- DF2040D31380CA810056300A /* tfmx.cpp in Sources */,
- DF2040F41380CAA40056300A /* adlib.cpp in Sources */,
- DF2040F51380CAA40056300A /* appleiigs.cpp in Sources */,
- DF2040F61380CAA40056300A /* cms.cpp in Sources */,
- DF2040F71380CAA40056300A /* eas.cpp in Sources */,
- DF2040F81380CAA40056300A /* fluidsynth.cpp in Sources */,
- DF2040F91380CAA40056300A /* mt32.cpp in Sources */,
- DF2040FA1380CAA40056300A /* pcspk.cpp in Sources */,
- DF2040FB1380CAA40056300A /* sid.cpp in Sources */,
- DF2040FC1380CAA40056300A /* wave6581.cpp in Sources */,
- DF46B6F31381E18900D08723 /* coroutine.cpp in Sources */,
- DF46B6FF1381E1FF00D08723 /* towns_audio.cpp in Sources */,
- DF46B7001381E1FF00D08723 /* towns_euphony.cpp in Sources */,
- DF46B7011381E1FF00D08723 /* towns_pc98_driver.cpp in Sources */,
- DF46B7021381E1FF00D08723 /* towns_pc98_fmsynth.cpp in Sources */,
- DF46B7191381E27000D08723 /* console.cpp in Sources */,
- DF46B71A1381E27000D08723 /* databases.cpp in Sources */,
- DF46B71B1381E27000D08723 /* dbase.cpp in Sources */,
- DF46B71C1381E27000D08723 /* iniconfig.cpp in Sources */,
- DF46B71D1381E27000D08723 /* init_v7.cpp in Sources */,
- DF46B71E1381E27000D08723 /* inter_inca2.cpp in Sources */,
- DF46B7441381E40500D08723 /* log.cpp in Sources */,
- DF46B7491381E40F00D08723 /* modular-backend.cpp in Sources */,
- DF46B7541381E46700D08723 /* player_v2base.cpp in Sources */,
- DF46B75E1381E4A400D08723 /* console.cpp in Sources */,
- DF46B7631381E4D400D08723 /* robot_decoder.cpp in Sources */,
- DF46B7671381E4E400D08723 /* vm_types.cpp in Sources */,
- DF46B77B1381E54200D08723 /* dcl.cpp in Sources */,
- DF46B77C1381E54200D08723 /* iff_container.cpp in Sources */,
- DF46B77D1381E54200D08723 /* winexe_ne.cpp in Sources */,
- DF46B77E1381E54200D08723 /* winexe_pe.cpp in Sources */,
- DF46B77F1381E54200D08723 /* winexe.cpp in Sources */,
- DF46B7931381E58000D08723 /* png.cpp in Sources */,
- DF46B7941381E58000D08723 /* wincursor.cpp in Sources */,
- DF46B79F1381E5B500D08723 /* winfont.cpp in Sources */,
- DF46B7A51381E5D900D08723 /* sdl-timer.cpp in Sources */,
- DF46B7A91381E5F100D08723 /* header.cpp in Sources */,
- DF46B7B41381E67800D08723 /* sdl-mutex.cpp in Sources */,
- DF46B7BD1381E6C000D08723 /* object.cpp in Sources */,
- DF46B7C81381E72500D08723 /* console.cpp in Sources */,
- DF46B7CF1381E76300D08723 /* sdl-events.cpp in Sources */,
- DF46B7D61381E7C600D08723 /* console.cpp in Sources */,
- DF46B83C1381F13500D08723 /* saveload_v7.cpp in Sources */,
- DF46B8441381F35500D08723 /* saveload_inca2.cpp in Sources */,
- DF46B8481381F38700D08723 /* inter_v7.cpp in Sources */,
- DF46B84D1381F39E00D08723 /* console.cpp in Sources */,
- DF46B8521381F3B400D08723 /* console.cpp in Sources */,
- DF46B8601381F44E00D08723 /* dbopl.cpp in Sources */,
- DF46B8611381F44E00D08723 /* dosbox.cpp in Sources */,
- DF46B8621381F44E00D08723 /* mame.cpp in Sources */,
- DF46B8711381F4A200D08723 /* sdl-audiocd.cpp in Sources */,
- DF46B87D1381F4F200D08723 /* default-audiocd.cpp in Sources */,
- DF46B8891381F5D800D08723 /* sdl-provider.cpp in Sources */,
- DF46B8921381F62B00D08723 /* adpcm.cpp in Sources */,
- DF46B89B1381F6C400D08723 /* null.cpp in Sources */,
- DFADEBB313820DF500C46364 /* maccursor.cpp in Sources */,
- DFADEBB713820E0C00C46364 /* posix-fs.cpp in Sources */,
- F92B4DCF139DD428000D1BF1 /* quicktime.cpp in Sources */,
- F92B4DD4139DD449000D1BF1 /* yuv_to_rgb.cpp in Sources */,
- F92B4DDA139DDC92000D1BF1 /* macosx-main.cpp in Sources */,
- F92B4DDB139DDC92000D1BF1 /* macosx.cpp in Sources */,
- F9946D9E139E1A560072D195 /* towns_midi.cpp in Sources */,
- F9946DA1139E1A560072D195 /* towns_pc98_plugins.cpp in Sources */,
- F9946DB6139E1A880072D195 /* freeverb.cpp in Sources */,
- F9946DB9139E1A880072D195 /* i386.cpp in Sources */,
- F9946DBC139E1A880072D195 /* mt32_file.cpp in Sources */,
- F9946DBF139E1A880072D195 /* part.cpp in Sources */,
- F9946DC2139E1A880072D195 /* partial.cpp in Sources */,
- F9946DC5139E1A880072D195 /* partialManager.cpp in Sources */,
- F9946DC8139E1A880072D195 /* synth.cpp in Sources */,
- F9946DCB139E1A880072D195 /* tables.cpp in Sources */,
- F9946DD7139E1AD30072D195 /* aac.cpp in Sources */,
- F9946DDA139E1AD30072D195 /* qdm2.cpp in Sources */,
- F9946DDD139E1AD30072D195 /* quicktime.cpp in Sources */,
- F9946DE4139E1B180072D195 /* posix-main.cpp in Sources */,
- F9946DE7139E1B180072D195 /* posix.cpp in Sources */,
- F9946DED139E1B6F0072D195 /* downscaler.cpp in Sources */,
- F9946DF2139E1BA00072D195 /* console.cpp in Sources */,
- F9946DF8139E1BBF0072D195 /* sdl-mixer.cpp in Sources */,
- F9946DFF139E1BEB0072D195 /* doublebuffersdl-mixer.cpp in Sources */,
- F9946E05139E1C390072D195 /* sdl-graphics.cpp in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- DFF959160FB22D5700A3EC78 /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- DFF959170FB22D5700A3EC78 /* commandLine.cpp in Sources */,
- DFF959180FB22D5700A3EC78 /* main.cpp in Sources */,
- DFF959190FB22D5700A3EC78 /* plugins.cpp in Sources */,
- DFF9591A0FB22D5700A3EC78 /* version.cpp in Sources */,
- DFF9591B0FB22D5700A3EC78 /* default-events.cpp in Sources */,
- DFF9591C0FB22D5700A3EC78 /* posix-fs-factory.cpp in Sources */,
- DFF9591D0FB22D5700A3EC78 /* iphone_main.m in Sources */,
- DFF9591F0FB22D5700A3EC78 /* posix-provider.cpp in Sources */,
- DFF959200FB22D5700A3EC78 /* default-saves.cpp in Sources */,
- DFF959210FB22D5700A3EC78 /* savefile.cpp in Sources */,
- DFF959220FB22D5700A3EC78 /* default-timer.cpp in Sources */,
- DFF959230FB22D5700A3EC78 /* config-file.cpp in Sources */,
- DFF959240FB22D5700A3EC78 /* config-manager.cpp in Sources */,
- DFF959250FB22D5700A3EC78 /* file.cpp in Sources */,
- DFF959260FB22D5700A3EC78 /* fs.cpp in Sources */,
- DFF959270FB22D5700A3EC78 /* hashmap.cpp in Sources */,
- DFF959280FB22D5700A3EC78 /* md5.cpp in Sources */,
- DFF959290FB22D5700A3EC78 /* mutex.cpp in Sources */,
- DFF9592A0FB22D5700A3EC78 /* str.cpp in Sources */,
- DFF9592B0FB22D5700A3EC78 /* stream.cpp in Sources */,
- DFF9592C0FB22D5700A3EC78 /* system.cpp in Sources */,
- DFF9592D0FB22D5700A3EC78 /* util.cpp in Sources */,
- DFF9592E0FB22D5700A3EC78 /* zlib.cpp in Sources */,
- DFF9592F0FB22D5700A3EC78 /* cursorman.cpp in Sources */,
- DFF959300FB22D5700A3EC78 /* font.cpp in Sources */,
- DFF959310FB22D5700A3EC78 /* fontman.cpp in Sources */,
- DFF959320FB22D5700A3EC78 /* consolefont.cpp in Sources */,
- DFF959330FB22D5700A3EC78 /* newfont.cpp in Sources */,
- DFF959340FB22D5700A3EC78 /* newfont_big.cpp in Sources */,
- DFF959360FB22D5700A3EC78 /* iff.cpp in Sources */,
- DFF959370FB22D5700A3EC78 /* imagedec.cpp in Sources */,
- DFF959380FB22D5700A3EC78 /* primitives.cpp in Sources */,
- DFF959390FB22D5700A3EC78 /* surface.cpp in Sources */,
- DFF9593A0FB22D5700A3EC78 /* about.cpp in Sources */,
- DFF9593B0FB22D5700A3EC78 /* Actions.cpp in Sources */,
- DFF9593C0FB22D5700A3EC78 /* browser.cpp in Sources */,
- DFF9593D0FB22D5700A3EC78 /* chooser.cpp in Sources */,
- DFF9593E0FB22D5700A3EC78 /* console.cpp in Sources */,
- DFF9593F0FB22D5700A3EC78 /* debugger.cpp in Sources */,
- DFF959400FB22D5700A3EC78 /* dialog.cpp in Sources */,
- DFF959430FB22D5700A3EC78 /* Key.cpp in Sources */,
- DFF959440FB22D5700A3EC78 /* launcher.cpp in Sources */,
- DFF959460FB22D5700A3EC78 /* massadd.cpp in Sources */,
- DFF959470FB22D5700A3EC78 /* message.cpp in Sources */,
- DFF959480FB22D5700A3EC78 /* object.cpp in Sources */,
- DFF959490FB22D5700A3EC78 /* options.cpp in Sources */,
- DFF9594D0FB22D5700A3EC78 /* themebrowser.cpp in Sources */,
- DFF9594E0FB22D5700A3EC78 /* widget.cpp in Sources */,
- DFF9596C0FB22D5700A3EC78 /* memorypool.cpp in Sources */,
- DFF9596D0FB22D5700A3EC78 /* seq.cpp in Sources */,
- DFF9596E0FB22D5700A3EC78 /* scaler.cpp in Sources */,
- DFF9596F0FB22D5700A3EC78 /* scalebit.cpp in Sources */,
- DFF959700FB22D5700A3EC78 /* 2xsai.cpp in Sources */,
- DFF959710FB22D5700A3EC78 /* aspect.cpp in Sources */,
- DFF959740FB22D5700A3EC78 /* scale2x.cpp in Sources */,
- DFF959750FB22D5700A3EC78 /* scale3x.cpp in Sources */,
- DFF959760FB22D5700A3EC78 /* iphone_keyboard.m in Sources */,
- DFF959770FB22D5700A3EC78 /* iphone_video.m in Sources */,
- DFF959780FB22D5700A3EC78 /* agi.cpp in Sources */,
- DFF959790FB22D5700A3EC78 /* checks.cpp in Sources */,
- DFF9597A0FB22D5700A3EC78 /* console.cpp in Sources */,
- DFF9597B0FB22D5700A3EC78 /* cycle.cpp in Sources */,
- DFF9597C0FB22D5700A3EC78 /* detection.cpp in Sources */,
- DFF9597D0FB22D5700A3EC78 /* global.cpp in Sources */,
- DFF9597E0FB22D5700A3EC78 /* graphics.cpp in Sources */,
- DFF9597F0FB22D5700A3EC78 /* id.cpp in Sources */,
- DFF959800FB22D5700A3EC78 /* inv.cpp in Sources */,
- DFF959810FB22D5700A3EC78 /* keyboard.cpp in Sources */,
- DFF959820FB22D5700A3EC78 /* loader_v2.cpp in Sources */,
- DFF959830FB22D5700A3EC78 /* loader_v3.cpp in Sources */,
- DFF959840FB22D5700A3EC78 /* logic.cpp in Sources */,
- DFF959850FB22D5700A3EC78 /* lzw.cpp in Sources */,
- DFF959860FB22D5700A3EC78 /* menu.cpp in Sources */,
- DFF959870FB22D5700A3EC78 /* motion.cpp in Sources */,
- DFF959880FB22D5700A3EC78 /* objects.cpp in Sources */,
- DFF959890FB22D5700A3EC78 /* op_cmd.cpp in Sources */,
- DFF9598A0FB22D5700A3EC78 /* op_dbg.cpp in Sources */,
- DFF9598B0FB22D5700A3EC78 /* op_test.cpp in Sources */,
- DFF9598C0FB22D5700A3EC78 /* picture.cpp in Sources */,
- DFF9598D0FB22D5700A3EC78 /* preagi.cpp in Sources */,
- DFF9598E0FB22D5700A3EC78 /* preagi_common.cpp in Sources */,
- DFF9598F0FB22D5700A3EC78 /* preagi_mickey.cpp in Sources */,
- DFF959900FB22D5700A3EC78 /* preagi_troll.cpp in Sources */,
- DFF959910FB22D5700A3EC78 /* preagi_winnie.cpp in Sources */,
- DFF959920FB22D5700A3EC78 /* predictive.cpp in Sources */,
- DFF959930FB22D5700A3EC78 /* saveload.cpp in Sources */,
- DFF959940FB22D5700A3EC78 /* sound.cpp in Sources */,
- DFF959950FB22D5700A3EC78 /* sprite.cpp in Sources */,
- DFF959960FB22D5700A3EC78 /* text.cpp in Sources */,
- DFF959970FB22D5700A3EC78 /* view.cpp in Sources */,
- DFF959980FB22D5700A3EC78 /* wagparser.cpp in Sources */,
- DFF959990FB22D5700A3EC78 /* words.cpp in Sources */,
- DFF9599A0FB22D5700A3EC78 /* agos.cpp in Sources */,
- DFF9599B0FB22D5700A3EC78 /* animation.cpp in Sources */,
- DFF9599C0FB22D5700A3EC78 /* charset-fontdata.cpp in Sources */,
- DFF9599D0FB22D5700A3EC78 /* charset.cpp in Sources */,
- DFF9599E0FB22D5700A3EC78 /* contain.cpp in Sources */,
- DFF9599F0FB22D5700A3EC78 /* cursor.cpp in Sources */,
- DFF959A00FB22D5700A3EC78 /* debug.cpp in Sources */,
- DFF959A10FB22D5700A3EC78 /* debugger.cpp in Sources */,
- DFF959A20FB22D5700A3EC78 /* detection.cpp in Sources */,
- DFF959A30FB22D5700A3EC78 /* draw.cpp in Sources */,
- DFF959A40FB22D5700A3EC78 /* event.cpp in Sources */,
- DFF959A50FB22D5700A3EC78 /* gfx.cpp in Sources */,
- DFF959A60FB22D5700A3EC78 /* icons.cpp in Sources */,
- DFF959A70FB22D5700A3EC78 /* input.cpp in Sources */,
- DFF959A80FB22D5700A3EC78 /* items.cpp in Sources */,
- DFF959A90FB22D5700A3EC78 /* menus.cpp in Sources */,
- DFF959AA0FB22D5700A3EC78 /* midi.cpp in Sources */,
- DFF959AB0FB22D5700A3EC78 /* midiparser_s1d.cpp in Sources */,
- DFF959AC0FB22D5700A3EC78 /* oracle.cpp in Sources */,
- DFF959AD0FB22D5700A3EC78 /* res.cpp in Sources */,
- DFF959AE0FB22D5700A3EC78 /* res_ami.cpp in Sources */,
- DFF959AF0FB22D5700A3EC78 /* res_snd.cpp in Sources */,
- DFF959B00FB22D5700A3EC78 /* rooms.cpp in Sources */,
- DFF959B10FB22D5700A3EC78 /* saveload.cpp in Sources */,
- DFF959B20FB22D5700A3EC78 /* script.cpp in Sources */,
- DFF959B30FB22D5700A3EC78 /* script_e1.cpp in Sources */,
- DFF959B40FB22D5700A3EC78 /* script_e2.cpp in Sources */,
- DFF959B50FB22D5700A3EC78 /* script_ff.cpp in Sources */,
- DFF959B60FB22D5700A3EC78 /* script_pp.cpp in Sources */,
- DFF959B70FB22D5700A3EC78 /* script_s1.cpp in Sources */,
- DFF959B80FB22D5700A3EC78 /* script_s2.cpp in Sources */,
- DFF959B90FB22D5700A3EC78 /* script_ww.cpp in Sources */,
- DFF959BA0FB22D5700A3EC78 /* sound.cpp in Sources */,
- DFF959BB0FB22D5700A3EC78 /* string.cpp in Sources */,
- DFF959BC0FB22D5700A3EC78 /* subroutine.cpp in Sources */,
- DFF959BD0FB22D5700A3EC78 /* verb.cpp in Sources */,
- DFF959BE0FB22D5700A3EC78 /* vga.cpp in Sources */,
- DFF959BF0FB22D5700A3EC78 /* vga_e2.cpp in Sources */,
- DFF959C00FB22D5700A3EC78 /* vga_ff.cpp in Sources */,
- DFF959C10FB22D5700A3EC78 /* vga_s1.cpp in Sources */,
- DFF959C20FB22D5700A3EC78 /* vga_s2.cpp in Sources */,
- DFF959C30FB22D5700A3EC78 /* vga_ww.cpp in Sources */,
- DFF959C40FB22D5700A3EC78 /* window.cpp in Sources */,
- DFF959C50FB22D5700A3EC78 /* zones.cpp in Sources */,
- DFF959C60FB22D5700A3EC78 /* anim.cpp in Sources */,
- DFF959C70FB22D5700A3EC78 /* bg.cpp in Sources */,
- DFF959C80FB22D5700A3EC78 /* bg_list.cpp in Sources */,
- DFF959C90FB22D5700A3EC78 /* cine.cpp in Sources */,
- DFF959CA0FB22D5700A3EC78 /* detection.cpp in Sources */,
- DFF959CB0FB22D5700A3EC78 /* gfx.cpp in Sources */,
- DFF959CC0FB22D5700A3EC78 /* main_loop.cpp in Sources */,
- DFF959CD0FB22D5700A3EC78 /* msg.cpp in Sources */,
- DFF959CE0FB22D5700A3EC78 /* object.cpp in Sources */,
- DFF959CF0FB22D5700A3EC78 /* pal.cpp in Sources */,
- DFF959D00FB22D5700A3EC78 /* part.cpp in Sources */,
- DFF959D10FB22D5700A3EC78 /* prc.cpp in Sources */,
- DFF959D20FB22D5700A3EC78 /* rel.cpp in Sources */,
- DFF959D30FB22D5700A3EC78 /* script_fw.cpp in Sources */,
- DFF959D40FB22D5700A3EC78 /* script_os.cpp in Sources */,
- DFF959D50FB22D5700A3EC78 /* sound.cpp in Sources */,
- DFF959D60FB22D5700A3EC78 /* texte.cpp in Sources */,
- DFF959D70FB22D5700A3EC78 /* unpack.cpp in Sources */,
- DFF959D80FB22D5700A3EC78 /* various.cpp in Sources */,
- DFF959D90FB22D5700A3EC78 /* actor.cpp in Sources */,
- DFF959DA0FB22D5700A3EC78 /* background.cpp in Sources */,
- DFF959DB0FB22D5700A3EC78 /* backgroundIncrust.cpp in Sources */,
- DFF959DC0FB22D5700A3EC78 /* cell.cpp in Sources */,
- DFF959DD0FB22D5700A3EC78 /* cruise.cpp in Sources */,
- DFF959DE0FB22D5700A3EC78 /* cruise_main.cpp in Sources */,
- DFF959DF0FB22D5700A3EC78 /* ctp.cpp in Sources */,
- DFF959E00FB22D5700A3EC78 /* dataLoader.cpp in Sources */,
- DFF959E10FB22D5700A3EC78 /* decompiler.cpp in Sources */,
- DFF959E20FB22D5700A3EC78 /* delphine-unpack.cpp in Sources */,
- DFF959E30FB22D5700A3EC78 /* detection.cpp in Sources */,
- DFF959E40FB22D5700A3EC78 /* font.cpp in Sources */,
- DFF959E50FB22D5700A3EC78 /* function.cpp in Sources */,
- DFF959E60FB22D5700A3EC78 /* gfxModule.cpp in Sources */,
- DFF959E70FB22D5700A3EC78 /* linker.cpp in Sources */,
- DFF959E80FB22D5700A3EC78 /* mainDraw.cpp in Sources */,
- DFF959E90FB22D5700A3EC78 /* menu.cpp in Sources */,
- DFF959EA0FB22D5700A3EC78 /* mouse.cpp in Sources */,
- DFF959EB0FB22D5700A3EC78 /* object.cpp in Sources */,
- DFF959EC0FB22D5700A3EC78 /* overlay.cpp in Sources */,
- DFF959ED0FB22D5700A3EC78 /* perso.cpp in Sources */,
- DFF959EE0FB22D5700A3EC78 /* polys.cpp in Sources */,
- DFF959EF0FB22D5700A3EC78 /* saveload.cpp in Sources */,
- DFF959F00FB22D5700A3EC78 /* script.cpp in Sources */,
- DFF959F10FB22D5700A3EC78 /* stack.cpp in Sources */,
- DFF959F20FB22D5700A3EC78 /* various.cpp in Sources */,
- DFF959F30FB22D5700A3EC78 /* vars.cpp in Sources */,
- DFF959F40FB22D5700A3EC78 /* volume.cpp in Sources */,
- DFF959F50FB22D5700A3EC78 /* dialogs.cpp in Sources */,
- DFF959F60FB22D5700A3EC78 /* actors.cpp in Sources */,
- DFF959F70FB22D5700A3EC78 /* animation.cpp in Sources */,
- DFF959F80FB22D5700A3EC78 /* converse.cpp in Sources */,
- DFF959F90FB22D5700A3EC78 /* detection.cpp in Sources */,
- DFF959FA0FB22D5700A3EC78 /* drascula.cpp in Sources */,
- DFF959FB0FB22D5700A3EC78 /* graphics.cpp in Sources */,
- DFF959FC0FB22D5700A3EC78 /* interface.cpp in Sources */,
- DFF959FD0FB22D5700A3EC78 /* objects.cpp in Sources */,
- DFF959FE0FB22D5700A3EC78 /* palette.cpp in Sources */,
- DFF959FF0FB22D5700A3EC78 /* rooms.cpp in Sources */,
- DFF95A000FB22D5700A3EC78 /* saveload.cpp in Sources */,
- DFF95A010FB22D5700A3EC78 /* sound.cpp in Sources */,
- DFF95A020FB22D5700A3EC78 /* talk.cpp in Sources */,
- DFF95A030FB22D5700A3EC78 /* engine.cpp in Sources */,
- DFF95A050FB22D5700A3EC78 /* dataio.cpp in Sources */,
- DFF95A060FB22D5700A3EC78 /* detection.cpp in Sources */,
- DFF95A070FB22D5700A3EC78 /* draw.cpp in Sources */,
- DFF95A080FB22D5700A3EC78 /* draw_bargon.cpp in Sources */,
- DFF95A090FB22D5700A3EC78 /* draw_v1.cpp in Sources */,
- DFF95A0A0FB22D5700A3EC78 /* draw_v2.cpp in Sources */,
- DFF95A0C0FB22D5700A3EC78 /* game.cpp in Sources */,
- DFF95A0F0FB22D5700A3EC78 /* global.cpp in Sources */,
- DFF95A100FB22D5700A3EC78 /* gob.cpp in Sources */,
- DFF95A110FB22D5700A3EC78 /* goblin.cpp in Sources */,
- DFF95A120FB22D5700A3EC78 /* goblin_v1.cpp in Sources */,
- DFF95A130FB22D5700A3EC78 /* goblin_v2.cpp in Sources */,
- DFF95A140FB22D5700A3EC78 /* goblin_v3.cpp in Sources */,
- DFF95A150FB22D5700A3EC78 /* goblin_v4.cpp in Sources */,
- DFF95A160FB22D5700A3EC78 /* init.cpp in Sources */,
- DFF95A170FB22D5700A3EC78 /* init_v1.cpp in Sources */,
- DFF95A180FB22D5700A3EC78 /* init_v2.cpp in Sources */,
- DFF95A190FB22D5700A3EC78 /* init_v3.cpp in Sources */,
- DFF95A1A0FB22D5700A3EC78 /* inter.cpp in Sources */,
- DFF95A1B0FB22D5700A3EC78 /* inter_bargon.cpp in Sources */,
- DFF95A1C0FB22D5700A3EC78 /* inter_v1.cpp in Sources */,
- DFF95A1D0FB22D5700A3EC78 /* inter_v2.cpp in Sources */,
- DFF95A1E0FB22D5700A3EC78 /* inter_v3.cpp in Sources */,
- DFF95A1F0FB22D5700A3EC78 /* inter_v4.cpp in Sources */,
- DFF95A200FB22D5700A3EC78 /* inter_v5.cpp in Sources */,
- DFF95A210FB22D5700A3EC78 /* inter_v6.cpp in Sources */,
- DFF95A220FB22D5700A3EC78 /* map.cpp in Sources */,
- DFF95A230FB22D5700A3EC78 /* map_v1.cpp in Sources */,
- DFF95A240FB22D5700A3EC78 /* map_v2.cpp in Sources */,
- DFF95A260FB22D5700A3EC78 /* mult.cpp in Sources */,
- DFF95A270FB22D5700A3EC78 /* mult_v1.cpp in Sources */,
- DFF95A280FB22D5700A3EC78 /* mult_v2.cpp in Sources */,
- DFF95A290FB22D5700A3EC78 /* palanim.cpp in Sources */,
- DFF95A310FB22D5700A3EC78 /* scenery.cpp in Sources */,
- DFF95A320FB22D5700A3EC78 /* scenery_v1.cpp in Sources */,
- DFF95A330FB22D5700A3EC78 /* scenery_v2.cpp in Sources */,
- DFF95A340FB22D5700A3EC78 /* adlib.cpp in Sources */,
- DFF95A350FB22D5700A3EC78 /* bgatmosphere.cpp in Sources */,
- DFF95A360FB22D5700A3EC78 /* cdrom.cpp in Sources */,
- DFF95A370FB22D5700A3EC78 /* infogrames.cpp in Sources */,
- DFF95A380FB22D5700A3EC78 /* pcspeaker.cpp in Sources */,
- DFF95A390FB22D5700A3EC78 /* sound.cpp in Sources */,
- DFF95A3A0FB22D5700A3EC78 /* soundblaster.cpp in Sources */,
- DFF95A3B0FB22D5700A3EC78 /* sounddesc.cpp in Sources */,
- DFF95A3C0FB22D5700A3EC78 /* soundmixer.cpp in Sources */,
- DFF95A3D0FB22D5700A3EC78 /* util.cpp in Sources */,
- DFF95A3E0FB22D5700A3EC78 /* variables.cpp in Sources */,
- DFF95A3F0FB22D5700A3EC78 /* video.cpp in Sources */,
- DFF95A400FB22D5700A3EC78 /* video_v1.cpp in Sources */,
- DFF95A410FB22D5700A3EC78 /* video_v2.cpp in Sources */,
- DFF95A420FB22D5700A3EC78 /* video_v6.cpp in Sources */,
- DFF95A430FB22D5700A3EC78 /* videoplayer.cpp in Sources */,
- DFF95A670FB22D5700A3EC78 /* animator_hof.cpp in Sources */,
- DFF95A680FB22D5700A3EC78 /* animator_lok.cpp in Sources */,
- DFF95A690FB22D5700A3EC78 /* animator_mr.cpp in Sources */,
- DFF95A6A0FB22D5700A3EC78 /* animator_v2.cpp in Sources */,
- DFF95A6B0FB22D5700A3EC78 /* debugger.cpp in Sources */,
- DFF95A6C0FB22D5700A3EC78 /* detection.cpp in Sources */,
- DFF95A6D0FB22D5700A3EC78 /* gui.cpp in Sources */,
- DFF95A6E0FB22D5700A3EC78 /* gui_hof.cpp in Sources */,
- DFF95A6F0FB22D5700A3EC78 /* gui_lok.cpp in Sources */,
- DFF95A700FB22D5700A3EC78 /* gui_mr.cpp in Sources */,
- DFF95A710FB22D5700A3EC78 /* gui_v2.cpp in Sources */,
- DFF95A720FB22D5700A3EC78 /* items_hof.cpp in Sources */,
- DFF95A730FB22D5700A3EC78 /* items_lok.cpp in Sources */,
- DFF95A740FB22D5700A3EC78 /* items_mr.cpp in Sources */,
- DFF95A750FB22D5700A3EC78 /* items_v2.cpp in Sources */,
- DFF95A760FB22D5700A3EC78 /* kyra_hof.cpp in Sources */,
- DFF95A770FB22D5700A3EC78 /* kyra_lok.cpp in Sources */,
- DFF95A780FB22D5700A3EC78 /* kyra_mr.cpp in Sources */,
- DFF95A790FB22D5700A3EC78 /* kyra_v1.cpp in Sources */,
- DFF95A7A0FB22D5700A3EC78 /* kyra_v2.cpp in Sources */,
- DFF95A7B0FB22D5700A3EC78 /* lol.cpp in Sources */,
- DFF95A7C0FB22D5700A3EC78 /* resource.cpp in Sources */,
- DFF95A7D0FB22D5700A3EC78 /* resource_intern.cpp in Sources */,
- DFF95A7E0FB22D5700A3EC78 /* saveload.cpp in Sources */,
- DFF95A7F0FB22D5700A3EC78 /* saveload_hof.cpp in Sources */,
- DFF95A800FB22D5700A3EC78 /* saveload_lok.cpp in Sources */,
- DFF95A810FB22D5700A3EC78 /* saveload_mr.cpp in Sources */,
- DFF95A820FB22D5700A3EC78 /* scene_hof.cpp in Sources */,
- DFF95A830FB22D5700A3EC78 /* scene_lok.cpp in Sources */,
- DFF95A840FB22D5700A3EC78 /* scene_mr.cpp in Sources */,
- DFF95A850FB22D5700A3EC78 /* scene_v1.cpp in Sources */,
- DFF95A860FB22D5700A3EC78 /* scene_v2.cpp in Sources */,
- DFF95A870FB22D5700A3EC78 /* screen.cpp in Sources */,
- DFF95A880FB22D5700A3EC78 /* screen_hof.cpp in Sources */,
- DFF95A890FB22D5700A3EC78 /* screen_lok.cpp in Sources */,
- DFF95A8A0FB22D5700A3EC78 /* screen_lol.cpp in Sources */,
- DFF95A8B0FB22D5700A3EC78 /* screen_mr.cpp in Sources */,
- DFF95A8C0FB22D5700A3EC78 /* screen_v2.cpp in Sources */,
- DFF95A8D0FB22D5700A3EC78 /* script.cpp in Sources */,
- DFF95A8E0FB22D5700A3EC78 /* script_hof.cpp in Sources */,
- DFF95A8F0FB22D5700A3EC78 /* script_lok.cpp in Sources */,
- DFF95A900FB22D5700A3EC78 /* script_mr.cpp in Sources */,
- DFF95A910FB22D5700A3EC78 /* script_tim.cpp in Sources */,
- DFF95A920FB22D5700A3EC78 /* script_v1.cpp in Sources */,
- DFF95A930FB22D5700A3EC78 /* script_v2.cpp in Sources */,
- DFF95A940FB22D5700A3EC78 /* seqplayer.cpp in Sources */,
- DFF95A950FB22D5700A3EC78 /* sequences_hof.cpp in Sources */,
- DFF95A960FB22D5700A3EC78 /* sequences_lok.cpp in Sources */,
- DFF95A970FB22D5700A3EC78 /* sequences_mr.cpp in Sources */,
- DFF95A980FB22D5700A3EC78 /* sequences_v2.cpp in Sources */,
- DFF95A990FB22D5700A3EC78 /* sound.cpp in Sources */,
- DFF95A9A0FB22D5700A3EC78 /* sound_adlib.cpp in Sources */,
- DFF95A9B0FB22D5700A3EC78 /* sound_digital.cpp in Sources */,
- DFF95A9C0FB22D5700A3EC78 /* sound_lok.cpp in Sources */,
- DFF95A9D0FB22D5700A3EC78 /* sound_towns.cpp in Sources */,
- DFF95A9E0FB22D5700A3EC78 /* sprites.cpp in Sources */,
- DFF95A9F0FB22D5700A3EC78 /* staticres.cpp in Sources */,
- DFF95AA00FB22D5700A3EC78 /* text.cpp in Sources */,
- DFF95AA10FB22D5700A3EC78 /* text_hof.cpp in Sources */,
- DFF95AA20FB22D5700A3EC78 /* text_lok.cpp in Sources */,
- DFF95AA30FB22D5700A3EC78 /* text_mr.cpp in Sources */,
- DFF95AA40FB22D5700A3EC78 /* timer.cpp in Sources */,
- DFF95AA50FB22D5700A3EC78 /* timer_hof.cpp in Sources */,
- DFF95AA60FB22D5700A3EC78 /* timer_lok.cpp in Sources */,
- DFF95AA70FB22D5700A3EC78 /* timer_mr.cpp in Sources */,
- DFF95AA80FB22D5700A3EC78 /* vqa.cpp in Sources */,
- DFF95AA90FB22D5700A3EC78 /* wsamovie.cpp in Sources */,
- DFF95AAA0FB22D5700A3EC78 /* animseq.cpp in Sources */,
- DFF95AAB0FB22D5700A3EC78 /* debugger.cpp in Sources */,
- DFF95AAC0FB22D5700A3EC78 /* decode.cpp in Sources */,
- DFF95AAD0FB22D5700A3EC78 /* detection.cpp in Sources */,
- DFF95AAE0FB22D5700A3EC78 /* disk.cpp in Sources */,
- DFF95AAF0FB22D5700A3EC78 /* events.cpp in Sources */,
- DFF95AB00FB22D5700A3EC78 /* fights.cpp in Sources */,
- DFF95AB10FB22D5700A3EC78 /* game.cpp in Sources */,
- DFF95AB20FB22D5700A3EC78 /* hotspots.cpp in Sources */,
- DFF95AB30FB22D5700A3EC78 /* intro.cpp in Sources */,
- DFF95AB40FB22D5700A3EC78 /* lure.cpp in Sources */,
- DFF95AB50FB22D5700A3EC78 /* memory.cpp in Sources */,
- DFF95AB60FB22D5700A3EC78 /* menu.cpp in Sources */,
- DFF95AB70FB22D5700A3EC78 /* palette.cpp in Sources */,
- DFF95AB80FB22D5700A3EC78 /* res.cpp in Sources */,
- DFF95AB90FB22D5700A3EC78 /* res_struct.cpp in Sources */,
- DFF95ABA0FB22D5700A3EC78 /* room.cpp in Sources */,
- DFF95ABB0FB22D5700A3EC78 /* screen.cpp in Sources */,
- DFF95ABC0FB22D5700A3EC78 /* scripts.cpp in Sources */,
- DFF95ABD0FB22D5700A3EC78 /* sound.cpp in Sources */,
- DFF95ABE0FB22D5700A3EC78 /* strings.cpp in Sources */,
- DFF95ABF0FB22D5700A3EC78 /* surface.cpp in Sources */,
- DFF95AC00FB22D5700A3EC78 /* actor.cpp in Sources */,
- DFF95AC10FB22D5700A3EC78 /* animation.cpp in Sources */,
- DFF95AC20FB22D5700A3EC78 /* assets.cpp in Sources */,
- DFF95AC30FB22D5700A3EC78 /* compression.cpp in Sources */,
- DFF95AC40FB22D5700A3EC78 /* console.cpp in Sources */,
- DFF95AC50FB22D5700A3EC78 /* converse.cpp in Sources */,
- DFF95AC60FB22D5700A3EC78 /* detection.cpp in Sources */,
- DFF95AC70FB22D5700A3EC78 /* events.cpp in Sources */,
- DFF95AC80FB22D5700A3EC78 /* font.cpp in Sources */,
- DFF95AC90FB22D5700A3EC78 /* globals.cpp in Sources */,
- DFF95ACA0FB22D5700A3EC78 /* graphics.cpp in Sources */,
- DFF95ACB0FB22D5700A3EC78 /* gui.cpp in Sources */,
- DFF95ACC0FB22D5700A3EC78 /* hotspot.cpp in Sources */,
- DFF95ACD0FB22D5700A3EC78 /* m4.cpp in Sources */,
- DFF95ACE0FB22D5700A3EC78 /* m4_menus.cpp in Sources */,
- DFF95ACF0FB22D5700A3EC78 /* m4_views.cpp in Sources */,
- DFF95AD00FB22D5700A3EC78 /* mads_anim.cpp in Sources */,
- DFF95AD10FB22D5700A3EC78 /* mads_menus.cpp in Sources */,
- DFF95AD20FB22D5700A3EC78 /* midi.cpp in Sources */,
- DFF95AD30FB22D5700A3EC78 /* rails.cpp in Sources */,
- DFF95AD40FB22D5700A3EC78 /* resource.cpp in Sources */,
- DFF95AD50FB22D5700A3EC78 /* saveload.cpp in Sources */,
- DFF95AD60FB22D5700A3EC78 /* scene.cpp in Sources */,
- DFF95AD70FB22D5700A3EC78 /* script.cpp in Sources */,
- DFF95AD80FB22D5700A3EC78 /* sound.cpp in Sources */,
- DFF95AD90FB22D5700A3EC78 /* sprite.cpp in Sources */,
- DFF95ADA0FB22D5700A3EC78 /* viewmgr.cpp in Sources */,
- DFF95ADB0FB22D5700A3EC78 /* woodscript.cpp in Sources */,
- DFF95ADC0FB22D5700A3EC78 /* ws_machine.cpp in Sources */,
- DFF95ADD0FB22D5700A3EC78 /* ws_sequence.cpp in Sources */,
- DFF95ADE0FB22D5700A3EC78 /* database.cpp in Sources */,
- DFF95ADF0FB22D5700A3EC78 /* detection.cpp in Sources */,
- DFF95AE00FB22D5700A3EC78 /* graphics.cpp in Sources */,
- DFF95AE10FB22D5700A3EC78 /* made.cpp in Sources */,
- DFF95AE20FB22D5700A3EC78 /* music.cpp in Sources */,
- DFF95AE30FB22D5700A3EC78 /* pmvplayer.cpp in Sources */,
- DFF95AE40FB22D5700A3EC78 /* redreader.cpp in Sources */,
- DFF95AE50FB22D5700A3EC78 /* resource.cpp in Sources */,
- DFF95AE60FB22D5700A3EC78 /* screen.cpp in Sources */,
- DFF95AE70FB22D5700A3EC78 /* screenfx.cpp in Sources */,
- DFF95AE80FB22D5700A3EC78 /* script.cpp in Sources */,
- DFF95AE90FB22D5700A3EC78 /* scriptfuncs.cpp in Sources */,
- DFF95AEA0FB22D5700A3EC78 /* sound.cpp in Sources */,
- DFF95AEB0FB22D5700A3EC78 /* balloons.cpp in Sources */,
- DFF95AEC0FB22D5700A3EC78 /* callables_br.cpp in Sources */,
- DFF95AED0FB22D5700A3EC78 /* callables_ns.cpp in Sources */,
- DFF95AEE0FB22D5700A3EC78 /* debug.cpp in Sources */,
- DFF95AEF0FB22D5700A3EC78 /* detection.cpp in Sources */,
- DFF95AF00FB22D5700A3EC78 /* dialogue.cpp in Sources */,
- DFF95AF10FB22D5700A3EC78 /* disk_br.cpp in Sources */,
- DFF95AF20FB22D5700A3EC78 /* disk_ns.cpp in Sources */,
- DFF95AF30FB22D5700A3EC78 /* exec_br.cpp in Sources */,
- DFF95AF40FB22D5700A3EC78 /* exec_ns.cpp in Sources */,
- DFF95AF50FB22D5700A3EC78 /* font.cpp in Sources */,
- DFF95AF60FB22D5700A3EC78 /* gfxbase.cpp in Sources */,
- DFF95AF70FB22D5700A3EC78 /* graphics.cpp in Sources */,
- DFF95AF80FB22D5700A3EC78 /* gui.cpp in Sources */,
- DFF95AF90FB22D5700A3EC78 /* gui_br.cpp in Sources */,
- DFF95AFA0FB22D5700A3EC78 /* gui_ns.cpp in Sources */,
- DFF95AFB0FB22D5700A3EC78 /* input.cpp in Sources */,
- DFF95AFC0FB22D5700A3EC78 /* inventory.cpp in Sources */,
- DFF95AFD0FB22D5700A3EC78 /* objects.cpp in Sources */,
- DFF95AFE0FB22D5700A3EC78 /* parallaction.cpp in Sources */,
- DFF95AFF0FB22D5700A3EC78 /* parallaction_br.cpp in Sources */,
- DFF95B000FB22D5700A3EC78 /* parallaction_ns.cpp in Sources */,
- DFF95B010FB22D5700A3EC78 /* parser.cpp in Sources */,
- DFF95B020FB22D5700A3EC78 /* parser_br.cpp in Sources */,
- DFF95B030FB22D5700A3EC78 /* parser_ns.cpp in Sources */,
- DFF95B040FB22D5700A3EC78 /* saveload.cpp in Sources */,
- DFF95B050FB22D5700A3EC78 /* staticres.cpp in Sources */,
- DFF95B060FB22D5700A3EC78 /* walk.cpp in Sources */,
- DFF95B070FB22D5700A3EC78 /* bankman.cpp in Sources */,
- DFF95B080FB22D5700A3EC78 /* command.cpp in Sources */,
- DFF95B090FB22D5700A3EC78 /* credits.cpp in Sources */,
- DFF95B0A0FB22D5700A3EC78 /* cutaway.cpp in Sources */,
- DFF95B0B0FB22D5700A3EC78 /* debug.cpp in Sources */,
- DFF95B0C0FB22D5700A3EC78 /* display.cpp in Sources */,
- DFF95B0D0FB22D5700A3EC78 /* graphics.cpp in Sources */,
- DFF95B0E0FB22D5700A3EC78 /* grid.cpp in Sources */,
- DFF95B0F0FB22D5700A3EC78 /* input.cpp in Sources */,
- DFF95B100FB22D5700A3EC78 /* journal.cpp in Sources */,
- DFF95B110FB22D5700A3EC78 /* logic.cpp in Sources */,
- DFF95B120FB22D5700A3EC78 /* midiadlib.cpp in Sources */,
- DFF95B130FB22D5700A3EC78 /* music.cpp in Sources */,
- DFF95B140FB22D5700A3EC78 /* musicdata.cpp in Sources */,
- DFF95B150FB22D5700A3EC78 /* queen.cpp in Sources */,
- DFF95B160FB22D5700A3EC78 /* resource.cpp in Sources */,
- DFF95B170FB22D5700A3EC78 /* restables.cpp in Sources */,
- DFF95B180FB22D5700A3EC78 /* sound.cpp in Sources */,
- DFF95B190FB22D5700A3EC78 /* state.cpp in Sources */,
- DFF95B1A0FB22D5700A3EC78 /* talk.cpp in Sources */,
- DFF95B1B0FB22D5700A3EC78 /* walk.cpp in Sources */,
- DFF95B1C0FB22D5700A3EC78 /* actor.cpp in Sources */,
- DFF95B1D0FB22D5700A3EC78 /* actor_path.cpp in Sources */,
- DFF95B1E0FB22D5700A3EC78 /* actor_walk.cpp in Sources */,
- DFF95B1F0FB22D5700A3EC78 /* animation.cpp in Sources */,
- DFF95B200FB22D5700A3EC78 /* console.cpp in Sources */,
- DFF95B210FB22D5700A3EC78 /* detection.cpp in Sources */,
- DFF95B220FB22D5700A3EC78 /* events.cpp in Sources */,
- DFF95B230FB22D5700A3EC78 /* font.cpp in Sources */,
- DFF95B240FB22D5700A3EC78 /* font_map.cpp in Sources */,
- DFF95B250FB22D5700A3EC78 /* gfx.cpp in Sources */,
- DFF95B260FB22D5700A3EC78 /* image.cpp in Sources */,
- DFF95B270FB22D5700A3EC78 /* input.cpp in Sources */,
- DFF95B280FB22D5700A3EC78 /* interface.cpp in Sources */,
- DFF95B290FB22D5700A3EC78 /* introproc_ihnm.cpp in Sources */,
- DFF95B2A0FB22D5700A3EC78 /* introproc_ite.cpp in Sources */,
- DFF95B2B0FB22D5700A3EC78 /* isomap.cpp in Sources */,
- DFF95B2C0FB22D5700A3EC78 /* itedata.cpp in Sources */,
- DFF95B2D0FB22D5700A3EC78 /* music.cpp in Sources */,
- DFF95B2E0FB22D5700A3EC78 /* objectmap.cpp in Sources */,
- DFF95B2F0FB22D5700A3EC78 /* palanim.cpp in Sources */,
- DFF95B300FB22D5700A3EC78 /* puzzle.cpp in Sources */,
- DFF95B310FB22D5700A3EC78 /* render.cpp in Sources */,
- DFF95B320FB22D5700A3EC78 /* saga.cpp in Sources */,
- DFF95B330FB22D5700A3EC78 /* saveload.cpp in Sources */,
- DFF95B340FB22D5700A3EC78 /* scene.cpp in Sources */,
- DFF95B350FB22D5700A3EC78 /* script.cpp in Sources */,
- DFF95B360FB22D5700A3EC78 /* sfuncs.cpp in Sources */,
- DFF95B370FB22D5700A3EC78 /* sndres.cpp in Sources */,
- DFF95B380FB22D5700A3EC78 /* sound.cpp in Sources */,
- DFF95B390FB22D5700A3EC78 /* sprite.cpp in Sources */,
- DFF95B3A0FB22D5700A3EC78 /* sthread.cpp in Sources */,
- DFF95B3B0FB22D5700A3EC78 /* actor.cpp in Sources */,
- DFF95B3C0FB22D5700A3EC78 /* akos.cpp in Sources */,
- DFF95B3D0FB22D5700A3EC78 /* base-costume.cpp in Sources */,
- DFF95B3E0FB22D5700A3EC78 /* bomp.cpp in Sources */,
- DFF95B3F0FB22D5700A3EC78 /* boxes.cpp in Sources */,
- DFF95B400FB22D5700A3EC78 /* camera.cpp in Sources */,
- DFF95B410FB22D5700A3EC78 /* charset-fontdata.cpp in Sources */,
- DFF95B420FB22D5700A3EC78 /* charset.cpp in Sources */,
- DFF95B430FB22D5700A3EC78 /* costume.cpp in Sources */,
- DFF95B440FB22D5700A3EC78 /* cursor.cpp in Sources */,
- DFF95B450FB22D5700A3EC78 /* debugger.cpp in Sources */,
- DFF95B460FB22D5700A3EC78 /* detection.cpp in Sources */,
- DFF95B470FB22D5700A3EC78 /* dialogs.cpp in Sources */,
- DFF95B480FB22D5700A3EC78 /* file.cpp in Sources */,
- DFF95B490FB22D5700A3EC78 /* file_nes.cpp in Sources */,
- DFF95B4A0FB22D5700A3EC78 /* gfx.cpp in Sources */,
- DFF95B4B0FB22D5700A3EC78 /* animation_he.cpp in Sources */,
- DFF95B4C0FB22D5700A3EC78 /* cup_player_he.cpp in Sources */,
- DFF95B4D0FB22D5700A3EC78 /* floodfill_he.cpp in Sources */,
- DFF95B4E0FB22D5700A3EC78 /* logic_he.cpp in Sources */,
- DFF95B4F0FB22D5700A3EC78 /* palette_he.cpp in Sources */,
- DFF95B500FB22D5700A3EC78 /* resource_he.cpp in Sources */,
- DFF95B510FB22D5700A3EC78 /* script_v100he.cpp in Sources */,
- DFF95B520FB22D5700A3EC78 /* script_v60he.cpp in Sources */,
- DFF95B530FB22D5700A3EC78 /* script_v70he.cpp in Sources */,
- DFF95B540FB22D5700A3EC78 /* script_v71he.cpp in Sources */,
- DFF95B550FB22D5700A3EC78 /* script_v72he.cpp in Sources */,
- DFF95B560FB22D5700A3EC78 /* script_v80he.cpp in Sources */,
- DFF95B570FB22D5700A3EC78 /* script_v90he.cpp in Sources */,
- DFF95B580FB22D5700A3EC78 /* sound_he.cpp in Sources */,
- DFF95B590FB22D5700A3EC78 /* sprite_he.cpp in Sources */,
- DFF95B5A0FB22D5700A3EC78 /* wiz_he.cpp in Sources */,
- DFF95B5B0FB22D5700A3EC78 /* help.cpp in Sources */,
- DFF95B5C0FB22D5700A3EC78 /* imuse.cpp in Sources */,
- DFF95B5D0FB22D5700A3EC78 /* imuse_part.cpp in Sources */,
- DFF95B5E0FB22D5700A3EC78 /* imuse_player.cpp in Sources */,
- DFF95B5F0FB22D5700A3EC78 /* instrument.cpp in Sources */,
- DFF95B600FB22D5700A3EC78 /* sysex_samnmax.cpp in Sources */,
- DFF95B610FB22D5700A3EC78 /* sysex_scumm.cpp in Sources */,
- DFF95B620FB22D5700A3EC78 /* dimuse.cpp in Sources */,
- DFF95B630FB22D5700A3EC78 /* dimuse_bndmgr.cpp in Sources */,
- DFF95B640FB22D5700A3EC78 /* dimuse_codecs.cpp in Sources */,
- DFF95B650FB22D5700A3EC78 /* dimuse_music.cpp in Sources */,
- DFF95B660FB22D5700A3EC78 /* dimuse_script.cpp in Sources */,
- DFF95B670FB22D5700A3EC78 /* dimuse_sndmgr.cpp in Sources */,
- DFF95B680FB22D5700A3EC78 /* dimuse_tables.cpp in Sources */,
- DFF95B690FB22D5700A3EC78 /* dimuse_track.cpp in Sources */,
- DFF95B6A0FB22D5700A3EC78 /* input.cpp in Sources */,
- DFF95B6B0FB22D5700A3EC78 /* insane.cpp in Sources */,
- DFF95B6C0FB22D5700A3EC78 /* insane_ben.cpp in Sources */,
- DFF95B6D0FB22D5700A3EC78 /* insane_enemy.cpp in Sources */,
- DFF95B6E0FB22D5700A3EC78 /* insane_iact.cpp in Sources */,
- DFF95B6F0FB22D5700A3EC78 /* insane_scenes.cpp in Sources */,
- DFF95B710FB22D5700A3EC78 /* midiparser_ro.cpp in Sources */,
- DFF95B720FB22D5700A3EC78 /* nut_renderer.cpp in Sources */,
- DFF95B730FB22D5700A3EC78 /* object.cpp in Sources */,
- DFF95B740FB22D5700A3EC78 /* palette.cpp in Sources */,
- DFF95B750FB22D5700A3EC78 /* player_mod.cpp in Sources */,
- DFF95B760FB22D5700A3EC78 /* player_nes.cpp in Sources */,
- DFF95B770FB22D5700A3EC78 /* player_v1.cpp in Sources */,
- DFF95B780FB22D5700A3EC78 /* player_v2.cpp in Sources */,
- DFF95B790FB22D5700A3EC78 /* player_v2a.cpp in Sources */,
- DFF95B7A0FB22D5700A3EC78 /* player_v3a.cpp in Sources */,
- DFF95B7B0FB22D5700A3EC78 /* resource.cpp in Sources */,
- DFF95B7C0FB22D5700A3EC78 /* resource_v2.cpp in Sources */,
- DFF95B7D0FB22D5700A3EC78 /* resource_v3.cpp in Sources */,
- DFF95B7E0FB22D5700A3EC78 /* resource_v4.cpp in Sources */,
- DFF95B7F0FB22D5700A3EC78 /* room.cpp in Sources */,
- DFF95B800FB22D5700A3EC78 /* saveload.cpp in Sources */,
- DFF95B810FB22D5700A3EC78 /* script.cpp in Sources */,
- DFF95B820FB22D5700A3EC78 /* script_v0.cpp in Sources */,
- DFF95B830FB22D5700A3EC78 /* script_v2.cpp in Sources */,
- DFF95B840FB22D5700A3EC78 /* script_v5.cpp in Sources */,
- DFF95B850FB22D5700A3EC78 /* script_v6.cpp in Sources */,
- DFF95B860FB22D5700A3EC78 /* script_v8.cpp in Sources */,
- DFF95B870FB22D5700A3EC78 /* scumm.cpp in Sources */,
- DFF95B880FB22D5700A3EC78 /* channel.cpp in Sources */,
- DFF95B890FB22D5700A3EC78 /* codec1.cpp in Sources */,
- DFF95B8A0FB22D5700A3EC78 /* codec37.cpp in Sources */,
- DFF95B8B0FB22D5700A3EC78 /* codec47.cpp in Sources */,
- DFF95B8C0FB22D5700A3EC78 /* imuse_channel.cpp in Sources */,
- DFF95B8D0FB22D5700A3EC78 /* saud_channel.cpp in Sources */,
- DFF95B8E0FB22D5700A3EC78 /* smush_font.cpp in Sources */,
- DFF95B8F0FB22D5700A3EC78 /* smush_mixer.cpp in Sources */,
- DFF95B900FB22D5700A3EC78 /* smush_player.cpp in Sources */,
- DFF95B910FB22D5700A3EC78 /* sound.cpp in Sources */,
- DFF95B920FB22D5700A3EC78 /* string.cpp in Sources */,
- DFF95B930FB22D5700A3EC78 /* usage_bits.cpp in Sources */,
- DFF95B940FB22D5700A3EC78 /* util.cpp in Sources */,
- DFF95B950FB22D5700A3EC78 /* vars.cpp in Sources */,
- DFF95B960FB22D5700A3EC78 /* verbs.cpp in Sources */,
- DFF95B970FB22D5700A3EC78 /* autoroute.cpp in Sources */,
- DFF95B980FB22D5700A3EC78 /* compact.cpp in Sources */,
- DFF95B990FB22D5700A3EC78 /* control.cpp in Sources */,
- DFF95B9A0FB22D5700A3EC78 /* debug.cpp in Sources */,
- DFF95B9B0FB22D5700A3EC78 /* disk.cpp in Sources */,
- DFF95B9C0FB22D5700A3EC78 /* grid.cpp in Sources */,
- DFF95B9D0FB22D5700A3EC78 /* hufftext.cpp in Sources */,
- DFF95B9E0FB22D5700A3EC78 /* intro.cpp in Sources */,
- DFF95B9F0FB22D5700A3EC78 /* logic.cpp in Sources */,
- DFF95BA00FB22D5700A3EC78 /* mouse.cpp in Sources */,
- DFF95BA10FB22D5700A3EC78 /* adlibchannel.cpp in Sources */,
- DFF95BA20FB22D5700A3EC78 /* adlibmusic.cpp in Sources */,
- DFF95BA30FB22D5700A3EC78 /* gmchannel.cpp in Sources */,
- DFF95BA40FB22D5700A3EC78 /* gmmusic.cpp in Sources */,
- DFF95BA50FB22D5700A3EC78 /* mt32music.cpp in Sources */,
- DFF95BA60FB22D5700A3EC78 /* musicbase.cpp in Sources */,
- DFF95BA70FB22D5700A3EC78 /* rnc_deco.cpp in Sources */,
- DFF95BA80FB22D5700A3EC78 /* screen.cpp in Sources */,
- DFF95BA90FB22D5700A3EC78 /* sky.cpp in Sources */,
- DFF95BAA0FB22D5700A3EC78 /* sound.cpp in Sources */,
- DFF95BAB0FB22D5700A3EC78 /* text.cpp in Sources */,
- DFF95BAC0FB22D5700A3EC78 /* animation.cpp in Sources */,
- DFF95BAD0FB22D5700A3EC78 /* control.cpp in Sources */,
- DFF95BAE0FB22D5700A3EC78 /* debug.cpp in Sources */,
- DFF95BAF0FB22D5700A3EC78 /* eventman.cpp in Sources */,
- DFF95BB00FB22D5700A3EC78 /* logic.cpp in Sources */,
- DFF95BB10FB22D5700A3EC78 /* memman.cpp in Sources */,
- DFF95BB20FB22D5700A3EC78 /* menu.cpp in Sources */,
- DFF95BB30FB22D5700A3EC78 /* mouse.cpp in Sources */,
- DFF95BB40FB22D5700A3EC78 /* music.cpp in Sources */,
- DFF95BB50FB22D5700A3EC78 /* objectman.cpp in Sources */,
- DFF95BB60FB22D5700A3EC78 /* resman.cpp in Sources */,
- DFF95BB70FB22D5700A3EC78 /* router.cpp in Sources */,
- DFF95BB80FB22D5700A3EC78 /* screen.cpp in Sources */,
- DFF95BB90FB22D5700A3EC78 /* sound.cpp in Sources */,
- DFF95BBA0FB22D5700A3EC78 /* staticres.cpp in Sources */,
- DFF95BBB0FB22D5700A3EC78 /* sword1.cpp in Sources */,
- DFF95BBC0FB22D5700A3EC78 /* text.cpp in Sources */,
- DFF95BBD0FB22D5700A3EC78 /* animation.cpp in Sources */,
- DFF95BBE0FB22D5700A3EC78 /* anims.cpp in Sources */,
- DFF95BBF0FB22D5700A3EC78 /* console.cpp in Sources */,
- DFF95BC00FB22D5700A3EC78 /* controls.cpp in Sources */,
- DFF95BC10FB22D5700A3EC78 /* debug.cpp in Sources */,
- DFF95BC20FB22D5700A3EC78 /* events.cpp in Sources */,
- DFF95BC30FB22D5700A3EC78 /* function.cpp in Sources */,
- DFF95BC40FB22D5700A3EC78 /* icons.cpp in Sources */,
- DFF95BC50FB22D5700A3EC78 /* interpreter.cpp in Sources */,
- DFF95BC60FB22D5700A3EC78 /* layers.cpp in Sources */,
- DFF95BC70FB22D5700A3EC78 /* logic.cpp in Sources */,
- DFF95BC80FB22D5700A3EC78 /* maketext.cpp in Sources */,
- DFF95BC90FB22D5700A3EC78 /* memory.cpp in Sources */,
- DFF95BCA0FB22D5700A3EC78 /* menu.cpp in Sources */,
- DFF95BCB0FB22D5700A3EC78 /* mouse.cpp in Sources */,
- DFF95BCC0FB22D5700A3EC78 /* music.cpp in Sources */,
- DFF95BCD0FB22D5700A3EC78 /* palette.cpp in Sources */,
- DFF95BCE0FB22D5700A3EC78 /* protocol.cpp in Sources */,
- DFF95BCF0FB22D5700A3EC78 /* render.cpp in Sources */,
- DFF95BD00FB22D5700A3EC78 /* resman.cpp in Sources */,
- DFF95BD10FB22D5700A3EC78 /* router.cpp in Sources */,
- DFF95BD20FB22D5700A3EC78 /* saveload.cpp in Sources */,
- DFF95BD30FB22D5700A3EC78 /* screen.cpp in Sources */,
- DFF95BD40FB22D5700A3EC78 /* scroll.cpp in Sources */,
- DFF95BD50FB22D5700A3EC78 /* sound.cpp in Sources */,
- DFF95BD60FB22D5700A3EC78 /* speech.cpp in Sources */,
- DFF95BD70FB22D5700A3EC78 /* sprite.cpp in Sources */,
- DFF95BD80FB22D5700A3EC78 /* startup.cpp in Sources */,
- DFF95BD90FB22D5700A3EC78 /* sword2.cpp in Sources */,
- DFF95BDA0FB22D5700A3EC78 /* sync.cpp in Sources */,
- DFF95BDB0FB22D5700A3EC78 /* walker.cpp in Sources */,
- DFF95BDC0FB22D5700A3EC78 /* actors.cpp in Sources */,
- DFF95BDD0FB22D5700A3EC78 /* anim.cpp in Sources */,
- DFF95BDE0FB22D5700A3EC78 /* background.cpp in Sources */,
- DFF95BDF0FB22D5700A3EC78 /* bg.cpp in Sources */,
- DFF95BE00FB22D5700A3EC78 /* cliprect.cpp in Sources */,
- DFF95BE10FB22D5700A3EC78 /* config.cpp in Sources */,
- DFF95BE20FB22D5700A3EC78 /* cursor.cpp in Sources */,
- DFF95BE30FB22D5700A3EC78 /* debugger.cpp in Sources */,
- DFF95BE40FB22D5700A3EC78 /* detection.cpp in Sources */,
- DFF95BE50FB22D5700A3EC78 /* effect.cpp in Sources */,
- DFF95BE60FB22D5700A3EC78 /* events.cpp in Sources */,
- DFF95BE70FB22D5700A3EC78 /* faders.cpp in Sources */,
- DFF95BE80FB22D5700A3EC78 /* font.cpp in Sources */,
- DFF95BE90FB22D5700A3EC78 /* graphics.cpp in Sources */,
- DFF95BEA0FB22D5700A3EC78 /* handle.cpp in Sources */,
- DFF95BEB0FB22D5700A3EC78 /* heapmem.cpp in Sources */,
- DFF95BEC0FB22D5700A3EC78 /* mareels.cpp in Sources */,
- DFF95BED0FB22D5700A3EC78 /* move.cpp in Sources */,
- DFF95BEE0FB22D5700A3EC78 /* multiobj.cpp in Sources */,
- DFF95BEF0FB22D5700A3EC78 /* music.cpp in Sources */,
- DFF95BF00FB22D5700A3EC78 /* object.cpp in Sources */,
- DFF95BF10FB22D5700A3EC78 /* palette.cpp in Sources */,
- DFF95BF20FB22D5700A3EC78 /* pcode.cpp in Sources */,
- DFF95BF30FB22D5700A3EC78 /* pdisplay.cpp in Sources */,
- DFF95BF40FB22D5700A3EC78 /* play.cpp in Sources */,
- DFF95BF50FB22D5700A3EC78 /* polygons.cpp in Sources */,
- DFF95BF60FB22D5700A3EC78 /* rince.cpp in Sources */,
- DFF95BF70FB22D5700A3EC78 /* saveload.cpp in Sources */,
- DFF95BF80FB22D5700A3EC78 /* savescn.cpp in Sources */,
- DFF95BF90FB22D5700A3EC78 /* scene.cpp in Sources */,
- DFF95BFA0FB22D5700A3EC78 /* sched.cpp in Sources */,
- DFF95BFB0FB22D5700A3EC78 /* scn.cpp in Sources */,
- DFF95BFC0FB22D5700A3EC78 /* scroll.cpp in Sources */,
- DFF95BFD0FB22D5700A3EC78 /* sound.cpp in Sources */,
- DFF95BFE0FB22D5700A3EC78 /* strres.cpp in Sources */,
- DFF95BFF0FB22D5700A3EC78 /* text.cpp in Sources */,
- DFF95C000FB22D5700A3EC78 /* timers.cpp in Sources */,
- DFF95C010FB22D5700A3EC78 /* tinlib.cpp in Sources */,
- DFF95C020FB22D5700A3EC78 /* tinsel.cpp in Sources */,
- DFF95C030FB22D5700A3EC78 /* token.cpp in Sources */,
- DFF95C040FB22D5700A3EC78 /* detection.cpp in Sources */,
- DFF95C050FB22D5700A3EC78 /* graphics.cpp in Sources */,
- DFF95C060FB22D5700A3EC78 /* menu.cpp in Sources */,
- DFF95C070FB22D5700A3EC78 /* midi.cpp in Sources */,
- DFF95C080FB22D5700A3EC78 /* opcodes.cpp in Sources */,
- DFF95C090FB22D5700A3EC78 /* resource.cpp in Sources */,
- DFF95C0A0FB22D5700A3EC78 /* saveload.cpp in Sources */,
- DFF95C0B0FB22D5700A3EC78 /* staticres.cpp in Sources */,
- DFF95C0C0FB22D5700A3EC78 /* touche.cpp in Sources */,
- DFF95C0D0FB22D5700A3EC78 /* blit.cpp in Sources */,
- DFF95C0E0FB22D5700A3EC78 /* timidity.cpp in Sources */,
- DFF95C0F0FB22D5700A3EC78 /* archive.cpp in Sources */,
- DFF95C100FB22D5700A3EC78 /* unarj.cpp in Sources */,
- DFF95C110FB22D5700A3EC78 /* stdiostream.cpp in Sources */,
- DFF95C130FB22D5700A3EC78 /* saveload.cpp in Sources */,
- DFF95C140FB22D5700A3EC78 /* ThemeEngine.cpp in Sources */,
- DFF95C150FB22D5700A3EC78 /* ThemeEval.cpp in Sources */,
- DFF95C160FB22D5700A3EC78 /* ThemeLayout.cpp in Sources */,
- DFF95C170FB22D5700A3EC78 /* ThemeParser.cpp in Sources */,
- DFF95C180FB22D5700A3EC78 /* thumbnail.cpp in Sources */,
- DFF95C190FB22D5700A3EC78 /* VectorRenderer.cpp in Sources */,
- DFF95C1A0FB22D5700A3EC78 /* VectorRendererSpec.cpp in Sources */,
- DFF95C1B0FB22D5700A3EC78 /* xmlparser.cpp in Sources */,
- DFF95C1C0FB22D5700A3EC78 /* game.cpp in Sources */,
- DFF95C1D0FB22D5700A3EC78 /* saveload.cpp in Sources */,
- DFF95C1E0FB22D5700A3EC78 /* detection.cpp in Sources */,
- DFF95C1F0FB22D5700A3EC78 /* detection.cpp in Sources */,
- DFF95C200FB22D5700A3EC78 /* thumbnail_intern.cpp in Sources */,
- DFF95C210FB22D5700A3EC78 /* dither.cpp in Sources */,
- DFF95C270FB22D5700A3EC78 /* debug.cpp in Sources */,
- DFF95C290FB22D5700A3EC78 /* posix-saves.cpp in Sources */,
- DFF95C2A0FB22D5700A3EC78 /* bmv.cpp in Sources */,
- DFF95C2B0FB22D5700A3EC78 /* dialogs.cpp in Sources */,
- DFF95C2C0FB22D5700A3EC78 /* drives.cpp in Sources */,
- DFF95C2D0FB22D5700A3EC78 /* sysvar.cpp in Sources */,
- DFF95C2E0FB22D5700A3EC78 /* gui_lol.cpp in Sources */,
- DFF95C2F0FB22D5700A3EC78 /* items_lol.cpp in Sources */,
- DFF95C300FB22D5700A3EC78 /* script_lol.cpp in Sources */,
- DFF95C310FB22D5700A3EC78 /* sequences_lol.cpp in Sources */,
- DFF95C320FB22D5700A3EC78 /* sound_midi.cpp in Sources */,
- DFF95C330FB22D5700A3EC78 /* util.cpp in Sources */,
- DFF95C370FB22D5700A3EC78 /* scene_lol.cpp in Sources */,
- DFF95C380FB22D5700A3EC78 /* advancedDetector.cpp in Sources */,
- DFF95C390FB22D5700A3EC78 /* base-backend.cpp in Sources */,
- DFF95C3A0FB22D5700A3EC78 /* resource.cpp in Sources */,
- DFF95C3B0FB22D5700A3EC78 /* resource_hrs.cpp in Sources */,
- DFF95C3C0FB22D5700A3EC78 /* resource_res.cpp in Sources */,
- DFF95C3D0FB22D5700A3EC78 /* resource_rsc.cpp in Sources */,
- DFF95C3E0FB22D5700A3EC78 /* sfuncs_ihnm.cpp in Sources */,
- DFF95C3F0FB22D5700A3EC78 /* debugger.cpp in Sources */,
- DFF95C400FB22D5700A3EC78 /* staticres.cpp in Sources */,
- DFF95C410FB22D5700A3EC78 /* cell.cpp in Sources */,
- DFF95C420FB22D5700A3EC78 /* cursor.cpp in Sources */,
- DFF95C430FB22D5700A3EC78 /* debug.cpp in Sources */,
- DFF95C440FB22D5700A3EC78 /* detection.cpp in Sources */,
- DFF95C450FB22D5700A3EC78 /* font.cpp in Sources */,
- DFF95C460FB22D5700A3EC78 /* graphics.cpp in Sources */,
- DFF95C470FB22D5700A3EC78 /* groovie.cpp in Sources */,
- DFF95C480FB22D5700A3EC78 /* lzss.cpp in Sources */,
- DFF95C490FB22D5700A3EC78 /* music.cpp in Sources */,
- DFF95C4A0FB22D5700A3EC78 /* player.cpp in Sources */,
- DFF95C4B0FB22D5700A3EC78 /* resource.cpp in Sources */,
- DFF95C4C0FB22D5700A3EC78 /* roq.cpp in Sources */,
- DFF95C4D0FB22D5700A3EC78 /* saveload.cpp in Sources */,
- DFF95C4E0FB22D5700A3EC78 /* script.cpp in Sources */,
- DFF95C4F0FB22D5700A3EC78 /* vdx.cpp in Sources */,
- DFF95C500FB22D5700A3EC78 /* detection.cpp in Sources */,
- DFF95C510FB22D5700A3EC78 /* graphics.cpp in Sources */,
- DFF95C520FB22D5700A3EC78 /* locations.cpp in Sources */,
- DFF95C530FB22D5700A3EC78 /* resource.cpp in Sources */,
- DFF95C540FB22D5700A3EC78 /* saveload.cpp in Sources */,
- DFF95C550FB22D5700A3EC78 /* sequences.cpp in Sources */,
- DFF95C560FB22D5700A3EC78 /* staticres.cpp in Sources */,
- DFF95C570FB22D5700A3EC78 /* tucker.cpp in Sources */,
- DFF95C580FB22D5700A3EC78 /* detection.cpp in Sources */,
- DFF95C5A0FB22D5700A3EC78 /* gc.cpp in Sources */,
- DFF95C5C0FB22D5700A3EC78 /* kernel.cpp in Sources */,
- DFF95C5D0FB22D5700A3EC78 /* kevent.cpp in Sources */,
- DFF95C5E0FB22D5700A3EC78 /* kfile.cpp in Sources */,
- DFF95C5F0FB22D5700A3EC78 /* kgraphics.cpp in Sources */,
- DFF95C600FB22D5700A3EC78 /* klists.cpp in Sources */,
- DFF95C610FB22D5700A3EC78 /* kmath.cpp in Sources */,
- DFF95C620FB22D5700A3EC78 /* kmenu.cpp in Sources */,
- DFF95C630FB22D5700A3EC78 /* kmovement.cpp in Sources */,
- DFF95C640FB22D5700A3EC78 /* kpathing.cpp in Sources */,
- DFF95C650FB22D5700A3EC78 /* kscripts.cpp in Sources */,
- DFF95C660FB22D5700A3EC78 /* ksound.cpp in Sources */,
- DFF95C670FB22D5700A3EC78 /* kstring.cpp in Sources */,
- DFF95C680FB22D5700A3EC78 /* message.cpp in Sources */,
- DFF95C6A0FB22D5700A3EC78 /* savegame.cpp in Sources */,
- DFF95C6C0FB22D5700A3EC78 /* scriptdebug.cpp in Sources */,
- DFF95C6D0FB22D5700A3EC78 /* seg_manager.cpp in Sources */,
- DFF95C6E0FB22D5700A3EC78 /* vm.cpp in Sources */,
- DFF95C770FB22D5700A3EC78 /* sci.cpp in Sources */,
- DFF95C880FB22D5700A3EC78 /* unzip.cpp in Sources */,
- DFF95C890FB22D5700A3EC78 /* console.cpp in Sources */,
- DFF95C8E0FB22D5700A3EC78 /* state.cpp in Sources */,
- DFF95C910FB22D5700A3EC78 /* exec.cpp in Sources */,
- DFF95C920FB22D5700A3EC78 /* timer_lol.cpp in Sources */,
- DFF95C940FB22D5700A3EC78 /* sprites_lol.cpp in Sources */,
- DFF95C950FB22D5700A3EC78 /* script.cpp in Sources */,
- DFF95C990FB22D5700A3EC78 /* pn.cpp in Sources */,
- DFF95C9A0FB22D5700A3EC78 /* script_pn.cpp in Sources */,
- DFF95C9B0FB22D5700A3EC78 /* vga_pn.cpp in Sources */,
- DFF95CA70FB22D5700A3EC78 /* sound_br.cpp in Sources */,
- DFF95CA80FB22D5700A3EC78 /* sound_ns.cpp in Sources */,
- DFF95CA90FB22D5700A3EC78 /* protracker.cpp in Sources */,
- DFF95CAC0FB22D5700A3EC78 /* sound.cpp in Sources */,
- DFF95CAE0FB22D5700A3EC78 /* batplayer.cpp in Sources */,
- DFF95CAF0FB22D5700A3EC78 /* demoplayer.cpp in Sources */,
- DFF95CB00FB22D5700A3EC78 /* scnplayer.cpp in Sources */,
- DFF95CB10FB22D5700A3EC78 /* draw_fascin.cpp in Sources */,
- DFF95CB30FB22D5700A3EC78 /* inter_fascin.cpp in Sources */,
- DFF95CB40FB22D5700A3EC78 /* script_v3.cpp in Sources */,
- DFF95CB50FB22D5700A3EC78 /* script_v4.cpp in Sources */,
- DF6118400FE3A8080042AD3F /* kmisc.cpp in Sources */,
- DF6118410FE3A8080042AD3F /* segment.cpp in Sources */,
- DF61184F0FE3A8250042AD3F /* decompressor.cpp in Sources */,
- DF6118500FE3A8250042AD3F /* resource.cpp in Sources */,
- DF6118570FE3A8990042AD3F /* disk.cpp in Sources */,
- DF6118A10FE3A9AA0042AD3F /* saveconverter.cpp in Sources */,
- DF6118A20FE3A9AA0042AD3F /* saveconverter_v2.cpp in Sources */,
- DF6118A30FE3A9AA0042AD3F /* saveconverter_v3.cpp in Sources */,
- DF6118A40FE3A9AA0042AD3F /* saveconverter_v4.cpp in Sources */,
- DF6118A60FE3A9AA0042AD3F /* savefile.cpp in Sources */,
- DF6118A70FE3A9AA0042AD3F /* savehandler.cpp in Sources */,
- DF6118A80FE3A9AA0042AD3F /* saveload.cpp in Sources */,
- DF6118A90FE3A9AA0042AD3F /* saveload_v2.cpp in Sources */,
- DF6118AA0FE3A9AA0042AD3F /* saveload_v3.cpp in Sources */,
- DF6118AB0FE3A9AA0042AD3F /* saveload_v4.cpp in Sources */,
- DF6118AC0FE3A9AA0042AD3F /* saveload_v6.cpp in Sources */,
- DF6118B10FE3A9EA0042AD3F /* feeble.cpp in Sources */,
- DF6118C00FE3AA280042AD3F /* saveload_lol.cpp in Sources */,
- DF6118C10FE3AA280042AD3F /* sound_lol.cpp in Sources */,
- DF6118C20FE3AA280042AD3F /* sound_pcspk.cpp in Sources */,
- DF6118C30FE3AA280042AD3F /* text_lol.cpp in Sources */,
- DF6118C90FE3AABD0042AD3F /* player_v2cms.cpp in Sources */,
- DF7585D4100CB66E00CC3324 /* expression.cpp in Sources */,
- DF7585D5100CB66E00CC3324 /* hotspots.cpp in Sources */,
- DF7585D6100CB66E00CC3324 /* init_v6.cpp in Sources */,
- DF7585D7100CB66E00CC3324 /* resources.cpp in Sources */,
- DF7585D8100CB66E00CC3324 /* script.cpp in Sources */,
- DF7585D9100CB66E00CC3324 /* totfile.cpp in Sources */,
- DF7585ED100CB6EA00CC3324 /* sjis.cpp in Sources */,
- DF7585F2100CB70600CC3324 /* saveload_playtoons.cpp in Sources */,
- DF7585F8100CB75800CC3324 /* static_selectors.cpp in Sources */,
- DF758619100CBA0200CC3324 /* osys_events.cpp in Sources */,
- DF75861A100CBA0200CC3324 /* osys_main.cpp in Sources */,
- DF75861B100CBA0200CC3324 /* osys_sound.cpp in Sources */,
- DF75861C100CBA0200CC3324 /* osys_video.cpp in Sources */,
- DF6BF4C410529DA50069811F /* conversion.cpp in Sources */,
- DF6BF4C510529DA50069811F /* jpeg.cpp in Sources */,
- DF6BF4D810529DE90069811F /* input_pn.cpp in Sources */,
- DF6BF4D910529DE90069811F /* string_pn.cpp in Sources */,
- DF6BF4DA10529DE90069811F /* verb_pn.cpp in Sources */,
- DF6BF4E410529E260069811F /* sound_amiga.cpp in Sources */,
- DF6BF4EA10529E6E0069811F /* init_v4.cpp in Sources */,
- DF6BF4EB10529E6E0069811F /* inter_playtoons.cpp in Sources */,
- DF6BF4F310529EE40069811F /* player_v4a.cpp in Sources */,
- DF6BF4FC10529F140069811F /* EventDispatcher.cpp in Sources */,
- DF6BF4FD10529F140069811F /* EventRecorder.cpp in Sources */,
- DF90E9C110AEDA9B00C8F93F /* selector.cpp in Sources */,
- DF90EAA510B0234300C8F93F /* draw_playtoons.cpp in Sources */,
- DF90EAAE10B0236F00C8F93F /* staticres.cpp in Sources */,
- DF2EC3FA10E64C0C00765801 /* dialogs.cpp in Sources */,
- DF2EC40010E64C4300765801 /* animator_tim.cpp in Sources */,
- DF2EC40710E64C8000765801 /* event.cpp in Sources */,
- DF2EC50510E64D7C00765801 /* player_pce.cpp in Sources */,
- DF2EC50610E64D7C00765801 /* player_sid.cpp in Sources */,
- DF2EC50D10E64DB300765801 /* textconsole.cpp in Sources */,
- DF45B21E116628A5009B85CC /* animate.cpp in Sources */,
- DF45B21F116628A5009B85CC /* cache.cpp in Sources */,
- DF45B220116628A5009B85CC /* compare.cpp in Sources */,
- DF45B221116628A5009B85CC /* controls.cpp in Sources */,
- DF45B222116628A5009B85CC /* coordadjuster.cpp in Sources */,
- DF45B223116628A5009B85CC /* cursor.cpp in Sources */,
- DF45B224116628A5009B85CC /* font.cpp in Sources */,
- DF45B228116628A5009B85CC /* menu.cpp in Sources */,
- DF45B229116628A5009B85CC /* paint.cpp in Sources */,
- DF45B22A116628A5009B85CC /* paint16.cpp in Sources */,
- DF45B22C116628A5009B85CC /* palette.cpp in Sources */,
- DF45B22D116628A5009B85CC /* picture.cpp in Sources */,
- DF45B22E116628A5009B85CC /* portrait.cpp in Sources */,
- DF45B22F116628A5009B85CC /* ports.cpp in Sources */,
- DF45B231116628A5009B85CC /* screen.cpp in Sources */,
- DF45B232116628A5009B85CC /* text16.cpp in Sources */,
- DF45B233116628A5009B85CC /* transitions.cpp in Sources */,
- DF45B234116628A5009B85CC /* view.cpp in Sources */,
- DF45B235116628A5009B85CC /* grammar.cpp in Sources */,
- DF45B236116628A5009B85CC /* said.cpp in Sources */,
- DF45B238116628A5009B85CC /* vocabulary.cpp in Sources */,
- DF45B239116628A5009B85CC /* audio.cpp in Sources */,
- DF45B23A116628A5009B85CC /* adlib.cpp in Sources */,
- DF45B23C116628A5009B85CC /* fb01.cpp in Sources */,
- DF45B23D116628A5009B85CC /* midi.cpp in Sources */,
- DF45B23E116628A5009B85CC /* pcjr.cpp in Sources */,
- DF45B243116628A5009B85CC /* midiparser_sci.cpp in Sources */,
- DF45B244116628A5009B85CC /* music.cpp in Sources */,
- DF45B245116628A5009B85CC /* soundcmd.cpp in Sources */,
- DF45B246116628A5009B85CC /* seq_decoder.cpp in Sources */,
- DFCDC6DD116629CE00A7D2A0 /* features.cpp in Sources */,
- DFCDC6DE116629CE00A7D2A0 /* kparse.cpp in Sources */,
- DFCDC6F911662AAB00A7D2A0 /* resource.cpp in Sources */,
- DFCDC70611662B0200A7D2A0 /* saveload_fascin.cpp in Sources */,
- DFCDC70D11662B6B00A7D2A0 /* macresman.cpp in Sources */,
- DFEC5D101166C5CF00C90552 /* random.cpp in Sources */,
- DFEC5D111166C5CF00C90552 /* tokenizer.cpp in Sources */,
- DFEC5D361166C67300C90552 /* savestate.cpp in Sources */,
- DF9B9248118E46730069C19D /* error.cpp in Sources */,
- DF9B9252118E46A00069C19D /* fontsjis.cpp in Sources */,
- DF9B9262118E46FE0069C19D /* error.cpp in Sources */,
- DFB0577611B753DA0015AE65 /* rational.cpp in Sources */,
- DFB0578011B7541F0015AE65 /* resource_audio.cpp in Sources */,
- DFB0578111B7541F0015AE65 /* util.cpp in Sources */,
- DFB0578A11B754570015AE65 /* maciconbar.cpp in Sources */,
- DFB0579111B7547D0015AE65 /* pict.cpp in Sources */,
- DF7F286111FF23D500159131 /* amigamac.cpp in Sources */,
- DF7F286711FF23EF00159131 /* kvideo.cpp in Sources */,
- DF7F286811FF23EF00159131 /* workarounds.cpp in Sources */,
- DF7F287A11FF243B00159131 /* sound_2gs.cpp in Sources */,
- DF7F287B11FF243B00159131 /* sound_coco3.cpp in Sources */,
- DF7F287C11FF243B00159131 /* sound_midi.cpp in Sources */,
- DF7F287D11FF243B00159131 /* sound_pcjr.cpp in Sources */,
- DF7F287E11FF243B00159131 /* sound_sarien.cpp in Sources */,
- DF7F288B11FF244F00159131 /* Tooltip.cpp in Sources */,
- DF7F289311FF247300159131 /* translation.cpp in Sources */,
- DF7F28A511FF24C400159131 /* console.cpp in Sources */,
- DF895C05124C24680077F6E8 /* player_towns.cpp in Sources */,
- DF895C27124C25150077F6E8 /* init_fascin.cpp in Sources */,
- DF895C2C124C25350077F6E8 /* script_patches.cpp in Sources */,
- DF0E303A1252C5BD0082D593 /* cms.cpp in Sources */,
- 8CB5A9C11253FD6900CB6BC7 /* m4_scene.cpp in Sources */,
- 8CB5A9C21253FD6900CB6BC7 /* mads_logic.cpp in Sources */,
- 8CB5A9C31253FD6900CB6BC7 /* mads_player.cpp in Sources */,
- 8CB5A9C41253FD6900CB6BC7 /* mads_scene.cpp in Sources */,
- 8CB5A9C51253FD6900CB6BC7 /* mads_views.cpp in Sources */,
- 8CD1ED0B126202AB00FA198C /* detection.cpp in Sources */,
- 8CD1ED0C126202AB00FA198C /* display.cpp in Sources */,
- 8CD1ED0E126202AB00FA198C /* file.cpp in Sources */,
- 8CD1ED0F126202AB00FA198C /* hugo.cpp in Sources */,
- 8CD1ED10126202AB00FA198C /* intro.cpp in Sources */,
- 8CD1ED11126202AB00FA198C /* inventory.cpp in Sources */,
- 8CD1ED14126202AB00FA198C /* mouse.cpp in Sources */,
- 8CD1ED15126202AB00FA198C /* parser.cpp in Sources */,
- 8CD1ED16126202AB00FA198C /* route.cpp in Sources */,
- 8CD1ED17126202AB00FA198C /* schedule.cpp in Sources */,
- 8CD1ED18126202AB00FA198C /* sound.cpp in Sources */,
- 8CD1ED19126202AB00FA198C /* util.cpp in Sources */,
- 8CD1ED1A126202AB00FA198C /* anim.cpp in Sources */,
- 8CD1ED1B126202AB00FA198C /* audio.cpp in Sources */,
- 8CD1ED1C126202AB00FA198C /* character.cpp in Sources */,
- 8CD1ED1D126202AB00FA198C /* conversation.cpp in Sources */,
- 8CD1ED1E126202AB00FA198C /* detection.cpp in Sources */,
- 8CD1ED1F126202AB00FA198C /* drew.cpp in Sources */,
- 8CD1ED20126202AB00FA198C /* flux.cpp in Sources */,
- 8CD1ED21126202AB00FA198C /* font.cpp in Sources */,
- 8CD1ED22126202AB00FA198C /* hotspot.cpp in Sources */,
- 8CD1ED25126202AB00FA198C /* movie.cpp in Sources */,
- 8CD1ED26126202AB00FA198C /* path.cpp in Sources */,
- 8CD1ED27126202AB00FA198C /* picture.cpp in Sources */,
- 8CD1ED28126202AB00FA198C /* resource.cpp in Sources */,
- 8CD1ED29126202AB00FA198C /* script.cpp in Sources */,
- 8CD1ED2A126202AB00FA198C /* script_func.cpp in Sources */,
- 8CD1ED2B126202AB00FA198C /* state.cpp in Sources */,
- 8CD1ED2C126202AB00FA198C /* text.cpp in Sources */,
- 8CD1ED2D126202AB00FA198C /* tools.cpp in Sources */,
- 8CD1ED2E126202AB00FA198C /* toon.cpp in Sources */,
- 8CD80C8B126271A9001C6C87 /* surface.cpp in Sources */,
- 8CD80C91126271BD001C6C87 /* gfx_towns.cpp in Sources */,
- 8CD80CE0126272A0001C6C87 /* actor.cpp in Sources */,
- 8CD80CE1126272A0001C6C87 /* animation.cpp in Sources */,
- 8CD80CE2126272A0001C6C87 /* callbacks.cpp in Sources */,
- 8CD80CE3126272A0001C6C87 /* console.cpp in Sources */,
- 8CD80CE4126272A0001C6C87 /* detection.cpp in Sources */,
- 8CD80CE5126272A0001C6C87 /* dialog.cpp in Sources */,
- 8CD80CE6126272A0001C6C87 /* font.cpp in Sources */,
- 8CD80CE7126272A0001C6C87 /* inventory.cpp in Sources */,
- 8CD80CE9126272A0001C6C87 /* music.cpp in Sources */,
- 8CD80CEA126272A0001C6C87 /* objects.cpp in Sources */,
- 8CD80CEB126272A0001C6C87 /* pack.cpp in Sources */,
- 8CD80CEC126272A0001C6C87 /* resources.cpp in Sources */,
- 8CD80CED126272A0001C6C87 /* scene.cpp in Sources */,
- 8CD80CEE126272A0001C6C87 /* segment.cpp in Sources */,
- 8CD80CEF126272A0001C6C87 /* surface.cpp in Sources */,
- 8CD80CF0126272A0001C6C87 /* surface_list.cpp in Sources */,
- 8CD80CF1126272A0001C6C87 /* teenagent.cpp in Sources */,
- DF203F491380C06E0056300A /* gui-manager.cpp in Sources */,
- DF203F731380C2750056300A /* avi_decoder.cpp in Sources */,
- DF203F741380C2750056300A /* coktel_decoder.cpp in Sources */,
- DF203F751380C2750056300A /* dxa_decoder.cpp in Sources */,
- DF203F761380C2750056300A /* flic_decoder.cpp in Sources */,
- DF203F781380C2750056300A /* qt_decoder.cpp in Sources */,
- DF203F791380C2750056300A /* smk_decoder.cpp in Sources */,
- DF203F7A1380C2750056300A /* video_decoder.cpp in Sources */,
- DF203FAB1380C2920056300A /* cdtoons.cpp in Sources */,
- DF203FAC1380C2920056300A /* cinepak.cpp in Sources */,
- DF203FAD1380C2920056300A /* indeo3.cpp in Sources */,
- DF203FAE1380C2920056300A /* mjpeg.cpp in Sources */,
- DF203FAF1380C2920056300A /* msrle.cpp in Sources */,
- DF203FB01380C2920056300A /* msvideo1.cpp in Sources */,
- DF203FB21380C2920056300A /* qtrle.cpp in Sources */,
- DF203FB31380C2920056300A /* rpza.cpp in Sources */,
- DF203FB41380C2920056300A /* smc.cpp in Sources */,
- DF203FB51380C2920056300A /* truemotion1.cpp in Sources */,
- DF203FF71380C3BC0056300A /* console.cpp in Sources */,
- DF203FF81380C3BC0056300A /* dialogs.cpp in Sources */,
- DF203FF91380C3BC0056300A /* file_v1d.cpp in Sources */,
- DF203FFA1380C3BC0056300A /* file_v1w.cpp in Sources */,
- DF203FFB1380C3BC0056300A /* file_v2d.cpp in Sources */,
- DF203FFC1380C3BC0056300A /* file_v2w.cpp in Sources */,
- DF203FFD1380C3BC0056300A /* file_v3d.cpp in Sources */,
- DF203FFE1380C3BC0056300A /* object_v1d.cpp in Sources */,
- DF203FFF1380C3BC0056300A /* object_v1w.cpp in Sources */,
- DF2040001380C3BC0056300A /* object_v2d.cpp in Sources */,
- DF2040011380C3BC0056300A /* object_v3d.cpp in Sources */,
- DF2040021380C3BC0056300A /* object.cpp in Sources */,
- DF2040031380C3BC0056300A /* parser_v1d.cpp in Sources */,
- DF2040041380C3BC0056300A /* parser_v1w.cpp in Sources */,
- DF2040051380C3BC0056300A /* parser_v2d.cpp in Sources */,
- DF2040061380C3BC0056300A /* parser_v3d.cpp in Sources */,
- DF2040071380C3BC0056300A /* text.cpp in Sources */,
- DF20403A1380C8B70056300A /* editable.cpp in Sources */,
- DF20403B1380C8B70056300A /* edittext.cpp in Sources */,
- DF20403C1380C8B70056300A /* list.cpp in Sources */,
- DF20403D1380C8B70056300A /* popup.cpp in Sources */,
- DF20403E1380C8B70056300A /* scrollbar.cpp in Sources */,
- DF20403F1380C8B70056300A /* tab.cpp in Sources */,
- DF2040761380CA230056300A /* audiostream.cpp in Sources */,
- DF2040771380CA230056300A /* fmopl.cpp in Sources */,
- DF2040781380CA230056300A /* mididrv.cpp in Sources */,
- DF2040791380CA230056300A /* midiparser_smf.cpp in Sources */,
- DF20407A1380CA230056300A /* midiparser_xmidi.cpp in Sources */,
- DF20407B1380CA230056300A /* midiparser.cpp in Sources */,
- DF20407C1380CA230056300A /* midiplayer.cpp in Sources */,
- DF20407D1380CA230056300A /* mixer.cpp in Sources */,
- DF20407E1380CA230056300A /* mpu401.cpp in Sources */,
- DF20407F1380CA230056300A /* musicplugin.cpp in Sources */,
- DF2040801380CA230056300A /* rate.cpp in Sources */,
- DF2040811380CA230056300A /* timestamp.cpp in Sources */,
- DF2040B01380CA400056300A /* adpcm.cpp in Sources */,
- DF2040B11380CA400056300A /* aiff.cpp in Sources */,
- DF2040B21380CA400056300A /* flac.cpp in Sources */,
- DF2040B31380CA400056300A /* iff_sound.cpp in Sources */,
- DF2040B41380CA400056300A /* mac_snd.cpp in Sources */,
- DF2040B51380CA400056300A /* mp3.cpp in Sources */,
- DF2040B61380CA400056300A /* raw.cpp in Sources */,
- DF2040B71380CA400056300A /* vag.cpp in Sources */,
- DF2040B81380CA400056300A /* voc.cpp in Sources */,
- DF2040B91380CA400056300A /* vorbis.cpp in Sources */,
- DF2040BA1380CA400056300A /* wave.cpp in Sources */,
- DF2040DC1380CA810056300A /* infogrames.cpp in Sources */,
- DF2040DD1380CA810056300A /* maxtrax.cpp in Sources */,
- DF2040DE1380CA810056300A /* module.cpp in Sources */,
- DF2040DF1380CA810056300A /* paula.cpp in Sources */,
- DF2040E01380CA810056300A /* protracker.cpp in Sources */,
- DF2040E11380CA810056300A /* rjp1.cpp in Sources */,
- DF2040E21380CA810056300A /* soundfx.cpp in Sources */,
- DF2040E31380CA810056300A /* tfmx.cpp in Sources */,
- DF2041081380CAA40056300A /* adlib.cpp in Sources */,
- DF2041091380CAA40056300A /* appleiigs.cpp in Sources */,
- DF20410A1380CAA40056300A /* cms.cpp in Sources */,
- DF20410B1380CAA40056300A /* eas.cpp in Sources */,
- DF20410C1380CAA40056300A /* fluidsynth.cpp in Sources */,
- DF20410D1380CAA40056300A /* mt32.cpp in Sources */,
- DF20410E1380CAA40056300A /* pcspk.cpp in Sources */,
- DF20410F1380CAA40056300A /* sid.cpp in Sources */,
- DF2041101380CAA40056300A /* wave6581.cpp in Sources */,
- DF46B6F51381E18900D08723 /* coroutine.cpp in Sources */,
- DF46B7071381E1FF00D08723 /* towns_audio.cpp in Sources */,
- DF46B7081381E1FF00D08723 /* towns_euphony.cpp in Sources */,
- DF46B7091381E1FF00D08723 /* towns_pc98_driver.cpp in Sources */,
- DF46B70A1381E1FF00D08723 /* towns_pc98_fmsynth.cpp in Sources */,
- DF46B7251381E27000D08723 /* console.cpp in Sources */,
- DF46B7261381E27000D08723 /* databases.cpp in Sources */,
- DF46B7271381E27000D08723 /* dbase.cpp in Sources */,
- DF46B7281381E27000D08723 /* iniconfig.cpp in Sources */,
- DF46B7291381E27000D08723 /* init_v7.cpp in Sources */,
- DF46B72A1381E27000D08723 /* inter_inca2.cpp in Sources */,
- DF46B7461381E40500D08723 /* log.cpp in Sources */,
- DF46B74B1381E40F00D08723 /* modular-backend.cpp in Sources */,
- DF46B7561381E46700D08723 /* player_v2base.cpp in Sources */,
- DF46B7601381E4A400D08723 /* console.cpp in Sources */,
- DF46B7651381E4D400D08723 /* robot_decoder.cpp in Sources */,
- DF46B7691381E4E400D08723 /* vm_types.cpp in Sources */,
- DF46B7851381E54200D08723 /* dcl.cpp in Sources */,
- DF46B7861381E54200D08723 /* iff_container.cpp in Sources */,
- DF46B7871381E54200D08723 /* winexe_ne.cpp in Sources */,
- DF46B7881381E54200D08723 /* winexe_pe.cpp in Sources */,
- DF46B7891381E54200D08723 /* winexe.cpp in Sources */,
- DF46B7971381E58000D08723 /* png.cpp in Sources */,
- DF46B7981381E58000D08723 /* wincursor.cpp in Sources */,
- DF46B7A11381E5B500D08723 /* winfont.cpp in Sources */,
- DF46B7AB1381E5F100D08723 /* header.cpp in Sources */,
- DF46B7B61381E67800D08723 /* sdl-mutex.cpp in Sources */,
- DF46B7BF1381E6C000D08723 /* object.cpp in Sources */,
- DF46B7CA1381E72500D08723 /* console.cpp in Sources */,
- DF46B7D81381E7C600D08723 /* console.cpp in Sources */,
- DF46B83E1381F13500D08723 /* saveload_v7.cpp in Sources */,
- DF46B8461381F35500D08723 /* saveload_inca2.cpp in Sources */,
- DF46B84A1381F38700D08723 /* inter_v7.cpp in Sources */,
- DF46B84F1381F39E00D08723 /* console.cpp in Sources */,
- DF46B8541381F3B400D08723 /* console.cpp in Sources */,
- DF46B8661381F44E00D08723 /* dbopl.cpp in Sources */,
- DF46B8671381F44E00D08723 /* dosbox.cpp in Sources */,
- DF46B8681381F44E00D08723 /* mame.cpp in Sources */,
- DF46B8731381F4A200D08723 /* sdl-audiocd.cpp in Sources */,
- DF46B87F1381F4F200D08723 /* default-audiocd.cpp in Sources */,
- DF46B88B1381F5D800D08723 /* sdl-provider.cpp in Sources */,
- DF46B8941381F62B00D08723 /* adpcm.cpp in Sources */,
- DF46B89D1381F6C400D08723 /* null.cpp in Sources */,
- DFADEBB513820DF500C46364 /* maccursor.cpp in Sources */,
- DFADEBB913820E0C00C46364 /* posix-fs.cpp in Sources */,
- F92B4DD0139DD428000D1BF1 /* quicktime.cpp in Sources */,
- F92B4DD5139DD449000D1BF1 /* yuv_to_rgb.cpp in Sources */,
- F9946D9F139E1A560072D195 /* towns_midi.cpp in Sources */,
- F9946DA2139E1A560072D195 /* towns_pc98_plugins.cpp in Sources */,
- F9946DB7139E1A880072D195 /* freeverb.cpp in Sources */,
- F9946DBA139E1A880072D195 /* i386.cpp in Sources */,
- F9946DBD139E1A880072D195 /* mt32_file.cpp in Sources */,
- F9946DC0139E1A880072D195 /* part.cpp in Sources */,
- F9946DC3139E1A880072D195 /* partial.cpp in Sources */,
- F9946DC6139E1A880072D195 /* partialManager.cpp in Sources */,
- F9946DC9139E1A880072D195 /* synth.cpp in Sources */,
- F9946DCC139E1A880072D195 /* tables.cpp in Sources */,
- F9946DD8139E1AD30072D195 /* aac.cpp in Sources */,
- F9946DDB139E1AD30072D195 /* qdm2.cpp in Sources */,
- F9946DDE139E1AD30072D195 /* quicktime.cpp in Sources */,
- F9946DE5139E1B180072D195 /* posix-main.cpp in Sources */,
- F9946DE8139E1B180072D195 /* posix.cpp in Sources */,
- F9946DEE139E1B6F0072D195 /* downscaler.cpp in Sources */,
- F9946DF3139E1BA00072D195 /* console.cpp in Sources */,
- F9946DF9139E1BBF0072D195 /* sdl-mixer.cpp in Sources */,
- F9946E00139E1BEB0072D195 /* doublebuffersdl-mixer.cpp in Sources */,
- F9946E06139E1C3A0072D195 /* sdl-graphics.cpp in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXSourcesBuildPhase section */
-
-/* Begin XCBuildConfiguration section */
- 1D6058940D05DD3E006BFB54 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)";
- CODE_SIGN_IDENTITY = "iPhone Developer";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
- COMPRESS_PNG_FILES = NO;
- COPY_PHASE_STRIP = NO;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- FRAMEWORK_SEARCH_PATHS = (
- "$(inherited)",
- "\"$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"",
- );
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_ENABLE_CPP_EXCEPTIONS = NO;
- GCC_ENABLE_FIX_AND_CONTINUE = NO;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_PRECOMPILE_PREFIX_HEADER = NO;
- GCC_PREFIX_HEADER = "";
- GCC_PREPROCESSOR_DEFINITIONS = (
- IPHONE_OFFICIAL,
- IPHONE,
- POSIX,
- ENABLE_SCUMM,
- ENABLE_SCUMM_7_8,
- ENABLE_HE,
- ENABLE_AGI,
- ENABLE_AGOS,
- ENABLE_CINE,
- ENABLE_CRUISE,
- ENABLE_DRASCULA,
- ENABLE_GOB,
- ENABLE_GROOVIE,
- ENABLE_IGOR,
- ENABLE_KYRA,
- ENABLE_LURE,
- ENABLE_MADE,
- ENABLE_PARALLACTION,
- ENABLE_QUEEN,
- ENABLE_SAGA,
- ENABLE_IHNM,
- ENABLE_SCI,
- ENABLE_SKY,
- ENABLE_SWORD1,
- ENABLE_SWORD2,
- ENABLE_TEENAGENT,
- ENABLE_TINSEL,
- ENABLE_TOUCHE,
- ENABLE_TUCKER,
- USE_FLAC,
- USE_MAD,
- USE_TREMOR,
- USE_VORBIS,
- USE_ZLIB,
- USE_TREMOR,
- USE_TRANSLATION,
- );
- GCC_THUMB_SUPPORT = NO;
- GCC_UNROLL_LOOPS = YES;
- HEADER_SEARCH_PATHS = (
- ../../engines/,
- ../../,
- include/,
- );
- INFOPLIST_FILE = Info.plist;
- IPHONEOS_DEPLOYMENT_TARGET = 3.0;
- LIBRARY_SEARCH_PATHS = (
- "$(inherited)",
- "\"$(SRCROOT)/lib\"",
- );
- ONLY_ACTIVE_ARCH = YES;
- PREBINDING = NO;
- PRODUCT_NAME = ScummVM;
- PROVISIONING_PROFILE = "";
- "PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
- SDKROOT = iphoneos4.2;
- TARGETED_DEVICE_FAMILY = "1,2";
- VALID_ARCHS = "armv6 armv7";
- };
- name = Debug;
- };
- 1D6058950D05DD3E006BFB54 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)";
- CODE_SIGN_IDENTITY = "iPhone Developer";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
- COMPRESS_PNG_FILES = NO;
- COPY_PHASE_STRIP = YES;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- FRAMEWORK_SEARCH_PATHS = (
- "$(inherited)",
- "\"$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"",
- );
- GCC_ENABLE_CPP_EXCEPTIONS = NO;
- GCC_ENABLE_FIX_AND_CONTINUE = NO;
- GCC_OPTIMIZATION_LEVEL = 3;
- GCC_PRECOMPILE_PREFIX_HEADER = NO;
- GCC_PREFIX_HEADER = "";
- GCC_PREPROCESSOR_DEFINITIONS = (
- IPHONE_OFFICIAL,
- IPHONE,
- POSIX,
- ENABLE_SCUMM,
- ENABLE_SCUMM_7_8,
- ENABLE_HE,
- ENABLE_AGI,
- ENABLE_AGOS,
- ENABLE_CINE,
- ENABLE_CRUISE,
- ENABLE_DRASCULA,
- ENABLE_GOB,
- ENABLE_GROOVIE,
- ENABLE_IGOR,
- ENABLE_KYRA,
- ENABLE_LURE,
- ENABLE_MADE,
- ENABLE_PARALLACTION,
- ENABLE_QUEEN,
- ENABLE_SAGA,
- ENABLE_IHNM,
- ENABLE_SCI,
- ENABLE_SKY,
- ENABLE_SWORD1,
- ENABLE_SWORD2,
- ENABLE_TEENAGENT,
- ENABLE_TINSEL,
- ENABLE_TOUCHE,
- ENABLE_TUCKER,
- USE_FLAC,
- USE_MAD,
- USE_TREMOR,
- USE_VORBIS,
- USE_ZLIB,
- USE_TREMOR,
- USE_TRANSLATION,
- );
- GCC_THUMB_SUPPORT = NO;
- GCC_UNROLL_LOOPS = YES;
- HEADER_SEARCH_PATHS = (
- ../../engines/,
- ../../,
- include/,
- );
- INFOPLIST_FILE = Info.plist;
- IPHONEOS_DEPLOYMENT_TARGET = 3.0;
- LIBRARY_SEARCH_PATHS = (
- "$(inherited)",
- "\"$(SRCROOT)/lib\"",
- );
- ONLY_ACTIVE_ARCH = YES;
- PREBINDING = NO;
- PRODUCT_NAME = ScummVM;
- PROVISIONING_PROFILE = "";
- "PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
- SDKROOT = iphoneos4.2;
- TARGETED_DEVICE_FAMILY = "1,2";
- VALID_ARCHS = "armv6 armv7";
- WRAPPER_EXTENSION = app;
- };
- name = Release;
- };
- C01FCF4F08A954540054247B /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- ARCHS = "$(NATIVE_ARCH_ACTUAL)";
- CODE_SIGN_IDENTITY = "Don't Code Sign";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Don't Code Sign";
- FRAMEWORK_SEARCH_PATHS = "";
- GCC_C_LANGUAGE_STANDARD = c99;
- GCC_ENABLE_CPP_EXCEPTIONS = NO;
- GCC_ENABLE_CPP_RTTI = NO;
- GCC_INPUT_FILETYPE = automatic;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_PREPROCESSOR_DEFINITIONS = "";
- GCC_THUMB_SUPPORT = NO;
- GCC_USE_GCC3_PFE_SUPPORT = NO;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- HEADER_SEARCH_PATHS = (
- ../../engines/,
- ../../,
- );
- IPHONEOS_DEPLOYMENT_TARGET = 3.0;
- LIBRARY_SEARCH_PATHS = "";
- ONLY_ACTIVE_ARCH = YES;
- OTHER_CFLAGS = "";
- OTHER_LDFLAGS = "-lz";
- PREBINDING = NO;
- SDKROOT = "";
- TARGETED_DEVICE_FAMILY = "1,2";
- VALID_ARCHS = "i386 ppc ppc64 x86_64 armv6 armv7";
- WARNING_CFLAGS = "-Wno-multichar";
- };
- name = Debug;
- };
- C01FCF5008A954540054247B /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- ARCHS = "$(NATIVE_ARCH_ACTUAL)";
- CODE_SIGN_IDENTITY = "Don't Code Sign";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Don't Code Sign";
- FRAMEWORK_SEARCH_PATHS = "";
- GCC_C_LANGUAGE_STANDARD = c99;
- GCC_ENABLE_CPP_EXCEPTIONS = NO;
- GCC_ENABLE_CPP_RTTI = NO;
- GCC_ENABLE_EXCEPTIONS = NO;
- GCC_INPUT_FILETYPE = automatic;
- GCC_PREPROCESSOR_DEFINITIONS = "";
- GCC_THUMB_SUPPORT = NO;
- GCC_USE_GCC3_PFE_SUPPORT = NO;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- HEADER_SEARCH_PATHS = (
- ../../engines/,
- ../../,
- );
- IPHONEOS_DEPLOYMENT_TARGET = 3.0;
- LIBRARY_SEARCH_PATHS = "";
- ONLY_ACTIVE_ARCH = YES;
- OTHER_CFLAGS = "";
- OTHER_LDFLAGS = "";
- PREBINDING = NO;
- SDKROOT = "";
- TARGETED_DEVICE_FAMILY = "1,2";
- VALID_ARCHS = "i386 ppc ppc64 x86_64 armv6 armv7";
- WARNING_CFLAGS = "-Wno-multichar";
- };
- name = Release;
- };
- DF0942280F63CB26002D821E /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ARCHS = "$(ARCHS_STANDARD_64_BIT)";
- COMPRESS_PNG_FILES = NO;
- COPY_PHASE_STRIP = NO;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- FRAMEWORK_SEARCH_PATHS = "";
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_ENABLE_FIX_AND_CONTINUE = NO;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_PRECOMPILE_PREFIX_HEADER = NO;
- GCC_PREFIX_HEADER = "";
- GCC_PREPROCESSOR_DEFINITIONS = (
- MACOSX,
- SDL_BACKEND,
- POSIX,
- ENABLE_SCUMM,
- ENABLE_SCUMM_7_8,
- ENABLE_HE,
- ENABLE_AGI,
- ENABLE_AGOS,
- ENABLE_CINE,
- ENABLE_CRUISE,
- ENABLE_DRASCULA,
- ENABLE_GOB,
- ENABLE_GROOVIE,
- ENABLE_IGOR,
- ENABLE_KYRA,
- ENABLE_LURE,
- ENABLE_MADE,
- ENABLE_PARALLACTION,
- ENABLE_QUEEN,
- ENABLE_SAGA,
- ENABLE_IHNM,
- ENABLE_SCI,
- ENABLE_SKY,
- ENABLE_SWORD1,
- ENABLE_SWORD2,
- ENABLE_TEENAGENT,
- ENABLE_TINSEL,
- ENABLE_TOUCHE,
- ENABLE_TUCKER,
- USE_FLAC,
- USE_MAD,
- USE_VORBIS,
- USE_ZLIB,
- USE_TRANSLATION,
- );
- GCC_VERSION = "";
- HEADER_SEARCH_PATHS = (
- /opt/local/include/SDL,
- /opt/local/include,
- /sw/include/SDL,
- /sw/include,
- ../../engines/,
- ../../,
- );
- INFOPLIST_FILE = "$(SRCROOT)/../macosx/Info.plist";
- LIBRARY_SEARCH_PATHS = (
- /sw/lib,
- /opt/local/lib,
- "$(inherited)",
- );
- MACOSX_DEPLOYMENT_TARGET = 10.4;
- ONLY_ACTIVE_ARCH = YES;
- OTHER_CFLAGS = "";
- OTHER_LDFLAGS = (
- "-lSDLmain",
- "-logg",
- "-lvorbisfile",
- "-lvorbis",
- "-lmad",
- "-lFLAC",
- "-lSDL",
- "-lz",
- );
- PREBINDING = NO;
- PRODUCT_NAME = ScummVM;
- SDKROOT = "";
- VALID_ARCHS = "i386 ppc ppc64 x86_64";
- WARNING_CFLAGS = "-Wno-multichar";
- };
- name = Debug;
- };
- DF0942290F63CB26002D821E /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ARCHS = "$(ARCHS_STANDARD_64_BIT)";
- COMPRESS_PNG_FILES = NO;
- COPY_PHASE_STRIP = YES;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- FRAMEWORK_SEARCH_PATHS = "";
- GCC_ENABLE_FIX_AND_CONTINUE = NO;
- GCC_PRECOMPILE_PREFIX_HEADER = NO;
- GCC_PREFIX_HEADER = "";
- GCC_PREPROCESSOR_DEFINITIONS = (
- MACOSX,
- SDL_BACKEND,
- POSIX,
- ENABLE_SCUMM,
- ENABLE_SCUMM_7_8,
- ENABLE_HE,
- ENABLE_AGI,
- ENABLE_AGOS,
- ENABLE_CINE,
- ENABLE_CRUISE,
- ENABLE_DRASCULA,
- ENABLE_GOB,
- ENABLE_GROOVIE,
- ENABLE_IGOR,
- ENABLE_KYRA,
- ENABLE_LURE,
- ENABLE_MADE,
- ENABLE_PARALLACTION,
- ENABLE_QUEEN,
- ENABLE_SAGA,
- ENABLE_IHNM,
- ENABLE_SCI,
- ENABLE_SKY,
- ENABLE_SWORD1,
- ENABLE_SWORD2,
- ENABLE_TEENAGENT,
- ENABLE_TINSEL,
- ENABLE_TOUCHE,
- ENABLE_TUCKER,
- USE_FLAC,
- USE_MAD,
- USE_VORBIS,
- USE_ZLIB,
- USE_TRANSLATION,
- );
- GCC_VERSION = "";
- HEADER_SEARCH_PATHS = (
- /opt/local/include/SDL,
- /opt/local/include,
- /sw/include/SDL,
- /sw/include,
- ../../engines/,
- ../../,
- );
- INFOPLIST_FILE = "$(SRCROOT)/../macosx/Info.plist";
- LIBRARY_SEARCH_PATHS = (
- /sw/lib,
- /opt/local/lib,
- "$(inherited)",
- );
- MACOSX_DEPLOYMENT_TARGET = 10.4;
- ONLY_ACTIVE_ARCH = YES;
- OTHER_CFLAGS = "";
- OTHER_LDFLAGS = (
- "-lSDLmain",
- "-logg",
- "-lvorbisfile",
- "-lvorbis",
- "-lmad",
- "-lFLAC",
- "-lSDL",
- "-lz",
- );
- PREBINDING = NO;
- PRODUCT_NAME = ScummVM;
- SDKROOT = "";
- VALID_ARCHS = "i386 ppc ppc64 x86_64";
- WARNING_CFLAGS = "-Wno-multichar";
- WRAPPER_EXTENSION = app;
- };
- name = Release;
- };
- DFF95CC80FB22D5700A3EC78 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)";
- CODE_SIGN_IDENTITY = "iPhone Developer";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
- COMPRESS_PNG_FILES = NO;
- COPY_PHASE_STRIP = NO;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- FRAMEWORK_SEARCH_PATHS = "$(inherited)";
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_ENABLE_CPP_EXCEPTIONS = NO;
- GCC_ENABLE_FIX_AND_CONTINUE = NO;
- GCC_OPTIMIZATION_LEVEL = 3;
- GCC_PRECOMPILE_PREFIX_HEADER = NO;
- GCC_PREFIX_HEADER = "";
- GCC_THUMB_SUPPORT = NO;
- GCC_UNROLL_LOOPS = YES;
- HEADER_SEARCH_PATHS = (
- /opt/local/include/SDL,
- /opt/local/include,
- /sw/include/SDL,
- /sw/include,
- ../../engines/,
- ../../,
- );
- INFOPLIST_FILE = Info.plist;
- LIBRARY_SEARCH_PATHS = (
- /sw/lib,
- /opt/local/lib,
- "$(inherited)",
- );
- ONLY_ACTIVE_ARCH = NO;
- OTHER_LDFLAGS = (
- "-lSDLmain",
- "-logg",
- "-lvorbisfile",
- "-lvorbis",
- "-lmad",
- "-lFLAC",
- "-lSDL",
- "-lz",
- );
- PREBINDING = NO;
- PRODUCT_NAME = ScummVM;
- PROVISIONING_PROFILE = "EF590570-5FAC-4346-9071-D609DE2B28D8";
- "PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
- SDKROOT = iphoneos;
- VALID_ARCHS = "i386 x86_64";
- };
- name = Debug;
- };
- DFF95CC90FB22D5700A3EC78 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)";
- CODE_SIGN_IDENTITY = "iPhone Developer";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
- COMPRESS_PNG_FILES = NO;
- COPY_PHASE_STRIP = YES;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- FRAMEWORK_SEARCH_PATHS = "$(inherited)";
- GCC_ENABLE_CPP_EXCEPTIONS = NO;
- GCC_ENABLE_FIX_AND_CONTINUE = NO;
- GCC_OPTIMIZATION_LEVEL = 3;
- GCC_PRECOMPILE_PREFIX_HEADER = NO;
- GCC_PREFIX_HEADER = "";
- GCC_THUMB_SUPPORT = NO;
- GCC_UNROLL_LOOPS = YES;
- HEADER_SEARCH_PATHS = (
- /opt/local/include/SDL,
- /opt/local/include,
- /sw/include/SDL,
- /sw/include,
- ../../engines/,
- ../../,
- );
- INFOPLIST_FILE = Info.plist;
- LIBRARY_SEARCH_PATHS = (
- /sw/lib,
- /opt/local/lib,
- "$(inherited)",
- );
- ONLY_ACTIVE_ARCH = NO;
- OTHER_LDFLAGS = (
- "-lSDLmain",
- "-logg",
- "-lvorbisfile",
- "-lvorbis",
- "-lmad",
- "-lFLAC",
- "-lSDL",
- "-lz",
- );
- PREBINDING = NO;
- PRODUCT_NAME = ScummVM;
- PROVISIONING_PROFILE = "EF590570-5FAC-4346-9071-D609DE2B28D8";
- "PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
- SDKROOT = iphoneos;
- VALID_ARCHS = "i386 x86_64";
- WRAPPER_EXTENSION = app;
- };
- name = Release;
- };
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
- 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "ScummVM-iPhone" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 1D6058940D05DD3E006BFB54 /* Debug */,
- 1D6058950D05DD3E006BFB54 /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
- C01FCF4E08A954540054247B /* Build configuration list for PBXProject "scummvm" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- C01FCF4F08A954540054247B /* Debug */,
- C01FCF5008A954540054247B /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
- DF0942270F63CB26002D821E /* Build configuration list for PBXNativeTarget "ScummVM-OS X" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- DF0942280F63CB26002D821E /* Debug */,
- DF0942290F63CB26002D821E /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
- DFF95CC70FB22D5700A3EC78 /* Build configuration list for PBXNativeTarget "ScummVM-Simulator" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- DFF95CC80FB22D5700A3EC78 /* Debug */,
- DFF95CC90FB22D5700A3EC78 /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
-/* End XCConfigurationList section */
- };
- rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
-}
diff --git a/dists/macosx/Info.plist b/dists/macosx/Info.plist
index fff0e47668..fffb18056e 100644
--- a/dists/macosx/Info.plist
+++ b/dists/macosx/Info.plist
@@ -28,7 +28,7 @@
<key>CFBundleExecutable</key>
<string>scummvm</string>
<key>CFBundleGetInfoString</key>
- <string>1.8.0git, Copyright 2001-2014 The ScummVM Team</string>
+ <string>1.8.0git, Copyright 2001-2015 The ScummVM Team</string>
<key>CFBundleIconFile</key>
<string>scummvm.icns</string>
<key>CFBundleIdentifier</key>
@@ -46,7 +46,7 @@
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSHumanReadableCopyright</key>
- <string>Copyright 2001-2014 The ScummVM Team</string>
+ <string>Copyright 2001-2015 The ScummVM Team</string>
<key>SUFeedURL</key>
<string>http://www.scummvm.org/appcasts/macosx/release.xml</string>
<key>SUPublicDSAKeyFile</key>
diff --git a/dists/macosx/Info.plist.in b/dists/macosx/Info.plist.in
index 9ef1584440..7e91984f39 100644
--- a/dists/macosx/Info.plist.in
+++ b/dists/macosx/Info.plist.in
@@ -28,7 +28,7 @@
<key>CFBundleExecutable</key>
<string>scummvm</string>
<key>CFBundleGetInfoString</key>
- <string>@VERSION@, Copyright 2001-2014 The ScummVM Team</string>
+ <string>@VERSION@, Copyright 2001-2015 The ScummVM Team</string>
<key>CFBundleIconFile</key>
<string>scummvm.icns</string>
<key>CFBundleIdentifier</key>
@@ -46,7 +46,7 @@
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSHumanReadableCopyright</key>
- <string>Copyright 2001-2014 The ScummVM Team</string>
+ <string>Copyright 2001-2015 The ScummVM Team</string>
<key>SUFeedURL</key>
<string>http://www.scummvm.org/appcasts/macosx/release.xml</string>
<key>SUPublicDSAKeyFile</key>
diff --git a/dists/scummvm.rc b/dists/scummvm.rc
index def6ee49f7..2028a5bfd3 100644
--- a/dists/scummvm.rc
+++ b/dists/scummvm.rc
@@ -81,7 +81,7 @@ BEGIN
VALUE "FileDescription", "http://www.scummvm.org/\0"
VALUE "FileVersion", "1.8.0git\0"
VALUE "InternalName", "scummvm\0"
- VALUE "LegalCopyright", "Copyright © 2001-2014 The ScummVM Team\0"
+ VALUE "LegalCopyright", "Copyright © 2001-2015 The ScummVM Team\0"
VALUE "LegalTrademarks", "'SCUMM', and all SCUMM games are a TM of LucasArts. Simon The Sorcerer is a TM of AdventureSoft. Beneath a Steel Sky and Broken Sword are a TM of Revolution. Flight of the Amazon Queen is a TM of John Passfield and Steve Stamatiadis. \0"
VALUE "OriginalFilename", "scummvm.exe\0"
VALUE "ProductName", "ScummVM\0"
diff --git a/dists/scummvm.rc.in b/dists/scummvm.rc.in
index 401c0abb0d..3a619334d5 100644
--- a/dists/scummvm.rc.in
+++ b/dists/scummvm.rc.in
@@ -81,7 +81,7 @@ BEGIN
VALUE "FileDescription", "http://www.scummvm.org/\0"
VALUE "FileVersion", "@VERSION@\0"
VALUE "InternalName", "scummvm\0"
- VALUE "LegalCopyright", "Copyright © 2001-2014 The ScummVM Team\0"
+ VALUE "LegalCopyright", "Copyright © 2001-2015 The ScummVM Team\0"
VALUE "LegalTrademarks", "'SCUMM', and all SCUMM games are a TM of LucasArts. Simon The Sorcerer is a TM of AdventureSoft. Beneath a Steel Sky and Broken Sword are a TM of Revolution. Flight of the Amazon Queen is a TM of John Passfield and Steve Stamatiadis. \0"
VALUE "OriginalFilename", "scummvm.exe\0"
VALUE "ProductName", "ScummVM\0"
diff --git a/dists/win32/scummvm.nsi b/dists/win32/scummvm.nsi
index bdefad43da..a7e891acc2 100644
--- a/dists/win32/scummvm.nsi
+++ b/dists/win32/scummvm.nsi
@@ -76,7 +76,7 @@ Name ScummVM
!define COMPANY "ScummVM Team"
!define URL "http://scummvm.org/"
!define DESCRIPTION "ScummVM Installer. Look! A three headed monkey (TM)!"
-!define COPYRIGHT "Copyright © 2001-2014 The ScummVM Team"
+!define COPYRIGHT "Copyright © 2001-2015 The ScummVM Team"
#########################################################################################
# Installer configuration
diff --git a/dists/win32/scummvm.nsi.in b/dists/win32/scummvm.nsi.in
index b8ddc74a86..7a156fb7b4 100644
--- a/dists/win32/scummvm.nsi.in
+++ b/dists/win32/scummvm.nsi.in
@@ -76,7 +76,7 @@ Name ScummVM
!define COMPANY "ScummVM Team"
!define URL "http://scummvm.org/"
!define DESCRIPTION "ScummVM Installer. Look! A three headed monkey (TM)!"
-!define COPYRIGHT "Copyright © 2001-2014 The ScummVM Team"
+!define COPYRIGHT "Copyright © 2001-2015 The ScummVM Team"
#########################################################################################
# Installer configuration
diff --git a/doc/de/Liesmich b/doc/de/Liesmich
index 9190bb0852..a962ae6baa 100644
--- a/doc/de/Liesmich
+++ b/doc/de/Liesmich
@@ -1,4 +1,4 @@
-ScummVM - Liesmich-Datei
+ScummVM – Liesmich-Datei
------------------------------------------------------------------------
Für weitere Informationen, Kompatibilitätslisten, Einzelheiten zu Spenden, die
@@ -15,26 +15,27 @@ Inhaltsverzeichnis:
* 2.1 Fehler berichten
3.0) Unterstützte Spiele
* 3.1 Kopierschutz
- * 3.2 Hinweise zu Commodore64-Spielen
- * 3.3 Hinweise zu Maniac Mansion NES
- * 3.4 Hinweise zu Macintosh-Spielen
- * 3.5 Hinweise zu Spielen auf mehren CDs
- * 3.6 Hinweise zu The Curse of Monkey Island
- * 3.7 Hinweise zu Baphomets Fluch I und II
- * 3.8 Hinweise zu Beneath a Steel Sky
- * 3.9 Hinweise zu Flight of the Amazon Queen
- * 3.10 Hinweise zu Gobliiins
- * 3.11 Hinweise zu Inherit the Earth: Quest for the Orb (Macintosh)
- * 3.12 Hinweise zu Simon the Sorcerer 1 und 2
- * 3.13 Hinweise zu Floyd - Es gibt noch Helden
- * 3.14 Hinweise zu The Legend of Kyrandia
- * 3.15 Hinweise zum vorhersagenden Eingabedialog bei Sierras AGI-Spielen
- * 3.16 Hinweise zu Mickey's Space Adventure
- * 3.17 Hinweise zu Winnie the Pooh
- * 3.18 Hinweise zu Troll's Tale
- * 3.19 Hinweise zu DraÄi Historie
- * 3.20 Gleichzeitige Sprachausgabe und Untertitel in Sierra-SCI-Spielen
- * 3.21 Bekannte Probleme
+ * 3.2 Hinweise zu Day of the Tentacle
+ * 3.3 Hinweise zu Commodore-64-Spielen
+ * 3.4 Hinweise zu Maniac Mansion (NES)
+ * 3.5 Hinweise zu Macintosh-Spielen
+ * 3.6 Hinweise zu Spielen auf mehren CDs
+ * 3.7 Hinweise zu The Curse of Monkey Island
+ * 3.8 Hinweise zu Baphomets Fluch I und II
+ * 3.9 Hinweise zu Beneath a Steel Sky
+ * 3.10 Hinweise zu Flight of the Amazon Queen
+ * 3.11 Hinweise zu Gobliiins
+ * 3.12 Hinweise zu Inherit the Earth: Quest for the Orb (Macintosh)
+ * 3.13 Hinweise zu Simon the Sorcerer 1 und 2
+ * 3.14 Hinweise zu Floyd – Es gibt noch Helden
+ * 3.15 Hinweise zu The Legend of Kyrandia
+ * 3.16 Hinweise zum vorhersagenden Eingabedialog bei Sierras AGI-Spielen
+ * 3.17 Hinweise zu Mickey's Space Adventure
+ * 3.18 Hinweise zu Winnie the Pooh
+ * 3.19 Hinweise zu Troll's Tale
+ * 3.20 Hinweise zu DraÄi Historie
+ * 3.21 Gleichzeitige Sprachausgabe und Untertitel in Sierra-SCI-Spielen
+ * 3.22 Bekannte Probleme
4.0) Unterstützte Plattformen
5.0) ScummVM verwenden
* 5.1 Kommandozeilenoptionen
@@ -43,16 +44,16 @@ Inhaltsverzeichnis:
* 5.4 Globales Menü
* 5.5 Tastenkürzel
6.0) Spielstände
- * 6.1 Automatische Spielstände
+ * 6.1 Automatische Spielstand-Speicherung
* 6.2 Spielstände umwandeln
- * 6.3 Spielstände von Kommandozeile aus anzeigen/laden
+ * 6.3 Spielstände von der Kommandozeile aus anzeigen/laden
7.0) Musik und Sound
* 7.1 AdLib-Emulation
* 7.2 FluidSynth-MIDI-Emulation
* 7.3 MT-32-Emulation
* 7.4 MIDI-Emulation
* 7.5 Native MIDI-Unterstützung
- * 7.6 UNIX-eigene, ALSA- und IRIX' Sequenzer-Unterstützung
+ * 7.6 UNIX-eigene, ALSA- und Dmedia-Sequenzer-Unterstützung
* 7.7 TiMidity++-MIDI-Server-Unterstützung
* 7.8 Komprimierte Audio-Dateien verwenden (MP3, Ogg Vorbis, FLAC)
* 7.9 Ausgabefrequenzen
@@ -69,10 +70,10 @@ Inhaltsverzeichnis:
---- -------------
ScummVM ist ein Programm, welches es Ihnen ermöglicht, bestimmte klassische
Grafik-Adventure (unter anderem aus dem Point-and-Click-Bereich) zu spielen,
-vorausgesetzt, Sie sind im Besitz der Dateien des Spiels. Der Trick dabei ist:
-ScummVM ersetzt lediglich die Funktion der ausführbaren Dateien, die mit den
-Spielen kamen, was ermöglicht, diese Spiele auf Systemen zu spielen, für welche
-sie nie erstellt wurden!
+vorausgesetzt, Sie sind im Besitz der entsprechenden Spieldateien. Der Trick
+dabei ist: ScummVM ersetzt lediglich die Funktion der ausführbaren Dateien, die
+mit den Spielen mitgeliefert wurden, was ermöglicht, diese Spiele auf Systemen
+zu spielen, für welche sie nie erstellt wurden!
Ursprünglich wurde dieses Programm dafür entwickelt, um SCUMM-Spiele von
LucasArts auszuführen, wie beispielsweise Maniac Mansion, Monkey Island, Day of
@@ -82,15 +83,15 @@ Maniac Mansion), was das erste Spiel von LucasArts war, für welches LucasArts
dieses System entworfen hatte. Und viel später verlieh es seinen Namen an
ScummVM (wobei „VM“ für „Virtuelle Maschine“ steht).
-Mit der Zeit wurde Unterstützung für viele Nicht-SCUMM-Spiele hinzugefügt und
-ScummVM unterstützt nun auch viele AGI- und SCI-Spiele von Sierra (wie
+Mit der Zeit wurde Unterstützung für viele Nicht-SCUMM-Spiele hinzugefügt, so
+unterstützt ScummVM nun auch viele AGI- und SCI-Spiele von Sierra (wie
beispielsweise King's Quest 1-6, Space Quest 1-5, ...), Discworld 1 und 2, Simon
the Sorcerer 1 und 2, Beneath A Steel Sky, Lure of the Temptress, Baphomets
Fluch I und II, Flight of the Amazon Queen, Gobliiins 1-3, die Adventure-Reihe
The Legend of Kyrandia, viele der SCUMM-Spiele für Kinder von Humongous
Entertainment (einschließlich der Spiele von Fritzi Fisch und Töff-Töff) und
viele mehr. Sie können eine vollständige Liste mit Einzelheiten einsehen, welche
-Auskunft darüber gibt, welche Spiele unterstützt werden und wie gut. Gehen Sie
+Auskunft darüber gibt, welche Spiele wie gut unterstützt werden. Gehen Sie
hierfür auf die Kompatibilitätsseite. ScummVM wird fortlaufend verbessert, also
schauen Sie öfter einmal vorbei.
@@ -100,17 +101,17 @@ Mac OS X, ...), Spielekonsolen (Dreamcast, Nintendo DS & Wii, PS2, PSP, ...),
Smartphones (Android, iPhone, PocketPC, Symbian ...) und einige weitere.
Zurzeit befindet sich ScummVM immer noch stark in der Entwicklung. Seien Sie
-sich bewusst, dass wir zwar versuchen, dass viele Spiele mit wenigen erheblichen
-Fehlern durchgespielt werden können, aber es dennoch zu Abstürzen kommen kann
-und wir keine Gewähr übernehmen. Davon abgesehen: Einige Spiele werden seit
-längerer Zeit unterstützt und sollten in jeder neusten stabilen veröffentlichten
-Version ohne größere Probleme laufen. Sie können sich einen Eindruck davon
-verschaffen, wie gut jedes Spiel unter ScummVM läuft, indem Sie auf die
-Kompatibilitätsseite schauen. Wenn Sie sich ein wenig im Internet umsehen,
-können Sie feststellen, dass ScummVM sogar kommerziell genutzt wird, um einige
-der unterstützen Spiele für moderne Plattformen wiederzuveröffentlichen. Dies
-zeigt, dass mehrere Firmen mit der Qualität der Software zufrieden sind und wie
-gut einige der Spiele mit Hilfe des Programms laufen.
+sich bewusst, dass wir zwar versuchen, viele Spiele ohne größere Probleme
+spielbar zu machen – dennoch kann es zu Abstürzen kommen und wir übernehmen
+keinerlei Gewähr. Davon abgesehen: Einige Spiele werden seit längerer Zeit
+unterstützt und sollten in jeder neusten stabilen veröffentlichten Version ohne
+größere Probleme laufen. Sie können sich einen Eindruck davon verschaffen, wie
+gut jedes Spiel unter ScummVM läuft, indem Sie auf die Kompatibilitätsseite
+schauen. Wenn Sie sich ein wenig im Internet umsehen, können Sie feststellen,
+dass ScummVM sogar kommerziell genutzt wird, um einige der unterstützen Spiele
+für moderne Plattformen wiederzuveröffentlichen. Dies zeigt, dass mehrere Firmen
+mit der Qualität der Software zufrieden sind und wie gut einige der Spiele mit
+Hilfe des Programms laufen.
Wenn Ihnen ScummVM gefällt, können Sie uns gerne Geld spenden, indem Sie auf die
PayPal-Schaltfläche auf der ScummVM-Website klicken. Dies hilft uns dabei,
@@ -140,12 +141,12 @@ jedes Spiel ein eigenes Verzeichnis zu verwenden).
Sollte an diesem Punkt ScummVM auf Englisch statt auf Deutsch erscheinen, gehen
Sie wie folgt vor, um die Spracheinstellung zu ändern:
--Klicken Sie auf „Options“.
--Klicken Sie auf den rechten Pfeil in der Reiterleiste und wählen den Reiter
+- Klicken Sie auf „Options“.
+- Klicken Sie auf den rechten Pfeil in der Reiterleiste und wählen den Reiter
„Misc“ aus.
--Wählen Sie im Feld „GUI Language“ „Deutsch“ aus und klicken auf „OK“.
--Bestätigen Sie die erscheinende Nachricht, klicken auf „Quit“, um ScummVM zu
- beenden, und starten dann das Programm erneut.
+- Wählen Sie im Feld „GUI Language“ „Deutsch“ aus und klicken auf „OK“.
+- Bestätigen Sie die erscheinende Nachricht, klicken auf „Quit“, um ScummVM zu
+ beenden, und starten dann das Programm erneut.
Nun klicken Sie auf „Spiel hinzufügen“, wählen das Verzeichnis mit den Dateien
des Spiels aus (versuchen Sie nicht, die Dateien des Spiels selbst auszuwählen!)
@@ -165,10 +166,10 @@ hinzugefügt haben, in der Liste angezeigt. Sie können somit direkt zu Schritt
Tipp: Wenn Sie mehrere Spiele auf einmal hinzufügen möchten, drücken Sie die
Umschalt-Taste (Shift), bevor Sie auf „Spiel hinzufügen“ klicken. Diese
-Schaltfläche wird somit ihren Text zu „Durchsuchen“ umändern und wenn Sie dann
-auf diese klicken, werden Sie auch dazu aufgefordert, ein Verzeichnis
-auszuwählen, nur dieses Mal wird ScummVM alle Unterverzeichnisse automatisch
-nach unterstützen Spielen durchsuchen.
+Schaltfläche wird dann ihren Text zu „Durchsuchen“ ändern. Wenn Sie dann auf
+diese klicken, werden Sie auch dazu aufgefordert, ein Verzeichnis auszuwählen,
+nur dieses Mal wird ScummVM alle Unterverzeichnisse automatisch nach
+unterstützen Spielen durchsuchen.
2.0) Kontakt:
@@ -189,8 +190,8 @@ sollte.
---- -----------------
Um einen Fehler zu berichten, erstellen Sie bitte ein SourceForge-Konto und
folgen Sie dem Link „Bug Tracker“ auf der ScummVM-Website. Bitte stellen Sie
-sicher, dass sich der Bug wiedererzeugen lässt und immer noch in der neusten
-Version von Git oder des Daily Builds auftritt. Bitte sehen Sie auch auf der
+sicher, dass sich der Bug reproduzieren lässt und immer noch in der aktuellen
+Git-Version oder im Daily Build auftritt. Bitte sehen Sie auch auf der
Kompatibilitätsliste der ScummVM-Website für dieses Spiel nach, um
sicherzustellen, dass das Problem nicht bereits bekannt ist:
@@ -209,22 +210,22 @@ Bitte liefern Sie folgende Informationen:
- Version des Spiels (Version mit Sprachausgabe [Talkie],
Diskettenversion, ...)
- Plattform und gegebenenfalls Compiler (Win32, Linux, FreeBSD, ...)
- - Fügen Sie - wenn möglich - einen Speicherstand hinzu.
+ - Fügen Sie – wenn möglich – einen Speicherstand hinzu.
- Wenn dieser Fehler erst seit kurzem Auftritt, teilen Sie bitte die letzte
Version ohne den Fehler mit und die erste Version mit diesem Fehler.
Auf diese Weise können wir diesen schneller beseitigen, indem wir die
vorgenommen Veränderungen einsehen.
-Zum Schluss möchten wir Sie noch bitten, jeden Punkt einzeln zu berichten. Bitte
-senden Sie nicht mehrere Punkte mit demselben Ticket ein, ansonsten wird es
+Zum Schluss möchten wir Sie noch bitten, jeden Fehler einzeln zu melden. Bitte
+senden Sie nicht mehrere Fehler in demselben Ticket ein, ansonsten wird es
schwierig, den Status jedes einzelnen Fehlers zu verfolgen. Denken Sie bitte
auch daran, dass alle Fehlerberichte in Englisch verfasst sein müssen.
3.0) Unterstützte Spiele:
---- --------------------
-Im Moment gelten folgende Spiele als funktionsfähig gemeldet und sollten bis zum
-Ende spielbar sein:
+Im Moment gelten folgende Spiele als funktionsfähig und sollten bis zum Ende
+spielbar sein:
SCUMM-Spiele von LucasArts:
Maniac Mansion [maniac]
@@ -240,7 +241,7 @@ SCUMM-Spiele von LucasArts:
The Dig [dig]
The Curse of Monkey Island [comi]
-AGI-Spiele von Sierra:
+AGI- und preAGI-Spiele von Sierra:
The Black Cauldron [bc]
Gold Rush! [goldrush]
King's Quest I [kq1]
@@ -256,7 +257,10 @@ AGI-Spiele von Sierra:
Angel [pq1]
Space Quest I: The Sarien Encounter [sq1]
Space Quest II: Vohaul's Revenge [sq2]
- Erstellte Spiele von Fans [agi-fanmade]
+ Von Fans erstellte Spiele [agi-fanmade]
+ Mickey's Space Adventure [mickey]
+ Troll's Tale [troll]
+ Winnie the Pooh in the Hundred Acre Wood [winnie]
AGOS-Spiele von Adventuresoft/Horrorsoft:
Elvira - Mistress of the Dark [elvira1]
@@ -275,6 +279,13 @@ AGOS-Spiele von Adventuresoft/Horrorsoft:
- Swampy Adventures [swampy]
Floyd - Es gibt noch Helden [feeble]
+Spiele von Animation Magic:
+ Darby der Drache [darby]
+ Gregory and the Hot Air Balloon [gregory]
+ Magic Tales: Liam Finds a Story [liam]
+ The Princess and the Crab [princess]
+ Sleeping Cub's Test of Courage [sleepingcub]
+
GOB-Spiele von Coktel Vision:
Bambou le sauveur de la jungle [bambou]
Bargon Attack [bargon]
@@ -289,6 +300,22 @@ GOB-Spiele von Coktel Vision:
Woodruff and the Schnibble of Azimuth [woodruff]
Ween: The Prophecy [ween]
+Living-Books-Spiele von Random House/Brøderbund:
+ Aesop's Fables: The Tortoise and the Hare [tortoise]
+ Arthur's Birthday [arthurbday]
+ Arthur's Teacher Trouble [arthur]
+ Dr. Seuss's ABC [seussabc]
+ Green Eggs and Ham [greeneggs]
+ Harry and the Haunted House [harryhh]
+ Just Grandma and Me [grandma]
+ Little Monster at School [lilmonster]
+ Ruff's Bone [ruff]
+ Sheila Rae, the Brave [sheila]
+ Stellaluna [stellaluna]
+ The Berenstain Bears Get in a Fight [bearfight]
+ The Berenstain Bears in the Dark [beardark]
+ The New Kid on the Block [newkid]
+
MADE-Spiele von Activision:
Leather Goddesses of Phobos 2 [lgop2]
Return to Zork [rtz]
@@ -296,35 +323,105 @@ MADE-Spiele von Activision:
The Manhole [manhole]
Andere Spiele:
- Beneath a Steel Sky [sky]
+ 3 Skulls of the Toltecs [toltecs]
Baphomets Fluch [sword1]
Baphomets Fluch II:
Die Spiegel der Finsternis [sword2]
+ Beneath a Steel Sky [sky]
+ Blue Force [blueforce]
Cruise for a Corpse [cruise]
Discworld [dw]
Discworld 2: Vermutlich vermisst [dw2]
DraÄi Historie [draci]
Drascula: The Vampire Strikes Back [drascula]
+ DreamWeb [dreamweb]
+ Erben der Erde: Die große Suche [ite]
Eye of the Beholder [eob]
Eye of the Beholder II: The Legend of
Darkmoon [eob2]
Flight of the Amazon Queen [queen]
Future Wars [fw]
- Erben der Erde: Die große Suche [ite]
- Nippon Safes Inc. [nippon]
+ Hopkins FBI [hopkins]
+ Hugo's House of Horrors [hugo1]
+ Hugo 2: Whodunit? [hugo2]
+ Hugo 3: Jungle Doom [hugo3]
+ I Have No Mouth, and I Must Scream [ihnm]
Lands of Lore: The Throne of Chaos [lol]
+ Lure of the Temptress [lure]
+ Mortville Manor [morteville]
+ Nippon Safes Inc. [nippon]
+ Ringworld: Revenge of the Patriarch [ringworld]
+ Return to Ringworld [ringworld2]
+ Sfinx [sfinx]
+ Soltys [soltys]
+ TeenAgent [teenagent]
+ The 7th Guest [t7g]
The Journeyman Project: Pegasus Prime [pegasus]
The Legend of Kyrandia [kyra1]
The Legend of Kyrandia: The Hand of Fate [kyra2]
The Legend of Kyrandia: Malcolm's Revenge [kyra3]
+ The Neverhood [neverhood]
+ Tony Tough and the Night of Roasted Moths [tony]
+ Toonstruck [toon]
Touché: Die Abenteuer des fünften
Musketiers [touche]
+ Voyeur [voyeur]
+
+SCI-Spiele von Sierra Entertainment:
+ Codename: ICEMAN [iceman]
+ Conquests of Camelot [camelot]
+ Conquests of the Longbow [longbow]
+ Das Schloß von Dr. Brain [castlebrain]
+ EcoQuest: Die Suche nach Cetus [ecoquest]
+ EcoQuest 2: Lost Secret of the Rainforest [ecoquest2]
+ Freddy Pharkas: Cowboy-Apotheker [freddypharkas]
+ Hoyle's Book of Games 1 [hoyle1]
+ Hoyle's Book of Games 2 [hoyle2]
+ Hoyle's Book of Games 3 [hoyle3]
+ Hoyle Classic Card Games [hoyle4]
+ Jones in the Fast Lane [jones]
+ King's Quest I [kq1sci]
+ King's Quest IV [kq4sci]
+ King's Quest V [kq5]
+ King's Quest VI [kq6]
+ Laura Bow: The Colonel's Bequest [laurabow]
+ Laura Bow 2: Der Dolch des Amon Ra [laurabow2]
+ Leisure Suit Larry 1 [lsl1sci]
+ Leisure Suit Larry 2 [lsl2]
+ Leisure Suit Larry 3 [lsl3]
+ Leisure Suit Larry 5 [lsl5]
+ Leisure Suit Larry 6 [lsl6]
+ Mixed-up Fairy Tales [fairytales]
+ Mixed-up Mother Goose [mothergoose]
+ Pepper's Adventures in Time [pepper]
+ Police Quest 1 [pq1sci]
+ Police Quest 2 [pq2]
+ Police Quest 3 [pq3]
+ Quest for Glory 1/Hero's Quest [qfg1]
+ Quest for Glory 1 [qfg1vga]
+ Quest for Glory 2 [qfg2]
+ Quest for Glory 3 [qfg3]
+ Slater & Charlie Go Camping [slater]
+ Space Quest I [sq1sci]
+ Space Quest III [sq3]
+ Space Quest IV [sq4]
+ Space Quest V [sq5]
+ The Island of Dr. Brain [islandbrain]
+
+Wintermute-Spiel von Deirdra Kiai Productions:
+ Chivalry is Not Dead [chivalry]
+
+ZVISION-Spiele von Activision:
+ Zork Nemesis: The Forbidden Lands [znemesis]
+ Zork: Grand Inquisitor [zgi]
SCUMM-Spiele von Humongous Entertainment:
Backyard Baseball [baseball]
Backyard Baseball 2001 [baseball2001]
+ Backyard Football 2002 [football2002]
Backyard Baseball 2003 [baseball2003]
Backyard Football [football]
+ Bear Stormin' [brstorm]
Big Thinkers First Grade [thinker1]
Big Thinkers Kindergarten [thinkerk]
Blue's 123 Time Activities [Blues123Time]
@@ -347,6 +444,7 @@ SCUMM-Spiele von Humongous Entertainment:
Let's Explore the Airport with Buzzy [airport]
Let's Explore the Farm with Buzzy [farm]
Let's Explore the Jungle with Buzzy [jungle]
+ Pajama Sam: Games to Play on Any Day [pjgames]
Pyjama Pit: Keine Angst im Dunkeln [pajama]
Pyjama Sam: Donner und Blitz
machen mir nix [pajama2]
@@ -369,22 +467,6 @@ SCUMM-Spiele von Humongous Entertainment:
SPY Fox in Cheese Chase [chase]
SPY Fox in Hold the Mustard [mustard]
-Spiele von Living Books:
- Aesop's Fables: The Tortoise and the Hare [tortoise]
- Arthur's Birthday [arthurbday]
- Arthur's Teacher Trouble [arthur]
- Dr. Seuss's ABC [seussabc]
- Green Eggs and Ham [greeneggs]
- Harry and the Haunted House [harryhh]
- Just Grandma and Me [grandma]
- Little Monster at School [lilmonster]
- Ruff's Bone [ruff]
- Sheila Rae, the Brave [sheila]
- Stellaluna [stellaluna]
- The Berenstain Bears Get in a Fight [bearfight]
- The Berenstain Bears in the Dark [beardark]
- The New Kid on the Block [newkid]
-
Die folgenden Spiele sollten geladen werden, sind aber noch nicht vollständig
spielbar. Spielen erfolgt auf eigenes Risiko. Bitte reichen Sie für diese Spiele
keine Fehlerberichte ein.
@@ -392,17 +474,15 @@ Wenn Sie über den neusten Stand bezüglich der Kompatibilität des Spiels erfah
möchten, besuchen Sie unsere Website und schauen Sie in der Kompatibilitätsliste
nach.
- Backyard Football 2002 [football2002]
Backyard Soccer [soccer]
Backyard Soccer MLS [soccermls]
Backyard Soccer 2004 [soccer2004]
Blue's Treasure Hunt [BluesTreasureHunt]
- Pajama Sam: Games to Play on Any Day [pjgames]
Die folgenden Spiele basieren auf der SCUMM-Engine, werden aber (noch) nicht von
ScummVM unterstützt:
- Andere Spiele von Humongous Entertainment
+ Moonbase Commander
Seien Sie sich bitte bewusst, dass die Engines („Motoren“ der Spiele) Fehler
enthalten können und manche Funktionen möglicherweise fehlen, was es unmöglich
@@ -451,8 +531,31 @@ ScummVM wird den Kopierschutz in folgenden Spielen überspringen:
* Zak McKracken and the Alien Mindbenders
-3.2) Hinweise zu Commodore64-Spielen:
----- --------------------------------
+3.2) Hinweise zu Day of the Tentacle
+---- -------------------------------
+
+An einem bestimmten Punkt im Spiel kommen Sie an einem Computer vorbei, der
+Ihnen erlaubt, das originale Maniac Mansion zu spielen. ScummVM unterstützt
+dies, jedoch gilt Folgendes zu beachten:
+
+ScummVM wird die Konfigurationsdatei nach einem Spiel durchsuchen, welches sich
+im Unterordner "Maniac" innerhalb des "Day of the Tentacle"-Ordners befindet.
+Wenn Sie die Spieldateien von der CD-Version kopiert haben, sollte dies bereits
+der Fall sein, Sie müssen das Spiel jedoch ebenfalls zu ScummVM hinzufügen.
+
+Um zu Day of the Tentacle zurückzukehren, drücken Sie F5 und wählen Sie „Zurück
+zum Hauptmenü“.
+
+Dies bedeutet, dass Sie theoretisch jedes Spiel als Easter Egg verwenden
+könnten. Es gibt eine "geheime" Konfigurationseinstellung namens "easter_egg",
+mit welcher Sie die ID des Spiels, welches als Easter-Egg gestartet werden soll,
+festlegen können. Jedoch erlauben nicht alle Spiele die Rückkehr zum Hauptmenü.
+Es ist nicht empfehlenswert, Day of the Tentacle selbst als Easter-Egg-Spiel
+festzulegen.
+
+
+3.3) Hinweise zu Commodore-64-Spielen:
+---- ---------------------------------
Sowohl Maniac Mansion als auch Zak McKracken laufen, aber Maniac Mansion ist
noch nicht spielbar. Benennen Sie einfach die D64-Datenträger um in
„maniac1.d64“ und „maniac2.d64“ und entsprechend „zak1.d64“ und „zak2.d64“, dann
@@ -461,13 +564,13 @@ das richtige Verzeichnis zeigen.
Alternativ können Sie „extract_mm_c64“ aus dem Tools-Paket verwenden, um die
Spieldateien zu extrahieren. Dann wird das Spiel jedoch nicht einwandfrei von
-ScummVM automatisch erkannt und Sie müssen sicherstellen, dass Commodore64 als
+ScummVM automatisch erkannt und Sie müssen sicherstellen, dass Commodore 64 als
Plattform eingestellt ist. Wir empfehlen, auf die viel einfachere Methode
zurückzugreifen, die im vorherigen Absatz beschrieben ist.
-3.3) Hinweise zu Maniac Mansion NES:
----- -------------------------------
+3.4) Hinweise zu Maniac Mansion (NES):
+---- ---------------------------------
Unterstützte Versionen sind Deutsch (G) [G=German], Englisch GB (E), Französisch
(F), Italienisch (I), Schwedisch (SW) und Englisch US (U). ScummVM benötigt nur
den PRG-Bereich und nicht die gesamte ROM-Datei, um das Spiel laufen zu lassen.
@@ -496,7 +599,7 @@ extrahieren. Um dies zu tun, verwenden Sie das Dienstprogramm „extract_mm_nesâ
aus dem Tools-Paket.
-3.4) Hinweise zu Macintosh-Spielen:
+3.5) Hinweise zu Macintosh-Spielen:
---- ------------------------------
Alle auf SCUMM basierenden Adventures von Lucasarts, mit Ausnahme von COMI,
existieren auch als Versionen für den Macintosh. ScummVM kann die meisten
@@ -526,7 +629,7 @@ Festplatte kopieren können, lesen Sie:
http://wiki.scummvm.org/index.php/HOWTO-Mac_Games
-3.5) Hinweise zu Spielen auf mehren CDs:
+3.6) Hinweise zu Spielen auf mehren CDs:
---- -----------------------------------
Allgemein kann ScummVM nicht sehr gut mit Spielen auf mehreren CDs umgehen. Das
liegt daran, dass ScummVM annimmt, alles von einem Spiel in einem Verzeichnis
@@ -543,7 +646,7 @@ vorkommt, ist es normalerweise egal, welche sie in das Verzeichnis
hineinkopieren.
-3.6) Hinweise zu The Curse of Monkey Island:
+3.7) Hinweise zu The Curse of Monkey Island:
---- ---------------------------------------
Für dieses Spiel benötigen Sie die Dateien comi.la0, comi.la1 und comi.la2. Die
Datei comi.la0 kann auf beiden CDs vorgefunden werden, ist aber auf beiden
@@ -555,7 +658,7 @@ dieser Dateien lassen sich auf beiden CDs vorfinden, jedoch sind sie auch in
diesem Fall identisch.
-3.7) Hinweise zu Baphomets Fluch I und II:
+3.8) Hinweise zu Baphomets Fluch I und II:
---- -------------------------------------
Die Anweisungen für die Spiele Baphomets Fluch I und II sind für die
ausverkauften Software-Versionen, bei welchen sich jedes Spiel auf je zwei CDs
@@ -564,7 +667,7 @@ für diese Spiele erlangte. Wir hoffen, dass sie allgemein ausreichend
ausführlich sind, um für andere Ausgaben genauso hilfreich zu sein.
-3.7.1) Zwischensequenzen von Baphomets Fluch I und II:
+3.8.1) Zwischensequenzen von Baphomets Fluch I und II:
------ -----------------------------------------------
Die Zwischensequenzen für Baphomets Fluch I und II haben eine kleine Geschichte
(schauen Sie im nächsten Abschnitt, wenn Sie interessiert sind), aber im Großen
@@ -610,7 +713,7 @@ funktioniert momentan nicht bei der Verwendung von PlayStation-Videos.
Arbeit notwendig.)
-3.7.2) Zwischensequenzen von Baphomets Fluch I und II im Rückblick:
+3.8.2) Zwischensequenzen von Baphomets Fluch I und II im Rückblick:
------ ------------------------------------------------------------
Die Originalausgaben von Baphomets Fluch I und II verwendeten das
Smacker™-Format der RAD Game Tools. Da RAD uns nicht die ältere Ur-Version
@@ -623,7 +726,7 @@ nie die alleinige Lösung für eine stabile Veröffentlichung.
In ScummVM 0.6.0 verwendeten wir MPEG, das einen zumutbaren Kompromiss zwischen
Größe und Qualität bot. In ScummVM 0.10.0 wurde dies durch DXA abgelöst (das
-ursprünglich für Adventure Softs „Floyd - Es gibt noch Helden“ hinzugefügt
+ursprünglich für Adventure Softs „Floyd – Es gibt noch Helden“ hinzugefügt
wurde). Dies gab uns die Möglichkeit, die Zwischensequenzen mit genau derselben
Qualität wie im Original anzubieten, zu dem Preis, dass die Dateien größer
waren.
@@ -636,7 +739,7 @@ Sache, da das Entschlüsseln von MPEG-Filmen mit vielen Schwierigkeiten verbunde
war und diese ohnehin nicht so gut aussahen wie Smacker- und DXA-Versionen.
-3.7.3) Baphomets Fluch:
+3.8.3) Baphomets Fluch:
------ ----------------
Für dieses Spiel benötigen Sie die Dateien aus dem Verzeichnis clusters von
beiden CDs. Für die Windows- und Macintosh-Versionen benötigen Sie auch die
@@ -653,7 +756,7 @@ Unterschied macht. Die PlayStation-Version erfordert die Dateien tunes.dat und
tunes.tab.
-3.7.4) Baphomets Fluch II:
+3.8.4) Baphomets Fluch II:
------ -------------------
Für dieses Spiel benötigen Sie die Dateien aus dem Verzeichnis clusters von
beiden CDs. (Ein paar von ihnen sind streng genommen eigentlich nicht notwendig,
@@ -668,7 +771,7 @@ Zusätzlich brauchen Sie die Datei cd.inf und optional die Datei startup.inf aus
dem Verzeichnis sword2 von CD 1.
-3.8) Hinweise zu Beneath a Steel Sky:
+3.9) Hinweise zu Beneath a Steel Sky:
---- --------------------------------
Beginnend mit ScummVM 0.8.0 benötigen Sie die zusätzliche Datei „SKY.CPT“, um
Beneath a Steel Sky laufen lassen.
@@ -679,8 +782,8 @@ SKY.DSK) ablegen, in einem Extrapfad oder im Verzeichnis, in dem sich Ihre
ausführbare ScummVM-Datei befindet.
-3.9) Hinweise zu Flight of the Amazon Queen:
----- ---------------------------------------
+3.10) Hinweise zu Flight of the Amazon Queen:
+----- ---------------------------------------
Um eine Nicht-Freeware-Version von Flight of the Amazon Queen zu verwenden (von
einer Original-CD), müssen Sie die Datei „queen.tbl“ (erhältlich von der Seite
„Downloads“ auf unserer Website) entweder im Verzeichnis mit der Spieldatei
@@ -694,7 +797,7 @@ Datei „queen.tbl“ zu lösen. Dieses Tool kann auch die Sprachausgabe und
Geräusch-Effekte mittels MP3, Ogg Vorbis oder FLAC komprimieren.
-3.10) Hinweise zu Gobliiins:
+3.11) Hinweise zu Gobliiins:
----- ----------------------
Die CD-Versionen der Gobliiins-Serie enthalten einen großen Audio-Titel, den Sie
extrahieren müssen (siehe Abschnitt über die Verwendung komprimierter
@@ -704,11 +807,11 @@ Sprachausgabe ist auch in diesem Titel und ihre Lautstärke wird deshalb ebenso
über die Musiklautstärke-Regelung geändert.
-3.11) Hinweise zu Inherit the Earth: Quest for the Orb (Macintosh):
+3.12) Hinweise zu Inherit the Earth: Quest for the Orb (Macintosh):
----- -------------------------------------------------------------
-Um die Neuausgabe des Spiels für Mac OS X von Wyrmkeep laufen zu lassen, müssen
-Sie die Daten von der CD auf die Festplatte kopieren. Wenn Sie an einem PC
-arbeiten, lesen Sie hierfür:
+Um die Wiederveröffentlichung des Spiels für Mac OS X von Wyrmkeep laufen zu
+lassen, müssen Sie die Daten von der CD auf die Festplatte kopieren. Wenn Sie an
+einem PC arbeiten, lesen Sie hierfür:
http://wiki.scummvm.org/index.php/HOWTO-Mac_Games
@@ -725,16 +828,16 @@ kopieren, da sie sowohl Ressourcen- als auch Datenverzweigungen beinhalten
sollten. Kopieren Sie alle „ITE *“-Dateien.
-3.12) Hinweise zu Simon the Sorcerer 1 und 2:
+3.13) Hinweise zu Simon the Sorcerer 1 und 2:
----- ---------------------------------------
Wenn Sie die Doppel-Version von Simon the Sorcerer 1 oder 2 auf CD haben, finden
Sie die Windows-Version im Hauptverzeichnis der CD und die DOS-Version im
DOS-Verzeichnis der CD.
-3.13) Hinweise zu Floyd - Es gibt noch Helden:
+3.14) Hinweise zu Floyd – Es gibt noch Helden:
----- ----------------------------------------
-Wenn Sie die Windows-Version von Floyd - Es gibt noch Helden haben, sind einige
+Wenn Sie die Windows-Version von Floyd – Es gibt noch Helden haben, sind einige
Dinge zu beachten.
Viele notwendige Dateien für das Spiel sind in einer InstallShield-Datei namens
@@ -751,7 +854,7 @@ voices.wav von CD3 in voices3.wav
voices.wav von CD4 in voices4.wav
-3.14) Hinweise zu The Legend of Kyrandia:
+3.15) Hinweise zu The Legend of Kyrandia:
----- -----------------------------------
Um The Legend of Kyrandia unter ScummVM laufen zu lassen, benötigen Sie die
Datei „kyra.dat“. Die Datei sollte immer in offiziellen ScummVM-Paketen
@@ -762,7 +865,7 @@ eingebettet sein sollte. Also müssen Sie sich nur diese besorgen, wenn sich
ScummVM darüber beschwert, dass diese Datei fehlt.
-3.15) Hinweise zum vorhersagenden Eingabedialog bei Sierras AGI-Spielen:
+3.16) Hinweise zum vorhersagenden Eingabedialog bei Sierras AGI-Spielen:
----- ------------------------------------------------------------------
Der vorhersagende Eingabedialog ist ein ScummVM-Hilfsmittel, um die englischen
Spiele der AGI-Engine (die offensichtlich Kommandozeilen-Eingabe erfordern) auf
@@ -821,7 +924,7 @@ Ziffernblock zugewiesen wurde. Ebenso können die Schaltflächen mittels der
Pfeiltasten und der Eingabetaste gesteuert werden.
-3.16) Hinweise zu Mickey's Space Adventure:
+3.17) Hinweise zu Mickey's Space Adventure:
----- -------------------------------------
Um Mickey's Space Adventure unter ScummVM laufen zu lassen, benötigen Sie die
originale EXE-Datei des Spiels (mickey.exe) sowie die Spieldateien.
@@ -836,7 +939,7 @@ Ort zu wechseln, ähnlich wie in vielen Adventures, was einfacher und viel
unkomplizierter ist, als sich mit dem Menü umherzubewegen.
-3.17) Hinweise zu Winnie the Pooh:
+3.18) Hinweise zu Winnie the Pooh:
----- ----------------------------
Es ist möglich, Spielstände vom Original-Interpreter des Spiels in ScummVM zu
importieren.
@@ -851,14 +954,14 @@ Ort zu wechseln, ähnlich wie in vielen Adventures, was einfacher und viel
unkomplizierter ist, als sich mit dem Menü umherzubewegen.
-3.18) Hinweise zu Troll's Tale:
+3.19) Hinweise zu Troll's Tale:
----- -------------------------
Das Originalspiel wurde auf einer PC-Boot-Diskette ausgeliefert, weshalb es
notwendig ist, die Inhalte dieser Diskette in einer Abbild-Datei auszugeben und
diese „troll.img“ zu nennen, um das Spiel unter ScummVM spielen zu können.
-3.19) Hinweise zu DraÄi Historie:
+3.20) Hinweise zu DraÄi Historie:
----- ---------------------------
Es gibt vier Sprachvarianten des Spiels: Tschechisch, Deutsch, Englisch und
Polnisch. Jede von ihnen wird in einem gesonderten Archiv bereitgestellt. Die
@@ -876,7 +979,7 @@ Alle Spieldateien und die Komplettlösung können von der folgenden Website
heruntergeladen werden: http://www.ucw.cz/draci-historie/index-en.html
-3.20) Gleichzeitige Sprachausgabe und Untertitel in Sierra-SCI-Spielen:
+3.21) Gleichzeitige Sprachausgabe und Untertitel in Sierra-SCI-Spielen:
----- -----------------------------------------------------------------
Bestimmte CD-Versionen von Sierra-SCI-Spielen boten sowohl Sprachausgabe als
auch Untertitel an. Bei einigen gab es die Möglichkeit, zwischen beidem hin- und
@@ -919,9 +1022,6 @@ Laura Bow 2 CD:
werden.
Leisure Suit Larry 6 CD:
- Either speech only or speech and text can be selected. There is no
- in-game option to toggle text only. Only ScummVM's audio options can
- be used to enable the text only mode.
Es kann zwischen alleiniger Sprachausgabe und Sprachausgabe und Untertitel
gewählt werden. Es gibt innerhalb des Spiels keine Option, um alleinige
Untertitel zu aktivieren. Dies ist nur über ScummVMs Audio-Optionen möglich.
@@ -932,7 +1032,7 @@ Space Quest 4 CD:
deaktiviert und aktiviert werden.
-3.21) Bekannte Probleme:
+3.22) Bekannte Probleme:
----- ------------------
Diese veröffentlichte Version hat die unten folgenden bekannten Probleme. Es ist
nicht notwendig, diese zu berichten, jedoch sind Patches, um diese zu beheben,
@@ -996,7 +1096,7 @@ Kompatibilitätsseite der Website aufgeführt ist, sehen Sie bitte im Abschnitt
- Keine Unterstützung in Swampy Adventures für das Anzeigen von Namen von
Gegenständen, wenn man über diese mit der Maus fährt
- Floyd - Es gibt noch Helden:
+ Floyd – Es gibt noch Helden:
- Untertitel sind oft unvollständig und nur in Englisch, da sie im
Originalspiel immer ausgeschaltet waren.
@@ -1067,6 +1167,11 @@ mehr als einem Ort aus zu verwenden. Weitere Informationen, einschließlich
darüber, wie man einen Pfad für Spielstände bestimmt, um diesen Sachverhalt zu
vermeiden, befinden sich im Abschnitt 6.0.
+Hinweis: Wird ScummVM auf einem Rechner mit dem Betriebssystem Microsoft
+Windows NT4/2000/XP/Vista/7/8/10 ausgeführt, werden die Spielstand-Dateien ab
+ScummVM 1.5.0 standardmäßig im Verzeichnis „%APPDATA%/ScummVM/Saved Games“
+gespeichert.
+
ScummVM kann direkt durch Aufruf der ausführbaren Datei gestartet werden. In
diesem Fall wird das eingebaute Startmenü aktiviert. Hier können Sie Spiele
hinzufügen, (klicken Sie auf „Spiel hinzufügen“) oder Spiele starten, die
@@ -1274,6 +1379,12 @@ Die einzelnen Grafikoptionen im Ãœberblick:
hq3x - Sehr hochwertiger, qualitativer Filter, aber langsam. Faktor 3.
tv2x - Zeilensprungfilter, emuliert Fernsehgerät. Faktor 2.
dotmatrix - Punktraster-Effekt. Faktor 2.
+ OpenGL - Verwendet OpenGL zur Darstellung. Wirkt bei Auflösung 320x200
+ etwas verwaschen, für Spiele in 640x400 und höher jedoch
+ empfohlen
+ OpenGL (ohne Filter) - Kein Filter, sehr scharfe Darstellung wenn Bildschirm
+ auf nativer Auflösung betrieben wird. Für 640x400 und
+ höher vielleicht etwas zu scharf.
Um einen Grafikfilter auszuwählen, stellen Sie diesen im Startmenü ein oder
übergeben Sie dessen Namen über die Option „-g“ an scummvm, z. B. mit der
@@ -1340,6 +1451,7 @@ Die Engines, die momentan das Zurückkehren zur Spieleliste unterstützen, sind:
TOUCHE
TSAGE
TUCKER
+ ZVISION
5.5) Tastenkürzel:
@@ -1365,6 +1477,9 @@ zwischen SCUMM-Spielen und anderen Spielen.
Vielfaches davon.
Alt+Enter - Wechselt zwischen Vollbild- und Fenstermodus.
Alt+s - Macht Bildschirmfoto (nur für SDL-System).
+ Strg+F7 - Öffnet virtuelle Tastatur (falls aktiviert).
+ Diese kann auch durch langes Drücken der mittleren
+ Maustaste bzw. des Mausrads aufgerufen werden.
SCUMM:
Strg 0-9 und Alt 0-9 - Lädt und speichert entsprechenden Speicherstand.
@@ -1442,6 +1557,9 @@ zwischen SCUMM-Spielen und anderen Spielen.
l - Spiel laden
s - Spiel speichern
+ Lure of the Temptress
+ - Keine Unterstützung für Roland MT-32
+ - Ton-Unterstützung ist nicht vollständig und klingt nicht wie das Original.
Simon the Sorcerer 1 und 2:
Strg 0-9 und Alt 0-9 - Lädt und speichert entsprechenden Speicherstand.
@@ -1544,8 +1662,8 @@ migration.bat kann verwendet werden, um die Spielstände vom alten
Standard-Verzeichnis in das neue zu kopieren.
-6.1) Automatische Spielstände:
----- -------------------------
+6.1) Automatische Speicherung der Spielstände:
+---- -----------------------------------------
Bei einigen Spielen (nämlich „Beneath a Steel Sky“, „Flight of the Amazon
Queen“, allen AGI-Spielen und allen SCUMM-Spielen) wird ScummVM standardmäßig
automatisch alle fünf Minuten den momentanen Spielstand speichern (über die
@@ -1555,7 +1673,7 @@ automatischen Spielstände auf Platz 0 abgelegt. Bei der SCUMM-Engine kann diese
Speicherstand über die Tastenkombination Strg+0 oder über das F5-Menü geladen
werden.
-Spielstände werden unter Windows NT4/2000/XP/Vista/7 in einem versteckten
+Spielstände werden unter Windows NT4/2000/XP/Vista/7/8/10 in einem versteckten
Bereich gespeichert, auf den durch Aufruf von „%APPDATA%\ScummVM\Saved Games\“
zugegriffen werden kann oder indem das Anzeigen versteckter Dateien im Windows
Explorer aktiviert wird.
@@ -1683,7 +1801,7 @@ abhängt.
null - Keine Ausgabe. Spielt keinerlei Musik ab.
adlib - Interne AdLib-Emulation
- fluidsynth - FluidSynth-MIDI-Emulation
+ fluidsynth – FluidSynth-MIDI-Emulation
mt32 - Interne MT-32-Emulation
pcjr - Interne PCjr-Emulation (nur in SCUMM-Spielen verwendbar)
pcspk - Interne PC-Lautsprecher-Emulation
@@ -1760,7 +1878,7 @@ Einige Spiele (wie beispielsweise Sam & Max) beinhalten nur MIDI-Musikdaten.
Einst hat dies verhindert, Musik in diesen Spielen auf Plattformen
wiederzugeben, auf welchen MIDI nicht unterstützt wird oder auf Soundkarten, die
keine MIDI-Treiber bereitstellen (z. B. können viele Soundkarten MIDI unter
-Linux nicht abspielen). ScummVM kann nun den MIDI-Modus emulieren mittels
+Linux nicht abspielen). ScummVM kann nun den MIDI-Modus emulieren, mittels
abgetasteter Wellen und AdLib, FluidSynth-MIDI-Emulation oder MT-32-Emulation
entsprechend über die Option -eadlib, -efluidsynth oder -emt32. Wenn Sie jedoch
in der Lage sind, natives MIDI zu verwenden, empfehlen wir zur Erzielung von
@@ -2289,11 +2407,16 @@ Die folgenden Schlüsselwörter werden erkannt:
boot_param Zahl Ruft Boot-Skript mit dieser Nummer auf.
Sierra-Spiele, welche die AGI-Engine verwenden, verfügen zusätzlich über
-folgendes nicht standardmäßiges Schlüsselwort:
+folgende nicht standardmäßige Schlüsselwörter:
originalsaveload Bool Falls „true“, werden die originalen Menüs zum
- Speichern und Laden statt der
- erweiterten von ScummVM verwendet.
+ Speichern und Laden statt der erweiterten
+ von ScummVM verwendet.
+ altamigapalette Bool Verwendet eine alternative Farbpalette für alle
+ Amiga-Spiele. Dies war das alte Verhalten.
+ mousesupport Bool Aktiviert Maus-Unterstützung. Erlaubt die
+ Verwendung einer Maus zur Bewegung und innerhalb
+ von Spiele-Menüs.
Sierra-Spiele, welche die SCI-Engine verwenden, verfügen zusätzlich über
folgende nicht standardmäßige Schlüsselwörter:
@@ -2309,6 +2432,15 @@ folgende nicht standardmäßige Schlüsselwörter:
der Musiktreiber für eine Music-Feature-Karte
von IBM oder für ein Yamaha-FB-01-FM-
Synthetisierungsmodul verwendet.
+ use_cdaudio Bool Verwende Ton von CD anstelle des spieleigenen,
+ sofern verfügbar.
+ windows_cursors Bool Falls „true“, werden die originalen
+ unskalierten, schwarz-weißen Windows-Zeiger
+ anstatt der von DOS verwendet (King's Quest 6).
+ silver_cursors Bool Falls „true“, wird ein alternativer Satz
+ silberner Mauszeiger verwendet anstatt der
+ originalen goldenen (Space Quest 4).
+
Baphomets Fluch II verfügt zusätzlich über folgende nicht standardmäßige
Schlüsselwörter:
@@ -2422,6 +2554,20 @@ Schlüsselwort:
Geschwindigkeit wiedergegeben, um Probleme bei
der Musik-Synchronität zu vermeiden.
+Zork Nemesis: The Forbidden Lands verfügt zusätzlich über folgende nicht
+standardmäßige Schlüsselwörter:
+
+ originalsaveload Bool Falls „true“, werden die originalen Menüs zum
+ Speichern und Laden statt der erweiterten
+ von ScummVM verwendet.
+ doublefps Bool Falls „true“, wird die Bildwiederholrate von 30
+ auf 60 Bilder pro Sekunde erhöht.
+ noanimwhileturning Bool Falls „true“, werden Animationen während des
+ Drehens im Panorama-Modus deaktiviert.
+ mpegmovies Bool Falls „true“, werden hochauflösende MPEG-Videos
+ der DVD-Version im Spiel verwendet, anstelle der
+ niedrig auflösenden AVI-Videos.
+
8.2) Spielspezifische Optionen bei der grafischen Benutzeroberfläche
---- ---------------------------------------------------------------
@@ -2464,24 +2610,24 @@ Debug-Nachrichten zu durchsuchen
GCC und MinGW32:
* Geben Sie „./configure“ ein.
- * Geben Sie „make“ ein (oder „gmake“ bzw. „gnumake“, abhängig davon, auf
- welchem GNU der Befehl „make“ auf Ihrem System aufgerufen wird) und mit
+ * Geben Sie „make“ ein (oder „gmake“ bzw. „gnumake“, abhängig davon,
+ wie GNU make auf Ihrem System genannt wird) und mit
etwas Glück wird ScummVM für Sie kompiliert.
* Weitere Information finden Sie hier:
http://wiki.scummvm.org/index.php/Compiling_ScummVM/GCC
entsprechend
http://wiki.scummvm.org/index.php/Compiling_ScummVM/MinGW
- Microsoft Visual C++ 8/9/10:
- * Lesen Sie nach, wie man die Projektmappendatei in „dists\msvc8“ bzw.
- entsprechend in „dists\msvc9“ oder „dists\msvc10“ erstellt.
+ Microsoft Visual C++ 9 und höher:
+ * Lesen Sie nach, wie man die Projektmappendatei im entsprechenden
+ „dists\msvc*“-Verzeichnis erstellt.
* Öffnen Sie die erstellte Projektmappendatei.
* Geben Sie die Pfade zu den benötigten Bibliotheksdateien
und Includedateien unter
„Extras|Optionen|Projekte und Projektmappen|VC++-Verzeichnisse“ ein.
* Jetzt sollte das Programm erfolgreich kompiliert werden können.
* Weitere Information finden Sie hier:
- http://wiki.scummvm.org/index.php/Compiling_ScummVM/VS2005
+ http://wiki.scummvm.org/index.php/Compiling_ScummVM/Visual_Studio
Windows Mobile:
* Bitte lesen Sie:
diff --git a/doc/de/Neues b/doc/de/Neues
index 8858e86c02..2b67913359 100644
--- a/doc/de/Neues
+++ b/doc/de/Neues
@@ -2,6 +2,60 @@ Umfangreichere Änderungsaufzeichnungen des neusten experimentellen Codes finden
Sie auf Englisch unter:
https://github.com/scummvm/scummvm/commits/
+1.8.0 (??.??.????)
+ Neue Spiele:
+ - Unterstützung für Rex Nebular and the Cosmic Gender Bender hinzugefügt.
+ - Unterstützung für Sfinx hinzugefügt.
+ - Unterstützung für Zork Nemesis: The Forbidden Lands hinzugefügt.
+ - Unterstützung für Zork: Grand Inquisitor hinzugefügt.
+
+ Allgemein:
+ - Code für Munt-MT-32-Emulation auf Version 1.5.0 aktualisiert.
+
+ 3 Skulls of the Toltecs:
+ - Unterstützung für AdLib-Musik verbessert.
+
+ AGI:
+ - Es ist nun möglich, die Maus-Unterstützung zu deaktivieren (außer bei
+Amiga-Versionen und Fan-Spielen, die eine Maus benötigen).
+ - Fehlerhafte Lautstärke-Dämpfung im PCjr-Sound-Code behoben (Fehler #6858).
+
+ AGOS:
+ - Arpeggio-Effekt in der Musik der Amiga-Version von Elvira 1 repariert.
+ - Lade- und Speicherfortschritt in der PC-Version von Waxworks repariert.
+ - Verb-Feld in der Amiga-Version von Simon the Sorcerer 1 repariert.
+ - Accolade AdLib- und MT32-Treiber für folgende Spiele hinzugefügt:
+ Elvira 1, Elvira 2, Waxworks und Simon the Sorcerer 1 (Demoversion)
+
+ Baphomets Fluch 1:
+ - Erkennung der Byte-Reihenfolge der Sprachausgabe auf Big-Endian-Systemen
+ für die Macintosh-Version (Fehler #6720) repariert.
+ - Absturz beim Neuladen eines Spiels aus dem Hauptmenü heraus, während sich
+ das Spiel in der Szene am Bull's Head Hill befindet, behoben
+ (Fehler #6728). Dieser Fehler trat womöglich auch in anderen Szenen auf.
+
+ MADE:
+ - Unterstützung für AdLib-Musik in Return to Zork verbessert.
+
+ SAGA:
+ - Unterstützung für AdLib-Musik verbessert.
+
+ SCI:
+ - Behandlung der Musik-Priorität extrem verbessert.
+ - Viele Fehler in den originalen Skripten behoben, die auch bei
+ Verwendung des originalen Interpreters auftreten:
+ KQ6 (Sprache und Untertitel), LSL5, QfG1 (EGA), QfG (VGA), QfG2, QfG3,
+ SQ1, SQ4 (CD)
+ - Rückkehr aus dem ScummVM-Menü im Spiel sollte nun immer funktionieren.
+ - Verbesserte Unterstützung für japanische PC-9801-Spiele
+
+ SCUMM:
+ - Es ist nun möglich, Maniac Mansion innerhalb von Day of the
+ Tentacle zu spielen. Bitte Liesmich-Datei für weitere Details lesen.
+
+ Tinsel:
+ - Unterstützung für AdLib-Musik in Discworld 1 verbessert.
+
1.7.0 (21.07.2014)
Neue Spiele:
- Unterstützung für Chivalry is Not Dead hinzugefügt.
@@ -11,17 +65,27 @@ Sie auf Englisch unter:
- Unterstützung für Voyeur hinzugefügt.
Allgemein:
- - Munt-MT-32-Emulationscode zu Version 1.3.0 aktualisiert.
+ - Munt-MT-32-Emulationscode zu Version 1.4.0 aktualisiert.
- Von unseren eigenen JPEG- und PNG-Dekodieren zu libjpeg(-turbo) und libpng
gewechselt, welche schneller sind und mehr Bilder verarbeiten können.
(HINWEIS: Der Wechsel zu libpng fand bereits in Version 1.6.0 statt, wurde
jedoch nicht in der Datei NEUES erwähnt.)
+ - Allgemeine Ausgabe für OpenGL (ES) hinzugefügt (basierend auf
+ GSoC-Aufgabe).
+ - Die Benutzeroberfläche kann jetzt mit 32 Bit Farbentiefe gerendert werden.
+ - Das Kompilierungssystem wurde baukastenartiger gemacht, damit es einfacher
+ ist, neue Engines hinzuzufügen.
+
+ SDL:
+ - OpenGL-Grafikmodus hinzugefügt, der auf unserer allgemeinen OpenGL-Ausgabe
+ basiert. Damit ist Grafikausgabe in beliebiger Größe möglich. Dieser
+ unterstützt jedoch nicht Spezialfilter wie AdvMAME, HQ usw.
AGOS:
- Unterstützung für Mausrad bei Inventar und Spielstandliste hinzugefügt.
- Anzeige der Interaktionsverben in Simon the Sorcerer 2 aktiviert.
- Fehler bei Loyalitätseinstufung in englischer 4CD-Version von
- Floyd - Es gibt noch Helden beseitigt. (Dies war offensichtlich ein Fehler
+ Floyd – Es gibt noch Helden beseitigt. (Dies war offensichtlich ein Fehler
im ursprünglichen Spiel. Es ist zurzeit nicht bekannt, ob noch weitere
Versionen hiervon betroffen sind.)
@@ -42,6 +106,11 @@ Sie auf Englisch unter:
- Fehler beseitigt, durch welchen die Musik manchmal vorzeitig zu spielen
aufhörte.
+ Pegasus:
+ - Mehrere seltene Abstürze und Störungen beseitigt
+ - Mehrere Fehler beseitigt, die aus der ausführbaren Datei des Originalspiels
+ übernommen wurden.
+
SCI:
- Unterstützung für die detailreicheren RAVE-Lippensynchronisationsdaten in
der Windows-Version von King’s Quest 6 hinzugefügt. Portraits wirken beim
@@ -62,10 +131,31 @@ SCUMM:
- AdLib-Unterstützung für Loom und Indiana Jones and the Last Crusade
verbessert. Dadurch klingen Geräusch-Effekte wie beispielsweise von der
Schreibmaschine und vom Wasserfall wie im Original.
+ - Unterstützung für Steam-Versionen von Indiana Jones and the Last Crusade,
+ Indiana Jones and the Fate of Atlantis, Loom und The Dig hinzugefügt.
+ Sowohl Windows- als auch Macintosh-Versionen werden unterstützt.
+
+ TONY:
+ - Spielstände von Tony Tough funktionieren nun auf Big-Endian-Systemen.
Tinsel:
- Discworld 1 und 2 stürzen nicht mehr auf Big-Endian-Systemen ab.
+ Android-Portierung:
+ - Experimentelle Unterstützung für die OUYA-Konsole hinzugefügt.
+
+ PS2-Portierung:
+ - Konfigurierbare TV-Modi hinzugefügt: NTSC und PAL.
+ - Konfigurierbare Grafikmodi hinzugefügt: SDTV stufenweise, SDTV
+ Zeilensprung, EDTV stufenweise und VESA.
+ - Konfigurierbare Option für zu verwendende Festplattenpartition hinzugefügt
+ - Konfigurierbare Option für zu verwendende IP-Adresse hinzugefügt.
+ - Konfigurierbare Option zum Aktivieren und Deaktivieren von
+ USB-Massenspeichergeräten hinzugefügt.
+
+ Tizen-Portierung:
+ - Die BADA-Portierung wurde mit Tizen zusammengeführt/aktualisiert.
+
1.6.0 (31.05.2013)
Neue Spiele:
- Unterstützung für 3 Skulls of the Toltecs hinzugefügt.
@@ -555,7 +645,7 @@ SCUMM:
- Unterstützung für King's Quest VI (hohe und niedrige Auflösung)
hinzugefügt.
- Unterstützung für Laura Bow: The Colonel's Bequest hinzugefügt.
- - Unterstützung für Laura Bow 2: The Dagger of Amon Ra hinzugefügt.
+ - Unterstützung für Laura Bow 2: Der Dolch des Amon Ra hinzugefügt.
- Unterstützung für Leisure Suit Larry 1 (SCI-Remake) (EGA und VGA)
hinzugefügt.
- Unterstützung für Leisure Suit Larry 2 hinzugefügt.
diff --git a/doc/de/Spieletitel Original-Deutsch Deutsch-Original b/doc/de/Spieletitel Original-Deutsch Deutsch-Original
new file mode 100644
index 0000000000..80719079cf
--- /dev/null
+++ b/doc/de/Spieletitel Original-Deutsch Deutsch-Original
@@ -0,0 +1,61 @@
+Original - Deutsch (bzw. Titel in Deutschland):
+Broken Sword: The Shadow of the Templars = Baphomets Fluch
+Broken Sword II: The Smoking Mirror = Baphomets Fluch II: Die Spiegel der Finsternis
+Castle of Dr. Brain = Das Schloß von Dr. Brain
+Darby the Dragon = Darby der Drache
+Discworld 2: Missing Presumed ...!? = Discworld 2: Vermutlich vermisst
+EcoQuest: The Search for Cetus = EcoQuest: Die Suche nach Cetus
+Freddi Fish 1: The Case of the Missing Kelp Seeds = Fritzi Fisch und der verschwundene Schatz
+Freddi Fish 2: The Case of the Haunted Schoolhouse = Fritzi Fisch und das Flossengespenst
+Freddi Fish 3: The Case of the Stolen Conch Shell = Fritzi Fisch und der Fall der gestohlenen Trompetenschnecke
+Freddi Fish 4: The Case of the Hogfish Rustlers of Briny Gulch = Freddi Fisch und das Geheimnis der Salzwasserschlucht
+Freddi Fish 5: The Case of the Creature of Coral Cove = Freddi Fisch und das Rätsel der Korallenbucht
+Freddy Pharkas: Frontier Pharmacist = Freddy Pharkas: Cowboy-Apotheker
+Full Throttle = Vollgas
+Inherit the Earth: Quest for the Orb = Erben der Erde: Die große Suche
+Laura Bow 2: The Dagger of Amon Ra = Laura Bow 2: Der Dolch des Amon Ra
+Pajama Sam 1: No Need to Hide When It's Dark Outside = Pyjama Pit: Keine Angst im Dunkeln
+Pajama Sam 2: Thunder and Lightning Aren't so Frightening = Pyjama Sam: Donner und Blitz machen mir nix
+Pajama Sam 3: You Are What You Eat From Your Head to Your Feet = Pyjama Sam 3: Süßigkeiten kriegen Saures
+Putt-Putt Enters the Race = Töff-Töff und das große Rennen
+Putt-Putt Joins the Circus = Töff-Töff geht zum Zirkus
+Putt-Putt Saves the Zoo = Töff-Töff rettet den Zoo
+Putt-Putt Travels Through Time = Töff-Töff reist durch die Zeit
+Simon the Sorcerer's Puzzle Pack = Simon the Sorcerer's Game Pack
+SPY Fox 1: Dry Cereal = SPY Fox: Das Milchkartell
+SPY Fox 2: Some Assembly Required = SPY Fox: Operation Robohund
+SPY Fox 3: Operation Ozone = SPY Fox: Alarm im Weltall
+The Bizarre Adventures of Woodruff and the Schnibble = Woodruff and the Schnibble of Azimuth
+The Feeble Files = Floyd - Es gibt noch Helden
+Touche: The Adventures of the Fifth Musketeer = Touché: Die Abenteuer des fünften Musketiers
+
+Deutsch (bzw. Titel in Deutschland) - Original:
+Baphomets Fluch = Broken Sword: The Shadow of the Templars
+Baphomets Fluch II: Die Spiegel der Finsternis = Broken Sword II: The Smoking Mirror
+Darby der Drache = Darby the Dragon
+Das Schloß von Dr. Brain = Castle of Dr. Brain
+Discworld 2: Vermutlich vermisst = Discworld 2: Missing Presumed ...!?
+EcoQuest: Die Suche nach Cetus = EcoQuest: The Search for Cetus
+Erben der Erde: Die große Suche = Inherit the Earth: Quest for the Orb
+Floyd - Es gibt noch Helden = The Feeble Files
+Freddi Fisch und das Geheimnis der Salzwasserschlucht = Freddi Fish 4: The Case of the Hogfish Rustlers of Briny Gulch
+Freddi Fisch und das Rätsel der Korallenbucht = Freddi Fish 5: The Case of the Creature of Coral Cove
+Freddy Pharkas: Cowboy-Apotheker = Freddy Pharkas: Frontier Pharmacist
+Fritzi Fisch und das Flossengespenst = Freddi Fish 2: The Case of the Haunted Schoolhouse
+Fritzi Fisch und der Fall der gestohlenen Trompetenschnecke = Freddi Fish 3: The Case of the Stolen Conch Shell
+Fritzi Fisch und der verschwundene Schatz = Freddi Fish 1: The Case of the Missing Kelp Seeds
+Laura Bow 2: Der Dolch des Amon Ra = Laura Bow 2: The Dagger of Amon Ra
+Pyjama Pit: Keine Angst im Dunkeln = Pajama Sam 1: No Need to Hide When It's Dark Outside
+Pyjama Sam 3: Süßigkeiten kriegen Saures = Pajama Sam 3: You Are What You Eat From Your Head to Your Feet
+Pyjama Sam: Donner und Blitz machen mir nix = Pajama Sam 2: Thunder and Lightning Aren't so Frightening
+Simon the Sorcerer's Game Pack = Simon the Sorcerer's Puzzle Pack
+SPY Fox: Alarm im Weltall = SPY Fox 3: Operation Ozone
+SPY Fox: Das Milchkartell = SPY Fox 1: Dry Cereal
+SPY Fox: Operation Robohund = SPY Fox 2: Some Assembly Required
+Töff-Töff geht zum Zirkus = Putt-Putt Joins the Circus
+Töff-Töff reist durch die Zeit = Putt-Putt Travels Through Time
+Töff-Töff rettet den Zoo = Putt-Putt Saves the Zoo
+Töff-Töff und das große Rennen = Putt-Putt Enters the Race
+Touché: Die Abenteuer des fünften Musketiers = Touche: The Adventures of the Fifth Musketeer
+Vollgas = Full Throttle
+Woodruff and the Schnibble of Azimuth = The Bizarre Adventures of Woodruff and the Schnibble
diff --git a/engines/access/access.cpp b/engines/access/access.cpp
index 9749706c96..3fd5c0698c 100644
--- a/engines/access/access.cpp
+++ b/engines/access/access.cpp
@@ -41,6 +41,7 @@ AccessEngine::AccessEngine(OSystem *syst, const AccessGameDescription *gameDesc)
_events = nullptr;
_files = nullptr;
_inventory = nullptr;
+ _midi = nullptr;
_player = nullptr;
_room = nullptr;
_screen = nullptr;
@@ -91,6 +92,10 @@ AccessEngine::AccessEngine(OSystem *syst, const AccessGameDescription *gameDesc)
_vidX = _vidY = 0;
_cheatFl = false;
_restartFl = false;
+ _printEnd = 0;
+ for (int i = 0; i < 100; i++)
+ _objectsTable[i] = nullptr;
+ _clearSummaryFlag = false;
for (int i = 0; i < 60; i++)
TRAVEL[i] = 0;
@@ -252,12 +257,13 @@ void AccessEngine::speakText(ASurface *s, const Common::String &msg) {
_events->clearEvents();
while (!shouldQuit()) {
_sound->freeSounds();
- Resource *sound = _sound->loadSound(_narateFile + 99, _sndSubFile);
- _sound->_soundTable.push_back(SoundEntry(sound, 1));
+ _sound->loadSoundTable(0, _narateFile + 99, _sndSubFile);
_sound->playSound(0);
- _scripts->cmdFreeSound();
- _events->pollEvents();
+ while(_sound->isSFXPlaying() && !shouldQuit())
+ _events->pollEvents();
+
+ _scripts->cmdFreeSound();
if (_events->isKeyMousePressed()) {
_sndSubFile += soundsLeft;
@@ -286,9 +292,11 @@ void AccessEngine::speakText(ASurface *s, const Common::String &msg) {
Resource *res = _sound->loadSound(_narateFile + 99, _sndSubFile);
_sound->_soundTable.push_back(SoundEntry(res, 1));
_sound->playSound(0);
- _scripts->cmdFreeSound();
- _events->pollEvents();
+ while(_sound->isSFXPlaying() && !shouldQuit())
+ _events->pollEvents();
+
+ _scripts->cmdFreeSound();
if (_events->_leftButton) {
_events->debounceLeft();
diff --git a/engines/access/amazon/amazon_game.cpp b/engines/access/amazon/amazon_game.cpp
index b469cf5597..9c39a9bd49 100644
--- a/engines/access/amazon/amazon_game.cpp
+++ b/engines/access/amazon/amazon_game.cpp
@@ -61,9 +61,16 @@ AmazonEngine::AmazonEngine(OSystem *syst, const AccessGameDescription *gameDesc)
_helpTbl[1] = _help2;
_helpTbl[2] = _help3;
+ _chapter = 0;
+ _rawInactiveX = _rawInactiveY = 0;
+ _inactiveYOff = 0;
+ _hintLevel = 0;
+ _updateChapter = 0;
+ _oldTitleChapter = 0;
+ _iqValue = 0;
+
_chapterCells.push_back(CellIdent(0, 96, 17));
_inactive._spritesPtr = nullptr;
- _inactive._altSpritesPtr = nullptr;
_inactive._flags = _inactive._frameNumber = _inactive._offsetY = 0;
_inactive._position = Common::Point(0, 0);
}
@@ -532,8 +539,8 @@ void AmazonEngine::startChapter(int chapter) {
_sound->freeSounds();
if (isCD()) {
- _sound->_soundTable.push_back(SoundEntry(_sound->loadSound(115, 0), 1));
- _sound->_soundTable.push_back(SoundEntry(_sound->loadSound(115, 1), 1));
+ _sound->loadSoundTable(0, 115, 0);
+ _sound->loadSoundTable(1, 115, 1);
_sound->playSound(0);
_sound->playSound(1);
@@ -562,7 +569,7 @@ void AmazonEngine::startChapter(int chapter) {
// Show chapter screen
_files->loadScreen(96, 15);
- _buffer2.copyFrom(*_screen);
+ _buffer2.blitFrom(*_screen);
const int *chapImg = &CHAPTER_TABLE[_chapter - 1][0];
_screen->plotImage(_objectsTable[0], _chapter - 1,
@@ -593,14 +600,14 @@ void AmazonEngine::startChapter(int chapter) {
_screen->clearBuffer();
_files->loadScreen(96, 16);
- _buffer2.copyFrom(*_screen);
+ _buffer2.blitFrom(*_screen);
_screen->plotImage(_objectsTable[0], chapImg[0], Common::Point(90, 7));
_midi->newMusic(7, 1);
_midi->newMusic(34, 0);
_screen->forceFadeIn();
- _buffer2.copyFrom(*_screen);
+ _buffer2.blitFrom(*_screen);
_fonts._charSet._lo = 1;
_fonts._charSet._hi = 10;
@@ -680,7 +687,7 @@ void AmazonEngine::dead(int deathId) {
_files->_setPaletteFlag = false;
_files->loadScreen(94, 0);
_files->_setPaletteFlag = true;
- _buffer2.copyFrom(*_screen);
+ _buffer2.blitFrom(*_screen);
if (!isDemo() || deathId != 10) {
for (int i = 0; i < 3; ++i) {
diff --git a/engines/access/amazon/amazon_logic.cpp b/engines/access/amazon/amazon_logic.cpp
index d24629a467..de53da51cd 100644
--- a/engines/access/amazon/amazon_logic.cpp
+++ b/engines/access/amazon/amazon_logic.cpp
@@ -106,8 +106,8 @@ void CampScene::mWhileDoOpen() {
_vm->_files->_setPaletteFlag = false;
_vm->_files->loadScreen(1, 2);
- _vm->_buffer2.copyFrom(*_vm->_screen);
- _vm->_buffer1.copyFrom(*_vm->_screen);
+ _vm->_buffer2.blitFrom(*_vm->_screen);
+ _vm->_buffer1.blitFrom(*_vm->_screen);
// Load animation data
_vm->_animation->freeAnimationData();
@@ -317,8 +317,8 @@ void Opening::doTitle() {
_vm->_events->hideCursor();
if (!_vm->isDemo()) {
- _vm->_sound->queueSound(0, 98, 30);
- _vm->_sound->queueSound(1, 98, 8);
+ _vm->_sound->loadSoundTable(0, 98, 30);
+ _vm->_sound->loadSoundTable(1, 98, 8);
_vm->_files->_setPaletteFlag = false;
_vm->_files->loadScreen(0, 3);
@@ -326,40 +326,27 @@ void Opening::doTitle() {
_vm->_buffer2.copyFrom(*_vm->_screen);
_vm->_buffer1.copyFrom(*_vm->_screen);
screen.forceFadeIn();
- _vm->_sound->playSound(1);
- // WORKAROUND: This delay has been added to replace original game delay that
- // came from loading resources, since nowadays it would be too fast to be visible
- // nowadays to be visible.
- _vm->_events->_vbCount = 70;
- while (!_vm->shouldQuit() && _vm->_events->_vbCount > 0)
- _vm->_events->pollEventsAndWait();
- if (_vm->shouldQuit())
- return;
+ _vm->_sound->playSound(1, true);
Resource *spriteData = _vm->_files->loadFile(0, 2);
_vm->_objectsTable[0] = new SpriteResource(_vm, spriteData);
delete spriteData;
- _vm->_sound->playSound(1);
-
_vm->_files->_setPaletteFlag = false;
_vm->_files->loadScreen(0, 4);
- _vm->_sound->playSound(1);
_vm->_buffer2.copyFrom(*_vm->_screen);
_vm->_buffer1.copyFrom(*_vm->_screen);
- _vm->_sound->playSound(1);
const int COUNTDOWN[6] = { 2, 0x80, 1, 0x7d, 0, 0x87 };
for (_pCount = 0; _pCount < 3 && !_vm->shouldQuit(); ++_pCount) {
- _vm->_buffer2.copyFrom(_vm->_buffer1);
+ _vm->_buffer2.blitFrom(_vm->_buffer1);
int id = COUNTDOWN[_pCount * 2];
int xp = COUNTDOWN[_pCount * 2 + 1];
_vm->_buffer2.plotImage(_vm->_objectsTable[0], id, Common::Point(xp, 71));
_vm->_buffer2.copyTo(_vm->_screen);
- _vm->_sound->playSound(1);
_vm->_events->_vbCount = 70;
while (!_vm->shouldQuit() && _vm->_events->_vbCount > 0 && !_skipStart) {
_vm->_events->pollEventsAndWait();
@@ -371,6 +358,7 @@ void Opening::doTitle() {
return;
_vm->_sound->stopSound();
+ _vm->_sound->checkSoundQueue(); // HACK: Clear sound 1 from the queue
_vm->_sound->playSound(0);
screen.forceFadeOut();
_vm->_events->_vbCount = 100;
@@ -385,11 +373,11 @@ void Opening::doTitle() {
_vm->_files->_setPaletteFlag = false;
_vm->_files->loadScreen(0, 5);
- _vm->_buffer2.copyFrom(*_vm->_screen);
- _vm->_buffer1.copyFrom(*_vm->_screen);
+ _vm->_buffer2.blitFrom(*_vm->_screen);
+ _vm->_buffer1.blitFrom(*_vm->_screen);
screen.forceFadeIn();
_vm->_midi->newMusic(1, 0);
- _vm->_events->_vbCount = 700;
+ _vm->_events->_vbCount = 950;
while (!_vm->shouldQuit() && (_vm->_events->_vbCount > 0) && !_vm->_events->isKeyMousePressed()) {
_vm->_events->pollEventsAndWait();
}
@@ -493,55 +481,62 @@ void Opening::doTent() {
_vm->_screen->setDisplayScan();
_vm->_screen->forceFadeOut();
_vm->_events->hideCursor();
- _vm->_sound->_soundTable.push_back(SoundEntry(_vm->_sound->loadSound(98, 39), 1));
- _vm->_sound->_soundTable.push_back(SoundEntry(_vm->_sound->loadSound(98, 14), 1));
- _vm->_sound->_soundTable.push_back(SoundEntry(_vm->_sound->loadSound(98, 15), 1));
- _vm->_sound->_soundTable.push_back(SoundEntry(_vm->_sound->loadSound(98, 16), 1));
- _vm->_sound->_soundTable.push_back(SoundEntry(_vm->_sound->loadSound(98, 31), 2));
- _vm->_sound->_soundTable.push_back(SoundEntry(_vm->_sound->loadSound(98, 52), 2));
+ _vm->_sound->loadSoundTable(0, 98, 39);
+ _vm->_sound->loadSoundTable(1, 98, 14);
+ _vm->_sound->loadSoundTable(2, 98, 15);
+ _vm->_sound->loadSoundTable(3, 98, 16);
+ _vm->_sound->loadSoundTable(4, 98, 31, 2);
+ _vm->_sound->loadSoundTable(5, 98, 52, 2);
_vm->_sound->playSound(0);
_vm->_files->_setPaletteFlag = false;
_vm->_files->loadScreen(2, 0);
- _vm->_buffer2.copyFrom(*_vm->_screen);
- _vm->_buffer1.copyFrom(*_vm->_screen);
+ _vm->_buffer2.blitFrom(*_vm->_screen);
+ _vm->_buffer1.blitFrom(*_vm->_screen);
_vm->_screen->forceFadeIn();
_vm->_video->setVideo(_vm->_screen, Common::Point(126, 73), FileIdent(2, 1), 10);
+ int previousFrame = -1;
while (!_vm->shouldQuit() && !_vm->_video->_videoEnd) {
_vm->_video->playVideo();
- if ((_vm->_video->_videoFrame == 32) || (_vm->_video->_videoFrame == 34))
- _vm->_sound->playSound(4);
- else if (_vm->_video->_videoFrame == 36) {
- if (step != 2) {
- _vm->_sound->playSound(2);
- step = 2;
- }
- } else if (_vm->_video->_videoFrame == 18) {
- if (step != 1) {
- _vm->_midi->newMusic(73, 1);
- _vm->_midi->newMusic(11, 0);
- step = 1;
- _vm->_sound->playSound(1);
+ if (previousFrame != _vm->_video->_videoFrame) {
+ previousFrame = _vm->_video->_videoFrame;
+
+ if ((_vm->_video->_videoFrame == 32) || (_vm->_video->_videoFrame == 34))
+ _vm->_sound->playSound(4);
+ else if (_vm->_video->_videoFrame == 36) {
+ if (step != 2) {
+ _vm->_sound->playSound(2);
+ step = 2;
+ }
+ } else if (_vm->_video->_videoFrame == 18) {
+ if (step != 1) {
+ _vm->_midi->newMusic(73, 1);
+ _vm->_midi->newMusic(11, 0);
+ step = 1;
+ _vm->_sound->playSound(1);
+ }
}
}
-
_vm->_events->pollEventsAndWait();
}
_vm->_sound->playSound(5);
_vm->_video->setVideo(_vm->_screen, Common::Point(43, 11), FileIdent(2, 2), 10);
+ previousFrame = -1;
while (!_vm->shouldQuit() && !_vm->_video->_videoEnd) {
_vm->_video->playVideo();
- if (_vm->_video->_videoFrame == 26) {
- _vm->_sound->playSound(5);
- } else if (_vm->_video->_videoFrame == 15) {
- if (step !=3) {
- _vm->_sound->playSound(3);
- step = 3;
+ if (previousFrame != _vm->_video->_videoFrame) {
+ previousFrame = _vm->_video->_videoFrame;
+ if (_vm->_video->_videoFrame == 26) {
+ _vm->_sound->playSound(5);
+ } else if (_vm->_video->_videoFrame == 15) {
+ if (step !=3) {
+ _vm->_sound->playSound(3);
+ step = 3;
+ }
}
}
-
_vm->_events->pollEventsAndWait();
}
@@ -1035,7 +1030,7 @@ void Guard::setHorizontalCode() {
if (_bottomRight.x < screen._orgX1)
_gCode2 |= 8;
- else if (_bottomRight.y > screen._orgX2)
+ else if (_bottomRight.x > screen._orgX2)
_gCode2 |= 2;
}
@@ -1276,8 +1271,8 @@ void Cast::doCast(int param1) {
_vm->_files->_setPaletteFlag = false;
_vm->_files->loadScreen(58, 1);
- _vm->_buffer2.copyFrom(*_vm->_screen);
- _vm->_buffer1.copyFrom(*_vm->_screen);
+ _vm->_buffer2.blitFrom(*_vm->_screen);
+ _vm->_buffer1.blitFrom(*_vm->_screen);
_xTrack = 0;
_yTrack = -6;
@@ -1319,7 +1314,7 @@ void Cast::doCast(int param1) {
while (!_vm->shouldQuit()) {
_vm->_images.clear();
pan();
- _vm->_buffer2.copyFrom(_vm->_buffer1);
+ _vm->_buffer2.blitFrom(_vm->_buffer1);
_vm->_newRects.clear();
_vm->plotList();
_vm->copyBlocks();
@@ -1371,6 +1366,18 @@ River::River(AmazonEngine *vm) : PannedScene(vm) {
_deathCount = 0;
_oldScrollCol = 0;
_maxHits = 0;
+ _mapPtr = nullptr;
+ _canoeMoveCount = 0;
+ _canoeVXPos = 0;
+ _canoeFrame = 0;
+ _canoeDir = 0;
+ _canoeLane = 0;
+ _canoeYPos = 0;
+ _hitCount = 0;
+ _riverIndex = 0;
+ _topList = _botList = nullptr;
+ _deathType = 0;
+ _hitSafe = 0;
}
void River::setRiverPan() {
@@ -1410,7 +1417,7 @@ void River::initRiver() {
_vm->_files->_setPaletteFlag = false;
_vm->_files->loadScreen(95, 4);
- _vm->_buffer2.copyFrom(*_vm->_screen);
+ _vm->_buffer2.blitFrom(*_vm->_screen);
screen.restorePalette();
screen.setBufferScan();
@@ -1480,11 +1487,11 @@ void River::initRiver() {
_maxHits = 2 - _vm->_riverFlag;
_saveRiver = false;
- Font &font2 = _vm->_fonts._font2;
- font2._fontColors[0] = 0;
- font2._fontColors[1] = 33;
- font2._fontColors[2] = 34;
- font2._fontColors[3] = 35;
+ // Set font colors for drawing using font2
+ Font::_fontColors[0] = 0;
+ Font::_fontColors[1] = 33;
+ Font::_fontColors[2] = 34;
+ Font::_fontColors[3] = 35;
}
void River::resetPositions() {
@@ -1510,8 +1517,6 @@ void River::checkRiverPan() {
}
bool River::riverJumpTest() {
- Screen &screen = *_vm->_screen;
-
if (_vm->_scrollCol == 120 || _vm->_scrollCol == 60 || _vm->_scrollCol == 0) {
int val = *++_mapPtr;
if (val == 0xFF)
@@ -1744,7 +1749,7 @@ void River::mWhileDownRiver() {
screen.savePalette();
if (!_vm->isDemo())
_vm->_files->loadScreen(95, 4);
- _vm->_buffer2.copyFrom(*_vm->_screen);
+ _vm->_buffer2.blitFrom(*_vm->_screen);
screen.restorePalette();
screen.setPalette();
screen.setBufferScan();
@@ -1909,7 +1914,6 @@ void River::synchronize(Common::Serializer &s) {
if (_vm->_player->_roomNumber == 45) {
if (s.isSaving()) {
// Set river properties to be saved out
- Screen &screen = *_vm->_screen;
_rScrollRow = _vm->_scrollRow;
_rScrollCol = _vm->_scrollCol;
_rScrollX = _vm->_scrollX;
diff --git a/engines/access/amazon/amazon_logic.h b/engines/access/amazon/amazon_logic.h
index a1fb4eef77..0d962483e6 100644
--- a/engines/access/amazon/amazon_logic.h
+++ b/engines/access/amazon/amazon_logic.h
@@ -242,6 +242,8 @@ public:
class InactivePlayer : public ImageEntry {
public:
SpriteResource *_altSpritesPtr;
+
+ InactivePlayer() { _altSpritesPtr = nullptr; }
};
} // End of namespace Amazon
diff --git a/engines/access/amazon/amazon_scripts.cpp b/engines/access/amazon/amazon_scripts.cpp
index 19777541e4..8c49424bc5 100644
--- a/engines/access/amazon/amazon_scripts.cpp
+++ b/engines/access/amazon/amazon_scripts.cpp
@@ -40,7 +40,7 @@ AmazonScripts::AmazonScripts(AccessEngine *vm) : Scripts(vm) {
void AmazonScripts::cLoop() {
searchForSequence();
_vm->_images.clear();
- _vm->_buffer2.copyFrom(_vm->_buffer1);
+ _vm->_buffer2.blitFrom(_vm->_buffer1);
_vm->_oldRects.clear();
_vm->_scripts->executeScript();
_vm->plotList1();
@@ -53,8 +53,8 @@ void AmazonScripts::mWhile1() {
_vm->_events->hideCursor();
_vm->_files->loadScreen(14, 0);
- _vm->_buffer2.copyFrom(*_vm->_screen);
- _vm->_buffer1.copyFrom(*_vm->_screen);
+ _vm->_buffer2.blitFrom(*_vm->_screen);
+ _vm->_buffer1.blitFrom(*_vm->_screen);
_vm->_events->showCursor();
_vm->_screen->setIconPalette();
@@ -88,8 +88,8 @@ void AmazonScripts::mWhile1() {
_vm->_files->loadScreen(14, 1);
_vm->_screen->setPalette();
- _vm->_buffer2.copyFrom(*_vm->_screen);
- _vm->_buffer1.copyFrom(*_vm->_screen);
+ _vm->_buffer2.blitFrom(*_vm->_screen);
+ _vm->_buffer1.blitFrom(*_vm->_screen);
_vm->_events->showCursor();
_vm->_screen->setIconPalette();
@@ -97,7 +97,7 @@ void AmazonScripts::mWhile1() {
_vm->_oldRects.clear();
_sequence = 2200;
- _vm->_sound->queueSound(0, 14, 15);
+ _vm->_sound->loadSoundTable(0, 14, 15);
do {
cLoop();
@@ -109,8 +109,8 @@ void AmazonScripts::mWhile1() {
_vm->_files->loadScreen(14, 2);
_vm->_screen->setPalette();
- _vm->_buffer2.copyFrom(*_vm->_screen);
- _vm->_buffer1.copyFrom(*_vm->_screen);
+ _vm->_buffer2.blitFrom(*_vm->_screen);
+ _vm->_buffer1.blitFrom(*_vm->_screen);
_vm->_events->showCursor();
_vm->_screen->setIconPalette();
@@ -140,8 +140,8 @@ void AmazonScripts::mWhile1() {
_vm->_files->loadScreen(14, 3);
_vm->_screen->setPalette();
- _vm->_buffer2.copyFrom(*_vm->_screen);
- _vm->_buffer1.copyFrom(*_vm->_screen);
+ _vm->_buffer2.blitFrom(*_vm->_screen);
+ _vm->_buffer1.blitFrom(*_vm->_screen);
_vm->_events->showCursor();
_vm->_screen->setIconPalette();
@@ -161,8 +161,8 @@ void AmazonScripts::mWhile2() {
_vm->_events->hideCursor();
_vm->_files->loadScreen(14, 0);
- _vm->_buffer2.copyFrom(*_vm->_screen);
- _vm->_buffer1.copyFrom(*_vm->_screen);
+ _vm->_buffer2.blitFrom(*_vm->_screen);
+ _vm->_buffer1.blitFrom(*_vm->_screen);
_vm->_events->showCursor();
_vm->_screen->setIconPalette();
@@ -192,8 +192,8 @@ void AmazonScripts::mWhile2() {
_vm->_files->loadScreen(14, 3);
_vm->_screen->setPalette();
- _vm->_buffer2.copyFrom(*_vm->_screen);
- _vm->_buffer1.copyFrom(*_vm->_screen);
+ _vm->_buffer2.blitFrom(*_vm->_screen);
+ _vm->_buffer1.blitFrom(*_vm->_screen);
_vm->_events->showCursor();
_vm->_screen->setIconPalette();
@@ -242,8 +242,8 @@ void AmazonScripts::loadBackground(int param1, int param2) {
_vm->_files->_setPaletteFlag = false;
_vm->_files->loadScreen(param1, param2);
- _vm->_buffer2.copyFrom(*_vm->_screen);
- _vm->_buffer1.copyFrom(*_vm->_screen);
+ _vm->_buffer2.blitFrom(*_vm->_screen);
+ _vm->_buffer1.blitFrom(*_vm->_screen);
_vm->_screen->forceFadeIn();
}
diff --git a/engines/access/animation.cpp b/engines/access/animation.cpp
index 548e7db02d..14d7c0d4cc 100644
--- a/engines/access/animation.cpp
+++ b/engines/access/animation.cpp
@@ -310,9 +310,7 @@ Animation *AnimationManager::setAnimation(int animId) {
anim->_countdownTicks = anim->_initialTicks;
anim->_frameNumber = 0;
- anim->_currentLoopCount = (anim->_type != 3 && anim->_type != 4) ? 0 :
- anim->_loopCount;
- anim->_field10 = 0;
+ anim->_currentLoopCount = (anim->_type != 3 && anim->_type != 4) ? 0 : anim->_loopCount;
return anim;
}
diff --git a/engines/access/animation.h b/engines/access/animation.h
index 722f5430ab..72621c4d11 100644
--- a/engines/access/animation.h
+++ b/engines/access/animation.h
@@ -106,7 +106,6 @@ public:
int _loopCount;
int _countdownTicks;
int _currentLoopCount;
- int _field10;
public:
Animation(AccessEngine *vm, Common::SeekableReadStream *stream);
~Animation();
diff --git a/engines/access/asurface.cpp b/engines/access/asurface.cpp
index 1029c355da..526690807a 100644
--- a/engines/access/asurface.cpp
+++ b/engines/access/asurface.cpp
@@ -108,7 +108,7 @@ void ImageEntryList::addToList(ImageEntry &ie) {
int ASurface::_clipWidth;
int ASurface::_clipHeight;
-ASurface::ASurface() {
+ASurface::ASurface(): Graphics::Surface() {
_leftSkip = _rightSkip = 0;
_topSkip = _bottomSkip = 0;
_lastBoundsX = _lastBoundsY = 0;
@@ -116,6 +116,7 @@ ASurface::ASurface() {
_orgX1 = _orgY1 = 0;
_orgX2 = _orgY2 = 0;
_lColor = 0;
+ _maxChars = 0;
}
ASurface::~ASurface() {
@@ -192,7 +193,7 @@ void ASurface::plotImage(SpriteResource *sprite, int frameNum, const Common::Poi
}
}
-void ASurface::transCopyFrom(ASurface *src, const Common::Point &destPos) {
+void ASurface::transBlitFrom(ASurface *src, const Common::Point &destPos) {
if (getPixels() == nullptr)
create(w, h);
@@ -207,7 +208,7 @@ void ASurface::transCopyFrom(ASurface *src, const Common::Point &destPos) {
}
}
-void ASurface::transCopyFrom(ASurface *src, const Common::Rect &bounds) {
+void ASurface::transBlitFrom(ASurface *src, const Common::Rect &bounds) {
const int SCALE_LIMIT = 0x100;
int scaleX = SCALE_LIMIT * bounds.width() / src->w;
int scaleY = SCALE_LIMIT * bounds.height() / src->h;
@@ -253,11 +254,12 @@ void ASurface::transCopyFrom(ASurface *src, const Common::Rect &bounds) {
}
}
-void ASurface::transCopyFrom(ASurface &src) {
- copyFrom(src);
+void ASurface::transBlitFrom(ASurface &src) {
+ blitFrom(src);
}
-void ASurface::copyFrom(Graphics::Surface &src) {
+void ASurface::blitFrom(Graphics::Surface &src) {
+ assert(w >= src.w && h >= src.h);
for (int y = 0; y < src.h; ++y) {
const byte *srcP = (const byte *)src.getBasePtr(0, y);
byte *destP = (byte *)getBasePtr(0, y);
@@ -266,7 +268,7 @@ void ASurface::copyFrom(Graphics::Surface &src) {
}
void ASurface::copyBuffer(Graphics::Surface *src) {
- copyFrom(*src);
+ blitFrom(*src);
}
void ASurface::plotF(SpriteFrame *frame, const Common::Point &pt) {
@@ -278,14 +280,14 @@ void ASurface::plotB(SpriteFrame *frame, const Common::Point &pt) {
}
void ASurface::sPlotF(SpriteFrame *frame, const Common::Rect &bounds) {
- transCopyFrom(frame, bounds);
+ transBlitFrom(frame, bounds);
}
void ASurface::sPlotB(SpriteFrame *frame, const Common::Rect &bounds) {
ASurface flippedFrame;
frame->flipHorizontal(flippedFrame);
- transCopyFrom(&flippedFrame, bounds);
+ transBlitFrom(&flippedFrame, bounds);
}
void ASurface::copyBlock(ASurface *src, const Common::Rect &bounds) {
diff --git a/engines/access/asurface.h b/engines/access/asurface.h
index 0c656a03a9..022e2534c1 100644
--- a/engines/access/asurface.h
+++ b/engines/access/asurface.h
@@ -100,20 +100,20 @@ public:
virtual void drawLine();
virtual void drawBox();
+
+ virtual void transBlitFrom(ASurface *src, const Common::Point &destPos);
- virtual void transCopyFrom(ASurface *src, const Common::Point &destPos);
+ virtual void transBlitFrom(ASurface *src, const Common::Rect &bounds);
- virtual void transCopyFrom(ASurface *src, const Common::Rect &bounds);
+ virtual void transBlitFrom(ASurface &src);
- virtual void transCopyFrom(ASurface &src);
-
- virtual void copyFrom(Graphics::Surface &src);
+ virtual void blitFrom(Graphics::Surface &src);
virtual void copyBuffer(Graphics::Surface *src);
virtual void addDirtyRect(const Common::Rect &r) {}
- void copyTo(ASurface *dest) { dest->copyFrom(*this); }
+ void copyTo(ASurface *dest) { dest->blitFrom(*this); }
void saveBlock(const Common::Rect &bounds);
diff --git a/engines/access/bubble_box.h b/engines/access/bubble_box.h
index 35b7ca2cdb..6bf752d1a3 100644
--- a/engines/access/bubble_box.h
+++ b/engines/access/bubble_box.h
@@ -73,7 +73,6 @@ public:
int _btnX3;
Common::Rect _btnUpPos;
Common::Rect _btnDownPos;
-
Common::Array<Common::Rect> _bubbles;
public:
BubbleBox(AccessEngine *vm, Access::BoxType type, int x, int y, int w, int h, int val1, int val2, int val3, int val4, Common::String title);
diff --git a/engines/access/char.cpp b/engines/access/char.cpp
index b3b026b6c9..aca7262952 100644
--- a/engines/access/char.cpp
+++ b/engines/access/char.cpp
@@ -124,8 +124,8 @@ void CharManager::loadChar(int charId) {
_vm->_screen->fadeIn();
}
- _vm->_buffer1.copyFrom(*_vm->_screen);
- _vm->_buffer2.copyFrom(*_vm->_screen);
+ _vm->_buffer1.blitFrom(*_vm->_screen);
+ _vm->_buffer2.blitFrom(*_vm->_screen);
_vm->_screen->setDisplayScan();
if (_charFlag != 2 && _charFlag != 3) {
diff --git a/engines/access/char.h b/engines/access/char.h
index e64e90078c..f2828e9779 100644
--- a/engines/access/char.h
+++ b/engines/access/char.h
@@ -51,11 +51,8 @@ private:
void charMenu();
public:
Common::Array<CharEntry> _charTable;
- int _converseMode;
int _charFlag;
- // Fields that are included in savegames
- int _conversation;
public:
CharManager(AccessEngine *vm);
diff --git a/engines/access/decompress.cpp b/engines/access/decompress.cpp
index 62bff87860..3de376c193 100644
--- a/engines/access/decompress.cpp
+++ b/engines/access/decompress.cpp
@@ -32,8 +32,9 @@ void LzwDecompressor::decompress(byte *source, byte *dest) {
_source = source;
- byte litByte;
- uint16 copyLength, maxCodeValue, code, nextCode, lastCode, oldCode;
+ byte litByte = 0;
+ uint16 oldCode = 0;
+ uint16 copyLength, maxCodeValue, code, nextCode, lastCode;
byte *copyBuf = new byte[8192];
@@ -45,7 +46,7 @@ void LzwDecompressor::decompress(byte *source, byte *dest) {
maxCodeValue = 512;
copyLength = 0;
- _bitPos = 0;
+ _sourceBitsLeft = 8;
while (1) {
@@ -96,17 +97,39 @@ uint16 LzwDecompressor::getCode() {
const byte bitMasks[9] = {
0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0x0FF
};
- uint16 bits, loCode, hiCode;
- loCode = (READ_LE_UINT16(_source) >> _bitPos) & 0xFF;
- _source++;
- bits = _codeLength - 8;
- hiCode = (READ_LE_UINT16(_source) >> _bitPos) & bitMasks[bits];
- _bitPos += bits;
- if (_bitPos > 8) {
- _source++;
- _bitPos -= 8;
+
+ byte resultBitsLeft = _codeLength;
+ byte resultBitsPos = 0;
+ uint16 result = 0;
+ byte currentByte = *_source;
+ byte currentBits = 0;
+
+ // Get bits of current byte
+ while (resultBitsLeft) {
+ if (resultBitsLeft < _sourceBitsLeft) {
+ // we need less than we have left
+ currentBits = (currentByte >> (8 - _sourceBitsLeft)) & bitMasks[resultBitsLeft];
+ result |= (currentBits << resultBitsPos);
+ _sourceBitsLeft -= resultBitsLeft;
+ resultBitsLeft = 0;
+
+ } else {
+ // we need as much as we have left or more
+ resultBitsLeft -= _sourceBitsLeft;
+ currentBits = currentByte >> (8 - _sourceBitsLeft);
+ result |= (currentBits << resultBitsPos);
+ resultBitsPos += _sourceBitsLeft;
+
+ // Go to next byte
+ _source++;
+
+ _sourceBitsLeft = 8;
+ if (resultBitsLeft) {
+ currentByte = *_source;
+ }
+ }
}
- return (hiCode << 8) | loCode;
+ return result;
}
uint32 decompressDBE(byte *source, byte **dest) {
diff --git a/engines/access/decompress.h b/engines/access/decompress.h
index eea450086b..bea9a1d3f8 100644
--- a/engines/access/decompress.h
+++ b/engines/access/decompress.h
@@ -32,7 +32,8 @@ public:
void decompress(byte *source, byte *dest);
private:
byte *_source;
- byte _codeLength, _bitPos;
+ byte _sourceBitsLeft;
+ byte _codeLength;
uint16 getCode();
};
diff --git a/engines/access/events.cpp b/engines/access/events.cpp
index 0867b09765..6ffe67acfb 100644
--- a/engines/access/events.cpp
+++ b/engines/access/events.cpp
@@ -140,6 +140,8 @@ void EventsManager::pollEvents(bool skipTimers) {
if (checkForNextTimerUpdate() && !skipTimers)
nextTimer();
+ _vm->_sound->checkSoundQueue();
+
_wheelUp = _wheelDown = false;
Common::Event event;
diff --git a/engines/access/files.cpp b/engines/access/files.cpp
index 42a7914638..4d734a67a9 100644
--- a/engines/access/files.cpp
+++ b/engines/access/files.cpp
@@ -40,6 +40,10 @@ void FileIdent::load(Common::SeekableReadStream &s) {
/*------------------------------------------------------------------------*/
+CellIdent:: CellIdent() {
+ _cell = 0;
+}
+
CellIdent::CellIdent(int cell, int fileNum, int subfile) {
_cell = cell;
_fileNum = fileNum;
diff --git a/engines/access/files.h b/engines/access/files.h
index 8b1aef0363..714ea44c75 100644
--- a/engines/access/files.h
+++ b/engines/access/files.h
@@ -46,7 +46,7 @@ struct FileIdent {
struct CellIdent : FileIdent {
byte _cell;
- CellIdent() {}
+ CellIdent();
CellIdent(int cell, int fileNum, int subfile);
};
diff --git a/engines/access/font.cpp b/engines/access/font.cpp
index da8f0b6ec5..8af183f193 100644
--- a/engines/access/font.cpp
+++ b/engines/access/font.cpp
@@ -27,6 +27,8 @@ namespace Access {
byte Font::_fontColors[4];
Font::Font() {
+ _bitWidth = 0;
+ _height = 0;
}
Font::~Font() {
diff --git a/engines/access/inventory.cpp b/engines/access/inventory.cpp
index 48add68424..d14f116376 100644
--- a/engines/access/inventory.cpp
+++ b/engines/access/inventory.cpp
@@ -64,6 +64,7 @@ InventoryManager::InventoryManager(AccessEngine *vm) : Manager(vm) {
_startAboutItem = 0;
_startTravelItem = 0;
_iconDisplayFlag = true;
+ _boxNum = 0;
const char *const *names;
const int *combineP;
diff --git a/engines/access/player.cpp b/engines/access/player.cpp
index b4af672a7c..ead24025a2 100644
--- a/engines/access/player.cpp
+++ b/engines/access/player.cpp
@@ -49,7 +49,6 @@ Player::Player(AccessEngine *vm) : Manager(vm), ImageEntry() {
_playerSprites1 = nullptr;
_manPal1 = nullptr;
_frameNumber = 0;
- _monData = nullptr;
_rawTempL = 0;
_rawXTemp = 0;
_rawYTempL = 0;
@@ -74,6 +73,12 @@ Player::Player(AccessEngine *vm) : Manager(vm), ImageEntry() {
_playerDirection = NONE;
_xFlag = _yFlag = 0;
_inactiveYOff = 0;
+
+ _sideWalkMin = _sideWalkMax = 0;
+ _upWalkMin = _upWalkMax = 0;
+ _downWalkMin = _downWalkMax = 0;
+ _diagUpWalkMin = _diagUpWalkMax = 0;
+ _diagDownWalkMin = _diagDownWalkMax = 0;
_walkOffRight = _walkOffLeft = nullptr;
_walkOffUp = _walkOffDown = nullptr;
_walkOffUR = _walkOffDR = nullptr;
@@ -410,7 +415,7 @@ void Player::walkUpLeft() {
tempL = _rawPlayerLow.y - _vm->_screen->_scaleTable2[walkOffset];
_rawYTempL = (byte)tempL;
_rawYTemp = _rawPlayer.y - _vm->_screen->_scaleTable1[walkOffset] -
- (tempL < 0 ? 1 : 0);;
+ (tempL < 0 ? 1 : 0);
if (_vm->_room->codeWalls()) {
plotCom2();
diff --git a/engines/access/player.h b/engines/access/player.h
index f3df2d027a..3c554556dd 100644
--- a/engines/access/player.h
+++ b/engines/access/player.h
@@ -79,7 +79,6 @@ public:
SpriteResource *_playerSprites;
// Fields in original Player structure
byte *_manPal1;
- byte *_monData;
int *_walkOffRight;
int *_walkOffLeft;
int *_walkOffUp;
diff --git a/engines/access/resources.cpp b/engines/access/resources.cpp
index b1cc64840b..8699a4a82f 100644
--- a/engines/access/resources.cpp
+++ b/engines/access/resources.cpp
@@ -46,17 +46,17 @@ const byte INITIAL_PALETTE[18 * 3] = {
0x00, 0x00, 0x00
};
-const char *const LOOK_MESSAGE = "LOOKING THERE REVEALS NOTHING OF INTEREST.";
-const char *const GET_MESSAGE = "YOU CAN'T TAKE THAT.";
-const char *const OPEN_MESSAGE = "THAT DOESN'T OPEN.";
-const char *const MOVE_MESSAGE = "THAT WON'T MOVE.";
-const char *const USE_MESSAGE = "THAT DOESN'T SEEM TO WORK.";
-const char *const GO_MESSAGE = "YOU CAN'T CLIMB THAT.";
-const char *const HELP_MESSAGE = "THIS OBJECT REQUIRES NO HINTS";
-const char *const TALK_MESSAGE = "THERE SEEMS TO BE NO RESPONSE.";
const char *const GENERAL_MESSAGES[] = {
- LOOK_MESSAGE, OPEN_MESSAGE, MOVE_MESSAGE, GET_MESSAGE, USE_MESSAGE,
- GO_MESSAGE, TALK_MESSAGE, HELP_MESSAGE, HELP_MESSAGE, USE_MESSAGE
+ "LOOKING THERE REVEALS NOTHING OF INTEREST.", // LOOK_MESSAGE
+ "THAT DOESN'T OPEN.", // OPEN_MESSAGE
+ "THAT WON'T MOVE." // MOVE_MESSAGE
+ "YOU CAN'T TAKE THAT.", // GET_MESSAGE
+ "THAT DOESN'T SEEM TO WORK.", // USE_MESSAGE
+ "YOU CAN'T CLIMB THAT.", // GO_MESSAGE
+ "THERE SEEMS TO BE NO RESPONSE.", // TALK_MESSAGE
+ "THIS OBJECT REQUIRES NO HINTS", // HELP_MESSAGE
+ "THIS OBJECT REQUIRES NO HINTS", // HELP_MESSAGE
+ "THAT DOESN'T SEEM TO WORK.", // USE_MESSAGE
};
const int INVCOORDS[][4] = {
diff --git a/engines/access/room.cpp b/engines/access/room.cpp
index 6e0a4aa6db..46e8d2c8d8 100644
--- a/engines/access/room.cpp
+++ b/engines/access/room.cpp
@@ -477,9 +477,9 @@ void Room::loadPlayField(int fileNum, int subfile) {
screen.loadRawPalette(playData->_stream);
// Copy off the tile data
- _tileSize = (int)header[2] << 8;
- _tile = new byte[_tileSize];
- playData->_stream->read(_tile, _tileSize);
+ int tileSize = (int)header[2] << 8;
+ _tile = new byte[tileSize];
+ playData->_stream->read(_tile, tileSize);
// Copy off the playfield data
_matrixSize = header[0] * header[1];
diff --git a/engines/access/room.h b/engines/access/room.h
index 022d940fa0..12e7375428 100644
--- a/engines/access/room.h
+++ b/engines/access/room.h
@@ -128,7 +128,6 @@ public:
int _playFieldWidth;
int _playFieldHeight;
byte *_tile;
- int _tileSize;
int _selectCommand;
bool _conFlag;
int _rMouse[10][2];
diff --git a/engines/access/screen.cpp b/engines/access/screen.cpp
index 5130d8ed5f..9392decead 100644
--- a/engines/access/screen.cpp
+++ b/engines/access/screen.cpp
@@ -56,6 +56,7 @@ Screen::Screen(AccessEngine *vm) : _vm(vm) {
_bufferBytesWide = _vWindowBytesWide = this->w;
_vWindowLinesTall = this->h;
+ _vWindowWidth = _vWindowHeight = 0;
_clipWidth = _vWindowBytesWide - 1;
_clipHeight = _vWindowLinesTall - 1;
_startCycle = 0;
@@ -198,7 +199,7 @@ void Screen::forceFadeIn() {
for (int idx = 0; idx < PALETTE_SIZE; ++idx, ++srcP, ++destP) {
if (*destP != *srcP) {
repeatFlag = true;
- *destP = MAX((int)*destP + FADE_AMOUNT, (int)*srcP);
+ *destP = MIN((int)*destP + FADE_AMOUNT, (int)*srcP);
}
}
@@ -281,19 +282,19 @@ void Screen::drawBox() {
ASurface::drawBox();
}
-void Screen::transCopyFrom(ASurface *src, const Common::Point &destPos) {
+void Screen::transBlitFrom(ASurface *src, const Common::Point &destPos) {
addDirtyRect(Common::Rect(destPos.x, destPos.y, destPos.x + src->w, destPos.y + src->h));
- ASurface::transCopyFrom(src, destPos);
+ ASurface::transBlitFrom(src, destPos);
}
-void Screen::transCopyFrom(ASurface *src, const Common::Rect &bounds) {
+void Screen::transBlitFrom(ASurface *src, const Common::Rect &bounds) {
addDirtyRect(bounds);
- ASurface::transCopyFrom(src, bounds);
+ ASurface::transBlitFrom(src, bounds);
}
-void Screen::copyFrom(Graphics::Surface &src) {
+void Screen::blitFrom(Graphics::Surface &src) {
addDirtyRect(Common::Rect(0, 0, src.w, src.h));
- ASurface::copyFrom(src);
+ ASurface::blitFrom(src);
}
void Screen::copyBuffer(Graphics::Surface *src) {
diff --git a/engines/access/screen.h b/engines/access/screen.h
index 97ec59d1d1..52485e5c7c 100644
--- a/engines/access/screen.h
+++ b/engines/access/screen.h
@@ -94,11 +94,11 @@ public:
virtual void drawBox();
- virtual void transCopyFrom(ASurface *src, const Common::Point &destPos);
+ virtual void transBlitFrom(ASurface *src, const Common::Point &destPos);
- virtual void transCopyFrom(ASurface *src, const Common::Rect &bounds);
+ virtual void transBlitFrom(ASurface *src, const Common::Rect &bounds);
- virtual void copyFrom(Graphics::Surface &src);
+ virtual void blitFrom(Graphics::Surface &src);
virtual void copyBuffer(Graphics::Surface *src);
diff --git a/engines/access/scripts.cpp b/engines/access/scripts.cpp
index db9053039c..b20189049e 100644
--- a/engines/access/scripts.cpp
+++ b/engines/access/scripts.cpp
@@ -29,10 +29,12 @@ namespace Access {
Scripts::Scripts(AccessEngine *vm) : Manager(vm) {
_resource = nullptr;
+ _specialFunction = -1;
_data = nullptr;
_sequence = 0;
_endFlag = false;
_returnCode = 0;
+ _scriptCommand = 0;
_choice = 0;
_choiceStart = 0;
_charsOrg = Common::Point(0, 0);
@@ -162,7 +164,7 @@ void Scripts::charLoop() {
_sequence = 2000;
searchForSequence();
_vm->_images.clear();
- _vm->_buffer2.copyFrom(_vm->_buffer1);
+ _vm->_buffer2.blitFrom(_vm->_buffer1);
_vm->_newRects.clear();
executeScript();
@@ -993,7 +995,7 @@ void Scripts::cmdFreeSound() {
charLoop();
_vm->_events->pollEvents();
- } while (!_vm->shouldQuit() && sound._playingSound);
+ } while (!_vm->shouldQuit() && sound.isSFXPlaying());
// Free the sounds
while (sound._soundTable.size() > 0) {
diff --git a/engines/access/sound.cpp b/engines/access/sound.cpp
index 9ade99cb72..f2dc0fdf4c 100644
--- a/engines/access/sound.cpp
+++ b/engines/access/sound.cpp
@@ -21,18 +21,18 @@
*/
#include "common/algorithm.h"
+#include "common/config-manager.h"
#include "audio/mixer.h"
-#include "audio/audiostream.h"
#include "audio/decoders/raw.h"
#include "audio/decoders/wave.h"
+// Miles Audio
+#include "audio/miles.h"
#include "access/access.h"
#include "access/sound.h"
namespace Access {
SoundManager::SoundManager(AccessEngine *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer) {
- _playingSound = false;
- _isVoice = false;
}
SoundManager::~SoundManager() {
@@ -44,11 +44,20 @@ void SoundManager::clearSounds() {
for (uint i = 0; i < _soundTable.size(); ++i)
delete _soundTable[i]._res;
+
_soundTable.clear();
+
+ if (_mixer->isSoundHandleActive(_effectsHandle))
+ _mixer->stopHandle(_effectsHandle);
+
+ while (_queue.size()) {
+ delete _queue[0];
+ _queue.remove_at(0);
+ }
}
-void SoundManager::queueSound(int idx, int fileNum, int subfile) {
- debugC(1, kDebugSound, "queueSound(%d, %d, %d)", idx, fileNum, subfile);
+void SoundManager::loadSoundTable(int idx, int fileNum, int subfile, int priority) {
+ debugC(1, kDebugSound, "loadSoundTable(%d, %d, %d)", idx, fileNum, subfile);
Resource *soundResource;
@@ -58,7 +67,7 @@ void SoundManager::queueSound(int idx, int fileNum, int subfile) {
delete _soundTable[idx]._res;
soundResource = _vm->_files->loadFile(fileNum, subfile);
_soundTable[idx]._res = soundResource;
- _soundTable[idx]._priority = 1;
+ _soundTable[idx]._priority = priority;
}
Resource *SoundManager::loadSound(int fileNum, int subfile) {
@@ -66,31 +75,26 @@ Resource *SoundManager::loadSound(int fileNum, int subfile) {
return _vm->_files->loadFile(fileNum, subfile);
}
-void SoundManager::playSound(int soundIndex) {
- debugC(1, kDebugSound, "playSound(%d)", soundIndex);
+void SoundManager::playSound(int soundIndex, bool loop) {
+ debugC(1, kDebugSound, "playSound(%d, %d)", soundIndex, loop);
int priority = _soundTable[soundIndex]._priority;
- playSound(_soundTable[soundIndex]._res, priority);
+ playSound(_soundTable[soundIndex]._res, priority, loop);
}
-void SoundManager::playSound(Resource *res, int priority) {
+void SoundManager::playSound(Resource *res, int priority, bool loop) {
debugC(1, kDebugSound, "playSound");
byte *resourceData = res->data();
- Audio::SoundHandle audioHandle;
- Audio::RewindableAudioStream *audioStream = 0;
assert(res->_size >= 32);
- // HACK: Simulates queueing for the rare sounds played one after the other
- while (_mixer->hasActiveChannelOfType(Audio::Mixer::kSFXSoundType))
- ;
+ Audio::RewindableAudioStream *audioStream;
if (READ_BE_UINT32(resourceData) == MKTAG('R','I','F','F')) {
// CD version uses WAVE-files
Common::SeekableReadStream *waveStream = new Common::MemoryReadStream(resourceData, res->_size, DisposeAfterUse::NO);
audioStream = Audio::makeWAVStream(waveStream, DisposeAfterUse::YES);
-
} else if (READ_BE_UINT32(resourceData) == MKTAG('S', 'T', 'E', 'V')) {
// sound files have a fixed header of 32 bytes in total
// header content:
@@ -130,22 +134,39 @@ void SoundManager::playSound(Resource *res, int priority) {
return;
}
- audioStream = Audio::makeRawStream(resourceData + 32, sampleSize, sampleRate, 0);
-
+ audioStream = Audio::makeRawStream(resourceData + 32, sampleSize, sampleRate, 0, DisposeAfterUse::NO);
} else
error("Unknown format");
- audioHandle = Audio::SoundHandle();
- _mixer->playStream(Audio::Mixer::kSFXSoundType, &audioHandle,
- audioStream, -1, _mixer->kMaxChannelVolume, 0,
+ if (loop) {
+ _queue.push_back(new Audio::LoopingAudioStream(audioStream, 0, DisposeAfterUse::NO));
+ } else {
+ _queue.push_back(audioStream);
+ }
+
+ if (!_mixer->isSoundHandleActive(_effectsHandle))
+ _mixer->playStream(Audio::Mixer::kSFXSoundType, &_effectsHandle,
+ _queue[0], -1, _mixer->kMaxChannelVolume, 0,
DisposeAfterUse::NO);
+}
- /*
- Audio::QueuingAudioStream *audioStream = Audio::makeQueuingAudioStream(22050, false);
- audioStream->queueBuffer(data, size, DisposeAfterUse::YES, 0);
- _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, audioStream, -1,
- Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::YES, false);
- */
+void SoundManager::checkSoundQueue() {
+ debugC(5, kDebugSound, "checkSoundQueue");
+
+ if (_queue.empty() || _mixer->isSoundHandleActive(_effectsHandle))
+ return;
+
+ delete _queue[0];
+ _queue.remove_at(0);
+
+ if (_queue.size() && _queue[0])
+ _mixer->playStream(Audio::Mixer::kSFXSoundType, &_effectsHandle,
+ _queue[0], -1, _mixer->kMaxChannelVolume, 0,
+ DisposeAfterUse::NO);
+}
+
+bool SoundManager::isSFXPlaying() {
+ return _mixer->isSoundHandleActive(_effectsHandle);
}
void SoundManager::loadSounds(Common::Array<RoomInfo::SoundIdent> &sounds) {
@@ -162,7 +183,7 @@ void SoundManager::loadSounds(Common::Array<RoomInfo::SoundIdent> &sounds) {
void SoundManager::stopSound() {
debugC(3, kDebugSound, "stopSound");
- _mixer->stopHandle(Audio::SoundHandle());
+ _mixer->stopHandle(_effectsHandle);
}
void SoundManager::freeSounds() {
@@ -178,19 +199,59 @@ MusicManager::MusicManager(AccessEngine *vm) : _vm(vm) {
_music = nullptr;
_tempMusic = nullptr;
_isLooping = false;
+ _driver = nullptr;
_byte1F781 = false;
+ MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MT32);
+ MusicType musicType = MidiDriver::getMusicType(dev);
+
+ // Amazon Guardians of Eden uses MIDPAK inside MIDIDRV.AP
+ // AdLib patches are inside MIDIDRV.AP too, 2nd resource file
+ //
+ // Amazon Guardians of Eden (demo) seems to use another type of driver, possibly written by Access themselves
+ // Martian Memorandum uses this other type of driver as well, which means it makes sense to reverse engineer it.
+ //
+ switch (musicType) {
+ case MT_ADLIB: {
+ Resource *midiDrvResource = _vm->_files->loadFile(92, 1);
+ Common::MemoryReadStream *adLibInstrumentStream = new Common::MemoryReadStream(midiDrvResource->data(), midiDrvResource->_size);
+
+ _driver = Audio::MidiDriver_Miles_AdLib_create("", "", adLibInstrumentStream);
+
+ delete midiDrvResource;
+ delete adLibInstrumentStream;
+ break;
+ }
+ case MT_MT32:
+ _driver = Audio::MidiDriver_Miles_MT32_create("");
+ _nativeMT32 = true;
+ break;
+ case MT_GM:
+ if (ConfMan.getBool("native_mt32")) {
+ _driver = Audio::MidiDriver_Miles_MT32_create("");
+ _nativeMT32 = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+#if 0
MidiPlayer::createDriver();
MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
+#endif
- int retValue = _driver->open();
- if (retValue == 0) {
- if (_nativeMT32)
- _driver->sendMT32Reset();
- else
- _driver->sendGMReset();
+ if (_driver) {
+ int retValue = _driver->open();
+ if (retValue == 0) {
+ if (_nativeMT32)
+ _driver->sendMT32Reset();
+ else
+ _driver->sendGMReset();
- _driver->setTimerCallback(this, &timerCallback);
+ _driver->setTimerCallback(this, &timerCallback);
+ }
}
}
@@ -200,16 +261,23 @@ MusicManager::~MusicManager() {
}
void MusicManager::send(uint32 b) {
+ // Pass data directly to driver
+ _driver->send(b);
+#if 0
if ((b & 0xF0) == 0xC0 && !_nativeMT32) {
b = (b & 0xFFFF00FF) | MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8;
}
Audio::MidiPlayer::send(b);
+#endif
}
void MusicManager::midiPlay() {
debugC(1, kDebugSound, "midiPlay");
+ if (!_driver)
+ return;
+
if (_music->_size < 4) {
error("midiPlay() wrong music resource size");
}
@@ -218,12 +286,6 @@ void MusicManager::midiPlay() {
if (READ_BE_UINT32(_music->data()) != MKTAG('F', 'O', 'R', 'M')) {
warning("midiPlay() Unexpected signature");
- Common::DumpFile *outFile = new Common::DumpFile();
- Common::String outName = "music.dump";
- outFile->open(outName);
- outFile->write(_music->data(), _music->_size);
- outFile->finalize();
- outFile->close();
_isPlaying = false;
} else {
_parser = MidiParser::createParser_XMIDI();
@@ -253,6 +315,8 @@ bool MusicManager::checkMidiDone() {
void MusicManager::midiRepeat() {
debugC(1, kDebugSound, "midiRepeat");
+ if (!_driver)
+ return;
if (!_parser)
return;
@@ -265,6 +329,9 @@ void MusicManager::midiRepeat() {
void MusicManager::stopSong() {
debugC(1, kDebugSound, "stopSong");
+ if (!_driver)
+ return;
+
stop();
}
@@ -283,6 +350,9 @@ void MusicManager::loadMusic(FileIdent file) {
void MusicManager::newMusic(int musicId, int mode) {
debugC(1, kDebugSound, "newMusic(%d, %d)", musicId, mode);
+ if (!_driver)
+ return;
+
if (mode == 1) {
stopSong();
freeMusic();
diff --git a/engines/access/sound.h b/engines/access/sound.h
index 6bfdbcda7d..e11a6b9730 100644
--- a/engines/access/sound.h
+++ b/engines/access/sound.h
@@ -24,6 +24,7 @@
#define ACCESS_SOUND_H
#include "common/scummsys.h"
+#include "audio/audiostream.h"
#include "audio/mixer.h"
#include "access/files.h"
#include "audio/midiplayer.h"
@@ -47,22 +48,24 @@ class SoundManager {
private:
AccessEngine *_vm;
Audio::Mixer *_mixer;
- Audio::SoundHandle _soundHandle;
+ Audio::SoundHandle _effectsHandle;
+ Common::Array<Audio::AudioStream *> _queue;
void clearSounds();
- void playSound(Resource *res, int priority);
+ void playSound(Resource *res, int priority, bool loop);
public:
Common::Array<SoundEntry> _soundTable;
bool _playingSound;
- bool _isVoice;
public:
SoundManager(AccessEngine *vm, Audio::Mixer *mixer);
~SoundManager();
- void queueSound(int idx, int fileNum, int subfile);
+ void loadSoundTable(int idx, int fileNum, int subfile, int priority = 1);
- void playSound(int soundIndex);
+ void playSound(int soundIndex, bool loop = false);
+ void checkSoundQueue();
+ bool isSFXPlaying();
Resource *loadSound(int fileNum, int subfile);
void loadSounds(Common::Array<RoomInfo::SoundIdent> &sounds);
diff --git a/engines/access/video.cpp b/engines/access/video.cpp
index 70d6ac62e8..5fc5f6762c 100644
--- a/engines/access/video.cpp
+++ b/engines/access/video.cpp
@@ -27,10 +27,21 @@ namespace Access {
VideoPlayer::VideoPlayer(AccessEngine *vm) : Manager(vm) {
_vidSurface = nullptr;
+ _videoData = nullptr;
+ _startCoord = nullptr;
+
+ _frameCount = 0;
+ _xCount = 0;
+ _scanCount = 0;
+ _frameSize = 0;
_videoFrame = 0;
_soundFlag = false;
_soundFrame = 0;
- _videoData = nullptr;
+ _videoEnd = false;
+
+ _header._frameCount = 0;
+ _header._width = _header._height = 0;
+ _header._flags = VIDEOFLAG_NONE;
}
VideoPlayer::~VideoPlayer() {
diff --git a/engines/agi/agi.cpp b/engines/agi/agi.cpp
index 1e663ec29a..2b5d7137bc 100644
--- a/engines/agi/agi.cpp
+++ b/engines/agi/agi.cpp
@@ -97,50 +97,62 @@ void AgiEngine::processEvents() {
}
break;
case Common::EVENT_LBUTTONDOWN:
- key = BUTTON_LEFT;
- _mouse.button = kAgiMouseButtonLeft;
- keyEnqueue(key);
- _mouse.x = event.mouse.x;
- _mouse.y = event.mouse.y;
+ if (_game.mouseEnabled) {
+ key = BUTTON_LEFT;
+ _mouse.button = kAgiMouseButtonLeft;
+ keyEnqueue(key);
+ _mouse.x = event.mouse.x;
+ _mouse.y = event.mouse.y;
+ }
break;
case Common::EVENT_RBUTTONDOWN:
- key = BUTTON_RIGHT;
- _mouse.button = kAgiMouseButtonRight;
- keyEnqueue(key);
- _mouse.x = event.mouse.x;
- _mouse.y = event.mouse.y;
+ if (_game.mouseEnabled) {
+ key = BUTTON_RIGHT;
+ _mouse.button = kAgiMouseButtonRight;
+ keyEnqueue(key);
+ _mouse.x = event.mouse.x;
+ _mouse.y = event.mouse.y;
+ }
break;
case Common::EVENT_WHEELUP:
- key = WHEEL_UP;
- keyEnqueue(key);
+ if (_game.mouseEnabled) {
+ key = WHEEL_UP;
+ keyEnqueue(key);
+ }
break;
case Common::EVENT_WHEELDOWN:
- key = WHEEL_DOWN;
- keyEnqueue(key);
+ if (_game.mouseEnabled) {
+ key = WHEEL_DOWN;
+ keyEnqueue(key);
+ }
break;
case Common::EVENT_MOUSEMOVE:
- _mouse.x = event.mouse.x;
- _mouse.y = event.mouse.y;
-
- if (!_game.mouseFence.isEmpty()) {
- if (_mouse.x < _game.mouseFence.left)
- _mouse.x = _game.mouseFence.left;
- if (_mouse.x > _game.mouseFence.right)
- _mouse.x = _game.mouseFence.right;
- if (_mouse.y < _game.mouseFence.top)
- _mouse.y = _game.mouseFence.top;
- if (_mouse.y > _game.mouseFence.bottom)
- _mouse.y = _game.mouseFence.bottom;
-
- g_system->warpMouse(_mouse.x, _mouse.y);
+ if (_game.mouseEnabled) {
+ _mouse.x = event.mouse.x;
+ _mouse.y = event.mouse.y;
+
+ if (!_game.mouseFence.isEmpty()) {
+ if (_mouse.x < _game.mouseFence.left)
+ _mouse.x = _game.mouseFence.left;
+ if (_mouse.x > _game.mouseFence.right)
+ _mouse.x = _game.mouseFence.right;
+ if (_mouse.y < _game.mouseFence.top)
+ _mouse.y = _game.mouseFence.top;
+ if (_mouse.y > _game.mouseFence.bottom)
+ _mouse.y = _game.mouseFence.bottom;
+
+ g_system->warpMouse(_mouse.x, _mouse.y);
+ }
}
break;
case Common::EVENT_LBUTTONUP:
case Common::EVENT_RBUTTONUP:
- _mouse.button = kAgiMouseButtonUp;
- _mouse.x = event.mouse.x;
- _mouse.y = event.mouse.y;
+ if (_game.mouseEnabled) {
+ _mouse.button = kAgiMouseButtonUp;
+ _mouse.x = event.mouse.x;
+ _mouse.y = event.mouse.y;
+ }
break;
case Common::EVENT_KEYDOWN:
if (event.kbd.hasFlags(Common::KBD_CTRL) && event.kbd.keycode == Common::KEYCODE_d) {
@@ -496,12 +508,15 @@ AgiBase::AgiBase(OSystem *syst, const AGIGameDescription *gameDesc) : Engine(sys
// Assign default values to the config manager, in case settings are missing
ConfMan.registerDefault("originalsaveload", "false");
ConfMan.registerDefault("altamigapalette", "false");
+ ConfMan.registerDefault("mousesupport", "true");
_noSaveLoadAllowed = false;
_rnd = new Common::RandomSource("agi");
_sound = 0;
+ _fontData = NULL;
+
initFeatures();
initVersion();
}
@@ -550,6 +565,19 @@ AgiEngine::AgiEngine(OSystem *syst, const AGIGameDescription *gameDesc) : AgiBas
memset(&_debug, 0, sizeof(struct AgiDebug));
memset(&_mouse, 0, sizeof(struct Mouse));
+ _game.mouseEnabled = true;
+ if (!ConfMan.getBool("mousesupport")) {
+ // we effectively disable the mouse for games, that explicitly do not want mouse support to be enabled
+ _game.mouseEnabled = false;
+ }
+
+ // We are currently using the custom font for all fanmade games
+ if (!(getFeatures() & (GF_FANMADE | GF_AGDS))) {
+ _fontData = fontData_Sierra; // original Sierra font
+ } else {
+ _fontData = fontData_FanGames; // our (own?) custom font, that supports umlauts etc.
+ }
+
_game._vm = this;
_game.clockEnabled = false;
@@ -708,7 +736,9 @@ Common::Error AgiBase::init() {
}
Common::Error AgiEngine::go() {
- CursorMan.showMouse(true);
+ if (_game.mouseEnabled) {
+ CursorMan.showMouse(true);
+ }
setTotalPlayTime(0);
if (_game.state < STATE_LOADED) {
diff --git a/engines/agi/agi.h b/engines/agi/agi.h
index 6256de05d2..04e02dcf87 100644
--- a/engines/agi/agi.h
+++ b/engines/agi/agi.h
@@ -643,6 +643,7 @@ struct AgiGame {
int simpleSave; /**< select simple savegames */
Common::Rect mouseFence; /**< rectangle set by fence.mouse command */
+ bool mouseEnabled; /**< if mouse is supposed to be active */
// IF condition handling
int testResult;
@@ -780,6 +781,8 @@ protected:
void initRenderMode();
+ const uint8 *_fontData;
+
public:
GfxMgr *_gfx;
@@ -839,6 +842,8 @@ public:
bool canLoadGameStateCurrently();
bool canSaveGameStateCurrently();
+
+ const uint8 *getFontData() { return _fontData; };
};
typedef void (*AgiCommand)(AgiGame *state, uint8 *p);
diff --git a/engines/agi/detection.cpp b/engines/agi/detection.cpp
index e7285d8112..823ec7be66 100644
--- a/engines/agi/detection.cpp
+++ b/engines/agi/detection.cpp
@@ -138,21 +138,41 @@ static const PlainGameDescriptor agiGames[] = {
{0, 0}
};
-static const ExtraGuiOption agiExtraGuiOption = {
- _s("Use original save/load screens"),
- _s("Use the original save/load screens, instead of the ScummVM ones"),
- "originalsaveload",
- false
-};
+#include "agi/detection_tables.h"
-static const ExtraGuiOption agiExtraGuiOptionAmiga = {
- _s("Use an alternative palette"),
- _s("Use an alternative palette, common for all Amiga games. This was the old behavior"),
- "altamigapalette",
- false
-};
+static const ADExtraGuiOptionsMap optionsList[] = {
+ {
+ GAMEOPTION_ORIGINAL_SAVELOAD,
+ {
+ _s("Use original save/load screens"),
+ _s("Use the original save/load screens, instead of the ScummVM ones"),
+ "originalsaveload",
+ false
+ }
+ },
+
+ {
+ GAMEOPTION_AMIGA_ALTERNATIVE_PALETTE,
+ {
+ _s("Use an alternative palette"),
+ _s("Use an alternative palette, common for all Amiga games. This was the old behavior"),
+ "altamigapalette",
+ false
+ }
+ },
+
+ {
+ GAMEOPTION_DISABLE_MOUSE,
+ {
+ _s("Mouse support"),
+ _s("Enables mouse support. Allows to use mouse for movement and in game menus."),
+ "mousesupport",
+ true
+ }
+ },
-#include "agi/detection_tables.h"
+ AD_EXTRA_GUI_OPTIONS_TERMINATOR
+};
using namespace Agi;
@@ -161,7 +181,7 @@ class AgiMetaEngine : public AdvancedMetaEngine {
mutable Common::String _extra;
public:
- AgiMetaEngine() : AdvancedMetaEngine(Agi::gameDescriptions, sizeof(Agi::AGIGameDescription), agiGames) {
+ AgiMetaEngine() : AdvancedMetaEngine(Agi::gameDescriptions, sizeof(Agi::AGIGameDescription), agiGames, optionsList) {
_singleid = "agi";
_guioptions = GUIO1(GUIO_NOSPEECH);
}
@@ -175,7 +195,6 @@ public:
virtual bool hasFeature(MetaEngineFeature f) const;
virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
- virtual const ExtraGuiOptions getExtraGuiOptions(const Common::String &target) const;
virtual SaveStateList listSaves(const char *target) const;
virtual int getMaximumSaveSlot() const;
virtual void removeSaveState(const char *target, int slot) const;
@@ -234,14 +253,6 @@ bool AgiMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameD
return res;
}
-const ExtraGuiOptions AgiMetaEngine::getExtraGuiOptions(const Common::String &target) const {
- ExtraGuiOptions options;
- options.push_back(agiExtraGuiOption);
- if (target.contains("-amiga"))
- options.push_back(agiExtraGuiOptionAmiga);
- return options;
-}
-
SaveStateList AgiMetaEngine::listSaves(const char *target) const {
const uint32 AGIflag = MKTAG('A','G','I',':');
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
@@ -276,15 +287,13 @@ SaveStateList AgiMetaEngine::listSaves(const char *target) const {
int AgiMetaEngine::getMaximumSaveSlot() const { return 999; }
void AgiMetaEngine::removeSaveState(const char *target, int slot) const {
- char fileName[MAXPATHLEN];
- sprintf(fileName, "%s.%03d", target, slot);
+ Common::String fileName = Common::String::format("%s.%03d", target, slot);
g_system->getSavefileManager()->removeSavefile(fileName);
}
SaveStateDescriptor AgiMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
const uint32 AGIflag = MKTAG('A','G','I',':');
- char fileName[MAXPATHLEN];
- sprintf(fileName, "%s.%03d", target, slot);
+ Common::String fileName = Common::String::format("%s.%03d", target, slot);
Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(fileName);
diff --git a/engines/agi/detection_tables.h b/engines/agi/detection_tables.h
index 2d7fba3507..0ae822a538 100644
--- a/engines/agi/detection_tables.h
+++ b/engines/agi/detection_tables.h
@@ -22,7 +22,16 @@
namespace Agi {
-#define GAME_LVFPN(id,extra,fname,md5,size,lang,ver,features,gid,platform,interp) { \
+#define GAMEOPTION_ORIGINAL_SAVELOAD GUIO_GAMEOPTIONS1
+#define GAMEOPTION_AMIGA_ALTERNATIVE_PALETTE GUIO_GAMEOPTIONS2
+#define GAMEOPTION_DISABLE_MOUSE GUIO_GAMEOPTIONS3
+// TODO: properly implement GAMEOPTIONs
+
+#define GAMEOPTIONS_DEFAULT GUIO2(GAMEOPTION_ORIGINAL_SAVELOAD,GAMEOPTION_DISABLE_MOUSE)
+#define GAMEOPTIONS_AMIGA GUIO2(GAMEOPTION_ORIGINAL_SAVELOAD,GAMEOPTION_AMIGA_ALTERNATIVE_PALETTE)
+#define GAMEOPTIONS_FANMADE_MOUSE GUIO1(GAMEOPTION_ORIGINAL_SAVELOAD)
+
+#define GAME_LVFPN(id,extra,fname,md5,size,lang,ver,features,gid,platform,interp,guioptions) { \
{ \
id, \
extra, \
@@ -30,7 +39,7 @@ namespace Agi {
lang, \
platform, \
ADGF_NO_FLAGS, \
- GUIO0() \
+ guioptions \
}, \
gid, \
interp, \
@@ -38,7 +47,7 @@ namespace Agi {
ver \
}
-#define GAME_LVFPNF(id,name,fname,md5,size,lang,ver,features,gid,platform,interp) { \
+#define GAME_LVFPNF(id,name,fname,md5,size,lang,ver,features,gid,platform,interp,guioptions) { \
{ \
id, \
name, \
@@ -46,7 +55,7 @@ namespace Agi {
lang, \
platform, \
ADGF_USEEXTRAASTITLE, \
- GUIO0() \
+ guioptions \
}, \
gid, \
interp, \
@@ -54,43 +63,52 @@ namespace Agi {
ver \
}
-#define BOOTER2(id,extra,fname,md5,size,ver,gid) GAME_LVFPN(id,extra,fname,md5,size,Common::EN_ANY,ver,0,gid,Common::kPlatformDOS,GType_V2)
-#define GAME(id,extra,md5,ver,gid) GAME_LVFPN(id,extra,"logdir",md5,-1,Common::EN_ANY,ver,0,gid,Common::kPlatformDOS,GType_V2)
-#define GAME3(id,extra,fname,md5,ver,gid) GAME_LVFPN(id,extra,fname,md5,-1,Common::EN_ANY,ver,0,gid,Common::kPlatformDOS,GType_V3)
+#define BOOTER2(id,extra,fname,md5,size,ver,gid) GAME_LVFPN(id,extra,fname,md5,size,Common::EN_ANY,ver,0,gid,Common::kPlatformDOS,GType_V2,GAMEOPTIONS_DEFAULT)
+#define GAME(id,extra,md5,ver,gid) GAME_LVFPN(id,extra,"logdir",md5,-1,Common::EN_ANY,ver,0,gid,Common::kPlatformDOS,GType_V2,GAMEOPTIONS_DEFAULT)
+#define GAME3(id,extra,fname,md5,ver,gid) GAME_LVFPN(id,extra,fname,md5,-1,Common::EN_ANY,ver,0,gid,Common::kPlatformDOS,GType_V3,GAMEOPTIONS_DEFAULT)
-#define GAME_P(id,extra,md5,ver,gid,platform) GAME_LVFPN(id,extra,"logdir",md5,-1,Common::EN_ANY,ver,0,gid,platform,GType_V2)
+#define GAME_P(id,extra,md5,ver,gid,platform) GAME_LVFPN(id,extra,"logdir",md5,-1,Common::EN_ANY,ver,0,gid,platform,GType_V2,GAMEOPTIONS_DEFAULT)
+#define GAME_PO(id,extra,md5,ver,gid,platform,guioptions) GAME_LVFPN(id,extra,"logdir",md5,-1,Common::EN_ANY,ver,0,gid,platform,GType_V2,guioptions)
-#define GAME_FP(id,extra,md5,ver,flags,gid,platform) GAME_LVFPN(id,extra,"logdir",md5,-1,Common::EN_ANY,ver,flags,gid,platform,GType_V2)
+#define GAME_FP(id,extra,md5,ver,flags,gid,platform) GAME_LVFPN(id,extra,"logdir",md5,-1,Common::EN_ANY,ver,flags,gid,platform,GType_V2,GAMEOPTIONS_DEFAULT)
+#define GAME_FPO(id,extra,md5,ver,flags,gid,platform,guioptions) GAME_LVFPN(id,extra,"logdir",md5,-1,Common::EN_ANY,ver,flags,gid,platform,GType_V2,guioptions)
#define GAME_F(id,extra,md5,ver,flags,gid) GAME_FP(id,extra,md5,ver,flags,gid,Common::kPlatformDOS)
+#define GAME_FO(id,extra,md5,ver,flags,gid,guioptions) GAME_FPO(id,extra,md5,ver,flags,gid,Common::kPlatformDOS,guioptions)
-#define GAME_PS(id,extra,md5,size,ver,gid,platform) GAME_LVFPN(id,extra,"logdir",md5,size,Common::EN_ANY,ver,0,gid,platform,GType_V2)
+#define GAME_PS(id,extra,md5,size,ver,gid,platform) GAME_LVFPN(id,extra,"logdir",md5,size,Common::EN_ANY,ver,0,gid,platform,GType_V2,GAMEOPTIONS_DEFAULT)
-#define GAME_LPS(id,extra,md5,size,lang,ver,gid,platform) GAME_LVFPN(id,extra,"logdir",md5,size,lang,ver,0,gid,platform,GType_V2)
+#define GAME_LPS(id,extra,md5,size,lang,ver,gid,platform) GAME_LVFPN(id,extra,"logdir",md5,size,lang,ver,0,gid,platform,GType_V2,GAMEOPTIONS_DEFAULT)
-#define GAME_LFPS(id,extra,md5,size,lang,ver,flags,gid,platform) GAME_LVFPN(id,extra,"logdir",md5,size,lang,ver,flags,gid,platform,GType_V2)
+#define GAME_LFPS(id,extra,md5,size,lang,ver,flags,gid,platform) GAME_LVFPN(id,extra,"logdir",md5,size,lang,ver,flags,gid,platform,GType_V2,GAMEOPTIONS_DEFAULT)
-#define GAME3_P(id,extra,fname,md5,ver,flags,gid,platform) GAME_LVFPN(id,extra,fname,md5,-1,Common::EN_ANY,ver,flags,gid,platform,GType_V3)
+#define GAME3_P(id,extra,fname,md5,ver,flags,gid,platform) GAME_LVFPN(id,extra,fname,md5,-1,Common::EN_ANY,ver,flags,gid,platform,GType_V3,GAMEOPTIONS_DEFAULT)
+#define GAME3_PO(id,extra,fname,md5,ver,flags,gid,platform,guioptions) GAME_LVFPN(id,extra,fname,md5,-1,Common::EN_ANY,ver,flags,gid,platform,GType_V3,guioptions)
-#define GAMEpre_P(id,extra,fname,md5,ver,gid,platform) GAME_LVFPN(id,extra,fname,md5,-1,Common::EN_ANY,ver,0,gid,platform,GType_PreAGI)
+#define GAMEpre_P(id,extra,fname,md5,ver,gid,platform) GAME_LVFPN(id,extra,fname,md5,-1,Common::EN_ANY,ver,0,gid,platform,GType_PreAGI,GAMEOPTIONS_DEFAULT)
+#define GAMEpre_PO(id,extra,fname,md5,ver,gid,platform,guioptions) GAME_LVFPN(id,extra,fname,md5,-1,Common::EN_ANY,ver,0,gid,platform,GType_PreAGI,guioptions)
-#define GAMEpre_PS(id,extra,fname,md5,size,ver,gid,platform) GAME_LVFPN(id,extra,fname,md5,size,Common::EN_ANY,ver,0,gid,platform,GType_PreAGI)
+#define GAMEpre_PS(id,extra,fname,md5,size,ver,gid,platform) GAME_LVFPN(id,extra,fname,md5,size,Common::EN_ANY,ver,0,gid,platform,GType_PreAGI,GAMEOPTIONS_DEFAULT)
-#define GAME3_PS(id,extra,fname,md5,size,ver,flags,gid,platform) GAME_LVFPN(id,extra,fname,md5,size,Common::EN_ANY,ver,flags,gid,platform,GType_V3)
+#define GAME3_PS(id,extra,fname,md5,size,ver,flags,gid,platform) GAME_LVFPN(id,extra,fname,md5,size,Common::EN_ANY,ver,flags,gid,platform,GType_V3,GAMEOPTIONS_DEFAULT)
+#define GAME3_PSO(id,extra,fname,md5,size,ver,flags,gid,platform,guioptions) GAME_LVFPN(id,extra,fname,md5,size,Common::EN_ANY,ver,flags,gid,platform,GType_V3,guioptions)
-#define FANMADE_ILVF(id,name,md5,lang,ver,features) GAME_LVFPNF(id,name,"logdir",md5,-1,lang,ver,(GF_FANMADE|features),GID_FANMADE,Common::kPlatformDOS,GType_V2)
+#define FANMADE_ILVFO(id,name,md5,lang,ver,features,guioptions) GAME_LVFPNF(id,name,"logdir",md5,-1,lang,ver,(GF_FANMADE|features),GID_FANMADE,Common::kPlatformDOS,GType_V2,guioptions)
-#define FANMADE_ISVP(id,name,md5,size,ver,platform) GAME_LVFPNF(id,name,"logdir",md5,size,Common::EN_ANY,ver,GF_FANMADE,GID_FANMADE,platform,GType_V2)
-#define FANMADE_SVP(name,md5,size,ver,platform) FANMADE_ISVP("agi-fanmade",name,md5,size,ver,platform)
+#define FANMADE_ISVPO(id,name,md5,size,ver,platform,guioptions) GAME_LVFPNF(id,name,"logdir",md5,size,Common::EN_ANY,ver,GF_FANMADE,GID_FANMADE,platform,GType_V2,guioptions)
+#define FANMADE_SVP(name,md5,size,ver,platform) FANMADE_ISVPO("agi-fanmade",name,md5,size,ver,platform,GAMEOPTIONS_DEFAULT)
-#define FANMADE_LVF(name,md5,lang,ver,features) FANMADE_ILVF("agi-fanmade",name,md5,lang,ver,features)
+#define FANMADE_LVFO(name,md5,lang,ver,features,guioptions) FANMADE_ILVFO("agi-fanmade",name,md5,lang,ver,features,guioptions)
-#define FANMADE_LF(name,md5,lang,features) FANMADE_LVF(name,md5,lang,0x2917,features)
+#define FANMADE_LF(name,md5,lang,features) FANMADE_LVFO(name,md5,lang,0x2917,features,GAMEOPTIONS_DEFAULT)
+#define FANMADE_LFO(name,md5,lang,features,guioptions) FANMADE_LVFO(name,md5,lang,0x2917,features,guioptions)
#define FANMADE_IF(id,name,md5,features) FANMADE_ILVF(id,name,md5,Common::EN_ANY,0x2917,features)
-#define FANMADE_V(name,md5,ver) FANMADE_LVF(name,md5,Common::EN_ANY,ver,0)
+#define FANMADE_V(name,md5,ver) FANMADE_LVFO(name,md5,Common::EN_ANY,ver,0,GAMEOPTIONS_DEFAULT)
#define FANMADE_F(name,md5,features) FANMADE_LF(name,md5,Common::EN_ANY,features)
+#define FANMADE_FO(name,md5,features,guioptions) FANMADE_LFO(name,md5,Common::EN_ANY,features,guioptions)
#define FANMADE_L(name,md5,lang) FANMADE_LF(name,md5,lang,0)
#define FANMADE_I(id,name,md5) FANMADE_IF(id,name,md5,0)
+#define FANMADE_O(name,md5,guioptions) FANMADE_FO(name,md5,0,guioptions)
#define FANMADE(name,md5) FANMADE_F(name,md5,0)
@@ -130,7 +148,7 @@ static const AGIGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
- GUIO0()
+ GAMEOPTIONS_DEFAULT
},
GID_BC,
GType_V1,
@@ -151,7 +169,7 @@ static const AGIGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
- GUIO0()
+ GAMEOPTIONS_DEFAULT
},
GID_BC,
GType_V1,
@@ -172,7 +190,7 @@ static const AGIGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
- GUIO0()
+ GAMEOPTIONS_DEFAULT
},
GID_BC,
GType_V1,
@@ -181,7 +199,7 @@ static const AGIGameDescription gameDescriptions[] = {
},
// Black Cauldron (Amiga) 2.00 6/14/87
- GAME_P("bc", "2.00 1987-06-14", "7b01694af21213b4727bb94476f64eb5", 0x2440, GID_BC, Common::kPlatformAmiga),
+ GAME_PO("bc", "2.00 1987-06-14", "7b01694af21213b4727bb94476f64eb5", 0x2440, GID_BC, Common::kPlatformAmiga, GAMEOPTIONS_AMIGA),
// Black Cauldron (Apple IIgs) 1.0O 2/24/89 (CE)
// Menus not tested
@@ -210,7 +228,7 @@ static const AGIGameDescription gameDescriptions[] = {
// Donald Duck's Playground (Amiga) 1.0C
// Menus not tested
- GAME_P("ddp", "1.0C 1987-04-27", "550971d196f65190a5c760d2479406ef", 0x2272, GID_DDP, Common::kPlatformAmiga),
+ GAME_PO("ddp", "1.0C 1987-04-27", "550971d196f65190a5c760d2479406ef", 0x2272, GID_DDP, Common::kPlatformAmiga, GAMEOPTIONS_AMIGA),
// Donald Duck's Playground (ST) 1.0A 8/8/86
// Menus not tested
@@ -221,7 +239,7 @@ static const AGIGameDescription gameDescriptions[] = {
GAME_PS("ddp", "1.0C 1986-06-09", "550971d196f65190a5c760d2479406ef", 132, 0x2272, GID_DDP, Common::kPlatformDOS),
// Gold Rush! (Amiga) 1.01 1/13/89 aka 2.05 3/9/89 # 2.316
- GAME3_PS("goldrush", "1.01 1989-01-13 aka 2.05 1989-03-09", "dirs", "a1d4de3e75c2688c1e2ca2634ffc3bd8", 2399, 0x3149, 0, GID_GOLDRUSH, Common::kPlatformAmiga),
+ GAME3_PSO("goldrush", "1.01 1989-01-13 aka 2.05 1989-03-09", "dirs", "a1d4de3e75c2688c1e2ca2634ffc3bd8", 2399, 0x3149, 0, GID_GOLDRUSH, Common::kPlatformAmiga, GAMEOPTIONS_AMIGA),
// Gold Rush! (Apple IIgs) 1.0M 2/28/89 (CE) aka 2.01 12/22/88
// Menus not tested
@@ -252,7 +270,7 @@ static const AGIGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO0()
+ GAMEOPTIONS_DEFAULT
},
GID_GOLDRUSH,
GType_V3,
@@ -269,7 +287,7 @@ static const AGIGameDescription gameDescriptions[] = {
// King's Quest 1 (Amiga) 1.0U # 2.082
// The original game did not have menus, they are enabled under ScummVM
- GAME_FP("kq1", "1.0U 1986", "246c695324f1c514aee2b904fa352fad", 0x2440, GF_MENUS, GID_KQ1, Common::kPlatformAmiga),
+ GAME_FPO("kq1", "1.0U 1986", "246c695324f1c514aee2b904fa352fad", 0x2440, GF_MENUS, GID_KQ1, Common::kPlatformAmiga, GAMEOPTIONS_AMIGA),
// King's Quest 1 (ST) 1.0V
// The original game did not have menus, they are enabled under ScummVM
@@ -298,7 +316,7 @@ static const AGIGameDescription gameDescriptions[] = {
GAME_P("kq2", "2.0A 1988-06-16 (CE)", "5203c8b95250a2ecfee93ddb99414753", 0x2917, GID_KQ2, Common::kPlatformApple2GS),
// King's Quest 2 (Amiga) 2.0J
- GAME_P("kq2", "2.0J 1987-01-29", "b866f0fab2fad91433a637a828cfa410", 0x2440, GID_KQ2, Common::kPlatformAmiga),
+ GAME_PO("kq2", "2.0J 1987-01-29", "b866f0fab2fad91433a637a828cfa410", 0x2440, GID_KQ2, Common::kPlatformAmiga, GAMEOPTIONS_AMIGA),
// King's Quest 2 (Mac) 2.0R
GAME_P("kq2", "2.0R 1988-03-23", "cbdb0083317c8e7cfb7ac35da4bc7fdc", 0x2440, GID_KQ2, Common::kPlatformMacintosh),
@@ -324,7 +342,7 @@ static const AGIGameDescription gameDescriptions[] = {
// King's Quest 3 (Amiga) 1.01 11/8/86
// The original game did not have menus, they are enabled under ScummVM
- GAME_FP("kq3", "1.01 1986-11-08", "8ab343306df0e2d98f136be4e8cfd0ef", 0x2440, GF_MENUS, GID_KQ3, Common::kPlatformAmiga),
+ GAME_FPO("kq3", "1.01 1986-11-08", "8ab343306df0e2d98f136be4e8cfd0ef", 0x2440, GF_MENUS, GID_KQ3, Common::kPlatformAmiga, GAMEOPTIONS_AMIGA),
// King's Quest 3 (ST) 1.02 11/18/86
// Does not have menus, crashes if menus are enforced. Therefore, ESC pauses the game
@@ -340,7 +358,7 @@ static const AGIGameDescription gameDescriptions[] = {
// Original pauses with ESC, has menus accessible with mouse.
// ver = 0x3086 -> menus accessible with ESC or mouse, bug #2835581 (KQ3: Game Crash When Leaving Tavern as Fly).
// ver = 0x3149 -> menus accessible with mouse, ESC pauses game, bug #2835581 disappears.
- GAME3_PS("kq3", "2.15 1989-11-15", "dirs", "8e35bded2bc5cf20f5eec2b15523b155", 1805, 0x3149, 0, GID_KQ3, Common::kPlatformAmiga),
+ GAME3_PSO("kq3", "2.15 1989-11-15", "dirs", "8e35bded2bc5cf20f5eec2b15523b155", 1805, 0x3149, 0, GID_KQ3, Common::kPlatformAmiga, GAMEOPTIONS_AMIGA),
// King's Quest 3 (PC) 1.01 11/08/86 [AGI 2.272]
// Does not have menus, crashes if menus are enforced. Therefore, ESC pauses the game
@@ -405,7 +423,7 @@ static const AGIGameDescription gameDescriptions[] = {
GAME_P("lsl1", "1.04 1987-06-18", "8b579f8673fe9448c2538f5ed9887cf0", 0x2440, GID_LSL1, Common::kPlatformAtariST),
// Leisure Suit Larry 1 (Amiga) 1.05 6/26/87 # x.yyy
- GAME_P("lsl1", "1.05 1987-06-26", "3f5d26d8834ca49c147fb60936869d56", 0x2440, GID_LSL1, Common::kPlatformAmiga),
+ GAME_PO("lsl1", "1.05 1987-06-26", "3f5d26d8834ca49c147fb60936869d56", 0x2440, GID_LSL1, Common::kPlatformAmiga, GAMEOPTIONS_AMIGA),
// Leisure Suit Larry 1 (IIgs) 1.0E
GAME_P("lsl1", "1.0E 1987", "5f9e1dd68d626c6d303131c119582ad4", 0x2440, GID_LSL1, Common::kPlatformApple2GS),
@@ -423,7 +441,7 @@ static const AGIGameDescription gameDescriptions[] = {
GAME3_P("mh1", "2.0E 1988-10-05 (CE)", "mhdir", "2f1509f76f24e6e7d213f2dadebbf156", 0x3149, 0, GID_MH1, Common::kPlatformApple2GS),
// Manhunter NY (Amiga) 1.06 3/18/89
- GAME3_P("mh1", "1.06 1989-03-18", "dirs", "92c6183042d1c2bb76236236a7d7a847", 0x3149, GF_OLDAMIGAV20, GID_MH1, Common::kPlatformAmiga),
+ GAME3_PO("mh1", "1.06 1989-03-18", "dirs", "92c6183042d1c2bb76236236a7d7a847", 0x3149, GF_OLDAMIGAV20, GID_MH1, Common::kPlatformAmiga, GAMEOPTIONS_AMIGA),
// reported by Filippos (thebluegr) in bugreport #1654500
// Manhunter NY (PC 5.25") 1.22 8/31/88 [AGI 3.002.107]
@@ -442,7 +460,7 @@ static const AGIGameDescription gameDescriptions[] = {
GAME3_P("mh2", "1.0 1989-07-29", "mh2dir", "5e3581495708b952fea24438a6c7e040", 0x3149, 0, GID_MH1, Common::kPlatformAtariST),
// Manhunter SF (Amiga) 3.06 8/17/89 # 2.333
- GAME3_PS("mh2", "3.06 1989-08-17", "dirs", "b412e8a126368b76696696f7632d4c16", 2573, 0x3086, GF_OLDAMIGAV20, GID_MH2, Common::kPlatformAmiga),
+ GAME3_PSO("mh2", "3.06 1989-08-17", "dirs", "b412e8a126368b76696696f7632d4c16", 2573, 0x3086, GF_OLDAMIGAV20, GID_MH2, Common::kPlatformAmiga, GAMEOPTIONS_AMIGA),
// Manhunter SF (PC 5.25") 3.03 8/17/89 [AGI 3.002.149]
GAME3("mh2", "3.03 1989-08-17 5.25\"", "mh2dir", "b90e4795413c43de469a715fb3c1fa93", 0x3149, GID_MH2),
@@ -464,7 +482,7 @@ static const AGIGameDescription gameDescriptions[] = {
// Mixed-Up Mother Goose (Amiga) 1.1
// Problematic: crashes
// Menus not tested
- GAME3_PS("mixedup", "1.1 1986-12-10", "dirs", "5c1295fe6daaf95831195ba12894dbd9", 2021, 0x3086, 0, GID_MIXEDUP, Common::kPlatformAmiga),
+ GAME3_PSO("mixedup", "1.1 1986-12-10", "dirs", "5c1295fe6daaf95831195ba12894dbd9", 2021, 0x3086, 0, GID_MIXEDUP, Common::kPlatformAmiga, GAMEOPTIONS_AMIGA),
#endif
// Mixed Up Mother Goose (IIgs)
@@ -486,7 +504,7 @@ static const AGIGameDescription gameDescriptions[] = {
GAME_P("pq1", "2.0B 1988-04-21", "e7c175918372336461e3811d594f482f", 0x2917, GID_PQ1, Common::kPlatformApple2GS),
// Police Quest 1 (Amiga) 2.0B 2/22/89 # 2.310
- GAME3_PS("pq1", "2.0B 1989-02-22", "dirs", "cfa93e5f2aa7378bddd10ad6746a2ffb", 1613, 0x3149, 0, GID_PQ1, Common::kPlatformAmiga),
+ GAME3_PSO("pq1", "2.0B 1989-02-22", "dirs", "cfa93e5f2aa7378bddd10ad6746a2ffb", 1613, 0x3149, 0, GID_PQ1, Common::kPlatformAmiga, GAMEOPTIONS_AMIGA),
// Police Quest 1 (IIgs) 2.0A-88318
GAME_P("pq1", "2.0A 1988-03-18", "8994e39d0901de3d07cecfb954075bb5", 0x2917, GID_PQ1, Common::kPlatformApple2GS),
@@ -524,7 +542,7 @@ static const AGIGameDescription gameDescriptions[] = {
// Space Quest 1 (Amiga) 1.2 # 2.082
// The original game did not have menus, they are enabled under ScummVM
- GAME_FP("sq1", "1.2 1986", "0b216d931e95750f1f4837d6a4b821e5", 0x2440, GF_MENUS | GF_OLDAMIGAV20, GID_SQ1, Common::kPlatformAmiga),
+ GAME_FPO("sq1", "1.2 1986", "0b216d931e95750f1f4837d6a4b821e5", 0x2440, GF_MENUS | GF_OLDAMIGAV20, GID_SQ1, Common::kPlatformAmiga, GAMEOPTIONS_AMIGA),
// Space Quest 1 (Mac) 1.5D
GAME_P("sq1", "1.5D 1987-04-02", "ce88419aadd073d1c6682d859b3d8aa2", 0x2440, GID_SQ1, Common::kPlatformMacintosh),
@@ -570,7 +588,7 @@ static const AGIGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO0()
+ GAMEOPTIONS_AMIGA
},
GID_SQ2,
GType_V2,
@@ -616,7 +634,7 @@ static const AGIGameDescription gameDescriptions[] = {
GAMEpre_P("winnie", "", "title.pic", "2e7900c1ccaa7671d65405f6d1efed30", 0x0000, GID_WINNIE, Common::kPlatformDOS),
// Winnie the Pooh in the Hundred Acre Wood (Amiga)
- GAMEpre_P("winnie", "", "title", "2e7900c1ccaa7671d65405f6d1efed30", 0x0000, GID_WINNIE, Common::kPlatformAmiga),
+ GAMEpre_PO("winnie", "", "title", "2e7900c1ccaa7671d65405f6d1efed30", 0x0000, GID_WINNIE, Common::kPlatformAmiga, GAMEOPTIONS_AMIGA),
// Winnie the Pooh in the Hundred Acre Wood (C64)
GAMEpre_P("winnie", "", "title.pic", "d4eb97cffc866110f71e1ec9f84fe643", 0x0000, GID_WINNIE, Common::kPlatformC64),
@@ -630,15 +648,15 @@ static const AGIGameDescription gameDescriptions[] = {
// Xmas Card 1986 (CoCo3 360k) [AGI 2.072]
GAME_PS("xmascard", "", "25ad35e9628fc77e5e0dd35852a272b6", 768, 0x2440, GID_XMASCARD, Common::kPlatformCoCo3),
- FANMADE_F("2 Player Demo", "4279f46b3cebd855132496476b1d2cca", GF_AGIMOUSE),
+ FANMADE_FO("2 Player Demo", "4279f46b3cebd855132496476b1d2cca", GF_AGIMOUSE, GAMEOPTIONS_FANMADE_MOUSE),
FANMADE("AGI Combat", "0be6a8a9e19203dcca0067d280798871"),
FANMADE("AGI Contest 1 Template", "d879aed25da6fc655564b29567358ae2"),
FANMADE("AGI Contest 2 Template", "5a2fb2894207eff36c72f5c1b08bcc07"),
- FANMADE("AGI Mouse Demo 0.60 demo 1", "c07e2519de674c67386cb2cc6f2e3904"),
- FANMADE("AGI Mouse Demo 0.60 demo 2", "cc49d8b88ed6faf4f53ce92c84e0fe1b"),
- FANMADE("AGI Mouse Demo 0.70", "3497c291e4afb6f758e61740678a2aec"),
- FANMADE_F("AGI Mouse Demo 1.00", "20397f0bf0ef936f416bb321fb768fc7", GF_AGIMOUSE),
- FANMADE_F("AGI Mouse Demo 1.10", "f4ad396b496d6167635ad0b410312ab8", GF_AGIMOUSE|GF_AGIPAL),
+ FANMADE_O("AGI Mouse Demo 0.60 demo 1", "c07e2519de674c67386cb2cc6f2e3904", GAMEOPTIONS_FANMADE_MOUSE),
+ FANMADE_O("AGI Mouse Demo 0.60 demo 2", "cc49d8b88ed6faf4f53ce92c84e0fe1b", GAMEOPTIONS_FANMADE_MOUSE),
+ FANMADE_O("AGI Mouse Demo 0.70", "3497c291e4afb6f758e61740678a2aec", GAMEOPTIONS_FANMADE_MOUSE),
+ FANMADE_FO("AGI Mouse Demo 1.00", "20397f0bf0ef936f416bb321fb768fc7", GF_AGIMOUSE, GAMEOPTIONS_FANMADE_MOUSE),
+ FANMADE_FO("AGI Mouse Demo 1.10", "f4ad396b496d6167635ad0b410312ab8", GF_AGIMOUSE|GF_AGIPAL, GAMEOPTIONS_FANMADE_MOUSE),
FANMADE("AGI Piano (v1.0)", "8778b3d89eb93c1d50a70ef06ef10310"),
FANMADE("AGI Quest (v1.46-TJ0)", "1cf1a5307c1a0a405f5039354f679814"),
GAME("tetris", "", "7a874e2db2162e7a4ce31c9130248d8a", 0x2917, GID_FANMADE),
@@ -657,15 +675,15 @@ static const AGIGameDescription gameDescriptions[] = {
FANMADE("Al Pond 1 - Al Lives Forever (v1.0)", "e8921c3043b749b056ff51f56d1b451b"),
FANMADE("Al Pond 1 - Al Lives Forever (v1.3)", "fb4699474054962e0dbfb4cf12ca52f6"),
FANMADE("Apocalyptic Quest (v0.03 Teaser)", "42ced528b67965d3bc3b52c635f94a57"),
- FANMADE_F("Apocalyptic Quest (v4.00 Alpha 1)", "e15581628d84949b8d352d224ec3184b", GF_AGIMOUSE),
- FANMADE_F("Apocalyptic Quest (v4.00 Alpha 2)", "0eee850005860e46345b38fea093d194", GF_AGIMOUSE),
- FANMADE_F("Band Quest (Demo)", "7326abefd793571cc17ed0db647bdf34", GF_AGIMOUSE),
- FANMADE_F("Band Quest (Early Demo)", "de4758dd34676b248c8301b32d93bc6f", GF_AGIMOUSE),
+ FANMADE_FO("Apocalyptic Quest (v4.00 Alpha 1)", "e15581628d84949b8d352d224ec3184b", GF_AGIMOUSE, GAMEOPTIONS_FANMADE_MOUSE),
+ FANMADE_FO("Apocalyptic Quest (v4.00 Alpha 2)", "0eee850005860e46345b38fea093d194", GF_AGIMOUSE, GAMEOPTIONS_FANMADE_MOUSE),
+ FANMADE_FO("Band Quest (Demo)", "7326abefd793571cc17ed0db647bdf34", GF_AGIMOUSE, GAMEOPTIONS_FANMADE_MOUSE),
+ FANMADE_FO("Band Quest (Early Demo)", "de4758dd34676b248c8301b32d93bc6f", GF_AGIMOUSE, GAMEOPTIONS_FANMADE_MOUSE),
FANMADE("Beyond the Titanic 2", "9b8de38dc64ffb3f52b7877ea3ebcef9"),
FANMADE("Biri Quest 1", "1b08f34f2c43e626c775c9d6649e2f17"),
FANMADE("Bob The Farmboy", "e4b7df9d0830addee5af946d380e66d7"),
- FANMADE_F("Boring Man 1: The Toad to Robinland", "d74481cbd227f67ace37ce6a5493039f", GF_AGIMOUSE),
- FANMADE_F("Boring Man 2: Ho Man! This Game Sucks!", "250032ba105bdf7c1bc4fed767c2d37e", GF_AGIMOUSE),
+ FANMADE_FO("Boring Man 1: The Toad to Robinland", "d74481cbd227f67ace37ce6a5493039f", GF_AGIMOUSE, GAMEOPTIONS_FANMADE_MOUSE),
+ FANMADE_FO("Boring Man 2: Ho Man! This Game Sucks!", "250032ba105bdf7c1bc4fed767c2d37e", GF_AGIMOUSE, GAMEOPTIONS_FANMADE_MOUSE),
FANMADE("Botz", "a8fabe4e807adfe5ec02bfec6d983695"),
FANMADE("Brian's Quest (v1.0)", "0964aa79b9cdcff7f33a12b1d7e04b9c"),
FANMADE("CPU-21 (v1.0)", "35b7cdb4d17e890e4c52018d96e9cbf4"),
@@ -676,12 +694,12 @@ static const AGIGameDescription gameDescriptions[] = {
FANMADE("Coco Coq (English) - Coco Coq In Grostesteing's Base (v.1.0.3)", "97631f8e710544a58bd6da9e780f9320"),
FANMADE_L("Coco Coq (French) - Coco Coq Dans la Base de Grostesteing (v1.0.2)", "ef579ebccfe5e356f9a557eb3b2d8649", Common::FR_FRA),
FANMADE("Corby's Murder Mystery (v1.0)", "4ebe62ac24c5a8c7b7898c8eb070efe5"),
- FANMADE_F("DG: The AGIMouse Adventure (English v1.1)", "efe453b92bc1487ea69fbebede4d5f26", GF_AGIMOUSE|GF_AGIPAL),
- FANMADE_LF("DG: The AGIMouse Adventure (French v1.1)", "eb3d17ca466d672cbb95947e8d6e846a", Common::FR_FRA, GF_AGIMOUSE|GF_AGIPAL),
+ FANMADE_FO("DG: The AGIMouse Adventure (English v1.1)", "efe453b92bc1487ea69fbebede4d5f26", GF_AGIMOUSE|GF_AGIPAL, GAMEOPTIONS_FANMADE_MOUSE),
+ FANMADE_LFO("DG: The AGIMouse Adventure (French v1.1)", "eb3d17ca466d672cbb95947e8d6e846a", Common::FR_FRA, GF_AGIMOUSE|GF_AGIPAL, GAMEOPTIONS_FANMADE_MOUSE),
FANMADE("DG: The Adventure Game (English v1.1)", "0d6376d493fa7a21ec4da1a063e12b25"),
FANMADE_L("DG: The Adventure Game (French v1.1)", "258bdb3bb8e61c92b71f2f456cc69e23", Common::FR_FRA),
FANMADE("Dashiki (16 Colors)", "9b2c7b9b0283ab9f12bedc0cb6770a07"),
- FANMADE_F("Dashiki (256 Colors)", "c68052bb209e23b39b55ff3d759958e6", GF_AGIMOUSE|GF_AGI256),
+ FANMADE_FO("Dashiki (256 Colors)", "c68052bb209e23b39b55ff3d759958e6", GF_AGIMOUSE|GF_AGI256, GAMEOPTIONS_FANMADE_MOUSE),
FANMADE("Date Quest 1 (v1.0)", "ba3dcb2600645be53a13170aa1a12e69"),
FANMADE("Date Quest 2 (v1.0 Demo)", "1602d6a2874856e928d9a8c8d2d166e9"),
FANMADE("Date Quest 2 (v1.0)", "f13f6fc85aa3e6e02b0c20408fb63b47"),
@@ -708,20 +726,20 @@ static const AGIGameDescription gameDescriptions[] = {
FANMADE("Good Man (demo v3.41)", "3facd8a8f856b7b6e0f6c3200274d88c"),
GAME_LVFPNF("agi-fanmade", "Groza (russian) [AGDS sample]", "logdir", "421da3a18004122a966d64ab6bd86d2e", -1,
- Common::RU_RUS, 0x2440, GF_AGDS, GID_FANMADE, Common::kPlatformDOS,GType_V2),
+ Common::RU_RUS, 0x2440, GF_AGDS, GID_FANMADE, Common::kPlatformDOS,GType_V2,GAMEOPTIONS_DEFAULT),
GAME_LVFPNF("agi-fanmade", "Get Outta Space Quest", "logdir", "aaea5b4a348acb669d13b0e6f22d4dc9", -1,
- Common::EN_ANY, 0x2440, GF_FANMADE, GID_GETOUTTASQ, Common::kPlatformDOS,GType_V2),
+ Common::EN_ANY, 0x2440, GF_FANMADE, GID_GETOUTTASQ, Common::kPlatformDOS,GType_V2,GAMEOPTIONS_DEFAULT),
- FANMADE_F("Half-Death - Terror At White-Mesa", "b62c05d0ace878261392073f57ae788c", GF_AGIMOUSE),
+ FANMADE_FO("Half-Death - Terror At White-Mesa", "b62c05d0ace878261392073f57ae788c", GF_AGIMOUSE, GAMEOPTIONS_FANMADE_MOUSE),
FANMADE("Hank's Quest (v1.0 English) - Victim of Society", "64c15b3d0483d17888129100dc5af213"),
FANMADE("Hank's Quest (v1.1 English) - Victim of Society", "86d1f1dd9b0c4858d096e2a60cca8a14"),
FANMADE_L("Hank's Quest (v1.81 Dutch) - Slachtoffer Van Het Gebeuren", "41e53972d55ff3dff9e90d15fe1b659f", Common::NL_NLD),
FANMADE("Hank's Quest (v1.81 English) - Victim of Society", "7a776383282f62a57c3a960dafca62d1"),
FANMADE("Herbao (v0.2)", "6a5186fc8383a9060517403e85214fc2"),
- FANMADE_F("Hitler's Legacy (v.0004q)", "a412881269ba34584bd0a3268e5a9863", GF_AGIMOUSE),
+ FANMADE_FO("Hitler's Legacy (v.0004q)", "a412881269ba34584bd0a3268e5a9863", GF_AGIMOUSE, GAMEOPTIONS_FANMADE_MOUSE),
FANMADE("Hobbits", "4a1c1ef3a7901baf0ab45fde0cfadd89"),
- FANMADE_F("Isabella Coq - A Present For My Dad", "55c6819f2330c4d5d6459874c9f123d9", GF_AGIMOUSE),
+ FANMADE_FO("Isabella Coq - A Present For My Dad", "55c6819f2330c4d5d6459874c9f123d9", GF_AGIMOUSE, GAMEOPTIONS_FANMADE_MOUSE),
FANMADE("Jack & Julia - VAMPYR", "8aa0b9a26f8d5a4421067ab8cc3706f6"),
FANMADE("Jeff's Quest (v.5 alpha Jun 1)", "10f1720eed40c12b02a0f32df3e72ded"),
FANMADE("Jeff's Quest (v.5 alpha May 31)", "51ff71c0ed90db4e987a488ed3bf0551"),
@@ -730,8 +748,8 @@ static const AGIGameDescription gameDescriptions[] = {
FANMADE("Jiggy Jiggy Uh! Uh!", "bc331588a71e7a1c8840f6cc9b9487e4"),
FANMADE("Jimmy In: The Alien Attack (v0.1)", "a4e9db0564a494728de7873684a4307c"),
FANMADE("Joe McMuffin In \"What's Cooking, Doc\" (v1.0)", "8a3de7e61a99cb605fa6d233dd91c8e1"),
- FANMADE_LVF("Jolimie, le Village Maudit (v0.5)", "21818501636b3cb8ad5de5c1a66de5c2", Common::FR_FRA, 0x2936, GF_AGIMOUSE|GF_AGIPAL),
- FANMADE_LVF("Jolimie, le Village Maudit (v1.1)", "68d7aef1161bb5972fe03efdf29ccb7f", Common::FR_FRA, 0x2936, GF_AGIMOUSE|GF_AGIPAL),
+ FANMADE_LVFO("Jolimie, le Village Maudit (v0.5)", "21818501636b3cb8ad5de5c1a66de5c2", Common::FR_FRA, 0x2936, GF_AGIMOUSE|GF_AGIPAL, GAMEOPTIONS_FANMADE_MOUSE),
+ FANMADE_LVFO("Jolimie, le Village Maudit (v1.1)", "68d7aef1161bb5972fe03efdf29ccb7f", Common::FR_FRA, 0x2936, GF_AGIMOUSE|GF_AGIPAL, GAMEOPTIONS_FANMADE_MOUSE),
FANMADE("Journey Of Chef", "aa0a0b5a6364801ae65fdb96d6741df5"),
FANMADE("Jukebox (v1.0)", "c4b9c5528cc67f6ba777033830de7751"),
FANMADE("Justin Quest (v1.0 in development)", "103050989da7e0ffdc1c5e1793a4e1ec"),
@@ -747,18 +765,18 @@ static const AGIGameDescription gameDescriptions[] = {
FANMADE("MD Quest - The Search for Michiel (v0.10)", "2a6fcb21d2b5e4144c38ed817fabe8ee"),
FANMADE("Maale Adummin Quest", "ddfbeb33feb7cf78504fe4dba14ec63b"),
FANMADE("Monkey Man", "2322d03f997e8cc235d4578efff69cfa"),
- FANMADE_F("Napalm Quest (v0.5)", "b659afb491d967bb34810d1c6ce22093", GF_AGIMOUSE),
+ FANMADE_FO("Napalm Quest (v0.5)", "b659afb491d967bb34810d1c6ce22093", GF_AGIMOUSE, GAMEOPTIONS_FANMADE_MOUSE),
FANMADE("Naturette 1 (English v1.2)", "0a75884e7f010974a230bdf269651117"),
FANMADE("Naturette 1 (English v1.3)", "f15bbf999ac55ebd404aa1eb84f7c1d9"),
FANMADE_L("Naturette 1 (French v1.2)", "d3665622cc41aeb9c7ecf4fa43f20e53", Common::FR_FRA),
- FANMADE_F("Naturette 2: Daughter of the Moon (v1.0)", "bdf76a45621c7f56d1c9d40292c6137a", GF_AGIMOUSE|GF_AGIPAL),
- FANMADE_F("Naturette 3: Adventure in Treeworld (v1.0a)", "6dbb0e7fc75fec442e6d9e5a06f1530e", GF_AGIMOUSE|GF_AGIPAL),
- FANMADE_F("Naturette 4: From a Planet to Another Planet (Not Finished)", "13be8cd9cf35aeff0a39b8757057fbc8", GF_AGIMOUSE),
+ FANMADE_FO("Naturette 2: Daughter of the Moon (v1.0)", "bdf76a45621c7f56d1c9d40292c6137a", GF_AGIMOUSE|GF_AGIPAL, GAMEOPTIONS_FANMADE_MOUSE),
+ FANMADE_FO("Naturette 3: Adventure in Treeworld (v1.0a)", "6dbb0e7fc75fec442e6d9e5a06f1530e", GF_AGIMOUSE|GF_AGIPAL, GAMEOPTIONS_FANMADE_MOUSE),
+ FANMADE_FO("Naturette 4: From a Planet to Another Planet (Not Finished)", "13be8cd9cf35aeff0a39b8757057fbc8", GF_AGIMOUSE, GAMEOPTIONS_FANMADE_MOUSE),
// FIXME: Actually Naturette 4 has both English and French language support built into it. How to add that information?
- FANMADE_F("Naturette 4: From a Planet to Another Planet (2007-10-05)", "8253706b6ef5423a79413b216760297c", GF_AGIMOUSE|GF_AGIPAL),
+ FANMADE_FO("Naturette 4: From a Planet to Another Planet (2007-10-05)", "8253706b6ef5423a79413b216760297c", GF_AGIMOUSE|GF_AGIPAL, GAMEOPTIONS_FANMADE_MOUSE),
FANMADE("New AGI Hangman Test", "d69c0e9050ccc29fd662b74d9fc73a15"),
FANMADE("Nick's Quest - In Pursuit of QuakeMovie (v2.1 Gold)", "e29cbf9222551aee40397fabc83eeca0"),
- FANMADE_F("Open Mic Night (v0.1)", "70000a2f67aac27d1133d019df70246d", GF_AGIMOUSE|GF_AGIPAL),
+ FANMADE_FO("Open Mic Night (v0.1)", "70000a2f67aac27d1133d019df70246d", GF_AGIMOUSE|GF_AGIPAL, GAMEOPTIONS_FANMADE_MOUSE),
FANMADE("Operation: Recon", "0679ce8405411866ccffc8a6743370d0"),
FANMADE("Patrick's Quest (Demo v1.0)", "f254f5b894b98fec5f92acc07fb62841"),
FANMADE("Phantasmagoria", "87d20c1c11aee99a4baad3797b63146b"),
@@ -802,14 +820,14 @@ static const AGIGameDescription gameDescriptions[] = {
FANMADE("Save Santa (v1.3)", "f8afdb6efc5af5e7c0228b44633066af"),
FANMADE("Schiller (preview 1)", "ade39dea968c959cfebe1cf935d653e9"),
FANMADE("Schiller (preview 2)", "62cd1f8fc758bf6b4aa334e553624cef"),
- GAME_F("serguei1", "v1.0", "b86725f067e456e10cdbdf5f58e01dec", 0x2917, GF_FANMADE|GF_AGIMOUSE|GF_AGIPAL, GID_FANMADE),
+ GAME_FO("serguei1", "v1.0", "b86725f067e456e10cdbdf5f58e01dec", 0x2917, GF_FANMADE|GF_AGIMOUSE|GF_AGIPAL, GID_FANMADE, GAMEOPTIONS_FANMADE_MOUSE),
// FIXME: The following two entries have identical MD5 checksums?
- GAME_F("serguei1", "v1.1 2002 Sep 5", "91975c1fb4b13b0f9a8e9ff74731030d", 0x2917, GF_FANMADE|GF_AGIMOUSE|GF_AGIPAL, GID_FANMADE),
- GAME_F("serguei1", "v1.1 2003 Apr 10", "91975c1fb4b13b0f9a8e9ff74731030d", 0x2917, GF_FANMADE|GF_AGIMOUSE|GF_AGIPAL, GID_FANMADE),
- GAME_F("serguei2", "v0.1.1 Demo", "906ccbc2ddedb29b63141acc6d10cd28", 0x2917, GF_FANMADE|GF_AGIMOUSE, GID_FANMADE),
- GAME_F("serguei2", "v1.3.1 Demo (March 22nd 2008)", "ad1308fcb8f48723cd388e012ebf5e20", 0x2917, GF_FANMADE|GF_AGIMOUSE|GF_AGIPAL, GID_FANMADE),
+ GAME_FO("serguei1", "v1.1 2002 Sep 5", "91975c1fb4b13b0f9a8e9ff74731030d", 0x2917, GF_FANMADE|GF_AGIMOUSE|GF_AGIPAL, GID_FANMADE, GAMEOPTIONS_FANMADE_MOUSE),
+ GAME_FO("serguei1", "v1.1 2003 Apr 10", "91975c1fb4b13b0f9a8e9ff74731030d", 0x2917, GF_FANMADE|GF_AGIMOUSE|GF_AGIPAL, GID_FANMADE, GAMEOPTIONS_FANMADE_MOUSE),
+ GAME_FO("serguei2", "v0.1.1 Demo", "906ccbc2ddedb29b63141acc6d10cd28", 0x2917, GF_FANMADE|GF_AGIMOUSE, GID_FANMADE, GAMEOPTIONS_FANMADE_MOUSE),
+ GAME_FO("serguei2", "v1.3.1 Demo (March 22nd 2008)", "ad1308fcb8f48723cd388e012ebf5e20", 0x2917, GF_FANMADE|GF_AGIMOUSE|GF_AGIPAL, GID_FANMADE, GAMEOPTIONS_FANMADE_MOUSE),
FANMADE("Shifty (v1.0)", "2a07984d27b938364bf6bd243ac75080"),
- FANMADE_F("Sliding Tile Game (v1.00)", "949bfff5d8a81c3139152eed4d84ca75", GF_AGIMOUSE),
+ FANMADE_FO("Sliding Tile Game (v1.00)", "949bfff5d8a81c3139152eed4d84ca75", GF_AGIMOUSE, GAMEOPTIONS_FANMADE_MOUSE),
FANMADE("Snowboarding Demo (v1.0)", "24bb8f29f1eddb5c0a099705267c86e4"),
FANMADE("Solar System Tour", "b5a3d0f392dfd76a6aa63f3d5f578403"),
FANMADE("Sorceror's Appraisal", "fe62615557b3cb7b08dd60c9d35efef1"),
@@ -819,7 +837,7 @@ static const AGIGameDescription gameDescriptions[] = {
GAME("sqx", "v10.0 Feb 05", "c992ae2f8ab18360404efdf16fa9edd1", 0x2917, GID_FANMADE),
GAME("sqx", "v10.0 Jul 18", "812edec45cefad559d190ffde2f9c910", 0x2917, GID_FANMADE),
GAME_PS("sqx", "", "f0a59044475a5fa37c055d8c3eb4d1a7", 768, 0x2440, GID_FANMADE, Common::kPlatformCoCo3),
- FANMADE_F("Space Quest 3.5", "c077bc28d7b36213dd99dc9ecb0147fc", GF_AGIMOUSE|GF_AGIPAL),
+ FANMADE_FO("Space Quest 3.5", "c077bc28d7b36213dd99dc9ecb0147fc", GF_AGIMOUSE|GF_AGIPAL, GAMEOPTIONS_FANMADE_MOUSE),
FANMADE_F("Space Trek (v1.0)", "807a1aeadb2ace6968831d36ab5ea37a", GF_CLIPCOORDS),
FANMADE("Special Delivery", "88764dfe61126b8e73612c851b510a33"),
FANMADE("Speeder Bike Challenge (v1.0)", "2deb25bab379285ca955df398d96c1e7"),
@@ -862,7 +880,7 @@ static const AGIGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_USEEXTRAASTITLE,
- GUIO0()
+ GAMEOPTIONS_DEFAULT
},
GID_FANMADE,
GType_V3,
@@ -890,7 +908,7 @@ static AGIGameDescription g_fallbackDesc = {
Common::UNK_LANG,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
- GUIO0()
+ GAMEOPTIONS_DEFAULT
},
GID_FANMADE,
GType_V2,
diff --git a/engines/agi/font.h b/engines/agi/font.h
index c77d8cf0c3..0e6b15f06b 100644
--- a/engines/agi/font.h
+++ b/engines/agi/font.h
@@ -26,7 +26,7 @@
namespace Agi {
// 8x8 font patterns
-static const uint8 curFont[] = {
+static const uint8 fontData_Sierra[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x7E, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7E, // cursor hollow
0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, // cursor solid
@@ -59,6 +59,267 @@ static const uint8 curFont[] = {
0x00, 0x24, 0x42, 0xFF, 0x42, 0x24, 0x00, 0x00,
0x00, 0x10, 0x38, 0x7C, 0xFE, 0xFE, 0x00, 0x00,
0x00, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x00,
+ // original sierra font starts here
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20 Space
+ 0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00,
+ 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00,
+ 0x30, 0x7C, 0xC0, 0x78, 0x0C, 0xF8, 0x30, 0x00,
+ 0x00, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xC6, 0x00,
+ 0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00,
+ 0x60, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00,
+ 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00,
+ 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00,
+ 0x00, 0x30, 0x30, 0xFC, 0x30, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60,
+ 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00,
+ 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00,
+ 0x7C, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0x7C, 0x00, // 0x30
+ 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xFC, 0x00,
+ 0x78, 0xCC, 0x0C, 0x38, 0x60, 0xCC, 0xFC, 0x00,
+ 0x78, 0xCC, 0x0C, 0x38, 0x0C, 0xCC, 0x78, 0x00,
+ 0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x1E, 0x00,
+ 0xFC, 0xC0, 0xF8, 0x0C, 0x0C, 0xCC, 0x78, 0x00,
+ 0x38, 0x60, 0xC0, 0xF8, 0xCC, 0xCC, 0x78, 0x00,
+ 0xFC, 0xCC, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00,
+ 0x78, 0xCC, 0xCC, 0x78, 0xCC, 0xCC, 0x78, 0x00,
+ 0x78, 0xCC, 0xCC, 0x7C, 0x0C, 0x18, 0x70, 0x00,
+ 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00,
+ 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60,
+ 0x18, 0x30, 0x60, 0xC0, 0x60, 0x30, 0x18, 0x00,
+ 0x00, 0x00, 0xFC, 0x00, 0x00, 0xFC, 0x00, 0x00,
+ 0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00,
+ 0x78, 0xCC, 0x0C, 0x18, 0x30, 0x00, 0x30, 0x00,
+ 0x7C, 0xC6, 0xDE, 0xDE, 0xDE, 0xC0, 0x78, 0x00, // 0x40
+ 0x30, 0x78, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0x00,
+ 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00,
+ 0x3C, 0x66, 0xC0, 0xC0, 0xC0, 0x66, 0x3C, 0x00,
+ 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00,
+ 0xFE, 0x62, 0x68, 0x78, 0x68, 0x62, 0xFE, 0x00,
+ 0xFE, 0x62, 0x68, 0x78, 0x68, 0x60, 0xF0, 0x00,
+ 0x3C, 0x66, 0xC0, 0xC0, 0xCE, 0x66, 0x3E, 0x00,
+ 0xCC, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0xCC, 0x00,
+ 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
+ 0x1E, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00,
+ 0xE6, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00,
+ 0xF0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00,
+ 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00,
+ 0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0xC6, 0x00,
+ 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00,
+ 0xFC, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00, // 0x50
+ 0x78, 0xCC, 0xCC, 0xCC, 0xDC, 0x78, 0x1C, 0x00,
+ 0xFC, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0xE6, 0x00,
+ 0x78, 0xCC, 0xE0, 0x70, 0x1C, 0xCC, 0x78, 0x00,
+ 0xFC, 0xB4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xFC, 0x00,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00,
+ 0xC6, 0xC6, 0xC6, 0xD6, 0xFE, 0xEE, 0xC6, 0x00,
+ 0xC6, 0xC6, 0x6C, 0x38, 0x38, 0x6C, 0xC6, 0x00,
+ 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x30, 0x78, 0x00,
+ 0xFE, 0xC6, 0x8C, 0x18, 0x32, 0x66, 0xFE, 0x00,
+ 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00,
+ 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x02, 0x00,
+ 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00,
+ 0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60
+ 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
+ 0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xDC, 0x00,
+ 0x00, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00,
+ 0x1C, 0x0C, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00,
+ 0x00, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00,
+ 0x38, 0x6C, 0x60, 0xF0, 0x60, 0x60, 0xF0, 0x00,
+ 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8,
+ 0xE0, 0x60, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00,
+ 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
+ 0x0C, 0x00, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78,
+ 0xE0, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0xE6, 0x00,
+ 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
+ 0x00, 0x00, 0xCC, 0xFE, 0xFE, 0xD6, 0xC6, 0x00,
+ 0x00, 0x00, 0xF8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00,
+ 0x00, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00,
+ 0x00, 0x00, 0xDC, 0x66, 0x66, 0x7C, 0x60, 0xF0, // 0x70
+ 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0x1E,
+ 0x00, 0x00, 0xDC, 0x76, 0x66, 0x60, 0xF0, 0x00,
+ 0x00, 0x00, 0x7C, 0xC0, 0x78, 0x0C, 0xF8, 0x00,
+ 0x10, 0x30, 0x7C, 0x30, 0x30, 0x34, 0x18, 0x00,
+ 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
+ 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00,
+ 0x00, 0x00, 0xC6, 0xD6, 0xFE, 0xFE, 0x6C, 0x00,
+ 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00,
+ 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8,
+ 0x00, 0x00, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00,
+ 0x1C, 0x30, 0x30, 0xE0, 0x30, 0x30, 0x1C, 0x00,
+ 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00,
+ 0xE0, 0x30, 0x30, 0x1C, 0x30, 0x30, 0xE0, 0x00,
+ 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ // custom font starting here at 0x80
+ 0x1E, 0x36, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x00, // 0x80
+ 0x7C, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x7C, 0x00,
+ 0x7C, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x7C, 0x00,
+ 0x7E, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x00,
+ 0x38, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0xFE, 0xC6,
+ 0x7E, 0x60, 0x60, 0x7C, 0x60, 0x60, 0x7E, 0x00,
+ 0xDB, 0xDB, 0x7E, 0x3C, 0x7E, 0xDB, 0xDB, 0x00,
+ 0x3C, 0x66, 0x06, 0x1C, 0x06, 0x66, 0x3C, 0x00,
+ 0x66, 0x66, 0x6E, 0x7E, 0x76, 0x66, 0x66, 0x00,
+ 0x3C, 0x66, 0x6E, 0x7E, 0x76, 0x66, 0x66, 0x00,
+ 0x66, 0x6C, 0x78, 0x70, 0x78, 0x6C, 0x66, 0x00,
+ 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00,
+ 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00,
+ 0x66, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00,
+ 0x3C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00,
+ 0x7E, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00,
+ 0x7C, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x00,
+ 0x3C, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3C, 0x00,
+ 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00,
+ 0x66, 0x66, 0x66, 0x3E, 0x06, 0x66, 0x3C, 0x00,
+ 0x7E, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x18, 0x00,
+ 0x66, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x66, 0x00,
+ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7F, 0x03,
+ 0x66, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x06, 0x00,
+ 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xFF, 0x00,
+ 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xFF, 0x03,
+ 0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x7C, 0x00,
+ 0xC6, 0xC6, 0xC6, 0xF6, 0xDE, 0xDE, 0xF6, 0x00,
+ 0x60, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x7C, 0x00,
+ 0x78, 0x8C, 0x06, 0x3E, 0x06, 0x8C, 0x78, 0x00,
+ 0xCE, 0xDB, 0xDB, 0xFB, 0xDB, 0xDB, 0xCE, 0x00,
+ 0x3E, 0x66, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x00,
+ 0x00, 0x00, 0x3C, 0x06, 0x3E, 0x66, 0x3A, 0x00,
+ 0x00, 0x3C, 0x60, 0x3C, 0x66, 0x66, 0x3C, 0x00,
+ 0x00, 0x00, 0x7C, 0x66, 0x7C, 0x66, 0x7C, 0x00,
+ 0x00, 0x00, 0x7E, 0x60, 0x60, 0x60, 0x60, 0x00,
+ 0x00, 0x00, 0x3C, 0x6C, 0x6C, 0x6C, 0xFE, 0xC6,
+ 0x00, 0x00, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00,
+ 0x00, 0x00, 0xDB, 0x7E, 0x3C, 0x7E, 0xDB, 0x00,
+ 0x00, 0x00, 0x3C, 0x66, 0x0C, 0x66, 0x3C, 0x00,
+ 0x00, 0x00, 0x66, 0x6E, 0x7E, 0x76, 0x66, 0x00,
+ 0x00, 0x18, 0x66, 0x6E, 0x7E, 0x76, 0x66, 0x00,
+ 0x00, 0x00, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0x00,
+ 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x00,
+ 0x00, 0x00, 0xC6, 0xFE, 0xFE, 0xD6, 0xC6, 0x00,
+ 0x00, 0x00, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x00,
+ 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x00,
+ 0x00, 0x00, 0x7E, 0x66, 0x66, 0x66, 0x66, 0x00,
+ 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
+ 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
+ 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18,
+ 0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36, 0x36,
+ 0x00, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18,
+ 0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x00, 0xFE, 0x06, 0xF6, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00, 0x00,
+ 0x36, 0x36, 0x36, 0xFE, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0xF8, 0x18, 0xF8, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x18,
+ 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
+ 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36, 0x36,
+ 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0x36, 0x36, 0x36, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x3F, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x3F, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0xFF, 0x36, 0x36, 0x36, 0x36,
+ 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0xF8, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18, 0x18,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
+ 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x00,
+ 0x00, 0x00, 0x3C, 0x66, 0x60, 0x66, 0x3C, 0x00,
+ 0x00, 0x00, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x00,
+ 0x00, 0x00, 0x66, 0x66, 0x3E, 0x06, 0x7C, 0x00,
+ 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0x7E, 0x18, 0x00,
+ 0x00, 0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x00,
+ 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x7F, 0x03,
+ 0x00, 0x00, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x00,
+ 0x00, 0x00, 0xDB, 0xDB, 0xDB, 0xDB, 0xFF, 0x00,
+ 0x00, 0x00, 0xDB, 0xDB, 0xDB, 0xDB, 0xFF, 0x03,
+ 0x00, 0x00, 0xE0, 0x60, 0x7C, 0x66, 0x7C, 0x00,
+ 0x00, 0x00, 0xC6, 0xC6, 0xF6, 0xDE, 0xF6, 0x00,
+ 0x00, 0x00, 0x60, 0x60, 0x7C, 0x66, 0x7C, 0x00,
+ 0x00, 0x00, 0x7C, 0x06, 0x3E, 0x06, 0x7C, 0x00,
+ 0x00, 0x00, 0xCE, 0xDB, 0xFB, 0xDB, 0xCE, 0x00,
+ 0x00, 0x00, 0x3E, 0x66, 0x3E, 0x36, 0x66, 0x00,
+ 0x00, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00,
+ 0x10, 0x10, 0x7C, 0x10, 0x10, 0x00, 0x7C, 0x00,
+ 0x00, 0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30,
+ 0x00, 0x0C, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C,
+ 0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8, 0x70,
+ 0x00, 0x18, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x18,
+ 0x00, 0x76, 0xDC, 0x00, 0x76, 0xDC, 0x00, 0x00,
+ 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x00,
+ 0x03, 0x02, 0x06, 0x04, 0xCC, 0x68, 0x38, 0x10,
+ 0x3C, 0x42, 0x99, 0xA1, 0xA1, 0x99, 0x42, 0x3C,
+ 0x30, 0x48, 0x10, 0x20, 0x78, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7C, 0x7C, 0x7C, 0x7C, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x7E, 0x00
+};
+
+static const uint8 fontData_FanGames[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x7E, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7E, /* cursor hollow */
+ 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, /* cursor solid */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* cursor empty */
+ 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00,
+ 0x3C, 0x3C, 0x18, 0xFF, 0xE7, 0x18, 0x3C, 0x00,
+ 0x10, 0x38, 0x7C, 0xFE, 0xEE, 0x10, 0x38, 0x00,
+ 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00,
+ 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF,
+ 0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* \n */
+ 0x0F, 0x07, 0x0F, 0x7D, 0xCC, 0xCC, 0xCC, 0x78,
+ 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18,
+ 0x08, 0x0C, 0x0A, 0x0A, 0x08, 0x78, 0xF0, 0x00,
+ 0x18, 0x14, 0x1A, 0x16, 0x72, 0xE2, 0x0E, 0x1C,
+ 0x10, 0x54, 0x38, 0xEE, 0x38, 0x54, 0x10, 0x00,
+ 0x80, 0xE0, 0xF8, 0xFE, 0xF8, 0xE0, 0x80, 0x00,
+ 0x02, 0x0E, 0x3E, 0xFE, 0x3E, 0x0E, 0x02, 0x00,
+ 0x18, 0x3C, 0x5A, 0x18, 0x5A, 0x3C, 0x18, 0x00,
+ 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00,
+ 0x7F, 0xDB, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x00,
+ 0x1C, 0x22, 0x38, 0x44, 0x44, 0x38, 0x88, 0x70,
+ 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x00,
+ 0x18, 0x3C, 0x5A, 0x18, 0x5A, 0x3C, 0x18, 0x7E,
+ 0x18, 0x3C, 0x5A, 0x18, 0x18, 0x18, 0x18, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0x5A, 0x3C, 0x18, 0x00,
+ 0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00,
+ 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00,
+ 0x00, 0x24, 0x42, 0xFF, 0x42, 0x24, 0x00, 0x00,
+ 0x00, 0x10, 0x38, 0x7C, 0xFE, 0xFE, 0x00, 0x00,
+ 0x00, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00,
0x6C, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -154,9 +415,7 @@ static const uint8 curFont[] = {
0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00,
0xE0, 0x30, 0x30, 0x18, 0x30, 0x30, 0xE0, 0x00,
0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, //replacement 0x7F
-
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /*replacement 0x7F */
0x1E, 0x36, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x00,
0x7C, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x7C, 0x00,
0x7C, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x7C, 0x00,
@@ -287,7 +546,7 @@ static const uint8 curFont[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x7E, 0x00
};
-static const uint8 mickey_fontdata[] = {
+static const uint8 fontData_Mickey[] = {
0x00, 0x36, 0x7F, 0x7F, 0x3E, 0x1C, 0x08, 0x00,
0x00, 0x00, 0x3F, 0x20, 0x2F, 0x28, 0x28, 0x28,
0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
@@ -546,7 +805,7 @@ static const uint8 mickey_fontdata[] = {
0x10, 0x18, 0x1C, 0x1E, 0x1C, 0x18, 0x10, 0x00,
};
-static const uint8 ibm_fontdata[] = {
+static const uint8 fontData_IBM[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E,
0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E,
diff --git a/engines/agi/graphics.cpp b/engines/agi/graphics.cpp
index 2b1bd8c829..c5cede71ef 100644
--- a/engines/agi/graphics.cpp
+++ b/engines/agi/graphics.cpp
@@ -72,6 +72,7 @@ static const uint8 egaPalette[16 * 3] = {
* from Donald Duck's Playground (1986) to Manhunter II (1989).
* 16 RGB colors. 3 bits per color component.
*/
+#if 0
static const uint8 atariStAgiPalette[16 * 3] = {
0x0, 0x0, 0x0,
0x0, 0x0, 0x7,
@@ -90,6 +91,7 @@ static const uint8 atariStAgiPalette[16 * 3] = {
0x7, 0x7, 0x4,
0x7, 0x7, 0x7
};
+#endif
/**
* Second generation Apple IIGS AGI palette.
@@ -109,6 +111,8 @@ static const uint8 atariStAgiPalette[16 * 3] = {
* 3.001 (Black Cauldron v1.0O 1989-02-24 (CE))
* 3.003 (Gold Rush! v1.0M 1989-02-28 (CE))
*/
+#if 0
+// FIXME: Identical to amigaAgiPaletteV2
static const uint8 appleIIgsAgiPaletteV2[16 * 3] = {
0x0, 0x0, 0x0,
0x0, 0x0, 0xF,
@@ -127,6 +131,7 @@ static const uint8 appleIIgsAgiPaletteV2[16 * 3] = {
0xE, 0xE, 0x0,
0xF, 0xF, 0xF
};
+#endif
/**
* First generation Amiga & Apple IIGS AGI palette.
@@ -616,6 +621,8 @@ void GfxMgr::putTextCharacter(int l, int x, int y, unsigned char c, int fg, int
int x1, y1, xx, yy, cc;
const uint8 *p;
+ assert(font);
+
p = font + ((unsigned int)c * CHAR_LINES);
for (y1 = 0; y1 < CHAR_LINES; y1++) {
for (x1 = 0; x1 < CHAR_COLS; x1++) {
@@ -699,7 +706,7 @@ void GfxMgr::printCharacter(int x, int y, char c, int fg, int bg) {
x *= CHAR_COLS;
y *= CHAR_LINES;
- putTextCharacter(0, x, y, c, fg, bg);
+ putTextCharacter(0, x, y, c, fg, bg, false, _vm->getFontData());
// redundant! already inside put_text_character!
// flush_block (x, y, x + CHAR_COLS - 1, y + CHAR_LINES - 1);
}
@@ -754,7 +761,7 @@ void GfxMgr::rawDrawButton(int x, int y, const char *s, int fgcolor, int bgcolor
drawRectangle(x1, y1, x2, y2, border ? BUTTON_BORDER : MSG_BOX_COLOR);
while (*s) {
- putTextCharacter(0, x + textOffset, y + textOffset, *s++, fgcolor, bgcolor);
+ putTextCharacter(0, x + textOffset, y + textOffset, *s++, fgcolor, bgcolor, false, _vm->getFontData());
x += CHAR_COLS;
}
diff --git a/engines/agi/graphics.h b/engines/agi/graphics.h
index 15668fbed3..506a9d93d6 100644
--- a/engines/agi/graphics.h
+++ b/engines/agi/graphics.h
@@ -56,7 +56,7 @@ public:
void gfxPutBlock(int x1, int y1, int x2, int y2);
- void putTextCharacter(int, int, int, unsigned char, int, int, bool checkerboard = false, const uint8 *font = curFont);
+ void putTextCharacter(int, int, int, unsigned char, int, int, bool checkerboard = false, const uint8 *font = fontData_Sierra);
void shakeScreen(int);
void shakeStart();
void shakeEnd();
diff --git a/engines/agi/loader_v2.cpp b/engines/agi/loader_v2.cpp
index 787eeaa0c7..693c53c2bf 100644
--- a/engines/agi/loader_v2.cpp
+++ b/engines/agi/loader_v2.cpp
@@ -135,13 +135,13 @@ int AgiLoader_v2::unloadResource(int t, int n) {
*/
uint8 *AgiLoader_v2::loadVolRes(struct AgiDir *agid) {
uint8 *data = NULL;
- char x[MAXPATHLEN], *path;
+ char x[6];
Common::File fp;
unsigned int sig;
+ Common::String path;
- sprintf(x, "vol.%i", agid->volume);
- path = x;
- debugC(3, kDebugLevelResources, "Vol res: path = %s", path);
+ path = Common::String::format("vol.%i", agid->volume);
+ debugC(3, kDebugLevelResources, "Vol res: path = %s", path.c_str());
if (agid->offset != _EMPTY && fp.open(path)) {
debugC(3, kDebugLevelResources, "loading resource at offset %d", agid->offset);
diff --git a/engines/agi/loader_v3.cpp b/engines/agi/loader_v3.cpp
index fa135e5476..39759b4649 100644
--- a/engines/agi/loader_v3.cpp
+++ b/engines/agi/loader_v3.cpp
@@ -198,14 +198,13 @@ int AgiLoader_v3::unloadResource(int t, int n) {
* NULL is returned if unsucsessful.
*/
uint8 *AgiLoader_v3::loadVolRes(AgiDir *agid) {
- char x[MAXPATHLEN];
+ char x[8];
uint8 *data = NULL, *compBuffer;
Common::File fp;
Common::String path;
debugC(3, kDebugLevelResources, "(%p)", (void *)agid);
- sprintf(x, "vol.%i", agid->volume);
- path = Common::String(_vm->_game.name) + x;
+ path = Common::String::format("%svol.%i", _vm->_game.name, agid->volume);
if (agid->offset != _EMPTY && fp.open(path)) {
fp.seek(agid->offset, SEEK_SET);
diff --git a/engines/agi/preagi.cpp b/engines/agi/preagi.cpp
index daadb5ffef..c368c7b195 100644
--- a/engines/agi/preagi.cpp
+++ b/engines/agi/preagi.cpp
@@ -59,6 +59,12 @@ void PreAgiEngine::initialize() {
_gfx = new GfxMgr(this);
_picture = new PictureMgr(this, _gfx);
+ if (getGameID() == GID_MICKEY) {
+ _fontData = fontData_Mickey;
+ } else {
+ _fontData = fontData_IBM;
+ }
+
_gfx->initMachine();
_game.gameFlags = 0;
@@ -137,7 +143,7 @@ void PreAgiEngine::drawStr(int row, int col, int attr, const char *buffer) {
break;
default:
- _gfx->putTextCharacter(1, col * 8 , row * 8, static_cast<char>(code), attr & 0x0f, (attr & 0xf0) / 0x10, false, getGameID() == GID_MICKEY ? mickey_fontdata : ibm_fontdata);
+ _gfx->putTextCharacter(1, col * 8 , row * 8, static_cast<char>(code), attr & 0x0f, (attr & 0xf0) / 0x10, false, _fontData);
if (++col == 320 / 8) {
col = 0;
diff --git a/engines/agi/preagi_mickey.cpp b/engines/agi/preagi_mickey.cpp
index a1572d7f1f..883107a957 100644
--- a/engines/agi/preagi_mickey.cpp
+++ b/engines/agi/preagi_mickey.cpp
@@ -2299,6 +2299,8 @@ void MickeyEngine::init() {
_gameStateMickey.fItemUsed[IDI_MSA_ITEM_LETTER] = true;
#endif
+
+ setflag(fSoundOn, true); // enable sound
}
Common::Error MickeyEngine::go() {
diff --git a/engines/agi/sound_pcjr.cpp b/engines/agi/sound_pcjr.cpp
index 51b2d067a4..ea7a2789e0 100644
--- a/engines/agi/sound_pcjr.cpp
+++ b/engines/agi/sound_pcjr.cpp
@@ -120,8 +120,6 @@ SoundGenPCJr::SoundGenPCJr(AgiBase *vm, Audio::Mixer *pMixer) : SoundGen(vm, pMi
else
_dissolveMethod = 0;
- _dissolveMethod = 3;
-
memset(_channel, 0, sizeof(_channel));
memset(_tchannel, 0, sizeof(_tchannel));
@@ -207,9 +205,6 @@ int SoundGenPCJr::volumeCalc(SndGenChan *chan) {
chan->attenuationCopy = attenuation;
attenuation &= 0x0F;
- attenuation += _mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType) / 17;
- if (attenuation > 0x0F)
- attenuation = 0x0F;
}
}
//if (computer_type == 2) && (attenuation < 8)
@@ -411,7 +406,7 @@ int SoundGenPCJr::chanGen(int chan, int16 *stream, int len) {
if (tpcm->noteCount <= 0) {
// get new tone data
if ((tpcm->avail) && (getNextNote(chan) == 0)) {
- tpcm->atten = _channel[chan].attenuation;
+ tpcm->atten = volumeCalc(&_channel[chan]);
tpcm->freqCount = _channel[chan].freqCount;
tpcm->genType = _channel[chan].genType;
@@ -477,8 +472,9 @@ int SoundGenPCJr::fillSquare(ToneChan *t, int16 *buf, int len) {
count = len;
+ int16 amp = (int16)(volTable[t->atten] * _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType) / Audio::Mixer::kMaxMixerVolume);
while (count > 0) {
- *(buf++) = t->sign ? volTable[t->atten] : -volTable[t->atten];
+ *(buf++) = t->sign ? amp : -amp;
count--;
// get next sample
@@ -515,8 +511,9 @@ int SoundGenPCJr::fillNoise(ToneChan *t, int16 *buf, int len) {
count = len;
+ int16 amp = (int16)(volTable[t->atten] * _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType) / Audio::Mixer::kMaxMixerVolume);
while (count > 0) {
- *(buf++) = t->sign ? volTable[t->atten] : -volTable[t->atten];
+ *(buf++) = t->sign ? amp : -amp;
count--;
// get next sample
diff --git a/engines/agi/text.cpp b/engines/agi/text.cpp
index eb48857bf2..16c8284ce0 100644
--- a/engines/agi/text.cpp
+++ b/engines/agi/text.cpp
@@ -50,7 +50,7 @@ void AgiEngine::printText2(int l, const char *msg, int foff, int xoff, int yoff,
// FR: strings with len == 1 were not printed
if (len == 1) {
- _gfx->putTextCharacter(l, xoff + foff, yoff, *msg, fg, bg, checkerboard);
+ _gfx->putTextCharacter(l, xoff + foff, yoff, *msg, fg, bg, checkerboard, _fontData);
maxx = 1;
minx = 0;
ofoff = foff;
@@ -74,7 +74,7 @@ void AgiEngine::printText2(int l, const char *msg, int foff, int xoff, int yoff,
if (xpos >= GFX_WIDTH)
continue;
- _gfx->putTextCharacter(l, xpos, ypos, *m, fg, bg, checkerboard);
+ _gfx->putTextCharacter(l, xpos, ypos, *m, fg, bg, checkerboard, _fontData);
if (x1 > maxx)
maxx = x1;
diff --git a/engines/agos/agos.cpp b/engines/agos/agos.cpp
index 6eda2eb9aa..8952e649fd 100644
--- a/engines/agos/agos.cpp
+++ b/engines/agos/agos.cpp
@@ -585,7 +585,9 @@ Common::Error AGOSEngine::init() {
((getFeatures() & GF_TALKIE) && getPlatform() == Common::kPlatformAcorn) ||
(getPlatform() == Common::kPlatformDOS)) {
- int ret = _midi->open(getGameType());
+ bool isDemo = (getFeatures() & GF_DEMO) ? true : false;
+
+ int ret = _midi->open(getGameType(), isDemo);
if (ret)
warning("MIDI Player init failed: \"%s\"", MidiDriver::getErrorName(ret));
diff --git a/engines/agos/detection_tables.h b/engines/agos/detection_tables.h
index 2f4709c49e..793d4081cf 100644
--- a/engines/agos/detection_tables.h
+++ b/engines/agos/detection_tables.h
@@ -1385,7 +1385,7 @@ static const AGOSGameDescription gameDescriptions[] = {
{
{
"simon1",
- "Floppy",
+ "Infocom Floppy",
{
{ "gamepc", GAME_BASEFILE, "9f93d27432ce44a787eef10adb640870", 37070},
@@ -1409,7 +1409,7 @@ static const AGOSGameDescription gameDescriptions[] = {
{
{
"simon1",
- "Floppy",
+ "Infocom Floppy",
{
{ "gamepc", GAME_BASEFILE, "62de24fc579b94fac7d3d23201b65b14", -1},
@@ -1599,11 +1599,11 @@ static const AGOSGameDescription gameDescriptions[] = {
GF_TALKIE
},
- // Simon the Sorcerer 1 - English DOS CD alternate?
+ // Simon the Sorcerer 1 - English DOS CD (Infocom)
{
{
"simon1",
- "CD",
+ "Infocom CD",
{
{ "gamepc", GAME_BASEFILE, "c0b948b6821d2140f8b977144f21027a", -1},
diff --git a/engines/agos/drivers/accolade/adlib.cpp b/engines/agos/drivers/accolade/adlib.cpp
new file mode 100644
index 0000000000..294be2b8a7
--- /dev/null
+++ b/engines/agos/drivers/accolade/adlib.cpp
@@ -0,0 +1,883 @@
+/* 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 "agos/agos.h"
+#include "agos/drivers/accolade/mididriver.h"
+
+#include "common/file.h"
+#include "common/mutex.h"
+#include "common/system.h"
+#include "common/textconsole.h"
+
+#include "audio/fmopl.h"
+#include "audio/softsynth/emumidi.h"
+
+namespace AGOS {
+
+#define AGOS_ADLIB_VOICES_COUNT 11
+#define AGOS_ADLIB_VOICES_MELODIC_COUNT 6
+#define AGOS_ADLIB_VOICES_PERCUSSION_START 6
+#define AGOS_ADLIB_VOICES_PERCUSSION_COUNT 5
+#define AGOS_ADLIB_VOICES_PERCUSSION_CYMBAL 9
+
+// 5 instruments on top of the regular MIDI ones
+// used by the MUSIC.DRV variant for percussion instruments
+#define AGOS_ADLIB_EXTRA_INSTRUMENT_COUNT 5
+
+const byte operator1Register[AGOS_ADLIB_VOICES_COUNT] = {
+ 0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x14, 0x12, 0x15, 0x11
+};
+
+const byte operator2Register[AGOS_ADLIB_VOICES_COUNT] = {
+ 0x03, 0x04, 0x05, 0x0B, 0x0C, 0x0D, 0x13, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+// percussion:
+// voice 6 - base drum - also uses operator 13h
+// voice 7 - snare drum
+// voice 8 - tom tom
+// voice 9 - cymbal
+// voice 10 - hi hat
+const byte percussionBits[AGOS_ADLIB_VOICES_PERCUSSION_COUNT] = {
+ 0x10, 0x08, 0x04, 0x02, 0x01
+};
+
+// hardcoded, dumped from Accolade music system
+// same for INSTR.DAT + MUSIC.DRV, except that MUSIC.DRV does the lookup differently
+const byte percussionKeyNoteChannelTable[] = {
+ 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x0A, 0x08, 0x0A, 0x08,
+ 0x0A, 0x08, 0x08, 0x09, 0x08, 0x09, 0x0F, 0x0F, 0x0A, 0x0F,
+ 0x0A, 0x0F, 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x0A, 0x0F, 0x0F, 0x08, 0x0F, 0x08
+};
+
+struct InstrumentEntry {
+ byte reg20op1; // Amplitude Modulation / Vibrato / Envelope Generator Type / Keyboard Scaling Rate / Modulator Frequency Multiple
+ byte reg40op1; // Level Key Scaling / Total Level
+ byte reg60op1; // Attack Rate / Decay Rate
+ byte reg80op1; // Sustain Level / Release Rate
+ byte reg20op2; // Amplitude Modulation / Vibrato / Envelope Generator Type / Keyboard Scaling Rate / Modulator Frequency Multiple
+ byte reg40op2; // Level Key Scaling / Total Level
+ byte reg60op2; // Attack Rate / Decay Rate
+ byte reg80op2; // Sustain Level / Release Rate
+ byte regC0; // Feedback / Algorithm, bit 0 - set -> both operators in use
+};
+
+// hardcoded, dumped from Accolade music system (INSTR.DAT variant)
+const uint16 frequencyLookUpTable[12] = {
+ 0x02B2, 0x02DB, 0x0306, 0x0334, 0x0365, 0x0399, 0x03CF,
+ 0xFE05, 0xFE23, 0xFE44, 0xFE67, 0xFE8B
+};
+
+// hardcoded, dumped from Accolade music system (MUSIC.DRV variant)
+const uint16 frequencyLookUpTableMusicDrv[12] = {
+ 0x0205, 0x0223, 0x0244, 0x0267, 0x028B, 0x02B2, 0x02DB,
+ 0x0306, 0x0334, 0x0365, 0x0399, 0x03CF
+};
+
+//
+// Accolade adlib music driver
+//
+// Remarks:
+//
+// There are at least 2 variants of this sound system.
+// One for the games Elvira 1 + Elvira 2
+// It seems it was also used for the game "Altered Destiny"
+// Another one for the games Waxworks + Simon, the Sorcerer 1 Demo
+//
+// First one uses the file INSTR.DAT for instrument data, channel mapping etc.
+// Second one uses the file MUSIC.DRV, which actually contains driver code + instrument data + channel mapping, etc.
+//
+// The second variant supported dynamic channel allocation for the FM voice channels, but this
+// feature was at least definitely disabled for Simon, the Sorcerer 1 demo and for the Waxworks demo too.
+//
+// I have currently not implemented dynamic channel allocation.
+
+class MidiDriver_Accolade_AdLib : public MidiDriver {
+public:
+ MidiDriver_Accolade_AdLib();
+ virtual ~MidiDriver_Accolade_AdLib();
+
+ // MidiDriver
+ int open();
+ void close();
+ void send(uint32 b);
+ MidiChannel *allocateChannel() { return NULL; }
+ MidiChannel *getPercussionChannel() { return NULL; }
+
+ bool isOpen() const { return _isOpen; }
+ uint32 getBaseTempo() { return 1000000 / OPL::OPL::kDefaultCallbackFrequency; }
+
+ void setVolume(byte volume);
+ virtual uint32 property(int prop, uint32 param);
+
+ bool setupInstruments(byte *instrumentData, uint16 instrumentDataSize, bool useMusicDrvFile);
+
+ void setTimerCallback(void *timerParam, Common::TimerManager::TimerProc timerProc);
+
+private:
+ bool _musicDrvMode;
+
+ // from INSTR.DAT/MUSIC.DRV - simple mapping between MIDI channel and MT32 channel
+ byte _channelMapping[AGOS_MIDI_CHANNEL_COUNT];
+ // from INSTR.DAT/MUSIC.DRV - simple mapping between MIDI instruments and MT32 instruments
+ byte _instrumentMapping[AGOS_MIDI_INSTRUMENT_COUNT];
+ // from INSTR.DAT/MUSIC.DRV - volume adjustment per instrument
+ signed char _instrumentVolumeAdjust[AGOS_MIDI_INSTRUMENT_COUNT];
+ // simple mapping between MIDI key notes and MT32 key notes
+ byte _percussionKeyNoteMapping[AGOS_MIDI_KEYNOTE_COUNT];
+
+ // from INSTR.DAT/MUSIC.DRV - adlib instrument data
+ InstrumentEntry *_instrumentTable;
+ byte _instrumentCount;
+
+ struct ChannelEntry {
+ const InstrumentEntry *currentInstrumentPtr;
+ byte currentNote;
+ byte currentA0hReg;
+ byte currentB0hReg;
+ int16 volumeAdjust;
+
+ ChannelEntry() : currentInstrumentPtr(NULL), currentNote(0),
+ currentA0hReg(0), currentB0hReg(0), volumeAdjust(0) { }
+ };
+
+ byte _percussionReg;
+
+ OPL::OPL *_opl;
+ int _masterVolume;
+
+ Common::TimerManager::TimerProc _adlibTimerProc;
+ void *_adlibTimerParam;
+
+ bool _isOpen;
+
+ // stores information about all FM voice channels
+ ChannelEntry _channels[AGOS_ADLIB_VOICES_COUNT];
+
+ void onTimer();
+
+ void resetAdLib();
+ void resetAdLibOperatorRegisters(byte baseRegister, byte value);
+ void resetAdLibFMVoiceChannelRegisters(byte baseRegister, byte value);
+
+ void programChange(byte FMvoiceChannel, byte mappedInstrumentNr, byte MIDIinstrumentNr);
+ void programChangeSetInstrument(byte FMvoiceChannel, byte mappedInstrumentNr, byte MIDIinstrumentNr);
+ void setRegister(int reg, int value);
+ void noteOn(byte FMvoiceChannel, byte note, byte velocity);
+ void noteOnSetVolume(byte FMvoiceChannel, byte operatorReg, byte adjustedVelocity);
+ void noteOff(byte FMvoiceChannel, byte note, bool dontCheckNote);
+};
+
+MidiDriver_Accolade_AdLib::MidiDriver_Accolade_AdLib()
+ : _masterVolume(15), _opl(0),
+ _adlibTimerProc(0), _adlibTimerParam(0), _isOpen(false) {
+ memset(_channelMapping, 0, sizeof(_channelMapping));
+ memset(_instrumentMapping, 0, sizeof(_instrumentMapping));
+ memset(_instrumentVolumeAdjust, 0, sizeof(_instrumentVolumeAdjust));
+ memset(_percussionKeyNoteMapping, 0, sizeof(_percussionKeyNoteMapping));
+
+ _instrumentTable = NULL;
+ _instrumentCount = 0;
+ _musicDrvMode = false;
+ _percussionReg = 0x20;
+}
+
+MidiDriver_Accolade_AdLib::~MidiDriver_Accolade_AdLib() {
+ if (_instrumentTable) {
+ delete[] _instrumentTable;
+ _instrumentCount = 0;
+ }
+}
+
+int MidiDriver_Accolade_AdLib::open() {
+// debugC(kDebugLevelAdLibDriver, "AdLib: starting driver");
+
+ _opl = OPL::Config::create(OPL::Config::kOpl2);
+
+ if (!_opl)
+ return -1;
+
+ _opl->init();
+
+ _isOpen = true;
+
+ _opl->start(new Common::Functor0Mem<void, MidiDriver_Accolade_AdLib>(this, &MidiDriver_Accolade_AdLib::onTimer));
+
+ resetAdLib();
+
+ // Finally set up default instruments
+ for (byte FMvoiceNr = 0; FMvoiceNr < AGOS_ADLIB_VOICES_COUNT; FMvoiceNr++) {
+ if (FMvoiceNr < AGOS_ADLIB_VOICES_PERCUSSION_START) {
+ // Regular FM voices with instrument 0
+ programChangeSetInstrument(FMvoiceNr, 0, 0);
+ } else {
+ byte percussionInstrument;
+ if (!_musicDrvMode) {
+ // INSTR.DAT: percussion voices with instrument 1, 2, 3, 4 and 5
+ percussionInstrument = FMvoiceNr - AGOS_ADLIB_VOICES_PERCUSSION_START + 1;
+ } else {
+ // MUSIC.DRV: percussion voices with instrument 0x80, 0x81, 0x82, 0x83 and 0x84
+ percussionInstrument = FMvoiceNr - AGOS_ADLIB_VOICES_PERCUSSION_START + 0x80;
+ }
+ programChangeSetInstrument(FMvoiceNr, percussionInstrument, percussionInstrument);
+ }
+ }
+
+ // driver initialization does this here:
+ // INSTR.DAT
+ // noteOn(9, 0x29, 0);
+ // noteOff(9, 0x26, false);
+ // MUSIC.DRV
+ // noteOn(9, 0x26, 0);
+ // noteOff(9, 0x26, false);
+
+ return 0;
+}
+
+void MidiDriver_Accolade_AdLib::close() {
+ delete _opl;
+ _isOpen = false;
+}
+
+void MidiDriver_Accolade_AdLib::setVolume(byte volume) {
+ _masterVolume = volume;
+ //renewNotes(-1, true);
+}
+
+void MidiDriver_Accolade_AdLib::onTimer() {
+ if (_adlibTimerProc)
+ (*_adlibTimerProc)(_adlibTimerParam);
+}
+
+void MidiDriver_Accolade_AdLib::resetAdLib() {
+ // The original driver sent 0x00 to register 0x00 up to 0xF5
+ setRegister(0xBD, 0x00); // Disable rhythm
+
+ // reset FM voice instrument data
+ resetAdLibOperatorRegisters(0x20, 0);
+ resetAdLibOperatorRegisters(0x60, 0);
+ resetAdLibOperatorRegisters(0x80, 0);
+ resetAdLibFMVoiceChannelRegisters(0xA0, 0);
+ resetAdLibFMVoiceChannelRegisters(0xB0, 0);
+ resetAdLibFMVoiceChannelRegisters(0xC0, 0);
+ resetAdLibOperatorRegisters(0xE0, 0);
+ resetAdLibOperatorRegisters(0x40, 0x3F); // original driver sent 0x00
+
+ setRegister(0x01, 0x20); // enable waveform control on both operators
+ setRegister(0x04, 0x60); // Timer control
+
+ setRegister(0x08, 0); // select FM music mode
+ setRegister(0xBD, 0x20); // Enable rhythm
+
+ // reset our percussion register
+ _percussionReg = 0x20;
+}
+
+void MidiDriver_Accolade_AdLib::resetAdLibOperatorRegisters(byte baseRegister, byte value) {
+ byte operatorIndex;
+
+ for (operatorIndex = 0; operatorIndex < 0x16; operatorIndex++) {
+ switch (operatorIndex) {
+ case 0x06:
+ case 0x07:
+ case 0x0E:
+ case 0x0F:
+ break;
+ default:
+ setRegister(baseRegister + operatorIndex, value);
+ }
+ }
+}
+
+void MidiDriver_Accolade_AdLib::resetAdLibFMVoiceChannelRegisters(byte baseRegister, byte value) {
+ byte FMvoiceChannel;
+
+ for (FMvoiceChannel = 0; FMvoiceChannel < AGOS_ADLIB_VOICES_COUNT; FMvoiceChannel++) {
+ setRegister(baseRegister + FMvoiceChannel, value);
+ }
+}
+
+// MIDI messages can be found at http://www.midi.org/techspecs/midimessages.php
+void MidiDriver_Accolade_AdLib::send(uint32 b) {
+ byte command = b & 0xf0;
+ byte channel = b & 0xf;
+ byte op1 = (b >> 8) & 0xff;
+ byte op2 = (b >> 16) & 0xff;
+
+ byte mappedChannel = _channelMapping[channel];
+ byte mappedInstrument = 0;
+
+ // Ignore everything that is outside of our channel range
+ if (mappedChannel >= AGOS_ADLIB_VOICES_COUNT)
+ return;
+
+ switch (command) {
+ case 0x80:
+ noteOff(mappedChannel, op1, false);
+ break;
+ case 0x90:
+ // Convert noteOn with velocity 0 to a noteOff
+ if (op2 == 0)
+ return noteOff(mappedChannel, op1, false);
+
+ noteOn(mappedChannel, op1, op2);
+ break;
+ case 0xb0: // Control change
+ // Doesn't seem to be implemented
+ break;
+ case 0xc0: // Program Change
+ mappedInstrument = _instrumentMapping[op1];
+ programChange(mappedChannel, mappedInstrument, op1);
+ break;
+ case 0xa0: // Polyphonic key pressure (aftertouch)
+ case 0xd0: // Channel pressure (aftertouch)
+ // Aftertouch doesn't seem to be implemented
+ break;
+ case 0xe0:
+ // No pitch bend change
+ break;
+ case 0xf0: // SysEx
+ warning("ADLIB: SysEx: %x", b);
+ break;
+ default:
+ warning("ADLIB: Unknown event %02x", command);
+ }
+}
+
+void MidiDriver_Accolade_AdLib::setTimerCallback(void *timerParam, Common::TimerManager::TimerProc timerProc) {
+ _adlibTimerProc = timerProc;
+ _adlibTimerParam = timerParam;
+}
+
+void MidiDriver_Accolade_AdLib::noteOn(byte FMvoiceChannel, byte note, byte velocity) {
+ byte adjustedNote = note;
+ byte adjustedVelocity = velocity;
+ byte regValueA0h = 0;
+ byte regValueB0h = 0;
+
+ // adjust velocity
+ int16 channelVolumeAdjust = _channels[FMvoiceChannel].volumeAdjust;
+ channelVolumeAdjust += adjustedVelocity;
+ channelVolumeAdjust = CLIP<int16>(channelVolumeAdjust, 0, 0x7F);
+
+ // TODO: adjust to global volume
+ // original drivers had a global volume variable, which was 0 for full volume, -64 for half volume
+ // and -128 for mute
+
+ adjustedVelocity = channelVolumeAdjust;
+
+ if (!_musicDrvMode) {
+ // INSTR.DAT
+ // force note-off
+ noteOff(FMvoiceChannel, note, true);
+
+ } else {
+ // MUSIC.DRV
+ if (FMvoiceChannel < AGOS_ADLIB_VOICES_PERCUSSION_START) {
+ // force note-off, but only for actual FM voice channels
+ noteOff(FMvoiceChannel, note, true);
+ }
+ }
+
+ if (FMvoiceChannel != 9) {
+ // regular FM voice
+
+ if (!_musicDrvMode) {
+ // INSTR.DAT: adjust key note
+ while (adjustedNote < 24)
+ adjustedNote += 12;
+ adjustedNote -= 12;
+ }
+
+ } else {
+ // percussion channel
+ // MUSIC.DRV variant didn't do this adjustment, it directly used a pointer
+ adjustedNote -= 36;
+ if (adjustedNote > 40) { // Security check
+ warning("ADLIB: bad percussion channel note");
+ return;
+ }
+
+ byte percussionChannel = percussionKeyNoteChannelTable[adjustedNote];
+ if (percussionChannel >= AGOS_ADLIB_VOICES_COUNT)
+ return; // INSTR.DAT variant checked for ">" instead of ">=", which seems to have been a bug
+
+ // Map the keynote accordingly
+ adjustedNote = _percussionKeyNoteMapping[adjustedNote];
+ // Now overwrite the FM voice channel
+ FMvoiceChannel = percussionChannel;
+ }
+
+ if (!_musicDrvMode) {
+ // INSTR.DAT
+
+ // Save this key note
+ _channels[FMvoiceChannel].currentNote = adjustedNote;
+
+ adjustedVelocity += 24;
+ if (adjustedVelocity > 120)
+ adjustedVelocity = 120;
+ adjustedVelocity = adjustedVelocity >> 1; // divide by 2
+
+ } else {
+ // MUSIC.DRV
+ adjustedVelocity = adjustedVelocity >> 1; // divide by 2
+ }
+
+ // Set volume of voice channel
+ noteOnSetVolume(FMvoiceChannel, 1, adjustedVelocity);
+ if (FMvoiceChannel <= AGOS_ADLIB_VOICES_PERCUSSION_START) {
+ // Set second operator for FM voices + first percussion
+ noteOnSetVolume(FMvoiceChannel, 2, adjustedVelocity);
+ }
+
+ if (FMvoiceChannel >= AGOS_ADLIB_VOICES_PERCUSSION_START) {
+ // Percussion
+ byte percussionIdx = FMvoiceChannel - AGOS_ADLIB_VOICES_PERCUSSION_START;
+
+ // Enable bit of the requested percussion type
+ assert(percussionIdx < AGOS_ADLIB_VOICES_PERCUSSION_COUNT);
+ _percussionReg |= percussionBits[percussionIdx];
+ setRegister(0xBD, _percussionReg);
+ }
+
+ if (FMvoiceChannel < AGOS_ADLIB_VOICES_PERCUSSION_CYMBAL) {
+ // FM voice, Base Drum, Snare Drum + Tom Tom
+ byte adlibNote = adjustedNote;
+ byte adlibOctave = 0;
+ byte adlibFrequencyIdx = 0;
+ uint16 adlibFrequency = 0;
+
+ if (!_musicDrvMode) {
+ // INSTR.DAT
+ if (adlibNote >= 0x60)
+ adlibNote = 0x5F;
+
+ adlibOctave = (adlibNote / 12) - 1;
+ adlibFrequencyIdx = adlibNote % 12;
+ adlibFrequency = frequencyLookUpTable[adlibFrequencyIdx];
+
+ if (adlibFrequency & 0x8000)
+ adlibOctave++;
+ if (adlibOctave & 0x80) {
+ adlibOctave++;
+ adlibFrequency = adlibFrequency >> 1;
+ }
+
+ } else {
+ // MUSIC.DRV variant
+ if (adlibNote >= 19)
+ adlibNote -= 19;
+
+ adlibOctave = (adlibNote / 12);
+ adlibFrequencyIdx = adlibNote % 12;
+ // additional code, that will lookup octave and do a multiplication with it
+ // noteOn however calls the frequency calculation in a way that it multiplies with 0
+ adlibFrequency = frequencyLookUpTableMusicDrv[adlibFrequencyIdx];
+ }
+
+ regValueA0h = adlibFrequency & 0xFF;
+ regValueB0h = ((adlibFrequency & 0x300) >> 8) | (adlibOctave << 2);
+ if (FMvoiceChannel < AGOS_ADLIB_VOICES_PERCUSSION_START) {
+ // set Key-On flag for regular FM voices, but not for percussion
+ regValueB0h |= 0x20;
+ }
+
+ setRegister(0xA0 + FMvoiceChannel, regValueA0h);
+ setRegister(0xB0 + FMvoiceChannel, regValueB0h);
+ _channels[FMvoiceChannel].currentA0hReg = regValueA0h;
+ _channels[FMvoiceChannel].currentB0hReg = regValueB0h;
+
+ if (_musicDrvMode) {
+ // MUSIC.DRV
+ if (FMvoiceChannel < AGOS_ADLIB_VOICES_MELODIC_COUNT) {
+ _channels[FMvoiceChannel].currentNote = adjustedNote;
+ }
+ }
+ }
+}
+
+// 100% the same for INSTR.DAT and MUSIC.DRV variants
+// except for a bug, that was introduced for MUSIC.DRV
+void MidiDriver_Accolade_AdLib::noteOnSetVolume(byte FMvoiceChannel, byte operatorNr, byte adjustedVelocity) {
+ byte operatorReg = 0;
+ byte regValue40h = 0;
+ const InstrumentEntry *curInstrument = NULL;
+
+ regValue40h = (63 - adjustedVelocity) & 0x3F;
+
+ if ((operatorNr == 1) && (FMvoiceChannel <= AGOS_ADLIB_VOICES_PERCUSSION_START)) {
+ // first operator of FM voice channels or first percussion channel
+ curInstrument = _channels[FMvoiceChannel].currentInstrumentPtr;
+ if (!(curInstrument->regC0 & 0x01)) { // check, if both operators produce sound
+ // only one does, instrument wants fixed volume
+ if (operatorNr == 1) {
+ regValue40h = curInstrument->reg40op1;
+ } else {
+ regValue40h = curInstrument->reg40op2;
+ }
+
+ // not sure, if we are supposed to implement these bugs, or not
+#if 0
+ if (!_musicDrvMode) {
+ // Table is 16 bytes instead of 18 bytes
+ if ((FMvoiceChannel == 7) || (FMvoiceChannel == 9)) {
+ regValue40h = 0;
+ warning("volume set bug (original)");
+ }
+ }
+ if (_musicDrvMode) {
+ // MUSIC.DRV variant has a bug, which will overwrite these registers
+ // for all operators above 11 / 0Bh, which means percussion will always
+ // get a value of 0 (the table holding those bytes was 12 bytes instead of 18
+ if (FMvoiceChannel >= AGOS_ADLIB_VOICES_PERCUSSION_START) {
+ regValue40h = 0;
+ warning("volume set bug (original)");
+ }
+ }
+#endif
+ }
+ }
+
+ if (operatorNr == 1) {
+ operatorReg = operator1Register[FMvoiceChannel];
+ } else {
+ operatorReg = operator2Register[FMvoiceChannel];
+ }
+ assert(operatorReg != 0xFF); // Security check
+ setRegister(0x40 + operatorReg, regValue40h);
+}
+
+void MidiDriver_Accolade_AdLib::noteOff(byte FMvoiceChannel, byte note, bool dontCheckNote) {
+ byte adjustedNote = note;
+ byte regValueB0h = 0;
+
+ if (FMvoiceChannel < AGOS_ADLIB_VOICES_PERCUSSION_START) {
+ // regular FM voice
+
+ if (!_musicDrvMode) {
+ // INSTR.DAT: adjust key note
+ while (adjustedNote < 24)
+ adjustedNote += 12;
+ adjustedNote -= 12;
+ }
+
+ if (!dontCheckNote) {
+ // check, if current note is also the current actually playing channel note
+ if (_channels[FMvoiceChannel].currentNote != adjustedNote)
+ return; // not the same -> ignore this note off command
+ }
+
+ regValueB0h = _channels[FMvoiceChannel].currentB0hReg & 0xDF; // Remove "key on" bit
+ setRegister(0xB0 + FMvoiceChannel, regValueB0h);
+
+ } else {
+ // percussion
+ adjustedNote -= 36;
+ if (adjustedNote > 40) { // Security check
+ warning("ADLIB: bad percussion channel note");
+ return;
+ }
+
+ byte percussionChannel = percussionKeyNoteChannelTable[adjustedNote];
+ if (percussionChannel > AGOS_ADLIB_VOICES_COUNT)
+ return;
+
+ byte percussionIdx = percussionChannel - AGOS_ADLIB_VOICES_PERCUSSION_START;
+
+ // Disable bit of the requested percussion type
+ assert(percussionIdx < AGOS_ADLIB_VOICES_PERCUSSION_COUNT);
+ _percussionReg &= ~percussionBits[percussionIdx];
+ setRegister(0xBD, _percussionReg);
+ }
+}
+
+void MidiDriver_Accolade_AdLib::programChange(byte FMvoiceChannel, byte mappedInstrumentNr, byte MIDIinstrumentNr) {
+ if (mappedInstrumentNr >= _instrumentCount) {
+ warning("ADLIB: tried to set non-existent instrument");
+ return; // out of range
+ }
+
+ // setup instrument
+ //warning("ADLIB: program change for FM voice channel %d, instrument id %d", FMvoiceChannel, mappedInstrumentNr);
+
+ if (FMvoiceChannel < AGOS_ADLIB_VOICES_PERCUSSION_START) {
+ // Regular FM voice
+ programChangeSetInstrument(FMvoiceChannel, mappedInstrumentNr, MIDIinstrumentNr);
+
+ } else {
+ // Percussion
+ // set default instrument (again)
+ byte percussionInstrumentNr = 0;
+ const InstrumentEntry *instrumentPtr;
+
+ if (!_musicDrvMode) {
+ // INSTR.DAT: percussion default instruments start at instrument 1
+ percussionInstrumentNr = FMvoiceChannel - AGOS_ADLIB_VOICES_PERCUSSION_START + 1;
+ } else {
+ // MUSIC.DRV: percussion default instruments start at instrument 0x80
+ percussionInstrumentNr = FMvoiceChannel - AGOS_ADLIB_VOICES_PERCUSSION_START + 0x80;
+ }
+ if (percussionInstrumentNr >= _instrumentCount) {
+ warning("ADLIB: tried to set non-existent instrument");
+ return;
+ }
+ instrumentPtr = &_instrumentTable[percussionInstrumentNr];
+ _channels[FMvoiceChannel].currentInstrumentPtr = instrumentPtr;
+ _channels[FMvoiceChannel].volumeAdjust = _instrumentVolumeAdjust[percussionInstrumentNr];
+ }
+}
+
+void MidiDriver_Accolade_AdLib::programChangeSetInstrument(byte FMvoiceChannel, byte mappedInstrumentNr, byte MIDIinstrumentNr) {
+ const InstrumentEntry *instrumentPtr;
+ byte op1Reg = 0;
+ byte op2Reg = 0;
+
+ if (mappedInstrumentNr >= _instrumentCount) {
+ warning("ADLIB: tried to set non-existent instrument");
+ return; // out of range
+ }
+
+ // setup instrument
+ instrumentPtr = &_instrumentTable[mappedInstrumentNr];
+ //warning("set instrument for FM voice channel %d, instrument id %d", FMvoiceChannel, mappedInstrumentNr);
+
+ op1Reg = operator1Register[FMvoiceChannel];
+ op2Reg = operator2Register[FMvoiceChannel];
+
+ setRegister(0x20 + op1Reg, instrumentPtr->reg20op1);
+ setRegister(0x40 + op1Reg, instrumentPtr->reg40op1);
+ setRegister(0x60 + op1Reg, instrumentPtr->reg60op1);
+ setRegister(0x80 + op1Reg, instrumentPtr->reg80op1);
+
+ if (FMvoiceChannel <= AGOS_ADLIB_VOICES_PERCUSSION_START) {
+ // set 2nd operator as well for FM voices and first percussion voice
+ setRegister(0x20 + op2Reg, instrumentPtr->reg20op2);
+ setRegister(0x40 + op2Reg, instrumentPtr->reg40op2);
+ setRegister(0x60 + op2Reg, instrumentPtr->reg60op2);
+ setRegister(0x80 + op2Reg, instrumentPtr->reg80op2);
+
+ if (!_musicDrvMode) {
+ // set Feedback / Algorithm as well
+ setRegister(0xC0 + FMvoiceChannel, instrumentPtr->regC0);
+ } else {
+ if (FMvoiceChannel < AGOS_ADLIB_VOICES_PERCUSSION_START) {
+ // set Feedback / Algorithm as well for regular FM voices only
+ setRegister(0xC0 + FMvoiceChannel, instrumentPtr->regC0);
+ }
+ }
+ }
+
+ // Remember instrument
+ _channels[FMvoiceChannel].currentInstrumentPtr = instrumentPtr;
+ _channels[FMvoiceChannel].volumeAdjust = _instrumentVolumeAdjust[MIDIinstrumentNr];
+}
+
+void MidiDriver_Accolade_AdLib::setRegister(int reg, int value) {
+ _opl->writeReg(reg, value);
+ //warning("OPL %x %x (%d)", reg, value, value);
+}
+
+uint32 MidiDriver_Accolade_AdLib::property(int prop, uint32 param) {
+ return 0;
+}
+
+// Called right at the start, we get an INSTR.DAT entry
+bool MidiDriver_Accolade_AdLib::setupInstruments(byte *driverData, uint16 driverDataSize, bool useMusicDrvFile) {
+ uint16 channelMappingOffset = 0;
+ uint16 channelMappingSize = 0;
+ uint16 instrumentMappingOffset = 0;
+ uint16 instrumentMappingSize = 0;
+ uint16 instrumentVolumeAdjustOffset = 0;
+ uint16 instrumentVolumeAdjustSize = 0;
+ uint16 keyNoteMappingOffset = 0;
+ uint16 keyNoteMappingSize = 0;
+ uint16 instrumentCount = 0;
+ uint16 instrumentDataOffset = 0;
+ uint16 instrumentDataSize = 0;
+ uint16 instrumentEntrySize = 0;
+
+ if (!useMusicDrvFile) {
+ // INSTR.DAT: we expect at least 354 bytes
+ if (driverDataSize < 354)
+ return false;
+
+ // Data is like this:
+ // 128 bytes instrument mapping
+ // 128 bytes instrument volume adjust (signed!)
+ // 16 bytes unknown
+ // 16 bytes channel mapping
+ // 64 bytes key note mapping (not used for MT32)
+ // 1 byte instrument count
+ // 1 byte bytes per instrument
+ // x bytes no instruments used for MT32
+
+ channelMappingOffset = 256 + 16;
+ channelMappingSize = 16;
+ instrumentMappingOffset = 0;
+ instrumentMappingSize = 128;
+ instrumentVolumeAdjustOffset = 128;
+ instrumentVolumeAdjustSize = 128;
+ keyNoteMappingOffset = 256 + 16 + 16;
+ keyNoteMappingSize = 64;
+
+ byte instrDatInstrumentCount = driverData[256 + 16 + 16 + 64];
+ byte instrDatBytesPerInstrument = driverData[256 + 16 + 16 + 64 + 1];
+
+ // We expect 9 bytes per instrument
+ if (instrDatBytesPerInstrument != 9)
+ return false;
+ // And we also expect at least one adlib instrument
+ if (!instrDatInstrumentCount)
+ return false;
+
+ instrumentCount = instrDatInstrumentCount;
+ instrumentDataOffset = 256 + 16 + 16 + 64 + 2;
+ instrumentDataSize = instrDatBytesPerInstrument * instrDatInstrumentCount;
+ instrumentEntrySize = instrDatBytesPerInstrument;
+
+ } else {
+ // MUSIC.DRV: we expect at least 468 bytes
+ if (driverDataSize < 468)
+ return false;
+
+ // music.drv is basically a driver, but with a few fixed locations for certain data
+
+ channelMappingOffset = 396;
+ channelMappingSize = 16;
+ instrumentMappingOffset = 140;
+ instrumentMappingSize = 128;
+ instrumentVolumeAdjustOffset = 140 + 128;
+ instrumentVolumeAdjustSize = 128;
+ keyNoteMappingOffset = 376 + 36; // adjust by 36, because we adjust keyNote before mapping (see noteOn)
+ keyNoteMappingSize = 64;
+
+ // seems to have used 128 + 5 instruments
+ // 128 regular ones and an additional 5 for percussion
+ instrumentCount = 128 + AGOS_ADLIB_EXTRA_INSTRUMENT_COUNT;
+ instrumentDataOffset = 722;
+ instrumentEntrySize = 9;
+ instrumentDataSize = instrumentCount * instrumentEntrySize;
+ }
+
+ // Channel mapping
+ if (channelMappingSize) {
+ // Get these 16 bytes for MIDI channel mapping
+ if (channelMappingSize != sizeof(_channelMapping))
+ return false;
+
+ memcpy(_channelMapping, driverData + channelMappingOffset, sizeof(_channelMapping));
+ } else {
+ // Set up straight mapping
+ for (uint16 channelNr = 0; channelNr < sizeof(_channelMapping); channelNr++) {
+ _channelMapping[channelNr] = channelNr;
+ }
+ }
+
+ if (instrumentMappingSize) {
+ // And these for instrument mapping
+ if (instrumentMappingSize > sizeof(_instrumentMapping))
+ return false;
+
+ memcpy(_instrumentMapping, driverData + instrumentMappingOffset, instrumentMappingSize);
+ }
+ // Set up straight mapping for the remaining data
+ for (uint16 instrumentNr = instrumentMappingSize; instrumentNr < sizeof(_instrumentMapping); instrumentNr++) {
+ _instrumentMapping[instrumentNr] = instrumentNr;
+ }
+
+ if (instrumentVolumeAdjustSize) {
+ if (instrumentVolumeAdjustSize != sizeof(_instrumentVolumeAdjust))
+ return false;
+
+ memcpy(_instrumentVolumeAdjust, driverData + instrumentVolumeAdjustOffset, instrumentVolumeAdjustSize);
+ }
+
+ // Get key note mapping, if available
+ if (keyNoteMappingSize) {
+ if (keyNoteMappingSize != sizeof(_percussionKeyNoteMapping))
+ return false;
+
+ memcpy(_percussionKeyNoteMapping, driverData + keyNoteMappingOffset, keyNoteMappingSize);
+ }
+
+ // Check, if there are enough bytes left to hold all instrument data
+ if (driverDataSize < (instrumentDataOffset + instrumentDataSize))
+ return false;
+
+ // We release previous instrument data, just in case
+ if (_instrumentTable)
+ delete[] _instrumentTable;
+
+ _instrumentTable = new InstrumentEntry[instrumentCount];
+ _instrumentCount = instrumentCount;
+
+ byte *instrDATReadPtr = driverData + instrumentDataOffset;
+ InstrumentEntry *instrumentWritePtr = _instrumentTable;
+
+ for (uint16 instrumentNr = 0; instrumentNr < _instrumentCount; instrumentNr++) {
+ memcpy(instrumentWritePtr, instrDATReadPtr, sizeof(InstrumentEntry));
+ instrDATReadPtr += instrumentEntrySize;
+ instrumentWritePtr++;
+ }
+
+ // Enable MUSIC.DRV-Mode (slightly different behaviour)
+ if (useMusicDrvFile)
+ _musicDrvMode = true;
+
+ if (_musicDrvMode) {
+ // Extra code for MUSIC.DRV
+
+ // This was done during "programChange" in the original driver
+ instrumentWritePtr = _instrumentTable;
+ for (uint16 instrumentNr = 0; instrumentNr < _instrumentCount; instrumentNr++) {
+ instrumentWritePtr->reg80op1 |= 0x03; // set release rate
+ instrumentWritePtr->reg80op2 |= 0x03;
+ instrumentWritePtr++;
+ }
+ }
+ return true;
+}
+
+MidiDriver *MidiDriver_Accolade_AdLib_create(Common::String driverFilename) {
+ byte *driverData = NULL;
+ uint16 driverDataSize = 0;
+ bool isMusicDrvFile = false;
+
+ MidiDriver_Accolade_readDriver(driverFilename, MT_ADLIB, driverData, driverDataSize, isMusicDrvFile);
+ if (!driverData)
+ error("ACCOLADE-ADLIB: error during readDriver()");
+
+ MidiDriver_Accolade_AdLib *driver = new MidiDriver_Accolade_AdLib();
+ if (driver) {
+ if (!driver->setupInstruments(driverData, driverDataSize, isMusicDrvFile)) {
+ delete driver;
+ driver = nullptr;
+ }
+ }
+
+ delete[] driverData;
+ return driver;
+}
+
+} // End of namespace AGOS
diff --git a/engines/agos/drivers/accolade/driverfile.cpp b/engines/agos/drivers/accolade/driverfile.cpp
new file mode 100644
index 0000000000..4ff2fd550f
--- /dev/null
+++ b/engines/agos/drivers/accolade/driverfile.cpp
@@ -0,0 +1,166 @@
+/* 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 "agos/agos.h"
+#include "audio/mididrv.h"
+#include "common/error.h"
+#include "common/file.h"
+
+namespace AGOS {
+
+// this reads and gets Accolade driver data
+// we need it for channel mapping, instrument mapping and other things
+// this driver data chunk gets passed to the actual music driver (MT32 / AdLib)
+void MidiDriver_Accolade_readDriver(Common::String filename, MusicType requestedDriverType, byte *&driverData, uint16 &driverDataSize, bool &isMusicDrvFile) {
+ Common::File *driverStream = new Common::File();
+
+ isMusicDrvFile = false;
+
+ if (!driverStream->open(filename)) {
+ error("%s: unable to open file", filename.c_str());
+ }
+
+ if (filename == "INSTR.DAT") {
+ // INSTR.DAT: used by Elvira 1
+ uint32 streamSize = driverStream->size();
+ uint32 streamLeft = streamSize;
+ uint16 skipChunks = 0; // 1 for MT32, 0 for AdLib
+ uint16 chunkSize = 0;
+
+ switch (requestedDriverType) {
+ case MT_ADLIB:
+ skipChunks = 0;
+ break;
+ case MT_MT32:
+ skipChunks = 1; // Skip one entry for MT32
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ do {
+ if (streamLeft < 2)
+ error("%s: unexpected EOF", filename.c_str());
+
+ chunkSize = driverStream->readUint16LE();
+ streamLeft -= 2;
+
+ if (streamLeft < chunkSize)
+ error("%s: unexpected EOF", filename.c_str());
+
+ if (skipChunks) {
+ // Skip the chunk
+ driverStream->skip(chunkSize);
+ streamLeft -= chunkSize;
+
+ skipChunks--;
+ }
+ } while (skipChunks);
+
+ // Seek over the ASCII string until there is a NUL terminator
+ byte curByte = 0;
+
+ do {
+ if (chunkSize == 0)
+ error("%s: no actual instrument data found", filename.c_str());
+
+ curByte = driverStream->readByte();
+ chunkSize--;
+ } while (curByte);
+
+ driverDataSize = chunkSize;
+
+ // Read the requested instrument data entry
+ driverData = new byte[driverDataSize];
+ driverStream->read(driverData, driverDataSize);
+
+ } else if (filename == "MUSIC.DRV") {
+ // MUSIC.DRV / used by Elvira 2 / Waxworks / Simon 1 demo
+ uint32 streamSize = driverStream->size();
+ uint32 streamLeft = streamSize;
+ uint16 getChunk = 0; // 4 for MT32, 2 for AdLib
+
+ switch (requestedDriverType) {
+ case MT_ADLIB:
+ getChunk = 2;
+ break;
+ case MT_MT32:
+ getChunk = 4;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ if (streamLeft < 2)
+ error("%s: unexpected EOF", filename.c_str());
+
+ uint16 chunkCount = driverStream->readUint16LE();
+ streamLeft -= 2;
+
+ if (getChunk >= chunkCount)
+ error("%s: required chunk not available", filename.c_str());
+
+ uint16 headerOffset = 2 + (28 * getChunk);
+ streamLeft -= (28 * getChunk);
+
+ if (streamLeft < 28)
+ error("%s: unexpected EOF", filename.c_str());
+
+ // Seek to required chunk
+ driverStream->seek(headerOffset);
+ driverStream->skip(20); // skip over name
+ streamLeft -= 20;
+
+ uint16 musicDrvSignature = driverStream->readUint16LE();
+ uint16 musicDrvType = driverStream->readUint16LE();
+ uint16 chunkOffset = driverStream->readUint16LE();
+ uint16 chunkSize = driverStream->readUint16LE();
+
+ // Security checks
+ if (musicDrvSignature != 0xFEDC)
+ error("%s: chunk signature mismatch", filename.c_str());
+ if (musicDrvType != 1)
+ error("%s: not a music driver", filename.c_str());
+ if (chunkOffset >= streamSize)
+ error("%s: driver chunk points outside of file", filename.c_str());
+
+ streamLeft = streamSize - chunkOffset;
+ if (streamLeft < chunkSize)
+ error("%s: driver chunk is larger than file", filename.c_str());
+
+ driverDataSize = chunkSize;
+
+ // Read the requested instrument data entry
+ driverData = new byte[driverDataSize];
+
+ driverStream->seek(chunkOffset);
+ driverStream->read(driverData, driverDataSize);
+ isMusicDrvFile = true;
+ }
+
+ driverStream->close();
+ delete driverStream;
+}
+
+} // End of namespace AGOS
diff --git a/engines/agos/drivers/accolade/mididriver.h b/engines/agos/drivers/accolade/mididriver.h
new file mode 100644
index 0000000000..253fb6b736
--- /dev/null
+++ b/engines/agos/drivers/accolade/mididriver.h
@@ -0,0 +1,44 @@
+/* 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 AGOS_DRIVERS_ACCOLADE_MIDIDRIVER_H
+#define AGOS_DRIVERS_ACCOLADE_MIDIDRIVER_H
+
+#include "agos/agos.h"
+#include "audio/mididrv.h"
+#include "common/error.h"
+
+namespace AGOS {
+
+#define AGOS_MIDI_CHANNEL_COUNT 16
+#define AGOS_MIDI_INSTRUMENT_COUNT 128
+
+#define AGOS_MIDI_KEYNOTE_COUNT 64
+
+extern void MidiDriver_Accolade_readDriver(Common::String filename, MusicType requestedDriverType, byte *&driverData, uint16 &driverDataSize, bool &isMusicDrvFile);
+
+extern MidiDriver *MidiDriver_Accolade_AdLib_create(Common::String driverFilename);
+extern MidiDriver *MidiDriver_Accolade_MT32_create(Common::String driverFilename);
+
+} // End of namespace AGOS
+
+#endif // AGOS_DRIVERS_ACCOLADE_MIDIDRIVER_H
diff --git a/engines/agos/drivers/accolade/mt32.cpp b/engines/agos/drivers/accolade/mt32.cpp
new file mode 100644
index 0000000000..319e0ebf56
--- /dev/null
+++ b/engines/agos/drivers/accolade/mt32.cpp
@@ -0,0 +1,278 @@
+/* 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 "agos/agos.h"
+#include "agos/drivers/accolade/mididriver.h"
+
+#include "audio/mididrv.h"
+
+#include "common/config-manager.h"
+#include "common/file.h"
+#include "common/mutex.h"
+#include "common/system.h"
+#include "common/textconsole.h"
+
+namespace AGOS {
+
+class MidiDriver_Accolade_MT32 : public MidiDriver {
+public:
+ MidiDriver_Accolade_MT32();
+ virtual ~MidiDriver_Accolade_MT32();
+
+ // MidiDriver
+ int open();
+ void close();
+ bool isOpen() const { return _isOpen; }
+
+ void send(uint32 b);
+
+ MidiChannel *allocateChannel() {
+ if (_driver)
+ return _driver->allocateChannel();
+ return NULL;
+ }
+ MidiChannel *getPercussionChannel() {
+ if (_driver)
+ return _driver->getPercussionChannel();
+ return NULL;
+ }
+
+ void setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc) {
+ if (_driver)
+ _driver->setTimerCallback(timer_param, timer_proc);
+ }
+
+ uint32 getBaseTempo() {
+ if (_driver) {
+ return _driver->getBaseTempo();
+ }
+ return 1000000 / _baseFreq;
+ }
+
+protected:
+ Common::Mutex _mutex;
+ MidiDriver *_driver;
+ bool _nativeMT32; // native MT32, may also be our MUNT, or MUNT over MIDI
+
+ bool _isOpen;
+ int _baseFreq;
+
+private:
+ // simple mapping between MIDI channel and MT32 channel
+ byte _channelMapping[AGOS_MIDI_CHANNEL_COUNT];
+ // simple mapping between MIDI instruments and MT32 instruments
+ byte _instrumentMapping[AGOS_MIDI_INSTRUMENT_COUNT];
+
+public:
+ bool setupInstruments(byte *instrumentData, uint16 instrumentDataSize, bool useMusicDrvFile);
+};
+
+MidiDriver_Accolade_MT32::MidiDriver_Accolade_MT32() {
+ _driver = NULL;
+ _isOpen = false;
+ _nativeMT32 = false;
+ _baseFreq = 250;
+
+ memset(_channelMapping, 0, sizeof(_channelMapping));
+ memset(_instrumentMapping, 0, sizeof(_instrumentMapping));
+}
+
+MidiDriver_Accolade_MT32::~MidiDriver_Accolade_MT32() {
+ Common::StackLock lock(_mutex);
+ if (_driver) {
+ _driver->setTimerCallback(0, 0);
+ _driver->close();
+ delete _driver;
+ }
+ _driver = NULL;
+}
+
+int MidiDriver_Accolade_MT32::open() {
+ assert(!_driver);
+
+// debugC(kDebugLevelMT32Driver, "MT32: starting driver");
+
+ // Setup midi driver
+ MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_PREFER_MT32);
+ MusicType musicType = MidiDriver::getMusicType(dev);
+
+ // check, if we got a real MT32 (or MUNT, or MUNT over MIDI)
+ switch (musicType) {
+ case MT_MT32:
+ _nativeMT32 = true;
+ break;
+ case MT_GM:
+ if (ConfMan.getBool("native_mt32")) {
+ _nativeMT32 = true;
+ }
+ break;
+ default:
+ break;
+ }
+
+ _driver = MidiDriver::createMidi(dev);
+ if (!_driver)
+ return 255;
+
+ int ret = _driver->open();
+ if (ret)
+ return ret;
+
+ if (_nativeMT32)
+ _driver->sendMT32Reset();
+ else
+ _driver->sendGMReset();
+
+ return 0;
+}
+
+void MidiDriver_Accolade_MT32::close() {
+ if (_driver) {
+ _driver->close();
+ }
+}
+
+// MIDI messages can be found at http://www.midi.org/techspecs/midimessages.php
+void MidiDriver_Accolade_MT32::send(uint32 b) {
+ byte command = b & 0xf0;
+ byte channel = b & 0xf;
+
+ if (command == 0xF0) {
+ if (_driver) {
+ _driver->send(b);
+ }
+ return;
+ }
+
+ byte mappedChannel = _channelMapping[channel];
+
+ if (mappedChannel < AGOS_MIDI_CHANNEL_COUNT) {
+ // channel mapped to an actual MIDI channel, so use that one
+ b = (b & 0xFFFFFFF0) | mappedChannel;
+ if (command == 0xC0) {
+ // Program change
+ // Figure out the requested instrument
+ byte midiInstrument = (b >> 8) & 0xFF;
+ byte mappedInstrument = _instrumentMapping[midiInstrument];
+
+ // If there is no actual MT32 (or MUNT), we make a second mapping to General MIDI instruments
+ if (!_nativeMT32) {
+ mappedInstrument = (MidiDriver::_mt32ToGm[mappedInstrument]);
+ }
+ // And replace it
+ b = (b & 0xFFFF00FF) | (mappedInstrument << 8);
+ }
+
+ if (_driver) {
+ _driver->send(b);
+ }
+ }
+}
+
+// Called right at the start, we get an INSTR.DAT entry
+bool MidiDriver_Accolade_MT32::setupInstruments(byte *driverData, uint16 driverDataSize, bool useMusicDrvFile) {
+ uint16 channelMappingOffset = 0;
+ uint16 channelMappingSize = 0;
+ uint16 instrumentMappingOffset = 0;
+ uint16 instrumentMappingSize = 0;
+
+ if (!useMusicDrvFile) {
+ // INSTR.DAT: we expect at least 354 bytes
+ if (driverDataSize < 354)
+ return false;
+
+ // Data is like this:
+ // 128 bytes instrument mapping
+ // 128 bytes instrument volume adjust (signed!) (not used for MT32)
+ // 16 bytes unknown
+ // 16 bytes channel mapping
+ // 64 bytes key note mapping (not really used for MT32)
+ // 1 byte instrument count
+ // 1 byte bytes per instrument
+ // x bytes no instruments used for MT32
+
+ channelMappingOffset = 256 + 16;
+ channelMappingSize = 16;
+ instrumentMappingOffset = 0;
+ instrumentMappingSize = 128;
+
+ } else {
+ // MUSIC.DRV: we expect at least 468 bytes
+ if (driverDataSize < 468)
+ return false;
+
+ channelMappingOffset = 396;
+ channelMappingSize = 16;
+ instrumentMappingOffset = 140;
+ instrumentMappingSize = 128;
+ }
+
+ // Channel mapping
+ if (channelMappingSize) {
+ // Get these 16 bytes for MIDI channel mapping
+ if (channelMappingSize != sizeof(_channelMapping))
+ return false;
+
+ memcpy(_channelMapping, driverData + channelMappingOffset, sizeof(_channelMapping));
+ } else {
+ // Set up straight mapping
+ for (uint16 channelNr = 0; channelNr < sizeof(_channelMapping); channelNr++) {
+ _channelMapping[channelNr] = channelNr;
+ }
+ }
+
+ if (instrumentMappingSize) {
+ // And these for instrument mapping
+ if (instrumentMappingSize > sizeof(_instrumentMapping))
+ return false;
+
+ memcpy(_instrumentMapping, driverData + instrumentMappingOffset, instrumentMappingSize);
+ }
+ // Set up straight mapping for the remaining data
+ for (uint16 instrumentNr = instrumentMappingSize; instrumentNr < sizeof(_instrumentMapping); instrumentNr++) {
+ _instrumentMapping[instrumentNr] = instrumentNr;
+ }
+ return true;
+}
+
+MidiDriver *MidiDriver_Accolade_MT32_create(Common::String driverFilename) {
+ byte *driverData = NULL;
+ uint16 driverDataSize = 0;
+ bool isMusicDrvFile = false;
+
+ MidiDriver_Accolade_readDriver(driverFilename, MT_MT32, driverData, driverDataSize, isMusicDrvFile);
+ if (!driverData)
+ error("ACCOLADE-ADLIB: error during readDriver()");
+
+ MidiDriver_Accolade_MT32 *driver = new MidiDriver_Accolade_MT32();
+ if (driver) {
+ if (!driver->setupInstruments(driverData, driverDataSize, isMusicDrvFile)) {
+ delete driver;
+ driver = nullptr;
+ }
+ }
+
+ delete[] driverData;
+ return driver;
+}
+
+} // End of namespace AGOS
diff --git a/engines/agos/gfx.cpp b/engines/agos/gfx.cpp
index 5a1f9f1917..867842276a 100644
--- a/engines/agos/gfx.cpp
+++ b/engines/agos/gfx.cpp
@@ -1303,6 +1303,13 @@ void AGOSEngine::setWindowImageEx(uint16 mode, uint16 vgaSpriteId) {
} else {
setWindowImage(mode, vgaSpriteId);
}
+
+ // Amiga versions wait for verb area to be displayed.
+ if (getGameType() == GType_SIMON1 && getPlatform() == Common::kPlatformAmiga && vgaSpriteId == 1) {
+ _copyScnFlag = 5;
+ while (_copyScnFlag && !shouldQuit())
+ delay(1);
+ }
}
void AGOSEngine::setWindowImage(uint16 mode, uint16 vgaSpriteId, bool specialCase) {
diff --git a/engines/agos/input.cpp b/engines/agos/input.cpp
index 687a8ef1cf..686b1c35b2 100644
--- a/engines/agos/input.cpp
+++ b/engines/agos/input.cpp
@@ -707,6 +707,7 @@ bool AGOSEngine::processSpecialKeys() {
if (_midiEnabled) {
_midi->pause(_musicPaused);
}
+ _mixer->pauseHandle(_modHandle, _musicPaused);
syncSoundSettings();
break;
case 's':
diff --git a/engines/agos/midi.cpp b/engines/agos/midi.cpp
index 045fd9dac5..85f2dd5977 100644
--- a/engines/agos/midi.cpp
+++ b/engines/agos/midi.cpp
@@ -23,10 +23,20 @@
#include "common/config-manager.h"
#include "common/file.h"
#include "common/textconsole.h"
+#include "common/memstream.h"
#include "agos/agos.h"
#include "agos/midi.h"
+#include "agos/drivers/accolade/mididriver.h"
+// Miles Audio for Simon 2
+#include "audio/miles.h"
+
+// PKWARE data compression library decompressor required for Simon 2
+#include "common/dcl.h"
+
+#include "gui/message.h"
+
namespace AGOS {
@@ -42,6 +52,9 @@ MidiPlayer::MidiPlayer() {
_driver = 0;
_map_mt32_to_gm = false;
+ _adlibPatches = NULL;
+
+ _adLibMusic = false;
_enable_sfx = true;
_current = 0;
@@ -52,9 +65,11 @@ MidiPlayer::MidiPlayer() {
_paused = false;
_currentTrack = 255;
- _loopTrackDefault = false;
+ _loopTrack = 0;
_queuedTrack = 255;
_loopQueuedTrack = 0;
+
+ _musicMode = kMusicModeDisabled;
}
MidiPlayer::~MidiPlayer() {
@@ -68,14 +83,160 @@ MidiPlayer::~MidiPlayer() {
}
_driver = NULL;
clearConstructs();
+ unloadAdlibPatches();
}
-int MidiPlayer::open(int gameType) {
+int MidiPlayer::open(int gameType, bool isDemo) {
// Don't call open() twice!
assert(!_driver);
- // Setup midi driver
- MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_ADLIB | MDT_MIDI | (gameType == GType_SIMON1 ? MDT_PREFER_MT32 : MDT_PREFER_GM));
+ Common::String accoladeDriverFilename;
+ MusicType musicType = MT_INVALID;
+
+ switch (gameType) {
+ case GType_ELVIRA1:
+ _musicMode = kMusicModeAccolade;
+ accoladeDriverFilename = "INSTR.DAT";
+ break;
+ case GType_ELVIRA2:
+ case GType_WW:
+ // Attention: Elvira 2 shipped with INSTR.DAT and MUSIC.DRV
+ // MUSIC.DRV is the correct one. INSTR.DAT seems to be a left-over
+ _musicMode = kMusicModeAccolade;
+ accoladeDriverFilename = "MUSIC.DRV";
+ break;
+ case GType_SIMON1:
+ if (isDemo) {
+ _musicMode = kMusicModeAccolade;
+ accoladeDriverFilename = "MUSIC.DRV";
+ }
+ break;
+ case GType_SIMON2:
+ //_musicMode = kMusicModeMilesAudio;
+ // currently disabled, because there are a few issues
+ // MT32 seems to work fine now, AdLib seems to use bad instruments and is also outputting music on
+ // the right speaker only. The original driver did initialize the panning to 0 and the Simon2 XMIDI
+ // tracks don't set panning at all. We can reset panning to be centered, which would solve this
+ // issue, but we still don't know who's setting it in the original interpreter.
+ break;
+ default:
+ break;
+ }
+
+ MidiDriver::DeviceHandle dev;
+ int ret = 0;
+
+ if (_musicMode != kMusicModeDisabled) {
+ dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MT32);
+ musicType = MidiDriver::getMusicType(dev);
+
+ switch (musicType) {
+ case MT_ADLIB:
+ case MT_MT32:
+ break;
+ case MT_GM:
+ if (!ConfMan.getBool("native_mt32")) {
+ // Not a real MT32 / no MUNT
+ ::GUI::MessageDialog dialog(("You appear to be using a General MIDI device,\n"
+ "but your game only supports Roland MT32 MIDI.\n"
+ "We try to map the Roland MT32 instruments to\n"
+ "General MIDI ones. It is still possible that\n"
+ "some tracks sound incorrect."));
+ dialog.runModal();
+ }
+ // Switch to MT32 driver in any case
+ musicType = MT_MT32;
+ break;
+ default:
+ _musicMode = kMusicModeDisabled;
+ break;
+ }
+ }
+
+ switch (_musicMode) {
+ case kMusicModeAccolade: {
+ // Setup midi driver
+ switch (musicType) {
+ case MT_ADLIB:
+ _driver = MidiDriver_Accolade_AdLib_create(accoladeDriverFilename);
+ break;
+ case MT_MT32:
+ _driver = MidiDriver_Accolade_MT32_create(accoladeDriverFilename);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ if (!_driver)
+ return 255;
+
+ ret = _driver->open();
+ if (ret == 0) {
+ // Reset is done inside our MIDI driver
+ _driver->setTimerCallback(this, &onTimer);
+ }
+
+ //setTimerRate(_driver->getBaseTempo());
+ return 0;
+ }
+
+ case kMusicModeMilesAudio: {
+ switch (musicType) {
+ case MT_ADLIB: {
+ Common::File instrumentDataFile;
+ if (instrumentDataFile.exists("MIDPAK.AD")) {
+ // if there is a file called MIDPAK.AD, use it directly
+ warning("SIMON 2: using MIDPAK.AD");
+ _driver = Audio::MidiDriver_Miles_AdLib_create("MIDPAK.AD", "MIDPAK.AD");
+ } else {
+ // if there is no file called MIDPAK.AD, try to extract it from the file SETUP.SHR
+ // if we didn't do this, the user would be forced to "install" the game instead of simply
+ // copying all files from CD-ROM.
+ Common::SeekableReadStream *midpakAdLibStream;
+ midpakAdLibStream = simon2SetupExtractFile("MIDPAK.AD");
+ if (!midpakAdLibStream)
+ error("MidiPlayer: could not extract MIDPAK.AD from SETUP.SHR");
+
+ // Pass this extracted data to the driver
+ warning("SIMON 2: using MIDPAK.AD extracted from SETUP.SHR");
+ _driver = Audio::MidiDriver_Miles_AdLib_create("", "", midpakAdLibStream);
+ delete midpakAdLibStream;
+ }
+ // TODO: not sure what's going wrong with AdLib
+ // it doesn't seem to matter if we use the regular XMIDI tracks or the 2nd set meant for MT32
+ break;
+ }
+ case MT_MT32:
+ _driver = Audio::MidiDriver_Miles_MT32_create("");
+ _nativeMT32 = true; // use 2nd set of XMIDI tracks
+ break;
+ case MT_GM:
+ if (ConfMan.getBool("native_mt32")) {
+ _driver = Audio::MidiDriver_Miles_MT32_create("");
+ _nativeMT32 = true; // use 2nd set of XMIDI tracks
+ }
+ break;
+
+ default:
+ break;
+ }
+ if (!_driver)
+ return 255;
+
+ ret = _driver->open();
+ if (ret == 0) {
+ // Reset is done inside our MIDI driver
+ _driver->setTimerCallback(this, &onTimer);
+ }
+ return 0;
+ }
+
+ default:
+ break;
+ }
+
+ dev = MidiDriver::detectDevice(MDT_ADLIB | MDT_MIDI | (gameType == GType_SIMON1 ? MDT_PREFER_MT32 : MDT_PREFER_GM));
+ _adLibMusic = (MidiDriver::getMusicType(dev) == MT_ADLIB);
_nativeMT32 = ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32"));
_driver = MidiDriver::createMidi(dev);
@@ -85,9 +246,15 @@ int MidiPlayer::open(int gameType) {
if (_nativeMT32)
_driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
+ /* Disabled due to not sounding right, and low volume level
+ if (gameType == GType_SIMON1 && MidiDriver::getMusicType(dev) == MT_ADLIB) {
+ loadAdlibPatches();
+ }
+ */
+
_map_mt32_to_gm = (gameType != GType_SIMON2 && !_nativeMT32);
- int ret = _driver->open();
+ ret = _driver->open();
if (ret)
return ret;
_driver->setTimerCallback(this, &onTimer);
@@ -104,6 +271,12 @@ void MidiPlayer::send(uint32 b) {
if (!_current)
return;
+ if (_musicMode != kMusicModeDisabled) {
+ // Send directly to Accolade/Miles Audio driver
+ _driver->send(b);
+ return;
+ }
+
byte channel = (byte)(b & 0x0F);
if ((b & 0xFFF0) == 0x07B0) {
// Adjust volume changes by master music and master sfx volume.
@@ -114,8 +287,10 @@ void MidiPlayer::send(uint32 b) {
else if (_current == &_music)
volume = volume * _musicVolume / 255;
b = (b & 0xFF00FFFF) | (volume << 16);
- } else if ((b & 0xF0) == 0xC0 && _map_mt32_to_gm) {
- b = (b & 0xFFFF00FF) | (MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8);
+ } else if ((b & 0xF0) == 0xC0) {
+ if (_map_mt32_to_gm && !_adlibPatches) {
+ b = (b & 0xFFFF00FF) | (MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8);
+ }
} else if ((b & 0xFFF0) == 0x007BB0) {
// Only respond to an All Notes Off if this channel
// has already been allocated.
@@ -135,8 +310,10 @@ void MidiPlayer::send(uint32 b) {
_current->volume[channel] = 127;
}
+ // Allocate channels if needed
if (!_current->channel[channel])
_current->channel[channel] = (channel == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel();
+
if (_current->channel[channel]) {
if (channel == 9) {
if (_current == &_sfx)
@@ -144,7 +321,16 @@ void MidiPlayer::send(uint32 b) {
else if (_current == &_music)
_current->channel[9]->volume(_current->volume[9] * _musicVolume / 255);
}
- _current->channel[channel]->send(b);
+
+ if ((b & 0xF0) == 0xC0 && _adlibPatches) {
+ // NOTE: In the percussion channel, this function is a
+ // no-op. Any percussion instruments you hear may
+ // be the stock ones from adlib.cpp.
+ _driver->sysEx_customInstrument(_current->channel[channel]->getNumber(), 'ADL ', _adlibPatches + 30 * ((b >> 8) & 0xFF));
+ } else {
+ _current->channel[channel]->send(b);
+ }
+
if ((b & 0xFFF0) == 0x79B0) {
// We have received a "Reset All Controllers" message
// and passed it on to the MIDI driver. This may or may
@@ -166,13 +352,13 @@ void MidiPlayer::metaEvent(byte type, byte *data, uint16 length) {
return;
} else if (_current == &_sfx) {
clearConstructs(_sfx);
- } else if (_current->loopTrack) {
+ } else if (_loopTrack) {
_current->parser->jumpToTick(0);
} else if (_queuedTrack != 255) {
_currentTrack = 255;
byte destination = _queuedTrack;
_queuedTrack = 255;
- _current->loopTrack = _loopQueuedTrack;
+ _loopTrack = _loopQueuedTrack;
_loopQueuedTrack = false;
// Remember, we're still inside the locked mutex.
@@ -300,7 +486,7 @@ void MidiPlayer::setVolume(int musicVol, int sfxVol) {
void MidiPlayer::setLoop(bool loop) {
Common::StackLock lock(_mutex);
- _loopTrackDefault = loop;
+ _loopTrack = loop;
}
void MidiPlayer::queueTrack(int track, bool loop) {
@@ -355,6 +541,47 @@ void MidiPlayer::resetVolumeTable() {
}
}
+void MidiPlayer::loadAdlibPatches() {
+ Common::File ibk;
+
+ if (!ibk.open("mt_fm.ibk"))
+ return;
+
+ if (ibk.readUint32BE() == 0x49424b1a) {
+ _adlibPatches = new byte[128 * 30];
+ byte *ptr = _adlibPatches;
+
+ memset(_adlibPatches, 0, 128 * 30);
+
+ for (int i = 0; i < 128; i++) {
+ byte instr[16];
+
+ ibk.read(instr, 16);
+
+ ptr[0] = instr[0]; // Modulator Sound Characteristics
+ ptr[1] = instr[2]; // Modulator Scaling/Output Level
+ ptr[2] = ~instr[4]; // Modulator Attack/Decay
+ ptr[3] = ~instr[6]; // Modulator Sustain/Release
+ ptr[4] = instr[8]; // Modulator Wave Select
+ ptr[5] = instr[1]; // Carrier Sound Characteristics
+ ptr[6] = instr[3]; // Carrier Scaling/Output Level
+ ptr[7] = ~instr[5]; // Carrier Attack/Delay
+ ptr[8] = ~instr[7]; // Carrier Sustain/Release
+ ptr[9] = instr[9]; // Carrier Wave Select
+ ptr[10] = instr[10]; // Feedback/Connection
+
+ // The remaining six bytes are reserved for future use
+
+ ptr += 30;
+ }
+ }
+}
+
+void MidiPlayer::unloadAdlibPatches() {
+ delete[] _adlibPatches;
+ _adlibPatches = NULL;
+}
+
static const int simon1_gmf_size[] = {
8900, 12166, 2848, 3442, 4034, 4508, 7064, 9730, 6014, 4742, 3138,
6570, 5384, 8909, 6457, 16321, 2742, 8968, 4804, 8442, 7717,
@@ -426,9 +653,11 @@ void MidiPlayer::loadSMF(Common::File *in, int song, bool sfx) {
// It seems that 4 corresponds to our base tempo, so
// this should be the right way to calculate it.
timerRate = (4 * _driver->getBaseTempo()) / p->data[5];
- p->loopTrack = (p->data[6] != 0);
- } else {
- p->loopTrack = _loopTrackDefault;
+
+ // According to bug #1004919 calling setLoop() from
+ // within a lock causes a lockup, though I have no
+ // idea when this actually happens.
+ _loopTrack = (p->data[6] != 0);
}
MidiParser *parser = MidiParser::createParser_SMF();
@@ -498,8 +727,6 @@ void MidiPlayer::loadMultipleSMF(Common::File *in, bool sfx) {
p->song_sizes[i] = size;
}
- p->loopTrack = _loopTrackDefault;
-
if (!sfx) {
_currentTrack = 255;
resetVolumeTable();
@@ -531,7 +758,6 @@ void MidiPlayer::loadXMIDI(Common::File *in, bool sfx) {
in->seek(pos, 0);
p->data = (byte *)calloc(size, 1);
in->read(p->data, size);
- p->loopTrack = _loopTrackDefault;
} else {
error("Expected 'FORM' tag but found '%c%c%c%c' instead", buf[0], buf[1], buf[2], buf[3]);
}
@@ -576,8 +802,105 @@ void MidiPlayer::loadS1D(Common::File *in, bool sfx) {
_currentTrack = 255;
resetVolumeTable();
}
- p->loopTrack = _loopTrackDefault;
p->parser = parser; // That plugs the power cord into the wall
}
+#define MIDI_SETUP_BUNDLE_HEADER_SIZE 56
+#define MIDI_SETUP_BUNDLE_FILEHEADER_SIZE 48
+#define MIDI_SETUP_BUNDLE_FILENAME_MAX_SIZE 12
+
+// PKWARE data compression library (called "DCL" in ScummVM) was used for storing files within SETUP.SHR
+// we need it to be able to get the file MIDPAK.AD, otherwise we would have to require the user
+// to "install" the game before being able to actually play it, when using AdLib.
+//
+// SETUP.SHR file format:
+// [bundle file header]
+// [compressed file header] [compressed file data]
+// * compressed file count
+Common::SeekableReadStream *MidiPlayer::simon2SetupExtractFile(const Common::String &requestedFileName) {
+ Common::File *setupBundleStream = new Common::File();
+ uint32 bundleSize = 0;
+ uint32 bundleBytesLeft = 0;
+ byte bundleHeader[MIDI_SETUP_BUNDLE_HEADER_SIZE];
+ byte bundleFileHeader[MIDI_SETUP_BUNDLE_FILEHEADER_SIZE];
+ uint16 bundleFileCount = 0;
+ uint16 bundleFileNr = 0;
+
+ Common::String fileName;
+ uint32 fileCompressedSize = 0;
+ byte *fileCompressedDataPtr = nullptr;
+
+ Common::SeekableReadStream *extractedStream = nullptr;
+
+ if (!setupBundleStream->open("setup.shr"))
+ error("MidiPlayer: could not open setup.shr");
+
+ bundleSize = setupBundleStream->size();
+ bundleBytesLeft = bundleSize;
+
+ if (bundleSize < MIDI_SETUP_BUNDLE_HEADER_SIZE)
+ error("MidiPlayer: unexpected EOF in setup.shr");
+
+ if (setupBundleStream->read(bundleHeader, MIDI_SETUP_BUNDLE_HEADER_SIZE) != MIDI_SETUP_BUNDLE_HEADER_SIZE)
+ error("MidiPlayer: setup.shr read error");
+ bundleBytesLeft -= MIDI_SETUP_BUNDLE_HEADER_SIZE;
+
+ // Verify header byte
+ if (bundleHeader[13] != 't')
+ error("MidiPlayer: setup.shr bundle header data mismatch");
+
+ bundleFileCount = READ_LE_UINT16(&bundleHeader[14]);
+
+ // Search for requested file
+ while (bundleFileNr < bundleFileCount) {
+ if (bundleBytesLeft < sizeof(bundleFileHeader))
+ error("MidiPlayer: unexpected EOF in setup.shr");
+
+ if (setupBundleStream->read(bundleFileHeader, sizeof(bundleFileHeader)) != sizeof(bundleFileHeader))
+ error("MidiPlayer: setup.shr read error");
+ bundleBytesLeft -= MIDI_SETUP_BUNDLE_FILEHEADER_SIZE;
+
+ // Extract filename from file-header
+ fileName.clear();
+ for (byte curPos = 0; curPos < MIDI_SETUP_BUNDLE_FILENAME_MAX_SIZE; curPos++) {
+ if (!bundleFileHeader[curPos]) // terminating NUL
+ break;
+ fileName.insertChar(bundleFileHeader[curPos], curPos);
+ }
+
+ // Get compressed
+ fileCompressedSize = READ_LE_UINT32(&bundleFileHeader[20]);
+ if (!fileCompressedSize)
+ error("MidiPlayer: compressed file is 0 bytes, data corruption?");
+ if (bundleBytesLeft < fileCompressedSize)
+ error("MidiPlayer: unexpected EOF in setup.shr");
+
+ if (fileName == requestedFileName) {
+ // requested file found
+ fileCompressedDataPtr = new byte[fileCompressedSize];
+
+ if (setupBundleStream->read(fileCompressedDataPtr, fileCompressedSize) != fileCompressedSize)
+ error("MidiPlayer: setup.shr read error");
+
+ Common::MemoryReadStream *compressedStream = nullptr;
+
+ compressedStream = new Common::MemoryReadStream(fileCompressedDataPtr, fileCompressedSize);
+ // we don't know the unpacked size, let decompressor figure it out
+ extractedStream = Common::decompressDCL(compressedStream);
+ delete compressedStream;
+ break;
+ }
+
+ // skip compressed size
+ setupBundleStream->skip(fileCompressedSize);
+ bundleBytesLeft -= fileCompressedSize;
+
+ bundleFileNr++;
+ }
+ setupBundleStream->close();
+ delete setupBundleStream;
+
+ return extractedStream;
+}
+
} // End of namespace AGOS
diff --git a/engines/agos/midi.h b/engines/agos/midi.h
index 398e445535..edb3402735 100644
--- a/engines/agos/midi.h
+++ b/engines/agos/midi.h
@@ -33,10 +33,15 @@ class File;
namespace AGOS {
+enum kMusicMode {
+ kMusicModeDisabled = 0,
+ kMusicModeAccolade = 1,
+ kMusicModeMilesAudio
+};
+
struct MusicInfo {
MidiParser *parser;
byte *data;
- bool loopTrack;
byte num_songs; // For Type 1 SMF resources
byte *songs[16]; // For Type 1 SMF resources
uint32 song_sizes[16]; // For Type 1 SMF resources
@@ -47,7 +52,6 @@ struct MusicInfo {
MusicInfo() { clear(); }
void clear() {
parser = 0; data = 0; num_songs = 0;
- loopTrack = false;
memset(songs, 0, sizeof(songs));
memset(song_sizes, 0, sizeof(song_sizes));
memset(channel, 0, sizeof(channel));
@@ -73,17 +77,22 @@ protected:
// These are only used for music.
byte _currentTrack;
- bool _loopTrackDefault;
+ bool _loopTrack;
byte _queuedTrack;
bool _loopQueuedTrack;
+ byte *_adlibPatches;
+
protected:
static void onTimer(void *data);
void clearConstructs();
void clearConstructs(MusicInfo &info);
void resetVolumeTable();
+ void loadAdlibPatches();
+ void unloadAdlibPatches();
public:
+ bool _adLibMusic;
bool _enable_sfx;
public:
@@ -109,12 +118,17 @@ public:
void setVolume(int musicVol, int sfxVol);
public:
- int open(int gameType);
+ int open(int gameType, bool isDemo);
// MidiDriver_BASE interface implementation
virtual void send(uint32 b);
virtual void metaEvent(byte type, byte *data, uint16 length);
+private:
+ kMusicMode _musicMode;
+
+private:
+ Common::SeekableReadStream *simon2SetupExtractFile(const Common::String &requestedFileName);
};
} // End of namespace AGOS
diff --git a/engines/agos/midiparser_s1d.cpp b/engines/agos/midiparser_s1d.cpp
index c2c08bf451..7b9a058efc 100644
--- a/engines/agos/midiparser_s1d.cpp
+++ b/engines/agos/midiparser_s1d.cpp
@@ -179,12 +179,43 @@ void MidiParser_S1D::parseNextEvent(EventInfo &info) {
bool MidiParser_S1D::loadMusic(byte *data, uint32 size) {
unloadMusic();
+ if (!size)
+ return false;
+
// The original actually just ignores the first two bytes.
byte *pos = data;
- if (*(pos++) != 0xFC)
- debug(1, "Expected 0xFC header but found 0x%02X instead", (int) *pos);
-
- pos += 1;
+ if (*pos == 0xFC) {
+ // SysEx found right at the start
+ // this seems to happen since Elvira 2, we ignore it
+ // 3rd byte after the SysEx seems to be saved into a global
+
+ // We expect at least 4 bytes in total
+ if (size < 4)
+ return false;
+
+ byte skipOffset = pos[2]; // get second byte after the SysEx
+ // pos[1] seems to have been ignored
+ // pos[3] is saved into a global inside the original interpreters
+
+ // Waxworks + Simon 1 demo typical header is:
+ // 0xFC 0x29 0x07 0x01 [0x00/0x01]
+ // Elvira 2 typical header is:
+ // 0xFC 0x04 0x06 0x06
+
+ if (skipOffset >= 6) {
+ // should be at least 6, so that we skip over the 2 size bytes and the
+ // smallest SysEx possible
+ skipOffset -= 2; // 2 size bytes were already read by previous code outside of this method
+
+ if (size <= skipOffset) // Skip to the end of file? -> something is not correct
+ return false;
+
+ // Do skip over the bytes
+ pos += skipOffset;
+ } else {
+ warning("MidiParser_S1D: unexpected skip offset in music file");
+ }
+ }
// And now we're at the actual data. Only one track.
_numTracks = 1;
diff --git a/engines/agos/module.mk b/engines/agos/module.mk
index 7069d8005b..6d4e72e433 100644
--- a/engines/agos/module.mk
+++ b/engines/agos/module.mk
@@ -1,6 +1,9 @@
MODULE := engines/agos
MODULE_OBJS := \
+ drivers/accolade/adlib.o \
+ drivers/accolade/driverfile.o \
+ drivers/accolade/mt32.o \
agos.o \
charset.o \
charset-fontdata.o \
diff --git a/engines/agos/res_snd.cpp b/engines/agos/res_snd.cpp
index 5d6ab60c8b..d04f1735d6 100644
--- a/engines/agos/res_snd.cpp
+++ b/engines/agos/res_snd.cpp
@@ -220,6 +220,7 @@ void AGOSEngine::playModule(uint16 music) {
}
_mixer->playStream(Audio::Mixer::kMusicSoundType, &_modHandle, audioStream);
+ _mixer->pauseHandle(_modHandle, _musicPaused);
}
void AGOSEngine_Simon1::playMusic(uint16 music, uint16 track) {
@@ -309,7 +310,9 @@ void AGOSEngine::stopMusic() {
}
void AGOSEngine::playSting(uint16 soundId) {
- if (!_midi->_enable_sfx)
+ // The sound effects in floppy disk version of
+ // Simon the Sorcerer 1 are only meant for AdLib
+ if (!_midi->_adLibMusic || !_midi->_enable_sfx)
return;
char filename[15];
diff --git a/engines/agos/rooms.cpp b/engines/agos/rooms.cpp
index 6185653d42..d1d6f2b99d 100644
--- a/engines/agos/rooms.cpp
+++ b/engines/agos/rooms.cpp
@@ -383,7 +383,7 @@ bool AGOSEngine::loadRoomItems(uint16 room) {
for (uint16 z = minNum; z <= maxNum; z++) {
uint16 itemNum = z + 2;
item = derefItem(itemNum);
- item->parent = 0;
+ _itemArrayPtr[itemNum] = 0;
uint16 num = (itemNum - _itemArrayInited);
_roomStates[num].state = item->state;
@@ -453,6 +453,7 @@ bool AGOSEngine::loadRoomItems(uint16 room) {
item->classFlags = _roomStates[num].classFlags;
SubRoom *subRoom = (SubRoom *)findChildOfType(item, kRoomType);
subRoom->roomExitStates = _roomStates[num].roomExitStates;
+
}
in.close();
diff --git a/engines/agos/saveload.cpp b/engines/agos/saveload.cpp
index 5d5e2d7b03..b968ae645c 100644
--- a/engines/agos/saveload.cpp
+++ b/engines/agos/saveload.cpp
@@ -1261,7 +1261,6 @@ bool AGOSEngine_Elvira2::loadGame(const Common::String &filename, bool restartMo
uint16 room = _currentRoom;
_currentRoom = f->readUint16BE();
-
if (_roomsListPtr) {
byte *p = _roomsListPtr;
if (room == _currentRoom) {
@@ -1293,8 +1292,7 @@ bool AGOSEngine_Elvira2::loadGame(const Common::String &filename, bool restartMo
for (uint16 z = minNum; z <= maxNum; z++) {
uint16 itemNum = z + 2;
- Item *item = derefItem(itemNum);
- item->parent = 0;
+ _itemArrayPtr[itemNum] = 0;
}
}
}
@@ -1318,6 +1316,9 @@ bool AGOSEngine_Elvira2::loadGame(const Common::String &filename, bool restartMo
uint parent = f->readUint16BE();
uint next = f->readUint16BE();
+ if (getGameType() == GType_WW && getPlatform() == Common::kPlatformDOS && derefItem(item->parent) == NULL)
+ item->parent = 0;
+
parent_item = derefItem(parent);
setItemParent(item, parent_item);
diff --git a/engines/agos/sound.cpp b/engines/agos/sound.cpp
index 812f46504f..762f60bd91 100644
--- a/engines/agos/sound.cpp
+++ b/engines/agos/sound.cpp
@@ -515,7 +515,7 @@ void Sound::readSfxFile(const Common::String &filename) {
// This method is only used by Simon2
void Sound::loadSfxTable(const char *gameFilename, uint32 base) {
- stopAll();
+ stopAllSfx();
delete _effects;
const bool dataIsUnsigned = true;
@@ -684,7 +684,7 @@ void Sound::playRawData(byte *soundData, uint sound, uint size, uint freq) {
memcpy(buffer, soundData, size);
byte flags = 0;
- if (_vm->getPlatform() == Common::kPlatformDOS)
+ if (_vm->getPlatform() == Common::kPlatformDOS && _vm->getGameId() != GID_ELVIRA2)
flags = Audio::FLAG_UNSIGNED;
Audio::AudioStream *stream = Audio::makeRawStream(buffer, size, freq, flags);
diff --git a/engines/agos/zones.cpp b/engines/agos/zones.cpp
index 1644213579..5a753d9b4b 100644
--- a/engines/agos/zones.cpp
+++ b/engines/agos/zones.cpp
@@ -94,8 +94,7 @@ void AGOSEngine::loadZone(uint16 zoneNum, bool useError) {
vpe->sfxFile = NULL;
- if ((getPlatform() == Common::kPlatformAmiga || getPlatform() == Common::kPlatformAtariST) &&
- getGameType() == GType_ELVIRA2) {
+ if (getGameType() == GType_ELVIRA2) {
// A singe sound file is used for Amiga and AtariST versions
if (loadVGASoundFile(1, 3)) {
vpe->sfxFile = _block;
diff --git a/engines/bbvs/minigames/bbairguitar.cpp b/engines/bbvs/minigames/bbairguitar.cpp
index 1984dbb0fd..26e27a966f 100644
--- a/engines/bbvs/minigames/bbairguitar.cpp
+++ b/engines/bbvs/minigames/bbairguitar.cpp
@@ -22,6 +22,12 @@
#include "bbvs/minigames/bbairguitar.h"
+#include "common/savefile.h"
+#include "common/translation.h"
+
+#include "gui/dialog.h"
+#include "gui/message.h"
+
namespace Bbvs {
static const char * const kNoteSoundFilenames[] = {
@@ -805,7 +811,7 @@ void MinigameBbAirGuitar::update() {
}
if (_vm->_keyCode == Common::KEYCODE_ESCAPE) {
- _gameDone = true;
+ _gameDone = querySaveModifiedTracks();
return;
}
@@ -925,7 +931,8 @@ void MinigameBbAirGuitar::afterButtonReleased() {
break;
case 4:
*_currFrameIndex = 1;
- // TODO Run load dialog
+ loadTracks();
+ _objects[1].kind = 0;
break;
case 5:
_objects[3].kind = 0;
@@ -950,7 +957,8 @@ void MinigameBbAirGuitar::afterButtonReleased() {
break;
case 12:
*_currFrameIndex = 1;
- // TODO Run save dialog
+ saveTracks();
+ _objects[2].kind = 0;
break;
case 13:
_objects[4].kind = 0;
@@ -1113,7 +1121,7 @@ void MinigameBbAirGuitar::noteOff(int noteNum) {
if (_actionTrackPos + _ticksDelta > 15000)
_ticksDelta = 15000 - _actionTrackPos;
_track[_trackCount].ticks = _ticksDelta;
- if (_trackCount < 2048)
+ if (_trackCount + 1 < 2048)
++_trackCount;
_track[_trackCount].noteNum = -2;
_noteStartTime = _vm->_system->getMillis();
@@ -1195,4 +1203,103 @@ void MinigameBbAirGuitar::stopNote(int noteNum) {
stopSound(2 + _currPatchNum * kNoteSoundFilenamesCount + noteNum);
}
+bool MinigameBbAirGuitar::getLoadFilename(Common::String &filename) {
+ // TODO Run dialog and return actual filename
+ filename = "test.air";
+ return true;
+}
+
+bool MinigameBbAirGuitar::getSaveFilename(Common::String &filename) {
+ // TODO Run dialog and return actual filename
+ filename = "test.air";
+ return true;
+}
+
+bool MinigameBbAirGuitar::querySaveModifiedDialog() {
+ /* NOTE The original button captions don't fit so shortened variants are used
+ Original ok button caption: "Yeah, heh, heh, save it!"
+ Original discard button caption: "Who cares? It sucked!"
+ */
+ GUI::MessageDialog query(_("Hey Beavis - you didn't save that last Jam!"),
+ _("Save it!"),
+ _("It sucked!"));
+ return query.runModal() == GUI::kMessageOK;
+}
+
+bool MinigameBbAirGuitar::querySaveModifiedTracks() {
+ if (_modified && querySaveModifiedDialog()) {
+ if (!saveTracks())
+ return false;
+ }
+ return true;
+}
+
+bool MinigameBbAirGuitar::loadTracks() {
+ if (_playerMode != 0)
+ return false;
+
+ if (!querySaveModifiedTracks())
+ return false;
+
+ Common::String filename;
+ if (!getLoadFilename(filename))
+ return false;
+
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ Common::InSaveFile *stream = saveFileMan->openForLoading(filename);
+ if (!loadFromStream(stream)) {
+ Common::String msg = Common::String::format("%s is not a valid Air Guitar file", filename.c_str());
+ GUI::MessageDialog dialog(msg);
+ dialog.runModal();
+ }
+ delete stream;
+
+ return true;
+}
+
+bool MinigameBbAirGuitar::saveTracks() {
+ if (_playerMode != 0)
+ return false;
+
+ Common::String filename;
+ if (!getSaveFilename(filename))
+ return false;
+
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ Common::OutSaveFile *stream = saveFileMan->openForSaving(filename);
+ saveToStream(stream);
+ delete stream;
+ _modified = false;
+
+ return true;
+}
+
+bool MinigameBbAirGuitar::loadFromStream(Common::ReadStream *stream) {
+ uint32 magic = stream->readUint32BE();
+ if (magic != MKTAG('A', 'I', 'R', 'G'))
+ return false;
+ for (uint i = 0; i < kMaxTracks; ++i) {
+ _track[i].noteNum = stream->readByte();
+ _track[i].ticks = stream->readUint16LE();
+ }
+ _trackCount = 0;
+ _actionTrackPos = 0;
+ while (_track[_trackCount].noteNum != -1) {
+ _actionTrackPos += _track[_trackCount].ticks;
+ ++_trackCount;
+ }
+ _totalTrackLength = _actionTrackPos;
+ _trackIndex = 0;
+ _currTrackPos = 0;
+ return true;
+}
+
+void MinigameBbAirGuitar::saveToStream(Common::WriteStream *stream) {
+ stream->writeUint32BE(MKTAG('A', 'I', 'R', 'G'));
+ for (uint i = 0; i < kMaxTracks; ++i) {
+ stream->writeByte(_track[i].noteNum);
+ stream->writeUint16LE(_track[i].ticks);
+ }
+}
+
} // End of namespace Bbvs
diff --git a/engines/bbvs/minigames/bbairguitar.h b/engines/bbvs/minigames/bbairguitar.h
index 40b8a50a03..b8b92ef433 100644
--- a/engines/bbvs/minigames/bbairguitar.h
+++ b/engines/bbvs/minigames/bbairguitar.h
@@ -47,7 +47,7 @@ public:
enum {
kMaxObjectsCount = 256,
- kMaxTracks = 2049
+ kMaxTracks = 2048
};
struct PianoKeyInfo {
@@ -141,6 +141,15 @@ public:
void playNote(int noteNum);
void stopNote(int noteNum);
+ bool getLoadFilename(Common::String &filename);
+ bool getSaveFilename(Common::String &filename);
+ bool querySaveModifiedDialog();
+ bool querySaveModifiedTracks();
+ bool loadTracks();
+ bool saveTracks();
+ bool loadFromStream(Common::ReadStream *stream);
+ void saveToStream(Common::WriteStream *stream);
+
};
} // End of namespace Bbvs
diff --git a/engines/bbvs/sound.h b/engines/bbvs/sound.h
index 4e44c2b962..4d3253c48e 100644
--- a/engines/bbvs/sound.h
+++ b/engines/bbvs/sound.h
@@ -38,7 +38,7 @@ public:
void stop();
bool isPlaying();
protected:
- Audio::SeekableAudioStream *_stream;
+ Audio::RewindableAudioStream *_stream;
Audio::SoundHandle _handle;
// Keep the filename for debugging purposes
Common::String _filename;
diff --git a/engines/cge2/detection.cpp b/engines/cge2/detection.cpp
index 6e1b93d0b8..4acdea3fde 100644
--- a/engines/cge2/detection.cpp
+++ b/engines/cge2/detection.cpp
@@ -80,6 +80,16 @@ static const ADGameDescription gameDescriptions[] = {
},
Common::EN_ANY, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO1(GAMEOPTION_COLOR_BLIND_DEFAULT_OFF)
},
+
+ {
+ "sfinx", "Freeware v1.1",
+ {
+ {"vol.cat", 0, "f158e469dccbebc5a632eb848df89779", 129024},
+ {"vol.dat", 0, "d40a6b4ae173d6930be54ba56bee15d5", 34182773},
+ AD_LISTEND
+ },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO1(GAMEOPTION_COLOR_BLIND_DEFAULT_OFF)
+ },
AD_TABLE_END_MARKER
};
diff --git a/engines/cine/detection_tables.h b/engines/cine/detection_tables.h
index 6069e3a99b..1188deb1a6 100644
--- a/engines/cine/detection_tables.h
+++ b/engines/cine/detection_tables.h
@@ -379,6 +379,20 @@ static const CINEGameDescription gameDescriptions[] = {
{
{
"os",
+ "Demo",
+ AD_ENTRY1("demo_os", "043859e4cfe3977ad95b6efd00b21c62"),
+ Common::EN_GRB,
+ Common::kPlatformDOS,
+ ADGF_DEMO | ADGF_UNSTABLE,
+ GUIO0()
+ },
+ GType_OS,
+ GF_DEMO,
+ },
+
+ {
+ {
+ "os",
"",
AD_ENTRY1("procs0", "a9da5531ead0ebf9ad387fa588c0cbb0"),
Common::EN_GRB,
diff --git a/engines/cine/sound.cpp b/engines/cine/sound.cpp
index 069a4787ac..0c788b816c 100644
--- a/engines/cine/sound.cpp
+++ b/engines/cine/sound.cpp
@@ -101,7 +101,7 @@ struct AdLibSoundInstrument {
byte amDepth;
};
-class AdLibSoundDriver : public PCSoundDriver, Audio::AudioStream {
+class AdLibSoundDriver : public PCSoundDriver {
public:
AdLibSoundDriver(Audio::Mixer *mixer);
virtual ~AdLibSoundDriver();
@@ -112,14 +112,8 @@ public:
virtual void stopChannel(int channel);
virtual void stopAll();
- // AudioStream interface
- virtual int readBuffer(int16 *buffer, const int numSamples);
- virtual bool isStereo() const { return false; }
- virtual bool endOfData() const { return false; }
- virtual int getRate() const { return _sampleRate; }
-
void initCard();
- void update(int16 *buf, int len);
+ void onTimer();
void setupInstrument(const byte *data, int channel);
void loadRegisterInstrument(const byte *data, AdLibRegisterSoundInstrument *reg);
virtual void loadInstrument(const byte *data, AdLibSoundInstrument *asi) = 0;
@@ -128,10 +122,8 @@ protected:
UpdateCallback _upCb;
void *_upRef;
- FM_OPL *_opl;
- int _sampleRate;
+ OPL::OPL *_opl;
Audio::Mixer *_mixer;
- Audio::SoundHandle _soundHandle;
byte _vibrato;
int _channelsVolumeTable[4];
@@ -282,17 +274,19 @@ void PCSoundDriver::resetChannel(int channel) {
AdLibSoundDriver::AdLibSoundDriver(Audio::Mixer *mixer)
: _upCb(0), _upRef(0), _mixer(mixer) {
- _sampleRate = _mixer->getOutputRate();
- _opl = makeAdLibOPL(_sampleRate);
+
+ _opl = OPL::Config::create();
+ if (!_opl || !_opl->init())
+ error("Failed to create OPL");
+
memset(_channelsVolumeTable, 0, sizeof(_channelsVolumeTable));
memset(_instrumentsTable, 0, sizeof(_instrumentsTable));
initCard();
- _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
+ _opl->start(new Common::Functor0Mem<void, AdLibSoundDriver>(this, &AdLibSoundDriver::onTimer), 50);
}
AdLibSoundDriver::~AdLibSoundDriver() {
- _mixer->stopHandle(_soundHandle);
- OPLDestroy(_opl);
+ delete _opl;
}
void AdLibSoundDriver::setUpdateCallback(UpdateCallback upCb, void *ref) {
@@ -322,71 +316,52 @@ void AdLibSoundDriver::stopChannel(int channel) {
channel = 6;
}
if (ins->mode == 0 || channel == 6) {
- OPLWriteReg(_opl, 0xB0 | channel, 0);
+ _opl->writeReg(0xB0 | channel, 0);
}
if (ins->mode != 0) {
_vibrato &= ~(1 << (10 - ins->channel));
- OPLWriteReg(_opl, 0xBD, _vibrato);
+ _opl->writeReg(0xBD, _vibrato);
}
}
void AdLibSoundDriver::stopAll() {
int i;
for (i = 0; i < 18; ++i) {
- OPLWriteReg(_opl, 0x40 | _operatorsTable[i], 63);
+ _opl->writeReg(0x40 | _operatorsTable[i], 63);
}
for (i = 0; i < 9; ++i) {
- OPLWriteReg(_opl, 0xB0 | i, 0);
+ _opl->writeReg(0xB0 | i, 0);
}
- OPLWriteReg(_opl, 0xBD, 0);
-}
-
-int AdLibSoundDriver::readBuffer(int16 *buffer, const int numSamples) {
- update(buffer, numSamples);
- return numSamples;
+ _opl->writeReg(0xBD, 0);
}
void AdLibSoundDriver::initCard() {
_vibrato = 0x20;
- OPLWriteReg(_opl, 0xBD, _vibrato);
- OPLWriteReg(_opl, 0x08, 0x40);
+ _opl->writeReg(0xBD, _vibrato);
+ _opl->writeReg(0x08, 0x40);
static const int oplRegs[] = { 0x40, 0x60, 0x80, 0x20, 0xE0 };
for (int i = 0; i < 9; ++i) {
- OPLWriteReg(_opl, 0xB0 | i, 0);
+ _opl->writeReg(0xB0 | i, 0);
}
for (int i = 0; i < 9; ++i) {
- OPLWriteReg(_opl, 0xC0 | i, 0);
+ _opl->writeReg(0xC0 | i, 0);
}
for (int j = 0; j < 5; j++) {
for (int i = 0; i < 18; ++i) {
- OPLWriteReg(_opl, oplRegs[j] | _operatorsTable[i], 0);
+ _opl->writeReg(oplRegs[j] | _operatorsTable[i], 0);
}
}
- OPLWriteReg(_opl, 1, 0x20);
- OPLWriteReg(_opl, 1, 0);
+ _opl->writeReg(1, 0x20);
+ _opl->writeReg(1, 0);
}
-void AdLibSoundDriver::update(int16 *buf, int len) {
- static int samplesLeft = 0;
- while (len != 0) {
- int count = samplesLeft;
- if (count > len) {
- count = len;
- }
- samplesLeft -= count;
- len -= count;
- YM3812UpdateOne(_opl, buf, count);
- if (samplesLeft == 0) {
- if (_upCb) {
- (*_upCb)(_upRef);
- }
- samplesLeft = _sampleRate / 50;
- }
- buf += count;
+void AdLibSoundDriver::onTimer() {
+ if (_upCb) {
+ (*_upCb)(_upRef);
}
}
@@ -408,32 +383,32 @@ void AdLibSoundDriver::setupInstrument(const byte *data, int channel) {
if (ins->mode == 0 || ins->channel == 6) {
reg = &ins->regMod;
- OPLWriteReg(_opl, 0x20 | mod, reg->vibrato);
+ _opl->writeReg(0x20 | mod, reg->vibrato);
if (reg->freqMod) {
tmp = reg->outputLevel & 0x3F;
} else {
tmp = (63 - (reg->outputLevel & 0x3F)) * _channelsVolumeTable[channel];
tmp = 63 - (2 * tmp + 127) / (2 * 127);
}
- OPLWriteReg(_opl, 0x40 | mod, tmp | (reg->keyScaling << 6));
- OPLWriteReg(_opl, 0x60 | mod, reg->attackDecay);
- OPLWriteReg(_opl, 0x80 | mod, reg->sustainRelease);
+ _opl->writeReg(0x40 | mod, tmp | (reg->keyScaling << 6));
+ _opl->writeReg(0x60 | mod, reg->attackDecay);
+ _opl->writeReg(0x80 | mod, reg->sustainRelease);
if (ins->mode != 0) {
- OPLWriteReg(_opl, 0xC0 | ins->channel, reg->feedbackStrength);
+ _opl->writeReg(0xC0 | ins->channel, reg->feedbackStrength);
} else {
- OPLWriteReg(_opl, 0xC0 | channel, reg->feedbackStrength);
+ _opl->writeReg(0xC0 | channel, reg->feedbackStrength);
}
- OPLWriteReg(_opl, 0xE0 | mod, ins->waveSelectMod);
+ _opl->writeReg(0xE0 | mod, ins->waveSelectMod);
}
reg = &ins->regCar;
- OPLWriteReg(_opl, 0x20 | car, reg->vibrato);
+ _opl->writeReg(0x20 | car, reg->vibrato);
tmp = (63 - (reg->outputLevel & 0x3F)) * _channelsVolumeTable[channel];
tmp = 63 - (2 * tmp + 127) / (2 * 127);
- OPLWriteReg(_opl, 0x40 | car, tmp | (reg->keyScaling << 6));
- OPLWriteReg(_opl, 0x60 | car, reg->attackDecay);
- OPLWriteReg(_opl, 0x80 | car, reg->sustainRelease);
- OPLWriteReg(_opl, 0xE0 | car, ins->waveSelectCar);
+ _opl->writeReg(0x40 | car, tmp | (reg->keyScaling << 6));
+ _opl->writeReg(0x60 | car, reg->attackDecay);
+ _opl->writeReg(0x80 | car, reg->sustainRelease);
+ _opl->writeReg(0xE0 | car, ins->waveSelectCar);
}
void AdLibSoundDriver::loadRegisterInstrument(const byte *data, AdLibRegisterSoundInstrument *reg) {
@@ -490,16 +465,16 @@ void AdLibSoundDriverINS::setChannelFrequency(int channel, int frequency) {
if (channel == 6)
oct = 0;
freq = _freqTable[note % 12];
- OPLWriteReg(_opl, 0xA0 | channel, freq);
+ _opl->writeReg(0xA0 | channel, freq);
freq = (oct << 2) | ((freq & 0x300) >> 8);
if (ins->mode == 0) {
freq |= 0x20;
}
- OPLWriteReg(_opl, 0xB0 | channel, freq);
+ _opl->writeReg(0xB0 | channel, freq);
}
if (ins->mode != 0) {
_vibrato |= 1 << (10 - ins->channel);
- OPLWriteReg(_opl, 0xBD, _vibrato);
+ _opl->writeReg(0xBD, _vibrato);
}
}
@@ -515,16 +490,16 @@ void AdLibSoundDriverINS::playSample(const byte *data, int size, int channel, in
if (ins->mode == 0 || channel == 6) {
uint16 note = 12;
int freq = _freqTable[note % 12];
- OPLWriteReg(_opl, 0xA0 | channel, freq);
+ _opl->writeReg(0xA0 | channel, freq);
freq = ((note / 12) << 2) | ((freq & 0x300) >> 8);
if (ins->mode == 0) {
freq |= 0x20;
}
- OPLWriteReg(_opl, 0xB0 | channel, freq);
+ _opl->writeReg(0xB0 | channel, freq);
}
if (ins->mode != 0) {
_vibrato |= 1 << (10 - ins->channel);
- OPLWriteReg(_opl, 0xBD, _vibrato);
+ _opl->writeReg(0xBD, _vibrato);
}
}
@@ -562,15 +537,15 @@ void AdLibSoundDriverADL::setChannelFrequency(int channel, int frequency) {
}
freq = _freqTable[note % 12];
- OPLWriteReg(_opl, 0xA0 | channel, freq);
+ _opl->writeReg(0xA0 | channel, freq);
freq = (oct << 2) | ((freq & 0x300) >> 8);
if (ins->mode == 0) {
freq |= 0x20;
}
- OPLWriteReg(_opl, 0xB0 | channel, freq);
+ _opl->writeReg(0xB0 | channel, freq);
if (ins->mode != 0) {
_vibrato |= 1 << (10 - channel);
- OPLWriteReg(_opl, 0xBD, _vibrato);
+ _opl->writeReg(0xBD, _vibrato);
}
}
@@ -580,11 +555,11 @@ void AdLibSoundDriverADL::playSample(const byte *data, int size, int channel, in
setupInstrument(data, channel);
AdLibSoundInstrument *ins = &_instrumentsTable[channel];
if (ins->mode != 0 && ins->channel == 6) {
- OPLWriteReg(_opl, 0xB0 | channel, 0);
+ _opl->writeReg(0xB0 | channel, 0);
}
if (ins->mode != 0) {
_vibrato &= ~(1 << (10 - ins->channel));
- OPLWriteReg(_opl, 0xBD, _vibrato);
+ _opl->writeReg(0xBD, _vibrato);
}
if (ins->mode != 0) {
channel = ins->channel;
@@ -599,15 +574,15 @@ void AdLibSoundDriverADL::playSample(const byte *data, int size, int channel, in
note = ins->amDepth;
}
int freq = _freqTable[note % 12];
- OPLWriteReg(_opl, 0xA0 | channel, freq);
+ _opl->writeReg(0xA0 | channel, freq);
freq = ((note / 12) << 2) | ((freq & 0x300) >> 8);
if (ins->mode == 0) {
freq |= 0x20;
}
- OPLWriteReg(_opl, 0xB0 | channel, freq);
+ _opl->writeReg(0xB0 | channel, freq);
if (ins->mode != 0) {
_vibrato |= 1 << (10 - channel);
- OPLWriteReg(_opl, 0xBD, _vibrato);
+ _opl->writeReg(0xBD, _vibrato);
}
}
diff --git a/engines/cruise/sound.cpp b/engines/cruise/sound.cpp
index 0b0fab8c4a..f57435f4f7 100644
--- a/engines/cruise/sound.cpp
+++ b/engines/cruise/sound.cpp
@@ -108,7 +108,7 @@ struct VolumeEntry {
int adjusted;
};
-class AdLibSoundDriver : public PCSoundDriver, Audio::AudioStream {
+class AdLibSoundDriver : public PCSoundDriver {
public:
AdLibSoundDriver(Audio::Mixer *mixer);
virtual ~AdLibSoundDriver();
@@ -118,14 +118,8 @@ public:
virtual void stopChannel(int channel);
virtual void stopAll();
- // AudioStream interface
- virtual int readBuffer(int16 *buffer, const int numSamples);
- virtual bool isStereo() const { return false; }
- virtual bool endOfData() const { return false; }
- virtual int getRate() const { return _sampleRate; }
-
void initCard();
- void update(int16 *buf, int len);
+ void onTimer();
void setupInstrument(const byte *data, int channel);
void setupInstrument(const AdLibSoundInstrument *ins, int channel);
void loadRegisterInstrument(const byte *data, AdLibRegisterSoundInstrument *reg);
@@ -135,10 +129,8 @@ public:
void adjustVolume(int channel, int volume);
protected:
- FM_OPL *_opl;
- int _sampleRate;
+ OPL::OPL *_opl;
Audio::Mixer *_mixer;
- Audio::SoundHandle _soundHandle;
byte _vibrato;
VolumeEntry _channelsVolumeTable[5];
@@ -302,8 +294,9 @@ void PCSoundDriver::syncSounds() {
AdLibSoundDriver::AdLibSoundDriver(Audio::Mixer *mixer)
: _mixer(mixer) {
- _sampleRate = _mixer->getOutputRate();
- _opl = makeAdLibOPL(_sampleRate);
+ _opl = OPL::Config::create();
+ if (!_opl || !_opl->init())
+ error("Failed to create OPL");
for (int i = 0; i < 5; ++i) {
_channelsVolumeTable[i].original = 0;
@@ -311,15 +304,15 @@ AdLibSoundDriver::AdLibSoundDriver(Audio::Mixer *mixer)
}
memset(_instrumentsTable, 0, sizeof(_instrumentsTable));
initCard();
- _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
_musicVolume = ConfMan.getBool("music_mute") ? 0 : MIN(255, ConfMan.getInt("music_volume"));
_sfxVolume = ConfMan.getBool("sfx_mute") ? 0 : MIN(255, ConfMan.getInt("sfx_volume"));
+
+ _opl->start(new Common::Functor0Mem<void, AdLibSoundDriver>(this, &AdLibSoundDriver::onTimer), 50);
}
AdLibSoundDriver::~AdLibSoundDriver() {
- _mixer->stopHandle(_soundHandle);
- OPLDestroy(_opl);
+ delete _opl;
}
void AdLibSoundDriver::syncSounds() {
@@ -368,70 +361,51 @@ void AdLibSoundDriver::stopChannel(int channel) {
channel = 6;
}
if (ins->mode == 0 || channel == 6) {
- OPLWriteReg(_opl, 0xB0 | channel, 0);
+ _opl->writeReg(0xB0 | channel, 0);
}
if (ins->mode != 0) {
_vibrato &= ~(1 << (10 - ins->channel));
- OPLWriteReg(_opl, 0xBD, _vibrato);
+ _opl->writeReg(0xBD, _vibrato);
}
}
void AdLibSoundDriver::stopAll() {
for (int i = 0; i < 18; ++i)
- OPLWriteReg(_opl, 0x40 | _operatorsTable[i], 63);
+ _opl->writeReg(0x40 | _operatorsTable[i], 63);
for (int i = 0; i < 9; ++i)
- OPLWriteReg(_opl, 0xB0 | i, 0);
-
- OPLWriteReg(_opl, 0xBD, 0);
-}
+ _opl->writeReg(0xB0 | i, 0);
-int AdLibSoundDriver::readBuffer(int16 *buffer, const int numSamples) {
- update(buffer, numSamples);
- return numSamples;
+ _opl->writeReg(0xBD, 0);
}
void AdLibSoundDriver::initCard() {
_vibrato = 0x20;
- OPLWriteReg(_opl, 0xBD, _vibrato);
- OPLWriteReg(_opl, 0x08, 0x40);
+ _opl->writeReg(0xBD, _vibrato);
+ _opl->writeReg(0x08, 0x40);
static const int oplRegs[] = { 0x40, 0x60, 0x80, 0x20, 0xE0 };
for (int i = 0; i < 9; ++i) {
- OPLWriteReg(_opl, 0xB0 | i, 0);
+ _opl->writeReg(0xB0 | i, 0);
}
for (int i = 0; i < 9; ++i) {
- OPLWriteReg(_opl, 0xC0 | i, 0);
+ _opl->writeReg(0xC0 | i, 0);
}
for (int j = 0; j < 5; j++) {
for (int i = 0; i < 18; ++i) {
- OPLWriteReg(_opl, oplRegs[j] | _operatorsTable[i], 0);
+ _opl->writeReg(oplRegs[j] | _operatorsTable[i], 0);
}
}
- OPLWriteReg(_opl, 1, 0x20);
- OPLWriteReg(_opl, 1, 0);
+ _opl->writeReg(1, 0x20);
+ _opl->writeReg(1, 0);
}
-void AdLibSoundDriver::update(int16 *buf, int len) {
- static int samplesLeft = 0;
- while (len != 0) {
- int count = samplesLeft;
- if (count > len) {
- count = len;
- }
- samplesLeft -= count;
- len -= count;
- YM3812UpdateOne(_opl, buf, count);
- if (samplesLeft == 0) {
- if (_upCb) {
- (*_upCb)(_upRef);
- }
- samplesLeft = _sampleRate / 50;
- }
- buf += count;
+void AdLibSoundDriver::onTimer() {
+ if (_upCb) {
+ (*_upCb)(_upRef);
}
}
@@ -457,32 +431,32 @@ void AdLibSoundDriver::setupInstrument(const AdLibSoundInstrument *ins, int chan
if (ins->mode == 0 || ins->channel == 6) {
reg = &ins->regMod;
- OPLWriteReg(_opl, 0x20 | mod, reg->vibrato);
+ _opl->writeReg(0x20 | mod, reg->vibrato);
if (reg->freqMod) {
tmp = reg->outputLevel & 0x3F;
} else {
tmp = (63 - (reg->outputLevel & 0x3F)) * _channelsVolumeTable[channel].adjusted;
tmp = 63 - (2 * tmp + 127) / (2 * 127);
}
- OPLWriteReg(_opl, 0x40 | mod, tmp | (reg->keyScaling << 6));
- OPLWriteReg(_opl, 0x60 | mod, reg->attackDecay);
- OPLWriteReg(_opl, 0x80 | mod, reg->sustainRelease);
+ _opl->writeReg(0x40 | mod, tmp | (reg->keyScaling << 6));
+ _opl->writeReg(0x60 | mod, reg->attackDecay);
+ _opl->writeReg(0x80 | mod, reg->sustainRelease);
if (ins->mode != 0) {
- OPLWriteReg(_opl, 0xC0 | ins->channel, reg->feedbackStrength);
+ _opl->writeReg(0xC0 | ins->channel, reg->feedbackStrength);
} else {
- OPLWriteReg(_opl, 0xC0 | channel, reg->feedbackStrength);
+ _opl->writeReg(0xC0 | channel, reg->feedbackStrength);
}
- OPLWriteReg(_opl, 0xE0 | mod, ins->waveSelectMod);
+ _opl->writeReg(0xE0 | mod, ins->waveSelectMod);
}
reg = &ins->regCar;
- OPLWriteReg(_opl, 0x20 | car, reg->vibrato);
+ _opl->writeReg(0x20 | car, reg->vibrato);
tmp = (63 - (reg->outputLevel & 0x3F)) * _channelsVolumeTable[channel].adjusted;
tmp = 63 - (2 * tmp + 127) / (2 * 127);
- OPLWriteReg(_opl, 0x40 | car, tmp | (reg->keyScaling << 6));
- OPLWriteReg(_opl, 0x60 | car, reg->attackDecay);
- OPLWriteReg(_opl, 0x80 | car, reg->sustainRelease);
- OPLWriteReg(_opl, 0xE0 | car, ins->waveSelectCar);
+ _opl->writeReg(0x40 | car, tmp | (reg->keyScaling << 6));
+ _opl->writeReg(0x60 | car, reg->attackDecay);
+ _opl->writeReg(0x80 | car, reg->sustainRelease);
+ _opl->writeReg(0xE0 | car, ins->waveSelectCar);
}
void AdLibSoundDriver::loadRegisterInstrument(const byte *data, AdLibRegisterSoundInstrument *reg) {
@@ -551,15 +525,15 @@ void AdLibSoundDriverADL::setChannelFrequency(int channel, int frequency) {
}
freq = _freqTable[note % 12];
- OPLWriteReg(_opl, 0xA0 | channel, freq);
+ _opl->writeReg(0xA0 | channel, freq);
freq = ((note / 12) << 2) | ((freq & 0x300) >> 8);
if (ins->mode == 0) {
freq |= 0x20;
}
- OPLWriteReg(_opl, 0xB0 | channel, freq);
+ _opl->writeReg(0xB0 | channel, freq);
if (ins->mode != 0) {
_vibrato |= 1 << (10 - channel);
- OPLWriteReg(_opl, 0xBD, _vibrato);
+ _opl->writeReg(0xBD, _vibrato);
}
}
@@ -570,11 +544,11 @@ void AdLibSoundDriverADL::playSample(const byte *data, int size, int channel, in
setupInstrument(data, channel);
AdLibSoundInstrument *ins = &_instrumentsTable[channel];
if (ins->mode != 0 && ins->channel == 6) {
- OPLWriteReg(_opl, 0xB0 | channel, 0);
+ _opl->writeReg(0xB0 | channel, 0);
}
if (ins->mode != 0) {
_vibrato &= ~(1 << (10 - ins->channel));
- OPLWriteReg(_opl, 0xBD, _vibrato);
+ _opl->writeReg(0xBD, _vibrato);
}
if (ins->mode != 0) {
channel = ins->channel;
@@ -589,15 +563,15 @@ void AdLibSoundDriverADL::playSample(const byte *data, int size, int channel, in
note = ins->amDepth;
}
int freq = _freqTable[note % 12];
- OPLWriteReg(_opl, 0xA0 | channel, freq);
+ _opl->writeReg(0xA0 | channel, freq);
freq = ((note / 12) << 2) | ((freq & 0x300) >> 8);
if (ins->mode == 0) {
freq |= 0x20;
}
- OPLWriteReg(_opl, 0xB0 | channel, freq);
+ _opl->writeReg(0xB0 | channel, freq);
if (ins->mode != 0) {
_vibrato |= 1 << (10 - channel);
- OPLWriteReg(_opl, 0xBD, _vibrato);
+ _opl->writeReg(0xBD, _vibrato);
}
}
diff --git a/engines/drascula/actors.cpp b/engines/drascula/actors.cpp
index 51148bbc05..849e2ccd24 100644
--- a/engines/drascula/actors.cpp
+++ b/engines/drascula/actors.cpp
@@ -396,6 +396,16 @@ void DrasculaEngine::increaseFrameNum() {
curHeight = (int)newHeight;
curWidth = (int)newWidth;
}
+
+ // Fix bug #5903 DRASCULA-IT: Crash/graphic glitch at castle towers
+ // Chapter 5 Room 45 is the castle tower part
+ // Fixing the character's coordinate(0,0) in the tower section to prevent out of window coordinates and crash
+ if ((currentChapter == 5) && (_roomNumber == 45)) {
+ curY = 0;
+ curX = 0;
+ curHeight = 0;
+ curWidth = 0;
+ }
}
void DrasculaEngine::walkDown() {
diff --git a/engines/drascula/detection.cpp b/engines/drascula/detection.cpp
index 833363669d..a84bd11cb1 100644
--- a/engines/drascula/detection.cpp
+++ b/engines/drascula/detection.cpp
@@ -382,8 +382,7 @@ SaveStateList DrasculaMetaEngine::listSaves(const char *target) const {
}
SaveStateDescriptor DrasculaMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
- char fileName[MAXPATHLEN];
- sprintf(fileName, "%s.%03d", target, slot);
+ Common::String fileName = Common::String::format("%s.%03d", target, slot);
Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(fileName);
diff --git a/engines/drascula/talk.cpp b/engines/drascula/talk.cpp
index ed29dc5fe4..e9fec868f8 100644
--- a/engines/drascula/talk.cpp
+++ b/engines/drascula/talk.cpp
@@ -379,6 +379,11 @@ void DrasculaEngine::talk(const char *said, const char *filename) {
int y_mask_talk = 170;
int face;
+
+ // Fix bug #5903 DRASCULA-IT: Crash/graphic glitch at castle towers
+ // Chapter 5 Room 45 is the castle tower part
+ // We use this variable as a condition below because at the castle towers we don't want to draw out the head
+ bool notTowers = !((currentChapter == 5) && (_roomNumber == 45));
if (currentChapter == 6) {
if (flags[0] == 0 && _roomNumber == 102) {
@@ -434,44 +439,56 @@ void DrasculaEngine::talk(const char *said, const char *filename) {
if (currentChapter == 2)
copyRect(x_talk_izq[face], y_mask_talk, curX + 8, curY - 1, TALK_WIDTH, TALK_HEIGHT,
extraSurface, screenSurface);
- else
+ else if (notTowers) {
reduce_hare_chico(x_talk_izq[face], y_mask_talk, curX + (int)((8.0f / 100) * factor_red[MIN(201, curY + curHeight)]),
- curY, TALK_WIDTH, TALK_HEIGHT, factor_red[MIN(201, curY + curHeight)],
- extraSurface, screenSurface);
-
+ curY, TALK_WIDTH, TALK_HEIGHT, factor_red[MIN(201, curY + curHeight)],
+ extraSurface, screenSurface);
+ }
updateRefresh();
} else if (trackProtagonist == 1) {
if (currentChapter == 2)
copyRect(x_talk_dch[face], y_mask_talk, curX + 12, curY, TALK_WIDTH, TALK_HEIGHT,
extraSurface, screenSurface);
- else
+ else if (notTowers) {
reduce_hare_chico(x_talk_dch[face], y_mask_talk, curX + (int)((12.0f / 100) * factor_red[MIN(201, curY + curHeight)]),
curY, TALK_WIDTH, TALK_HEIGHT, factor_red[MIN(201, curY + curHeight)], extraSurface, screenSurface);
+ }
updateRefresh();
} else if (trackProtagonist == 2) {
if (currentChapter == 2)
copyRect(x_talk_izq[face], y_mask_talk, curX + 12, curY, TALK_WIDTH, TALK_HEIGHT,
frontSurface, screenSurface);
- else
+ else if (notTowers) {
reduce_hare_chico(x_talk_izq[face], y_mask_talk,
- talkOffset + curX + (int)((12.0f / 100) * factor_red[MIN(201, curY + curHeight)]),
- curY, TALK_WIDTH, TALK_HEIGHT, factor_red[MIN(201, curY + curHeight)],
- frontSurface, screenSurface);
+ talkOffset + curX + (int)((12.0f / 100) * factor_red[MIN(201, curY + curHeight)]),
+ curY, TALK_WIDTH, TALK_HEIGHT, factor_red[MIN(201, curY + curHeight)],
+ frontSurface, screenSurface);
+ }
updateRefresh();
} else if (trackProtagonist == 3) {
if (currentChapter == 2)
copyRect(x_talk_dch[face], y_mask_talk, curX + 8, curY, TALK_WIDTH, TALK_HEIGHT,
frontSurface, screenSurface);
- else
+ else if (notTowers) {
reduce_hare_chico(x_talk_dch[face], y_mask_talk,
- talkOffset + curX + (int)((8.0f / 100) * factor_red[MIN(201, curY + curHeight)]),
- curY, TALK_WIDTH,TALK_HEIGHT, factor_red[MIN(201, curY + curHeight)],
- frontSurface, screenSurface);
+ talkOffset + curX + (int)((8.0f / 100) * factor_red[MIN(201, curY + curHeight)]),
+ curY, TALK_WIDTH, TALK_HEIGHT, factor_red[MIN(201, curY + curHeight)],
+ frontSurface, screenSurface);
+ }
updateRefresh();
}
- if (!_subtitlesDisabled)
- centerText(said, curX, curY);
+ // Fix bug #5903 DRASCULA-IT: Crash/graphic glitch at castle towers
+ // Without the head we have to fix the subtitle's coordinates(upper-center) at the tower section
+ if (!_subtitlesDisabled) {
+ if (notTowers) {
+ centerText(said, curX, curY);
+ }
+ else {
+ centerText(said, 160, 25);
+ }
+ }
+
updateScreen();
updateEvents();
diff --git a/engines/engine.cpp b/engines/engine.cpp
index c63437f800..24008dd073 100644
--- a/engines/engine.cpp
+++ b/engines/engine.cpp
@@ -45,6 +45,7 @@
#include "common/taskbar.h"
#include "common/textconsole.h"
#include "common/translation.h"
+#include "common/singleton.h"
#include "backends/keymapper/keymapper.h"
@@ -101,6 +102,36 @@ static void defaultErrorHandler(const char *msg) {
}
}
+// Chained games manager
+
+ChainedGamesManager::ChainedGamesManager() {
+ clear();
+}
+
+void ChainedGamesManager::clear() {
+ _chainedGames.clear();
+}
+
+void ChainedGamesManager::push(const Common::String target, const int slot) {
+ Game game;
+ game.target = target;
+ game.slot = slot;
+ _chainedGames.push(game);
+}
+
+bool ChainedGamesManager::pop(Common::String &target, int &slot) {
+ if (_chainedGames.empty()) {
+ return false;
+ }
+ Game game = _chainedGames.pop();
+ target = game.target;
+ slot = game.slot;
+ return true;
+}
+
+namespace Common {
+DECLARE_SINGLETON(ChainedGamesManager);
+}
Engine::Engine(OSystem *syst)
: _system(syst),
diff --git a/engines/engine.h b/engines/engine.h
index e325cc1ba2..d3415d584c 100644
--- a/engines/engine.h
+++ b/engines/engine.h
@@ -27,6 +27,8 @@
#include "common/str.h"
#include "common/language.h"
#include "common/platform.h"
+#include "common/queue.h"
+#include "common/singleton.h"
class OSystem;
@@ -334,6 +336,32 @@ protected:
};
+// Chained games
+
+/**
+ * Singleton class which manages chained games. A chained game is one that
+ * starts automatically, optionally loading a saved game, instead of returning
+ * to the launcher.
+ */
+class ChainedGamesManager : public Common::Singleton<ChainedGamesManager> {
+private:
+ struct Game {
+ Common::String target;
+ int slot;
+ };
+
+ Common::Queue<Game> _chainedGames;
+
+public:
+ ChainedGamesManager();
+ void clear();
+ void push(const Common::String target, const int slot = -1);
+ bool pop(Common::String &target, int &slot);
+};
+
+/** Convenience shortcut for accessing the chained games manager. */
+#define ChainedGamesMan ChainedGamesManager::instance()
+
// FIXME: HACK for MidiEmu & error()
extern Engine *g_engine;
diff --git a/engines/fullpipe/gameloader.cpp b/engines/fullpipe/gameloader.cpp
index fbf96b3060..7815475d37 100644
--- a/engines/fullpipe/gameloader.cpp
+++ b/engines/fullpipe/gameloader.cpp
@@ -323,7 +323,7 @@ bool preloadCallback(PreloadItem &pre, int flag) {
if (!g_fp->_loaderScene) {
g_fp->_gameLoader->loadScene(SC_LDR);
- g_fp->_loaderScene = g_fp->accessScene(SC_LDR);;
+ g_fp->_loaderScene = g_fp->accessScene(SC_LDR);
}
StaticANIObject *pbar = g_fp->_loaderScene->getStaticANIObject1ById(ANI_PBAR, -1);
diff --git a/engines/fullpipe/inventory.cpp b/engines/fullpipe/inventory.cpp
index e79f9c54df..f9b507c50b 100644
--- a/engines/fullpipe/inventory.cpp
+++ b/engines/fullpipe/inventory.cpp
@@ -126,7 +126,7 @@ void Inventory2::removeItem2(Scene *sceneObj, int itemId, int x, int y, int prio
int idx = getInventoryItemIndexById(itemId);
if (idx >= 0) {
- if (_inventoryItems[idx]->itemId >> 16) {
+ if (_inventoryItems[idx]->count) {
removeItem(itemId, 1);
Scene *sc = g_fp->accessScene(_sceneId);
diff --git a/engines/fullpipe/mgm.cpp b/engines/fullpipe/mgm.cpp
index aacfd5452a..1c8ca2a7b1 100644
--- a/engines/fullpipe/mgm.cpp
+++ b/engines/fullpipe/mgm.cpp
@@ -155,13 +155,14 @@ void MGM::rebuildTables(int objId) {
if (!obj)
return;
- for (uint i = 0; i < obj->_staticsList.size(); i++)
+ for (uint i = 0; i < obj->_staticsList.size(); i++) {
_items[idx]->statics.push_back((Statics *)obj->_staticsList[i]);
+ _items[idx]->subItems.push_back(new MGMSubItem);
+ }
+
for (uint i = 0; i < obj->_movements.size(); i++)
_items[idx]->movements1.push_back((Movement *)obj->_movements[i]);
-
- _items[idx]->subItems.clear();
}
int MGM::getItemIndexById(int objId) {
diff --git a/engines/fullpipe/modal.cpp b/engines/fullpipe/modal.cpp
index 2fd7ef0c21..096323781f 100644
--- a/engines/fullpipe/modal.cpp
+++ b/engines/fullpipe/modal.cpp
@@ -305,7 +305,7 @@ bool ModalMap::init(int counterdiff) {
if (_flag) {
_rect2.left = _mouseX + _field_38 - g_fp->_mouseScreenPos.x;
- _rect2.top = _mouseY + _field_3C - g_fp->_mouseScreenPos.y;;
+ _rect2.top = _mouseY + _field_3C - g_fp->_mouseScreenPos.y;
_rect2.right = _rect2.left + 800;
_rect2.bottom = _rect2.top + 600;
diff --git a/engines/fullpipe/motion.cpp b/engines/fullpipe/motion.cpp
index 9573e0517b..5845ad1501 100644
--- a/engines/fullpipe/motion.cpp
+++ b/engines/fullpipe/motion.cpp
@@ -1232,7 +1232,7 @@ MessageQueue *MovGraph::method50(StaticANIObject *ani, MovArr *movarr, int stati
return 0;
uint idx;
- int movidx;
+ int movidx = 0;
bool done = false;
for (idx = 0; idx <= _items.size() && !done; idx++) {
diff --git a/engines/fullpipe/scene.cpp b/engines/fullpipe/scene.cpp
index 00dd70c1b2..5a3fbe34b6 100644
--- a/engines/fullpipe/scene.cpp
+++ b/engines/fullpipe/scene.cpp
@@ -672,11 +672,6 @@ void Scene::drawContent(int minPri, int maxPri, bool drawBg) {
debug(1, "_bigPict: %d objlist: %d", _bigPictureArray1Count, _picObjList.size());
- for (uint i = 0; i < _picObjList.size(); i++) {
- debug(1, "%d: %d", i, ((PictureObject *)_picObjList[i])->_priority);
- }
-
-
if (drawBg && _bigPictureArray1Count && _picObjList.size()) {
_bigPictureArray[0][0]->getDimensions(&point);
@@ -743,7 +738,6 @@ void Scene::drawContent(int minPri, int maxPri, bool drawBg) {
for (uint i = 1; i < _picObjList.size(); i++) {
PictureObject *obj = (PictureObject *)_picObjList[i];
- debug(8, "pri: %d", obj->_priority);
if (obj->_priority < minPri || obj->_priority >= maxPri)
continue;
diff --git a/engines/fullpipe/scenes/scene04.cpp b/engines/fullpipe/scenes/scene04.cpp
index fd1ececdf2..4a87ae5b87 100644
--- a/engines/fullpipe/scenes/scene04.cpp
+++ b/engines/fullpipe/scenes/scene04.cpp
@@ -949,7 +949,7 @@ void sceneHandler04_springWobble() {
if (g_vars->scene04_bottleWeight < newdelta)
g_vars->scene04_springOffset--;
- if ((oldDynIndex > g_vars->scene04_bottleWeight && newdelta > g_vars->scene04_bottleWeight) || newdelta <= g_vars->scene04_bottleWeight) {
+ if ((oldDynIndex <= g_vars->scene04_bottleWeight && newdelta > g_vars->scene04_bottleWeight) || newdelta <= g_vars->scene04_bottleWeight) {
g_vars->scene04_springDelay++;
if (g_vars->scene04_springOffset && g_vars->scene04_springDelay > 1) {
@@ -960,6 +960,8 @@ void sceneHandler04_springWobble() {
Common::Point point;
+ int oldpos = g_vars->scene04_spring->getCurrDimensions(point)->y - oldDynIndex;
+
if (g_vars->scene04_dynamicPhaseIndex) {
if (!g_vars->scene04_spring->_movement)
g_vars->scene04_spring->startAnim(MV_SPR_LOWER, 0, -1);
@@ -969,8 +971,9 @@ void sceneHandler04_springWobble() {
g_vars->scene04_spring->changeStatics2(ST_SPR_UP);
}
- if (g_vars->scene04_dynamicPhaseIndex != oldDynIndex)
- sceneHandler04_bottleUpdateObjects(oldDynIndex - g_vars->scene04_dynamicPhaseIndex);
+ if (g_vars->scene04_dynamicPhaseIndex != oldDynIndex) {
+ sceneHandler04_bottleUpdateObjects(oldpos - (g_vars->scene04_spring->getCurrDimensions(point)->y - g_vars->scene04_dynamicPhaseIndex));
+ }
}
void sceneHandler04_leaveScene() {
diff --git a/engines/fullpipe/scenes/scene16.cpp b/engines/fullpipe/scenes/scene16.cpp
index e9d3a37efd..df005950d2 100644
--- a/engines/fullpipe/scenes/scene16.cpp
+++ b/engines/fullpipe/scenes/scene16.cpp
@@ -182,7 +182,7 @@ void sceneHandler16_fillMug() {
mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC16_BOYOUT), 0, 1);
mq->replaceKeyCode(-1, g_vars->scene16_walkingBoy->_okeyCode);
- if (!mq || mq->chain(g_vars->scene16_walkingBoy))
+ if (mq->chain(g_vars->scene16_walkingBoy))
return;
} else {
if (!g_vars->scene16_walkingGirl)
diff --git a/engines/fullpipe/scenes/scene23.cpp b/engines/fullpipe/scenes/scene23.cpp
index f66ea12b4b..ded467e438 100644
--- a/engines/fullpipe/scenes/scene23.cpp
+++ b/engines/fullpipe/scenes/scene23.cpp
@@ -299,14 +299,14 @@ void sceneHandler23_pushButton(ExCommand *cmd) {
MessageQueue *mq = getCurrSceneSc2MotionController()->method34(g_fp->_aniMan, 276, 438, 1, ST_MAN_RIGHT);
if (mq) {
- mq->addExCommandToEnd(cmd->createClone());;
+ mq->addExCommandToEnd(cmd->createClone());
postExCommand(g_fp->_aniMan->_id, 2, 276, 438, 0, -1);
}
} else {
MessageQueue *mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC23_TOCALENDAR), 0, 0);
- mq->addExCommandToEnd(cmd->createClone());;
+ mq->addExCommandToEnd(cmd->createClone());
mq->setFlags(mq->getFlags() | 1);
mq->chain(0);
}
diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp
index 880c2eb0df..de3e1ea728 100644
--- a/engines/fullpipe/statics.cpp
+++ b/engines/fullpipe/statics.cpp
@@ -1048,8 +1048,11 @@ MessageQueue *StaticANIObject::changeStatics1(int msgNum) {
if (_flags & 1)
_messageQueueId = mq->_id;
} else {
- if (!queueMessageQueue(mq))
+ if (!queueMessageQueue(mq)) {
+ delete mq;
+
return 0;
+ }
g_fp->_globalMessageQueueList->addMessageQueue(mq);
}
@@ -1594,6 +1597,12 @@ Movement::Movement(Movement *src, int *oldIdxs, int newSize, StaticANIObject *an
newSize = src->_dynamicPhases.size();
}
+ if (!newSize) {
+ warning("Movement::Movement: newSize = 0");
+
+ return;
+ }
+
_framePosOffsets = (Common::Point **)calloc(newSize, sizeof(Common::Point *));
for (int i = 0; i < newSize; i++)
diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp
index 5ab3271a8f..24bdb858d8 100644
--- a/engines/gob/gob.cpp
+++ b/engines/gob/gob.cpp
@@ -389,6 +389,9 @@ void GobEngine::syncSoundSettings() {
Engine::syncSoundSettings();
_init->updateConfig();
+
+ if (_sound)
+ _sound->adlibSyncVolume();
}
void GobEngine::pauseGame() {
diff --git a/engines/gob/sound/adlib.cpp b/engines/gob/sound/adlib.cpp
index 65b43cae7a..1e024d5a50 100644
--- a/engines/gob/sound/adlib.cpp
+++ b/engines/gob/sound/adlib.cpp
@@ -37,6 +37,28 @@ static const int kPitchTomToSnare = 7;
static const int kPitchSnareDrum = kPitchTom + kPitchTomToSnare;
+// Attenuation map for GUI volume slider
+// Note: no volume control in the original engine
+const uint8 AdLib::kVolumeTable[Audio::Mixer::kMaxMixerVolume + 1] = {
+ 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 62, 61, 59, 57, 56, 55,
+ 53, 52, 51, 50, 49, 48, 47, 46, 46, 45, 44, 43, 43, 42, 41, 41,
+ 40, 39, 39, 38, 38, 37, 37, 36, 36, 35, 35, 34, 34, 33, 33, 33,
+ 32, 32, 31, 31, 31, 30, 30, 30, 29, 29, 29, 28, 28, 28, 27, 27,
+ 27, 26, 26, 26, 26, 25, 25, 25, 24, 24, 24, 24, 23, 23, 23, 23,
+ 22, 22, 22, 22, 21, 21, 21, 21, 21, 20, 20, 20, 20, 19, 19, 19,
+ 19, 19, 18, 18, 18, 18, 18, 18, 17, 17, 17, 17, 17, 16, 16, 16,
+ 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 13,
+ 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11,
+ 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9,
+ 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
+ 0
+};
+
// Is the operator a modulator (0) or a carrier (1)?
const uint8 AdLib::kOperatorType[kOperatorCount] = {
0, 0, 0, 1, 1, 1,
@@ -93,23 +115,20 @@ const uint16 AdLib::kHihatParams [kParamCount] = {
0, 1, 0, 15, 11, 0, 7, 5, 0, 0, 0, 0, 0, 0 };
-AdLib::AdLib(Audio::Mixer &mixer) : _mixer(&mixer), _opl(0),
- _toPoll(0), _repCount(0), _first(true), _playing(false), _ended(true) {
-
- _rate = _mixer->getOutputRate();
+AdLib::AdLib(int callbackFreq) : _opl(0),
+ _toPoll(0), _repCount(0), _first(true), _playing(false), _ended(true), _volume(0) {
initFreqs();
createOPL();
initOPL();
- _mixer->playStream(Audio::Mixer::kMusicSoundType, &_handle,
- this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
+ syncVolume();
+
+ _opl->start(new Common::Functor0Mem<void, AdLib>(this, &AdLib::onTimer), callbackFreq);
}
AdLib::~AdLib() {
- _mixer->stopHandle(_handle);
-
delete _opl;
}
@@ -136,46 +155,38 @@ void AdLib::createOPL() {
}
_opl = OPL::Config::create(OPL::Config::parse(oplDriver), OPL::Config::kOpl2);
- if (!_opl || !_opl->init(_rate)) {
+ if (!_opl || !_opl->init()) {
delete _opl;
error("Could not create an AdLib emulator");
}
}
-int AdLib::readBuffer(int16 *buffer, const int numSamples) {
+void AdLib::onTimer() {
Common::StackLock slock(_mutex);
- // Nothing to do, fill with silence
- if (!_playing) {
- memset(buffer, 0, numSamples * sizeof(int16));
- return numSamples;
+ // Nothing to do
+ if (!_playing)
+ return;
+
+ // Check if there's anything to do on this step
+ // If not, decrease the poll number and move on
+ if (_toPoll > 0) {
+ _toPoll--;
+ return;
}
- // Read samples from the OPL, polling in more music when necessary
- uint32 samples = numSamples;
- while (samples && _playing) {
- if (_toPoll) {
- const uint32 render = MIN(samples, _toPoll);
-
- _opl->readBuffer(buffer, render);
-
- buffer += render;
- samples -= render;
- _toPoll -= render;
-
- } else {
- // Song ended, fill the rest with silence
- if (_ended) {
- memset(buffer, 0, samples * sizeof(int16));
- samples = 0;
- break;
- }
-
- // Poll more music
- _toPoll = pollMusic(_first);
- _first = false;
+ // Poll until we have to delay until the next poll
+ while (_toPoll == 0 && _playing) {
+ // Song ended, break out
+ if (_ended) {
+ _toPoll = 0;
+ break;
}
+
+ // Poll more music
+ _toPoll = pollMusic(_first);
+ _first = false;
}
// Song ended, loop if requested
@@ -195,24 +206,6 @@ int AdLib::readBuffer(int16 *buffer, const int numSamples) {
} else
_playing = false;
}
-
- return numSamples;
-}
-
-bool AdLib::isStereo() const {
- return _opl->isStereo();
-}
-
-bool AdLib::endOfData() const {
- return !_playing;
-}
-
-bool AdLib::endOfStream() const {
- return false;
-}
-
-int AdLib::getRate() const {
- return _rate;
}
bool AdLib::isPlaying() const {
@@ -231,10 +224,6 @@ void AdLib::setRepeating(int32 repCount) {
_repCount = repCount;
}
-uint32 AdLib::getSamplesPerSecond() const {
- return _rate * (isStereo() ? 2 : 1);
-}
-
void AdLib::startPlay() {
Common::StackLock slock(_mutex);
@@ -442,6 +431,13 @@ void AdLib::writeKeyScaleLevelVolume(uint8 oper) {
volume = (63 - (_operatorParams[oper][kParamLevel] & 0x3F)) * _operatorVolume[oper];
volume = 63 - ((2 * volume + kMaxVolume) / (2 * kMaxVolume));
+ // Adjust carriers for GUI volume slider
+ if (kOperatorType[oper] == 1) {
+ volume += kVolumeTable[_volume];
+ if (volume > 63)
+ volume = 63;
+ }
+
uint8 keyScale = _operatorParams[oper][kParamKeyScaleLevel] << 6;
writeOPL(0x40 + kOperatorOffset[oper], volume | keyScale);
@@ -639,4 +635,23 @@ void AdLib::setFreq(uint8 voice, uint16 note, bool on) {
writeOPL(0xB0 + voice, value);
}
+void AdLib::setTimerFrequency(int timerFrequency) {
+ _opl->setCallbackFrequency(timerFrequency);
+}
+
+void AdLib::syncVolume() {
+ Common::StackLock slock(_mutex);
+
+ bool mute = false;
+ if (ConfMan.hasKey("mute"))
+ mute = ConfMan.getBool("mute");
+
+ _volume = (mute ? 0 : ConfMan.getInt("music_volume"));
+
+ if (_playing) {
+ for(int i = 0; i < kOperatorCount; i++)
+ writeKeyScaleLevelVolume(i);
+ }
+}
+
} // End of namespace Gob
diff --git a/engines/gob/sound/adlib.h b/engines/gob/sound/adlib.h
index 8071249374..d60458295c 100644
--- a/engines/gob/sound/adlib.h
+++ b/engines/gob/sound/adlib.h
@@ -35,9 +35,9 @@ namespace OPL {
namespace Gob {
/** Base class for a player of an AdLib music format. */
-class AdLib : public Audio::AudioStream {
+class AdLib {
public:
- AdLib(Audio::Mixer &mixer);
+ AdLib(int callbackFrequency);
virtual ~AdLib();
bool isPlaying() const; ///< Are we currently playing?
@@ -53,13 +53,7 @@ public:
void startPlay();
void stopPlay();
-
-// AudioStream API
- int readBuffer(int16 *buffer, const int numSamples);
- bool isStereo() const;
- bool endOfData() const;
- bool endOfStream() const;
- int getRate() const;
+ void syncVolume();
protected:
enum kVoice {
@@ -120,8 +114,6 @@ protected:
static const int kOPLMidC = 48; ///< A mid C for the OPL.
- /** Return the number of samples per second. */
- uint32 getSamplesPerSecond() const;
/** Write a value into an OPL register. */
void writeOPL(byte reg, byte val);
@@ -135,7 +127,7 @@ protected:
/** The callback function that's called for polling more AdLib commands.
*
* @param first Is this the first poll since the start of the song?
- * @return The number of samples until the next poll.
+ * @return The number of ticks until the next poll.
*/
virtual uint32 pollMusic(bool first) = 0;
@@ -207,7 +199,14 @@ protected:
/** Switch a voice off. */
void noteOff(uint8 voice);
+ /**
+ * Set the OPL timer frequency
+ */
+ void setTimerFrequency(int timerFrequency);
+
private:
+ static const uint8 kVolumeTable[Audio::Mixer::kMaxMixerVolume + 1];
+
static const uint8 kOperatorType [kOperatorCount];
static const uint8 kOperatorOffset[kOperatorCount];
static const uint8 kOperatorVoice [kOperatorCount];
@@ -226,13 +225,11 @@ private:
static const uint16 kHihatParams [kParamCount];
- Audio::Mixer *_mixer;
- Audio::SoundHandle _handle;
OPL::OPL *_opl;
Common::Mutex _mutex;
- uint32 _rate;
+ int _volume;
uint32 _toPoll;
@@ -300,6 +297,11 @@ private:
void changePitch(uint8 voice, uint16 pitchBend);
void setFreq(uint8 voice, uint16 note, bool on);
+
+ /**
+ * Callback function for OPL
+ */
+ void onTimer();
};
} // End of namespace Gob
diff --git a/engines/gob/sound/adlplayer.cpp b/engines/gob/sound/adlplayer.cpp
index 384a928360..6354d8c37f 100644
--- a/engines/gob/sound/adlplayer.cpp
+++ b/engines/gob/sound/adlplayer.cpp
@@ -28,7 +28,7 @@
namespace Gob {
-ADLPlayer::ADLPlayer(Audio::Mixer &mixer) : AdLib(mixer),
+ADLPlayer::ADLPlayer() : AdLib(1000),
_songData(0), _songDataSize(0), _playPos(0) {
}
@@ -135,14 +135,7 @@ uint32 ADLPlayer::pollMusic(bool first) {
if (delay & 0x80)
delay = ((delay & 3) << 8) | *_playPos++;
- return getSampleDelay(delay);
-}
-
-uint32 ADLPlayer::getSampleDelay(uint16 delay) const {
- if (delay == 0)
- return 0;
-
- return ((uint32)delay * getSamplesPerSecond()) / 1000;
+ return delay;
}
void ADLPlayer::rewind() {
diff --git a/engines/gob/sound/adlplayer.h b/engines/gob/sound/adlplayer.h
index 3edd238343..50e1db5b70 100644
--- a/engines/gob/sound/adlplayer.h
+++ b/engines/gob/sound/adlplayer.h
@@ -36,7 +36,7 @@ namespace Gob {
/** A player for Coktel Vision's ADL music format. */
class ADLPlayer : public AdLib {
public:
- ADLPlayer(Audio::Mixer &mixer);
+ ADLPlayer();
~ADLPlayer();
bool load(Common::SeekableReadStream &adl);
@@ -76,8 +76,6 @@ private:
bool readHeader (Common::SeekableReadStream &adl, int &timbreCount);
bool readTimbres (Common::SeekableReadStream &adl, int timbreCount);
bool readSongData(Common::SeekableReadStream &adl);
-
- uint32 getSampleDelay(uint16 delay) const;
};
} // End of namespace Gob
diff --git a/engines/gob/sound/musplayer.cpp b/engines/gob/sound/musplayer.cpp
index 7001a5724b..dcbb712b56 100644
--- a/engines/gob/sound/musplayer.cpp
+++ b/engines/gob/sound/musplayer.cpp
@@ -27,7 +27,7 @@
namespace Gob {
-MUSPlayer::MUSPlayer(Audio::Mixer &mixer) : AdLib(mixer),
+MUSPlayer::MUSPlayer() : AdLib(60),
_songData(0), _songDataSize(0), _playPos(0), _songID(0) {
}
@@ -43,15 +43,6 @@ void MUSPlayer::unload() {
unloadMUS();
}
-uint32 MUSPlayer::getSampleDelay(uint16 delay) const {
- if (delay == 0)
- return 0;
-
- uint32 freq = (_ticksPerBeat * _tempo) / 60;
-
- return ((uint32)delay * getSamplesPerSecond()) / freq;
-}
-
void MUSPlayer::skipToTiming() {
while (*_playPos < 0x80)
_playPos++;
@@ -66,8 +57,12 @@ uint32 MUSPlayer::pollMusic(bool first) {
return 0;
}
- if (first)
- return getSampleDelay(*_playPos++);
+ if (first) {
+ // Set the timer frequency on first run.
+ // Do not set it in rewind() for thread safety reasons.
+ setTimerFrequency((_ticksPerBeat * _tempo) / 60);
+ return *_playPos++;
+ }
uint16 delay = 0;
while (delay == 0) {
@@ -100,6 +95,7 @@ uint32 MUSPlayer::pollMusic(bool first) {
uint32 denom = *_playPos++;
_tempo = _baseTempo * num + ((_baseTempo * denom) >> 7);
+ setTimerFrequency((_ticksPerBeat * _tempo) / 60);
_playPos++;
} else {
@@ -182,7 +178,7 @@ uint32 MUSPlayer::pollMusic(bool first) {
delay += *_playPos++;
}
- return getSampleDelay(delay);
+ return delay;
}
void MUSPlayer::rewind() {
diff --git a/engines/gob/sound/musplayer.h b/engines/gob/sound/musplayer.h
index c76c5aab38..973192ffd9 100644
--- a/engines/gob/sound/musplayer.h
+++ b/engines/gob/sound/musplayer.h
@@ -40,7 +40,7 @@ namespace Gob {
*/
class MUSPlayer : public AdLib {
public:
- MUSPlayer(Audio::Mixer &mixer);
+ MUSPlayer();
~MUSPlayer();
/** Load the instruments (.SND or .TBR) */
@@ -97,7 +97,6 @@ private:
bool readMUSHeader(Common::SeekableReadStream &mus);
bool readMUSSong (Common::SeekableReadStream &mus);
- uint32 getSampleDelay(uint16 delay) const;
void setInstrument(uint8 voice, uint8 instrument);
void skipToTiming();
diff --git a/engines/gob/sound/sound.cpp b/engines/gob/sound/sound.cpp
index d2b2d3d6e8..22dfe9d3c3 100644
--- a/engines/gob/sound/sound.cpp
+++ b/engines/gob/sound/sound.cpp
@@ -234,7 +234,7 @@ bool Sound::adlibLoadADL(const char *fileName) {
return false;
if (!_adlPlayer)
- _adlPlayer = new ADLPlayer(*_vm->_mixer);
+ _adlPlayer = new ADLPlayer();
debugC(1, kDebugSound, "AdLib: Loading ADL data (\"%s\")", fileName);
@@ -256,7 +256,7 @@ bool Sound::adlibLoadADL(byte *data, uint32 size, int index) {
return false;
if (!_adlPlayer)
- _adlPlayer = new ADLPlayer(*_vm->_mixer);
+ _adlPlayer = new ADLPlayer();
debugC(1, kDebugSound, "AdLib: Loading ADL data (%d)", index);
@@ -425,6 +425,16 @@ int32 Sound::adlibGetRepeating() const {
return false;
}
+void Sound::adlibSyncVolume() {
+ if (!_hasAdLib)
+ return;
+
+ if (_adlPlayer)
+ _adlPlayer->syncVolume();
+ if (_mdyPlayer)
+ _mdyPlayer->syncVolume();
+}
+
void Sound::adlibSetRepeating(int32 repCount) {
if (!_hasAdLib)
return;
@@ -739,7 +749,7 @@ void Sound::createMDYPlayer() {
delete _adlPlayer;
_adlPlayer = 0;
- _mdyPlayer = new MUSPlayer(*_vm->_mixer);
+ _mdyPlayer = new MUSPlayer();
}
void Sound::createADLPlayer() {
@@ -749,7 +759,7 @@ void Sound::createADLPlayer() {
delete _mdyPlayer;
_mdyPlayer= 0;
- _adlPlayer = new ADLPlayer(*_vm->_mixer);
+ _adlPlayer = new ADLPlayer();
}
} // End of namespace Gob
diff --git a/engines/gob/sound/sound.h b/engines/gob/sound/sound.h
index c959959755..6ebc323b18 100644
--- a/engines/gob/sound/sound.h
+++ b/engines/gob/sound/sound.h
@@ -96,6 +96,7 @@ public:
int32 adlibGetRepeating() const;
void adlibSetRepeating(int32 repCount);
+ void adlibSyncVolume();
// Infogrames
diff --git a/engines/gob/surface.cpp b/engines/gob/surface.cpp
index 42ac2b0d74..ed83e8255c 100644
--- a/engines/gob/surface.cpp
+++ b/engines/gob/surface.cpp
@@ -470,7 +470,7 @@ void Surface::blitScaled(const Surface &from, Common::Rational scale, int32 tran
blitScaled(from, 0, 0, from._width - 1, from._height - 1, 0, 0, scale, transp);
}
-void Surface::fillRect(uint16 left, uint16 top, uint16 right, uint16 bottom, uint32 color) {
+void Surface::fillRect(int16 left, int16 top, int16 right, int16 bottom, uint32 color) {
// Just in case those are swapped
if (left > right)
SWAP(left, right);
@@ -481,6 +481,11 @@ void Surface::fillRect(uint16 left, uint16 top, uint16 right, uint16 bottom, uin
// Nothing to do
return;
+ left = CLIP<int32>(left , 0, _width - 1);
+ top = CLIP<int32>(top , 0, _height - 1);
+ right = CLIP<int32>(right , 0, _width - 1);
+ bottom = CLIP<int32>(bottom, 0, _height - 1);
+
// Area to actually fill
uint16 width = CLIP<int32>(right - left + 1, 0, _width - left);
uint16 height = CLIP<int32>(bottom - top + 1, 0, _height - top);
diff --git a/engines/gob/surface.h b/engines/gob/surface.h
index c931731908..eb0a5bf1a4 100644
--- a/engines/gob/surface.h
+++ b/engines/gob/surface.h
@@ -121,7 +121,7 @@ public:
void blitScaled(const Surface &from, int16 x, int16 y, Common::Rational scale, int32 transp = -1);
void blitScaled(const Surface &from, Common::Rational scale, int32 transp = -1);
- void fillRect(uint16 left, uint16 top, uint16 right, uint16 bottom, uint32 color);
+ void fillRect(int16 left, int16 top, int16 right, int16 bottom, uint32 color);
void fill(uint32 color);
void clear();
diff --git a/engines/groovie/music.cpp b/engines/groovie/music.cpp
index 2c164e020c..c00290b155 100644
--- a/engines/groovie/music.cpp
+++ b/engines/groovie/music.cpp
@@ -36,6 +36,7 @@
#include "common/textconsole.h"
#include "audio/audiostream.h"
#include "audio/midiparser.h"
+#include "audio/miles.h"
namespace Groovie {
@@ -379,14 +380,56 @@ bool MusicPlayerMidi::loadParser(Common::SeekableReadStream *stream, bool loop)
MusicPlayerXMI::MusicPlayerXMI(GroovieEngine *vm, const Common::String &gtlName) :
MusicPlayerMidi(vm) {
- // Create the parser
- _midiParser = MidiParser::createParser_XMIDI();
// Create the driver
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
- _driver = MidiDriver::createMidi(dev);
+ MusicType musicType = MidiDriver::getMusicType(dev);
+ _driver = NULL;
+
+ // new Miles Audio support, to disable set milesAudioEnabled to false
+ _milesAudioMode = false;
+ bool milesAudioEnabled = true;
+ MidiParser::XMidiNewTimbreListProc newTimbreListProc = NULL;
+
+ if (milesAudioEnabled) {
+ // 7th Guest uses FAT.AD/FAT.OPL/FAT.MT
+ // 11th Hour uses SAMPLE.AD/SAMPLE.OPL/SAMPLE.MT
+ switch (musicType) {
+ case MT_ADLIB:
+ _driver = Audio::MidiDriver_Miles_AdLib_create(gtlName + ".AD", gtlName + ".OPL");
+ break;
+ case MT_MT32:
+ _driver = Audio::MidiDriver_Miles_MT32_create(gtlName + ".MT");
+ break;
+ case MT_GM:
+ if (ConfMan.getBool("native_mt32")) {
+ _driver = Audio::MidiDriver_Miles_MT32_create(gtlName + ".MT");
+ musicType = MT_MT32;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (musicType == MT_MT32) {
+ newTimbreListProc = Audio::MidiDriver_Miles_MT32_processXMIDITimbreChunk;
+ }
+ }
+
+ if (_driver) {
+ _milesAudioMode = true;
+ }
+
+ if (!_driver) {
+ // No driver yet? create a generic one
+ _driver = MidiDriver::createMidi(dev);
+ }
+
assert(_driver);
+ // Create the parser
+ _midiParser = MidiParser::createParser_XMIDI(NULL, NULL, newTimbreListProc, _driver);
+
_driver->open(); // TODO: Handle return value != 0 (indicating an error)
// Set the parser's driver
@@ -400,6 +443,9 @@ MusicPlayerXMI::MusicPlayerXMI(GroovieEngine *vm, const Common::String &gtlName)
_chanBanks[i] = 0;
}
+ if (_milesAudioMode)
+ return;
+
// Load the Global Timbre Library
if (MidiDriver::getMusicType(dev) == MT_ADLIB) {
// MIDI through AdLib
@@ -433,6 +479,11 @@ MusicPlayerXMI::~MusicPlayerXMI() {
}
void MusicPlayerXMI::send(uint32 b) {
+ if (_milesAudioMode) {
+ MusicPlayerMidi::send(b);
+ return;
+ }
+
if ((b & 0xFFF0) == 0x72B0) { // XMIDI Patch Bank Select 114
// From AIL2's documentation: XMIDI Patch Bank Select controller (114)
// selects a bank to be used when searching the next patches
diff --git a/engines/groovie/music.h b/engines/groovie/music.h
index 4853840673..dcb91d42a8 100644
--- a/engines/groovie/music.h
+++ b/engines/groovie/music.h
@@ -134,6 +134,8 @@ private:
// Output music type
uint8 _musicType;
+ bool _milesAudioMode;
+
// Timbres
class Timbre {
public:
diff --git a/engines/hopkins/lines.cpp b/engines/hopkins/lines.cpp
index 709f17a8b2..f511e6aa5a 100644
--- a/engines/hopkins/lines.cpp
+++ b/engines/hopkins/lines.cpp
@@ -2110,7 +2110,7 @@ RouteItem *LinesManager::cityMapCarRoute(int x1, int y1, int x2, int y2) {
_testRoute0[superRouteIdx].set(curRouteX, curRouteY, curRouteDir);
superRouteIdx++;
if (curRouteX == -1)
- break;;
+ break;
}
if (curRouteX != -1) {
curRouteLineIdx = arrLineIdx[DIR_UP];
diff --git a/engines/hugo/mouse.cpp b/engines/hugo/mouse.cpp
index 558a596b35..3674c90757 100644
--- a/engines/hugo/mouse.cpp
+++ b/engines/hugo/mouse.cpp
@@ -121,12 +121,24 @@ void MouseHandler::cursorText(const char *buffer, const int16 cx, const int16 cy
int16 sx, sy;
if (cx < kXPix / 2) {
sx = cx + kCursorNameOffX;
- sy = (_vm->_inventory->getInventoryObjId() == -1) ? cy + kCursorNameOffY : cy + kCursorNameOffY - (_vm->_screen->fontHeight() + 1);
+ if (_vm->_inventory->getInventoryObjId() == -1) {
+ sy = cy + kCursorNameOffY;
+ } else {
+ sy = cy + kCursorNameOffY - (_vm->_screen->fontHeight() + 1);
+ if (sy < 0) {
+ sx = cx + kCursorNameOffX + 25;
+ sy = cy + kCursorNameOffY;
+ }
+ }
} else {
sx = cx - sdx - kCursorNameOffX / 2;
sy = cy + kCursorNameOffY;
}
+ if (sy < 0) {
+ sy = 0;
+ }
+
// Display the string and add rect to display list
_vm->_screen->shadowStr(sx, sy, buffer, _TBRIGHTWHITE);
_vm->_screen->displayList(kDisplayAdd, sx, sy, sdx, sdy);
diff --git a/engines/kyra/sound_adlib.cpp b/engines/kyra/sound_adlib.cpp
index 89ee41e859..1d741d8bd0 100644
--- a/engines/kyra/sound_adlib.cpp
+++ b/engines/kyra/sound_adlib.cpp
@@ -55,7 +55,7 @@
namespace Kyra {
-class AdLibDriver : public Audio::AudioStream {
+class AdLibDriver {
public:
AdLibDriver(Audio::Mixer *mixer, int version);
~AdLibDriver();
@@ -70,34 +70,6 @@ public:
void callback();
- // AudioStream API
- int readBuffer(int16 *buffer, const int numSamples) {
- int32 samplesLeft = numSamples;
- memset(buffer, 0, sizeof(int16) * numSamples);
- while (samplesLeft) {
- if (!_samplesTillCallback) {
- callback();
- _samplesTillCallback = _samplesPerCallback;
- _samplesTillCallbackRemainder += _samplesPerCallbackRemainder;
- if (_samplesTillCallbackRemainder >= CALLBACKS_PER_SECOND) {
- _samplesTillCallback++;
- _samplesTillCallbackRemainder -= CALLBACKS_PER_SECOND;
- }
- }
-
- int32 render = MIN(samplesLeft, _samplesTillCallback);
- samplesLeft -= render;
- _samplesTillCallback -= render;
- YM3812UpdateOne(_adlib, buffer, render);
- buffer += render;
- }
- return numSamples;
- }
-
- bool isStereo() const { return false; }
- bool endOfData() const { return false; }
- int getRate() const { return _mixer->getOutputRate(); }
-
void setSyncJumpMask(uint16 mask) { _syncJumpMask = mask; }
void setMusicVolume(uint8 volume);
@@ -334,11 +306,6 @@ private:
// _unkTable2_2[] - One of the tables in _unkTable2[]
// _unkTable2_3[] - One of the tables in _unkTable2[]
- int32 _samplesPerCallback;
- int32 _samplesPerCallbackRemainder;
- int32 _samplesTillCallback;
- int32 _samplesTillCallbackRemainder;
-
int _curChannel;
uint8 _soundTrigger;
@@ -365,7 +332,7 @@ private:
uint8 _unkValue19;
uint8 _unkValue20;
- FM_OPL *_adlib;
+ OPL::OPL *_adlib;
uint8 *_soundData;
uint32 _soundDataSize;
@@ -411,7 +378,6 @@ private:
Common::Mutex _mutex;
Audio::Mixer *_mixer;
- Audio::SoundHandle _soundHandle;
uint8 _musicVolume, _sfxVolume;
@@ -427,8 +393,9 @@ AdLibDriver::AdLibDriver(Audio::Mixer *mixer, int version) {
_mixer = mixer;
- _adlib = makeAdLibOPL(getRate());
- assert(_adlib);
+ _adlib = OPL::Config::create();
+ if (!_adlib || !_adlib->init())
+ error("Failed to create OPL");
memset(_channels, 0, sizeof(_channels));
_soundData = 0;
@@ -451,13 +418,6 @@ AdLibDriver::AdLibDriver(Audio::Mixer *mixer, int version) {
_tablePtr1 = _tablePtr2 = 0;
- _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
-
- _samplesPerCallback = getRate() / CALLBACKS_PER_SECOND;
- _samplesPerCallbackRemainder = getRate() % CALLBACKS_PER_SECOND;
- _samplesTillCallback = 0;
- _samplesTillCallbackRemainder = 0;
-
_syncJumpMask = 0;
_musicVolume = 0;
@@ -467,11 +427,12 @@ AdLibDriver::AdLibDriver(Audio::Mixer *mixer, int version) {
_programQueueStart = _programQueueEnd = 0;
_retrySounds = false;
+
+ _adlib->start(new Common::Functor0Mem<void, AdLibDriver>(this, &AdLibDriver::callback), CALLBACKS_PER_SECOND);
}
AdLibDriver::~AdLibDriver() {
- _mixer->stopHandle(_soundHandle);
- OPLDestroy(_adlib);
+ delete _adlib;
_adlib = 0;
}
@@ -877,7 +838,7 @@ void AdLibDriver::resetAdLibState() {
// New calling style: writeOPL(0xAB, 0xCD)
void AdLibDriver::writeOPL(byte reg, byte val) {
- OPLWriteReg(_adlib, reg, val);
+ _adlib->writeReg(reg, val);
}
void AdLibDriver::initChannel(Channel &channel) {
@@ -947,15 +908,10 @@ void AdLibDriver::unkOutput2(uint8 chan) {
//
// This is very strange behavior, and causes problems with the ancient
// FMOPL code we borrowed from AdPlug. I've added a workaround. See
- // fmopl.cpp for more details.
- //
- // More recent versions of the MAME FMOPL don't seem to have this
- // problem, but cannot currently be used because of licensing and
- // performance issues.
+ // audio/softsynth/opl/mame.cpp for more details.
//
- // Ken Silverman's AdLib emulator (which can be found on his Web page -
- // http://www.advsys.net/ken - and as part of AdPlug) also seems to be
- // immune, but is apparently not as feature complete as MAME's.
+ // Fortunately, the more modern DOSBox FMOPL code does not seem to have
+ // any trouble with this.
writeOPL(0xB0 + chan, 0x20);
}
diff --git a/engines/lure/res.h b/engines/lure/res.h
index 9002ca3056..19fbde1aad 100644
--- a/engines/lure/res.h
+++ b/engines/lure/res.h
@@ -100,7 +100,6 @@ public:
static Resources &getReference();
void reset();
- byte *getResource(uint16 resId);
RoomDataList &roomData() { return _roomData; }
RoomData *getRoom(uint16 roomNumber);
bool checkHotspotExtent(HotspotData *hotspot);
diff --git a/engines/made/database.cpp b/engines/made/database.cpp
index a9855ba1fe..3eab31acc2 100644
--- a/engines/made/database.cpp
+++ b/engines/made/database.cpp
@@ -252,6 +252,10 @@ byte *ObjectV3::getData() {
GameDatabase::GameDatabase(MadeEngine *vm) : _vm(vm) {
+ _gameState = nullptr;
+ _gameStateSize = 0;
+ _mainCodeObjectIndex = 0;
+ _isRedSource = false;
}
GameDatabase::~GameDatabase() {
@@ -595,6 +599,8 @@ const char *GameDatabaseV2::getString(uint16 offset) {
/* GameDatabaseV3 */
GameDatabaseV3::GameDatabaseV3(MadeEngine *vm) : GameDatabase(vm) {
+ _gameText = nullptr;
+ _gameStateOffs = 0;
}
void GameDatabaseV3::load(Common::SeekableReadStream &sourceS) {
diff --git a/engines/made/made.cpp b/engines/made/made.cpp
index af8156fc3e..ab07ef757b 100644
--- a/engines/made/made.cpp
+++ b/engines/made/made.cpp
@@ -275,7 +275,7 @@ void MadeEngine::handleEvents() {
}
Common::Error MadeEngine::run() {
- _music = new MusicPlayer();
+ _music = new MusicPlayer(getGameID() == GID_RTZ);
syncSoundSettings();
// Initialize backend
diff --git a/engines/made/music.cpp b/engines/made/music.cpp
index b2917b58ed..f57da833c2 100644
--- a/engines/made/music.cpp
+++ b/engines/made/music.cpp
@@ -25,27 +25,67 @@
// MIDI and digital music class
#include "made/music.h"
+#include "made/redreader.h"
#include "made/resource.h"
#include "audio/midiparser.h"
+#include "audio/miles.h"
+
+#include "common/file.h"
+#include "common/stream.h"
namespace Made {
-MusicPlayer::MusicPlayer() : _isGM(false) {
- MidiPlayer::createDriver();
+MusicPlayer::MusicPlayer(bool milesAudio) : _isGM(false),_milesAudioMode(false) {
+ MusicType musicType = MT_INVALID;
+ if (milesAudio) {
+ MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MT32);
+ musicType = MidiDriver::getMusicType(dev);
+ Common::SeekableReadStream *adLibInstrumentStream = nullptr;
+ switch (musicType) {
+ case MT_ADLIB:
+ _milesAudioMode = true;
+ if (Common::File::exists("rtzcd.red")) {
+ // Installing Return to Zork produces both a SAMPLE.AD and
+ // a SAMPLE.OPL file, but they are identical. The resource
+ // file appears to only contain SAMPLE.AD.
+ adLibInstrumentStream = RedReader::loadFromRed("rtzcd.red", "SAMPLE.AD");
+ }
+ _driver = Audio::MidiDriver_Miles_AdLib_create("SAMPLE.AD", "SAMPLE.OPL", adLibInstrumentStream);
+ delete adLibInstrumentStream;
+ break;
+ case MT_MT32:
+ _milesAudioMode = true;
+ _driver = Audio::MidiDriver_Miles_MT32_create("");
+ break;
+ default:
+ _milesAudioMode = false;
+ MidiPlayer::createDriver();
+ break;
+ }
+ } else {
+ MidiPlayer::createDriver();
+ }
int ret = _driver->open();
if (ret == 0) {
- if (_nativeMT32)
- _driver->sendMT32Reset();
- else
- _driver->sendGMReset();
+ if (musicType != MT_ADLIB) {
+ if (_nativeMT32)
+ _driver->sendMT32Reset();
+ else
+ _driver->sendGMReset();
+ }
_driver->setTimerCallback(this, &timerCallback);
}
}
void MusicPlayer::send(uint32 b) {
+ if (_milesAudioMode) {
+ _driver->send(b);
+ return;
+ }
+
if ((b & 0xF0) == 0xC0 && !_isGM && !_nativeMT32) {
b = (b & 0xFFFF00FF) | MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8;
}
diff --git a/engines/made/music.h b/engines/made/music.h
index 95d1bd35c1..558b41c2e2 100644
--- a/engines/made/music.h
+++ b/engines/made/music.h
@@ -38,7 +38,7 @@ enum MusicFlags {
class MusicPlayer : public Audio::MidiPlayer {
public:
- MusicPlayer();
+ MusicPlayer(bool milesAudio);
void playXMIDI(GenericResource *midiResource, MusicFlags flags = MUSIC_NORMAL);
void playSMF(GenericResource *midiResource, MusicFlags flags = MUSIC_NORMAL);
@@ -51,6 +51,7 @@ public:
protected:
bool _isGM;
+ bool _milesAudioMode;
};
} // End of namespace Made
diff --git a/engines/made/pmvplayer.cpp b/engines/made/pmvplayer.cpp
index 3cac017e10..453e2a4872 100644
--- a/engines/made/pmvplayer.cpp
+++ b/engines/made/pmvplayer.cpp
@@ -37,16 +37,18 @@
namespace Made {
-PmvPlayer::PmvPlayer(MadeEngine *vm, Audio::Mixer *mixer) : _fd(NULL), _vm(vm), _mixer(mixer) {
+PmvPlayer::PmvPlayer(MadeEngine *vm, Audio::Mixer *mixer) : _fd(nullptr), _vm(vm), _mixer(mixer) {
+ _audioStream = nullptr;
+ _surface = nullptr;
+ _aborted = false;
}
PmvPlayer::~PmvPlayer() {
}
bool PmvPlayer::play(const char *filename) {
-
_aborted = false;
- _surface = NULL;
+ _surface = nullptr;
_fd = new Common::File();
if (!_fd->open(filename)) {
@@ -81,8 +83,11 @@ bool PmvPlayer::play(const char *filename) {
// results to sound being choppy. Therefore, we set them to more
// "common" values here (11025 instead of 11127 and 22050 instead
// of 22254)
- if (soundFreq == 11127) soundFreq = 11025;
- if (soundFreq == 22254) soundFreq = 22050;
+ if (soundFreq == 11127)
+ soundFreq = 11025;
+
+ if (soundFreq == 22254)
+ soundFreq = 22050;
for (int i = 0; i < 22; i++) {
int unk = _fd->readUint16LE();
@@ -113,6 +118,8 @@ bool PmvPlayer::play(const char *filename) {
// get it to work well?
_audioStream = Audio::makeQueuingAudioStream(soundFreq, false);
+ SoundDecoderData *soundDecoderData = new SoundDecoderData();
+
while (!_vm->shouldQuit() && !_aborted && !_fd->eos() && frameNumber < frameCount) {
int32 frameTime = _vm->_system->getMillis();
@@ -148,7 +155,7 @@ bool PmvPlayer::play(const char *filename) {
soundSize = chunkCount * chunkSize;
soundData = (byte *)malloc(soundSize);
- decompressSound(audioData + 8, soundData, chunkSize, chunkCount);
+ decompressSound(audioData + 8, soundData, chunkSize, chunkCount, NULL, soundDecoderData);
_audioStream->queueBuffer(soundData, soundSize, DisposeAfterUse::YES, Audio::FLAG_UNSIGNED);
}
@@ -208,6 +215,7 @@ bool PmvPlayer::play(const char *filename) {
}
+ delete soundDecoderData;
delete[] frameData;
_audioStream->finish();
diff --git a/engines/made/redreader.cpp b/engines/made/redreader.cpp
index f5e6ca85b3..f92ffd8dd8 100644
--- a/engines/made/redreader.cpp
+++ b/engines/made/redreader.cpp
@@ -76,6 +76,22 @@ bool RedReader::seekFile(Common::File &fd, FileEntry &fileEntry, const char *fil
}
LzhDecompressor::LzhDecompressor() {
+ freq = nullptr;
+ len_table = nullptr;
+ sortptr = nullptr;
+ _source = nullptr;
+
+ _compSize = 0;
+ _blockPos = 0;
+ _bitbuf = 0;
+ _subbitbuf = 0;
+ _bitcount = 0;
+ _blocksize = 0;
+ tree_n = 0;
+ heapsize = 0;
+ decode_i = 0;
+ decode_j = 0;
+ count_len_depth = 0;
}
LzhDecompressor::~LzhDecompressor() {
diff --git a/engines/made/resource.cpp b/engines/made/resource.cpp
index 2c75965976..f8e763e74e 100644
--- a/engines/made/resource.cpp
+++ b/engines/made/resource.cpp
@@ -241,6 +241,7 @@ void AnimationResource::load(byte *source, int size) {
/* SoundResource */
SoundResource::SoundResource() : _soundSize(0), _soundData(NULL) {
+ _soundEnergyArray = nullptr;
}
SoundResource::~SoundResource() {
@@ -377,6 +378,9 @@ void GenericResource::load(byte *source, int size) {
ResourceReader::ResourceReader() {
_isV1 = false;
_cacheDataSize = 0;
+
+ _fd = _fdMusic = _fdPics = _fdSounds = nullptr;
+ _cacheCount = 0;
}
ResourceReader::~ResourceReader() {
diff --git a/engines/made/screenfx.cpp b/engines/made/screenfx.cpp
index 2a155d67ac..bae59f05cc 100644
--- a/engines/made/screenfx.cpp
+++ b/engines/made/screenfx.cpp
@@ -51,7 +51,12 @@ ScreenEffects::ScreenEffects(Screen *screen) : _screen(screen) {
vfxHeight = 0;
_fxPalette = new byte[768];
-
+
+ _blendedPaletteStatus._active = false;
+ _blendedPaletteStatus._palette = _blendedPaletteStatus._newPalette = nullptr;
+ _blendedPaletteStatus._colorCount = 0;
+ _blendedPaletteStatus._value = _blendedPaletteStatus._maxValue = 0;
+ _blendedPaletteStatus._incr = 0;
}
ScreenEffects::~ScreenEffects() {
@@ -196,7 +201,7 @@ void ScreenEffects::startBlendedPalette(byte *palette, byte *newPalette, int col
}
void ScreenEffects::stepBlendedPalette() {
- if (_blendedPaletteStatus._active && _blendedPaletteStatus._value < _blendedPaletteStatus._maxValue) {
+ if (_blendedPaletteStatus._active && _blendedPaletteStatus._value <= _blendedPaletteStatus._maxValue) {
setBlendedPalette(_blendedPaletteStatus._palette, _blendedPaletteStatus._newPalette,
_blendedPaletteStatus._colorCount, _blendedPaletteStatus._value, _blendedPaletteStatus._maxValue);
if (_blendedPaletteStatus._value == _blendedPaletteStatus._maxValue)
diff --git a/engines/made/screenfx.h b/engines/made/screenfx.h
index fd216bfd63..cedb059927 100644
--- a/engines/made/screenfx.h
+++ b/engines/made/screenfx.h
@@ -38,7 +38,6 @@ struct BlendedPaletteStatus {
byte *_palette, *_newPalette;
int _colorCount;
int16 _value, _maxValue, _incr;
- int cnt;
};
class ScreenEffects {
diff --git a/engines/made/script.cpp b/engines/made/script.cpp
index 20fa026a40..f9f7acffde 100644
--- a/engines/made/script.cpp
+++ b/engines/made/script.cpp
@@ -122,6 +122,11 @@ ScriptInterpreter::ScriptInterpreter(MadeEngine *vm) : _vm(vm) {
_functions = new ScriptFunctions(_vm);
_functions->setupExternalsTable();
+ _localStackPos = 0;
+ _runningScriptObjectIndex = 0;
+ _codeBase = nullptr;
+ _codeIp = nullptr;
+
#undef COMMAND
}
diff --git a/engines/made/script.h b/engines/made/script.h
index bf75bc0875..f28425d13b 100644
--- a/engines/made/script.h
+++ b/engines/made/script.h
@@ -84,7 +84,6 @@ protected:
int16 _localStackPos;
int16 _runningScriptObjectIndex;
byte *_codeBase, *_codeIp;
- bool _terminated;
ScriptFunctions *_functions;
diff --git a/engines/made/scriptfuncs.cpp b/engines/made/scriptfuncs.cpp
index efa765c7eb..bcc08e0dcc 100644
--- a/engines/made/scriptfuncs.cpp
+++ b/engines/made/scriptfuncs.cpp
@@ -42,6 +42,8 @@ ScriptFunctions::ScriptFunctions(MadeEngine *vm) : _vm(vm), _soundStarted(false)
_pcSpeaker2 = new Audio::PCSpeaker();
_vm->_system->getMixer()->playStream(Audio::Mixer::kMusicSoundType, &_pcSpeakerHandle1, _pcSpeaker1);
_vm->_system->getMixer()->playStream(Audio::Mixer::kMusicSoundType, &_pcSpeakerHandle2, _pcSpeaker2);
+ _soundResource = nullptr;
+ _musicRes = nullptr;
}
ScriptFunctions::~ScriptFunctions() {
diff --git a/engines/made/sound.cpp b/engines/made/sound.cpp
index 91e855cbf5..ad49031e7b 100644
--- a/engines/made/sound.cpp
+++ b/engines/made/sound.cpp
@@ -133,10 +133,10 @@ void ManholeEgaSoundDecompressor::update3() {
_sample2 += _sample1;
}
-void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCount, SoundEnergyArray *soundEnergyArray) {
+void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCount, SoundEnergyArray *soundEnergyArray, SoundDecoderData *soundDecoderData) {
- int16 prevSample = 0, workSample = 0;
- byte soundBuffer[1025];
+ int16 prevSample, workSample;
+ byte* soundBuffer;
byte deltaSoundBuffer[1024];
int16 soundBuffer2[16];
byte deltaType, type;
@@ -159,6 +159,15 @@ void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCou
if (soundEnergyArray)
soundEnergyArray->clear();
+ if (soundDecoderData) {
+ soundBuffer = soundDecoderData->_soundBuffer;
+ prevSample = soundDecoderData->_prevSample;
+ } else {
+ soundBuffer = new byte[1025];
+ memset(soundBuffer, 0x80, 1025);
+ prevSample = 0;
+ }
+
while (chunkCount--) {
deltaType = (*source) >> 6;
workChunkSize = chunkSize;
@@ -233,6 +242,11 @@ void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCou
}
if (deltaType > 0) {
+ // NB: The original did not add this extra value at the end (as far
+ // as I can tell), and so technically read past the filled part of
+ // soundBuffer.
+ soundBuffer[workChunkSize] = soundBuffer[workChunkSize - 1];
+
if (deltaType == 1) {
for (i = 0; i < chunkSize - 1; i += 2) {
l = i / 2;
@@ -255,9 +269,13 @@ void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCou
prevSample = workSample;
memcpy(dest, soundBuffer, chunkSize);
dest += chunkSize;
-
}
+ if (soundDecoderData) {
+ soundDecoderData->_prevSample = prevSample;
+ } else {
+ delete[] soundBuffer;
+ }
}
} // End of namespace Made
diff --git a/engines/made/sound.h b/engines/made/sound.h
index 6ffca13aaa..72537322f9 100644
--- a/engines/made/sound.h
+++ b/engines/made/sound.h
@@ -53,7 +53,22 @@ struct SoundEnergyItem {
typedef Common::Array<SoundEnergyItem> SoundEnergyArray;
-void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCount, SoundEnergyArray *soundEnergyArray = NULL);
+
+// Persistent data for decompressSound(). When calling decompressSound()
+// repeatedly (for the same stream), pass the same SoundDecoderData object to
+// ensure decoding properly resumes.
+class SoundDecoderData {
+public:
+ SoundDecoderData() {
+ memset(_soundBuffer, 0x80, sizeof(_soundBuffer));
+ _prevSample = 0;
+ }
+
+ byte _soundBuffer[1025];
+ int16 _prevSample;
+};
+
+void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCount, SoundEnergyArray *soundEnergyArray = NULL, SoundDecoderData *decoderData = NULL);
} // End of namespace Made
diff --git a/engines/mads/action.cpp b/engines/mads/action.cpp
index 199ae39000..f1c562675f 100644
--- a/engines/mads/action.cpp
+++ b/engines/mads/action.cpp
@@ -8,12 +8,12 @@
* 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.
@@ -567,9 +567,8 @@ void MADSAction::leftClick() {
switch (userInterface._category) {
case CAT_COMMAND:
if (_selectedRow >= 0) {
- if (_verbType == VERB_ONLY) {
+ if (_verbType == VERB_ONLY)
_selectedAction = -1;
- }
else {
_recentCommand = _selectedRow;
_recentCommandSource = _commandSource;
diff --git a/engines/mads/action.h b/engines/mads/action.h
index cfd5a3be3f..3ea10cd964 100644
--- a/engines/mads/action.h
+++ b/engines/mads/action.h
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/animation.cpp b/engines/mads/animation.cpp
index 2b999fa305..e4f44fc308 100644
--- a/engines/mads/animation.cpp
+++ b/engines/mads/animation.cpp
@@ -8,12 +8,12 @@
* 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.
@@ -41,7 +41,7 @@ void AAHeader::load(Common::SeekableReadStream *f) {
_spritesIndex = f->readUint16LE();
_scrollPosition.x = f->readSint16LE();
_scrollPosition.y = f->readSint16LE();
- _scrollTicks = f->readUint32LE();
+ _scrollTicks = f->readUint32LE() & 0xffff;
f->skip(6);
char buffer[FILENAME_SIZE];
@@ -436,10 +436,8 @@ void Animation::update() {
if (_vm->_game->_scene._frameStartTime < _nextFrameTimer)
return;
- for (uint idx = 0; idx < scene._spriteSlots.size(); ++idx) {
- if (scene._spriteSlots[idx]._seqIndex >= 0x80)
- scene._spriteSlots[idx]._flags = IMG_ERASE;
- }
+ // Erase any active sprites
+ eraseSprites();
// Validate the current frame
if (_currentFrame >= (int)_miscEntries.size()) {
@@ -598,12 +596,19 @@ void Animation::setCurrentFrame(int frameNumber) {
_currentFrame = frameNumber;
_oldFrameEntry = 0;
_freeFlag = false;
-
- _nextScrollTimer = _nextFrameTimer = _vm->_game->_scene._frameStartTime;
}
void Animation::setNextFrameTimer(int frameNumber) {
_nextFrameTimer = frameNumber;
}
+void Animation::eraseSprites() {
+ Scene &scene = _vm->_game->_scene;
+
+ for (uint idx = 0; idx < scene._spriteSlots.size(); ++idx) {
+ if (scene._spriteSlots[idx]._seqIndex >= 0x80)
+ scene._spriteSlots[idx]._flags = IMG_ERASE;
+ }
+}
+
} // End of namespace MADS
diff --git a/engines/mads/animation.h b/engines/mads/animation.h
index 8b85a5370d..46ef85c5eb 100644
--- a/engines/mads/animation.h
+++ b/engines/mads/animation.h
@@ -8,12 +8,12 @@
* 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.
@@ -219,6 +219,11 @@ public:
*/
void update();
+ /**
+ * Erases any sprites from the previous animation frame
+ */
+ void eraseSprites();
+
void setNextFrameTimer(int frameNumber);
int getNextFrameTimer() const { return _nextFrameTimer; }
void setCurrentFrame(int frameNumber);
diff --git a/engines/mads/assets.cpp b/engines/mads/assets.cpp
index a2d495f311..1d4634e383 100644
--- a/engines/mads/assets.cpp
+++ b/engines/mads/assets.cpp
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/assets.h b/engines/mads/assets.h
index 155590f9bd..8a0dc2cd44 100644
--- a/engines/mads/assets.h
+++ b/engines/mads/assets.h
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/audio.cpp b/engines/mads/audio.cpp
index def2cd6c62..8f33f22243 100644
--- a/engines/mads/audio.cpp
+++ b/engines/mads/audio.cpp
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/audio.h b/engines/mads/audio.h
index 13c540bf85..5c3cd5e682 100644
--- a/engines/mads/audio.h
+++ b/engines/mads/audio.h
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/compression.cpp b/engines/mads/compression.cpp
index 79cd1786de..1f6f1ee202 100644
--- a/engines/mads/compression.cpp
+++ b/engines/mads/compression.cpp
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/compression.h b/engines/mads/compression.h
index f7381e4af3..b560ed33c1 100644
--- a/engines/mads/compression.h
+++ b/engines/mads/compression.h
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/debugger.cpp b/engines/mads/debugger.cpp
index 99251f9fbb..a6a4d3edbc 100644
--- a/engines/mads/debugger.cpp
+++ b/engines/mads/debugger.cpp
@@ -8,12 +8,12 @@
* 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
+ * 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.
diff --git a/engines/mads/debugger.h b/engines/mads/debugger.h
index c8fee5f5b2..70b2cadc65 100644
--- a/engines/mads/debugger.h
+++ b/engines/mads/debugger.h
@@ -8,12 +8,12 @@
* 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
+ * 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.
diff --git a/engines/mads/detection.cpp b/engines/mads/detection.cpp
index 971acde024..57f4776e82 100644
--- a/engines/mads/detection.cpp
+++ b/engines/mads/detection.cpp
@@ -8,12 +8,12 @@
* 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.
@@ -29,6 +29,7 @@
#include "common/memstream.h"
#include "engines/advancedDetector.h"
#include "common/system.h"
+#include "common/translation.h"
#include "graphics/colormasks.h"
#include "graphics/surface.h"
#include "mads/events.h"
@@ -75,11 +76,71 @@ static const PlainGameDescriptor MADSGames[] = {
{0, 0}
};
+#define GAMEOPTION_EASY_MOUSE GUIO_GAMEOPTIONS1
+#define GAMEOPTION_ANIMATED_INVENTORY GUIO_GAMEOPTIONS2
+#define GAMEOPTION_ANIMATED_INTERFACE GUIO_GAMEOPTIONS3
+#define GAMEOPTION_NAUGHTY_MODE GUIO_GAMEOPTIONS4
+//#define GAMEOPTION_GRAPHICS_DITHERING GUIO_GAMEOPTIONS5
+
#include "mads/detection_tables.h"
+static const ADExtraGuiOptionsMap optionsList[] = {
+ {
+ GAMEOPTION_EASY_MOUSE,
+ {
+ _s("Easy mouse interface"),
+ _s("Shows object names when hovering the mouse over them"),
+ "EasyMouse",
+ true
+ }
+ },
+
+ {
+ GAMEOPTION_ANIMATED_INVENTORY,
+ {
+ _s("Animated inventory items"),
+ _s("Animated inventory items"),
+ "InvObjectsAnimated",
+ true
+ }
+ },
+
+ {
+ GAMEOPTION_ANIMATED_INTERFACE,
+ {
+ _s("Animated game interface"),
+ _s("Animated game interface"),
+ "TextWindowAnimated",
+ true
+ }
+ },
+
+ {
+ GAMEOPTION_NAUGHTY_MODE,
+ {
+ _s("Naughty game mode"),
+ _s("Naughty game mode"),
+ "NaughtyMode",
+ true
+ }
+ },
+
+ /*{
+ GAMEOPTION_GRAPHICS_DITHERING,
+ {
+ _s("Graphics dithering"),
+ _s("Graphics dithering"),
+ "GraphicsDithering",
+ true
+ }
+ },*/
+
+ AD_EXTRA_GUI_OPTIONS_TERMINATOR
+};
+
class MADSMetaEngine : public AdvancedMetaEngine {
public:
- MADSMetaEngine() : AdvancedMetaEngine(MADS::gameDescriptions, sizeof(MADS::MADSGameDescription), MADSGames) {
+ MADSMetaEngine() : AdvancedMetaEngine(MADS::gameDescriptions, sizeof(MADS::MADSGameDescription), MADSGames, optionsList) {
_maxScanDepth = 3;
}
diff --git a/engines/mads/detection_tables.h b/engines/mads/detection_tables.h
index e68ae380d0..56df09577c 100644
--- a/engines/mads/detection_tables.h
+++ b/engines/mads/detection_tables.h
@@ -8,12 +8,12 @@
* 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.
@@ -37,7 +37,7 @@ static const MADSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO5(GUIO_NOSPEECH, GAMEOPTION_EASY_MOUSE, GAMEOPTION_ANIMATED_INVENTORY, GAMEOPTION_ANIMATED_INTERFACE, GAMEOPTION_NAUGHTY_MODE)
},
GType_RexNebular,
0
@@ -55,8 +55,8 @@ static const MADSGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformDOS,
- ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ ADGF_TESTING,
+ GUIO5(GUIO_NOSPEECH, GAMEOPTION_EASY_MOUSE, GAMEOPTION_ANIMATED_INVENTORY, GAMEOPTION_ANIMATED_INTERFACE, GAMEOPTION_NAUGHTY_MODE)
},
GType_RexNebular,
0
@@ -73,8 +73,8 @@ static const MADSGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformDOS,
- ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ ADGF_TESTING,
+ GUIO5(GUIO_NOSPEECH, GAMEOPTION_EASY_MOUSE, GAMEOPTION_ANIMATED_INVENTORY, GAMEOPTION_ANIMATED_INTERFACE, GAMEOPTION_NAUGHTY_MODE)
},
GType_RexNebular,
0
@@ -92,7 +92,7 @@ static const MADSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GAMEOPTION_EASY_MOUSE)
},
GType_Phantom,
0
@@ -110,7 +110,7 @@ static const MADSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GAMEOPTION_EASY_MOUSE)
},
GType_Dragonsphere,
0
diff --git a/engines/mads/dialogs.cpp b/engines/mads/dialogs.cpp
index 5e38f34fc6..d9b27ce926 100644
--- a/engines/mads/dialogs.cpp
+++ b/engines/mads/dialogs.cpp
@@ -8,12 +8,12 @@
* 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.
@@ -43,6 +43,7 @@ Dialog::Dialog(MADSEngine *vm)
}
Dialog::~Dialog() {
+ delete _savedSurface;
}
void Dialog::save() {
@@ -430,6 +431,7 @@ void FullScreenDialog::display() {
if (_screenId > 0) {
SceneInfo *sceneInfo = SceneInfo::init(_vm);
sceneInfo->load(_screenId, 0, "", 0, scene._depthSurface, scene._backgroundSurface);
+ delete sceneInfo;
}
scene._priorSceneId = priorSceneId;
@@ -449,7 +451,7 @@ void FullScreenDialog::display() {
}
// Set Fx state and palette entries
- game._fx = _vm->_screenFade == SCREEN_FADE_SMOOTH ? kTransitionFadeIn : kCenterVertTransition;
+ game._fx = _vm->_screenFade == SCREEN_FADE_SMOOTH ? kTransitionFadeIn : kNullPaletteCopy;
game._trigger = 0;
// Clear the screen and draw the upper and lower horizontal lines
diff --git a/engines/mads/dialogs.h b/engines/mads/dialogs.h
index 317c7bd792..efd2871d89 100644
--- a/engines/mads/dialogs.h
+++ b/engines/mads/dialogs.h
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/dragonsphere/dragonsphere_scenes.cpp b/engines/mads/dragonsphere/dragonsphere_scenes.cpp
index f32d17d9c9..6f5a28bff9 100644
--- a/engines/mads/dragonsphere/dragonsphere_scenes.cpp
+++ b/engines/mads/dragonsphere/dragonsphere_scenes.cpp
@@ -8,12 +8,12 @@
* 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.
@@ -201,6 +201,10 @@ Common::String DragonsphereScene::formAnimName(char sepChar, int suffixNum) {
/*------------------------------------------------------------------------*/
void SceneInfoDragonsphere::loadCodes(MSurface &depthSurface, int variant) {
+ // The intro scenes do not have any codes
+ if (_sceneId >= 900)
+ return;
+
Common::String ext = Common::String::format(".WW%d", variant);
File f(Resources::formatName(RESPREFIX_RM, _sceneId, ext));
MadsPack codesPack(&f);
diff --git a/engines/mads/dragonsphere/dragonsphere_scenes.h b/engines/mads/dragonsphere/dragonsphere_scenes.h
index a6c778eca7..173cc667ce 100644
--- a/engines/mads/dragonsphere/dragonsphere_scenes.h
+++ b/engines/mads/dragonsphere/dragonsphere_scenes.h
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/dragonsphere/game_dragonsphere.cpp b/engines/mads/dragonsphere/game_dragonsphere.cpp
index 3836adb6d2..b07eab9daa 100644
--- a/engines/mads/dragonsphere/game_dragonsphere.cpp
+++ b/engines/mads/dragonsphere/game_dragonsphere.cpp
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/dragonsphere/game_dragonsphere.h b/engines/mads/dragonsphere/game_dragonsphere.h
index 7869dc87b4..b57f8833c6 100644
--- a/engines/mads/dragonsphere/game_dragonsphere.h
+++ b/engines/mads/dragonsphere/game_dragonsphere.h
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/events.cpp b/engines/mads/events.cpp
index de4dc3c070..7ba9098935 100644
--- a/engines/mads/events.cpp
+++ b/engines/mads/events.cpp
@@ -8,12 +8,12 @@
* 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.
@@ -41,10 +41,9 @@ EventsManager::EventsManager(MADSEngine *vm) {
_mouseReleased = false;
_mouseButtons = 0;
_mouseStatus = 0;
- _vD2 = 0;
+ _strokeGoing = 0;
_mouseStatusCopy = 0;
_mouseMoved = false;
- _vD8 = 0;
_rightMousePressed = false;
_eventTarget = nullptr;
}
@@ -85,8 +84,8 @@ void EventsManager::waitCursor() {
CursorType cursorId = (CursorType)MIN(_cursorSprites->getCount(), (int)CURSOR_WAIT);
_newCursorId = cursorId;
if (_cursorId != _newCursorId) {
- changeCursor();
_cursorId = _newCursorId;
+ changeCursor();
}
}
@@ -158,11 +157,17 @@ void EventsManager::pollEvents() {
_vm->_debugger->attach();
_vm->_debugger->onFrame();
} else {
- _pendingKeys.push(event);
+ _pendingKeys.push(event.kbd);
}
return;
case Common::EVENT_KEYUP:
return;
+ case Common::EVENT_WHEELUP:
+ _pendingKeys.push(Common::KeyState(Common::KEYCODE_PAGEUP));
+ return;
+ case Common::EVENT_WHEELDOWN:
+ _pendingKeys.push(Common::KeyState(Common::KEYCODE_PAGEDOWN));
+ return;
case Common::EVENT_LBUTTONDOWN:
case Common::EVENT_RBUTTONDOWN:
_mouseClicked = true;
@@ -261,7 +266,7 @@ void EventsManager::waitForNextFrame() {
void EventsManager::initVars() {
_mousePos = Common::Point(-1, -1);
_mouseStatusCopy = _mouseStatus;
- _vD2 = _vD8 = 0;
+ _strokeGoing = 0;
}
} // End of namespace MADS
diff --git a/engines/mads/events.h b/engines/mads/events.h
index 54df337efd..1a2579cae0 100644
--- a/engines/mads/events.h
+++ b/engines/mads/events.h
@@ -8,12 +8,12 @@
* 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.
@@ -67,11 +67,10 @@ public:
byte _mouseButtons;
bool _rightMousePressed;
int _mouseStatus;
- int _vD2;
+ int _strokeGoing;
int _mouseStatusCopy;
bool _mouseMoved;
- int _vD8;
- Common::Stack<Common::Event> _pendingKeys;
+ Common::Stack<Common::KeyState> _pendingKeys;
public:
/**
* Constructor
@@ -169,6 +168,8 @@ public:
* Returns true if there's any pending keys to be processed
*/
bool isKeyPressed() const { return !_pendingKeys.empty(); }
+
+ Common::KeyState getKey() { return _pendingKeys.pop(); }
};
} // End of namespace MADS
diff --git a/engines/mads/font.cpp b/engines/mads/font.cpp
index f7c1c52703..3e6d23fe6f 100644
--- a/engines/mads/font.cpp
+++ b/engines/mads/font.cpp
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/font.h b/engines/mads/font.h
index 47df647637..486cadcfff 100644
--- a/engines/mads/font.h
+++ b/engines/mads/font.h
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/game.cpp b/engines/mads/game.cpp
index 94653f9a39..91f6cd5630 100644
--- a/engines/mads/game.cpp
+++ b/engines/mads/game.cpp
@@ -8,12 +8,12 @@
* 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.
@@ -100,13 +100,12 @@ Game::~Game() {
}
delete _saveFile;
+ _surface->free();
delete _surface;
delete _sectionHandler;
}
void Game::run() {
- initializeGlobals();
-
// If requested, load a savegame instead of showing the intro
if (ConfMan.hasKey("save_slot")) {
int saveSlot = ConfMan.getInt("save_slot");
@@ -116,15 +115,17 @@ void Game::run() {
_statusFlag = true;
- if (_loadGameSlot == -1) {
- startGame();
- }
+ while (!_vm->shouldQuit()) {
+ if (_loadGameSlot == -1) {
+ startGame();
+ }
- // Get the initial starting time for the first scene
- _scene._frameStartTime = _vm->_events->getFrameCounter();
+ // Get the initial starting time for the first scene
+ _scene._frameStartTime = _vm->_events->getFrameCounter();
- if (!_vm->shouldQuit())
- gameLoop();
+ if (!_vm->shouldQuit())
+ gameLoop();
+ }
}
void Game::splitQuote(const Common::String &source, Common::String &line1, Common::String &line2) {
@@ -140,7 +141,7 @@ void Game::splitQuote(const Common::String &source, Common::String &line1, Commo
}
void Game::gameLoop() {
- while (!_vm->shouldQuit() && _statusFlag) {
+ while (!_vm->shouldQuit() && _statusFlag && !_winStatus) {
if (_loadGameSlot != -1) {
loadGame(_loadGameSlot);
_loadGameSlot = -1;
@@ -158,7 +159,7 @@ void Game::gameLoop() {
sectionLoop();
_player.releasePlayerSprites();
- assert(_scene._sprites._assetCount == 0);
+ assert(_scene._sprites.size() == 0);
_vm->_palette->unlock();
_vm->_events->waitCursor();
@@ -168,7 +169,8 @@ void Game::gameLoop() {
}
void Game::sectionLoop() {
- while (!_vm->shouldQuit() && _statusFlag && (_sectionNumber == _currentSectionNumber)) {
+ while (!_vm->shouldQuit() && _statusFlag && !_winStatus &&
+ (_sectionNumber == _currentSectionNumber)) {
_kernelMode = KERNEL_ROOM_PRELOAD;
_player._spritesChanged = true;
_quoteEmergency = false;
@@ -240,7 +242,7 @@ void Game::sectionLoop() {
_fx = kTransitionFadeOutIn;
break;
case SCREEN_FADE_FAST:
- _fx = kCenterVertTransition;
+ _fx = kNullPaletteCopy;
break;
default:
_fx = kTransitionNone;
@@ -324,7 +326,7 @@ void Game::initSection(int sectionNumber) {
_vm->_palette->resetGamePalette(18, 10);
_vm->_palette->setLowRange();
- if (_scene._layer == LAYER_GUI)
+ if (_scene._mode == SCREENMODE_VGA)
_vm->_palette->setPalette(_vm->_palette->_mainPalette, 0, 4);
_vm->_events->loadCursors("*CURSOR.SS");
@@ -403,12 +405,12 @@ Common::StringArray Game::getMessage(uint32 id) {
static const char *const DEBUG_STRING = "WIDEPIPE";
-void Game::handleKeypress(const Common::Event &event) {
- if (event.kbd.flags & Common::KBD_CTRL) {
+void Game::handleKeypress(const Common::KeyState &kbd) {
+ if (kbd.flags & Common::KBD_CTRL) {
if (_widepipeCtr == 8) {
// Implement original game cheating keys here someday
} else {
- if (event.kbd.keycode == (Common::KEYCODE_a +
+ if (kbd.keycode == (Common::KEYCODE_a +
(DEBUG_STRING[_widepipeCtr] - 'a'))) {
if (++_widepipeCtr == 8) {
MessageDialog *dlg = new MessageDialog(_vm, 2,
@@ -420,7 +422,8 @@ void Game::handleKeypress(const Common::Event &event) {
}
}
- switch (event.kbd.keycode) {
+ Scene &scene = _vm->_game->_scene;
+ switch (kbd.keycode) {
case Common::KEYCODE_F1:
_vm->_dialogs->_pendingDialog = DIALOG_GAME_MENU;
break;
@@ -430,6 +433,16 @@ void Game::handleKeypress(const Common::Event &event) {
case Common::KEYCODE_F7:
_vm->_dialogs->_pendingDialog = DIALOG_RESTORE;
break;
+ case Common::KEYCODE_PAGEUP:
+ scene._userInterface._scrollbarStrokeType = SCROLLBAR_UP;
+ scene._userInterface.changeScrollBar();
+ break;
+ case Common::KEYCODE_PAGEDOWN:
+ scene._userInterface._scrollbarStrokeType = SCROLLBAR_DOWN;
+ scene._userInterface.changeScrollBar();
+ break;
+
+
default:
break;
}
diff --git a/engines/mads/game.h b/engines/mads/game.h
index 1a61fc8ac8..95b54b0d1a 100644
--- a/engines/mads/game.h
+++ b/engines/mads/game.h
@@ -8,12 +8,12 @@
* 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.
@@ -195,6 +195,9 @@ public:
*/
virtual void synchronize(Common::Serializer &s, bool phase1);
+ virtual void setNaughtyMode(bool naughtyMode) {}
+ virtual bool getNaughtyMode() const { return true; }
+
// DEPRECATED: ScummVM re-implementation keeps all the quotes loaded, so the methods below are stubs
void clearQuotes() {}
void loadQuoteRange(int startNum, int endNum) {}
@@ -204,7 +207,7 @@ public:
/**
* Handle a keyboard event
*/
- void handleKeypress(const Common::Event &event);
+ void handleKeypress(const Common::KeyState &kbd);
/**
* Starts a savegame loading.
diff --git a/engines/mads/game_data.cpp b/engines/mads/game_data.cpp
index 70e9e6c30b..6421d057e8 100644
--- a/engines/mads/game_data.cpp
+++ b/engines/mads/game_data.cpp
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/game_data.h b/engines/mads/game_data.h
index 65a9ae1553..e9bf45d8a5 100644
--- a/engines/mads/game_data.h
+++ b/engines/mads/game_data.h
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/globals.cpp b/engines/mads/globals.cpp
index 1d088992ea..e4a681d551 100644
--- a/engines/mads/globals.cpp
+++ b/engines/mads/globals.cpp
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/globals.h b/engines/mads/globals.h
index a6c9b628dd..27553a2b06 100644
--- a/engines/mads/globals.h
+++ b/engines/mads/globals.h
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/hotspots.cpp b/engines/mads/hotspots.cpp
index d75d7ae13e..8afef2e524 100644
--- a/engines/mads/hotspots.cpp
+++ b/engines/mads/hotspots.cpp
@@ -8,12 +8,12 @@
* 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
+ * 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.
@@ -137,7 +137,7 @@ void DynamicHotspots::refresh() {
switch (scrObjects._inputMode) {
case kInputBuildingSentences:
case kInputLimitedSentences:
- scrObjects.add(dh._bounds, _vm->_game->_scene._layer, CAT_12, dh._descId);
+ scrObjects.add(dh._bounds, _vm->_game->_scene._mode, CAT_12, dh._descId);
scrObjects._forceRescan = true;
break;
default:
@@ -193,9 +193,8 @@ Hotspot::Hotspot(Common::SeekableReadStream &f, bool isV2) {
_active = f.readByte() != 0;
_cursor = (CursorType)f.readByte();
if (isV2) {
- // This looks to be some sort of bitmask. Perhaps it signifies
- // the valid verbs for this hotspot
- f.skip(2); // unknown
+ f.skip(1); // cursor
+ f.skip(1); // syntax
}
_vocabId = f.readUint16LE();
_verbId = f.readUint16LE();
diff --git a/engines/mads/hotspots.h b/engines/mads/hotspots.h
index f9334eace8..902275bb21 100644
--- a/engines/mads/hotspots.h
+++ b/engines/mads/hotspots.h
@@ -8,12 +8,12 @@
* 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
+ * 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.
diff --git a/engines/mads/inventory.cpp b/engines/mads/inventory.cpp
index ca05575ec5..fe1d24baea 100644
--- a/engines/mads/inventory.cpp
+++ b/engines/mads/inventory.cpp
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/inventory.h b/engines/mads/inventory.h
index cf82de59f1..2897f950e4 100644
--- a/engines/mads/inventory.h
+++ b/engines/mads/inventory.h
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/mads.cpp b/engines/mads/mads.cpp
index 52a0b40561..8c7b6b1ce3 100644
--- a/engines/mads/mads.cpp
+++ b/engines/mads/mads.cpp
@@ -8,12 +8,12 @@
* 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.
@@ -38,12 +38,13 @@ namespace MADS {
MADSEngine::MADSEngine(OSystem *syst, const MADSGameDescription *gameDesc) :
_gameDescription(gameDesc), Engine(syst), _randomSource("MADS") {
- // Initialize fields
+ // Initialize game/engine options
_easyMouse = true;
_invObjectsAnimated = true;
_textWindowStill = false;
_screenFade = SCREEN_FADE_SMOOTH;
_musicFlag = true;
+ _soundFlag = true;
_dithering = false;
_debugger = nullptr;
@@ -95,9 +96,63 @@ void MADSEngine::initialize() {
_audio = new AudioPlayer(_mixer, getGameID());
_game = Game::init(this);
+ loadOptions();
+
_screen.empty();
}
+void MADSEngine::loadOptions() {
+ if (ConfMan.hasKey("EasyMouse"))
+ _easyMouse = ConfMan.getBool("EasyMouse");
+
+ if (ConfMan.hasKey("mute") && ConfMan.getBool("mute")) {
+ _soundFlag = false;
+ _musicFlag = false;
+ } else {
+ _soundFlag = !ConfMan.hasKey("sfx_mute") || !ConfMan.getBool("sfx_mute");
+ _musicFlag = !ConfMan.hasGameDomain("music_mute") || !ConfMan.getBool("music_mute");
+ }
+
+ if (ConfMan.hasKey("ScreenFade"))
+ _screenFade = (ScreenFade)ConfMan.getInt("ScreenFade");
+ //if (ConfMan.hasKey("GraphicsDithering"))
+ // _dithering = ConfMan.getBool("GraphicsDithering");
+
+ if (getGameID() == GType_RexNebular) {
+ if (ConfMan.hasKey("InvObjectsAnimated"))
+ _invObjectsAnimated = ConfMan.getBool("InvObjectsAnimated");
+ if (ConfMan.hasKey("TextWindowStill"))
+ _textWindowStill = !ConfMan.getBool("TextWindowAnimated");
+ if (ConfMan.hasKey("NaughtyMode"))
+ _game->setNaughtyMode(ConfMan.getBool("NaughtyMode"));
+ }
+
+ // Note: MADS is weird in that sfx and music are handled by the same driver,
+ // and the game scripts themselves check for music being enabled before playing
+ // a "music" sound. Which means we can independantly mute music in ScummVM, but
+ // otherwise all sound, music and sfx, is controlled by the SFX volume slider.
+ int soundVolume = MIN(255, ConfMan.getInt("sfx_volume"));
+ _sound->setVolume(soundVolume);
+}
+
+void MADSEngine::saveOptions() {
+ ConfMan.setBool("EasyMouse", _easyMouse);
+ ConfMan.setInt("ScreenFade", (int)_screenFade);
+ //ConfMan.setBool("GraphicsDithering", _dithering);
+
+ ConfMan.setBool("mute", !_soundFlag && !_musicFlag);
+ ConfMan.setBool("sfx_mute", !_soundFlag && _musicFlag);
+ ConfMan.setBool("music_mute", _soundFlag && !_musicFlag);
+
+ if (getGameID() == GType_RexNebular) {
+ ConfMan.setBool("InvObjectsAnimated", _invObjectsAnimated);
+ ConfMan.setBool("TextWindowAnimated", !_textWindowStill);
+ ConfMan.setBool("NaughtyMode", _game->getNaughtyMode());
+ }
+
+ ConfMan.flushToDisk();
+}
+
Common::Error MADSEngine::run() {
initGraphics(MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT, false);
initialize();
@@ -134,6 +189,12 @@ bool MADSEngine::canSaveGameStateCurrently() {
&& _events->_cursorId != CURSOR_WAIT;
}
+void MADSEngine::syncSoundSettings() {
+ Engine::syncSoundSettings();
+
+ loadOptions();
+}
+
/**
* Support method that generates a savegame name
* @param slot Slot number
diff --git a/engines/mads/mads.h b/engines/mads/mads.h
index 9a8f2152a1..901035320a 100644
--- a/engines/mads/mads.h
+++ b/engines/mads/mads.h
@@ -8,12 +8,12 @@
* 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.
@@ -84,6 +84,8 @@ private:
* Handles basic initialisation
*/
void initialize();
+
+ void loadOptions();
protected:
// Engine APIs
virtual Common::Error run();
@@ -104,6 +106,7 @@ public:
bool _textWindowStill;
ScreenFade _screenFade;
bool _musicFlag;
+ bool _soundFlag;
bool _dithering;
public:
MADSEngine(OSystem *syst, const MADSGameDescription *gameDesc);
@@ -145,6 +148,13 @@ public:
* Handles saving the game via the GMM
*/
virtual Common::Error saveGameState(int slot, const Common::String &desc);
+
+ /**
+ * Handles updating sound settings after they're changed in the GMM dialog
+ */
+ virtual void syncSoundSettings();
+
+ void saveOptions();
};
} // End of namespace MADS
diff --git a/engines/mads/menu_views.cpp b/engines/mads/menu_views.cpp
index ee4268a650..cfc3b09461 100644
--- a/engines/mads/menu_views.cpp
+++ b/engines/mads/menu_views.cpp
@@ -8,12 +8,12 @@
* 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.
@@ -426,7 +426,7 @@ void TextView::doFrame() {
scene._textDisplay.expire(tl._textDisplayIndex);
tl._pos.y--;
- if (tl._pos.y < 0) {
+ if (tl._pos.y + _font->getHeight() < 0) {
_textLines.remove_at(i);
} else {
tl._textDisplayIndex = scene._textDisplay.add(tl._pos.x, tl._pos.y,
@@ -484,6 +484,7 @@ AnimationView::AnimationView(MADSEngine *vm) : MenuView(vm) {
_animFrameNumber = 0;
_nextCyclingActive = false;
_sceneInfo = SceneInfo::init(_vm);
+ _scrollFrameCtr = 0;
load();
}
@@ -543,16 +544,26 @@ void AnimationView::doFrame() {
scriptDone();
} else {
scene._frameStartTime = 0;
+ scene._spriteSlots.clear();
loadNextResource();
}
} else if (_currentAnimation->getCurrentFrame() == 1) {
scene._cyclingActive = _nextCyclingActive;
}
+ if (_currentAnimation && (++_scrollFrameCtr >= _currentAnimation->_header._scrollTicks)) {
+ _scrollFrameCtr = 0;
+ scroll();
+ }
+
if (_currentAnimation) {
++scene._frameStartTime;
_currentAnimation->update();
_redrawFlag = true;
+
+ if (_currentAnimation->freeFlag())
+ // We don't want the sprites removed after the last animation frame
+ scene._spriteSlots.clear();
}
}
@@ -636,6 +647,21 @@ void AnimationView::loadNextResource() {
scene.initPaletteAnimation(paletteCycles, _nextCyclingActive && !_vm->_game->_fx);
}
+void AnimationView::scroll() {
+ Scene &scene = _vm->_game->_scene;
+ Common::Point pt = _currentAnimation->_header._scrollPosition;
+
+ if (pt.x != 0) {
+ scene._backgroundSurface.scrollX(pt.x);
+ scene._spriteSlots.fullRefresh();
+ }
+
+ if (pt.y != 0) {
+ scene._backgroundSurface.scrollY(pt.y);
+ scene._spriteSlots.fullRefresh();
+ }
+}
+
void AnimationView::scriptDone() {
_breakFlag = true;
_vm->_dialogs->_pendingDialog = DIALOG_MAIN_MENU;
@@ -657,6 +683,10 @@ void AnimationView::processLines() {
_currentLine += c;
}
+ // Check for comment line
+ if (_currentLine.hasPrefix("#"))
+ continue;
+
// Process the line
while (!_currentLine.empty()) {
if (_currentLine.hasPrefix("-")) {
diff --git a/engines/mads/menu_views.h b/engines/mads/menu_views.h
index cc5a13006f..6c8a2a8bdd 100644
--- a/engines/mads/menu_views.h
+++ b/engines/mads/menu_views.h
@@ -8,12 +8,12 @@
* 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.
@@ -191,6 +191,7 @@ private:
int _manualFrame2;
int _animFrameNumber;
bool _nextCyclingActive;
+ uint _scrollFrameCtr;
private:
void load();
@@ -201,6 +202,8 @@ private:
int getParameter();
void loadNextResource();
+
+ void scroll();
protected:
virtual void display();
diff --git a/engines/mads/messages.cpp b/engines/mads/messages.cpp
index e83b69d210..d88806150d 100644
--- a/engines/mads/messages.cpp
+++ b/engines/mads/messages.cpp
@@ -8,12 +8,12 @@
* 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.
@@ -69,7 +69,7 @@ void KernelMessages::clear() {
}
int KernelMessages::add(const Common::Point &pt, uint fontColor, uint8 flags,
- uint8 abortTimers, uint32 timeout, const Common::String &msg) {
+ int endTrigger, uint32 timeout, const Common::String &msg) {
Scene &scene = _vm->_game->_scene;
// Find a free slot
@@ -77,7 +77,7 @@ int KernelMessages::add(const Common::Point &pt, uint fontColor, uint8 flags,
while ((idx < _entries.size()) && ((_entries[idx]._flags & KMSG_ACTIVE) != 0))
++idx;
if (idx == _entries.size()) {
- if (abortTimers == 0)
+ if (endTrigger == 0)
return -1;
error("KernelMessages overflow");
@@ -91,8 +91,8 @@ int KernelMessages::add(const Common::Point &pt, uint fontColor, uint8 flags,
rec._position = pt;
rec._textDisplayIndex = -1;
rec._timeout = timeout;
- rec._frameTimer = _vm->_game->_priorFrameTimer;
- rec._trigger = abortTimers;
+ rec._frameTimer = scene._frameStartTime;
+ rec._trigger = endTrigger;
rec._abortMode = _vm->_game->_triggerSetupMode;
rec._actionDetails = scene._action._activeAction;
@@ -104,10 +104,10 @@ int KernelMessages::add(const Common::Point &pt, uint fontColor, uint8 flags,
return idx;
}
-int KernelMessages::addQuote(int quoteId, int abortTimers, uint32 timeout) {
+int KernelMessages::addQuote(int quoteId, int endTrigger, uint32 timeout) {
Common::String quoteStr = _vm->_game->getQuote(quoteId);
return add(Common::Point(), 0x1110, KMSG_PLAYER_TIMEOUT | KMSG_CENTER_ALIGN,
- abortTimers, timeout, quoteStr);
+ endTrigger, timeout, quoteStr);
}
void KernelMessages::scrollMessage(int msgIndex, int numTicks, bool quoted) {
@@ -162,8 +162,10 @@ void KernelMessages::update() {
uint32 currentTimer = _vm->_game->_scene._frameStartTime;
for (uint i = 0; i < _entries.size() && !_vm->_game->_trigger; ++i) {
- KernelMessage &msg = _entries[i];
+ if (_vm->_game->_trigger)
+ break;
+ KernelMessage &msg = _entries[i];
if (((msg._flags & KMSG_ACTIVE) != 0) && (currentTimer >= msg._frameTimer))
processText(i);
}
@@ -172,7 +174,7 @@ void KernelMessages::update() {
void KernelMessages::processText(int msgIndex) {
Scene &scene = _vm->_game->_scene;
KernelMessage &msg = _entries[msgIndex];
- uint32 currentTimer = _vm->_game->_priorFrameTimer;
+ uint32 currentTimer = scene._frameStartTime;
bool flag = false;
if ((msg._flags & KMSG_EXPIRE) != 0) {
diff --git a/engines/mads/messages.h b/engines/mads/messages.h
index a7411d98d1..764477a7fc 100644
--- a/engines/mads/messages.h
+++ b/engines/mads/messages.h
@@ -8,12 +8,12 @@
* 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.
@@ -99,9 +99,9 @@ public:
~KernelMessages();
void clear();
- int add(const Common::Point &pt, uint fontColor, uint8 flags, uint8 abortTimers,
+ int add(const Common::Point &pt, uint fontColor, uint8 flags, int endTrigger,
uint32 timeout, const Common::String &msg);
- int addQuote(int quoteId, int abortTimers, uint32 timeout);
+ int addQuote(int quoteId, int endTrigger, uint32 timeout);
void scrollMessage(int msgIndex, int numTicks, bool quoted);
void setSeqIndex(int msgIndex, int seqIndex);
void remove(int msgIndex);
diff --git a/engines/mads/module.mk b/engines/mads/module.mk
index fc04a2f8ba..7cb7a91e8c 100644
--- a/engines/mads/module.mk
+++ b/engines/mads/module.mk
@@ -4,7 +4,9 @@ MODULE_OBJS := \
dragonsphere/game_dragonsphere.o \
dragonsphere/dragonsphere_scenes.o \
phantom/game_phantom.o \
+ phantom/globals_phantom.o \
phantom/phantom_scenes.o \
+ phantom/phantom_scenes1.o \
nebular/dialogs_nebular.o \
nebular/game_nebular.o \
nebular/globals_nebular.o \
diff --git a/engines/mads/msurface.cpp b/engines/mads/msurface.cpp
index 39824bac4b..f768624278 100644
--- a/engines/mads/msurface.cpp
+++ b/engines/mads/msurface.cpp
@@ -8,12 +8,12 @@
* 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.
@@ -308,6 +308,9 @@ void MSurface::copyFrom(MSurface *src, const Common::Point &destPos, int depth,
if (!copyRect.isValidRect())
return;
+ if (flipped)
+ copyRect.moveTo(0, copyRect.top);
+
byte *data = src->getData();
byte *srcPtr = data + (src->getWidth() * copyRect.top + copyRect.left);
byte *destPtr = (byte *)pixels + (destY * pitch) + destX;
@@ -397,14 +400,16 @@ void MSurface::copyFrom(MSurface *src, const Common::Point &destPos, int depth,
const byte *srcP = srcPixelsP;
byte *destP = destPixelsP;
- for (int xp = 0, sprX = 0; xp < frameWidth; ++xp, ++srcP) {
- if (xp < spriteLeft)
- // Not yet reached start of display area
- continue;
- if (!lineDist[sprX++])
+ for (int xp = 0, sprX = -1; xp < frameWidth; ++xp, ++srcP) {
+ if (!lineDist[xp])
// Not a display pixel
continue;
+ ++sprX;
+ if (sprX < spriteLeft || sprX >= spriteRight)
+ // Skip pixel if it's not in horizontal display portion
+ continue;
+
// Get depth of current output pixel in depth surface
Common::Point pt((destP - (byte *)this->pixels) % this->pitch,
(destP - (byte *)this->pixels) / this->pitch);
@@ -485,7 +490,6 @@ void MSurface::scrollY(int yAmount) {
delete[] tempData;
}
-
void MSurface::translate(Common::Array<RGB6> &palette) {
for (int y = 0; y < this->h; ++y) {
byte *pDest = getBasePtr(0, y);
@@ -521,6 +525,20 @@ MSurface *MSurface::flipHorizontal() const {
return dest;
}
+void MSurface::copyRectTranslate(MSurface &srcSurface, const byte *paletteMap,
+ const Common::Point &destPos, const Common::Rect &srcRect) {
+ // Loop through the lines
+ for (int yCtr = 0; yCtr < srcRect.height(); ++yCtr) {
+ const byte *srcP = srcSurface.getBasePtr(srcRect.left, srcRect.top + yCtr);
+ byte *destP = getBasePtr(destPos.x, destPos.y + yCtr);
+
+ // Copy the line over
+ for (int xCtr = 0; xCtr < srcRect.width(); ++xCtr, ++srcP, ++destP) {
+ *destP = paletteMap[*srcP];
+ }
+ }
+}
+
/*------------------------------------------------------------------------*/
int DepthSurface::getDepth(const Common::Point &pt) {
diff --git a/engines/mads/msurface.h b/engines/mads/msurface.h
index 650d7fdaee..80891afb83 100644
--- a/engines/mads/msurface.h
+++ b/engines/mads/msurface.h
@@ -8,12 +8,12 @@
* 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.
@@ -220,6 +220,13 @@ public:
* Create a new surface which is a flipped horizontal copy of the current one
*/
MSurface *flipHorizontal() const;
+
+ /**
+ * Copy an area from one surface to another, translating it using a palette
+ * map as it's done
+ */
+ void copyRectTranslate(MSurface &srcSurface, const byte *paletteMap,
+ const Common::Point &destPos, const Common::Rect &srcRect);
};
class DepthSurface : public MSurface {
diff --git a/engines/mads/nebular/dialogs_nebular.cpp b/engines/mads/nebular/dialogs_nebular.cpp
index f5355517bd..960a2cc2f4 100644
--- a/engines/mads/nebular/dialogs_nebular.cpp
+++ b/engines/mads/nebular/dialogs_nebular.cpp
@@ -8,12 +8,12 @@
* 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.
@@ -91,6 +91,8 @@ bool DialogsNebular::show(int messageId, int objectId) {
dialog->incNumLines();
}
} else if (commandCheck("ASK", valStr, commandText)) {
+ if (!dialog)
+ error("DialogsNebular::show - Uninitialized dialog");
dialog->addInput();
} else if (commandCheck("VERB", valStr, commandText)) {
dialogText += getVocab(action._activeAction._verbId);
@@ -114,12 +116,18 @@ bool DialogsNebular::show(int messageId, int objectId) {
} else if (commandCheck("WIDTH", valStr, commandText)) {
_dialogWidth = atoi(valStr.c_str());
} else if (commandCheck("BAR", valStr, commandText)) {
+ if (!dialog)
+ error("DialogsNebular::show - Uninitialized dialog");
dialog->addBarLine();
} else if (commandCheck("UNDER", valStr, commandText)) {
underlineFlag = true;
} else if (commandCheck("DOWN", valStr, commandText)) {
+ if (!dialog)
+ error("DialogsNebular::show - Uninitialized dialog");
dialog->downPixelLine();
} else if (commandCheck("TAB", valStr, commandText)) {
+ if (!dialog)
+ error("DialogsNebular::show - Uninitialized dialog");
int xp = atoi(valStr.c_str());
dialog->setLineXp(xp);
}
@@ -164,6 +172,9 @@ bool DialogsNebular::show(int messageId, int objectId) {
if (!centerFlag)
dialog->incNumLines();
+ if (!dialog)
+ error("DialogsNebular::show - Uninitialized dialog");
+
// Show the dialog
_vm->_events->setCursor(CURSOR_ARROW);
dialog->show();
@@ -317,7 +328,7 @@ void DialogsNebular::showDialog() {
TextView *dlg = new RexTextView(_vm);
dlg->show();
delete dlg;
- break;
+ return;
}
case DIALOG_ANIMVIEW: {
AnimationView *dlg = new RexAnimationView(_vm);
@@ -333,7 +344,7 @@ void DialogsNebular::showDialog() {
void DialogsNebular::showScummVMSaveDialog() {
Nebular::GameNebular &game = *(Nebular::GameNebular *)_vm->_game;
- Scene *scene = &(game._scene);
+ Scene &scene = game._scene;
GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true);
int slot = dialog->runModalWithCurrentTarget();
@@ -345,24 +356,31 @@ void DialogsNebular::showScummVMSaveDialog() {
desc = dialog->createDefaultSaveDescription(slot);
}
- scene->_spriteSlots.reset();
- scene->loadScene(scene->_currentSceneId, game._aaName, true);
- scene->_userInterface.noInventoryAnim();
+ scene._spriteSlots.reset();
+ scene.loadScene(scene._currentSceneId, game._aaName, true);
+ scene._userInterface.noInventoryAnim();
game._scene.drawElements(kTransitionFadeIn, false);
game.saveGame(slot, desc);
}
+
+ // Flag for scene loading that we're returning from a dialog
+ scene._currentSceneId = RETURNING_FROM_DIALOG;
}
void DialogsNebular::showScummVMRestoreDialog() {
Nebular::GameNebular &game = *(Nebular::GameNebular *)_vm->_game;
GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false);
+ Scene &scene = game._scene;
int slot = dialog->runModalWithCurrentTarget();
if (slot >= 0) {
game._loadGameSlot = slot;
- game._scene._currentSceneId = -1;
+ game._scene._currentSceneId = RETURNING_FROM_LOADING;
game._currentSectionNumber = -1;
+ } else {
+ // Flag for scene loading that we're returning from a dialog
+ scene._currentSceneId = RETURNING_FROM_DIALOG;
}
}
@@ -376,8 +394,7 @@ TextDialog(vm, FONT_INTERFACE, Common::Point(-1, -1), 32) {
addLine("ANSWER INCORRECT!", true);
wordWrap("\n");
addLine("(But we'll give you another chance!)");
- }
- else {
+ } else {
addLine("REX NEBULAR version 8.43", true);
wordWrap("\n");
addLine("(Copy Protection, for your convenience)");
@@ -400,7 +417,7 @@ TextDialog(vm, FONT_INTERFACE, Common::Point(-1, -1), 32) {
_hogEntry._pageNum, _hogEntry._lineNum, _hogEntry._wordNum);
wordWrap(line);
- wordWrap("and type it on the line below (we',27h,'ve even given you");
+ wordWrap("and type it on the line below (we've even given you");
wordWrap("first letter as a hint). As soon as you do that, we can get");
wordWrap("right into this really COOL adventure game!\n");
wordWrap("\n");
@@ -411,17 +428,58 @@ TextDialog(vm, FONT_INTERFACE, Common::Point(-1, -1), 32) {
void CopyProtectionDialog::show() {
draw();
- _vm->_events->showCursor();
- // TODO: Replace with text input
- while (!_vm->shouldQuit() && !_vm->_events->isKeyPressed() &&
- !_vm->_events->_mouseClicked) {
- _vm->_events->delay(1);
+ Common::KeyState curKey;
+ const Common::Rect inputArea(110, 165, 210, 175);
+ MSurface *origInput = new MSurface(inputArea.width(), inputArea.height());
+ _vm->_screen.frameRect(inputArea, TEXTDIALOG_BLACK);
+ _vm->_screen.copyTo(origInput, inputArea, Common::Point(0, 0));
+ _font->setColors(TEXTDIALOG_FE, TEXTDIALOG_FE, TEXTDIALOG_FE, TEXTDIALOG_FE);
+ _vm->_screen.copyRectToScreen(inputArea);
+ _vm->_screen.updateScreen();
+
+ bool firstTime = true;
+
+ while (!_vm->shouldQuit()) {
+ if (!firstTime) {
+ while (!_vm->shouldQuit() && !_vm->_events->isKeyPressed()) {
+ _vm->_events->delay(1);
+ }
+
+ if (_vm->shouldQuit())
+ break;
+
+ curKey = _vm->_events->getKey();
+
+ if (curKey.keycode == Common::KEYCODE_RETURN || curKey.keycode == Common::KEYCODE_KP_ENTER)
+ break;
+ else if (curKey.keycode == Common::KEYCODE_BACKSPACE)
+ _textInput.deleteLastChar();
+ else if (_textInput.size() < 14)
+ _textInput += curKey.ascii;
+
+ _vm->_events->_pendingKeys.clear();
+ } else {
+ firstTime = false;
+ _textInput = _hogEntry._word[0];
+ }
+
+ _vm->_screen.copyFrom(origInput, Common::Rect(0, 0, inputArea.width(), inputArea.height()), Common::Point(inputArea.left, inputArea.top));
+ _font->writeString(&_vm->_screen, _textInput,
+ Common::Point(inputArea.left + 2, inputArea.top + 1), 1);
+ _vm->_screen.copyRectToScreen(inputArea);
+ _vm->_screen.updateScreen();
}
- _vm->_events->_pendingKeys.clear();
+ origInput->free();
+ delete origInput;
+}
+
+bool CopyProtectionDialog::isCorrectAnswer() {
+ return _hogEntry._word == _textInput;
}
+
bool CopyProtectionDialog::getHogAnusEntry(HOGANUS &entry) {
File f;
f.open("*HOGANUS.DAT");
@@ -535,6 +593,7 @@ void PictureDialog::save() {
void PictureDialog::restore() {
if (_savedSurface) {
_savedSurface->copyTo(&_vm->_screen);
+ _savedSurface->free();
delete _savedSurface;
_savedSurface = nullptr;
@@ -602,9 +661,12 @@ GameDialog::GameDialog(MADSEngine *vm) : FullScreenDialog(vm) {
}
void GameDialog::display() {
+ Palette &palette = *_vm->_palette;
+ palette.initPalette();
+ palette.resetGamePalette(18, 10);
+
FullScreenDialog::display();
- Palette &palette = *_vm->_palette;
palette.setEntry(10, 0, 63, 0);
palette.setEntry(11, 0, 45, 0);
palette.setEntry(12, 63, 63, 0);
@@ -624,6 +686,7 @@ void GameDialog::display() {
GameDialog::~GameDialog() {
_vm->_screen.resetClipBounds();
+ _vm->_game->_scene._currentSceneId = RETURNING_FROM_DIALOG;
}
void GameDialog::clearLines() {
@@ -643,14 +706,14 @@ void GameDialog::setClickableLines() {
int maxHeight = _lines[idx]._font->getHeight();
screenObjects.add(Common::Rect(pt.x, pt.y, pt.x + strWidth, pt.y + maxHeight - 1),
- LAYER_GUI, CAT_COMMAND, idx);
+ SCREENMODE_VGA, CAT_COMMAND, idx);
}
}
if (_vm->_dialogs->_pendingDialog == DIALOG_SAVE ||
_vm->_dialogs->_pendingDialog == DIALOG_RESTORE) {
- screenObjects.add(Common::Rect(293, 26, 312, 75), LAYER_GUI, CAT_INV_LIST, 50);
- screenObjects.add(Common::Rect(293, 78, 312, 127), LAYER_GUI, CAT_INV_LIST, 51);
+ screenObjects.add(Common::Rect(293, 26, 312, 75), SCREENMODE_VGA, CAT_INV_LIST, 50);
+ screenObjects.add(Common::Rect(293, 78, 312, 127), SCREENMODE_VGA, CAT_INV_LIST, 51);
}
}
@@ -794,7 +857,7 @@ void GameDialog::show() {
Scene &scene = _vm->_game->_scene;
- while (_selectedLine < 1 && !_vm->shouldQuit()) {
+ while (_selectedLine == -1 && !_vm->shouldQuit()) {
handleEvents();
if (_redrawFlag) {
if (!_tempLine)
@@ -821,11 +884,21 @@ void GameDialog::handleEvents() {
_lines[i]._state = DLGSTATE_UNSELECTED;
// Process pending events
- _vm->_events->pollEvents();
+ events.pollEvents();
+
+ if (events.isKeyPressed()) {
+ switch (events.getKey().keycode) {
+ case Common::KEYCODE_ESCAPE:
+ _selectedLine = 0;
+ break;
+ default:
+ break;
+ }
+ }
// Scan for objects in the dialog
Common::Point mousePos = events.currentPos() - Common::Point(0, DIALOG_TOP);
- int objIndex = screenObjects.scan(mousePos, LAYER_GUI);
+ int objIndex = screenObjects.scan(mousePos, SCREENMODE_VGA);
if (_movedFlag) {
int yp = mousePos.y;
@@ -1000,12 +1073,13 @@ void GameMenuDialog::show() {
_vm->_dialogs->_pendingDialog = DIALOG_OPTIONS;
_vm->_dialogs->showDialog();
break;
+ case 5:
+ _vm->quitGame();
+ break;
case 4:
+ default:
// Resume game
break;
- case 5:
- default:
- _vm->quitGame();
}
}
@@ -1018,12 +1092,11 @@ OptionsDialog::OptionsDialog(MADSEngine *vm) : GameDialog(vm) {
int OptionsDialog::getOptionQuote(int option) {
Nebular::GameNebular &game = *(Nebular::GameNebular *)_vm->_game;
- // TODO: Hook the rest of the options to the current config
switch (option) {
case 17: // Music
- return 24; // 24: ON, 25: OFF
+ return _vm->_musicFlag ? 24 : 25; // 24: ON, 25: OFF
case 18: // Sound
- return 26; // 26: ON, 27: OFF
+ return _vm->_soundFlag ? 26 : 27; // 26: ON, 27: OFF
case 19: // Interface
return !_vm->_easyMouse ? 28 : 29; // 28: Standard, 29: Easy
case 20: // Inventory
@@ -1066,6 +1139,7 @@ void OptionsDialog::show() {
Nebular::GameNebular &game = *(Nebular::GameNebular *)_vm->_game;
// Previous options, restored when cancel is selected
+ bool prevMusicFlag = _vm->_musicFlag;
bool prevEasyMouse = _vm->_easyMouse;
bool prevInvObjectsAnimated = _vm->_invObjectsAnimated;
bool prevTextWindowStill = _vm->_textWindowStill;
@@ -1073,15 +1147,15 @@ void OptionsDialog::show() {
StoryMode prevStoryMode = game._storyMode;
do {
- _selectedLine = 0;
+ _selectedLine = -1;
GameDialog::show();
switch (_selectedLine) {
case 1: // Music
- warning("STUB: Music toggle");
+ _vm->_musicFlag = _vm->_soundFlag = !_vm->_musicFlag;
break;
case 2: // Sound
- warning("STUB: Sound toggle");
+ _vm->_musicFlag = _vm->_soundFlag = !_vm->_musicFlag;
break;
case 3: // Interface
_vm->_easyMouse = !_vm->_easyMouse;
@@ -1110,24 +1184,22 @@ void OptionsDialog::show() {
// Reload menu
_lineIndex = -1;
clearLines();
+ _vm->_game->_screenObjects.clear();
+ _vm->_game->_scene._spriteSlots.reset();
setLines();
- setClickableLines();
- } while (_selectedLine <= 7);
-
- switch (_selectedLine) {
- case 8: // Done
- // New options will be applied
- break;
- case 9: // Cancel
- // Revert all options from the saved ones
+ } while (!_vm->shouldQuit() && _selectedLine != 0 && _selectedLine <= 7);
+
+ if (_selectedLine == 8) {
+ // OK button, save settings
+ _vm->saveOptions();
+ } else if (_selectedLine == 9) {
+ // Cancel button, revert all options from the saved ones
+ _vm->_musicFlag = _vm->_soundFlag = prevMusicFlag;
_vm->_easyMouse = prevEasyMouse;
_vm->_invObjectsAnimated = prevInvObjectsAnimated;
_vm->_textWindowStill = prevTextWindowStill;
_vm->_screenFade = prevScreenFade;
game._storyMode = prevStoryMode;
- break;
- default:
- break;
}
}
diff --git a/engines/mads/nebular/dialogs_nebular.h b/engines/mads/nebular/dialogs_nebular.h
index 5dbe4da6f0..4935ee4b8c 100644
--- a/engines/mads/nebular/dialogs_nebular.h
+++ b/engines/mads/nebular/dialogs_nebular.h
@@ -8,12 +8,12 @@
* 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.
@@ -69,6 +69,7 @@ struct HOGANUS {
class CopyProtectionDialog : public TextDialog {
private:
HOGANUS _hogEntry;
+ Common::String _textInput;
/**
* Get a random copy protection entry from the HOGANUS resource
@@ -84,6 +85,8 @@ public:
* Show the dialog
*/
virtual void show();
+
+ bool isCorrectAnswer();
};
class PictureDialog : public TextDialog {
diff --git a/engines/mads/nebular/game_nebular.cpp b/engines/mads/nebular/game_nebular.cpp
index fd669bc5cf..e8e0a4f42c 100644
--- a/engines/mads/nebular/game_nebular.cpp
+++ b/engines/mads/nebular/game_nebular.cpp
@@ -8,12 +8,12 @@
* 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.
@@ -45,30 +45,86 @@ GameNebular::GameNebular(MADSEngine *vm)
}
ProtectionResult GameNebular::checkCopyProtection() {
- /*
- // DEBUG: Flag copy protection failure
- _globals[kCopyProtectFailed] = -1;
+ //if (!ConfMan.getBool("copy_protection"))
+ // return PROTECTION_SUCCEED;
- if (!ConfMan.getBool("copy_protection"))
- return true;
+ CopyProtectionDialog *dlg;
+ bool correctAnswer;
- * DEBUG: Disabled for now
- CopyProtectionDialog *dlg = new CopyProtectionDialog(_vm, false);
+ dlg = new CopyProtectionDialog(_vm, false);
dlg->show();
+ correctAnswer = dlg->isCorrectAnswer();
delete dlg;
- */
- return PROTECTION_SUCCEED;
+
+ if (!correctAnswer && !_vm->shouldQuit()) {
+ dlg = new CopyProtectionDialog(_vm, true);
+ dlg->show();
+ correctAnswer = dlg->isCorrectAnswer();
+ delete dlg;
+ }
+
+ return correctAnswer ? PROTECTION_SUCCEED : PROTECTION_FAIL;
}
void GameNebular::startGame() {
- /*
+ // First handle any ending credits from a just finished game session.
+ // Note that, with the exception of the decompression ending, which doesn't
+ // use animations, the remaining animations will automatically launch their
+ // own text view credits when the animation is completed
+ switch (_winStatus) {
+ case 1:
+ // No shields failure ending
+ AnimationView::execute(_vm, "rexend1");
+ break;
+ case 2:
+ // Shields, but no targetting failure ending
+ AnimationView::execute(_vm, "rexend2");
+ break;
+ case 3:
+ // Completed game successfully, so activate quotes item on the main menu
+ ConfMan.setBool("ShowQuotes", true);
+ ConfMan.flushToDisk();
+
+ AnimationView::execute(_vm, "rexend3");
+ break;
+ case 4:
+ // Decompression ending
+ TextView::execute(_vm, "ending4");
+ break;
+ }
+
+ do {
+ checkShowDialog();
+ _winStatus = 0;
+
+ _sectionNumber = 1;
+ initSection(_sectionNumber);
+ _vm->_events->setCursor(CURSOR_ARROW);
+ _statusFlag = true;
+
+ // Show the main menu
+ _vm->_dialogs->_pendingDialog = DIALOG_MAIN_MENU;
+ _vm->_dialogs->showDialog();
+ } while (!_vm->shouldQuit() && _vm->_dialogs->_pendingDialog != DIALOG_NONE);
+
+ if (_vm->shouldQuit())
+ return;
+
+ _priorSectionNumber = 0;
+ _priorSectionNumber = -1;
+ _scene._priorSceneId = 0;
+ _scene._currentSceneId = -1;
+ _scene._nextSceneId = 101;
+
+ initializeGlobals();
+
// Check copy protection
ProtectionResult protectionResult = checkCopyProtection();
+
switch (protectionResult) {
case PROTECTION_FAIL:
// Copy protection failed
_scene._nextSceneId = 804;
- initializeGlobals();
_globals[kCopyProtectFailed] = true;
return;
case PROTECTION_ESCAPE:
@@ -79,23 +135,6 @@ void GameNebular::startGame() {
// Copy protection check succeeded
break;
}
- */
-
- initSection(_sectionNumber);
- _statusFlag = true;
-
- // Show the main menu
- _vm->_dialogs->_pendingDialog = DIALOG_MAIN_MENU;
- _vm->_dialogs->showDialog();
- _vm->_dialogs->_pendingDialog = DIALOG_NONE;
-
- _priorSectionNumber = 0;
- _priorSectionNumber = -1;
- _scene._priorSceneId = 0;
- _scene._currentSceneId = -1;
- _scene._nextSceneId = 101;
-
- initializeGlobals();
}
void GameNebular::initializeGlobals() {
@@ -245,10 +284,12 @@ void GameNebular::initializeGlobals() {
// Final setup based on selected difficulty level
switch (_difficulty) {
case DIFFICULTY_HARD:
- _objects.setRoom(OBJ_PLANT_STALK, NOWHERE);
- _objects.setRoom(OBJ_PENLIGHT, NOWHERE);
+ _objects.setRoom(OBJ_BLOWGUN, NOWHERE);
+ _objects.setRoom(OBJ_NOTE, NOWHERE);
- _globals[kLeavesStatus] = LEAVES_ON_TRAP;
+ _globals[kLeavesStatus] = LEAVES_ON_GROUND;
+ _globals[kDurafailRecharged] = 0;
+ _globals[kPenlightCellStatus] = FIRST_TIME_UNCHARGED_DURAFAIL;
break;
case DIFFICULTY_MEDIUM:
@@ -260,12 +301,10 @@ void GameNebular::initializeGlobals() {
break;
case DIFFICULTY_EASY:
- _objects.setRoom(OBJ_BLOWGUN, NOWHERE);
- _objects.setRoom(OBJ_NOTE, NOWHERE);
+ _objects.setRoom(OBJ_PLANT_STALK, NOWHERE);
+ _objects.setRoom(OBJ_PENLIGHT, NOWHERE);
- _globals[kLeavesStatus] = LEAVES_ON_GROUND;
- _globals[kPenlightCellStatus] = FIRST_TIME_UNCHARGED_DURAFAIL;
- _globals[kDurafailRecharged] = 0;
+ _globals[kLeavesStatus] = LEAVES_ON_TRAP;
break;
}
@@ -310,32 +349,9 @@ void GameNebular::setSectionHandler() {
}
void GameNebular::checkShowDialog() {
- // Handling to start endgame sequences if the win/lose type has been set
- switch (_winStatus) {
- case 1:
- // No shields failure ending
- AnimationView::execute(_vm, "rexend1");
- break;
- case 2:
- // Shields, but no targetting failure ending
- AnimationView::execute(_vm, "rexend2");
- break;
- case 3:
- // Completed game successfully, so activate quotes item on the main menu
- ConfMan.setBool("ShowQuotes", true);
- ConfMan.flushToDisk();
-
- AnimationView::execute(_vm, "rexend3");
- break;
- case 4:
- // Decompression ending
- TextView::execute(_vm, "ending4");
- break;
- }
- _winStatus = 0;
-
// Loop for showing dialogs, if any need to be shown
- if (_vm->_dialogs->_pendingDialog && _player._stepEnabled && !_globals[kCopyProtectFailed]) {
+ if (_vm->_dialogs->_pendingDialog && (_player._stepEnabled || _winStatus)
+ && !_globals[kCopyProtectFailed]) {
_player.releasePlayerSprites();
// Make a thumbnail in case it's needed for making a savegame
@@ -454,7 +470,7 @@ void GameNebular::doObjectAction() {
dialogs.show(464);
} else if (action.isAction(VERB_REFLECT)) {
dialogs.show(466);
- } else if (action.isAction(VERB_GAZE_INTO, NOUN_REARVIEW_MIRROR)) {
+ } else if (action.isAction(VERB_GAZE_INTO, NOUN_REARVIEW_MIRROR)) {
dialogs.show(467);
} else if (action.isAction(VERB_EAT, NOUN_CHICKEN_BOMB)) {
dialogs.show(469);
@@ -810,7 +826,7 @@ void GameNebular::step() {
(_player._facing == _player._turnToFacing)) {
if (_scene._frameStartTime >= *((uint32 *)&_globals[kWalkerTiming])) {
if (!_player._stopWalkerIndex) {
- int randomVal = _vm->getRandomNumber(29999);;
+ int randomVal = _vm->getRandomNumber(29999);
if (_globals[kSexOfRex] == REX_MALE) {
switch (_player._facing) {
case FACING_SOUTHWEST:
diff --git a/engines/mads/nebular/game_nebular.h b/engines/mads/nebular/game_nebular.h
index efa21a2e73..3cf7aefc18 100644
--- a/engines/mads/nebular/game_nebular.h
+++ b/engines/mads/nebular/game_nebular.h
@@ -8,12 +8,12 @@
* 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.
@@ -131,6 +131,9 @@ public:
virtual void step();
virtual void synchronize(Common::Serializer &s, bool phase1);
+
+ virtual void setNaughtyMode(bool naughtyMode) { _storyMode = naughtyMode ? STORYMODE_NAUGHTY : STORYMODE_NICE; }
+ virtual bool getNaughtyMode() const { return _storyMode == STORYMODE_NAUGHTY; }
};
// Section handlers aren't needed in ScummVM implementation
diff --git a/engines/mads/nebular/globals_nebular.cpp b/engines/mads/nebular/globals_nebular.cpp
index 9f8b8a7888..c44506e546 100644
--- a/engines/mads/nebular/globals_nebular.cpp
+++ b/engines/mads/nebular/globals_nebular.cpp
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/nebular/globals_nebular.h b/engines/mads/nebular/globals_nebular.h
index bd1c6d84b0..7c7069892e 100644
--- a/engines/mads/nebular/globals_nebular.h
+++ b/engines/mads/nebular/globals_nebular.h
@@ -8,12 +8,12 @@
* 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.
@@ -148,9 +148,9 @@ enum GlobalId {
/* Section #6 Variables */
kConvHermit1 = 130,
- kconvHermit2 = 131,
+ kConvHermit2 = 131,
kHasTalkedToHermit = 132,
- kExecuted_1_11 = 133,
+ kHermitWantsBatteries = 133,
kHandsetCellStatus = 134,
kBeenInVideoStore = 135,
kDurafailRecharged = 136,
diff --git a/engines/mads/nebular/menu_nebular.cpp b/engines/mads/nebular/menu_nebular.cpp
index 28de4e5650..6fe17f3beb 100644
--- a/engines/mads/nebular/menu_nebular.cpp
+++ b/engines/mads/nebular/menu_nebular.cpp
@@ -8,12 +8,12 @@
* 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.
@@ -86,7 +86,7 @@ void MainMenu::display() {
frame0->_offset.y - frame0->h);
screenObjects.add(
Common::Rect(pt.x, pt.y + DIALOG_TOP, pt.x + frame0->w,
- pt.y + frame0->h + DIALOG_TOP), LAYER_GUI, CAT_COMMAND, i);
+ pt.y + frame0->h + DIALOG_TOP), SCREENMODE_VGA, CAT_COMMAND, i);
}
// Set the cursor for when it's shown
@@ -292,7 +292,7 @@ bool MainMenu::onEvent(Common::Event &event) {
}
int MainMenu::getHighlightedItem(const Common::Point &pt) {
- return _vm->_game->_screenObjects.scan(pt, LAYER_GUI) - 1;
+ return _vm->_game->_screenObjects.scan(pt, SCREENMODE_VGA) - 1;
}
void MainMenu::unhighlightItem() {
diff --git a/engines/mads/nebular/menu_nebular.h b/engines/mads/nebular/menu_nebular.h
index 77b8b6fc6e..35af0bb34f 100644
--- a/engines/mads/nebular/menu_nebular.h
+++ b/engines/mads/nebular/menu_nebular.h
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/nebular/nebular_scenes.cpp b/engines/mads/nebular/nebular_scenes.cpp
index b5e2491624..eb6f7a5610 100644
--- a/engines/mads/nebular/nebular_scenes.cpp
+++ b/engines/mads/nebular/nebular_scenes.cpp
@@ -8,12 +8,12 @@
* 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.
@@ -432,7 +432,7 @@ void SceneTeleporter::teleporterHandleKey() {
case 0: {
_game._player._stepEnabled = false;
Common::Point msgPos = teleporterComputeLocation();
- _handSequenceId = _scene->_sequences.startReverseCycle(_handSpriteId, false, 4, 2, 0, 0);
+ _handSequenceId = _scene->_sequences.startPingPongCycle(_handSpriteId, false, 4, 2, 0, 0);
_scene->_sequences.setPosition(_handSequenceId, msgPos);
_scene->_sequences.setDepth(_handSequenceId, 2);
_scene->_sequences.addSubEntry(_handSequenceId, SEQUENCE_TRIGGER_LOOP, 0, 1);
@@ -451,7 +451,10 @@ void SceneTeleporter::teleporterHandleKey() {
_curCode *= 10;
_curCode += _buttonTyped;
_digitCount++;
- _msgText = Common::String::format("%d", _curCode);
+
+ Common::String format = "%01d";
+ format.setChar('0' + _digitCount, 2);
+ _msgText = Common::String::format(format.c_str(), _curCode);
if (_digitCount < 4)
_msgText += "_";
@@ -535,7 +538,7 @@ void SceneTeleporter::teleporterEnter() {
_curMessageId = -1;
_msgText = "_";
- if (_scene->_priorSceneId == -2)
+ if (_scene->_priorSceneId == RETURNING_FROM_DIALOG)
_scene->_priorSceneId = _globals[kTeleporterDestination];
if (_scene->_priorSceneId < 101)
diff --git a/engines/mads/nebular/nebular_scenes.h b/engines/mads/nebular/nebular_scenes.h
index cf33b21aad..58a6d1c98f 100644
--- a/engines/mads/nebular/nebular_scenes.h
+++ b/engines/mads/nebular/nebular_scenes.h
@@ -8,12 +8,12 @@
* 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.
@@ -106,6 +106,7 @@ enum Verb {
VERB_WALK_UP = 0x227,
VERB_WALK_INTO = 0x242,
VERB_EXIT = 0x298,
+ VERB_WALK_BEHIND = 0x2A2,
VERB_WALK_ONTO = 0x2B5,
VERB_RETURN_TO = 0x2D5,
VERB_CLIMB_INTO = 0x2F7,
@@ -216,9 +217,9 @@ enum Noun {
NOUN_CLEARING_TO_EAST = 0x4B,
NOUN_CLEARING_TO_SOUTH = 0x4C,
NOUN_CLIFF_FACE = 0x4D,
- NOUN_CLIMB_DOWN = 0x4E,
- NOUN_CLIMB_THROUGH = 0x4F,
- NOUN_CLIMB_UP = 0x50,
+ //NOUN_CLIMB_DOWN = 0x4E,
+ //NOUN_CLIMB_THROUGH = 0x4F,
+ //NOUN_CLIMB_UP = 0x50,
NOUN_CLOCK = 0x51,
NOUN_CLOSET = 0x52,
NOUN_CLOTHESLINE = 0x53,
@@ -397,7 +398,7 @@ enum Noun {
NOUN_PALM_TREE = 0x100,
NOUN_PASSAGE_WAY_TO_SOUTH = 0x101,
NOUN_PASSION_PUSS = 0x102,
- NOUN_PEER_THROUGH = 0x103,
+ //NOUN_PEER_THROUGH = 0x103,
NOUN_PENCIL = 0x104,
NOUN_PENDULOUS_CRAG = 0x105,
NOUN_PENLIGHT = 0x106,
@@ -812,7 +813,7 @@ enum Noun {
NOUN_COUNTER = 0x29F,
NOUN_SENSOR = 0x2A0,
NOUN_SOFTWARE_INFORMATION = 0x2A1,
- NOUN_WALK_BEHIND = 0x2A2,
+ //NOUN_WALK_BEHIND = 0x2A2,
NOUN_BARGAINS = 0x2A3,
NOUN_SCAN_LIGHT = 0x2A4,
NOUN_OLD_SOFTWARE_STAND = 0x2A5,
@@ -831,7 +832,7 @@ enum Noun {
//NOUN_GAWK_AT = 0x2B2,
NOUN_CORRIDOR_TO_SOUTH = 0x2B3,
NOUN_CORRIDOR_TO_NORTH = 0x2B4,
- NOUN_WALK_ONTO = 0x2B5,
+ //NOUN_WALK_ONTO = 0x2B5,
NOUN_ROCK_WALL = 0x2B6,
NOUN_WOMAN = 0x2B7,
NOUN_WOMEN = 0x2B8,
@@ -897,7 +898,7 @@ enum Noun {
NOUN_YOUR_STUFF = 0x2F4,
NOUN_OTHER_STUFF = 0x2F5,
NOUN_LAMP = 0x2F6,
- NOUN_CLIMB_INTO = 0x2F7,
+ //NOUN_CLIMB_INTO = 0x2F7,
NOUN_LIGHT_BULB = 0x2F8,
//NOUN_STEP_INTO = 0x2F9,
NOUN_ROOM = 0x2FA,
@@ -924,7 +925,6 @@ enum Noun {
NOUN_WHISKEY = 0x30F,
NOUN_ALCOHOL = 0x310,
NOUN_RIM = 0x311,
- //NOUN_WALK_ALONG = 0x312,
NOUN_SUBMERGED_CITY = 0x313,
NOUN_GOVERNORS_HOUSE = 0x314,
NOUN_RIM_TOWARDS_EAST = 0x315,
@@ -1057,7 +1057,7 @@ enum Noun {
NOUN_PAD_TO_EAST = 0x394,
NOUN_PAD_TO_WEST = 0x395,
NOUN_TOWER = 0x396,
- NOUN_LOOK_OUT = 0x397,
+ //NOUN_LOOK_OUT = 0x397,
NOUN_SERVICE_PANEL = 0x398,
NOUN_CRACK = 0x399,
NOUN_THROTTLE = 0x39A,
diff --git a/engines/mads/nebular/nebular_scenes1.cpp b/engines/mads/nebular/nebular_scenes1.cpp
index ab072c1d3c..fd97f71727 100644
--- a/engines/mads/nebular/nebular_scenes1.cpp
+++ b/engines/mads/nebular/nebular_scenes1.cpp
@@ -8,12 +8,12 @@
* 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
+ * 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.
@@ -134,7 +134,7 @@ void Scene101::sayDang() {
switch (_game._trigger) {
case 0:
_scene->_sequences.remove(_globals._sequenceIndexes[11]);
- _globals._sequenceIndexes[11] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[11], false, 3, 6, 0, 0);
+ _globals._sequenceIndexes[11] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[11], false, 3, 6, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[11], 17, 21);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[11], SEQUENCE_TRIGGER_EXPIRE, 0, 72);
_vm->_sound->command(17);
@@ -188,13 +188,13 @@ void Scene101::enter() {
_scene->_hotspots.activate(NOUN_SHIELD_MODULATOR, false);
_panelOpened = false;
- if (_scene->_priorSceneId != -1)
+ if (_scene->_priorSceneId != RETURNING_FROM_LOADING)
_globals[kNeedToStandUp] = false;
- if (_scene->_priorSceneId != -2)
+ if (_scene->_priorSceneId != RETURNING_FROM_DIALOG)
_game._player._playerPos = Common::Point(100, 152);
- if ((_scene->_priorSceneId == 112) || ((_scene->_priorSceneId == -2) && _sittingFl )) {
+ if ((_scene->_priorSceneId == 112) || ((_scene->_priorSceneId == RETURNING_FROM_DIALOG) && _sittingFl )) {
_game._player._visible = false;
_sittingFl = true;
_game._player._playerPos = Common::Point(161, 123);
@@ -696,7 +696,7 @@ void Scene102::enter() {
_globals._spriteIndexes[11] = _scene->_sprites.addSprites("*RXMRC_8");
_globals._spriteIndexes[13] = _scene->_sprites.addSprites(formAnimName('x', 0));
- _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 8, 0, 0, 0);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[1], false, 8, 0, 0, 0);
_globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 170, 0, 1, 6);
_globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 11, 0, 2, 3);
_globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 4, 0, 1, 0);
@@ -721,7 +721,7 @@ void Scene102::enter() {
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[6], SEQUENCE_TRIGGER_EXPIRE, 0, 70);
} else if (_scene->_priorSceneId == 103)
_game._player._playerPos = Common::Point(47, 152);
- else if (_scene->_priorSceneId != -2) {
+ else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._facing = FACING_NORTHWEST;
_game._player._playerPos = Common::Point(32, 129);
}
@@ -906,7 +906,7 @@ void Scene102::actions() {
_fridgeFirstOpenFl = false;
int quoteId = _vm->getRandomNumber(59, 63);
Common::String curQuote = _game.getQuote(quoteId);
- int width = _vm->_font->getWidth(curQuote, -1);
+ int width = _scene->_kernelMessages._talkFont->getWidth(curQuote, -1);
_scene->_kernelMessages.reset();
_game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
_scene->_kernelMessages.add(Common::Point(210, 60), 0x1110, 0, 73, 120, curQuote);
@@ -1201,7 +1201,7 @@ void Scene102::actions() {
if (_action.isAction(VERB_TAKE, NOUN_BINOCULARS) && _game._objects.isInRoom(OBJ_BINOCULARS)) {
switch (_game._trigger) {
case 0:
- _globals._sequenceIndexes[11] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[11], false, 3, 1, 0, 0);
+ _globals._sequenceIndexes[11] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[11], false, 3, 1, 0, 0);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[11]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[11], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
_game._player._visible = false;
@@ -1342,7 +1342,7 @@ void Scene103::enter() {
_scene->_hotspots.activate(362, false);
}
- if (_scene->_priorSceneId != -2)
+ if (_scene->_priorSceneId != RETURNING_FROM_DIALOG)
_game._player._playerPos = Common::Point(237, 74);
if (_scene->_priorSceneId == 102) {
@@ -1433,7 +1433,7 @@ void Scene103::actions() {
switch (_vm->_game->_trigger) {
case 0:
_scene->changeVariant(1);
- _globals._sequenceIndexes[13] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[13], false, 3, 2);
+ _globals._sequenceIndexes[13] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[13], false, 3, 2);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[13]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_SPRITE, 7, 1);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
@@ -1453,17 +1453,16 @@ void Scene103::actions() {
_scene->_hotspots.activate(371, false);
_vm->_game->_player._visible = true;
_vm->_game->_player._stepEnabled = true;
- _vm->_dialogs->showItem(OBJ_REBREATHER, 805);
+ _vm->_dialogs->showItem(OBJ_TIMER_MODULE, 805);
break;
default:
break;
}
- } else if (_action.isAction(VERB_TAKE, 289, 0) && _game._objects.isInRoom(OBJ_REBREATHER)) {
+ } else if (_action.isAction(VERB_TAKE, NOUN_REBREATHER, 0) && _game._objects.isInRoom(OBJ_REBREATHER)) {
switch (_vm->_game->_trigger) {
case 0:
- _scene->changeVariant(1);
- _globals._sequenceIndexes[12] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[12], false, 3, 2);
+ _globals._sequenceIndexes[12] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[12], false, 3, 2);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[12]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[12], SEQUENCE_TRIGGER_SPRITE, 6, 1);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[12], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
@@ -1621,10 +1620,11 @@ void Scene104::setup() {
void Scene104::enter() {
_globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('h', -1));
_globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 14, 0, 0, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 8);
if (_scene->_priorSceneId == 105)
_game._player._playerPos = Common::Point(302, 107);
- else if (_scene->_priorSceneId != -2)
+ else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG)
_game._player._playerPos = Common::Point(160, 134);
_loseFl = false;
@@ -1846,7 +1846,7 @@ void Scene105::enter() {
if (_scene->_priorSceneId == 104)
_game._player._playerPos = Common::Point(13, 97);
- else if (_scene->_priorSceneId != -2)
+ else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG)
_game._player._playerPos = Common::Point(116, 147);
_game.loadQuoteSet(0x4A, 0x4B, 0x4C, 0x35, 0x34, 0);
@@ -2009,7 +2009,7 @@ void Scene106::enter() {
}
_globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('G', -1));
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 21, 0, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 21, 0, 0, 0);
_globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('I', -1));
_globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 6, 0, 32, 47);
@@ -2020,7 +2020,7 @@ void Scene106::enter() {
_game._player._stepEnabled = false;
_game._player._facing = FACING_EAST;
_game._player._playerPos = Common::Point(106, 69);
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
if (_scene->_priorSceneId == 107) {
_game._player._playerPos = Common::Point(319, 84);
_game._player._facing = _game._player._prepareWalkFacing = FACING_WEST;
@@ -2112,9 +2112,9 @@ void Scene106::step() {
}
if (msgId >= 0) {
- int nextAbortVal = _game._trigger + 1;
+ int nextTrigger = _game._trigger + 1;
_scene->_kernelMessages.add(Common::Point(15, _positionY), 0x1110, 0, 0, 360, _game.getQuote(msgId));
- _scene->_sequences.addTimer(150, nextAbortVal);
+ _scene->_sequences.addTimer(150, nextTrigger);
_positionY += 14;
}
}
@@ -2239,7 +2239,7 @@ void Scene107::enter() {
_game._player._playerPos = Common::Point(132, 47);
else if (_scene->_priorSceneId == 106)
_game._player._playerPos = Common::Point(20, 91);
- else if (_scene->_priorSceneId != -2)
+ else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG)
_game._player._playerPos = Common::Point(223, 151);
if (((_scene->_priorSceneId == 105) || (_scene->_priorSceneId == 106)) && (_vm->getRandomNumber(1, 3) == 1)) {
@@ -2351,7 +2351,7 @@ void Scene108::enter() {
if (_scene->_priorSceneId == 107)
_game._player._playerPos = Common::Point(138, 58);
- else if (_scene->_priorSceneId != -2)
+ else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG)
_game._player._playerPos = Common::Point(305, 98);
_game.loadQuoteSet(0x4A, 0x4B, 0x4C, 0x35, 0x34, 0);
@@ -2458,7 +2458,7 @@ void Scene109::enter() {
if (_scene->_priorSceneId == 110) {
_game._player._playerPos = Common::Point(248, 38);
_globals[kHoovicSated] = 2;
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(20, 68);
_game._player._facing = FACING_EAST;
}
@@ -2502,7 +2502,7 @@ void Scene109::enter() {
_globals._spriteIndexes[10] = _scene->_sprites.addSprites(Resources::formatName(105, 'F', 1, EXT_SS, ""));
_globals._spriteIndexes[9] = _scene->_sprites.addSprites(formAnimName('H', 1));
- _globals._sequenceIndexes[10] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[10], true, 4, 0, 0, 0);
+ _globals._sequenceIndexes[10] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[10], true, 4, 0, 0, 0);
_scene->_sequences.setDepth(_globals._sequenceIndexes[10], 5);
_scene->_sequences.setPosition(_globals._sequenceIndexes[10], Common::Point(126, 39));
_scene->_sequences.setMotion(_globals._sequenceIndexes[10], 0, 200, 0);
@@ -2589,8 +2589,8 @@ void Scene109::preActions() {
_game._player._walkOffScreenSceneId = 108;
if ((_action.isAction(VERB_THROW) || _action.isAction(VERB_GIVE) || _action.isAction(VERB_PUT))
- && (_action.isObject(NOUN_SMALL_HOLE) || _action.isObject(NOUN_TUNNEL))
- && (_action.isObject(NOUN_DEAD_FISH) || _action.isObject(NOUN_STUFFED_FISH) || _action.isObject(NOUN_BURGER))) {
+ && (_action.isTarget(NOUN_SMALL_HOLE) || _action.isTarget(NOUN_TUNNEL))
+ && (_action.isObject(NOUN_DEAD_FISH) || _action.isObject(NOUN_STUFFED_FISH) || _action.isObject(NOUN_BURGER))) {
int idx = _game._objects.getIdFromDesc(_action._activeAction._objectNameId);
if ((idx >= 0) && _game._objects.isInInventory(idx)) {
_game._player._prepareWalkPos = Common::Point(106, 38);
@@ -2637,7 +2637,7 @@ void Scene109::actions() {
break;
case OBJ_BURGER:
- _hoovicDifficultFl = (_game._difficulty == DIFFICULTY_EASY);
+ _hoovicDifficultFl = (_game._difficulty == DIFFICULTY_HARD);
_globals._spriteIndexes[8] = _scene->_sprites.addSprites(formAnimName('H', (_hoovicDifficultFl ? 3 : 1)));
break;
}
@@ -2675,7 +2675,7 @@ void Scene109::actions() {
case 2:
if (_hoovicDifficultFl)
- _globals._sequenceIndexes[8] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[8], false, 4, 2, 0, 0);
+ _globals._sequenceIndexes[8] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[8], false, 4, 2, 0, 0);
else
_globals._sequenceIndexes[8] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[8], false, 4, 1, 0, 0);
@@ -2864,7 +2864,7 @@ void Scene110::enter() {
_scene->_dynamicHotspots.setPosition(idx, Common::Point(-1, 0), FACING_NONE);
idx = _scene->_dynamicHotspots.add(91, 348, _globals._sequenceIndexes[3], Common::Rect(0, 0, 0, 0));
_scene->_dynamicHotspots.setPosition(idx, Common::Point(-1, 0), FACING_NONE);
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(194, 23);
_game._player._facing = FACING_SOUTH;
_game._player._visible = false;
@@ -3007,7 +3007,7 @@ void Scene111::enter() {
_launched2Fl = false;
_stampedFl = false;
- if ((_scene->_priorSceneId < 201) && (_scene->_priorSceneId != -2)) {
+ if ((_scene->_priorSceneId < 201) && (_scene->_priorSceneId != RETURNING_FROM_DIALOG)) {
_game._player._stepEnabled = false;
_game._player._visible = false;
_scene->loadAnimation(Resources::formatName(111, 'A', 0, EXT_AA, ""), 70);
@@ -3018,7 +3018,7 @@ void Scene111::enter() {
_launched2Fl = true;
_vm->_sound->command(36);
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(300, 130);
_game._player._facing = FACING_WEST;
}
diff --git a/engines/mads/nebular/nebular_scenes1.h b/engines/mads/nebular/nebular_scenes1.h
index 1afa7fccc1..d8c9059846 100644
--- a/engines/mads/nebular/nebular_scenes1.h
+++ b/engines/mads/nebular/nebular_scenes1.h
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/nebular/nebular_scenes2.cpp b/engines/mads/nebular/nebular_scenes2.cpp
index 94e30aa4f2..1cbd6f56ef 100644
--- a/engines/mads/nebular/nebular_scenes2.cpp
+++ b/engines/mads/nebular/nebular_scenes2.cpp
@@ -8,12 +8,12 @@
* 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
+ * 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.
@@ -152,7 +152,7 @@ void Scene201::enter() {
int idx = _scene->_dynamicHotspots.add(NOUN_BIRDS, 209, _globals._sequenceIndexes[4], Common::Rect(0, 0, 0, 0));
_scene->_dynamicHotspots.setPosition(idx, Common::Point(186, 81), FACING_NORTH);
- if ((_scene->_priorSceneId == 202) || (_scene->_priorSceneId == -1)) {
+ if ((_scene->_priorSceneId == 202) || (_scene->_priorSceneId == RETURNING_FROM_LOADING)) {
_game._player._playerPos = Common::Point(165, 152);
} else {
_game._player._playerPos = Common::Point(223, 149);
@@ -165,16 +165,16 @@ void Scene201::enter() {
int sepChar = (_globals[kSexOfRex] == SEX_MALE) ? 't' : 'u';
// Guess values. What is the default value used by the compiler?
int suffixNum = -1;
- int abortTimers = -1;
+ int endTrigger = -1;
switch(_globals[kTeleporterCommand]) {
case 1:
suffixNum = 3;
- abortTimers = 76;
+ endTrigger = 76;
_globals[kTeleporterUnderstood] = true;
break;
case 2:
suffixNum = 1;
- abortTimers = 77;
+ endTrigger = 77;
break;
case 3:
_game._player._visible = true;
@@ -183,12 +183,12 @@ void Scene201::enter() {
break;
case 4:
suffixNum = 2;
- abortTimers = 78;
+ endTrigger = 78;
break;
}
_globals[kTeleporterCommand] = 0;
if (suffixNum >= 0)
- _scene->loadAnimation(formAnimName(sepChar, suffixNum), abortTimers);
+ _scene->loadAnimation(formAnimName(sepChar, suffixNum), endTrigger);
}
if ((_scene->_priorSceneId == 202) && (_globals[kMeteorologistStatus] == METEOROLOGIST_PRESENT) && !_scene->_roomChanged) {
@@ -430,7 +430,7 @@ void Scene202::enter() {
if (_scene->_priorSceneId == 201) {
_game._player._playerPos = Common::Point(190, 91);
_game._player._facing = FACING_SOUTH;
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(178, 152);
_game._player._facing = FACING_NORTH;
}
@@ -446,7 +446,7 @@ void Scene202::enter() {
_game.loadQuoteSet(0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x62, 0x63, 0x64, 0x65, 0x66, 0x61, 0);
_activeMsgFl = false;
- if (_scene->_priorSceneId == -2) {
+ if (_scene->_priorSceneId == RETURNING_FROM_DIALOG) {
if (_waitingMeteoFl) {
_globals._sequenceIndexes[9] = _scene->_sequences.startCycle(_globals._spriteIndexes[9], false, 1);
_game._player._visible = false;
@@ -556,7 +556,7 @@ void Scene202::step() {
case 90:
_vm->_sound->command(41);
_scene->_sequences.remove(_globals._sequenceIndexes[10]);
- _globals._sequenceIndexes[9] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[9], true, 6, 1, 0, 0);
+ _globals._sequenceIndexes[9] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[9], true, 6, 1, 0, 0);
_scene->_sequences.setPosition(_globals._sequenceIndexes[9], Common::Point(247, 82));
_scene->_sequences.setDepth(_globals._sequenceIndexes[9], 1);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[9], SEQUENCE_TRIGGER_EXPIRE, 0, 91);
@@ -811,7 +811,7 @@ void Scene202::actions() {
} else {
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[7] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[7], false, 3, 2, 0, 0);
+ _globals._sequenceIndexes[7] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[7], false, 3, 2, 0, 0);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[7]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[7], SEQUENCE_TRIGGER_SPRITE, 6, 1);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[7], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
@@ -1044,7 +1044,7 @@ void Scene203::enter() {
} else if (_scene->_priorSceneId == 209) {
_game._player._playerPos = Common::Point(308, 117);
_game._player._facing = FACING_WEST;
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(155, 152);
_game._player._facing = FACING_NORTH;
}
@@ -1152,8 +1152,9 @@ void Scene205::setup() {
}
Scene205::Scene205(MADSEngine *vm) : Scene2xx(vm) {
- _lastFishTime = 0;
- _chickenTime = 0;
+ _lastFishTime = _scene->_frameStartTime;
+ _chickenTime = _scene->_frameStartTime;
+
_beingKicked = false;
_kernelMessage = -1;
}
@@ -1161,8 +1162,6 @@ Scene205::Scene205(MADSEngine *vm) : Scene2xx(vm) {
void Scene205::synchronize(Common::Serializer &s) {
Scene2xx::synchronize(s);
- s.syncAsUint32LE(_lastFishTime);
- s.syncAsUint32LE(_chickenTime);
s.syncAsByte(_beingKicked);
s.syncAsSint16LE(_kernelMessage);
}
@@ -1191,7 +1190,6 @@ void Scene205::enter() {
_scene->_sequences.setDepth(_globals._sequenceIndexes[5], 11);
if (!_game._visitedScenes._sceneRevisited) {
- _lastFishTime = _scene->_frameStartTime;
_globals._sequenceIndexes[6] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[6], false, 7, 1, 0, 0);
idx = _scene->_dynamicHotspots.add(269, 13, _globals._sequenceIndexes[6], Common::Rect(0, 0, 0, 0));
_scene->_dynamicHotspots.setPosition(idx, Common::Point(49, 86), FACING_NORTH);
@@ -1224,7 +1222,7 @@ void Scene205::enter() {
Common::Rect(195, 99, 264, 134), 13, 2, 0xFDFC, 60,
108, 108, 109, 109, 110, 110, 111, 108, 0);
- if (_scene->_priorSceneId != -2)
+ if (_scene->_priorSceneId != RETURNING_FROM_DIALOG)
_game._player._playerPos = Common::Point(99, 152);
if (_globals[kSexOfRex] != SEX_MALE) {
@@ -1448,8 +1446,9 @@ Scene207::Scene207(MADSEngine *vm) : Scene2xx(vm) {
_eyeFl = false;
_spiderHotspotId = -1;
_vultureHotspotId = -1;
- _spiderTime = 0;
- _vultureTime = 0;
+
+ _spiderTime = _game._player._priorTimer;
+ _vultureTime = _game._player._priorTimer;
}
void Scene207::synchronize(Common::Serializer &s) {
@@ -1461,8 +1460,6 @@ void Scene207::synchronize(Common::Serializer &s) {
s.syncAsSint32LE(_spiderHotspotId);
s.syncAsSint32LE(_vultureHotspotId);
- s.syncAsSint32LE(_spiderTime);
- s.syncAsSint32LE(_vultureTime);
}
void Scene207::setup() {
@@ -1500,8 +1497,7 @@ void Scene207::enter() {
_spiderFl = (var2 & 1);
if (_vultureFl) {
- _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 30, 0, 0, 400);
- _vultureTime = _game._player._priorTimer;
+ _globals._sequenceIndexes[1] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[1], false, 30, 0, 0, 400);
_vultureHotspotId = _scene->_dynamicHotspots.add(389, 13, _globals._sequenceIndexes[1], Common::Rect(0, 0, 0, 0));
_scene->_dynamicHotspots.setPosition(_vultureHotspotId, Common::Point(254, 94), FACING_WEST);
}
@@ -1509,7 +1505,6 @@ void Scene207::enter() {
if (_spiderFl) {
_globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 7, 1, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], -1, -1);
- _spiderTime = _game._player._priorTimer;
_spiderHotspotId = _scene->_dynamicHotspots.add(333, 13, _globals._sequenceIndexes[4], Common::Rect(0, 0, 0, 0));
_scene->_dynamicHotspots.setPosition(_spiderHotspotId, Common::Point(59, 132), FACING_SOUTH);
}
@@ -1521,7 +1516,7 @@ void Scene207::enter() {
} else if (_scene->_priorSceneId == 214) {
_game._player._playerPos = Common::Point(164, 117);
_game._player._facing = FACING_SOUTH;
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(305, 131);
}
@@ -1549,11 +1544,17 @@ void Scene207::moveSpider() {
}
void Scene207::step() {
- if (!_vultureFl)
- moveVulture();
+ Player &player = _game._player;
+
+ if (_vultureFl) {
+ if (((int32)player._priorTimer - _vultureTime) > 1700)
+ moveVulture();
+ }
- if (_spiderFl)
- moveSpider();
+ if (_spiderFl) {
+ if (((int32)player._priorTimer - _spiderTime) > 800)
+ moveSpider();
+ }
if (_game._trigger == 70) {
_globals._sequenceIndexes[6] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[6], false, 10, 0, 0, 0);
@@ -1685,18 +1686,18 @@ void Scene208::updateTrap() {
}
switch (_globals[kLeavesStatus]) {
- case 0: {
+ case LEAVES_ON_GROUND: {
_globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 1);
_scene->_sequences.setDepth(_globals._sequenceIndexes[2], 15);
int idx = _scene->_dynamicHotspots.add(NOUN_PILE_OF_LEAVES, VERB_WALKTO, _globals._sequenceIndexes[2], Common::Rect(0, 0, 0, 0));
_scene->_dynamicHotspots.setPosition(idx, Common::Point(60, 152), FACING_NORTH);
}
break;
- case 2: {
+ case LEAVES_ON_TRAP: {
_scene->_sequences.setDepth(_globals._sequenceIndexes[3], 15);
_globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 1);
_scene->_hotspots.activate(NOUN_DEEP_PIT, false);
- int idx = _scene->_dynamicHotspots.add(NOUN_LEAF_COVERED_PIT, VERB_WALKTO, _globals._sequenceIndexes[2], Common::Rect(0, 0, 0, 0));
+ int idx = _scene->_dynamicHotspots.add(NOUN_LEAF_COVERED_PIT, VERB_WALKTO, _globals._sequenceIndexes[3], Common::Rect(0, 0, 0, 0));
_scene->_dynamicHotspots.setPosition(idx, Common::Point(100, 146), FACING_NORTH);
_scene->_dynamicHotspots[idx]._articleNumber = PREP_ON;
}
@@ -1727,7 +1728,7 @@ void Scene208::enter() {
} else if (_scene->_priorSceneId == 209) {
_game._player._playerPos = Common::Point(307, 123);
_game._player._facing = FACING_WEST;
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(162, 149);
_game._player._facing = FACING_NORTH;
}
@@ -1745,7 +1746,8 @@ void Scene208::enter() {
}
void Scene208::step() {
- if (_boundingFl && (_rhotundaTime <= _scene->_activeAnimation->getCurrentFrame())) {
+ if (_boundingFl && _scene->_activeAnimation &&
+ (_rhotundaTime <= _scene->_activeAnimation->getCurrentFrame())) {
_rhotundaTime = _scene->_activeAnimation->getCurrentFrame();
if (_rhotundaTime == 125)
@@ -1794,7 +1796,6 @@ void Scene208::preActions() {
}
void Scene208::subAction(int mode) {
-
switch (_game._trigger) {
case 0: {
_game._player._stepEnabled = false;
@@ -1802,21 +1803,21 @@ void Scene208::subAction(int mode) {
_globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[5], false, 6, 1, 0, 0);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
- int abortVal;
+ int endTrigger;
if ((mode == 1) || (mode == 2))
- abortVal = 1;
+ endTrigger = 1;
else
- abortVal = 2;
+ endTrigger = 2;
- _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, abortVal);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, endTrigger);
}
break;
case 1: {
- int oldVal = _globals._sequenceIndexes[5];
- _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[6], false, 12, 3, 0, 0);
+ int oldSeq = _globals._sequenceIndexes[5];
+ _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[5], false, 12, 3, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 3, 4);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
- _scene->_sequences.updateTimeout(_globals._sequenceIndexes[5], oldVal);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[5], oldSeq);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
_vm->_sound->command(20);
}
@@ -2157,7 +2158,7 @@ void Scene209::handleLookRight() {
switch (_game._trigger) {
case 151:
_scene->_sequences.remove(_globals._sequenceIndexes[3]);
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 8, 2, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 8, 2, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 8, 14);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 152);
break;
@@ -2224,7 +2225,7 @@ void Scene209::handleGetBinoculars() {
case 162: {
int oldIdx = _globals._sequenceIndexes[3];
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 8, 6, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 8, 6, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 23, 25);
_scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 163);
@@ -2233,7 +2234,7 @@ void Scene209::handleGetBinoculars() {
case 163: {
int oldIdx = _globals._sequenceIndexes[3];
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 8, 0, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 8, 0, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 23, 24);
_scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
_scene->_sequences.addTimer(8, 164);
@@ -2257,7 +2258,7 @@ void Scene209::handleBinocularBlink() {
case 167: {
int oldIdx = _globals._sequenceIndexes[3];
_scene->_sequences.remove(_globals._sequenceIndexes[3]);
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 8, 2, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 8, 2, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 23, 25);
_scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 168);
@@ -2266,7 +2267,7 @@ void Scene209::handleBinocularBlink() {
case 168: {
int oldIdx = _globals._sequenceIndexes[3];
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 8, 0, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 8, 0, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 23, 24);
_scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
_scene->_sequences.addTimer(30, 169);
@@ -2286,7 +2287,7 @@ void Scene209::handleBinocularScan() {
case 171: {
int oldIdx = _globals._sequenceIndexes[3];
_scene->_sequences.remove(_globals._sequenceIndexes[3]);
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 12, 2, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 12, 2, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 43, 45);
_scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 172);
@@ -2298,10 +2299,10 @@ void Scene209::handleBinocularScan() {
int randAction = _vm->getRandomNumber(1,2);
switch (randAction) {
case 1:
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 12, 2, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 12, 2, 0, 0);
break;
case 2:
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 12, 4, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 12, 4, 0, 0);
break;
}
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 23, 25);
@@ -2312,7 +2313,7 @@ void Scene209::handleBinocularScan() {
case 173: {
int oldIdx = _globals._sequenceIndexes[3];
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 12, 2, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 12, 2, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 26, 30);
_scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 174);
@@ -2321,7 +2322,7 @@ void Scene209::handleBinocularScan() {
case 174: {
int oldIdx = _globals._sequenceIndexes[3];
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 12, 0, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 12, 0, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 23, 24);
_scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
_scene->_sequences.addTimer(60, 175);
@@ -2407,7 +2408,7 @@ void Scene209::handleTongue() {
case 185: {
_vm->_sound->command(18);
int oldIdx = _globals._sequenceIndexes[3];
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 6, 20, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 6, 20, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 38, 39);
_scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 186);
@@ -2527,7 +2528,7 @@ void Scene209::handleMonkeyEating() {
case 200: {
int oldIdx = _globals._sequenceIndexes[4];
- _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 10, 10, 0, 0);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 10, 10, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 15, 16);
_scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], oldIdx);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 201);
@@ -2556,14 +2557,14 @@ void Scene209::handleMonkeyEating() {
case 204:
_scene->_sequences.remove(_globals._sequenceIndexes[4]);
- _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 10, 8, 0, 0);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 10, 8, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 18, 19);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 205);
break;
case 205: {
int oldIdx = _globals._sequenceIndexes[4];
- _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 10, 8, 0, 0);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 10, 8, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 20, 21);
_scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], oldIdx);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 206);
@@ -2588,7 +2589,7 @@ void Scene209::handleMonkeyEating() {
_scene->_kernelMessages.setQuoted(msgIndex, 4, true);
int oldIdx = _globals._sequenceIndexes[4];
- _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 15, 4, 0, 0);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 15, 4, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 26, 27);
_scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], oldIdx);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 208);
@@ -2598,7 +2599,7 @@ void Scene209::handleMonkeyEating() {
case 208: {
_scene->_kernelMessages.add(Common::Point(180, 39), 0xFDFC, 0, 0, 90, _game.getQuote(131));
int oldIdx = _globals._sequenceIndexes[4];
- _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 10, 4, 0, 0);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 10, 4, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 28, 29);
_scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], oldIdx);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 209);
@@ -2837,6 +2838,7 @@ void Scene209::enter() {
_globals._spriteIndexes[5] = _scene->_sprites.addSprites(formAnimName('m', 3));
_globals._spriteIndexes[6] = _scene->_sprites.addSprites(formAnimName('m', 6));
_globals._spriteIndexes[7] = _scene->_sprites.addSprites(formAnimName('m', 8));
+ _globals._spriteIndexes[11] = _scene->_sprites.addSprites("*RXMBD_2");
_game.loadQuoteSet(0x82, 0x83, 0x84, 0x9C, 0x97, 0x95, 0x99, 0x9E, 0x98, 0x9B, 0xA0, 0x96, 0x9F,
0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x91, 0x92, 0x93, 0x94, 0x89, 0x85, 0x8A, 0x86, 0x87, 0x88, 0);
@@ -2854,7 +2856,7 @@ void Scene209::enter() {
if (_scene->_priorSceneId == 208) {
_game._player._playerPos = Common::Point(11, 121);
_game._player._facing = FACING_EAST;
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(28, 121);
_game._player._facing = FACING_SOUTH;
}
@@ -3438,10 +3440,9 @@ void Scene209::actions() {
if (_action.isAction(VERB_TAKE, NOUN_PLANT_STALK) && (_game._trigger || _game._objects.isInRoom(OBJ_PLANT_STALK))) {
switch (_game._trigger) {
case 0:
- _globals._spriteIndexes[11] = _scene->_sprites.addSprites("*RXMBD_2");
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[11] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[11], false, 3, 2, 0, 0);
+ _globals._sequenceIndexes[11] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[11], false, 3, 2, 0, 0);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[11]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[11], SEQUENCE_TRIGGER_SPRITE, 4, 1);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[11], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
@@ -3460,7 +3461,6 @@ void Scene209::actions() {
break;
case 3:
- _scene->_sprites.remove(_globals._spriteIndexes[11]);
break;
}
_action._inProgress = false;
@@ -3473,7 +3473,7 @@ void Scene209::actions() {
_globals._spriteIndexes[10] = _scene->_sprites.addSprites("*RXMBD_8");
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[10] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[10], false, 3, 2, 0, 0);
+ _globals._sequenceIndexes[10] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[10], false, 3, 2, 0, 0);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[10]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[10], SEQUENCE_TRIGGER_SPRITE, 4, 1);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[10], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
@@ -4173,7 +4173,7 @@ void Scene210::enter() {
_game._player._playerPos = Common::Point(168, 128);
_game._player._facing = FACING_SOUTH;
_globals[kCurtainOpen] = true;
- } else if (_scene->_priorSceneId != -2)
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG)
_game._player._playerPos = Common::Point(308, 132);
if (!_globals[kCurtainOpen]) {
@@ -4210,7 +4210,7 @@ void Scene210::enter() {
_twinkleAnimationType = 0;
_twinklesCurrentFrame = 0;
- if (_scene->_priorSceneId != -2) {
+ if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_shouldMoveHead = false;
_shouldFaceRex = false;
_shouldTalk = false;
@@ -4647,7 +4647,7 @@ void Scene211::enter() {
_game._player._visible = false;
_scene->loadAnimation(formAnimName('A', -1), 100);
_scene->_activeAnimation->setCurrentFrame(169);
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(310, 31);
_game._player._facing = FACING_SOUTHWEST;
}
@@ -4905,7 +4905,7 @@ void Scene212::enter() {
if (_scene->_priorSceneId == 208) {
_game._player._playerPos = Common::Point(195, 85);
_game._player._facing = FACING_SOUTH;
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(67, 117);
_game._player._facing = FACING_NORTHEAST;
}
@@ -5061,7 +5061,7 @@ void Scene214::enter() {
_scene->_hotspots.activate(NOUN_BLOWGUN, false);
}
- if (_scene->_priorSceneId != -2)
+ if (_scene->_priorSceneId != RETURNING_FROM_DIALOG)
_game._player._playerPos = Common::Point(191, 152);
sceneEntrySound();
@@ -5257,7 +5257,7 @@ void Scene215::enter() {
_game._player._stepEnabled = false;
_globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 1);
_scene->_sequences.addTimer(120, 70);
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(204, 152);
_game._player._facing = FACING_NORTH;
}
@@ -5290,7 +5290,7 @@ void Scene215::actions() {
if (_globals[kSexOfRex] == REX_MALE) {
_game._player._visible = false;
_game._player._stepEnabled = false;
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 6, 2, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 6, 2, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 4);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_LOOP, 0, 1);
diff --git a/engines/mads/nebular/nebular_scenes2.h b/engines/mads/nebular/nebular_scenes2.h
index c860db9470..0ea4702eea 100644
--- a/engines/mads/nebular/nebular_scenes2.h
+++ b/engines/mads/nebular/nebular_scenes2.h
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/nebular/nebular_scenes3.cpp b/engines/mads/nebular/nebular_scenes3.cpp
index bcedf95a27..5a6edbf995 100644
--- a/engines/mads/nebular/nebular_scenes3.cpp
+++ b/engines/mads/nebular/nebular_scenes3.cpp
@@ -8,12 +8,12 @@
* 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
+ * 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.
@@ -370,7 +370,7 @@ void Scene304::enter() {
_globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('a', 1));
_globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('b', 0));
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 150, 0, 3, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 150, 0, 3, 0);
_scene->_sequences.setDepth(_globals._sequenceIndexes[3], 2);
_vm->_palette->setEntry(252, 45, 63, 45);
_vm->_palette->setEntry(253, 20, 45, 20);
@@ -521,11 +521,11 @@ void Scene307::setup() {
setPlayerSpritesPrefix();
setAAName();
_scene->addActiveVocab(NOUN_AIR_VENT);
- _scene->addActiveVocab(NOUN_CLIMB_INTO);
+ _scene->addActiveVocab(VERB_CLIMB_INTO);
}
void Scene307::handleRexDialog(int quote) {
- Common::String curQuote = _game.getQuote(_action._activeAction._verbId);
+ Common::String curQuote = _game.getQuote(quote);
if (_vm->_font->getWidth(curQuote, _scene->_textSpacing) > 200) {
Common::String subQuote1;
_game.splitQuote(curQuote, subQuote1, _subQuote2);
@@ -769,7 +769,7 @@ void Scene307::enter() {
_dialog2.write(0x11E, true);
- if (_scene->_priorSceneId == -2) {
+ if (_scene->_priorSceneId == RETURNING_FROM_DIALOG) {
if (_grateOpenedFl)
_vm->_sound->command(10);
else
@@ -953,7 +953,7 @@ void Scene307::actions() {
case 2: {
int oldIdx = _globals._sequenceIndexes[5];
- _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], false, 12, 6, 0, 0);
+ _globals._sequenceIndexes[5] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[5], false, 12, 6, 0, 0);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 2, 3);
_scene->_sequences.updateTimeout(_globals._sequenceIndexes[5], oldIdx);
@@ -992,7 +992,7 @@ void Scene307::actions() {
_scene->_sequences.remove(_globals._sequenceIndexes[5]);
_grateOpenedFl = true;
_scene->_hotspots.activate(17, false);
- int idx = _scene->_dynamicHotspots.add(17, NOUN_CLIMB_INTO, -1, Common::Rect(117, 67, 117 + 19, 67 + 13));
+ int idx = _scene->_dynamicHotspots.add(17, VERB_CLIMB_INTO, -1, Common::Rect(117, 67, 117 + 19, 67 + 13));
int hotspotId = _scene->_dynamicHotspots.setPosition(idx, Common::Point(129, 104), FACING_NORTH);
_scene->_dynamicHotspots.setCursor(hotspotId, CURSOR_GO_UP);
_game._objects.removeFromInventory(OBJ_SCALPEL, NOWHERE);
@@ -1245,7 +1245,7 @@ void Scene308::step() {
switch (_game._trigger) {
case 70: {
_scene->_sequences.remove(_globals._sequenceIndexes[3]);
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 18, 9, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 18, 9, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 2, 3);
_scene->_sequences.setDepth(_globals._sequenceIndexes[3], 9);
_scene->_kernelMessages.reset();
@@ -1266,7 +1266,7 @@ void Scene308::step() {
case 72:
_scene->_sequences.remove(_globals._sequenceIndexes[3]);
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 20, 5, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 20, 5, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 3, 4);
_scene->_sequences.setDepth(_globals._sequenceIndexes[3], 9);
_scene->_kernelMessages.reset();
@@ -1284,7 +1284,7 @@ void Scene308::step() {
case 74: {
_scene->_sequences.remove(_globals._sequenceIndexes[3]);
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 20, 8, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 20, 8, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 6, 7);
_scene->_sequences.setDepth(_globals._sequenceIndexes[3], 9);
_scene->_kernelMessages.reset();
@@ -1306,7 +1306,7 @@ void Scene308::step() {
case 76: {
int seqIdx = _globals._sequenceIndexes[3];
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 26, 0, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 26, 0, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 2, 3);
_scene->_sequences.setDepth(_globals._sequenceIndexes[3], 9);
_scene->_kernelMessages.reset();
@@ -1441,7 +1441,7 @@ void Scene309::step() {
case 70: {
int idx = _scene->_dynamicHotspots.add(689, 690, _globals._sequenceIndexes[3], Common::Rect(0, 0, 0, 0));
_scene->_dynamicHotspots.setPosition(idx, Common::Point(142, 146), FACING_NORTHEAST);
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 7, 4, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 7, 4, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 2, 3);
_scene->_sequences.setDepth(_globals._sequenceIndexes[3], 11);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
@@ -1462,7 +1462,7 @@ void Scene309::step() {
case 72: {
int _oldIdx = _globals._sequenceIndexes[3];
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 7, 8, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 7, 8, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 8, 11);
_scene->_sequences.setDepth(_globals._sequenceIndexes[3], 11);
_scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], _oldIdx);
@@ -1484,7 +1484,7 @@ void Scene309::step() {
case 74: {
int _oldIdx = _globals._sequenceIndexes[3];
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 7, 6, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 7, 6, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 21, 23);
_scene->_sequences.setDepth(_globals._sequenceIndexes[3], 11);
_scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], _oldIdx);
@@ -1494,7 +1494,7 @@ void Scene309::step() {
case 75: {
int _oldIdx = _globals._sequenceIndexes[3];
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 12, 6, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 12, 6, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 24, 25);
_scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], _oldIdx);
_scene->_sequences.setDepth(_globals._sequenceIndexes[3], 11);
@@ -1513,7 +1513,7 @@ void Scene309::step() {
break;
case 77: {
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 90, 0, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 90, 0, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 29, 30);
_scene->_sequences.setDepth(_globals._sequenceIndexes[3], 11);
int idx = _scene->_kernelMessages.add(Common::Point(15, 46), 0xFDFC, 0, 0, 120, _game.getQuote(247));
@@ -1618,7 +1618,7 @@ void Scene311::enter() {
else if (_scene->_priorSceneId == 320) {
_game._player._playerPos = Common::Point(129, 113);
_game._player._facing = FACING_SOUTH;
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._visible = false;
_game._player._stepEnabled = false;
_scene->loadAnimation(formAnimName('a', -1), 70);
@@ -1749,7 +1749,7 @@ void Scene311::actions() {
else if (_checkGuardFl) {
_checkGuardFl = false;
_scene->_kernelMessages.reset();
- _scene->_kernelMessages.addQuote(0xFA, 120, 0);
+ _scene->_kernelMessages.addQuote(250, 0, 240);
} else if (_action.isAction(VERB_SIT_AT, NOUN_DESK))
_scene->_nextSceneId = 320;
else if (_action.isAction(VERB_CLIMB_INTO, NOUN_AIR_VENT)) {
@@ -1896,7 +1896,7 @@ void Scene313::enter() {
} else if (_scene->_priorSceneId == 388) {
_game._player._playerPos = Common::Point(199, 70);
_game._player._facing = FACING_WEST;
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(234, 70);
_game._player._facing = FACING_WEST;
}
@@ -1965,7 +1965,7 @@ void Scene316::handleRexInGrate() {
case 1:
_scene->_sequences.setDone(_globals._sequenceIndexes[4]);
- _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 12, 3, 0, 0);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 12, 3, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 2, 3);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
@@ -2085,7 +2085,7 @@ void Scene316::handleRoxInGrate() {
case 1:
_scene->_sequences.setDone(_globals._sequenceIndexes[5]);
- _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], false, 17, 3, 0, 0);
+ _globals._sequenceIndexes[5] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[5], false, 17, 3, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 2, 3);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
@@ -2215,7 +2215,7 @@ void Scene316::enter() {
_globals._sequenceIndexes[1] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[spriteIdx], false, 6, 1, 0, 0);
_scene->_sequences.setDepth(_globals._sequenceIndexes[1], 2);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 60);
- } else if (_scene->_priorSceneId != -2)
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG)
_game._player._playerPos = Common::Point(291, 126);
sceneEntrySound();
@@ -2523,7 +2523,7 @@ void Scene318::handleDialog() {
case 0x19C:
case 0x19D:
_scene->_sequences.remove(_globals._sequenceIndexes[2]);
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 8, 1, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[2], false, 8, 1, 0, 0);
_scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
_scene->_sequences.setPosition(_globals._sequenceIndexes[2], Common::Point(142, 121));
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 6, 8);
@@ -2581,6 +2581,12 @@ void Scene318::handleInternDialog(int quoteId, int quoteNum, uint32 timeout) {
_scene->_kernelMessages.reset();
_internTalkingFl = true;
+ // WORKAROUND: In case the player launches multiple talk selections with the
+ // intern before previous ones have finished, take care of removing any
+ int seqIndex;
+ while ((seqIndex = _scene->_sequences.findByTrigger(63)) != -1)
+ _scene->_sequences.remove(seqIndex);
+
for (int i = 0; i < quoteNum; i++) {
_game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
_scene->_sequences.addTimer(180, 63);
@@ -2611,7 +2617,7 @@ void Scene318::enter() {
if (_scene->_priorSceneId == 357)
_game._player._playerPos = Common::Point(15, 110);
- else if (_scene->_priorSceneId != -2)
+ else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG)
_game._player._playerPos = Common::Point(214, 152);
_dialog1.setup(0x47, 0x191, 0x192, 0x193, 0x194, 0x195, 0x196, 0x197, 0x198, 0x199, 0x19A, 0x19B, 0x19C, 0x19D, 0);
@@ -2632,7 +2638,7 @@ void Scene318::enter() {
_lastFrame = 0;
_scene->_hotspots.activate(NOUN_INTERN, false);
- if (_scene->_priorSceneId != -2) {
+ if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_dialogFl = false;
_internWalkingFl = false;
_counter= 0;
@@ -2649,7 +2655,8 @@ void Scene318::enter() {
0x1C8, 0x1C9, 0x1CA, 0x1CB, 0x1CC, 0x1CD, 0x1CE, 0x1CF, 0x1D0, 0x1D1, 0x1D2, 0x1D3,
0x190, 0x19D, 0);
- if ((_scene->_priorSceneId== -2) || (((_scene->_priorSceneId == 318) || (_scene->_priorSceneId == -1)) && (!_globals[kAfterHavoc]))) {
+ if ((_scene->_priorSceneId == RETURNING_FROM_DIALOG) || (((_scene->_priorSceneId == 318) ||
+ (_scene->_priorSceneId == RETURNING_FROM_LOADING)) && (!_globals[kAfterHavoc]))) {
if (!_globals[kAfterHavoc]) {
_game._player._visible = false;
_globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('g', -1));
@@ -2883,7 +2890,7 @@ void Scene318::actions() {
case 0:
_game._player._stepEnabled = false;
_scene->_sequences.remove(_globals._sequenceIndexes[2]);
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 8, 2, 0, 80);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 8, 2, 0, 80);
_scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
_scene->_sequences.setPosition(_globals._sequenceIndexes[2], Common::Point(142, 121));
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 2, 5);
@@ -3113,7 +3120,7 @@ void Scene319::enter() {
_dialog2.setup(0x44, 0x171, 0x172, 0x173, 0x174, 0x175, 0x176, 0);
_dialog3.setup(0x45, 0x17D, 0x17E, 0x17F, 0x180, 0x181, 0x182, 0x183, 0);
- if (_scene->_priorSceneId != -2) {
+ if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_dialog1.set(0x165, 0x166, 0x167, 0x168, 0);
_dialog2.set(0x171, 0x172, 0x173, 0x174, 0);
_dialog3.set(0x17D, 0x17E, 0x17F, 0x180, 0);
@@ -3136,7 +3143,7 @@ void Scene319::enter() {
_scene->loadAnimation(formAnimName('b', 0));
- if (_scene->_priorSceneId != -2) {
+ if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_animMode = 1;
_nextAction1 = 2;
_nextAction2 = 2;
@@ -3306,7 +3313,7 @@ void Scene319::step() {
switch (_game._trigger) {
case 70:
- case 71:
+ case 71: {
_animMode = 1;
_nextAction1 = _nextAction2;
_animFrame = 0;
@@ -3329,7 +3336,14 @@ void Scene319::step() {
_scene->_sequences.updateTimeout(_globals._sequenceIndexes[i], oldIdx);
}
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[0], SEQUENCE_TRIGGER_EXPIRE, 0, 74);
+
+ // WORKAROUND: This fixes the game sometimes going into an endless waiting
+ // loop even after the doctor has finished hitting Rex. Note sure if it's due
+ // to a bug in room script or in the engine, but this at least fixes it
+ int seqIndex = _scene->_sequences.findByTrigger(2);
+ _scene->_sequences[seqIndex]._doneFlag = false;
break;
+ }
case 72:
_vm->_palette->setColorFlags(0xFF, 0, 0);
@@ -3588,7 +3602,7 @@ void Scene320::setLeftView(int view) {
_scene->_sequences.remove(_globals._sequenceIndexes[0]);
if (view != 10) {
- _globals._sequenceIndexes[0] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[view], false, 6, 0, 0, 18);
+ _globals._sequenceIndexes[0] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[view], false, 6, 0, 0, 18);
_scene->_sequences.setDepth(_globals._sequenceIndexes[0], 0);
if (!_blinkFl)
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[0], 2, 2);
@@ -3752,7 +3766,7 @@ void Scene320::actions() {
case 0:
_game._player._stepEnabled = false;
handleButtons();
- _globals._sequenceIndexes[18] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[18], _flippedFl, 4, 2, 0, 0);
+ _globals._sequenceIndexes[18] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[18], _flippedFl, 4, 2, 0, 0);
_scene->_sequences.setScale(_globals._sequenceIndexes[18], 60);
_scene->_sequences.setPosition(_globals._sequenceIndexes[18], Common::Point(_posX, 170));
_scene->_sequences.setDepth(_globals._sequenceIndexes[18], 0);
@@ -3825,7 +3839,7 @@ void Scene320::actions() {
else if (_action.isAction(VERB_LOOK, NOUN_DOUGHNUT))
_vm->_dialogs->show(32006);
else if (_action.isAction(VERB_LOOK, NOUN_MAGAZINE))
- _vm->_dialogs->show(32006);
+ _vm->_dialogs->show(32007);
else if (_action.isAction(VERB_LOOK, NOUN_PAPER_FOOTBALL))
_vm->_dialogs->show(32008);
else if (_action.isAction(VERB_LOOK, NOUN_NEWSPAPER))
@@ -3975,7 +3989,7 @@ void Scene351::enter() {
if (_scene->_priorSceneId == 352)
_game._player._playerPos = Common::Point(148, 152);
- else if (_scene->_priorSceneId != -2) {
+ else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(207, 81);
_game._player._facing = FACING_NORTH;
}
@@ -4053,12 +4067,12 @@ void Scene351::actions() {
_game._player._stepEnabled = false;
_game._player._visible = false;
if (_globals[kSexOfRex] == REX_FEMALE) {
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 5, 2, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 5, 2, 0, 0);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 5, 1);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
} else {
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 5, 2, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 5, 2, 0, 0);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_SPRITE, 6, 1);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
@@ -4152,7 +4166,7 @@ void Scene352::setup() {
void Scene352::putArmDown(bool corridorExit, bool doorwayExit) {
switch (_game._trigger) {
case 0:
- _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 60, _game.getQuote(0xFF));
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0xFF));
_scene->_sequences.addTimer(48, 1);
break;
@@ -4160,12 +4174,12 @@ void Scene352::putArmDown(bool corridorExit, bool doorwayExit) {
_game._player._stepEnabled = false;
_game._player._visible = false;
if (_globals[kSexOfRex] == REX_FEMALE) {
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 5, 2, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 5, 2, 0, 0);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_SPRITE, 5, 2);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
} else {
- _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 5, 2, 0, 0);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 5, 2, 0, 0);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_SPRITE, 6, 2);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
@@ -4197,7 +4211,6 @@ void Scene352::putArmDown(bool corridorExit, bool doorwayExit) {
case 4:
_game._player.walk(Common::Point(116, 107), FACING_NORTH);
- _game._player._stepEnabled = true;
_mustPutArmDownFl = false;
_scene->_sequences.addTimer(180, 5);
_leaveRoomFl = true;
@@ -4261,7 +4274,7 @@ void Scene352::enter() {
_vaultOpenFl = false;
- if (_scene->_priorSceneId != -2) {
+ if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_mustPutArmDownFl = false;
if (!_game._visitedScenes._sceneRevisited)
_globals[kHaveYourStuff] = false;
@@ -4276,7 +4289,7 @@ void Scene352::enter() {
if (_scene->_priorSceneId == 353)
_game._player._playerPos = Common::Point(171, 155);
- else if (_scene->_priorSceneId != -2)
+ else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG)
_game._player._playerPos = Common::Point(116, 107);
sceneEntrySound();
@@ -4305,7 +4318,7 @@ void Scene352::preActions() {
_game._player._stepEnabled = false;
_scene->_sequences.remove(_commonSequenceIdx);
_vm->_sound->command(20);
- _commonSequenceIdx = _scene->_sequences.startReverseCycle(_commonSpriteIndex, false, 6, 1, 0, 0);
+ _commonSequenceIdx = _scene->_sequences.addReverseSpriteCycle(_commonSpriteIndex, false, 6, 1, 0, 0);
_scene->_sequences.addSubEntry(_commonSequenceIdx, SEQUENCE_TRIGGER_EXPIRE, 0, 1);
_scene->_sequences.setDepth(_commonSequenceIdx, 15);
}
@@ -4364,7 +4377,7 @@ void Scene352::actions() {
case 1: {
_vm->_sound->command(21);
- _globals._sequenceIndexes[12] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[12], false, 7, 2, 20, 0);
+ _globals._sequenceIndexes[12] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[12], false, 7, 2, 20, 0);
_scene->_sequences.setDepth(_globals._sequenceIndexes[12], FACING_NORTH);
int oldIdx = _commonSequenceIdx;
_commonSequenceIdx = _scene->_sequences.startCycle(_commonSpriteIndex, false, -2);
@@ -4376,7 +4389,7 @@ void Scene352::actions() {
case 2:
_vm->_sound->command(22);
_scene->_sequences.remove(_commonSequenceIdx);
- _commonSequenceIdx = _scene->_sequences.startReverseCycle(_commonSpriteIndex, false, 8, 1, 0, 0);
+ _commonSequenceIdx = _scene->_sequences.startPingPongCycle(_commonSpriteIndex, false, 8, 1, 0, 0);
_scene->_sequences.setAnimRange(_commonSequenceIdx, 1, 3);
_scene->_sequences.addSubEntry(_commonSequenceIdx, SEQUENCE_TRIGGER_EXPIRE, 0, 3);
break;
@@ -4431,12 +4444,12 @@ void Scene352::actions() {
_game._player._stepEnabled = false;
_game._player._visible = false;
if (_globals[kSexOfRex] == REX_FEMALE) {
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 5, 2, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 5, 2, 0, 0);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_SPRITE, 5, 1);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
} else {
- _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 5, 2, 0, 0);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 5, 2, 0, 0);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_SPRITE, 6, 1);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
@@ -4478,7 +4491,7 @@ void Scene352::actions() {
case 1: {
_vm->_sound->command(21);
- _globals._sequenceIndexes[12] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[12], false, 7, 2, 20, 0);
+ _globals._sequenceIndexes[12] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[12], false, 7, 2, 20, 0);
_scene->_sequences.setDepth(_globals._sequenceIndexes[12], 8);
int oldIdx = _commonSequenceIdx;
_commonSequenceIdx = _scene->_sequences.startCycle(_commonSpriteIndex, false, -2);
@@ -4490,7 +4503,7 @@ void Scene352::actions() {
case 2:
_vm->_sound->command(23);
_scene->_sequences.remove(_commonSequenceIdx);
- _commonSequenceIdx = _scene->_sequences.startReverseCycle(_commonSpriteIndex, false, 8, 1, 0, 0);
+ _commonSequenceIdx = _scene->_sequences.addReverseSpriteCycle(_commonSpriteIndex, false, 8, 1, 0, 0);
_scene->_sequences.setAnimRange(_commonSequenceIdx, 1, 4);
_scene->_sequences.addSubEntry(_commonSequenceIdx, SEQUENCE_TRIGGER_EXPIRE, 0, 3);
break;
@@ -4545,13 +4558,13 @@ void Scene352::actions() {
_game._player._stepEnabled = false;
_game._player._visible = false;
if (_globals[kSexOfRex] == REX_MALE) {
- _globals._sequenceIndexes[14] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[14], false, 8, 1, 0, 0);
+ _globals._sequenceIndexes[14] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[14], false, 8, 1, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[14], 1, 2);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[14]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[14], SEQUENCE_TRIGGER_SPRITE, 2, 1);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[14], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
} else {
- _globals._sequenceIndexes[15] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[15], false, 8, 1, 0, 0);
+ _globals._sequenceIndexes[15] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[15], false, 8, 1, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[15], 1, 2);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[15]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[15], SEQUENCE_TRIGGER_SPRITE, 2, 1);
@@ -4592,12 +4605,12 @@ void Scene352::actions() {
_game._player._stepEnabled = false;
_game._player._visible = false;
if (_globals[kSexOfRex] == REX_MALE) {
- _globals._sequenceIndexes[6] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[6], true, 6, 2, 0, 0);
+ _globals._sequenceIndexes[6] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[6], true, 6, 2, 0, 0);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[6]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[6], SEQUENCE_TRIGGER_SPRITE, 6, 1);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[6], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
} else {
- _globals._sequenceIndexes[7] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[7], true, 6, 2, 0, 0);
+ _globals._sequenceIndexes[7] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[7], true, 6, 2, 0, 0);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[7]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[7], SEQUENCE_TRIGGER_SPRITE, 6, 1);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[7], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
@@ -4745,7 +4758,7 @@ void Scene354::enter() {
_game._player._facing = FACING_NORTH;
} else if (_scene->_priorSceneId == 316)
_game._player._playerPos = Common::Point(71, 107);
- else if (_scene->_priorSceneId != -2)
+ else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG)
_game._player._playerPos = Common::Point(167, 57);
sceneEntrySound();
@@ -4812,7 +4825,7 @@ void Scene357::enter() {
_game._player._playerPos = Common::Point(298, 142);
else if (_scene->_priorSceneId == 313)
_game._player._playerPos = Common::Point(127, 101);
- else if (_scene->_priorSceneId != -2)
+ else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG)
_game._player._playerPos = Common::Point(15, 148);
sceneEntrySound();
@@ -4876,7 +4889,7 @@ void Scene358::enter() {
if (_scene->_priorSceneId == 357)
_game._player._playerPos = Common::Point(305, 142);
- else if (_scene->_priorSceneId != -2)
+ else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG)
_game._player._playerPos = Common::Point(12, 141);
sceneEntrySound();
@@ -4952,7 +4965,7 @@ void Scene359::enter() {
if (_scene->_priorSceneId == 358)
_game._player._playerPos = Common::Point(301, 141);
- else if (_scene->_priorSceneId != -2)
+ else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG)
_game._player._playerPos = Common::Point(15, 148);
sceneEntrySound();
@@ -4980,12 +4993,12 @@ void Scene359::actions() {
_game._player._visible = false;
_vm->_dialogs->show(35920);
if (_globals[kSexOfRex] == REX_MALE) {
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 4, 2, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 4, 2, 0, 0);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 6, 1);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
} else {
- _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], true, 7, 2, 0, 0);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], true, 7, 2, 0, 0);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
_scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(106, 110));
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_SPRITE, 6, 1);
@@ -5075,7 +5088,7 @@ void Scene360::enter() {
if (_scene->_priorSceneId == 359)
_game._player._playerPos = Common::Point(304, 143);
- else if (_scene->_priorSceneId != -2)
+ else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG)
_game._player._playerPos = Common::Point(13, 141);
sceneEntrySound();
@@ -5341,7 +5354,7 @@ void Scene361::enter() {
else if (_scene->_priorSceneId == 320) {
_game._player._playerPos = Common::Point(129, 113);
_game._player._facing = FACING_SOUTH;
- } else if (_scene->_priorSceneId != -2)
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG)
_game._player._playerPos = Common::Point(13, 145);
_game.loadQuoteSet(0xFB, 0xFC, 0);
@@ -5466,7 +5479,7 @@ void Scene361::actions() {
_vm->_dialogs->show(36119);
else if (_action.isAction(VERB_SIT_AT, NOUN_DESK)) {
_scene->_kernelMessages.reset();
- _scene->_kernelMessages.addQuote(0xFC, 120, 0);
+ _scene->_kernelMessages.addQuote(252, 0, 120);
} else if (_action.isAction(VERB_CLIMB_INTO, NOUN_AIR_VENT)) {
if (_globals[kSexOfRex] == REX_FEMALE)
handleRoxAction();
diff --git a/engines/mads/nebular/nebular_scenes3.h b/engines/mads/nebular/nebular_scenes3.h
index 9efd38e9a4..cf925b3867 100644
--- a/engines/mads/nebular/nebular_scenes3.h
+++ b/engines/mads/nebular/nebular_scenes3.h
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/nebular/nebular_scenes4.cpp b/engines/mads/nebular/nebular_scenes4.cpp
index 56f6fb4466..c981f6a6e4 100644
--- a/engines/mads/nebular/nebular_scenes4.cpp
+++ b/engines/mads/nebular/nebular_scenes4.cpp
@@ -8,12 +8,12 @@
* 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
+ * 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.
@@ -113,7 +113,7 @@ void Scene401::setup() {
}
void Scene401::enter() {
- if (_scene->_priorSceneId != -2)
+ if (_scene->_priorSceneId != RETURNING_FROM_DIALOG)
_northFl = false;
_timer = 0;
@@ -125,7 +125,7 @@ void Scene401::enter() {
_game._player._playerPos = Common::Point(149, 90);
_game._player._facing = FACING_SOUTH;
_northFl = true;
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(142, 131);
_game._player._facing = FACING_NORTH;
}
@@ -718,7 +718,7 @@ void Scene402::enter() {
_roxOnStool = false;
_bartenderDialogNode = 1;
_conversationFl = false;
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(160, 150);
_game._player._facing = FACING_NORTH;
_game._objects.addToInventory(OBJ_CREDIT_CHIP);
@@ -962,7 +962,7 @@ void Scene402::step() {
}
if (!_bartenderTalking) {
- _globals._sequenceIndexes[10] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[10], false, 7, 0, 0, 0);
+ _globals._sequenceIndexes[10] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[10], false, 7, 0, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[10], 3, 4);
_scene->_sequences.setDepth(_globals._sequenceIndexes[10], 8);
int idx = _scene->_dynamicHotspots.add(NOUN_BARTENDER, VERB_WALKTO, _globals._sequenceIndexes[10], Common::Rect(0, 0, 0, 0));
@@ -1514,7 +1514,7 @@ void Scene402::step() {
break;
case 3:
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 12, 2, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 12, 2, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 4, 5);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 32);
_rightWomanMoving = true;
@@ -1697,7 +1697,7 @@ void Scene402::step() {
_scene->_kernelMessages.add(Common::Point(171, 47), 0xFBFA, 0, 0, 130, _game.getQuote(0x200));
_scene->_sequences.addTimer(150, 63);
_scene->_sequences.remove(_globals._sequenceIndexes[13]);
- _globals._sequenceIndexes[13] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[13], false, 30, 4, 0, 0);
+ _globals._sequenceIndexes[13] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[13], false, 30, 4, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], 10, 11);
_scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 62);
@@ -1769,7 +1769,7 @@ void Scene402::step() {
case 69: {
int seqIdx = _globals._sequenceIndexes[13];
- _globals._sequenceIndexes[13] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[13], false, 25, 4, 0, 0);
+ _globals._sequenceIndexes[13] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[13], false, 25, 4, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], 10, 11);
_scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
_scene->_sequences.updateTimeout(_globals._sequenceIndexes[13], seqIdx);
@@ -1783,7 +1783,7 @@ void Scene402::step() {
break;
case 70:
- _globals._sequenceIndexes[13] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[13], false, 25, 4, 0, 0);
+ _globals._sequenceIndexes[13] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[13], false, 25, 4, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], 10, 12);
_scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 72);
@@ -1840,7 +1840,7 @@ void Scene402::step() {
_cutSceneReady = false;
_helgaReady = false;
_scene->_sequences.remove(_globals._sequenceIndexes[13]);
- _globals._sequenceIndexes[13] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[13], false, 15, 2, 0, 0);
+ _globals._sequenceIndexes[13] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[13], false, 15, 2, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], 11, 13);
_scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 26);
@@ -1860,7 +1860,7 @@ void Scene402::step() {
_cutSceneReady = false;
_helgaReady = false;
_scene->_sequences.remove(_globals._sequenceIndexes[13]);
- _globals._sequenceIndexes[13] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[13], false, 15, 2, 0, 0);
+ _globals._sequenceIndexes[13] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[13], false, 15, 2, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], 14, 15);
_scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 26);
@@ -2069,7 +2069,7 @@ void Scene402::actions() {
if (_game._trigger == 0) {
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[21] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[21], false, 7, 2, 0, 0);
+ _globals._sequenceIndexes[21] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[21], false, 7, 2, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[21], 1, 2);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[21]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[21], SEQUENCE_TRIGGER_SPRITE, 2, 165);
@@ -2202,7 +2202,7 @@ void Scene402::actions() {
_game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[22] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[22], false, 7, 2, 0, 0);
+ _globals._sequenceIndexes[22] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[22], false, 7, 2, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[22], 1, 2);
_scene->_sequences.setPosition(_globals._sequenceIndexes[22], Common::Point(_game._player._playerPos.x, _game._player._playerPos.y + 1));
_scene->_sequences.setDepth(_globals._sequenceIndexes[22], 5);
@@ -2411,7 +2411,7 @@ void Scene405::enter() {
} else if (_scene->_priorSceneId == 413) {
_game._player._playerPos = Common::Point(284, 109);
_game._player._facing = FACING_SOUTH;
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(23, 123);
_game._player._facing = FACING_EAST;
}
@@ -2445,7 +2445,7 @@ void Scene405::step() {
if (_game._trigger == 70) {
_game._player._priorTimer = _scene->_frameStartTime + _game._player._ticksAmount ;
_game._player._visible = true;
- _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0);
+ _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);
_vm->_sound->command(19);
}
@@ -2495,7 +2495,7 @@ void Scene405::actions() {
_game._player._stepEnabled = false;
_game._player._visible = false;
_game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 7, 2, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 7, 2, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 2);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 75);
Common::Point msgPos = Common::Point(_game._player._playerPos.x, _game._player._playerPos.y + 1);
@@ -2505,7 +2505,7 @@ void Scene405::actions() {
_game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 7, 2, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 7, 2, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 2);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 70);
_scene->_sequences.setPosition(_globals._sequenceIndexes[3], _game._player._playerPos);
@@ -2514,7 +2514,7 @@ void Scene405::actions() {
_game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 7, 2, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 7, 2, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 2);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 80);
_scene->_sequences.setPosition(_globals._sequenceIndexes[3], _game._player._playerPos);
@@ -2587,7 +2587,7 @@ void Scene406::enter() {
} else if (_scene->_priorSceneId == 411) {
_game._player._playerPos = Common::Point(153, 108);
_game._player._facing = FACING_SOUTH;
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(15, 129);
_game._player._facing = FACING_EAST;
}
@@ -2609,7 +2609,7 @@ void Scene406::enter() {
else {
_game._player._stepEnabled = false;
_game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 3, 1, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[3], false, 3, 1, 0, 0);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 90);
_vm->_sound->command(19);
}
@@ -2647,7 +2647,7 @@ void Scene406::step() {
if (_game._trigger == 70) {
_game._player._priorTimer = _scene->_frameStartTime + _game._player._ticksAmount;
_game._player._visible = true;
- _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 4, 1, 0, 0);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[1], false, 4, 1, 0, 0);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
_vm->_sound->command(19);
}
@@ -2703,7 +2703,7 @@ void Scene406::actions() {
_game._player._stepEnabled = false;
_game._player._visible = false;
_game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 7, 2, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 7, 2, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 2);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 75);
Common::Point msgPos = Common::Point(_game._player._playerPos.x, _game._player._playerPos.y + 1);
@@ -2713,7 +2713,7 @@ void Scene406::actions() {
_game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 7, 2, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 7, 2, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 2);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 70);
Common::Point msgPos = Common::Point(_game._player._playerPos.x, _game._player._playerPos.y + 1);
@@ -2723,7 +2723,7 @@ void Scene406::actions() {
_game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 7, 2, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 7, 2, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 2);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 110);
_scene->_sequences.setPosition(_globals._sequenceIndexes[2], _game._player._playerPos);
@@ -2791,14 +2791,14 @@ void Scene407::setup() {
}
void Scene407::enter() {
- if (_scene->_priorSceneId != -2)
+ if (_scene->_priorSceneId != RETURNING_FROM_DIALOG)
_fromNorth = false;
if (_scene->_priorSceneId == 318) {
_game._player._playerPos = Common::Point(172, 92);
_game._player._facing = FACING_SOUTH;
_fromNorth = true;
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(172, 132);
_game._player._facing = FACING_NORTH;
}
@@ -2934,7 +2934,7 @@ void Scene408::actions() {
_vm->_sound->command(57);
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], true, 7, 2, 0, 0);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[1], true, 7, 2, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[1], 1, 2);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[1]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_SPRITE, 2, 1);
@@ -3118,7 +3118,7 @@ void Scene410::enter() {
else
_scene->_hotspots.activate(NOUN_CHARGE_CASES, false);
- if (_scene->_priorSceneId != -2) {
+ if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(155, 150);
_game._player._facing = FACING_NORTH;
}
@@ -3182,7 +3182,7 @@ void Scene410::actions() {
_vm->_sound->command(57);
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 7, 2, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 7, 2, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 3);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 3, 1);
@@ -3646,7 +3646,7 @@ void Scene411::enter() {
_scene->_dynamicHotspots.setPosition(idx, Common::Point(220, 121), FACING_NORTHEAST);
}
- if (_scene->_priorSceneId != -2) {
+ if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(60, 146);
_game._player._facing = FACING_NORTHEAST;
}
@@ -3842,7 +3842,7 @@ void Scene411::actions() {
_vm->_sound->command(57);
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[8] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[8], false, 7, 2, 0, 0);
+ _globals._sequenceIndexes[8] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[8], false, 7, 2, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[8], 1, 2);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[8]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[8], SEQUENCE_TRIGGER_SPRITE, 2, 1);
@@ -3879,7 +3879,7 @@ void Scene411::actions() {
_vm->_sound->command(57);
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[8] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[8], false, 7, 2, 0, 0);
+ _globals._sequenceIndexes[8] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[8], false, 7, 2, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[8], 1, 2);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[8]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[8], SEQUENCE_TRIGGER_SPRITE, 2, 1);
@@ -4058,7 +4058,7 @@ void Scene413::enter() {
_game._player._playerPos = Common::Point(142, 146);
_game._player._facing = FACING_NORTH;
_game._player._visible = true;
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
if (_globals[kSexOfRex] == REX_MALE) {
_scene->loadAnimation(Resources::formatName(413, 'd', 1, EXT_AA, ""), 78);
_vm->_sound->command(30);
@@ -4078,7 +4078,7 @@ void Scene413::enter() {
case 1:
_vm->_sound->command(30);
_game._player._visible = false;
- _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 7, 1, 0, 0);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[1], false, 7, 1, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[1], 1, 19);
_scene->_sequences.setDepth(_globals._sequenceIndexes[1], 8);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 76);
diff --git a/engines/mads/nebular/nebular_scenes4.h b/engines/mads/nebular/nebular_scenes4.h
index fbd5ce81f0..de11bd4129 100644
--- a/engines/mads/nebular/nebular_scenes4.h
+++ b/engines/mads/nebular/nebular_scenes4.h
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/nebular/nebular_scenes5.cpp b/engines/mads/nebular/nebular_scenes5.cpp
index 66d8294fc6..95eb429193 100644
--- a/engines/mads/nebular/nebular_scenes5.cpp
+++ b/engines/mads/nebular/nebular_scenes5.cpp
@@ -8,12 +8,12 @@
* 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
+ * 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.
@@ -132,7 +132,7 @@ void Scene501::handleSlotActions() {
frameIndex = 2;
}
- _mainSequenceId = _scene->_sequences.startReverseCycle(_mainSpriteId, false, numTicks, 1, 0, 0);
+ _mainSequenceId = _scene->_sequences.startPingPongCycle(_mainSpriteId, false, numTicks, 1, 0, 0);
_scene->_sequences.setAnimRange(_mainSequenceId, 1, frameIndex);
_scene->_sequences.setMsgLayout(_mainSequenceId);
_vm->_sound->command(10);
@@ -199,7 +199,7 @@ void Scene501::enter() {
_game._player._playerPos = Common::Point(317, 102);
_game._player._facing = FACING_SOUTHWEST;
_scene->_sequences.addTimer(15, 80);
- } else if (_scene->_priorSceneId != -2)
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG)
_game._player._playerPos = Common::Point(299, 131);
if (_scene->_roomChanged) {
@@ -238,7 +238,7 @@ void Scene501::step() {
break;
case 82:
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 9, 1, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[3], false, 9, 1, 0, 0);
_scene->_sequences.setDepth(_globals._sequenceIndexes[3], 7);
_vm->_sound->command(12);
_doorHotspotid = _scene->_dynamicHotspots.add(NOUN_DOOR, VERB_WALK_THROUGH, _globals._sequenceIndexes[3], Common::Rect(0, 0, 0, 0));
@@ -273,7 +273,7 @@ void Scene501::step() {
case 72:
_scene->_sequences.remove(_globals._sequenceIndexes[2]);
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 6, 1, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[2], false, 6, 1, 0, 0);
_scene->_sequences.setDepth(_globals._sequenceIndexes[2], 4);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 73);
break;
@@ -415,7 +415,7 @@ void Scene501::actions() {
case 7: {
_vm->_sound->command(12);
int syncIdx = _globals._sequenceIndexes[3];
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 9, 1, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[3], false, 9, 1, 0, 0);
_scene->_sequences.setDepth(_globals._sequenceIndexes[3], 7);
_scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], syncIdx);
_vm->_sound->command(12);
@@ -563,7 +563,7 @@ void Scene503::enter() {
_scene->_dynamicHotspots.setPosition(_detonatorHotspotId, Common::Point(254, 135), FACING_SOUTH);
}
- if (_scene->_priorSceneId != -2) {
+ if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(191, 152);
_game._player._facing = FACING_NORTHWEST;
}
@@ -581,13 +581,13 @@ void Scene503::actions() {
_game._player._stepEnabled = false;
_game._player._visible = false;
if (_globals[kSexOfRex] == REX_MALE) {
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 8, 1, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 8, 1, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 3);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 3, 1);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
} else {
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], true, 8, 1, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], true, 8, 1, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 4);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_SPRITE, 4, 1);
@@ -709,7 +709,7 @@ void Scene504::enter() {
_globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('a', 3));
_carAnimationMode = 1;
_scene->loadAnimation(formAnimName('A', -1));
- if ((_scene->_priorSceneId != -2) && (_scene->_priorSceneId != 505))
+ if ((_scene->_priorSceneId != RETURNING_FROM_DIALOG) && (_scene->_priorSceneId != 505))
_globals[kHoverCarLocation] = _scene->_priorSceneId;
_globals._sequenceIndexes[7] = _scene->_sequences.startCycle(_globals._spriteIndexes[7], false, 1);
@@ -800,7 +800,7 @@ void Scene504::actions() {
case 1: {
int syncIdx = _globals._sequenceIndexes[3];
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 6, 1, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[3], false, 6, 1, 0, 0);
_scene->_sequences.setDepth(_globals._sequenceIndexes[3], 13);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 6);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
@@ -912,8 +912,8 @@ void Scene505::enter() {
_globals._spriteIndexes[11] = _scene->_sprites.addSprites(formAnimName('t', -1));
_globals._spriteIndexes[12] = _scene->_sprites.addSprites(formAnimName('e', -1));
- if (_scene->_priorSceneId != -2)
- _globals._sequenceIndexes[12] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[12], false, 6, 1, 0, 0);
+ if (_scene->_priorSceneId != RETURNING_FROM_DIALOG)
+ _globals._sequenceIndexes[12] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[12], false, 6, 1, 0, 0);
_globals._sequenceIndexes[13] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[13], false, 6, 1, 120, 0);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 60);
@@ -934,7 +934,7 @@ void Scene505::enter() {
for (int i = 0; i < 9; i++) {
if (_globals[kHoverCarLocation] == _carLocations[i]) {
_homeSelectedId = i;
- if (_scene->_priorSceneId != -2)
+ if (_scene->_priorSceneId != RETURNING_FROM_DIALOG)
_selectedId = i;
}
}
@@ -996,7 +996,7 @@ void Scene505::step() {
_scene->_sequences.remove(_globals._sequenceIndexes[1]);
_scene->_sequences.remove(_globals._sequenceIndexes[0]);
_scene->_sequences.remove(_globals._sequenceIndexes[13]);
- _globals._sequenceIndexes[13] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[13], false, 6, 1, 0, 0);
+ _globals._sequenceIndexes[13] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[13], false, 6, 1, 0, 0);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 63);
_vm->_sound->command(18);
}
@@ -1222,7 +1222,7 @@ void Scene506::enter() {
_game._player._facing = FACING_SOUTHEAST;
_scene->_sequences.addTimer(60, 80);
_game._player._stepEnabled = false;
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(138, 116);
_game._player._facing = FACING_NORTHEAST;
_game._player._visible = false;
@@ -1260,7 +1260,7 @@ void Scene506::step() {
case 71:
_scene->_sequences.remove(_globals._sequenceIndexes[3]);
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 6, 1, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[3], false, 6, 1, 0, 0);
_scene->_sequences.setDepth(_globals._sequenceIndexes[3], 5);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 72);
break;
@@ -1317,7 +1317,7 @@ void Scene506::handleDoorSequences() {
case 82:
_scene->_sequences.remove(_doorSequenceIdx);
- _doorSequenceIdx = _scene->_sequences.startReverseCycle(_doorSpriteIdx, false, 7, 1, 0, 0);
+ _doorSequenceIdx = _scene->_sequences.addReverseSpriteCycle(_doorSpriteIdx, false, 7, 1, 0, 0);
_scene->_sequences.setDepth(_doorSequenceIdx, _doorDepth);
if (_actionFl)
_scene->_sequences.addSubEntry(_doorSequenceIdx, SEQUENCE_TRIGGER_EXPIRE, 0, 84);
@@ -1471,7 +1471,7 @@ void Scene507::enter() {
_scene->_dynamicHotspots.setPosition(_penlightHotspotId, Common::Point(233, 152), FACING_SOUTHEAST);
}
- if (_scene->_priorSceneId != -2) {
+ if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(121, 147);
_game._player._facing = FACING_NORTH;
}
@@ -1487,7 +1487,7 @@ void Scene507::actions() {
case 0:
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 6, 1, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 6, 1, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 5);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 5, 1);
@@ -1547,7 +1547,9 @@ void Scene507::actions() {
_vm->_dialogs->show(50724);
else if (_action.isAction(VERB_LOOK, NOUN_WINDOW))
_vm->_dialogs->show(50725);
- else if (_action.isAction(VERB_LOOK, NOUN_COUNTER)) {
+ else if (_action.isAction(VERB_WALK_BEHIND, NOUN_COUNTER)) {
+ // WORKAROUND: Empty handling to prevent default "can't do that" dialogs showing
+ } else if (_action.isAction(VERB_LOOK, NOUN_COUNTER)) {
if (_game._objects.isInRoom(OBJ_PENLIGHT))
_vm->_dialogs->show(50728);
else
@@ -1613,7 +1615,7 @@ void Scene508::enter() {
_scene->_sequences.setDepth(_globals._sequenceIndexes[4], 11);
int idx = _scene->_dynamicHotspots.add(NOUN_LASER_BEAM, VERB_WALKTO, _globals._sequenceIndexes[4], Common::Rect(0, 0, 0, 0));
_scene->_dynamicHotspots.setPosition(idx, Common::Point(57, 116), FACING_NORTHEAST);
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 15, 0, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 15, 0, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 6, 8);
_scene->_sequences.setDepth(_globals._sequenceIndexes[2], 6);
if (_globals[kLaserHoleIsThere]) {
@@ -1628,7 +1630,7 @@ void Scene508::enter() {
if (_scene->_priorSceneId == 515) {
_game._player._playerPos = Common::Point(57, 116);
_game._player._facing = FACING_NORTHEAST;
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(289, 139);
_game._player._facing = FACING_WEST;
}
@@ -1659,7 +1661,7 @@ void Scene508::handlePedestral() {
case 0:
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[6] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[6], false, 9, 1, 0, 0);
+ _globals._sequenceIndexes[6] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[6], false, 9, 1, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[6], 1, 4);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[6]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[6], SEQUENCE_TRIGGER_SPRITE, 4, 1);
@@ -1732,7 +1734,7 @@ void Scene508::actions() {
break;
case 4:
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 15, 0, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 15, 0, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 6, 8);
_scene->_sequences.setDepth(_globals._sequenceIndexes[2], 6);
break;
@@ -1866,7 +1868,7 @@ void Scene511::enter() {
_globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('c', 0));
_globals._spriteIndexes[4] = _scene->_sprites.addSprites("*RXCD_6");
- if (_scene->_priorSceneId != -2)
+ if (_scene->_priorSceneId != RETURNING_FROM_DIALOG)
_handingLine = false;
if (_globals[kBoatRaised]) {
@@ -1921,7 +1923,7 @@ void Scene511::enter() {
if (_scene->_priorSceneId == 512) {
_game._player._playerPos = Common::Point(60, 112);
_game._player._facing = FACING_SOUTHEAST;
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(55, 152);
_game._player._facing = FACING_NORTHWEST;
_game._player._visible = false;
@@ -2024,7 +2026,7 @@ void Scene511::actions() {
case 0:
_game._player._stepEnabled = false;
_scene->_sequences.remove(_globals._sequenceIndexes[1]);
- _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0);
_scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
break;
@@ -2064,6 +2066,7 @@ void Scene511::actions() {
if (_game._trigger == 0) {
_game._player._stepEnabled = false;
_game._player._visible = false;
+ _game._player.update();
_lineAnimationMode = 1;
_lineAnimationPosition = 1;
_lineMoving = true;
@@ -2086,7 +2089,8 @@ void Scene511::actions() {
} else {
_vm->_dialogs->show(51130);
}
- } else if (_action.isAction(VERB_TIE, NOUN_FISHING_LINE, NOUN_BOAT) || _action.isAction(VERB_ATTACH, NOUN_FISHING_LINE, NOUN_BOAT)) {
+ } else if (_action.isAction(VERB_TIE, NOUN_FISHING_LINE, NOUN_BOAT) ||
+ _action.isAction(VERB_ATTACH, NOUN_FISHING_LINE, NOUN_BOAT)) {
if (_globals[kBoatRaised])
_vm->_dialogs->show(51131);
else if (_globals[kLineStatus] == 1)
@@ -2104,7 +2108,6 @@ void Scene511::actions() {
_scene->_sequences.addTimer(1, 1);
else {
_game._player._visible = true;
- _game._player._priorTimer = _scene->_frameStartTime - _game._player._ticksAmount;
_globals._sequenceIndexes[7] = _scene->_sequences.startCycle(_globals._spriteIndexes[7], false, -2);
_scene->_sequences.setDepth(_globals._sequenceIndexes[7], 4);
int idx = _scene->_dynamicHotspots.add(NOUN_FISHING_LINE, VERB_WALKTO, _globals._sequenceIndexes[7], Common::Rect(0, 0, 0, 0));
@@ -2114,6 +2117,10 @@ void Scene511::actions() {
_lineMoving = true;
_globals[kLineStatus] = 3;
_game._player._stepEnabled = true;
+
+ if (_scene->_activeAnimation)
+ _scene->_activeAnimation->eraseSprites();
+ _game._player.update();
}
}
}
@@ -2240,7 +2247,7 @@ void Scene512::enter() {
} else
_scene->_hotspots.activate(NOUN_PADLOCK_KEY, false);
- if (_scene->_priorSceneId != -2) {
+ if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(144, 152);
_game._player._facing = FACING_NORTHEAST;
}
@@ -2257,7 +2264,7 @@ void Scene512::actions() {
case 0:
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 8, 1, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 8, 1, 0, 0);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 5, 1);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
@@ -2293,7 +2300,7 @@ void Scene512::actions() {
case 1:
_game._player._visible = false;
- _globals._sequenceIndexes[8] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[8], false, 9, 1, 0, 0);
+ _globals._sequenceIndexes[8] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[8], false, 9, 1, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[8], 1, 3);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[8]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[8], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
@@ -2326,7 +2333,7 @@ void Scene512::actions() {
break;
case 5:
- _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], false, 14, 0, 0, 0);
+ _globals._sequenceIndexes[5] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[5], false, 14, 0, 0, 0);
_scene->_sequences.setDepth(_globals._sequenceIndexes[5], 3);
_scene->_hotspots.activate(NOUN_PADLOCK_KEY, true);
_scene->_sequences.addTimer(60, 6);
@@ -2347,7 +2354,7 @@ void Scene512::actions() {
case 0:
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 10, 1, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 10, 1, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 2);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
@@ -2358,12 +2365,12 @@ void Scene512::actions() {
_game._player._visible = true;
if (!_game._objects.isInRoom(OBJ_PADLOCK_KEY) || _game._difficulty == DIFFICULTY_EASY) {
_scene->_sequences.remove(_globals._sequenceIndexes[3]);
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 12, 1, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 12, 1, 0, 0);
_scene->_sequences.setDepth(_globals._sequenceIndexes[3], 3);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
} else {
_scene->_sequences.remove(_globals._sequenceIndexes[5]);
- _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 12, 1, 0, 0);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 12, 1, 0, 0);
_scene->_sequences.setDepth(_globals._sequenceIndexes[4], 3);
_scene->_hotspots.activate(NOUN_PADLOCK_KEY, false);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
@@ -2391,7 +2398,7 @@ void Scene512::actions() {
else
endVal = 2;
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 10, 1, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 10, 1, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, endVal);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, endVal, 1);
@@ -2427,7 +2434,8 @@ void Scene512::actions() {
_vm->_dialogs->show(51225);
else if (_action.isAction(VERB_LOOK, NOUN_PADLOCK_KEY) && _game._objects.isInRoom(OBJ_PADLOCK_KEY))
_vm->_dialogs->show(51215);
- else if (_action.isAction(VERB_LOOK, NOUN_FISHING_ROD) && (_scene->_activeAnimation->getCurrentFrame() == 4))
+ else if (_action.isAction(VERB_LOOK, NOUN_FISHING_ROD) && (!_scene->_activeAnimation ||
+ _scene->_activeAnimation->getCurrentFrame() == 4))
_vm->_dialogs->show(51216);
else if (_action.isAction(VERB_LOOK, NOUN_SHIPS_WHEEL))
_vm->_dialogs->show(51218);
@@ -2460,7 +2468,9 @@ void Scene512::actions() {
_vm->_dialogs->show(51233);
else if (_action.isAction(VERB_LOOK, NOUN_LAMP))
_vm->_dialogs->show(51234);
- else if (_action.isAction(VERB_LOOK, NOUN_COUNTER))
+ else if (_action.isAction(VERB_WALK_BEHIND, NOUN_COUNTER)) {
+ // WORKAROUND: Empty handling to prevent default "can't do that" dialogs showing
+ } else if (_action.isAction(VERB_LOOK, NOUN_COUNTER))
_vm->_dialogs->show(51235);
else if (_action.isAction(VERB_LOOK, NOUN_ICE_CHESTS))
_vm->_dialogs->show(51237);
@@ -2505,7 +2515,7 @@ void Scene513::enter() {
_game._player._facing = FACING_WEST;
_game._player._stepEnabled = false;
_scene->_sequences.addTimer(15, 80);
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(63, 149);
_game._player._facing = FACING_NORTHEAST;
_game._player._visible = false;
@@ -2529,7 +2539,7 @@ void Scene513::step() {
case 80:
_game._player._stepEnabled = false;
_scene->_sequences.remove(_globals._sequenceIndexes[2]);
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0);
_scene->_sequences.setDepth(_globals._sequenceIndexes[2], 2);
_vm->_sound->command(24);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 81);
@@ -2588,7 +2598,7 @@ void Scene513::actions() {
case 0:
_game._player._stepEnabled = false;
_scene->_sequences.remove(_globals._sequenceIndexes[1]);
- _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0);
_scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
break;
@@ -2626,7 +2636,7 @@ void Scene513::actions() {
case 0:
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 7, 1, 0, 0);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 7, 1, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 1, 2);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
@@ -2636,7 +2646,7 @@ void Scene513::actions() {
_scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[4]);
_game._player._visible = true;
_scene->_sequences.remove(_globals._sequenceIndexes[2]);
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0);
_scene->_sequences.setDepth(_globals._sequenceIndexes[2], 2);
_vm->_sound->command(24);
_scene->_kernelMessages.reset();
@@ -2739,7 +2749,7 @@ void Scene551::enter() {
if (_scene->_priorSceneId == 501)
_game._player._playerPos = Common::Point(18, 130);
- else if (_scene->_priorSceneId != -2) {
+ else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(124, 119);
_game._player._facing = FACING_NORTH;
}
diff --git a/engines/mads/nebular/nebular_scenes5.h b/engines/mads/nebular/nebular_scenes5.h
index 2face26508..f314ae8513 100644
--- a/engines/mads/nebular/nebular_scenes5.h
+++ b/engines/mads/nebular/nebular_scenes5.h
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/nebular/nebular_scenes6.cpp b/engines/mads/nebular/nebular_scenes6.cpp
index 679039535f..d97e37ea0b 100644
--- a/engines/mads/nebular/nebular_scenes6.cpp
+++ b/engines/mads/nebular/nebular_scenes6.cpp
@@ -8,12 +8,12 @@
* 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
+ * 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.
@@ -112,7 +112,7 @@ void Scene601::enter() {
_globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -2);
_scene->_sequences.setDepth(_globals._sequenceIndexes[2], 3);
_scene->loadAnimation(formAnimName('R', 1), 70);
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(229, 129);
_game._player._facing = FACING_SOUTHWEST;
}
@@ -130,7 +130,7 @@ void Scene601::step() {
case 71:
_scene->_sequences.remove(_globals._sequenceIndexes[2]);
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 6, 1, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[2], false, 6, 1, 0, 0);
_scene->_sequences.setDepth(_globals._sequenceIndexes[2], 3);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 72);
break;
@@ -293,7 +293,7 @@ void Scene602::enter() {
if (_scene->_priorSceneId == 603) {
_game._player._playerPos = Common::Point(228, 126);
_game._player._facing = FACING_WEST;
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(50, 127);
_game._player._facing = FACING_EAST;
}
@@ -313,7 +313,7 @@ void Scene602::handleSafeActions() {
case 0:
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], true, 12, 1, 0, 0);
+ _globals._sequenceIndexes[5] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[5], true, 12, 1, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 1, 3);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_SPRITE, 3, 1);
@@ -348,7 +348,7 @@ void Scene602::handleSafeActions() {
else
_lastSpriteIdx = _globals._spriteIndexes[3];
- _lastSequenceIdx = _scene->_sequences.startReverseCycle(_lastSpriteIdx, false, 12, 1, 0, 0);
+ _lastSequenceIdx = _scene->_sequences.startPingPongCycle(_lastSpriteIdx, false, 12, 1, 0, 0);
_scene->_sequences.setDepth(_lastSequenceIdx, 14);
if (_game._objects[OBJ_DOOR_KEY]._roomNumber == _scene->_currentSceneId)
_scene->_hotspots.activate(NOUN_DOOR_KEY, false);
@@ -460,7 +460,7 @@ void Scene602::actions() {
case 0:
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], true, 8, 1, 0, 0);
+ _globals._sequenceIndexes[5] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[5], true, 8, 1, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 1, 3);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_SPRITE, 3, 1);
@@ -585,7 +585,7 @@ void Scene603::enter() {
_scene->_dynamicHotspots.setPosition(_noteHotspotId, Common::Point(242, 118), FACING_NORTHEAST);
}
- if (_scene->_priorSceneId != -2)
+ if (_scene->_priorSceneId != RETURNING_FROM_DIALOG)
_game._player._playerPos = Common::Point(113, 134);
sceneEntrySound();
@@ -600,7 +600,7 @@ void Scene603::actions() {
case 0:
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 8, 1, 0, 0);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 8, 1, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 1, 5);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_SPRITE, 5, 1);
@@ -750,7 +750,7 @@ void Scene604::enter() {
_vm->_palette->setEntry(253, 45, 24, 17);
_animationActiveFl = false;
- if (_scene->_priorSceneId != -2) {
+ if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(72, 149);
_game._player._facing = FACING_NORTHEAST;
_game._player._visible = false;
@@ -858,7 +858,7 @@ void Scene604::handleBombActions() {
case 0:
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], false, 9, 1, 0, 0);
+ _globals._sequenceIndexes[5] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[5], false, 9, 1, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 1, 3);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
if (_bombMode == 1)
@@ -908,7 +908,7 @@ void Scene604::actions() {
case 0:
_game._player._stepEnabled = false;
_scene->_sequences.remove(_globals._sequenceIndexes[2]);
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 6, 1, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[2], false, 6, 1, 0, 0);
_scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
break;
@@ -948,8 +948,14 @@ void Scene604::actions() {
_bombMode = 1;
if ((_game._difficulty == DIFFICULTY_HARD) || _globals[kWarnedFloodCity])
handleBombActions();
- else if ((_game._objects.isInInventory(OBJ_POLYCEMENT) && _game._objects.isInInventory(OBJ_CHICKEN))
- && ((_globals[kLineStatus] == LINE_TIED) || ((_game._difficulty == DIFFICULTY_EASY) && (!_globals[kBoatRaised]))))
+ else if (
+ (_game._objects.isInInventory(OBJ_POLYCEMENT) && (_game._objects.isInInventory(OBJ_CHICKEN) || _game._objects.isInInventory(OBJ_CHICKEN_BOMB)))
+ && (_globals[kLineStatus] == LINE_TIED || (_game._difficulty == DIFFICULTY_EASY && !_globals[kBoatRaised]))
+ )
+ // The original can get in an impossible state at this point, if the player has
+ // combined the chicken with the bomb before placing the timer bomb on the ledge.
+ // Therefore, we also allow the player to place the bomb if the chicken bomb is
+ // in the inventory.
handleBombActions();
else if (_game._difficulty == DIFFICULTY_EASY)
_vm->_dialogs->show(60424);
@@ -1003,12 +1009,12 @@ void Scene605::enter() {
_globals._spriteIndexes[5] = _scene->_sprites.addSprites(formAnimName('n', -1));
_globals._spriteIndexes[6] = _scene->_sprites.addSprites(formAnimName('f', -1));
- _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 15, 0, 0, 0);
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 17, 0, 0, 0);
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 14, 0, 0, 0);
- _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 13, 0, 0, 0);
- _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], false, 17, 0, 0, 0);
- _globals._sequenceIndexes[6] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[6], false, 18, 0, 0, 0);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[1], false, 15, 0, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 17, 0, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 14, 0, 0, 0);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 13, 0, 0, 0);
+ _globals._sequenceIndexes[5] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[5], false, 17, 0, 0, 0);
+ _globals._sequenceIndexes[6] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[6], false, 18, 0, 0, 0);
_game._player._visible = false;
_game._player._stepEnabled = false;
@@ -1106,7 +1112,7 @@ void Scene607::enter() {
if (_scene->_priorSceneId == 608) {
_game._player._playerPos = Common::Point(297, 50);
_game._player._facing = FACING_SOUTHEAST;
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(40, 104);
_game._player._facing = FACING_SOUTHEAST;
_game._player._visible = false;
@@ -1164,7 +1170,7 @@ void Scene607::step() {
&& !_dogBarking && (_vm->getRandomNumber(1, 50) == 10)) {
_dogBarking = true;
_scene->_sequences.remove(_globals._sequenceIndexes[1]);
- _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 5, 8, 0, 0);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[1], false, 5, 8, 0, 0);
_scene->_sequences.setDepth(_globals._sequenceIndexes[1], 6);
_scene->_kernelMessages.reset();
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_SPRITE, 2, 100);
@@ -1250,7 +1256,7 @@ void Scene607::step() {
case 61: {
int syncIdx = _globals._sequenceIndexes[4];
- _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 15, 3, 0, 0);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 15, 3, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 46, -2);
_scene->_sequences.setDepth(_globals._sequenceIndexes[4], 1);
_scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], syncIdx);
@@ -1397,7 +1403,7 @@ void Scene607::actions() {
case 0:
_game._player._stepEnabled = false;
_scene->_sequences.remove(_globals._sequenceIndexes[2]);
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 6, 1, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[2], false, 6, 1, 0, 0);
_scene->_sequences.setDepth(_globals._sequenceIndexes[2], 4);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
break;
@@ -1778,7 +1784,7 @@ void Scene608::enter() {
_vm->_palette->setEntry(252, 63, 44, 30);
_vm->_palette->setEntry(253, 63, 20, 22);
- if (_scene->_priorSceneId != -2) {
+ if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(46, 132);
_game._player._facing = FACING_EAST;
if (_game._difficulty == DIFFICULTY_HARD) {
@@ -1791,7 +1797,7 @@ void Scene608::enter() {
if (!_dogUnderCar)
resetDogVariables();
else {
- _globals._sequenceIndexes[10] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[10], false, 9, 0, 0, 0);
+ _globals._sequenceIndexes[10] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[10], false, 9, 0, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[10], 10, 11);
_scene->_sequences.setDepth(_globals._sequenceIndexes[10], 6);
}
@@ -1833,7 +1839,7 @@ void Scene608::step() {
if (_vm->getRandomNumber(1, 50) == 10) {
_dogBarkingFl = true;
_scene->_sequences.remove(_globals._sequenceIndexes[5]);
- _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], false, 5, 8, 0, 0);
+ _globals._sequenceIndexes[5] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[5], false, 5, 8, 0, 0);
_scene->_sequences.setDepth(_globals._sequenceIndexes[5], 4);
int idx = _scene->_dynamicHotspots.add(NOUN_OBNOXIOUS_DOG, VERB_WALKTO, _globals._sequenceIndexes[5], Common::Rect(0, 0, 0, 0));
_scene->_dynamicHotspots.setPosition(idx, Common::Point(194, 142), FACING_EAST);
@@ -1958,7 +1964,7 @@ void Scene608::step() {
_game._player._visible = true;
_game._player._priorTimer = _scene->_activeAnimation->getNextFrameTimer() - _game._player._ticksAmount;
} else if (_carFrame == 41) {
- _globals._sequenceIndexes[10] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[10], false, 9, 0, 0, 0);
+ _globals._sequenceIndexes[10] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[10], false, 9, 0, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[10], 10, 11);
_scene->_sequences.setDepth(_globals._sequenceIndexes[10], 6);
_dogUnderCar = true;
@@ -2148,7 +2154,7 @@ void Scene608::step() {
case 82: {
int syncIdx = _globals._sequenceIndexes[9];
- _globals._sequenceIndexes[9] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[9], false, 15, 5, 0, 0);
+ _globals._sequenceIndexes[9] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[9], false, 15, 5, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[9], 39, 40);
_scene->_sequences.setDepth(_globals._sequenceIndexes[9], 5);
_scene->_sequences.updateTimeout(_globals._sequenceIndexes[9], syncIdx);
@@ -2219,7 +2225,7 @@ void Scene608::actions() {
if ((_globals[kCarStatus] == CAR_UP) || (_globals[kCarStatus] == CAR_SQUASHES_DOG) || (_globals[kCarStatus] == CAR_SQUASHES_DOG_AGAIN)) {
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], true, 6, 2, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], true, 6, 2, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 2);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
@@ -2293,7 +2299,7 @@ void Scene608::actions() {
if ((_globals[kCarStatus] == CAR_DOWN) || (_globals[kCarStatus] == CAR_DOWN_ON_SQUASHED_DOG)) {
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], true, 6, 2, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], true, 6, 2, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 3);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
@@ -2379,7 +2385,7 @@ void Scene608::actions() {
case 0:
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], true, 6, 2, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], true, 6, 2, 0, 0);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 4, 1);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
@@ -2407,7 +2413,7 @@ void Scene608::actions() {
case 0:
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], true, 6, 2, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], true, 6, 2, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 2);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 2, 1);
@@ -2535,7 +2541,7 @@ void Scene609::enter() {
_game._player._facing = FACING_EAST;
_scene->_sequences.addTimer(60, 60);
_game._player._stepEnabled = false;
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(86, 136);
_game._player._facing = FACING_NORTHEAST;
_game._player._visible = false;
@@ -2574,7 +2580,7 @@ void Scene609::step() {
case 62:
_scene->_sequences.remove( _globals._sequenceIndexes[2]);
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0);
_scene->_hotspots.activate(NOUN_VIDEO_STORE_DOOR, true);
_scene->_sequences.setDepth(_globals._sequenceIndexes[2], 9);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 63);
@@ -2582,7 +2588,7 @@ void Scene609::step() {
case 63:
if (!_globals[kHasTalkedToHermit] && (_game._difficulty != DIFFICULTY_HARD)) {
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 26, 2, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 26, 2, 0, 0);
_scene->_sequences.setDepth(_globals._sequenceIndexes[3], 7);
_scene->_sequences.setPosition(_globals._sequenceIndexes[3], Common::Point(287, 73));
_scene->_sequences.setScale(_globals._sequenceIndexes[3], 47);
@@ -2605,7 +2611,7 @@ void Scene609::step() {
case 71:
if (!_globals[kHasTalkedToHermit]) {
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 26, 2, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 26, 2, 0, 0);
_scene->_sequences.setDepth(_globals._sequenceIndexes[3], 7);
_scene->_sequences.setPosition(_globals._sequenceIndexes[3], Common::Point(287, 73));
_scene->_sequences.setScale(_globals._sequenceIndexes[3], 47);
@@ -2648,7 +2654,7 @@ void Scene609::enterStore() {
case 2:
_game._player._visible = false;
- _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], true, 11, 2, 0, 0);
+ _globals._sequenceIndexes[5] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[5], true, 11, 2, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 1, 2);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
@@ -2690,7 +2696,7 @@ void Scene609::enterStore() {
case 7:
_scene->_sequences.remove(_globals._sequenceIndexes[2]);
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0);
_scene->_sequences.setDepth(_globals._sequenceIndexes[2], 9);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 8);
break;
@@ -2766,7 +2772,7 @@ void Scene609::actions() {
case 0:
_game._player._stepEnabled = false;
_scene->_sequences.remove(_globals._sequenceIndexes[1]);
- _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0);
_scene->_sequences.setDepth(_globals._sequenceIndexes[1], 5);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
break;
@@ -2884,7 +2890,7 @@ void Scene610::enter() {
if (_scene->_roomChanged && _game._difficulty != DIFFICULTY_EASY)
_game._objects.addToInventory(OBJ_PENLIGHT);
- if (_scene->_priorSceneId != -2) {
+ if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(175, 152);
_game._player._facing = FACING_NORTHWEST;
}
@@ -2922,7 +2928,7 @@ void Scene610::actions() {
case 0:
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], true, 8, 1, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], true, 8, 1, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 2);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 2, 1);
@@ -2952,7 +2958,7 @@ void Scene610::actions() {
case 0:
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], true, 8, 1, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], true, 8, 1, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 2);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 2, 1);
@@ -3253,6 +3259,8 @@ void Scene611::handleSubDialog1() {
handleTalking(500);
displayHermitQuestions(17);
_dialog1.write(0x290, false);
+ _dialog1.write(0x28e, false);
+
if (!_dialog1.read(0x28F))
_dialog1.write(0x291, true);
@@ -3271,8 +3279,9 @@ void Scene611::handleSubDialog1() {
if ((_game._objects.isInInventory(OBJ_DURAFAIL_CELLS)) || (_game._objects.isInInventory(OBJ_PHONE_CELLS)))
_dialog1.write(0x294, true);
- if (!_game._objects.isInInventory(OBJ_DURAFAIL_CELLS) && !_game._objects.isInInventory(OBJ_PHONE_CELLS))
- _globals[kExecuted_1_11] = true;
+ // WORKAROUND: Fix bug in the original where the option to give Hermit batteries
+ // would be given before the player even has any batteries
+ _globals[kHermitWantsBatteries] = true;
setDialogNode(1);
break;
@@ -3826,29 +3835,29 @@ void Scene611::displayHermitQuestions(int question) {
Common::String curQuote = _game.getQuote(0x2D3);
int width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
int quotePosX = _defaultDialogPos.x - (width / 2);
- _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 3), 0xFDFC, 0, 0, 9999999, curQuote);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 3), 0xFDFC, 0, 0, 800, curQuote);
curQuote = _game.getQuote(0x2D4);
width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
quotePosX = _defaultDialogPos.x - (width / 2);
- _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 17), 0xFDFC, 0, 0, 9999999, curQuote);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 17), 0xFDFC, 0, 0, 800, curQuote);
curQuote = _game.getQuote(0x2D5);
width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
quotePosX = _defaultDialogPos.x - (width / 2);
- _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 31), 0xFDFC, 0, 0, 9999999, curQuote);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 31), 0xFDFC, 0, 0, 800, curQuote);
curQuote = _game.getQuote(0x2D6);
width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
quotePosX = _defaultDialogPos.x - (width / 2);
- _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 45), 0xFDFC, 0, 0, 9999999, curQuote);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 45), 0xFDFC, 0, 0, 800, curQuote);
curQuote = _game.getQuote(0x2D7);
width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
quotePosX = _defaultDialogPos.x - (width / 2);
- _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 59), 0xFDFC, 0, 0, 9999999, curQuote);
- }
- break;
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 59), 0xFDFC, 0, 0, 800, curQuote);
+ }
+ break;
case 22: {
Common::String curQuote = _game.getQuote(0x2D8);
@@ -3921,14 +3930,14 @@ void Scene611::enter() {
0x2D9, 0x2DA, 0x2DB, 0x2DC, 0x2DD, 0x2DE, 0x2DF, 0x2E0, 0x2E1, 0x2E2, 0x2E3, 0x2E4, 0x2E5, 0x2E6,
0x323, 0x324, 0);
- _dialog1.setup(0x82, 0x287, 0x288, 0x289, 0x28A, 0x28B, 0x28C, 0x28D, 0x28E, 0x28F, 0x290,
+ _dialog1.setup(kConvHermit1, 0x287, 0x288, 0x289, 0x28A, 0x28B, 0x28C, 0x28D, 0x28E, 0x28F, 0x290,
0x291, 0x292, 0x293, 0x294, 0x295, 0x296, 0);
- _dialog2.setup(0x83, 0x29C, 0x29D, 0x29E, 0x29F, 0);
+ _dialog2.setup(kConvHermit2, 0x29C, 0x29D, 0x29E, 0x29F, 0);
if (!_game._visitedScenes._sceneRevisited) {
- _dialog1.set(0x82, 0x287, 0x288, 0x296, 0);
- _dialog2.set(0x83, 0x29F, 0);
+ _dialog1.set(kConvHermit1, 0x287, 0x288, 0x296, 0);
+ _dialog2.set(kConvHermit2, 0x29F, 0);
}
_vm->_palette->setEntry(252, 51, 51, 47);
@@ -3945,7 +3954,7 @@ void Scene611::enter() {
_alreadyTalkingFl = false;
_startTradingFl = false;
- if (_scene->_priorSceneId != -2) {
+ if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(22, 132);
_game._player._facing = FACING_EAST;
_duringDialogFl = false;
@@ -3964,11 +3973,10 @@ void Scene611::enter() {
_scene->_hotspots.activate(NOUN_HERMIT, false);
}
- // CHECKME: The last line of the block looks extremely useless
- if (_globals[kExecuted_1_11]) {
- _dialog1.write(0x294, true);
- _dialog1.write(0x292, false);
- _globals[kExecuted_1_11] = true;
+ // WORKAROUND: Fix original adding 'give batteries' option even if you don't have them
+ if (_globals[kHermitWantsBatteries]) {
+ if ((_game._objects.isInInventory(OBJ_DURAFAIL_CELLS)) || (_game._objects.isInInventory(OBJ_PHONE_CELLS)))
+ _dialog1.write(0x294, true);
}
if (_duringDialogFl) {
@@ -4012,7 +4020,7 @@ void Scene611::step() {
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 81);
} else if (_game._trigger == 81) {
int syncId = _globals._sequenceIndexes[1];
- _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 20, 0, 0, 0);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[1], false, 20, 0, 0, 0);
int idx = _scene->_dynamicHotspots.add(NOUN_RAT, VERB_WALKTO, _globals._sequenceIndexes[1], Common::Rect(0, 0, 0, 0));
_ratHotspotId = _scene->_dynamicHotspots.setPosition(idx, Common::Point(272, 154), FACING_SOUTHEAST);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[1], 9, 10);
@@ -4040,7 +4048,7 @@ void Scene611::step() {
break;
case 6:
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 12, 3, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 12, 3, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 2, 4);
_scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
@@ -4260,7 +4268,7 @@ void Scene611::step() {
if (_hermitMode == 6) {
if ((_scene->_activeAnimation->getCurrentFrame() == 9) && _check1Fl) {
_scene->_sequences.remove(_globals._sequenceIndexes[3]);
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 7, 1, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 7, 1, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 2);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 112);
@@ -4300,7 +4308,7 @@ void Scene611::step() {
_resetBatterieText = true;
int syncIdx = _globals._sequenceIndexes[3];
_nextFrame = 10;
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 7, 1, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 7, 1, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 2);
_scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], syncIdx);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
@@ -4488,7 +4496,7 @@ void Scene612::handleWinchMovement() {
case 0:
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 10, 1, 0, 0);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 10, 1, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 1, 5);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_SPRITE, 5, 1);
@@ -4506,7 +4514,7 @@ void Scene612::handleWinchMovement() {
_globals[kBoatRaised] = false;
} else {
_scene->_sequences.remove(_globals._sequenceIndexes[2]);
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 17, 9, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 17, 9, 0, 0);
_vm->_sound->command(18);
}
_scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
@@ -4558,7 +4566,7 @@ void Scene612::enter() {
_globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, _cycleIndex);
_scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
- if (_scene->_priorSceneId != -2) {
+ if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(280, 75);
_game._player._facing = FACING_SOUTHWEST;
_game._player._visible = false;
@@ -4608,7 +4616,7 @@ void Scene612::actions() {
case 0:
_game._player._stepEnabled = false;
_scene->_sequences.remove(_globals._sequenceIndexes[1]);
- _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0);
_scene->_sequences.setDepth(_globals._sequenceIndexes[1], 2);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
break;
diff --git a/engines/mads/nebular/nebular_scenes6.h b/engines/mads/nebular/nebular_scenes6.h
index c5cac56626..4fc4a2e8ae 100644
--- a/engines/mads/nebular/nebular_scenes6.h
+++ b/engines/mads/nebular/nebular_scenes6.h
@@ -8,12 +8,12 @@
* 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
+ * 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.
diff --git a/engines/mads/nebular/nebular_scenes7.cpp b/engines/mads/nebular/nebular_scenes7.cpp
index 0f019c4b19..c2a249e5f8 100644
--- a/engines/mads/nebular/nebular_scenes7.cpp
+++ b/engines/mads/nebular/nebular_scenes7.cpp
@@ -8,12 +8,12 @@
* 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
+ * 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.
@@ -148,17 +148,20 @@ void Scene701::enter() {
switch (boatStatus) {
case BOAT_TIED_FLOATING:
- _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 20, 0, 0, 0);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 20, 0, 0, 0);
_scene->_sequences.setDepth(_globals._sequenceIndexes[4], 10);
break;
case BOAT_ADRIFT:
- _globals._sequenceIndexes[6] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[6], false, 20, 0, 0, 0);
+ _globals._sequenceIndexes[6] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[6], false, 20, 0, 0, 0);
_scene->_sequences.setDepth(_globals._sequenceIndexes[6], 10);
break;
- case BOAT_TIED:
+ case BOAT_TIED: {
_globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -1);
_scene->_sequences.setDepth(_globals._sequenceIndexes[2], 9);
+ int idx = _scene->_dynamicHotspots.add(837, 759, _globals._sequenceIndexes[2], Common::Rect());
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(231, 127), FACING_NORTH);
break;
+ }
case BOAT_GONE:
_scene->_hotspots.activate(NOUN_BOAT, false);
break;
@@ -191,7 +194,7 @@ void Scene701::enter() {
_game._player._stepEnabled = false;
_scene->loadAnimation(formAnimName('B', 1), 80);
_vm->_sound->command(28);
- } else if (_scene->_priorSceneId != -2 && _scene->_priorSceneId != 620) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG && _scene->_priorSceneId != 620) {
_game._player._playerPos = Common::Point(22, 131);
_game._player._facing = FACING_EAST;
_game._player._stepEnabled = false;
@@ -206,7 +209,7 @@ void Scene701::step() {
switch(_game._trigger) {
case 60:
_scene->_sequences.remove(_globals._sequenceIndexes[5]);
- _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], false, 6, 1, 0, 0);
+ _globals._sequenceIndexes[5] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[5], false, 6, 1, 0, 0);
_scene->_sequences.setPosition(_globals._sequenceIndexes[5], Common::Point(155, 129));
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, 61);
break;
@@ -276,10 +279,8 @@ void Scene701::preActions() {
}
void Scene701::actions() {
- if (_action.isAction(VERB_WALK_ALONG, NOUN_PLATFORM))
- return;
-
- if (_action.isAction(VERB_LOOK, NOUN_BINOCULARS, NOUN_BUILDING) && _game._objects[OBJ_VASE]._roomNumber == 706) {
+ if (_action.isAction(VERB_WALK_ALONG, NOUN_PLATFORM)) {
+ } else if (_action.isAction(VERB_LOOK, NOUN_BINOCULARS, NOUN_BUILDING) && _game._objects[OBJ_VASE]._roomNumber == 706) {
switch (_game._trigger) {
case 0:
_game._player._stepEnabled = false;
@@ -326,7 +327,7 @@ void Scene701::actions() {
case 3:
_vm->_sound->command(17);
- _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 5, 1, 0, 0);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[1], false, 5, 1, 0, 0);
_scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(48, 136));
_scene->_sequences.setDepth(_globals._sequenceIndexes[1], 10);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 4);
@@ -415,7 +416,7 @@ void Scene701::actions() {
_vm->_dialogs->show(70111);
} else if (_action.isAction(VERB_LOOK, NOUN_SUBMERGED_CITY))
_vm->_dialogs->show(70112);
- else if (_action.isAction(VERB_LOOK, 0))
+ else if (_action.isAction(VERB_LOOK, NOUN_ELEVATOR))
_vm->_dialogs->show(70113);
else if (_action.isAction(VERB_LOOK, NOUN_PLATFORM))
_vm->_dialogs->show(70114);
@@ -460,7 +461,7 @@ void Scene702::enter() {
if (_scene->_priorSceneId == 701) {
_game._player._playerPos = Common::Point(13, 145);
_game._player._facing = FACING_EAST;
- } else if (_scene->_priorSceneId != -2 && _scene->_priorSceneId != 620) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG && _scene->_priorSceneId != 620) {
_game._player._playerPos = Common::Point(289, 138);
_game._player.walk(Common::Point(262, 148), FACING_WEST);
_game._player._facing = FACING_WEST;
@@ -502,7 +503,7 @@ void Scene702::actions() {
case 0:
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[12] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[12], false, 5, 2, 0, 0);
+ _globals._sequenceIndexes[12] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[12], false, 5, 2, 0, 0);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[12]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[12], SEQUENCE_TRIGGER_SPRITE, 4, 1);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[12], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
@@ -694,7 +695,7 @@ void Scene703::enter() {
_monsterMode = 0;
_scene->loadAnimation(formAnimName('A', -1));
_scene->_activeAnimation->setCurrentFrame(34);
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._stepEnabled = false;
_boatDir = 1;
if (_globals[kMonsterAlive]) {
@@ -1218,7 +1219,7 @@ void Scene704::handleFillBottle(int quote) {
void Scene704::enter() {
if (_game._objects[OBJ_BOTTLE]._roomNumber == _scene->_currentSceneId) {
_globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('b', 0));
- _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 6, 0, 0, 0);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[1], false, 6, 0, 0, 0);
_scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
if (_scene->_priorSceneId == 705) {
_scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(123, 125));
@@ -1241,7 +1242,7 @@ void Scene704::enter() {
_boatDirection = 2;
_scene->loadAnimation(formAnimName('A', -1));
_scene->_activeAnimation->setCurrentFrame(36);
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._stepEnabled = false;
_boatDirection = 1;
_scene->loadAnimation(formAnimName('A', -1));
@@ -1567,7 +1568,7 @@ void Scene705::enter() {
_globals._sequenceIndexes[3] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[3], false, 9, 1, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 4);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._stepEnabled = false;
_scene->_sequences.addTimer(1, 80);
_vm->_sound->command(28);
@@ -1585,7 +1586,7 @@ void Scene705::enter() {
void Scene705::step() {
switch (_game._trigger) {
case 70:
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 9, 1, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[3], false, 9, 1, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 4);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
break;
@@ -1798,7 +1799,7 @@ void Scene706::handleTakeVase() {
case 0:
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 4, 2, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 4, 2, 0, 0);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_SPRITE, 7, 1);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
@@ -1854,7 +1855,7 @@ void Scene706::enter() {
if (_scene->_priorSceneId == 707) {
_game._player._playerPos = Common::Point(277, 103);
_game._player._facing = FACING_SOUTHWEST;
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(167, 152);
_game._player._facing = FACING_NORTH;
}
@@ -2087,7 +2088,7 @@ void Scene710::enter() {
if (_game._objects[OBJ_VASE]._roomNumber == 706) {
_globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('g', -1));
- _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 6, 0, 0, 0);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[1], false, 6, 0, 0, 0);
}
_game._player._visible = false;
@@ -2213,7 +2214,7 @@ void Scene751::enter() {
_globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, -2);
_scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(155, 129));
_scene->_sequences.addTimer(15, 70);
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(22, 131);
_game._player._facing = FACING_EAST;
_game._player._stepEnabled = false;
@@ -2248,7 +2249,7 @@ void Scene751::step() {
switch (_game._trigger) {
case 70:
_scene->_sequences.remove(_globals._sequenceIndexes[4]);
- _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 6, 1, 0, 0);
+ _globals._sequenceIndexes[4] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[4], false, 6, 1, 0, 0);
_scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(155, 129));
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
break;
@@ -2287,7 +2288,7 @@ void Scene751::step() {
case 62:
_vm->_sound->command(17);
- _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 5, 1, 0, 0);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[1], false, 5, 1, 0, 0);
_scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(48, 136));
_scene->_sequences.setDepth(_globals._sequenceIndexes[1], 10);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 63);
@@ -2329,7 +2330,7 @@ void Scene751::preActions() {
_game._player._readyToWalk = false;
_game._player._stepEnabled = false;
_scene->_sequences.remove(_globals._sequenceIndexes[2]);
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 11, 1, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[2], false, 11, 1, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], -1, 7);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
break;
@@ -2398,7 +2399,7 @@ void Scene751::actions() {
case 3:
_vm->_sound->command(17);
- _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 5, 1, 0, 0);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[1], false, 5, 1, 0, 0);
_scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(48, 136));
_scene->_sequences.setDepth(_globals._sequenceIndexes[1], 10);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 4);
@@ -2527,7 +2528,7 @@ void Scene752::enter() {
if (_scene->_priorSceneId == 751) {
_game._player._playerPos = Common::Point(13, 145);
_game._player._facing = FACING_EAST;
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(289, 138);
_game._player.walk(Common::Point(262, 148), FACING_WEST);
_game._player._facing = FACING_WEST;
@@ -2597,7 +2598,7 @@ void Scene752::actions() {
case 0:
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[12] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[12], false, 5, 2, 0, 0);
+ _globals._sequenceIndexes[12] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[12], false, 5, 2, 0, 0);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[12]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[12], SEQUENCE_TRIGGER_SPRITE, 4, 1);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[12], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
@@ -2622,7 +2623,7 @@ void Scene752::actions() {
case 0:
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[12] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[12], false, 5, 2, 0, 0);
+ _globals._sequenceIndexes[12] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[12], false, 5, 2, 0, 0);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[12]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[12], SEQUENCE_TRIGGER_SPRITE, 4, 1);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[12], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
diff --git a/engines/mads/nebular/nebular_scenes7.h b/engines/mads/nebular/nebular_scenes7.h
index dfb3c0f16e..b5aeba818c 100644
--- a/engines/mads/nebular/nebular_scenes7.h
+++ b/engines/mads/nebular/nebular_scenes7.h
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/nebular/nebular_scenes8.cpp b/engines/mads/nebular/nebular_scenes8.cpp
index 62a1a262b0..a904569624 100644
--- a/engines/mads/nebular/nebular_scenes8.cpp
+++ b/engines/mads/nebular/nebular_scenes8.cpp
@@ -8,12 +8,12 @@
* 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
+ * 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.
@@ -121,7 +121,7 @@ void Scene801::enter() {
_game._player._playerPos = Common::Point(307, 111);
_game._player.walk(Common::Point(270, 118), FACING_WEST);
_game._player._visible = true;
- } else if ((_scene->_priorSceneId != -2) && !_globals[kTeleporterCommand]) {
+ } else if ((_scene->_priorSceneId != RETURNING_FROM_DIALOG) && !_globals[kTeleporterCommand]) {
_game._player._playerPos = Common::Point(8, 117);
_game._player.walk(Common::Point(41, 115), FACING_EAST);
_game._player._visible = true;
@@ -145,10 +145,10 @@ void Scene801::enter() {
case 2:
_game._player._playerPos = Common::Point(8, 117);
_globals[kTeleporterUnderstood] = true;
- _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 8, 1, 0, 0);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[1], false, 8, 1, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[1], 1, 13);
_game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
- _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 8090);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 80);
_vm->_sound->command(30);
break;
@@ -283,7 +283,7 @@ void Scene801::actions() {
_globals[kBetweenRooms] = true;
_game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
_scene->_sequences.remove(_globals._sequenceIndexes[2]);
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 4, 1, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[2], false, 4, 1, 0, 0);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 90);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 5);
_scene->_sequences.setDepth(_globals._sequenceIndexes[2], 13);
@@ -346,7 +346,7 @@ void Scene802::enter() {
_game._player._playerPos = Common::Point(303, 119);
_game._player._facing = FACING_WEST;
- } else if (_scene->_priorSceneId != -2) {
+ } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(15, 129);
_game._player._facing = FACING_EAST;
}
@@ -419,7 +419,7 @@ void Scene802::actions() {
case 0:
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], true, 7, 2, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], true, 7, 2, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 2);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 2, 1);
@@ -451,7 +451,7 @@ void Scene802::actions() {
case 0:
_game._player._stepEnabled = false;
_game._player._visible = false;
- _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], true, 7, 2, 0, 0);
+ _globals._sequenceIndexes[5] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[5], true, 7, 2, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 1, 4);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_SPRITE, 4, 1);
@@ -557,7 +557,7 @@ void Scene803::enter() {
if (!_globals[kFromCockpit]) {
if (!_globals[kReturnFromCut]) {
- if (_scene->_priorSceneId != -2) {
+ if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) {
_game._player._playerPos = Common::Point(15, 130);
_game._player._facing = FACING_EAST;
}
@@ -692,7 +692,7 @@ void Scene803::step() {
if (_game._trigger == 90) {
int syncIdx = _globals._sequenceIndexes[4];
- _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 15, 0, 0, 0);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 15, 0, 0, 0);
_scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], syncIdx);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 4, 9);
if (_globals[kHoppyDead])
@@ -719,14 +719,14 @@ void Scene803::step() {
else
_game._winStatus = 3;
- _vm->quitGame();
+ return;
}
}
if (_game._trigger == 150) {
_scene->_sequences.remove(_globals._sequenceIndexes[6]);
_vm->_sound->command(18);
- _globals._sequenceIndexes[6] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[6], false, 8, 1, 0, 0);
+ _globals._sequenceIndexes[6] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[6], false, 8, 1, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[6], 1, 19);
_scene->_sequences.setDepth(_globals._sequenceIndexes[6], 4);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[6], SEQUENCE_TRIGGER_EXPIRE, 0, 151);
@@ -778,7 +778,7 @@ void Scene803::actions() {
case 162:
_scene->_sequences.remove(_globals._sequenceIndexes[9]);
- _globals._sequenceIndexes[9] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[9], true, 6, 1, 0, 0);
+ _globals._sequenceIndexes[9] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[9], true, 6, 1, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[9], 1, 4);
_scene->_sequences.setMsgLayout(_globals._sequenceIndexes[9]);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[9], SEQUENCE_TRIGGER_EXPIRE, 0, 163);
@@ -899,15 +899,17 @@ void Scene804::enter() {
_scene->_sequences.addTimer(60, 100);
} else {
_globals._sequenceIndexes[6] = _scene->_sequences.startCycle(_globals._spriteIndexes[6], false, 1);
- _globals._sequenceIndexes[7] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[7], false, 4, 0, 0, 0);
+ _globals._sequenceIndexes[7] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[7], false, 4, 0, 0, 0);
_scene->_sequences.addTimer(160, 70);
_game._player._stepEnabled = false;
}
} else {
- if (_globals[kBeamIsUp] == 0)
+ if (_globals[kBeamIsUp]) {
_globals._sequenceIndexes[8] = _scene->_sequences.startCycle(_globals._spriteIndexes[8], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[8], 7);
+ }
- if (_globals[kWindowFixed] == 0)
+ if (_globals[kWindowFixed])
_globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 1);
_globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
@@ -955,9 +957,9 @@ void Scene804::step() {
_globals[kInSpace] = false;
_globals[kBeamIsUp] = true;
- assert(!_globals[kCopyProtectFailed]);
+ //assert(!_globals[kCopyProtectFailed]);
_game._winStatus = 4;
- _vm->quitGame();
+ return;
}
break;
@@ -969,7 +971,7 @@ void Scene804::step() {
assert(!_globals[kCopyProtectFailed]);
_game._winStatus = 4;
- _vm->quitGame();
+ return;
}
}
@@ -1129,8 +1131,7 @@ void Scene804::actions() {
} else {
_messWithThrottle = true;
}
- }
- else if (_action.isAction(VERB_APPLY, NOUN_POLYCEMENT, NOUN_CRACK) ||
+ } else if (_action.isAction(VERB_APPLY, NOUN_POLYCEMENT, NOUN_CRACK) ||
_action.isAction(VERB_PUT, NOUN_POLYCEMENT, NOUN_CRACK)) {
if (!_globals[kWindowFixed]) {
_resetFrame = 2;
@@ -1219,6 +1220,8 @@ void Scene805::enter() {
}
void Scene805::step() {
+ UserInterface &userInterface = _vm->_game->_scene._userInterface;
+
if (_game._trigger == 70) {
_scene->_hotspots.activate(OBJ_SHIELD_MODULATOR, false);
_globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 25);
@@ -1226,6 +1229,7 @@ void Scene805::step() {
_scene->_dynamicHotspots.setPosition(idx, Common::Point(0, 0), FACING_DUMMY);
_globals[kShieldModInstalled] = true;
_game._objects.setRoom(OBJ_SHIELD_MODULATOR, NOWHERE);
+ userInterface._selectedInvIndex = -1;
_game._player._stepEnabled = true;
_vm->_sound->command(24);
}
@@ -1237,6 +1241,7 @@ void Scene805::step() {
_scene->_dynamicHotspots.setPosition(idx, Common::Point(0, 0), FACING_DUMMY);
_globals[kTargetModInstalled] = true;
_game._objects.setRoom(OBJ_TARGET_MODULE, NOWHERE);
+ userInterface._selectedInvIndex = -1;
_game._player._stepEnabled = true;
_vm->_sound->command(24);
}
@@ -1278,14 +1283,14 @@ void Scene805::actions() {
} else if (_action.isAction(VERB_REMOVE, NOUN_SHIELD_MODULATOR) && _globals[kShieldModInstalled]) {
_scene->_sequences.remove(_globals._sequenceIndexes[1]);
_game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
- _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 7, 1, 0, 0);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[1], false, 7, 1, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[1], -1, -2);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
_game._player._stepEnabled = false;
} else if (_action.isAction(VERB_REMOVE, NOUN_TARGET_MODULE) && _globals[kTargetModInstalled]) {
_scene->_sequences.remove(_globals._sequenceIndexes[2]);
_game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
- _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0);
_scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], -1, -2);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 81);
_game._player._stepEnabled = false;
@@ -1434,7 +1439,7 @@ void Scene808::actions() {
_vm->_sound->command(20);
_vm->_sound->command(25);
}
- _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 4, 1, 0, 0);
+ _globals._sequenceIndexes[4] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[4], false, 4, 1, 0, 0);
_scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(248, 211));
_scene->_sequences.setDepth(_globals._sequenceIndexes[4], 2);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
@@ -1469,7 +1474,7 @@ void Scene808::actions() {
_vm->_sound->command(20);
}
_globals[kTopButtonPushed] = false;
- _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 4, 1, 0, 0);
+ _globals._sequenceIndexes[4] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[4], false, 4, 1, 0, 0);
_scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(248, 186));
_scene->_sequences.setDepth(_globals._sequenceIndexes[4], 2);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 91);
@@ -1500,7 +1505,7 @@ void Scene808::actions() {
_vm->_sound->command(20);
}
_globals[kTopButtonPushed] = true;
- _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 4, 1, 0, 0);
+ _globals._sequenceIndexes[4] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[4], false, 4, 1, 0, 0);
_scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(248, 163));
_scene->_sequences.setDepth(_globals._sequenceIndexes[4], 2);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 81);
@@ -1517,7 +1522,7 @@ void Scene808::actions() {
switch (_game._trigger) {
case 0:
_game._player._stepEnabled = false;
- _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 4, 2, 0, 0);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 4, 2, 0, 0);
_scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(168, 211));
_scene->_sequences.setDepth(_globals._sequenceIndexes[4], 2);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 70);
@@ -1534,7 +1539,7 @@ void Scene808::actions() {
switch (_game._trigger) {
case 0:
_game._player._stepEnabled = false;
- _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 4, 2, 0, 0);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 4, 2, 0, 0);
_scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(172, 163));
_scene->_sequences.setDepth(_globals._sequenceIndexes[4], 2);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 80);
@@ -1551,7 +1556,7 @@ void Scene808::actions() {
switch (_game._trigger) {
case 0:
_game._player._stepEnabled = false;
- _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 4, 2, 0, 0);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 4, 2, 0, 0);
_scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(172, 186));
_scene->_sequences.setDepth(_globals._sequenceIndexes[4], 2);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 90);
@@ -1601,7 +1606,8 @@ void Scene810::enter() {
}
void Scene810::step() {
- if ((_scene->_activeAnimation->getCurrentFrame() == 200) && _moveAllowed) {
+ if (_scene->_activeAnimation && (_scene->_activeAnimation->getCurrentFrame() == 200)
+ && _moveAllowed) {
_scene->_sequences.addTimer(100, 70);
_moveAllowed = false;
}
diff --git a/engines/mads/nebular/nebular_scenes8.h b/engines/mads/nebular/nebular_scenes8.h
index 7f2c34a843..439815f05c 100644
--- a/engines/mads/nebular/nebular_scenes8.h
+++ b/engines/mads/nebular/nebular_scenes8.h
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/nebular/sound_nebular.cpp b/engines/mads/nebular/sound_nebular.cpp
index 0a054440b2..711f82a05b 100644
--- a/engines/mads/nebular/sound_nebular.cpp
+++ b/engines/mads/nebular/sound_nebular.cpp
@@ -8,12 +8,12 @@
* 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.
@@ -21,6 +21,7 @@
*/
#include "audio/audiostream.h"
+#include "audio/fmopl.h"
#include "audio/decoders/raw.h"
#include "common/algorithm.h"
#include "common/debug.h"
@@ -36,6 +37,7 @@ namespace Nebular {
bool AdlibChannel::_channelsEnabled;
AdlibChannel::AdlibChannel() {
+ _owner = nullptr;
_activeCount = 0;
_field1 = 0;
_field2 = 0;
@@ -43,6 +45,7 @@ AdlibChannel::AdlibChannel() {
_field4 = 0;
_sampleIndex = 0;
_volume = 0;
+ _volumeOffset = 0;
_field7 = 0;
_field8 = 0;
_field9 = 0;
@@ -55,11 +58,11 @@ AdlibChannel::AdlibChannel() {
_pSrc = nullptr;
_ptr3 = nullptr;
_ptr4 = nullptr;
+ _ptrEnd = nullptr;
_field17 = 0;
_field19 = 0;
_soundData = nullptr;
_field1D = 0;
- _field1E = 0;
_field1F = 0;
_field20 = 0;
@@ -95,6 +98,7 @@ void AdlibChannel::setPtr2(byte *pData) {
void AdlibChannel::load(byte *pData) {
_ptr1 = _pSrc = _ptr3 = pData;
_ptr4 = _soundData = pData;
+ _volumeOffset = 0;
_fieldA = 0xFF;
_activeCount = 1;
_fieldD = 64;
@@ -102,17 +106,20 @@ void AdlibChannel::load(byte *pData) {
_field1F = 0;
_field2 = _field3 = 0;
_volume = _field7 = 0;
- _field1D = _field1E = 0;
+ _field1D = 0;
_fieldE = 0;
_field9 = 0;
_fieldB = 0;
_field17 = 0;
_field19 = 0;
+
+ CachedDataEntry &cacheEntry = _owner->getCachedData(pData);
+ _ptrEnd = cacheEntry._dataEnd;
}
void AdlibChannel::check(byte *nullPtr) {
if (_activeCount && _fieldE) {
- if (!_field1E) {
+ if (!_volumeOffset) {
_pSrc = nullPtr;
_fieldE = 0;
} else {
@@ -150,7 +157,7 @@ AdlibSample::AdlibSample(Common::SeekableReadStream &s) {
/*-----------------------------------------------------------------------*/
-ASound::ASound(Audio::Mixer *mixer, FM_OPL *opl, const Common::String &filename, int dataOffset) {
+ASound::ASound(Audio::Mixer *mixer, OPL::OPL *opl, const Common::String &filename, int dataOffset) {
// Open up the appropriate sound file
if (!_soundFile.open(filename))
error("Could not open file - %s", filename.c_str());
@@ -161,6 +168,7 @@ ASound::ASound(Audio::Mixer *mixer, FM_OPL *opl, const Common::String &filename,
_samplePtr = nullptr;
_frameCounter = 0;
_isDisabled = false;
+ _masterVolume = 255;
_v1 = 0;
_v2 = 0;
_activeChannelNumber = 0;
@@ -181,17 +189,15 @@ ASound::ASound(Audio::Mixer *mixer, FM_OPL *opl, const Common::String &filename,
_randomSeed = 1234;
_amDep = _vibDep = _splitPoint = true;
- _samplesTillCallback = 0;
- _samplesTillCallbackRemainder = 0;
- _samplesPerCallback = getRate() / CALLBACKS_PER_SECOND;
- _samplesPerCallbackRemainder = getRate() % CALLBACKS_PER_SECOND;
-
for (int i = 0; i < 11; ++i) {
_channelData[i]._field0 = 0;
_channelData[i]._freqMask = 0;
_channelData[i]._freqBase = 0;
_channelData[i]._field6 = 0;
}
+
+ for (int i = 0; i < ADLIB_CHANNEL_COUNT; ++i)
+ _channels[i]._owner = this;
AdlibChannel::_channelsEnabled = false;
@@ -200,23 +206,19 @@ ASound::ASound(Audio::Mixer *mixer, FM_OPL *opl, const Common::String &filename,
_mixer = mixer;
_opl = opl;
- _opl->init(getRate());
- _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1,
- Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
-
// Initialize the Adlib
adlibInit();
// Reset the adlib
command0();
+
+ _opl->start(new Common::Functor0Mem<void, ASound>(this, &ASound::onTimer), CALLBACKS_PER_SECOND);
}
ASound::~ASound() {
Common::List<CachedDataEntry>::iterator i;
for (i = _dataCache.begin(); i != _dataCache.end(); ++i)
delete[] (*i)._data;
-
- _mixer->stopHandle(_soundHandle);
}
void ASound::validate() {
@@ -283,6 +285,17 @@ void ASound::noise() {
}
}
+CachedDataEntry &ASound::getCachedData(byte *pData) {
+ Common::List<CachedDataEntry>::iterator i;
+ for (i = _dataCache.begin(); i != _dataCache.end(); ++i) {
+ CachedDataEntry &e = *i;
+ if (e._data == pData)
+ return e;
+ }
+
+ error("Could not find previously loaded data");
+}
+
void ASound::write(int reg, int val) {
_queue.push(RegisterValue(reg, val));
}
@@ -331,6 +344,7 @@ byte *ASound::loadData(int offset, int size) {
CachedDataEntry rec;
rec._offset = offset;
rec._data = new byte[size];
+ rec._dataEnd = rec._data + size - 1;
_soundFile.seek(_dataOffset + offset);
_soundFile.read(rec._data, size);
_dataCache.push_back(rec);
@@ -449,6 +463,10 @@ void ASound::pollActiveChannel() {
warning("pollActiveChannel(): No data found for sound channel");
break;
}
+ if (pSrc > chan->_ptrEnd) {
+ warning("Read beyond end of loaded sound data");
+ }
+
if (!(*pSrc & 0x80) || (*pSrc <= 0xF0)) {
if (updateFlag)
updateActiveChannel();
@@ -516,7 +534,7 @@ void ASound::pollActiveChannel() {
chan->_field1 = 0;
chan->_field2 = chan->_field3 = 0;
chan->_volume = chan->_field7 = 0;
- chan->_field1D = chan->_field1E = 0;
+ chan->_field1D = chan->_volumeOffset = 0;
chan->_field8 = 0;
chan->_field9 = 0;
chan->_fieldB = 0;
@@ -570,7 +588,7 @@ void ASound::pollActiveChannel() {
break;
case 8:
- chan->_field1D = *++pSrc;
+ chan->_field1D = (int8)*++pSrc;
chan->_pSrc += 2;
break;
@@ -591,7 +609,7 @@ void ASound::pollActiveChannel() {
if (chan->_fieldE) {
chan->_pSrc += 2;
} else {
- chan->_field1E = *pSrc >> 1;
+ chan->_volumeOffset = *pSrc >> 1;
updateFlag = true;
chan->_pSrc += 2;
}
@@ -635,7 +653,7 @@ void ASound::pollActiveChannel() {
if (!--chan->_field9) {
chan->_field9 = chan->_fieldA;
if (chan->_field2) {
- int8 newVal = (int8)chan->_field2 + (int8)chan->_field1E;
+ int8 newVal = (int8)chan->_field2 + (int8)chan->_volumeOffset;
if (newVal < 0) {
chan->_field9 = 0;
newVal = 0;
@@ -644,7 +662,7 @@ void ASound::pollActiveChannel() {
newVal = 63;
}
- chan->_field1E = newVal;
+ chan->_volumeOffset = newVal;
updateFlag = true;
}
}
@@ -709,8 +727,8 @@ void ASound::updateChannelState() {
resultCheck();
} else {
int reg = 0xA0 + _activeChannelNumber;
- int vTimes = (_activeChannelPtr->_field4 + _activeChannelPtr->_field1F) / 12;
- int vOffset = (_activeChannelPtr->_field4 + _activeChannelPtr->_field1F) % 12;
+ int vTimes = (byte)(_activeChannelPtr->_field4 + _activeChannelPtr->_field1F) / 12;
+ int vOffset = (byte)(_activeChannelPtr->_field4 + _activeChannelPtr->_field1F) % 12;
int val = _vList1[vOffset] + _activeChannelPtr->_field1D;
write2(8, reg, val & 0xFF);
@@ -727,32 +745,18 @@ static const int outputIndexes[] = {
static const int outputChannels[] = {
0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 16, 17, 18, 19, 20, 21, 0
};
-static const int volumeList[] = {
- 0x3F, 0x3F, 0x36, 0x31, 0x2D, 0x2A, 0x28, 0x26, 0x24, 0x22, 0x21, 0x20, 0x1F, 0x1E, 0x1D, 0x1C,
- 0x1B, 0x1A, 0x19, 0x19, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x14, 0x14, 0x13, 0x12, 0x12,
- 0x11, 0x11, 0x10, 0x10, 0x0F, 0x0F, 0x0E, 0x0E, 0x0D, 0x0D, 0x0C, 0x0C, 0x0B, 0x0B, 0x0A, 0x0A,
- 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
void ASound::updateActiveChannel() {
int reg = 0x40 + outputChannels[outputIndexes[_activeChannelNumber * 2 + 1]];
int portVal = _ports[reg] & 0xFFC0;
- int newVolume = CLIP(_activeChannelPtr->_volume + _activeChannelPtr->_field1E, 0, 63);
+ int newVolume = CLIP(_activeChannelPtr->_volume + _activeChannelPtr->_volumeOffset, 0, 63);
+ newVolume = newVolume * _masterVolume / 255;
// Note: Original had a whole block not seeming to be used, since the initialisation
// sets a variable to 5660h, and doesn't change it, so the branch is never taken
- int val = CLIP(newVolume - volumeList[_activeChannelPtr->_fieldD], 0, 63);
- val = (63 - val) | portVal;
+ portVal |= 63 - newVolume;
- int val2 = CLIP(newVolume - volumeList[-(_activeChannelPtr->_fieldD - 127)], 0, 63);
- val2 = (63 - val2) | portVal;
- write2(0, reg, val);
- write2(2, reg, val2);
+ write2(8, reg, portVal);
}
void ASound::loadSample(int sampleIndex) {
@@ -820,32 +824,16 @@ void ASound::updateFNumber() {
write2(8, hiReg, val2);
}
-int ASound::readBuffer(int16 *buffer, const int numSamples) {
+void ASound::onTimer() {
Common::StackLock slock(_driverMutex);
+ poll();
+ flush();
+}
- int32 samplesLeft = numSamples;
- memset(buffer, 0, sizeof(int16) * numSamples);
- while (samplesLeft) {
- if (!_samplesTillCallback) {
- poll();
- flush();
-
- _samplesTillCallback = _samplesPerCallback;
- _samplesTillCallbackRemainder += _samplesPerCallbackRemainder;
- if (_samplesTillCallbackRemainder >= CALLBACKS_PER_SECOND) {
- _samplesTillCallback++;
- _samplesTillCallbackRemainder -= CALLBACKS_PER_SECOND;
- }
- }
-
- int32 render = MIN<int>(samplesLeft, _samplesTillCallback);
- samplesLeft -= render;
- _samplesTillCallback -= render;
-
- _opl->readBuffer(buffer, render);
- buffer += render;
- }
- return numSamples;
+void ASound::setVolume(int volume) {
+ _masterVolume = volume;
+ if (!volume)
+ command0();
}
int ASound::command0() {
@@ -966,7 +954,7 @@ const ASound1::CommandPtr ASound1::_commandList[42] = {
&ASound1::command40, &ASound1::command41
};
-ASound1::ASound1(Audio::Mixer *mixer, FM_OPL *opl)
+ASound1::ASound1(Audio::Mixer *mixer, OPL::OPL *opl)
: ASound(mixer, opl, "asound.001", 0x1520) {
_cmd23Toggle = false;
@@ -1005,22 +993,22 @@ int ASound1::command10() {
int ASound1::command11() {
command111213();
- _channels[0]._field1E = 0;
- _channels[1]._field1E = 0;
+ _channels[0]._volumeOffset = 0;
+ _channels[1]._volumeOffset = 0;
return 0;
}
int ASound1::command12() {
command111213();
- _channels[0]._field1E = 40;
- _channels[1]._field1E = 0;
+ _channels[0]._volumeOffset = 40;
+ _channels[1]._volumeOffset = 0;
return 0;
}
int ASound1::command13() {
command111213();
- _channels[0]._field1E = 40;
- _channels[1]._field1E = 50;
+ _channels[0]._volumeOffset = 40;
+ _channels[1]._volumeOffset = 50;
return 0;
}
@@ -1267,7 +1255,7 @@ const ASound2::CommandPtr ASound2::_commandList[44] = {
&ASound2::command40, &ASound2::command41, &ASound2::command42, &ASound2::command43
};
-ASound2::ASound2(Audio::Mixer *mixer, FM_OPL *opl) : ASound(mixer, opl, "asound.002", 0x15E0) {
+ASound2::ASound2(Audio::Mixer *mixer, OPL::OPL *opl) : ASound(mixer, opl, "asound.002", 0x15E0) {
_command12Param = 0xFD;
// Load sound samples
@@ -1638,7 +1626,7 @@ const ASound3::CommandPtr ASound3::_commandList[61] = {
&ASound3::command60
};
-ASound3::ASound3(Audio::Mixer *mixer, FM_OPL *opl) : ASound(mixer, opl, "asound.003", 0x15B0) {
+ASound3::ASound3(Audio::Mixer *mixer, OPL::OPL *opl) : ASound(mixer, opl, "asound.003", 0x15B0) {
_command39Flag = false;
// Load sound samples
@@ -2042,7 +2030,7 @@ const ASound4::CommandPtr ASound4::_commandList[61] = {
&ASound4::command60
};
-ASound4::ASound4(Audio::Mixer *mixer, FM_OPL *opl) : ASound(mixer, opl, "asound.004", 0x14F0) {
+ASound4::ASound4(Audio::Mixer *mixer, OPL::OPL *opl) : ASound(mixer, opl, "asound.004", 0x14F0) {
// Load sound samples
_soundFile.seek(_dataOffset + 0x122);
for (int i = 0; i < 210; ++i)
@@ -2298,7 +2286,7 @@ const ASound5::CommandPtr ASound5::_commandList[42] = {
&ASound5::command40, &ASound5::command41
};
-ASound5::ASound5(Audio::Mixer *mixer, FM_OPL *opl) : ASound(mixer, opl, "asound.002", 0x15E0) {
+ASound5::ASound5(Audio::Mixer *mixer, OPL::OPL *opl) : ASound(mixer, opl, "asound.002", 0x15E0) {
// Load sound samples
_soundFile.seek(_dataOffset + 0x144);
for (int i = 0; i < 164; ++i)
@@ -2539,7 +2527,7 @@ const ASound6::CommandPtr ASound6::_commandList[30] = {
&ASound6::nullCommand, &ASound6::command29
};
-ASound6::ASound6(Audio::Mixer *mixer, FM_OPL *opl) : ASound(mixer, opl, "asound.006", 0x1390) {
+ASound6::ASound6(Audio::Mixer *mixer, OPL::OPL *opl) : ASound(mixer, opl, "asound.006", 0x1390) {
// Load sound samples
_soundFile.seek(_dataOffset + 0x122);
for (int i = 0; i < 200; ++i)
@@ -2695,7 +2683,7 @@ const ASound7::CommandPtr ASound7::_commandList[38] = {
&ASound7::command36, &ASound7::command37
};
-ASound7::ASound7(Audio::Mixer *mixer, FM_OPL *opl) : ASound(mixer, opl, "asound.007", 0x1460) {
+ASound7::ASound7(Audio::Mixer *mixer, OPL::OPL *opl) : ASound(mixer, opl, "asound.007", 0x1460) {
// Load sound samples
_soundFile.seek(_dataOffset + 0x122);
for (int i = 0; i < 214; ++i)
@@ -2901,7 +2889,7 @@ const ASound8::CommandPtr ASound8::_commandList[38] = {
&ASound8::command36, &ASound8::command37
};
-ASound8::ASound8(Audio::Mixer *mixer, FM_OPL *opl) : ASound(mixer, opl, "asound.008", 0x1490) {
+ASound8::ASound8(Audio::Mixer *mixer, OPL::OPL *opl) : ASound(mixer, opl, "asound.008", 0x1490) {
// Load sound samples
_soundFile.seek(_dataOffset + 0x122);
for (int i = 0; i < 174; ++i)
@@ -3157,7 +3145,7 @@ const ASound9::CommandPtr ASound9::_commandList[52] = {
&ASound9::command48, &ASound9::command49, &ASound9::command50, &ASound9::command51
};
-ASound9::ASound9(Audio::Mixer *mixer, FM_OPL *opl) : ASound(mixer, opl, "asound.009", 0x16F0) {
+ASound9::ASound9(Audio::Mixer *mixer, OPL::OPL *opl) : ASound(mixer, opl, "asound.009", 0x16F0) {
_v1 = _v2 = 0;
_soundPtr = nullptr;
diff --git a/engines/mads/nebular/sound_nebular.h b/engines/mads/nebular/sound_nebular.h
index ccfd40ad52..2b80b08d89 100644
--- a/engines/mads/nebular/sound_nebular.h
+++ b/engines/mads/nebular/sound_nebular.h
@@ -8,12 +8,12 @@
* 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.
@@ -28,20 +28,27 @@
#include "common/mutex.h"
#include "common/queue.h"
#include "audio/audiostream.h"
-#include "audio/fmopl.h"
#include "audio/mixer.h"
+namespace OPL {
+class OPL;
+}
+
namespace MADS {
class SoundManager;
namespace Nebular {
+class ASound;
+
/**
* Represents the data for a channel on the Adlib
*/
class AdlibChannel {
public:
+ ASound *_owner;
+
int _activeCount;
int _field1;
int _field2;
@@ -61,11 +68,12 @@ public:
byte *_pSrc;
byte *_ptr3;
byte *_ptr4;
+ byte *_ptrEnd;
int _field17;
int _field19;
byte *_soundData;
int _field1D;
- int _field1E;
+ int _volumeOffset;
int _field1F;
// TODO: Only used by asound.003. Figure out usage
@@ -128,17 +136,20 @@ struct RegisterValue {
#define ADLIB_CHANNEL_MIDWAY 5
#define CALLBACKS_PER_SECOND 60
+struct CachedDataEntry {
+ int _offset;
+ byte *_data;
+ byte *_dataEnd;
+};
+
/**
* Base class for the sound player resource files
*/
-class ASound : public Audio::AudioStream {
+class ASound {
private:
- struct CachedDataEntry {
- int _offset;
- byte *_data;
- };
Common::List<CachedDataEntry> _dataCache;
uint16 _randomSeed;
+ int _masterVolume;
/**
* Does the initial Adlib initialisation
@@ -184,6 +195,11 @@ private:
void processSample();
void updateFNumber();
+
+ /**
+ * Timer function for OPL
+ */
+ void onTimer();
protected:
int _commandParam;
@@ -265,8 +281,7 @@ protected:
int nullCommand() { return 0; }
public:
Audio::Mixer *_mixer;
- FM_OPL *_opl;
- Audio::SoundHandle _soundHandle;
+ OPL::OPL *_opl;
AdlibChannel _channels[ADLIB_CHANNEL_COUNT];
AdlibChannel *_activeChannelPtr;
AdlibChannelData _channelData[11];
@@ -298,10 +313,6 @@ public:
int _activeChannelReg;
int _v11;
bool _amDep, _vibDep, _splitPoint;
- int _samplesPerCallback;
- int _samplesPerCallbackRemainder;
- int _samplesTillCallback;
- int _samplesTillCallbackRemainder;
public:
/**
* Constructor
@@ -310,7 +321,7 @@ public:
* @param filename Specifies the adlib sound player file to use
* @param dataOffset Offset in the file of the data segment
*/
- ASound(Audio::Mixer *mixer, FM_OPL *opl, const Common::String &filename, int dataOffset);
+ ASound(Audio::Mixer *mixer, OPL::OPL *opl, const Common::String &filename, int dataOffset);
/**
* Destructor
@@ -350,26 +361,15 @@ public:
*/
int getFrameCounter() { return _frameCounter; }
- // AudioStream interface
- /**
- * Main buffer read
- */
- virtual int readBuffer(int16 *buffer, const int numSamples);
-
- /**
- * Mono sound only
- */
- virtual bool isStereo() const { return false; }
-
/**
- * Data is continuously pushed, so definitive end
+ * Return the cached data block record for previously loaded sound data
*/
- virtual bool endOfData() const { return false; }
+ CachedDataEntry &getCachedData(byte *pData);
/**
- * Return sample rate
+ * Set the volume
*/
- virtual int getRate() const { return 11025; }
+ void setVolume(int volume);
};
class ASound1 : public ASound {
@@ -415,7 +415,7 @@ private:
void command111213();
int command2627293032();
public:
- ASound1(Audio::Mixer *mixer, FM_OPL *opl);
+ ASound1(Audio::Mixer *mixer, OPL::OPL *opl);
virtual int command(int commandId, int param);
};
@@ -467,7 +467,7 @@ private:
void command9Randomize();
void command9Apply(byte *data, int val, int incr);
public:
- ASound2(Audio::Mixer *mixer, FM_OPL *opl);
+ ASound2(Audio::Mixer *mixer, OPL::OPL *opl);
virtual int command(int commandId, int param);
};
@@ -527,7 +527,7 @@ private:
void command9Randomize();
void command9Apply(byte *data, int val, int incr);
public:
- ASound3(Audio::Mixer *mixer, FM_OPL *opl);
+ ASound3(Audio::Mixer *mixer, OPL::OPL *opl);
virtual int command(int commandId, int param);
};
@@ -565,7 +565,7 @@ private:
void method1();
public:
- ASound4(Audio::Mixer *mixer, FM_OPL *opl);
+ ASound4(Audio::Mixer *mixer, OPL::OPL *opl);
virtual int command(int commandId, int param);
};
@@ -611,7 +611,7 @@ private:
int command42();
int command43();
public:
- ASound5(Audio::Mixer *mixer, FM_OPL *opl);
+ ASound5(Audio::Mixer *mixer, OPL::OPL *opl);
virtual int command(int commandId, int param);
};
@@ -640,7 +640,7 @@ private:
int command25();
int command29();
public:
- ASound6(Audio::Mixer *mixer, FM_OPL *opl);
+ ASound6(Audio::Mixer *mixer, OPL::OPL *opl);
virtual int command(int commandId, int param);
};
@@ -672,7 +672,7 @@ private:
int command36();
int command37();
public:
- ASound7(Audio::Mixer *mixer, FM_OPL *opl);
+ ASound7(Audio::Mixer *mixer, OPL::OPL *opl);
virtual int command(int commandId, int param);
};
@@ -715,7 +715,7 @@ private:
void method1(byte *pData);
void adjustRange(byte *pData, byte v, int incr);
public:
- ASound8(Audio::Mixer *mixer, FM_OPL *opl);
+ ASound8(Audio::Mixer *mixer, OPL::OPL *opl);
virtual int command(int commandId, int param);
};
@@ -774,7 +774,7 @@ private:
int command59();
int command60();
public:
- ASound9(Audio::Mixer *mixer, FM_OPL *opl);
+ ASound9(Audio::Mixer *mixer, OPL::OPL *opl);
virtual int command(int commandId, int param);
};
diff --git a/engines/mads/palette.cpp b/engines/mads/palette.cpp
index 836d04f7c0..7651fe8e65 100644
--- a/engines/mads/palette.cpp
+++ b/engines/mads/palette.cpp
@@ -8,12 +8,12 @@
* 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.
@@ -178,31 +178,29 @@ int PaletteUsage::process(Common::Array<RGB6> &palette, uint flags) {
}
if (!changed && !noUsageFlag) {
- int var2 = (palette[palIndex]._flags & 0x20) ||
- (((flags & 0x2000) || (palette[palIndex]._flags & 0x4000)) &&
+ int bestHash = (palette[palIndex]._flags & 0x20) ||
+ (((flags & 0x2000) || (palette[palIndex]._flags & 0x40)) &&
((flags & 0x1000) || (palCount == 0))) ? 0x7fff : 1;
int var36 = (palette[palIndex]._flags & 0x80) ? 0 : 2;
for (int idx = palLow; idx < palIdx; ++idx) {
uint32 v = _vm->_palette->_palFlags[idx];
if ((v & var3A) && !(v & var36)) {
- int var10;
-
- if (var2 > 1) {
- var10 = rgbFactor(&_vm->_palette->_mainPalette[idx * 3], palette[palIndex]);
- }
- else if (_vm->_palette->_mainPalette[idx * 3] != palette[palIndex].r ||
+ int hash;
+ if (bestHash > 1) {
+ hash = rgbFactor(&_vm->_palette->_mainPalette[idx * 3], palette[palIndex]);
+ } else if (_vm->_palette->_mainPalette[idx * 3] != palette[palIndex].r ||
_vm->_palette->_mainPalette[idx * 3 + 1] != palette[palIndex].g ||
_vm->_palette->_mainPalette[idx * 3 + 2] != palette[palIndex].b) {
- var10 = 1;
+ hash = 1;
} else {
- var10 = 0;
+ hash = 0;
}
- if (var2 > var10) {
+ if (bestHash > hash) {
changed = true;
newPalIndex = idx;
- var2 = var10;
+ bestHash = hash;
}
}
}
@@ -430,6 +428,14 @@ void Fader::grabPalette(byte *colors, uint start, uint num) {
g_system->getPaletteManager()->grabPalette(colors, start, num);
}
+void Fader::getFullPalette(byte palette[PALETTE_SIZE]) {
+ grabPalette(&palette[0], 0, PALETTE_COUNT);
+}
+
+void Fader::setFullPalette(byte palette[PALETTE_SIZE]) {
+ setPalette(&palette[0], 0, PALETTE_COUNT);
+}
+
void Fader::fadeOut(byte palette[PALETTE_SIZE], byte *paletteMap,
int baseColor, int numColors, int baseGrey, int numGreys,
int tickDelay, int steps) {
@@ -491,7 +497,7 @@ void Fader::fadeIn(byte palette[PALETTE_SIZE], byte destPalette[PALETTE_SIZE],
int baseColor, int numColors, int baseGrey, int numGreys,
int tickDelay, int steps) {
GreyEntry map[PALETTE_COUNT];
- byte tempPal[PALETTE_SIZE];;
+ byte tempPal[PALETTE_SIZE];
int8 signs[PALETTE_COUNT][3];
byte palIndex[PALETTE_COUNT][3];
int intensity;
@@ -505,16 +511,12 @@ void Fader::fadeIn(byte palette[PALETTE_SIZE], byte destPalette[PALETTE_SIZE],
for (int colorCtr = 0; colorCtr < 3; ++colorCtr) {
if (_colorFlags[colorCtr]) {
int shiftSign = _colorValues[colorCtr];
- if (shiftSign >= 0) {
+ if (shiftSign >= 0)
intensity = map[index]._intensity << shiftSign;
- }
- else {
+ else
intensity = map[index]._intensity >> abs(shiftSign);
- }
- }
- else {
+ } else
intensity = _colorValues[colorCtr];
- }
int diff = _rgb64Map[destPalette[palCtr * 3 + colorCtr]] - intensity;
palIndex[palCtr][colorCtr] = (byte)ABS(diff);
@@ -891,4 +893,30 @@ void Palette::refreshSceneColors() {
setPalette(_mainPalette + (val * 3), val, 256 - val);
}
+int Palette::closestColor(const byte *matchColor, const byte *refPalette,
+ int paletteInc, int count) {
+ int bestColor = 0;
+ int bestDistance = 0x7fff;
+
+ for (int idx = 0; idx < count; ++idx) {
+ // Figure out figure for 'distance' between two colors
+ int distance = 0;
+ for (int rgbIdx = 0; rgbIdx < RGB_SIZE; ++rgbIdx) {
+ int diff = refPalette[rgbIdx] - matchColor[rgbIdx];
+ distance += diff * diff;
+ }
+
+ // If the given color is a closer match to our color, store the index
+ if (distance <= bestDistance) {
+ bestDistance = distance;
+ bestColor = idx;
+ }
+
+ refPalette += paletteInc;
+ }
+
+ return bestColor;
+}
+
+
} // End of namespace MADS
diff --git a/engines/mads/palette.h b/engines/mads/palette.h
index 27d25f266b..6c98947384 100644
--- a/engines/mads/palette.h
+++ b/engines/mads/palette.h
@@ -8,12 +8,12 @@
* 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.
@@ -36,6 +36,7 @@ class MADSEngine;
#define PALETTE_RESERVED_HIGH_COUNT 10
#define PALETTE_COUNT 256
+#define RGB_SIZE 3
#define PALETTE_SIZE (256 * 3)
/**
@@ -212,16 +213,12 @@ public:
/**
* Gets the entire palette at once
*/
- void getFullPalette(byte palette[PALETTE_SIZE]) {
- grabPalette(&palette[0], 0, PALETTE_COUNT);
- }
+ void getFullPalette(byte palette[PALETTE_SIZE]);
/**
* Sets the entire palette at once
*/
- void setFullPalette(byte palette[PALETTE_SIZE]) {
- setPalette(&palette[0], 0, PALETTE_COUNT);
- }
+ void setFullPalette(byte palette[PALETTE_SIZE]);
/**
* Calculates a merge/hash for a given palette entry
@@ -318,6 +315,9 @@ public:
void unlock();
void refreshSceneColors();
+
+ static int closestColor(const byte *matchColor, const byte *refPalette,
+ int paletteInc, int count);
};
} // End of namespace MADS
diff --git a/engines/mads/phantom/game_phantom.cpp b/engines/mads/phantom/game_phantom.cpp
index 0b2531ef65..592a108aea 100644
--- a/engines/mads/phantom/game_phantom.cpp
+++ b/engines/mads/phantom/game_phantom.cpp
@@ -8,12 +8,12 @@
* 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.
@@ -28,7 +28,7 @@
#include "mads/msurface.h"
#include "mads/phantom/game_phantom.h"
//#include "mads/nebular/dialogs_nebular.h"
-//#include "mads/nebular/globals_nebular.h"
+#include "mads/phantom/globals_phantom.h"
#include "mads/phantom/phantom_scenes.h"
namespace MADS {
@@ -52,29 +52,74 @@ void GamePhantom::startGame() {
void GamePhantom::initializeGlobals() {
_globals.reset();
- warning("TODO: sub_316DA()");
+ // TODO: Catacombs setup
_player._facing = FACING_NORTH;
_player._turnToFacing = FACING_NORTH;
- /* Section #1 variables */
- // TODO
-
- /* Section #2 variables */
- // TODO
-
- /* Section #3 variables */
- // TODO
-
- /* Section #4 variables */
- // TODO
-
- /* Section #5 variables */
- // TODO
-
- /* Section #9 variables */
- // TODO
-
+ _globals[kTempVar] = false;
+ _globals[kRoom103104Transition] = 1; // new room
+ _globals[kCurrentYear] = 1993;
+ _globals[kTrapDoorStatus] = 0; // open
+ _globals[kChristineDoorStatus] = 0; // Christine is in her room
+ _globals[kSandbagStatus] = 0; // sandbag is secure
+ _globals[kJacquesStatus] = 0; // alive
+ _globals[kChrisFStatus] = 1; // Christine F. is alive in 1993
+ _globals[kBrieTalkStatus] = 0; // before Brie motions
+ _globals[kPanelIn206] = 0; // not discovered
+ _globals[kFightStatus] = 0;
+ _globals[kJuliesDoor] = 1; // cracked open
+ _globals[kPrompterStandStatus] = 0;
+ _globals[kChrisDStatus] = 0; // before love
+ _globals[kJulieNameIsKnown] = 0;
+ _globals[kDoorsIn205] = 0; // both locked
+ _globals[kMadameGiryLocation] = 1; // middle
+ _globals[kTicketPeoplePresent] = 0;
+ _globals[kCoffinStatus] = 0; // closed and locked
+ _globals[kDoneBrieConv203] = 0;
+ _globals[kFlorentNameIsKnown] = 0;
+ _globals[kDegasNameIsKnown] = 0;
+ _globals[kMadameGiryShowsUp] = false;
+ _globals[kJacquesNameIsKnown] = 0;
+ _globals[kCharlesNameIsKnown] = false;
+ _globals[kTopFloorLocked] = true;
+ _globals[kMadameNameIsKnown] = 0;
+ _globals[kChrisKickedRaoulOut] = false;
+ _globals[kLookedAtCase] = false;
+ _globals[kRingIsOnFinger] = false;
+ _globals[kHeListened] = false;
+ _globals[kKnockedOverHead] = false;
+ _globals[kObservedPhan104] = false;
+ _globals[kReadBook] = false;
+ _globals[kCanFindBookInLibrary] = false;
+ _globals[kLookedAtSkullFace] = false;
+ _globals[kScannedBookcase] = false;
+ _globals[kRanConvIn205] = false;
+ _globals[kDoneRichConv203] = false;
+ _globals[kHintThatDaaeIsHome1] = false;
+ _globals[kHintThatDaaeIsHome2] = false;
+ _globals[kMakeBrieLeave203] = false;
+ _globals[kMakeRichLeave203] = false;
+ _globals[kCameFromFade] = false;
+ _globals[kChristineToldEnvelope] = false;
+ _globals[kLeaveAngelMusicOn] = false;
+ _globals[kDoorIn409IsOpen] = false;
+ _globals[kUnknown] = false;
+ _globals[kCobwebIsCut] = false;
+ _globals[kChristineIsInBoat] = false;
+ _globals[kRightDoorIsOpen504] = false;
+ _globals[kChrisLeft505] = false;
+ _globals[kChrisWillTakeSeat] = true;
+ _globals[kFlickedLever1] = 0;
+ _globals[kFlickedLever2] = 0;
+ _globals[kFlickedLever3] = 0;
+ _globals[kFlickedLever4] = 0;
+ _globals[kPlayerScore] = 0;
+ _globals[kPlayerScoreFlags] = 0;
+
+ _globals[kMusicSelected] = _vm->getRandomNumber(1, 4);
+
+ _player._spritesPrefix = "RAL"; // Fixed prefix
Player::preloadSequences("RAL", 1);
}
@@ -106,6 +151,11 @@ void GamePhantom::checkShowDialog() {
// TODO: Copied from Nebular
if (_vm->_dialogs->_pendingDialog && _player._stepEnabled && !_globals[5]) {
_player.releasePlayerSprites();
+
+ // HACK: Skip the main menu (since it'll then try to show Rex's main menu)
+ if (_vm->_dialogs->_pendingDialog == DIALOG_MAIN_MENU)
+ _vm->_dialogs->_pendingDialog = DIALOG_NONE;
+
_vm->_dialogs->showDialog();
_vm->_dialogs->_pendingDialog = DIALOG_NONE;
}
diff --git a/engines/mads/phantom/game_phantom.h b/engines/mads/phantom/game_phantom.h
index 99cc2c1230..44b2321f42 100644
--- a/engines/mads/phantom/game_phantom.h
+++ b/engines/mads/phantom/game_phantom.h
@@ -8,12 +8,12 @@
* 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.
@@ -26,7 +26,7 @@
#include "common/scummsys.h"
#include "mads/game.h"
#include "mads/globals.h"
-//#include "mads/nebular/globals_nebular.h"
+#include "mads/phantom/globals_phantom.h"
namespace MADS {
@@ -64,15 +64,6 @@ enum InventoryObject {
OBJ_OAR = 24
};
-// HACK: A stub for now, remove from here once it's implemented properly
-class PhantomGlobals : public Globals {
-public:
- PhantomGlobals() {
- resize(210); // Rex has 210 globals
- }
- virtual ~PhantomGlobals() {}
-};
-
class GamePhantom : public Game {
friend class Game;
protected:
diff --git a/engines/mads/phantom/globals_phantom.cpp b/engines/mads/phantom/globals_phantom.cpp
new file mode 100644
index 0000000000..e0db0a1bb0
--- /dev/null
+++ b/engines/mads/phantom/globals_phantom.cpp
@@ -0,0 +1,49 @@
+/* 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/scummsys.h"
+#include "common/config-manager.h"
+#include "mads/phantom/globals_phantom.h"
+
+namespace MADS {
+
+namespace Phantom {
+
+PhantomGlobals::PhantomGlobals()
+ : Globals() {
+ // Initialize lists
+ resize(210);
+ _spriteIndexes.resize(30);
+ _sequenceIndexes.resize(30);
+}
+
+void PhantomGlobals::synchronize(Common::Serializer &s) {
+ Globals::synchronize(s);
+
+ _spriteIndexes.synchronize(s);
+ _sequenceIndexes.synchronize(s);
+}
+
+
+} // End of namespace Phantom
+
+} // End of namespace MADS
diff --git a/engines/mads/phantom/globals_phantom.h b/engines/mads/phantom/globals_phantom.h
new file mode 100644
index 0000000000..c23b53cdf5
--- /dev/null
+++ b/engines/mads/phantom/globals_phantom.h
@@ -0,0 +1,143 @@
+/* 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 MADS_GLOBALS_PHANTOM_H
+#define MADS_GLOBALS_PHANTOM_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "mads/game.h"
+#include "mads/resources.h"
+
+namespace MADS {
+
+namespace Phantom {
+
+enum GlobalId {
+ // Global variables
+
+ kWalkerTiming = 0,
+ kWalkerTiming2 = 1,
+ kStopWalkerDisabled = 2, // disable walker idle animations
+ kTempInterface = 3,
+ kWalkerConverse = 4, // conversation started with an NPC
+ kWalkerConverseState = 5,
+ kWalkerConverseNow = 6,
+
+ kCurrentYear = 10, // current year (1881 or 1993)
+ kMusicSelected = 11,
+ kPlayerScore = 12,
+ kPlayerScoreFlags = 13,
+ kDoneBrieConv203 = 14,
+ kLanternStatus = 15,
+
+ // Section #1 variables
+ kLeaveAngelMusicOn = 19,
+ kTrapDoorStatus = 20,
+ kChristineDoorStatus = 21,
+ kSandbagStatus = 22,
+ kChrisFStatus = 23,
+ kBrieTalkStatus = 24,
+ kJuliesDoor = 25,
+ kPrompterStandStatus = 26,
+ kChrisDStatus = 27,
+ kJulieNameIsKnown = 28,
+ kChrisKickedRaoulOut = 29,
+ kJacquesNameIsKnown = 30,
+ kJacquesStatus = 31,
+ kFlorentNameIsKnown = 32,
+ kCharlesNameIsKnown = 33,
+ kRoom103104Transition = 34,
+ kObservedPhan104 = 35,
+ kDeathLocation = 36,
+ kMakeBrieLeave203 = 37,
+ kHintThatDaaeIsHome1 = 38,
+ kHintThatDaaeIsHome2 = 39,
+
+ // Section #2 variables
+ kChristineToldEnvelope = 40,
+ kReadBook = 41,
+ kScannedBookcase = 42,
+ kRanConvIn205 = 43,
+ kDoorsIn205 = 44,
+ kPanelIn206 = 45,
+ kMadameNameIsKnown = 46,
+ kMadameGiryLocation = 47,
+ kLookedAtCase = 48,
+ kMadameGiryShowsUp = 49,
+ kDoneRichConv203 = 50,
+ kCameFromFade = 51,
+ kTicketPeoplePresent = 52,
+ kDegasNameIsKnown = 53,
+ kTempVar = 54,
+ kFlickedLever1 = 55,
+ kFlickedLever2 = 56,
+ kFlickedLever3 = 57,
+ kFlickedLever4 = 58,
+
+ // Section #3 Variables
+ kTopFloorLocked = 60,
+
+ // Section #4 Variables
+ kCatacombsRoom = 80,
+ // TODO
+ kDoorIn409IsOpen = 93,
+ kUnknown = 94, // TODO
+ kCobwebIsCut = 95,
+
+ // Section #5 Variables
+ kChristineIsInBoat = 100,
+ kChrisWillTakeSeat = 101,
+ kRightDoorIsOpen504 = 102,
+ kCoffinStatus = 103,
+ kChrisLeft505 = 104,
+ kKnockedOverHead = 105,
+ kFightStatus = 106,
+ kHeListened = 107,
+ kCanFindBookInLibrary = 108,
+ kRingIsOnFinger = 109,
+ kLookedAtSkullFace = 110,
+ kCableHookWasSeparate = 111,
+ kMakeRichLeave203 = 112
+};
+
+class PhantomGlobals : public Globals {
+public:
+ SynchronizedList _spriteIndexes;
+ SynchronizedList _sequenceIndexes;
+public:
+ /**
+ * Constructor
+ */
+ PhantomGlobals();
+
+ /**
+ * Synchronize the globals data
+ */
+ virtual void synchronize(Common::Serializer &s);
+};
+
+} // End of namespace Phantom
+
+} // End of namespace MADS
+
+#endif /* MADS_GLOBALS_PHANTOM_H */
diff --git a/engines/mads/phantom/phantom_scenes.cpp b/engines/mads/phantom/phantom_scenes.cpp
index 7fd7ce642d..f7f4d154df 100644
--- a/engines/mads/phantom/phantom_scenes.cpp
+++ b/engines/mads/phantom/phantom_scenes.cpp
@@ -8,12 +8,12 @@
* 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.
@@ -28,6 +28,7 @@
#include "mads/scene.h"
#include "mads/phantom/game_phantom.h"
#include "mads/phantom/phantom_scenes.h"
+#include "mads/phantom/phantom_scenes1.h"
namespace MADS {
@@ -42,9 +43,9 @@ SceneLogic *SceneFactory::createScene(MADSEngine *vm) {
switch (scene._nextSceneId) {
// Scene group #1 (theater, stage and dressing rooms)
case 101: // seats
- return new DummyScene(vm); // TODO
+ return new Scene101(vm);
case 102: // music stands
- return new DummyScene(vm); // TODO
+ return new Scene102(vm);
case 103: // below stage
return new DummyScene(vm); // TODO
case 104: // stage
@@ -169,6 +170,10 @@ Common::String PhantomScene::formAnimName(char sepChar, int suffixNum) {
/*------------------------------------------------------------------------*/
void SceneInfoPhantom::loadCodes(MSurface &depthSurface, int variant) {
+ // The intro scenes do not have any codes
+ if (_sceneId >= 900)
+ return;
+
Common::String ext = Common::String::format(".WW%d", variant);
File f(Resources::formatName(RESPREFIX_RM, _sceneId, ext));
MadsPack codesPack(&f);
diff --git a/engines/mads/phantom/phantom_scenes.h b/engines/mads/phantom/phantom_scenes.h
index cd295a28b6..c0a823ae06 100644
--- a/engines/mads/phantom/phantom_scenes.h
+++ b/engines/mads/phantom/phantom_scenes.h
@@ -8,12 +8,12 @@
* 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.
@@ -34,20 +34,40 @@ namespace MADS {
namespace Phantom {
+enum Verb {
+ VERB_LOOK = 0x3,
+ VERB_TAKE = 0x4,
+ VERB_PUSH = 0x5,
+ VERB_OPEN = 0x6,
+ VERB_PUT = 0x7,
+ VERB_TALK_TO = 0x8,
+ VERB_GIVE = 0x9,
+ VERB_PULL = 0xA,
+ VERB_CLOSE = 0xB,
+ VERB_THROW = 0xC,
+ VERB_WALK_TO = 0xD,
+ VERB_CLIMB_DOWN = 0x21,
+ VERB_CLIMB_INTO = 0x22,
+ VERB_CLIMB_THROUGH = 0x23,
+ VERB_EXIT_TO = 0x37,
+ VERB_JUMP_INTO = 0x53,
+ VERB_LOOK_AT = 0x60,
+ VERB_LOOK_THROUGH = 0x61,
+ VERB_TURN_OFF = 0x95,
+ VERB_TURN_ON = 0x96,
+ VERB_UNLOCK = 0x97,
+ VERB_WALK_ACROSS = 0x99,
+ VERB_WALK_DOWN = 0x9A,
+ VERB_WALK_THROUGH = 0x9B,
+ VERB_WALK_UP = 0x9C,
+ VERB_CLIMB_UP = 0xA5,
+ VERB_WALK_ONTO = 0xA6,
+ VERB_WALK = 0xA7
+};
+
enum Noun {
NOUN_GAME = 0x1,
NOUN_QSAVE = 0x2,
- NOUN_LOOK = 0x3,
- NOUN_TAKE = 0x4,
- NOUN_PUSH = 0x5,
- NOUN_OPEN = 0x6,
- NOUN_PUT = 0x7,
- NOUN_TALK_TO = 0x8,
- NOUN_GIVE = 0x9,
- NOUN_PULL = 0xA,
- NOUN_CLOSE = 0xB,
- NOUN_THROW = 0xC,
- NOUN_WALK_TO = 0xD,
NOUN_ = 0xE,
NOUN_IN_ONE = 0xF,
NOUN_IN_TWO = 0x10,
@@ -67,9 +87,6 @@ enum Noun {
NOUN_CEILING = 0x1E,
NOUN_CHAIR = 0x1F,
NOUN_CIRCULAR_STAIRCASE = 0x20,
- NOUN_CLIMB_DOWN = 0x21,
- NOUN_CLIMB_INTO = 0x22,
- NOUN_CLIMB_THROUGH = 0x23,
NOUN_COLUMN_PROP = 0x24,
NOUN_CONDUCTORS_STAND = 0x25,
NOUN_CORRIDOR = 0x26,
@@ -89,7 +106,6 @@ enum Noun {
NOUN_EXIT = 0x34,
NOUN_EXIT_DOWN = 0x35,
NOUN_EXIT_SIGN = 0x36,
- NOUN_EXIT_TO = 0x37,
NOUN_EXIT_TO_BACKSTAGE = 0x38,
NOUN_EXIT_TO_CELLAR = 0x39,
NOUN_EXIT_TO_CORRIDOR = 0x3A,
@@ -117,7 +133,6 @@ enum Noun {
NOUN_HOUSE = 0x50,
NOUN_IN_ONE2 = 0x51,
NOUN_IN_TWO2 = 0x52,
- NOUN_JUMP_INTO = 0x53,
NOUN_JUNK = 0x54,
NOUN_KEY = 0x55,
NOUN_LAMP = 0x56,
@@ -130,8 +145,6 @@ enum Noun {
NOUN_LOCK = 0x5D,
NOUN_LOCKING_RAIL = 0x5E,
NOUN_LOCKRAIL = 0x5F,
- NOUN_LOOK_AT = 0x60,
- NOUN_LOOK_THROUGH = 0x61,
NOUN_MANNEQUINS = 0x62,
NOUN_MIRROR = 0x63,
NOUN_MUMMY_PROP = 0x64,
@@ -183,14 +196,7 @@ enum Noun {
NOUN_TICKET = 0x92,
NOUN_TRAP_CEILING = 0x93,
NOUN_TRAP_DOOR = 0x94,
- NOUN_TURN_OFF = 0x95,
- NOUN_TURN_ON = 0x96,
- NOUN_UNLOCK = 0x97,
NOUN_URN = 0x98,
- NOUN_WALK_ACROSS = 0x99,
- NOUN_WALK_DOWN = 0x9A,
- NOUN_WALK_THROUGH = 0x9B,
- NOUN_WALK_UP = 0x9C,
NOUN_WALL = 0x9D,
NOUN_WARDROBE = 0x9E,
NOUN_WASTE_BASKET = 0x9F,
@@ -199,9 +205,6 @@ enum Noun {
NOUN_WEDDING_RING = 0xA2,
NOUN_YELLOW_FRAME = 0xA3,
NOUN_PROP = 0xA4,
- NOUN_CLIMB_UP = 0xA5,
- NOUN_WALK_ONTO = 0xA6,
- NOUN_WALK = 0xA7,
NOUN_LEFT_DOOR = 0xA8,
NOUN_RIGHT_DOOR = 0xA9,
NOUN_DOOR_TO_PIT = 0xAA,
@@ -482,27 +485,6 @@ protected:
};
// TODO: Temporary, remove once implemented properly
-class Scene1xx : public PhantomScene {
-protected:
- /**
- * Plays an appropriate sound when entering a scene
- */
- void sceneEntrySound() {}
-
- /**
- *Sets the AA file to use for the scene
- */
- void setAAName() {}
-
- /**
- * Updates the prefix used for getting player sprites for the scene
- */
- void setPlayerSpritesPrefix() {}
-public:
- Scene1xx(MADSEngine *vm) : PhantomScene(vm) {}
-};
-
-// TODO: Temporary, remove once implemented properly
class DummyScene : public PhantomScene {
public:
DummyScene(MADSEngine *vm) : PhantomScene(vm) {
diff --git a/engines/mads/phantom/phantom_scenes1.cpp b/engines/mads/phantom/phantom_scenes1.cpp
new file mode 100644
index 0000000000..2d991fd3bc
--- /dev/null
+++ b/engines/mads/phantom/phantom_scenes1.cpp
@@ -0,0 +1,282 @@
+/* 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/scummsys.h"
+#include "mads/mads.h"
+#include "mads/scene.h"
+#include "mads/phantom/phantom_scenes.h"
+#include "mads/phantom/phantom_scenes1.h"
+
+namespace MADS {
+
+namespace Phantom {
+
+void Scene1xx::setAAName() {
+ // TODO
+ //int idx = 0;
+ //_game._aaName = Resources::formatAAName(idx);
+}
+
+void Scene1xx::sceneEntrySound() {
+ // TODO
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene101::Scene101(MADSEngine *vm) : Scene1xx(vm) {
+
+}
+
+void Scene101::synchronize(Common::Serializer &s) {
+ Scene1xx::synchronize(s);
+
+}
+
+void Scene101::setup() {
+ //setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene101::enter() {
+ // TODO
+
+ if (_globals[kCurrentYear] == 1993) {
+ _globals._spriteIndexes[0] = _scene->_sprites.addSprites(formAnimName('z', -1));
+ // TODO
+ //_scene->_sequences.setDepth(_globals._sequenceIndexes[0], 14);
+ } else {
+ // TODO
+ }
+
+ // TODO
+}
+
+void Scene101::step() {
+ // TODO
+}
+
+void Scene101::preActions() {
+ if (_action.isAction(VERB_EXIT_TO, NOUN_ORCHESTRA_PIT)) {
+ // TODO: Handle Brie
+ _game._player._walkOffScreenSceneId = 102;
+ } else if (_action.isAction(VERB_EXIT_TO, NOUN_GRAND_FOYER)) {
+ // TODO: Handle Brie
+ _game._player._walkOffScreenSceneId = 202;
+ } else if (_action.isAction(VERB_TAKE, NOUN_MONSIEUR_BRIE)) {
+ _vm->_dialogs->show(10121);
+ } else if (_action.isAction(VERB_TALK_TO, NOUN_MONSIEUR_BRIE)) {
+ if (_globals[kBrieTalkStatus] == 2)
+ _game._player._needToWalk = false;
+ }
+
+ // TODO
+}
+
+void Scene101::actions() {
+ // TODO: Brie conversation
+
+ // TODO: Look around
+
+ if (_action.isAction(VERB_LOOK) || _action.isAction(VERB_LOOK_AT)) {
+ if (_action.isObject(NOUN_AISLE)) {
+ _vm->_dialogs->show(10112);
+ } else if (_action.isObject(NOUN_CHANDELIER)) {
+ _vm->_dialogs->show(10113);
+ } else if (_action.isObject(NOUN_BACK_WALL)) {
+ _vm->_dialogs->show(10114);
+ } else if (_action.isObject(NOUN_SIDE_WALL)) {
+ _vm->_dialogs->show(10115);
+ } else if (_action.isObject(NOUN_SEATS)) {
+ // TODO: Finish this
+ _vm->_dialogs->show(10116);
+ } else if (_action.isObject(NOUN_GRAND_FOYER)) {
+ _vm->_dialogs->show(10117);
+ } else if (_action.isObject(NOUN_ORCHESTRA_PIT)) {
+ _vm->_dialogs->show(10118);
+ } else if (_action.isObject(NOUN_MONSIEUR_BRIE)) {
+ _vm->_dialogs->show(10120);
+ }
+
+ _game._player._stepEnabled = true;
+ } else if (_action.isAction(VERB_TALK_TO, NOUN_MONSIEUR_BRIE)) {
+ if (_globals[kBrieTalkStatus] == 2)
+ _vm->_dialogs->show(10122);
+ _game._player._stepEnabled = true;
+ } else if (_action.isAction(VERB_TAKE, NOUN_MONSIEUR_BRIE)) {
+ _game._player._stepEnabled = true;
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene102::Scene102(MADSEngine *vm) : Scene1xx(vm) {
+ _animRunningFl = false;
+}
+
+void Scene102::synchronize(Common::Serializer &s) {
+ Scene1xx::synchronize(s);
+
+ s.syncAsByte(_animRunningFl);
+}
+
+void Scene102::setup() {
+ //setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene102::enter() {
+ _animRunningFl = false;
+
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('x', 0));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites("*RAL86");
+
+ if (_globals[kCurrentYear] == 1993) {
+ _globals._spriteIndexes[0] = _scene->_sprites.addSprites(formAnimName('z', -1));
+ // TODO
+ //_scene->_sequences.setDepth(_globals._sequenceIndexes[0], 14);
+ } else {
+ // TODO
+ }
+
+ if (_scene->_priorSceneId == 101) {
+ _game._player._playerPos = Common::Point(97, 79);
+ _game._player._facing = FACING_SOUTHEAST;
+ // TODO
+ _game._player.walk(Common::Point(83, 87), FACING_SOUTHEAST);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 14);
+ } else if (_scene->_priorSceneId == 104) {
+ // Player fell from pit -> death
+ // TODO
+ } else if (_scene->_priorSceneId == 103 || _scene->_priorSceneId != -1) {
+ _game._player._playerPos = Common::Point(282, 145);
+ _game._player._facing = FACING_WEST;
+ _animRunningFl = true;
+ // TODO: Door closing animation
+ } else if (_scene->_priorSceneId == -1) {
+ // TODO
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 14);
+ }
+
+ sceneEntrySound();
+}
+
+void Scene102::step() {
+ if (_game._trigger == 60) { // Door closes
+ // TODO
+ _animRunningFl = false;
+ } else if (_game._trigger == 65) { // Death
+ // TODO
+ _scene->_currentSceneId = 104;
+ }
+}
+
+void Scene102::preActions() {
+ if (_action.isAction(VERB_OPEN, NOUN_ORCHESTRA_DOOR) || _action.isAction(VERB_PUSH, NOUN_ORCHESTRA_DOOR)) {
+ _game._player.walk(Common::Point(282, 145), FACING_EAST);
+ }
+}
+
+void Scene102::actions() {
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_AISLE)) {
+ _scene->_nextSceneId = 101;
+ _game._player._stepEnabled = true;
+ }
+
+ if (_action.isAction(VERB_WALK_THROUGH, NOUN_ORCHESTRA_DOOR) ||
+ _action.isAction(VERB_PUSH, NOUN_ORCHESTRA_DOOR) ||
+ _action.isAction(VERB_OPEN, NOUN_ORCHESTRA_DOOR)) {
+ if (_animRunningFl) {
+ // TODO
+ } else {
+ _scene->_nextSceneId = 103; // FIXME: temporary HACK - remove!
+
+ switch (_game._trigger) {
+ case 70: // try again
+ case 0:
+ // TODO
+ break;
+ case 1:
+ _scene->_nextSceneId = 103;
+ break;
+ }
+ }
+
+ _game._player._stepEnabled = true;
+ }
+
+ // TODO: Look around
+
+ if (_action.isAction(VERB_LOOK) || _action.isAction(VERB_LOOK_AT)) {
+ if (_action.isObject(NOUN_PIT))
+ _vm->_dialogs->show(10211);
+ else if (_action.isObject(NOUN_SEATS))
+ if (_globals[kCurrentYear] == 1881)
+ _vm->_dialogs->show(10212);
+ else
+ _vm->_dialogs->show(10230);
+ else if (_action.isObject(NOUN_ORCHESTRA_DOOR))
+ _vm->_dialogs->show(10213);
+ else if (_action.isObject(NOUN_CONDUCTORS_STAND))
+ _vm->_dialogs->show(10214);
+ else if (_action.isObject(NOUN_MUSIC_STAND) || _action.isObject(NOUN_MUSIC_STANDS))
+ _vm->_dialogs->show(10215);
+ else if (_action.isObject(NOUN_PROMPTERS_BOX))
+ _vm->_dialogs->show(10217);
+ else if (_action.isObject(NOUN_STAGE))
+ _vm->_dialogs->show(10218);
+ else if (_action.isObject(NOUN_APRON))
+ _vm->_dialogs->show(10219);
+ else if (_action.isObject(NOUN_SIDE_WALL))
+ _vm->_dialogs->show(10220);
+ else if (_action.isObject(NOUN_FOLDING_CHAIRS))
+ _vm->_dialogs->show(10221);
+ else if (_action.isObject(NOUN_AISLE))
+ _vm->_dialogs->show(10222);
+ else if (_action.isObject(NOUN_PROSCENIUM_ARCH))
+ _vm->_dialogs->show(10223);
+ else if (_action.isObject(NOUN_ACT_CURTAIN))
+ _vm->_dialogs->show(10224);
+ else if (_action.isObject(NOUN_IN_ONE))
+ _vm->_dialogs->show(10225);
+ else if (_action.isObject(NOUN_IN_TWO))
+ _vm->_dialogs->show(10226);
+ else if (_action.isObject(NOUN_LEG))
+ _vm->_dialogs->show(10227);
+ else if (_action.isObject(NOUN_CHANDELIER))
+ _vm->_dialogs->show(10231);
+ else
+ return;
+
+ _game._player._stepEnabled = true;
+ }
+
+ if (_action.isAction(VERB_CLOSE, NOUN_ORCHESTRA_DOOR)) {
+ _vm->_dialogs->show(10228);
+ _game._player._stepEnabled = true;
+ }
+}
+
+
+/*------------------------------------------------------------------------*/
+
+} // End of namespace Phantom
+} // End of namespace MADS
diff --git a/engines/mads/phantom/phantom_scenes1.h b/engines/mads/phantom/phantom_scenes1.h
new file mode 100644
index 0000000000..0f5f56a4cf
--- /dev/null
+++ b/engines/mads/phantom/phantom_scenes1.h
@@ -0,0 +1,89 @@
+/* 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 MADS_PHANTOM_SCENES1_H
+#define MADS_PHANTOM_SCENES1_H
+
+#include "common/scummsys.h"
+#include "common/serializer.h"
+#include "mads/game.h"
+#include "mads/scene.h"
+#include "mads/phantom/phantom_scenes.h"
+
+namespace MADS {
+
+namespace Phantom {
+
+class Scene1xx : public PhantomScene {
+protected:
+ /**
+ * Plays an appropriate sound when entering a scene
+ */
+ void sceneEntrySound();
+
+ /**
+ *Sets the AA file to use for the scene
+ */
+ void setAAName();
+
+ /**
+ * Updates the prefix used for getting player sprites for the scene
+ */
+ void setPlayerSpritesPrefix();
+public:
+ Scene1xx(MADSEngine *vm) : PhantomScene(vm) {}
+};
+
+class Scene101 : public Scene1xx {
+private:
+ // TODO
+
+public:
+ Scene101(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene102 : public Scene1xx {
+private:
+ bool _animRunningFl;
+
+public:
+ Scene102(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+} // End of namespace Phantom
+} // End of namespace MADS
+
+#endif /* MADS_PHANTOM_SCENES1_H */
diff --git a/engines/mads/player.cpp b/engines/mads/player.cpp
index bde313af8d..bb747f4b52 100644
--- a/engines/mads/player.cpp
+++ b/engines/mads/player.cpp
@@ -8,12 +8,12 @@
* 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.
@@ -235,12 +235,18 @@ void Player::selectSeries() {
void Player::updateFrame() {
// WORKAROUND: Prevent character info being referenced when not present
- if ((_spritesStart + _spritesIdx) < 0 || !_spriteSetsPresent[_spritesStart + _spritesIdx])
+ int idx = _spritesStart + _spritesIdx;
+ if (idx < 0 || (idx < PLAYER_SPRITES_FILE_COUNT && !_spriteSetsPresent[idx]))
return;
Scene &scene = _vm->_game->_scene;
- SpriteAsset &spriteSet = *scene._sprites[_spritesStart + _spritesIdx];
- assert(spriteSet._charInfo);
+ assert(scene._sprites[idx] != nullptr);
+ SpriteAsset &spriteSet = *scene._sprites[idx];
+
+ // WORKAROUND: Certain cutscenes set up player sprites that don't have any
+ // character info. In such cases, simply ignore player updates
+ if (!spriteSet._charInfo)
+ return;
if (!spriteSet._charInfo->_numEntries) {
_frameNumber = 1;
@@ -509,12 +515,12 @@ void Player::idle() {
return;
}
- if ((_spritesStart + _spritesIdx) < 0 || !_spriteSetsPresent[_spritesStart + _spritesIdx])
+ int idx = _spritesStart + _spritesIdx;
+ if (idx < 0 || (idx < PLAYER_SPRITES_FILE_COUNT && !_spriteSetsPresent[idx]))
return;
- SpriteAsset &spriteSet = *scene._sprites[_spritesStart + _spritesIdx];
- assert(spriteSet._charInfo);
- if (spriteSet._charInfo->_numEntries == 0)
+ SpriteAsset &spriteSet = *scene._sprites[idx];
+ if (spriteSet._charInfo == nullptr || spriteSet._charInfo->_numEntries == 0)
// No entries, so exit immediately
return;
@@ -528,11 +534,11 @@ void Player::idle() {
_frameNumber += direction;
_forceRefresh = true;
- if (spriteSet._charInfo->_stopFrames[frameIndex] < _frameNumber) {
+ if (_frameNumber > spriteSet._charInfo->_stopFrames[frameIndex]) {
_trigger = _upcomingTrigger;
updateFrame();
}
- if (spriteSet._charInfo->_startFrames[frameIndex] < _frameNumber) {
+ if (_frameNumber < spriteSet._charInfo->_startFrames[frameIndex]) {
_trigger = _upcomingTrigger;
updateFrame();
}
@@ -658,7 +664,7 @@ void Player::startMovement() {
_deltaDistance = (majorChange == 0) ? 0 : _totalDistance / majorChange;
if (_playerPos.x > _targetPos.x)
- _pixelAccum = MAX(_posChange.x, _posChange.y);
+ _pixelAccum = MIN(_posChange.x, _posChange.y);
else
_pixelAccum = 0;
@@ -703,7 +709,7 @@ void Player::releasePlayerSprites() {
_spritesLoaded = false;
_spritesChanged = true;
- if (scene._sprites._assetCount > 0) {
+ if (scene._sprites.size() > 0) {
warning("Player::releasePlayerSprites(): leftover sprites remain, clearing list");
scene._sprites.clear();
}
@@ -779,14 +785,14 @@ void Player::removePlayerSprites() {
int heroSpriteId = _spritesStart;
for (int i = 0; i < 8; i++) {
if (_spriteSetsPresent[i]) {
- scene._sprites.remove(heroSpriteId++);
+ delete scene._sprites[heroSpriteId];
+ scene._sprites[heroSpriteId] = nullptr;
_spriteSetsPresent[i] = false;
+ ++heroSpriteId;
}
}
- if (scene._activeAnimation != nullptr)
- scene._activeAnimation->resetSpriteSetsCount();
-
+ scene._spriteSlots.clear();
scene._spriteSlots.fullRefresh();
_visible = false;
}
diff --git a/engines/mads/player.h b/engines/mads/player.h
index 671ac9d16e..e5765a9bca 100644
--- a/engines/mads/player.h
+++ b/engines/mads/player.h
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/rails.cpp b/engines/mads/rails.cpp
index 322e6e7cb3..9b2ec71de6 100644
--- a/engines/mads/rails.cpp
+++ b/engines/mads/rails.cpp
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/rails.h b/engines/mads/rails.h
index e6cab08f85..c95f5c47a6 100644
--- a/engines/mads/rails.h
+++ b/engines/mads/rails.h
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/resources.cpp b/engines/mads/resources.cpp
index 1fb75e6ba2..d5352fb205 100644
--- a/engines/mads/resources.cpp
+++ b/engines/mads/resources.cpp
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/resources.h b/engines/mads/resources.h
index 8d9ab1e39f..95ea17d3c4 100644
--- a/engines/mads/resources.h
+++ b/engines/mads/resources.h
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/scene.cpp b/engines/mads/scene.cpp
index d2b4b29622..ee5f1a5440 100644
--- a/engines/mads/scene.cpp
+++ b/engines/mads/scene.cpp
@@ -8,12 +8,12 @@
* 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.
@@ -52,7 +52,7 @@ Scene::Scene(MADSEngine *vm)
_activeAnimation = nullptr;
_textSpacing = -1;
_frameStartTime = 0;
- _layer = LAYER_GUI;
+ _mode = SCREENMODE_VGA;
_lookFlag = false;
_bandsRange = 0;
_scaleRange = 0;
@@ -500,14 +500,12 @@ void Scene::drawElements(ScreenTransition transitionType, bool surfaceFlag) {
_dirtyAreas.copy(&_backgroundSurface, &_vm->_screen, _posAdjust);
// Handle dirty areas for foreground objects
- if (_vm->getGameID() == GType_RexNebular) // TODO: Implement for V2 games
- _spriteSlots.setDirtyAreas();
+ _spriteSlots.setDirtyAreas();
_textDisplay.setDirtyAreas2();
_dirtyAreas.merge(1, DIRTY_AREAS_SIZE);
// Draw sprites that have changed
- if (_vm->getGameID() == GType_RexNebular) // TODO: Implement for V2 games
- _spriteSlots.drawSprites(&_sceneSurface);
+ _spriteSlots.drawSprites(&_sceneSurface);
// Draw text elements onto the view
_textDisplay.draw(&_vm->_screen);
@@ -592,12 +590,14 @@ void Scene::doSceneStep() {
}
void Scene::checkKeyboard() {
- if (_vm->_events->isKeyPressed()) {
- Common::Event evt = _vm->_events->_pendingKeys.pop();
+ EventsManager &events = *_vm->_events;
+
+ if (events.isKeyPressed()) {
+ Common::KeyState evt = events.getKey();
_vm->_game->handleKeypress(evt);
}
- if ((_vm->_events->_mouseStatus & 3) == 3 && _vm->_game->_player._stepEnabled) {
+ if ((events._mouseStatus & 3) == 3 && _vm->_game->_player._stepEnabled) {
_reloadSceneFlag = true;
_vm->_dialogs->_pendingDialog = DIALOG_GAME_MENU;
_action.clear();
@@ -664,6 +664,7 @@ void Scene::freeCurrentScene() {
}
_vm->_palette->_paletteUsage.load(nullptr);
+ _cyclingActive = false;
_hotspots.clear();
_backgroundSurface.free();
_depthSurface.free();
diff --git a/engines/mads/scene.h b/engines/mads/scene.h
index 9fd99ad8e5..c0784c3812 100644
--- a/engines/mads/scene.h
+++ b/engines/mads/scene.h
@@ -8,12 +8,12 @@
* 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.
@@ -40,6 +40,8 @@
namespace MADS {
+enum { RETURNING_FROM_DIALOG = -2, RETURNING_FROM_LOADING = -1 };
+
class Scene {
private:
/**
@@ -121,7 +123,7 @@ public:
bool _reloadSceneFlag;
Common::Point _posAdjust;
uint32 _frameStartTime;
- Layer _layer;
+ ScreenMode _mode;
bool _lookFlag;
Common::Point _customDest;
Common::Array<PaletteUsage::UsageEntry> _paletteUsageF;
diff --git a/engines/mads/scene_data.cpp b/engines/mads/scene_data.cpp
index b5e219ed04..e48bcd8c6f 100644
--- a/engines/mads/scene_data.cpp
+++ b/engines/mads/scene_data.cpp
@@ -86,7 +86,8 @@ void ARTHeader::load(Common::SeekableReadStream *f, bool isV2) {
void SceneInfo::SpriteInfo::load(Common::SeekableReadStream *f) {
f->skip(3);
_spriteSetIndex = f->readByte();
- f->skip(2);
+ _frameNumber = f->readSByte();
+ f->skip(1);
_position.x = f->readSint16LE();
_position.y = f->readSint16LE();
_depth = f->readByte();
@@ -263,9 +264,9 @@ void SceneInfo::load(int sceneId, int variant, const Common::String &resName,
SpriteAsset *asset = spriteSets[si._spriteSetIndex];
assert(asset && _depthStyle != 2);
- MSprite *spr = asset->getFrame(asset->getCount() - 1);
+ MSprite *spr = asset->getFrame(si._frameNumber);
bgSurface.copyFrom(spr, si._position, si._depth, &depthSurface,
- si._scale, spr->getTransparencyIndex());
+ si._scale, false, spr->getTransparencyIndex());
}
// Free the sprite sets
@@ -468,6 +469,7 @@ void SceneInfo::loadMadsV2Background(int sceneId, const Common::String &resName,
for (int i = 0; i < tileIndex; i++)
++tile;
((*tile).get())->copyTo(&bgSurface, Common::Point(x * tileWidth, y * tileHeight));
+ ((*tile).get())->free();
}
}
tileSet.clear();
diff --git a/engines/mads/scene_data.h b/engines/mads/scene_data.h
index 41e094b8f5..41a08f74eb 100644
--- a/engines/mads/scene_data.h
+++ b/engines/mads/scene_data.h
@@ -144,6 +144,7 @@ class SceneInfo {
public:
int _spriteSetIndex;
Common::Point _position;
+ int _frameNumber;
int _depth;
int _scale;
diff --git a/engines/mads/screen.cpp b/engines/mads/screen.cpp
index c9a0863d85..3c27001ae0 100644
--- a/engines/mads/screen.cpp
+++ b/engines/mads/screen.cpp
@@ -8,12 +8,12 @@
* 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.
@@ -244,7 +244,7 @@ void DirtyAreas::reset() {
ScreenObject::ScreenObject() {
_category = CAT_NONE;
_descId = 0;
- _layer = 0;
+ _mode = 0;
_active = false;
}
@@ -265,17 +265,17 @@ ScreenObjects::ScreenObjects(MADSEngine *vm) : _vm(vm) {
_baseTime = 0;
}
-void ScreenObjects::add(const Common::Rect &bounds, Layer layer, ScrCategory category, int descId) {
- //assert(size() < 100);
-
+ScreenObject *ScreenObjects::add(const Common::Rect &bounds, ScreenMode mode, ScrCategory category, int descId) {
ScreenObject so;
so._bounds = bounds;
so._category = category;
so._descId = descId;
- so._layer = layer;
+ so._mode = mode;
so._active = true;
push_back(so);
+
+ return &(*this)[size()];
}
void ScreenObjects::check(bool scanFlag) {
@@ -288,7 +288,7 @@ void ScreenObjects::check(bool scanFlag) {
if ((_vm->_events->_mouseMoved || userInterface._scrollbarActive
|| _v8332A || _forceRescan) && scanFlag) {
_category = CAT_NONE;
- _selectedObject = scanBackwards(_vm->_events->currentPos(), LAYER_GUI);
+ _selectedObject = scanBackwards(_vm->_events->currentPos(), SCREENMODE_VGA);
if (_selectedObject > 0) {
ScreenObject &scrObject = (*this)[_selectedObject];
_category = (ScrCategory)(scrObject._category & 7);
@@ -308,10 +308,10 @@ void ScreenObjects::check(bool scanFlag) {
}
//_released = _vm->_events->_mouseReleased;
- if (_vm->_events->_vD2 || (_vm->_easyMouse && !_vm->_events->_mouseStatusCopy))
+ if (_vm->_events->_mouseButtons || (_vm->_easyMouse && !_vm->_events->_mouseStatusCopy))
scene._userInterface._category = _category;
- if (!_vm->_events->_mouseButtons || _vm->_easyMouse) {
+ if (_vm->_events->_mouseButtons || _vm->_easyMouse) {
if (userInterface._category >= CAT_COMMAND && userInterface._category <= CAT_TALK_ENTRY) {
elementHighlighted();
}
@@ -365,7 +365,7 @@ void ScreenObjects::check(bool scanFlag) {
int ScreenObjects::scan(const Common::Point &pt, int layer) {
for (uint i = 1; i <= size(); ++i) {
ScreenObject &sObj = (*this)[i];
- if (sObj._active && sObj._bounds.contains(pt) && sObj._layer == layer)
+ if (sObj._active && sObj._bounds.contains(pt) && sObj._mode == layer)
return i;
}
@@ -376,7 +376,7 @@ int ScreenObjects::scan(const Common::Point &pt, int layer) {
int ScreenObjects::scanBackwards(const Common::Point &pt, int layer) {
for (int i = (int)size(); i >= 1; --i) {
ScreenObject &sObj = (*this)[i];
- if (sObj._active && sObj._bounds.contains(pt) && sObj._layer == layer)
+ if (sObj._active && sObj._bounds.contains(pt) && sObj._mode == layer)
return i;
}
@@ -526,7 +526,7 @@ void ScreenObjects::elementHighlighted() {
action._pickedWord = newIndex;
if (_category == CAT_INV_LIST || _category == CAT_INV_ANIM) {
- if (action._interAwaiting == 1 && newIndex >= 0 && _released &&
+ if (action._interAwaiting == AWAITING_COMMAND && newIndex >= 0 && _released &&
(!_vm->_events->_mouseReleased || !_vm->_easyMouse))
newIndex = -1;
}
@@ -540,7 +540,7 @@ void ScreenObjects::elementHighlighted() {
}
void ScreenObjects::setActive(ScrCategory category, int descId, bool active) {
- for (uint idx = 1; idx < size(); ++idx) {
+ for (uint idx = 1; idx <= size(); ++idx) {
ScreenObject &sObj = (*this)[idx];
if (sObj._category == category && sObj._descId == descId)
sObj._active = active;
@@ -571,7 +571,7 @@ void ScreenSurface::init() {
}
ScreenSurface::~ScreenSurface() {
- delete[] _surfacePixels;
+ ::free(_surfacePixels);
}
void ScreenSurface::copyRectToScreen(const Common::Rect &bounds) {
@@ -609,9 +609,10 @@ void ScreenSurface::updateScreen() {
void ScreenSurface::transition(ScreenTransition transitionType, bool surfaceFlag) {
Palette &pal = *_vm->_palette;
+ Scene &scene = _vm->_game->_scene;
byte palData[PALETTE_SIZE];
- switch (transitionType) {
+ switch (transitionType) {
case kTransitionFadeIn:
case kTransitionFadeOutIn:
Common::fill(&pal._colorValues[0], &pal._colorValues[3], 0);
@@ -641,8 +642,9 @@ void ScreenSurface::transition(ScreenTransition transitionType, bool surfaceFlag
case kTransitionPanLeftToRight:
case kTransitionPanRightToLeft:
- warning("TODO: pan transition");
- transition(kTransitionFadeIn, surfaceFlag);
+ panTransition(scene._backgroundSurface, pal._mainPalette,
+ transitionType - kTransitionPanLeftToRight,
+ Common::Point(0, 0), scene._posAdjust, THROUGH_BLACK2, true, 1);
break;
case kTransitionCircleIn1:
@@ -653,8 +655,10 @@ void ScreenSurface::transition(ScreenTransition transitionType, bool surfaceFlag
transition(kTransitionFadeIn, surfaceFlag);
break;
- case kCenterVertTransition:
- warning("TODO: center vert transition");
+ case kNullPaletteCopy:
+ // Original temporarily set the palette to black, copied the scene to the
+ // screen, and then restored the palette. We can give a similiar effect
+ // by doing a standard quick palette fade in
transition(kTransitionFadeIn, surfaceFlag);
break;
@@ -674,5 +678,143 @@ void ScreenSurface::resetClipBounds() {
setClipBounds(Common::Rect(0, 0, MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT));
}
+void ScreenSurface::panTransition(MSurface &newScreen, byte *palData, int entrySide,
+ const Common::Point &srcPos, const Common::Point &destPos,
+ ThroughBlack throughBlack, bool setPalette, int numTicks) {
+ EventsManager &events = *_vm->_events;
+ Palette &palette = *_vm->_palette;
+ Common::Point size;
+ int y1, y2;
+ int startX = 0;
+ int deltaX;
+ int xAt;
+ int loopStart;
+// uint32 baseTicks, currentTicks;
+ byte paletteMap[256];
+
+ size.x = MIN(newScreen.w, (uint16)MADS_SCREEN_WIDTH);
+ size.y = newScreen.h;
+ if (newScreen.h >= MADS_SCREEN_HEIGHT)
+ size.y = MADS_SCENE_HEIGHT;
+
+ // Set starting position and direction delta for the transition
+ if (entrySide == 1)
+ // Right to left
+ startX = size.x - 1;
+ deltaX = startX ? -1 : 1;
+
+ if (setPalette & !throughBlack)
+ palette.setFullPalette(palData);
+
+ // TODO: Original uses a different frequency ticks counter. Need to
+ // confirm frequency and see whether we need to implement it, or
+ // if the current frame ticks can substitute for it
+// baseTicks = events.getFrameCounter();
+
+ y1 = 0;
+ y2 = size.y - 1;
+// sizeY = y2 - y1 + 1;
+
+ if (throughBlack == THROUGH_BLACK2)
+ swapForeground(palData, &paletteMap[0]);
+
+ loopStart = throughBlack == THROUGH_BLACK1 ? 0 : 1;
+ for (int loop = loopStart; loop < 2; ++loop) {
+ xAt = startX;
+ for (int xCtr = 0; xCtr < size.x; ++xCtr, xAt += deltaX) {
+ if (!loop) {
+ fillRect(Common::Rect(xAt + destPos.x, y1 + destPos.y,
+ xAt + destPos.x + 1, y2 + destPos.y), 0);
+ } else if (throughBlack == THROUGH_BLACK2) {
+ copyRectTranslate(newScreen, paletteMap,
+ Common::Point(xAt, destPos.y),
+ Common::Rect(srcPos.x + xAt, srcPos.y,
+ srcPos.x + xAt + 1, srcPos.y + size.y));
+ } else {
+ newScreen.copyRectToSurface(*this, xAt, destPos.y,
+ Common::Rect(srcPos.x + xAt, srcPos.y,
+ srcPos.x + xAt + 1, srcPos.y + size.y));
+ }
+
+ copyRectToScreen(Common::Rect(xAt, destPos.y, xAt + 1, destPos.y + size.y));
+
+ // Slight delay
+ events.pollEvents();
+ g_system->delayMillis(1);
+ }
+
+ if ((setPalette && !loop) || throughBlack == THROUGH_BLACK2)
+ palette.setFullPalette(palData);
+ }
+
+ if (throughBlack == THROUGH_BLACK2) {
+ Common::Rect r(srcPos.x, srcPos.y, srcPos.x + size.x, srcPos.y + size.y);
+ copyRectToSurface(newScreen, destPos.x, destPos.y, r);
+ copyRectToScreen(r);
+ }
+}
+
+/**
+ * Translates the current screen from the old palette to the new palette
+ */
+void ScreenSurface::swapForeground(byte newPalette[PALETTE_SIZE], byte *paletteMap) {
+ Palette &palette = *_vm->_palette;
+ byte oldPalette[PALETTE_SIZE];
+ byte oldMap[PALETTE_COUNT];
+
+ palette.getFullPalette(oldPalette);
+ swapPalette(oldPalette, oldMap, true);
+ swapPalette(newPalette, paletteMap, false);
+
+ // Transfer translated foreground colors. Since foregrounds are interleaved
+ // with background, we only copy over each alternate RGB tuplet
+ const byte *srcP = &newPalette[RGB_SIZE];
+ byte *destP = &oldPalette[RGB_SIZE];
+ while (destP < &oldPalette[PALETTE_SIZE]) {
+ Common::copy(srcP, srcP + RGB_SIZE, destP);
+ srcP += 2 * RGB_SIZE;
+ destP += 2 * RGB_SIZE;
+ }
+
+ Common::Rect oldClip = _clipBounds;
+ resetClipBounds();
+
+ copyRectTranslate(*this, oldMap, Common::Point(0, 0),
+ Common::Rect(0, 0, MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT));
+ palette.setFullPalette(oldPalette);
+
+ setClipBounds(oldClip);
+}
+
+/**
+ * Translates a given palette into a mapping table.
+ * Palettes consist of 128 RGB entries for the foreground and background
+ * respectively, with the two interleaved together. So the start
+ */
+void ScreenSurface::swapPalette(const byte *palData, byte swapTable[PALETTE_COUNT],
+ bool foreground) {
+ int start = foreground ? 1 : 0;
+ const byte *dynamicList = &palData[start * RGB_SIZE];
+ int staticStart = 1 - start;
+ const byte *staticList = &palData[staticStart * RGB_SIZE];
+ const int PALETTE_START = 1;
+ const int PALETTE_END = 252;
+
+ // Set initial index values
+ for (int idx = 0; idx < PALETTE_COUNT; ++idx)
+ swapTable[idx] = idx;
+
+ // Handle the 128 palette entries for the foreground or background
+ for (int idx = 0; idx < (PALETTE_COUNT / 2); ++idx) {
+ if (start >= PALETTE_START && start <= PALETTE_END) {
+ swapTable[start] = Palette::closestColor(dynamicList, staticList,
+ 2 * RGB_SIZE, PALETTE_COUNT / 2) * 2 + staticStart;
+ }
+
+ dynamicList += 2 * RGB_SIZE;
+ start += 2;
+ }
+}
+
} // End of namespace MADS
diff --git a/engines/mads/screen.h b/engines/mads/screen.h
index 9d01ca82e3..d910e88633 100644
--- a/engines/mads/screen.h
+++ b/engines/mads/screen.h
@@ -8,12 +8,12 @@
* 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.
@@ -33,8 +33,8 @@ namespace MADS {
#define MADS_SCREEN_WIDTH 320
#define MADS_SCREEN_HEIGHT 200
-enum Layer {
- LAYER_GUI = 19
+enum ScreenMode {
+ SCREENMODE_VGA = 19
};
enum ScreenTransition {
@@ -47,7 +47,7 @@ enum ScreenTransition {
kTransitionCircleIn3, kTransitionCircleIn4,
kVertTransition1, kVertTransition2, kVertTransition3,
kVertTransition4, kVertTransition5, kVertTransition6,
- kVertTransition7, kCenterVertTransition
+ kVertTransition7, kNullPaletteCopy
};
enum InputMode {
@@ -56,6 +56,11 @@ enum InputMode {
kInputLimitedSentences = 2 // Use only scene hotspots
};
+enum ThroughBlack {
+ THROUGH_BLACK1 = 1,
+ THROUGH_BLACK2 = 2
+};
+
class SpriteSlot;
class TextDisplay;
class UISlot;
@@ -130,7 +135,7 @@ public:
Common::Rect _bounds;
ScrCategory _category;
int _descId;
- int _layer;
+ int _mode;
ScreenObject();
};
@@ -162,7 +167,7 @@ public:
/**
* Add a new item to the list
*/
- void add(const Common::Rect &bounds, Layer layer, ScrCategory category, int descId);
+ ScreenObject *add(const Common::Rect &bounds, ScreenMode mode, ScrCategory category, int descId);
/**
* Check objects on the screen
@@ -207,6 +212,14 @@ private:
uint16 _random;
byte *_surfacePixels;
Common::Rect _clipBounds;
+
+ void panTransition(MSurface &newScreen, byte *palData, int entrySide,
+ const Common::Point &srcPos, const Common::Point &destPos,
+ ThroughBlack throughBlack, bool setPalette, int numTicks);
+
+ void swapForeground(byte newPalette[PALETTE_SIZE], byte *paletteMap);
+
+ void swapPalette(const byte palData[PALETTE_SIZE], byte swapTable[PALETTE_COUNT], bool foreground);
public:
int _shakeCountdown;
public:
diff --git a/engines/mads/sequence.cpp b/engines/mads/sequence.cpp
index 05f00afb5a..e5bf1631c2 100644
--- a/engines/mads/sequence.cpp
+++ b/engines/mads/sequence.cpp
@@ -8,12 +8,12 @@
* 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.
@@ -95,8 +95,8 @@ bool SequenceList::addSubEntry(int index, SequenceTrigger mode, int frameIndex,
}
int SequenceList::add(int spriteListIndex, bool flipped, int frameIndex, int triggerCountdown, int delayTicks, int extraTicks, int numTicks,
- int msgX, int msgY, bool nonFixed, int scale, int depth, int frameInc, SpriteAnimType animType, int numSprites,
- int frameStart) {
+ int msgX, int msgY, bool nonFixed, int scale, int depth, int frameInc, SpriteAnimType animType, int numSprites,
+ int frameStart) {
Scene &scene = _vm->_game->_scene;
// Find a free slot
@@ -144,7 +144,7 @@ int SequenceList::add(int spriteListIndex, bool flipped, int frameIndex, int tri
return seqIndex;
}
-int SequenceList::addTimer(int timeout, int abortVal) {
+int SequenceList::addTimer(int timeout, int endTrigger) {
Scene &scene = _vm->_game->_scene;
uint seqIndex;
for (seqIndex = 0; seqIndex < _entries.size(); ++seqIndex) {
@@ -164,7 +164,7 @@ int SequenceList::addTimer(int timeout, int abortVal) {
se._entries._count = 0;
se._triggerMode = _vm->_game->_triggerSetupMode;
se._actionNouns = _vm->_game->_scene._action._activeAction;
- addSubEntry(seqIndex, SEQUENCE_TRIGGER_EXPIRE, 0, abortVal);
+ addSubEntry(seqIndex, SEQUENCE_TRIGGER_EXPIRE, 0, endTrigger);
return seqIndex;
}
@@ -181,6 +181,19 @@ void SequenceList::remove(int seqIndex) {
scene._spriteSlots.deleteTimer(seqIndex);
}
+int SequenceList::findByTrigger(int trigger) {
+ for (uint idx = 0; idx < _entries.size(); ++idx) {
+ if (_entries[idx]._active) {
+ for (int subIdx = 0; subIdx < _entries[idx]._entries._count; ++subIdx) {
+ if (_entries[idx]._entries._trigger[subIdx] == trigger)
+ return idx;
+ }
+ }
+ }
+
+ return -1;
+}
+
void SequenceList::setSpriteSlot(int seqIndex, SpriteSlot &spriteSlot) {
Scene &scene = _vm->_game->_scene;
SequenceEntry &timerEntry = _entries[seqIndex];
@@ -466,28 +479,28 @@ int SequenceList::startCycle(int srcSpriteIndex, bool flipped, int cycleIndex) {
return result;
}
-int SequenceList::startReverseCycle(int srcSpriteIndex, bool flipped, int numTicks,
+int SequenceList::startPingPongCycle(int srcSpriteIndex, bool flipped, int numTicks,
int triggerCountdown, int timeoutTicks, int extraTicks) {
SpriteAsset *sprites = _vm->_game->_scene._sprites[srcSpriteIndex];
MSprite *frame = sprites->getFrame(0);
int depth = _vm->_game->_scene._depthSurface.getDepth(Common::Point(
frame->_offset.x + frame->w / 2, frame->_offset.y + frame->h / 2));
- return add(srcSpriteIndex, flipped, sprites->getCount(), triggerCountdown, timeoutTicks,
- extraTicks, numTicks, 0, 0, true, 100, depth - 1, -1, ANIMTYPE_REVERSIBLE, 0, 0);
+ return add(srcSpriteIndex, flipped, 1, triggerCountdown, timeoutTicks,
+ extraTicks, numTicks, 0, 0, true, 100, depth - 1, 1, ANIMTYPE_PING_PONG, 0, 0);
}
-void SequenceList::updateTimeout(int spriteIdx, int seqIndex) {
+void SequenceList::updateTimeout(int srcSeqIndex, int destSeqIndex) {
Player &player = _vm->_game->_player;
int timeout;
- if (spriteIdx >= 0)
- timeout = _entries[spriteIdx]._timeout;
+ if (srcSeqIndex >= 0)
+ timeout = _entries[srcSeqIndex]._timeout;
else
timeout = player._priorTimer + player._ticksAmount;
- if (seqIndex >= 0)
- _entries[seqIndex]._timeout = timeout;
+ if (destSeqIndex >= 0)
+ _entries[destSeqIndex]._timeout = timeout;
else
player._priorTimer = timeout - player._ticksAmount;
@@ -526,8 +539,7 @@ void SequenceList::setMotion(int seqIndex, int flags, int deltaX, int deltaY) {
if (deltaY > 0) {
se._posSign.y = 1;
- }
- else if (deltaY < 0) {
+ } else if (deltaY < 0) {
se._posSign.y = -1;
} else {
se._posSign.y = 0;
diff --git a/engines/mads/sequence.h b/engines/mads/sequence.h
index ee587ff02d..c3a277c5a5 100644
--- a/engines/mads/sequence.h
+++ b/engines/mads/sequence.h
@@ -8,12 +8,12 @@
* 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.
@@ -38,7 +38,7 @@ enum SequenceTrigger {
SEQUENCE_TRIGGER_SPRITE = 2 // Trigger when sequence reaches specific sprite
};
-enum SpriteAnimType { ANIMTYPE_NONE = 0, ANIMTYPE_CYCLED = 1, ANIMTYPE_REVERSIBLE = 2 };
+enum SpriteAnimType { ANIMTYPE_NONE = 0, ANIMTYPE_CYCLED = 1, ANIMTYPE_PING_PONG = 2 };
#define SEQUENCE_ENTRY_SUBSET_MAX 5
@@ -101,8 +101,9 @@ public:
int extraTicks, int numTicks, int msgX, int msgY, bool nonFixed, int scale, int depth,
int frameInc, SpriteAnimType animType, int numSprites, int frameStart);
- int addTimer(int timeout, int abortVal);
+ int addTimer(int timeout, int endTrigger);
void remove(int seqIndex);
+ int findByTrigger(int trigger);
void setSpriteSlot(int seqIndex, SpriteSlot &spriteSlot);
bool loadSprites(int seqIndex);
void tick();
@@ -117,9 +118,9 @@ public:
int triggerCountdown = 0, int timeoutTicks = 0, int extraTicks = 0);
int startCycle(int srcSpriteIdx, bool flipped, int cycleIndex);
- int startReverseCycle(int srcSpriteIndex, bool flipped, int numTicks,
+ int startPingPongCycle(int srcSpriteIndex, bool flipped, int numTicks,
int triggerCountdown = 0, int timeoutTicks = 0, int extraTicks = 0);
- void updateTimeout(int spriteIdx, int seqIndex);
+ void updateTimeout(int destSeqIndex, int srcSeqIndex);
void setScale(int spriteIdx, int scale);
void setMsgLayout(int seqIndex);
void setDone(int seqIndex);
diff --git a/engines/mads/sound.cpp b/engines/mads/sound.cpp
index 1652550ba3..4a35edb80f 100644
--- a/engines/mads/sound.cpp
+++ b/engines/mads/sound.cpp
@@ -8,12 +8,12 @@
* 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.
@@ -21,6 +21,7 @@
*/
#include "audio/audiostream.h"
+#include "audio/fmopl.h"
#include "audio/decoders/raw.h"
#include "common/memstream.h"
#include "mads/sound.h"
@@ -36,9 +37,10 @@ SoundManager::SoundManager(MADSEngine *vm, Audio::Mixer *mixer) {
_pollSoundEnabled = false;
_soundPollFlag = false;
_newSoundsPaused = false;
+ _masterVolume = 255;
_opl = OPL::Config::create();
- _opl->init(11025);
+ _opl->init();
// Validate sound files
switch (_vm->getGameID()) {
@@ -62,6 +64,9 @@ SoundManager::~SoundManager() {
void SoundManager::init(int sectionNumber) {
assert(sectionNumber > 0 && sectionNumber < 10);
+ if (_driver != nullptr)
+ delete _driver;
+
switch (_vm->getGameID()) {
case GType_RexNebular:
switch (sectionNumber) {
@@ -94,15 +99,18 @@ void SoundManager::init(int sectionNumber) {
break;
default:
_driver = nullptr;
- break;
+ return;
}
break;
default:
warning("SoundManager: Unknown game");
_driver = nullptr;
- break;
+ return;
}
+
+ // Set volume for newly loaded driver
+ _driver->setVolume(_masterVolume);
}
void SoundManager::closeDriver() {
@@ -138,12 +146,22 @@ void SoundManager::startQueuedCommands() {
}
}
+void SoundManager::setVolume(int volume) {
+ _masterVolume = volume;
+
+ if (_driver)
+ _driver->setVolume(volume);
+}
+
void SoundManager::command(int commandId, int param) {
if (_newSoundsPaused) {
if (_queuedCommands.size() < 8)
_queuedCommands.push(commandId);
} else if (_driver) {
- _driver->command(commandId, param);
+ // Note: I don't know any way to identify music commands versus sfx
+ // commands, so if sfx is mute, then so is music
+ if (_vm->_soundFlag)
+ _driver->command(commandId, param);
}
}
diff --git a/engines/mads/sound.h b/engines/mads/sound.h
index 72bb21a812..9882f65e5a 100644
--- a/engines/mads/sound.h
+++ b/engines/mads/sound.h
@@ -8,12 +8,12 @@
* 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.
@@ -37,12 +37,13 @@ class SoundManager {
private:
MADSEngine *_vm;
Audio::Mixer *_mixer;
- FM_OPL *_opl;
+ OPL::OPL *_opl;
Nebular::ASound *_driver;
bool _pollSoundEnabled;
bool _soundPollFlag;
bool _newSoundsPaused;
Common::Queue<int> _queuedCommands;
+ int _masterVolume;
public:
SoundManager(MADSEngine *vm, Audio::Mixer *mixer);
~SoundManager();
@@ -78,6 +79,11 @@ public:
*/
void startQueuedCommands();
+ /**
+ * Set the master volume
+ */
+ void setVolume(int volume);
+
//@{
/**
* Executes a command on the sound driver
diff --git a/engines/mads/sprites.cpp b/engines/mads/sprites.cpp
index fd73930475..0a1c0b710d 100644
--- a/engines/mads/sprites.cpp
+++ b/engines/mads/sprites.cpp
@@ -8,12 +8,12 @@
* 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.
@@ -347,8 +347,10 @@ void SpriteSlots::drawSprites(MSurface *s) {
spr->copyTo(s, Common::Point(xp, yp), sprite->getTransparencyIndex());
// Free sprite if it was a flipped one
- if (flipped)
+ if (flipped) {
+ spr->free();
delete spr;
+ }
}
}
}
@@ -368,22 +370,18 @@ SpriteSets::~SpriteSets() {
}
int SpriteSets::add(SpriteAsset *asset, int idx) {
- if (idx)
- idx = idx + 49;
- else
- idx = size();
-
- if (idx >= (int)size())
- resize(idx + 1);
+ if (idx) {
+ assert(idx == 1);
+ delete _uiSprites;
+ _uiSprites = asset;
- if ((*this)[idx]) {
- delete (*this)[idx];
+ return SPRITE_SLOTS_MAX_SIZE;
} else {
- ++_assetCount;
- }
+ assert(size() < SPRITE_SLOTS_MAX_SIZE);
+ push_back(asset);
- (*this)[idx] = asset;
- return idx;
+ return (int)size() - 1;
+ }
}
int SpriteSets::addSprites(const Common::String &resName, int flags) {
@@ -393,25 +391,32 @@ int SpriteSets::addSprites(const Common::String &resName, int flags) {
void SpriteSets::clear() {
for (uint i = 0; i < size(); ++i)
delete (*this)[i];
-
- _assetCount = 0;
Common::Array<SpriteAsset *>::clear();
+
+ delete _uiSprites;
+ _uiSprites = nullptr;
}
void SpriteSets::remove(int idx) {
- if (idx >= 0) {
+ if (idx == SPRITE_SLOTS_MAX_SIZE) {
+ delete _uiSprites;
+ _uiSprites = nullptr;
+ } else if (idx >= 0 && idx < (int)size()) {
+ delete (*this)[idx];
+
if (idx < ((int)size() - 1)) {
- delete (*this)[idx];
(*this)[idx] = nullptr;
} else {
do {
remove_at(size() - 1);
} while (size() > 0 && (*this)[size() - 1] == nullptr);
}
-
- if (_assetCount > 0)
- --_assetCount;
}
}
+SpriteAsset *&SpriteSets::operator[](int idx) {
+ return (idx == SPRITE_SLOTS_MAX_SIZE) ? _uiSprites :
+ Common::Array<SpriteAsset *>::operator[](idx);
+}
+
} // End of namespace MADS
diff --git a/engines/mads/sprites.h b/engines/mads/sprites.h
index 6ea3c9e52e..3db922c40b 100644
--- a/engines/mads/sprites.h
+++ b/engines/mads/sprites.h
@@ -8,12 +8,12 @@
* 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.
@@ -202,12 +202,12 @@ class SpriteSets : public Common::Array<SpriteAsset *> {
private:
MADSEngine *_vm;
public:
- int _assetCount;
-
+ SpriteAsset *_uiSprites;
+public:
/**
* Constructor
*/
- SpriteSets(MADSEngine *vm) : _vm(vm), _assetCount(0) {}
+ SpriteSets(MADSEngine *vm) : _vm(vm), _uiSprites(nullptr) {}
/**
* Destructor
@@ -233,6 +233,8 @@ public:
* Remove an asset from the list
*/
void remove(int idx);
+
+ SpriteAsset *&operator[](int idx);
};
} // End of namespace MADS
diff --git a/engines/mads/staticres.cpp b/engines/mads/staticres.cpp
index 189e5f72e7..b659d9a27c 100644
--- a/engines/mads/staticres.cpp
+++ b/engines/mads/staticres.cpp
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/staticres.h b/engines/mads/staticres.h
index 560fd12e67..b805729327 100644
--- a/engines/mads/staticres.h
+++ b/engines/mads/staticres.h
@@ -8,12 +8,12 @@
* 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.
diff --git a/engines/mads/user_interface.cpp b/engines/mads/user_interface.cpp
index 1f8d5037bc..62fd036c03 100644
--- a/engines/mads/user_interface.cpp
+++ b/engines/mads/user_interface.cpp
@@ -8,12 +8,12 @@
* 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.
@@ -164,6 +164,7 @@ void UISlots::draw(bool updateFlag, bool delFlag) {
MSurface *spr = sprite->flipHorizontal();
userInterface.mergeFrom(spr, spr->getBounds(), slot._position,
sprite->getTransparencyIndex());
+ spr->free();
delete spr;
} else {
userInterface.mergeFrom(sprite, sprite->getBounds(), slot._position,
@@ -410,13 +411,21 @@ void UserInterface::setup(InputMode inputMode) {
}
void UserInterface::drawTextElements() {
- if (_vm->_game->_screenObjects._inputMode) {
- drawConversationList();
- } else {
+ switch (_vm->_game->_screenObjects._inputMode) {
+ case kInputBuildingSentences:
// Draw the actions
drawActions();
drawInventoryList();
drawItemVocabList();
+ break;
+
+ case kInputConversation:
+ drawConversationList();
+ break;
+
+ case kInputLimitedSentences:
+ default:
+ break;
}
}
@@ -495,7 +504,6 @@ void UserInterface::drawScroller() {
void UserInterface::updateInventoryScroller() {
ScreenObjects &screenObjects = _vm->_game->_screenObjects;
- Common::Array<int> &inventoryList = _vm->_game->_objects._inventoryList;
if (screenObjects._inputMode != kInputBuildingSentences)
return;
@@ -515,48 +523,11 @@ void UserInterface::updateInventoryScroller() {
uint32 timeInc = _scrollbarQuickly ? 100 : 380;
if (_vm->_events->_mouseStatus && (_scrollbarMilliTime + timeInc) <= currentMilli) {
- _scrollbarQuickly = _vm->_events->_vD2 < 1;
+ _scrollbarQuickly = _vm->_events->_strokeGoing < 1;
_scrollbarMilliTime = currentMilli;
- switch (_scrollbarStrokeType) {
- case SCROLLBAR_UP:
- // Scroll up
- if (_inventoryTopIndex > 0 && inventoryList.size() > 0) {
- --_inventoryTopIndex;
- _inventoryChanged = true;
- }
- break;
-
- case SCROLLBAR_DOWN:
- // Scroll down
- if (_inventoryTopIndex < ((int)inventoryList.size() - 1) && inventoryList.size() > 1) {
- ++_inventoryTopIndex;
- _inventoryChanged = true;
- }
- break;
-
- case SCROLLBAR_ELEVATOR: {
- // Inventory slider
- int newIndex = CLIP((int)_vm->_events->currentPos().y - 170, 0, 17)
- * inventoryList.size() / 10;
- if (newIndex >= (int)inventoryList.size())
- newIndex = inventoryList.size() - 1;
-
- if (inventoryList.size() > 0) {
- _inventoryChanged = newIndex != _inventoryTopIndex;
- _inventoryTopIndex = newIndex;
- }
- break;
- }
-
- default:
- break;
- }
-
- if (_inventoryChanged) {
- int dummy;
- updateSelection(CAT_INV_LIST, 0, &dummy);
- }
+ // Change the scrollbar and visible inventory list
+ changeScrollBar();
}
}
}
@@ -569,6 +540,54 @@ void UserInterface::updateInventoryScroller() {
_scrollbarOldElevator = _scrollbarElevator;
}
+void UserInterface::changeScrollBar() {
+ Common::Array<int> &inventoryList = _vm->_game->_objects._inventoryList;
+ ScreenObjects &screenObjects = _vm->_game->_screenObjects;
+
+ if (screenObjects._inputMode != kInputBuildingSentences)
+ return;
+
+ switch (_scrollbarStrokeType) {
+ case SCROLLBAR_UP:
+ // Scroll up
+ if (_inventoryTopIndex > 0 && inventoryList.size() > 0) {
+ --_inventoryTopIndex;
+ _inventoryChanged = true;
+ }
+ break;
+
+ case SCROLLBAR_DOWN:
+ // Scroll down
+ if (_inventoryTopIndex < ((int)inventoryList.size() - 1) && inventoryList.size() > 1) {
+ ++_inventoryTopIndex;
+ _inventoryChanged = true;
+ }
+ break;
+
+ case SCROLLBAR_ELEVATOR: {
+ // Inventory slider
+ int newIndex = CLIP((int)_vm->_events->currentPos().y - 170, 0, 17)
+ * inventoryList.size() / 10;
+ if (newIndex >= (int)inventoryList.size())
+ newIndex = inventoryList.size() - 1;
+
+ if (inventoryList.size() > 0) {
+ _inventoryChanged = newIndex != _inventoryTopIndex;
+ _inventoryTopIndex = newIndex;
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ if (_inventoryChanged) {
+ int dummy;
+ updateSelection(CAT_INV_LIST, 0, &dummy);
+ }
+}
+
void UserInterface::scrollbarChanged() {
Common::Rect r(73, 4, 73 + 9, 4 + 38);
_uiSlots.add(r);
@@ -673,7 +692,7 @@ void UserInterface::loadElements() {
getBounds(CAT_INV_SCROLLER, idx, bounds);
moveRect(bounds);
- _vm->_game->_screenObjects.add(bounds, LAYER_GUI, CAT_INV_SCROLLER, idx);
+ _vm->_game->_screenObjects.add(bounds, SCREENMODE_VGA, CAT_INV_SCROLLER, idx);
}
// Set up actions
@@ -682,7 +701,7 @@ void UserInterface::loadElements() {
getBounds(CAT_COMMAND, idx, bounds);
moveRect(bounds);
- _vm->_game->_screenObjects.add(bounds, LAYER_GUI, CAT_COMMAND, idx);
+ _vm->_game->_screenObjects.add(bounds, SCREENMODE_VGA, CAT_COMMAND, idx);
}
// Set up inventory list
@@ -691,7 +710,7 @@ void UserInterface::loadElements() {
getBounds(CAT_INV_LIST, _inventoryTopIndex + idx, bounds);
moveRect(bounds);
- _vm->_game->_screenObjects.add(bounds, LAYER_GUI, CAT_INV_LIST, idx);
+ _vm->_game->_screenObjects.add(bounds, SCREENMODE_VGA, CAT_INV_LIST, idx);
}
// Set up the inventory vocab list
@@ -700,12 +719,12 @@ void UserInterface::loadElements() {
getBounds(CAT_INV_VOCAB, idx, bounds);
moveRect(bounds);
- _vm->_game->_screenObjects.add(bounds, LAYER_GUI, CAT_INV_VOCAB, idx);
+ _vm->_game->_screenObjects.add(bounds, SCREENMODE_VGA, CAT_INV_VOCAB, idx);
}
// Set up the inventory item picture
_categoryIndexes[CAT_INV_ANIM - 1] = _vm->_game->_screenObjects.size() + 1;
- _vm->_game->_screenObjects.add(Common::Rect(160, 159, 231, 194), LAYER_GUI,
+ _vm->_game->_screenObjects.add(Common::Rect(160, 159, 231, 194), SCREENMODE_VGA,
CAT_INV_ANIM, 0);
}
@@ -714,7 +733,9 @@ void UserInterface::loadElements() {
_categoryIndexes[CAT_HOTSPOT - 1] = _vm->_game->_screenObjects.size() + 1;
for (int hotspotIdx = scene._hotspots.size() - 1; hotspotIdx >= 0; --hotspotIdx) {
Hotspot &hs = scene._hotspots[hotspotIdx];
- _vm->_game->_screenObjects.add(hs._bounds, LAYER_GUI, CAT_HOTSPOT, hotspotIdx);
+ ScreenObject *so = _vm->_game->_screenObjects.add(hs._bounds, SCREENMODE_VGA,
+ CAT_HOTSPOT, hotspotIdx);
+ so->_active = hs._active;
}
}
@@ -725,7 +746,7 @@ void UserInterface::loadElements() {
getBounds(CAT_TALK_ENTRY, idx, bounds);
moveRect(bounds);
- _vm->_game->_screenObjects.add(bounds, LAYER_GUI, CAT_TALK_ENTRY, idx);
+ _vm->_game->_screenObjects.add(bounds, SCREENMODE_VGA, CAT_TALK_ENTRY, idx);
}
}
@@ -833,23 +854,24 @@ void UserInterface::emptyConversationList() {
}
void UserInterface::addConversationMessage(int vocabId, const Common::String &msg) {
- assert(_talkStrings.size() < 5);
-
- _talkStrings.push_back(msg);
- _talkIds.push_back(vocabId);
+ // Only allow a maximum of 5 talk entries to be displayed
+ if (_talkStrings.size() < 5) {
+ _talkStrings.push_back(msg);
+ _talkIds.push_back(vocabId);
+ }
}
void UserInterface::loadInventoryAnim(int objectId) {
Scene &scene = _vm->_game->_scene;
noInventoryAnim();
- if (_vm->_invObjectsAnimated) {
- Common::String resName = Common::String::format("*OB%.3dI", objectId);
- SpriteAsset *asset = new SpriteAsset(_vm, resName, ASSET_SPINNING_OBJECT);
- _invSpritesIndex = scene._sprites.add(asset, 1);
- if (_invSpritesIndex >= 0) {
- _invFrameNumber = 1;
- }
+ // WORKAROUND: Even in still mode, we now load the animation frames for the
+ // object, so we can show the first frame as a 'still'
+ Common::String resName = Common::String::format("*OB%.3dI", objectId);
+ SpriteAsset *asset = new SpriteAsset(_vm, resName, ASSET_SPINNING_OBJECT);
+ _invSpritesIndex = scene._sprites.add(asset, 1);
+ if (_invSpritesIndex >= 0) {
+ _invFrameNumber = 1;
}
}
@@ -881,10 +903,13 @@ void UserInterface::inventoryAnim() {
_invSpritesIndex < 0)
return;
- // Move to the next frame number in the sequence, resetting if at the end
- SpriteAsset *asset = scene._sprites[_invSpritesIndex];
- if (++_invFrameNumber > asset->getCount())
- _invFrameNumber = 1;
+ // WORKAROUND: Fix still inventory display, which was broken in the original
+ if (_vm->_invObjectsAnimated) {
+ // Move to the next frame number in the sequence, resetting if at the end
+ SpriteAsset *asset = scene._sprites[_invSpritesIndex];
+ if (++_invFrameNumber > asset->getCount())
+ _invFrameNumber = 1;
+ }
// Loop through the slots list for inventory animation entry
for (uint i = 0; i < _uiSlots.size(); ++i) {
diff --git a/engines/mads/user_interface.h b/engines/mads/user_interface.h
index 89044c9bf1..1366aa2c32 100644
--- a/engines/mads/user_interface.h
+++ b/engines/mads/user_interface.h
@@ -8,12 +8,12 @@
* 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.
@@ -140,7 +140,6 @@ private:
bool _scrollFlag;
int _noSegmentsActive;
int _someSegmentsActive;
- ScrollbarActive _scrollbarStrokeType;
/**
* Loads the elements of the user interface
@@ -216,6 +215,7 @@ public:
bool _scrollbarQuickly;
uint32 _scrollbarMilliTime;
int _scrollbarElevator, _scrollbarOldElevator;
+ ScrollbarActive _scrollbarStrokeType;
public:
/**
* Constructor
@@ -275,6 +275,11 @@ public:
void updateSelection(ScrCategory category, int newIndex, int *idx);
+ /**
+ * Updates the current top visible item of the scrollbar
+ */
+ void changeScrollBar();
+
void scrollerChanged();
void scrollInventory();
diff --git a/engines/mohawk/configure.engine b/engines/mohawk/configure.engine
index fa9d15cffc..47402c4560 100644
--- a/engines/mohawk/configure.engine
+++ b/engines/mohawk/configure.engine
@@ -3,4 +3,4 @@
add_engine mohawk "Mohawk" yes "cstime myst riven" "Living Books"
add_engine cstime "Where in Time is Carmen Sandiego?" no
add_engine riven "Riven: The Sequel to Myst" no "" "" "16bit"
-add_engine myst "Myst" no "" "" "16bit"
+add_engine myst "Myst" no
diff --git a/engines/mohawk/console.cpp b/engines/mohawk/console.cpp
index d49f3e8637..9b5bae78be 100644
--- a/engines/mohawk/console.cpp
+++ b/engines/mohawk/console.cpp
@@ -248,9 +248,9 @@ bool MystConsole::Cmd_PlayMovie(int argc, const char **argv) {
return true;
}
- int8 stackNum = 0;
-
+ Common::String fileName;
if (argc == 3 || argc > 4) {
+ int8 stackNum = 0;
for (byte i = 1; i <= ARRAYSIZE(mystStackNames); i++)
if (!scumm_stricmp(argv[2], mystStackNames[i - 1])) {
stackNum = i;
@@ -261,16 +261,27 @@ bool MystConsole::Cmd_PlayMovie(int argc, const char **argv) {
debugPrintf("\'%s\' is not a stack name!\n", argv[2]);
return true;
}
+
+ fileName = _vm->wrapMovieFilename(argv[1], stackNum - 1);
+ } else {
+ fileName = argv[1];
}
- if (argc == 2)
- _vm->_video->playMovie(argv[1], 0, 0);
- else if (argc == 3)
- _vm->_video->playMovie(_vm->wrapMovieFilename(argv[1], stackNum - 1), 0, 0);
- else if (argc == 4)
- _vm->_video->playMovie(argv[1], atoi(argv[2]), atoi(argv[3]));
- else
- _vm->_video->playMovie(_vm->wrapMovieFilename(argv[1], stackNum - 1), atoi(argv[3]), atoi(argv[4]));
+ VideoHandle handle = _vm->_video->playMovie(fileName);
+ if (!handle) {
+ debugPrintf("Failed to open movie '%s'\n", fileName.c_str());
+ return true;
+ }
+
+ if (argc == 4) {
+ handle->setX(atoi(argv[2]));
+ handle->setY(atoi(argv[3]));
+ } else if (argc > 4) {
+ handle->setX(atoi(argv[3]));
+ handle->setY(atoi(argv[4]));
+ } else {
+ handle->center();
+ }
return false;
}
diff --git a/engines/mohawk/cursors.cpp b/engines/mohawk/cursors.cpp
index f1baac02e2..4b66829e6a 100644
--- a/engines/mohawk/cursors.cpp
+++ b/engines/mohawk/cursors.cpp
@@ -122,7 +122,11 @@ void MystCursorManager::setCursor(uint16 id) {
// Myst ME stores some cursors as 24bpp images instead of 8bpp
if (surface->format.bytesPerPixel == 1) {
CursorMan.replaceCursor(surface->getPixels(), surface->w, surface->h, hotspotX, hotspotY, 0);
- CursorMan.replaceCursorPalette(mhkSurface->getPalette(), 0, 256);
+
+ // We're using the screen palette for the original game, but we need
+ // to use this for any 8bpp cursor in ME.
+ if (_vm->getFeatures() & GF_ME)
+ CursorMan.replaceCursorPalette(mhkSurface->getPalette(), 0, 256);
} else {
Graphics::PixelFormat pixelFormat = g_system->getScreenFormat();
CursorMan.replaceCursor(surface->getPixels(), surface->w, surface->h, hotspotX, hotspotY, pixelFormat.RGBToColor(255, 255, 255), false, &pixelFormat);
diff --git a/engines/mohawk/detection_tables.h b/engines/mohawk/detection_tables.h
index 7632cde294..6bb836b5b8 100644
--- a/engines/mohawk/detection_tables.h
+++ b/engines/mohawk/detection_tables.h
@@ -1379,6 +1379,22 @@ static const MohawkGameDescription gameDescriptions[] = {
"GRANDMA.EXE"
},
+ // Just Grandma and Me 1.0, Macintosh
+ {
+ {
+ "grandma",
+ "v1.0",
+ AD_ENTRY1("BookOutline", "9162483da06179e76f4a082412245efa"),
+ Common::EN_ANY,
+ Common::kPlatformMacintosh,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NOASPECT)
+ },
+ GType_LIVINGBOOKSV1,
+ GF_LB_10,
+ 0
+ },
+
// Just Grandma and Me 1.1 Mac
// From eisnerguy1 in bug#3610725
{
diff --git a/engines/mohawk/livingbooks.cpp b/engines/mohawk/livingbooks.cpp
index 998ef048f6..5af8fac901 100644
--- a/engines/mohawk/livingbooks.cpp
+++ b/engines/mohawk/livingbooks.cpp
@@ -363,6 +363,44 @@ void MohawkEngine_LivingBooks::destroyPage() {
_focus = NULL;
}
+// Replace any colons (originally a slash) with another character
+static Common::String replaceColons(const Common::String &in, char replace) {
+ Common::String out;
+
+ for (uint32 i = 0; i < in.size(); i++) {
+ if (in[i] == ':')
+ out += replace;
+ else
+ out += in[i];
+ }
+
+ return out;
+}
+
+// Helper function to assist in opening pages
+static bool tryOpenPage(Archive *archive, const Common::String &fileName) {
+ // Try the plain file name first
+ if (archive->openFile(fileName))
+ return true;
+
+ // No colons, then bail out
+ if (!fileName.contains(':'))
+ return false;
+
+ // Try replacing colons with underscores (in case the original was
+ // a Mac version and had slashes not as a separator).
+ if (archive->openFile(replaceColons(fileName, '_')))
+ return true;
+
+ // Try replacing colons with slashes (in case the original was a Mac
+ // version and had slashes as a separator).
+ if (archive->openFile(replaceColons(fileName, '/')))
+ return true;
+
+ // Failed to open the archive
+ return false;
+}
+
bool MohawkEngine_LivingBooks::loadPage(LBMode mode, uint page, uint subpage) {
destroyPage();
@@ -410,7 +448,7 @@ bool MohawkEngine_LivingBooks::loadPage(LBMode mode, uint page, uint subpage) {
}
Archive *pageArchive = createArchive();
- if (!filename.empty() && pageArchive->openFile(filename)) {
+ if (!filename.empty() && tryOpenPage(pageArchive, filename)) {
_page = new LBPage(this);
_page->open(pageArchive, 1000);
} else {
@@ -824,18 +862,18 @@ int MohawkEngine_LivingBooks::getIntFromConfig(const Common::String &section, co
Common::String MohawkEngine_LivingBooks::getFileNameFromConfig(const Common::String &section, const Common::String &key, Common::String &leftover) {
Common::String string = getStringFromConfig(section, key, leftover);
- Common::String x;
- uint32 i = 0;
if (string.hasPrefix("//")) {
// skip "//CD-ROM Title/" prefixes which we don't care about
- i = 3;
+ uint i = 3;
while (i < string.size() && string[i - 1] != '/')
i++;
+
+ // Already uses slashes, no need to convert further
+ return string.c_str() + i;
}
- x = string.c_str() + i;
- return (getPlatform() == Common::kPlatformMacintosh) ? convertMacFileName(x) : convertWinFileName(x);
+ return (getPlatform() == Common::kPlatformMacintosh) ? convertMacFileName(string) : convertWinFileName(string);
}
Common::String MohawkEngine_LivingBooks::removeQuotesFromString(const Common::String &string, Common::String &leftover) {
@@ -866,8 +904,10 @@ Common::String MohawkEngine_LivingBooks::convertMacFileName(const Common::String
for (uint32 i = 0; i < string.size(); i++) {
if (i == 0 && string[i] == ':') // First character should be ignored (another colon)
continue;
- if (string[i] == ':')
+ if (string[i] == ':') // Directory separator
filename += '/';
+ else if (string[i] == '/') // Literal slash
+ filename += ':'; // Replace by colon, as used by Mac OS X for slash
else
filename += string[i];
}
@@ -3772,7 +3812,7 @@ LBMovieItem::~LBMovieItem() {
void LBMovieItem::update() {
if (_playing) {
VideoHandle videoHandle = _vm->_video->findVideoHandle(_resourceId);
- if (videoHandle == NULL_VID_HANDLE || _vm->_video->endOfVideo(videoHandle))
+ if (!videoHandle || videoHandle->endOfVideo())
done(true);
}
@@ -3783,8 +3823,11 @@ bool LBMovieItem::togglePlaying(bool playing, bool restart) {
if (playing) {
if ((_loaded && _enabled && _globalEnabled) || _phase == kLBPhaseNone) {
debug("toggled video for phase %d", _phase);
- _vm->_video->playMovie(_resourceId, _rect.left, _rect.top);
+ VideoHandle handle = _vm->_video->playMovie(_resourceId);
+ if (!handle)
+ error("Failed to open tMOV %d", _resourceId);
+ handle->moveTo(_rect.left, _rect.top);
return true;
}
}
@@ -3808,9 +3851,9 @@ bool LBMiniGameItem::togglePlaying(bool playing, bool restart) {
// just skip to the most logical page. For optional minigames, this
// will return the player to the previous page. For mandatory minigames,
// this will send the player to the next page.
- // TODO: Document mini games from Arthur's Reading Race
- uint16 destPage;
+ uint16 destPage = 0;
+ bool returnToMenu = false;
// Figure out what minigame we have and bring us back to a page where
// the player can continue
@@ -3820,13 +3863,31 @@ bool LBMiniGameItem::togglePlaying(bool playing, bool restart) {
destPage = 5;
else if (_desc == "Fall") // Green Eggs and Ham: Fall minigame
destPage = 13;
+ else if (_desc == "MagicWrite3") // Arthur's Reading Race: "Let Me Write" minigame (Page 3)
+ destPage = 3;
+ else if (_desc == "MagicWrite4") // Arthur's Reading Race: "Let Me Write" minigame (Page 4)
+ destPage = 4;
+ else if (_desc == "MagicSpy5") // Arthur's Reading Race: "I Spy" minigame (Page 5)
+ destPage = 5;
+ else if (_desc == "MagicSpy6") // Arthur's Reading Race: "I Spy" minigame (Page 6)
+ destPage = 6;
+ else if (_desc == "MagicWrite7") // Arthur's Reading Race: "Let Me Write" minigame (Page 7)
+ destPage = 7;
+ else if (_desc == "MagicSpy8") // Arthur's Reading Race: "I Spy" minigame (Page 8)
+ destPage = 8;
+ else if (_desc == "MagicRace") // Arthur's Reading Race: Race minigame
+ returnToMenu = true;
else
error("Unknown minigame '%s'", _desc.c_str());
GUI::MessageDialog dialog(Common::String::format("The '%s' minigame is not supported yet.", _desc.c_str()));
dialog.runModal();
- _vm->addNotifyEvent(NotifyEvent(kLBNotifyChangePage, destPage));
+ // Go back to the menu if requested, otherwise go to the requested page
+ if (returnToMenu)
+ _vm->addNotifyEvent(NotifyEvent(kLBNotifyGoToControls, 1));
+ else
+ _vm->addNotifyEvent(NotifyEvent(kLBNotifyChangePage, destPage));
return false;
}
@@ -3863,7 +3924,7 @@ void LBProxyItem::load() {
debug(1, "LBProxyItem loading archive '%s' with id %d", filename.c_str(), baseId);
Archive *pageArchive = _vm->createArchive();
- if (!pageArchive->openFile(filename))
+ if (!tryOpenPage(pageArchive, filename))
error("failed to open archive '%s' (for proxy '%s')", filename.c_str(), _desc.c_str());
_page = new LBPage(_vm);
_page->open(pageArchive, baseId);
diff --git a/engines/mohawk/livingbooks_code.cpp b/engines/mohawk/livingbooks_code.cpp
index 6dcd8c3ce7..b5ea547414 100644
--- a/engines/mohawk/livingbooks_code.cpp
+++ b/engines/mohawk/livingbooks_code.cpp
@@ -842,8 +842,8 @@ CodeCommandInfo generalCommandInfo[NUM_GENERAL_COMMANDS] = {
{ "bottom", &LBCode::cmdBottom },
// 0x10
{ "right", &LBCode::cmdRight },
- { "xpos", 0 },
- { "ypos", 0 },
+ { "xpos", &LBCode::cmdXPos },
+ { "ypos", &LBCode::cmdYPos },
{ "playFrom", 0 },
{ "move", &LBCode::cmdMove },
{ 0, 0 },
@@ -852,13 +852,13 @@ CodeCommandInfo generalCommandInfo[NUM_GENERAL_COMMANDS] = {
{ "resetDragParams", 0 },
{ "enableRollover", &LBCode::cmdUnimplemented /* FIXME */ },
{ "setCursor", 0 },
- { "width", 0 },
- { "height", 0 },
+ { "width", &LBCode::cmdWidth },
+ { "height", &LBCode::cmdHeight },
{ "getFrameBounds", 0 }, // also "getFrameRect"
{ "traceRect", 0 },
{ "sqrt", 0 },
// 0x20
- { "deleteVar", 0 },
+ { "deleteVar", &LBCode::cmdDeleteVar },
{ "saveVars", 0 },
{ "scriptLink", 0 },
{ "setViewOrigin", &LBCode::cmdUnimplemented },
@@ -1131,6 +1131,38 @@ void LBCode::cmdRight(const Common::Array<LBValue> &params) {
_stack.push(rect.right);
}
+void LBCode::cmdXPos(const Common::Array<LBValue> &params) {
+ if (params.size() != 1)
+ error("too many parameters (%d) to xpos", params.size());
+
+ Common::Point point = params[0].toPoint();
+ _stack.push(point.x);
+}
+
+void LBCode::cmdYPos(const Common::Array<LBValue> &params) {
+ if (params.size() != 1)
+ error("too many parameters (%d) to ypos", params.size());
+
+ Common::Point point = params[0].toPoint();
+ _stack.push(point.y);
+}
+
+void LBCode::cmdWidth(const Common::Array<LBValue> &params) {
+ if (params.size() > 1)
+ error("too many parameters (%d) to width", params.size());
+
+ Common::Rect rect = getRectFromParams(params);
+ _stack.push(rect.width());
+}
+
+void LBCode::cmdHeight(const Common::Array<LBValue> &params) {
+ if (params.size() > 1)
+ error("too many parameters (%d) to height", params.size());
+
+ Common::Rect rect = getRectFromParams(params);
+ _stack.push(rect.height());
+}
+
void LBCode::cmdMove(const Common::Array<LBValue> &params) {
if (params.size() != 1 && params.size() != 2)
error("incorrect number of parameters (%d) to move", params.size());
@@ -1263,6 +1295,14 @@ void LBCode::cmdGetProperty(const Common::Array<LBValue> &params) {
_stack.push(target->_variables[name]);
}
+void LBCode::cmdDeleteVar(const Common::Array<LBValue> &params) {
+ if (params.size() != 1)
+ error("incorrect number of parameters (%d) to deleteVar", params.size());
+
+ const Common::String &string = params[0].toString();
+ _vm->_variables.erase(string);
+}
+
void LBCode::cmdExec(const Common::Array<LBValue> &params) {
if (params.size() != 1)
error("incorrect number of parameters (%d) to exec", params.size());
@@ -1706,6 +1746,10 @@ uint LBCode::parseCode(const Common::String &source) {
if (token != ' ' && token != '(' && wasFunction)
error("while parsing script '%s', encountered incomplete function call", source.c_str());
+ // Skip C++-style comments
+ if (token == '/' && lookahead == '/')
+ break;
+
// First, we check for simple operators.
for (uint i = 0; i < NUM_LB_OPERATORS; i++) {
if (token != operators[i].token)
@@ -1736,6 +1780,7 @@ uint LBCode::parseCode(const Common::String &source) {
switch (token) {
// whitespace
case ' ':
+ case '\t':
// ignore
break;
// literal string
diff --git a/engines/mohawk/livingbooks_code.h b/engines/mohawk/livingbooks_code.h
index 080377ce99..6f6297d592 100644
--- a/engines/mohawk/livingbooks_code.h
+++ b/engines/mohawk/livingbooks_code.h
@@ -263,6 +263,10 @@ public:
void cmdLeft(const Common::Array<LBValue> &params);
void cmdBottom(const Common::Array<LBValue> &params);
void cmdRight(const Common::Array<LBValue> &params);
+ void cmdXPos(const Common::Array<LBValue> &params);
+ void cmdYPos(const Common::Array<LBValue> &params);
+ void cmdWidth(const Common::Array<LBValue> &params);
+ void cmdHeight(const Common::Array<LBValue> &params);
void cmdMove(const Common::Array<LBValue> &params);
void cmdSetDragParams(const Common::Array<LBValue> &params);
void cmdNewList(const Common::Array<LBValue> &params);
@@ -273,6 +277,7 @@ public:
void cmdDeleteAt(const Common::Array<LBValue> &params);
void cmdSetProperty(const Common::Array<LBValue> &params);
void cmdGetProperty(const Common::Array<LBValue> &params);
+ void cmdDeleteVar(const Common::Array<LBValue> &params);
void cmdExec(const Common::Array<LBValue> &params);
void cmdReturn(const Common::Array<LBValue> &params);
void cmdSetPlayParams(const Common::Array<LBValue> &params);
diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp
index 7634e8d88a..b6a6c27329 100644
--- a/engines/mohawk/myst.cpp
+++ b/engines/mohawk/myst.cpp
@@ -413,7 +413,12 @@ void MohawkEngine_Myst::changeToStack(uint16 stack, uint16 card, uint16 linkSrcS
// Fill screen with black and empty cursor
_cursor->setCursor(0);
- _system->fillScreen(_system->getScreenFormat().RGBToColor(0, 0, 0));
+
+ if (getFeatures() & GF_ME)
+ _system->fillScreen(_system->getScreenFormat().RGBToColor(0, 0, 0));
+ else
+ _gfx->clearScreenPalette();
+
_system->updateScreen();
_sound->stopSound();
@@ -495,9 +500,10 @@ void MohawkEngine_Myst::changeToStack(uint16 stack, uint16 card, uint16 linkSrcS
_cache.clear();
_gfx->clearCache();
- // Play Flyby Entry Movie on Masterpiece Edition.
- const char *flyby = 0;
if (getFeatures() & GF_ME) {
+ // Play Flyby Entry Movie on Masterpiece Edition.
+ const char *flyby = 0;
+
switch (_curStack) {
case kSeleniticStack:
flyby = "selenitic flyby";
diff --git a/engines/mohawk/myst_areas.cpp b/engines/mohawk/myst_areas.cpp
index 4a3001774a..7a9596d8e0 100644
--- a/engines/mohawk/myst_areas.cpp
+++ b/engines/mohawk/myst_areas.cpp
@@ -223,20 +223,26 @@ VideoHandle MystResourceType6::playMovie() {
VideoHandle handle = _vm->_video->findVideoHandle(_videoFile);
// If the video is not running, play it
- if (handle == NULL_VID_HANDLE || _vm->_video->endOfVideo(handle)) {
- handle = _vm->_video->playMovie(_videoFile, _left, _top, _loop);
+ if (!handle || handle->endOfVideo()) {
+ handle = _vm->_video->playMovie(_videoFile);
+ if (!handle)
+ error("Failed to open '%s'", _videoFile.c_str());
+
+ handle->moveTo(_left, _top);
+ handle->setLooping(_loop != 0);
+
if (_direction == -1) {
- _vm->_video->seekToTime(handle, _vm->_video->getDuration(handle));
- _vm->_video->setVideoRate(handle, -1);
+ handle->seek(handle->getDuration());
+ handle->setRate(-1);
}
} else {
// Resume the video
- _vm->_video->pauseMovie(handle, false);
+ handle->pause(false);
}
if (_playBlocking) {
_vm->_video->waitUntilMovieEnds(handle);
- handle = NULL_VID_HANDLE;
+ return VideoHandle();
}
return handle;
@@ -249,13 +255,13 @@ void MystResourceType6::handleCardChange() {
bool MystResourceType6::isPlaying() {
VideoHandle handle = _vm->_video->findVideoHandle(_videoFile);
- return handle != NULL_VID_HANDLE && !_vm->_video->endOfVideo(handle);
+ return handle && !handle->endOfVideo();
}
void MystResourceType6::pauseMovie(bool pause) {
VideoHandle handle = _vm->_video->findVideoHandle(_videoFile);
- if (handle != NULL_VID_HANDLE && !_vm->_video->endOfVideo(handle))
- _vm->_video->pauseMovie(handle, pause);
+ if (handle && !handle->endOfVideo())
+ handle->pause(pause);
}
MystResourceType7::MystResourceType7(MohawkEngine_Myst *vm, Common::SeekableReadStream *rlstStream, MystResource *parent) : MystResource(vm, rlstStream, parent) {
diff --git a/engines/mohawk/myst_graphics.cpp b/engines/mohawk/myst_graphics.cpp
index 9ea9f15444..49f97cca63 100644
--- a/engines/mohawk/myst_graphics.cpp
+++ b/engines/mohawk/myst_graphics.cpp
@@ -28,6 +28,7 @@
#include "common/system.h"
#include "common/textconsole.h"
#include "engines/util.h"
+#include "graphics/palette.h"
#include "image/pict.h"
namespace Mohawk {
@@ -37,16 +38,20 @@ MystGraphics::MystGraphics(MohawkEngine_Myst* vm) : GraphicsManager(), _vm(vm) {
_viewport = Common::Rect(544, 332);
- // The original version of Myst could run in 8bpp color too.
- // However, it dithered videos to 8bpp and they looked considerably
- // worse (than they already did :P). So we're not even going to
- // support 8bpp mode in Myst (Myst ME required >8bpp anyway).
- initGraphics(_viewport.width(), _viewport.height(), true, NULL); // What an odd screen size!
+ if (_vm->getFeatures() & GF_ME) {
+ // High color
+ initGraphics(_viewport.width(), _viewport.height(), true, NULL);
- _pixelFormat = _vm->_system->getScreenFormat();
+ if (_vm->_system->getScreenFormat().bytesPerPixel == 1)
+ error("Myst ME requires greater than 256 colors to run");
+ } else {
+ // Paletted
+ initGraphics(_viewport.width(), _viewport.height(), true);
+ setBasePalette();
+ setPaletteToScreen();
+ }
- if (_pixelFormat.bytesPerPixel == 1)
- error("Myst requires greater than 256 colors to run");
+ _pixelFormat = _vm->_system->getScreenFormat();
// Initialize our buffer
_backBuffer = new Graphics::Surface();
@@ -101,7 +106,9 @@ MohawkSurface *MystGraphics::decodeImage(uint16 id) {
mhkSurface = new MohawkSurface(pict.getSurface()->convertTo(_pixelFormat));
} else {
mhkSurface = _bmpDecoder->decodeImage(dataStream);
- mhkSurface->convertToTrueColor();
+
+ if (_vm->getFeatures() & GF_ME)
+ mhkSurface->convertToTrueColor();
}
assert(mhkSurface);
@@ -151,7 +158,8 @@ void MystGraphics::copyImageSectionToScreen(uint16 image, Common::Rect src, Comm
}
void MystGraphics::copyImageSectionToBackBuffer(uint16 image, Common::Rect src, Common::Rect dest) {
- Graphics::Surface *surface = findImage(image)->getSurface();
+ MohawkSurface *mhkSurface = findImage(image);
+ Graphics::Surface *surface = mhkSurface->getSurface();
// Make sure the image is bottom aligned in the dest rect
dest.top = dest.bottom - MIN<int>(surface->h, dest.height());
@@ -190,6 +198,13 @@ void MystGraphics::copyImageSectionToBackBuffer(uint16 image, Common::Rect src,
for (uint16 i = 0; i < height; i++)
memcpy(_backBuffer->getBasePtr(dest.left, i + dest.top), surface->getBasePtr(src.left, top + i), width * surface->format.bytesPerPixel);
+
+ if (!(_vm->getFeatures() & GF_ME)) {
+ // Make sure the palette is set
+ assert(mhkSurface->getPalette());
+ memcpy(_palette + 10 * 3, mhkSurface->getPalette() + 10 * 3, (256 - 10 * 2) * 3);
+ setPaletteToScreen();
+ }
}
void MystGraphics::copyImageToScreen(uint16 image, Common::Rect dest) {
@@ -419,12 +434,16 @@ void MystGraphics::transitionDissolve(Common::Rect rect, uint step) {
for (uint16 x = rect.left; x < rect.right; x++) {
if (linePattern[x % 4]) {
- if (_pixelFormat.bytesPerPixel == 2) {
- uint16 *dst = (uint16 *)screen->getBasePtr(x, y);
- *dst = *(const uint16 *)_backBuffer->getBasePtr(x, y);
- } else {
- uint32 *dst = (uint32 *)screen->getBasePtr(x, y);
- *dst = *(const uint32 *)_backBuffer->getBasePtr(x, y);
+ switch (_pixelFormat.bytesPerPixel) {
+ case 1:
+ *((byte *)screen->getBasePtr(x, y)) = *((const byte *)_backBuffer->getBasePtr(x, y));
+ break;
+ case 2:
+ *((uint16 *)screen->getBasePtr(x, y)) = *((const uint16 *)_backBuffer->getBasePtr(x, y));
+ break;
+ case 4:
+ *((uint32 *)screen->getBasePtr(x, y)) = *((const uint32 *)_backBuffer->getBasePtr(x, y));
+ break;
}
}
}
@@ -588,11 +607,11 @@ void MystGraphics::drawRect(Common::Rect rect, RectState state) {
Graphics::Surface *screen = _vm->_system->lockScreen();
if (state == kRectEnabled)
- screen->frameRect(rect, _pixelFormat.RGBToColor(0, 255, 0));
+ screen->frameRect(rect, (_vm->getFeatures() & GF_ME) ? _pixelFormat.RGBToColor(0, 255, 0) : 250);
else if (state == kRectUnreachable)
- screen->frameRect(rect, _pixelFormat.RGBToColor(0, 0, 255));
+ screen->frameRect(rect, (_vm->getFeatures() & GF_ME) ? _pixelFormat.RGBToColor(0, 0, 255) : 252);
else
- screen->frameRect(rect, _pixelFormat.RGBToColor(255, 0, 0));
+ screen->frameRect(rect, (_vm->getFeatures() & GF_ME) ? _pixelFormat.RGBToColor(255, 0, 0) : 249);
_vm->_system->unlockScreen();
}
@@ -629,50 +648,94 @@ void MystGraphics::simulatePreviousDrawDelay(const Common::Rect &dest) {
_nextAllowedDrawTime = time + _constantDrawDelay + dest.height() * dest.width() / _proportionalDrawDelay;
}
-void MystGraphics::copyBackBufferToScreenWithSaturation(int16 saturation) {
- Graphics::Surface *screen = _vm->_system->lockScreen();
+void MystGraphics::fadeToBlack() {
+ // This is only for the demo
+ assert(!(_vm->getFeatures() & GF_ME));
- for (uint16 y = 0; y < _viewport.height(); y++)
- for (uint16 x = 0; x < _viewport.width(); x++) {
- uint32 color;
- uint8 r, g, b;
+ // Linear fade in 64 steps
+ for (int i = 63; i >= 0; i--) {
+ byte palette[256 * 3];
+ byte *src = _palette;
+ byte *dst = palette;
- if (_pixelFormat.bytesPerPixel == 2)
- color = *(const uint16 *)_backBuffer->getBasePtr(x, y);
- else
- color = *(const uint32 *)_backBuffer->getBasePtr(x, y);
+ for (uint j = 0; j < sizeof(palette); j++)
+ *dst++ = *src++ * i / 64;
- _pixelFormat.colorToRGB(color, r, g, b);
+ _vm->_system->getPaletteManager()->setPalette(palette, 0, 256);
+ _vm->_system->updateScreen();
+ }
+}
- r = CLIP<int16>((int16)r - saturation, 0, 255);
- g = CLIP<int16>((int16)g - saturation, 0, 255);
- b = CLIP<int16>((int16)b - saturation, 0, 255);
+void MystGraphics::fadeFromBlack() {
+ // This is only for the demo
+ assert(!(_vm->getFeatures() & GF_ME));
- color = _pixelFormat.RGBToColor(r, g, b);
+ copyBackBufferToScreen(_viewport);
- if (_pixelFormat.bytesPerPixel == 2) {
- uint16 *dst = (uint16 *)screen->getBasePtr(x, y);
- *dst = color;
- } else {
- uint32 *dst = (uint32 *)screen->getBasePtr(x, y);
- *dst = color;
- }
- }
+ // Linear fade in 64 steps
+ for (int i = 0; i < 64; i++) {
+ byte palette[256 * 3];
+ byte *src = _palette;
+ byte *dst = palette;
- _vm->_system->unlockScreen();
+ for (uint j = 0; j < sizeof(palette); j++)
+ *dst++ = *src++ * i / 64;
+
+ _vm->_system->getPaletteManager()->setPalette(palette, 0, 256);
+ _vm->_system->updateScreen();
+ }
+
+ // Set the full palette
+ _vm->_system->getPaletteManager()->setPalette(_palette, 0, 256);
_vm->_system->updateScreen();
}
-void MystGraphics::fadeToBlack() {
- for (int16 i = 0; i < 256; i += 32) {
- copyBackBufferToScreenWithSaturation(i);
- }
+void MystGraphics::clearScreenPalette() {
+ // Set the palette to all black
+ byte palette[256 * 3];
+ memset(palette, 0, sizeof(palette));
+ _vm->_system->getPaletteManager()->setPalette(palette, 0, 256);
}
-void MystGraphics::fadeFromBlack() {
- for (int16 i = 256; i >= 0; i -= 32) {
- copyBackBufferToScreenWithSaturation(i);
- }
+void MystGraphics::setBasePalette() {
+ // Entries [0, 9] of the palette
+ static const byte lowPalette[] = {
+ 0xFF, 0xFF, 0xFF,
+ 0x80, 0x00, 0x00,
+ 0x00, 0x80, 0x00,
+ 0x80, 0x80, 0x00,
+ 0x00, 0x00, 0x80,
+ 0x80, 0x00, 0x80,
+ 0x00, 0x80, 0x80,
+ 0xC0, 0xC0, 0xC0,
+ 0xC0, 0xDC, 0xC0,
+ 0xA6, 0xCA, 0xF0
+ };
+
+ // Entries [246, 255] of the palette
+ static const byte highPalette[] = {
+ 0xFF, 0xFB, 0xF0,
+ 0xA0, 0xA0, 0xA4,
+ 0x80, 0x80, 0x80,
+ 0xFF, 0x00, 0x00,
+ 0x00, 0xFF, 0x00,
+ 0xFF, 0xFF, 0x00,
+ 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0xFF,
+ 0x00, 0xFF, 0xFF,
+ 0x00, 0x00, 0x00
+ };
+
+ // Note that 0 and 255 are different from normal Windows.
+ // Myst seems to hack that to white, resp. black (probably for Mac compat).
+
+ memcpy(_palette, lowPalette, sizeof(lowPalette));
+ memset(_palette + sizeof(lowPalette), 0, sizeof(_palette) - sizeof(lowPalette) - sizeof(highPalette));
+ memcpy(_palette + sizeof(_palette) - sizeof(highPalette), highPalette, sizeof(highPalette));
+}
+
+void MystGraphics::setPaletteToScreen() {
+ _vm->_system->getPaletteManager()->setPalette(_palette, 0, 256);
}
} // End of namespace Mohawk
diff --git a/engines/mohawk/myst_graphics.h b/engines/mohawk/myst_graphics.h
index 1f70320bf6..6281c94cc8 100644
--- a/engines/mohawk/myst_graphics.h
+++ b/engines/mohawk/myst_graphics.h
@@ -40,7 +40,7 @@ enum RectState {
class MystGraphics : public GraphicsManager {
public:
- MystGraphics(MohawkEngine_Myst*);
+ MystGraphics(MohawkEngine_Myst *vm);
~MystGraphics();
void copyImageSectionToScreen(uint16 image, Common::Rect src, Common::Rect dest);
@@ -55,18 +55,15 @@ public:
void fadeToBlack();
void fadeFromBlack();
+ void clearScreenPalette();
+ void setBasePalette();
+ void setPaletteToScreen();
+ const byte *getPalette() const { return _palette; }
+
protected:
MohawkSurface *decodeImage(uint16 id);
MohawkEngine *getVM() { return (MohawkEngine *)_vm; }
- void simulatePreviousDrawDelay(const Common::Rect &dest);
- void copyBackBufferToScreenWithSaturation(int16 saturation);
- void transitionDissolve(Common::Rect rect, uint step);
- void transitionSlideToLeft(Common::Rect rect, uint16 steps, uint16 delay);
- void transitionSlideToRight(Common::Rect rect, uint16 steps, uint16 delay);
- void transitionSlideToTop(Common::Rect rect, uint16 steps, uint16 delay);
- void transitionSlideToBottom(Common::Rect rect, uint16 steps, uint16 delay);
- void transitionPartialToRight(Common::Rect rect, uint32 width, uint32 steps);
- void transitionPartialToLeft(Common::Rect rect, uint32 width, uint32 steps);
+
private:
MohawkEngine_Myst *_vm;
MystBitmap *_bmpDecoder;
@@ -74,11 +71,21 @@ private:
Graphics::Surface *_backBuffer;
Graphics::PixelFormat _pixelFormat;
Common::Rect _viewport;
+ byte _palette[256 * 3];
int _enableDrawingTimeSimulation;
uint32 _nextAllowedDrawTime;
static const uint _constantDrawDelay = 10; // ms
static const uint _proportionalDrawDelay = 500; // pixels per ms
+
+ void simulatePreviousDrawDelay(const Common::Rect &dest);
+ void transitionDissolve(Common::Rect rect, uint step);
+ void transitionSlideToLeft(Common::Rect rect, uint16 steps, uint16 delay);
+ void transitionSlideToRight(Common::Rect rect, uint16 steps, uint16 delay);
+ void transitionSlideToTop(Common::Rect rect, uint16 steps, uint16 delay);
+ void transitionSlideToBottom(Common::Rect rect, uint16 steps, uint16 delay);
+ void transitionPartialToRight(Common::Rect rect, uint32 width, uint32 steps);
+ void transitionPartialToLeft(Common::Rect rect, uint32 width, uint32 steps);
};
} // End of namespace Mohawk
diff --git a/engines/mohawk/myst_stacks/channelwood.cpp b/engines/mohawk/myst_stacks/channelwood.cpp
index 2dd5745550..dfa15a9b6c 100644
--- a/engines/mohawk/myst_stacks/channelwood.cpp
+++ b/engines/mohawk/myst_stacks/channelwood.cpp
@@ -299,13 +299,17 @@ bool Channelwood::pipeChangeValve(bool open, uint16 mask) {
void Channelwood::o_bridgeToggle(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
debugC(kDebugScript, "Opcode %d: Bridge rise / skink video", op);
- VideoHandle bridge = _vm->_video->playMovie(_vm->wrapMovieFilename("bridge", kChannelwoodStack), 292, 203);
+ VideoHandle bridge = _vm->_video->playMovie(_vm->wrapMovieFilename("bridge", kChannelwoodStack));
+ if (!bridge)
+ error("Failed to open 'bridge' movie");
+
+ bridge->moveTo(292, 203);
// Toggle bridge state
if (_state.waterPumpBridgeState)
- _vm->_video->setVideoBounds(bridge, Audio::Timestamp(0, 3050, 600), Audio::Timestamp(0, 6100, 600));
+ bridge->setBounds(Audio::Timestamp(0, 3050, 600), Audio::Timestamp(0, 6100, 600));
else
- _vm->_video->setVideoBounds(bridge, Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 3050, 600));
+ bridge->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 3050, 600));
_vm->_video->waitUntilMovieEnds(bridge);
}
@@ -317,13 +321,17 @@ void Channelwood::o_pipeExtend(uint16 op, uint16 var, uint16 argc, uint16 *argv)
debugC(kDebugScript, "\tsoundId: %d", soundId);
_vm->_sound->replaceSoundMyst(soundId);
- VideoHandle pipe = _vm->_video->playMovie(_vm->wrapMovieFilename("pipebrid", kChannelwoodStack), 267, 170);
+ VideoHandle pipe = _vm->_video->playMovie(_vm->wrapMovieFilename("pipebrid", kChannelwoodStack));
+ if (!pipe)
+ error("Failed to open 'pipebrid' movie");
+
+ pipe->moveTo(267, 170);
// Toggle pipe state
if (_state.pipeState)
- _vm->_video->setVideoBounds(pipe, Audio::Timestamp(0, 3040, 600), Audio::Timestamp(0, 6080, 600));
+ pipe->setBounds(Audio::Timestamp(0, 3040, 600), Audio::Timestamp(0, 6080, 600));
else
- _vm->_video->setVideoBounds(pipe, Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 3040, 600));
+ pipe->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 3040, 600));
_vm->_video->waitUntilMovieEnds(pipe);
_vm->_sound->resumeBackgroundMyst();
@@ -605,23 +613,29 @@ void Channelwood::o_hologramMonitor(uint16 op, uint16 var, uint16 argc, uint16 *
_vm->_video->stopVideos();
+ VideoHandle handle;
+
switch (button) {
case 0:
- _vm->_video->playMovie(_vm->wrapMovieFilename("monalgh", kChannelwoodStack), 227, 70);
+ handle = _vm->_video->playMovie(_vm->wrapMovieFilename("monalgh", kChannelwoodStack));
break;
case 1:
- _vm->_video->playMovie(_vm->wrapMovieFilename("monamth", kChannelwoodStack), 227, 70);
+ handle = _vm->_video->playMovie(_vm->wrapMovieFilename("monamth", kChannelwoodStack));
break;
case 2:
- _vm->_video->playMovie(_vm->wrapMovieFilename("monasirs", kChannelwoodStack), 227, 70);
+ handle = _vm->_video->playMovie(_vm->wrapMovieFilename("monasirs", kChannelwoodStack));
break;
case 3:
- _vm->_video->playMovie(_vm->wrapMovieFilename("monsmsg", kChannelwoodStack), 227, 70);
+ handle = _vm->_video->playMovie(_vm->wrapMovieFilename("monsmsg", kChannelwoodStack));
break;
default:
warning("Opcode %d Control Variable Out of Range", op);
break;
}
+
+ // Move the video to the right location
+ if (handle)
+ handle->moveTo(227, 70);
}
}
diff --git a/engines/mohawk/myst_stacks/dni.cpp b/engines/mohawk/myst_stacks/dni.cpp
index 3eb3c40cbb..6ba0b63423 100644
--- a/engines/mohawk/myst_stacks/dni.cpp
+++ b/engines/mohawk/myst_stacks/dni.cpp
@@ -103,14 +103,14 @@ void Dni::o_handPage(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
VideoHandle atrus = _vm->_video->findVideoHandle(_video);
// Good ending and Atrus asked to give page
- if (_globals.ending == 1 && _vm->_video->getTime(atrus) > (uint)Audio::Timestamp(0, 6801, 600).msecs()) {
+ if (_globals.ending == 1 && atrus && atrus->getTime() > (uint)Audio::Timestamp(0, 6801, 600).msecs()) {
_globals.ending = 2;
_globals.heldPage = 0;
_vm->setMainCursor(kDefaultMystCursor);
// Play movie end (atrus leaving)
- _vm->_video->setVideoBounds(atrus, Audio::Timestamp(0, 14813, 600), _vm->_video->getDuration(atrus));
- _vm->_video->setVideoLooping(atrus, false);
+ atrus->setBounds(Audio::Timestamp(0, 14813, 600), atrus->getDuration());
+ atrus->setLooping(false);
_atrusLeft = true;
_waitForLoop = false;
@@ -121,8 +121,12 @@ void Dni::o_handPage(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
void Dni::atrusLeft_run() {
if (_vm->_system->getMillis() > _atrusLeftTime + 63333) {
_video = _vm->wrapMovieFilename("atrus2", kDniStack);
- VideoHandle atrus = _vm->_video->playMovie(_video, 215, 77);
- _vm->_video->setVideoBounds(atrus, Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 98000, 600));
+ VideoHandle atrus = _vm->_video->playMovie(_video);
+ if (!atrus)
+ error("Failed to open '%s'", _video.c_str());
+
+ atrus->moveTo(215, 77);
+ atrus->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 98000, 600));
_waitForLoop = true;
_loopStart = 73095;
@@ -139,9 +143,13 @@ void Dni::atrusLeft_run() {
void Dni::loopVideo_run() {
if (!_vm->_video->isVideoPlaying()) {
- VideoHandle atrus = _vm->_video->playMovie(_video, 215, 77);
- _vm->_video->setVideoBounds(atrus, Audio::Timestamp(0, _loopStart, 600), Audio::Timestamp(0, _loopEnd, 600));
- _vm->_video->setVideoLooping(atrus, true);
+ VideoHandle atrus = _vm->_video->playMovie(_video);
+ if (!atrus)
+ error("Failed to open '%s'", _video.c_str());
+
+ atrus->moveTo(215, 77);
+ atrus->setBounds(Audio::Timestamp(0, _loopStart, 600), Audio::Timestamp(0, _loopEnd, 600));
+ atrus->setLooping(true);
_waitForLoop = false;
}
@@ -155,14 +163,23 @@ void Dni::atrus_run() {
// Atrus asking for page
if (!_vm->_video->isVideoPlaying()) {
_video = _vm->wrapMovieFilename("atr1page", kDniStack);
- VideoHandle atrus = _vm->_video->playMovie(_video, 215, 77, true);
- _vm->_video->setVideoBounds(atrus, Audio::Timestamp(0, 7388, 600), Audio::Timestamp(0, 14700, 600));
+ VideoHandle atrus = _vm->_video->playMovie(_video);
+ if (!atrus)
+ error("Failed to open '%s'", _video.c_str());
+
+ atrus->moveTo(215, 77);
+ atrus->setLooping(true);
+ atrus->setBounds(Audio::Timestamp(0, 7388, 600), Audio::Timestamp(0, 14700, 600));
}
} else if (_globals.ending != 3 && _globals.ending != 4) {
if (_globals.heldPage == 13) {
_video = _vm->wrapMovieFilename("atr1page", kDniStack);
- VideoHandle atrus = _vm->_video->playMovie(_video, 215, 77);
- _vm->_video->setVideoBounds(atrus, Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 14700, 600));
+ VideoHandle atrus = _vm->_video->playMovie(_video);
+ if (!atrus)
+ error("Failed to open '%s'", _video.c_str());
+
+ atrus->moveTo(215, 77);
+ atrus->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 14700, 600));
_waitForLoop = true;
_loopStart = 7388;
@@ -173,8 +190,12 @@ void Dni::atrus_run() {
} else {
_video = _vm->wrapMovieFilename("atr1nopg", kDniStack);
- VideoHandle atrus = _vm->_video->playMovie(_video, 215, 77);
- _vm->_video->setVideoBounds(atrus, Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 46175, 600));
+ VideoHandle atrus = _vm->_video->playMovie(_video);
+ if (!atrus)
+ error("Failed to open '%s'", _video.c_str());
+
+ atrus->moveTo(215, 77);
+ atrus->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 46175, 600));
_waitForLoop = true;
_loopStart = 30656;
@@ -184,7 +205,12 @@ void Dni::atrus_run() {
_globals.ending = 3;
}
} else if (!_vm->_video->isVideoPlaying()) {
- _vm->_video->playMovie(_vm->wrapMovieFilename("atrwrite", kDniStack), 215, 77, true);
+ VideoHandle handle = _vm->_video->playMovie(_vm->wrapMovieFilename("atrwrite", kDniStack));
+ if (!handle)
+ error("Failed to open atrwrite movie");
+
+ handle->moveTo(215, 77);
+ handle->setLooping(true);
}
}
diff --git a/engines/mohawk/myst_stacks/intro.cpp b/engines/mohawk/myst_stacks/intro.cpp
index 2a33379198..dc66984398 100644
--- a/engines/mohawk/myst_stacks/intro.cpp
+++ b/engines/mohawk/myst_stacks/intro.cpp
@@ -98,10 +98,16 @@ void Intro::introMovies_run() {
// Play Intro Movies
// This is all quite messy...
+ VideoHandle handle;
+
switch (_introStep) {
case 0:
_introStep = 1;
- _vm->_video->playMovie(_vm->wrapMovieFilename("broder", kIntroStack));
+ handle = _vm->_video->playMovie(_vm->wrapMovieFilename("broder", kIntroStack));
+ if (!handle)
+ error("Failed to open broder movie");
+
+ handle->center();
break;
case 1:
if (!_vm->_video->isVideoPlaying())
@@ -109,7 +115,11 @@ void Intro::introMovies_run() {
break;
case 2:
_introStep = 3;
- _vm->_video->playMovie(_vm->wrapMovieFilename("cyanlogo", kIntroStack));
+ handle = _vm->_video->playMovie(_vm->wrapMovieFilename("cyanlogo", kIntroStack));
+ if (!handle)
+ error("Failed to open cyanlogo movie");
+
+ handle->center();
break;
case 3:
if (!_vm->_video->isVideoPlaying())
@@ -118,8 +128,13 @@ void Intro::introMovies_run() {
case 4:
_introStep = 5;
- if (!(_vm->getFeatures() & GF_DEMO)) // The demo doesn't have the intro video
- _vm->_video->playMovie(_vm->wrapMovieFilename("intro", kIntroStack));
+ if (!(_vm->getFeatures() & GF_DEMO)) { // The demo doesn't have the intro video
+ handle = _vm->_video->playMovie(_vm->wrapMovieFilename("intro", kIntroStack));
+ if (!handle)
+ error("Failed to open intro movie");
+
+ handle->center();
+ }
break;
case 5:
if (!_vm->_video->isVideoPlaying())
diff --git a/engines/mohawk/myst_stacks/mechanical.cpp b/engines/mohawk/myst_stacks/mechanical.cpp
index b5d1285435..ffcaa226c6 100644
--- a/engines/mohawk/myst_stacks/mechanical.cpp
+++ b/engines/mohawk/myst_stacks/mechanical.cpp
@@ -316,12 +316,16 @@ void Mechanical::o_snakeBoxTrigger(uint16 op, uint16 var, uint16 argc, uint16 *a
void Mechanical::o_fortressStaircaseMovie(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
debugC(kDebugScript, "Opcode %d: Play Stairs Movement Movie", op);
- VideoHandle staircase = _vm->_video->playMovie(_vm->wrapMovieFilename("hhstairs", kMechanicalStack), 174, 222);
+ VideoHandle staircase = _vm->_video->playMovie(_vm->wrapMovieFilename("hhstairs", kMechanicalStack));
+ if (!staircase)
+ error("Failed to open hhstairs movie");
+
+ staircase->moveTo(174, 222);
if (_state.staircaseState) {
- _vm->_video->setVideoBounds(staircase, Audio::Timestamp(0, 840, 600), Audio::Timestamp(0, 1680, 600));
+ staircase->setBounds(Audio::Timestamp(0, 840, 600), Audio::Timestamp(0, 1680, 600));
} else {
- _vm->_video->setVideoBounds(staircase, Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 840, 600));
+ staircase->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 840, 600));
}
_vm->_video->waitUntilMovieEnds(staircase);
@@ -571,8 +575,12 @@ void Mechanical::o_elevatorWindowMovie(uint16 op, uint16 var, uint16 argc, uint1
debugC(kDebugScript, "Opcode %d Movie Time Index %d to %d", op, startTime, endTime);
- VideoHandle window = _vm->_video->playMovie(_vm->wrapMovieFilename("ewindow", kMechanicalStack), 253, 0);
- _vm->_video->setVideoBounds(window, Audio::Timestamp(0, startTime, 600), Audio::Timestamp(0, endTime, 600));
+ VideoHandle window = _vm->_video->playMovie(_vm->wrapMovieFilename("ewindow", kMechanicalStack));
+ if (!window)
+ error("Failed to open ewindow movie");
+
+ window->moveTo(253, 0);
+ window->setBounds(Audio::Timestamp(0, startTime, 600), Audio::Timestamp(0, endTime, 600));
_vm->_video->waitUntilMovieEnds(window);
}
@@ -644,8 +652,12 @@ void Mechanical::o_elevatorTopMovie(uint16 op, uint16 var, uint16 argc, uint16 *
debugC(kDebugScript, "Opcode %d Movie Time Index %d to %d", op, startTime, endTime);
- VideoHandle window = _vm->_video->playMovie(_vm->wrapMovieFilename("hcelev", kMechanicalStack), 206, 38);
- _vm->_video->setVideoBounds(window, Audio::Timestamp(0, startTime, 600), Audio::Timestamp(0, endTime, 600));
+ VideoHandle window = _vm->_video->playMovie(_vm->wrapMovieFilename("hcelev", kMechanicalStack));
+ if (!window)
+ error("Failed to open hcelev movie");
+
+ window->moveTo(206, 38);
+ window->setBounds(Audio::Timestamp(0, startTime, 600), Audio::Timestamp(0, endTime, 600));
_vm->_video->waitUntilMovieEnds(window);
}
@@ -653,7 +665,7 @@ void Mechanical::o_fortressRotationSetPosition(uint16 op, uint16 var, uint16 arg
debugC(kDebugScript, "Opcode %d: Set fortress position", op);
VideoHandle gears = _fortressRotationGears->playMovie();
- uint32 moviePosition = Audio::Timestamp(_vm->_video->getTime(gears), 600).totalNumberOfFrames();
+ uint32 moviePosition = Audio::Timestamp(gears->getTime(), 600).totalNumberOfFrames();
// Myst ME short movie workaround, explained in o_fortressRotation_init
if (_fortressRotationShortMovieWorkaround) {
@@ -788,9 +800,8 @@ void Mechanical::o_elevatorRotation_init(uint16 op, uint16 var, uint16 argc, uin
void Mechanical::fortressRotation_run() {
VideoHandle gears = _fortressRotationGears->playMovie();
- double oldRate = _vm->_video->getVideoRate(gears).toDouble();
-
- uint32 moviePosition = Audio::Timestamp(_vm->_video->getTime(gears), 600).totalNumberOfFrames();
+ double oldRate = gears->getRate().toDouble();
+ uint32 moviePosition = Audio::Timestamp(gears->getTime(), 600).totalNumberOfFrames();
// Myst ME short movie workaround, explained in o_fortressRotation_init
if (_fortressRotationShortMovieWorkaround) {
@@ -837,19 +848,19 @@ void Mechanical::fortressRotation_run() {
newRate = CLIP<double>(newRate, -2.5, 2.5);
- _vm->_video->setVideoRate(gears, Common::Rational((int)(newRate * 1000.0), 1000));
+ gears->setRate(Common::Rational((int)(newRate * 1000.0), 1000));
_gearsWereRunning = true;
} else if (_gearsWereRunning) {
// The fortress has stopped. Set its new position
_fortressPosition = (moviePosition + 900) / 1800 % 4;
- _vm->_video->setVideoRate(gears, 0);
+ gears->setRate(0);
if (!_fortressRotationShortMovieWorkaround) {
- _vm->_video->seekToTime(gears, Audio::Timestamp(0, 1800 * _fortressPosition, 600));
+ gears->seek(Audio::Timestamp(0, 1800 * _fortressPosition, 600));
} else {
- _vm->_video->seekToTime(gears, Audio::Timestamp(0, 1800 * (_fortressPosition % 2), 600));
+ gears->seek(Audio::Timestamp(0, 1800 * (_fortressPosition % 2), 600));
}
_vm->_sound->playSoundBlocking(_fortressRotationSounds[_fortressPosition]);
@@ -864,9 +875,9 @@ void Mechanical::o_fortressRotation_init(uint16 op, uint16 var, uint16 argc, uin
_fortressRotationGears = static_cast<MystResourceType6 *>(_invokingResource);
VideoHandle gears = _fortressRotationGears->playMovie();
- _vm->_video->setVideoLooping(gears, true);
- _vm->_video->seekToTime(gears, Audio::Timestamp(0, 1800 * _fortressPosition, 600));
- _vm->_video->setVideoRate(gears, 0);
+ gears->setLooping(true);
+ gears->seek(Audio::Timestamp(0, 1800 * _fortressPosition, 600));
+ gears->setRate(0);
_fortressRotationSounds[0] = argv[0];
_fortressRotationSounds[1] = argv[1];
@@ -884,7 +895,7 @@ void Mechanical::o_fortressRotation_init(uint16 op, uint16 var, uint16 argc, uin
// ScummVM simulates a longer movie by counting the number of times the movie
// looped and adding that time to the current movie position.
// Hence allowing the fortress position to be properly computed.
- uint32 movieDuration = _vm->_video->getDuration(gears).convertToFramerate(600).totalNumberOfFrames();
+ uint32 movieDuration = gears->getDuration().convertToFramerate(600).totalNumberOfFrames();
if (movieDuration == 3680) {
_fortressRotationShortMovieWorkaround = true;
_fortressRotationShortMovieCount = 0;
@@ -924,8 +935,8 @@ void Mechanical::fortressSimulation_run() {
_fortressSimulationStartup->pauseMovie(true);
VideoHandle holo = _fortressSimulationHolo->playMovie();
- _vm->_video->setVideoLooping(holo, true);
- _vm->_video->setVideoRate(holo, 0);
+ holo->setLooping(true);
+ holo->setRate(0);
_vm->_cursor->showCursor();
@@ -933,9 +944,8 @@ void Mechanical::fortressSimulation_run() {
} else {
VideoHandle holo = _fortressSimulationHolo->playMovie();
- double oldRate = _vm->_video->getVideoRate(holo).toDouble();
-
- uint32 moviePosition = Audio::Timestamp(_vm->_video->getTime(holo), 600).totalNumberOfFrames();
+ double oldRate = holo->getRate().toDouble();
+ uint32 moviePosition = Audio::Timestamp(holo->getTime(), 600).totalNumberOfFrames();
int32 positionInQuarter = 900 - (moviePosition + 900) % 1800;
@@ -968,15 +978,15 @@ void Mechanical::fortressSimulation_run() {
newRate = CLIP<double>(newRate, -2.5, 2.5);
- _vm->_video->setVideoRate(holo, Common::Rational((int)(newRate * 1000.0), 1000));
+ holo->setRate(Common::Rational((int)(newRate * 1000.0), 1000));
_gearsWereRunning = true;
} else if (_gearsWereRunning) {
// The fortress has stopped. Set its new position
uint16 simulationPosition = (moviePosition + 900) / 1800 % 4;
- _vm->_video->setVideoRate(holo, 0);
- _vm->_video->seekToTime(holo, Audio::Timestamp(0, 1800 * simulationPosition, 600));
+ holo->setRate(0);
+ holo->seek(Audio::Timestamp(0, 1800 * simulationPosition, 600));
_vm->_sound->playSoundBlocking( _fortressRotationSounds[simulationPosition]);
_gearsWereRunning = false;
diff --git a/engines/mohawk/myst_stacks/myst.cpp b/engines/mohawk/myst_stacks/myst.cpp
index c500df5ad3..98f0aa5349 100644
--- a/engines/mohawk/myst_stacks/myst.cpp
+++ b/engines/mohawk/myst_stacks/myst.cpp
@@ -51,8 +51,6 @@ Myst::Myst(MohawkEngine_Myst *vm) :
_dockVaultState = 0;
_cabinDoorOpened = 0;
_cabinMatchState = 2;
- _cabinGaugeMovie = NULL_VID_HANDLE;
- _cabinFireMovie = NULL_VID_HANDLE;
_matchBurning = false;
_tree = 0;
_treeAlcove = 0;
@@ -1135,10 +1133,13 @@ void Myst::o_clockWheelsExecute(uint16 op, uint16 var, uint16 argc, uint16 *argv
_vm->_system->delayMillis(500);
// Gears rise up
- VideoHandle gears = _vm->_video->playMovie(_vm->wrapMovieFilename("gears", kMystStack), 305, 33);
- _vm->_video->setVideoBounds(gears, Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 650, 600));
- _vm->_video->waitUntilMovieEnds(gears);
+ VideoHandle gears = _vm->_video->playMovie(_vm->wrapMovieFilename("gears", kMystStack));
+ if (!gears)
+ error("Failed to open gears movie");
+ gears->moveTo(305, 33);
+ gears->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 650, 600));
+ _vm->_video->waitUntilMovieEnds(gears);
_state.clockTowerBridgeOpen = 1;
_vm->redrawArea(12);
@@ -1147,8 +1148,12 @@ void Myst::o_clockWheelsExecute(uint16 op, uint16 var, uint16 argc, uint16 *argv
_vm->_system->delayMillis(500);
// Gears sink down
- VideoHandle gears = _vm->_video->playMovie(_vm->wrapMovieFilename("gears", kMystStack), 305, 33);
- _vm->_video->setVideoBounds(gears, Audio::Timestamp(0, 700, 600), Audio::Timestamp(0, 1300, 600));
+ VideoHandle gears = _vm->_video->playMovie(_vm->wrapMovieFilename("gears", kMystStack));
+ if (!gears)
+ error("Failed to open gears movie");
+
+ gears->moveTo(305, 33);
+ gears->setBounds(Audio::Timestamp(0, 700, 600), Audio::Timestamp(0, 1300, 600));
_vm->_video->waitUntilMovieEnds(gears);
_state.clockTowerBridgeOpen = 0;
@@ -1191,15 +1196,23 @@ void Myst::o_imagerPlayButton(uint16 op, uint16 var, uint16 argc, uint16 *argv)
if (_state.imagerActive) {
// Mountains disappearing
Common::String file = _vm->wrapMovieFilename("vltmntn", kMystStack);
- VideoHandle mountain = _vm->_video->playMovie(file, 159, 96, false);
- _vm->_video->setVideoBounds(mountain, Audio::Timestamp(0, 11180, 600), Audio::Timestamp(0, 16800, 600));
+ VideoHandle mountain = _vm->_video->playMovie(file);
+ if (!mountain)
+ error("Failed to open '%s'", file.c_str());
+
+ mountain->moveTo(159, 96);
+ mountain->setBounds(Audio::Timestamp(0, 11180, 600), Audio::Timestamp(0, 16800, 600));
_state.imagerActive = 0;
} else {
// Mountains appearing
Common::String file = _vm->wrapMovieFilename("vltmntn", kMystStack);
- VideoHandle mountain = _vm->_video->playMovie(file, 159, 96, false);
- _vm->_video->setVideoBounds(mountain, Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 11180, 600));
+ VideoHandle mountain = _vm->_video->playMovie(file);
+ if (!mountain)
+ error("Failed to open '%s'", file.c_str());
+
+ mountain->moveTo(159, 96);
+ mountain->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 11180, 600));
_state.imagerActive = 1;
}
@@ -1212,20 +1225,20 @@ void Myst::o_imagerPlayButton(uint16 op, uint16 var, uint16 argc, uint16 *argv)
// Water disappearing
VideoHandle water = _imagerMovie->playMovie();
- _vm->_video->setVideoBounds(water, Audio::Timestamp(0, 4204, 600), Audio::Timestamp(0, 6040, 600));
- _vm->_video->setVideoLooping(water, false);
+ water->setBounds(Audio::Timestamp(0, 4204, 600), Audio::Timestamp(0, 6040, 600));
+ water->setLooping(false);
_state.imagerActive = 0;
} else {
// Water appearing
VideoHandle water = _imagerMovie->playMovie();
- _vm->_video->setVideoBounds(water, Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 1814, 600));
+ water->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 1814, 600));
_vm->_video->waitUntilMovieEnds(water);
// Water looping
water = _imagerMovie->playMovie();
- _vm->_video->setVideoBounds(water, Audio::Timestamp(0, 1814, 600), Audio::Timestamp(0, 4204, 600));
- _vm->_video->setVideoLooping(water, true);
+ water->setBounds(Audio::Timestamp(0, 1814, 600), Audio::Timestamp(0, 4204, 600));
+ water->setLooping(true);
_state.imagerActive = 1;
}
@@ -1902,11 +1915,19 @@ Common::Rational Myst::boilerComputeGaugeRate(uint16 pressure, uint32 delay) {
}
void Myst::boilerResetGauge(const Common::Rational &rate) {
- if (_vm->_video->endOfVideo(_cabinGaugeMovie)) {
+ if (!_cabinGaugeMovie || _cabinGaugeMovie->endOfVideo()) {
if (_vm->getCurCard() == 4098) {
- _cabinGaugeMovie = _vm->_video->playMovie(_vm->wrapMovieFilename("cabingau", kMystStack), 243, 96);
+ _cabinGaugeMovie = _vm->_video->playMovie(_vm->wrapMovieFilename("cabingau", kMystStack));
+ if (!_cabinGaugeMovie)
+ error("Failed to open cabingau movie");
+
+ _cabinGaugeMovie->moveTo(243, 96);
} else {
- _cabinGaugeMovie = _vm->_video->playMovie(_vm->wrapMovieFilename("cabcgfar", kMystStack), 254, 136);
+ _cabinGaugeMovie = _vm->_video->playMovie(_vm->wrapMovieFilename("cabcgfar", kMystStack));
+ if (!_cabinGaugeMovie)
+ error("Failed to open cabingau movie");
+
+ _cabinGaugeMovie->moveTo(254, 136);
}
}
@@ -1914,10 +1935,10 @@ void Myst::boilerResetGauge(const Common::Rational &rate) {
if (rate > 0)
goTo = Audio::Timestamp(0, 0, 600);
else
- goTo = _vm->_video->getDuration(_cabinGaugeMovie);
+ goTo = _cabinGaugeMovie->getDuration();
- _vm->_video->seekToTime(_cabinGaugeMovie, goTo);
- _vm->_video->setVideoRate(_cabinGaugeMovie, rate);
+ _cabinGaugeMovie->seek(goTo);
+ _cabinGaugeMovie->setRate(rate);
}
void Myst::o_boilerIncreasePressureStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -1931,10 +1952,10 @@ void Myst::o_boilerIncreasePressureStop(uint16 op, uint16 var, uint16 argc, uint
if (_state.cabinValvePosition > 0)
_vm->_sound->replaceBackgroundMyst(8098, 49152);
- if (!_vm->_video->endOfVideo(_cabinGaugeMovie)) {
+ if (_cabinGaugeMovie && !_cabinGaugeMovie->endOfVideo()) {
uint16 delay = treeNextMoveDelay(_state.cabinValvePosition);
Common::Rational rate = boilerComputeGaugeRate(_state.cabinValvePosition, delay);
- _vm->_video->setVideoRate(_cabinGaugeMovie, rate);
+ _cabinGaugeMovie->setRate(rate);
}
} else if (_state.cabinValvePosition > 0)
@@ -2006,10 +2027,10 @@ void Myst::o_boilerDecreasePressureStop(uint16 op, uint16 var, uint16 argc, uint
if (_state.cabinValvePosition > 0)
_vm->_sound->replaceBackgroundMyst(8098, 49152);
- if (!_vm->_video->endOfVideo(_cabinGaugeMovie)) {
+ if (_cabinGaugeMovie && !_cabinGaugeMovie->endOfVideo()) {
uint16 delay = treeNextMoveDelay(_state.cabinValvePosition);
Common::Rational rate = boilerComputeGaugeRate(_state.cabinValvePosition, delay);
- _vm->_video->setVideoRate(_cabinGaugeMovie, rate);
+ _cabinGaugeMovie->setRate(rate);
}
} else {
@@ -2117,7 +2138,7 @@ void Myst::tree_run() {
// Check if alcove is accessible
treeSetAlcoveAccessible();
- if (_cabinGaugeMovie != NULL_VID_HANDLE) {
+ if (_cabinGaugeMovie) {
Common::Rational rate = boilerComputeGaugeRate(pressure, delay);
boilerResetGauge(rate);
}
@@ -2246,13 +2267,22 @@ void Myst::rocketCheckSolution() {
// Book appearing
Common::String movieFile = _vm->wrapMovieFilename("selenbok", kMystStack);
- _rocketLinkBook = _vm->_video->playMovie(movieFile, 224, 41);
- _vm->_video->setVideoBounds(_rocketLinkBook, Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 660, 600));
+ _rocketLinkBook = _vm->_video->playMovie(movieFile);
+ if (!_rocketLinkBook)
+ error("Failed to open '%s'", movieFile.c_str());
+
+ _rocketLinkBook->moveTo(224, 41);
+ _rocketLinkBook->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 660, 600));
_vm->_video->waitUntilMovieEnds(_rocketLinkBook);
// Book looping closed
- _rocketLinkBook = _vm->_video->playMovie(movieFile, 224, 41, true);
- _vm->_video->setVideoBounds(_rocketLinkBook, Audio::Timestamp(0, 660, 600), Audio::Timestamp(0, 3500, 600));
+ _rocketLinkBook = _vm->_video->playMovie(movieFile);
+ if (!_rocketLinkBook)
+ error("Failed to open '%s'", movieFile.c_str());
+
+ _rocketLinkBook->moveTo(224, 41);
+ _rocketLinkBook->setLooping(true);
+ _rocketLinkBook->setBounds(Audio::Timestamp(0, 660, 600), Audio::Timestamp(0, 3500, 600));
_tempVar = 1;
}
@@ -2367,7 +2397,7 @@ void Myst::o_rocketOpenBook(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
debugC(kDebugScript, "Opcode %d: Rocket open link book", op);
// Flyby movie
- _vm->_video->setVideoBounds(_rocketLinkBook, Audio::Timestamp(0, 3500, 600), Audio::Timestamp(0, 13100, 600));
+ _rocketLinkBook->setBounds(Audio::Timestamp(0, 3500, 600), Audio::Timestamp(0, 13100, 600));
// Set linkable
_tempVar = 2;
@@ -2889,8 +2919,12 @@ void Myst::clockGearForwardOneStep(uint16 gear) {
// Set video bounds
uint16 gearPosition = _clockGearsPositions[gear] - 1;
- _clockGearsVideos[gear] = _vm->_video->playMovie(_vm->wrapMovieFilename(videos[gear], kMystStack), x[gear], y[gear]);
- _vm->_video->setVideoBounds(_clockGearsVideos[gear],
+ _clockGearsVideos[gear] = _vm->_video->playMovie(_vm->wrapMovieFilename(videos[gear], kMystStack));
+ if (!_clockGearsVideos[gear])
+ error("Failed to open %s movie", videos[gear]);
+
+ _clockGearsVideos[gear]->moveTo(x[gear], y[gear]);
+ _clockGearsVideos[gear]->setBounds(
Audio::Timestamp(0, startTime[gearPosition], 600),
Audio::Timestamp(0, endTime[gearPosition], 600));
}
@@ -2902,8 +2936,12 @@ void Myst::clockWeightDownOneStep() {
// Set video bounds
if (updateVideo) {
- _clockWeightVideo = _vm->_video->playMovie(_vm->wrapMovieFilename("cl1wlfch", kMystStack) , 124, 0);
- _vm->_video->setVideoBounds(_clockWeightVideo,
+ _clockWeightVideo = _vm->_video->playMovie(_vm->wrapMovieFilename("cl1wlfch", kMystStack));
+ if (!_clockWeightVideo)
+ error("Failed to open cl1wlfch movie");
+
+ _clockWeightVideo->moveTo(124, 0);
+ _clockWeightVideo->setBounds(
Audio::Timestamp(0, _clockWeightPosition, 600),
Audio::Timestamp(0, _clockWeightPosition + 246, 600));
}
@@ -2931,7 +2969,7 @@ void Myst::o_clockLeverEndMove(uint16 op, uint16 var, uint16 argc, uint16 *argv)
// Let movies stop playing
for (uint i = 0; i < ARRAYSIZE(videos); i++) {
VideoHandle handle = _vm->_video->findVideoHandle(_vm->wrapMovieFilename(videos[i], kMystStack));
- if (handle != NULL_VID_HANDLE)
+ if (handle)
_vm->_video->delayUntilMovieEnds(handle);
}
@@ -2956,8 +2994,12 @@ void Myst::clockGearsCheckSolution() {
// Make weight go down
_vm->_sound->replaceSoundMyst(9113);
- _clockWeightVideo = _vm->_video->playMovie(_vm->wrapMovieFilename("cl1wlfch", kMystStack) , 124, 0);
- _vm->_video->setVideoBounds(_clockWeightVideo,
+ _clockWeightVideo = _vm->_video->playMovie(_vm->wrapMovieFilename("cl1wlfch", kMystStack));
+ if (!_clockWeightVideo)
+ error("Failed to open cl1wlfch movie");
+
+ _clockWeightVideo->moveTo(124, 0);
+ _clockWeightVideo->setBounds(
Audio::Timestamp(0, _clockWeightPosition, 600),
Audio::Timestamp(0, 2214, 600));
_vm->_video->waitUntilMovieEnds(_clockWeightVideo);
@@ -2968,7 +3010,7 @@ void Myst::clockGearsCheckSolution() {
_vm->_sound->replaceSoundMyst(7113);
// Gear opening video
- _vm->_video->playMovieBlocking(_vm->wrapMovieFilename("cl1wggat", kMystStack) , 195, 225);
+ _vm->_video->playMovieBlocking(_vm->wrapMovieFilename("cl1wggat", kMystStack), 195, 225);
_state.gearsOpen = 1;
_vm->redrawArea(40);
@@ -3011,7 +3053,7 @@ void Myst::clockReset() {
// Let movies stop playing
for (uint i = 0; i < ARRAYSIZE(videos); i++) {
VideoHandle handle = _vm->_video->findVideoHandle(_vm->wrapMovieFilename(videos[i], kMystStack));
- if (handle != NULL_VID_HANDLE)
+ if (handle)
_vm->_video->delayUntilMovieEnds(handle);
}
@@ -3024,9 +3066,13 @@ void Myst::clockReset() {
_vm->_sound->replaceSoundMyst(7113);
// Gear closing movie
- VideoHandle handle = _vm->_video->playMovie(_vm->wrapMovieFilename("cl1wggat", kMystStack) , 195, 225);
- _vm->_video->seekToTime(handle, _vm->_video->getDuration(handle));
- _vm->_video->setVideoRate(handle, -1);
+ VideoHandle handle = _vm->_video->playMovie(_vm->wrapMovieFilename("cl1wggat", kMystStack));
+ if (!handle)
+ error("Failed to open cl1wggat movie");
+
+ handle->moveTo(195, 225);
+ handle->seek(handle->getDuration());
+ handle->setRate(-1);
_vm->_video->waitUntilMovieEnds(handle);
// Redraw gear
@@ -3038,11 +3084,15 @@ void Myst::clockReset() {
}
void Myst::clockResetWeight() {
- _clockWeightVideo = _vm->_video->playMovie(_vm->wrapMovieFilename("cl1wlfch", kMystStack) , 124, 0);
+ _clockWeightVideo = _vm->_video->playMovie(_vm->wrapMovieFilename("cl1wlfch", kMystStack));
+ if (!_clockWeightVideo)
+ error("Failed to open cl1wlfch movie");
+
+ _clockWeightVideo->moveTo(124, 0);
// Play the movie backwards, weight going up
- _vm->_video->seekToTime(_clockWeightVideo, Audio::Timestamp(0, _clockWeightPosition, 600));
- _vm->_video->setVideoRate(_clockWeightVideo, -1);
+ _clockWeightVideo->seek(Audio::Timestamp(0, _clockWeightPosition, 600));
+ _clockWeightVideo->setRate(-1);
// Reset position
_clockWeightPosition = 0;
@@ -3057,8 +3107,12 @@ void Myst::clockResetGear(uint16 gear) {
// Set video bounds, gears going to 3
uint16 gearPosition = _clockGearsPositions[gear] - 1;
if (gearPosition != 2) {
- _clockGearsVideos[gear] = _vm->_video->playMovie(_vm->wrapMovieFilename(videos[gear], kMystStack), x[gear], y[gear]);
- _vm->_video->setVideoBounds(_clockGearsVideos[gear],
+ _clockGearsVideos[gear] = _vm->_video->playMovie(_vm->wrapMovieFilename(videos[gear], kMystStack));
+ if (!_clockGearsVideos[gear])
+ error("Failed to open gears movie");
+
+ _clockGearsVideos[gear]->moveTo(x[gear], y[gear]);
+ _clockGearsVideos[gear]->setBounds(
Audio::Timestamp(0, time[gearPosition], 600),
Audio::Timestamp(0, time[2], 600));
}
@@ -3201,13 +3255,21 @@ Common::Point Myst::towerRotationMapComputeCoords(const Common::Point &center, u
}
void Myst::towerRotationMapDrawLine(const Common::Point &center, const Common::Point &end) {
- Graphics::PixelFormat pf = _vm->_system->getScreenFormat();
- uint32 color = 0;
+ uint32 color;
- if (!_towerRotationOverSpot)
- color = pf.RGBToColor(0xFF, 0xFF, 0xFF); // White
- else
- color = pf.RGBToColor(0xFF, 0, 0); // Red
+ if (_vm->getFeatures() & GF_ME) {
+ Graphics::PixelFormat pf = _vm->_system->getScreenFormat();
+
+ if (!_towerRotationOverSpot)
+ color = pf.RGBToColor(0xFF, 0xFF, 0xFF); // White
+ else
+ color = pf.RGBToColor(0xFF, 0, 0); // Red
+ } else {
+ if (!_towerRotationOverSpot)
+ color = 0x00; // White
+ else
+ color = 0xF9; // Red
+ }
const Common::Rect rect = Common::Rect(106, 42, 459, 273);
@@ -3281,8 +3343,8 @@ void Myst::imager_run() {
if (_state.imagerActive && _state.imagerSelection == 67) {
VideoHandle water = _imagerMovie->playMovie();
- _vm->_video->setVideoBounds(water, Audio::Timestamp(0, 1814, 600), Audio::Timestamp(0, 4204, 600));
- _vm->_video->setVideoLooping(water, true);
+ water->setBounds(Audio::Timestamp(0, 1814, 600), Audio::Timestamp(0, 4204, 600));
+ water->setLooping(true);
}
}
@@ -3394,8 +3456,11 @@ void Myst::gullsFly1_run() {
else
x = _vm->_rnd->getRandomNumber(160) + 260;
- _vm->_video->playMovie(_vm->wrapMovieFilename(gulls[video], kMystStack), x, 0);
+ VideoHandle handle = _vm->_video->playMovie(_vm->wrapMovieFilename(gulls[video], kMystStack));
+ if (!handle)
+ error("Failed to open gulls movie");
+ handle->moveTo(x, 0);
_gullsNextTime = time + _vm->_rnd->getRandomNumber(16667) + 13334;
}
}
@@ -3540,8 +3605,11 @@ void Myst::gullsFly2_run() {
if (time > _gullsNextTime) {
uint16 video = _vm->_rnd->getRandomNumber(3);
if (video != 3) {
- _vm->_video->playMovie(_vm->wrapMovieFilename(gulls[video], kMystStack), 424, 0);
-
+ VideoHandle handle = _vm->_video->playMovie(_vm->wrapMovieFilename(gulls[video], kMystStack));
+ if (!handle)
+ error("Failed to open gulls movie");
+
+ handle->moveTo(424, 0);
_gullsNextTime = time + _vm->_rnd->getRandomNumber(16667) + 13334;
}
}
@@ -3572,31 +3640,41 @@ void Myst::o_boilerMovies_init(uint16 op, uint16 var, uint16 argc, uint16 *argv)
void Myst::boilerFireInit() {
if (_vm->getCurCard() == 4098) {
- _cabinFireMovie = _vm->_video->playMovie(_vm->wrapMovieFilename("cabfire", kMystStack), 240, 279, true);
- _vm->_video->pauseMovie(_cabinFireMovie, true);
+ _cabinFireMovie = _vm->_video->playMovie(_vm->wrapMovieFilename("cabfire", kMystStack));
+ if (!_cabinFireMovie)
+ error("Failed to open cabfire movie");
+
+ _cabinFireMovie->moveTo(240, 279);
+ _cabinFireMovie->setLooping(true);
+ _cabinFireMovie->pause(true);
_vm->redrawArea(305);
boilerFireUpdate(true);
} else {
if (_state.cabinPilotLightLit == 1 && _state.cabinValvePosition >= 1) {
- _cabinFireMovie = _vm->_video->playMovie(_vm->wrapMovieFilename("cabfirfr", kMystStack), 254, 244, true);
+ _cabinFireMovie = _vm->_video->playMovie(_vm->wrapMovieFilename("cabfirfr", kMystStack));
+ if (!_cabinFireMovie)
+ error("Failed to open cabfirfr movie");
+
+ _cabinFireMovie->moveTo(254, 244);
+ _cabinFireMovie->setLooping(true);
}
}
}
void Myst::boilerFireUpdate(bool init) {
- uint position = _vm->_video->getTime(_cabinFireMovie);
+ uint position = _cabinFireMovie->getTime();
if (_state.cabinPilotLightLit == 1) {
if (_state.cabinValvePosition == 0) {
if (position > (uint)Audio::Timestamp(0, 200, 600).msecs() || init) {
- _vm->_video->setVideoBounds(_cabinFireMovie, Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 100, 600));
- _vm->_video->pauseMovie(_cabinFireMovie, false);
+ _cabinFireMovie->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 100, 600));
+ _cabinFireMovie->pause(false);
}
} else {
if (position < (uint)Audio::Timestamp(0, 200, 600).msecs() || init) {
- _vm->_video->setVideoBounds(_cabinFireMovie, Audio::Timestamp(0, 201, 600), Audio::Timestamp(0, 1900, 600));
- _vm->_video->pauseMovie(_cabinFireMovie, false);
+ _cabinFireMovie->setBounds(Audio::Timestamp(0, 201, 600), Audio::Timestamp(0, 1900, 600));
+ _cabinFireMovie->pause(false);
}
}
}
@@ -3604,15 +3682,23 @@ void Myst::boilerFireUpdate(bool init) {
void Myst::boilerGaugeInit() {
if (_vm->getCurCard() == 4098) {
- _cabinGaugeMovie = _vm->_video->playMovie(_vm->wrapMovieFilename("cabingau", kMystStack), 243, 96);
+ _cabinGaugeMovie = _vm->_video->playMovie(_vm->wrapMovieFilename("cabingau", kMystStack));
+ if (!_cabinFireMovie)
+ error("Failed to open cabingau movie");
+
+ _cabinFireMovie->moveTo(243, 96);
} else {
- _cabinGaugeMovie = _vm->_video->playMovie(_vm->wrapMovieFilename("cabcgfar", kMystStack), 254, 136);
+ _cabinGaugeMovie = _vm->_video->playMovie(_vm->wrapMovieFilename("cabcgfar", kMystStack));
+ if (!_cabinFireMovie)
+ error("Failed to open cabcgfar movie");
+
+ _cabinFireMovie->moveTo(254, 136);
}
Audio::Timestamp frame;
if (_state.cabinPilotLightLit == 1 && _state.cabinValvePosition > 12)
- frame = _vm->_video->getDuration(_cabinGaugeMovie);
+ frame = _cabinGaugeMovie->getDuration();
else
frame = Audio::Timestamp(0, 0, 600);
@@ -3672,18 +3758,27 @@ void Myst::greenBook_run() {
_vm->_sound->stopSound();
_vm->_sound->pauseBackgroundMyst();
+ VideoHandle book = _vm->_video->playMovie(file);
+ if (!book)
+ error("Failed to open '%s'", file.c_str());
+
+ book->moveTo(314, 76);
+
if (_globals.ending != 4) {
_tempVar = 2;
- _vm->_video->playMovie(file, 314, 76);
} else {
- VideoHandle book = _vm->_video->playMovie(file, 314, 76, true);
- _vm->_video->setVideoBounds(book, Audio::Timestamp(0, loopStart, 600), Audio::Timestamp(0, loopEnd, 600));
+ book->setBounds(Audio::Timestamp(0, loopStart, 600), Audio::Timestamp(0, loopEnd, 600));
+ book->setLooping(true);
_tempVar = 0;
}
} else if (_tempVar == 2 && !_vm->_video->isVideoPlaying()) {
- VideoHandle book = _vm->_video->playMovie(file, 314, 76);
- _vm->_video->setVideoBounds(book, Audio::Timestamp(0, loopStart, 600), Audio::Timestamp(0, loopEnd, 600));
- _vm->_video->setVideoLooping(book, true);
+ VideoHandle book = _vm->_video->playMovie(file);
+ if (!book)
+ error("Failed to open '%s'", file.c_str());
+
+ book->moveTo(314, 76);
+ book->setBounds(Audio::Timestamp(0, loopStart, 600), Audio::Timestamp(0, loopEnd, 600));
+ book->setLooping(true);
_tempVar = 0;
}
}
@@ -3706,8 +3801,11 @@ void Myst::gullsFly3_run() {
if (video != 3) {
uint16 x = _vm->_rnd->getRandomNumber(280) + 135;
- _vm->_video->playMovie(_vm->wrapMovieFilename(gulls[video], kMystStack), x, 0);
+ VideoHandle handle = _vm->_video->playMovie(_vm->wrapMovieFilename(gulls[video], kMystStack));
+ if (!handle)
+ error("Failed to open gulls movie");
+ handle->moveTo(x, 0);
_gullsNextTime = time + _vm->_rnd->getRandomNumber(16667) + 13334;
}
}
@@ -3742,8 +3840,8 @@ void Myst::o_treeEntry_exit(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
void Myst::o_boiler_exit(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
debugC(kDebugScript, "Opcode %d: Exit boiler card", op);
- _cabinGaugeMovie = NULL_VID_HANDLE;
- _cabinFireMovie = NULL_VID_HANDLE;
+ _cabinGaugeMovie = VideoHandle();
+ _cabinFireMovie = VideoHandle();
}
void Myst::o_generatorControlRoom_exit(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
diff --git a/engines/mohawk/myst_stacks/stoneship.cpp b/engines/mohawk/myst_stacks/stoneship.cpp
index d8dbeef641..1113ceeac9 100644
--- a/engines/mohawk/myst_stacks/stoneship.cpp
+++ b/engines/mohawk/myst_stacks/stoneship.cpp
@@ -425,8 +425,12 @@ void Stoneship::o_cabinBookMovie(uint16 op, uint16 var, uint16 argc, uint16 *arg
uint16 startTime = argv[0];
uint16 endTime = argv[1];
- VideoHandle book = _vm->_video->playMovie(_vm->wrapMovieFilename("bkroom", kStoneshipStack), 159, 99);
- _vm->_video->setVideoBounds(book, Audio::Timestamp(0, startTime, 600), Audio::Timestamp(0, endTime, 600));
+ VideoHandle book = _vm->_video->playMovie(_vm->wrapMovieFilename("bkroom", kStoneshipStack));
+ if (!book)
+ error("Failed to open bkroom movie");
+
+ book->moveTo(159, 99);
+ book->setBounds(Audio::Timestamp(0, startTime, 600), Audio::Timestamp(0, endTime, 600));
_vm->_video->waitUntilMovieEnds(book);
}
@@ -597,9 +601,9 @@ void Stoneship::o_hologramPlayback(uint16 op, uint16 var, uint16 argc, uint16 *a
if (_hologramTurnedOn) {
if (_hologramDisplayPos)
endPoint = _hologramDisplayPos;
- _vm->_video->setVideoBounds(displayMovie, Audio::Timestamp(0, startPoint, 600), Audio::Timestamp(0, endPoint, 600));
+ displayMovie->setBounds(Audio::Timestamp(0, startPoint, 600), Audio::Timestamp(0, endPoint, 600));
} else {
- _vm->_video->setVideoBounds(displayMovie, Audio::Timestamp(0, startPoint, 600), Audio::Timestamp(0, endPoint, 600));
+ displayMovie->setBounds(Audio::Timestamp(0, startPoint, 600), Audio::Timestamp(0, endPoint, 600));
}
_vm->_video->delayUntilMovieEnds(displayMovie);
@@ -673,29 +677,45 @@ void Stoneship::o_chestValveVideos(uint16 op, uint16 var, uint16 argc, uint16 *a
if (_state.chestValveState) {
// Valve closing
- VideoHandle valve = _vm->_video->playMovie(movie, 97, 267);
- _vm->_video->setVideoBounds(valve, Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 350, 600));
+ VideoHandle valve = _vm->_video->playMovie(movie);
+ if (!valve)
+ error("Failed to open '%s'", movie.c_str());
+
+ valve->moveTo(97, 267);
+ valve->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 350, 600));
_vm->_video->waitUntilMovieEnds(valve);
} else if (_state.chestWaterState) {
// Valve opening, spilling water
- VideoHandle valve = _vm->_video->playMovie(movie, 97, 267);
- _vm->_video->setVideoBounds(valve, Audio::Timestamp(0, 350, 600), Audio::Timestamp(0, 650, 600));
+ VideoHandle valve = _vm->_video->playMovie(movie);
+ if (!valve)
+ error("Failed to open '%s'", movie.c_str());
+
+ valve->moveTo(97, 267);
+ valve->setBounds(Audio::Timestamp(0, 350, 600), Audio::Timestamp(0, 650, 600));
_vm->_video->waitUntilMovieEnds(valve);
_vm->_sound->playSound(3132);
for (uint i = 0; i < 25; i++) {
- valve = _vm->_video->playMovie(movie, 97, 267);
- _vm->_video->setVideoBounds(valve, Audio::Timestamp(0, 650, 600), Audio::Timestamp(0, 750, 600));
+ valve = _vm->_video->playMovie(movie);
+ if (!valve)
+ error("Failed to open '%s'", movie.c_str());
+
+ valve->moveTo(97, 267);
+ valve->setBounds(Audio::Timestamp(0, 650, 600), Audio::Timestamp(0, 750, 600));
_vm->_video->waitUntilMovieEnds(valve);
}
_vm->_sound->resumeBackgroundMyst();
} else {
// Valve opening
- VideoHandle valve = _vm->_video->playMovie(movie, 97, 267);
- _vm->_video->seekToTime(valve, Audio::Timestamp(0, 350, 600));
- _vm->_video->setVideoRate(valve, -1);
+ VideoHandle valve = _vm->_video->playMovie(movie);
+ if (!valve)
+ error("Failed to open '%s'", movie.c_str());
+
+ valve->moveTo(97, 267);
+ valve->seek(Audio::Timestamp(0, 350, 600));
+ valve->setRate(-1);
_vm->_video->waitUntilMovieEnds(valve);
}
}
@@ -716,14 +736,22 @@ void Stoneship::o_trapLockOpen(uint16 op, uint16 var, uint16 argc, uint16 *argv)
Common::String movie = _vm->wrapMovieFilename("openloc", kStoneshipStack);
- VideoHandle lock = _vm->_video->playMovie(movie, 187, 71);
- _vm->_video->setVideoBounds(lock, Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 750, 600));
+ VideoHandle lock = _vm->_video->playMovie(movie);
+ if (!lock)
+ error("Failed to open '%s'", movie.c_str());
+
+ lock->moveTo(187, 71);
+ lock->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 750, 600));
_vm->_video->waitUntilMovieEnds(lock);
_vm->_sound->playSound(2143);
- lock = _vm->_video->playMovie(movie, 187, 71);
- _vm->_video->setVideoBounds(lock, Audio::Timestamp(0, 750, 600), Audio::Timestamp(0, 10000, 600));
+ lock = _vm->_video->playMovie(movie);
+ if (!lock)
+ error("Failed to open '%s'", movie.c_str());
+
+ lock->moveTo(187, 71);
+ lock->setBounds(Audio::Timestamp(0, 750, 600), Audio::Timestamp(0, 10000, 600));
_vm->_video->waitUntilMovieEnds(lock);
if (_state.pumpState != 4)
diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp
index a7fe12b9e1..898f68c581 100644
--- a/engines/mohawk/riven.cpp
+++ b/engines/mohawk/riven.cpp
@@ -828,7 +828,7 @@ static void sunnersTopStairsTimer(MohawkEngine_Riven *vm) {
VideoHandle oldHandle = vm->_video->findVideoHandleRiven(1);
uint32 timerTime = 500;
- if (oldHandle == NULL_VID_HANDLE || vm->_video->endOfVideo(oldHandle)) {
+ if (!oldHandle || oldHandle->endOfVideo()) {
uint32 &sunnerTime = vm->_vars["jsunnertime"];
if (sunnerTime == 0) {
@@ -836,7 +836,7 @@ static void sunnersTopStairsTimer(MohawkEngine_Riven *vm) {
} else if (sunnerTime < vm->getTotalPlayTime()) {
VideoHandle handle = vm->_video->playMovieRiven(vm->_rnd->getRandomNumberRng(1, 3));
- timerTime = vm->_video->getDuration(handle).msecs() + vm->_rnd->getRandomNumberRng(2, 15) * 1000;
+ timerTime = handle->getDuration().msecs() + vm->_rnd->getRandomNumberRng(2, 15) * 1000;
}
sunnerTime = timerTime + vm->getTotalPlayTime();
@@ -858,7 +858,7 @@ static void sunnersMidStairsTimer(MohawkEngine_Riven *vm) {
VideoHandle oldHandle = vm->_video->findVideoHandleRiven(1);
uint32 timerTime = 500;
- if (oldHandle == NULL_VID_HANDLE || vm->_video->endOfVideo(oldHandle)) {
+ if (!oldHandle || oldHandle->endOfVideo()) {
uint32 &sunnerTime = vm->_vars["jsunnertime"];
if (sunnerTime == 0) {
@@ -874,7 +874,7 @@ static void sunnersMidStairsTimer(MohawkEngine_Riven *vm) {
VideoHandle handle = vm->_video->playMovieRiven(movie);
- timerTime = vm->_video->getDuration(handle).msecs() + vm->_rnd->getRandomNumberRng(1, 10) * 1000;
+ timerTime = handle->getDuration().msecs() + vm->_rnd->getRandomNumberRng(1, 10) * 1000;
}
sunnerTime = timerTime + vm->getTotalPlayTime();
@@ -896,7 +896,7 @@ static void sunnersLowerStairsTimer(MohawkEngine_Riven *vm) {
VideoHandle oldHandle = vm->_video->findVideoHandleRiven(1);
uint32 timerTime = 500;
- if (oldHandle == NULL_VID_HANDLE || vm->_video->endOfVideo(oldHandle)) {
+ if (!oldHandle || oldHandle->endOfVideo()) {
uint32 &sunnerTime = vm->_vars["jsunnertime"];
if (sunnerTime == 0) {
@@ -904,7 +904,7 @@ static void sunnersLowerStairsTimer(MohawkEngine_Riven *vm) {
} else if (sunnerTime < vm->getTotalPlayTime()) {
VideoHandle handle = vm->_video->playMovieRiven(vm->_rnd->getRandomNumberRng(3, 5));
- timerTime = vm->_video->getDuration(handle).msecs() + vm->_rnd->getRandomNumberRng(1, 30) * 1000;
+ timerTime = handle->getDuration().msecs() + vm->_rnd->getRandomNumberRng(1, 30) * 1000;
}
sunnerTime = timerTime + vm->getTotalPlayTime();
@@ -926,7 +926,7 @@ static void sunnersBeachTimer(MohawkEngine_Riven *vm) {
VideoHandle oldHandle = vm->_video->findVideoHandleRiven(3);
uint32 timerTime = 500;
- if (oldHandle == NULL_VID_HANDLE || vm->_video->endOfVideo(oldHandle)) {
+ if (!oldHandle || oldHandle->endOfVideo()) {
uint32 &sunnerTime = vm->_vars["jsunnertime"];
if (sunnerTime == 0) {
@@ -938,7 +938,7 @@ static void sunnersBeachTimer(MohawkEngine_Riven *vm) {
vm->_video->activateMLST(mlstID, vm->getCurCard());
VideoHandle handle = vm->_video->playMovieRiven(mlstID);
- timerTime = vm->_video->getDuration(handle).msecs() + vm->_rnd->getRandomNumberRng(1, 30) * 1000;
+ timerTime = handle->getDuration().msecs() + vm->_rnd->getRandomNumberRng(1, 30) * 1000;
}
sunnerTime = timerTime + vm->getTotalPlayTime();
@@ -969,7 +969,7 @@ void MohawkEngine_Riven::installCardTimer() {
}
void MohawkEngine_Riven::doVideoTimer(VideoHandle handle, bool force) {
- assert(handle != NULL_VID_HANDLE);
+ assert(handle);
uint16 id = _scriptMan->getStoredMovieOpcodeID();
@@ -977,7 +977,7 @@ void MohawkEngine_Riven::doVideoTimer(VideoHandle handle, bool force) {
return;
// Run the opcode if we can at this point
- if (force || _video->getTime(handle) >= _scriptMan->getStoredMovieOpcodeTime())
+ if (force || handle->getTime() >= _scriptMan->getStoredMovieOpcodeTime())
_scriptMan->runStoredMovieOpcode();
}
@@ -1003,7 +1003,7 @@ void MohawkEngine_Riven::checkSunnerAlertClick() {
// If the alert video is no longer playing, we have nothing left to do
VideoHandle handle = _video->findVideoHandleRiven(1);
- if (handle == NULL_VID_HANDLE || _video->endOfVideo(handle))
+ if (!handle || handle->endOfVideo())
return;
sunners = 1;
diff --git a/engines/mohawk/riven_external.cpp b/engines/mohawk/riven_external.cpp
index cda0683028..7ca41e253c 100644
--- a/engines/mohawk/riven_external.cpp
+++ b/engines/mohawk/riven_external.cpp
@@ -229,7 +229,7 @@ void RivenExternal::runCredits(uint16 video, uint32 delay) {
VideoHandle videoHandle = _vm->_video->findVideoHandleRiven(video);
while (!_vm->shouldQuit() && _vm->_gfx->getCurCreditsImage() <= 320) {
- if (_vm->_video->getCurFrame(videoHandle) >= (int32)_vm->_video->getFrameCount(videoHandle) - 1) {
+ if (videoHandle->getCurFrame() >= (int32)videoHandle->getFrameCount() - 1) {
if (nextCreditsFrameStart == 0) {
// Set us up to start after delay ms
nextCreditsFrameStart = _vm->_system->getMillis() + delay;
@@ -265,10 +265,10 @@ void RivenExternal::runDomeCheck() {
// Check if we clicked while the golden frame was showing
VideoHandle video = _vm->_video->findVideoHandleRiven(1);
- assert(video != NULL_VID_HANDLE);
+ assert(video);
- int32 curFrame = _vm->_video->getCurFrame(video);
- int32 frameCount = _vm->_video->getFrameCount(video);
+ int32 curFrame = video->getCurFrame();
+ int32 frameCount = video->getFrameCount();
// The final frame of the video is the 'golden' frame (double meaning: the
// frame that is the magic one is the one with the golden symbol) but we
@@ -857,8 +857,12 @@ void RivenExternal::xbupdateboiler(uint16 argc, uint16 *argv) {
_vm->_video->playMovieRiven(7);
}
} else {
- _vm->_video->disableMovieRiven(7);
- _vm->_video->disableMovieRiven(8);
+ VideoHandle handle = _vm->_video->findVideoHandleRiven(7);
+ if (handle)
+ handle->setEnabled(false);
+ handle = _vm->_video->findVideoHandleRiven(8);
+ if (handle)
+ handle->setEnabled(false);
}
}
@@ -1149,8 +1153,8 @@ void RivenExternal::lowerPins() {
// Play the video of the pins going down
VideoHandle handle = _vm->_video->playMovieRiven(upMovie);
- assert(handle != NULL_VID_HANDLE);
- _vm->_video->setVideoBounds(handle, Audio::Timestamp(0, startTime, 600), Audio::Timestamp(0, startTime + 550, 600));
+ assert(handle);
+ handle->setBounds(Audio::Timestamp(0, startTime, 600), Audio::Timestamp(0, startTime + 550, 600));
_vm->_video->waitUntilMovieEnds(handle);
upMovie = 0;
@@ -1181,8 +1185,8 @@ void RivenExternal::xgrotatepins(uint16 argc, uint16 *argv) {
// Play the video of the pins rotating
VideoHandle handle = _vm->_video->playMovieRiven(_vm->_vars["gupmoov"]);
- assert(handle != NULL_VID_HANDLE);
- _vm->_video->setVideoBounds(handle, Audio::Timestamp(0, startTime, 600), Audio::Timestamp(0, startTime + 1215, 600));
+ assert(handle);
+ handle->setBounds(Audio::Timestamp(0, startTime, 600), Audio::Timestamp(0, startTime + 1215, 600));
_vm->_video->waitUntilMovieEnds(handle);
}
@@ -1265,9 +1269,9 @@ void RivenExternal::xgpincontrols(uint16 argc, uint16 *argv) {
// Actually play the movie
VideoHandle handle = _vm->_video->playMovieRiven(pinMovieCodes[imagePos - 1]);
- assert(handle != NULL_VID_HANDLE);
+ assert(handle);
uint32 startTime = 9630 - pinPos * 600;
- _vm->_video->setVideoBounds(handle, Audio::Timestamp(0, startTime, 600), Audio::Timestamp(0, startTime + 550, 600));
+ handle->setBounds(Audio::Timestamp(0, startTime, 600), Audio::Timestamp(0, startTime + 550, 600));
_vm->_video->waitUntilMovieEnds(handle);
// Update the relevant variables
@@ -1343,8 +1347,8 @@ void RivenExternal::xgrviewer(uint16 argc, uint16 *argv) {
// Now play the movie
VideoHandle handle = _vm->_video->playMovieRiven(1);
- assert(handle != NULL_VID_HANDLE);
- _vm->_video->setVideoBounds(handle, Audio::Timestamp(0, s_viewerTimeIntervals[curPos], 600), Audio::Timestamp(0, s_viewerTimeIntervals[newPos], 600));
+ assert(handle);
+ handle->setBounds(Audio::Timestamp(0, s_viewerTimeIntervals[curPos], 600), Audio::Timestamp(0, s_viewerTimeIntervals[newPos], 600));
_vm->_video->waitUntilMovieEnds(handle);
// Set the new position and let the card's scripts take over again
@@ -1412,8 +1416,8 @@ void RivenExternal::xglviewer(uint16 argc, uint16 *argv) {
// Now play the movie
VideoHandle handle = _vm->_video->playMovieRiven(1);
- assert(handle != NULL_VID_HANDLE);
- _vm->_video->setVideoBounds(handle, Audio::Timestamp(0, s_viewerTimeIntervals[curPos], 600), Audio::Timestamp(0, s_viewerTimeIntervals[newPos], 600));
+ assert(handle);
+ handle->setBounds(Audio::Timestamp(0, s_viewerTimeIntervals[curPos], 600), Audio::Timestamp(0, s_viewerTimeIntervals[newPos], 600));
_vm->_video->waitUntilMovieEnds(handle);
// Set the new position to the variable
@@ -1467,7 +1471,7 @@ static void catherineViewerIdleTimer(MohawkEngine_Riven *vm) {
VideoHandle videoHandle = vm->_video->playMovieRiven(30);
// Reset the timer
- vm->installTimer(&catherineViewerIdleTimer, vm->_video->getDuration(videoHandle).msecs() + vm->_rnd->getRandomNumber(60) * 1000);
+ vm->installTimer(&catherineViewerIdleTimer, videoHandle->getDuration().msecs() + vm->_rnd->getRandomNumber(60) * 1000);
}
void RivenExternal::xglview_prisonon(uint16 argc, uint16 *argv) {
@@ -1507,7 +1511,7 @@ void RivenExternal::xglview_prisonon(uint16 argc, uint16 *argv) {
_vm->_video->activateMLST(cathMovie, _vm->getCurCard());
VideoHandle videoHandle = _vm->_video->playMovieRiven(30);
- timeUntilNextMovie = _vm->_video->getDuration(videoHandle).msecs() + _vm->_rnd->getRandomNumber(60) * 1000;
+ timeUntilNextMovie = videoHandle->getDuration().msecs() + _vm->_rnd->getRandomNumber(60) * 1000;
} else {
// Otherwise, just redraw the imager
timeUntilNextMovie = _vm->_rnd->getRandomNumberRng(10, 20) * 1000;
@@ -1986,7 +1990,7 @@ void RivenExternal::xschool280_playwhark(uint16 argc, uint16 *argv) {
Audio::Timestamp startTime = Audio::Timestamp(0, (11560 / 19) * (*posVar), 600);
*posVar += number; // Adjust to the end
Audio::Timestamp endTime = Audio::Timestamp(0, (11560 / 19) * (*posVar), 600);
- _vm->_video->setVideoBounds(handle, startTime, endTime);
+ handle->setBounds(startTime, endTime);
_vm->_video->waitUntilMovieEnds(handle);
if (*posVar > 19) {
@@ -2059,7 +2063,7 @@ void RivenExternal::xbookclick(uint16 argc, uint16 *argv) {
debug(0, "\tHotspot = %d -> %d", argv[3], hotspotMap[argv[3] - 1]);
// Just let the video play while we wait until Gehn opens the trap book for us
- while (_vm->_video->getTime(video) < startTime && !_vm->shouldQuit()) {
+ while (video->getTime() < startTime && !_vm->shouldQuit()) {
if (_vm->_video->updateMovies())
_vm->_system->updateScreen();
@@ -2084,7 +2088,7 @@ void RivenExternal::xbookclick(uint16 argc, uint16 *argv) {
// OK, Gehn has opened the trap book and has asked us to go in. Let's watch
// and see what the player will do...
- while (_vm->_video->getTime(video) < endTime && !_vm->shouldQuit()) {
+ while (video->getTime() < endTime && !_vm->shouldQuit()) {
bool updateScreen = _vm->_video->updateMovies();
Common::Event event;
@@ -2335,7 +2339,7 @@ static void rebelPrisonWindowTimer(MohawkEngine_Riven *vm) {
VideoHandle handle = vm->_video->playMovieRiven(movie);
// Ensure the next video starts after this one ends
- uint32 timeUntilNextVideo = vm->_video->getDuration(handle).msecs() + vm->_rnd->getRandomNumberRng(38, 58) * 1000;
+ uint32 timeUntilNextVideo = handle->getDuration().msecs() + vm->_rnd->getRandomNumberRng(38, 58) * 1000;
// Save the time in case we leave the card and return
vm->_vars["rvillagetime"] = timeUntilNextVideo + vm->getTotalPlayTime();
@@ -2434,7 +2438,7 @@ void RivenExternal::xtexterior300_telescopedown(uint16 argc, uint16 *argv) {
static const uint32 timeIntervals[] = { 4320, 3440, 2560, 1760, 880, 0 };
uint16 movieCode = telescopeCover ? 1 : 2;
VideoHandle handle = _vm->_video->playMovieRiven(movieCode);
- _vm->_video->setVideoBounds(handle, Audio::Timestamp(0, timeIntervals[telescopePos], 600), Audio::Timestamp(0, timeIntervals[telescopePos - 1], 600));
+ handle->setBounds(Audio::Timestamp(0, timeIntervals[telescopePos], 600), Audio::Timestamp(0, timeIntervals[telescopePos - 1], 600));
_vm->_sound->playSound(14); // Play the moving sound
_vm->_video->waitUntilMovieEnds(handle);
@@ -2467,7 +2471,7 @@ void RivenExternal::xtexterior300_telescopeup(uint16 argc, uint16 *argv) {
static const uint32 timeIntervals[] = { 0, 800, 1680, 2560, 3440, 4320 };
uint16 movieCode = _vm->_vars["ttelecover"] ? 4 : 5;
VideoHandle handle = _vm->_video->playMovieRiven(movieCode);
- _vm->_video->setVideoBounds(handle, Audio::Timestamp(0, timeIntervals[telescopePos - 1], 600), Audio::Timestamp(0, timeIntervals[telescopePos], 600));
+ handle->setBounds(Audio::Timestamp(0, timeIntervals[telescopePos - 1], 600), Audio::Timestamp(0, timeIntervals[telescopePos], 600));
_vm->_sound->playSound(14); // Play the moving sound
_vm->_video->waitUntilMovieEnds(handle);
@@ -2569,26 +2573,47 @@ void RivenExternal::xt7500_checkmarbles(uint16 argc, uint16 *argv) {
void RivenExternal::xt7600_setupmarbles(uint16 argc, uint16 *argv) {
// Draw the small marbles when we're a step away from the waffle
- uint16 baseBitmapId = _vm->findResourceID(ID_TBMP, "*tsmallred");
+
+ // Convert from marble X coordinate to screen X coordinate
+ static const uint16 xPosOffsets[] = {
+ 246, 245, 244, 243, 243, 241, 240, 240, 239, 238, 237, 237, 236, 235, 234, 233, 232, 231, 230, 229, 228, 227, 226, 226, 225
+ };
+
+ // Convert from marble Y coordinate to screen Y coordinate
+ static const uint16 yPosOffsets[] = {
+ 261, 263, 265, 267, 268, 270, 272, 274, 276, 278, 281, 284, 285, 288, 290, 293, 295, 298, 300, 303, 306, 309, 311, 314, 316
+ };
+
+ // Handle spacing for y coordinates due to the angle
+ static const double yAdjusts[] = {
+ 4.56, 4.68, 4.76, 4.84, 4.84, 4.96, 5.04, 5.04, 5.12, 5.2, 5.28, 5.28, 5.36, 5.44, 5.4, 5.6, 5.72, 5.8, 5.88, 5.96, 6.04, 6.12, 6.2, 6.2, 6.28
+ };
+
+ // Waffle state of 0 is up, 1 down
bool waffleDown = _vm->_vars["twaffle"] != 0;
// Note that each of the small marble images is exactly 4x2
+ // The original seems to scale the marble images from extras.mhk, but
+ // we're using the pre-scaled images in the stack.
+ uint16 baseBitmapId = _vm->findResourceID(ID_TBMP, "*tsmallred");
for (uint16 i = 0; i < kMarbleCount; i++) {
- uint32 &var = _vm->_vars[s_marbleNames[i]];
+ uint32 var = _vm->_vars[s_marbleNames[i]];
if (var == 0) {
// The marble is still in its initial place
// (Note that this is still drawn even if the waffle is down)
- int marbleX = 376 + i * 2;
- int marbleY = 253 + i * 4;
- _vm->_gfx->copyImageToScreen(baseBitmapId + i, marbleX, marbleY, marbleX + kSmallMarbleWidth, marbleY + kSmallMarbleHeight);
+ static const uint16 defaultX[] = { 375, 377, 379, 381, 383, 385 };
+ static const uint16 defaultY[] = { 253, 257, 261, 265, 268, 273 };
+ _vm->_gfx->copyImageToScreen(baseBitmapId + i, defaultX[i], defaultY[i], defaultX[i] + kSmallMarbleWidth, defaultY[i] + kSmallMarbleHeight);
} else if (waffleDown) {
// The marble is on the grid and the waffle is down
// (Nothing to draw here)
} else {
// The marble is on the grid and the waffle is up
- // TODO: Draw them onto the grid
+ int marbleX = (int)round(getMarbleX(var) * yAdjusts[getMarbleY(var)] + xPosOffsets[getMarbleY(var)]);
+ int marbleY = yPosOffsets[getMarbleY(var)];
+ _vm->_gfx->copyImageToScreen(baseBitmapId + i, marbleX, marbleY, marbleX + kSmallMarbleWidth, marbleY + kSmallMarbleHeight);
}
}
}
diff --git a/engines/mohawk/riven_scripts.cpp b/engines/mohawk/riven_scripts.cpp
index 29ee5cd50b..caa235ec8b 100644
--- a/engines/mohawk/riven_scripts.cpp
+++ b/engines/mohawk/riven_scripts.cpp
@@ -493,7 +493,9 @@ void RivenScript::changeStack(uint16 op, uint16 argc, uint16 *argv) {
// Command 28: disable a movie
void RivenScript::disableMovie(uint16 op, uint16 argc, uint16 *argv) {
- _vm->_video->disableMovieRiven(argv[0]);
+ VideoHandle handle = _vm->_video->findVideoHandleRiven(argv[0]);
+ if (handle)
+ handle->setEnabled(false);
}
// Command 29: disable all movies
@@ -503,7 +505,9 @@ void RivenScript::disableAllMovies(uint16 op, uint16 argc, uint16 *argv) {
// Command 31: enable a movie
void RivenScript::enableMovie(uint16 op, uint16 argc, uint16 *argv) {
- _vm->_video->enableMovieRiven(argv[0]);
+ VideoHandle handle = _vm->_video->findVideoHandleRiven(argv[0]);
+ if (handle)
+ handle->setEnabled(true);
}
// Command 32: play foreground movie - blocking (movie_id)
diff --git a/engines/mohawk/video.cpp b/engines/mohawk/video.cpp
index cebb72e24f..ff4a69cd28 100644
--- a/engines/mohawk/video.cpp
+++ b/engines/mohawk/video.cpp
@@ -24,6 +24,7 @@
#include "mohawk/resource.h"
#include "mohawk/video.h"
+#include "common/algorithm.h"
#include "common/debug.h"
#include "common/events.h"
#include "common/textconsole.h"
@@ -37,22 +38,115 @@
namespace Mohawk {
-void VideoEntry::clear() {
- video = 0;
- x = 0;
- y = 0;
- loop = false;
- enabled = false;
- start = Audio::Timestamp(0, 1);
- filename.clear();
- id = -1;
+VideoEntry::VideoEntry() : _video(0), _id(-1), _x(0), _y(0), _loop(false), _enabled(true) {
}
-bool VideoEntry::endOfVideo() {
- return !video || video->endOfVideo();
+VideoEntry::VideoEntry(Video::VideoDecoder *video, const Common::String &fileName) : _video(video), _fileName(fileName), _id(-1), _x(0), _y(0), _loop(false), _enabled(true) {
+}
+
+VideoEntry::VideoEntry(Video::VideoDecoder *video, int id) : _video(video), _id(id), _x(0), _y(0), _loop(false), _enabled(true) {
+}
+
+VideoEntry::~VideoEntry() {
+ close();
+}
+
+void VideoEntry::close() {
+ delete _video;
+ _video = 0;
+}
+
+bool VideoEntry::endOfVideo() const {
+ return !isOpen() || _video->endOfVideo();
+}
+
+int VideoEntry::getCurFrame() const {
+ assert(_video);
+ return _video->getCurFrame();
+}
+
+uint32 VideoEntry::getFrameCount() const {
+ assert(_video);
+ return _video->getFrameCount();
+}
+
+uint32 VideoEntry::getTime() const {
+ assert(_video);
+ return _video->getTime();
+}
+
+Audio::Timestamp VideoEntry::getDuration() const {
+ assert(_video);
+ return _video->getDuration();
+}
+
+Common::Rational VideoEntry::getRate() const {
+ assert(_video);
+ return _video->getRate();
+}
+
+void VideoEntry::center() {
+ assert(_video);
+ _x = (g_system->getWidth() - _video->getWidth()) / 2;
+ _y = (g_system->getHeight() - _video->getHeight()) / 2;
+}
+
+void VideoEntry::setBounds(const Audio::Timestamp &startTime, const Audio::Timestamp &endTime) {
+ assert(_video);
+ _start = startTime;
+ _video->setEndTime(endTime);
+ _video->seek(startTime);
+}
+
+void VideoEntry::seek(const Audio::Timestamp &time) {
+ assert(_video);
+ _video->seek(time);
+}
+
+void VideoEntry::setRate(const Common::Rational &rate) {
+ assert(_video);
+ _video->setRate(rate);
+}
+
+void VideoEntry::pause(bool isPaused) {
+ assert(_video);
+ _video->pauseVideo(isPaused);
+}
+
+void VideoEntry::start() {
+ assert(_video);
+ _video->start();
+}
+
+void VideoEntry::stop() {
+ assert(_video);
+ _video->stop();
+}
+
+bool VideoEntry::isPlaying() const {
+ assert(_video);
+ return _video->isPlaying();
+}
+
+int VideoEntry::getVolume() const {
+ assert(_video);
+ return _video->getVolume();
+}
+
+void VideoEntry::setVolume(int volume) {
+ assert(_video);
+ _video->setVolume(CLIP(volume, 0, 255));
+}
+
+VideoHandle::VideoHandle(VideoEntryPtr ptr) : _ptr(ptr) {
+}
+
+VideoHandle::VideoHandle(const VideoHandle &handle) : _ptr(handle._ptr) {
}
VideoManager::VideoManager(MohawkEngine* vm) : _vm(vm) {
+ // Set dithering enabled, if required
+ _enableDither = _vm->getGameType() == GType_MYST && !(_vm->getFeatures() & GF_ME);
}
VideoManager::~VideoManager() {
@@ -60,41 +154,42 @@ VideoManager::~VideoManager() {
}
void VideoManager::pauseVideos() {
- for (uint16 i = 0; i < _videoStreams.size(); i++)
- if (_videoStreams[i].video)
- _videoStreams[i]->pauseVideo(true);
+ for (VideoList::iterator it = _videos.begin(); it != _videos.end(); it++)
+ (*it)->pause(true);
}
void VideoManager::resumeVideos() {
- for (uint16 i = 0; i < _videoStreams.size(); i++)
- if (_videoStreams[i].video)
- _videoStreams[i]->pauseVideo(false);
+ for (VideoList::iterator it = _videos.begin(); it != _videos.end(); it++)
+ (*it)->pause(false);
}
void VideoManager::stopVideos() {
- for (uint16 i = 0; i < _videoStreams.size(); i++)
- delete _videoStreams[i].video;
+ for (VideoList::iterator it = _videos.begin(); it != _videos.end(); it++)
+ (*it)->close();
- _videoStreams.clear();
+ _videos.clear();
}
-void VideoManager::playMovieBlocking(const Common::String &filename, uint16 x, uint16 y, bool clearScreen) {
- VideoHandle videoHandle = createVideoHandle(filename, x, y, false);
- if (videoHandle == NULL_VID_HANDLE)
+void VideoManager::playMovieBlocking(const Common::String &fileName, uint16 x, uint16 y, bool clearScreen) {
+ VideoEntryPtr ptr = open(fileName);
+ if (!ptr)
return;
+ ptr->moveTo(x, y);
+
// Clear screen if requested
if (clearScreen) {
_vm->_system->fillScreen(_vm->_system->getScreenFormat().RGBToColor(0, 0, 0));
_vm->_system->updateScreen();
}
- waitUntilMovieEnds(videoHandle);
+ ptr->start();
+ waitUntilMovieEnds(ptr);
}
-void VideoManager::playMovieBlockingCentered(const Common::String &filename, bool clearScreen) {
- VideoHandle videoHandle = createVideoHandle(filename, 0, 0, false);
- if (videoHandle == NULL_VID_HANDLE)
+void VideoManager::playMovieBlockingCentered(const Common::String &fileName, bool clearScreen) {
+ VideoEntryPtr ptr = open(fileName);
+ if (!ptr)
return;
// Clear screen if requested
@@ -103,19 +198,22 @@ void VideoManager::playMovieBlockingCentered(const Common::String &filename, boo
_vm->_system->updateScreen();
}
- _videoStreams[videoHandle].x = (_vm->_system->getWidth() - _videoStreams[videoHandle]->getWidth()) / 2;
- _videoStreams[videoHandle].y = (_vm->_system->getHeight() - _videoStreams[videoHandle]->getHeight()) / 2;
-
- waitUntilMovieEnds(videoHandle);
+ ptr->center();
+ ptr->start();
+ waitUntilMovieEnds(ptr);
}
void VideoManager::waitUntilMovieEnds(VideoHandle videoHandle) {
- if (videoHandle == NULL_VID_HANDLE)
+ if (!videoHandle)
return;
+ // Sanity check
+ if (videoHandle._ptr->isLooping())
+ error("Called waitUntilMovieEnds() on a looping video");
+
bool continuePlaying = true;
- while (!_videoStreams[videoHandle].endOfVideo() && !_vm->shouldQuit() && continuePlaying) {
+ while (!videoHandle->endOfVideo() && !_vm->shouldQuit() && continuePlaying) {
if (updateMovies())
_vm->_system->updateScreen();
@@ -147,12 +245,22 @@ void VideoManager::waitUntilMovieEnds(VideoHandle videoHandle) {
_vm->_system->delayMillis(10);
}
- delete _videoStreams[videoHandle].video;
- _videoStreams[videoHandle].clear();
+ // Ensure it's removed
+ removeEntry(videoHandle._ptr);
}
void VideoManager::delayUntilMovieEnds(VideoHandle videoHandle) {
- while (!_videoStreams[videoHandle].endOfVideo() && !_vm->shouldQuit()) {
+ // FIXME: Why is this separate from waitUntilMovieEnds?
+ // It seems to only cut out the event loop (which is bad).
+
+ if (!videoHandle)
+ return;
+
+ // Sanity check
+ if (videoHandle._ptr->isLooping())
+ error("Called delayUntilMovieEnds() on a looping video");
+
+ while (!videoHandle->endOfVideo() && !_vm->shouldQuit()) {
if (updateMovies())
_vm->_system->updateScreen();
@@ -160,92 +268,85 @@ void VideoManager::delayUntilMovieEnds(VideoHandle videoHandle) {
_vm->_system->delayMillis(10);
}
- delete _videoStreams[videoHandle].video;
- _videoStreams[videoHandle].clear();
+ // Ensure it's removed
+ removeEntry(videoHandle._ptr);
}
-VideoHandle VideoManager::playMovie(const Common::String &filename, int16 x, int16 y, bool loop) {
- VideoHandle videoHandle = createVideoHandle(filename, x, y, loop);
- if (videoHandle == NULL_VID_HANDLE)
- return NULL_VID_HANDLE;
-
- // Center x if requested
- if (x < 0)
- _videoStreams[videoHandle].x = (_vm->_system->getWidth() - _videoStreams[videoHandle]->getWidth()) / 2;
+VideoHandle VideoManager::playMovie(const Common::String &fileName) {
+ VideoEntryPtr ptr = open(fileName);
+ if (!ptr)
+ return VideoHandle();
- // Center y if requested
- if (y < 0)
- _videoStreams[videoHandle].y = (_vm->_system->getHeight() - _videoStreams[videoHandle]->getHeight()) / 2;
-
- return videoHandle;
+ ptr->start();
+ return ptr;
}
-VideoHandle VideoManager::playMovie(uint16 id, int16 x, int16 y, bool loop) {
- VideoHandle videoHandle = createVideoHandle(id, x, y, loop);
- if (videoHandle == NULL_VID_HANDLE)
- return NULL_VID_HANDLE;
-
- // Center x if requested
- if (x < 0)
- _videoStreams[videoHandle].x = (_vm->_system->getWidth() - _videoStreams[videoHandle]->getWidth()) / 2;
+VideoHandle VideoManager::playMovie(uint16 id) {
+ VideoEntryPtr ptr = open(id);
+ if (!ptr)
+ return VideoHandle();
- // Center y if requested
- if (y < 0)
- _videoStreams[videoHandle].y = (_vm->_system->getHeight() - _videoStreams[videoHandle]->getHeight()) / 2;
-
- return videoHandle;
+ ptr->start();
+ return ptr;
}
bool VideoManager::updateMovies() {
bool updateScreen = false;
- for (uint32 i = 0; i < _videoStreams.size() && !_vm->shouldQuit(); i++) {
- // Skip deleted videos
- if (!_videoStreams[i].video)
- continue;
-
- // Remove any videos that are over
- if (_videoStreams[i].endOfVideo()) {
- if (_videoStreams[i].loop) {
- _videoStreams[i]->seek(_videoStreams[i].start);
+ for (VideoList::iterator it = _videos.begin(); it != _videos.end(); ) {
+ // Check of the video has reached the end
+ if ((*it)->endOfVideo()) {
+ if ((*it)->isLooping()) {
+ // Seek back if looping
+ (*it)->seek((*it)->getStart());
} else {
- // Check the video time one last time before deleting it
- _vm->doVideoTimer(i, true);
- delete _videoStreams[i].video;
- _videoStreams[i].clear();
+ // Done; close and continue on
+ (*it)->close();
+ it = _videos.erase(it);
continue;
}
}
- // Nothing more to do if we're paused
- if (_videoStreams[i]->isPaused())
+ Video::VideoDecoder *video = (*it)->_video;
+
+ // Ignore paused videos
+ if (video->isPaused()) {
+ it++;
continue;
+ }
// Check if we need to draw a frame
- if (_videoStreams[i]->needsUpdate()) {
- const Graphics::Surface *frame = _videoStreams[i]->decodeNextFrame();
+ if (video->needsUpdate()) {
+ const Graphics::Surface *frame = video->decodeNextFrame();
Graphics::Surface *convertedFrame = 0;
- if (frame && _videoStreams[i].enabled) {
+ if (frame && (*it)->isEnabled()) {
Graphics::PixelFormat pixelFormat = _vm->_system->getScreenFormat();
if (frame->format != pixelFormat) {
- // We don't support downconverting to 8bpp
- if (pixelFormat.bytesPerPixel == 1)
- error("Cannot convert high color video frame to 8bpp");
+ // We don't support downconverting to 8bpp without having
+ // support in the codec. Set _enableDither if shows up.
+ if (pixelFormat.bytesPerPixel == 1) {
+ warning("Cannot convert high color video frame to 8bpp");
+ (*it)->close();
+ it = _videos.erase(it);
+ continue;
+ }
// Convert to the current screen format
- convertedFrame = frame->convertTo(pixelFormat, _videoStreams[i]->getPalette());
+ convertedFrame = frame->convertTo(pixelFormat, video->getPalette());
frame = convertedFrame;
- } else if (pixelFormat.bytesPerPixel == 1 && _videoStreams[i]->hasDirtyPalette()) {
+ } else if (pixelFormat.bytesPerPixel == 1 && video->hasDirtyPalette()) {
// Set the palette when running in 8bpp mode only
- _vm->_system->getPaletteManager()->setPalette(_videoStreams[i]->getPalette(), 0, 256);
+ // Don't do this for Myst, which has its own per-stack handling
+ if (_vm->getGameType() != GType_MYST)
+ _vm->_system->getPaletteManager()->setPalette(video->getPalette(), 0, 256);
}
// Clip the width/height to make sure we stay on the screen (Myst does this a few times)
- uint16 width = MIN<int32>(_videoStreams[i]->getWidth(), _vm->_system->getWidth() - _videoStreams[i].x);
- uint16 height = MIN<int32>(_videoStreams[i]->getHeight(), _vm->_system->getHeight() - _videoStreams[i].y);
- _vm->_system->copyRectToScreen(frame->getPixels(), frame->pitch, _videoStreams[i].x, _videoStreams[i].y, width, height);
+ uint16 width = MIN<int32>(video->getWidth(), _vm->_system->getWidth() - (*it)->getX());
+ uint16 height = MIN<int32>(video->getHeight(), _vm->_system->getHeight() - (*it)->getY());
+ _vm->_system->copyRectToScreen(frame->getPixels(), frame->pitch, (*it)->getX(), (*it)->getY(), width, height);
// We've drawn something to the screen, make sure we update it
updateScreen = true;
@@ -259,7 +360,10 @@ bool VideoManager::updateMovies() {
}
// Check the video time
- _vm->doVideoTimer(i, false);
+ _vm->doVideoTimer(*it, false);
+
+ // Remember to increase the iterator
+ it++;
}
// Return true if we need to update the screen
@@ -314,241 +418,180 @@ void VideoManager::clearMLST() {
}
VideoHandle VideoManager::playMovieRiven(uint16 id) {
- for (uint16 i = 0; i < _mlstRecords.size(); i++)
+ for (uint16 i = 0; i < _mlstRecords.size(); i++) {
if (_mlstRecords[i].code == id) {
debug(1, "Play tMOV %d (non-blocking) at (%d, %d) %s, Volume = %d", _mlstRecords[i].movieID, _mlstRecords[i].left, _mlstRecords[i].top, _mlstRecords[i].loop != 0 ? "looping" : "non-looping", _mlstRecords[i].volume);
- return createVideoHandle(_mlstRecords[i].movieID, _mlstRecords[i].left, _mlstRecords[i].top, _mlstRecords[i].loop != 0, _mlstRecords[i].volume);
+
+ VideoEntryPtr ptr = open(_mlstRecords[i].movieID);
+ if (ptr) {
+ ptr->moveTo(_mlstRecords[i].left, _mlstRecords[i].top);
+ ptr->setLooping(_mlstRecords[i].loop != 0);
+ ptr->setVolume(_mlstRecords[i].volume);
+ ptr->start();
+ }
+
+ return ptr;
}
+ }
- return NULL_VID_HANDLE;
+ return VideoHandle();
}
void VideoManager::playMovieBlockingRiven(uint16 id) {
- for (uint16 i = 0; i < _mlstRecords.size(); i++)
+ for (uint16 i = 0; i < _mlstRecords.size(); i++) {
if (_mlstRecords[i].code == id) {
debug(1, "Play tMOV %d (blocking) at (%d, %d), Volume = %d", _mlstRecords[i].movieID, _mlstRecords[i].left, _mlstRecords[i].top, _mlstRecords[i].volume);
- VideoHandle videoHandle = createVideoHandle(_mlstRecords[i].movieID, _mlstRecords[i].left, _mlstRecords[i].top, false);
- waitUntilMovieEnds(videoHandle);
+ VideoEntryPtr ptr = open(_mlstRecords[i].movieID);
+ ptr->moveTo(_mlstRecords[i].left, _mlstRecords[i].top);
+ ptr->setVolume(_mlstRecords[i].volume);
+ ptr->start();
+ waitUntilMovieEnds(ptr);
return;
}
+ }
}
void VideoManager::stopMovieRiven(uint16 id) {
debug(2, "Stopping movie %d", id);
- for (uint16 i = 0; i < _mlstRecords.size(); i++)
- if (_mlstRecords[i].code == id)
- for (uint16 j = 0; j < _videoStreams.size(); j++)
- if (_mlstRecords[i].movieID == _videoStreams[j].id) {
- delete _videoStreams[j].video;
- _videoStreams[j].clear();
- return;
- }
-}
-
-void VideoManager::enableMovieRiven(uint16 id) {
- debug(2, "Enabling movie %d", id);
- for (uint16 i = 0; i < _mlstRecords.size(); i++)
- if (_mlstRecords[i].code == id)
- for (uint16 j = 0; j < _videoStreams.size(); j++)
- if (_mlstRecords[i].movieID == _videoStreams[j].id) {
- _videoStreams[j].enabled = true;
- return;
- }
-}
-
-void VideoManager::disableMovieRiven(uint16 id) {
- debug(2, "Disabling movie %d", id);
- for (uint16 i = 0; i < _mlstRecords.size(); i++)
- if (_mlstRecords[i].code == id)
- for (uint16 j = 0; j < _videoStreams.size(); j++)
- if (_mlstRecords[i].movieID == _videoStreams[j].id) {
- _videoStreams[j].enabled = false;
- return;
- }
+ VideoHandle handle = findVideoHandleRiven(id);
+ if (handle)
+ removeEntry(handle._ptr);
}
void VideoManager::disableAllMovies() {
debug(2, "Disabling all movies");
- for (uint16 i = 0; i < _videoStreams.size(); i++)
- _videoStreams[i].enabled = false;
+ for (VideoList::iterator it = _videos.begin(); it != _videos.end(); it++)
+ (*it)->setEnabled(false);
}
-VideoHandle VideoManager::createVideoHandle(uint16 id, uint16 x, uint16 y, bool loop, uint16 volume) {
- // First, check to see if that video is already playing
- for (uint32 i = 0; i < _videoStreams.size(); i++)
- if (_videoStreams[i].id == id)
- return i;
+VideoEntryPtr VideoManager::open(uint16 id) {
+ // If this video is already playing, return that handle
+ VideoHandle oldHandle = findVideoHandle(id);
+ if (oldHandle._ptr)
+ return oldHandle._ptr;
// Otherwise, create a new entry
- Video::QuickTimeDecoder *decoder = new Video::QuickTimeDecoder();
- decoder->setChunkBeginOffset(_vm->getResourceOffset(ID_TMOV, id));
- decoder->loadStream(_vm->getResource(ID_TMOV, id));
- decoder->setVolume((volume >= 256) ? 255 : volume);
-
- VideoEntry entry;
- entry.clear();
- entry.video = decoder;
- entry.x = x;
- entry.y = y;
- entry.id = id;
- entry.loop = loop;
- entry.enabled = true;
-
- entry->start();
-
- // Search for any deleted videos so we can take a formerly used slot
- for (uint32 i = 0; i < _videoStreams.size(); i++)
- if (!_videoStreams[i].video) {
- _videoStreams[i] = entry;
- return i;
- }
+ Video::QuickTimeDecoder *video = new Video::QuickTimeDecoder();
+ video->setChunkBeginOffset(_vm->getResourceOffset(ID_TMOV, id));
+ video->loadStream(_vm->getResource(ID_TMOV, id));
+
+ // Create the entry
+ VideoEntryPtr entry(new VideoEntry(video, id));
+
+ // Enable dither if necessary
+ checkEnableDither(entry);
+
+ // Add it to the video list
+ _videos.push_back(entry);
- // Otherwise, just add it to the list
- _videoStreams.push_back(entry);
- return _videoStreams.size() - 1;
+ return entry;
}
-VideoHandle VideoManager::createVideoHandle(const Common::String &filename, uint16 x, uint16 y, bool loop, byte volume) {
- // First, check to see if that video is already playing
- for (uint32 i = 0; i < _videoStreams.size(); i++)
- if (_videoStreams[i].filename == filename)
- return i;
+VideoEntryPtr VideoManager::open(const Common::String &fileName) {
+ // If this video is already playing, return that entry
+ VideoHandle oldHandle = findVideoHandle(fileName);
+ if (oldHandle._ptr)
+ return oldHandle._ptr;
// Otherwise, create a new entry
- VideoEntry entry;
- entry.clear();
- entry.video = new Video::QuickTimeDecoder();
- entry.x = x;
- entry.y = y;
- entry.filename = filename;
- entry.loop = loop;
- entry.enabled = true;
-
- Common::File *file = new Common::File();
- if (!file->open(filename)) {
- delete file;
- return NULL_VID_HANDLE;
+ Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(fileName);
+ if (!stream)
+ return VideoEntryPtr();
+
+ Video::VideoDecoder *video = new Video::QuickTimeDecoder();
+ if (!video->loadStream(stream)) {
+ // FIXME: Better error handling
+ delete video;
+ return VideoEntryPtr();
}
- entry->loadStream(file);
- entry->setVolume(volume);
- entry->start();
+ // Create the entry
+ VideoEntryPtr entry(new VideoEntry(video, fileName));
- // Search for any deleted videos so we can take a formerly used slot
- for (uint32 i = 0; i < _videoStreams.size(); i++)
- if (!_videoStreams[i].video) {
- _videoStreams[i] = entry;
- return i;
- }
+ // Enable dither if necessary
+ checkEnableDither(entry);
+
+ // Add it to the video list
+ _videos.push_back(entry);
- // Otherwise, just add it to the list
- _videoStreams.push_back(entry);
- return _videoStreams.size() - 1;
+ return entry;
}
VideoHandle VideoManager::findVideoHandleRiven(uint16 id) {
for (uint16 i = 0; i < _mlstRecords.size(); i++)
if (_mlstRecords[i].code == id)
- for (uint32 j = 0; j < _videoStreams.size(); j++)
- if (_videoStreams[j].video && _mlstRecords[i].movieID == _videoStreams[j].id)
- return j;
+ for (VideoList::iterator it = _videos.begin(); it != _videos.end(); it++)
+ if ((*it)->getID() == _mlstRecords[i].movieID)
+ return *it;
- return NULL_VID_HANDLE;
+ return VideoHandle();
}
VideoHandle VideoManager::findVideoHandle(uint16 id) {
- if (!id)
- return NULL_VID_HANDLE;
+ if (id == 0)
+ return VideoHandle();
- for (uint32 i = 0; i < _videoStreams.size(); i++)
- if (_videoStreams[i].video && _videoStreams[i].id == id)
- return i;
+ for (VideoList::iterator it = _videos.begin(); it != _videos.end(); it++)
+ if ((*it)->getID() == id)
+ return *it;
- return NULL_VID_HANDLE;
+ return VideoHandle();
}
-VideoHandle VideoManager::findVideoHandle(const Common::String &filename) {
- if (filename.empty())
- return NULL_VID_HANDLE;
-
- for (uint32 i = 0; i < _videoStreams.size(); i++)
- if (_videoStreams[i].video && _videoStreams[i].filename.equalsIgnoreCase(filename))
- return i;
+VideoHandle VideoManager::findVideoHandle(const Common::String &fileName) {
+ if (fileName.empty())
+ return VideoHandle();
- return NULL_VID_HANDLE;
-}
-
-int VideoManager::getCurFrame(VideoHandle handle) {
- assert(handle != NULL_VID_HANDLE);
- return _videoStreams[handle]->getCurFrame();
-}
+ for (VideoList::iterator it = _videos.begin(); it != _videos.end(); it++)
+ if ((*it)->getFileName().equalsIgnoreCase(fileName))
+ return *it;
-uint32 VideoManager::getFrameCount(VideoHandle handle) {
- assert(handle != NULL_VID_HANDLE);
- return _videoStreams[handle]->getFrameCount();
-}
-
-uint32 VideoManager::getTime(VideoHandle handle) {
- assert(handle != NULL_VID_HANDLE);
- return _videoStreams[handle]->getTime();
-}
-
-Audio::Timestamp VideoManager::getDuration(VideoHandle handle) {
- assert(handle != NULL_VID_HANDLE);
- return _videoStreams[handle]->getDuration();
-}
-
-bool VideoManager::endOfVideo(VideoHandle handle) {
- assert(handle != NULL_VID_HANDLE);
- return _videoStreams[handle].endOfVideo();
+ return VideoHandle();
}
bool VideoManager::isVideoPlaying() {
- for (uint32 i = 0; i < _videoStreams.size(); i++)
- if (!_videoStreams[i].endOfVideo())
+ for (VideoList::iterator it = _videos.begin(); it != _videos.end(); it++)
+ if (!(*it)->endOfVideo())
return true;
return false;
}
-void VideoManager::setVideoBounds(VideoHandle handle, Audio::Timestamp start, Audio::Timestamp end) {
- assert(handle != NULL_VID_HANDLE);
- _videoStreams[handle].start = start;
- _videoStreams[handle]->setEndTime(end);
- _videoStreams[handle]->seek(start);
-}
-
-void VideoManager::drawVideoFrame(VideoHandle handle, Audio::Timestamp time) {
- assert(handle != NULL_VID_HANDLE);
- _videoStreams[handle]->seek(time);
+void VideoManager::drawVideoFrame(VideoHandle handle, const Audio::Timestamp &time) {
+ // FIXME: This should be done separately from the "playing"
+ // videos eventually.
+ assert(handle);
+ handle->seek(time);
updateMovies();
- delete _videoStreams[handle].video;
- _videoStreams[handle].clear();
+ handle->close();
}
-void VideoManager::seekToTime(VideoHandle handle, Audio::Timestamp time) {
- assert(handle != NULL_VID_HANDLE);
- _videoStreams[handle]->seek(time);
+VideoManager::VideoList::iterator VideoManager::findEntry(VideoEntryPtr ptr) {
+ return Common::find(_videos.begin(), _videos.end(), ptr);
}
-void VideoManager::setVideoLooping(VideoHandle handle, bool loop) {
- assert(handle != NULL_VID_HANDLE);
- _videoStreams[handle].loop = loop;
+void VideoManager::removeEntry(VideoEntryPtr ptr) {
+ VideoManager::VideoList::iterator it = findEntry(ptr);
+ if (it != _videos.end())
+ _videos.erase(it);
}
-Common::Rational VideoManager::getVideoRate(VideoHandle handle) const {
- assert(handle != NULL_VID_HANDLE);
- return _videoStreams[handle]->getRate();
-}
+void VideoManager::checkEnableDither(VideoEntryPtr &entry) {
+ // If we're not dithering, bail out
+ if (!_enableDither)
+ return;
-void VideoManager::setVideoRate(VideoHandle handle, const Common::Rational &rate) {
- assert(handle != NULL_VID_HANDLE);
- _videoStreams[handle]->setRate(rate);
-}
+ // Set the palette
+ byte palette[256 * 3];
+ g_system->getPaletteManager()->grabPalette(palette, 0, 256);
+ entry->_video->setDitheringPalette(palette);
-void VideoManager::pauseMovie(VideoHandle handle, bool pause) {
- assert(handle != NULL_VID_HANDLE);
- _videoStreams[handle]->pauseVideo(pause);
+ if (entry->_video->getPixelFormat().bytesPerPixel != 1) {
+ if (entry->getFileName().empty())
+ error("Failed to set dither for video tMOV %d", entry->getID());
+ else
+ error("Failed to set dither for video %s", entry->getFileName().c_str());
+ }
}
} // End of namespace Mohawk
diff --git a/engines/mohawk/video.h b/engines/mohawk/video.h
index 43181e3e6c..106a32f8e2 100644
--- a/engines/mohawk/video.h
+++ b/engines/mohawk/video.h
@@ -23,9 +23,17 @@
#ifndef MOHAWK_VIDEO_H
#define MOHAWK_VIDEO_H
+#include "audio/timestamp.h"
#include "common/array.h"
+#include "common/list.h"
+#include "common/noncopyable.h"
+#include "common/ptr.h"
+#include "common/rational.h"
#include "graphics/pixelformat.h"
-#include "video/video_decoder.h"
+
+namespace Video {
+class VideoDecoder;
+}
namespace Mohawk {
@@ -43,29 +51,254 @@ struct MLSTRecord {
uint16 u1;
};
-struct VideoEntry {
+/**
+ * A video monitored by the VideoManager
+ */
+class VideoEntry : private Common::NonCopyable {
+ // The private members should be able to be manipulated by VideoManager
+ friend class VideoManager;
+
+private:
+ // Hide the destructor/constructor
+ // Only VideoManager should be allowed
+ VideoEntry();
+ VideoEntry(Video::VideoDecoder *video, const Common::String &fileName);
+ VideoEntry(Video::VideoDecoder *video, int id);
+
+public:
+ ~VideoEntry();
+
+ /**
+ * Convenience implicit cast to bool
+ */
+ operator bool() const { return isOpen(); }
+
+ /**
+ * Is the video open?
+ */
+ bool isOpen() const { return _video != 0; }
+
+ /**
+ * Close the video
+ */
+ void close();
+
+ /**
+ * Has the video reached its end?
+ */
+ bool endOfVideo() const;
+
+ /**
+ * Get the X position of where the video is displayed
+ */
+ uint16 getX() const { return _x; }
+
+ /**
+ * Get the Y position of where the video is displayed
+ */
+ uint16 getY() const { return _y; }
+
+ /**
+ * Is the video looping?
+ */
+ bool isLooping() const { return _loop; }
+
+ /**
+ * Is the video enabled? (Drawing to the screen)
+ */
+ bool isEnabled() const { return _enabled; }
+
+ /**
+ * Get the start time of the video bounds
+ */
+ const Audio::Timestamp &getStart() const { return _start; }
+
+ /**
+ * Get the file name of the video, or empty if by ID
+ */
+ const Common::String &getFileName() const { return _fileName; }
+
+ /**
+ * Get the ID of the video, or -1 if by file name
+ */
+ int getID() const { return _id; }
+
+ /**
+ * Get the current frame of the video
+ */
+ int getCurFrame() const;
+
+ /**
+ * Get the frame count of the video
+ */
+ uint32 getFrameCount() const;
+
+ /**
+ * Get the current time position of the video
+ */
+ uint32 getTime() const;
+
+ /**
+ * Get the duration of the video
+ */
+ Audio::Timestamp getDuration() const;
+
+ /**
+ * Get the current playback rate of the videos
+ */
+ Common::Rational getRate() const;
+
+ /**
+ * Move the x position of the video
+ */
+ void setX(uint16 x) { _x = x; }
+
+ /**
+ * Move the y position of the video
+ */
+ void setY(uint16 y) { _y = y; }
+
+ /**
+ * Move the video to the specified coordinates
+ */
+ void moveTo(uint16 x, uint16 y) { setX(x); setY(y); }
+
+ /**
+ * Center the video on the screen
+ */
+ void center();
+
+ /**
+ * Set the start time when using video bounds
+ */
+ void setStart(const Audio::Timestamp &time) { _start = time; }
+
+ /**
+ * Set the video to loop (true) or not (false)
+ */
+ void setLooping(bool loop) { _loop = loop; }
+
+ /**
+ * Set the video's enabled status
+ */
+ void setEnabled(bool enabled) { _enabled = enabled; }
+
+ /**
+ * Set the bounds of the video
+ *
+ * This automatically seeks to the start time
+ */
+ void setBounds(const Audio::Timestamp &startTime, const Audio::Timestamp &endTime);
+
+ /**
+ * Seek to the given time
+ */
+ void seek(const Audio::Timestamp &time);
+
+ /**
+ * Set the playback rate
+ */
+ void setRate(const Common::Rational &rate);
+
+ /**
+ * Pause the video
+ */
+ void pause(bool isPaused);
+
+ /**
+ * Start playing the video
+ */
+ void start();
+
+ /**
+ * Stop playing the video
+ */
+ void stop();
+
+ /**
+ * Is the video playing?
+ */
+ bool isPlaying() const;
+
+ /**
+ * Get the volume of the video
+ */
+ int getVolume() const;
+
+ /**
+ * Set the volume of the video
+ */
+ void setVolume(int volume);
+
+private:
+ // Non-changing variables
+ Video::VideoDecoder *_video;
+ Common::String _fileName; // External video files
+ int _id; // Internal Mohawk files
+
// Playback variables
- Video::VideoDecoder *video;
- uint16 x;
- uint16 y;
- bool loop;
- bool enabled;
- Audio::Timestamp start;
-
- // Identification
- Common::String filename; // External video files
- int id; // Internal Mohawk files
-
- // Helper functions
- Video::VideoDecoder *operator->() const { assert(video); return video; } // TODO: Remove this eventually
- void clear();
- bool endOfVideo();
+ uint16 _x;
+ uint16 _y;
+ bool _loop;
+ bool _enabled;
+ Audio::Timestamp _start;
};
-typedef int32 VideoHandle;
+typedef Common::SharedPtr<VideoEntry> VideoEntryPtr;
+
+/**
+ * A handle for manipulating a video
+ */
+class VideoHandle {
+ // The private members should be able to be manipulated by VideoManager
+ friend class VideoManager;
+
+public:
+ /**
+ * Default constructor
+ */
+ VideoHandle() {}
+
+ /**
+ * Copy constructor
+ */
+ VideoHandle(const VideoHandle &handle);
+
+ /**
+ * Is this handle pointing to a valid video entry?
+ */
+ bool isValid() const { return _ptr && _ptr->isOpen(); }
+
+ /**
+ * Convenience implicit cast to bool
+ */
+ operator bool() const { return isValid(); }
+
+ /**
+ * Simple equality operator
+ */
+ bool operator==(const VideoHandle &other) const { return _ptr.get() == other._ptr.get(); }
-enum {
- NULL_VID_HANDLE = -1
+ /**
+ * Simple inequality operator
+ */
+ bool operator!=(const VideoHandle &other) const { return !(*this == other); }
+
+ /**
+ * Convenience operator-> override to give direct access to the VideoEntry
+ */
+ VideoEntryPtr operator->() const { return _ptr; }
+
+private:
+ /**
+ * Constructor for internal VideoManager use
+ */
+ VideoHandle(VideoEntryPtr ptr);
+
+ /**
+ * The video entry this is associated with
+ */
+ VideoEntryPtr _ptr;
};
class VideoManager {
@@ -76,8 +309,8 @@ public:
// Generic movie functions
void playMovieBlocking(const Common::String &filename, uint16 x = 0, uint16 y = 0, bool clearScreen = false);
void playMovieBlockingCentered(const Common::String &filename, bool clearScreen = true);
- VideoHandle playMovie(const Common::String &filename, int16 x = -1, int16 y = -1, bool loop = false);
- VideoHandle playMovie(uint16 id, int16 x = -1, int16 y = -1, bool loop = false);
+ VideoHandle playMovie(const Common::String &filename);
+ VideoHandle playMovie(uint16 id);
bool updateMovies();
void pauseVideos();
void resumeVideos();
@@ -87,31 +320,18 @@ public:
// Riven-related functions
void activateMLST(uint16 mlstId, uint16 card);
void clearMLST();
- void enableMovieRiven(uint16 id);
- void disableMovieRiven(uint16 id);
void disableAllMovies();
VideoHandle playMovieRiven(uint16 id);
- void stopMovieRiven(uint16 id);
void playMovieBlockingRiven(uint16 id);
VideoHandle findVideoHandleRiven(uint16 id);
+ void stopMovieRiven(uint16 id);
// Handle functions
VideoHandle findVideoHandle(uint16 id);
- VideoHandle findVideoHandle(const Common::String &filename);
- int getCurFrame(VideoHandle handle);
- uint32 getFrameCount(VideoHandle handle);
- uint32 getTime(VideoHandle handle);
- Audio::Timestamp getDuration(VideoHandle videoHandle);
- bool endOfVideo(VideoHandle handle);
- void setVideoBounds(VideoHandle handle, Audio::Timestamp start, Audio::Timestamp end);
- void drawVideoFrame(VideoHandle handle, Audio::Timestamp time);
- void seekToTime(VideoHandle handle, Audio::Timestamp time);
- void setVideoLooping(VideoHandle handle, bool loop);
- Common::Rational getVideoRate(VideoHandle handle) const;
- void setVideoRate(VideoHandle handle, const Common::Rational &rate);
- void waitUntilMovieEnds(VideoHandle videoHandle);
- void delayUntilMovieEnds(VideoHandle videoHandle);
- void pauseMovie(VideoHandle videoHandle, bool pause);
+ VideoHandle findVideoHandle(const Common::String &fileName);
+ void waitUntilMovieEnds(VideoHandle handle);
+ void delayUntilMovieEnds(VideoHandle handle);
+ void drawVideoFrame(VideoHandle handle, const Audio::Timestamp &time);
private:
MohawkEngine *_vm;
@@ -120,10 +340,19 @@ private:
Common::Array<MLSTRecord> _mlstRecords;
// Keep tabs on any videos playing
- Common::Array<VideoEntry> _videoStreams;
+ typedef Common::List<VideoEntryPtr> VideoList;
+ VideoList _videos;
+
+ // Utility functions for managing entries
+ VideoEntryPtr open(uint16 id);
+ VideoEntryPtr open(const Common::String &fileName);
+
+ VideoList::iterator findEntry(VideoEntryPtr ptr);
+ void removeEntry(VideoEntryPtr ptr);
- VideoHandle createVideoHandle(uint16 id, uint16 x, uint16 y, bool loop, uint16 volume = 0xff);
- VideoHandle createVideoHandle(const Common::String &filename, uint16 x, uint16 y, bool loop, byte volume = 0xff);
+ // Dithering control
+ bool _enableDither;
+ void checkEnableDither(VideoEntryPtr &entry);
};
} // End of namespace Mohawk
diff --git a/engines/mortevielle/actions.cpp b/engines/mortevielle/actions.cpp
index 556475d515..b7b9c1e000 100644
--- a/engines/mortevielle/actions.cpp
+++ b/engines/mortevielle/actions.cpp
@@ -571,6 +571,7 @@ void MortevielleEngine::fctSearch() {
_curSearchObjId = getFirstObject();
if (_curSearchObjId != 0) {
_searchCount = 0;
+ _is = 0;
_heroSearching = true;
_menu->setSearchMenu();
prepareNextObject();
@@ -1678,9 +1679,8 @@ void MortevielleEngine::endGame() {
handleDescriptionText(2, 35);
startMusicOrSpeech(0);
testKey(false);
- // A wait message was displayed.
- // testKey (aka tkey1) was called before and after.
- // This double call is useless, thus removed
+ displayInterScreenMessage(2036);
+ testKey(false);
resetVariables();
}
diff --git a/engines/mortevielle/dialogs.cpp b/engines/mortevielle/dialogs.cpp
index 89098fabe5..9df66846d2 100644
--- a/engines/mortevielle/dialogs.cpp
+++ b/engines/mortevielle/dialogs.cpp
@@ -66,12 +66,12 @@ int DialogManager::show(const Common::String &msg) {
drawAlertBox(10, 5, colNumb);
} else {
drawAlertBox(8, 7, colNumb);
- int i = 0;
+ int i = -1;
_vm->_screenSurface->_textPos.y = 70;
do {
curPos.x = 320;
Common::String displayStr = "";
- while ((alertStr[i + 1] != '\174') && (alertStr[i + 1] != '\135')) {
+ while ((alertStr[i + 1] != '|') && (alertStr[i + 1] != ']')) {
++i;
displayStr += alertStr[i];
curPos.x -= 3;
@@ -405,7 +405,7 @@ void DialogManager::drawF3F8() {
int f8Width = _vm->_screenSurface->getStringWidth(f8);
// Write out the bounding box
- _vm->_screenSurface->drawBox(0, 42, MAX(f3Width, f8Width) + 6, 18, 7);
+ _vm->_screenSurface->drawBox(0, 42, MAX(f3Width, f8Width) + 4, 16, 7);
}
/**
diff --git a/engines/mortevielle/graphics.cpp b/engines/mortevielle/graphics.cpp
index 553c1a759e..aa479fdd44 100644
--- a/engines/mortevielle/graphics.cpp
+++ b/engines/mortevielle/graphics.cpp
@@ -1019,6 +1019,8 @@ void ScreenSurface::writeCharacter(const Common::Point &pt, unsigned char ch, in
* simulate the original 640x400 surface, all Y values have to be doubled
*/
void ScreenSurface::drawBox(int x, int y, int dx, int dy, int col) {
+ dx++; dy++; // Original function draws 1px bigger
+
Graphics::Surface destSurface = lockArea(Common::Rect(x, y * 2, x + dx, (y + dy) * 2));
destSurface.hLine(0, 0, dx, col);
diff --git a/engines/mortevielle/mortevielle.h b/engines/mortevielle/mortevielle.h
index 5f7f175c26..42d70fcb37 100644
--- a/engines/mortevielle/mortevielle.h
+++ b/engines/mortevielle/mortevielle.h
@@ -92,6 +92,7 @@ enum DataType {
#define MORT_DAT_REQUIRED_VERSION 1
#define MORT_DAT "mort.dat"
#define GAME_FRAME_DELAY (1000 / 50)
+#define DISK_ACCESS_DELAY 1000
const int kTime1 = 410;
const int kTime2 = 250;
@@ -115,6 +116,7 @@ const int kInventoryStringIndex = 186;
const int kQuestionStringIndex = 247;
const int kDialogStringIndex = 292;
const int kMenuPlaceStringIndex = 435;
+const int kStartingScreenStringIndex = 456;
const int kMenuActionStringIndex = 476;
const int kMenuSelfStringIndex = 497;
const int kMenuSayStringIndex = 502;
@@ -415,6 +417,7 @@ public:
int _maff;
int _caff;
int _crep;
+ int _is; // ???
byte _destinationArray[7][25];
@@ -465,6 +468,7 @@ public:
void gameLoaded();
void initGame();
void displayAloneText();
+ void displayInterScreenMessage(int mesgId);
void draw(int x, int y);
void charToHour();
void hourToChar();
diff --git a/engines/mortevielle/outtext.cpp b/engines/mortevielle/outtext.cpp
index 6a479c0859..5cbe4deab3 100644
--- a/engines/mortevielle/outtext.cpp
+++ b/engines/mortevielle/outtext.cpp
@@ -227,7 +227,31 @@ void TextHandler::taffich() {
Common::String filename, altFilename;
if ((a != 50) && (a != 51)) {
+ int m = a + 2000;
+
+ if ((m > 2001) && (m < 2010))
+ m = 2001;
+ else if (m == 2011)
+ m = 2010;
+ if (a == 32)
+ m = 2034;
+ else if ((a == 17) && (_vm->_maff == 14))
+ m = 2018;
+ else if (a > 99) {
+ if ((_vm->_is == 1) || (_vm->_is == 0))
+ m = 2031;
+ else
+ m = 2032;
+ }
+
+ if ( ((a > 69) && (a < 80)) || (a == 30) || (a == 31) || (a == 144) || (a == 147) || (a == 149) )
+ m = 2030;
+ else if ( ((a < 27) && ( ((_vm->_maff > 69) && (!_vm->_coreVar._alreadyEnteredManor)) || (_vm->_maff > 99) )) || ((_vm->_maff > 29) && (_vm->_maff < 33)) )
+ m = 2033;
+
+ _vm->displayInterScreenMessage(m);
_vm->_maff = a;
+
if (a == 159)
a = 86;
else if (a > 140)
diff --git a/engines/mortevielle/utils.cpp b/engines/mortevielle/utils.cpp
index 40136ad78b..5137e1892b 100644
--- a/engines/mortevielle/utils.cpp
+++ b/engines/mortevielle/utils.cpp
@@ -234,6 +234,7 @@ void MortevielleEngine::setMousePos(const Common::Point &pt) {
void MortevielleEngine::delay(int amount) {
uint32 endTime = g_system->getMillis() + amount;
+ g_system->showMouse(false);
while (g_system->getMillis() < endTime) {
if (g_system->getMillis() > (_lastGameFrame + GAME_FRAME_DELAY)) {
_lastGameFrame = g_system->getMillis();
@@ -244,6 +245,7 @@ void MortevielleEngine::delay(int amount) {
g_system->delayMillis(10);
}
+ g_system->showMouse(true);
}
/**
@@ -389,7 +391,7 @@ void MortevielleEngine::setTextColor(int col) {
*/
void MortevielleEngine::prepareScreenType1() {
// Large drawing
- _screenSurface->drawBox(0, 11, 512, 164, 15);
+ _screenSurface->drawBox(0, 11, 512, 163, 15);
}
/**
@@ -705,11 +707,11 @@ void MortevielleEngine::displayAloneText() {
Common::String sAlone = getEngineString(S_ALONE);
clearUpperRightPart();
- _screenSurface->putxy(580 - (_screenSurface->getStringWidth(sYou) / 2), 30);
+ _screenSurface->putxy(560, 30);
_screenSurface->drawString(sYou, 4);
- _screenSurface->putxy(580 - (_screenSurface->getStringWidth(sAre) / 2), 50);
+ _screenSurface->putxy(560, 50);
_screenSurface->drawString(sAre, 4);
- _screenSurface->putxy(580 - (_screenSurface->getStringWidth(sAlone) / 2), 70);
+ _screenSurface->putxy(560, 70);
_screenSurface->drawString(sAlone, 4);
_currBitIndex = 0;
@@ -1357,6 +1359,7 @@ void MortevielleEngine::endSearch() {
_heroSearching = false;
_obpart = false;
_searchCount = 0;
+ _is = 0;
_menu->unsetSearchMenu();
}
@@ -1379,7 +1382,7 @@ void MortevielleEngine::gotoDiningRoom() {
showPeoplePresent(_currBitIndex);
_caff = 77;
drawPictureWithText();
- _screenSurface->drawBox(223, 47, 155, 92, 15);
+ _screenSurface->drawBox(223, 47, 155, 91, 15);
handleDescriptionText(2, 33);
testKey(false);
menuUp();
@@ -1467,6 +1470,7 @@ void MortevielleEngine::gameLoaded() {
_num = 0;
_startTime = 0;
_endTime = 0;
+ _is = 0;
_searchCount = 0;
_roomDoorId = OWN_ROOM;
_syn = true;
@@ -1653,11 +1657,11 @@ void MortevielleEngine::clearDescriptionBar() {
_mouse->hideMouse();
if (_largestClearScreen) {
_screenSurface->fillRect(0, Common::Rect(1, 176, 633, 199));
- _screenSurface->drawBox(0, 176, 634, 23, 15);
+ _screenSurface->drawBox(0, 175, 634, 24, 15);
_largestClearScreen = false;
} else {
_screenSurface->fillRect(0, Common::Rect(1, 176, 633, 190));
- _screenSurface->drawBox(0, 176, 634, 14, 15);
+ _screenSurface->drawBox(0, 175, 634, 15, 15);
}
_mouse->showMouse();
}
@@ -1691,7 +1695,7 @@ void MortevielleEngine::clearUpperRightPart() {
else if (_coreVar._faithScore > 65)
st = getEngineString(S_MALSAINE);
- int x1 = 580 - (_screenSurface->getStringWidth(st) / 2);
+ int x1 = 574 - (_screenSurface->getStringWidth(st) / 2);
_screenSurface->putxy(x1, 92);
_screenSurface->drawString(st, 4);
@@ -1722,6 +1726,22 @@ void MortevielleEngine::showMoveMenuAlert() {
* @remarks Originally called 'dialpre'
*/
void MortevielleEngine::showConfigScreen() {
+ // FIXME: need a DOS palette, index 9 (light blue). Also we should show DOS font here
+ Common::String tmpStr;
+ int width, cy = 0;
+ clearScreen();
+ do {
+ ++cy;
+ tmpStr = getString(cy + kStartingScreenStringIndex);
+ width = _screenSurface->getStringWidth(tmpStr);
+ _text->displayStr(tmpStr, 320 - width / 2, cy * 8, 80, 1, 2);
+ } while (cy != 20);
+
+ int ix = 0;
+ do {
+ ++ix;
+ } while (!(keyPressed() || ix == 0x5e5));
+
_crep = 998;
}
@@ -2124,9 +2144,11 @@ void MortevielleEngine::showTitleScreen() {
_caff = 51;
_text->taffich();
testKeyboard();
+ delay(DISK_ACCESS_DELAY);
clearScreen();
draw(0, 0);
+ // FIXME: should be a DOS font here
Common::String cpr = "COPYRIGHT 1989 : LANKHOR";
_screenSurface->putxy(104 + 72 * kResolutionScaler, 185);
_screenSurface->drawString(cpr, 0);
@@ -2521,6 +2543,18 @@ void MortevielleEngine::handleDescriptionText(int f, int mesgId) {
_coreVar._pctHintFound[10] = '*';
}
break;
+ case 7: {
+ prepareScreenType3();
+ Common::String tmpStr = getString(mesgId);
+ // CHECKME: original code seems to consider one extra character
+ // See text position in the 3rd intro screen
+ int size = tmpStr.size() + 1;
+ if (size < 40)
+ _text->displayStr(tmpStr, 252 - size * 3, 86, 50, 3, 5);
+ else
+ _text->displayStr(tmpStr, 144, 86, 50, 3, 5);
+ }
+ break;
default:
break;
}
@@ -2870,10 +2904,10 @@ void MortevielleEngine::drawPicture() {
clearUpperLeftPart();
if (_caff > 99) {
draw(60, 33);
- _screenSurface->drawBox(118, 32, 291, 122, 15); // Medium box
+ _screenSurface->drawBox(118, 32, 291, 121, 15); // Medium box
} else if (_caff > 69) {
draw(112, 48); // Heads
- _screenSurface->drawBox(222, 47, 155, 92, 15);
+ _screenSurface->drawBox(222, 47, 155, 91, 15);
} else {
draw(0, 12);
prepareScreenType1();
@@ -2911,6 +2945,9 @@ void MortevielleEngine::drawPicture() {
}
}
+/**
+ * @remarks Originally called 'afdes'
+ */
void MortevielleEngine::drawPictureWithText() {
_text->taffich();
drawPicture();
@@ -2971,6 +3008,26 @@ void MortevielleEngine::displayNarrativePicture(int af, int ob) {
}
/**
+ * Display a message switching from a screen to another.
+ * @remarks Originally called 'messint'
+ */
+void MortevielleEngine::displayInterScreenMessage(int mesgId) {
+ clearUpperLeftPart();
+ clearDescriptionBar();
+ clearVerbBar();
+
+ GfxSurface surface;
+ surface.decode(_rightFramePict + 1008);
+ surface._offset.x = 80;
+ surface._offset.y = 40;
+ setPal(90);
+ _screenSurface->drawPicture(surface, 0, 0);
+ _screenSurface->drawPicture(surface, 0, 70);
+ handleDescriptionText(7, mesgId);
+ delay(DISK_ACCESS_DELAY);
+}
+
+/**
* Prepare Display Text
* @remarks Originally called 'affrep'
*/
@@ -3072,7 +3129,7 @@ void MortevielleEngine::menuUp() {
*/
void MortevielleEngine::drawDiscussionBox() {
draw(10, 80);
- _screenSurface->drawBox(18, 79, 155, 92, 15);
+ _screenSurface->drawBox(18, 79, 155, 91, 15);
}
/**
@@ -3178,6 +3235,7 @@ void MortevielleEngine::prepareNextObject() {
} while ((objId == 0) && (_searchCount <= 9));
if ((objId != 0) && (_searchCount < 11)) {
+ _is++;
_caff = objId;
_crep = _caff + 400;
if (_currBitIndex != 0)
diff --git a/engines/neverhood/menumodule.cpp b/engines/neverhood/menumodule.cpp
index 255d04dc86..6911041e58 100644
--- a/engines/neverhood/menumodule.cpp
+++ b/engines/neverhood/menumodule.cpp
@@ -202,7 +202,7 @@ uint32 MenuModule::handleMessage(int messageNum, const MessageParam &param, Enti
break;
}
- return Module::handleMessage(messageNum, param, sender);;
+ return Module::handleMessage(messageNum, param, sender);
}
void MenuModule::createLoadGameMenu() {
diff --git a/engines/parallaction/adlib.cpp b/engines/parallaction/adlib.cpp
index 7c1dd1681f..568ad190aa 100644
--- a/engines/parallaction/adlib.cpp
+++ b/engines/parallaction/adlib.cpp
@@ -25,7 +25,7 @@
#include "audio/fmopl.h"
#include "audio/mpu401.h"
-#include "audio/softsynth/emumidi.h"
+#include "audio/mididrv.h"
namespace Parallaction {
@@ -270,11 +270,13 @@ struct MelodicVoice {
int8 _octave;
};
-class AdLibDriver : public MidiDriver_Emulated {
+class AdLibDriver : public MidiDriver {
public:
- AdLibDriver(Audio::Mixer *mixer) : MidiDriver_Emulated(mixer) {
+ AdLibDriver(Audio::Mixer *mixer) {
for (uint i = 0; i < 16; ++i)
_channels[i].init(this, i);
+
+ _isOpen = false;
}
int open();
@@ -282,11 +284,13 @@ public:
void send(uint32 b);
MidiChannel *allocateChannel();
MidiChannel *getPercussionChannel() { return &_channels[9]; }
+ bool isOpen() const { return _isOpen; }
+ uint32 getBaseTempo() { return 1000000 / OPL::OPL::kDefaultCallbackFrequency; }
- bool isStereo() const { return false; }
- int getRate() const { return _mixer->getOutputRate(); }
-
- void generateSamples(int16 *buf, int len);
+ virtual void setTimerCallback(void *timerParam, Common::TimerManager::TimerProc timerProc) {
+ _adlibTimerProc = timerProc;
+ _adlibTimerParam = timerParam;
+ }
protected:
OPL::OPL *_opl;
@@ -320,6 +324,13 @@ protected:
void muteMelodicVoice(uint8 voice);
void initVoices();
+
+private:
+ void onTimer();
+
+ Common::TimerManager::TimerProc _adlibTimerProc;
+ void *_adlibTimerParam;
+ bool _isOpen;
};
MidiDriver *createAdLibDriver() {
@@ -348,10 +359,10 @@ int AdLibDriver::open() {
if (_isOpen)
return MERR_ALREADY_OPEN;
- MidiDriver_Emulated::open();
+ _isOpen = true;
_opl = OPL::Config::create();
- _opl->init(getRate());
+ _opl->init();
_opl->writeReg(0x1, 0x20); // set bit 5 (enable all waveforms)
// Reset the OPL registers.
@@ -364,7 +375,7 @@ int AdLibDriver::open() {
initVoices();
- _mixer->playStream(Audio::Mixer::kMusicSoundType, &_mixerSoundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
+ _opl->start(new Common::Functor0Mem<void, AdLibDriver>(this, &AdLibDriver::onTimer));
return 0;
}
@@ -373,7 +384,6 @@ void AdLibDriver::close() {
return;
_isOpen = false;
- _mixer->stopHandle(_mixerSoundHandle);
delete _opl;
}
@@ -777,9 +787,9 @@ MidiChannel *AdLibDriver::allocateChannel() {
return NULL;
}
-void AdLibDriver::generateSamples(int16 *buf, int len) {
- memset(buf, 0, sizeof(int16) * len);
- _opl->readBuffer(buf, len);
+void AdLibDriver::onTimer() {
+ if (_adlibTimerProc)
+ (*_adlibTimerProc)(_adlibTimerParam);
}
void AdLibDriver::initVoices() {
diff --git a/engines/pegasus/menu.cpp b/engines/pegasus/menu.cpp
index 4bbda8fd93..3e9bf540fe 100644
--- a/engines/pegasus/menu.cpp
+++ b/engines/pegasus/menu.cpp
@@ -258,12 +258,12 @@ void MainMenu::handleInput(const Input &input, const Hotspot *cursorSpot) {
bool isDemo = vm->isDemo();
if (input.upButtonDown()) {
- if (_menuSelection > (isDemo ? kFirstSelectionDemo : kFirstSelection)) {
+ if (_menuSelection > (uint32)(isDemo ? kFirstSelectionDemo : kFirstSelection)) {
_menuSelection--;
updateDisplay();
}
} else if (input.downButtonDown()) {
- if (_menuSelection < (isDemo ? kLastSelectionDemo : kLastSelection)) {
+ if (_menuSelection < (uint32)(isDemo ? kLastSelectionDemo : kLastSelection)) {
_menuSelection++;
updateDisplay();
}
diff --git a/engines/pegasus/sound.cpp b/engines/pegasus/sound.cpp
index 5b437b81d4..ddcb2be010 100644
--- a/engines/pegasus/sound.cpp
+++ b/engines/pegasus/sound.cpp
@@ -59,7 +59,15 @@ void Sound::initFromAIFFFile(const Common::String &fileName) {
return;
}
- _stream = Audio::makeAIFFStream(file, DisposeAfterUse::YES);
+ Audio::RewindableAudioStream *stream = Audio::makeAIFFStream(file, DisposeAfterUse::YES);
+
+ _stream = dynamic_cast<Audio::SeekableAudioStream *>(stream);
+
+ if (!_stream) {
+ delete stream;
+ warning("AIFF stream '%s' is not seekable", fileName.c_str());
+ return;
+ }
}
void Sound::initFromQuickTime(const Common::String &fileName) {
diff --git a/engines/queen/midiadlib.cpp b/engines/queen/midiadlib.cpp
index 25175c21d7..f5bc0f4d58 100644
--- a/engines/queen/midiadlib.cpp
+++ b/engines/queen/midiadlib.cpp
@@ -23,118 +23,29 @@
#include "common/endian.h"
#include "common/textconsole.h"
-#include "audio/fmopl.h"
-#include "audio/softsynth/emumidi.h"
+#include "engines/queen/midiadlib.h"
namespace Queen {
-class AdLibMidiDriver : public MidiDriver_Emulated {
-public:
-
- AdLibMidiDriver(Audio::Mixer *mixer) : MidiDriver_Emulated(mixer) { _adlibWaveformSelect = 0; }
- ~AdLibMidiDriver() {}
-
- // MidiDriver
- int open();
- void close();
- void send(uint32 b);
- void metaEvent(byte type, byte *data, uint16 length);
- MidiChannel *allocateChannel() { return 0; }
- MidiChannel *getPercussionChannel() { return 0; }
-
- // AudioStream
- bool isStereo() const { return false; }
- int getRate() const { return _mixer->getOutputRate(); }
-
- // MidiDriver_Emulated
- void generateSamples(int16 *buf, int len);
-
-private:
-
- void handleMidiEvent0x90_NoteOn(int channel, int param1, int param2);
- void handleSequencerSpecificMetaEvent1(int channel, const uint8 *data);
- void handleSequencerSpecificMetaEvent2(uint8 value);
- void handleSequencerSpecificMetaEvent3(uint8 value);
-
- void adlibWrite(uint8 port, uint8 value);
- void adlibSetupCard();
- void adlibSetupChannels(int fl);
- void adlibResetAmpVibratoRhythm(int am, int vib, int kso);
- void adlibResetChannels();
- void adlibSetAmpVibratoRhythm();
- void adlibSetCSMKeyboardSplit();
- void adlibSetNoteMul(int mul);
- void adlibSetWaveformSelect(int fl);
- void adlibSetPitchBend(int channel, int range);
- void adlibPlayNote(int channel);
- uint8 adlibPlayNoteHelper(int channel, int note1, int note2, int oct);
- void adlibTurnNoteOff(int channel);
- void adlibTurnNoteOn(int channel, int note);
- void adlibSetupChannelFromSequence(int channel, const uint8 *src, int fl);
- void adlibSetupChannel(int channel, const uint16 *src, int fl);
- void adlibSetNoteVolume(int channel, int volume);
- void adlibSetupChannelHelper(int channel);
- void adlibSetChannel0x40(int channel);
- void adlibSetChannel0xC0(int channel);
- void adlibSetChannel0x60(int channel);
- void adlibSetChannel0x80(int channel);
- void adlibSetChannel0x20(int channel);
- void adlibSetChannel0xE0(int channel);
-
- FM_OPL *_opl;
- int _midiNumberOfChannels;
- int _adlibNoteMul;
- int _adlibWaveformSelect;
- int _adlibAMDepthEq48;
- int _adlibVibratoDepthEq14;
- int _adlibRhythmEnabled;
- int _adlibKeyboardSplitOn;
- int _adlibVibratoRhythm;
- uint8 _midiChannelsFreqTable[9];
- uint8 _adlibChannelsLevelKeyScalingTable[11];
- uint8 _adlibSetupChannelSequence1[14 * 18];
- uint16 _adlibSetupChannelSequence2[14];
- int16 _midiChannelsNote2Table[9];
- uint8 _midiChannelsNote1Table[9];
- uint8 _midiChannelsOctTable[9];
- uint16 _adlibChannelsVolume[11];
- uint16 _adlibMetaSequenceData[28];
-
- static const uint8 _adlibChannelsMappingTable1[];
- static const uint8 _adlibChannelsNoFeedback[];
- static const uint8 _adlibChannelsMappingTable2[];
- static const uint8 _adlibChannelsMappingTable3[];
- static const uint8 _adlibChannelsKeyScalingTable1[];
- static const uint8 _adlibChannelsKeyScalingTable2[];
- static const uint8 _adlibChannelsVolumeTable[];
- static const uint8 _adlibInitSequenceData1[];
- static const uint8 _adlibInitSequenceData2[];
- static const uint8 _adlibInitSequenceData3[];
- static const uint8 _adlibInitSequenceData4[];
- static const uint8 _adlibInitSequenceData5[];
- static const uint8 _adlibInitSequenceData6[];
- static const uint8 _adlibInitSequenceData7[];
- static const uint8 _adlibInitSequenceData8[];
- static const int16 _midiChannelsNoteTable[];
- static const int16 _midiNoteFreqTable[];
-};
-
int AdLibMidiDriver::open() {
- MidiDriver_Emulated::open();
- _opl = makeAdLibOPL(getRate());
+ _isOpen = true;
+ _opl = OPL::Config::create();
+ if (!_opl || !_opl->init())
+ error("Failed to create OPL");
+
adlibSetupCard();
for (int i = 0; i < 11; ++i) {
_adlibChannelsVolume[i] = 0;
adlibSetNoteVolume(i, 0);
adlibTurnNoteOff(i);
}
- _mixer->playStream(Audio::Mixer::kMusicSoundType, &_mixerSoundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
+
+ _opl->start(new Common::Functor0Mem<void, AdLibMidiDriver>(this, &AdLibMidiDriver::onTimer));
return 0;
}
void AdLibMidiDriver::close() {
- _mixer->stopHandle(_mixerSoundHandle);
- OPLDestroy(_opl);
+ delete _opl;
}
void AdLibMidiDriver::send(uint32 b) {
@@ -164,6 +75,11 @@ void AdLibMidiDriver::send(uint32 b) {
}
}
+void AdLibMidiDriver::setVolume(uint32 volume) {
+ for (int i = 0; i < _midiNumberOfChannels; ++i)
+ adlibSetChannelVolume(i, volume * 64 / 256 + 64);
+}
+
void AdLibMidiDriver::metaEvent(byte type, byte *data, uint16 length) {
int event = 0;
if (length > 4 && READ_BE_UINT32(data) == 0x3F00) {
@@ -192,9 +108,14 @@ void AdLibMidiDriver::metaEvent(byte type, byte *data, uint16 length) {
warning("Unhandled meta event %d len %d", event, length);
}
-void AdLibMidiDriver::generateSamples(int16 *data, int len) {
- memset(data, 0, sizeof(int16) * len);
- YM3812UpdateOne(_opl, data, len);
+void AdLibMidiDriver::setTimerCallback(void *timerParam, Common::TimerManager::TimerProc timerProc) {
+ _adlibTimerProc = timerProc;
+ _adlibTimerParam = timerParam;
+}
+
+void AdLibMidiDriver::onTimer() {
+ if (_adlibTimerProc)
+ (*_adlibTimerProc)(_adlibTimerParam);
}
void AdLibMidiDriver::handleSequencerSpecificMetaEvent1(int channel, const uint8 *data) {
@@ -238,7 +159,7 @@ void AdLibMidiDriver::handleMidiEvent0x90_NoteOn(int channel, int param1, int pa
}
void AdLibMidiDriver::adlibWrite(uint8 port, uint8 value) {
- OPLWriteReg(_opl, port, value);
+ _opl->writeReg(port, value);
}
void AdLibMidiDriver::adlibSetupCard() {
@@ -253,6 +174,7 @@ void AdLibMidiDriver::adlibSetupCard() {
_midiChannelsFreqTable[i] = 0;
}
memset(_adlibChannelsLevelKeyScalingTable, 127, 11);
+ memset(_adlibChannelsVolumeTable, 128, 11);
adlibSetupChannels(0);
adlibResetAmpVibratoRhythm(0, 0, 0);
adlibSetNoteMul(1);
@@ -448,6 +370,11 @@ void AdLibMidiDriver::adlibSetNoteVolume(int channel, int volume) {
}
}
+void AdLibMidiDriver::adlibSetChannelVolume(int channel, uint8 volume) {
+ if (channel < (_adlibRhythmEnabled ? 11 : 9))
+ _adlibChannelsVolumeTable[channel] = volume;
+}
+
void AdLibMidiDriver::adlibSetupChannelHelper(int channel) {
adlibSetAmpVibratoRhythm();
adlibSetCSMKeyboardSplit();
@@ -558,10 +485,6 @@ const uint8 AdLibMidiDriver::_adlibChannelsKeyScalingTable2[] = {
0, 3, 1, 4, 2, 5, 6, 9, 7, 10, 8, 11, 12, 15, 16, 255, 14, 255, 17, 255, 13, 255
};
-const uint8 AdLibMidiDriver::_adlibChannelsVolumeTable[] = {
- 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128
-};
-
const uint8 AdLibMidiDriver::_adlibInitSequenceData1[] = {
1, 1, 3, 15, 5, 0, 1, 3, 15, 0, 0, 0, 1, 0
};
@@ -617,8 +540,4 @@ const int16 AdLibMidiDriver::_midiNoteFreqTable[] = {
-363, -361, -359, -356, -354, -351, -349, -347, -344, -342, -339, -337
};
-MidiDriver *C_Player_CreateAdLibMidiDriver(Audio::Mixer *mixer) {
- return new AdLibMidiDriver(mixer);
-}
-
} // End of namespace Queen
diff --git a/engines/queen/midiadlib.h b/engines/queen/midiadlib.h
new file mode 100644
index 0000000000..8692e51840
--- /dev/null
+++ b/engines/queen/midiadlib.h
@@ -0,0 +1,128 @@
+/* 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/fmopl.h"
+#include "audio/mididrv.h"
+
+namespace Queen {
+
+class AdLibMidiDriver : public MidiDriver {
+public:
+
+ AdLibMidiDriver() {
+ _adlibWaveformSelect = 0;
+ _isOpen = false;
+ }
+
+ ~AdLibMidiDriver() {}
+
+ // MidiDriver
+ int open();
+ void close();
+ void send(uint32 b);
+ void metaEvent(byte type, byte *data, uint16 length);
+ MidiChannel *allocateChannel() { return 0; }
+ MidiChannel *getPercussionChannel() { return 0; }
+ void setTimerCallback(void *timerParam, Common::TimerManager::TimerProc timerProc);
+ bool isOpen() const { return _isOpen; }
+ uint32 getBaseTempo() { return 1000000 / OPL::OPL::kDefaultCallbackFrequency; }
+
+ void setVolume(uint32 volume);
+
+private:
+
+ void handleMidiEvent0x90_NoteOn(int channel, int param1, int param2);
+ void handleSequencerSpecificMetaEvent1(int channel, const uint8 *data);
+ void handleSequencerSpecificMetaEvent2(uint8 value);
+ void handleSequencerSpecificMetaEvent3(uint8 value);
+
+ void adlibWrite(uint8 port, uint8 value);
+ void adlibSetupCard();
+ void adlibSetupChannels(int fl);
+ void adlibResetAmpVibratoRhythm(int am, int vib, int kso);
+ void adlibResetChannels();
+ void adlibSetAmpVibratoRhythm();
+ void adlibSetCSMKeyboardSplit();
+ void adlibSetNoteMul(int mul);
+ void adlibSetWaveformSelect(int fl);
+ void adlibSetPitchBend(int channel, int range);
+ void adlibPlayNote(int channel);
+ uint8 adlibPlayNoteHelper(int channel, int note1, int note2, int oct);
+ void adlibTurnNoteOff(int channel);
+ void adlibTurnNoteOn(int channel, int note);
+ void adlibSetupChannelFromSequence(int channel, const uint8 *src, int fl);
+ void adlibSetupChannel(int channel, const uint16 *src, int fl);
+ void adlibSetNoteVolume(int channel, int volume);
+ void adlibSetChannelVolume(int channel, uint8 volume);
+ void adlibSetupChannelHelper(int channel);
+ void adlibSetChannel0x40(int channel);
+ void adlibSetChannel0xC0(int channel);
+ void adlibSetChannel0x60(int channel);
+ void adlibSetChannel0x80(int channel);
+ void adlibSetChannel0x20(int channel);
+ void adlibSetChannel0xE0(int channel);
+
+ void onTimer();
+
+ OPL::OPL *_opl;
+ int _midiNumberOfChannels;
+ int _adlibNoteMul;
+ int _adlibWaveformSelect;
+ int _adlibAMDepthEq48;
+ int _adlibVibratoDepthEq14;
+ int _adlibRhythmEnabled;
+ int _adlibKeyboardSplitOn;
+ int _adlibVibratoRhythm;
+ uint8 _midiChannelsFreqTable[9];
+ uint8 _adlibChannelsLevelKeyScalingTable[11];
+ uint8 _adlibSetupChannelSequence1[14 * 18];
+ uint16 _adlibSetupChannelSequence2[14];
+ int16 _midiChannelsNote2Table[9];
+ uint8 _midiChannelsNote1Table[9];
+ uint8 _midiChannelsOctTable[9];
+ uint16 _adlibChannelsVolume[11];
+ uint16 _adlibMetaSequenceData[28];
+ uint8 _adlibChannelsVolumeTable[11];
+
+ bool _isOpen;
+ Common::TimerManager::TimerProc _adlibTimerProc;
+ void *_adlibTimerParam;
+
+ static const uint8 _adlibChannelsMappingTable1[];
+ static const uint8 _adlibChannelsNoFeedback[];
+ static const uint8 _adlibChannelsMappingTable2[];
+ static const uint8 _adlibChannelsMappingTable3[];
+ static const uint8 _adlibChannelsKeyScalingTable1[];
+ static const uint8 _adlibChannelsKeyScalingTable2[];
+ static const uint8 _adlibInitSequenceData1[];
+ static const uint8 _adlibInitSequenceData2[];
+ static const uint8 _adlibInitSequenceData3[];
+ static const uint8 _adlibInitSequenceData4[];
+ static const uint8 _adlibInitSequenceData5[];
+ static const uint8 _adlibInitSequenceData6[];
+ static const uint8 _adlibInitSequenceData7[];
+ static const uint8 _adlibInitSequenceData8[];
+ static const int16 _midiChannelsNoteTable[];
+ static const int16 _midiNoteFreqTable[];
+};
+
+} // End of namespace Queen
diff --git a/engines/queen/music.cpp b/engines/queen/music.cpp
index 93d6527622..9f74aab915 100644
--- a/engines/queen/music.cpp
+++ b/engines/queen/music.cpp
@@ -23,6 +23,7 @@
#include "common/config-manager.h"
#include "common/events.h"
+#include "queen/midiadlib.h"
#include "queen/music.h"
#include "queen/queen.h"
#include "queen/resource.h"
@@ -33,8 +34,6 @@
namespace Queen {
-extern MidiDriver *C_Player_CreateAdLibMidiDriver(Audio::Mixer *);
-
MidiMusic::MidiMusic(QueenEngine *vm)
: _isPlaying(false), _isLooping(false),
_randomLoop(false), _masterVolume(192),
@@ -69,7 +68,7 @@ MidiMusic::MidiMusic(QueenEngine *vm)
// if (READ_LE_UINT16(_musicData + 2) != infoOffset) {
// defaultAdLibVolume = _musicData[infoOffset];
// }
- _driver = C_Player_CreateAdLibMidiDriver(vm->_mixer);
+ _driver = new AdLibMidiDriver();
} else {
_driver = MidiDriver::createMidi(dev);
if (_nativeMT32) {
@@ -117,6 +116,9 @@ void MidiMusic::setVolume(int volume) {
if (_channelsTable[i])
_channelsTable[i]->volume(_channelsVolume[i] * _masterVolume / 255);
}
+
+ if (_adlib)
+ static_cast<AdLibMidiDriver*>(_driver)->setVolume(volume);
}
void MidiMusic::playSong(uint16 songNum) {
diff --git a/engines/queen/walk.cpp b/engines/queen/walk.cpp
index dd7e46c765..17d12b0b9f 100644
--- a/engines/queen/walk.cpp
+++ b/engines/queen/walk.cpp
@@ -130,7 +130,7 @@ void Walk::animateJoe() {
_vm->logic()->joeScale(pbs->scale);
pbs->scaleWalkSpeed(6);
_vm->update(true);
- if (_vm->input()->cutawayQuit() || _vm->logic()->joeWalk() == JWM_EXECUTE) {
+ if (_vm->input()->cutawayQuit() || _vm->logic()->joeWalk() == JWM_EXECUTE || _vm->shouldQuit()) {
stopJoe();
break;
}
@@ -249,7 +249,7 @@ void Walk::animatePerson(const MovePersonData *mpd, uint16 image, uint16 bobNum,
_vm->update();
pbs->scale = pwd->area->calcScale(pbs->y);
pbs->scaleWalkSpeed(mpd->moveSpeed);
- if (_vm->input()->cutawayQuit()) {
+ if (_vm->input()->cutawayQuit() || _vm->shouldQuit()) {
stopPerson(bobNum);
break;
}
diff --git a/engines/saga/detection_tables.h b/engines/saga/detection_tables.h
index 2f72e7a13c..98009326ae 100644
--- a/engines/saga/detection_tables.h
+++ b/engines/saga/detection_tables.h
@@ -192,9 +192,9 @@ static const SAGAGameDescription gameDescriptions[] = {
ADGF_DEMO,
GUIO1(GUIO_NOSPEECH)
},
- GID_ITE, // Game id
- GF_OLD_ITE_DOS, // features
- ITE_DEFAULT_SCENE, // Starting scene number
+ GID_ITE,
+ GF_ITE_DOS_DEMO,
+ ITE_DEFAULT_SCENE,
&ITEDemo_Resources,
ARRAYSIZE(ITEDEMO_GameFonts),
ITEDEMO_GameFonts,
@@ -393,6 +393,33 @@ static const SAGAGameDescription gameDescriptions[] = {
NULL,
},
+ // Inherit the earth - German Wyrmkeep combined Windows/Mac/Linux CD
+
+ // Supplied by user nicode in bug #6428.
+ // Contains voices.rsc instead of "Inherit the Earth Voices".
+ {
+ {
+ "ite",
+ "Multi-OS CD Version",
+ {
+ {"ite.rsc", GAME_RESOURCEFILE, "420e09cfdbb4db12baefd4bc81d8e154", 8925349},
+ {"scripts.rsc", GAME_SCRIPTFILE, "a891405405edefc69c9d6c420c868b84", -1},
+ { NULL, 0, NULL, 0}
+ },
+ Common::DE_DEU,
+ Common::kPlatformUnknown,
+ ADGF_CD,
+ GUIO0()
+ },
+ GID_ITE,
+ 0,
+ ITE_DEFAULT_SCENE,
+ &ITE_Resources,
+ ARRAYSIZE(ITE_GameFonts),
+ ITE_GameFonts,
+ NULL,
+ },
+
// Inherit the earth - Italian Wyrmkeep combined Windows/Mac/Linux CD (fan translation)
// version is different from the other Wyrmkeep re-releases in that it does
diff --git a/engines/saga/introproc_ihnm.cpp b/engines/saga/introproc_ihnm.cpp
index fc28d2372f..dc3f55e8c1 100644
--- a/engines/saga/introproc_ihnm.cpp
+++ b/engines/saga/introproc_ihnm.cpp
@@ -68,7 +68,7 @@ int Scene::IHNMStartProc() {
// Play the title music
_vm->_music->play(1, MUSIC_NORMAL);
// Play title screen
- playTitle(2, 17);
+ playTitle(2, _vm->_music->isAdlib() ? 20 : 27);
}
}
} else {
@@ -150,7 +150,7 @@ bool Scene::checkKey() {
break;
case Common::EVENT_KEYDOWN:
// Don't react to modifier keys alone. The original did
- // non, and the user may want to change scaler without
+ // not, and the user may want to change scaler without
// terminating the intro.
if (event.kbd.ascii)
res = true;
diff --git a/engines/saga/introproc_ite.cpp b/engines/saga/introproc_ite.cpp
index 0b129dbcc0..3c10cbe1dd 100644
--- a/engines/saga/introproc_ite.cpp
+++ b/engines/saga/introproc_ite.cpp
@@ -59,6 +59,11 @@ namespace Saga {
#define RID_ITE_FAIREPATH_SCENE 1564
#define RID_ITE_FAIRETENT_SCENE 1567
+// Intro scenes - DOS demo
+#define RID_ITE_INTRO_ANIM_SCENE_DOS_DEMO 298
+#define RID_ITE_CAVE_SCENE_DOS_DEMO 302
+#define RID_ITE_VALLEY_SCENE_DOS_DEMO 310
+
// ITE intro music
#define MUSIC_INTRO 9
#define MUSIC_TITLE_THEME 10
@@ -75,22 +80,24 @@ LoadSceneParams ITE_IntroList[] = {
{RID_ITE_FAIRETENT_SCENE, kLoadByResourceId, Scene::SC_ITEIntroFaireTentProc, false, kTransitionNoFade, 0, NO_CHAPTER_CHANGE}
};
-int Scene::ITEStartProc() {
- size_t scenesCount;
- size_t i;
+LoadSceneParams ITE_DOS_Demo_IntroList[] = {
+ {RID_ITE_INTRO_ANIM_SCENE_DOS_DEMO, kLoadByResourceId, Scene::SC_ITEIntroAnimProc, false, kTransitionNoFade, 0, NO_CHAPTER_CHANGE},
+ {RID_ITE_CAVE_SCENE_DOS_DEMO, kLoadByResourceId, Scene::SC_ITEIntroCaveDemoProc, false, kTransitionFade, 0, NO_CHAPTER_CHANGE},
+ {RID_ITE_VALLEY_SCENE_DOS_DEMO, kLoadByResourceId, Scene::SC_ITEIntroValleyProc, false, kTransitionFade, 0, NO_CHAPTER_CHANGE},
+};
+int Scene::ITEStartProc() {
LoadSceneParams firstScene;
LoadSceneParams tempScene;
+ bool dosDemo = (_vm->getFeatures() & GF_ITE_DOS_DEMO);
+ int scenesCount = (!dosDemo) ? ARRAYSIZE(ITE_IntroList) : ARRAYSIZE(ITE_DOS_Demo_IntroList);
- scenesCount = ARRAYSIZE(ITE_IntroList);
-
- for (i = 0; i < scenesCount; i++) {
- tempScene = ITE_IntroList[i];
+ for (int i = 0; i < scenesCount; i++) {
+ tempScene = (!dosDemo) ? ITE_IntroList[i] : ITE_DOS_Demo_IntroList[i];
tempScene.sceneDescriptor = _vm->_resource->convertResourceId(tempScene.sceneDescriptor);
_vm->_scene->queueScene(tempScene);
}
-
firstScene.loadFlag = kLoadBySceneNumber;
firstScene.sceneDescriptor = _vm->getStartSceneNumber();
firstScene.sceneSkipTarget = true;
@@ -437,6 +444,53 @@ int Scene::ITEIntroCaveCommonProc(int param, int caveScene) {
return 0;
}
+int Scene::ITEIntroCaveDemoProc(int param) {
+ Event event;
+ EventColumns *eventColumns = NULL;
+
+ switch (param) {
+ case SCENE_BEGIN:
+ // Begin palette cycling animation for candles
+ event.type = kEvTOneshot;
+ event.code = kPalAnimEvent;
+ event.op = kEventCycleStart;
+ event.time = 0;
+ eventColumns = _vm->_events->chain(eventColumns, event);
+
+ // Queue narrator dialogue list
+ for (int i = 0; i < 11; i++) {
+ // Play voice
+ event.type = kEvTOneshot;
+ event.code = kVoiceEvent;
+ event.op = kEventPlay;
+ event.param = i;
+ event.time = _vm->_sndRes->getVoiceLength(i);
+ _vm->_events->chain(eventColumns, event);
+ }
+
+ // End scene after last dialogue over
+ event.type = kEvTOneshot;
+ event.code = kSceneEvent;
+ event.op = kEventEnd;
+ event.time = INTRO_VOICE_PAD;
+ _vm->_events->chain(eventColumns, event);
+
+ break;
+ case SCENE_END:
+ break;
+
+ default:
+ warning("Illegal scene procedure parameter");
+ break;
+ }
+
+ return 0;
+}
+
+int Scene::SC_ITEIntroCaveDemoProc(int param, void *refCon) {
+ return ((Scene *)refCon)->ITEIntroCaveDemoProc(param);
+}
+
// Handles first introductory cave painting scene
int Scene::SC_ITEIntroCave1Proc(int param, void *refCon) {
return ((Scene *)refCon)->ITEIntroCaveCommonProc(param, 1);
diff --git a/engines/saga/music.cpp b/engines/saga/music.cpp
index d20882ca26..663f5991d0 100644
--- a/engines/saga/music.cpp
+++ b/engines/saga/music.cpp
@@ -31,6 +31,7 @@
#include "audio/mididrv.h"
#include "audio/midiparser.h"
#include "audio/midiparser_qt.h"
+#include "audio/miles.h"
#include "audio/decoders/raw.h"
#include "common/config-manager.h"
#include "common/file.h"
@@ -42,24 +43,51 @@ namespace Saga {
#define MUSIC_SUNSPOT 26
MusicDriver::MusicDriver() : _isGM(false) {
-
- MidiPlayer::createDriver();
-
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
_driverType = MidiDriver::getMusicType(dev);
+ switch (_driverType) {
+ case MT_ADLIB:
+ if (Common::File::exists("INSTR.AD") && Common::File::exists("INSTR.OPL")) {
+ _milesAudioMode = true;
+ _driver = Audio::MidiDriver_Miles_AdLib_create("INSTR.AD", "INSTR.OPL");
+ } else if (Common::File::exists("SAMPLE.AD") && Common::File::exists("SAMPLE.OPL")) {
+ _milesAudioMode = true;
+ _driver = Audio::MidiDriver_Miles_AdLib_create("SAMPLE.AD", "SAMPLE.OPL");
+ } else {
+ _milesAudioMode = false;
+ MidiPlayer::createDriver();
+ }
+ break;
+ case MT_MT32:
+ _milesAudioMode = true;
+ _driver = Audio::MidiDriver_Miles_MT32_create("");
+ break;
+ default:
+ _milesAudioMode = false;
+ MidiPlayer::createDriver();
+ break;
+ }
+
int retValue = _driver->open();
if (retValue == 0) {
- if (_nativeMT32)
- _driver->sendMT32Reset();
- else
- _driver->sendGMReset();
+ if (_driverType != MT_ADLIB) {
+ if (_driverType == MT_MT32 || _nativeMT32)
+ _driver->sendMT32Reset();
+ else
+ _driver->sendGMReset();
+ }
_driver->setTimerCallback(this, &timerCallback);
}
}
void MusicDriver::send(uint32 b) {
+ if (_milesAudioMode) {
+ _driver->send(b);
+ return;
+ }
+
if ((b & 0xF0) == 0xC0 && !_isGM && !_nativeMT32) {
// Remap MT32 instruments to General Midi
b = (b & 0xFFFF00FF) | MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8;
@@ -249,7 +277,11 @@ void Music::play(uint32 resourceId, MusicFlags flags) {
debug(2, "Music::play %d, %d", resourceId, flags);
- if (isPlaying() && _trackNumber == resourceId) {
+ if (isPlaying() && _trackNumber == resourceId)
+ return;
+
+ if (_vm->getFeatures() & GF_ITE_DOS_DEMO) {
+ warning("TODO: Music::play %d, %d for ITE DOS demo", resourceId, flags);
return;
}
diff --git a/engines/saga/music.h b/engines/saga/music.h
index 2106fb6fa6..2e7cc4c5ec 100644
--- a/engines/saga/music.h
+++ b/engines/saga/music.h
@@ -61,6 +61,7 @@ public:
protected:
MusicType _driverType;
bool _isGM;
+ bool _milesAudioMode;
};
class Music {
@@ -79,6 +80,8 @@ public:
void setVolume(int volume, int time = 1);
int getVolume() { return _currentVolume; }
+ bool isAdlib() const { return _player->isAdlib(); }
+
Common::Array<int32> _songTable;
private:
diff --git a/engines/saga/saga.cpp b/engines/saga/saga.cpp
index 3d38b3ea52..b94bb66bb4 100644
--- a/engines/saga/saga.cpp
+++ b/engines/saga/saga.cpp
@@ -117,6 +117,9 @@ SagaEngine::SagaEngine(OSystem *syst, const SAGAGameDescription *gameDesc)
SearchMan.addSubDirectoryMatching(gameDataDir, "music");
SearchMan.addSubDirectoryMatching(gameDataDir, "sound");
+ // Location of Miles audio files (sample.ad and sample.opl) in IHNM
+ SearchMan.addSubDirectoryMatching(gameDataDir, "drivers");
+
// The Multi-OS version puts the voices file in the root directory of
// the CD. The rest of the data files are in game/itedata
SearchMan.addSubDirectoryMatching(gameDataDir, "game/itedata");
@@ -634,6 +637,9 @@ void SagaEngine::syncSoundSettings() {
}
void SagaEngine::pauseEngineIntern(bool pause) {
+ if (!_render || !_music)
+ return;
+
bool engineIsPaused = (_render->getFlags() & RF_RENDERPAUSE);
if (engineIsPaused == pause)
return;
diff --git a/engines/saga/saga.h b/engines/saga/saga.h
index 6077e55094..9c7b2f5295 100644
--- a/engines/saga/saga.h
+++ b/engines/saga/saga.h
@@ -137,9 +137,7 @@ enum GameFileTypes {
enum GameFeatures {
GF_ITE_FLOPPY = 1 << 0,
-#if 0
- GF_OLD_ITE_DOS = 1 << 1, // Currently unused
-#endif
+ GF_ITE_DOS_DEMO = 1 << 1,
GF_EXTRA_ITE_CREDITS = 1 << 2,
GF_8BIT_UNSIGNED_PCM = 1 << 3
};
diff --git a/engines/saga/scene.cpp b/engines/saga/scene.cpp
index f19645dd99..efd4c371b1 100644
--- a/engines/saga/scene.cpp
+++ b/engines/saga/scene.cpp
@@ -835,13 +835,14 @@ void Scene::loadScene(LoadSceneParams &loadSceneParams) {
loadSceneParams.sceneProc(SCENE_BEGIN, this);
}
- // We probably don't want "followers" to go into scene -1 , 0. At the very
- // least we don't want garbage to be drawn that early in the ITE intro.
- if (_sceneNumber > 0 && _sceneNumber != ITE_SCENE_PUZZLE)
- _vm->_actor->updateActorsScene(loadSceneParams.actorsEntrance);
-
- if (_sceneNumber == ITE_SCENE_PUZZLE)
+ if (_vm->getGameId() == GID_ITE && _sceneNumber == ITE_SCENE_PUZZLE) {
_vm->_puzzle->execute();
+ } else {
+ // We probably don't want "followers" to go into scene -1 , 0. At the very
+ // least we don't want garbage to be drawn that early in the ITE intro.
+ if (_sceneNumber > 0)
+ _vm->_actor->updateActorsScene(loadSceneParams.actorsEntrance);
+ }
if (getFlags() & kSceneFlagShowCursor) {
// Activate user interface
@@ -865,15 +866,13 @@ void Scene::loadSceneDescriptor(uint32 resourceId) {
_sceneDescription.reset();
- if (resourceId == 0) {
+ if (resourceId == 0)
return;
- }
_vm->_resource->loadResource(_sceneContext, resourceId, sceneDescriptorData);
+ ByteArrayReadStreamEndian readS(sceneDescriptorData, _sceneContext->isBigEndian());
- if (sceneDescriptorData.size() == 16) {
- ByteArrayReadStreamEndian readS(sceneDescriptorData, _sceneContext->isBigEndian());
-
+ if (sceneDescriptorData.size() == 14 || sceneDescriptorData.size() == 16) {
_sceneDescription.flags = readS.readSint16();
_sceneDescription.resourceListResourceId = readS.readSint16();
_sceneDescription.endSlope = readS.readSint16();
@@ -881,7 +880,10 @@ void Scene::loadSceneDescriptor(uint32 resourceId) {
_sceneDescription.scriptModuleNumber = readS.readUint16();
_sceneDescription.sceneScriptEntrypointNumber = readS.readUint16();
_sceneDescription.startScriptEntrypointNumber = readS.readUint16();
- _sceneDescription.musicResourceId = readS.readSint16();
+ if (sceneDescriptorData.size() == 16)
+ _sceneDescription.musicResourceId = readS.readSint16();
+ } else {
+ warning("Scene::loadSceneDescriptor: Unknown scene descriptor data size (%d)", sceneDescriptorData.size());
}
}
diff --git a/engines/saga/scene.h b/engines/saga/scene.h
index 410713c5d5..1a710cfe9c 100644
--- a/engines/saga/scene.h
+++ b/engines/saga/scene.h
@@ -400,12 +400,14 @@ class Scene {
static int SC_ITEIntroTreeHouseProc(int param, void *refCon);
static int SC_ITEIntroFairePathProc(int param, void *refCon);
static int SC_ITEIntroFaireTentProc(int param, void *refCon);
+ static int SC_ITEIntroCaveDemoProc(int param, void *refCon);
private:
EventColumns *queueIntroDialogue(EventColumns *eventColumns, int n_dialogues, const IntroDialogue dialogue[]);
EventColumns *queueCredits(int delta_time, int duration, int n_credits, const IntroCredit credits[]);
int ITEIntroAnimProc(int param);
int ITEIntroCaveCommonProc(int param, int caveScene);
+ int ITEIntroCaveDemoProc(int param);
int ITEIntroValleyProc(int param);
int ITEIntroTreeHouseProc(int param);
int ITEIntroFairePathProc(int param);
diff --git a/engines/saga/script.cpp b/engines/saga/script.cpp
index 94b26c8da3..3cc6586432 100644
--- a/engines/saga/script.cpp
+++ b/engines/saga/script.cpp
@@ -977,19 +977,15 @@ void Script::opSpeak(SCRIPTOP_PARAMS) {
// now data contains last string index
-#if 0
- if (_vm->getFeatures() & GF_OLD_ITE_DOS) { // special ITE dos
+ if (_vm->getFeatures() & GF_ITE_DOS_DEMO) {
if ((_vm->_scene->currentSceneNumber() == ITE_DEFAULT_SCENE) &&
(iparam1 >= 288) && (iparam1 <= (RID_SCENE1_VOICE_END - RID_SCENE1_VOICE_START + 288))) {
sampleResourceId = RID_SCENE1_VOICE_START + iparam1 - 288;
}
} else {
-#endif
if (thread->_voiceLUT->size() > uint16(first))
sampleResourceId = (*thread->_voiceLUT)[uint16(first)];
-#if 0
}
-#endif
if (sampleResourceId < 0 || sampleResourceId > 4000)
sampleResourceId = -1;
diff --git a/engines/saga/sndres.cpp b/engines/saga/sndres.cpp
index 39578e96f0..b8d03c9c08 100644
--- a/engines/saga/sndres.cpp
+++ b/engines/saga/sndres.cpp
@@ -327,9 +327,18 @@ bool SndRes::load(ResourceContext *context, uint32 resourceId, SoundBuffer &buff
result = true;
} break;
case kSoundAIFF: {
- Audio::SeekableAudioStream *audStream = Audio::makeAIFFStream(READ_STREAM(soundResourceLength), DisposeAfterUse::YES);
- buffer.stream = audStream;
- buffer.streamLength = audStream->getLength();
+ Audio::RewindableAudioStream *audStream = Audio::makeAIFFStream(READ_STREAM(soundResourceLength), DisposeAfterUse::YES);
+ Audio::SeekableAudioStream *seekStream = dynamic_cast<Audio::SeekableAudioStream *>(audStream);
+
+ if (!seekStream) {
+ warning("AIFF file is not seekable");
+ delete audStream;
+ result = false;
+ break;
+ }
+
+ buffer.stream = seekStream;
+ buffer.streamLength = seekStream->getLength();
result = true;
} break;
case kSoundVOC: {
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index e233c4cba4..1e95393e4d 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -209,6 +209,11 @@ Console::Console(SciEngine *engine) : GUI::Debugger(),
registerCmd("bpe", WRAP_METHOD(Console, cmdBreakpointFunction)); // alias
// VM
registerCmd("script_steps", WRAP_METHOD(Console, cmdScriptSteps));
+ registerCmd("script_objects", WRAP_METHOD(Console, cmdScriptObjects));
+ registerCmd("scro", WRAP_METHOD(Console, cmdScriptObjects));
+ registerCmd("script_strings", WRAP_METHOD(Console, cmdScriptStrings));
+ registerCmd("scrs", WRAP_METHOD(Console, cmdScriptStrings));
+ registerCmd("script_said", WRAP_METHOD(Console, cmdScriptSaid));
registerCmd("vm_varlist", WRAP_METHOD(Console, cmdVMVarlist));
registerCmd("vmvarlist", WRAP_METHOD(Console, cmdVMVarlist)); // alias
registerCmd("vl", WRAP_METHOD(Console, cmdVMVarlist)); // alias
@@ -660,10 +665,33 @@ bool Console::cmdRegisters(int argc, const char **argv) {
return true;
}
+bool Console::parseResourceNumber36(const char *userParameter, uint16 &resourceNumber, uint32 &resourceTuple) {
+ int userParameterLen = strlen(userParameter);
+
+ if (userParameterLen != 10) {
+ debugPrintf("Audio36/Sync36 resource numbers must be specified as RRRNNVVCCS\n");
+ debugPrintf("where RRR is the resource number/map\n");
+ debugPrintf(" NN is the noun\n");
+ debugPrintf(" VV is the verb\n");
+ debugPrintf(" CC is the cond\n");
+ debugPrintf(" S is the seq\n");
+ return false;
+ }
+
+ // input: RRRNNVVCCS
+ resourceNumber = strtol(Common::String(userParameter, 3).c_str(), 0, 36);
+ uint16 noun = strtol(Common::String(userParameter + 3, 2).c_str(), 0, 36);
+ uint16 verb = strtol(Common::String(userParameter + 5, 2).c_str(), 0, 36);
+ uint16 cond = strtol(Common::String(userParameter + 7, 2).c_str(), 0, 36);
+ uint16 seq = strtol(Common::String(userParameter + 9, 1).c_str(), 0, 36);
+ resourceTuple = ((noun & 0xff) << 24) | ((verb & 0xff) << 16) | ((cond & 0xff) << 8) | (seq & 0xff);
+ return true;
+}
+
bool Console::cmdDiskDump(int argc, const char **argv) {
- int resNumFrom = 0;
- int resNumTo = 0;
- int resNumCur = 0;
+ bool resourceAll = false;
+ uint16 resourceNumber = 0;
+ uint32 resourceTuple = 0;
if (argc != 3) {
debugPrintf("Dumps the specified resource to disk as a patch file\n");
@@ -673,42 +701,90 @@ bool Console::cmdDiskDump(int argc, const char **argv) {
return true;
}
+ ResourceType resourceType = parseResourceType(argv[1]);
+ if (resourceType == kResourceTypeInvalid) {
+ debugPrintf("Resource type '%s' is not valid\n", argv[1]);
+ return true;
+ }
+
if (strcmp(argv[2], "*") == 0) {
- resNumFrom = 0;
- resNumTo = 65535;
+ resourceAll = true;
} else {
- resNumFrom = atoi(argv[2]);
- resNumTo = resNumFrom;
+ switch (resourceType) {
+ case kResourceTypeAudio36:
+ case kResourceTypeSync36:
+ if (!parseResourceNumber36(argv[2], resourceNumber, resourceTuple)) {
+ return true;
+ }
+ break;
+ default:
+ resourceNumber = atoi(argv[2]);
+ break;
+ }
}
- ResourceType res = parseResourceType(argv[1]);
-
- if (res == kResourceTypeInvalid)
+ if (resourceType == kResourceTypeInvalid) {
debugPrintf("Resource type '%s' is not valid\n", argv[1]);
- else {
- for (resNumCur = resNumFrom; resNumCur <= resNumTo; resNumCur++) {
- Resource *resource = _engine->getResMan()->findResource(ResourceId(res, resNumCur), 0);
- if (resource) {
- char outFileName[50];
- sprintf(outFileName, "%s.%03d", getResourceTypeName(res), resNumCur);
- Common::DumpFile *outFile = new Common::DumpFile();
- outFile->open(outFileName);
- resource->writeToStream(outFile);
- outFile->finalize();
- outFile->close();
- delete outFile;
- debugPrintf("Resource %s.%03d (located in %s) has been dumped to disk\n", argv[1], resNumCur, resource->getResourceLocation().c_str());
- } else {
- if (resNumFrom == resNumTo) {
- debugPrintf("Resource %s.%03d not found\n", argv[1], resNumCur);
- }
- }
+ return true;
+ }
+
+ if (resourceAll) {
+ // "*" used, dump everything of that type
+ Common::List<ResourceId> resources = _engine->getResMan()->listResources(resourceType, -1);
+ Common::sort(resources.begin(), resources.end());
+
+ Common::List<ResourceId>::iterator itr;
+ for (itr = resources.begin(); itr != resources.end(); ++itr) {
+ resourceNumber = itr->getNumber();
+ resourceTuple = itr->getTuple();
+ cmdDiskDumpWorker(resourceType, resourceNumber, resourceTuple);
}
+ } else {
+ // id was given, dump only this resource
+ cmdDiskDumpWorker(resourceType, resourceNumber, resourceTuple);
}
return true;
}
+void Console::cmdDiskDumpWorker(ResourceType resourceType, int resourceNumber, uint32 resourceTuple) {
+ const char *resourceTypeName = getResourceTypeName(resourceType);
+ ResourceId resourceId;
+ Resource *resource = NULL;
+ char outFileName[50];
+
+ switch (resourceType) {
+ case kResourceTypeAudio36:
+ case kResourceTypeSync36: {
+ resourceId = ResourceId(resourceType, resourceNumber, resourceTuple);
+ resource = _engine->getResMan()->findResource(resourceId, 0);
+ sprintf(outFileName, "%s", resourceId.toPatchNameBase36().c_str());
+ // patch filename is: [type:1 char] [map:3 chars] [noun:2 chars] [verb:2 chars] "." [cond: 2 chars] [seq:1 char]
+ // e.g. "@5EG0000.014"
+ break;
+ }
+ default:
+ resourceId = ResourceId(resourceType, resourceNumber);
+ resource = _engine->getResMan()->findResource(resourceId, 0);
+ sprintf(outFileName, "%s.%03d", resourceTypeName, resourceNumber);
+ // patch filename is: [resourcetype].[resourcenumber]
+ // e.g. "Script.0"
+ break;
+ }
+
+ if (resource) {
+ Common::DumpFile *outFile = new Common::DumpFile();
+ outFile->open(outFileName);
+ resource->writeToStream(outFile);
+ outFile->finalize();
+ outFile->close();
+ delete outFile;
+ debugPrintf("Resource %s (located in %s) has been dumped to disk\n", outFileName, resource->getResourceLocation().c_str());
+ } else {
+ debugPrintf("Resource %s not found\n", outFileName);
+ }
+}
+
bool Console::cmdHexDump(int argc, const char **argv) {
if (argc != 3) {
debugPrintf("Dumps the specified resource to standard output\n");
@@ -748,6 +824,77 @@ bool Console::cmdResourceId(int argc, const char **argv) {
return true;
}
+bool Console::cmdList(int argc, const char **argv) {
+ int selectedMapNumber = -1;
+ Common::List<ResourceId> resources;
+ Common::List<ResourceId>::iterator itr;
+ int displayCount = 0;
+ int currentMap = -1;
+
+ if (argc < 2) {
+ debugPrintf("Lists all the resources of a given type\n");
+ cmdResourceTypes(argc, argv);
+ return true;
+ }
+
+ ResourceType resourceType = parseResourceType(argv[1]);
+ if (resourceType == kResourceTypeInvalid) {
+ debugPrintf("Unknown resource type: '%s'\n", argv[1]);
+ return true;
+ }
+
+ switch (resourceType) {
+ case kResourceTypeAudio36:
+ case kResourceTypeSync36:
+ if (argc != 3) {
+ debugPrintf("Please specify map number (-1: all maps)\n");
+ return true;
+ }
+ selectedMapNumber = atoi(argv[2]);
+ resources = _engine->getResMan()->listResources(resourceType, selectedMapNumber);
+ Common::sort(resources.begin(), resources.end());
+
+ for (itr = resources.begin(); itr != resources.end(); ++itr) {
+ const uint16 map = itr->getNumber();
+ const uint32 resourceTuple = itr->getTuple();
+ const uint16 noun = (resourceTuple >> 24) & 0xff;
+ const uint16 verb = (resourceTuple >> 16) & 0xff;
+ const uint16 cond = (resourceTuple >> 8) & 0xff;
+ const uint16 seq = resourceTuple & 0xff;
+
+ if (currentMap != map) {
+ if (displayCount % 3)
+ debugPrintf("\n");
+ debugPrintf("Map %04x (%i):\n", map, map);
+ currentMap = map;
+ displayCount = 0;
+ }
+
+ if (displayCount % 3 == 0)
+ debugPrintf(" ");
+
+ debugPrintf("%02x %02x %02x %02x (%3i %3i %3i %3i) ", noun, verb, cond, seq, noun, verb, cond, seq);
+
+ if (++displayCount % 3 == 0)
+ debugPrintf("\n");
+ }
+ break;
+ default:
+ resources = _engine->getResMan()->listResources(resourceType);
+ Common::sort(resources.begin(), resources.end());
+
+ for (itr = resources.begin(); itr != resources.end(); ++itr) {
+ debugPrintf("%8i", itr->getNumber());
+ if (++displayCount % 10 == 0)
+ debugPrintf("\n");
+ }
+ break;
+ }
+
+ debugPrintf("\n");
+ return true;
+}
+
bool Console::cmdDissectScript(int argc, const char **argv) {
if (argc != 2) {
debugPrintf("Examines a script\n");
@@ -1124,52 +1271,6 @@ bool Console::cmdMapInstrument(int argc, const char **argv) {
return true;
}
-bool Console::cmdList(int argc, const char **argv) {
- if (argc < 2) {
- debugPrintf("Lists all the resources of a given type\n");
- cmdResourceTypes(argc, argv);
- return true;
- }
-
-
- ResourceType res = parseResourceType(argv[1]);
- if (res == kResourceTypeInvalid)
- debugPrintf("Unknown resource type: '%s'\n", argv[1]);
- else {
- int number = -1;
-
- if ((res == kResourceTypeAudio36) || (res == kResourceTypeSync36)) {
- if (argc != 3) {
- debugPrintf("Please specify map number (-1: all maps)\n");
- return true;
- }
- number = atoi(argv[2]);
- }
-
- Common::List<ResourceId> resources = _engine->getResMan()->listResources(res, number);
- Common::sort(resources.begin(), resources.end());
-
- int cnt = 0;
- Common::List<ResourceId>::iterator itr;
- for (itr = resources.begin(); itr != resources.end(); ++itr) {
- if (number == -1) {
- debugPrintf("%8i", itr->getNumber());
- if (++cnt % 10 == 0)
- debugPrintf("\n");
- } else if (number == (int)itr->getNumber()) {
- const uint32 tuple = itr->getTuple();
- debugPrintf("(%3i, %3i, %3i, %3i) ", (tuple >> 24) & 0xff, (tuple >> 16) & 0xff,
- (tuple >> 8) & 0xff, tuple & 0xff);
- if (++cnt % 4 == 0)
- debugPrintf("\n");
- }
- }
- debugPrintf("\n");
- }
-
- return true;
-}
-
bool Console::cmdSaveGame(int argc, const char **argv) {
if (argc != 2) {
debugPrintf("Saves the current game state to the hard disk\n");
@@ -2172,6 +2273,7 @@ bool Console::cmdStartSound(int argc, const char **argv) {
return true;
}
+ // TODO: Maybe also add a playBed option.
g_sci->_soundCmd->startNewSound(number);
return cmdExit(0, 0);
}
@@ -2198,9 +2300,10 @@ bool Console::cmdToggleSound(int argc, const char **argv) {
Common::String newState = argv[2];
newState.toLowercase();
- if (newState == "play")
- g_sci->_soundCmd->processPlaySound(id);
- else if (newState == "stop")
+ if (newState == "play") {
+ // Maybe also have a 'playbed' option. (Second argument to processPlaySound.)
+ g_sci->_soundCmd->processPlaySound(id, false);
+ } else if (newState == "stop")
g_sci->_soundCmd->processStopSound(id, false);
else
debugPrintf("New state can either be 'play' or 'stop'");
@@ -2730,6 +2833,186 @@ bool Console::cmdScriptSteps(int argc, const char **argv) {
return true;
}
+bool Console::cmdScriptObjects(int argc, const char **argv) {
+ int curScriptNr = -1;
+
+ if (argc < 2) {
+ debugPrintf("Shows all objects inside a specified script.\n");
+ debugPrintf("Usage: %s <script number>\n", argv[0]);
+ debugPrintf("Example: %s 999\n", argv[0]);
+ debugPrintf("<script number> may be * to show objects inside all loaded scripts\n");
+ return true;
+ }
+
+ if (strcmp(argv[1], "*") == 0) {
+ // get said-strings of all currently loaded scripts
+ curScriptNr = -1;
+ } else {
+ curScriptNr = atoi(argv[1]);
+ }
+
+ printOffsets(curScriptNr, SCI_SCR_OFFSET_TYPE_OBJECT);
+ return true;
+}
+
+bool Console::cmdScriptStrings(int argc, const char **argv) {
+ int curScriptNr = -1;
+
+ if (argc < 2) {
+ debugPrintf("Shows all strings inside a specified script.\n");
+ debugPrintf("Usage: %s <script number>\n", argv[0]);
+ debugPrintf("Example: %s 999\n", argv[0]);
+ debugPrintf("<script number> may be * to show strings inside all loaded scripts\n");
+ return true;
+ }
+
+ if (strcmp(argv[1], "*") == 0) {
+ // get strings of all currently loaded scripts
+ curScriptNr = -1;
+ } else {
+ curScriptNr = atoi(argv[1]);
+ }
+
+ printOffsets(curScriptNr, SCI_SCR_OFFSET_TYPE_STRING);
+ return true;
+}
+
+bool Console::cmdScriptSaid(int argc, const char **argv) {
+ int curScriptNr = -1;
+
+ if (argc < 2) {
+ debugPrintf("Shows all said-strings inside a specified script.\n");
+ debugPrintf("Usage: %s <script number>\n", argv[0]);
+ debugPrintf("Example: %s 999\n", argv[0]);
+ debugPrintf("<script number> may be * to show said-strings inside all loaded scripts\n");
+ return true;
+ }
+
+ if (strcmp(argv[1], "*") == 0) {
+ // get said-strings of all currently loaded scripts
+ curScriptNr = -1;
+ } else {
+ curScriptNr = atoi(argv[1]);
+ }
+
+ printOffsets(curScriptNr, SCI_SCR_OFFSET_TYPE_SAID);
+ return true;
+}
+
+void Console::printOffsets(int scriptNr, uint16 showType) {
+ SegManager *segMan = _engine->_gamestate->_segMan;
+ Vocabulary *vocab = _engine->_vocabulary;
+ SegmentId curSegmentNr;
+ Common::List<SegmentId> segmentNrList;
+
+ SegmentType curSegmentType = SEG_TYPE_INVALID;
+ SegmentObj *curSegmentObj = NULL;
+ Script *curScriptObj = NULL;
+ const byte *curScriptData = NULL;
+
+ segmentNrList.clear();
+ if (scriptNr < 0) {
+ // get offsets of all currently loaded scripts
+ for (curSegmentNr = 0; curSegmentNr < segMan->_heap.size(); curSegmentNr++) {
+ curSegmentObj = segMan->_heap[curSegmentNr];
+ if (curSegmentObj && curSegmentObj->getType() == SEG_TYPE_SCRIPT) {
+ segmentNrList.push_back(curSegmentNr);
+ }
+ }
+
+ } else {
+ curSegmentNr = segMan->getScriptSegment(scriptNr);
+ if (!curSegmentNr) {
+ debugPrintf("Script %d is currently not loaded/available\n", scriptNr);
+ return;
+ }
+ segmentNrList.push_back(curSegmentNr);
+ }
+
+ const offsetLookupArrayType *scriptOffsetLookupArray;
+ offsetLookupArrayType::const_iterator arrayIterator;
+ int showTypeCount = 0;
+
+ reg_t objectPos;
+ const char *objectNamePtr = NULL;
+ const byte *stringPtr = NULL;
+ const byte *saidPtr = NULL;
+
+ Common::List<SegmentId>::iterator it;
+ const Common::List<SegmentId>::iterator end = segmentNrList.end();
+
+ for (it = segmentNrList.begin(); it != end; it++) {
+ curSegmentNr = *it;
+ // get object of this segment
+ curSegmentObj = segMan->getSegmentObj(curSegmentNr);
+ if (!curSegmentObj)
+ continue;
+
+ curSegmentType = curSegmentObj->getType();
+ if (curSegmentType != SEG_TYPE_SCRIPT) // safety check
+ continue;
+
+ curScriptObj = (Script *)curSegmentObj;
+ debugPrintf("=== SCRIPT %d inside Segment %d ===\n", curScriptObj->getScriptNumber(), curSegmentNr);
+ debugN("=== SCRIPT %d inside Segment %d ===\n", curScriptObj->getScriptNumber(), curSegmentNr);
+
+ // now print the list
+ scriptOffsetLookupArray = curScriptObj->getOffsetArray();
+ curScriptData = curScriptObj->getBuf();
+ showTypeCount = 0;
+
+ for (arrayIterator = scriptOffsetLookupArray->begin(); arrayIterator != scriptOffsetLookupArray->end(); arrayIterator++) {
+ if (arrayIterator->type == showType) {
+ switch (showType) {
+ case SCI_SCR_OFFSET_TYPE_OBJECT:
+ objectPos = make_reg(curSegmentNr, arrayIterator->offset);
+ objectNamePtr = segMan->getObjectName(objectPos);
+ debugPrintf(" %03d:%04x: %s\n", arrayIterator->id, arrayIterator->offset, objectNamePtr);
+ debugN(" %03d:%04x: %s\n", arrayIterator->id, arrayIterator->offset, objectNamePtr);
+ break;
+ case SCI_SCR_OFFSET_TYPE_STRING:
+ stringPtr = curScriptData + arrayIterator->offset;
+ debugPrintf(" %03d:%04x: '%s' (size %d)\n", arrayIterator->id, arrayIterator->offset, stringPtr, arrayIterator->stringSize);
+ debugN(" %03d:%04x: '%s' (size %d)\n", arrayIterator->id, arrayIterator->offset, stringPtr, arrayIterator->stringSize);
+ break;
+ case SCI_SCR_OFFSET_TYPE_SAID:
+ saidPtr = curScriptData + arrayIterator->offset;
+ debugPrintf(" %03d:%04x:\n", arrayIterator->id, arrayIterator->offset);
+ debugN(" %03d:%04x: ", arrayIterator->id, arrayIterator->offset);
+ vocab->debugDecipherSaidBlock(saidPtr);
+ debugN("\n");
+ break;
+ default:
+ break;
+ }
+ showTypeCount++;
+ }
+ }
+
+ if (showTypeCount == 0) {
+ switch (showType) {
+ case SCI_SCR_OFFSET_TYPE_OBJECT:
+ debugPrintf(" no objects\n");
+ debugN(" no objects\n");
+ break;
+ case SCI_SCR_OFFSET_TYPE_STRING:
+ debugPrintf(" no strings\n");
+ debugN(" no strings\n");
+ break;
+ case SCI_SCR_OFFSET_TYPE_SAID:
+ debugPrintf(" no said-strings\n");
+ debugN(" no said-strings\n");
+ break;
+ default:
+ break;
+ }
+ }
+
+ debugPrintf("\n");
+ debugN("\n");
+ }
+}
+
bool Console::cmdBacktrace(int argc, const char **argv) {
debugPrintf("Call stack (current base: 0x%x):\n", _engine->_gamestate->executionStackBase);
Common::List<ExecStack>::const_iterator iter;
@@ -3209,6 +3492,7 @@ bool Console::cmdSend(int argc, const char **argv) {
// We call run_engine explictly so we can restore the value of r_acc
// after execution.
run_vm(_engine->_gamestate);
+ _engine->_gamestate->xs = old_xstack;
}
diff --git a/engines/sci/console.h b/engines/sci/console.h
index c8e99f78f7..8b10912fbe 100644
--- a/engines/sci/console.h
+++ b/engines/sci/console.h
@@ -68,6 +68,7 @@ private:
bool cmdSaid(int argc, const char **argv);
// Resources
bool cmdDiskDump(int argc, const char **argv);
+ void cmdDiskDumpWorker(ResourceType resourceType, int resourceNumber, uint32 resourceTuple);
bool cmdHexDump(int argc, const char **argv);
bool cmdResourceId(int argc, const char **argv);
bool cmdResourceInfo(int argc, const char **argv);
@@ -146,6 +147,9 @@ private:
bool cmdBreakpointFunction(int argc, const char **argv);
// VM
bool cmdScriptSteps(int argc, const char **argv);
+ bool cmdScriptObjects(int argc, const char **argv);
+ bool cmdScriptStrings(int argc, const char **argv);
+ bool cmdScriptSaid(int argc, const char **argv);
bool cmdVMVarlist(int argc, const char **argv);
bool cmdVMVars(int argc, const char **argv);
bool cmdStack(int argc, const char **argv);
@@ -157,6 +161,7 @@ private:
bool cmdViewAccumulatorObject(int argc, const char **argv);
bool parseInteger(const char *argument, int &result);
+ bool parseResourceNumber36(const char *userParameter, uint16 &resourceNumber, uint32 &resourceTuple);
void printBasicVarInfo(reg_t variable);
@@ -164,6 +169,7 @@ private:
void printList(List *list);
int printNode(reg_t addr);
void hexDumpReg(const reg_t *data, int len, int regsPerLine = 4, int startOffset = 0, bool isArray = false);
+ void printOffsets(int scriptNr, uint16 showType);
private:
/**
diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp
index 85ff1c0062..bac9b3467a 100644
--- a/engines/sci/detection.cpp
+++ b/engines/sci/detection.cpp
@@ -371,8 +371,8 @@ static const ADExtraGuiOptionsMap optionsList[] = {
{
GAMEOPTION_EGA_UNDITHER,
{
- _s("EGA undithering"),
- _s("Enable undithering in EGA games"),
+ _s("Skip EGA dithering pass (full color backgrounds)"),
+ _s("Skip dithering pass in EGA games, graphics are shown with full colors"),
"disable_dithering",
false
}
@@ -791,22 +791,9 @@ void SciMetaEngine::removeSaveState(const char *target, int slot) const {
}
Common::Error SciEngine::loadGameState(int slot) {
- Common::String fileName = Common::String::format("%s.%03d", _targetName.c_str(), slot);
- Common::SaveFileManager *saveFileMan = g_engine->getSaveFileManager();
- Common::SeekableReadStream *in = saveFileMan->openForLoading(fileName);
-
- if (in) {
- // found a savegame file
- gamestate_restore(_gamestate, in);
- delete in;
- }
-
- if (_gamestate->r_acc != make_reg(0, 1)) {
- return Common::kNoError;
- } else {
- warning("Restoring gamestate '%s' failed", fileName.c_str());
- return Common::kUnknownError;
- }
+ _gamestate->_delayedRestoreGameId = slot;
+ _gamestate->_delayedRestoreGame = true;
+ return Common::kNoError;
}
Common::Error SciEngine::saveGameState(int slot, const Common::String &desc) {
@@ -834,16 +821,12 @@ Common::Error SciEngine::saveGameState(int slot, const Common::String &desc) {
return Common::kNoError;
}
-// Before enabling the load option in the ScummVM menu, the main game loop must
-// have run at least once. When the game loop runs, kGameIsRestarting is invoked,
-// thus the speed throttler is initialized. Hopefully fixes bug #3565505.
-
bool SciEngine::canLoadGameStateCurrently() {
- return !_gamestate->executionStackBase && (_gamestate->_throttleLastTime > 0 || _gamestate->_throttleTrigger);
+ return !_gamestate->executionStackBase;
}
bool SciEngine::canSaveGameStateCurrently() {
- return !_gamestate->executionStackBase && (_gamestate->_throttleLastTime > 0 || _gamestate->_throttleTrigger);
+ return !_gamestate->executionStackBase;
}
} // End of namespace Sci
diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h
index d6bdef946b..55305c4b42 100644
--- a/engines/sci/detection_tables.h
+++ b/engines/sci/detection_tables.h
@@ -904,16 +904,14 @@ static const struct ADGameDescription SciGameDescriptions[] = {
AD_LISTEND},
Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
-#if 0 // TODO: unknown if these files are corrupt
- // Hoyle 1 - English Amiga (from www.back2roots.org)
- // SCI interpreter version 0.000.519 - FIXME: some have 0.000.530, others x.yyy.zzz
+ // Hoyle 1 - English Amiga (from www.back2roots.org - verified by waltervn in bug report #6870)
+ // Game version 1.000.139, SCI interpreter version x.yyy.zzz
{"hoyle1", "", {
{"resource.map", 0, "2a72b1aba65fa6e339370eb86d8601d1", 5166},
{"resource.001", 0, "e0dd44069a62a463fd124974b915f10d", 218755},
{"resource.002", 0, "e0dd44069a62a463fd124974b915f10d", 439502},
AD_LISTEND},
Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
-#endif
// Hoyle 2 - English DOS
// SCI interpreter version 0.000.572
@@ -1552,6 +1550,17 @@ static const struct ADGameDescription SciGameDescriptions[] = {
AD_LISTEND},
Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ // King's Quest 6 - English DOS Playable CD "Sneak Peaks" Demo (first island fully playable)
+ // (supplied by KQ5 G5 in bug report #6824)
+ // Executable scanning reports "1.cfs.158 Not a release version", VERSION file reports "1.000.000"
+ // SCI interpreter version ???
+ {"kq6", "Demo/CD", {
+ {"resource.000", 0, "233394a5f33b475ae5975e7e9a420865", 8345598},
+ {"resource.map", 0, "eb9e177281b7cde188dc0d83194cd365", 8960},
+ {"resource.msg", 0, "3cf5de44de36191f109d425b8450efc8", 259510},
+ AD_LISTEND},
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_CD | ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+
// King's Quest 6 - English DOS Floppy
// SCI interpreter version 1.001.054
{"kq6", "", {
@@ -2069,6 +2078,20 @@ static const struct ADGameDescription SciGameDescriptions[] = {
AD_LISTEND},
Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ // Larry 3 - German DOS (German+English, 5 1/4" floppies)
+ // SCI interpreter version S.old.114 (executable), VERSION is "1.056"
+ {"lsl3", "", {
+ {"resource.map", 0, "2468da5d664bb6ca3df866074a05e43c", 8910},
+ {"resource.001", 0, "3827a9b17b926e12dcc336860f50612a", 163326},
+ {"resource.002", 0, "3827a9b17b926e12dcc336860f50612a", 312436},
+ {"resource.003", 0, "3827a9b17b926e12dcc336860f50612a", 347307},
+ {"resource.004", 0, "3827a9b17b926e12dcc336860f50612a", 332369},
+ {"resource.005", 0, "3827a9b17b926e12dcc336860f50612a", 347654},
+ {"resource.006", 0, "3827a9b17b926e12dcc336860f50612a", 326011},
+ {"resource.007", 0, "3827a9b17b926e12dcc336860f50612a", 309553},
+ AD_LISTEND},
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+
// Larry 3 - French DOS (provided by richiefs in bug report #2670691, also includes english language)
// Executable scanning reports "S.old.123"
// SCI interpreter version 0.000.572 (just a guess)
@@ -2422,6 +2445,16 @@ static const struct ADGameDescription SciGameDescriptions[] = {
AD_LISTEND},
Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ // Lighthouse - Japanese DOS (from m_kiewitz)
+ // Executable scanning reports "3.000.000", VERSION file reports "1.0C"
+ {"lighthouse", "", {
+ {"resmap.001", 0, "18e0ac1597fe1cf6dc663118fe983e3b", 7885},
+ {"ressci.001", 0, "14e922c47b92156377cb49e241691792", 99573473},
+ {"resmap.002", 0, "723fc742c623d8933e5753a264324cb0", 7657},
+ {"ressci.002", 0, "175468431a979b9f317c294ce3bc1430", 94627469},
+ AD_LISTEND},
+ Common::JA_JPN, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+
// Lighthouse - Spanish DOS (from jvprat)
// Executable scanning reports "3.000.000", VERSION file reports "1.1"
{"lighthouse", "", {
diff --git a/engines/sci/engine/file.cpp b/engines/sci/engine/file.cpp
index 2ba7d15ac0..623caec856 100644
--- a/engines/sci/engine/file.cpp
+++ b/engines/sci/engine/file.cpp
@@ -252,6 +252,9 @@ void DirSeeker::addAsVirtualFiles(Common::String title, Common::String fileMask)
Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager();
Common::StringArray foundFiles = saveFileMan->listSavefiles(fileMask);
if (!foundFiles.empty()) {
+ // Sort all filenames alphabetically
+ Common::sort(foundFiles.begin(), foundFiles.end());
+
_files.push_back(title);
_virtualFiles.push_back("");
Common::StringArray::iterator it;
diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp
index 2b16bb3d99..bfb7bfcd08 100644
--- a/engines/sci/engine/kernel.cpp
+++ b/engines/sci/engine/kernel.cpp
@@ -432,57 +432,66 @@ static const SignatureDebugType signatureDebugTypeList[] = {
{ 0, NULL }
};
-static void kernelSignatureDebugType(const uint16 type) {
+static void kernelSignatureDebugType(Common::String &signatureDetailsStr, const uint16 type) {
bool firstPrint = true;
const SignatureDebugType *list = signatureDebugTypeList;
while (list->typeCheck) {
if (type & list->typeCheck) {
if (!firstPrint)
- debugN(", ");
- debugN("%s", list->text);
+// debugN(", ");
+ signatureDetailsStr += ", ";
+// debugN("%s", list->text);
+// signatureDetailsStr += signatureDetailsStr.format("%s", list->text);
+ signatureDetailsStr += list->text;
firstPrint = false;
}
list++;
}
}
-// Shows kernel call signature and current arguments for debugging purposes
-void Kernel::signatureDebug(const uint16 *sig, int argc, const reg_t *argv) {
+// Create string, that holds the details of a kernel call signature and current arguments
+// For debugging purposes
+void Kernel::signatureDebug(Common::String &signatureDetailsStr, const uint16 *sig, int argc, const reg_t *argv) {
int argnr = 0;
+
+ // add ERROR: to debug output
+ debugN("ERROR:");
+
while (*sig || argc) {
- debugN("parameter %d: ", argnr++);
+ // add leading spaces for additional parameters
+ signatureDetailsStr += signatureDetailsStr.format("parameter %d: ", argnr++);
if (argc) {
reg_t parameter = *argv;
- debugN("%04x:%04x (", PRINT_REG(parameter));
+ signatureDetailsStr += signatureDetailsStr.format("%04x:%04x (", PRINT_REG(parameter));
int regType = findRegType(parameter);
if (regType)
- kernelSignatureDebugType(regType);
+ kernelSignatureDebugType(signatureDetailsStr, regType);
else
- debugN("unknown type of %04x:%04x", PRINT_REG(parameter));
- debugN(")");
+ signatureDetailsStr += signatureDetailsStr.format("unknown type of %04x:%04x", PRINT_REG(parameter));
+ signatureDetailsStr += ")";
argv++;
argc--;
} else {
- debugN("not passed");
+ signatureDetailsStr += "not passed";
}
if (*sig) {
const uint16 signature = *sig;
if ((signature & SIG_MAYBE_ANY) == SIG_MAYBE_ANY) {
- debugN(", may be any");
+ signatureDetailsStr += ", may be any";
} else {
- debugN(", should be ");
- kernelSignatureDebugType(signature);
+ signatureDetailsStr += ", should be ";
+ kernelSignatureDebugType(signatureDetailsStr, signature);
}
if (signature & SIG_IS_OPTIONAL)
- debugN(" (optional)");
+ signatureDetailsStr += " (optional)";
if (signature & SIG_NEEDS_MORE)
- debugN(" (needs more)");
+ signatureDetailsStr += " (needs more)";
if (signature & SIG_MORE_MAY_FOLLOW)
- debugN(" (more may follow)");
+ signatureDetailsStr += " (more may follow)";
sig++;
}
- debugN("\n");
+ signatureDetailsStr += "\n";
}
}
diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h
index a65bcb7df5..57b4d9455b 100644
--- a/engines/sci/engine/kernel.h
+++ b/engines/sci/engine/kernel.h
@@ -186,7 +186,7 @@ public:
bool signatureMatch(const uint16 *sig, int argc, const reg_t *argv);
// Prints out debug information in case a signature check fails
- void signatureDebug(const uint16 *sig, int argc, const reg_t *argv);
+ void signatureDebug(Common::String &signatureDetails, const uint16 *sig, int argc, const reg_t *argv);
/**
* Determines the type of the object indicated by reg.
diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h
index 0c2fd4e3ea..2cbd79366d 100644
--- a/engines/sci/engine/kernel_tables.h
+++ b/engines/sci/engine/kernel_tables.h
@@ -105,10 +105,6 @@ static const SciKernelMapSubEntry kDoSound_subops[] = {
{ SIG_SOUNDSCI1EARLY, 5, MAP_CALL(DoSoundInit), NULL, NULL },
{ SIG_SOUNDSCI1EARLY, 6, MAP_CALL(DoSoundDispose), NULL, NULL },
{ SIG_SOUNDSCI1EARLY, 7, MAP_CALL(DoSoundPlay), "oi", NULL },
- // ^^ TODO: In SCI1-SCI1.1 DoSound (play) is called by 2 methods of the Sound object: play and
- // playBed. The methods are the same, apart from the second integer parameter: it's 0 in
- // play and 1 in playBed, to distinguish the caller. It's passed on, we should find out what
- // it actually does internally
{ SIG_SOUNDSCI1EARLY, 8, MAP_CALL(DoSoundStop), NULL, NULL },
{ SIG_SOUNDSCI1EARLY, 9, MAP_CALL(DoSoundPause), "[o0]i", NULL },
{ SIG_SOUNDSCI1EARLY, 10, MAP_CALL(DoSoundFade), "oiiii", kDoSoundFade_workarounds },
diff --git a/engines/sci/engine/kevent.cpp b/engines/sci/engine/kevent.cpp
index cb81da2279..8e16e0a07a 100644
--- a/engines/sci/engine/kevent.cpp
+++ b/engines/sci/engine/kevent.cpp
@@ -24,9 +24,10 @@
#include "sci/sci.h"
#include "sci/engine/features.h"
-#include "sci/engine/state.h"
-#include "sci/engine/selector.h"
#include "sci/engine/kernel.h"
+#include "sci/engine/savegame.h"
+#include "sci/engine/selector.h"
+#include "sci/engine/state.h"
#include "sci/console.h"
#include "sci/debug.h" // for g_debug_simulated_key
#include "sci/event.h"
@@ -71,9 +72,15 @@ reg_t kGetEvent(EngineState *s, int argc, reg_t *argv) {
g_debug_simulated_key = 0;
return make_reg(0, 1);
}
-
+
curEvent = g_sci->getEventManager()->getSciEvent(mask);
+ if (s->_delayedRestoreGame) {
+ // delayed restore game from ScummVM menu got triggered
+ gamestate_delayedrestore(s);
+ return NULL_REG;
+ }
+
// For a real event we use its associated mouse position
mousePos = curEvent.mousePos;
#ifdef ENABLE_SCI32
diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp
index c56eb09482..61ac76d0a7 100644
--- a/engines/sci/engine/kfile.cpp
+++ b/engines/sci/engine/kfile.cpp
@@ -933,6 +933,11 @@ reg_t kRestoreGame(EngineState *s, int argc, reg_t *argv) {
g_sci->_gfxMenu->kernelSetAttribute(1025 >> 8, 1025 & 0xFF, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Status -> Statistics
g_sci->_gfxMenu->kernelSetAttribute(1026 >> 8, 1026 & 0xFF, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Status -> Goals
break;
+ case GID_PQ2:
+ // HACK: Same as above - enable the save game menu option when loading in PQ2 (bug #6875).
+ // It gets disabled in the game's death screen.
+ g_sci->_gfxMenu->kernelSetAttribute(2, 1, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Game -> Save Game
+ break;
default:
break;
}
diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp
index ee2249bd9d..8b790e6a58 100644
--- a/engines/sci/engine/kgraphics.cpp
+++ b/engines/sci/engine/kgraphics.cpp
@@ -32,6 +32,7 @@
#include "sci/event.h"
#include "sci/resource.h"
#include "sci/engine/features.h"
+#include "sci/engine/savegame.h"
#include "sci/engine/state.h"
#include "sci/engine/selector.h"
#include "sci/engine/kernel.h"
@@ -400,6 +401,12 @@ reg_t kWait(EngineState *s, int argc, reg_t *argv) {
s->wait(sleep_time);
+ if (s->_delayedRestoreGame) {
+ // delayed restore game from ScummVM menu got triggered
+ gamestate_delayedrestore(s);
+ return NULL_REG;
+ }
+
return s->r_acc;
}
@@ -955,8 +962,9 @@ reg_t kDrawControl(EngineState *s, int argc, reg_t *argv) {
reg_t textReference = readSelector(s->_segMan, controlObject, SELECTOR(text));
if (!textReference.isNull()) {
Common::String text = s->_segMan->getString(textReference);
- if ((text == "a:hq1_hero.sav") || (text == "a:glory1.sav") || (text == "a:glory2.sav") || (text == "a:glory3.sav")) {
+ if ((text == "a:hq1_hero.sav") || (text == "a:glory1.sav") || (text == "a:glory2.sav") || (text == "a:glory3.sav") || (text == "a:gloire3.sauv")) {
// Remove "a:" from hero quest / quest for glory export default filenames
+ // The french version of Quest For Glory 3 uses "gloire3.sauv". It seems a translator translated the filename.
text.deleteChar(0);
text.deleteChar(0);
s->_segMan->strcpy(textReference, text.c_str());
diff --git a/engines/sci/engine/kmovement.cpp b/engines/sci/engine/kmovement.cpp
index 51d49eea9f..9b83dbc52d 100644
--- a/engines/sci/engine/kmovement.cpp
+++ b/engines/sci/engine/kmovement.cpp
@@ -305,12 +305,23 @@ reg_t kDoBresen(EngineState *s, int argc, reg_t *argv) {
for (uint i = 0; i < clientVarNum; ++i)
clientBackup[i] = clientObject->getVariable(i);
- if (mover_xAxis) {
- if (ABS(mover_x - client_x) < ABS(mover_dx))
- completed = true;
+ if ((getSciVersion() <= SCI_VERSION_1_EGA_ONLY)) {
+ if (mover_xAxis) {
+ if (ABS(mover_x - client_x) < ABS(mover_dx))
+ completed = true;
+ } else {
+ if (ABS(mover_y - client_y) < ABS(mover_dy))
+ completed = true;
+ }
} else {
- if (ABS(mover_y - client_y) < ABS(mover_dy))
- completed = true;
+ // SCI1EARLY+ code
+ if (mover_xAxis) {
+ if (ABS(mover_x - client_x) <= ABS(mover_dx))
+ completed = true;
+ } else {
+ if (ABS(mover_y - client_y) <= ABS(mover_dy))
+ completed = true;
+ }
}
if (completed) {
client_x = mover_x;
@@ -336,10 +347,10 @@ reg_t kDoBresen(EngineState *s, int argc, reg_t *argv) {
bool collision = false;
reg_t cantBeHere = NULL_REG;
+ // adding this here for hoyle 3 to get happy. CantBeHere is a dummy in hoyle 3 and acc is != 0 so we would
+ // get a collision otherwise. Resetting the result was always done in SSCI
+ s->r_acc = NULL_REG;
if (SELECTOR(cantBeHere) != -1) {
- // adding this here for hoyle 3 to get happy. CantBeHere is a dummy in hoyle 3 and acc is != 0 so we would
- // get a collision otherwise
- s->r_acc = NULL_REG;
invokeSelector(s, client, SELECTOR(cantBeHere), argc, argv);
if (!s->r_acc.isNull())
collision = true;
diff --git a/engines/sci/engine/kparse.cpp b/engines/sci/engine/kparse.cpp
index aa89b963cc..f85f33e3e8 100644
--- a/engines/sci/engine/kparse.cpp
+++ b/engines/sci/engine/kparse.cpp
@@ -117,6 +117,8 @@ reg_t kParse(EngineState *s, int argc, reg_t *argv) {
}
#endif
+ voc->replacePronouns(words);
+
int syntax_fail = voc->parseGNF(words);
if (syntax_fail) {
@@ -130,6 +132,7 @@ reg_t kParse(EngineState *s, int argc, reg_t *argv) {
} else {
voc->parserIsValid = true;
+ voc->storePronounReference();
writeSelectorValue(segMan, event, SELECTOR(claimed), 0);
#ifdef DEBUG_PARSER
diff --git a/engines/sci/engine/kvideo.cpp b/engines/sci/engine/kvideo.cpp
index 319469cb08..f925111fc9 100644
--- a/engines/sci/engine/kvideo.cpp
+++ b/engines/sci/engine/kvideo.cpp
@@ -123,6 +123,8 @@ void playVideo(Video::VideoDecoder *videoDecoder, VideoState videoState) {
if ((event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE) || event.type == Common::EVENT_LBUTTONUP)
skipVideo = true;
}
+ if (g_sci->getEngineState()->_delayedRestoreGame)
+ skipVideo = true;
g_system->delayMillis(10);
}
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index 0b55425406..93b3a997cc 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -20,6 +20,7 @@
*
*/
+#include "common/savefile.h"
#include "common/stream.h"
#include "common/system.h"
#include "common/func.h"
@@ -40,6 +41,7 @@
#include "sci/graphics/helpers.h"
#include "sci/graphics/palette.h"
#include "sci/graphics/ports.h"
+#include "sci/graphics/screen.h"
#include "sci/parser/vocabulary.h"
#include "sci/sound/audio.h"
#include "sci/sound/music.h"
@@ -132,13 +134,6 @@ void SegManager::saveLoadWithSerializer(Common::Serializer &s) {
// Reset _scriptSegMap, to be restored below
_scriptSegMap.clear();
-
-#ifdef ENABLE_SCI32
- // Clear any planes/screen items currently showing so they
- // don't show up after the load.
- if (getSciVersion() >= SCI_VERSION_2)
- g_sci->_gfxFrameout->clear();
-#endif
}
s.skip(4, VER(14), VER(18)); // OBSOLETE: Used to be _exportsAreWide
@@ -617,6 +612,14 @@ void MusicEntry::saveLoadWithSerializer(Common::Serializer &s) {
s.syncAsSint32LE(fadeTicker);
s.syncAsSint32LE(fadeTickerStep);
s.syncAsByte(status);
+ if (s.getVersion() >= 32)
+ s.syncAsByte(playBed);
+ else if (s.isLoading())
+ playBed = false;
+ if (s.getVersion() >= 33)
+ s.syncAsByte(overridePriority);
+ else if (s.isLoading())
+ overridePriority = false;
// pMidiParser and pStreamAud will be initialized when the
// sound list is reconstructed in gamestate_restore()
@@ -635,8 +638,12 @@ void SoundCommandParser::syncPlayList(Common::Serializer &s) {
void SoundCommandParser::reconstructPlayList() {
Common::StackLock lock(_music->_mutex);
- const MusicList::iterator end = _music->getPlayListEnd();
- for (MusicList::iterator i = _music->getPlayListStart(); i != end; ++i) {
+ // We store all songs here because starting songs may re-shuffle their order
+ MusicList songs;
+ for (MusicList::iterator i = _music->getPlayListStart(); i != _music->getPlayListEnd(); ++i)
+ songs.push_back(*i);
+
+ for (MusicList::iterator i = songs.begin(); i != songs.end(); ++i) {
initSoundResource(*i);
if ((*i)->status == kSoundPlaying) {
@@ -650,7 +657,7 @@ void SoundCommandParser::reconstructPlayList() {
if (_soundVersion >= SCI_VERSION_1_EARLY)
writeSelectorValue(_segMan, (*i)->soundObj, SELECTOR(vol), (*i)->volume);
- processPlaySound((*i)->soundObj);
+ processPlaySound((*i)->soundObj, (*i)->playBed);
}
}
}
@@ -715,9 +722,7 @@ void GfxPalette::saveLoadWithSerializer(Common::Serializer &s) {
}
void GfxPorts::saveLoadWithSerializer(Common::Serializer &s) {
- if (s.isLoading())
- reset(); // remove all script generated windows
-
+ // reset() is called directly way earlier in gamestate_restore()
if (s.getVersion() >= 27) {
uint windowCount = 0;
uint id = PORTS_FIRSTSCRIPTWINDOWID;
@@ -760,10 +765,17 @@ void GfxPorts::saveLoadWithSerializer(Common::Serializer &s) {
if (window->counterTillFree) {
_freeCounter++;
} else {
- if (window->wndStyle & SCI_WINDOWMGR_STYLE_TOPMOST)
- _windowList.push_front(window);
- else
- _windowList.push_back(window);
+ // we don't put the saved script windows into _windowList[], so that they aren't used
+ // by kernel functions. This is important and would cause issues otherwise.
+ // see Conquests of Camelot - bug #6744 - when saving on the map screen (room 103),
+ // restoring would result in a black window in place
+ // where the area name was displayed before
+ // In Sierra's SCI the behaviour is identical to us
+ // Sierra's SCI won't show those windows after restoring
+ // If this should cause issues in another game, we would have to add a flag to simply
+ // avoid any drawing operations for such windows
+ // We still have to restore script windows, because for example Conquests of Camelot
+ // will immediately delete windows, that were created before saving the game.
}
windowCount--;
@@ -853,6 +865,22 @@ bool gamestate_save(EngineState *s, Common::WriteStream *fh, const Common::Strin
extern void showScummVMDialog(const Common::String &message);
+void gamestate_delayedrestore(EngineState *s) {
+ Common::String fileName = g_sci->getSavegameName(s->_delayedRestoreGameId);
+ Common::SeekableReadStream *in = g_sci->getSaveFileManager()->openForLoading(fileName);
+
+ if (in) {
+ // found a savegame file
+ gamestate_restore(s, in);
+ delete in;
+ if (s->r_acc != make_reg(0, 1)) {
+ return;
+ }
+ }
+
+ error("Restoring gamestate '%s' failed", fileName.c_str());
+}
+
void gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) {
SavegameMetadata meta;
@@ -889,6 +917,20 @@ void gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) {
// We don't need the thumbnail here, so just read it and discard it
Graphics::skipThumbnail(*fh);
+ // reset ports is one of the first things we do, because that may free() some hunk memory
+ // and we don't want to do that after we read in the saved game hunk memory
+ if (g_sci->_gfxPorts)
+ g_sci->_gfxPorts->reset();
+ // clear screen
+ if (g_sci->_gfxScreen)
+ g_sci->_gfxScreen->clearForRestoreGame();
+#ifdef ENABLE_SCI32
+ // Also clear any SCI32 planes/screen items currently showing so they
+ // don't show up after the load.
+ if (getSciVersion() >= SCI_VERSION_2)
+ g_sci->_gfxFrameout->clear();
+#endif
+
s->reset(true);
s->saveLoadWithSerializer(ser); // FIXME: Error handling?
diff --git a/engines/sci/engine/savegame.h b/engines/sci/engine/savegame.h
index 8f2835654b..5512b90fa8 100644
--- a/engines/sci/engine/savegame.h
+++ b/engines/sci/engine/savegame.h
@@ -37,6 +37,8 @@ struct EngineState;
*
* Version - new/changed feature
* =============================
+ * 33 - new overridePriority flag in MusicEntry
+ * 32 - new playBed flag in MusicEntry
* 31 - priority for sound effects/music is now a signed int16, instead of a byte
* 30 - synonyms
* 29 - system strings
@@ -56,7 +58,7 @@ struct EngineState;
*/
enum {
- CURRENT_SAVEGAME_VERSION = 31,
+ CURRENT_SAVEGAME_VERSION = 33,
MINIMUM_SAVEGAME_VERSION = 14
};
@@ -72,7 +74,6 @@ struct SavegameMetadata {
uint16 script0Size;
};
-
/**
* Saves a game state to the hard disk in a portable way.
* @param s The state to save
@@ -82,6 +83,9 @@ struct SavegameMetadata {
*/
bool gamestate_save(EngineState *s, Common::WriteStream *save, const Common::String &savename, const Common::String &version);
+// does a delayed saved game restore, used by ScummVM game menu - see detection.cpp / SciEngine::loadGameState()
+void gamestate_delayedrestore(EngineState *s);
+
/**
* Restores a game state from a directory.
* @param s An older state from the same game
diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp
index 2fe1aba975..36e33ccfa6 100644
--- a/engines/sci/engine/script.cpp
+++ b/engines/sci/engine/script.cpp
@@ -20,6 +20,7 @@
*
*/
+#include "sci/console.h"
#include "sci/sci.h"
#include "sci/resource.h"
#include "sci/util.h"
@@ -64,6 +65,11 @@ void Script::freeScript() {
_lockers = 1;
_markedAsDeleted = false;
_objects.clear();
+
+ _offsetLookupArray.clear();
+ _offsetLookupObjectCount = 0;
+ _offsetLookupStringCount = 0;
+ _offsetLookupSaidCount = 0;
}
void Script::load(int script_nr, ResourceManager *resMan, ScriptPatcher *scriptPatcher) {
@@ -115,8 +121,8 @@ void Script::load(int script_nr, ResourceManager *resMan, ScriptPatcher *scriptP
//
// TODO: Remove this once such a mechanism is in place
if (script->size > 65535)
- error("TODO: SCI script %d is over 64KB - it's %d bytes long. This can't "
- "be handled at the moment, thus stopping", script_nr, script->size);
+ warning("TODO: SCI script %d is over 64KB - it's %d bytes long. This can't "
+ "be fully handled at the moment", script_nr, script->size);
}
uint extraLocalsWorkaround = 0;
@@ -136,9 +142,6 @@ void Script::load(int script_nr, ResourceManager *resMan, ScriptPatcher *scriptP
assert(_bufSize >= script->size);
memcpy(_buf, script->data, script->size);
- // Check scripts for matching signatures and patch those, if found
- scriptPatcher->processScript(_nr, _buf, script->size);
-
if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1) {
Resource *heap = resMan->findResource(ResourceId(kResourceTypeHeap, _nr), 0);
assert(heap != 0);
@@ -149,6 +152,9 @@ void Script::load(int script_nr, ResourceManager *resMan, ScriptPatcher *scriptP
memcpy(_heapStart, heap->data, heap->size);
}
+ // Check scripts (+ possibly SCI 1.1 heap) for matching signatures and patch those, if found
+ scriptPatcher->processScript(_nr, _buf, _bufSize);
+
if (getSciVersion() <= SCI_VERSION_1_LATE) {
_exportTable = (const uint16 *)findBlockSCI0(SCI_OBJ_EXPORTS);
if (_exportTable) {
@@ -204,6 +210,397 @@ void Script::load(int script_nr, ResourceManager *resMan, ScriptPatcher *scriptP
//_localsCount = (_bufSize - _localsOffset) >> 1;
}
}
+
+ // find all strings of this script
+ identifyOffsets();
+}
+
+void Script::identifyOffsets() {
+ offsetLookupArrayEntry arrayEntry;
+ const byte *scriptDataPtr = NULL;
+ const byte *stringStartPtr = NULL;
+ const byte *stringDataPtr = NULL;
+ uint32 scriptDataLeft = 0;
+ uint32 stringDataLeft = 0;
+ byte stringDataByte = 0;
+ uint16 typeObject_id = 0;
+ uint16 typeString_id = 0;
+ uint16 typeSaid_id = 0;
+
+ uint16 blockType = 0;
+ uint16 blockSize = 0;
+
+ _offsetLookupArray.clear();
+ _offsetLookupObjectCount = 0;
+ _offsetLookupStringCount = 0;
+ _offsetLookupSaidCount = 0;
+
+ if (getSciVersion() < SCI_VERSION_1_1) {
+ // SCI0 + SCI1
+ scriptDataPtr = _buf;
+ scriptDataLeft = _bufSize;
+
+ // Go through all blocks
+ if (getSciVersion() == SCI_VERSION_0_EARLY) {
+ if (scriptDataLeft < 2)
+ error("Script::identifyOffsets(): unexpected end of script %d", _nr);
+ scriptDataPtr += 2;
+ scriptDataLeft -= 2;
+ }
+
+ do {
+ if (scriptDataLeft < 2)
+ error("Script::identifyOffsets(): unexpected end of script %d", _nr);
+
+ blockType = READ_LE_UINT16(scriptDataPtr);
+ scriptDataPtr += 2;
+ scriptDataLeft -= 2;
+ if (blockType == 0) // end of blocks detected
+ break;
+
+ if (scriptDataLeft < 2)
+ error("Script::identifyOffsets(): unexpected end of script %d", _nr);
+
+ blockSize = READ_LE_UINT16(scriptDataPtr);
+ if (blockSize < 4)
+ error("Script::identifyOffsets(): invalid block size in script %d", _nr);
+ blockSize -= 4; // block size includes block-type UINT16 and block-size UINT16
+ scriptDataPtr += 2;
+ scriptDataLeft -= 2;
+
+ if (scriptDataLeft < blockSize)
+ error("Script::identifyOffsets(): invalid block size in script %d", _nr);
+
+ switch (blockType) {
+ case SCI_OBJ_OBJECT:
+ case SCI_OBJ_CLASS:
+ typeObject_id++;
+ arrayEntry.type = SCI_SCR_OFFSET_TYPE_OBJECT;
+ arrayEntry.id = typeObject_id;
+ arrayEntry.offset = scriptDataPtr - _buf + 8; // Calculate offset inside script data (VM uses +8)
+ arrayEntry.stringSize = 0;
+ _offsetLookupArray.push_back(arrayEntry);
+ _offsetLookupObjectCount++;
+ break;
+
+ case SCI_OBJ_STRINGS:
+ // string block detected, we now grab all NUL terminated strings out of this block
+ stringDataPtr = scriptDataPtr;
+ stringDataLeft = blockSize;
+
+ arrayEntry.type = SCI_SCR_OFFSET_TYPE_STRING;
+
+ do {
+ if (stringDataLeft < 1) // no more bytes left
+ break;
+
+ stringStartPtr = stringDataPtr;
+
+ if (stringDataLeft == 1) {
+ // only 1 byte left and that byte is a [00], in that case we also exit
+ stringDataByte = *stringStartPtr;
+ if (stringDataByte == 0x00)
+ break;
+ }
+
+ // now look for terminating [NUL]
+ do {
+ stringDataByte = *stringDataPtr;
+ stringDataPtr++;
+ stringDataLeft--;
+ if (!stringDataByte) // NUL found, exit this loop
+ break;
+ if (stringDataLeft < 1) {
+ // no more bytes left
+ warning("Script::identifyOffsets(): string without terminating NUL in script %d", _nr);
+ break;
+ }
+ } while (1);
+
+ if (stringDataByte)
+ break;
+
+ typeString_id++;
+ arrayEntry.id = typeString_id;
+ arrayEntry.offset = stringStartPtr - _buf; // Calculate offset inside script data
+ arrayEntry.stringSize = stringDataPtr - stringStartPtr;
+ _offsetLookupArray.push_back(arrayEntry);
+ _offsetLookupStringCount++;
+ } while (1);
+ break;
+
+ case SCI_OBJ_SAID:
+ // said block detected, we now try to find every single said "string" inside this block
+ // said strings are terminated with a 0xFF, the string itself may contain words (2 bytes), where
+ // the second byte of a word may also be a 0xFF.
+ stringDataPtr = scriptDataPtr;
+ stringDataLeft = blockSize;
+
+ arrayEntry.type = SCI_SCR_OFFSET_TYPE_SAID;
+
+ do {
+ if (stringDataLeft < 1) // no more bytes left
+ break;
+
+ stringStartPtr = stringDataPtr;
+ if (stringDataLeft == 1) {
+ // only 1 byte left and that byte is a [00], in that case we also exit
+ // happens in some scripts, for example Conquests of Camelot, script 997
+ // may have been a bug in the compiler or just an intentional filler byte
+ stringDataByte = *stringStartPtr;
+ if (stringDataByte == 0x00)
+ break;
+ }
+
+ // now look for terminating 0xFF
+ do {
+ stringDataByte = *stringDataPtr;
+ stringDataPtr++;
+ stringDataLeft--;
+ if (stringDataByte == 0xFF) // Terminator found, exit this loop
+ break;
+ if (stringDataLeft < 1) // no more bytes left
+ error("Script::identifyOffsets(): said-string without terminator in script %d", _nr);
+ if (stringDataByte < 0xF0) {
+ // Part of a word, skip second byte
+ stringDataPtr++;
+ stringDataLeft--;
+ if (stringDataLeft < 1) // no more bytes left
+ error("Script::identifyOffsets(): said-string without terminator in script %d", _nr);
+ }
+ } while (1);
+
+ typeSaid_id++;
+ arrayEntry.id = typeSaid_id;
+ arrayEntry.offset = stringStartPtr - _buf; // Calculate offset inside script data
+ arrayEntry.stringSize = 0;
+ _offsetLookupArray.push_back(arrayEntry);
+ _offsetLookupSaidCount++;
+ } while (1);
+ break;
+
+ default:
+ break;
+ }
+
+ scriptDataPtr += blockSize;
+ scriptDataLeft -= blockSize;
+ } while (1);
+
+ } else if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1) {
+ // Strings in SCI1.1 up to SCI2 come after the object instances
+ scriptDataPtr = _heapStart;
+ scriptDataLeft = _heapSize;
+
+ if (scriptDataLeft < 4)
+ error("Script::identifyOffsets(): unexpected end of script in script %d", _nr);
+
+ uint16 endOfStringOffset = READ_SCI11ENDIAN_UINT16(scriptDataPtr);
+ uint16 objectStartOffset = READ_SCI11ENDIAN_UINT16(scriptDataPtr + 2) * 2 + 4;
+
+ if (scriptDataLeft < objectStartOffset)
+ error("Script::identifyOffsets(): object start is beyond heap size in script %d", _nr);
+ if (scriptDataLeft < endOfStringOffset)
+ error("Script::identifyOffsets(): end of string is beyond heap size in script %d", _nr);
+
+ const byte *endOfStringPtr = scriptDataPtr + endOfStringOffset;
+
+ scriptDataPtr += objectStartOffset;
+ scriptDataLeft -= objectStartOffset;
+
+ // go through all objects
+ do {
+ if (scriptDataLeft < 2)
+ error("Script::identifyOffsets(): unexpected end of script %d", _nr);
+
+ blockType = READ_SCI11ENDIAN_UINT16(scriptDataPtr);
+ scriptDataPtr += 2;
+ scriptDataLeft -= 2;
+ if (blockType != SCRIPT_OBJECT_MAGIC_NUMBER)
+ break;
+
+ // Object found, add offset of object
+ typeObject_id++;
+ arrayEntry.type = SCI_SCR_OFFSET_TYPE_OBJECT;
+ arrayEntry.id = typeObject_id;
+ arrayEntry.offset = scriptDataPtr - _buf - 2; // the VM uses a pointer to the Magic-Number
+ arrayEntry.stringSize = 0;
+ _offsetLookupArray.push_back(arrayEntry);
+ _offsetLookupObjectCount++;
+
+ if (scriptDataLeft < 2)
+ error("Script::identifyOffsets(): unexpected end of script in script %d", _nr);
+
+ blockSize = READ_SCI11ENDIAN_UINT16(scriptDataPtr) * 2;
+ if (blockSize < 4)
+ error("Script::identifyOffsets(): invalid block size in script %d", _nr);
+ scriptDataPtr += 2;
+ scriptDataLeft -= 2;
+ blockSize -= 4; // blocksize contains UINT16 type and UINT16 size
+ if (scriptDataLeft < blockSize)
+ error("Script::identifyOffsets(): invalid block size in script %d", _nr);
+
+ scriptDataPtr += blockSize;
+ scriptDataLeft -= blockSize;
+ } while (1);
+
+ // now scriptDataPtr points to right at the start of the strings
+ if (scriptDataPtr > endOfStringPtr)
+ error("Script::identifyOffsets(): string block / end-of-string block mismatch in script %d", _nr);
+
+ stringDataPtr = scriptDataPtr;
+ stringDataLeft = endOfStringPtr - scriptDataPtr; // Calculate byte count within string-block
+
+ arrayEntry.type = SCI_SCR_OFFSET_TYPE_STRING;
+ do {
+ if (stringDataLeft < 1) // no more bytes left
+ break;
+
+ stringStartPtr = stringDataPtr;
+ // now look for terminating [NUL]
+ do {
+ stringDataByte = *stringDataPtr;
+ stringDataPtr++;
+ stringDataLeft--;
+ if (!stringDataByte) // NUL found, exit this loop
+ break;
+ if (stringDataLeft < 1) {
+ // no more bytes left
+ warning("Script::identifyOffsets(): string without terminating NUL in script %d", _nr);
+ break;
+ }
+ } while (1);
+
+ if (stringDataByte)
+ break;
+
+ typeString_id++;
+ arrayEntry.id = typeString_id;
+ arrayEntry.offset = stringStartPtr - _buf; // Calculate offset inside script data
+ arrayEntry.stringSize = stringDataPtr - stringStartPtr;
+ _offsetLookupArray.push_back(arrayEntry);
+ _offsetLookupStringCount++;
+ } while (1);
+
+ } else if (getSciVersion() == SCI_VERSION_3) {
+ // SCI3
+ uint32 sci3StringOffset = 0;
+ uint32 sci3RelocationOffset = 0;
+ uint32 sci3BoundaryOffset = 0;
+
+ if (_bufSize < 22)
+ error("Script::identifyOffsets(): script %d smaller than expected SCI3-header", _nr);
+
+ sci3StringOffset = READ_LE_UINT32(_buf + 4);
+ sci3RelocationOffset = READ_LE_UINT32(_buf + 8);
+
+ if (sci3RelocationOffset > _bufSize)
+ error("Script::identifyOffsets(): relocation offset is beyond end of script %d", _nr);
+
+ // First we get all the objects
+ scriptDataPtr = getSci3ObjectsPointer();
+ scriptDataLeft = _bufSize - (scriptDataPtr - _buf);
+ do {
+ if (scriptDataLeft < 2)
+ error("Script::identifyOffsets(): unexpected end of script %d", _nr);
+
+ blockType = READ_SCI11ENDIAN_UINT16(scriptDataPtr);
+ scriptDataPtr += 2;
+ scriptDataLeft -= 2;
+ if (blockType != SCRIPT_OBJECT_MAGIC_NUMBER)
+ break;
+
+ // Object found, add offset of object
+ typeObject_id++;
+ arrayEntry.type = SCI_SCR_OFFSET_TYPE_OBJECT;
+ arrayEntry.id = typeObject_id;
+ arrayEntry.offset = scriptDataPtr - _buf - 2; // the VM uses a pointer to the Magic-Number
+ arrayEntry.stringSize = 0;
+ _offsetLookupArray.push_back(arrayEntry);
+ _offsetLookupObjectCount++;
+
+ if (scriptDataLeft < 2)
+ error("Script::identifyOffsets(): unexpected end of script in script %d", _nr);
+
+ blockSize = READ_SCI11ENDIAN_UINT16(scriptDataPtr);
+ if (blockSize < 4)
+ error("Script::identifyOffsets(): invalid block size in script %d", _nr);
+ scriptDataPtr += 2;
+ scriptDataLeft -= 2;
+ blockSize -= 4; // blocksize contains UINT16 type and UINT16 size
+ if (scriptDataLeft < blockSize)
+ error("Script::identifyOffsets(): invalid block size in script %d", _nr);
+
+ scriptDataPtr += blockSize;
+ scriptDataLeft -= blockSize;
+ } while (1);
+
+ // And now we get all the strings
+ if (sci3StringOffset > 0) {
+ // string offset set, we expect strings
+ if (sci3StringOffset > _bufSize)
+ error("Script::identifyOffsets(): string offset is beyond end of script %d", _nr);
+
+ if (sci3RelocationOffset < sci3StringOffset)
+ error("Script::identifyOffsets(): string offset points beyond relocation offset in script %d", _nr);
+
+ stringDataPtr = _buf + sci3StringOffset;
+ stringDataLeft = sci3RelocationOffset - sci3StringOffset;
+
+ arrayEntry.type = SCI_SCR_OFFSET_TYPE_STRING;
+
+ do {
+ if (stringDataLeft < 1) // no more bytes left
+ break;
+
+ stringStartPtr = stringDataPtr;
+
+ if (stringDataLeft == 1) {
+ // only 1 byte left and that byte is a [00], in that case we also exit
+ stringDataByte = *stringStartPtr;
+ if (stringDataByte == 0x00)
+ break;
+ }
+
+ // now look for terminating [NUL]
+ do {
+ stringDataByte = *stringDataPtr;
+ stringDataPtr++;
+ stringDataLeft--;
+ if (!stringDataByte) // NUL found, exit this loop
+ break;
+ if (stringDataLeft < 1) {
+ // no more bytes left
+ warning("Script::identifyOffsets(): string without terminating NUL in script %d", _nr);
+ break;
+ }
+ } while (1);
+
+ if (stringDataByte)
+ break;
+
+ typeString_id++;
+ arrayEntry.id = typeString_id;
+ arrayEntry.offset = stringStartPtr - _buf; // Calculate offset inside script data
+ arrayEntry.stringSize = stringDataPtr - stringStartPtr;
+ _offsetLookupArray.push_back(arrayEntry);
+ _offsetLookupStringCount++;
+
+ // SCI3 seems to have aligned all string on DWORD boundaries
+ sci3BoundaryOffset = stringDataPtr - _buf; // Calculate current offset inside script data
+ sci3BoundaryOffset = sci3BoundaryOffset & 3; // Check boundary offset
+ if (sci3BoundaryOffset) {
+ // lower 2 bits are set? Then we have to adjust the offset
+ sci3BoundaryOffset = 4 - sci3BoundaryOffset;
+ if (stringDataLeft < sci3BoundaryOffset)
+ error("Script::identifyOffsets(): SCI3 string boundary adjustment goes beyond end of string block in script %d", _nr);
+ stringDataLeft -= sci3BoundaryOffset;
+ stringDataPtr += sci3BoundaryOffset;
+ }
+ } while (1);
+ }
+ return;
+ }
}
const byte *Script::getSci3ObjectsPointer() {
@@ -689,9 +1086,14 @@ void Script::initializeObjectsSci3(SegManager *segMan, SegmentId segmentId) {
const byte *seeker = getSci3ObjectsPointer();
while (READ_SCI11ENDIAN_UINT16(seeker) == SCRIPT_OBJECT_MAGIC_NUMBER) {
- reg_t reg = make_reg(segmentId, seeker - _buf);
- Object *obj = scriptObjInit(reg);
+ // We call setSegment and setOffset directly here, instead of using
+ // make_reg, as in large scripts, seeker - _buf can be larger than
+ // a 16-bit integer
+ reg_t reg;
+ reg.setSegment(segmentId);
+ reg.setOffset(seeker - _buf);
+ Object *obj = scriptObjInit(reg);
obj->setSuperClassSelector(segMan->getClassAddress(obj->getSuperClassSelector().getOffset(), SCRIPT_GET_LOCK, 0));
seeker += READ_SCI11ENDIAN_UINT16(seeker + 2);
}
diff --git a/engines/sci/engine/script.h b/engines/sci/engine/script.h
index 46d6ace917..755e2f3698 100644
--- a/engines/sci/engine/script.h
+++ b/engines/sci/engine/script.h
@@ -49,6 +49,21 @@ enum ScriptObjectTypes {
typedef Common::HashMap<uint16, Object> ObjMap;
+enum ScriptOffsetEntryTypes {
+ SCI_SCR_OFFSET_TYPE_OBJECT = 0, // classes are handled by this type as well
+ SCI_SCR_OFFSET_TYPE_STRING,
+ SCI_SCR_OFFSET_TYPE_SAID
+};
+
+struct offsetLookupArrayEntry {
+ uint16 type; // type of entry
+ uint16 id; // id of this type, first item inside script data is 1, second item is 2, etc.
+ uint32 offset; // offset of entry within script resource data
+ uint16 stringSize; // size of string, including terminating [NUL]
+};
+
+typedef Common::Array<offsetLookupArrayEntry> offsetLookupArrayType;
+
class Script : public SegmentObj {
private:
int _nr; /**< Script number */
@@ -75,6 +90,14 @@ private:
ObjMap _objects; /**< Table for objects, contains property variables */
+protected:
+ offsetLookupArrayType _offsetLookupArray; // Table of all elements of currently loaded script, that may get pointed to
+
+private:
+ uint16 _offsetLookupObjectCount;
+ uint16 _offsetLookupStringCount;
+ uint16 _offsetLookupSaidCount;
+
public:
int getLocalsOffset() const { return _localsOffset; }
uint16 getLocalsCount() const { return _localsCount; }
@@ -248,6 +271,14 @@ public:
*/
int getCodeBlockOffsetSci3() { return READ_SCI11ENDIAN_UINT32(_buf); }
+ /**
+ * Get the offset array
+ */
+ const offsetLookupArrayType *getOffsetArray() { return &_offsetLookupArray; };
+ uint16 getOffsetObjectCount() { return _offsetLookupObjectCount; };
+ uint16 getOffsetStringCount() { return _offsetLookupStringCount; };
+ uint16 getOffsetSaidCount() { return _offsetLookupSaidCount; };
+
private:
/**
* Processes a relocation block within a SCI0-SCI2.1 script
@@ -294,6 +325,11 @@ private:
void initializeObjectsSci3(SegManager *segMan, SegmentId segmentId);
LocalVariables *allocLocalsSegment(SegManager *segMan);
+
+ /**
+ * Identifies certain offsets within script data and set up lookup-table
+ */
+ void identifyOffsets();
};
} // End of namespace Sci
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index 03cd1d06e9..6915e12a0e 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -94,6 +94,8 @@ static const char *const selectorNameTable[] = {
"deskSarg", // Gabriel Knight
"localize", // Freddy Pharkas
"put", // Police Quest 1 VGA
+ "say", // Quest For Glory 1 VGA
+ "contains", // Quest For Glory 2
"solvePuzzle", // Quest For Glory 3
"timesShownID", // Space Quest 1 VGA
"startText", // King's Quest 6 CD / Laura Bow 2 CD for audio+text support
@@ -119,6 +121,8 @@ enum ScriptPatcherSelectors {
SELECTOR_deskSarg,
SELECTOR_localize,
SELECTOR_put,
+ SELECTOR_say,
+ SELECTOR_contains,
SELECTOR_solvePuzzle,
SELECTOR_timesShownID,
SELECTOR_startText,
@@ -562,12 +566,12 @@ static const uint16 gk1SignatureDay6PoliceSleep[] = {
0x34, SIG_UINT16(0x00dc), // ldi 220
0x65, SIG_ADDTOOFFSET(+1), // aTop cycles (1a for PC, 1c for Mac)
0x32, // jmp [end]
- 0
+ SIG_END
};
static const uint16 gk1PatchDay6PoliceSleep[] = {
PATCH_ADDTOOFFSET(+5),
- 0x34, SIG_UINT16(0x002a), // ldi 42
+ 0x34, PATCH_UINT16(0x002a), // ldi 42
0x65, PATCH_GETORIGINALBYTEADJUST(+9, +2), // aTop seconds (1c for PC, 1e for Mac)
PATCH_END
};
@@ -1421,6 +1425,37 @@ static const SciScriptPatcherEntry larry2Signatures[] = {
// ===========================================================================
// Leisure Suit Larry 5
+// In Miami the player can call the green card telephone number and get
+// green card including limo at the same time in the English 1.000 PC release.
+// This results later in a broken game in case the player doesn't read
+// the second telephone number for the actual limousine service, because
+// in that case it's impossible for the player to get back to the airport.
+//
+// We disable the code, that is responsible to make the limo arrive.
+//
+// This bug was fixed in the European (dual language) versions of the game.
+//
+// Applies to at least: English PC floppy (1.000)
+// Responsible method: sPhone::changeState(40)
+static const uint16 larry5SignatureGreenCardLimoBug[] = {
+ 0x7a, // push2
+ SIG_MAGICDWORD,
+ 0x39, 0x07, // pushi 07
+ 0x39, 0x0c, // pushi 0Ch
+ 0x45, 0x0a, 0x04, // call export 10 of script 0
+ 0x78, // push1
+ 0x39, 0x26, // pushi 26h (limo arrived flag)
+ 0x45, 0x07, 0x02, // call export 7 of script 0 (sets flag)
+ SIG_END
+};
+
+static const uint16 larry5PatchGreenCardLimoBug[] = {
+ PATCH_ADDTOOFFSET(+8),
+ 0x34, PATCH_UINT16(0), // ldi 0000 (dummy)
+ 0x34, PATCH_UINT16(0), // ldi 0000 (dummy)
+ PATCH_END
+};
+
// In one of the conversations near the end (to be exact - room 380 and the text
// about using champagne on Reverse Biaz - only used when you actually did that
// in the game), the German text is too large, causing the textbox to get too large.
@@ -1444,6 +1479,7 @@ static const uint16 larry5PatchGermanEndingPattiTalker[] = {
// script, description, signature patch
static const SciScriptPatcherEntry larry5Signatures[] = {
+ { true, 280, "English-only: fix green card limo bug", 1, larry5SignatureGreenCardLimoBug, larry5PatchGreenCardLimoBug },
{ true, 380, "German-only: Enlarge Patti Textbox", 1, larry5SignatureGermanEndingPattiTalker, larry5PatchGermanEndingPattiTalker },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -2087,21 +2123,30 @@ static const uint16 qfg1vgaPatchMoveToCrusher[] = {
// Same pathfinding bug as above, where Ego is set to move to an impossible
// spot when sneaking. In GuardsTrumpet::changeState, we change the final
-// location where Ego is moved from 111, 111 to 114, 114.
+// location where Ego is moved from 111, 111 to 116, 116.
+// target coordinate is really problematic here.
+//
+// 114, 114 works when the speed slider is all the way up, but doesn't work
+// when the speed slider is not.
+//
+// It seems that this bug was fixed by Sierra for the Macintosh version.
+//
+// Applies to at least: English PC floppy
+// Responsible method: GuardsTrumpet::changeState(8)
// Fixes bug: #6248
static const uint16 qfg1vgaSignatureMoveToCastleGate[] = {
+ 0x51, SIG_ADDTOOFFSET(+1), // class MoveTo
SIG_MAGICDWORD,
- 0x51, 0x1f, // class MoveTo
0x36, // push
- 0x39, 0x6f, // pushi 6f (111 - x)
- 0x3c, // dup (111 - y)
+ 0x39, 0x6f, // pushi 6f (111d)
+ 0x3c, // dup (111d) - coordinates 111, 111
0x7c, // pushSelf
SIG_END
};
static const uint16 qfg1vgaPatchMoveToCastleGate[] = {
PATCH_ADDTOOFFSET(+3),
- 0x39, 0x72, // pushi 72 (114 - x)
+ 0x39, 0x74, // pushi 74 (116d), changes coordinates to 116, 116
PATCH_END
};
@@ -2116,7 +2161,7 @@ static const uint16 qfg1vgaSignatureCheetaurDescription[] = {
0x34, SIG_UINT16(0x01b8), // ldi 01b8
0x1a, // eq?
0x31, 0x16, // bnt 16
- 0x38, SIG_UINT16(0x0127), // pushi 0127
+ 0x38, SIG_SELECTOR16(say), // pushi 0127h (selector "say")
0x39, 0x06, // pushi 06
0x39, 0x03, // pushi 03
0x78, // push1
@@ -2140,6 +2185,7 @@ static const uint16 qfg1vgaPatchCheetaurDescription[] = {
// Local 5 of that room is a timer, that closes the door (object door11).
// Setting it to 1 during happyFace::changeState(0) stops door11::doit from
// calling goTo6::init, so the whole issue is stopped from happening.
+//
// Applies to at least: English floppy
// Responsible method: happyFace::changeState, door11::doit
// Fixes bug #6181
@@ -2166,20 +2212,172 @@ static const uint16 qfg1vgaPatchFunnyRoomFix[] = {
PATCH_END
};
+// The player is able to buy (and also steal) potions in the healer's hut
+// Strangely Sierra delays the actual buy/get potion code for 60 ticks
+// Why they did that is unknown. The code is triggered anyway only after
+// the relevant dialog boxes are closed.
+//
+// This delay causes problems in case the user quickly enters the inventory.
+// That's why we change the amount of ticks to 1, so that the remaining states
+// are executed right after the dialog boxes are closed.
+//
+// Applies to at least: English floppy
+// Responsible method: cueItScript::changeState
+// Fixes bug #6706
+static const uint16 qfg1vgaSignatureHealerHutNoDelay[] = {
+ 0x65, 0x14, // aTop 14 (state)
+ 0x36, // push
+ 0x3c, // dup
+ 0x35, 0x00, // ldi 00
+ 0x1a, // eq?
+ 0x31, 0x07, // bnt 07 [-> next state]
+ SIG_MAGICDWORD,
+ 0x35, 0x3c, // ldi 3c (60 ticks)
+ 0x65, 0x20, // aTop ticks
+ 0x32, // jmp [-> end of method]
+ SIG_END
+};
+
+static const uint16 qfg1vgaPatchHealerHutNoDelay[] = {
+ PATCH_ADDTOOFFSET(+9),
+ 0x35, 0x01, // ldi 01 (1 tick only, so that execution will resume as soon as dialog box is closed)
+ PATCH_END
+};
+
+// When following the white stag, you can actually enter the 2nd room from the mushroom/fairy location,
+// which results in ego entering from the top. When you then throw a dagger at the stag, one animation
+// frame will stay on screen, because of a script bug.
+//
+// Applies to at least: English floppy, Mac floppy
+// Responsible method: stagHurt::changeState
+// Fixes bug #6135
+static const uint16 qfg1vgaSignatureWhiteStagDagger[] = {
+ 0x87, 0x01, // lap param[1]
+ 0x65, 0x14, // aTop state
+ 0x36, // push
+ 0x3c, // dup
+ 0x35, 0x00, // ldi 0
+ 0x1a, // eq?
+ 0x31, 0x16, // bnt [next parameter check]
+ 0x76, // push0
+ 0x45, 0x02, 0x00, // callb export 2 from script 0, 0
+ SIG_MAGICDWORD,
+ 0x38, SIG_SELECTOR16(say), // pushi 0127h (selector "say")
+ 0x39, 0x05, // pushi 05
+ 0x39, 0x03, // pushi 03
+ 0x39, 0x51, // pushi 51h
+ 0x76, // push0
+ 0x76, // push0
+ 0x7c, // pushSelf
+ 0x81, 0x5b, // lag global[5Bh] -> qg1Messager
+ 0x4a, 0x0e, // send 0Eh -> qg1Messager::say(3, 51h, 0, 0, stagHurt)
+ 0x33, 0x12, // jmp -> [ret]
+ 0x3c, // dup
+ 0x35, 0x01, // ldi 1
+ 0x1a, // eq?
+ 0x31, 0x0c, // bnt [ret]
+ 0x38, // pushi...
+ SIG_ADDTOOFFSET(+11),
+ 0x3a, // toss
+ 0x48, // ret
+ SIG_END
+};
+
+static const uint16 qfg1vgaPatchWhiteStagDagger[] = {
+ PATCH_ADDTOOFFSET(+4),
+ 0x2f, 0x05, // bt [next check] (state != 0)
+ // state = 0 code
+ 0x35, 0x01, // ldi 1
+ 0x65, 0x1a, // aTop cycles
+ 0x48, // ret
+ 0x36, // push
+ 0x35, 0x01, // ldi 1
+ 0x1a, // eq?
+ 0x31, 0x16, // bnt [state = 2 code]
+ // state = 1 code
+ 0x76, // push0
+ 0x45, 0x02, 0x00, // callb export 2 from script 0, 0
+ 0x38, PATCH_SELECTOR16(say), // pushi 0127h (selector "say")
+ 0x39, 0x05, // pushi 05
+ 0x39, 0x03, // pushi 03
+ 0x39, 0x51, // pushi 51h
+ 0x76, // push0
+ 0x76, // push0
+ 0x7c, // pushSelf
+ 0x81, 0x5b, // lag global[5Bh] -> qg1Messager
+ 0x4a, 0x0e, // send 0Eh -> qg1Messager::say(3, 51h, 0, 0, stagHurt)
+ 0x48, // ret
+ // state = 2 code
+ PATCH_ADDTOOFFSET(+13),
+ 0x48, // ret (remove toss)
+ PATCH_END
+};
+
// script, description, signature patch
static const SciScriptPatcherEntry qfg1vgaSignatures[] = {
+ { true, 41, "moving to castle gate", 1, qfg1vgaSignatureMoveToCastleGate, qfg1vgaPatchMoveToCastleGate },
+ { true, 55, "healer's hut, no delay for buy/steal", 1, qfg1vgaSignatureHealerHutNoDelay, qfg1vgaPatchHealerHutNoDelay },
+ { true, 77, "white stag dagger throw animation glitch", 1, qfg1vgaSignatureWhiteStagDagger, qfg1vgaPatchWhiteStagDagger },
+ { true, 96, "funny room script bug fixed", 1, qfg1vgaSignatureFunnyRoomFix, qfg1vgaPatchFunnyRoomFix },
+ { true, 210, "cheetaur description fixed", 1, qfg1vgaSignatureCheetaurDescription, qfg1vgaPatchCheetaurDescription },
{ true, 215, "fight event issue", 1, qfg1vgaSignatureFightEvents, qfg1vgaPatchFightEvents },
{ true, 216, "weapon master event issue", 1, qfg1vgaSignatureFightEvents, qfg1vgaPatchFightEvents },
+ { true, 331, "moving to crusher", 1, qfg1vgaSignatureMoveToCrusher, qfg1vgaPatchMoveToCrusher },
{ true, 814, "window text temp space", 1, qfg1vgaSignatureTempSpace, qfg1vgaPatchTempSpace },
{ true, 814, "dialog header offset", 3, qfg1vgaSignatureDialogHeader, qfg1vgaPatchDialogHeader },
- { true, 331, "moving to crusher", 1, qfg1vgaSignatureMoveToCrusher, qfg1vgaPatchMoveToCrusher },
- { true, 41, "moving to castle gate", 1, qfg1vgaSignatureMoveToCastleGate, qfg1vgaPatchMoveToCastleGate },
- { true, 210, "cheetaur description fixed", 1, qfg1vgaSignatureCheetaurDescription, qfg1vgaPatchCheetaurDescription },
- { true, 96, "funny room script bug fixed", 1, qfg1vgaSignatureFunnyRoomFix, qfg1vgaPatchFunnyRoomFix },
SCI_SIGNATUREENTRY_TERMINATOR
};
// ===========================================================================
+
+// This is a very complicated bug.
+// When the player encounters an enemy in the desert while riding a saurus and later
+// tries to get back on it by entering "ride", the game will not give control back
+// to the player.
+//
+// This is caused by script mountSaurus getting triggered twice.
+// Once by entering the command "ride" and then a second time by a proximity check.
+//
+// Both are calling mountSaurus::init() in script 20, this one disables controls
+// then mountSaurus::changeState() from script 660 is triggered
+// mountSaurus::changeState(5) finally calls mountSaurus::dispose(), which is also in script 20
+// which finally re-enables controls
+//
+// A fix is difficult to implement. The code in script 20 is generic and used by multiple objects
+//
+// Originally I decided to change the responsible globals (66h and A1h) during mountSaurus::changeState(5).
+// This worked as far as for controls, but mountSaurus::init changes a few selectors of ego as well, which
+// won't get restored in that situation, which then messes up room changes and other things.
+//
+// I have now decided to change sheepScript::changeState(2) in script 665 instead.
+//
+// This fix could cause issues in case there is a cutscene, where ego is supposed to get onto the saurus using
+// sheepScript.
+//
+// Applies to at least: English PC Floppy, English Amiga Floppy
+// Responsible method: mountSaurus::changeState(), mountSaurus::init(), mountSaurus::dispose()
+// Fixes bug: #5156
+static const uint16 qfg2SignatureSaurusFreeze[] = {
+ 0x3c, // dup
+ 0x35, 0x02, // ldi 5
+ SIG_MAGICDWORD,
+ 0x1a, // eq?
+ 0x30, SIG_UINT16(0x0043), // bnt [ret]
+ 0x76, // push0
+ SIG_ADDTOOFFSET(+61), // skip to dispose code
+ 0x39, SIG_SELECTOR8(dispose), // pushi "dispose"
+ 0x76, // push0
+ 0x54, 0x04, // self 04
+ SIG_END
+};
+
+static const uint16 qfg2PatchSaurusFreeze[] = {
+ 0x81, 0x66, // lag 66h
+ 0x2e, SIG_UINT16(0x0040), // bt [to dispose code]
+ 0x35, 0x00, // ldi 0 (waste 2 bytes)
+ PATCH_END
+};
+
// Script 944 in QFG2 contains the FileSelector system class, used in the
// character import screen. This gets incorrectly called constantly, whenever
// the user clicks on a button in order to refresh the file list. This was
@@ -2211,9 +2409,58 @@ static const uint16 qfg2PatchImportDialog[] = {
PATCH_END
};
-// script, description, signature patch
+// Quest For Glory 2 character import doesn't properly set the character type
+// in versions 1.102 and below, which makes all importerted characters a fighter.
+//
+// Sierra released an official patch. However the fix is really easy to
+// implement on our side, so we also patch the flaw in here in case we find it.
+//
+// The version released on GOG is 1.102 without this patch applied, so us
+// patching it is quite useful.
+//
+// Applies to at least: English Floppy
+// Responsible method: importHero::changeState
+// Fixes bug: inside versions 1.102 and below
+static const uint16 qfg2SignatureImportCharType[] = {
+ 0x35, 0x04, // ldi 04
+ 0x90, SIG_UINT16(0x023b), // lagi global[23Bh]
+ 0x02, // add
+ 0x36, // push
+ 0x35, 0x04, // ldi 04
+ 0x08, // div
+ 0x36, // push
+ 0x35, 0x0d, // ldi 0D
+ 0xb0, SIG_UINT16(0x023b), // sagi global[023Bh]
+ 0x8b, 0x1f, // lsl local[1Fh]
+ 0x35, 0x05, // ldi 05
+ SIG_MAGICDWORD,
+ 0xb0, SIG_UINT16(0x0150), // sagi global[0150h]
+ 0x8b, 0x02, // lsl local[02h]
+ SIG_END
+};
+
+static const uint16 qfg2PatchImportCharType[] = {
+ 0x80, PATCH_UINT16(0x023f), // lag global[23Fh] <-- patched to save 2 bytes
+ 0x02, // add
+ 0x36, // push
+ 0x35, 0x04, // ldi 04
+ 0x08, // div
+ 0x36, // push
+ 0xa8, SIG_UINT16(0x0248), // ssg global[0248h] <-- patched to save 2 bytes
+ 0x8b, 0x1f, // lsl local[1Fh]
+ 0xa8, SIG_UINT16(0x0155), // ssg global[0155h] <-- patched to save 2 bytes
+ // new code, directly from the official sierra patch file
+ 0x83, 0x01, // lal local[01h]
+ 0xa1, 0xbb, // sag global[BBh]
+ 0xa1, 0x73, // sag global[73h]
+ PATCH_END
+};
+
+// script, description, signature patch
static const SciScriptPatcherEntry qfg2Signatures[] = {
- { true, 944, "import dialog continuous calls", 1, qfg2SignatureImportDialog, qfg2PatchImportDialog },
+ { true, 665, "getting back on saurus freeze fix", 1, qfg2SignatureSaurusFreeze, qfg2PatchSaurusFreeze },
+ { true, 805, "import character type fix", 1, qfg2SignatureImportCharType, qfg2PatchImportCharType },
+ { true, 944, "import dialog continuous calls", 1, qfg2SignatureImportDialog, qfg2PatchImportDialog },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -2282,10 +2529,158 @@ static const uint16 qfg3PatchWooDialog[] = {
PATCH_END
};
-// script, description, signature patch
+// Alternative version, with uint16 offsets, for GOG release of QfG3.
+static const uint16 qfg3SignatureWooDialogAlt[] = {
+ SIG_MAGICDWORD,
+ 0x67, 0x12, // pTos 12 (query)
+ 0x35, 0xb6, // ldi b6
+ 0x1a, // eq?
+ 0x2e, SIG_UINT16(0x0005), // bt 05
+ 0x67, 0x12, // pTos 12 (query)
+ 0x35, 0x9b, // ldi 9b
+ 0x1a, // eq?
+ 0x30, SIG_UINT16(0x000c), // bnt 0c
+ 0x38, SIG_SELECTOR16(solvePuzzle), // pushi 0297
+ 0x7a, // push2
+ 0x38, SIG_UINT16(0x010c), // pushi 010c
+ 0x7a, // push2
+ 0x81, 0x00, // lag 00
+ 0x4a, 0x08, // send 08
+ 0x67, 0x12, // pTos 12 (query)
+ 0x35, 0xb5, // ldi b5
+ SIG_END
+};
+
+static const uint16 qfg3PatchWooDialogAlt[] = {
+ PATCH_ADDTOOFFSET(+0x2C),
+ 0x33, 0x12, // jmp to 0x708, the call to hero::solvePuzzle for 0xFFFC
+ PATCH_END
+};
+
+// When exporting characters at the end of Quest for Glory 3, the underlying
+// code has issues with values, that are above 9999.
+// For further study: https://github.com/Blazingstix/QFGImporter/blob/master/QFGImporter/QFGImporter/QFG3.txt
+//
+// If a value is above 9999, parts or even the whole character file will get corrupted.
+//
+// We are fixing the code because of that. We are patching code, that is calculating the checksum
+// and add extra code to lower such values to 9999.
+//
+// Applies to at least: English, French, German, Italian, Spanish floppy
+// Responsible method: saveHero::changeState
+// Fixes bug #6807
+static const uint16 qfg3SignatureExportChar[] = {
+ 0x35, SIG_ADDTOOFFSET(+1), // ldi 00 / ldi 01 (2 loops, we patch both)
+ 0xa5, 0x00, // sat temp[0] [contains index to data]
+ 0x8d, 0x00, // lst temp[0]
+ SIG_MAGICDWORD,
+ 0x35, 0x2c, // ldi 2c
+ 0x22, // lt? [index above or equal 2Ch (44d)?
+ 0x31, 0x23, // bnt [exit loop]
+ // from this point it's actually useless code, maybe a sci compiler bug
+ 0x8d, 0x00, // lst temp[0]
+ 0x35, 0x01, // ldi 01
+ 0x02, // add
+ 0x9b, 0x00, // lsli local[0] ---------- load local[0 + ACC] onto stack
+ 0x8d, 0x00, // lst temp[0]
+ 0x35, 0x01, // ldi 01
+ 0x02, // add
+ 0xb3, 0x00, // sali local[0] ---------- save stack to local[0 + ACC]
+ // end of useless code
+ 0x8b, SIG_ADDTOOFFSET(+1), // lsl local[36h/37h] ---- load local[36h/37h] onto stack
+ 0x8d, 0x00, // lst temp[0]
+ 0x35, 0x01, // ldi 01
+ 0x02, // add
+ 0x93, 0x00, // lali local[0] ---------- load local[0 + ACC] into ACC
+ 0x02, // add -------------------- add ACC + stack and put into ACC
+ 0xa3, SIG_ADDTOOFFSET(+1), // sal local[36h/37h] ---- save ACC to local[36h/37h]
+ 0x8d, 0x00, // lst temp[0] ------------ temp[0] to stack
+ 0x35, 0x02, // ldi 02
+ 0x02, // add -------------------- add 2 to stack
+ 0xa5, 0x00, // sat temp[0] ------------ save ACC to temp[0]
+ 0x33, 0xd6, // jmp [loop]
+ SIG_END
+};
+
+static const uint16 qfg3PatchExportChar[] = {
+ PATCH_ADDTOOFFSET(+11),
+ 0x85, 0x00, // lat temp[0]
+ 0x9b, 0x01, // lsli local[0] + 1 ------ load local[ ACC + 1] onto stack
+ 0x3c, // dup
+ 0x34, PATCH_UINT16(0x2710), // ldi 2710h (10000d)
+ 0x2c, // ult? ------------------- is value smaller than 10000?
+ 0x2f, 0x0a, // bt [jump over]
+ 0x3a, // toss
+ 0x38, PATCH_UINT16(0x270f), // pushi 270fh (9999d)
+ 0x3c, // dup
+ 0x85, 0x00, // lat temp[0]
+ 0xba, PATCH_UINT16(0x0001), // ssli local[0] + 1 ------ save stack to local[ ACC + 1] (UINT16 to waste 1 byte)
+ // jump offset
+ 0x83, PATCH_GETORIGINALBYTE(+26), // lal local[37h/36h] ---- load local[37h/36h] into ACC
+ 0x02, // add -------------------- add local[37h/36h] + data value
+ PATCH_END
+};
+
+// Quest for Glory 3 doesn't properly import the character type of Quest for Glory 1 character files.
+// This issue was never addressed. It's caused by Sierra reading data directly from the local
+// area, which is only set by Quest For Glory 2 import data, instead of reading the properly set global variable.
+//
+// We fix it, by also directly setting the local variable.
+//
+// Applies to at least: English, French, German, Italian, Spanish floppy
+// Responsible method: importHero::changeState(4)
+static const uint16 qfg3SignatureImportQfG1Char[] = {
+ SIG_MAGICDWORD,
+ 0x82, SIG_UINT16(0x0238), // lal local[0x0238]
+ 0xa0, SIG_UINT16(0x016a), // sag global[0x016a]
+ 0xa1, 0x7d, // sag global[0x7d]
+ 0x35, 0x01, // ldi 01
+ 0x99, 0xfb, // lsgi global[0xfb]
+ SIG_END
+};
+
+static const uint16 qfg3PatchImportQfG1Char[] = {
+ PATCH_ADDTOOFFSET(+8),
+ 0xa3, 0x01, // sal 01 -> also set local[01]
+ 0x89, 0xfc, // lsg global[0xFD] -> save 2 bytes
+ PATCH_END
+};
+
+// The chief in his hut (room 640) is not drawn using the correct priority,
+// which results in a graphical glitch. This is a game bug and also happens
+// in Sierra's SCI. We adjust priority accordingly to fix it.
+//
+// Applies to at least: English, French, German, Italian, Spanish floppy
+// Responsible method: heap in script 640
+// Fixes bug #5173
+static const uint16 qfg3SignatureChiefPriority[] = {
+ SIG_MAGICDWORD,
+ SIG_UINT16(0x0002), // yStep 0x0002
+ SIG_UINT16(0x0281), // view 0x0281
+ SIG_UINT16(0x0000), // loop 0x0000
+ SIG_UINT16(0x0000), // cel 0x0000
+ SIG_UINT16(0x0000), // priority 0x0000
+ SIG_UINT16(0x0000), // underbits 0x0000
+ SIG_UINT16(0x1000), // signal 0x1000
+ SIG_END
+};
+
+static const uint16 qfg3PatchChiefPriority[] = {
+ PATCH_ADDTOOFFSET(+8),
+ PATCH_UINT16(0x000A), // new priority 0x000A (10d)
+ PATCH_ADDTOOFFSET(+2),
+ PATCH_UINT16(0x1010), // signal 0x1010 (set fixed priority flag)
+ PATCH_END
+};
+
+// script, description, signature patch
static const SciScriptPatcherEntry qfg3Signatures[] = {
- { true, 944, "import dialog continuous calls", 1, qfg3SignatureImportDialog, qfg3PatchImportDialog },
- { true, 440, "dialog crash when asking about Woo", 1, qfg3SignatureWooDialog, qfg3PatchWooDialog },
+ { true, 944, "import dialog continuous calls", 1, qfg3SignatureImportDialog, qfg3PatchImportDialog },
+ { true, 440, "dialog crash when asking about Woo", 1, qfg3SignatureWooDialog, qfg3PatchWooDialog },
+ { true, 440, "dialog crash when asking about Woo", 1, qfg3SignatureWooDialogAlt, qfg3PatchWooDialogAlt },
+ { true, 52, "export character save bug", 2, qfg3SignatureExportChar, qfg3PatchExportChar },
+ { true, 54, "import character from QfG1 bug", 1, qfg3SignatureImportQfG1Char, qfg3PatchImportQfG1Char },
+ { true, 640, "chief in hut priority fix", 1, qfg3SignatureChiefPriority, qfg3PatchChiefPriority },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -2345,6 +2740,102 @@ static const uint16 sq4FloppyPatchThrowStuffAtSequelPoliceBug[] = {
PATCH_END
};
+// Right at the start of Space Quest 4 CD, when walking up in the first room, ego will
+// immediately walk down just after entering the upper room.
+//
+// This is caused by the scripts setting ego's vertical coordinate to 189 (BDh), which is the
+// trigger in rooms to walk to the room below it. Sometimes this isn't triggered, because
+// the scripts also initiate a motion to vertical coordinate 188 (BCh). When you lower the game's speed,
+// this bug normally always triggers. And it triggers of course also in the original interpreter.
+//
+// It doesn't happen in PC floppy, because nsRect is not the same as in CD.
+//
+// We fix it by setting ego's vertical coordinate to 188 and we also initiate a motion to 187.
+//
+// Applies to at least: English PC CD
+// Responsible method: rm045::doit
+// Fixes bug: #5468
+static const uint16 sq4CdSignatureWalkInFromBelowRoom45[] = {
+ 0x76, // push0
+ SIG_MAGICDWORD,
+ 0x78, // push1
+ 0x38, SIG_UINT16(0x00bd), // pushi 00BDh
+ 0x38, SIG_ADDTOOFFSET(+2), // pushi [setMotion selector]
+ 0x39, 0x03, // pushi 3
+ 0x51, SIG_ADDTOOFFSET(+1), // class [MoveTo]
+ 0x36, // push
+ 0x78, // push1
+ 0x76, // push0
+ 0x81, 0x00, // lag global[0]
+ 0x4a, 0x04, // send 04 -> get ego::x
+ 0x36, // push
+ 0x38, SIG_UINT16(0x00bc), // pushi 00BCh
+ SIG_END
+};
+
+static const uint16 sq4CdPatchWalkInFromBelowRoom45[] = {
+ PATCH_ADDTOOFFSET(+2),
+ 0x38, PATCH_UINT16(0x00bc), // pushi 00BCh
+ PATCH_ADDTOOFFSET(+15),
+ 0x38, PATCH_UINT16(0x00bb), // pushi 00BBh
+ PATCH_END
+};
+
+// It seems that Sierra forgot to set a script flag, when cleaning out the bank account
+// in Space Quest 4 CD. This was probably caused by the whole bank account interaction
+// getting a rewrite and polish in the CD version.
+//
+// Because of this bug, points for changing back clothes will not get awarded, which
+// makes it impossible to get a perfect point score in the CD version of the game.
+// The points are awarded by rm371::doit in script 371.
+//
+// We fix this. Bug also happened, when using the original interpreter.
+// Bug does not happen for PC floppy.
+//
+// Attention: Some Let's Plays on youtube show that points are in fact awarded. Which is true.
+// But those Let's Plays were actually created by playing a hacked Space Quest 4 version
+// (which is part Floppy, part CD version - we consider it to be effectively pirated)
+// and not the actual CD version of Space Quest 4.
+// It's easy to identify - talkie + store called "Radio Shack" -> is hacked version.
+//
+// Applies to at least: English PC CD
+// Responsible method: but2Script::changeState(2)
+// Fixes bug: #6866
+static const uint16 sq4CdSignatureGetPointsForChangingBackClothes[] = {
+ 0x35, 0x02, // ldi 02
+ SIG_MAGICDWORD,
+ 0x1a, // eq?
+ 0x30, SIG_UINT16(0x006a), // bnt [state 3]
+ 0x76,
+ SIG_ADDTOOFFSET(+46), // jump over "withdraw funds" code
+ 0x33, 0x33, // jmp [end of state 2, set cycles code]
+ SIG_ADDTOOFFSET(+51), // jump over "clean bank account" code
+ 0x35, 0x02, // ldi 02
+ 0x65, 0x1a, // aTop cycles
+ 0x33, 0x0b, // jmp [toss/ret]
+ 0x3c, // dup
+ 0x35, 0x03, // ldi 03
+ 0x1a, // eq?
+ 0x31, 0x05, // bnt [toss/ret]
+ SIG_END
+};
+
+static const uint16 sq4CdPatchGetPointsForChangingBackClothes[] = {
+ PATCH_ADDTOOFFSET(+3),
+ 0x30, PATCH_UINT16(0x0070), // bnt [state 3]
+ PATCH_ADDTOOFFSET(+47), // "withdraw funds" code
+ 0x33, 0x39, // jmp [end of state 2, set cycles code]
+ PATCH_ADDTOOFFSET(+51),
+ 0x78, // push1
+ 0x39, 0x1d, // ldi 1Dh
+ 0x45, 0x07, 0x02, // call export 7 of script 0 (set flag) -> effectively sets global 73h, bit 2
+ 0x35, 0x02, // ldi 02
+ 0x65, 0x1c, // aTop cycles
+ 0x33, 0x05, // jmp [toss/ret]
+ // check for state 3 code removed to save 6 bytes
+ PATCH_END
+};
+
// The scripts in SQ4CD support simultaneous playing of speech and subtitles,
// but this was not available as an option. The following two patches enable
// this functionality in the game's GUI options dialog.
@@ -2439,8 +2930,10 @@ static const uint16 sq4CdPatchTextOptions[] = {
static const SciScriptPatcherEntry sq4Signatures[] = {
{ true, 298, "Floppy: endless flight", 1, sq4FloppySignatureEndlessFlight, sq4FloppyPatchEndlessFlight },
{ true, 700, "Floppy: throw stuff at sequel police bug", 1, sq4FloppySignatureThrowStuffAtSequelPoliceBug, sq4FloppyPatchThrowStuffAtSequelPoliceBug },
- { true, 818, "CD: Speech and subtitles option", 1, sq4CdSignatureTextOptions, sq4CdPatchTextOptions },
+ { true, 45, "CD: walk in from below for room 45 fix", 1, sq4CdSignatureWalkInFromBelowRoom45, sq4CdPatchWalkInFromBelowRoom45 },
+ { true, 396, "CD: get points for changing back clothes fix",1, sq4CdSignatureGetPointsForChangingBackClothes, sq4CdPatchGetPointsForChangingBackClothes },
{ true, 0, "CD: Babble icon speech and subtitles fix", 1, sq4CdSignatureBabbleIcon, sq4CdPatchBabbleIcon },
+ { true, 818, "CD: Speech and subtitles option", 1, sq4CdSignatureTextOptions, sq4CdPatchTextOptions },
{ true, 818, "CD: Speech and subtitles option button", 1, sq4CdSignatureTextOptionsButton, sq4CdPatchTextOptionsButton },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -2471,6 +2964,29 @@ static const uint16 sq1vgaPatchUlenceFlatsTimepodGfxGlitch[] = {
PATCH_END
};
+// In Ulence Flats, there is a space ship, that you will use at some point.
+// Near that space ship are 2 force field generators.
+// When you look at the top of those generators, the game will crash.
+// This happens also in Sierra SCI. It's caused by a jump, that goes out of bounds.
+// We currently do not know if this was caused by a compiler glitch or if it was a developer error.
+// Anyway we patch this glitchy code, so that the game won't crash anymore.
+//
+// Applies to at least: English Floppy
+// Responsible method: radar1::doVerb
+// Fixes bug: #6816
+static const uint16 sq1vgaSignatureUlenceFlatsGeneratorGlitch[] = {
+ SIG_MAGICDWORD, 0x1a, // eq?
+ 0x30, SIG_UINT16(0xcdf4), // bnt absolute 0xf000
+ SIG_END
+};
+
+static const uint16 sq1vgaPatchUlenceFlatsGeneratorGlitch[] = {
+ PATCH_ADDTOOFFSET(+1),
+ 0x32, PATCH_UINT16(0x0000), // jmp 0x0000 (waste bytes)
+ PATCH_END
+};
+
+// No documentation for this patch (TODO)
static const uint16 sq1vgaSignatureEgoShowsCard[] = {
SIG_MAGICDWORD,
0x38, SIG_SELECTOR16(timesShownID), // push "timesShownID"
@@ -2595,6 +3111,7 @@ static const uint16 sq1vgaPatchSpiderDroidTiming[] = {
// script, description, signature patch
static const SciScriptPatcherEntry sq1vgaSignatures[] = {
{ true, 45, "Ulence Flats: timepod graphic glitch", 1, sq1vgaSignatureUlenceFlatsTimepodGfxGlitch, sq1vgaPatchUlenceFlatsTimepodGfxGlitch },
+ { true, 45, "Ulence Flats: force field generator glitch", 1, sq1vgaSignatureUlenceFlatsGeneratorGlitch, sq1vgaPatchUlenceFlatsGeneratorGlitch },
{ true, 58, "Sarien armory droid zapping ego first time", 1, sq1vgaSignatureEgoShowsCard, sq1vgaPatchEgoShowsCard },
{ true, 704, "spider droid timing issue", 1, sq1vgaSignatureSpiderDroidTiming, sq1vgaPatchSpiderDroidTiming },
SCI_SIGNATUREENTRY_TERMINATOR
@@ -2670,6 +3187,7 @@ ScriptPatcher::ScriptPatcher() {
_selectorIdTable[selectorNr] = -1;
_runtimeTable = NULL;
+ _isMacSci11 = false;
}
ScriptPatcher::~ScriptPatcher() {
@@ -2678,7 +3196,7 @@ ScriptPatcher::~ScriptPatcher() {
}
// will actually patch previously found signature area
-void ScriptPatcher::applyPatch(const SciScriptPatcherEntry *patchEntry, byte *scriptData, const uint32 scriptSize, int32 signatureOffset, const bool isMacSci11) {
+void ScriptPatcher::applyPatch(const SciScriptPatcherEntry *patchEntry, byte *scriptData, const uint32 scriptSize, int32 signatureOffset) {
const uint16 *patchData = patchEntry->patchData;
byte orgData[PATCH_VALUELIMIT];
int32 offset = signatureOffset;
@@ -2742,7 +3260,7 @@ void ScriptPatcher::applyPatch(const SciScriptPatcherEntry *patchEntry, byte *sc
default:
byte1 = 0; byte2 = 0;
}
- if (!isMacSci11) {
+ if (!_isMacSci11) {
scriptData[offset++] = byte1;
scriptData[offset++] = byte2;
} else {
@@ -2769,8 +3287,94 @@ void ScriptPatcher::applyPatch(const SciScriptPatcherEntry *patchEntry, byte *sc
}
}
+bool ScriptPatcher::verifySignature(uint32 byteOffset, const uint16 *signatureData, const char *signatureDescription, const byte *scriptData, const uint32 scriptSize) {
+ uint16 sigSelector = 0;
+
+ uint16 sigWord = *signatureData;
+ while (sigWord != SIG_END) {
+ uint16 sigCommand = sigWord & SIG_COMMANDMASK;
+ uint16 sigValue = sigWord & SIG_VALUEMASK;
+ switch (sigCommand) {
+ case SIG_CODE_ADDTOOFFSET: {
+ // add value to offset
+ byteOffset += sigValue;
+ break;
+ }
+ case SIG_CODE_UINT16:
+ case SIG_CODE_SELECTOR16: {
+ if ((byteOffset + 1) < scriptSize) {
+ byte byte1;
+ byte byte2;
+
+ switch (sigCommand) {
+ case SIG_CODE_UINT16: {
+ byte1 = sigValue & SIG_BYTEMASK;
+ signatureData++; sigWord = *signatureData;
+ if (sigWord & SIG_COMMANDMASK)
+ error("Script-Patcher: signature inconsistent\nFaulty signature: '%s'", signatureDescription);
+ byte2 = sigWord & SIG_BYTEMASK;
+ break;
+ }
+ case SIG_CODE_SELECTOR16: {
+ sigSelector = _selectorIdTable[sigValue];
+ byte1 = sigSelector & 0xFF;
+ byte2 = sigSelector >> 8;
+ break;
+ }
+ default:
+ byte1 = 0; byte2 = 0;
+ }
+ if (!_isMacSci11) {
+ if ((scriptData[byteOffset] != byte1) || (scriptData[byteOffset + 1] != byte2))
+ sigWord = SIG_MISMATCH;
+ } else {
+ // SCI1.1+ on macintosh had uint16s in script in BE-order
+ if ((scriptData[byteOffset] != byte2) || (scriptData[byteOffset + 1] != byte1))
+ sigWord = SIG_MISMATCH;
+ }
+ byteOffset += 2;
+ } else {
+ sigWord = SIG_MISMATCH;
+ }
+ break;
+ }
+ case SIG_CODE_SELECTOR8: {
+ if (byteOffset < scriptSize) {
+ sigSelector = _selectorIdTable[sigValue];
+ if (sigSelector & 0xFF00)
+ error("Script-Patcher: 8 bit selector required, game uses 16 bit selector\nFaulty signature: '%s'", signatureDescription);
+ if (scriptData[byteOffset] != (sigSelector & 0xFF))
+ sigWord = SIG_MISMATCH;
+ byteOffset++;
+ } else {
+ sigWord = SIG_MISMATCH; // out of bounds
+ }
+ break;
+ }
+ case SIG_CODE_BYTE:
+ if (byteOffset < scriptSize) {
+ if (scriptData[byteOffset] != sigWord)
+ sigWord = SIG_MISMATCH;
+ byteOffset++;
+ } else {
+ sigWord = SIG_MISMATCH; // out of bounds
+ }
+ }
+
+ if (sigWord == SIG_MISMATCH)
+ break;
+
+ signatureData++;
+ sigWord = *signatureData;
+ }
+
+ if (sigWord == SIG_END) // signature fully matched?
+ return true;
+ return false;
+}
+
// will return -1 if no match was found, otherwise an offset to the start of the signature match
-int32 ScriptPatcher::findSignature(const SciScriptPatcherEntry *patchEntry, SciScriptPatcherRuntimeEntry *runtimeEntry, const byte *scriptData, const uint32 scriptSize, const bool isMacSci11) {
+int32 ScriptPatcher::findSignature(const SciScriptPatcherEntry *patchEntry, SciScriptPatcherRuntimeEntry *runtimeEntry, const byte *scriptData, const uint32 scriptSize) {
if (scriptSize < 4) // we need to find a DWORD, so less than 4 bytes is not okay
return -1;
@@ -2782,89 +3386,8 @@ int32 ScriptPatcher::findSignature(const SciScriptPatcherEntry *patchEntry, SciS
if (magicDWord == READ_UINT32(scriptData + DWordOffset)) {
// magic DWORD found, check if actual signature matches
uint32 offset = DWordOffset + runtimeEntry->magicOffset;
- uint32 byteOffset = offset;
- const uint16 *signatureData = patchEntry->signatureData;
- uint16 sigSelector = 0;
-
- uint16 sigWord = *signatureData;
- while (sigWord != SIG_END) {
- uint16 sigCommand = sigWord & SIG_COMMANDMASK;
- uint16 sigValue = sigWord & SIG_VALUEMASK;
- switch (sigCommand) {
- case SIG_CODE_ADDTOOFFSET: {
- // add value to offset
- byteOffset += sigValue;
- break;
- }
- case SIG_CODE_UINT16:
- case SIG_CODE_SELECTOR16: {
- if ((byteOffset + 1) < scriptSize) {
- byte byte1;
- byte byte2;
-
- switch (sigCommand) {
- case SIG_CODE_UINT16: {
- byte1 = sigValue & SIG_BYTEMASK;
- signatureData++; sigWord = *signatureData;
- if (sigWord & SIG_COMMANDMASK)
- error("Script-Patcher: signature inconsistent\nFaulty patch: '%s'", patchEntry->description);
- byte2 = sigWord & SIG_BYTEMASK;
- break;
- }
- case SIG_CODE_SELECTOR16: {
- sigSelector = _selectorIdTable[sigValue];
- byte1 = sigSelector & 0xFF;
- byte2 = sigSelector >> 8;
- break;
- }
- default:
- byte1 = 0; byte2 = 0;
- }
- if (!isMacSci11) {
- if ((scriptData[byteOffset] != byte1) || (scriptData[byteOffset + 1] != byte2))
- sigWord = SIG_MISMATCH;
- } else {
- // SCI1.1+ on macintosh had uint16s in script in BE-order
- if ((scriptData[byteOffset] != byte2) || (scriptData[byteOffset + 1] != byte1))
- sigWord = SIG_MISMATCH;
- }
- byteOffset += 2;
- } else {
- sigWord = SIG_MISMATCH;
- }
- break;
- }
- case SIG_CODE_SELECTOR8: {
- if (byteOffset < scriptSize) {
- sigSelector = _selectorIdTable[sigValue];
- if (sigSelector & 0xFF00)
- error("Script-Patcher: 8 bit selector required, game uses 16 bit selector\nFaulty patch: '%s'", patchEntry->description);
- if (scriptData[byteOffset] != (sigSelector & 0xFF))
- sigWord = SIG_MISMATCH;
- byteOffset++;
- } else {
- sigWord = SIG_MISMATCH; // out of bounds
- }
- break;
- }
- case SIG_CODE_BYTE:
- if (byteOffset < scriptSize) {
- if (scriptData[byteOffset] != sigWord)
- sigWord = SIG_MISMATCH;
- byteOffset++;
- } else {
- sigWord = SIG_MISMATCH; // out of bounds
- }
- }
-
- if (sigWord == SIG_MISMATCH)
- break;
-
- signatureData++;
- sigWord = *signatureData;
- }
- if (sigWord == SIG_END) // signature fully matched?
+ if (verifySignature(offset, patchEntry->signatureData, patchEntry->description, scriptData, scriptSize))
return offset;
}
DWordOffset++;
@@ -2875,7 +3398,7 @@ int32 ScriptPatcher::findSignature(const SciScriptPatcherEntry *patchEntry, SciS
// This method calculates the magic DWORD for each entry in the signature table
// and it also initializes the selector table for selectors used in the signatures/patches of the current game
-void ScriptPatcher::initSignature(const SciScriptPatcherEntry *patchTable, bool isMacSci11) {
+void ScriptPatcher::initSignature(const SciScriptPatcherEntry *patchTable) {
const SciScriptPatcherEntry *curEntry = patchTable;
SciScriptPatcherRuntimeEntry *curRuntimeEntry;
Selector curSelector = -1;
@@ -2943,7 +3466,7 @@ void ScriptPatcher::initSignature(const SciScriptPatcherEntry *patchTable, bool
curData++; curWord = *curData;
if (curWord & SIG_COMMANDMASK)
error("Script-Patcher: signature entry inconsistent\nFaulty patch: '%s'", curEntry->description);
- if (!isMacSci11) {
+ if (!_isMacSci11) {
byte1 = curValue;
byte2 = curWord & SIG_BYTEMASK;
} else {
@@ -2958,7 +3481,7 @@ void ScriptPatcher::initSignature(const SciScriptPatcherEntry *patchTable, bool
curSelector = g_sci->getKernel()->findSelector(selectorNameTable[curValue]);
_selectorIdTable[curValue] = curSelector;
}
- if (!isMacSci11) {
+ if (!_isMacSci11) {
byte1 = curSelector & 0x00FF;
byte2 = curSelector >> 8;
} else {
@@ -3120,7 +3643,7 @@ void ScriptPatcher::processScript(uint16 scriptNr, byte *scriptData, const uint3
}
if (signatureTable) {
- bool isMacSci11 = (g_sci->getPlatform() == Common::kPlatformMacintosh && getSciVersion() >= SCI_VERSION_1_1);
+ _isMacSci11 = (g_sci->getPlatform() == Common::kPlatformMacintosh && getSciVersion() >= SCI_VERSION_1_1);
if (!_runtimeTable) {
// Abort, in case selectors are not yet initialized (happens for games w/o selector-dictionary)
@@ -3128,7 +3651,7 @@ void ScriptPatcher::processScript(uint16 scriptNr, byte *scriptData, const uint3
return;
// signature table needs to get initialized (Magic DWORD set, selector table set)
- initSignature(signatureTable, isMacSci11);
+ initSignature(signatureTable);
// Do additional game-specific initialization
switch (gameId) {
@@ -3163,11 +3686,11 @@ void ScriptPatcher::processScript(uint16 scriptNr, byte *scriptData, const uint3
int32 foundOffset = 0;
int16 applyCount = curEntry->applyCount;
do {
- foundOffset = findSignature(curEntry, curRuntimeEntry, scriptData, scriptSize, isMacSci11);
+ foundOffset = findSignature(curEntry, curRuntimeEntry, scriptData, scriptSize);
if (foundOffset != -1) {
// found, so apply the patch
debugC(kDebugLevelScriptPatcher, "Script-Patcher: '%s' on script %d offset %d", curEntry->description, scriptNr, foundOffset);
- applyPatch(curEntry, scriptData, scriptSize, foundOffset, isMacSci11);
+ applyPatch(curEntry, scriptData, scriptSize, foundOffset);
}
applyCount--;
} while ((foundOffset != -1) && (applyCount));
diff --git a/engines/sci/engine/script_patches.h b/engines/sci/engine/script_patches.h
index 7023ef327e..d15fce321b 100644
--- a/engines/sci/engine/script_patches.h
+++ b/engines/sci/engine/script_patches.h
@@ -74,7 +74,6 @@ struct SciScriptPatcherEntry {
const uint16 *patchData;
};
-//#define SCI_SIGNATUREENTRY_TERMINATOR { false, 0, NULL, 0, 0, 0, NULL, NULL }
#define SCI_SIGNATUREENTRY_TERMINATOR { false, 0, NULL, 0, NULL, NULL }
struct SciScriptPatcherRuntimeEntry {
@@ -92,15 +91,17 @@ public:
~ScriptPatcher();
void processScript(uint16 scriptNr, byte *scriptData, const uint32 scriptSize);
+ bool verifySignature(uint32 byteOffset, const uint16 *signatureData, const char *signatureDescription, const byte *scriptData, const uint32 scriptSize);
private:
- void initSignature(const SciScriptPatcherEntry *patchTable, bool isMacSci11);
+ void initSignature(const SciScriptPatcherEntry *patchTable);
void enablePatch(const SciScriptPatcherEntry *patchTable, const char *searchDescription);
- int32 findSignature(const SciScriptPatcherEntry *patchEntry, SciScriptPatcherRuntimeEntry *runtimeEntry, const byte *scriptData, const uint32 scriptSize, bool isMacSci11);
- void applyPatch(const SciScriptPatcherEntry *patchEntry, byte *scriptData, const uint32 scriptSize, int32 signatureOffset, bool isMacSci11);
+ int32 findSignature(const SciScriptPatcherEntry *patchEntry, SciScriptPatcherRuntimeEntry *runtimeEntry, const byte *scriptData, const uint32 scriptSize);
+ void applyPatch(const SciScriptPatcherEntry *patchEntry, byte *scriptData, const uint32 scriptSize, int32 signatureOffset);
Selector *_selectorIdTable;
SciScriptPatcherRuntimeEntry *_runtimeTable;
+ bool _isMacSci11;
};
} // End of namespace Sci
diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp
index c07dc925e0..417d98e2e2 100644
--- a/engines/sci/engine/state.cpp
+++ b/engines/sci/engine/state.cpp
@@ -92,6 +92,10 @@ void EngineState::reset(bool isRestoring) {
abortScriptProcessing = kAbortNone;
}
+ // reset delayed restore game functionality
+ _delayedRestoreGame = false;
+ _delayedRestoreGameId = 0;
+
executionStackBase = 0;
_executionStackPosChanged = false;
stack_base = 0;
@@ -205,7 +209,7 @@ static kLanguage charToLanguage(const char c) {
Common::String SciEngine::getSciLanguageString(const Common::String &str, kLanguage requestedLanguage, kLanguage *secondaryLanguage, uint16 *languageSplitter) const {
kLanguage foundLanguage = K_LANG_NONE;
- const byte *textPtr = (byte *)str.c_str();
+ const byte *textPtr = (const byte *)str.c_str();
byte curChar = 0;
byte curChar2 = 0;
diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h
index ecc8cb7dfe..e7499e66c9 100644
--- a/engines/sci/engine/state.h
+++ b/engines/sci/engine/state.h
@@ -131,6 +131,10 @@ public:
VirtualIndexFile *_virtualIndexFile;
#endif
+ // see detection.cpp / SciEngine::loadGameState()
+ bool _delayedRestoreGame; // boolean, that triggers delayed restore (triggered by ScummVM menu)
+ int _delayedRestoreGameId; // the saved game id, that it supposed to get restored (triggered by ScummVM menu)
+
uint _chosenQfGImportItem; // Remembers the item selected in QfG import rooms
bool _cursorWorkaroundActive; // Refer to GfxCursor::setPosition()
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index 06858540ec..6f02c96de8 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -358,12 +358,15 @@ static void callKernelFunc(EngineState *s, int kernelCallNr, int argc) {
SciTrackOriginReply originReply;
SciWorkaroundSolution solution = trackOriginAndFindWorkaround(0, kernelCall.workarounds, &originReply);
switch (solution.type) {
- case WORKAROUND_NONE:
- kernel->signatureDebug(kernelCall.signature, argc, argv);
- error("[VM] k%s[%x]: signature mismatch via method %s::%s (room %d, script %d, localCall 0x%x)",
+ case WORKAROUND_NONE: {
+ Common::String signatureDetailsStr;
+ kernel->signatureDebug(signatureDetailsStr, kernelCall.signature, argc, argv);
+ error("\n%s[VM] k%s[%x]: signature mismatch in method %s::%s (room %d, script %d, localCall 0x%x)",
+ signatureDetailsStr.c_str(),
kernelCall.name, kernelCallNr, originReply.objectName.c_str(), originReply.methodName.c_str(),
s->currentRoomNumber(), originReply.scriptNr, originReply.localCallOffset);
break;
+ }
case WORKAROUND_IGNORE: // don't do kernel call, leave acc alone
return;
case WORKAROUND_STILLCALL: // call kernel anyway
@@ -408,15 +411,18 @@ static void callKernelFunc(EngineState *s, int kernelCallNr, int argc) {
SciWorkaroundSolution solution = trackOriginAndFindWorkaround(0, kernelSubCall.workarounds, &originReply);
switch (solution.type) {
case WORKAROUND_NONE: {
- kernel->signatureDebug(kernelSubCall.signature, argc, argv);
+ Common::String signatureDetailsStr;
+ kernel->signatureDebug(signatureDetailsStr, kernelSubCall.signature, argc, argv);
int callNameLen = strlen(kernelCall.name);
if (strncmp(kernelCall.name, kernelSubCall.name, callNameLen) == 0) {
const char *subCallName = kernelSubCall.name + callNameLen;
- error("[VM] k%s(%s): signature mismatch via method %s::%s (room %d, script %d, localCall %x)",
+ error("\n%s[VM] k%s(%s): signature mismatch in method %s::%s (room %d, script %d, localCall %x)",
+ signatureDetailsStr.c_str(),
kernelCall.name, subCallName, originReply.objectName.c_str(), originReply.methodName.c_str(),
s->currentRoomNumber(), originReply.scriptNr, originReply.localCallOffset);
}
- error("[VM] k%s: signature mismatch via method %s::%s (room %d, script %d, localCall %x)",
+ error("\n%s[VM] k%s: signature mismatch in method %s::%s (room %d, script %d, localCall %x)",
+ signatureDetailsStr.c_str(),
kernelSubCall.name, originReply.objectName.c_str(), originReply.methodName.c_str(),
s->currentRoomNumber(), originReply.scriptNr, originReply.localCallOffset);
break;
diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp
index c5730b5345..aab32032f7 100644
--- a/engines/sci/engine/workarounds.cpp
+++ b/engines/sci/engine/workarounds.cpp
@@ -24,426 +24,716 @@
#include "sci/engine/object.h"
#include "sci/engine/state.h"
#include "sci/engine/vm.h"
+#include "sci/engine/script_patches.h"
#include "sci/engine/workarounds.h"
-#define SCI_WORKAROUNDENTRY_TERMINATOR { (SciGameId)0, -1, -1, 0, NULL, NULL, -1, 0, { WORKAROUND_NONE, 0 } }
+#define SCI_WORKAROUNDENTRY_TERMINATOR { (SciGameId)0, -1, -1, 0, NULL, NULL, NULL, 0, { WORKAROUND_NONE, 0 } }
namespace Sci {
-// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+// Attention:
+// To identify local-call-subroutines code signatures are used.
+// Offsets change a lot between different versions of games, especially between different language releases.
+// That's why it isn't good to hardcode the offsets of those subroutines.
+//
+// Those signatures are just like the script patcher signatures (for further study: engine\script_patches.cpp)
+// However you may NOT use command SIG_SELECTOR8 nor SIG_SELECTOR16 atm. Proper support for those may be added later.
+
+// Game: Conquests of Camelot
+// Calling method: endingCartoon2::changeState
+// Subroutine offset: English 0x020d (script 92)
+// Applies to at least: English PC floppy
+static const uint16 sig_arithmetic_camelot_1[] = {
+ 0x83, 0x32, // lal local[32h]
+ 0x30, SIG_UINT16(0x001d), // bnt [...]
+ 0x7a, // push2
+ 0x39, 0x08, // pushi 08
+ 0x36, // push
+ 0x43, // callk Graph
+ SIG_END
+};
+
+// Game: Eco Quest 2
+// Calling method: Rain::points
+// Subroutine offset: English 0x0cc6, French/Spanish 0x0ce0 (script 0)
+// Applies to at least: English/French/Spanish PC floppy
+static const uint16 sig_arithmetic_ecoq2_1[] = {
+ 0x8f, 0x01, // lsp param[1]
+ 0x35, 0x10, // ldi 10h
+ 0x08, // div
+ 0x99, 0x6e, // lsgi global[6Eh]
+ 0x38, SIG_UINT16(0x8000), // pushi 8000h
+ 0x8f, 0x01, // lsp param[1]
+ 0x35, 0x10, // ldi 10h
+ 0x0a, // mod
+ 0x0c, // shr
+ 0x14, // or
+ 0x36, // push
+ SIG_END
+};
+
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry arithmeticWorkarounds[] = {
- { GID_CAMELOT, 92, 92, 0, "endingCartoon2", "changeState", 0x20d, 0, { WORKAROUND_FAKE, 0 } }, // op_lai: during the ending, sub gets called with no parameters, uses parameter 1 which is theGrail in this case - bug #5237
- { GID_ECOQUEST2, 100, 0, 0, "Rain", "points", 0xcc6, 0, { WORKAROUND_FAKE, 0 } }, // op_or: when giving the papers to the customs officer, gets called against a pointer instead of a number - bug #4939
- { GID_ECOQUEST2, 100, 0, 0, "Rain", "points", 0xce0, 0, { WORKAROUND_FAKE, 0 } }, // Same as above, for the Spanish version - bug #5750
- { GID_FANMADE, 516, 983, 0, "Wander", "setTarget", -1, 0, { WORKAROUND_FAKE, 0 } }, // op_mul: The Legend of the Lost Jewel Demo (fan made): called with object as second parameter when attacked by insects - bug #5124
- { GID_GK1, 800,64992, 0, "Fwd", "doit", -1, 0, { WORKAROUND_FAKE, 1 } }, // op_gt: when Mosely finds Gabriel and Grace near the end of the game, compares the Grooper object with 7
- { GID_HOYLE4, 700, -1, 1, "Code", "doit", -1, 0, { WORKAROUND_FAKE, 1 } }, // op_add: while bidding in Bridge, an object ("Bid") is added to an object in another segment ("hand3")
- { GID_ICEMAN, 199, 977, 0, "Grooper", "doit", -1, 0, { WORKAROUND_FAKE, 0 } }, // op_add: While dancing with the girl
- { GID_MOTHERGOOSE256, -1, 999, 0, "Event", "new", -1, 0, { WORKAROUND_FAKE, 0 } }, // op_and: constantly during the game (SCI1 version)
- { GID_MOTHERGOOSE256, -1, 4, 0, "rm004", "doit", -1, 0, { WORKAROUND_FAKE, 0 } }, // op_or: when going north and reaching the castle (rooms 4 and 37) - bug #5101
- { GID_MOTHERGOOSEHIRES,90, 90, 0, "newGameButton", "select", -1, 0, { WORKAROUND_FAKE, 0 } }, // op_ge: MUMG Deluxe, when selecting "New Game" in the main menu. It tries to compare an integer with a list. Needs to return false for the game to continue.
- { GID_PHANTASMAGORIA, 902, 0, 0, "", "export 7", -1, 0, { WORKAROUND_FAKE, 0 } }, // op_shr: when starting a chapter in Phantasmagoria
- { GID_QFG1VGA, 301, 928, 0, "Blink", "init", -1, 0, { WORKAROUND_FAKE, 0 } }, // op_div: when entering the inn, gets called with 1 parameter, but 2nd parameter is used for div which happens to be an object
- { GID_QFG2, 200, 200, 0, "astro", "messages", -1, 0, { WORKAROUND_FAKE, 0 } }, // op_lsi: when getting asked for your name by the astrologer - bug #5152
- { GID_QFG3, 780, 999, 0, "", "export 6", -1, 0, { WORKAROUND_FAKE, 0 } }, // op_add: trying to talk to yourself at the top of the giant tree - bug #6692
- { GID_QFG4, 710,64941, 0, "RandCycle", "doit", -1, 0, { WORKAROUND_FAKE, 1 } }, // op_gt: when the tentacle appears in the third room of the caves
- SCI_WORKAROUNDENTRY_TERMINATOR
-};
-
-// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+ { GID_CAMELOT, 92, 92, 0, "endingCartoon2", "changeState", sig_arithmetic_camelot_1, 0, { WORKAROUND_FAKE, 0 } }, // op_lai: during the ending, sub gets called with no parameters, uses parameter 1 which is theGrail in this case - bug #5237
+ { GID_ECOQUEST2, 100, 0, 0, "Rain", "points", sig_arithmetic_ecoq2_1, 0, { WORKAROUND_FAKE, 0 } }, // op_or: when giving the papers to the customs officer, gets called against a pointer instead of a number - bug #4939, Spanish version - bug #5750
+ { GID_FANMADE, 516, 983, 0, "Wander", "setTarget", NULL, 0, { WORKAROUND_FAKE, 0 } }, // op_mul: The Legend of the Lost Jewel Demo (fan made): called with object as second parameter when attacked by insects - bug #5124
+ { GID_GK1, 800,64992, 0, "Fwd", "doit", NULL, 0, { WORKAROUND_FAKE, 1 } }, // op_gt: when Mosely finds Gabriel and Grace near the end of the game, compares the Grooper object with 7
+ { GID_HOYLE4, 700, -1, 1, "Code", "doit", NULL, 0, { WORKAROUND_FAKE, 1 } }, // op_add: while bidding in Bridge, an object ("Bid") is added to an object in another segment ("hand3")
+ { GID_ICEMAN, 199, 977, 0, "Grooper", "doit", NULL, 0, { WORKAROUND_FAKE, 0 } }, // op_add: While dancing with the girl
+ { GID_MOTHERGOOSE256, -1, 999, 0, "Event", "new", NULL, 0, { WORKAROUND_FAKE, 0 } }, // op_and: constantly during the game (SCI1 version)
+ { GID_MOTHERGOOSE256, -1, 4, 0, "rm004", "doit", NULL, 0, { WORKAROUND_FAKE, 0 } }, // op_or: when going north and reaching the castle (rooms 4 and 37) - bug #5101
+ { GID_MOTHERGOOSEHIRES,90, 90, 0, "newGameButton", "select", NULL, 0, { WORKAROUND_FAKE, 0 } }, // op_ge: MUMG Deluxe, when selecting "New Game" in the main menu. It tries to compare an integer with a list. Needs to return false for the game to continue.
+ { GID_PHANTASMAGORIA, 902, 0, 0, "", "export 7", NULL, 0, { WORKAROUND_FAKE, 0 } }, // op_shr: when starting a chapter in Phantasmagoria
+ { GID_QFG1VGA, 301, 928, 0, "Blink", "init", NULL, 0, { WORKAROUND_FAKE, 0 } }, // op_div: when entering the inn, gets called with 1 parameter, but 2nd parameter is used for div which happens to be an object
+ { GID_QFG2, 200, 200, 0, "astro", "messages", NULL, 0, { WORKAROUND_FAKE, 0 } }, // op_lsi: when getting asked for your name by the astrologer - bug #5152
+ { GID_QFG3, 780, 999, 0, "", "export 6", NULL, 0, { WORKAROUND_FAKE, 0 } }, // op_add: trying to talk to yourself at the top of the giant tree - bug #6692
+ { GID_QFG4, 710,64941, 0, "RandCycle", "doit", NULL, 0, { WORKAROUND_FAKE, 1 } }, // op_gt: when the tentacle appears in the third room of the caves
+ SCI_WORKAROUNDENTRY_TERMINATOR
+};
+
+// Game: Fan-Made "Ocean Battle"
+// Calling method: RoomScript::doit
+// Subroutine offset: 0x1f17
+// Applies to at least: Ocean Battle
+static const uint16 sig_uninitread_fanmade_1[] = {
+ 0x3f, 0x04, // link 04
+ 0x88, SIG_UINT16(0x023b), // lsg global[23Bh]
+ SIG_END
+};
+
+// Game: Hoyle 1
+// Calling method: export 0
+// Subroutine offset: 0x037c (script 16)
+// Applies to at least: English PC floppy
+static const uint16 sig_uninitread_hoyle1_1[] = {
+ 0x3f, 0x05, // link 05
+ 0x78, // push1
+ 0x76, // push0
+ 0x40, // call [...]
+ SIG_END
+};
+
+// Game: Hoyle 4
+// Calling method: export 2
+// Subroutine offset: 0x1d4d (script 300)
+// Applies to at least: English PC floppy
+static const uint16 sig_uninitread_hoyle4_1[] = {
+ 0x3f, 0x01, // link 01
+ 0x39, 0x40, // pushi 40h
+ 0x78, // push1
+ SIG_END
+};
+
+// Game: Jones in the fast lane
+// Calling method: weekendText::draw
+// Subroutine offset: 0x03d3 (script 232)
+// Applies to at least: English PC CD
+static const uint16 sig_uninitread_jones_1[] = {
+ 0x3f, 0x02, // link 02
+ 0x8d, 0x00, // lst temp[0]
+ 0x35, 0x01, // ldi 01
+ 0x22, // lt?
+ SIG_END
+};
+
+// Game: Conquests of the Longbow
+// Calling method: letter::handleEvent
+// Subroutine offset: English PC/Amiga 0x00a8 (script 213)
+// Applies to at least: English PC floppy, English Amiga floppy
+static const uint16 sig_uninitread_longbow_1[] = {
+ 0x3f, 0x02, // link 02
+ 0x35, 0x00, // ldi 00
+ 0xa5, 0x00, // sat temp[0]
+ 0x8d, 0x00, // lst temp[0]
+ SIG_END
+};
+
+// Game: Quest for Glory 1 / Hero's Quest 1
+// Calling method: Encounter::init
+// Subroutine offset: English Hero's Quest 0x0bd0, English Quest for Glory 1 0x0be4 (script 210)
+// Applies to at least: English PC floppy (Hero's Quest, Quest For Glory 1), Japanese PC-9801 floppy
+static const uint16 sig_uninitread_qfg1_1[] = {
+ 0x3f, 0x02, // link 02
+ 0x87, 0x00, // lap param[0]
+ 0x30, SIG_UINT16(0x000c), // bnt [...]
+ 0x87, 0x01, // lap param[1]
+ 0x30, SIG_UINT16(0x0007), // bnt [...]
+ 0x87, 0x01, // lap param[1]
+ 0xa5, 0x01, // sat temp[1]
+ SIG_END
+};
+
+// Game: Quest for Glory 1 VGA
+// Calling method: Encounter::init
+// Subroutine offset: English w/o patch 0x0cee, w/ patch 0x0ce7 (script 210)
+// Applies to at least: English PC floppy
+static const uint16 sig_uninitread_qfg1vga_1[] = {
+ 0x3f, 0x02, // link 02
+ 0x87, 0x00, // lap param[0]
+ 0x31, 0x0b, // bnt [...]
+ 0x87, 0x01, // lap param[1]
+ 0x31, 0x07, // bnt [...]
+ 0x87, 0x01, // lap param[1]
+ 0xa5, 0x01, // sat temp[1]
+ // following jump is different for patched and unpatched game
+ SIG_END
+};
+
+// Game: Quest for Glory 2
+// Calling method: abdulS::changeState, jabbarS::changeState
+// Subroutine offset: English 0x2d22 (script 260)
+// Applies to at least: English PC floppy
+static const uint16 sig_uninitread_qfg2_1[] = {
+ 0x3f, 0x03, // link 03
+ 0x39, 0x3b, // pushi 3Bh
+ 0x76, // push0
+ 0x81, 0x00, // lag global[0]
+ 0x4a, 0x04, // send 04
+ SIG_END
+};
+
+// Game: Quest for Glory 3
+// Calling method: rm140::init
+// Subroutine offset: English 0x1008 (script 140)
+// Applies to at least: English, French, German, Italian, Spanish PC floppy
+static const uint16 sig_uninitread_qfg3_1[] = {
+ 0x3f, 0x01, // link 01
+ 0x89, 0x7d, // lsg global[7Dh]
+ 0x35, 0x03, // ldi 03
+ SIG_END
+};
+
+// Game: Quest for Glory 3
+// Calling method: computersMove::changeState
+// Subroutine offset: English/etc. 0x0f53 (script 490)
+// Applies to at least: English, French, German, Italian, Spanish PC floppy
+static const uint16 sig_uninitread_qfg3_2[] = {
+ 0x3f, 0x1d, // link 1Dh
+ 0x35, 0x01, // ldi 01
+ 0xa5, 0x18, // sat temp[18h]
+ 0x35, 0xce, // ldi CEh
+ 0xa5, 0x19, // sat temp[19h]
+ 0x35, 0x00, // ldi 00
+ 0xa5, 0x00, // sat temp[0]
+ SIG_END
+};
+
+// Game: Space Quest 1
+// Calling method: firePulsar::changeState
+// Subroutine offset: English 0x018a (script 703)
+// Applies to at least: English PC floppy, English Amiga floppy
+static const uint16 sig_uninitread_sq1_1[] = {
+ 0x3f, 0x01, // link 01
+ 0x38, SIG_ADDTOOFFSET(+2), // pushi 0242 (selector egoStatus)
+ 0x76, // push0
+ 0x72, SIG_ADDTOOFFSET(+2), // lofsa DeltaurRegion
+ 0x4a, 0x04, // send 04
+ SIG_END
+};
+
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry uninitializedReadWorkarounds[] = {
- { GID_CAMELOT, 40, 40, 0, "Rm40", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // when looking at the ground at the pool of Siloam - bug #6401
- { GID_CASTLEBRAIN, 280, 280, 0, "programmer", "dispatchEvent", -1, 0, { WORKAROUND_FAKE, 0xf } }, // pressing 'q' on the computer screen in the robot room, and closing the help dialog that pops up (bug #5143). Moves the cursor to the view with the ID returned (in this case, the robot hand)
- { GID_CNICK_KQ, -1, 0, 1, "Character", "say", -1, -1, { WORKAROUND_FAKE, 0 } }, // checkers/backgammon, like in hoyle 3 - temps 504 and 505 - bug #6255
- { GID_CNICK_KQ, -1, 700, 0, "gcWindow", "open", -1, -1, { WORKAROUND_FAKE, 0 } }, // when entering the control menu, like in hoyle 3
- { GID_CNICK_KQ, 300, 303, 0, "theDoubleCube", "<noname520>", -1, 5, { WORKAROUND_FAKE, 0 } }, // while playing backgammon with doubling enabled - bug #6426 (same as the theDoubleCube::make workaround for Hoyle 3)
- { GID_CNICK_KQ, 300, 303, 0, "theDoubleCube", "<noname519>", -1, 9, { WORKAROUND_FAKE, 0 } }, // when accepting a double, while playing backgammon with doubling enabled (same as the theDoubleCube::accept workaround for Hoyle 3)
- { GID_CNICK_LAURABOW, -1, 0, 1, "Character", "say", -1, -1, { WORKAROUND_FAKE, 0 } }, // Yatch, like in hoyle 3 - temps 504 and 505 - bug #6424
- { GID_CNICK_LAURABOW, -1, 700, 0, NULL, "open", -1, -1, { WORKAROUND_FAKE, 0 } }, // when entering control menu - bug #6423 (same as the gcWindow workaround for Hoyle 3)
- { GID_CNICK_LAURABOW,100, 100, 0, NULL, "<noname144>", -1, 1, { WORKAROUND_FAKE, 0 } }, // while playing domino - bug #6429 (same as the dominoHand2 workaround for Hoyle 3)
- { GID_CNICK_LAURABOW,100, 110, 0, NULL, "doit", -1, -1, { WORKAROUND_FAKE, 0 } }, // when changing the "Dominoes per hand" setting - bug #6430
- { GID_CNICK_LONGBOW, 0, 0, 0, "RH Budget", "init", -1, 1, { WORKAROUND_FAKE, 0 } }, // when starting the game
- { GID_ECOQUEST, -1, -1, 0, NULL, "doVerb", -1, 0, { WORKAROUND_FAKE, 0 } }, // almost clicking anywhere triggers this in almost all rooms
- { GID_FANMADE, 516, 979, 0, "", "export 0", -1, 20, { WORKAROUND_FAKE, 0 } }, // Happens in Grotesteing after the logos
- { GID_FANMADE, 528, 990, 0, "GDialog", "doit", -1, 4, { WORKAROUND_FAKE, 0 } }, // Happens in Cascade Quest when closing the glossary - bug #5116
- { GID_FANMADE, 488, 1, 0, "RoomScript", "doit", 0x1f17, 1, { WORKAROUND_FAKE, 0 } }, // Happens in Ocean Battle while playing - bug #5335
- { GID_FREDDYPHARKAS, -1, 24, 0, "gcWin", "open", -1, 5, { WORKAROUND_FAKE, 0xf } }, // is used as priority for game menu
- { GID_FREDDYPHARKAS, -1, 31, 0, "quitWin", "open", -1, 5, { WORKAROUND_FAKE, 0xf } }, // is used as priority for game menu
- { GID_FREDDYPHARKAS, 540, 540, 0, "WaverCode", "init", -1, -1, { WORKAROUND_FAKE, 0 } }, // Gun pratice mini-game - bug #5232
- { GID_GK1, -1, 64950, -1, "Feature", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // sometimes when walk-clicking
- { GID_GK2, -1, 11, 0, "", "export 10", -1, 3, { WORKAROUND_FAKE, 0 } }, // called when the game starts
- { GID_GK2, -1, 11, 0, "", "export 10", -1, 4, { WORKAROUND_FAKE, 0 } }, // called during the game
- { GID_HOYLE1, 4, 104, 0, "GinRummyCardList", "calcRuns", -1, 4, { WORKAROUND_FAKE, 0 } }, // Gin Rummy / right when the game starts
- { GID_HOYLE1, 5, 204, 0, "tableau", "checkRuns", -1, 2, { WORKAROUND_FAKE, 0 } }, // Cribbage / during the game
- { GID_HOYLE1, 3, 16, 0, "", "export 0", 0x37c, 3, { WORKAROUND_FAKE, 0 } }, // Hearts / during the game - bug #5299
- { GID_HOYLE1, -1, 997, 0, "MenuBar", "doit", -1, 0, { WORKAROUND_FAKE, 0 } }, // When changing game speed settings - bug #5512
- { GID_HOYLE3, -1, 0, 1, "Character", "say", -1, -1, { WORKAROUND_FAKE, 0 } }, // when starting checkers or dominoes, first time a character says something - temps 504 and 505
- { GID_HOYLE3, -1, 700, 0, "gcWindow", "open", -1, -1, { WORKAROUND_FAKE, 0 } }, // when entering control menu
- { GID_HOYLE3, 100, 100, 0, "dominoHand2", "cue", -1, 1, { WORKAROUND_FAKE, 0 } }, // while playing domino - bug #5042
- { GID_HOYLE3, 100, 110, 0, "OKButton", "doit", -1, -1, { WORKAROUND_FAKE, 0 } }, // when changing the "Dominoes per hand" setting - bug #6430
- { GID_HOYLE3, 300, 303, 0, "theDoubleCube", "make", -1, 5, { WORKAROUND_FAKE, 0 } }, // while playing backgammon with doubling enabled
- { GID_HOYLE3, 300, 303, 0, "theDoubleCube", "accept", -1, 9, { WORKAROUND_FAKE, 0 } }, // when accepting a double, while playing backgammon with doubling enabled
- { GID_HOYLE4, -1, 0, 0, NULL, "open", -1, -1, { WORKAROUND_FAKE, 0 } }, // when selecting "Control" from the menu (temp vars 0-3) - bug #5132
- { GID_HOYLE4, 910, 18, 0, NULL, "init", -1, 0, { WORKAROUND_FAKE, 0 } }, // during tutorial - bug #5213
- { GID_HOYLE4, 910, 910, 0, NULL, "setup", -1, 3, { WORKAROUND_FAKE, 0 } }, // when selecting "Tutorial" from the main menu - bug #5132
- { GID_HOYLE4, 700, 700, 1, "BridgeHand", "calcQTS", -1, 3, { WORKAROUND_FAKE, 0 } }, // when placing a bid in bridge (always)
- { GID_HOYLE4, 700, 710, 1, "BridgeStrategyPlay", "checkSplitTops", -1, 10, { WORKAROUND_FAKE, 0 } }, // while playing bridge, objects LeadReturn_Trump, SecondSeat_Trump, ThirdSeat_Trump and others - bug #5794
- { GID_HOYLE4, 700, -1, 1, "BridgeDefense", "think", -1, -1, { WORKAROUND_FAKE, 0 } }, // sometimes while playing bridge, temp var 3, 17 and others, objects LeadReturn_Trump, ThirdSeat_Trump and others
- { GID_HOYLE4, 700, 730, 1, "BridgeDefense", "beatTheirBest", -1, 3, { WORKAROUND_FAKE, 0 } }, // rarely while playing bridge
- { GID_HOYLE4, 700, -1, 1, "Code", "doit", -1, -1, { WORKAROUND_FAKE, 0 } }, // when placing a bid in bridge (always), temp var 11, 24, 27, 46, 75, objects compete_tree, compwe_tree, other1_tree, b1 - bugs #5663 and #5794
- { GID_HOYLE4, 700, 921, 0, "Print", "addEdit", -1, 0, { WORKAROUND_FAKE, 118 } }, // when saving the game (may also occur in other situations) - bug #6601, bug #6614
- { GID_HOYLE4, 700, 921, 0, "Print", "addEdit", -1, 1, { WORKAROUND_FAKE, 1 } }, // see above, Text-control saves its coordinates to temp[0] and temp[1], Edit-control adjusts to those uninitialized temps, who by accident were left over from the Text-control
- { GID_HOYLE4, 300, 300, 0, "", "export 2", 0x1d4d, 0, { WORKAROUND_FAKE, 0 } }, // after passing around cards in hearts
- { GID_HOYLE4, 400, 400, 1, "GinHand", "calcRuns", -1, 4, { WORKAROUND_FAKE, 0 } }, // sometimes while playing Gin Rummy (e.g. when knocking and placing a card) - bug #5665
- { GID_HOYLE4, 500, 17, 1, "Character", "say", -1, 504, { WORKAROUND_FAKE, 0 } }, // sometimes while playing Cribbage (e.g. when the opponent says "Last Card") - bug #5662
- { GID_HOYLE4, -1, 937, 0, "IconBar", "dispatchEvent", -1, 408, { WORKAROUND_FAKE, 0 } }, // pressing ENTER on scoreboard while mouse is not on OK button, may not happen all the time - bug #6603
- { GID_ISLANDBRAIN, 100, 937, 0, "IconBar", "dispatchEvent", -1, 58, { WORKAROUND_FAKE, 0 } }, // when using ENTER at the startup menu - bug #5241
- { GID_ISLANDBRAIN, 140, 140, 0, "piece", "init", -1, 3, { WORKAROUND_FAKE, 1 } }, // first puzzle right at the start, some initialization variable. bnt is done on it, and it should be non-0
- { GID_ISLANDBRAIN, 200, 268, 0, "anElement", "select", -1, 0, { WORKAROUND_FAKE, 0 } }, // elements puzzle, gets used before super TextIcon
- { GID_JONES, 1, 232, 0, "weekendText", "draw", 0x3d3, 0, { WORKAROUND_FAKE, 0 } }, // jones/cd only - gets called during the game
- { GID_JONES, 1, 255, 0, "", "export 0", -1, -1, { WORKAROUND_FAKE, 0 } }, // jones/cd only - called when a game ends, temps 13 and 14
- { GID_JONES, 764, 255, 0, "", "export 0", -1, -1, { WORKAROUND_FAKE, 0 } }, // jones/ega&vga only - called when the game starts, temps 13 and 14
- //{ GID_KQ5, -1, 0, 0, "", "export 29", -1, 3, { WORKAROUND_FAKE, 0xf } }, // called when playing harp for the harpies or when aborting dialog in toy shop, is used for kDoAudio - bug #4961
+ { GID_CAMELOT, 40, 40, 0, "Rm40", "handleEvent", NULL, 0, { WORKAROUND_FAKE, 0 } }, // when looking at the ground at the pool of Siloam - bug #6401
+ { GID_CASTLEBRAIN, 280, 280, 0, "programmer", "dispatchEvent", NULL, 0, { WORKAROUND_FAKE, 0xf } }, // pressing 'q' on the computer screen in the robot room, and closing the help dialog that pops up (bug #5143). Moves the cursor to the view with the ID returned (in this case, the robot hand)
+ { GID_CNICK_KQ, -1, 0, 1, "Character", "say", NULL, -1, { WORKAROUND_FAKE, 0 } }, // checkers/backgammon, like in hoyle 3 - temps 504 and 505 - bug #6255
+ { GID_CNICK_KQ, -1, 700, 0, "gcWindow", "open", NULL, -1, { WORKAROUND_FAKE, 0 } }, // when entering the control menu, like in hoyle 3
+ { GID_CNICK_KQ, 300, 303, 0, "theDoubleCube", "<noname520>", NULL, 5, { WORKAROUND_FAKE, 0 } }, // while playing backgammon with doubling enabled - bug #6426 (same as the theDoubleCube::make workaround for Hoyle 3)
+ { GID_CNICK_KQ, 300, 303, 0, "theDoubleCube", "<noname519>", NULL, 9, { WORKAROUND_FAKE, 0 } }, // when accepting a double, while playing backgammon with doubling enabled (same as the theDoubleCube::accept workaround for Hoyle 3)
+ { GID_CNICK_LAURABOW, -1, 0, 1, "Character", "say", NULL, -1, { WORKAROUND_FAKE, 0 } }, // Yatch, like in hoyle 3 - temps 504 and 505 - bug #6424
+ { GID_CNICK_LAURABOW, -1, 700, 0, NULL, "open", NULL, -1, { WORKAROUND_FAKE, 0 } }, // when entering control menu - bug #6423 (same as the gcWindow workaround for Hoyle 3)
+ { GID_CNICK_LAURABOW,100, 100, 0, NULL, "<noname144>", NULL, 1, { WORKAROUND_FAKE, 0 } }, // while playing domino - bug #6429 (same as the dominoHand2 workaround for Hoyle 3)
+ { GID_CNICK_LAURABOW,100, 110, 0, NULL, "doit", NULL, -1, { WORKAROUND_FAKE, 0 } }, // when changing the "Dominoes per hand" setting - bug #6430
+ { GID_CNICK_LONGBOW, 0, 0, 0, "RH Budget", "init", NULL, 1, { WORKAROUND_FAKE, 0 } }, // when starting the game
+ { GID_ECOQUEST, -1, -1, 0, NULL, "doVerb", NULL, 0, { WORKAROUND_FAKE, 0 } }, // almost clicking anywhere triggers this in almost all rooms
+ { GID_FANMADE, 516, 979, 0, "", "export 0", NULL, 20, { WORKAROUND_FAKE, 0 } }, // Happens in Grotesteing after the logos
+ { GID_FANMADE, 528, 990, 0, "GDialog", "doit", NULL, 4, { WORKAROUND_FAKE, 0 } }, // Happens in Cascade Quest when closing the glossary - bug #5116
+ { GID_FANMADE, 488, 1, 0, "RoomScript", "doit", sig_uninitread_fanmade_1, 1, { WORKAROUND_FAKE, 0 } }, // Happens in Ocean Battle while playing - bug #5335
+ { GID_FREDDYPHARKAS, -1, 24, 0, "gcWin", "open", NULL, 5, { WORKAROUND_FAKE, 0xf } }, // is used as priority for game menu
+ { GID_FREDDYPHARKAS, -1, 31, 0, "quitWin", "open", NULL, 5, { WORKAROUND_FAKE, 0xf } }, // is used as priority for game menu
+ { GID_FREDDYPHARKAS, 540, 540, 0, "WaverCode", "init", NULL, -1, { WORKAROUND_FAKE, 0 } }, // Gun pratice mini-game - bug #5232
+ { GID_GK1, -1, 64950, -1, "Feature", "handleEvent", NULL, 0, { WORKAROUND_FAKE, 0 } }, // sometimes when walk-clicking
+ { GID_GK2, -1, 11, 0, "", "export 10", NULL, 3, { WORKAROUND_FAKE, 0 } }, // called when the game starts
+ { GID_GK2, -1, 11, 0, "", "export 10", NULL, 4, { WORKAROUND_FAKE, 0 } }, // called during the game
+ { GID_HOYLE1, 4, 104, 0, "GinRummyCardList", "calcRuns", NULL, 4, { WORKAROUND_FAKE, 0 } }, // Gin Rummy / right when the game starts
+ { GID_HOYLE1, 5, 204, 0, "tableau", "checkRuns", NULL, 2, { WORKAROUND_FAKE, 0 } }, // Cribbage / during the game
+ { GID_HOYLE1, 3, 16, 0, "", "export 0", sig_uninitread_hoyle1_1, 3, { WORKAROUND_FAKE, 0 } }, // Hearts / during the game - bug #5299
+ { GID_HOYLE1, -1, 997, 0, "MenuBar", "doit", NULL, 0, { WORKAROUND_FAKE, 0 } }, // When changing game speed settings - bug #5512
+ { GID_HOYLE3, -1, 0, 1, "Character", "say", NULL, -1, { WORKAROUND_FAKE, 0 } }, // when starting checkers or dominoes, first time a character says something - temps 504 and 505
+ { GID_HOYLE3, -1, 700, 0, "gcWindow", "open", NULL, -1, { WORKAROUND_FAKE, 0 } }, // when entering control menu
+ { GID_HOYLE3, 100, 100, 0, "dominoHand2", "cue", NULL, 1, { WORKAROUND_FAKE, 0 } }, // while playing domino - bug #5042
+ { GID_HOYLE3, 100, 110, 0, "OKButton", "doit", NULL, -1, { WORKAROUND_FAKE, 0 } }, // when changing the "Dominoes per hand" setting - bug #6430
+ { GID_HOYLE3, 300, 303, 0, "theDoubleCube", "make", NULL, 5, { WORKAROUND_FAKE, 0 } }, // while playing backgammon with doubling enabled
+ { GID_HOYLE3, 300, 303, 0, "theDoubleCube", "accept", NULL, 9, { WORKAROUND_FAKE, 0 } }, // when accepting a double, while playing backgammon with doubling enabled
+ { GID_HOYLE4, -1, 0, 0, NULL, "open", NULL, -1, { WORKAROUND_FAKE, 0 } }, // when selecting "Control" from the menu (temp vars 0-3) - bug #5132
+ { GID_HOYLE4, 910, 18, 0, NULL, "init", NULL, 0, { WORKAROUND_FAKE, 0 } }, // during tutorial - bug #5213
+ { GID_HOYLE4, 910, 910, 0, NULL, "setup", NULL, 3, { WORKAROUND_FAKE, 0 } }, // when selecting "Tutorial" from the main menu - bug #5132
+ { GID_HOYLE4, 700, 700, 1, "BridgeHand", "calcQTS", NULL, 3, { WORKAROUND_FAKE, 0 } }, // when placing a bid in bridge (always)
+ { GID_HOYLE4, 700, 710, 1, "BridgeStrategyPlay", "checkSplitTops", NULL, 10, { WORKAROUND_FAKE, 0 } }, // while playing bridge, objects LeadReturn_Trump, SecondSeat_Trump, ThirdSeat_Trump and others - bug #5794
+ { GID_HOYLE4, 700, -1, 1, "BridgeDefense", "think", NULL, -1, { WORKAROUND_FAKE, 0 } }, // sometimes while playing bridge, temp var 3, 17 and others, objects LeadReturn_Trump, ThirdSeat_Trump and others
+ { GID_HOYLE4, 700, 730, 1, "BridgeDefense", "beatTheirBest", NULL, 3, { WORKAROUND_FAKE, 0 } }, // rarely while playing bridge
+ { GID_HOYLE4, 700, -1, 1, "Code", "doit", NULL, -1, { WORKAROUND_FAKE, 0 } }, // when placing a bid in bridge (always), temp var 11, 24, 27, 46, 75, objects compete_tree, compwe_tree, other1_tree, b1 - bugs #5663 and #5794
+ { GID_HOYLE4, 700, 921, 0, "Print", "addEdit", NULL, 0, { WORKAROUND_FAKE, 118 } }, // when saving the game (may also occur in other situations) - bug #6601, bug #6614
+ { GID_HOYLE4, 700, 921, 0, "Print", "addEdit", NULL, 1, { WORKAROUND_FAKE, 1 } }, // see above, Text-control saves its coordinates to temp[0] and temp[1], Edit-control adjusts to those uninitialized temps, who by accident were left over from the Text-control
+ { GID_HOYLE4, 300, 300, 0, "", "export 2", sig_uninitread_hoyle4_1, 0, { WORKAROUND_FAKE, 0 } }, // after passing around cards in hearts
+ { GID_HOYLE4, 400, 400, 1, "GinHand", "calcRuns", NULL, 4, { WORKAROUND_FAKE, 0 } }, // sometimes while playing Gin Rummy (e.g. when knocking and placing a card) - bug #5665
+ { GID_HOYLE4, 500, 17, 1, "Character", "say", NULL, 504, { WORKAROUND_FAKE, 0 } }, // sometimes while playing Cribbage (e.g. when the opponent says "Last Card") - bug #5662
+ { GID_HOYLE4, 800, 870, 0, "EuchreStrategy", "thinkLead", NULL, 0, { WORKAROUND_FAKE, 0 } }, // while playing Euchre, happens at least on 2nd or 3rd turn - bug #6602
+ { GID_HOYLE4, -1, 937, 0, "IconBar", "dispatchEvent", NULL, 408, { WORKAROUND_FAKE, 0 } }, // pressing ENTER on scoreboard while mouse is not on OK button, may not happen all the time - bug #6603
+ { GID_ISLANDBRAIN, 100, 937, 0, "IconBar", "dispatchEvent", NULL, 58, { WORKAROUND_FAKE, 0 } }, // when using ENTER at the startup menu - bug #5241
+ { GID_ISLANDBRAIN, 140, 140, 0, "piece", "init", NULL, 3, { WORKAROUND_FAKE, 1 } }, // first puzzle right at the start, some initialization variable. bnt is done on it, and it should be non-0
+ { GID_ISLANDBRAIN, 200, 268, 0, "anElement", "select", NULL, 0, { WORKAROUND_FAKE, 0 } }, // elements puzzle, gets used before super TextIcon
+ { GID_JONES, 1, 232, 0, "weekendText", "draw", sig_uninitread_jones_1, 0, { WORKAROUND_FAKE, 0 } }, // jones/cd only - gets called during the game
+ { GID_JONES, 1, 255, 0, "", "export 0", NULL, -1, { WORKAROUND_FAKE, 0 } }, // jones/cd only - called when a game ends, temps 13 and 14
+ { GID_JONES, 764, 255, 0, "", "export 0", NULL, -1, { WORKAROUND_FAKE, 0 } }, // jones/ega&vga only - called when the game starts, temps 13 and 14
+ //{ GID_KQ5, -1, 0, 0, "", "export 29", NULL, 3, { WORKAROUND_FAKE, 0xf } }, // called when playing harp for the harpies or when aborting dialog in toy shop, is used for kDoAudio - bug #4961
// ^^ shouldn't be needed anymore, we got a script patch instead (kq5PatchCdHarpyVolume)
- { GID_KQ5, 25, 25, 0, "rm025", "doit", -1, 0, { WORKAROUND_FAKE, 0 } }, // inside witch forest, when going to the room where the walking rock is
- { GID_KQ5, 55, 55, 0, "helpScript", "doit", -1, 0, { WORKAROUND_FAKE, 0 } }, // when giving the tambourine to the monster in the labyrinth (only happens at one of the locations) - bug #5198
- { GID_KQ5, -1, 755, 0, "gcWin", "open", -1, -1, { WORKAROUND_FAKE, 0 } }, // when entering control menu in the FM-Towns version
- { GID_KQ6, -1, 30, 0, "rats", "changeState", -1, -1, { WORKAROUND_FAKE, 0 } }, // rats in the catacombs (temps 1 - 5) - bugs #4958, #4998, #5017
- { GID_KQ6, 210, 210, 0, "rm210", "scriptCheck", -1, 0, { WORKAROUND_FAKE, 1 } }, // using inventory in that room - bug #4953
- { GID_KQ6, 500, 500, 0, "rm500", "init", -1, 0, { WORKAROUND_FAKE, 0 } }, // going to island of the beast
- { GID_KQ6, 520, 520, 0, "rm520", "init", -1, 0, { WORKAROUND_FAKE, 0 } }, // going to boiling water trap on beast isle
- { GID_KQ6, -1, 903, 0, "controlWin", "open", -1, 4, { WORKAROUND_FAKE, 0 } }, // when opening the controls window (save, load etc)
- { GID_KQ6, -1, 907, 0, "tomato", "doVerb", -1, 2, { WORKAROUND_FAKE, 0 } }, // when looking at the rotten tomato in the inventory - bug #5331
- { GID_KQ6, -1, 928, 0, NULL, "startText", -1, 0, { WORKAROUND_FAKE, 0 } }, // gets caused by Text+Audio support (see script patcher)
- { GID_KQ7, -1, 64996, 0, "User", "handleEvent", -1, 1, { WORKAROUND_FAKE, 0 } }, // called when pushing a keyboard key
- { GID_LAURABOW, 37, 0, 0, "CB1", "doit", -1, 1, { WORKAROUND_FAKE, 0 } }, // when going up the stairs - bug #5084
- { GID_LAURABOW, -1, 967, 0, "myIcon", "cycle", -1, 1, { WORKAROUND_FAKE, 0 } }, // having any portrait conversation coming up - initial bug #4971
- { GID_LAURABOW2, -1, 24, 0, "gcWin", "open", -1, 5, { WORKAROUND_FAKE, 0xf } }, // is used as priority for game menu
- { GID_LAURABOW2, -1, 21, 0, "dropCluesCode", "doit", -1, 1, { WORKAROUND_FAKE, 0x7fff } }, // when asking some questions (e.g. the reporter about the burglary, or the policeman about Ziggy). Must be big, as the game scripts perform lt on it and start deleting journal entries - bugs #4979, #5026
- { GID_LAURABOW2, -1, 90, 1, "MuseumActor", "init", -1, 6, { WORKAROUND_FAKE, 0 } }, // Random actors in museum - bug #5197
- { GID_LAURABOW2, 240, 240, 0, "sSteveAnimates", "changeState", -1, 0, { WORKAROUND_FAKE, 0 } }, // Steve Dorian's idle animation at the docks - bug #5028
- { GID_LAURABOW2, -1, 928, 0, NULL, "startText", -1, 0, { WORKAROUND_FAKE, 0 } }, // gets caused by Text+Audio support (see script patcher)
- { GID_LONGBOW, -1, 0, 0, "Longbow", "restart", -1, 0, { WORKAROUND_FAKE, 0 } }, // When canceling a restart game - bug #5244
- { GID_LONGBOW, -1, 213, 0, "clear", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // When giving an answer using the druid hand sign code in any room
- { GID_LONGBOW, -1, 213, 0, "letter", "handleEvent", 0xa8, 1, { WORKAROUND_FAKE, 0 } }, // When using the druid hand sign code in any room - bug #5035
- { GID_LSL1, 250, 250, 0, "increase", "handleEvent", -1, 2, { WORKAROUND_FAKE, 0 } }, // casino, playing game, increasing bet
- { GID_LSL1, 720, 720, 0, "rm720", "init", -1, 0, { WORKAROUND_FAKE, 0 } }, // age check room
- { GID_LSL2, 38, 38, 0, "cloudScript", "changeState", -1, 1, { WORKAROUND_FAKE, 0 } }, // entering the room in the middle deck of the ship - bug #5034
- { GID_LSL3, 340, 340, 0, "ComicScript", "changeState", -1, -1, { WORKAROUND_FAKE, 0 } }, // right after entering the 3 ethnic groups inside comedy club (temps 200, 201, 202, 203)
- { GID_LSL3, -1, 997, 0, "TheMenuBar", "handleEvent", -1, 1, { WORKAROUND_FAKE, 0xf } }, // when setting volume the first time, this temp is used to set volume on entry (normally it would have been initialized to 's')
- { GID_LSL6, 820, 82, 0, "", "export 0", -1, -1, { WORKAROUND_FAKE, 0 } }, // when touching the electric fence - bug #5103
- { GID_LSL6, -1, 85, 0, "washcloth", "doVerb", -1, 0, { WORKAROUND_FAKE, 0 } }, // washcloth in inventory
- { GID_LSL6, -1, 928, -1, "Narrator", "startText", -1, 0, { WORKAROUND_FAKE, 0 } }, // used by various objects that are even translated in foreign versions, that's why we use the base-class
- { GID_LSL6HIRES, 0, 85, 0, "LL6Inv", "init", -1, 0, { WORKAROUND_FAKE, 0 } }, // on startup
- { GID_LSL6HIRES, -1, 64950, 1, "Feature", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // at least when entering swimming pool area
- { GID_LSL6HIRES, -1, 64964, 0, "DPath", "init", -1, 1, { WORKAROUND_FAKE, 0 } }, // during the game
- { GID_MOTHERGOOSE256, -1, 0, 0, "MG", "doit", -1, 5, { WORKAROUND_FAKE, 0 } }, // SCI1.1: When moving the cursor all the way to the left during the game - bug #5224
- { GID_MOTHERGOOSE256, -1, 992, 0, "AIPath", "init", -1, 0, { WORKAROUND_FAKE, 0 } }, // Happens in the demo and full version. In the demo, it happens when walking two screens from mother goose's house to the north. In the full version, it happens in rooms 7 and 23 - bug #5269
- { GID_MOTHERGOOSE256, 90, 90, 0, "introScript", "changeState", -1, 65, { WORKAROUND_FAKE, 0 } }, // SCI1(CD): At the very end, after the game is completed and restarted - bug #5626
- { GID_MOTHERGOOSE256, 94, 94, 0, "sunrise", "changeState", -1, 367, { WORKAROUND_FAKE, 0 } }, // At the very end, after the game is completed - bug #5294
- { GID_MOTHERGOOSEHIRES,-1,64950, 1, "Feature", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // right when clicking on a child at the start and probably also later
- { GID_MOTHERGOOSEHIRES,-1,64950, 1, "View", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // see above
- { GID_PEPPER, -1, 894, 0, "Package", "doVerb", -1, 3, { WORKAROUND_FAKE, 0 } }, // using the hand on the book in the inventory - bug #5154
- { GID_PEPPER, 150, 928, 0, "Narrator", "startText", -1, 0, { WORKAROUND_FAKE, 0 } }, // happens during the non-interactive demo of Pepper
- { GID_PQ4, -1, 25, 0, "iconToggle", "select", -1, 1, { WORKAROUND_FAKE, 0 } }, // when toggling the icon bar to auto-hide or not
- { GID_PQSWAT, -1, 64950, 0, "View", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // Using the menu in the beginning
- { GID_QFG1, -1, 210, 0, "Encounter", "init", 0xbd0, 0, { WORKAROUND_FAKE, 0 } }, // hq1: going to the brigands hideout
- { GID_QFG1, -1, 210, 0, "Encounter", "init", 0xbe4, 0, { WORKAROUND_FAKE, 0 } }, // qfg1: going to the brigands hideout
- { GID_QFG1VGA, 16, 16, 0, "lassoFailed", "changeState", -1, -1, { WORKAROUND_FAKE, 0 } }, // qfg1vga: casting the "fetch" spell in the screen with the flowers, temps 0 and 1 - bug #5309
- { GID_QFG1VGA, -1, 210, 0, "Encounter", "init", 0xcee, 0, { WORKAROUND_FAKE, 0 } }, // qfg1vga: going to the brigands hideout - bug #5515
- { GID_QFG1VGA, -1, 210, 0, "Encounter", "init", 0xce7, 0, { WORKAROUND_FAKE, 0 } }, // qfg1vga: going to room 92
- { GID_QFG2, -1, 71, 0, "theInvSheet", "doit", -1, 1, { WORKAROUND_FAKE, 0 } }, // accessing the inventory
- { GID_QFG2, -1, 701, -1, "Alley", "at", -1, 0, { WORKAROUND_FAKE, 0 } }, // when walking inside the alleys in the town - bug #5019 & #5106
- { GID_QFG2, -1, 990, 0, "Restore", "doit", -1, 364, { WORKAROUND_FAKE, 0 } }, // when pressing enter in restore dialog w/o any saved games present
- { GID_QFG2, 260, 260, 0, "abdulS", "changeState",0x2d22, -1, { WORKAROUND_FAKE, 0 } }, // During the thief's first mission (in the house), just before Abdul is about to enter the house (where you have to hide in the wardrobe), bug #5153, temps 1 and 2
- { GID_QFG2, 260, 260, 0, "jabbarS", "changeState",0x2d22, -1, { WORKAROUND_FAKE, 0 } }, // During the thief's first mission (in the house), just before Jabbar is about to enter the house (where you have to hide in the wardrobe), bug #5164, temps 1 and 2
- { GID_QFG2, 500, 500, 0, "lightNextCandleS", "changeState", -1, -1, { WORKAROUND_FAKE, 0 } }, // Inside the last room, while Ad Avis performs the ritual to summon the genie - bug #5566
- { GID_QFG2, -1, 700, 0, NULL, "showSign", -1, 10, { WORKAROUND_FAKE, 0 } }, // Occurs sometimes when reading a sign in Raseir, Shapeir et al - bugs #5627, #5635
- { GID_QFG3, 510, 510, 0, "awardPrize", "changeState", -1, 0, { WORKAROUND_FAKE, 1 } }, // Simbani warrior challenge, after throwing the spears and retrieving the ring - bug #5277. Must be non-zero, otherwise the prize is awarded twice - bug #6160
- { GID_QFG3, 140, 140, 0, "rm140", "init", 0x1008, 0, { WORKAROUND_FAKE, 0 } }, // when importing a character and selecting the previous profession - bug #5163
- { GID_QFG3, 330, 330, -1, "Teller", "doChild", -1, -1, { WORKAROUND_FAKE, 0 } }, // when talking to King Rajah about "Rajah" (bug #5033, temp 1) or "Tarna" (temp 0), or when clicking on yourself and saying "Greet" (bug #5148, temp 1)
- { GID_QFG3, 700, 700, -1, "monsterIsDead", "changeState", -1, 0, { WORKAROUND_FAKE, 0 } }, // in the jungle, after winning any fight, bug #5169
- { GID_QFG3, 470, 470, -1, "rm470", "notify", -1, 0, { WORKAROUND_FAKE, 0 } }, // closing the character screen in the Simbani village in the room with the bridge, bug #5165
- { GID_QFG3, 490, 490, -1, "computersMove", "changeState", -1, 0, { WORKAROUND_FAKE, 0 } }, // when finishing awari game, bug #5167
- { GID_QFG3, 490, 490, -1, "computersMove", "changeState", 0xf53, 4, { WORKAROUND_FAKE, 0 } }, // also when finishing awari game
- { GID_QFG3, 851, 32, -1, "ProjObj", "doit", -1, 1, { WORKAROUND_FAKE, 0 } }, // near the end, when throwing the spear of death, bug #5282
- { GID_QFG4, -1, 15, -1, "charInitScreen", "dispatchEvent", -1, 5, { WORKAROUND_FAKE, 0 } }, // floppy version, when viewing the character screen
- { GID_QFG4, -1, 64917, -1, "controlPlane", "setBitmap", -1, 3, { WORKAROUND_FAKE, 0 } }, // floppy version, when entering the game menu
- { GID_QFG4, -1, 64917, -1, "Plane", "setBitmap", -1, 3, { WORKAROUND_FAKE, 0 } }, // floppy version, happens sometimes in fight scenes
- { GID_QFG4, 520, 64950, 0, "fLake2", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // CD version, at the lake, when meeting the Rusalka and attempting to leave
- { GID_QFG4, 800, 64950, 0, "View", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // CD version, in the room with the spider pillar, when climbing on the pillar
- { GID_RAMA, 12, 64950, -1, "InterfaceFeature", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // Demo, right when it starts
- { GID_RAMA, 12, 64950, -1, "hiliteOptText", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // Demo, right when it starts
- { GID_RAMA, 12, 64950, -1, "View", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // Demo, right when it starts
- { GID_SHIVERS, -1, 952, 0, "SoundManager", "stop", -1, 2, { WORKAROUND_FAKE, 0 } }, // Just after Sierra logo
- { GID_SHIVERS, -1, 64950, 0, "Feature", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // When clicking on the locked door at the beginning
- { GID_SHIVERS, -1, 64950, 0, "View", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // When clicking on the gargoyle eye at the beginning
- { GID_SHIVERS, 20311, 64964, 0, "DPath", "init", -1, 1, { WORKAROUND_FAKE, 0 } }, // Just after door puzzle is solved and the metal balls start to roll
- { GID_SHIVERS, 29260, 29260, 0, "spMars", "handleEvent", -1, 4, { WORKAROUND_FAKE, 0 } }, // When clicking mars after seeing fortune to align earth etc...
- { GID_SHIVERS, 29260, 29260, 0, "spVenus", "handleEvent", -1, 4, { WORKAROUND_FAKE, 0 } }, // When clicking venus after seeing fortune to align earth etc...
- { GID_SQ1, 103, 103, 0, "hand", "internalEvent", -1, -1, { WORKAROUND_FAKE, 0 } }, // Spanish (and maybe early versions?) only: when moving cursor over input pad, temps 1 and 2
- { GID_SQ1, -1, 703, 0, "", "export 1", -1, 0, { WORKAROUND_FAKE, 0 } }, // sub that's called from several objects while on sarien battle cruiser
- { GID_SQ1, -1, 703, 0, "firePulsar", "changeState", 0x18a, 0, { WORKAROUND_FAKE, 0 } }, // export 1, but called locally (when shooting at aliens)
- { GID_SQ4, -1, 398, 0, "showBox", "changeState", -1, 0, { WORKAROUND_FAKE, 0 } }, // CD: called when rummaging in Software Excess bargain bin
- { GID_SQ4, -1, 928, -1, "Narrator", "startText", -1, 1000, { WORKAROUND_FAKE, 1 } }, // CD: happens in the options dialog and in-game when speech and subtitles are used simultaneously
- { GID_SQ4, -1, 708, -1, "exitBut", "doVerb", -1, 0, { WORKAROUND_FAKE, 0 } }, // Floppy: happens, when looking at the "close" button in the sq4 hintbook - bug #6447
- { GID_SQ4, -1, 708, -1, "prevBut", "doVerb", -1, 0, { WORKAROUND_FAKE, 0 } }, // Floppy: happens, when looking at the "previous" button in the sq4 hintbook - bug #6447
- { GID_SQ4, -1, 708, -1, "nextBut", "doVerb", -1, 0, { WORKAROUND_FAKE, 0 } }, // Floppy: happens, when looking at the "next" button in the sq4 hintbook - bug #6447
- { GID_SQ5, 201, 201, 0, "buttonPanel", "doVerb", -1, 0, { WORKAROUND_FAKE, 1 } }, // when looking at the orange or red button - bug #5112
- { GID_SQ6, -1, 0, 0, "SQ6", "init", -1, 2, { WORKAROUND_FAKE, 0 } }, // Demo and full version: called when the game starts (demo: room 0, full: room 100)
- { GID_SQ6, -1, 64950, -1, "Feature", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // called when pressing "Start game" in the main menu, when entering the Orion's Belt bar (room 300), and perhaps other places
- { GID_SQ6, -1, 64964, 0, "DPath", "init", -1, 1, { WORKAROUND_FAKE, 0 } }, // during the game
- { GID_TORIN, -1, 64017, 0, "oFlags", "clear", -1, 0, { WORKAROUND_FAKE, 0 } }, // entering Torin's home in the French version
- SCI_WORKAROUNDENTRY_TERMINATOR
-};
-
-// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+ { GID_KQ5, 25, 25, 0, "rm025", "doit", NULL, 0, { WORKAROUND_FAKE, 0 } }, // inside witch forest, when going to the room where the walking rock is
+ { GID_KQ5, 55, 55, 0, "helpScript", "doit", NULL, 0, { WORKAROUND_FAKE, 0 } }, // when giving the tambourine to the monster in the labyrinth (only happens at one of the locations) - bug #5198
+ { GID_KQ5, -1, 755, 0, "gcWin", "open", NULL, -1, { WORKAROUND_FAKE, 0 } }, // when entering control menu in the FM-Towns version
+ { GID_KQ6, -1, 30, 0, "rats", "changeState", NULL, -1, { WORKAROUND_FAKE, 0 } }, // rats in the catacombs (temps 1 - 5) - bugs #4958, #4998, #5017
+ { GID_KQ6, 210, 210, 0, "rm210", "scriptCheck", NULL, 0, { WORKAROUND_FAKE, 1 } }, // using inventory in that room - bug #4953
+ { GID_KQ6, 500, 500, 0, "rm500", "init", NULL, 0, { WORKAROUND_FAKE, 0 } }, // going to island of the beast
+ { GID_KQ6, 520, 520, 0, "rm520", "init", NULL, 0, { WORKAROUND_FAKE, 0 } }, // going to boiling water trap on beast isle
+ { GID_KQ6, -1, 903, 0, "controlWin", "open", NULL, 4, { WORKAROUND_FAKE, 0 } }, // when opening the controls window (save, load etc)
+ { GID_KQ6, -1, 907, 0, "tomato", "doVerb", NULL, 2, { WORKAROUND_FAKE, 0 } }, // when looking at the rotten tomato in the inventory - bug #5331
+ { GID_KQ6, -1, 928, 0, NULL, "startText", NULL, 0, { WORKAROUND_FAKE, 0 } }, // gets caused by Text+Audio support (see script patcher)
+ { GID_KQ7, -1, 64996, 0, "User", "handleEvent", NULL, 1, { WORKAROUND_FAKE, 0 } }, // called when pushing a keyboard key
+ { GID_LAURABOW, 37, 0, 0, "CB1", "doit", NULL, 1, { WORKAROUND_FAKE, 0 } }, // when going up the stairs - bug #5084
+ { GID_LAURABOW, -1, 967, 0, "myIcon", "cycle", NULL, 1, { WORKAROUND_FAKE, 0 } }, // having any portrait conversation coming up - initial bug #4971
+ { GID_LAURABOW2, -1, 24, 0, "gcWin", "open", NULL, 5, { WORKAROUND_FAKE, 0xf } }, // is used as priority for game menu
+ { GID_LAURABOW2, -1, 21, 0, "dropCluesCode", "doit", NULL, 1, { WORKAROUND_FAKE, 0x7fff } }, // when asking some questions (e.g. the reporter about the burglary, or the policeman about Ziggy). Must be big, as the game scripts perform lt on it and start deleting journal entries - bugs #4979, #5026
+ { GID_LAURABOW2, -1, 90, 1, "MuseumActor", "init", NULL, 6, { WORKAROUND_FAKE, 0 } }, // Random actors in museum - bug #5197
+ { GID_LAURABOW2, 240, 240, 0, "sSteveAnimates", "changeState", NULL, 0, { WORKAROUND_FAKE, 0 } }, // Steve Dorian's idle animation at the docks - bug #5028
+ { GID_LAURABOW2, -1, 928, 0, NULL, "startText", NULL, 0, { WORKAROUND_FAKE, 0 } }, // gets caused by Text+Audio support (see script patcher)
+ { GID_LONGBOW, -1, 0, 0, "Longbow", "restart", NULL, 0, { WORKAROUND_FAKE, 0 } }, // When canceling a restart game - bug #5244
+ { GID_LONGBOW, -1, 213, 0, "clear", "handleEvent", NULL, 0, { WORKAROUND_FAKE, 0 } }, // When giving an answer using the druid hand sign code in any room
+ { GID_LONGBOW, -1, 213, 0, "letter", "handleEvent", sig_uninitread_longbow_1, 1, { WORKAROUND_FAKE, 0 } }, // When using the druid hand sign code in any room - bug #5035
+ { GID_LSL1, 250, 250, 0, "increase", "handleEvent", NULL, 2, { WORKAROUND_FAKE, 0 } }, // casino, playing game, increasing bet
+ { GID_LSL1, 720, 720, 0, "rm720", "init", NULL, 0, { WORKAROUND_FAKE, 0 } }, // age check room
+ { GID_LSL2, 38, 38, 0, "cloudScript", "changeState", NULL, 1, { WORKAROUND_FAKE, 0 } }, // entering the room in the middle deck of the ship - bug #5034
+ { GID_LSL3, 340, 340, 0, "ComicScript", "changeState", NULL, -1, { WORKAROUND_FAKE, 0 } }, // right after entering the 3 ethnic groups inside comedy club (temps 200, 201, 202, 203)
+ { GID_LSL3, -1, 997, 0, "TheMenuBar", "handleEvent", NULL, 1, { WORKAROUND_FAKE, 0xf } }, // when setting volume the first time, this temp is used to set volume on entry (normally it would have been initialized to 's')
+ { GID_LSL6, 820, 82, 0, "", "export 0", NULL, -1, { WORKAROUND_FAKE, 0 } }, // when touching the electric fence - bug #5103
+ { GID_LSL6, -1, 85, 0, "washcloth", "doVerb", NULL, 0, { WORKAROUND_FAKE, 0 } }, // washcloth in inventory
+ { GID_LSL6, -1, 928, -1, "Narrator", "startText", NULL, 0, { WORKAROUND_FAKE, 0 } }, // used by various objects that are even translated in foreign versions, that's why we use the base-class
+ { GID_LSL6HIRES, 0, 85, 0, "LL6Inv", "init", NULL, 0, { WORKAROUND_FAKE, 0 } }, // on startup
+ { GID_LSL6HIRES, -1, 64950, 1, "Feature", "handleEvent", NULL, 0, { WORKAROUND_FAKE, 0 } }, // at least when entering swimming pool area
+ { GID_LSL6HIRES, -1, 64964, 0, "DPath", "init", NULL, 1, { WORKAROUND_FAKE, 0 } }, // during the game
+ { GID_MOTHERGOOSE256, -1, 0, 0, "MG", "doit", NULL, 5, { WORKAROUND_FAKE, 0 } }, // SCI1.1: When moving the cursor all the way to the left during the game - bug #5224
+ { GID_MOTHERGOOSE256, -1, 992, 0, "AIPath", "init", NULL, 0, { WORKAROUND_FAKE, 0 } }, // Happens in the demo and full version. In the demo, it happens when walking two screens from mother goose's house to the north. In the full version, it happens in rooms 7 and 23 - bug #5269
+ { GID_MOTHERGOOSE256, 90, 90, 0, "introScript", "changeState", NULL, 65, { WORKAROUND_FAKE, 0 } }, // SCI1(CD): At the very end, after the game is completed and restarted - bug #5626
+ { GID_MOTHERGOOSE256, 94, 94, 0, "sunrise", "changeState", NULL, 367, { WORKAROUND_FAKE, 0 } }, // At the very end, after the game is completed - bug #5294
+ { GID_MOTHERGOOSEHIRES,-1,64950, 1, "Feature", "handleEvent", NULL, 0, { WORKAROUND_FAKE, 0 } }, // right when clicking on a child at the start and probably also later
+ { GID_MOTHERGOOSEHIRES,-1,64950, 1, "View", "handleEvent", NULL, 0, { WORKAROUND_FAKE, 0 } }, // see above
+ { GID_PEPPER, -1, 894, 0, "Package", "doVerb", NULL, 3, { WORKAROUND_FAKE, 0 } }, // using the hand on the book in the inventory - bug #5154
+ { GID_PEPPER, 150, 928, 0, "Narrator", "startText", NULL, 0, { WORKAROUND_FAKE, 0 } }, // happens during the non-interactive demo of Pepper
+ { GID_PQ4, -1, 25, 0, "iconToggle", "select", NULL, 1, { WORKAROUND_FAKE, 0 } }, // when toggling the icon bar to auto-hide or not
+ { GID_PQSWAT, -1, 64950, 0, "View", "handleEvent", NULL, 0, { WORKAROUND_FAKE, 0 } }, // Using the menu in the beginning
+ { GID_QFG1, -1, 210, 0, "Encounter", "init", sig_uninitread_qfg1_1, 0, { WORKAROUND_FAKE, 0 } }, // qfg1/hq1: going to the brigands hideout
+ { GID_QFG1VGA, 16, 16, 0, "lassoFailed", "changeState", NULL, -1, { WORKAROUND_FAKE, 0 } }, // qfg1vga: casting the "fetch" spell in the screen with the flowers, temps 0 and 1 - bug #5309
+ { GID_QFG1VGA, -1, 210, 0, "Encounter", "init", sig_uninitread_qfg1vga_1, 0, { WORKAROUND_FAKE, 0 } }, // qfg1vga: going to the brigands hideout - bug #5515
+ { GID_QFG2, -1, 71, 0, "theInvSheet", "doit", NULL, 1, { WORKAROUND_FAKE, 0 } }, // accessing the inventory
+ { GID_QFG2, -1, 79, 0, "TryToMoveTo", "onTarget", NULL, 0, { WORKAROUND_FAKE, 0 } }, // when throwing pot at air elemental, happens when client coordinates are the same as airElemental coordinates. happened to me right after room change - bug #6859
+ { GID_QFG2, -1, 701, -1, "Alley", "at", NULL, 0, { WORKAROUND_FAKE, 0 } }, // when walking inside the alleys in the town - bug #5019 & #5106
+ { GID_QFG2, -1, 990, 0, "Restore", "doit", NULL, 364, { WORKAROUND_FAKE, 0 } }, // when pressing enter in restore dialog w/o any saved games present
+ { GID_QFG2, 260, 260, 0, "abdulS", "changeState", sig_uninitread_qfg2_1, -1, { WORKAROUND_FAKE, 0 } }, // During the thief's first mission (in the house), just before Abdul is about to enter the house (where you have to hide in the wardrobe), bug #5153, temps 1 and 2
+ { GID_QFG2, 260, 260, 0, "jabbarS", "changeState", sig_uninitread_qfg2_1, -1, { WORKAROUND_FAKE, 0 } }, // During the thief's first mission (in the house), just before Jabbar is about to enter the house (where you have to hide in the wardrobe), bug #5164, temps 1 and 2
+ { GID_QFG2, 500, 500, 0, "lightNextCandleS", "changeState", NULL, -1, { WORKAROUND_FAKE, 0 } }, // Inside the last room, while Ad Avis performs the ritual to summon the genie - bug #5566
+ { GID_QFG2, -1, 700, 0, NULL, "showSign", NULL, 10, { WORKAROUND_FAKE, 0 } }, // Occurs sometimes when reading a sign in Raseir, Shapeir et al - bugs #5627, #5635
+ { GID_QFG3, 510, 510, 0, "awardPrize", "changeState", NULL, 0, { WORKAROUND_FAKE, 1 } }, // Simbani warrior challenge, after throwing the spears and retrieving the ring - bug #5277. Must be non-zero, otherwise the prize is awarded twice - bug #6160
+ { GID_QFG3, 140, 140, 0, "rm140", "init", sig_uninitread_qfg3_1, 0, { WORKAROUND_FAKE, 0 } }, // when importing a character and selecting the previous profession - bug #5163
+ { GID_QFG3, 330, 330, -1, "Teller", "doChild", NULL, -1, { WORKAROUND_FAKE, 0 } }, // when talking to King Rajah about "Rajah" (bug #5033, temp 1) or "Tarna" (temp 0), or when clicking on yourself and saying "Greet" (bug #5148, temp 1)
+ { GID_QFG3, 700, 700, -1, "monsterIsDead", "changeState", NULL, 0, { WORKAROUND_FAKE, 0 } }, // in the jungle, after winning any fight, bug #5169
+ { GID_QFG3, 470, 470, -1, "rm470", "notify", NULL, 0, { WORKAROUND_FAKE, 0 } }, // closing the character screen in the Simbani village in the room with the bridge, bug #5165
+ { GID_QFG3, 490, 490, -1, "computersMove", "changeState", NULL, 0, { WORKAROUND_FAKE, 0 } }, // when finishing awari game, bug #5167
+ { GID_QFG3, 490, 490, -1, "computersMove", "changeState", sig_uninitread_qfg3_2, 4, { WORKAROUND_FAKE, 0 } }, // also when finishing awari game
+ { GID_QFG3, 851, 32, -1, "ProjObj", "doit", NULL, 1, { WORKAROUND_FAKE, 0 } }, // near the end, when throwing the spear of death, bug #5282
+ { GID_QFG4, -1, 15, -1, "charInitScreen", "dispatchEvent", NULL, 5, { WORKAROUND_FAKE, 0 } }, // floppy version, when viewing the character screen
+ { GID_QFG4, -1, 64917, -1, "controlPlane", "setBitmap", NULL, 3, { WORKAROUND_FAKE, 0 } }, // floppy version, when entering the game menu
+ { GID_QFG4, -1, 64917, -1, "Plane", "setBitmap", NULL, 3, { WORKAROUND_FAKE, 0 } }, // floppy version, happens sometimes in fight scenes
+ { GID_QFG4, 520, 64950, 0, "fLake2", "handleEvent", NULL, 0, { WORKAROUND_FAKE, 0 } }, // CD version, at the lake, when meeting the Rusalka and attempting to leave
+ { GID_QFG4, 800, 64950, 0, "View", "handleEvent", NULL, 0, { WORKAROUND_FAKE, 0 } }, // CD version, in the room with the spider pillar, when climbing on the pillar
+ { GID_RAMA, 12, 64950, -1, "InterfaceFeature", "handleEvent", NULL, 0, { WORKAROUND_FAKE, 0 } }, // Demo, right when it starts
+ { GID_RAMA, 12, 64950, -1, "hiliteOptText", "handleEvent", NULL, 0, { WORKAROUND_FAKE, 0 } }, // Demo, right when it starts
+ { GID_RAMA, 12, 64950, -1, "View", "handleEvent", NULL, 0, { WORKAROUND_FAKE, 0 } }, // Demo, right when it starts
+ { GID_SHIVERS, -1, 952, 0, "SoundManager", "stop", NULL, 2, { WORKAROUND_FAKE, 0 } }, // Just after Sierra logo
+ { GID_SHIVERS, -1, 64950, 0, "Feature", "handleEvent", NULL, 0, { WORKAROUND_FAKE, 0 } }, // When clicking on the locked door at the beginning
+ { GID_SHIVERS, -1, 64950, 0, "View", "handleEvent", NULL, 0, { WORKAROUND_FAKE, 0 } }, // When clicking on the gargoyle eye at the beginning
+ { GID_SHIVERS, 20311, 64964, 0, "DPath", "init", NULL, 1, { WORKAROUND_FAKE, 0 } }, // Just after door puzzle is solved and the metal balls start to roll
+ { GID_SHIVERS, 29260, 29260, 0, "spMars", "handleEvent", NULL, 4, { WORKAROUND_FAKE, 0 } }, // When clicking mars after seeing fortune to align earth etc...
+ { GID_SHIVERS, 29260, 29260, 0, "spVenus", "handleEvent", NULL, 4, { WORKAROUND_FAKE, 0 } }, // When clicking venus after seeing fortune to align earth etc...
+ { GID_SQ1, 103, 103, 0, "hand", "internalEvent", NULL, -1, { WORKAROUND_FAKE, 0 } }, // Spanish (and maybe early versions?) only: when moving cursor over input pad, temps 1 and 2
+ { GID_SQ1, -1, 703, 0, "", "export 1", NULL, 0, { WORKAROUND_FAKE, 0 } }, // sub that's called from several objects while on sarien battle cruiser
+ { GID_SQ1, -1, 703, 0, "firePulsar", "changeState", sig_uninitread_sq1_1, 0, { WORKAROUND_FAKE, 0 } }, // export 1, but called locally (when shooting at aliens)
+ { GID_SQ4, -1, 398, 0, "showBox", "changeState", NULL, 0, { WORKAROUND_FAKE, 0 } }, // CD: called when rummaging in Software Excess bargain bin
+ { GID_SQ4, -1, 928, -1, "Narrator", "startText", NULL, 1000, { WORKAROUND_FAKE, 1 } }, // CD: happens in the options dialog and in-game when speech and subtitles are used simultaneously
+ { GID_SQ4, -1, 708, -1, "exitBut", "doVerb", NULL, 0, { WORKAROUND_FAKE, 0 } }, // Floppy: happens, when looking at the "close" button in the sq4 hintbook - bug #6447
+ { GID_SQ4, -1, 708, -1, "", "doVerb", NULL, 0, { WORKAROUND_FAKE, 0 } }, // Floppy: happens, when looking at the "close" button... in Russian version - bug #5573
+ { GID_SQ4, -1, 708, -1, "prevBut", "doVerb", NULL, 0, { WORKAROUND_FAKE, 0 } }, // Floppy: happens, when looking at the "previous" button in the sq4 hintbook - bug #6447
+ { GID_SQ4, -1, 708, -1, "\xA8\xE6\xE3 \xAD\xA0\xA7\xA0\xA4.", "doVerb", NULL, 0, { WORKAROUND_FAKE, 0 } }, // Floppy: happens, when looking at the "previous" button... in Russian version - bug #5573
+ { GID_SQ4, -1, 708, -1, "nextBut", "doVerb", NULL, 0, { WORKAROUND_FAKE, 0 } }, // Floppy: happens, when looking at the "next" button in the sq4 hintbook - bug #6447
+ { GID_SQ4, -1, 708, -1, ".", "doVerb", NULL, 0, { WORKAROUND_FAKE, 0 } }, // Floppy: happens, when looking at the "next" button... in Russian version - bug #5573
+ { GID_SQ5, 201, 201, 0, "buttonPanel", "doVerb", NULL, 0, { WORKAROUND_FAKE, 1 } }, // when looking at the orange or red button - bug #5112
+ { GID_SQ6, -1, 0, 0, "SQ6", "init", NULL, 2, { WORKAROUND_FAKE, 0 } }, // Demo and full version: called when the game starts (demo: room 0, full: room 100)
+ { GID_SQ6, -1, 64950, -1, "Feature", "handleEvent", NULL, 0, { WORKAROUND_FAKE, 0 } }, // called when pressing "Start game" in the main menu, when entering the Orion's Belt bar (room 300), and perhaps other places
+ { GID_SQ6, -1, 64964, 0, "DPath", "init", NULL, 1, { WORKAROUND_FAKE, 0 } }, // during the game
+ { GID_TORIN, -1, 64017, 0, "oFlags", "clear", NULL, 0, { WORKAROUND_FAKE, 0 } }, // entering Torin's home in the French version
+ SCI_WORKAROUNDENTRY_TERMINATOR
+};
+
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kAbs_workarounds[] = {
- { GID_HOYLE1, 1, 1, 0, "room1", "doit", -1, 0, { WORKAROUND_FAKE, 0x3e9 } }, // crazy eights - called with objects instead of integers
- { GID_HOYLE1, 2, 2, 0, "room2", "doit", -1, 0, { WORKAROUND_FAKE, 0x3e9 } }, // old maid - called with objects instead of integers
- { GID_HOYLE1, 3, 3, 0, "room3", "doit", -1, 0, { WORKAROUND_FAKE, 0x3e9 } }, // hearts - called with objects instead of integers
- { GID_QFG1VGA, -1, -1, 0, NULL, "doit", -1, 0, { WORKAROUND_FAKE, 0x3e9 } }, // when the game is patched with the NRS patch
- { GID_QFG3 , -1, -1, 0, NULL, "doit", -1, 0, { WORKAROUND_FAKE, 0x3e9 } }, // when the game is patched with the NRS patch - bugs #6042, #6043
+ { GID_HOYLE1, 1, 1, 0, "room1", "doit", NULL, 0, { WORKAROUND_FAKE, 0x3e9 } }, // crazy eights - called with objects instead of integers
+ { GID_HOYLE1, 2, 2, 0, "room2", "doit", NULL, 0, { WORKAROUND_FAKE, 0x3e9 } }, // old maid - called with objects instead of integers
+ { GID_HOYLE1, 3, 3, 0, "room3", "doit", NULL, 0, { WORKAROUND_FAKE, 0x3e9 } }, // hearts - called with objects instead of integers
+ { GID_QFG1VGA, -1, -1, 0, NULL, "doit", NULL, 0, { WORKAROUND_FAKE, 0x3e9 } }, // when the game is patched with the NRS patch
+ { GID_QFG3 , -1, -1, 0, NULL, "doit", NULL, 0, { WORKAROUND_FAKE, 0x3e9 } }, // when the game is patched with the NRS patch - bugs #6042, #6043
SCI_WORKAROUNDENTRY_TERMINATOR
};
-// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kCelHigh_workarounds[] = {
- { GID_KQ5, -1, 255, 0, "deathIcon", "setSize", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // english floppy: when getting beaten up in the inn and probably more, called with 2nd parameter as object - bug #5049
- { GID_PQ2, -1, 255, 0, "DIcon", "setSize", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // when showing picture within windows, called with 2nd/3rd parameters as objects
- { GID_SQ1, 1, 255, 0, "DIcon", "setSize", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // DEMO: Called with 2nd/3rd parameters as objects when clicking on the menu - bug #5012
- { GID_FANMADE, -1, 979, 0, "DIcon", "setSize", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // In The Gem Scenario and perhaps other fanmade games, this is called with 2nd/3rd parameters as objects - bug #5144
+ { GID_KQ5, -1, 255, 0, "deathIcon", "setSize", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // english floppy: when getting beaten up in the inn and probably more, called with 2nd parameter as object - bug #5049
+ { GID_PQ2, -1, 255, 0, "DIcon", "setSize", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // when showing picture within windows, called with 2nd/3rd parameters as objects
+ { GID_SQ1, 1, 255, 0, "DIcon", "setSize", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // DEMO: Called with 2nd/3rd parameters as objects when clicking on the menu - bug #5012
+ { GID_FANMADE, -1, 979, 0, "DIcon", "setSize", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // In The Gem Scenario and perhaps other fanmade games, this is called with 2nd/3rd parameters as objects - bug #5144
SCI_WORKAROUNDENTRY_TERMINATOR
};
-// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kCelWide_workarounds[] = {
- { GID_KQ5, -1, 255, 0, "deathIcon", "setSize", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // english floppy: when getting beaten up in the inn and probably more, called with 2nd parameter as object - bug #5049
- { GID_PQ2, -1, 255, 0, "DIcon", "setSize", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // when showing picture within windows, called with 2nd/3rd parameters as objects
- { GID_SQ1, 1, 255, 0, "DIcon", "setSize", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // DEMO: Called with 2nd/3rd parameters as objects when clicking on the menu - bug #5012
- { GID_FANMADE, -1, 979, 0, "DIcon", "setSize", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // In The Gem Scenario and perhaps other fanmade games, this is called with 2nd/3rd parameters as objects - bug #5144
+ { GID_KQ5, -1, 255, 0, "deathIcon", "setSize", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // english floppy: when getting beaten up in the inn and probably more, called with 2nd parameter as object - bug #5049
+ { GID_PQ2, -1, 255, 0, "DIcon", "setSize", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // when showing picture within windows, called with 2nd/3rd parameters as objects
+ { GID_SQ1, 1, 255, 0, "DIcon", "setSize", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // DEMO: Called with 2nd/3rd parameters as objects when clicking on the menu - bug #5012
+ { GID_FANMADE, -1, 979, 0, "DIcon", "setSize", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // In The Gem Scenario and perhaps other fanmade games, this is called with 2nd/3rd parameters as objects - bug #5144
SCI_WORKAROUNDENTRY_TERMINATOR
};
-// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kDeleteKey_workarounds[] = {
- { GID_HOYLE4, 300, 999, 0, "handleEventList", "delete", -1, 0, { WORKAROUND_IGNORE, 0 } }, // restarting hearts, while tray is shown - bug #6604
- { GID_HOYLE4, 500, 999, 0, "handleEventList", "delete", -1, 0, { WORKAROUND_IGNORE, 0 } }, // restarting cribbage, while tray is shown - bug #6604
- { GID_HOYLE4, 975, 999, 0, "handleEventList", "delete", -1, 0, { WORKAROUND_IGNORE, 0 } }, // going back to gamelist from hearts/cribbage, while tray is shown - bug #6604
- SCI_WORKAROUNDENTRY_TERMINATOR
-};
-
-// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+ { GID_HOYLE4, 300, 999, 0, "handleEventList", "delete", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // restarting hearts, while tray is shown - bug #6604
+ { GID_HOYLE4, 500, 999, 0, "handleEventList", "delete", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // restarting cribbage, while tray is shown - bug #6604
+ { GID_HOYLE4, 975, 999, 0, "handleEventList", "delete", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // going back to gamelist from hearts/cribbage, while tray is shown - bug #6604
+ SCI_WORKAROUNDENTRY_TERMINATOR
+};
+
+// Game: Fan-Made games (SCI Studio)
+// Calling method: Game::save, Game::restore
+// Subroutine offset: Al Pond 2: 0x0e5c (ldi 0001)
+// Black Cauldron: 0x000a (ldi 01)
+// Cascade Quest: 0x0d1c (ldi 0001)
+// Demo Quest: 0x0e55 (ldi 0001)
+// I want my C64 back: 0x0e57 (ldi 0001)
+// Applies to at least: games listed above
+static const uint16 sig_kDeviceInfo_Fanmade_1[] = {
+ 0x3f, 0x79, // link 79h
+ 0x34, SIG_UINT16(0x0001), // ldi 0001
+ 0xa5, 0x00, // sat temp[0]
+ SIG_END
+};
+static const uint16 sig_kDeviceInfo_Fanmade_2[] = {
+ 0x3f, 0x79, // link 79h
+ 0x35, 0x01, // ldi 01
+ 0xa5, 0x00, // sat temp[0]
+ SIG_END
+};
+
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kDeviceInfo_workarounds[] = {
- { GID_FANMADE, -1, 994, 1, "Game", "save", 0xd1c, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (Cascade Quest)
- { GID_FANMADE, -1, 994, 1, "Game", "save", 0xe55, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (Demo Quest)
- { GID_FANMADE, -1, 994, 1, "Game", "save", 0xe57, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (I Want My C64 Back)
- { GID_FANMADE, -1, 994, 0, "Black", "save", 0xa, 0, { WORKAROUND_IGNORE, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (Black Cauldron Remake)
- { GID_FANMADE, -1, 994, 1, "Game", "save", 0xe5c, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (Most of them)
- { GID_FANMADE, -1, 994, 1, "Game", "restore", 0xd1c, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (Cascade Quest)
- { GID_FANMADE, -1, 994, 1, "Game", "restore", 0xe55, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (Demo Quest)
- { GID_FANMADE, -1, 994, 1, "Game", "restore", 0xe57, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (I Want My C64 Back)
- { GID_FANMADE, -1, 994, 1, "Game", "restore", 0xe5c, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (Most of them)
- SCI_WORKAROUNDENTRY_TERMINATOR
-};
-
-// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+ { GID_FANMADE, -1, 994, 1, "Game", "save", sig_kDeviceInfo_Fanmade_1, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games (SCI Studio), this is called with one parameter for CurDevice LDI 01 variant
+ { GID_FANMADE, -1, 994, 1, "Game", "save", sig_kDeviceInfo_Fanmade_2, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games (SCI Studio), this is called with one parameter for CurDevice LDI 0001 variant
+ { GID_FANMADE, -1, 994, 0, "Black", "save", sig_kDeviceInfo_Fanmade_1, 0, { WORKAROUND_IGNORE, 0 } }, // In fanmade games (SCI Studio), this is called with one parameter for CurDevice (Black Cauldron Remake)
+ { GID_FANMADE, -1, 994, 1, "Game", "restore", sig_kDeviceInfo_Fanmade_1, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games (SCI Studio), this is called with one parameter for CurDevice LDI 01 variant
+ { GID_FANMADE, -1, 994, 1, "Game", "restore", sig_kDeviceInfo_Fanmade_2, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games (SCI Studio), this is called with one parameter for CurDevice LDI 0001 variant
+ SCI_WORKAROUNDENTRY_TERMINATOR
+};
+
+// Game: Police Quest 2
+// Calling method: rm23Script::elements
+// Subroutine offset: English 1.001.000: 0x04ae, English 1.002.011: 0x04ca, Japanese: 0x04eb (script 23)
+// Applies to at least: English PC floppy, Japanese PC-9801
+static const uint16 sig_kDisplay_pq2_1[] = {
+ 0x35, 0x00, // ldi 00
+ 0xa3, 0x09, // sal local[9]
+ 0x35, 0x01, // ldi 01
+ 0xa3, 0x0a, // sal local[0Ah]
+ 0x38, SIG_ADDTOOFFSET(+2), // pushi selector[drawPic] TODO: implement selectors
+ 0x7a, // push2
+ 0x39, 0x5a, // pushi 5Ah
+ 0x7a, // push2
+ 0x81, 0x02, // lag global[2]
+ 0x4a, 0x08, // send 08
+ SIG_END
+};
+
+// Game: Space Quest 4
+// Calling method: doCatalog::mode
+// Subroutine offset: English PC CD: 0x0084 (script 391)
+// Applies to at least: English PC CD
+static const uint16 sig_kDisplay_sq4_1[] = {
+ 0x38, SIG_UINT16(0x0187), // pushi 0187h (drawPic)
+ 0x78, // push1
+ 0x38, SIG_UINT16(0x0189), // pushi 0189h (reflectPosn)
+ 0x81, 0x02, // lag global[2]
+ 0x4a, 0x06, // send 06
+ SIG_END
+};
+
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kDisplay_workarounds[] = {
- { GID_ISLANDBRAIN, 300, 300, 0, "geneDude", "show", -1, 0, { WORKAROUND_IGNORE, 0 } }, // when looking at the gene explanation chart - a parameter is an object
- { GID_PQ2, 23, 23, 0, "rm23Script", "elements", 0x4ae, 0, { WORKAROUND_IGNORE, 0 } }, // when looking at the 2nd page of pate's file - 0x75 as id
- { GID_PQ2, 23, 23, 0, "rm23Script", "elements", 0x4c1, 0, { WORKAROUND_IGNORE, 0 } }, // when looking at the 2nd page of pate's file - 0x75 as id (another pq2 version, bug #5223)
- { GID_QFG1, 11, 11, 0, "battle", "<noname90>", -1, 0, { WORKAROUND_IGNORE, 0 } }, // DEMO: When entering battle, 0x75 as id
- { GID_SQ4, 397, 0, 0, "", "export 12", -1, 0, { WORKAROUND_IGNORE, 0 } }, // FLOPPY: when going into the computer store - bug #5227
- { GID_SQ4, 391, 391, 0, "doCatalog", "mode", 0x84, 0, { WORKAROUND_IGNORE, 0 } }, // CD: clicking on catalog in roboter sale - a parameter is an object
- { GID_SQ4, 391, 391, 0, "choosePlug", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // CD: ordering connector in roboter sale - a parameter is an object
+ { GID_ISLANDBRAIN, 300, 300, 0, "geneDude", "show", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // when looking at the gene explanation chart - a parameter is an object
+ { GID_LONGBOW, 95, 95, 0, "countDown", "changeState", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // DEMO: during title screen "Robin Hood! Your bow is needed"
+ { GID_LONGBOW, 220, 220, 0, "moveOn", "changeState", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // DEMO: during second room "Outwit and outfight..."
+ { GID_LONGBOW, 210, 210, 0, "mama", "changeState", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // DEMO: during third room "Fall under the spell..."
+ { GID_LONGBOW, 320, 320, 0, "flyin", "changeState", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // DEMO: during fourth room "Conspiracies, love..."
+ { GID_PQ2, 23, 23, 0, "rm23Script", "elements", sig_kDisplay_pq2_1, 0, { WORKAROUND_IGNORE, 0 } }, // when looking at the 2nd page of pate's file - 0x75 as id - bug #5223
+ { GID_QFG1, 11, 11, 0, "battle", "init", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // DEMO: When entering battle, 0x75 as id
+ { GID_SQ4, 397, 0, 0, "", "export 12", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // FLOPPY: when going into the computer store - bug #5227
+ { GID_SQ4, 391, 391, 0, "doCatalog", "mode", sig_kDisplay_sq4_1, 0, { WORKAROUND_IGNORE, 0 } }, // CD: clicking on catalog in roboter sale - a parameter is an object
+ { GID_SQ4, 391, 391, 0, "choosePlug", "changeState", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // CD: ordering connector in roboter sale - a parameter is an object
SCI_WORKAROUNDENTRY_TERMINATOR
};
-// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kDirLoop_workarounds[] = {
- { GID_KQ4, 4, 992, 0, "Avoid", "doit", -1, 0, { WORKAROUND_IGNORE, 0 } }, // when the ogre catches you in front of his house, second parameter points to the same object as the first parameter, instead of being an integer (the angle) - bug #5217
+ { GID_KQ4, 4, 992, 0, "Avoid", "doit", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // when the ogre catches you in front of his house, second parameter points to the same object as the first parameter, instead of being an integer (the angle) - bug #5217
SCI_WORKAROUNDENTRY_TERMINATOR
};
-// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kDisposeScript_workarounds[] = {
- { GID_LAURABOW, 777, 777, 0, "myStab", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // DEMO: after the will is signed, parameter 0 is an object - bug #4967
- { GID_QFG1, -1, 64, 0, "rm64", "dispose", -1, 0, { WORKAROUND_IGNORE, 0 } }, // when leaving graveyard, parameter 0 is an object
- { GID_SQ4, 150, 151, 0, "fightScript", "dispose", -1, 0, { WORKAROUND_IGNORE, 0 } }, // during fight with Vohaul, parameter 0 is an object
- { GID_SQ4, 150, 152, 0, "driveCloseUp", "dispose", -1, 0, { WORKAROUND_IGNORE, 0 } }, // when choosing "beam download", parameter 0 is an object
+ { GID_LAURABOW, 777, 777, 0, "myStab", "changeState", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // DEMO: after the will is signed, parameter 0 is an object - bug #4967
+ { GID_LSL2, -1, 54, 0, "rm54", "dispose", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // Amiga: room 55, script tries to kDisposeScript an object (does not happen for DOS) - bug #6818
+ { GID_QFG1, -1, 64, 0, "rm64", "dispose", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // when leaving graveyard, parameter 0 is an object
+ { GID_SQ4, 150, 151, 0, "fightScript", "dispose", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // during fight with Vohaul, parameter 0 is an object
+ { GID_SQ4, 150, 152, 0, "driveCloseUp", "dispose", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // when choosing "beam download", parameter 0 is an object
+ { GID_SQ4, 150, 152, 0, "", "dispose", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // when choosing "beam download"... in Russian version - bug #5573
SCI_WORKAROUNDENTRY_TERMINATOR
};
-// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kDoSoundFade_workarounds[] = {
- { GID_KQ5, 213, 989, 0, "globalSound3", "fade", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // english floppy: when bandits leave the secret temple, parameter 4 is an object - bug #5078
- { GID_KQ6, 105, 989, 0, "globalSound", "fade", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // floppy: during intro, parameter 4 is an object
- { GID_KQ6, 460, 989, 0, "globalSound2", "fade", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // after pulling the black widow's web on the isle of wonder, parameter 4 is an object - bug #4954
- { GID_QFG4, -1, 64989, 0, "longSong", "fade", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // CD version: many places, parameter 4 is an object (longSong)
- { GID_SQ5, 800, 989, 0, "sq5Music1", "fade", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // when cutting the wrong part of Goliath with the laser - bug #6341
+ { GID_KQ5, 213, 989, 0, "globalSound3", "fade", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // english floppy: when bandits leave the secret temple, parameter 4 is an object - bug #5078
+ { GID_KQ6, 105, 989, 0, "globalSound", "fade", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // floppy: during intro, parameter 4 is an object
+ { GID_KQ6, 460, 989, 0, "globalSound2", "fade", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // after pulling the black widow's web on the isle of wonder, parameter 4 is an object - bug #4954
+ { GID_QFG4, -1, 64989, 0, "longSong", "fade", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // CD version: many places, parameter 4 is an object (longSong)
+ { GID_SQ5, 800, 989, 0, "sq5Music1", "fade", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // when cutting the wrong part of Goliath with the laser - bug #6341
SCI_WORKAROUNDENTRY_TERMINATOR
};
-// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kGetAngle_workarounds[] = {
- { GID_FANMADE, 516, 992, 0, "Motion", "init", -1, 0, { WORKAROUND_FAKE, 0 } }, // The Legend of the Lost Jewel Demo (fan made): called with third/fourth parameters as objects
- { GID_KQ6, -1, 752, 0, "throwDazzle", "changeState", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // room 740/790 after the Genie is exposed in the Palace (short and long ending), it starts shooting lightning bolts around. An extra 5th parameter is passed - bug #4959 & #5203
- { GID_SQ1, -1, 927, 0, "PAvoider", "doit", -1, 0, { WORKAROUND_FAKE, 0 } }, // all rooms in Ulence Flats after getting the Pilot Droid: called with a single parameter when the droid is in Roger's path - bug #6016
+ { GID_FANMADE, 516, 992, 0, "Motion", "init", NULL, 0, { WORKAROUND_FAKE, 0 } }, // The Legend of the Lost Jewel Demo (fan made): called with third/fourth parameters as objects
+ { GID_KQ6, -1, 752, 0, "throwDazzle", "changeState", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // room 740/790 after the Genie is exposed in the Palace (short and long ending), it starts shooting lightning bolts around. An extra 5th parameter is passed - bug #4959 & #5203
+ { GID_SQ1, -1, 927, 0, "PAvoider", "doit", NULL, 0, { WORKAROUND_FAKE, 0 } }, // all rooms in Ulence Flats after getting the Pilot Droid: called with a single parameter when the droid is in Roger's path - bug #6016
SCI_WORKAROUNDENTRY_TERMINATOR
};
-// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kFindKey_workarounds[] = {
- { GID_ECOQUEST2, 100, 999, 0, "myList", "contains", -1, 0, { WORKAROUND_FAKE, 0 } }, // When Noah Greene gives Adam the Ecorder, and just before the game gives a demonstration, a null reference to a list is passed - bug #4987
- { GID_HOYLE4, 300, 999, 0, "Piles", "contains", -1, 0, { WORKAROUND_FAKE, 0 } }, // When passing the three cards in Hearts, a null reference to a list is passed - bug #5664
+ { GID_ECOQUEST2, 100, 999, 0, "myList", "contains", NULL, 0, { WORKAROUND_FAKE, 0 } }, // When Noah Greene gives Adam the Ecorder, and just before the game gives a demonstration, a null reference to a list is passed - bug #4987
+ { GID_HOYLE4, 300, 999, 0, "Piles", "contains", NULL, 0, { WORKAROUND_FAKE, 0 } }, // When passing the three cards in Hearts, a null reference to a list is passed - bug #5664
SCI_WORKAROUNDENTRY_TERMINATOR
};
-// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kGraphDrawLine_workarounds[] = {
- { GID_ISLANDBRAIN, 300, 300, 0, "dudeViewer", "show", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // when looking at the gene explanation chart, gets called with 1 extra parameter
- { GID_SQ1, 43, 43, 0, "someoneDied", "changeState", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // when ordering beer, gets called with 1 extra parameter
- { GID_SQ1, 71, 71, 0, "destroyXenon", "changeState", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // during the Xenon destruction cutscene (which results in death), gets called with 1 extra parameter - bug #5176
- { GID_SQ1, 53, 53, 0, "blastEgo", "changeState", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // when Roger is found and zapped by the cleaning robot, gets called with 1 extra parameter - bug #5177
+ { GID_ISLANDBRAIN, 300, 300, 0, "dudeViewer", "show", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // when looking at the gene explanation chart, gets called with 1 extra parameter
+ { GID_SQ1, 43, 43, 0, "someoneDied", "changeState", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // when ordering beer, gets called with 1 extra parameter
+ { GID_SQ1, 71, 71, 0, "destroyXenon", "changeState", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // during the Xenon destruction cutscene (which results in death), gets called with 1 extra parameter - bug #5176
+ { GID_SQ1, 53, 53, 0, "blastEgo", "changeState", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // when Roger is found and zapped by the cleaning robot, gets called with 1 extra parameter - bug #5177
SCI_WORKAROUNDENTRY_TERMINATOR
};
-// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+// Game: Island of Dr. Brain
+// Calling method: upElevator::changeState, downElevator::changeState, correctElevator::changeState
+// Subroutine offset: 0x201f (script 291)
+// Applies to at least: English PC floppy
+static const uint16 sig_kGraphSaveBox_ibrain_1[] = {
+ 0x3f, 0x01, // link 01
+ 0x87, 0x01, // lap param[1]
+ 0x30, SIG_UINT16(0x0043), // bnt [...]
+ 0x76, // push0
+ SIG_END
+};
+
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kGraphSaveBox_workarounds[] = {
- { GID_CASTLEBRAIN, 420, 427, 0, "alienIcon", "select", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // when selecting a card during the alien card game, gets called with 1 extra parameter
- { GID_ISLANDBRAIN, 290, 291, 0, "upElevator", "changeState",0x201f, 0, { WORKAROUND_STILLCALL, 0 } }, // when testing in the elevator puzzle, gets called with 1 argument less - 15 is on stack - bug #4943
- { GID_ISLANDBRAIN, 290, 291, 0, "downElevator", "changeState",0x201f, 0, { WORKAROUND_STILLCALL, 0 } }, // see above
- { GID_ISLANDBRAIN, 290, 291, 0, "correctElevator", "changeState",0x201f, 0, { WORKAROUND_STILLCALL, 0 } }, // see above (when testing the correct solution)
- { GID_PQ3, 202, 202, 0, "MapEdit", "movePt", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // when plotting crimes, gets called with 2 extra parameters - bug #5099
+ { GID_CASTLEBRAIN, 420, 427, 0, "alienIcon", "select", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // when selecting a card during the alien card game, gets called with 1 extra parameter
+ { GID_ISLANDBRAIN, 290, 291, 0, "upElevator", "changeState", sig_kGraphSaveBox_ibrain_1, 0, { WORKAROUND_STILLCALL, 0 } }, // when testing in the elevator puzzle, gets called with 1 argument less - 15 is on stack - bug #4943
+ { GID_ISLANDBRAIN, 290, 291, 0, "downElevator", "changeState", sig_kGraphSaveBox_ibrain_1, 0, { WORKAROUND_STILLCALL, 0 } }, // see above
+ { GID_ISLANDBRAIN, 290, 291, 0, "correctElevator", "changeState", sig_kGraphSaveBox_ibrain_1, 0, { WORKAROUND_STILLCALL, 0 } }, // see above (when testing the correct solution)
+ { GID_PQ3, 202, 202, 0, "MapEdit", "movePt", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // when plotting crimes, gets called with 2 extra parameters - bug #5099
SCI_WORKAROUNDENTRY_TERMINATOR
};
-// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kGraphRestoreBox_workarounds[] = {
- { GID_LSL6, -1, 86, 0, "LL6Inv", "hide", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // happens during the game, gets called with 1 extra parameter
+ { GID_LSL6, -1, 86, 0, "LL6Inv", "hide", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // happens during the game, gets called with 1 extra parameter
SCI_WORKAROUNDENTRY_TERMINATOR
};
-// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kGraphFillBoxForeground_workarounds[] = {
- { GID_LSL6, -1, 0, 0, "LSL6", "hideControls", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // happens when giving the bungee key to merrily (room 240) and at least in room 650 too - gets called with additional 5th parameter
+ { GID_LSL6, -1, 0, 0, "LSL6", "hideControls", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // happens when giving the bungee key to merrily (room 240) and at least in room 650 too - gets called with additional 5th parameter
SCI_WORKAROUNDENTRY_TERMINATOR
};
-// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kGraphFillBoxAny_workarounds[] = {
- { GID_ECOQUEST2, 100, 333, 0, "showEcorder", "changeState", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // necessary workaround for our ecorder script patch, because there isn't enough space to patch the function
- { GID_SQ4, -1, 818, 0, "iconTextSwitch", "show", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // CD: game menu "text/speech" display - parameter 5 is missing, but the right color number is on the stack
+ { GID_ECOQUEST2, 100, 333, 0, "showEcorder", "changeState", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // necessary workaround for our ecorder script patch, because there isn't enough space to patch the function
+ { GID_SQ4, -1, 818, 0, "iconTextSwitch", "show", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // CD: game menu "text/speech" display - parameter 5 is missing, but the right color number is on the stack
SCI_WORKAROUNDENTRY_TERMINATOR
};
-// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+// Game: Space Quest 4
+// Calling method: laserScript::changeState
+// Subroutine offset: English/German/French/Russian PC floppy, Japanese PC-9801: 0x0016, English PC CD: 0x00b2 (script 150)
+// Applies to at least: English/German/French/Russian PC floppy, English PC CD, Japanese PC-9801
+static const uint16 sig_kGraphRedrawBox_sq4_1[] = {
+ 0x3f, 0x07, // link 07
+ 0x39, SIG_ADDTOOFFSET(+1), // pushi 2Ah for PC floppy, pushi 27h for PC CD
+ 0x76, // push0
+ 0x72, // lofsa laserSound
+ SIG_END
+};
+
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kGraphRedrawBox_workarounds[] = {
- { GID_SQ4, 405, 405, 0, "swimAfterEgo", "changeState", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // skateOrama when "swimming" in the air - accidental additional parameter specified
- { GID_SQ4, 406, 406, 0, "egoFollowed", "changeState", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // FLOPPY: when getting shot by the police - accidental additional parameter specified
- { GID_SQ4, 406, 406, 0, "swimAndShoot", "changeState", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // skateOrama when "swimming" in the air - accidental additional parameter specified
- { GID_SQ4, 410, 410, 0, "swimAfterEgo", "changeState", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // skateOrama when "swimming" in the air - accidental additional parameter specified
- { GID_SQ4, 411, 411, 0, "swimAndShoot", "changeState", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // skateOrama when "swimming" in the air - accidental additional parameter specified
- { GID_SQ4, 150, 150, 0, "laserScript", "changeState", 0xb2, 0, { WORKAROUND_STILLCALL, 0 } }, // when visiting the pedestral where Roger Jr. is trapped, before trashing the brain icon in the programming chapter, accidental additional parameter specified - bug #5479
- { GID_SQ4, 150, 150, 0, "laserScript", "changeState", 0x16, 0, { WORKAROUND_STILLCALL, 0 } }, // same as above, for the German version - bug #5527
- { GID_SQ4, -1, 704, 0, "shootEgo", "changeState", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // When shot by Droid in Super Computer Maze (Rooms 500, 505, 510...) - accidental additional parameter specified
- { GID_KQ5, -1, 981, 0, "myWindow", "dispose", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // Happens in the floppy version, when closing any dialog box, accidental additional parameter specified - bug #5031
- { GID_KQ5, -1, 995, 0, "invW", "doit", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // Happens in the floppy version, when closing the inventory window, accidental additional parameter specified
- { GID_KQ5, -1, 995, 0, "", "export 0", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // Happens in the floppy version, when opening the gem pouch, accidental additional parameter specified - bug #5138
- { GID_KQ5, -1, 403, 0, "KQ5Window", "dispose", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // Happens in the FM Towns version when closing any dialog box, accidental additional parameter specified
- SCI_WORKAROUNDENTRY_TERMINATOR
-};
-
-// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+ { GID_SQ4, 405, 405, 0, "swimAfterEgo", "changeState", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // skateOrama when "swimming" in the air - accidental additional parameter specified
+ { GID_SQ4, 405, 405, 0, "", "changeState", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // skateOrama when "swimming" in the air... Russian version - bug #5573
+ { GID_SQ4, 406, 406, 0, "egoFollowed", "changeState", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // FLOPPY: when getting shot by the police - accidental additional parameter specified
+ { GID_SQ4, -1, 406, 0, "swimAndShoot", "changeState", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // skateOrama when "swimming" in the air - accidental additional parameter specified
+ { GID_SQ4, -1, 406, 0, "", "changeState", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // skateOrama when "swimming" in the air... Russian version - bug #5573 (is for both egoFollowed and swimAndShoot)
+ { GID_SQ4, 410, 410, 0, "swimAfterEgo", "changeState", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // skateOrama when "swimming" in the air - accidental additional parameter specified
+ { GID_SQ4, 410, 410, 0, "", "changeState", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // skateOrama when "swimming" in the air... Russian version - bug #5573
+ { GID_SQ4, 411, 411, 0, "swimAndShoot", "changeState", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // skateOrama when "swimming" in the air - accidental additional parameter specified
+ { GID_SQ4, 411, 411, 0, "", "changeState", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // skateOrama when "swimming" in the air... Russian version - bug #5573
+ { GID_SQ4, 150, 150, 0, "laserScript", "changeState", sig_kGraphRedrawBox_sq4_1, 0, { WORKAROUND_STILLCALL, 0 } }, // when visiting the pedestral where Roger Jr. is trapped, before trashing the brain icon in the programming chapter, accidental additional parameter specified - bug #5479, German - bug #5527
+ { GID_SQ4, 150, 150, 0, "", "changeState", sig_kGraphRedrawBox_sq4_1, 0, { WORKAROUND_STILLCALL, 0 } }, // same as above, for the Russian version - bug #5573
+ { GID_SQ4, -1, 704, 0, "shootEgo", "changeState", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // When shot by Droid in Super Computer Maze (Rooms 500, 505, 510...) - accidental additional parameter specified
+ { GID_KQ5, -1, 981, 0, "myWindow", "dispose", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // Happens in the floppy version, when closing any dialog box, accidental additional parameter specified - bug #5031
+ { GID_KQ5, -1, 995, 0, "invW", "doit", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // Happens in the floppy version, when closing the inventory window, accidental additional parameter specified
+ { GID_KQ5, -1, 995, 0, "", "export 0", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // Happens in the floppy version, when opening the gem pouch, accidental additional parameter specified - bug #5138
+ { GID_KQ5, -1, 403, 0, "KQ5Window", "dispose", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // Happens in the FM Towns version when closing any dialog box, accidental additional parameter specified
+ SCI_WORKAROUNDENTRY_TERMINATOR
+};
+
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kGraphUpdateBox_workarounds[] = {
- { GID_ECOQUEST2, 100, 333, 0, "showEcorder", "changeState", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // necessary workaround for our ecorder script patch, because there isn't enough space to patch the function
- { GID_PQ3, 202, 202, 0, "MapEdit", "addPt", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // when plotting crimes, gets called with 2 extra parameters - bug #5099
- { GID_PQ3, 202, 202, 0, "MapEdit", "movePt", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // when plotting crimes, gets called with 2 extra parameters - bug #5099
- { GID_PQ3, 202, 202, 0, "MapEdit", "dispose", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // when plotting crimes, gets called with 2 extra parameters
+ { GID_ECOQUEST2, 100, 333, 0, "showEcorder", "changeState", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // necessary workaround for our ecorder script patch, because there isn't enough space to patch the function
+ { GID_PQ3, 202, 202, 0, "MapEdit", "addPt", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // when plotting crimes, gets called with 2 extra parameters - bug #5099
+ { GID_PQ3, 202, 202, 0, "MapEdit", "movePt", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // when plotting crimes, gets called with 2 extra parameters - bug #5099
+ { GID_PQ3, 202, 202, 0, "MapEdit", "dispose", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // when plotting crimes, gets called with 2 extra parameters
SCI_WORKAROUNDENTRY_TERMINATOR
};
-// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kIsObject_workarounds[] = {
- { GID_GK1, 50, 999, 0, "List", "eachElementDo", -1, 0, { WORKAROUND_FAKE, 0 } }, // GK1 demo, when asking Grace for messages it gets called with an invalid parameter (type "error") - bug #4950
- { GID_ISLANDBRAIN, -1, 999, 0, "List", "eachElementDo", -1, 0, { WORKAROUND_FAKE, 0 } }, // when going to the game options, choosing "Info" and selecting anything from the list, gets called with an invalid parameter (type "error") - bug #4989
- { GID_QFG3, -1, 999, 0, "List", "eachElementDo", -1, 0, { WORKAROUND_FAKE, 0 } }, // when asking for something, gets called with type error parameter
+ { GID_GK1, 50, 999, 0, "List", "eachElementDo", NULL, 0, { WORKAROUND_FAKE, 0 } }, // GK1 demo, when asking Grace for messages it gets called with an invalid parameter (type "error") - bug #4950
+ { GID_ISLANDBRAIN, -1, 999, 0, "List", "eachElementDo", NULL, 0, { WORKAROUND_FAKE, 0 } }, // when going to the game options, choosing "Info" and selecting anything from the list, gets called with an invalid parameter (type "error") - bug #4989
+ { GID_QFG3, -1, 999, 0, "List", "eachElementDo", NULL, 0, { WORKAROUND_FAKE, 0 } }, // when asking for something, gets called with type error parameter
SCI_WORKAROUNDENTRY_TERMINATOR
};
-// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kMemory_workarounds[] = {
- { GID_LAURABOW2, -1, 999, 0, "", "export 6", -1, 0, { WORKAROUND_FAKE, 0 } }, // during the intro, when exiting the train (room 160), talking to Mr. Augustini, etc. - bug #4944
- { GID_SQ1, -1, 999, 0, "", "export 6", -1, 0, { WORKAROUND_FAKE, 0 } }, // during walking Roger around Ulence Flats - bug #6017
+ { GID_LAURABOW2, -1, 999, 0, "", "export 6", NULL, 0, { WORKAROUND_FAKE, 0 } }, // during the intro, when exiting the train (room 160), talking to Mr. Augustini, etc. - bug #4944
+ { GID_SQ1, -1, 999, 0, "", "export 6", NULL, 0, { WORKAROUND_FAKE, 0 } }, // during walking Roger around Ulence Flats - bug #6017
SCI_WORKAROUNDENTRY_TERMINATOR
};
-// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kMoveCursor_workarounds[] = {
- { GID_KQ5, -1, 937, 0, "IconBar", "handleEvent", -1, 0, { WORKAROUND_IGNORE, 0 } }, // when pressing escape to open the menu, gets called with one parameter instead of 2 - bug #5575
+ { GID_KQ5, -1, 937, 0, "IconBar", "handleEvent", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // when pressing escape to open the menu, gets called with one parameter instead of 2 - bug #5575
SCI_WORKAROUNDENTRY_TERMINATOR
};
-// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kNewWindow_workarounds[] = {
- { GID_ECOQUEST, -1, 981, 0, "SysWindow", "open", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // EcoQuest 1 demo uses an in-between interpreter from SCI1 to SCI1.1. It's SCI1.1, but uses the SCI1 semantics for this call - bug #4976
+ { GID_ECOQUEST, -1, 981, 0, "SysWindow", "open", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // EcoQuest 1 demo uses an in-between interpreter from SCI1 to SCI1.1. It's SCI1.1, but uses the SCI1 semantics for this call - bug #4976
SCI_WORKAROUNDENTRY_TERMINATOR
};
-// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kReadNumber_workarounds[] = {
- { GID_CNICK_LAURABOW,100, 101, 0, "dominoes.opt", "doit", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // When dominoes.opt is present, the game scripts call kReadNumber with an extra integer parameter - bug #6425
- { GID_HOYLE3, 100, 101, 0, "dominoes.opt", "doit", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // When dominoes.opt is present, the game scripts call kReadNumber with an extra integer parameter - bug #6425
+ { GID_CNICK_LAURABOW,100, 101, 0, "dominoes.opt", "doit", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // When dominoes.opt is present, the game scripts call kReadNumber with an extra integer parameter - bug #6425
+ { GID_HOYLE3, 100, 101, 0, "dominoes.opt", "doit", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // When dominoes.opt is present, the game scripts call kReadNumber with an extra integer parameter - bug #6425
SCI_WORKAROUNDENTRY_TERMINATOR
};
-// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kPaletteUnsetFlag_workarounds[] = {
- { GID_QFG4, 100, 100, 0, "doMovie", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // after the Sierra logo, no flags are passed, thus the call is meaningless - bug #4947
+ { GID_QFG4, 100, 100, 0, "doMovie", "changeState", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // after the Sierra logo, no flags are passed, thus the call is meaningless - bug #4947
SCI_WORKAROUNDENTRY_TERMINATOR
};
-// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kSetCursor_workarounds[] = {
- { GID_KQ5, -1, 768, 0, "KQCursor", "init", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // CD: gets called with 4 additional "900d" parameters
+ { GID_KQ5, -1, 768, 0, "KQCursor", "init", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // CD: gets called with 4 additional "900d" parameters
SCI_WORKAROUNDENTRY_TERMINATOR
};
-// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kSetPort_workarounds[] = {
- { GID_LSL6, 740, 740, 0, "rm740", "drawPic", -1, 0, { WORKAROUND_IGNORE, 0 } }, // ending scene, is called with additional 3 (!) parameters
- { GID_QFG3, 830, 830, 0, "portalOpens", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // when the portal appears during the end, gets called with 4 parameters - bug #5174
+ { GID_LSL6, 740, 740, 0, "rm740", "drawPic", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // ending scene, is called with additional 3 (!) parameters
+ { GID_QFG3, 830, 830, 0, "portalOpens", "changeState", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // when the portal appears during the end, gets called with 4 parameters - bug #5174
SCI_WORKAROUNDENTRY_TERMINATOR
};
-// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+// Game: Island of Dr. Brain
+// Calling method: childBreed::changeState
+// Subroutine offset: 0x1c7c (script 310)
+// Applies to at least: English PC floppy
+static const uint16 sig_kStrAt_ibrain_1[] = {
+ 0x3f, 0x16, // link 16
+ 0x78, // push1
+ 0x8f, 0x01, // lsp param[1]
+ 0x43, // callk StrLen
+ SIG_END
+};
+
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kStrAt_workarounds[] = {
- { GID_CASTLEBRAIN, 220, 220, 0, "robotJokes", "animateOnce", -1, 0, { WORKAROUND_FAKE, 0 } }, // when trying to view the terminal at the end of the maze without having collected any robot jokes - bug #5127
- { GID_ISLANDBRAIN, 300, 310, 0, "childBreed", "changeState",0x1c7c, 0, { WORKAROUND_FAKE, 0 } }, // when clicking Breed to get the second-generation cyborg hybrid (Standard difficulty), the two parameters are swapped - bug #5088
+ { GID_CASTLEBRAIN, 220, 220, 0, "robotJokes", "animateOnce", NULL, 0, { WORKAROUND_FAKE, 0 } }, // when trying to view the terminal at the end of the maze without having collected any robot jokes - bug #5127
+ { GID_ISLANDBRAIN, 300, 310, 0, "childBreed", "changeState", sig_kStrAt_ibrain_1, 0, { WORKAROUND_FAKE, 0 } }, // when clicking Breed to get the second-generation cyborg hybrid (Standard difficulty), the two parameters are swapped - bug #5088
SCI_WORKAROUNDENTRY_TERMINATOR
};
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kStrCpy_workarounds[] = {
- { GID_MOTHERGOOSE, 23, 23, 0, "talkScript", "changeState", -1, 0, { WORKAROUND_FAKE, 0 } }, // when talking to the girl in scene 23, there's no destination parameter (script bug - wrong instruction order). The original source is used directly afterwards in kDisplay, to show the girl's text - bug #6485
+ { GID_MOTHERGOOSE, 23, 23, 0, "talkScript", "changeState", NULL, 0, { WORKAROUND_FAKE, 0 } }, // when talking to the girl in scene 23, there's no destination parameter (script bug - wrong instruction order). The original source is used directly afterwards in kDisplay, to show the girl's text - bug #6485
SCI_WORKAROUNDENTRY_TERMINATOR
};
-// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+// Game: Quest for Glory 2
+// Calling method: export 21 of script 2
+// Subroutine offset: English 0x0deb (script 2)
+// Applies to at least: English PC floppy
+static const uint16 sig_kStrLen_qfg2_1[] = {
+ 0x3f, 0x04, // link 04
+ 0x78, // push1
+ 0x8f, 0x02, // lsp param[2]
+ 0x43, // callk StrLen
+ SIG_END
+};
+
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kStrLen_workarounds[] = {
- { GID_QFG2, 210, 2, 0, "", "export 21", 0xdeb, 0, { WORKAROUND_FAKE, 0 } }, // When saying something incorrect at the WIT, an integer is passed instead of a reference - bug #5489
+ { GID_QFG2, 210, 2, 0, "", "export 21", sig_kStrLen_qfg2_1, 0, { WORKAROUND_FAKE, 0 } }, // When saying something incorrect at the WIT, an integer is passed instead of a reference - bug #5489
SCI_WORKAROUNDENTRY_TERMINATOR
};
-// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kUnLoad_workarounds[] = {
- { GID_ECOQUEST, 380, 61, 0, "gotIt", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // CD version: after talking to the dolphin the first time, a 3rd parameter is passed by accident
- { GID_ECOQUEST, 380, 69, 0, "lookAtBlackBoard", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // German version, when closing the blackboard closeup in the dolphin room, a 3rd parameter is passed by accident - bug #5483
- { GID_LAURABOW2, -1, -1, 0, "sCartoon", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // DEMO: during the intro, a 3rd parameter is passed by accident - bug #4966
- { GID_LSL6, 130, 130, 0, "recruitLarryScr", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // during intro, a 3rd parameter is passed by accident
- { GID_LSL6, 740, 740, 0, "showCartoon", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // during ending, 4 additional parameters are passed by accident
- { GID_LSL6HIRES, 130, 130, 0, "recruitLarryScr", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // during intro, a 3rd parameter is passed by accident
- { GID_SQ1, 43, 303, 0, "slotGuy", "dispose", -1, 0, { WORKAROUND_IGNORE, 0 } }, // when leaving ulence flats bar, parameter 1 is not passed - script error
- { GID_QFG4, -1, 110, 0, "dreamer", "dispose", -1, 0, { WORKAROUND_IGNORE, 0 } }, // during the dream sequence, a 3rd parameter is passed by accident
+ { GID_ECOQUEST, 380, 61, 0, "gotIt", "changeState", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // CD version: after talking to the dolphin the first time, a 3rd parameter is passed by accident
+ { GID_ECOQUEST, 380, 69, 0, "lookAtBlackBoard", "changeState", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // German version, when closing the blackboard closeup in the dolphin room, a 3rd parameter is passed by accident - bug #5483
+ { GID_LAURABOW2, -1, -1, 0, "sCartoon", "changeState", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // DEMO: during the intro, a 3rd parameter is passed by accident - bug #4966
+ { GID_LSL6, 130, 130, 0, "recruitLarryScr", "changeState", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // during intro, a 3rd parameter is passed by accident
+ { GID_LSL6, 740, 740, 0, "showCartoon", "changeState", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // during ending, 4 additional parameters are passed by accident
+ { GID_LSL6HIRES, 130, 130, 0, "recruitLarryScr", "changeState", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // during intro, a 3rd parameter is passed by accident
+ { GID_SQ1, 43, 303, 0, "slotGuy", "dispose", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // when leaving ulence flats bar, parameter 1 is not passed - script error
+ { GID_QFG4, -1, 110, 0, "dreamer", "dispose", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // during the dream sequence, a 3rd parameter is passed by accident
SCI_WORKAROUNDENTRY_TERMINATOR
};
@@ -461,8 +751,9 @@ SciWorkaroundSolution trackOriginAndFindWorkaround(int index, const SciWorkaroun
ExecStack *lastCall = state->xs;
const Script *localScript = state->_segMan->getScriptIfLoaded(lastCall->local_segment);
int curScriptNr = localScript->getScriptNumber();
+ int curLocalCallOffset = lastCall->debugLocalCallOffset;
- if (lastCall->debugLocalCallOffset != -1) {
+ if (curLocalCallOffset != -1) {
// if lastcall was actually a local call search back for a real call
Common::List<ExecStack>::const_iterator callIterator = state->_executionStack.end();
while (callIterator != state->_executionStack.begin()) {
@@ -494,19 +785,17 @@ SciWorkaroundSolution trackOriginAndFindWorkaround(int index, const SciWorkaroun
// Search if there is a workaround for this one
const SciWorkaroundEntry *workaround;
int16 inheritanceLevel = 0;
- Common::String searchObjectName = curObjectName;
+ Common::String searchObjectName = g_sci->getSciLanguageString(curObjectName, K_LANG_ENGLISH);
reg_t searchObject = lastCall->sendp;
+ const byte *curScriptPtr = NULL;
+ uint32 curScriptSize = 0;
+ bool matched = false;
+
do {
workaround = workaroundList;
while (workaround->methodName) {
bool objectNameMatches = (workaround->objectName == NULL) ||
- (workaround->objectName == g_sci->getSciLanguageString(searchObjectName, K_LANG_ENGLISH));
-
- // Special case: in the fanmade Russian translation of SQ4, all
- // of the object names have been deleted or renamed to Russian,
- // thus we disable checking of the object name. Fixes bug #5573.
- if (g_sci->getLanguage() == Common::RU_RUS && g_sci->getGameId() == GID_SQ4)
- objectNameMatches = true;
+ (workaround->objectName == searchObjectName);
if (workaround->gameId == gameId
&& ((workaround->scriptNr == -1) || (workaround->scriptNr == curScriptNr))
@@ -514,10 +803,46 @@ SciWorkaroundSolution trackOriginAndFindWorkaround(int index, const SciWorkaroun
&& ((workaround->inheritanceLevel == -1) || (workaround->inheritanceLevel == inheritanceLevel))
&& objectNameMatches
&& workaround->methodName == g_sci->getSciLanguageString(curMethodName, K_LANG_ENGLISH)
- && workaround->localCallOffset == lastCall->debugLocalCallOffset
&& ((workaround->index == -1) || (workaround->index == index))) {
// Workaround found
- return workaround->newValue;
+ if ((workaround->localCallSignature) || (curLocalCallOffset >= 0)) {
+ // local call signature found and/or subcall was made
+ if ((workaround->localCallSignature) && (curLocalCallOffset >= 0)) {
+ // local call signature found and subcall was made -> check signature accordingly
+ if (!curScriptPtr) {
+ // get script data
+ int segmentId = g_sci->getEngineState()->_segMan->getScriptSegment(curScriptNr);
+ SegmentObj *segmentObj = NULL;
+ if (segmentId) {
+ segmentObj = g_sci->getEngineState()->_segMan->getScriptIfLoaded(segmentId);
+ }
+ if (!segmentObj) {
+ workaround++;
+ continue;
+ }
+ Script *scriptObj = (Script *)segmentObj;
+ curScriptPtr = scriptObj->getBuf();
+ curScriptSize = scriptObj->getScriptSize();
+ }
+
+ // now actually check for signature match
+ if (g_sci->getScriptPatcher()->verifySignature(curLocalCallOffset, workaround->localCallSignature, "workaround signature", curScriptPtr, curScriptSize)) {
+ matched = true;
+ }
+
+ } else {
+ // mismatch, so workaround doesn't match
+ workaround++;
+ continue;
+ }
+ } else {
+ // no localcalls involved -> workaround matches
+ matched = true;
+ }
+ if (matched) {
+ debugC(kDebugLevelWorkarounds, "Workaround: '%s:%s' in script %d, localcall %x", workaround->objectName, workaround->methodName, curScriptNr, curLocalCallOffset);
+ return workaround->newValue;
+ }
}
workaround++;
}
diff --git a/engines/sci/engine/workarounds.h b/engines/sci/engine/workarounds.h
index 9cad618481..46059a175c 100644
--- a/engines/sci/engine/workarounds.h
+++ b/engines/sci/engine/workarounds.h
@@ -60,7 +60,7 @@ struct SciWorkaroundEntry {
int16 inheritanceLevel;
const char *objectName;
const char *methodName;
- int localCallOffset;
+ const uint16 *localCallSignature;
int index;
SciWorkaroundSolution newValue;
};
diff --git a/engines/sci/graphics/paint16.cpp b/engines/sci/graphics/paint16.cpp
index f80703e14d..6004e9ce7a 100644
--- a/engines/sci/graphics/paint16.cpp
+++ b/engines/sci/graphics/paint16.cpp
@@ -471,9 +471,6 @@ void GfxPaint16::kernelGraphRedrawBox(Common::Rect rect) {
#define SCI_DISPLAY_WIDTH 106
#define SCI_DISPLAY_SAVEUNDER 107
#define SCI_DISPLAY_RESTOREUNDER 108
-#define SCI_DISPLAY_DUMMY1 114
-#define SCI_DISPLAY_DUMMY2 115
-#define SCI_DISPLAY_DUMMY3 117
#define SCI_DISPLAY_DONTSHOWBITS 121
reg_t GfxPaint16::kernelDisplay(const char *text, uint16 languageSplitter, int argc, reg_t *argv) {
@@ -543,22 +540,6 @@ reg_t GfxPaint16::kernelDisplay(const char *text, uint16 languageSplitter, int a
bRedraw = 0;
break;
- // The following three dummy calls are not supported by the Sierra SCI
- // interpreter, but are erroneously called in some game scripts.
- case SCI_DISPLAY_DUMMY1: // Longbow demo (all rooms) and QFG1 EGA demo (room 11)
- case SCI_DISPLAY_DUMMY2: // Longbow demo (all rooms)
- case SCI_DISPLAY_DUMMY3: // QFG1 EGA demo (room 11) and PQ2 (room 23)
- if (!(g_sci->getGameId() == GID_LONGBOW && g_sci->isDemo()) &&
- !(g_sci->getGameId() == GID_QFG1 && g_sci->isDemo()) &&
- !(g_sci->getGameId() == GID_PQ2))
- error("Unknown kDisplay argument %d", displayArg.getOffset());
-
- if (displayArg.getOffset() == SCI_DISPLAY_DUMMY2) {
- if (!argc)
- error("No parameter left for kDisplay(115)");
- argc--; argv++;
- }
- break;
default:
SciTrackOriginReply originReply;
SciWorkaroundSolution solution = trackOriginAndFindWorkaround(0, kDisplay_workarounds, &originReply);
diff --git a/engines/sci/graphics/portrait.cpp b/engines/sci/graphics/portrait.cpp
index 668de616fb..cb425f3be9 100644
--- a/engines/sci/graphics/portrait.cpp
+++ b/engines/sci/graphics/portrait.cpp
@@ -57,13 +57,39 @@ void Portrait::init() {
// 4 bytes paletteSize (base 1)
// -> 17 bytes
// paletteSize bytes paletteData
- // 14 bytes bitmap header
- // -> 4 bytes unknown
- // -> 2 bytes height
- // -> 2 bytes width
- // -> 6 bytes unknown
- // height * width bitmap data
- // another animation count times bitmap header and data
+ //
+ // bitmap-data follows, total of [animation count]
+ // 14 bytes bitmap header
+ // -> 4 bytes unknown
+ // -> 2 bytes height
+ // -> 2 bytes width
+ // -> 6 bytes unknown
+ // height * width bitmap data
+ //
+ // 4 bytes offset table size (may be larger than the actual known entries?!)
+ // 14 bytes all zeroes (dummy entry?!)
+ //
+ // 14 bytes for each entry
+ // -> 2 bytes displace X
+ // -> 2 bytes displace Y
+ // -> 2 bytes height (again)
+ // -> 2 bytes width (again)
+ // -> 6 bytes unknown (normally 01 00 00 00 00 00 for delta bitmaps, 00 00 00 00 00 00 for first bitmap)
+ // random data may be used as filler
+ //
+ // 4 bytes lip sync id table size (is [lip sync id count] * 4, should be 0x2E0 for all actors)
+ // 4 bytes per lip sync id
+ // -> 1 byte length of ID
+ // -> 3 bytes actual ID
+ //
+ // 4 bytes lip sync id data table size (seems to be the same for all actors, always 0x220 in size)
+ // 1 byte animation number or 0xFF as terminator
+ // 1 byte delay, if last byte was not terminator
+ // one array for every lip sync id
+ //
+ // 4 bytes appended, seem to be random
+ // 9E11120E for alex
+ // 9E9E9E9E for vizier
int32 fileSize = 0;
Common::SeekableReadStream *file =
SearchMan.createReadStreamForMember("actors/" + _resourceName + ".bin");
@@ -202,8 +228,9 @@ void Portrait::doit(Common::Point position, uint16 resourceId, uint16 noun, uint
if (raveResource->size < 4000) {
memcpy(debugPrint, raveResource->data, raveResource->size);
debugPrint[raveResource->size] = 0; // set terminating NUL
+ debug("kPortrait: using actor %s", _resourceName.c_str());
debug("kPortrait (noun %d, verb %d, cond %d, seq %d)", noun, verb, cond, seq);
- debug("kPortrait: %s", debugPrint);
+ debug("kPortrait: rave data is '%s'", debugPrint);
}
#endif
@@ -273,6 +300,14 @@ void Portrait::doit(Common::Point position, uint16 resourceId, uint16 noun, uint
raveLipSyncData = NULL;
}
+#ifdef DEBUG_PORTRAIT
+ if (raveID & 0x0ff) {
+ debug("kPortrait: rave '%c%c' after %d ticks", raveID >> 8, raveID & 0x0ff, raveTicks);
+ } else if (raveID) {
+ debug("kPortrait: rave '%c' after %d ticks", raveID >> 8, raveTicks);
+ }
+#endif
+
timerPosition += raveTicks;
// Wait till syncTime passed, then show specific animation bitmap
@@ -282,7 +317,8 @@ void Portrait::doit(Common::Point position, uint16 resourceId, uint16 noun, uint
curEvent = _event->getSciEvent(SCI_EVENT_ANY);
if (curEvent.type == SCI_EVENT_MOUSE_PRESS ||
(curEvent.type == SCI_EVENT_KEYBOARD && curEvent.data == SCI_KEY_ESC) ||
- g_sci->getEngineState()->abortScriptProcessing == kAbortQuitGame)
+ g_sci->getEngineState()->abortScriptProcessing == kAbortQuitGame ||
+ g_sci->getEngineState()->_delayedRestoreGame)
userAbort = true;
curPosition = _audio->getAudioPosition();
} while ((curPosition != -1) && (curPosition < timerPosition) && (!userAbort));
@@ -295,6 +331,8 @@ void Portrait::doit(Common::Point position, uint16 resourceId, uint16 noun, uint
timerPositionWithin = timerPosition;
raveLipSyncTicks = *raveLipSyncData++;
while ( (raveLipSyncData < _lipSyncDataOffsetTableEnd) && (raveLipSyncTicks != 0xFF) ) {
+ if (raveLipSyncTicks)
+ raveLipSyncTicks--; // 1 -> wait 0 ticks, 2 -> wait 1 tick, etc.
timerPositionWithin += raveLipSyncTicks;
do {
@@ -308,6 +346,13 @@ void Portrait::doit(Common::Point position, uint16 resourceId, uint16 noun, uint
} while ((curPosition != -1) && (curPosition < timerPositionWithin) && (!userAbort));
raveLipSyncBitmapNr = *raveLipSyncData++;
+#ifdef DEBUG_PORTRAIT
+ if (!raveLipSyncTicks) {
+ debug("kPortrait: showing frame %d", raveLipSyncBitmapNr);
+ } else {
+ debug("kPortrait: showing frame %d after %d ticks", raveLipSyncBitmapNr, raveLipSyncTicks);
+ }
+#endif
// bitmap nr within sync data is base 1, we need base 0
raveLipSyncBitmapNr--;
diff --git a/engines/sci/graphics/screen.cpp b/engines/sci/graphics/screen.cpp
index 8b0e76332f..ca5b5b3b8c 100644
--- a/engines/sci/graphics/screen.cpp
+++ b/engines/sci/graphics/screen.cpp
@@ -81,7 +81,8 @@ GfxScreen::GfxScreen(ResourceManager *resMan) : _resMan(resMan) {
case GID_LSL1:
case GID_LSL5:
case GID_SQ1:
- _width = 190;
+ _scriptHeight = 190;
+ break;
default:
break;
}
@@ -238,6 +239,8 @@ GfxScreen::GfxScreen(ResourceManager *resMan) : _resMan(resMan) {
_vectorPutPixelPtr = &GfxScreen::putPixelDisplayUpscaled;
_putPixelPtr = &GfxScreen::putPixelDisplayUpscaled;
break;
+ case GFX_SCREEN_UPSCALED_DISABLED:
+ break;
}
}
@@ -248,6 +251,18 @@ GfxScreen::~GfxScreen() {
free(_displayScreen);
}
+// should not be used regularly; only meant for restore game
+void GfxScreen::clearForRestoreGame() {
+ // reset all screen data
+ memset(_visualScreen, 0, _pixels);
+ memset(_priorityScreen, 0, _pixels);
+ memset(_controlScreen, 0, _pixels);
+ memset(_displayScreen, 0, _displayPixels);
+ memset(&_ditheredPicColors, 0, sizeof(_ditheredPicColors));
+ _fontIsUpscaled = false;
+ copyToScreen();
+}
+
void GfxScreen::copyToScreen() {
g_system->copyRectToScreen(_activeScreen, _displayWidth, 0, 0, _displayWidth, _displayHeight);
}
diff --git a/engines/sci/graphics/screen.h b/engines/sci/graphics/screen.h
index 766e32614a..1c946ef02f 100644
--- a/engines/sci/graphics/screen.h
+++ b/engines/sci/graphics/screen.h
@@ -76,6 +76,7 @@ public:
byte getColorWhite() { return _colorWhite; }
byte getColorDefaultVectorData() { return _colorDefaultVectorData; }
+ void clearForRestoreGame();
void copyToScreen();
void copyFromScreen(byte *buffer);
void kernelSyncWithFramebuffer();
diff --git a/engines/sci/parser/vocabulary.cpp b/engines/sci/parser/vocabulary.cpp
index 000b037b44..828a57abeb 100644
--- a/engines/sci/parser/vocabulary.cpp
+++ b/engines/sci/parser/vocabulary.cpp
@@ -74,6 +74,8 @@ Vocabulary::Vocabulary(ResourceManager *resMan, bool foreign) : _resMan(resMan),
parser_event = NULL_REG;
parserIsValid = false;
+
+ _pronounReference = 0x1000; // Non-existent word
}
Vocabulary::~Vocabulary() {
@@ -738,4 +740,79 @@ int Vocabulary::parseNodes(int *i, int *pos, int type, int nr, int argc, const c
return oldPos;
}
+
+// FIXME: Duplicated from said.cpp
+static int node_major(ParseTreeNode* node) {
+ assert(node->type == kParseTreeBranchNode);
+ assert(node->left->type == kParseTreeLeafNode);
+ return node->left->value;
+}
+static bool node_is_terminal(ParseTreeNode* node) {
+ return (node->right->right &&
+ node->right->right->type != kParseTreeBranchNode);
+}
+static int node_terminal_value(ParseTreeNode* node) {
+ assert(node_is_terminal(node));
+ return node->right->right->value;
+}
+
+static ParseTreeNode* scanForMajor(ParseTreeNode *tree, int major) {
+ assert(tree);
+
+ if (node_is_terminal(tree)) {
+ if (node_major(tree) == major)
+ return tree;
+ else
+ return 0;
+ }
+
+ ParseTreeNode* ptr = tree->right;
+
+ // Scan children
+ while (ptr->right) {
+ ptr = ptr->right;
+
+ if (node_major(ptr->left) == major)
+ return ptr->left;
+ }
+
+ if (major == 0x141)
+ return 0;
+
+ // If not found, go into a 0x141 and try again
+ tree = scanForMajor(tree, 0x141);
+ if (!tree)
+ return 0;
+ return scanForMajor(tree, major);
+}
+
+bool Vocabulary::storePronounReference() {
+ assert(parserIsValid);
+
+ ParseTreeNode *ptr = scanForMajor(_parserNodes, 0x142); // 0x142 = object?
+
+ while (ptr && !node_is_terminal(ptr))
+ ptr = scanForMajor(ptr, 0x141);
+
+ if (!ptr)
+ return false;
+
+ _pronounReference = node_terminal_value(ptr);
+
+ debugC(kDebugLevelParser, "Stored pronoun reference: %x", _pronounReference);
+ return true;
+}
+
+void Vocabulary::replacePronouns(ResultWordListList &words) {
+ if (_pronounReference == 0x1000)
+ return;
+
+ for (ResultWordListList::iterator i = words.begin(); i != words.end(); ++i)
+ for (ResultWordList::iterator j = i->begin(); j != i->end(); ++j)
+ if (j->_class & (VOCAB_CLASS_PRONOUN << 4)) {
+ j->_class = VOCAB_CLASS_NOUN << 4;
+ j->_group = _pronounReference;
+ }
+}
+
} // End of namespace Sci
diff --git a/engines/sci/parser/vocabulary.h b/engines/sci/parser/vocabulary.h
index 09499946cb..f4adee6e55 100644
--- a/engines/sci/parser/vocabulary.h
+++ b/engines/sci/parser/vocabulary.h
@@ -233,6 +233,16 @@ public:
int parseGNF(const ResultWordListList &words, bool verbose = false);
/**
+ * Find and store reference for future pronouns
+ */
+ bool storePronounReference();
+
+ /**
+ * Replace pronouns by stored reference
+ */
+ void replacePronouns(ResultWordListList &words);
+
+ /**
* Constructs the Greibach Normal Form of the grammar supplied in 'branches'.
* @param verbose Set to true for debugging. If true, the list is
* freed before the function ends
@@ -360,6 +370,8 @@ private:
SynonymList _synonyms; /**< The list of synonyms */
Common::Array<Common::List<AltInput> > _altInputs;
+ int _pronounReference;
+
public:
// Accessed by said()
ParseTreeNode _parserNodes[VOCAB_TREE_NODES]; /**< The parse tree */
diff --git a/engines/sci/resource.h b/engines/sci/resource.h
index 62f3c584ac..ef48998b04 100644
--- a/engines/sci/resource.h
+++ b/engines/sci/resource.h
@@ -596,6 +596,7 @@ public:
Track *getDigitalTrack();
int getChannelFilterMask(int hardwareMask, bool wantsRhythm);
byte getInitialVoiceCount(byte channel);
+ byte getSoundPriority() const { return _soundPriority; }
private:
SciVersion _soundVersion;
@@ -603,6 +604,7 @@ private:
Track *_tracks;
Resource *_innerResource;
ResourceManager *_resMan;
+ byte _soundPriority;
};
} // End of namespace Sci
diff --git a/engines/sci/resource_audio.cpp b/engines/sci/resource_audio.cpp
index c775f502c5..3a43774492 100644
--- a/engines/sci/resource_audio.cpp
+++ b/engines/sci/resource_audio.cpp
@@ -579,6 +579,7 @@ SoundResource::SoundResource(uint32 resourceNr, ResourceManager *resMan, SciVers
return;
_innerResource = resource;
+ _soundPriority = 0xFF;
byte *data, *data2;
byte *dataEnd;
@@ -725,6 +726,9 @@ SoundResource::SoundResource(uint32 resourceNr, ResourceManager *resMan, SciVers
data += 6;
}
} else {
+ // The first byte of the 0xF0 track's channel list is priority
+ _soundPriority = *data;
+
// Skip over digital track
data += 6;
}
diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp
index 60a1271b89..668ad053cc 100644
--- a/engines/sci/sci.cpp
+++ b/engines/sci/sci.cpp
@@ -114,6 +114,7 @@ SciEngine::SciEngine(OSystem *syst, const ADGameDescription *desc, SciGameId gam
DebugMan.addDebugChannel(kDebugLevelVM, "VM", "VM debugging");
DebugMan.addDebugChannel(kDebugLevelScripts, "Scripts", "Notifies when scripts are unloaded");
DebugMan.addDebugChannel(kDebugLevelScriptPatcher, "ScriptPatcher", "Notifies when scripts are patched");
+ DebugMan.addDebugChannel(kDebugLevelWorkarounds, "Workarounds", "Notifies when workarounds are triggered");
DebugMan.addDebugChannel(kDebugLevelGC, "GC", "Garbage Collector debugging");
DebugMan.addDebugChannel(kDebugLevelResMan, "ResMan", "Resource manager debugging");
DebugMan.addDebugChannel(kDebugLevelOnStartup, "OnStartup", "Enter debugger at start of game");
@@ -281,25 +282,13 @@ Common::Error SciEngine::run() {
// Check whether loading a savestate was requested
int directSaveSlotLoading = ConfMan.getInt("save_slot");
if (directSaveSlotLoading >= 0) {
- // call GameObject::play (like normally)
- initStackBaseWithSelector(SELECTOR(play));
- // We set this, so that the game automatically quit right after init
- _gamestate->variables[VAR_GLOBAL][4] = TRUE_REG;
+ _gamestate->_delayedRestoreGame = true;
+ _gamestate->_delayedRestoreGameId = directSaveSlotLoading;
// Jones only initializes its menus when restarting/restoring, thus set
// the gameIsRestarting flag here before initializing. Fixes bug #6536.
if (g_sci->getGameId() == GID_JONES)
_gamestate->gameIsRestarting = GAMEISRESTARTING_RESTORE;
-
- _gamestate->_executionStackPosChanged = false;
- run_vm(_gamestate);
-
- // As soon as we get control again, actually restore the game
- reg_t restoreArgv[2] = { NULL_REG, make_reg(0, directSaveSlotLoading) }; // special call (argv[0] is NULL)
- kRestoreGame(_gamestate, 2, restoreArgv);
-
- // this indirectly calls GameObject::init, which will setup menu, text font/color codes etc.
- // without this games would be pretty badly broken
}
// Show any special warnings for buggy scripts with severe game bugs,
diff --git a/engines/sci/sci.h b/engines/sci/sci.h
index 4928fd1b4e..c6813aa07c 100644
--- a/engines/sci/sci.h
+++ b/engines/sci/sci.h
@@ -105,7 +105,8 @@ enum kDebugLevels {
kDebugLevelResMan = 1 << 19,
kDebugLevelOnStartup = 1 << 20,
kDebugLevelDebugMode = 1 << 21,
- kDebugLevelScriptPatcher = 1 << 22
+ kDebugLevelScriptPatcher = 1 << 22,
+ kDebugLevelWorkarounds = 1 << 23
};
enum SciGameId {
diff --git a/engines/sci/sound/audio.cpp b/engines/sci/sound/audio.cpp
index 8e35d6b055..fb9a3f17b9 100644
--- a/engines/sci/sound/audio.cpp
+++ b/engines/sci/sound/audio.cpp
@@ -391,18 +391,13 @@ Audio::RewindableAudioStream *AudioPlayer::getAudioStream(uint32 number, uint32
} else if (audioRes->size > 4 && READ_BE_UINT32(audioRes->data) == MKTAG('F','O','R','M')) {
// AIFF detected
Common::SeekableReadStream *waveStream = new Common::MemoryReadStream(audioRes->data, audioRes->size, DisposeAfterUse::NO);
+ Audio::RewindableAudioStream *rewindStream = Audio::makeAIFFStream(waveStream, DisposeAfterUse::YES);
+ audioSeekStream = dynamic_cast<Audio::SeekableAudioStream *>(rewindStream);
- // Calculate samplelen from AIFF header
- int waveSize = 0, waveRate = 0;
- byte waveFlags = 0;
- bool ret = Audio::loadAIFFFromStream(*waveStream, waveSize, waveRate, waveFlags);
- if (!ret)
- error("Failed to load AIFF from stream");
-
- *sampleLen = (waveFlags & Audio::FLAG_16BITS ? waveSize >> 1 : waveSize) * 60 / waveRate;
-
- waveStream->seek(0, SEEK_SET);
- audioStream = Audio::makeAIFFStream(waveStream, DisposeAfterUse::YES);
+ if (!audioSeekStream) {
+ warning("AIFF file is not seekable");
+ delete rewindStream;
+ }
} else if (audioRes->size > 14 && READ_BE_UINT16(audioRes->data) == 1 && READ_BE_UINT16(audioRes->data + 2) == 1
&& READ_BE_UINT16(audioRes->data + 4) == 5 && READ_BE_UINT32(audioRes->data + 10) == 0x00018051) {
// Mac snd detected
diff --git a/engines/sci/sound/drivers/adlib.cpp b/engines/sci/sound/drivers/adlib.cpp
index fcfda2f532..4f557be95e 100644
--- a/engines/sci/sound/drivers/adlib.cpp
+++ b/engines/sci/sound/drivers/adlib.cpp
@@ -27,7 +27,7 @@
#include "common/textconsole.h"
#include "audio/fmopl.h"
-#include "audio/softsynth/emumidi.h"
+#include "audio/mididrv.h"
#include "sci/resource.h"
#include "sci/sound/drivers/mididriver.h"
@@ -43,29 +43,30 @@ namespace Sci {
// FIXME: We don't seem to be sending the polyphony init data, so disable this for now
#define ADLIB_DISABLE_VOICE_MAPPING
-class MidiDriver_AdLib : public MidiDriver_Emulated {
+class MidiDriver_AdLib : public MidiDriver {
public:
enum {
kVoices = 9,
kRhythmKeys = 62
};
- MidiDriver_AdLib(Audio::Mixer *mixer) : MidiDriver_Emulated(mixer), _playSwitch(true), _masterVolume(15), _rhythmKeyMap(0), _opl(0) { }
+ MidiDriver_AdLib(Audio::Mixer *mixer) :_playSwitch(true), _masterVolume(15), _rhythmKeyMap(0), _opl(0), _isOpen(false) { }
virtual ~MidiDriver_AdLib() { }
// MidiDriver
+ int open() { return -1; } // Dummy implementation (use openAdLib)
int openAdLib(bool isSCI0);
void close();
void send(uint32 b);
MidiChannel *allocateChannel() { return NULL; }
MidiChannel *getPercussionChannel() { return NULL; }
+ bool isOpen() const { return _isOpen; }
+ uint32 getBaseTempo() { return 1000000 / OPL::OPL::kDefaultCallbackFrequency; }
- // AudioStream
- bool isStereo() const { return _stereo; }
- int getRate() const { return _mixer->getOutputRate(); }
+ // MidiDriver
+ void setTimerCallback(void *timerParam, Common::TimerManager::TimerProc timerProc);
- // MidiDriver_Emulated
- void generateSamples(int16 *buf, int len);
+ void onTimer();
void setVolume(byte volume);
void playSwitch(bool play);
@@ -133,6 +134,7 @@ private:
bool _stereo;
bool _isSCI0;
OPL::OPL *_opl;
+ bool _isOpen;
bool _playSwitch;
int _masterVolume;
Channel _channels[MIDI_CHANNELS];
@@ -140,6 +142,9 @@ private:
byte *_rhythmKeyMap;
Common::Array<AdLibPatch> _patches;
+ Common::TimerManager::TimerProc _adlibTimerProc;
+ void *_adlibTimerParam;
+
void loadInstrument(const byte *ins);
void voiceOn(int voice, int note, int velocity);
void voiceOff(int voice);
@@ -215,14 +220,12 @@ static const int ym3812_note[13] = {
};
int MidiDriver_AdLib::openAdLib(bool isSCI0) {
- int rate = _mixer->getOutputRate();
-
_stereo = STEREO;
debug(3, "ADLIB: Starting driver in %s mode", (isSCI0 ? "SCI0" : "SCI1"));
_isSCI0 = isSCI0;
- _opl = OPL::Config::create(isStereo() ? OPL::Config::kDualOpl2 : OPL::Config::kOpl2);
+ _opl = OPL::Config::create(_stereo ? OPL::Config::kDualOpl2 : OPL::Config::kOpl2);
// Try falling back to mono, thus plain OPL2 emualtor, when no Dual OPL2 is available.
if (!_opl && _stereo) {
@@ -233,22 +236,24 @@ int MidiDriver_AdLib::openAdLib(bool isSCI0) {
if (!_opl)
return -1;
- _opl->init(rate);
+ if (!_opl->init()) {
+ delete _opl;
+ _opl = nullptr;
+ return -1;
+ }
setRegister(0xBD, 0);
setRegister(0x08, 0);
setRegister(0x01, 0x20);
- MidiDriver_Emulated::open();
+ _isOpen = true;
- _mixer->playStream(Audio::Mixer::kPlainSoundType, &_mixerSoundHandle, this, -1, _mixer->kMaxChannelVolume, 0, DisposeAfterUse::NO);
+ _opl->start(new Common::Functor0Mem<void, MidiDriver_AdLib>(this, &MidiDriver_AdLib::onTimer));
return 0;
}
void MidiDriver_AdLib::close() {
- _mixer->stopHandle(_mixerSoundHandle);
-
delete _opl;
delete[] _rhythmKeyMap;
}
@@ -325,10 +330,14 @@ void MidiDriver_AdLib::send(uint32 b) {
}
}
-void MidiDriver_AdLib::generateSamples(int16 *data, int len) {
- if (isStereo())
- len <<= 1;
- _opl->readBuffer(data, len);
+void MidiDriver_AdLib::setTimerCallback(void *timerParam, Common::TimerManager::TimerProc timerProc) {
+ _adlibTimerProc = timerProc;
+ _adlibTimerParam = timerParam;
+}
+
+void MidiDriver_AdLib::onTimer() {
+ if (_adlibTimerProc)
+ (*_adlibTimerProc)(_adlibTimerParam);
// Increase the age of the notes
for (int i = 0; i < kVoices; i++) {
@@ -684,7 +693,7 @@ void MidiDriver_AdLib::setVelocityReg(int regOffset, int velocity, int kbScaleLe
if (!_playSwitch)
velocity = 0;
- if (isStereo()) {
+ if (_stereo) {
int velLeft = velocity;
int velRight = velocity;
@@ -734,7 +743,7 @@ void MidiDriver_AdLib::setRegister(int reg, int value, int channels) {
_opl->write(0x221, value);
}
- if (isStereo()) {
+ if (_stereo) {
if (channels & kRightChannel) {
_opl->write(0x222, reg);
_opl->write(0x223, value);
diff --git a/engines/sci/sound/midiparser_sci.cpp b/engines/sci/sound/midiparser_sci.cpp
index c0b4f3122e..9f0d8d150f 100644
--- a/engines/sci/sound/midiparser_sci.cpp
+++ b/engines/sci/sound/midiparser_sci.cpp
@@ -360,6 +360,13 @@ void MidiParser_SCI::sendInitCommands() {
sendToDriver(0xB0 | i, 0x4B, voiceCount);
}
}
+ } else {
+ for (int i = 0; i < _track->channelCount; ++i) {
+ byte voiceCount = _track->channels[i].poly;
+ byte num = _track->channels[i].number;
+ // TODO: Should we skip the control channel?
+ sendToDriver(0xB0 | num, 0x4B, voiceCount);
+ }
}
}
@@ -480,19 +487,25 @@ void MidiParser_SCI::trackState(uint32 b) {
s._sustain = (op2 != 0);
break;
case 0x4B: // voices
+ if (s._voices != op2) {
+ // CHECKME: Should we directly call remapChannels() if _mainThreadCalled?
+ debugC(2, kDebugLevelSound, "Dynamic voice change (%d to %d)", s._voices, op2);
+ _music->needsRemap();
+ }
s._voices = op2;
_pSnd->_chan[channel]._voices = op2; // Also sync our MusicEntry
break;
case 0x4E: // mute
// This is channel mute only for sci1.
// (It's velocity control for sci0, but we don't need state in sci0)
- if (_soundVersion >= SCI_VERSION_1_EARLY) {
+ if (_soundVersion > SCI_VERSION_1_EARLY) {
// FIXME: mute is a level, not a bool, in some SCI versions
bool m = op2;
if (_pSnd->_chan[channel]._mute != m) {
_pSnd->_chan[channel]._mute = m;
- // TODO: If muting/unmuting a channel, remap channels.
- warning("Mute change without immediate remapping (mainThread = %d)", _mainThreadCalled);
+ // CHECKME: Should we directly call remapChannels() if _mainThreadCalled?
+ _music->needsRemap();
+ debugC(2, kDebugLevelSound, "Dynamic mute change (arg = %d, mainThread = %d)", m, _mainThreadCalled);
}
}
break;
diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp
index 7a6eaf62b4..dca73c3f51 100644
--- a/engines/sci/sound/music.cpp
+++ b/engines/sci/sound/music.cpp
@@ -144,6 +144,8 @@ void SciMusic::init() {
_globalReverb = _pMidiDrv->getReverb(); // Init global reverb for SCI0
_currentlyPlayingSample = NULL;
+ _timeCounter = 0;
+ _needsRemap = false;
}
void SciMusic::miditimerCallback(void *p) {
@@ -158,6 +160,11 @@ void SciMusic::onTimer() {
// sending out queued commands that were "sent" via main thread
sendMidiCommandsFromQueue();
+ // remap channels, if requested
+ if (_needsRemap)
+ remapChannels(false);
+ _needsRemap = false;
+
for (MusicList::iterator i = _playList.begin(); i != end; ++i)
(*i)->onTimer();
}
@@ -285,8 +292,10 @@ byte SciMusic::getCurrentReverb() {
return _pMidiDrv->getReverb();
}
+// A larger priority value has higher priority. For equal priority values,
+// songs that have been added later have higher priority.
static bool musicEntryCompare(const MusicEntry *l, const MusicEntry *r) {
- return (l->priority > r->priority);
+ return (l->priority > r->priority) || (l->priority == r->priority && l->time > r->time);
}
void SciMusic::sortPlayList() {
@@ -317,6 +326,8 @@ void SciMusic::soundInitSnd(MusicEntry *pSnd) {
track = digital;
}
+ pSnd->time = ++_timeCounter;
+
if (track) {
// Play digital sample
if (track->digitalChannelNr != -1) {
@@ -334,6 +345,8 @@ void SciMusic::soundInitSnd(MusicEntry *pSnd) {
pSnd->pLoopStream = 0;
pSnd->soundType = Audio::Mixer::kSFXSoundType;
pSnd->hCurrentAud = Audio::SoundHandle();
+ pSnd->playBed = false;
+ pSnd->overridePriority = false;
} else {
// play MIDI track
Common::StackLock lock(_mutex);
@@ -380,6 +393,8 @@ void SciMusic::soundInitSnd(MusicEntry *pSnd) {
int16 prevHold = pSnd->hold;
pSnd->loop = 0;
pSnd->hold = -1;
+ pSnd->playBed = false;
+ pSnd->overridePriority = false;
pSnd->pMidiParser->loadMusic(track, pSnd, channelFilterMask, _soundVersion);
pSnd->reverb = pSnd->pMidiParser->getSongReverb();
@@ -395,6 +410,23 @@ void SciMusic::soundInitSnd(MusicEntry *pSnd) {
void SciMusic::soundPlay(MusicEntry *pSnd) {
_mutex.lock();
+ if (_soundVersion <= SCI_VERSION_1_EARLY && pSnd->playBed) {
+ // If pSnd->playBed, and version <= SCI1_EARLY, then kill
+ // existing sounds with playBed enabled.
+
+ uint playListCount = _playList.size();
+ for (uint i = 0; i < playListCount; i++) {
+ if (_playList[i] != pSnd && _playList[i]->playBed) {
+ debugC(2, kDebugLevelSound, "Automatically stopping old playBed song from soundPlay");
+ MusicEntry *old = _playList[i];
+ _mutex.unlock();
+ soundStop(old);
+ _mutex.lock();
+ break;
+ }
+ }
+ }
+
uint playListCount = _playList.size();
uint playListNo = playListCount;
MusicEntry *alreadyPlaying = NULL;
@@ -408,9 +440,11 @@ void SciMusic::soundPlay(MusicEntry *pSnd) {
}
if (playListNo == playListCount) { // not found
_playList.push_back(pSnd);
- sortPlayList();
}
+ pSnd->time = ++_timeCounter;
+ sortPlayList();
+
_mutex.unlock(); // unlock to perform mixer-related calls
if (pSnd->pMidiParser) {
@@ -554,6 +588,7 @@ void SciMusic::soundSetPriority(MusicEntry *pSnd, byte prio) {
Common::StackLock lock(_mutex);
pSnd->priority = prio;
+ pSnd->time = ++_timeCounter;
sortPlayList();
}
@@ -905,12 +940,12 @@ int ChannelRemapping::lowestPrio() const {
}
-void SciMusic::remapChannels() {
+void SciMusic::remapChannels(bool mainThread) {
if (_soundVersion <= SCI_VERSION_0_LATE)
return;
- // NB: This function should only be called from the main thread,
- // with _mutex locked
+ // NB: This function should only be called with _mutex locked
+ // Make sure to set the mainThread argument correctly.
ChannelRemapping *map = determineChannelMap();
@@ -963,9 +998,9 @@ void SciMusic::remapChannels() {
for (int j = 0; j < 16; ++j) {
if (!channelMapped[j]) {
- song->pMidiParser->mainThreadBegin();
+ if (mainThread) song->pMidiParser->mainThreadBegin();
song->pMidiParser->remapChannel(j, -1);
- song->pMidiParser->mainThreadEnd();
+ if (mainThread) song->pMidiParser->mainThreadEnd();
#ifdef DEBUG_REMAP
if (channelUsed[j])
debug(" Unmapping song %d, channel %d", songIndex, j);
@@ -997,9 +1032,9 @@ void SciMusic::remapChannels() {
#ifdef DEBUG_REMAP
debug(" Mapping (dontRemap) song %d, channel %d to device channel %d", songIndex, _channelMap[i]._channel, i);
#endif
- _channelMap[i]._song->pMidiParser->mainThreadBegin();
+ if (mainThread) _channelMap[i]._song->pMidiParser->mainThreadBegin();
_channelMap[i]._song->pMidiParser->remapChannel(_channelMap[i]._channel, i);
- _channelMap[i]._song->pMidiParser->mainThreadEnd();
+ if (mainThread) _channelMap[i]._song->pMidiParser->mainThreadEnd();
}
}
@@ -1052,9 +1087,9 @@ void SciMusic::remapChannels() {
#ifdef DEBUG_REMAP
debug(" Mapping song %d, channel %d to device channel %d", songIndex, _channelMap[j]._channel, j);
#endif
- _channelMap[j]._song->pMidiParser->mainThreadBegin();
+ if (mainThread) _channelMap[j]._song->pMidiParser->mainThreadBegin();
_channelMap[j]._song->pMidiParser->remapChannel(_channelMap[j]._channel, j);
- _channelMap[j]._song->pMidiParser->mainThreadEnd();
+ if (mainThread) _channelMap[j]._song->pMidiParser->mainThreadEnd();
break;
}
}
@@ -1062,9 +1097,9 @@ void SciMusic::remapChannels() {
}
// And finally, stop any empty channels
- for (int i = _driverFirstChannel; i <= _driverLastChannel; ++i) {
- if (!_channelMap[i]._song)
- resetDeviceChannel(i);
+ for (int i = _driverLastChannel; i >= _driverFirstChannel; --i) {
+ if (!_channelMap[i]._song && currentMap[i]._song)
+ resetDeviceChannel(i, mainThread);
}
delete map;
@@ -1105,7 +1140,8 @@ ChannelRemapping *SciMusic::determineChannelMap() {
#ifdef DEBUG_REMAP
- debug(" Song %d (%p), prio %d", songIndex, (void*)song, song->priority);
+ const char* name = g_sci->getEngineState()->_segMan->getObjectName(song->soundObj);
+ debug(" Song %d (%p) [%s], prio %d%s", songIndex, (void*)song, name, song->priority, song->playBed ? ", bed" : "");
#endif
// Store backup. If we fail to map this song, we will revert to this.
@@ -1118,13 +1154,23 @@ ChannelRemapping *SciMusic::determineChannelMap() {
if (c == 0xFF || c == 0xFE || c == 0x0F)
continue;
const MusicEntryChannel &channel = song->_chan[c];
- if (channel._dontMap)
+ if (channel._dontMap) {
+#ifdef DEBUG_REMAP
+ debug(" Channel %d dontMap, skipping", c);
+#endif
continue;
- if (channel._mute)
+ }
+ if (channel._mute) {
+#ifdef DEBUG_REMAP
+ debug(" Channel %d muted, skipping", c);
+#endif
continue;
+ }
+
+ bool dontRemap = channel._dontRemap || song->playBed;
#ifdef DEBUG_REMAP
- debug(" Channel %d: prio %d, %d voice%s%s", c, channel._prio, channel._voices, channel._voices == 1 ? "" : "s", channel._dontRemap ? ", dontRemap" : "" );
+ debug(" Channel %d: prio %d, %d voice%s%s", c, channel._prio, channel._voices, channel._voices == 1 ? "" : "s", dontRemap ? ", dontRemap" : "" );
#endif
DeviceChannelUsage dc = { song, c };
@@ -1132,7 +1178,7 @@ ChannelRemapping *SciMusic::determineChannelMap() {
// our target
int devChannel = -1;
- if (channel._dontRemap && map->_map[c]._song == 0) {
+ if (dontRemap && map->_map[c]._song == 0) {
// unremappable channel, with channel still free
devChannel = c;
}
@@ -1192,8 +1238,12 @@ ChannelRemapping *SciMusic::determineChannelMap() {
int neededVoices = channel._voices;
// do we have enough free voices?
if (map->_freeVoices < neededVoices) {
- // We only care for essential channels
- if (prio > 0) {
+ // We only care for essential channels.
+ // Note: In early SCI1 interpreters, a song started by 'playBed'
+ // would not be skipped even if some channels couldn't be
+ // mapped due to voice limits. So, we treat all channels as
+ // non-essential here for playBed songs.
+ if (prio > 0 || (song->playBed && _soundVersion <= SCI_VERSION_1_EARLY)) {
#ifdef DEBUG_REMAP
debug(" not enough voices; need %d, have %d. Skipping this channel.", neededVoices, map->_freeVoices);
#endif
@@ -1229,10 +1279,10 @@ ChannelRemapping *SciMusic::determineChannelMap() {
map->_map[devChannel] = dc;
map->_voices[devChannel] = neededVoices;
map->_prio[devChannel] = prio;
- map->_dontRemap[devChannel] = channel._dontRemap;
+ map->_dontRemap[devChannel] = dontRemap;
map->_freeVoices -= neededVoices;
- if (!channel._dontRemap || devChannel == c) {
+ if (!dontRemap || devChannel == c) {
// If this channel fits here, we're done.
#ifdef DEBUG_REMAP
debug(" OK");
@@ -1285,14 +1335,18 @@ ChannelRemapping *SciMusic::determineChannelMap() {
return map;
}
-void SciMusic::resetDeviceChannel(int devChannel) {
- // NB: This function should only be called from the main thread
-
+void SciMusic::resetDeviceChannel(int devChannel, bool mainThread) {
assert(devChannel >= 0 && devChannel <= 0x0F);
- putMidiCommandInQueue(0x0040B0 | devChannel); // sustain off
- putMidiCommandInQueue(0x007BB0 | devChannel); // notes off
- putMidiCommandInQueue(0x004BB0 | devChannel); // release voices
+ if (mainThread) {
+ putMidiCommandInQueue(0x0040B0 | devChannel); // sustain off
+ putMidiCommandInQueue(0x007BB0 | devChannel); // notes off
+ putMidiCommandInQueue(0x004BB0 | devChannel); // release voices
+ } else {
+ _pMidiDrv->send(0x0040B0 | devChannel); // sustain off
+ _pMidiDrv->send(0x007BB0 | devChannel); // notes off
+ _pMidiDrv->send(0x004BB0 | devChannel); // release voices
+ }
}
diff --git a/engines/sci/sound/music.h b/engines/sci/sound/music.h
index 4e44074630..a610f32d89 100644
--- a/engines/sci/sound/music.h
+++ b/engines/sci/sound/music.h
@@ -75,6 +75,8 @@ public:
SoundResource *soundRes;
uint16 resourceId;
+ int time; // "tim"estamp to indicate in which order songs have been added
+
bool isQueued; // for SCI0 only!
uint16 dataInc;
@@ -85,6 +87,8 @@ public:
int16 volume;
int16 hold;
int8 reverb;
+ bool playBed;
+ bool overridePriority; // Use soundObj's priority instead of resource's
int16 pauseCounter;
uint sampleLoopCounter;
@@ -224,6 +228,8 @@ public:
byte getCurrentReverb();
+ void needsRemap() { _needsRemap = true; }
+
virtual void saveLoadWithSerializer(Common::Serializer &ser);
// Mutex for music code. Used to guard access to the song playlist, to the
@@ -245,9 +251,9 @@ protected:
bool _useDigitalSFX;
// remapping:
- void remapChannels();
+ void remapChannels(bool mainThread = true);
ChannelRemapping *determineChannelMap();
- void resetDeviceChannel(int devChannel);
+ void resetDeviceChannel(int devChannel, bool mainThread);
private:
MusicList _playList;
@@ -256,6 +262,7 @@ private:
MusicEntry *_usedChannel[16];
int8 _channelRemap[16];
int8 _globalReverb;
+ bool _needsRemap;
DeviceChannelUsage _channelMap[16];
@@ -266,6 +273,9 @@ private:
int _driverLastChannel;
MusicEntry *_currentlyPlayingSample;
+
+ int _timeCounter; // Used to keep track of the order in which MusicEntries
+ // are added, for priority purposes.
};
} // End of namespace Sci
diff --git a/engines/sci/sound/soundcmd.cpp b/engines/sci/sound/soundcmd.cpp
index 73e0a23a6a..ee5903fda2 100644
--- a/engines/sci/sound/soundcmd.cpp
+++ b/engines/sci/sound/soundcmd.cpp
@@ -142,11 +142,14 @@ void SoundCommandParser::processInitSound(reg_t obj) {
reg_t SoundCommandParser::kDoSoundPlay(int argc, reg_t *argv, reg_t acc) {
debugC(kDebugLevelSound, "kDoSound(play): %04x:%04x", PRINT_REG(argv[0]));
- processPlaySound(argv[0]);
+ bool playBed = false;
+ if (argc >= 2 && !argv[1].isNull())
+ playBed = true;
+ processPlaySound(argv[0], playBed);
return acc;
}
-void SoundCommandParser::processPlaySound(reg_t obj) {
+void SoundCommandParser::processPlaySound(reg_t obj, bool playBed) {
MusicEntry *musicSlot = _music->getSlot(obj);
if (!musicSlot) {
warning("kDoSound(play): Slot not found (%04x:%04x), initializing it manually", PRINT_REG(obj));
@@ -181,15 +184,26 @@ void SoundCommandParser::processPlaySound(reg_t obj) {
}
musicSlot->loop = readSelectorValue(_segMan, obj, SELECTOR(loop));
- musicSlot->priority = readSelectorValue(_segMan, obj, SELECTOR(priority));
+
+ // Get song priority from either obj or soundRes
+ byte resourcePriority = 0xFF;
+ if (musicSlot->soundRes)
+ resourcePriority = musicSlot->soundRes->getSoundPriority();
+ if (!musicSlot->overridePriority && resourcePriority != 0xFF) {
+ musicSlot->priority = resourcePriority;
+ } else {
+ musicSlot->priority = readSelectorValue(_segMan, obj, SELECTOR(priority));
+ }
+
// Reset hold when starting a new song. kDoSoundSetHold is always called after
// kDoSoundPlay to set it properly, if needed. Fixes bug #3413589.
musicSlot->hold = -1;
+ musicSlot->playBed = playBed;
if (_soundVersion >= SCI_VERSION_1_EARLY)
musicSlot->volume = readSelectorValue(_segMan, obj, SELECTOR(vol));
- debugC(kDebugLevelSound, "kDoSound(play): %04x:%04x number %d, loop %d, prio %d, vol %d", PRINT_REG(obj),
- resourceId, musicSlot->loop, musicSlot->priority, musicSlot->volume);
+ debugC(kDebugLevelSound, "kDoSound(play): %04x:%04x number %d, loop %d, prio %d, vol %d, bed %d", PRINT_REG(obj),
+ resourceId, musicSlot->loop, musicSlot->priority, musicSlot->volume, playBed ? 1 : 0);
_music->soundPlay(musicSlot);
@@ -538,7 +552,7 @@ void SoundCommandParser::processUpdateCues(reg_t obj) {
if (_soundVersion >= SCI_VERSION_1_EARLY) {
writeSelectorValue(_segMan, obj, SELECTOR(min), musicSlot->ticker / 3600);
writeSelectorValue(_segMan, obj, SELECTOR(sec), musicSlot->ticker % 3600 / 60);
- writeSelectorValue(_segMan, obj, SELECTOR(frame), musicSlot->ticker);
+ writeSelectorValue(_segMan, obj, SELECTOR(frame), musicSlot->ticker % 60 / 2);
}
}
@@ -673,23 +687,19 @@ reg_t SoundCommandParser::kDoSoundSetPriority(int argc, reg_t *argv, reg_t acc)
}
if (value == -1) {
- uint16 resourceId = musicSlot->resourceId;
+ musicSlot->overridePriority = false;
+ musicSlot->priority = 0;
- // Set priority from the song data
- Resource *song = _resMan->findResource(ResourceId(kResourceTypeSound, resourceId), 0);
- if (song->data[0] == 0xf0)
- _music->soundSetPriority(musicSlot, song->data[1]);
- else
- warning("kDoSound(setPriority): Attempt to unset song priority when there is no built-in value");
+ // NB: It seems SSCI doesn't actually reset the priority here.
- //pSnd->prio=0;field_15B=0
writeSelectorValue(_segMan, obj, SELECTOR(flags), readSelectorValue(_segMan, obj, SELECTOR(flags)) & 0xFD);
} else {
// Scripted priority
+ musicSlot->overridePriority = true;
- //pSnd->field_15B=1;
writeSelectorValue(_segMan, obj, SELECTOR(flags), readSelectorValue(_segMan, obj, SELECTOR(flags)) | 2);
- //DoSOund(0xF,hobj,w)
+
+ _music->soundSetPriority(musicSlot, value);
}
return acc;
}
@@ -777,6 +787,8 @@ void SoundCommandParser::stopAllSounds() {
}
void SoundCommandParser::startNewSound(int number) {
+ // NB: This is only used by the debugging console.
+
Common::StackLock lock(_music->_mutex);
// Overwrite the first sound in the playlist
@@ -785,7 +797,7 @@ void SoundCommandParser::startNewSound(int number) {
processDisposeSound(soundObj);
writeSelectorValue(_segMan, soundObj, SELECTOR(number), number);
processInitSound(soundObj);
- processPlaySound(soundObj);
+ processPlaySound(soundObj, false);
}
void SoundCommandParser::setMasterVolume(int vol) {
diff --git a/engines/sci/sound/soundcmd.h b/engines/sci/sound/soundcmd.h
index 4effda68e4..5bb7cf2cb1 100644
--- a/engines/sci/sound/soundcmd.h
+++ b/engines/sci/sound/soundcmd.h
@@ -63,7 +63,7 @@ public:
void printPlayList(Console *con);
void printSongInfo(reg_t obj, Console *con);
- void processPlaySound(reg_t obj);
+ void processPlaySound(reg_t obj, bool playBed);
void processStopSound(reg_t obj, bool sampleFinishedPlaying);
void initSoundResource(MusicEntry *newSound);
diff --git a/engines/scumm/debugger.cpp b/engines/scumm/debugger.cpp
index 2b718b2cfe..0ebea94608 100644
--- a/engines/scumm/debugger.cpp
+++ b/engines/scumm/debugger.cpp
@@ -256,7 +256,7 @@ bool ScummDebugger::Cmd_Hide(int argc, const char **argv) {
bool ScummDebugger::Cmd_Script(int argc, const char** argv) {
int scriptnum;
- if (argc < 2) {
+ if (argc < 3) {
debugPrintf("Syntax: script <scriptnum> <command>\n");
return true;
}
diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h
index 82a8b4452b..5a994cb699 100644
--- a/engines/scumm/detection_tables.h
+++ b/engines/scumm/detection_tables.h
@@ -306,11 +306,11 @@ static const GameSettings gameVariantsTable[] = {
// Humongous Entertainment Scumm Version 7.2
{"airport", "", 0, GID_HEGAME, 6, 72, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"farm", "", 0, GID_HEGAME, 6, 72, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
// Changed o_getResourceSize to cover all resource types
- {"farm", "", 0, GID_HEGAME, 6, 73, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
{"puttzoo", "", 0, GID_PUTTZOO, 6, 73, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
- {"puttzoo", "HE 72", 0, GID_PUTTZOO, 6, 72, MDT_NONE, GF_USE_KEY | GF_HE_985, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"puttzoo", "HE 72", 0, GID_PUTTZOO, 6, 72, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
{"puttzoo", "HE 98.5", 0, GID_PUTTZOO, 6, 98, MDT_NONE, GF_USE_KEY | GF_HE_985, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
{"puttzoo", "HE 99", 0, GID_PUTTZOO, 6, 99, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
{"puttzoo", "HE 100", 0, GID_PUTTZOO, 6, 100, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
@@ -812,6 +812,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "pajama3", "PyjamaHG", kGenHEPC, Common::FR_FRA, UNK, 0 },
{ "pajama3", "PyjamaSKS", kGenHEPC, Common::DE_DEU, UNK, 0 },
{ "pajama3", "PyjamaSKS", kGenHEMac, Common::DE_DEU, Common::kPlatformMacintosh, 0 },
+ { "pajama3", "SamLDM", kGenHEPC, Common::IT_ITA, Common::kPlatformWindows, 0 },
{ "pajama3", "UKPajamaEAT", kGenHEPC, Common::RU_RUS, UNK, 0 },
{ "puttcircus", "puttcircus", kGenHEPC, UNK_LANG, UNK, 0 },
@@ -830,6 +831,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "puttrace", "500demo", kGenHEPC, Common::NL_NLD, Common::kPlatformWindows, 0 },
{ "puttrace", "course", kGenHEPC, Common::FR_FRA, UNK, 0 },
{ "puttrace", "CourseDemo", kGenHEPC, Common::FR_FRA, UNK, 0 },
+ { "puttrace", "GasGasEG", kGenHEPC, Common::IT_ITA, Common::kPlatformWindows, 0 },
{ "puttrace", "racedemo", kGenHEPC, UNK_LANG, Common::kPlatformWindows, 0 },
{ "puttrace", "RaceDemo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "puttrace", "Rennen", kGenHEPC, Common::DE_DEU, UNK, 0 },
@@ -926,6 +928,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "spyfox2", "Sf2demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "spyfox2", "Spy Fox 2", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "spyfox2", "Spy Fox 2 - Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
+ { "spyfox2", "SPyFoxMCR", kGenHEPC, Common::IT_ITA, Common::kPlatformWindows, 0 },
{ "spyfox2", "SpyFoxOR", kGenHEPC, Common::DE_DEU, UNK, 0 },
{ "spyfox2", "SpyFoxOR", kGenHEMac, Common::DE_DEU, Common::kPlatformMacintosh, 0 },
{ "spyfox2", "SPYFoxORE", kGenHEPC, Common::FR_FRA, UNK, 0 },
diff --git a/engines/scumm/help.cpp b/engines/scumm/help.cpp
index cfb23a392a..2281e954ef 100644
--- a/engines/scumm/help.cpp
+++ b/engines/scumm/help.cpp
@@ -36,6 +36,8 @@ int ScummHelp::numPages(byte gameId) {
case GID_MANIAC:
case GID_ZAK:
return 4;
+ case GID_INDY4:
+ return 5;
case GID_INDY3:
return 6;
case GID_LOOM:
@@ -43,7 +45,6 @@ int ScummHelp::numPages(byte gameId) {
case GID_MONKEY_VGA:
case GID_MONKEY:
case GID_MONKEY2:
- case GID_INDY4:
case GID_TENTACLE:
case GID_SAMNMAX:
case GID_DIG:
@@ -287,10 +288,19 @@ void ScummHelp::updateStrings(byte gameId, byte version, Common::Platform platfo
ADD_BIND("F3", "Melissa");
ADD_BIND("F4", "Leslie");
}
+ if (gameId == GID_INDY4) {
+ ADD_BIND("i", _("Toggle Inventory/IQ Points display"));
+ ADD_BIND("f", _("Toggle Keyboard/Mouse Fighting (*)"));
+ ADD_LINE;
+ ADD_TEXT(_("* Keyboard Fighting is always on,"));
+ ADD_TEXT(_(" so despite the in-game message this"));
+ ADD_TEXT(_(" actually toggles Mouse Fighting Off/On"));
+ }
break;
case 5:
switch (gameId) {
case GID_INDY3:
+ case GID_INDY4:
title = _("Fighting controls (numpad):");
ADD_BIND("7", _("Step back"));
ADD_BIND("4", _("Step back"));
@@ -301,7 +311,9 @@ void ScummHelp::updateStrings(byte gameId, byte version, Common::Platform platfo
ADD_BIND("9", _("Punch high"));
ADD_BIND("6", _("Punch middle"));
ADD_BIND("3", _("Punch low"));
- ADD_LINE;
+ if (gameId == GID_INDY4) {
+ ADD_BIND("0", _("Sucker punch"));
+ }
ADD_LINE;
ADD_TEXT(_("These are for Indy on left."));
ADD_TEXT(_("When Indy is on the right,"));
diff --git a/engines/scumm/players/player_ad.cpp b/engines/scumm/players/player_ad.cpp
index adcda68e10..4d4be2c3c2 100644
--- a/engines/scumm/players/player_ad.cpp
+++ b/engines/scumm/players/player_ad.cpp
@@ -27,6 +27,7 @@
#include "scumm/saveload.h"
#include "audio/fmopl.h"
+#include "audio/mixer.h"
#include "common/textconsole.h"
#include "common/config-manager.h"
@@ -35,26 +36,19 @@ namespace Scumm {
#define AD_CALLBACK_FREQUENCY 472
-Player_AD::Player_AD(ScummEngine *scumm, Audio::Mixer *mixer)
- : _vm(scumm), _mixer(mixer), _rate(mixer->getOutputRate()) {
+Player_AD::Player_AD(ScummEngine *scumm)
+ : _vm(scumm) {
_opl2 = OPL::Config::create();
- if (!_opl2->init(_rate)) {
+ if (!_opl2->init()) {
error("Could not initialize OPL2 emulator");
}
- _samplesPerCallback = _rate / AD_CALLBACK_FREQUENCY;
- _samplesPerCallbackRemainder = _rate % AD_CALLBACK_FREQUENCY;
- _samplesTillCallback = 0;
- _samplesTillCallbackRemainder = 0;
-
memset(_registerBackUpTable, 0, sizeof(_registerBackUpTable));
writeReg(0x01, 0x00);
writeReg(0xBD, 0x00);
writeReg(0x08, 0x00);
writeReg(0x01, 0x20);
- _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
-
_engineMusicTimer = 0;
_soundPlaying = -1;
@@ -78,11 +72,11 @@ Player_AD::Player_AD(ScummEngine *scumm, Audio::Mixer *mixer)
_musicVolume = _sfxVolume = 255;
_isSeeking = false;
+
+ _opl2->start(new Common::Functor0Mem<void, Player_AD>(this, &Player_AD::onTimer), AD_CALLBACK_FREQUENCY);
}
Player_AD::~Player_AD() {
- _mixer->stopHandle(_soundHandle);
-
stopAllSounds();
Common::StackLock lock(_mutex);
delete _opl2;
@@ -244,36 +238,14 @@ void Player_AD::saveLoadWithSerializer(Serializer *ser) {
}
}
-int Player_AD::readBuffer(int16 *buffer, const int numSamples) {
+void Player_AD::onTimer() {
Common::StackLock lock(_mutex);
- int len = numSamples;
-
- while (len > 0) {
- if (!_samplesTillCallback) {
- if (_curOffset) {
- updateMusic();
- }
-
- updateSfx();
-
- _samplesTillCallback = _samplesPerCallback;
- _samplesTillCallbackRemainder += _samplesPerCallbackRemainder;
- if (_samplesTillCallbackRemainder >= AD_CALLBACK_FREQUENCY) {
- ++_samplesTillCallback;
- _samplesTillCallbackRemainder -= AD_CALLBACK_FREQUENCY;
- }
- }
-
- const int samplesToRead = MIN(len, _samplesTillCallback);
- _opl2->readBuffer(buffer, samplesToRead);
-
- buffer += samplesToRead;
- len -= samplesToRead;
- _samplesTillCallback -= samplesToRead;
+ if (_curOffset) {
+ updateMusic();
}
- return numSamples;
+ updateSfx();
}
void Player_AD::setupVolume() {
diff --git a/engines/scumm/players/player_ad.h b/engines/scumm/players/player_ad.h
index 63a8503f47..63fda3cc7c 100644
--- a/engines/scumm/players/player_ad.h
+++ b/engines/scumm/players/player_ad.h
@@ -26,7 +26,6 @@
#include "scumm/music.h"
#include "audio/audiostream.h"
-#include "audio/mixer.h"
#include "common/mutex.h"
@@ -41,9 +40,9 @@ class ScummEngine;
/**
* Sound output for v3/v4 AdLib data.
*/
-class Player_AD : public MusicEngine, public Audio::AudioStream {
+class Player_AD : public MusicEngine {
public:
- Player_AD(ScummEngine *scumm, Audio::Mixer *mixer);
+ Player_AD(ScummEngine *scumm);
virtual ~Player_AD();
// MusicEngine API
@@ -56,18 +55,12 @@ public:
virtual void saveLoadWithSerializer(Serializer *ser);
- // AudioStream API
- virtual int readBuffer(int16 *buffer, const int numSamples);
- virtual bool isStereo() const { return false; }
- virtual bool endOfData() const { return false; }
- virtual int getRate() const { return _rate; }
+ // Timer callback
+ void onTimer();
private:
ScummEngine *const _vm;
Common::Mutex _mutex;
- Audio::Mixer *const _mixer;
- const int _rate;
- Audio::SoundHandle _soundHandle;
void setupVolume();
int _musicVolume;
@@ -75,11 +68,6 @@ private:
OPL::OPL *_opl2;
- int _samplesPerCallback;
- int _samplesPerCallbackRemainder;
- int _samplesTillCallback;
- int _samplesTillCallbackRemainder;
-
int _soundPlaying;
int32 _engineMusicTimer;
diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp
index 0c0f6be73b..e5673c1803 100644
--- a/engines/scumm/saveload.cpp
+++ b/engines/scumm/saveload.cpp
@@ -149,7 +149,7 @@ void ScummEngine::requestSave(int slot, const Common::String &name) {
void ScummEngine::requestLoad(int slot) {
_saveLoadSlot = slot;
- _saveTemporaryState = false;
+ _saveTemporaryState = (slot == 100);
_saveLoadFlag = 2; // 2 for load
}
diff --git a/engines/scumm/script_v6.cpp b/engines/scumm/script_v6.cpp
index d2f4133f74..6c81f17f2f 100644
--- a/engines/scumm/script_v6.cpp
+++ b/engines/scumm/script_v6.cpp
@@ -2597,7 +2597,11 @@ void ScummEngine_v6::o6_kernelSetFunctions() {
fadeIn(args[1]);
break;
case 8:
- startManiac();
+ if (startManiac()) {
+ // This is so that the surprised exclamation happens
+ // after we return to the game again, not before.
+ o6_breakHere();
+ }
break;
case 9:
killAllScriptsExceptCurrent();
diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h
index 5be18fb990..a836cf12bc 100644
--- a/engines/scumm/scumm-md5.h
+++ b/engines/scumm/scumm-md5.h
@@ -1,5 +1,5 @@
/*
- This file was generated by the md5table tool on Sun Dec 7 23:09:10 2014
+ This file was generated by the md5table tool on Sun Jun 28 03:19:52 2015
DO NOT EDIT MANUALLY!
*/
@@ -27,6 +27,7 @@ static const MD5Table md5table[] = {
{ "0557df19f046a84c2fdc63507c6616cb", "farm", "HE 72", "Demo", -1, Common::NL_NLD, Common::kPlatformWindows },
{ "055ffe4f47753e47594ac67823220c54", "puttrace", "HE 99", "", -1, Common::DE_DEU, Common::kPlatformUnknown },
{ "057c9b456dedcc4d71b991a3072a20b3", "monkey", "SEGA", "", 9465, Common::JA_JPN, Common::kPlatformSegaCD },
+ { "05d3143827ab4f5d2521a1a47dab8ff2", "puttrace", "HE 98", "", -1, Common::IT_ITA, Common::kPlatformUnknown },
{ "06b187468113f9ae5a400b148a847fac", "atlantis", "Floppy", "Floppy", 12075, Common::EN_ANY, Common::kPlatformMacintosh },
{ "06c3cf4f31daad8b1cd93153491db9e6", "pajama3", "", "", 79382, Common::NL_NLD, Common::kPlatformUnknown },
{ "07433205acdca3bc553d0e731588b35f", "airport", "", "", -1, Common::EN_ANY, Common::kPlatformWindows },
@@ -67,6 +68,7 @@ static const MD5Table md5table[] = {
{ "114acdc2659a273c220f86ee9edb24c1", "maniac", "V2", "V2", -1, Common::FR_FRA, Common::kPlatformDOS },
{ "11ddf1fde76e3156eb3a38da213f484e", "monkey2", "", "", -1, Common::IT_ITA, Common::kPlatformAmiga },
{ "11e6e244078ff09b0f3832e35420e0a7", "catalog", "", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows },
+ { "12cdc256eae5a461bcc9a49975999841", "atlantis", "Floppy", "Demo", -1, Common::EN_ANY, Common::kPlatformDOS },
{ "132bff65e6367c09cc69318ce1b59333", "monkey2", "", "", 11155, Common::EN_ANY, Common::kPlatformAmiga },
{ "1387d16aa620dc1c2d1fd87f8a9e7a09", "puttcircus", "", "Demo", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "13d2a86a7290813a1c386490447d72db", "fbear", "HE 62", "", -1, Common::EN_ANY, Common::kPlatform3DO },
@@ -119,6 +121,7 @@ static const MD5Table md5table[] = {
{ "22c9eb04455440131ffc157aeb8d40a8", "fbear", "HE 70", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "22de86b2f7ec6e5db745ed1123310b44", "spyfox2", "", "Demo", 15832, Common::FR_FRA, Common::kPlatformWindows },
{ "22f4ea88a09da12df9308ba30bcb7d0f", "loom", "EGA", "EGA", -1, Common::EN_ANY, Common::kPlatformDOS },
+ { "2328be0317008ef047eed7912a4b0850", "pajama2", "HE 98.5", "", -1, Common::EN_GRB, Common::kPlatformWindows },
{ "23394c8d29cc63c61313959431a12476", "spyfox", "HE 100", "Updated", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "24942a4200d99bdb4bdb78f9c7e07027", "pajama3", "", "Mini Game", 13911, Common::NL_NLD, Common::kPlatformWindows },
{ "254fede2f15dbb32a23760d601b01816", "zak", "V1", "", -1, Common::EN_ANY, Common::kPlatformC64 },
@@ -164,6 +167,7 @@ static const MD5Table md5table[] = {
{ "3686cf8f89e102ececf4366e1d2c8126", "monkey2", "", "", 11135, Common::EN_ANY, Common::kPlatformDOS },
{ "36a6750e03fb505fc19fc2bf3e4dbe91", "pajama2", "", "Demo", 58749, Common::EN_ANY, Common::kPlatformUnknown },
{ "3769b56c9a22f5521d74525ee459f88d", "puttrace", "HE 99", "Demo", 13108, Common::DE_DEU, Common::kPlatformWindows },
+ { "3785fd25f7e02b5782bfc5072d8f77c8", "spyfox2", "", "", -1, Common::IT_ITA, Common::kPlatformUnknown },
{ "37aed3f91c1ef959e0bd265f9b13781f", "pajama", "HE 100", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "37f56ceb13e401a7ac7d9e6b37fecaf7", "loom", "EGA", "EGA", 5748, Common::EN_ANY, Common::kPlatformDOS },
{ "37ff1b308999c4cca7319edfcc1280a0", "puttputt", "HE 70", "Demo", 8269, Common::EN_ANY, Common::kPlatformWindows },
@@ -176,7 +180,7 @@ static const MD5Table md5table[] = {
{ "3a03dab514e4038df192d8a8de469788", "atlantis", "Floppy", "Floppy", -1, Common::EN_ANY, Common::kPlatformAmiga },
{ "3a0c35f3c147b98a2bdf8d400cfc4ab5", "indy3", "FM-TOWNS", "", -1, Common::JA_JPN, Common::kPlatformFMTowns },
{ "3a3e592b074f595489f7f11e150c398d", "puttzoo", "HE 99", "Updated", -1, Common::EN_USA, Common::kPlatformWindows },
- { "3a5d13675e9a23aedac0bac7730f0ac1", "samnmax", "", "CD", -1, Common::FR_FRA, Common::kPlatformMacintosh },
+ { "3a5d13675e9a23aedac0bac7730f0ac1", "samnmax", "", "CD", 228446581, Common::FR_FRA, Common::kPlatformMacintosh },
{ "3a5ec90d556d4920976c5578bfbfaf79", "maniac", "NES", "", -1, Common::DE_DEU, Common::kPlatformNES },
{ "3ae7f002d9256b8bdf76aaf8a3a069f8", "freddi", "HE 100", "", 34837, Common::EN_GRB, Common::kPlatformWii },
{ "3af61c5edf8e15b43dbafd285b2e9777", "puttcircus", "", "Demo", -1, Common::HE_ISR, Common::kPlatformWindows },
@@ -189,6 +193,7 @@ static const MD5Table md5table[] = {
{ "3df6ead57930488bc61e6e41901d0e97", "fbear", "HE 62", "", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "3e48298920fab9b7aec5a971e1bd1fab", "pajama3", "", "Demo", -1, Common::EN_GRB, Common::kPlatformWindows },
{ "3e861421f494711bc6f619d4aba60285", "airport", "", "", 93231, Common::RU_RUS, Common::kPlatformWindows },
+ { "403d2ec4d60d3cdae925e6cbf67716d6", "ft", "", "", 489436643, Common::FR_FRA, Common::kPlatformMacintosh },
{ "40564ec47da48a67787d1f9bd043902a", "maniac", "V2 Demo", "V2 Demo", 1988, Common::EN_ANY, Common::kPlatformDOS },
{ "4167a92a1d46baa4f4127d918d561f88", "tentacle", "", "CD", 7932, Common::EN_ANY, Common::kPlatformUnknown },
{ "41958e24d03181ff9a381a66d048a581", "ft", "", "", -1, Common::PT_BRA, Common::kPlatformUnknown },
@@ -250,6 +255,7 @@ static const MD5Table md5table[] = {
{ "55f4e9402bec2bded383843123f37c5c", "pajama2", "HE 98.5", "", -1, Common::DE_DEU, Common::kPlatformWindows },
{ "566165a7338fa11029e7c14d94fa70d0", "freddi", "HE 73", "Demo", 9800, Common::EN_ANY, Common::kPlatformWindows },
{ "56b5922751be7ffd771b38dda56b028b", "freddi", "HE 100", "", 34837, Common::NL_NLD, Common::kPlatformWii },
+ { "56e8c37a0a08c3a7076f82417461a877", "indy3", "EGA", "EGA", -1, Common::EN_ANY, Common::kPlatformDOS },
{ "5719fc8a13b4638b78d9d8d12f091f94", "puttrace", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "5798972220cd458be2626d54c80f71d7", "atlantis", "Floppy", "Floppy", -1, Common::IT_ITA, Common::kPlatformAmiga },
{ "57a17febe2183f521250e55d55b83e60", "PuttTime", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformWindows },
@@ -266,7 +272,7 @@ static const MD5Table md5table[] = {
{ "5c21fc49aee8f46e58fef21579e614a1", "thinker1", "", "", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "5c9cecbd2952ccec14c9ecebf5822a34", "puttzoo", "HE 100", "", -1, Common::EN_ANY, Common::kPlatformIOS },
{ "5d88b9d6a88e6f8e90cded9d01b7f082", "loom", "VGA", "VGA", 8307, Common::EN_ANY, Common::kPlatformDOS },
- { "5dda73606533d66a4c3f4f9ea6e842af", "farm", "", "", 87061, Common::RU_RUS, Common::kPlatformWindows },
+ { "5dda73606533d66a4c3f4f9ea6e842af", "farm", "HE 73", "", 87061, Common::RU_RUS, Common::kPlatformWindows },
{ "5e8fb66971a60e523e5afbc4c129c0e8", "socks", "HE 85", "", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "5ebb57234b2fe5c5dff641e00184ad81", "freddi", "HE 73", "", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "5fbe557049892eb4b709d90916ec97ca", "indy3", "EGA", "EGA", 5361, Common::EN_ANY, Common::kPlatformDOS },
@@ -376,6 +382,7 @@ static const MD5Table md5table[] = {
{ "8368f552b1e3eba559f8d559bcc4cadb", "freddi3", "", "", -1, Common::UNK_LANG, Common::kPlatformUnknown },
{ "839a658f7d22de00787ebc945348cdb6", "dog", "", "", 19681, Common::DE_DEU, Common::kPlatformWindows },
{ "83cedbe26aa8b58988e984e3d34cac8e", "freddi3", "HE 99", "", -1, Common::DE_DEU, Common::kPlatformUnknown },
+ { "83e7a9205567dceb456ee35eeaf26ffa", "pajama3", "", "", -1, Common::IT_ITA, Common::kPlatformUnknown },
{ "84e3c23a49ded8a6f9197735c8eb3de7", "PuttTime", "HE 85", "", -1, Common::DE_DEU, Common::kPlatformWindows },
{ "8539c0ff89868e55a08e652ac44daaae", "water", "HE 98.5", "", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "861e59ed72a1cd0e6d454f7ee7e2bf3d", "comi", "", "", -1, Common::RU_RUS, Common::kPlatformWindows },
@@ -458,7 +465,7 @@ static const MD5Table md5table[] = {
{ "a194f15f51ee62badab74b9e7da97693", "baseball2001", "", "Demo", 20507, Common::EN_ANY, Common::kPlatformUnknown },
{ "a197a87ae77f3b3333f09a7a2c448fe2", "freddi", "HE 99", "Updated", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "a22af0ad0e3126d19d22707b0267a37d", "balloon", "HE 80", "", -1, Common::NL_NLD, Common::kPlatformWindows },
- { "a2386da005672cbd5136f4f27a626c5f", "farm", "", "", 87061, Common::NL_NLD, Common::kPlatformWindows },
+ { "a2386da005672cbd5136f4f27a626c5f", "farm", "HE 73", "", 87061, Common::NL_NLD, Common::kPlatformWindows },
{ "a28135a7ade38cc0208b04507c46efd1", "spyfox", "HE 99", "", -1, Common::DE_DEU, Common::kPlatformUnknown },
{ "a2bb6aa0537402c1b3c2ea899ccef64b", "lost", "HE 99", "Demo", 15540, Common::EN_ANY, Common::kPlatformWindows },
{ "a3036878840720fbefa41e6965fa4a0a", "samnmax", "Floppy", "Floppy", -1, Common::EN_ANY, Common::kPlatformDOS },
@@ -473,7 +480,7 @@ static const MD5Table md5table[] = {
{ "a654fb60c3b67d6317a7894ffd9f25c5", "pajama3", "", "Demo", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "a71014c53a6d18c66ef2ea0ee42328e9", "PuttTime", "HE 99", "Mini Game", 18458, Common::NL_NLD, Common::kPlatformWindows },
{ "a7cacad9c40c4dc9e1812abf6c8af9d5", "puttcircus", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown },
- { "a85856675429fe88051744f755b72f93", "farm", "", "", -1, Common::EN_ANY, Common::kPlatformWindows },
+ { "a85856675429fe88051744f755b72f93", "farm", "HE 73", "", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "a86f9c49355579c30d4a55b477c0d869", "baseball2001", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "a8fcc3084ad5e3e569722755f205b1ef", "pajama3", "", "Mini Game", 13911, Common::DE_DEU, Common::kPlatformWindows },
{ "a9543ef0d79bcb47cd76ec197ad0a967", "puttmoon", "", "", -1, Common::EN_ANY, Common::kPlatform3DO },
@@ -637,13 +644,13 @@ static const MD5Table md5table[] = {
{ "ecc4340c2b801f5af8da4e00c0e432d9", "puttcircus", "", "", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "ed2b074bc3166087a747acb2a3c6abb0", "freddi3", "HE 98.5", "Demo", -1, Common::DE_DEU, Common::kPlatformUnknown },
{ "ed361270102e355afe5236954216aba2", "lost", "", "", -1, Common::EN_USA, Common::kPlatformUnknown },
- { "ede149fda3edfc1dbd7347e0737cb583", "tentacle", "", "CD", -1, Common::FR_FRA, Common::kPlatformMacintosh },
+ { "ede149fda3edfc1dbd7347e0737cb583", "tentacle", "", "CD", 282830409, Common::FR_FRA, Common::kPlatformMacintosh },
{ "edfdb24a499d92c59f824c52987c0eec", "atlantis", "Floppy", "Floppy", -1, Common::FR_FRA, Common::kPlatformDOS },
{ "ee41f6afbc5b26fa475754b56fe92048", "puttputt", "HE 61", "", 8032, Common::JA_JPN, Common::kPlatform3DO },
{ "ee785fe2569bc9965526e774f7ab86f1", "spyfox", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformMacintosh },
{ "ee8cfeb76e55d43a01c25e0865a9db76", "puttrace", "HE 98", "Demo", 13135, Common::NL_NLD, Common::kPlatformMacintosh },
{ "eea4d9ac2fb6f145945a308e8866915b", "maniac", "C64", "", -1, Common::EN_ANY, Common::kPlatformC64 },
- { "eeb606c2d2ec877a712a9f20c10bcdda", "farm", "", "", 87034, Common::NL_NLD, Common::kPlatformMacintosh },
+ { "eeb606c2d2ec877a712a9f20c10bcdda", "farm", "HE 73", "", 87034, Common::NL_NLD, Common::kPlatformMacintosh },
{ "ef347474f3c7be3b29584eaa133cca05", "samnmax", "Floppy", "Floppy", -1, Common::FR_FRA, Common::kPlatformDOS },
{ "ef71a322b6530ac45b1a070f7c0795f7", "moonbase", "Demo", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "ef74d9071d4e564b037cb44bd6774de7", "fbear", "HE 62", "", -1, Common::HE_ISR, Common::kPlatformDOS },
@@ -651,6 +658,7 @@ static const MD5Table md5table[] = {
{ "f049e38c1f8302b5db6170f1872af89a", "monkey", "CD", "CD", 8955, Common::ES_ESP, Common::kPlatformDOS },
{ "f06e66fd45b2f8b0f4a2833ff4476050", "fbpack", "", "", -1, Common::HE_ISR, Common::kPlatformDOS },
{ "f08145577e4f13584cc90b3d6e9caa55", "pajama3", "", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown },
+ { "f0ccc12a8704bf57706b42a37f877128", "tentacle", "Floppy", "Floppy", -1, Common::EN_ANY, Common::kPlatformDOS },
{ "f1b0e0d587b85052de5534a3847e68fe", "water", "HE 99", "Updated", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "f237bf8a5ef9af78b2a6a4f3901da341", "pajama", "", "Demo", 18354, Common::EN_ANY, Common::kPlatformUnknown },
{ "f27b1ba0eadaf2a6617b2b58192d1dbf", "samnmax", "Floppy", "Floppy", -1, Common::DE_DEU, Common::kPlatformDOS },
@@ -671,7 +679,7 @@ static const MD5Table md5table[] = {
{ "faa89ab5e67ba4eebb4399f584f7490c", "pajama3", "", "Mini Game", 13911, Common::FR_FRA, Common::kPlatformWindows },
{ "fb66aa42de21675116346213f176a366", "monkey", "VGA", "VGA", -1, Common::IT_ITA, Common::kPlatformAmiga },
{ "fbb697d89d2beca87360a145f467bdae", "PuttTime", "HE 90", "Demo", -1, Common::DE_DEU, Common::kPlatformUnknown },
- { "fbbbb38a81fc9d6a61d509278390a290", "farm", "", "", -1, Common::EN_ANY, Common::kPlatformMacintosh },
+ { "fbbbb38a81fc9d6a61d509278390a290", "farm", "HE 73", "", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "fbdd947d21e8f5bac6d6f7a316af1c5a", "spyfox", "", "Demo", 15693, Common::EN_ANY, Common::kPlatformUnknown },
{ "fc53ce0e5f6562b1c1e1b4b8203acafb", "samnmax", "Floppy", "Floppy", -1, Common::ES_ESP, Common::kPlatformDOS },
{ "fc6b6148e80d67939d9a18697c0f626a", "monkey", "EGA", "EGA", 8367, Common::DE_DEU, Common::kPlatformDOS },
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 6040344c2c..24d676a1ff 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -316,6 +316,7 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
_NES_lastTalkingActor = 0;
_NES_talkColor = 0;
_keepText = false;
+ _msgCount = 0;
_costumeLoader = NULL;
_costumeRenderer = NULL;
_2byteFontPtr = 0;
@@ -1904,7 +1905,7 @@ void ScummEngine::setupMusic(int midi) {
// EGA/VGA. However, we support multi MIDI for that game and we cannot
// support this with the Player_AD code at the moment. The reason here
// is that multi MIDI is supported internally by our iMuse output.
- _musicEngine = new Player_AD(this, _mixer);
+ _musicEngine = new Player_AD(this);
} else if (_game.version >= 3 && _game.heversion <= 62) {
MidiDriver *nativeMidiDriver = 0;
MidiDriver *adlibMidiDriver = 0;
@@ -2597,9 +2598,52 @@ void ScummEngine_v90he::runBootscript() {
}
#endif
-void ScummEngine::startManiac() {
- debug(0, "stub startManiac()");
- displayMessage(0, "%s", _("Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' directory inside the Tentacle game directory."));
+bool ScummEngine::startManiac() {
+ Common::String currentPath = ConfMan.get("path");
+ Common::String maniacTarget;
+
+ if (!ConfMan.hasKey("easter_egg")) {
+ // Look for a game with a game path pointing to a 'Maniac' directory
+ // as a subdirectory to the current game.
+ Common::ConfigManager::DomainMap::iterator iter = ConfMan.beginGameDomains();
+ for (; iter != ConfMan.endGameDomains(); ++iter) {
+ Common::ConfigManager::Domain &dom = iter->_value;
+ Common::String path = dom.getVal("path");
+
+ if (path.hasPrefix(currentPath)) {
+ path.erase(0, currentPath.size() + 1);
+ if (path.equalsIgnoreCase("maniac")) {
+ maniacTarget = iter->_key;
+ break;
+ }
+ }
+ }
+ } else {
+ maniacTarget = ConfMan.get("easter_egg");
+ }
+
+ if (!maniacTarget.empty()) {
+ // Request a temporary save game to be made.
+ _saveLoadFlag = 1;
+ _saveLoadSlot = 100;
+ _saveTemporaryState = true;
+
+ // Set up the chanined games to Maniac Mansion, and then back
+ // to the current game again with that save slot.
+ ChainedGamesMan.push(maniacTarget);
+ ChainedGamesMan.push(ConfMan.getActiveDomainName(), 100);
+
+ // Force a return to the launcher. This will start the first
+ // chained game.
+ Common::EventManager *eventMan = g_system->getEventManager();
+ Common::Event event;
+ event.type = Common::EVENT_RTL;
+ eventMan->pushEvent(event);
+ return true;
+ } else {
+ displayMessage(0, "%s", _("Usually, Maniac Mansion would start now. But for that to work, the game files for Maniac Mansion have to be in the 'Maniac' directory inside the Tentacle game directory, and the game has to be added to ScummVM."));
+ return false;
+ }
}
#pragma mark -
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index 967909e505..6e0adc3ff3 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -654,7 +654,7 @@ protected:
int getScriptSlot();
void startScene(int room, Actor *a, int b);
- void startManiac();
+ bool startManiac();
public:
void runScript(int script, bool freezeResistant, bool recursive, int *lvarptr, int cycle = 0);
@@ -1182,6 +1182,7 @@ protected:
byte _charsetBuffer[512];
bool _keepText;
+ byte _msgCount;
int _nextLeft, _nextTop;
diff --git a/engines/scumm/smush/smush_player.cpp b/engines/scumm/smush/smush_player.cpp
index 7617fc541f..05c7ff2d9a 100644
--- a/engines/scumm/smush/smush_player.cpp
+++ b/engines/scumm/smush/smush_player.cpp
@@ -115,6 +115,11 @@ public:
if (data_end[-2] == '\r' && data_end[-1] == '\n' && data_end[0] == '\r' && data_end[1] == '\n') {
break;
}
+ // In the Steam Mac version of The Dig, LF-LF is used
+ // instead of CR-LF
+ if (data_end[-2] == '\n' && data_end[-1] == '\n') {
+ break;
+ }
// In Russian Full Throttle strings are finished with
// just one pair of CR-LF
if (data_end[-2] == '\r' && data_end[-1] == '\n' && data_end[0] == '#') {
diff --git a/engines/scumm/string.cpp b/engines/scumm/string.cpp
index d60c4c6a50..3049fbcf62 100644
--- a/engines/scumm/string.cpp
+++ b/engines/scumm/string.cpp
@@ -283,6 +283,7 @@ bool ScummEngine::handleNextCharsetCode(Actor *a, int *code) {
switch (c) {
case 1:
c = 13; // new line
+ _msgCount = _screenWidth;
endLoop = true;
break;
case 2:
@@ -293,6 +294,7 @@ bool ScummEngine::handleNextCharsetCode(Actor *a, int *code) {
case 3:
_haveMsg = (_game.version >= 7) ? 1 : 0xFF;
_keepText = false;
+ _msgCount = 0;
endLoop = true;
break;
case 8:
@@ -573,6 +575,9 @@ void ScummEngine::CHARSET_1() {
#endif
restoreCharsetBg();
}
+ _msgCount = 0;
+ } else if (_game.version <= 2) {
+ _talkDelay += _msgCount * _defaultTalkDelay;
}
if (_game.version > 3) {
@@ -600,6 +605,7 @@ void ScummEngine::CHARSET_1() {
// End of text reached, set _haveMsg accordingly
_haveMsg = (_game.version >= 7) ? 2 : 1;
_keepText = false;
+ _msgCount = 0;
break;
}
@@ -648,6 +654,7 @@ void ScummEngine::CHARSET_1() {
}
if (_game.version <= 3) {
_charset->printChar(c, false);
+ _msgCount += 1;
} else {
if (_game.features & GF_16BIT_COLOR) {
// HE games which use sprites for subtitles
diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp
new file mode 100644
index 0000000000..bbf7c913b7
--- /dev/null
+++ b/engines/sherlock/animation.cpp
@@ -0,0 +1,324 @@
+/* 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 "sherlock/animation.h"
+#include "sherlock/sherlock.h"
+#include "common/algorithm.h"
+
+namespace Sherlock {
+
+static const int NO_FRAMES = FRAMES_END;
+
+Animation::Animation(SherlockEngine *vm) : _vm(vm) {
+}
+
+bool Animation::play(const Common::String &filename, bool intro, int minDelay, int fade,
+ bool setPalette, int speed) {
+ Events &events = *_vm->_events;
+ Screen &screen = *_vm->_screen;
+ Sound &sound = *_vm->_sound;
+ int soundNumber = 0;
+
+ // Check for any any sound frames for the given animation
+ const int *soundFrames = checkForSoundFrames(filename, intro);
+
+ // Add on the VDX extension
+ Common::String vdxName = filename + ".vdx";
+
+ // Load the animation
+ Common::SeekableReadStream *stream;
+ if (!_gfxLibraryFilename.empty())
+ stream = _vm->_res->load(vdxName, _gfxLibraryFilename);
+ else if (_vm->_useEpilogue2)
+ stream = _vm->_res->load(vdxName, "epilog2.lib");
+ else
+ stream = _vm->_res->load(vdxName, "epilogue.lib");
+
+ // Load initial image
+ Common::String vdaName = filename + ".vda";
+ ImageFile images(vdaName, true, true);
+
+ events.wait(minDelay);
+ if (fade != 0 && fade != 255)
+ screen.fadeToBlack();
+
+ if (setPalette) {
+ if (fade != 255)
+ screen.setPalette(images._palette);
+ }
+
+ int frameNumber = 0;
+ Common::Point pt;
+ bool skipped = false;
+ while (!_vm->shouldQuit()) {
+ // Get the next sprite to display
+ int imageFrame = stream->readSint16LE();
+
+ if (imageFrame == -2) {
+ // End of animation reached
+ break;
+ } else if (imageFrame != -1) {
+ // Read position from either animation stream or the sprite frame itself
+ if (imageFrame < 0) {
+ imageFrame += 32768;
+ pt.x = stream->readUint16LE();
+ pt.y = stream->readUint16LE();
+ } else {
+ pt = images[imageFrame]._offset;
+ }
+
+ // Draw the sprite. Note that we explicitly use the raw frame below, rather than the ImageFrame,
+ // since we don't want the offsets in the image file to be used, just the explicit position we specify
+ screen.transBlitFrom(images[imageFrame]._frame, pt);
+ } else {
+ // At this point, either the sprites for the frame has been complete, or there weren't any sprites
+ // at all to draw for the frame
+ if (fade == 255) {
+ // Gradual fade in
+ if (screen.equalizePalette(images._palette) == 0)
+ fade = 0;
+ }
+
+ // Check if we've reached a frame with sound
+ if (frameNumber++ == *soundFrames) {
+ ++soundNumber;
+ ++soundFrames;
+
+ Common::String sampleFilename;
+
+ if (!intro) {
+ // regular animation, append 1-digit number
+ sampleFilename = Common::String::format("%s%01d", filename.c_str(), soundNumber);
+ } else {
+ // intro animation, append 2-digit number
+ sampleFilename = Common::String::format("%s%02d", filename.c_str(), soundNumber);
+ }
+
+ if (sound._voices)
+ sound.playSound(sampleFilename, WAIT_RETURN_IMMEDIATELY, 100, _soundLibraryFilename.c_str());
+ }
+
+ events.wait(speed * 3);
+ }
+
+ if (events.kbHit()) {
+ Common::KeyState keyState = events.getKey();
+ if (keyState.keycode == Common::KEYCODE_ESCAPE ||
+ keyState.keycode == Common::KEYCODE_SPACE) {
+ skipped = true;
+ break;
+ }
+ } else if (events._pressed) {
+ skipped = true;
+ break;
+ }
+ }
+
+ events.clearEvents();
+ sound.stopSound();
+ delete stream;
+
+ return !skipped && !_vm->shouldQuit();
+}
+
+bool Animation::play3DO(const Common::String &filename, bool intro, int minDelay, bool fadeFromGrey,
+ int speed) {
+ Events &events = *_vm->_events;
+ Screen &screen = *_vm->_screen;
+ Sound &sound = *_vm->_sound;
+ int soundNumber = 0;
+
+ bool fadeActive = false;
+ uint16 fadeLimitColor = 0;
+ uint16 fadeLimitColorRed = 0;
+ uint16 fadeLimitColorGreen = 0;
+ uint16 fadeLimitColorBlue = 0;
+
+ // Check for any any sound frames for the given animation
+ const int *soundFrames = checkForSoundFrames(filename, intro);
+
+ // Add the VDX extension
+ Common::String indexName = "prologue/" + filename + ".3dx";
+
+ // Load the animation
+ Common::File *indexStream = new Common::File();
+
+ if (!indexStream->open(indexName)) {
+ warning("unable to open %s\n", indexName.c_str());
+ return false;
+ }
+
+ // Load initial image
+ Common::String graphicsName = "prologue/" + filename + ".3da";
+ ImageFile3DO images(graphicsName, kImageFile3DOType_Animation);
+
+ events.wait(minDelay);
+
+ if (fadeFromGrey) {
+ fadeActive = true;
+ fadeLimitColor = 0xCE59; // RGB565: 25, 50, 25 -> "grey"
+ }
+
+ int frameNumber = 0;
+ Common::Point pt;
+ bool skipped = false;
+ while (!_vm->shouldQuit()) {
+ // Get the next sprite to display
+ int imageFrame = indexStream->readSint16BE();
+
+ if (imageFrame == -2) {
+ // End of animation reached
+ break;
+ } else if (imageFrame != -1) {
+ // Read position from either animation stream or the sprite frame itself
+ if (imageFrame < 0) {
+ imageFrame += 32768;
+ pt.x = indexStream->readUint16BE();
+ pt.y = indexStream->readUint16BE();
+ } else {
+ pt = images[imageFrame]._offset;
+ }
+
+ // Draw the sprite. Note that we explicitly use the raw frame below, rather than the ImageFrame,
+ // since we don't want the offsets in the image file to be used, just the explicit position we specify
+ if (!fadeActive) {
+ screen.transBlitFrom(images[imageFrame]._frame, pt);
+ } else {
+ // Fade active, blit to backbuffer1
+ screen._backBuffer1.transBlitFrom(images[imageFrame]._frame, pt);
+ }
+ } else {
+ // At this point, either the sprites for the frame has been complete, or there weren't any sprites
+ // at all to draw for the frame
+
+ if (fadeActive) {
+ // process fading
+ screen.blitFrom3DOcolorLimit(fadeLimitColor);
+
+ if (!fadeLimitColor) {
+ // we are at the end, so stop
+ fadeActive = false;
+ } else {
+ // decrease limit color
+ fadeLimitColorRed = fadeLimitColor & 0xF800;
+ fadeLimitColorGreen = fadeLimitColor & 0x07E0;
+ fadeLimitColorBlue = fadeLimitColor & 0x001F;
+ if (fadeLimitColorRed)
+ fadeLimitColor -= 0x0800;
+ if (fadeLimitColorGreen)
+ fadeLimitColor -= 0x0040; // -2 because we are using RGB565, sherlock uses RGB555
+ if (fadeLimitColorBlue)
+ fadeLimitColor -= 0x0001;
+ }
+ }
+
+ // Check if we've reached a frame with sound
+ if (frameNumber++ == *soundFrames) {
+ ++soundNumber;
+ ++soundFrames;
+
+ Common::String sampleFilename;
+
+ // append 1-digit number
+ sampleFilename = Common::String::format("prologue/sounds/%s%01d", filename.c_str(), soundNumber);
+
+ if (sound._voices)
+ sound.playSound(sampleFilename, WAIT_RETURN_IMMEDIATELY, 100); // no sound library
+ }
+ events.wait(speed * 3);
+ }
+
+ if (events.kbHit()) {
+ Common::KeyState keyState = events.getKey();
+ if (keyState.keycode == Common::KEYCODE_ESCAPE ||
+ keyState.keycode == Common::KEYCODE_SPACE) {
+ skipped = true;
+ break;
+ }
+ } else if (events._pressed) {
+ skipped = true;
+ break;
+ }
+ }
+
+ events.clearEvents();
+ sound.stopSound();
+ delete indexStream;
+
+ return !skipped && !_vm->shouldQuit();
+}
+
+void Animation::setPrologueNames(const char *const *names, int count) {
+ for (int idx = 0; idx < count; ++idx, ++names) {
+ _prologueNames.push_back(*names);
+ }
+}
+
+void Animation::setPrologueFrames(const int *frames, int count, int maxFrames) {
+ _prologueFrames.resize(count);
+
+ for (int idx = 0; idx < count; ++idx, frames += maxFrames) {
+ _prologueFrames[idx].resize(maxFrames);
+ Common::copy(frames, frames + maxFrames, &_prologueFrames[idx][0]);
+ }
+}
+
+void Animation::setTitleNames(const char *const *names, int count) {
+ for (int idx = 0; idx < count; ++idx, ++names) {
+ _titleNames.push_back(*names);
+ }
+}
+
+void Animation::setTitleFrames(const int *frames, int count, int maxFrames) {
+ _titleFrames.resize(count);
+
+ for (int idx = 0; idx < count; ++idx, frames += maxFrames) {
+ _titleFrames[idx].resize(maxFrames);
+ Common::copy(frames, frames + maxFrames, &_titleFrames[idx][0]);
+ }
+}
+
+const int *Animation::checkForSoundFrames(const Common::String &filename, bool intro) {
+ const int *frames = &NO_FRAMES;
+
+ if (!intro) {
+ // regular animation is playing
+ for (uint idx = 0; idx < _prologueNames.size(); ++idx) {
+ if (filename.equalsIgnoreCase(_prologueNames[idx])) {
+ frames = &_prologueFrames[idx][0];
+ break;
+ }
+ }
+ } else {
+ // intro-animation is playing
+ for (uint idx = 0; idx < _titleNames.size(); ++idx) {
+ if (filename.equalsIgnoreCase(_titleNames[idx])) {
+ frames = &_titleFrames[idx][0];
+ break;
+ }
+ }
+ }
+
+ return frames;
+}
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/animation.h b/engines/sherlock/animation.h
new file mode 100644
index 0000000000..f3c95d4027
--- /dev/null
+++ b/engines/sherlock/animation.h
@@ -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.
+ *
+ */
+
+#ifndef SHERLOCK_ANIMATION_H
+#define SHERLOCK_ANIMATION_H
+
+#include "common/scummsys.h"
+#include "common/str.h"
+#include "common/array.h"
+
+namespace Sherlock {
+
+#define FRAMES_END 32000
+
+class SherlockEngine;
+
+class Animation {
+private:
+ SherlockEngine *_vm;
+
+ Common::Array<const char *> _prologueNames;
+ Common::Array<Common::Array<int> > _prologueFrames;
+ Common::Array<const char *> _titleNames;
+ Common::Array<Common::Array<int> > _titleFrames;
+
+ /**
+ * Checks for whether an animation is being played that has associated sound
+ */
+ const int *checkForSoundFrames(const Common::String &filename, bool intro);
+public:
+ Common::String _soundLibraryFilename;
+ Common::String _gfxLibraryFilename;
+
+public:
+ Animation(SherlockEngine *vm);
+
+ /**
+ * Load the prologue name array
+ */
+ void setPrologueNames(const char *const *names, int count);
+
+ /**
+ * Load the prologue frame array
+ */
+ void setPrologueFrames(const int *frames, int count, int maxFrames);
+
+ /**
+ * Load the title name array
+ */
+ void setTitleNames(const char *const *names, int count);
+
+ /**
+ * Load the title frame array
+ */
+ void setTitleFrames(const int *frames, int count, int maxFrames);
+
+ /**
+ * Play a full-screen animation
+ */
+ bool play(const Common::String &filename, bool intro, int minDelay, int fade, bool setPalette, int speed);
+
+ bool play3DO(const Common::String &filename, bool intro, int minDelay, bool fadeFromGrey, int speed);
+};
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/configure.engine b/engines/sherlock/configure.engine
new file mode 100644
index 0000000000..a56129a8f0
--- /dev/null
+++ b/engines/sherlock/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine sherlock "The Lost Files of Sherlock Holmes" no
diff --git a/engines/sherlock/debugger.cpp b/engines/sherlock/debugger.cpp
new file mode 100644
index 0000000000..2813a7eb69
--- /dev/null
+++ b/engines/sherlock/debugger.cpp
@@ -0,0 +1,138 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "sherlock/debugger.h"
+#include "sherlock/sherlock.h"
+#include "sherlock/music.h"
+#include "sherlock/scalpel/3do/movie_decoder.h"
+#include "sherlock/scalpel/scalpel_debugger.h"
+#include "sherlock/tattoo/tattoo_debugger.h"
+#include "audio/mixer.h"
+#include "audio/decoders/aiff.h"
+#include "audio/decoders/wave.h"
+
+namespace Sherlock {
+
+Debugger *Debugger::init(SherlockEngine *vm) {
+ if (vm->getGameID() == GType_RoseTattoo)
+ return new Tattoo::TattooDebugger(vm);
+ else
+ return new Scalpel::ScalpelDebugger(vm);
+}
+
+Debugger::Debugger(SherlockEngine *vm) : GUI::Debugger(), _vm(vm) {
+ _showAllLocations = LOC_DISABLED;
+
+ registerCmd("continue", WRAP_METHOD(Debugger, cmdExit));
+ registerCmd("scene", WRAP_METHOD(Debugger, cmdScene));
+ registerCmd("song", WRAP_METHOD(Debugger, cmdSong));
+ registerCmd("dumpfile", WRAP_METHOD(Debugger, cmdDumpFile));
+ registerCmd("locations", WRAP_METHOD(Debugger, cmdLocations));
+}
+
+void Debugger::postEnter() {
+ if (!_3doPlayMovieFile.empty()) {
+ Scalpel3DOMoviePlay(_3doPlayMovieFile.c_str(), Common::Point(0, 0));
+
+ _3doPlayMovieFile.clear();
+ }
+
+ _vm->pauseEngine(false);
+}
+
+int Debugger::strToInt(const char *s) {
+ if (!*s)
+ // No string at all
+ return 0;
+ else if (toupper(s[strlen(s) - 1]) != 'H')
+ // Standard decimal string
+ return atoi(s);
+
+ // Hexadecimal string
+ uint tmp = 0;
+ int read = sscanf(s, "%xh", &tmp);
+ if (read < 1)
+ error("strToInt failed on string \"%s\"", s);
+ return (int)tmp;
+}
+
+bool Debugger::cmdScene(int argc, const char **argv) {
+ if (argc != 2) {
+ debugPrintf("Format: scene <room>\n");
+ return true;
+ } else {
+ _vm->_scene->_goToScene = strToInt(argv[1]);
+ return false;
+ }
+}
+
+bool Debugger::cmdSong(int argc, const char **argv) {
+ if (argc != 2) {
+ debugPrintf("Format: song <room>\n");
+ return true;
+ }
+
+ if (!_vm->_music->loadSong(strToInt(argv[1]))) {
+ debugPrintf("Invalid song number.\n");
+ return true;
+ }
+ return false;
+}
+
+bool Debugger::cmdDumpFile(int argc, const char **argv) {
+ if (argc != 2) {
+ debugPrintf("Format: dumpfile <resource name>\n");
+ return true;
+ }
+
+ Common::SeekableReadStream *s = _vm->_res->load(argv[1]);
+ if (!s) {
+ debugPrintf("Invalid resource.\n");
+ return true;
+ }
+
+ byte *buffer = new byte[s->size()];
+ s->read(buffer, s->size());
+
+ Common::DumpFile dumpFile;
+ dumpFile.open(argv[1]);
+
+ dumpFile.write(buffer, s->size());
+ dumpFile.flush();
+ dumpFile.close();
+
+ delete[] buffer;
+
+ debugPrintf("Resource %s has been dumped to disk.\n", argv[1]);
+
+ return true;
+}
+
+bool Debugger::cmdLocations(int argc, const char **argv) {
+ _showAllLocations = LOC_REFRESH;
+
+ debugPrintf("Now showing all map locations\n");
+ return false;
+}
+
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/debugger.h b/engines/sherlock/debugger.h
new file mode 100644
index 0000000000..abc8ef012d
--- /dev/null
+++ b/engines/sherlock/debugger.h
@@ -0,0 +1,76 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SHERLOCK_DEBUGGER_H
+#define SHERLOCK_DEBUGGER_H
+
+#include "common/scummsys.h"
+#include "gui/debugger.h"
+
+namespace Sherlock {
+
+class SherlockEngine;
+
+enum AllLocations { LOC_REFRESH = -1, LOC_DISABLED = 0, LOC_ALL = 1 };
+
+class Debugger : public GUI::Debugger {
+private:
+ /**
+ * Converts a decimal or hexadecimal string into a number
+ */
+ int strToInt(const char *s);
+
+ /**
+ * Switch to another scene
+ */
+ bool cmdScene(int argc, const char **argv);
+
+ /**
+ * Plays a song
+ */
+ bool cmdSong(int argc, const char **argv);
+
+ /**
+ * Dumps a file to disk
+ */
+ bool cmdDumpFile(int argc, const char **argv);
+
+ /**
+ * Show all locations on the map
+ */
+ bool cmdLocations(int argc, const char **argv);
+protected:
+ SherlockEngine *_vm;
+ Common::String _3doPlayMovieFile;
+public:
+ AllLocations _showAllLocations;
+public:
+ Debugger(SherlockEngine *vm);
+ virtual ~Debugger() {}
+ static Debugger *init(SherlockEngine *vm);
+
+ void postEnter();
+};
+
+} // End of namespace Sherlock
+
+#endif /* SHERLOCK_DEBUGGER_H */
diff --git a/engines/sherlock/decompress.cpp b/engines/sherlock/decompress.cpp
new file mode 100644
index 0000000000..8e02da3212
--- /dev/null
+++ b/engines/sherlock/decompress.cpp
@@ -0,0 +1,128 @@
+/* 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 "sherlock/decompress.h"
+
+namespace Sherlock {
+
+/**
+ * Decompresses an LZW compressed resource. If no outSize is specified, it will
+ * decompress the entire resource. If, however, an explicit size is specified,
+ * then it means we're already within a resource, and only want to decompress
+ * part of it.
+ */
+Common::SeekableReadStream *decompressLZ(Common::SeekableReadStream &source, int32 outSize) {
+ if (outSize == -1) {
+ source.seek(5);
+ outSize = source.readSint32LE();
+ }
+
+ byte lzWindow[4096];
+ uint16 lzWindowPos;
+ uint16 cmd;
+
+ byte *outBuffer = new byte[outSize];
+ byte *outBufferEnd = outBuffer + outSize;
+ Common::MemoryReadStream *outS = new Common::MemoryReadStream(outBuffer, outSize, DisposeAfterUse::YES);
+
+ memset(lzWindow, 0xFF, 0xFEE);
+ lzWindowPos = 0xFEE;
+ cmd = 0;
+
+ do {
+ cmd >>= 1;
+ if (!(cmd & 0x100))
+ cmd = source.readByte() | 0xFF00;
+
+ if (cmd & 1) {
+ byte literal = source.readByte();
+ *outBuffer++ = literal;
+ lzWindow[lzWindowPos] = literal;
+ lzWindowPos = (lzWindowPos + 1) & 0x0FFF;
+ } else {
+ int copyPos, copyLen;
+ copyPos = source.readByte();
+ copyLen = source.readByte();
+ copyPos = copyPos | ((copyLen & 0xF0) << 4);
+ copyLen = (copyLen & 0x0F) + 3;
+ while (copyLen--) {
+ byte literal = lzWindow[copyPos];
+ copyPos = (copyPos + 1) & 0x0FFF;
+ *outBuffer++ = literal;
+ lzWindow[lzWindowPos] = literal;
+ lzWindowPos = (lzWindowPos + 1) & 0x0FFF;
+ }
+ }
+ } while (outBuffer < outBufferEnd);
+
+ return outS;
+}
+
+
+/**
+ * Decompresses a Rose Tattoo resource
+ *
+Common::SeekableReadStream *decompress32(Common::SeekableReadStream &source, int32 outSize) {
+ if (outSize == -1) {
+ outSize = source.readSint32LE();
+ }
+
+ byte lzWindow[8192];
+ byte *outBuffer = new byte[outSize];
+ byte *outBufferEnd = outBuffer + outSize;
+ Common::MemoryReadStream *outS = new Common::MemoryReadStream(outBuffer, outSize, DisposeAfterUse::YES);
+
+ memset(lzWindow, 0xFF, 8192);
+ int lzWindowPos = 0xFEE;
+ int cmd = 0;
+
+ do {
+ cmd >>= 1;
+ if (!(cmd & 0x100))
+ cmd = source.readByte() | 0xFF00;
+
+ if (cmd & 1) {
+ byte literal = source.readByte();
+ *outBuffer++ = literal;
+ lzWindow[lzWindowPos] = literal;
+ lzWindowPos = (lzWindowPos + 1) & 0x0FFF;
+ } else {
+ int copyPos, copyLen;
+ copyPos = source.readByte();
+ copyLen = source.readByte();
+ copyPos = copyPos | ((copyLen & 0xF0) << 4);
+ copyLen = (copyLen & 0x0F) + 3;
+ while (copyLen--) {
+ byte literal = lzWindow[copyPos];
+ copyPos = (copyPos + 1) & 0x0FFF;
+ *outBuffer++ = literal;
+ lzWindow[lzWindowPos] = literal;
+ lzWindowPos = (lzWindowPos + 1) & 0x0FFF;
+ }
+ }
+ } while (outBuffer < outBufferEnd);
+
+ return outS;
+}
+*/
+
+} // namespace Sherlock
diff --git a/engines/sherlock/detection.cpp b/engines/sherlock/detection.cpp
new file mode 100644
index 0000000000..35a810efb1
--- /dev/null
+++ b/engines/sherlock/detection.cpp
@@ -0,0 +1,245 @@
+/* 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 "sherlock/sherlock.h"
+#include "sherlock/saveload.h"
+#include "sherlock/scalpel/scalpel.h"
+#include "sherlock/tattoo/tattoo.h"
+#include "common/system.h"
+#include "common/translation.h"
+#include "engines/advancedDetector.h"
+
+namespace Sherlock {
+
+struct SherlockGameDescription {
+ ADGameDescription desc;
+
+ GameType gameID;
+};
+
+GameType SherlockEngine::getGameID() const {
+ return _gameDescription->gameID;
+}
+
+Common::Platform SherlockEngine::getPlatform() const {
+ return _gameDescription->desc.platform;
+}
+
+Common::Language SherlockEngine::getLanguage() const {
+ return _gameDescription->desc.language;
+}
+
+} // End of namespace Sherlock
+
+static const PlainGameDescriptor sherlockGames[] = {
+ { "scalpel", "The Case of the Serrated Scalpel" },
+ { "rosetattoo", "The Case of the Rose Tattoo" },
+ {0, 0}
+};
+
+
+#define GAMEOPTION_ORIGINAL_SAVES GUIO_GAMEOPTIONS1
+#define GAMEOPTION_FADE_STYLE GUIO_GAMEOPTIONS2
+#define GAMEOPTION_HELP_STYLE GUIO_GAMEOPTIONS3
+#define GAMEOPTION_PORTRAITS_ON GUIO_GAMEOPTIONS4
+#define GAMEOPTION_WINDOW_STYLE GUIO_GAMEOPTIONS5
+
+static const ADExtraGuiOptionsMap optionsList[] = {
+ {
+ GAMEOPTION_ORIGINAL_SAVES,
+ {
+ _s("Use original savegame dialog"),
+ _s("Files button in-game shows original savegame dialog rather than the ScummVM menu"),
+ "originalsaveload",
+ false
+ }
+ },
+
+ {
+ GAMEOPTION_FADE_STYLE,
+ {
+ _s("Pixellated scene transitions"),
+ _s("When changing scenes, a randomized pixel transition is done"),
+ "fade_style",
+ true
+ }
+ },
+
+ {
+ GAMEOPTION_HELP_STYLE,
+ {
+ _s("Don't show hotspots when moving mouse"),
+ _s("Only show hotspot names after you actually click on a hotspot or action button"),
+ "help_style",
+ false
+ }
+ },
+
+ {
+ GAMEOPTION_PORTRAITS_ON,
+ {
+ _s("Show character portraits"),
+ _s("Show portraits for the characters when conversing"),
+ "portraits_on",
+ true
+ }
+ },
+
+ {
+ GAMEOPTION_WINDOW_STYLE,
+ {
+ _s("Slide dialogs into view"),
+ _s("Slide UI dialogs into view, rather than simply showing them immediately"),
+ "window_style",
+ true
+ }
+ },
+
+ AD_EXTRA_GUI_OPTIONS_TERMINATOR
+};
+
+
+#include "sherlock/detection_tables.h"
+
+class SherlockMetaEngine : public AdvancedMetaEngine {
+public:
+ SherlockMetaEngine() : AdvancedMetaEngine(Sherlock::gameDescriptions, sizeof(Sherlock::SherlockGameDescription),
+ sherlockGames, optionsList) {}
+
+ virtual const char *getName() const {
+ return "Sherlock Engine";
+ }
+
+ virtual const char *getOriginalCopyright() const {
+ return "Sherlock Engine (C) 1992-1996 Mythos Software, 1992-1996 (C) Electronic Arts";
+ }
+
+ /**
+ * Creates an instance of the game engine
+ */
+ virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
+
+ /**
+ * Returns a list of features the game's MetaEngine support
+ */
+ virtual bool hasFeature(MetaEngineFeature f) const;
+
+ /**
+ * Return a list of savegames
+ */
+ virtual SaveStateList listSaves(const char *target) const;
+
+ /**
+ * Returns the maximum number of allowed save slots
+ */
+ virtual int getMaximumSaveSlot() const;
+
+ /**
+ * Deletes a savegame in the specified slot
+ */
+ virtual void removeSaveState(const char *target, int slot) const;
+
+ /**
+ * Given a specified savegame slot, returns extended information for the save
+ */
+ SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
+};
+
+bool SherlockMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
+ const Sherlock::SherlockGameDescription *gd = (const Sherlock::SherlockGameDescription *)desc;
+ if (gd) {
+ switch (gd->gameID) {
+ case Sherlock::GType_SerratedScalpel:
+ *engine = new Sherlock::Scalpel::ScalpelEngine(syst, gd);
+ break;
+ case Sherlock::GType_RoseTattoo:
+ *engine = new Sherlock::Tattoo::TattooEngine(syst, gd);
+ break;
+ default:
+ error("Unknown game");
+ break;
+ }
+ }
+ return gd != 0;
+}
+
+bool SherlockMetaEngine::hasFeature(MetaEngineFeature f) const {
+ return
+ (f == kSupportsListSaves) ||
+ (f == kSupportsLoadingDuringStartup) ||
+ (f == kSupportsDeleteSave) ||
+ (f == kSavesSupportMetaInfo) ||
+ (f == kSavesSupportThumbnail);
+}
+
+bool Sherlock::SherlockEngine::hasFeature(EngineFeature f) const {
+ return
+ (f == kSupportsRTL) ||
+ (f == kSupportsLoadingDuringRuntime) ||
+ (f == kSupportsSavingDuringRuntime);
+}
+
+bool Sherlock::SherlockEngine::isDemo() const {
+ return _gameDescription->desc.flags & ADGF_DEMO;
+}
+
+SaveStateList SherlockMetaEngine::listSaves(const char *target) const {
+ return Sherlock::SaveManager::getSavegameList(target);
+}
+
+int SherlockMetaEngine::getMaximumSaveSlot() const {
+ return MAX_SAVEGAME_SLOTS;
+}
+
+void SherlockMetaEngine::removeSaveState(const char *target, int slot) const {
+ Common::String filename = Sherlock::SaveManager(nullptr, target).generateSaveName(slot);
+ g_system->getSavefileManager()->removeSavefile(filename);
+}
+
+SaveStateDescriptor SherlockMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
+ Common::String filename = Sherlock::SaveManager(nullptr, target).generateSaveName(slot);
+ Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(filename);
+
+ if (f) {
+ Sherlock::SherlockSavegameHeader header;
+ Sherlock::SaveManager::readSavegameHeader(f, header);
+ delete f;
+
+ // Create the return descriptor
+ SaveStateDescriptor desc(slot, header._saveName);
+ desc.setThumbnail(header._thumbnail);
+ desc.setSaveDate(header._year, header._month, header._day);
+ desc.setSaveTime(header._hour, header._minute);
+ desc.setPlayTime(header._totalFrames * GAME_FRAME_TIME);
+
+ return desc;
+ }
+
+ return SaveStateDescriptor();
+}
+
+
+#if PLUGIN_ENABLED_DYNAMIC(SHERLOCK)
+ REGISTER_PLUGIN_DYNAMIC(SHERLOCK, PLUGIN_TYPE_ENGINE, SherlockMetaEngine);
+#else
+ REGISTER_PLUGIN_STATIC(SHERLOCK, PLUGIN_TYPE_ENGINE, SherlockMetaEngine);
+#endif
diff --git a/engines/sherlock/detection_tables.h b/engines/sherlock/detection_tables.h
new file mode 100644
index 0000000000..991fc2055d
--- /dev/null
+++ b/engines/sherlock/detection_tables.h
@@ -0,0 +1,171 @@
+/* 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 Sherlock {
+
+static const SherlockGameDescription gameDescriptions[] = {
+ {
+ // Case of the Serrated Scalpel - English 3.5" Floppy
+ // The HitSquad CD version has the same MD5
+ {
+ "scalpel",
+ 0,
+ AD_ENTRY1s("talk.lib", "ad0c4d6865edf15da4e9204c08815875", 238928),
+ Common::EN_ANY,
+ Common::kPlatformDOS,
+ ADGF_UNSTABLE,
+ GUIO6(GUIO_NOSPEECH, GAMEOPTION_ORIGINAL_SAVES, GAMEOPTION_FADE_STYLE, GAMEOPTION_HELP_STYLE,
+ GAMEOPTION_PORTRAITS_ON, GAMEOPTION_WINDOW_STYLE)
+ },
+ GType_SerratedScalpel,
+ },
+
+ {
+ // Case of the Serrated Scalpel - German CD (from multilingual CD)
+ // Provided by m_kiewitz
+ {
+ "scalpel",
+ 0, {
+ {"talk.lib", 0, "40a5f9f37c0e0d2ad48d8f44d8e393c9", 284278},
+ {"music.lib", 0, "68ae2f7684ecf903bd60a00bb6bae195", 366465},
+ AD_LISTEND},
+ Common::DE_DEU,
+ Common::kPlatformDOS,
+ ADGF_UNSTABLE,
+ GUIO6(GUIO_NOSPEECH, GAMEOPTION_ORIGINAL_SAVES, GAMEOPTION_FADE_STYLE, GAMEOPTION_HELP_STYLE,
+ GAMEOPTION_PORTRAITS_ON, GAMEOPTION_WINDOW_STYLE)
+ },
+ GType_SerratedScalpel,
+ },
+
+ {
+ // Case of the Serrated Scalpel - Spanish CD (from multilingual CD)
+ // Provided by m_kiewitz
+ {
+ "scalpel",
+ 0, {
+ {"talk.lib", 0, "27697804b637a7f3b77234bf16f15dce", 171419},
+ {"music.lib", 0, "68ae2f7684ecf903bd60a00bb6bae195", 366465},
+ AD_LISTEND},
+ Common::ES_ESP,
+ Common::kPlatformDOS,
+ ADGF_UNSTABLE,
+ GUIO6(GUIO_NOSPEECH, GAMEOPTION_ORIGINAL_SAVES, GAMEOPTION_FADE_STYLE, GAMEOPTION_HELP_STYLE,
+ GAMEOPTION_PORTRAITS_ON, GAMEOPTION_WINDOW_STYLE)
+ },
+ GType_SerratedScalpel,
+ },
+
+ {
+ // Case of the Serrated Scalpel - English 3DO
+ {
+ "scalpel",
+ 0,
+ AD_ENTRY1s("talk.lib", "20f74a29f2db6475e85b029ac9fc03bc", 240610),
+ Common::EN_ANY,
+ Common::kPlatform3DO,
+ ADGF_UNSTABLE,
+ GUIO6(GUIO_NOSPEECH, GAMEOPTION_ORIGINAL_SAVES, GAMEOPTION_FADE_STYLE, GAMEOPTION_HELP_STYLE,
+ GAMEOPTION_PORTRAITS_ON, GAMEOPTION_WINDOW_STYLE)
+ },
+ GType_SerratedScalpel,
+ },
+
+ {
+ // Case of the Serrated Scalpel - Interactive English Demo
+ // Provided by Strangerke
+ {
+ "scalpel",
+ "Interactive Demo",
+ AD_ENTRY1s("talk.lib", "dbdc8a20c96900aa7e4d02f3fe8a274c", 121102),
+ Common::EN_ANY,
+ Common::kPlatformDOS,
+ ADGF_UNSTABLE | ADGF_DEMO,
+ GUIO1(GUIO_NOSPEECH)
+ },
+ GType_SerratedScalpel,
+ },
+
+ {
+ // Case of the Serrated Scalpel - Non-Interactive English Demo
+ // Provided by Strangerke
+ {
+ "scalpel",
+ "Non Interactive Demo",
+ AD_ENTRY1s("music.lib", "ec19a09b7fef6fd90b1ab812ce6e9739", 38563),
+ Common::EN_ANY,
+ Common::kPlatformDOS,
+ ADGF_UNSTABLE | ADGF_DEMO,
+ GUIO1(GUIO_NOSPEECH)
+ },
+ GType_SerratedScalpel,
+ },
+
+ {
+ // Case of the Rose Tattoo - French CD
+ // Provided by Strangerke
+ {
+ "rosetattoo",
+ "CD",
+ AD_ENTRY1s("talk.lib", "22e8e6406dd2fbbb238c9898928df42e", 770756),
+ Common::EN_ANY,
+ Common::kPlatformDOS,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
+ GType_RoseTattoo
+ },
+
+ {
+ // Case of the Rose Tattoo - English CD
+ // Provided by dreammaster
+ {
+ "rosetattoo",
+ "CD",
+ AD_ENTRY1s("talk.lib", "9639a756b0993ebd71cb5f4d8b78b2dc", 765134),
+ Common::EN_ANY,
+ Common::kPlatformDOS,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
+ GType_RoseTattoo,
+ },
+
+ {
+ // Case of the Rose Tattoo - German CD
+ // Provided by m_kiewitz
+ {
+ "rosetattoo",
+ "CD",
+ AD_ENTRY1s("talk.lib", "5027aa72f0d263ed3b1c764a6c397911", 873864),
+ Common::DE_DEU,
+ Common::kPlatformDOS,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
+ GType_RoseTattoo,
+ },
+
+ { AD_TABLE_END_MARKER, (GameType)0 }
+};
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp
new file mode 100644
index 0000000000..a8912f6f1e
--- /dev/null
+++ b/engines/sherlock/events.cpp
@@ -0,0 +1,318 @@
+/* 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/scummsys.h"
+#include "common/events.h"
+#include "common/system.h"
+#include "engines/util.h"
+#include "graphics/cursorman.h"
+#include "sherlock/sherlock.h"
+#include "sherlock/events.h"
+
+namespace Sherlock {
+
+enum ButtonFlag { LEFT_BUTTON = 1, RIGHT_BUTTON = 2 };
+
+Events::Events(SherlockEngine *vm): _vm(vm) {
+ _cursorImages = nullptr;
+ _cursorId = INVALID_CURSOR;
+ _frameCounter = 1;
+ _priorFrameTime = 0;
+ _mouseButtons = 0;
+ _pressed = _released = false;
+ _rightPressed = _rightReleased = false;
+ _oldButtons = _oldRightButton = false;
+ _firstPress = false;
+
+ if (_vm->_interactiveFl)
+ loadCursors("rmouse.vgs");
+}
+
+Events::~Events() {
+ delete _cursorImages;
+}
+
+void Events::loadCursors(const Common::String &filename) {
+ hideCursor();
+ delete _cursorImages;
+
+ if (!IS_3DO) {
+ // PC
+ _cursorImages = new ImageFile(filename);
+ } else {
+ // 3DO
+ _cursorImages = new ImageFile3DO(filename, kImageFile3DOType_RoomFormat);
+ }
+ _cursorId = INVALID_CURSOR;
+}
+
+void Events::setCursor(CursorId cursorId) {
+ if (cursorId == _cursorId)
+ return;
+
+ int hotspotX, hotspotY;
+
+ if (cursorId == MAGNIFY) {
+ hotspotX = 8;
+ hotspotY = 8;
+ } else {
+ hotspotX = 0;
+ hotspotY = 0;
+ }
+
+ // Set the cursor data
+ Graphics::Surface &s = (*_cursorImages)[cursorId]._frame;
+
+ setCursor(s, hotspotX, hotspotY);
+
+ _cursorId = cursorId;
+}
+
+void Events::setCursor(const Graphics::Surface &src, int hotspotX, int hotspotY) {
+ _cursorId = INVALID_CURSOR;
+ _hotspotPos = Common::Point(hotspotX, hotspotY);
+
+ if (!IS_3DO) {
+ // PC 8-bit palettized
+ CursorMan.replaceCursor(src.getPixels(), src.w, src.h, hotspotX, hotspotY, 0xff);
+ } else {
+ // 3DO RGB565
+ CursorMan.replaceCursor(src.getPixels(), src.w, src.h, hotspotX, hotspotY, 0x0000, false, &src.format);
+ }
+ showCursor();
+}
+
+void Events::setCursor(CursorId cursorId, const Graphics::Surface &surface) {
+ _cursorId = cursorId;
+
+ int hotspotX, hotspotY;
+ if (cursorId == MAGNIFY) {
+ hotspotX = 8;
+ hotspotY = 8;
+ } else {
+ hotspotX = 0;
+ hotspotY = 0;
+ }
+
+ // Get the standard cursor frame
+ Graphics::Surface &surface2 = (*_cursorImages)[cursorId]._frame;
+
+ // Form a single surface containing both frames
+ int maxWidth = MAX(surface.w, surface2.w);
+ Graphics::Surface s;
+ s.create(maxWidth, surface.h + surface2.h, Graphics::PixelFormat::createFormatCLUT8());
+ s.fillRect(Common::Rect(0, 0, maxWidth, surface.h + surface2.h), TRANSPARENCY);
+
+ s.copyRectToSurface(surface, (maxWidth - surface.w) / 2, 0, Common::Rect(0, 0, surface.w, surface.h));
+ s.copyRectToSurface(surface2, (maxWidth - surface2.w) / 2, surface.h, Common::Rect(0, 0, surface2.w, surface2.h));
+
+ // Adjust hotspot position
+ hotspotX += (maxWidth - surface2.w) / 2;
+ hotspotY += surface.h;
+
+ // Set the cursor
+ setCursor(s, hotspotX, hotspotY);
+}
+
+void Events::animateCursorIfNeeded() {
+ if (_cursorId >= WAIT && _cursorId < (WAIT + 3)) {
+ CursorId newId = (_cursorId == WAIT + 2) ? WAIT : (CursorId)((int)_cursorId + 1);
+ setCursor(newId);
+ }
+}
+
+
+void Events::showCursor() {
+ CursorMan.showMouse(true);
+}
+
+void Events::hideCursor() {
+ CursorMan.showMouse(false);
+}
+
+CursorId Events::getCursor() const {
+ return _cursorId;
+}
+
+bool Events::isCursorVisible() const {
+ return CursorMan.isVisible();
+}
+
+void Events::moveMouse(const Common::Point &pt) {
+ g_system->warpMouse(pt.x, pt.y);
+}
+
+void Events::pollEvents() {
+ checkForNextFrameCounter();
+
+ Common::Event event;
+ while (g_system->getEventManager()->pollEvent(event)) {
+ // Handle keypress
+ switch (event.type) {
+ case Common::EVENT_QUIT:
+ case Common::EVENT_RTL:
+ return;
+
+ case Common::EVENT_KEYDOWN:
+ // Check for debugger
+ if (event.kbd.keycode == Common::KEYCODE_d && (event.kbd.flags & Common::KBD_CTRL)) {
+ // Attach to the debugger
+ _vm->_debugger->attach();
+ _vm->_debugger->onFrame();
+ } else {
+ _pendingKeys.push(event.kbd);
+ }
+ return;
+ case Common::EVENT_KEYUP:
+ return;
+ case Common::EVENT_LBUTTONDOWN:
+ _mouseButtons |= LEFT_BUTTON;
+ return;
+ case Common::EVENT_RBUTTONDOWN:
+ _mouseButtons |= RIGHT_BUTTON;
+ return;
+ case Common::EVENT_LBUTTONUP:
+ _mouseButtons &= ~LEFT_BUTTON;
+ return;
+ case Common::EVENT_RBUTTONUP:
+ _mouseButtons &= ~RIGHT_BUTTON;
+ return;
+ default:
+ break;
+ }
+ }
+}
+
+void Events::pollEventsAndWait() {
+ pollEvents();
+ g_system->delayMillis(10);
+}
+
+void Events::warpMouse(const Common::Point &pt) {
+ g_system->warpMouse(pt.x, pt.y);
+}
+
+bool Events::checkForNextFrameCounter() {
+ // Check for next game frame
+ uint32 milli = g_system->getMillis();
+ if ((milli - _priorFrameTime) >= GAME_FRAME_TIME) {
+ ++_frameCounter;
+ _priorFrameTime = milli;
+
+ // Give time to the debugger
+ _vm->_debugger->onFrame();
+
+ // Display the frame
+ _vm->_screen->update();
+
+ return true;
+ }
+
+ return false;
+}
+
+Common::Point Events::screenMousePos() const {
+ return g_system->getEventManager()->getMousePos();
+}
+
+Common::Point Events::mousePos() const {
+ return screenMousePos() + _vm->_screen->_currentScroll;
+}
+
+Common::KeyState Events::getKey() {
+ return _pendingKeys.pop();
+}
+
+void Events::clearEvents() {
+ _pendingKeys.clear();
+ _mouseButtons = 0;
+ _pressed = _released = false;
+ _rightPressed = _rightReleased = false;
+ _oldButtons = _oldRightButton = false;
+ _firstPress = false;
+}
+
+void Events::clearKeyboard() {
+ _pendingKeys.clear();
+}
+
+void Events::wait(int numFrames) {
+ uint32 totalMilli = numFrames * 1000 / GAME_FRAME_RATE;
+ delay(totalMilli);
+}
+
+bool Events::delay(uint32 time, bool interruptable) {
+ // Different handling for really short versus extended times
+ if (time < 10) {
+ // For really short periods, simply delay by the desired amount
+ pollEvents();
+ g_system->delayMillis(time);
+ bool result = !(interruptable && (kbHit() || _pressed || _vm->shouldQuit()));
+
+ clearEvents();
+ return result;
+ } else {
+ // For long periods go into a loop where we delay by 10ms at a time and then
+ // check for events. This ensures for longer delays that responsiveness is
+ // maintained
+ uint32 delayEnd = g_system->getMillis() + time;
+
+ while (!_vm->shouldQuit() && g_system->getMillis() < delayEnd) {
+ pollEventsAndWait();
+
+ if (interruptable && (kbHit() || _pressed)) {
+ clearEvents();
+ return false;
+ }
+ }
+
+ return !_vm->shouldQuit();
+ }
+}
+
+void Events::setButtonState() {
+ _firstPress = ((_mouseButtons & 1) && !_pressed) || ((_mouseButtons & 2) && !_rightPressed);
+
+ _released = _rightReleased = false;
+ if (_mouseButtons & LEFT_BUTTON)
+ _pressed = _oldButtons = true;
+
+ if ((_mouseButtons & LEFT_BUTTON) == 0 && _oldButtons) {
+ _pressed = _oldButtons = false;
+ _released = true;
+ }
+
+ if (_mouseButtons & RIGHT_BUTTON)
+ _rightPressed = _oldRightButton = true;
+
+ if ((_mouseButtons & RIGHT_BUTTON) == 0 && _oldRightButton) {
+ _rightPressed = _oldRightButton = false;
+ _rightReleased = true;
+ }
+}
+
+bool Events::checkInput() {
+ setButtonState();
+ return kbHit() || _pressed || _released || _rightPressed || _rightReleased;
+}
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/events.h b/engines/sherlock/events.h
new file mode 100644
index 0000000000..93a5e54f81
--- /dev/null
+++ b/engines/sherlock/events.h
@@ -0,0 +1,194 @@
+/* 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 SHERLOCK_EVENTS_H
+#define SHERLOCK_EVENTS_H
+
+#include "common/scummsys.h"
+#include "common/events.h"
+#include "common/stack.h"
+#include "sherlock/image_file.h"
+
+namespace Sherlock {
+
+#define GAME_FRAME_RATE 60
+#define GAME_FRAME_TIME (1000 / GAME_FRAME_RATE)
+
+enum CursorId { ARROW = 0, MAGNIFY = 1, WAIT = 2, EXIT_ZONES_START = 5, INVALID_CURSOR = -1 };
+
+class SherlockEngine;
+
+class Events {
+private:
+ SherlockEngine *_vm;
+ uint32 _frameCounter;
+ uint32 _priorFrameTime;
+ ImageFile *_cursorImages;
+ int _mouseButtons;
+
+ /**
+ * Check whether it's time to display the next screen frame
+ */
+ bool checkForNextFrameCounter();
+public:
+ CursorId _cursorId;
+ bool _pressed;
+ bool _released;
+ bool _rightPressed;
+ bool _rightReleased;
+ bool _oldButtons;
+ bool _oldRightButton;
+ bool _firstPress;
+ Common::Stack<Common::KeyState> _pendingKeys;
+ Common::Point _hotspotPos;
+public:
+ Events(SherlockEngine *vm);
+ ~Events();
+
+ /**
+ * Load a set of cursors from the specified file
+ */
+ void loadCursors(const Common::String &filename);
+
+ /**
+ * Set the cursor to show
+ */
+ void setCursor(CursorId cursorId);
+
+ /**
+ * Set the cursor to show from a passed frame
+ */
+ void setCursor(const Graphics::Surface &src, int hotspotX = 0, int hotspotY = 0);
+
+ /**
+ * Set both a standard cursor as well as an inventory item above it
+ */
+ void setCursor(CursorId cursorId, const Graphics::Surface &surface);
+
+ /**
+ * Animates the mouse cursor if the Wait cursor is showing
+ */
+ void animateCursorIfNeeded();
+
+ /**
+ * Show the mouse cursor
+ */
+ void showCursor();
+
+ /**
+ * Hide the mouse cursor
+ */
+ void hideCursor();
+
+ /**
+ * Returns the cursor
+ */
+ CursorId getCursor() const;
+
+ /**
+ * Returns true if the mouse cursor is visible
+ */
+ bool isCursorVisible() const;
+
+ /**
+ * Move the mouse
+ */
+ void moveMouse(const Common::Point &pt);
+
+ /**
+ * Check for any pending events
+ */
+ void pollEvents();
+
+ /**
+ * Poll for events and introduce a small delay, to allow the system to
+ * yield to other running programs
+ */
+ void pollEventsAndWait();
+
+ /**
+ * Move the mouse cursor
+ */
+ void warpMouse(const Common::Point &pt);
+
+ /**
+ * Get the current mouse position
+ */
+ Common::Point screenMousePos() const;
+
+ /**
+ * Get the current mouse position within the scene, adjusted by the scroll position
+ */
+ Common::Point mousePos() const;
+
+ /**
+ * Return the current game frame number
+ */
+ uint32 getFrameCounter() const { return _frameCounter; }
+
+ /**
+ * Returns true if there's a pending keyboard key
+ */
+ bool kbHit() const { return !_pendingKeys.empty(); }
+
+ /**
+ * Get a pending keypress
+ */
+ Common::KeyState getKey();
+
+ /**
+ * Clear any current keypress or mouse click
+ */
+ void clearEvents();
+
+ /**
+ * Clear any pending keyboard inputs
+ */
+ void clearKeyboard();
+
+ /**
+ * Delay for a given number of game frames, where each frame is 1/60th of a second
+ */
+ void wait(int numFrames);
+
+ /**
+ * Does a delay of the specified number of milliseconds
+ */
+ bool delay(uint32 time, bool interruptable = false);
+
+ /**
+ * Sets the pressed and released button flags on the raw button state previously set in pollEvents calls.
+ * @remarks The events manager has separate variables for the raw immediate and old button state
+ * versus the current buttons states for the frame. This method is expected to be called only once
+ * per game frame
+ */
+ void setButtonState();
+
+ /**
+ * Checks to see to see if a key or a mouse button is pressed.
+ */
+ bool checkInput();
+};
+
+} // End of namespace Sherlock
+
+#endif /* SHERLOCK_EVENTS_H */
diff --git a/engines/sherlock/fixed_text.cpp b/engines/sherlock/fixed_text.cpp
new file mode 100644
index 0000000000..cbee944120
--- /dev/null
+++ b/engines/sherlock/fixed_text.cpp
@@ -0,0 +1,38 @@
+/* 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 "sherlock/sherlock.h"
+#include "sherlock/fixed_text.h"
+#include "sherlock/scalpel/scalpel_fixed_text.h"
+#include "sherlock/tattoo/tattoo_fixed_text.h"
+
+namespace Sherlock {
+
+FixedText *FixedText::init(SherlockEngine *vm) {
+ if (vm->getGameID() == GType_SerratedScalpel)
+ return new Scalpel::ScalpelFixedText(vm);
+ else
+ return new Tattoo::TattooFixedText(vm);
+}
+
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/fixed_text.h b/engines/sherlock/fixed_text.h
new file mode 100644
index 0000000000..40444f4052
--- /dev/null
+++ b/engines/sherlock/fixed_text.h
@@ -0,0 +1,66 @@
+/* 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 SHERLOCK_FIXED_TEXT_H
+#define SHERLOCK_FIXED_TEXT_H
+
+#include "common/scummsys.h"
+#include "common/language.h"
+
+namespace Sherlock {
+
+#define FIXED(MSG) _vm->_fixedText->getText(kFixedText_##MSG)
+
+enum FixedTextActionId {
+ kFixedTextAction_Invalid = -1,
+ kFixedTextAction_Open = 0,
+ kFixedTextAction_Close,
+ kFixedTextAction_Move,
+ kFixedTextAction_Pick,
+ kFixedTextAction_Use
+};
+
+class SherlockEngine;
+
+class FixedText {
+protected:
+ SherlockEngine *_vm;
+
+ FixedText(SherlockEngine *vm) : _vm(vm) {}
+public:
+ static FixedText *init(SherlockEngine *vm);
+ virtual ~FixedText() {}
+
+ /**
+ * Gets text
+ */
+ virtual const char *getText(int fixedTextId) = 0;
+
+ /**
+ * Get action message
+ */
+ virtual const Common::String getActionMessage(FixedTextActionId actionId, int messageIndex) = 0;
+};
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/fonts.cpp b/engines/sherlock/fonts.cpp
new file mode 100644
index 0000000000..440e31915c
--- /dev/null
+++ b/engines/sherlock/fonts.cpp
@@ -0,0 +1,204 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/system.h"
+#include "common/platform.h"
+#include "sherlock/fonts.h"
+#include "sherlock/image_file.h"
+#include "sherlock/surface.h"
+#include "sherlock/sherlock.h"
+
+namespace Sherlock {
+
+SherlockEngine *Fonts::_vm;
+ImageFile *Fonts::_font;
+int Fonts::_fontNumber;
+int Fonts::_fontHeight;
+int Fonts::_widestChar;
+uint16 Fonts::_charCount;
+byte Fonts::_yOffsets[255];
+
+void Fonts::setVm(SherlockEngine *vm) {
+ _vm = vm;
+ _font = nullptr;
+ _charCount = 0;
+}
+
+void Fonts::free() {
+ delete _font;
+}
+
+void Fonts::setFont(int fontNum) {
+ _fontNumber = fontNum;
+
+ // Discard previous font
+ delete _font;
+
+ Common::String fontFilename;
+
+ if (_vm->getPlatform() != Common::kPlatform3DO) {
+ // PC
+ // use FONT[number].VGS, which is a regular sherlock graphic file
+ fontFilename = Common::String::format("FONT%d.VGS", fontNum + 1);
+
+ // load font data
+ _font = new ImageFile(fontFilename);
+ } else {
+ // 3DO
+ switch (fontNum) {
+ case 0:
+ case 1:
+ fontFilename = "helvetica14.font";
+ break;
+ case 2:
+ fontFilename = "darts.font";
+ break;
+ default:
+ error("setFont(): unsupported 3DO font number");
+ }
+
+ // load font data
+ _font = new ImageFile3DO(fontFilename, kImageFile3DOType_Font);
+ }
+
+ _charCount = _font->size();
+
+ // Iterate through the frames to find the widest and tallest font characters
+ _fontHeight = _widestChar = 0;
+ for (uint idx = 0; idx < _charCount; ++idx) {
+ _fontHeight = MAX((uint16)_fontHeight, (*_font)[idx]._frame.h);
+ _widestChar = MAX((uint16)_widestChar, (*_font)[idx]._frame.w);
+ }
+
+ // Initialize the Y offset table for the extended character set
+ for (int idx = 0; idx < 255; ++idx) {
+ _yOffsets[idx] = 0;
+
+ if (IS_ROSE_TATTOO) {
+ if ((idx >= 129 && idx < 135) || (idx >= 136 && idx < 143) || (idx >= 147 && idx < 155) ||
+ (idx >= 156 && idx < 165))
+ _yOffsets[idx] = 1;
+ else if ((idx >= 143 && idx < 146) || idx == 165)
+ _yOffsets[idx] = 2;
+ }
+ }
+}
+
+inline byte Fonts::translateChar(byte c) {
+ switch (c) {
+ case ' ':
+ return 0; // translate to first actual character
+ case 225:
+ // This was done in the German interpreter
+ // happens when talking to the kid in the 2nd room
+ return 135; // special handling for 0xE1
+ default:
+ if (c >= 0x80) { // German SH1 version did this
+ c--;
+ }
+ // Spanish SH1 did this (reverse engineered code)
+ //if ((c >= 0xA0) && (c <= 0xAD) || (c == 0x82)) {
+ // c--;
+ //}
+ assert(c > 32); // anything above space is allowed
+ return c - 33;
+ }
+}
+
+void Fonts::writeString(Surface *surface, const Common::String &str,
+ const Common::Point &pt, int overrideColor) {
+ Common::Point charPos = pt;
+
+ if (!_font)
+ return;
+
+ for (const char *curCharPtr = str.c_str(); *curCharPtr; ++curCharPtr) {
+ byte curChar = *curCharPtr;
+
+ if (curChar == ' ') {
+ charPos.x += 5; // hardcoded space
+ continue;
+ }
+ curChar = translateChar(curChar);
+
+ assert(curChar < _charCount);
+ ImageFrame &frame = (*_font)[curChar];
+ surface->transBlitFrom(frame, Common::Point(charPos.x, charPos.y + _yOffsets[curChar]), false, overrideColor);
+ charPos.x += frame._frame.w + 1;
+ }
+}
+
+int Fonts::stringWidth(const Common::String &str) {
+ int width = 0;
+
+ if (!_font)
+ return 0;
+
+ for (const char *c = str.c_str(); *c; ++c)
+ width += charWidth(*c);
+
+ return width;
+}
+
+int Fonts::stringHeight(const Common::String &str) {
+ int height = 0;
+
+ if (!_font)
+ return 0;
+
+ for (const char *c = str.c_str(); *c; ++c)
+ height = MAX(height, charHeight(*c));
+
+ return height;
+}
+
+int Fonts::charWidth(unsigned char c) {
+ byte curChar;
+
+ if (!_font)
+ return 0;
+
+ if (c == ' ') {
+ return 5; // hardcoded space
+ }
+ curChar = translateChar(c);
+
+ if (curChar < _charCount)
+ return (*_font)[curChar]._frame.w + 1;
+ return 0;
+}
+
+int Fonts::charHeight(unsigned char c) {
+ byte curChar;
+
+ if (!_font)
+ return 0;
+
+ // Space is supposed to be handled like the first actual character (which is decimal 33)
+ curChar = translateChar(c);
+
+ assert(curChar < _charCount);
+ const ImageFrame &img = (*_font)[curChar];
+ return img._height + img._offset.y + 1;
+}
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/fonts.h b/engines/sherlock/fonts.h
new file mode 100644
index 0000000000..a527cc73c0
--- /dev/null
+++ b/engines/sherlock/fonts.h
@@ -0,0 +1,105 @@
+/* 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 SHERLOCK_FONTS_H
+#define SHERLOCK_FONTS_H
+
+#include "common/rect.h"
+#include "common/platform.h"
+#include "graphics/surface.h"
+
+namespace Sherlock {
+
+class SherlockEngine;
+class ImageFile;
+class Surface;
+
+class Fonts {
+private:
+ static ImageFile *_font;
+ static byte _yOffsets[255];
+protected:
+ static SherlockEngine *_vm;
+ static int _fontNumber;
+ static int _fontHeight;
+ static int _widestChar;
+ static uint16 _charCount;
+
+ static void writeString(Surface *surface, const Common::String &str,
+ const Common::Point &pt, int overrideColor = 0);
+
+ static inline byte translateChar(byte c);
+public:
+ /**
+ * Initialise the font manager
+ */
+ static void setVm(SherlockEngine *vm);
+
+ /**
+ * Frees the font manager
+ */
+ static void free();
+
+ /**
+ * Set the font to use for writing text on the screen
+ */
+ void setFont(int fontNum);
+
+ /**
+ * Returns the width of a string in pixels
+ */
+ int stringWidth(const Common::String &str);
+
+ /**
+ * Returns the height of a string in pixels (i.e. the tallest displayed character)
+ */
+ int stringHeight(const Common::String &str);
+
+ /**
+ * Returns the width of a character in pixels
+ */
+ int charWidth(unsigned char c);
+
+ /**
+ * Returns the width of a character in pixels
+ */
+ int charHeight(unsigned char c);
+
+ /**
+ * Return the font height
+ */
+ int fontHeight() const { return _fontHeight; }
+
+ /**
+ * Return the width of the widest character in the font
+ */
+ int widestChar() const { return _widestChar; }
+
+ /**
+ * Return the currently active font number
+ */
+ int fontNumber() const { return _fontNumber; }
+};
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/image_file.cpp b/engines/sherlock/image_file.cpp
new file mode 100644
index 0000000000..81087dae8b
--- /dev/null
+++ b/engines/sherlock/image_file.cpp
@@ -0,0 +1,1085 @@
+/* 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 "sherlock/image_file.h"
+#include "sherlock/screen.h"
+#include "sherlock/sherlock.h"
+#include "common/debug.h"
+#include "common/memstream.h"
+
+namespace Sherlock {
+
+SherlockEngine *ImageFile::_vm;
+
+void ImageFile::setVm(SherlockEngine *vm) {
+ _vm = vm;
+}
+
+ImageFile::ImageFile() {
+}
+
+ImageFile::ImageFile(const Common::String &name, bool skipPal, bool animImages) {
+ Common::SeekableReadStream *stream = _vm->_res->load(name);
+
+ Common::fill(&_palette[0], &_palette[PALETTE_SIZE], 0);
+ load(*stream, skipPal, animImages);
+
+ delete stream;
+}
+
+ImageFile::ImageFile(Common::SeekableReadStream &stream, bool skipPal) {
+ Common::fill(&_palette[0], &_palette[PALETTE_SIZE], 0);
+ load(stream, skipPal, false);
+}
+
+ImageFile::~ImageFile() {
+ for (uint idx = 0; idx < size(); ++idx)
+ (*this)[idx]._frame.free();
+}
+
+void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette, bool animImages) {
+ loadPalette(stream);
+
+ int streamSize = stream.size();
+ while (stream.pos() < streamSize) {
+ ImageFrame frame;
+ frame._width = stream.readUint16LE() + 1;
+ frame._height = stream.readUint16LE() + 1;
+ frame._paletteBase = stream.readByte();
+
+ if (animImages) {
+ // Animation cutscene image files use a 16-bit x offset
+ frame._offset.x = stream.readUint16LE();
+ frame._rleEncoded = (frame._offset.x & 0xff) == 1;
+ frame._offset.y = stream.readByte();
+ } else {
+ // Standard image files have a separate byte for the RLE flag, and an 8-bit X offset
+ frame._rleEncoded = stream.readByte() == 1;
+ frame._offset.x = stream.readByte();
+ frame._offset.y = stream.readByte();
+ }
+
+ frame._rleEncoded = !skipPalette && frame._rleEncoded;
+
+ if (frame._paletteBase) {
+ // Nibble packed frame data
+ frame._size = (frame._width * frame._height) / 2;
+ } else if (frame._rleEncoded) {
+ // This size includes the header size, which we subtract
+ frame._size = stream.readUint16LE() - 11;
+ frame._rleMarker = stream.readByte();
+ } else {
+ // Uncompressed data
+ frame._size = frame._width * frame._height;
+ }
+
+ // Load data for frame and decompress it
+ byte *data = new byte[frame._size + 4];
+ stream.read(data, frame._size);
+ Common::fill(data + frame._size, data + frame._size + 4, 0);
+ frame.decompressFrame(data, IS_ROSE_TATTOO);
+ delete[] data;
+
+ push_back(frame);
+ }
+}
+
+void ImageFile::loadPalette(Common::SeekableReadStream &stream) {
+ // Check for palette
+ uint16 width = stream.readUint16LE() + 1;
+ uint16 height = stream.readUint16LE() + 1;
+ byte paletteBase = stream.readByte();
+ byte rleEncoded = stream.readByte();
+ byte offsetX = stream.readByte();
+ byte offsetY = stream.readByte();
+ uint32 palSignature = 0;
+
+ if ((width == 390) && (height == 2) && (!paletteBase) && (!rleEncoded) && (!offsetX) && (!offsetY)) {
+ // We check for these specific values
+ // We can't do "width * height", because at least the first German+Spanish menu bar is 60 x 13
+ // which is 780, which is the size of the palette. We obviously don't want to detect it as palette.
+
+ // As another security measure, we also check for the signature text
+ palSignature = stream.readUint32BE();
+ if (palSignature != MKTAG('V', 'G', 'A', ' ')) {
+ // signature mismatch, rewind
+ stream.seek(-12, SEEK_CUR);
+ return;
+ }
+ // Found palette, so read it in
+ stream.seek(8, SEEK_CUR); // Skip over the rest of the signature text "VGA palette"
+ for (int idx = 0; idx < PALETTE_SIZE; ++idx)
+ _palette[idx] = VGA_COLOR_TRANS(stream.readByte());
+ } else {
+ // Not a palette, so rewind to start of frame data for normal frame processing
+ stream.seek(-8, SEEK_CUR);
+ }
+}
+
+void ImageFrame::decompressFrame(const byte *src, bool isRoseTattoo) {
+ _frame.create(_width, _height, Graphics::PixelFormat::createFormatCLUT8());
+ byte *dest = (byte *)_frame.getPixels();
+ Common::fill(dest, dest + _width * _height, 0xff);
+
+ if (_paletteBase) {
+ // Nibble-packed
+ for (uint idx = 0; idx < _size; ++idx, ++src) {
+ *dest++ = *src & 0xF;
+ *dest++ = (*src >> 4);
+ }
+ } else if (_rleEncoded && isRoseTattoo) {
+ // Rose Tattoo run length encoding doesn't use the RLE marker byte
+ for (int yp = 0; yp < _height; ++yp) {
+ int xSize = _width;
+ while (xSize > 0) {
+ // Skip a given number of pixels
+ byte skip = *src++;
+ dest += skip;
+ xSize -= skip;
+ if (!xSize)
+ break;
+
+ // Get a run length, and copy the following number of pixels
+ int rleCount = *src++;
+ xSize -= rleCount;
+ while (rleCount-- > 0)
+ *dest++ = *src++;
+ }
+ assert(xSize == 0);
+ }
+ } else if (_rleEncoded) {
+ // RLE encoded
+ int frameSize = _width * _height;
+ while (frameSize > 0) {
+ if (*src == _rleMarker) {
+ byte rleColor = src[1];
+ byte rleCount = src[2];
+ src += 3;
+ frameSize -= rleCount;
+ while (rleCount--)
+ *dest++ = rleColor;
+ } else {
+ *dest++ = *src++;
+ --frameSize;
+ }
+ }
+ assert(frameSize == 0);
+ } else {
+ // Uncompressed frame
+ Common::copy(src, src + _width * _height, dest);
+ }
+}
+
+/*----------------------------------------------------------------*/
+
+int ImageFrame::sDrawXSize(int scaleVal) const {
+ int width = _width;
+ int scale = scaleVal == 0 ? 1 : scaleVal;
+
+ if (scaleVal >= SCALE_THRESHOLD)
+ --width;
+
+ int result = width * SCALE_THRESHOLD / scale;
+ if (scaleVal >= SCALE_THRESHOLD)
+ ++result;
+
+ return result;
+}
+
+int ImageFrame::sDrawYSize(int scaleVal) const {
+ int height = _height;
+ int scale = scaleVal == 0 ? 1 : scaleVal;
+
+ if (scaleVal >= SCALE_THRESHOLD)
+ --height;
+
+ int result = height * SCALE_THRESHOLD / scale;
+ if (scaleVal >= SCALE_THRESHOLD)
+ ++result;
+
+ return result;
+}
+
+int ImageFrame::sDrawXOffset(int scaleVal) const {
+ int width = _offset.x;
+ int scale = scaleVal == 0 ? 1 : scaleVal;
+
+ if (scaleVal >= SCALE_THRESHOLD)
+ --width;
+
+ int result = width * SCALE_THRESHOLD / scale;
+ if (scaleVal >= SCALE_THRESHOLD)
+ ++result;
+
+ return result;
+}
+
+int ImageFrame::sDrawYOffset(int scaleVal) const {
+ int height = _offset.y;
+ int scale = scaleVal == 0 ? 1 : scaleVal;
+
+ if (scaleVal >= SCALE_THRESHOLD)
+ --height;
+
+ int result = height * SCALE_THRESHOLD / scale;
+ if (scaleVal >= SCALE_THRESHOLD)
+ ++result;
+
+ return result;
+}
+
+// *******************************************************
+
+/*----------------------------------------------------------------*/
+
+SherlockEngine *ImageFile3DO::_vm;
+
+void ImageFile3DO::setVm(SherlockEngine *vm) {
+ _vm = vm;
+}
+
+ImageFile3DO::ImageFile3DO(const Common::String &name, ImageFile3DOType imageFile3DOType) {
+#if 0
+ Common::File *dataStream = new Common::File();
+
+ if (!dataStream->open(name)) {
+ error("unable to open %s\n", name.c_str());
+ }
+#endif
+ Common::SeekableReadStream *dataStream = _vm->_res->load(name);
+
+ switch(imageFile3DOType) {
+ case kImageFile3DOType_Animation:
+ loadAnimationFile(*dataStream);
+ break;
+ case kImageFile3DOType_Cel:
+ case kImageFile3DOType_CelAnimation:
+ load3DOCelFile(*dataStream);
+ break;
+ case kImageFile3DOType_RoomFormat:
+ load3DOCelRoomData(*dataStream);
+ break;
+ case kImageFile3DOType_Font:
+ loadFont(*dataStream);
+ break;
+ default:
+ error("unknown Imagefile-3DO-Type");
+ break;
+ }
+
+ delete dataStream;
+}
+
+ImageFile3DO::ImageFile3DO(Common::SeekableReadStream &stream, bool isRoomData) {
+ if (!isRoomData) {
+ load(stream, isRoomData);
+ } else {
+ load3DOCelRoomData(stream);
+ }
+}
+
+ImageFile3DO::~ImageFile3DO() {
+ // already done in ImageFile destructor
+ //for (uint idx = 0; idx < size(); ++idx)
+ // (*this)[idx]._frame.free();
+}
+
+void ImageFile3DO::load(Common::SeekableReadStream &stream, bool isRoomData) {
+ uint32 headerId = 0;
+
+ if (isRoomData) {
+ load3DOCelRoomData(stream);
+ return;
+ }
+
+ headerId = stream.readUint32BE();
+ assert(!stream.eos());
+
+ // Seek back to the start
+ stream.seek(-4, SEEK_CUR);
+
+ // Identify type of file
+ switch (headerId) {
+ case MKTAG('C', 'C', 'B', ' '):
+ case MKTAG('A', 'N', 'I', 'M'):
+ case MKTAG('O', 'F', 'S', 'T'): // 3DOSplash.cel
+ // 3DO .cel (title1a.cel, etc.) or animation file (walk.anim)
+ load3DOCelFile(stream);
+ break;
+
+ default:
+ // Sherlock animation file (.3da files)
+ loadAnimationFile(stream);
+ break;
+ }
+}
+
+// 3DO uses RGB555, we use RGB565 internally so that more platforms are able to run us
+inline uint16 ImageFile3DO::convertPixel(uint16 pixel3DO) {
+ byte red = (pixel3DO >> 10) & 0x1F;
+ byte green = (pixel3DO >> 5) & 0x1F;
+ byte blue = pixel3DO & 0x1F;
+
+ return ((red << 11) | (green << 6) | (blue));
+}
+
+void ImageFile3DO::loadAnimationFile(Common::SeekableReadStream &stream) {
+ uint32 streamLeft = stream.size() - stream.pos();
+ uint32 celDataSize = 0;
+
+ while (streamLeft > 0) {
+ ImageFrame frame;
+
+ // We expect a basic header of 8 bytes
+ if (streamLeft < 8)
+ error("load3DOAnimationFile: expected animation header, not enough bytes");
+
+ celDataSize = stream.readUint16BE();
+
+ frame._width = stream.readUint16BE() + 1; // 2 bytes BE width
+ frame._height = stream.readByte() + 1; // 1 byte BE height
+ frame._paletteBase = 0;
+
+ frame._rleEncoded = true; // always compressed
+ if (frame._width & 0x8000) {
+ frame._width &= 0x7FFF;
+ celDataSize += 0x10000;
+ }
+
+ frame._offset.x = stream.readUint16BE();
+ frame._offset.y = stream.readByte();
+ frame._size = 0;
+ // Got header
+ streamLeft -= 8;
+
+ // cel data follows
+ if (streamLeft < celDataSize)
+ error("load3DOAnimationFile: expected cel data, not enough bytes");
+
+ //
+ // Load data for frame and decompress it
+ byte *data = new byte[celDataSize];
+ stream.read(data, celDataSize);
+ streamLeft -= celDataSize;
+
+ // always 16 bits per pixel (RGB555)
+ decompress3DOCelFrame(frame, data, celDataSize, 16, NULL);
+
+ delete[] data;
+
+ push_back(frame);
+ }
+}
+
+static byte imagefile3DO_cel_bitsPerPixelLookupTable[8] = {
+ 0, 1, 2, 4, 6, 8, 16, 0
+};
+
+// Reads a 3DO .cel/.anim file
+void ImageFile3DO::load3DOCelFile(Common::SeekableReadStream &stream) {
+ int32 streamSize = stream.size();
+ int32 chunkStartPos = 0;
+ uint32 chunkTag = 0;
+ uint32 chunkSize = 0;
+ byte *chunkDataPtr = NULL;
+
+ // ANIM chunk (animation header for animation files)
+ bool animFound = false;
+ uint32 animVersion = 0;
+ uint32 animType = 0;
+ uint32 animFrameCount = 1; // we expect 1 frame without an ANIM header
+ // CCB chunk (cel control block)
+ bool ccbFound = false;
+ uint32 ccbVersion = 0;
+ uint32 ccbFlags = 0;
+ bool ccbFlags_compressed = false;
+ uint16 ccbPPMP0 = 0;
+ uint16 ccbPPMP1 = 0;
+ uint32 ccbPRE0 = 0;
+ uint16 ccbPRE0_height = 0;
+ byte ccbPRE0_bitsPerPixel = 0;
+ uint32 ccbPRE1 = 0;
+ uint16 ccbPRE1_width = 0;
+ uint32 ccbWidth = 0;
+ uint32 ccbHeight = 0;
+ // pixel lookup table
+ bool plutFound = false;
+ uint32 plutCount = 0;
+ ImageFile3DOPixelLookupTable plutRGBlookupTable;
+
+ memset(&plutRGBlookupTable, 0, sizeof(plutRGBlookupTable));
+
+ while (!stream.err() && (stream.pos() < streamSize)) {
+ chunkStartPos = stream.pos();
+ chunkTag = stream.readUint32BE();
+ chunkSize = stream.readUint32BE();
+
+ if (stream.eos() || stream.err())
+ break;
+
+ if (chunkSize < 8)
+ error("load3DOCelFile: Invalid chunk size");
+
+ uint32 dataSize = chunkSize - 8;
+
+ switch (chunkTag) {
+ case MKTAG('A', 'N', 'I', 'M'):
+ // animation header
+ assert(dataSize >= 24);
+
+ if (animFound)
+ error("load3DOCelFile: multiple ANIM chunks not supported");
+
+ animFound = true;
+ animVersion = stream.readUint32BE();
+ animType = stream.readUint32BE();
+ animFrameCount = stream.readUint32BE();
+ // UINT32 - framerate (0x2000 in walk.anim???)
+ // UINT32 - starting frame (0 for walk.anim)
+ // UINT32 - number of loops (0 for walk.anim)
+
+ if (animVersion != 0)
+ error("load3DOCelFile: Unsupported animation file version");
+ if (animType != 1)
+ error("load3DOCelFile: Only single CCB animation files are supported");
+ break;
+
+ case MKTAG('C', 'C', 'B', ' '):
+ // CEL control block
+ assert(dataSize >= 72);
+
+ if (ccbFound)
+ error("load3DOCelFile: multiple CCB chunks not supported");
+
+ ccbFound = true;
+ ccbVersion = stream.readUint32BE();
+ ccbFlags = stream.readUint32BE();
+ stream.skip(3 * 4); // skip over 3 pointer fields, which are used in memory only by 3DO hardware
+ stream.skip(8 * 4); // skip over 8 offset fields
+ ccbPPMP0 = stream.readUint16BE();
+ ccbPPMP1 = stream.readUint16BE();
+ ccbPRE0 = stream.readUint32BE();
+ ccbPRE1 = stream.readUint32BE();
+ ccbWidth = stream.readUint32BE();
+ ccbHeight = stream.readUint32BE();
+
+ if (ccbVersion != 0)
+ error("load3DOCelFile: Unsupported CCB version");
+
+ if (ccbFlags & 0x200) // bit 9
+ ccbFlags_compressed = true;
+
+ // bit 5 of ccbFlags defines how RGB-black (0, 0, 0) will get treated
+ // = false -> RGB-black is treated as transparent
+ // = true -> RGB-black is treated as actual black
+ // atm we are always treating it as transparent
+ // it seems this bit is not set for any data of Sherlock Holmes
+
+ // PRE0 first 3 bits define how many bits per encoded pixel are used
+ ccbPRE0_bitsPerPixel = imagefile3DO_cel_bitsPerPixelLookupTable[ccbPRE0 & 0x07];
+ if (!ccbPRE0_bitsPerPixel)
+ error("load3DOCelFile: Invalid CCB PRE0 bits per pixel");
+
+ ccbPRE0_height = ((ccbPRE0 >> 6) & 0x03FF) + 1;
+ ccbPRE1_width = (ccbPRE1 & 0x03FF) + 1;
+ assert(ccbPRE0_height == ccbHeight);
+ assert(ccbPRE1_width == ccbWidth);
+ break;
+
+ case MKTAG('P', 'L', 'U', 'T'):
+ // pixel lookup table
+ // optional, not required for at least 16-bit pixel data
+ assert(dataSize >= 6);
+
+ if (!ccbFound)
+ error("load3DOCelFile: PLUT chunk found without CCB chunk");
+ if (plutFound)
+ error("load3DOCelFile: multiple PLUT chunks currently not supported");
+
+ plutFound = true;
+ plutCount = stream.readUint32BE();
+ // table follows, each entry is 16bit RGB555
+ assert(dataSize >= 4 + (plutCount * 2)); // security check
+ assert(plutCount <= 256); // security check
+
+ assert(plutCount <= 32); // PLUT should never contain more than 32 entries
+
+ for (uint32 plutColorNr = 0; plutColorNr < plutCount; plutColorNr++) {
+ plutRGBlookupTable.pixelColor[plutColorNr] = stream.readUint16BE();
+ }
+
+ if (ccbPRE0_bitsPerPixel == 8) {
+ // In case we are getting 8-bits per pixel, we calculate the shades accordingly
+ // I'm not 100% sure if the calculation is correct. It's difficult to find information
+ // on this topic.
+ // The map uses this type of cel
+ assert(plutCount == 32); // And we expect 32 entries inside PLUT chunk
+
+ uint16 plutColorRGB = 0;
+ for (uint32 plutColorNr = 0; plutColorNr < plutCount; plutColorNr++) {
+ plutColorRGB = plutRGBlookupTable.pixelColor[plutColorNr];
+
+ // Extract RGB values
+ byte plutColorRed = (plutColorRGB >> 10) & 0x1F;
+ byte plutColorGreen = (plutColorRGB >> 5) & 0x1F;
+ byte plutColorBlue = plutColorRGB & 0x1F;
+
+ byte shadeMultiplier = 2;
+ for (uint32 plutShadeNr = 1; plutShadeNr < 8; plutShadeNr++) {
+ uint16 shadedColorRGB;
+ byte shadedColorRed = (plutColorRed * shadeMultiplier) >> 3;
+ byte shadedColorGreen = (plutColorGreen * shadeMultiplier) >> 3;
+ byte shadedColorBlue = (plutColorBlue * shadeMultiplier) >> 3;
+
+ shadedColorRed = CLIP<byte>(shadedColorRed, 0, 0x1F);
+ shadedColorGreen = CLIP<byte>(shadedColorGreen, 0, 0x1F);
+ shadedColorBlue = CLIP<byte>(shadedColorBlue, 0, 0x1F);
+ shadedColorRGB = (shadedColorRed << 10) | (shadedColorGreen << 5) | shadedColorBlue;
+
+ plutRGBlookupTable.pixelColor[plutColorNr + (plutShadeNr << 5)] = shadedColorRGB;
+ shadeMultiplier++;
+ }
+ }
+ }
+ break;
+
+ case MKTAG('X', 'T', 'R', 'A'):
+ // Unknown contents, occurs right before PDAT
+ break;
+
+ case MKTAG('P', 'D', 'A', 'T'): {
+ // pixel data for one frame
+ // may be compressed or uncompressed pixels
+
+ if (ccbPRE0_bitsPerPixel != 16) {
+ // We require a pixel lookup table in case bits-per-pixel is lower than 16
+ if (!plutFound)
+ error("load3DOCelFile: bits per pixel < 16, but no pixel lookup table was found");
+ } else {
+ // But we don't like it in case bits-per-pixel is 16 and we find one
+ if (plutFound)
+ error("load3DOCelFile: bits per pixel == 16, but pixel lookup table was found as well");
+ }
+ // read data into memory
+ chunkDataPtr = new byte[dataSize];
+
+ stream.read(chunkDataPtr, dataSize);
+
+ // Set up frame
+ ImageFrame imageFrame;
+
+ imageFrame._width = ccbWidth;
+ imageFrame._height = ccbHeight;
+ imageFrame._paletteBase = 0;
+ imageFrame._offset.x = 0;
+ imageFrame._offset.y = 0;
+ imageFrame._rleEncoded = ccbFlags_compressed;
+ imageFrame._size = 0;
+
+ // Decompress/copy this frame
+ if (!plutFound) {
+ decompress3DOCelFrame(imageFrame, chunkDataPtr, dataSize, ccbPRE0_bitsPerPixel, NULL);
+ } else {
+ decompress3DOCelFrame(imageFrame, chunkDataPtr, dataSize, ccbPRE0_bitsPerPixel, &plutRGBlookupTable);
+ }
+
+ delete[] chunkDataPtr;
+
+ push_back(imageFrame);
+ break;
+ }
+
+ case MKTAG('O', 'F', 'S', 'T'): // 3DOSplash.cel
+ // unknown contents
+ break;
+
+ default:
+ error("Unsupported '%s' chunk in 3DO cel file", tag2str(chunkTag));
+ }
+
+ // Seek to end of chunk
+ stream.seek(chunkStartPos + chunkSize);
+ }
+
+ // Warning below being used to silence unused variable warnings for now
+ warning("TODO: Remove %d %d %d", animFrameCount, ccbPPMP0, ccbPPMP1);
+}
+
+// Reads 3DO .cel data (room file format)
+void ImageFile3DO::load3DOCelRoomData(Common::SeekableReadStream &stream) {
+ uint32 streamLeft = stream.size() - stream.pos();
+ uint16 roomDataHeader_size = 0;
+ byte roomDataHeader_offsetX = 0;
+ byte roomDataHeader_offsetY = 0;
+
+ // CCB chunk (cel control block)
+ uint32 ccbFlags = 0;
+ bool ccbFlags_compressed = false;
+ uint16 ccbPPMP0 = 0;
+ uint16 ccbPPMP1 = 0;
+ uint32 ccbPRE0 = 0;
+ uint16 ccbPRE0_height = 0;
+ byte ccbPRE0_bitsPerPixel = 0;
+ uint32 ccbPRE1 = 0;
+ uint16 ccbPRE1_width = 0;
+ uint32 ccbWidth = 0;
+ uint32 ccbHeight = 0;
+ // cel data
+ uint32 celDataSize = 0;
+
+ while (streamLeft > 0) {
+ // We expect at least 8 bytes basic header
+ if (streamLeft < 8)
+ error("load3DOCelRoomData: expected room data header, not enough bytes");
+
+ // 3DO sherlock holmes room data header
+ stream.skip(4); // Possibly UINT16 width, UINT16 height?!?!
+ roomDataHeader_size = stream.readUint16BE();
+ roomDataHeader_offsetX = stream.readByte();
+ roomDataHeader_offsetY = stream.readByte();
+ streamLeft -= 8;
+
+ // We expect the header size specified in the basic header to be at least a raw CCB
+ if (roomDataHeader_size < 68)
+ error("load3DOCelRoomData: header size is too small");
+ // Check, that enough bytes for CCB are available
+ if (streamLeft < 68)
+ error("load3DOCelRoomData: expected raw cel control block, not enough bytes");
+
+ // 3DO raw cel control block
+ ccbFlags = stream.readUint32BE();
+ stream.skip(3 * 4); // skip over 3 pointer fields, which are used in memory only by 3DO hardware
+ stream.skip(8 * 4); // skip over 8 offset fields
+ ccbPPMP0 = stream.readUint16BE();
+ ccbPPMP1 = stream.readUint16BE();
+ ccbPRE0 = stream.readUint32BE();
+ ccbPRE1 = stream.readUint32BE();
+ ccbWidth = stream.readUint32BE();
+ ccbHeight = stream.readUint32BE();
+
+ if (ccbFlags & 0x200) // bit 9
+ ccbFlags_compressed = true;
+
+ // PRE0 first 3 bits define how many bits per encoded pixel are used
+ ccbPRE0_bitsPerPixel = imagefile3DO_cel_bitsPerPixelLookupTable[ccbPRE0 & 0x07];
+ if (!ccbPRE0_bitsPerPixel)
+ error("load3DOCelRoomData: Invalid CCB PRE0 bits per pixel");
+
+ ccbPRE0_height = ((ccbPRE0 >> 6) & 0x03FF) + 1;
+ ccbPRE1_width = (ccbPRE1 & 0x03FF) + 1;
+ assert(ccbPRE0_height == ccbHeight);
+ assert(ccbPRE1_width == ccbWidth);
+
+ if (ccbPRE0_bitsPerPixel != 16) {
+ // We currently support 16-bits per pixel in here
+ error("load3DOCelRoomData: bits per pixel < 16?!?!?");
+ }
+ // Got the raw CCB
+ streamLeft -= 68;
+
+ // cel data follows
+ // size field does not include the 8 byte header
+ celDataSize = roomDataHeader_size - 68;
+
+ if (streamLeft < celDataSize)
+ error("load3DOCelRoomData: expected cel data, not enough bytes");
+
+ // read data into memory
+ byte *celDataPtr = new byte[celDataSize];
+
+ stream.read(celDataPtr, celDataSize);
+ streamLeft -= celDataSize;
+
+ // Set up frame
+ {
+ ImageFrame imageFrame;
+
+ imageFrame._width = ccbWidth;
+ imageFrame._height = ccbHeight;
+ imageFrame._paletteBase = 0;
+ imageFrame._offset.x = roomDataHeader_offsetX;
+ imageFrame._offset.y = roomDataHeader_offsetY;
+ imageFrame._rleEncoded = ccbFlags_compressed;
+ imageFrame._size = 0;
+
+ // Decompress/copy this frame
+ decompress3DOCelFrame(imageFrame, celDataPtr, celDataSize, ccbPRE0_bitsPerPixel, NULL);
+
+ delete[] celDataPtr;
+
+ push_back(imageFrame);
+ }
+ }
+
+ // Suppress compiler warning
+ warning("ccbPPMP0 = %d, ccbPPMP1 = %d", ccbPPMP0, ccbPPMP1);
+}
+
+static uint16 imagefile3DO_cel_bitsMask[17] = {
+ 0,
+ 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF,
+ 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF
+};
+
+// gets [bitCount] bits from dataPtr, going from MSB to LSB
+inline uint16 ImageFile3DO::celGetBits(const byte *&dataPtr, byte bitCount, byte &dataBitsLeft) {
+ byte resultBitsLeft = bitCount;
+ uint16 result = 0;
+ byte currentByte = *dataPtr;
+
+ // Get bits of current byte
+ while (resultBitsLeft) {
+ if (resultBitsLeft < dataBitsLeft) {
+ // we need less than we have left
+ result |= (currentByte >> (dataBitsLeft - resultBitsLeft)) & imagefile3DO_cel_bitsMask[resultBitsLeft];
+ dataBitsLeft -= resultBitsLeft;
+ resultBitsLeft = 0;
+
+ } else {
+ // we need as much as we have left or more
+ resultBitsLeft -= dataBitsLeft;
+ result |= (currentByte & imagefile3DO_cel_bitsMask[dataBitsLeft]) << resultBitsLeft;
+
+ // Go to next byte
+ dataPtr++;
+ dataBitsLeft = 8;
+ if (resultBitsLeft) {
+ currentByte = *dataPtr;
+ }
+ }
+ }
+ return result;
+}
+
+// decompress/copy 3DO cel data
+void ImageFile3DO::decompress3DOCelFrame(ImageFrame &frame, const byte *dataPtr, uint32 dataSize, byte bitsPerPixel, ImageFile3DOPixelLookupTable *pixelLookupTable) {
+ frame._frame.create(frame._width, frame._height, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));
+ uint16 *dest = (uint16 *)frame._frame.getPixels();
+ Common::fill(dest, dest + frame._width * frame._height, 0);
+
+ int frameHeightLeft = frame._height;
+ int frameWidthLeft = frame._width;
+ uint16 pixelCount = 0;
+ uint16 pixel = 0;
+
+ const byte *srcLineStart = dataPtr;
+ const byte *srcLineData = dataPtr;
+ byte srcLineDataBitsLeft = 0;
+ uint16 lineDWordSize = 0;
+ uint16 lineByteSize = 0;
+
+ if (bitsPerPixel == 16) {
+ // Must not use pixel lookup table on 16-bits-per-pixel data
+ assert(!pixelLookupTable);
+ }
+
+ if (frame._rleEncoded) {
+ // compressed
+ byte compressionType = 0;
+ byte compressionPixels = 0;
+
+ while (frameHeightLeft > 0) {
+ frameWidthLeft = frame._width;
+
+ if (bitsPerPixel >= 8) {
+ lineDWordSize = READ_BE_UINT16(srcLineStart);
+ srcLineData = srcLineStart + 2;
+ } else {
+ lineDWordSize = *srcLineStart;
+ srcLineData = srcLineStart + 1;
+ }
+ srcLineDataBitsLeft = 8;
+
+ lineDWordSize += 2;
+ lineByteSize = lineDWordSize * 4; // calculate compressed data size in bytes for current line
+
+ // debug
+ //warning("offset %d: decoding line, size %d, bytesize %d", srcSeeker - src, dwordSize, lineByteSize);
+
+ while (frameWidthLeft > 0) {
+ // get 2 bits -> compressionType
+ // get 6 bits -> pixel count (0 = 1 pixel)
+ compressionType = celGetBits(srcLineData, 2, srcLineDataBitsLeft);
+ // 6 bits == length (0 = 1 pixel)
+ compressionPixels = celGetBits(srcLineData, 6, srcLineDataBitsLeft) + 1;
+
+ if (!compressionType) // end of line
+ break;
+
+ switch(compressionType) {
+ case 1: // simple copy
+ for (pixelCount = 0; pixelCount < compressionPixels; pixelCount++) {
+ pixel = celGetBits(srcLineData, bitsPerPixel, srcLineDataBitsLeft);
+ if (pixelLookupTable) {
+ pixel = pixelLookupTable->pixelColor[pixel];
+ }
+ *dest++ = convertPixel(pixel);
+ }
+ break;
+ case 2: // transparent
+ for (pixelCount = 0; pixelCount < compressionPixels; pixelCount++) {
+ *dest++ = 0;
+ }
+ break;
+ case 3: // duplicate pixels
+ pixel = celGetBits(srcLineData, bitsPerPixel, srcLineDataBitsLeft);
+ if (pixelLookupTable) {
+ pixel = pixelLookupTable->pixelColor[pixel];
+ }
+ pixel = convertPixel(pixel);
+ for (pixelCount = 0; pixelCount < compressionPixels; pixelCount++) {
+ *dest++ = pixel;
+ }
+ break;
+ default:
+ break;
+ }
+ frameWidthLeft -= compressionPixels;
+ }
+
+ assert(frameWidthLeft >= 0);
+
+ if (frameWidthLeft > 0) {
+ // still pixels left? skip them
+ dest += frameWidthLeft;
+ }
+
+ frameHeightLeft--;
+
+ // Seek to next line start
+ srcLineStart += lineByteSize;
+ }
+ } else {
+ // uncompressed
+ srcLineDataBitsLeft = 8;
+ lineDWordSize = ((frame._width * bitsPerPixel) + 31) >> 5;
+ lineByteSize = lineDWordSize * 4;
+ uint32 totalExpectedSize = lineByteSize * frame._height;
+
+ assert(totalExpectedSize <= dataSize); // security check
+
+ while (frameHeightLeft > 0) {
+ srcLineData = srcLineStart;
+ frameWidthLeft = frame._width;
+
+ while (frameWidthLeft > 0) {
+ pixel = celGetBits(srcLineData, bitsPerPixel, srcLineDataBitsLeft);
+ if (pixelLookupTable) {
+ pixel = pixelLookupTable->pixelColor[pixel];
+ }
+ *dest++ = convertPixel(pixel);
+
+ frameWidthLeft--;
+ }
+ frameHeightLeft--;
+
+ // Seek to next line start
+ srcLineStart += lineByteSize;
+ }
+ }
+}
+
+// Reads Sherlock Holmes 3DO font file
+void ImageFile3DO::loadFont(Common::SeekableReadStream &stream) {
+ uint32 streamSize = stream.size();
+ uint32 header_offsetWidthTable = 0;
+ uint32 header_offsetBitsTable = 0;
+ uint32 header_fontHeight = 0;
+ uint32 header_bytesPerLine = 0;
+ uint32 header_maxChar = 0;
+ uint32 header_charCount = 0;
+
+ byte *widthTablePtr = NULL;
+ uint32 bitsTableSize = 0;
+ byte *bitsTablePtr = NULL;
+
+ stream.skip(2); // Unknown bytes
+ stream.skip(2); // Unknown bytes (0x000E)
+ header_offsetWidthTable = stream.readUint32BE();
+ header_offsetBitsTable = stream.readUint32BE();
+ stream.skip(4); // Unknown bytes (0x00000004)
+ header_fontHeight = stream.readUint32BE();
+ header_bytesPerLine = stream.readUint32BE();
+ header_maxChar = stream.readUint32BE();
+
+ assert(header_maxChar <= 255);
+ header_charCount = header_maxChar + 1;
+
+ // Allocate memory for width table
+ widthTablePtr = new byte[header_charCount];
+
+ stream.seek(header_offsetWidthTable);
+ stream.read(widthTablePtr, header_charCount);
+
+ // Allocate memory for the bits
+ assert(header_offsetBitsTable < streamSize); // Security check
+ bitsTableSize = streamSize - header_offsetBitsTable;
+ bitsTablePtr = new byte[bitsTableSize];
+ 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;
+
+ assert(bitsTableSize >= (header_maxChar * header_fontHeight * header_bytesPerLine)); // Security
+
+ // first frame needs to be "!" (33 decimal)
+ // our font code is subtracting 33 from the actual character code
+ curBitsLinePtr += (33 * (header_fontHeight * header_bytesPerLine));
+
+ for (curChar = 33; curChar < header_charCount; curChar++) {
+ // create frame
+ {
+ ImageFrame imageFrame;
+
+ imageFrame._width = widthTablePtr[curChar];
+ imageFrame._height = header_fontHeight;
+ imageFrame._paletteBase = 0;
+ imageFrame._offset.x = 0;
+ imageFrame._offset.y = 0;
+ imageFrame._rleEncoded = false;
+ imageFrame._size = 0;
+
+ // Extract pixels
+ imageFrame._frame.create(imageFrame._width, imageFrame._height, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));
+ uint16 *dest = (uint16 *)imageFrame._frame.getPixels();
+ Common::fill(dest, dest + imageFrame._width * imageFrame._height, 0);
+
+ curCharHeightLeft = header_fontHeight;
+ while (curCharHeightLeft) {
+ curCharWidthLeft = widthTablePtr[curChar];
+ curBitsPtr = curBitsLinePtr;
+ curBitsLeft = 8;
+ curPosX = 0;
+
+ while (curCharWidthLeft) {
+ if (!(curPosX & 1)) {
+ curBits = *curBitsPtr >> 4;
+ } else {
+ curBits = *curBitsPtr & 0x0F;
+ curBitsPtr++;
+ }
+ // doing this properly is complicated
+ // the 3DO has built-in anti-aliasing
+ // this here at least results in somewhat readable text
+ // TODO: make it better
+ if (curBits) {
+ curBitsReversed = (curBits >> 3) | ((curBits & 0x04) >> 1) | ((curBits & 0x02) << 1) | ((curBits & 0x01) << 3);
+ curBits = 20 - curBits;
+ }
+
+ byte curIntensity = curBits;
+ *dest = (curIntensity << 11) | (curIntensity << 6) | curIntensity;
+ dest++;
+
+ curCharWidthLeft--;
+ curPosX++;
+ }
+
+ curCharHeightLeft--;
+ curBitsLinePtr += header_bytesPerLine;
+ }
+
+ push_back(imageFrame);
+ }
+ }
+
+ // Warning below being used to silence unused variable warnings for now
+ warning("TODO: Remove %d %d", curBitsLeft, curBitsReversed);
+
+ delete[] bitsTablePtr;
+ delete[] widthTablePtr;
+}
+
+/*----------------------------------------------------------------*/
+
+StreamingImageFile::StreamingImageFile() {
+ _frameNumber = 0;
+ _stream = nullptr;
+ _flags = 0;
+ _scaleVal = 0;
+ _zPlacement = 0;
+ _compressed = false;
+}
+
+StreamingImageFile::~StreamingImageFile() {
+ close();
+}
+
+void StreamingImageFile::load(Common::SeekableReadStream *stream, bool compressed) {
+ _stream = stream;
+ _compressed = compressed;
+ _frameNumber = -1;
+}
+
+void StreamingImageFile::close() {
+ delete _stream;
+ _stream = nullptr;
+ _frameNumber = -1;
+}
+
+void StreamingImageFile::getNextFrame() {
+ // Don't proceed if we're already at the end of the stream
+ if (_stream->pos() >= _stream->size())
+ return;
+
+ // Increment frame number
+ ++_frameNumber;
+
+ // If necessary, decompress the next frame
+ Common::SeekableReadStream *frameStream = _stream;
+ if (_compressed) {
+ uint32 inSize = _stream->readUint32LE();
+ Resources::decompressLZ(*_stream, _buffer, STREAMING_BUFFER_SIZE, inSize);
+ frameStream = new Common::MemoryReadStream(_buffer, 11, DisposeAfterUse::NO);
+ }
+
+ // Load the data for the frame
+ _imageFrame._width = frameStream->readUint16LE() + 1;
+ _imageFrame._height = frameStream->readUint16LE() + 1;
+ _imageFrame._paletteBase = frameStream->readByte();
+ _imageFrame._rleEncoded = frameStream->readByte() == 1;
+ _imageFrame._offset.x = frameStream->readByte();
+ _imageFrame._offset.y = frameStream->readByte();
+ _imageFrame._size = frameStream->readUint16LE() - 11;
+ _imageFrame._rleMarker = frameStream->readByte();
+
+ // Decode the frame
+ if (_compressed) {
+ delete frameStream;
+ _imageFrame.decompressFrame(_buffer + 11, true);
+ } else {
+ byte *data = new byte[_imageFrame._size];
+ _stream->read(data, _imageFrame._size);
+ _imageFrame.decompressFrame(_buffer + 11, true);
+ delete[] data;
+ }
+}
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/image_file.h b/engines/sherlock/image_file.h
new file mode 100644
index 0000000000..3ac0cf4b5f
--- /dev/null
+++ b/engines/sherlock/image_file.h
@@ -0,0 +1,207 @@
+/* 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 SHERLOCK_IMAGE_FILE_H
+#define SHERLOCK_IMAGE_FILE_H
+
+#include "common/array.h"
+#include "common/file.h"
+#include "common/hashmap.h"
+#include "common/hash-str.h"
+#include "common/rect.h"
+#include "common/str.h"
+#include "common/stream.h"
+#include "graphics/surface.h"
+
+namespace Sherlock {
+
+class SherlockEngine;
+
+struct ImageFrame {
+ uint32 _size;
+ uint16 _width, _height;
+ int _paletteBase;
+ bool _rleEncoded;
+ Common::Point _offset;
+ byte _rleMarker;
+ Graphics::Surface _frame;
+
+ /**
+ * Decompress a single frame for the sprite
+ */
+ void decompressFrame(const byte *src, bool isRoseTattoo);
+
+ /**
+ * Return the frame width adjusted by a specified scale amount
+ */
+ int sDrawXSize(int scaleVal) const;
+
+ /**
+ * Return the frame height adjusted by a specified scale amount
+ */
+ int sDrawYSize(int scaleVal) const;
+
+ /**
+ * Return the frame offset x adjusted by a specified scale amount
+ */
+ int sDrawXOffset(int scaleVal) const;
+
+ /**
+ * Return the frame offset y adjusted by a specified scale amount
+ */
+ int sDrawYOffset(int scaleVal) const;
+};
+
+class ImageFile : public Common::Array<ImageFrame> {
+private:
+ static SherlockEngine *_vm;
+
+ /**
+ * Load the data of the sprite
+ */
+ void load(Common::SeekableReadStream &stream, bool skipPalette, bool animImages);
+
+ /**
+ * Gets the palette at the start of the sprite file
+ */
+ void loadPalette(Common::SeekableReadStream &stream);
+public:
+ byte _palette[256 * 3];
+public:
+ ImageFile();
+ ImageFile(const Common::String &name, bool skipPal = false, bool animImages = false);
+ ImageFile(Common::SeekableReadStream &stream, bool skipPal = false);
+ ~ImageFile();
+ static void setVm(SherlockEngine *vm);
+};
+
+enum ImageFile3DOType {
+ kImageFile3DOType_Animation = 0,
+ kImageFile3DOType_Cel = 1,
+ kImageFile3DOType_CelAnimation = 2,
+ kImageFile3DOType_RoomFormat = 3,
+ kImageFile3DOType_Font = 4
+};
+
+struct ImageFile3DOPixelLookupTable {
+ uint16 pixelColor[256];
+};
+
+class ImageFile3DO : public ImageFile { // Common::Array<ImageFrame> {
+private:
+ static SherlockEngine *_vm;
+
+ /**
+ * Load the data of the sprite
+ */
+ void load(Common::SeekableReadStream &stream, bool isRoomData);
+
+ /**
+ * convert pixel RGB values from RGB555 to RGB565
+ */
+ inline uint16 convertPixel(uint16 pixel3DO);
+
+ /**
+ * Load 3DO cel file
+ */
+ void load3DOCelFile(Common::SeekableReadStream &stream);
+
+ /**
+ * Load 3DO cel data (room file format)
+ */
+ void load3DOCelRoomData(Common::SeekableReadStream &stream);
+
+ inline uint16 celGetBits(const byte *&dataPtr, byte bitCount, byte &dataBitsLeft);
+
+ /**
+ * Decompress a single frame of a 3DO cel file
+ */
+ void decompress3DOCelFrame(ImageFrame &frame, const byte *dataPtr, uint32 dataSize, byte bitsPerPixel, ImageFile3DOPixelLookupTable *pixelLookupTable);
+
+ /**
+ * Load animation graphics file
+ */
+ void loadAnimationFile(Common::SeekableReadStream &stream);
+
+ /**
+ * Load Sherlock Holmes 3DO font file
+ */
+ void loadFont(Common::SeekableReadStream &stream);
+
+public:
+ ImageFile3DO(const Common::String &name, ImageFile3DOType imageFile3DOType);
+ ImageFile3DO(Common::SeekableReadStream &stream, bool isRoomData = false);
+ ~ImageFile3DO();
+ static void setVm(SherlockEngine *vm);
+};
+
+#define STREAMING_BUFFER_SIZE 65536
+
+class StreamingImageFile {
+private:
+ int _frameNumber;
+ Common::SeekableReadStream *_stream;
+ bool _compressed;
+ byte _buffer[STREAMING_BUFFER_SIZE];
+public:
+ ImageFrame _imageFrame;
+
+ Common::Point _position; // Animation position
+ Common::Rect _oldBounds; // Bounds of previous frame
+ Common::Rect _removeBounds; // Remove area for just drawn frame
+
+ int _flags; // Flags
+ int _scaleVal; // Specifies the scale amount
+ int _zPlacement; // Used by doBgAnim for determining Z order
+public:
+ StreamingImageFile();
+ ~StreamingImageFile();
+
+ /**
+ * Initialize reading of the specified stream
+ */
+ void load(Common::SeekableReadStream *stream, bool compressed);
+
+ /**
+ * Close the streamining image file
+ */
+ void close();
+
+ /**
+ * Get the next frame of the file
+ */
+ void getNextFrame();
+
+ /**
+ * Returns whether there are any remaining frames or not
+ */
+ bool active() const { return _stream != nullptr && _stream->pos() < _stream->size(); }
+
+ /**
+ * Return the current frame number
+ */
+ int frameNumber() const { return _frameNumber; }
+};
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp
new file mode 100644
index 0000000000..d0982542f2
--- /dev/null
+++ b/engines/sherlock/inventory.cpp
@@ -0,0 +1,246 @@
+/* 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 "sherlock/inventory.h"
+#include "sherlock/sherlock.h"
+#include "sherlock/scalpel/scalpel_inventory.h"
+#include "sherlock/scalpel/scalpel_user_interface.h"
+#include "sherlock/tattoo/tattoo_inventory.h"
+
+namespace Sherlock {
+
+InventoryItem::InventoryItem(int requiredFlag, const Common::String &name,
+ const Common::String &description, const Common::String &examine) :
+ _requiredFlag(requiredFlag), _requiredFlag1(0), _name(name), _description(description),
+ _examine(examine), _lookFlag(0) {
+}
+
+InventoryItem::InventoryItem(int requiredFlag, const Common::String &name,
+ const Common::String &description, const Common::String &examine, const Common::String &verbName) :
+ _requiredFlag(requiredFlag), _requiredFlag1(0), _name(name), _description(description),
+ _examine(examine), _lookFlag(0) {
+ _verb._verb = verbName;
+}
+
+void InventoryItem::synchronize(Serializer &s) {
+ s.syncAsSint16LE(_requiredFlag);
+ s.syncAsSint16LE(_lookFlag);
+ s.syncString(_name);
+ s.syncString(_description);
+ s.syncString(_examine);
+ _verb.synchronize(s);
+}
+
+/*----------------------------------------------------------------*/
+
+Inventory *Inventory::init(SherlockEngine *vm) {
+ if (vm->getGameID() == GType_SerratedScalpel)
+ return new Scalpel::ScalpelInventory(vm);
+ else
+ return new Tattoo::TattooInventory(vm);
+}
+
+Inventory::Inventory(SherlockEngine *vm) : Common::Array<InventoryItem>(), _vm(vm) {
+ _invGraphicsLoaded = false;
+ _invIndex = 0;
+ _holdings = 0;
+ _invMode = INVMODE_EXIT;
+}
+
+Inventory::~Inventory() {
+ freeGraphics();
+}
+
+void Inventory::freeInv() {
+ freeGraphics();
+
+ _names.clear();
+ _invGraphicsLoaded = false;
+}
+
+void Inventory::freeGraphics() {
+ int count = _invShapes.size();
+ for (int idx = 0; idx < count; ++idx)
+ delete _invShapes[idx];
+ _invShapes.clear();
+ _invShapes.resize(count);
+
+ _invGraphicsLoaded = false;
+}
+
+void Inventory::loadGraphics() {
+ if (_invGraphicsLoaded)
+ return;
+
+ for (int idx = _invIndex; (idx < _holdings) && (idx - _invIndex) < (int)_invShapes.size(); ++idx) {
+ // Get the name of the item to be displayed, figure out its accompanying
+ // .VGS file with its picture, and then load it
+ int invNum = findInv((*this)[idx]._name);
+ Common::String filename = Common::String::format("item%02d.vgs", invNum + 1);
+
+ if (!IS_3DO) {
+ // PC
+ _invShapes[idx - _invIndex] = new ImageFile(filename);
+ } else {
+ _invShapes[idx - _invIndex] = new ImageFile3DO(filename, kImageFile3DOType_RoomFormat);
+ }
+ }
+
+ _invGraphicsLoaded = true;
+}
+
+int Inventory::findInv(const Common::String &name) {
+ for (int idx = 0; idx < (int)_names.size(); ++idx) {
+ if (name.equalsIgnoreCase(_names[idx]))
+ return idx;
+ }
+
+ // Couldn't find the desired item
+ error("Couldn't find inventory item - %s", name.c_str());
+}
+
+int Inventory::putNameInInventory(const Common::String &name) {
+ Scene &scene = *_vm->_scene;
+ int matches = 0;
+
+ for (uint idx = 0; idx < scene._bgShapes.size(); ++idx) {
+ Object &o = scene._bgShapes[idx];
+ if (name.equalsIgnoreCase(o._name) && o._type != INVALID) {
+ putItemInInventory(o);
+ ++matches;
+ }
+ }
+
+ return matches;
+}
+
+int Inventory::putItemInInventory(Object &obj) {
+ Scene &scene = *_vm->_scene;
+ int matches = 0;
+ bool pickupFound = false;
+
+ if (obj._pickupFlag)
+ _vm->setFlags(obj._pickupFlag);
+
+ for (int useNum = 0; useNum < USE_COUNT; ++useNum) {
+ if (obj._use[useNum]._target.equalsIgnoreCase("*PICKUP*")) {
+ pickupFound = true;
+
+ for (int namesNum = 0; namesNum < NAMES_COUNT; ++namesNum) {
+ for (uint bgNum = 0; bgNum < scene._bgShapes.size(); ++bgNum) {
+ Object &bgObj = scene._bgShapes[bgNum];
+ if (obj._use[useNum]._names[namesNum].equalsIgnoreCase(bgObj._name)) {
+ copyToInventory(bgObj);
+ if (bgObj._pickupFlag)
+ _vm->setFlags(bgObj._pickupFlag);
+
+ if (bgObj._type == ACTIVE_BG_SHAPE || bgObj._type == NO_SHAPE || bgObj._type == HIDE_SHAPE) {
+ if (bgObj._imageFrame == nullptr || bgObj._frameNumber < 0)
+ // No shape to erase, so flag as hidden
+ bgObj._type = INVALID;
+ else
+ bgObj._type = REMOVE;
+ } else if (bgObj._type == HIDDEN) {
+ bgObj._type = INVALID;
+ }
+
+ ++matches;
+ }
+ }
+ }
+ }
+ }
+
+ if (!pickupFound) {
+ // No pickup item found, so add the passed item
+ copyToInventory(obj);
+ matches = 0;
+ }
+
+ if (matches == 0) {
+ if (!pickupFound)
+ matches = 1;
+
+ if (obj._type == ACTIVE_BG_SHAPE || obj._type == NO_SHAPE || obj._type == HIDE_SHAPE) {
+ if (obj._imageFrame == nullptr || obj._frameNumber < 0)
+ // No shape to erase, so flag as hidden
+ obj._type = INVALID;
+ else
+ obj._type = REMOVE;
+ } else if (obj._type == HIDDEN) {
+ obj._type = INVALID;
+ }
+ }
+
+ return matches;
+}
+
+void Inventory::copyToInventory(Object &obj) {
+ InventoryItem invItem;
+ invItem._name = obj._name;
+ invItem._description = obj._description;
+ invItem._examine = obj._examine;
+ invItem._lookFlag = obj._lookFlag;
+ invItem._requiredFlag = obj._requiredFlag[0];
+
+ insert_at(_holdings, invItem);
+ ++_holdings;
+}
+
+int Inventory::deleteItemFromInventory(const Common::String &name) {
+ int invNum = -1;
+
+ for (int idx = 0; idx < (int)size() && invNum == -1; ++idx) {
+ if (name.equalsIgnoreCase((*this)[idx]._name))
+ invNum = idx;
+ }
+
+ if (invNum == -1)
+ // Item not present
+ return 0;
+
+ // Item found, so delete it
+ remove_at(invNum);
+ --_holdings;
+
+ return 1;
+}
+
+void Inventory::synchronize(Serializer &s) {
+ s.syncAsSint16LE(_holdings);
+
+ uint count = size();
+ s.syncAsUint16LE(count);
+ if (s.isLoading()) {
+ resize(count);
+
+ // Reset inventory back to start
+ _invIndex = 0;
+ }
+
+ for (uint idx = 0; idx < size(); ++idx) {
+ (*this)[idx].synchronize(s);
+
+ }
+}
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/inventory.h b/engines/sherlock/inventory.h
new file mode 100644
index 0000000000..057e923e5d
--- /dev/null
+++ b/engines/sherlock/inventory.h
@@ -0,0 +1,150 @@
+/* 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 SHERLOCK_INVENTORY_H
+#define SHERLOCK_INVENTORY_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/str-array.h"
+#include "sherlock/objects.h"
+#include "sherlock/resources.h"
+#include "sherlock/saveload.h"
+
+namespace Sherlock {
+
+enum InvMode {
+ INVMODE_EXIT = 0,
+ INVMODE_LOOK = 1,
+ INVMODE_USE = 2,
+ INVMODE_GIVE = 3,
+ INVMODE_FIRST = 4,
+ INVMODE_PREVIOUS = 5,
+ INVMODE_NEXT = 6,
+ INVMODE_LAST = 7,
+ INVMODE_INVALID = 8,
+ INVMODE_USE55 = 255
+};
+
+enum InvNewMode {
+ PLAIN_INVENTORY = 0, LOOK_INVENTORY_MODE = 1, USE_INVENTORY_MODE = 2,
+ GIVE_INVENTORY_MODE = 3, INVENTORY_DONT_DISPLAY = 128
+};
+
+enum InvSlamMode { SLAM_DONT_DISPLAY, SLAM_DISPLAY = 1, SLAM_SECONDARY_BUFFER };
+
+
+struct InventoryItem {
+ int _requiredFlag;
+ Common::String _name;
+ Common::String _description;
+ Common::String _examine;
+ int _lookFlag;
+
+ // Rose Tattoo fields
+ int _requiredFlag1;
+ UseType _verb;
+
+ InventoryItem() : _requiredFlag(0), _lookFlag(0), _requiredFlag1(0) {}
+ InventoryItem(int requiredFlag, const Common::String &name,
+ const Common::String &description, const Common::String &examine);
+ InventoryItem(int requiredFlag, const Common::String &name,
+ const Common::String &description, const Common::String &examine, const Common::String &verbName);
+
+ /**
+ * Synchronize the data for an inventory item
+ */
+ void synchronize(Serializer &s);
+};
+
+class Inventory : public Common::Array<InventoryItem> {
+protected:
+ SherlockEngine *_vm;
+ Common::StringArray _names;
+
+ /**
+ * Copy the passed object into the inventory
+ */
+ void copyToInventory(Object &obj);
+public:
+ Common::Array<ImageFile *> _invShapes;
+ bool _invGraphicsLoaded;
+ InvMode _invMode;
+ int _invIndex;
+ int _holdings; // Used to hold number of visible items in active inventory.
+ // Since Inventory array also contains some special hidden items
+ /**
+ * Free any loaded inventory graphics
+ */
+ void freeGraphics();
+public:
+ static Inventory *init(SherlockEngine *vm);
+ Inventory(SherlockEngine *vm);
+ virtual ~Inventory();
+
+ /**
+ * Free inventory data
+ */
+ void freeInv();
+
+ /**
+ * Load the list of names of graphics for the inventory
+ */
+ void loadGraphics();
+
+ /**
+ * Searches through the list of names that correspond to the inventory items
+ * and returns the number that matches the passed name
+ */
+ int findInv(const Common::String &name);
+
+ /**
+ * Adds a shape from the scene to the player's inventory
+ */
+ int putNameInInventory(const Common::String &name);
+
+ /**
+ * Moves a specified item into the player's inventory If the item has a *PICKUP* use action,
+ * then the item in the use action are added to the inventory.
+ */
+ int putItemInInventory(Object &obj);
+
+ /**
+ * Deletes a specified item from the player's inventory
+ */
+ int deleteItemFromInventory(const Common::String &name);
+
+ /**
+ * Synchronize the data for a savegame
+ */
+ void synchronize(Serializer &s);
+
+ /**
+ * Load the list of names the inventory items correspond to, if not already loaded,
+ * and then calls loadGraphics to load the associated graphics
+ */
+ virtual void loadInv() = 0;
+};
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp
new file mode 100644
index 0000000000..9441d6682a
--- /dev/null
+++ b/engines/sherlock/journal.cpp
@@ -0,0 +1,706 @@
+/* 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 "sherlock/journal.h"
+#include "sherlock/scalpel/scalpel.h"
+#include "sherlock/scalpel/scalpel_fixed_text.h"
+#include "sherlock/scalpel/scalpel_journal.h"
+#include "sherlock/tattoo/tattoo.h"
+#include "sherlock/tattoo/tattoo_journal.h"
+
+namespace Sherlock {
+
+Journal *Journal::init(SherlockEngine *vm) {
+ if (vm->getGameID() == GType_SerratedScalpel)
+ return new Scalpel::ScalpelJournal(vm);
+ else
+ return new Tattoo::TattooJournal(vm);
+}
+
+Journal::Journal(SherlockEngine *vm) : _vm(vm) {
+ _up = _down = false;
+ _index = 0;
+ _page = 0;
+ _maxPage = 0;
+ _sub = 0;
+}
+
+bool Journal::drawJournal(int direction, int howFar) {
+ Events &events = *_vm->_events;
+ FixedText &fixedText = *_vm->_fixedText;
+ Screen &screen = *_vm->_screen;
+ Talk &talk = *_vm->_talk;
+ int yp = 37;
+ int startPage = _page;
+ bool endJournal = false;
+ bool firstOccurance = true;
+ bool searchSuccessful = false;
+ bool endFlag = false;
+ int lineNum = 0;
+ int savedIndex;
+ int temp;
+ const char *matchP;
+ int width;
+
+ talk._converseNum = -1;
+ _down = true;
+
+ do {
+ // Get the number of lines for the current journal entry
+ loadJournalFile(false);
+ if (_lines.empty()) {
+ // Entry has no text, so it must be a stealth eny. Move onto further journal entries
+ // until an entry with text is found
+ if (++_index == (int)_journal.size()) {
+ endJournal = true;
+ } else {
+ _sub = 0;
+ loadJournalFile(false);
+ }
+ }
+ } while (!endJournal && _lines.empty());
+
+ // Check if there no further pages with text until the end of the journal
+ if (endJournal) {
+ // If moving forward or backwards, clear the page before printing
+ if (direction)
+ drawFrame();
+
+ screen.gPrint(Common::Point(235, 21), COL_PEN_COLOR, "Page %d", _page);
+ return false;
+ }
+
+ // If the journal page is being changed, set the wait cursor
+ if (direction)
+ events.setCursor(WAIT);
+
+ switch (direction) {
+ case 1:
+ case 4:
+ // Move backwards howFar number of lines unless either the start of the journal is reached,
+ // or a searched for keyword is found
+ do {
+ // Move backwards through the journal file a line at a time
+ if (--_sub < 0) {
+ do {
+ if (--_index < 0) {
+ _index = 0;
+ _sub = 0;
+ endJournal = true;
+ }
+ else {
+ loadJournalFile(false);
+ _sub = _lines.size() - 1;
+ }
+ } while (!endJournal && _lines.empty());
+ }
+
+ // If it's search mode, check each line for the given keyword
+ if (direction >= 3 && !_lines.empty() && !endJournal && !searchSuccessful) {
+ Common::String line = _lines[_sub];
+ line.toUppercase();
+ if (strstr(line.c_str(), _find.c_str()) != nullptr) {
+ // Found a match. Reset howFar so that the start of page that the match
+ // was found on will be displayed
+ searchSuccessful = true;
+ howFar = ((lineNum / LINES_PER_PAGE) + 1) * LINES_PER_PAGE;
+ }
+ }
+
+ ++lineNum;
+ } while (lineNum < howFar && !endJournal);
+
+ if (!_index && !_sub)
+ _page = 1;
+ else
+ _page -= howFar / LINES_PER_PAGE;
+ break;
+
+ case 2:
+ case 3:
+ // Move howFar lines ahead unless the end of the journal is reached,
+ // or a searched for keyword is found
+ for (temp = 0; (temp < (howFar / LINES_PER_PAGE)) && !endJournal && !searchSuccessful; ++temp) {
+ // Handle animating mouse cursor
+ int cursorNum = (int)events.getCursor() + 1;
+ if (cursorNum >(WAIT + 2))
+ cursorNum = WAIT;
+ events.setCursor((CursorId)cursorNum);
+
+ lineNum = 0;
+ savedIndex = _index;
+ int savedSub = _sub;
+
+ // Move a single page ahead
+ do {
+ // If in search mode, check for keyword
+ if (direction >= 3 && _page != startPage) {
+ Common::String line = _lines[_sub];
+ line.toUppercase();
+ if (strstr(line.c_str(), _find.c_str()) != nullptr)
+ searchSuccessful = true;
+ }
+
+ // Move forwards a line at a time, unless search word was found
+ if (!searchSuccessful) {
+ if (++_sub == (int)_lines.size()) {
+ // Reached end of page
+ do {
+ if (++_index == (int)_journal.size()) {
+ _index = savedIndex;
+ _sub = savedSub;
+ loadJournalFile(false);
+ endJournal = true;
+ } else {
+ _sub = 0;
+ loadJournalFile(false);
+ }
+ } while (!endJournal && _lines.empty());
+ }
+
+ ++lineNum;
+ }
+ } while ((lineNum < LINES_PER_PAGE) && !endJournal && !searchSuccessful);
+
+ if (!endJournal && !searchSuccessful)
+ // Move to next page
+ ++_page;
+
+ if (searchSuccessful) {
+ // Search found, so show top of the page it was found on
+ _index = savedIndex;
+ _sub = savedSub;
+ loadJournalFile(false);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (direction) {
+ events.setCursor(ARROW);
+ drawFrame();
+ }
+
+ Common::String fixedText_Page = IS_SERRATED_SCALPEL ? fixedText.getText(Scalpel::kFixedText_Journal_Page) : "TODO";
+
+ screen.gPrint(Common::Point(235, 21), COL_PEN_COLOR, fixedText_Page.c_str(), _page);
+
+ temp = _sub;
+ savedIndex = _index;
+ lineNum = 0;
+
+ do {
+ bool inc = true;
+
+ // If there wasn't any line to print at the top of the page, we won't need to
+ // increment the y position
+ if (_lines[temp].empty() && yp == 37)
+ inc = false;
+
+ // If there's a searched for keyword in the line, it will need to be highlighted
+ if (searchSuccessful && firstOccurance) {
+ // Check if line has the keyword
+ Common::String line = _lines[temp];
+ line.toUppercase();
+ if ((matchP = strstr(line.c_str(), _find.c_str())) != nullptr) {
+ matchP = _lines[temp].c_str() + (matchP - line.c_str());
+ firstOccurance = false;
+
+ // Print out the start of the line before the matching keyword
+ Common::String lineStart(_lines[temp].c_str(), matchP);
+ if (lineStart.hasPrefix("@")) {
+ width = screen.stringWidth(lineStart.c_str() + 1);
+ screen.gPrint(Common::Point(53, yp), 15, "%s", lineStart.c_str() + 1);
+ } else {
+ width = screen.stringWidth(lineStart.c_str());
+ screen.gPrint(Common::Point(53, yp), COL_PEN_COLOR, "%s", lineStart.c_str());
+ }
+
+ // Print out the found keyword
+ Common::String lineMatch(matchP, matchP + _find.size());
+ byte fgColor = IS_SERRATED_SCALPEL ? (byte)Scalpel::INV_FOREGROUND : (byte)Tattoo::INV_FOREGROUND;
+ screen.gPrint(Common::Point(53 + width, yp), fgColor, "%s", lineMatch.c_str());
+ width += screen.stringWidth(lineMatch.c_str());
+
+ // Print remainder of line
+ screen.gPrint(Common::Point(53 + width, yp), COL_PEN_COLOR, "%s", matchP + _find.size());
+ } else if (_lines[temp].hasPrefix("@")) {
+ screen.gPrint(Common::Point(53, yp), 15, "%s", _lines[temp].c_str() + 1);
+ } else {
+ screen.gPrint(Common::Point(53, yp), COL_PEN_COLOR, "%s", _lines[temp].c_str());
+ }
+ } else {
+ if (_lines[temp].hasPrefix("@")) {
+ screen.gPrint(Common::Point(53, yp), 15, "%s", _lines[temp].c_str() + 1);
+ } else {
+ screen.gPrint(Common::Point(53, yp), COL_PEN_COLOR, "%s", _lines[temp].c_str());
+ }
+ }
+
+ if (++temp == (int)_lines.size()) {
+ // Move to next page
+ do {
+ if (_index < ((int)_journal.size() - 1) && lineNum < (LINES_PER_PAGE - 1)) {
+ ++_index;
+ loadJournalFile(false);
+ temp = 0;
+ } else {
+ if (_index == ((int)_journal.size() - 1))
+ _down = false;
+ endFlag = true;
+ }
+ } while (!endFlag && _lines.empty());
+ }
+
+ if (inc) {
+ // Move to next line
+ ++lineNum;
+ yp += 13;
+ }
+ } while (lineNum < LINES_PER_PAGE && !endFlag);
+
+ _index = savedIndex;
+ _up = _index || _sub;
+
+ return direction >= 3 && searchSuccessful;
+}
+
+void Journal::loadJournalFile(bool alreadyLoaded) {
+ People &people = *_vm->_people;
+ Screen &screen = *_vm->_screen;
+ Talk &talk = *_vm->_talk;
+ JournalEntry &journalEntry = _journal[_index];
+ const byte *opcodes = talk._opcodes;
+
+ Common::String dirFilename = _directory[journalEntry._converseNum];
+ bool replyOnly = journalEntry._replyOnly;
+
+ // Get the location number from within the filename
+ Common::String locStr(dirFilename.c_str() + 4, dirFilename.c_str() + 6);
+ int newLocation = atoi(locStr.c_str());
+
+ // If not flagged as already loaded, load the conversation into script variables
+ if (!alreadyLoaded) {
+ // See if the file to be used is already loaded
+ if (journalEntry._converseNum != talk._converseNum) {
+ // Nope. Free any previously loaded talk
+ talk.freeTalkVars();
+
+ // Find the person being referred to
+ talk._talkTo = -1;
+ for (int idx = 0; idx < (int)people._characters.size(); ++idx) {
+ Common::String portrait = people._characters[idx]._portrait;
+ Common::String numStr(portrait.c_str(), portrait.c_str() + 4);
+
+ if (locStr == numStr) {
+ talk._talkTo = idx;
+ break;
+ }
+ }
+
+ // Load their talk file
+ talk.loadTalkFile(dirFilename);
+ }
+ }
+
+ if (talk[0]._statement.hasPrefix("*") || talk[0]._statement.hasPrefix("^"))
+ replyOnly = true;
+
+ // If this isn't the first journal entry, see if the previous journal entry
+ // was in the same scene to see if we need to include the scene header
+ int oldLocation = -1;
+ if (_index != 0) {
+ // Get the scene number of the prior journal entry
+ Common::String priorEntry = _directory[_journal[_index - 1]._converseNum];
+ oldLocation = atoi(Common::String(priorEntry.c_str() + 4, priorEntry.c_str() + 6).c_str());
+ }
+
+ // Start building journal string
+ Statement &statement = talk[journalEntry._statementNum];
+ Common::String journalString;
+
+ if (newLocation != oldLocation) {
+ // Add in scene title
+ journalString = "@";
+ if (IS_SERRATED_SCALPEL || newLocation - 1 < 100)
+ journalString += _locations[newLocation - 1];
+ journalString += ":";
+
+ // See if title can fit into a single line, or requires splitting on 2 lines
+ int width = screen.stringWidth(journalString.c_str() + 1);
+ if (width > JOURNAL_MAX_WIDTH) {
+ // Scan backwards from end of title to find a space between a word
+ // where the width is less than the maximum allowed for the line
+ const char *lineP = journalString.c_str() + journalString.size() - 1;
+ while (width > JOURNAL_MAX_WIDTH || *lineP != ' ')
+ width -= screen.charWidth(*lineP--);
+
+ // Split the header into two lines, and add a '@' prefix
+ // to the second line as well
+ journalString = Common::String(journalString.c_str(), lineP) + "\n@" +
+ Common::String(lineP + 1);
+ }
+
+ // Add a newline at the end of the title
+ journalString += '\n';
+ }
+
+ // If Holmes has something to say first, then take care of it
+ if (!replyOnly) {
+ // Handle the grammar
+ journalString += "Holmes ";
+ if (talk[journalEntry._statementNum]._statement.hasSuffix("?"))
+ journalString += "asked ";
+ else
+ journalString += "said to ";
+
+ if (talk._talkTo == 1) {
+ journalString += "me";
+ } else if ((talk._talkTo == 2 && IS_SERRATED_SCALPEL) || (talk._talkTo == 18 && IS_ROSE_TATTOO)) {
+ journalString += "the Inspector";
+ } else {
+ journalString += people._characters[talk._talkTo]._name;
+ }
+ journalString += ", \"";
+
+ // Add the statement
+ journalString += statement._statement;
+ }
+
+ // Handle including the reply
+ bool startOfReply = true;
+ bool ctrlSpace = false;
+ bool commentFlag = false;
+ bool commentJustPrinted = false;
+ const byte *replyP = (const byte *)statement._reply.c_str();
+ const int inspectorId = (IS_SERRATED_SCALPEL) ? 2 : 18;
+
+ while (*replyP) {
+ byte c = *replyP++;
+
+ if (IS_ROSE_TATTOO) {
+ // Ignore commented out data
+ if (c == '/' && *(replyP + 1) == '*') {
+ replyP++; // skip *
+ while (*replyP++ != '*') {} // empty loop on purpose
+ replyP++; // skip /
+ c = *replyP;
+ }
+ }
+
+ // Is it a control character?
+ if (c < opcodes[0]) {
+ // Nope. Set flag for allowing control codes to insert spaces
+ ctrlSpace = true;
+ assert(c >= ' ');
+
+ // Check for embedded comments
+ if (c == '{' || c == '}') {
+
+ // TODO: Rose Tattoo checks if no text was added for the last
+ // comment here. In such a case, the last "XXX said" string is
+ // removed here.
+
+ // Comment characters. If we're starting a comment and there's
+ // already text displayed, add a closing quote
+ if (c == '{' && !startOfReply && !commentJustPrinted)
+ journalString += '"';
+
+ // If a reply isn't just being started, and we didn't just end
+ // a comment (which would have added a line), add a carriage return
+ if (!startOfReply && ((!commentJustPrinted && c == '{') || c == '}'))
+ journalString += '\n';
+ startOfReply = false;
+
+ // Handle setting or clearing comment state
+ if (c == '{') {
+ commentFlag = true;
+ commentJustPrinted = false;
+ } else {
+ commentFlag = false;
+ commentJustPrinted = true;
+ }
+ } else {
+ if (startOfReply) {
+ if (!replyOnly) {
+ journalString += "\"\n";
+
+ if (talk._talkTo == 1)
+ journalString += "I replied, \"";
+ else
+ journalString += "The reply was, \"";
+ } else {
+ if (talk._talkTo == 1)
+ journalString += "I";
+ else if (talk._talkTo == inspectorId)
+ journalString += "The Inspector";
+ else
+ journalString += people._characters[talk._talkTo]._name;
+
+ const byte *strP = replyP + 1;
+ byte v;
+ do {
+ v = *strP++;
+ } while (v && (v < opcodes[0]) && (v != '.') && (v != '!') && (v != '?'));
+
+ if (v == '?')
+ journalString += " asked, \"";
+ else
+ journalString += " said, \"";
+ }
+
+ startOfReply = false;
+ }
+
+ // Copy text from the place until either the reply ends, a comment
+ // {} block is started, or a control character is encountered
+ journalString += c;
+ do {
+ journalString += *replyP++;
+ } while (*replyP && *replyP < opcodes[0] && *replyP != '{' && *replyP != '}');
+
+ commentJustPrinted = false;
+ }
+ } else if (c == opcodes[OP_SWITCH_SPEAKER]) {
+ if (!startOfReply) {
+ if (!commentFlag && !commentJustPrinted)
+ journalString += "\"\n";
+
+ journalString += "Then ";
+ commentFlag = false;
+ } else if (!replyOnly) {
+ journalString += "\"\n";
+ }
+
+ startOfReply = false;
+ c = *replyP++ - 1;
+ if (IS_ROSE_TATTOO)
+ replyP++;
+
+ if (c == 0)
+ journalString += "Holmes";
+ else if (c == 1)
+ journalString += "I";
+ else if (c == inspectorId)
+ journalString += "the Inspector";
+ else
+ journalString += people._characters[c]._name;
+
+ const byte *strP = replyP;
+ byte v;
+ do {
+ v = *strP++;
+ } while (v && v < opcodes[0] && v != '.' && v != '!' && v != '?');
+
+ if (v == '?')
+ journalString += " asked, \"";
+ else
+ journalString += " said, \"";
+ } else {
+ if (IS_SERRATED_SCALPEL) {
+ // Control code, so move past it and any parameters
+ if (c == opcodes[OP_RUN_CANIMATION] ||
+ c == opcodes[OP_ASSIGN_PORTRAIT_LOCATION] ||
+ c == opcodes[OP_PAUSE] ||
+ c == opcodes[OP_PAUSE_WITHOUT_CONTROL] ||
+ c == opcodes[OP_WALK_TO_CANIMATION]) {
+ // These commands have a single parameter
+ ++replyP;
+ } else if (c == opcodes[OP_ADJUST_OBJ_SEQUENCE]) {
+ replyP += (replyP[0] & 127) + replyP[1] + 2;
+ } else if (c == opcodes[OP_WALK_TO_COORDS] || c == opcodes[OP_MOVE_MOUSE]) {
+ replyP += 4;
+ } else if (c == opcodes[OP_SET_FLAG] || c == opcodes[OP_IF_STATEMENT]) {
+ replyP += 2;
+ } else if (c == opcodes[OP_SFX_COMMAND] || c == opcodes[OP_PLAY_PROLOGUE] ||
+ c == opcodes[OP_CALL_TALK_FILE]) {
+ replyP += 8;
+ break;
+ } else if (
+ c == opcodes[OP_TOGGLE_OBJECT] ||
+ c == opcodes[OP_ADD_ITEM_TO_INVENTORY] ||
+ c == opcodes[OP_SET_OBJECT] ||
+ c == opcodes[OP_DISPLAY_INFO_LINE] ||
+ c == opcodes[OP_REMOVE_ITEM_FROM_INVENTORY]) {
+ replyP += (*replyP & 127) + 1;
+ } else if (c == opcodes[OP_GOTO_SCENE]) {
+ replyP += 5;
+ } else if (c == opcodes[OP_END_TEXT_WINDOW]) {
+ journalString += "\n";
+ }
+ } else {
+ if (c == opcodes[OP_RUN_CANIMATION] ||
+ c == opcodes[OP_PAUSE] ||
+ c == opcodes[OP_MOUSE_OFF_ON] ||
+ c == opcodes[OP_SET_WALK_CONTROL] ||
+ c == opcodes[OP_PAUSE_WITHOUT_CONTROL] ||
+ c == opcodes[OP_WALK_TO_CANIMATION] ||
+ c == opcodes[OP_TURN_NPC_OFF] ||
+ c == opcodes[OP_TURN_NPC_ON] ||
+ c == opcodes[OP_RESTORE_PEOPLE_SEQUENCE])
+ ++replyP;
+ else if (
+ c == opcodes[OP_SET_TALK_SEQUENCE] ||
+ c == opcodes[OP_SET_FLAG] ||
+ c == opcodes[OP_WALK_NPC_TO_CANIM] ||
+ c == opcodes[OP_WALK_HOLMES_AND_NPC_TO_CANIM] ||
+ c == opcodes[OP_NPC_PATH_LABEL] ||
+ c == opcodes[OP_PATH_GOTO_LABEL])
+ replyP += 2;
+ else if (
+ c == opcodes[OP_SET_NPC_PATH_PAUSE] ||
+ c == opcodes[OP_NPC_PATH_PAUSE_TAKING_NOTES] ||
+ c == opcodes[OP_NPC_PATH_PAUSE_LOOKING_HOLMES] ||
+ c == opcodes[OP_NPC_VERB_CANIM])
+ replyP += 3;
+ else if (
+ c == opcodes[OP_SET_SCENE_ENTRY_FLAG] ||
+ c == opcodes[OP_PATH_IF_FLAG_GOTO_LABEL])
+ replyP += 4;
+ else if (
+ c == opcodes[OP_WALK_TO_COORDS])
+ replyP += 5;
+ else if (
+ c == opcodes[OP_WALK_NPC_TO_COORDS] ||
+ c == opcodes[OP_GOTO_SCENE] ||
+ c == opcodes[OP_SET_NPC_PATH_DEST] ||
+ c == opcodes[OP_SET_NPC_POSITION])
+ replyP += 6;
+ else if (
+ c == opcodes[OP_PLAY_SONG] ||
+ c == opcodes[OP_NEXT_SONG])
+ replyP += 8;
+ else if (
+ c == opcodes[OP_CALL_TALK_FILE] ||
+ c == opcodes[OP_SET_NPC_TALK_FILE] ||
+ c == opcodes[OP_NPC_WALK_GRAPHICS])
+ replyP += 9;
+ else if (
+ c == opcodes[OP_NPC_VERB_SCRIPT])
+ replyP += 10;
+ else if (
+ c == opcodes[OP_WALK_HOLMES_AND_NPC_TO_COORDS])
+ replyP += 11;
+ else if (
+ c == opcodes[OP_NPC_VERB] ||
+ c == opcodes[OP_NPC_VERB_TARGET])
+ replyP += 14;
+ else if (
+ c == opcodes[OP_ADJUST_OBJ_SEQUENCE])
+ replyP += (replyP[0] & 127) + replyP[1] + 2;
+ else if (
+ c == opcodes[OP_TOGGLE_OBJECT] ||
+ c == opcodes[OP_ADD_ITEM_TO_INVENTORY] ||
+ c == opcodes[OP_SET_OBJECT] ||
+ c == opcodes[OP_REMOVE_ITEM_FROM_INVENTORY])
+ replyP += (*replyP & 127) + 1;
+ else if (
+ c == opcodes[OP_END_TEXT_WINDOW]) {
+ journalString += '\n';
+ } else if (
+ c == opcodes[OP_NPC_DESC_ON_OFF]) {
+ replyP++;
+ while (replyP[0] && replyP[0] != opcodes[OP_NPC_DESC_ON_OFF])
+ replyP++;
+ replyP++;
+ } else if (
+ c == opcodes[OP_SET_NPC_INFO_LINE])
+ replyP += replyP[1] + 2;
+ }
+
+ // Put a space in the output for a control character, unless it's
+ // immediately coming after another control character
+ if (ctrlSpace && c != opcodes[OP_ASSIGN_PORTRAIT_LOCATION] && c != opcodes[OP_END_TEXT_WINDOW] &&
+ !commentJustPrinted) {
+ journalString += " ";
+ ctrlSpace = false;
+ }
+ }
+ }
+
+ if (!startOfReply && !commentJustPrinted)
+ journalString += '"';
+
+ // Finally finished building the journal text. Need to process the text to
+ // word wrap it to fit on-screen. The resulting lines are stored in the
+ // _lines array
+ _lines.clear();
+
+ while (!journalString.empty()) {
+ const char *startP = journalString.c_str();
+
+ // If the first character is a '@' flagging a title line, then move
+ // past it, so the @ won't be included in the line width calculation
+ if (*startP == '@')
+ ++startP;
+
+ // Build up chacters until a full line is found
+ int width = 0;
+ const char *endP = startP;
+ while (width < JOURNAL_MAX_WIDTH && *endP && *endP != '\n' && (endP - startP) < (JOURNAL_MAX_CHARS - 1))
+ width += screen.charWidth(*endP++);
+
+ // If word wrapping, move back to end of prior word
+ if (width >= JOURNAL_MAX_WIDTH || (endP - startP) >= (JOURNAL_MAX_CHARS - 1)) {
+ while (*--endP != ' ')
+ ;
+ }
+
+ // Add in the line
+ _lines.push_back(Common::String(journalString.c_str(), endP));
+
+ // Strip line off from string being processed
+ journalString = *endP ? Common::String(endP + 1) : "";
+ }
+
+ // Add a blank line at the end of the text as long as text was present
+ if (!startOfReply) {
+ _lines.push_back("");
+ } else {
+ _lines.clear();
+ }
+}
+
+void Journal::synchronize(Serializer &s) {
+ s.syncAsSint16LE(_index);
+ s.syncAsSint16LE(_sub);
+ s.syncAsSint16LE(_page);
+ s.syncAsSint16LE(_maxPage);
+
+ int journalCount = _journal.size();
+ s.syncAsUint16LE(journalCount);
+ if (s.isLoading())
+ _journal.resize(journalCount);
+
+ for (uint idx = 0; idx < _journal.size(); ++idx) {
+ JournalEntry &je = _journal[idx];
+
+ s.syncAsSint16LE(je._converseNum);
+ s.syncAsByte(je._replyOnly);
+ s.syncAsSint16LE(je._statementNum);
+ }
+}
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/journal.h b/engines/sherlock/journal.h
new file mode 100644
index 0000000000..d2baae11a9
--- /dev/null
+++ b/engines/sherlock/journal.h
@@ -0,0 +1,105 @@
+/* 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 SHERLOCK_JOURNAL_H
+#define SHERLOCK_JOURNAL_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/rect.h"
+#include "common/str-array.h"
+#include "common/stream.h"
+#include "sherlock/saveload.h"
+
+namespace Sherlock {
+
+#define LINES_PER_PAGE (IS_SERRATED_SCALPEL ? 11 : 17)
+
+class SherlockEngine;
+
+struct JournalEntry {
+ int _converseNum;
+ bool _replyOnly;
+ int _statementNum;
+
+ JournalEntry() : _converseNum(0), _replyOnly(false), _statementNum(0) {}
+ JournalEntry(int converseNum, int statementNum, bool replyOnly = false) :
+ _converseNum(converseNum), _statementNum(statementNum), _replyOnly(replyOnly) {}
+};
+
+class Journal {
+protected:
+ SherlockEngine *_vm;
+ Common::StringArray _directory;
+ Common::StringArray _locations;
+ Common::Array<JournalEntry> _journal;
+ Common::StringArray _lines;
+ bool _up, _down;
+ int _index;
+ int _page;
+ int _maxPage;
+ int _sub;
+ Common::String _find;
+
+ Journal(SherlockEngine *vm);
+
+ /**
+ * Loads the description for the current display index in the journal, and then
+ * word wraps the result to prepare it for being displayed
+ * @param alreadyLoaded Indicates whether the journal file is being loaded for the
+ * first time, or being reloaded
+ */
+ void loadJournalFile(bool alreadyLoaded);
+public:
+ static Journal *init(SherlockEngine *vm);
+ virtual ~Journal() {}
+
+ /**
+ * Displays a page of the journal at the current index
+ */
+ bool drawJournal(int direction, int howFar);
+
+ /**
+ * Synchronize the data for a savegame
+ */
+ void synchronize(Serializer &s);
+public:
+ /**
+ * Draw the journal background, frame, and interface buttons
+ */
+ virtual void drawFrame() = 0;
+
+ /**
+ * Records statements that are said, in the order which they are said. The player
+ * can then read the journal to review them
+ */
+ virtual void record(int converseNum, int statementNum, bool replyOnly = false) {}
+
+ /**
+ * Reset viewing position to the start of the journal
+ */
+ virtual void resetPosition() {}
+};
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp
new file mode 100644
index 0000000000..fbccaf244f
--- /dev/null
+++ b/engines/sherlock/map.cpp
@@ -0,0 +1,52 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/system.h"
+#include "sherlock/map.h"
+#include "sherlock/sherlock.h"
+#include "sherlock/scalpel/scalpel_map.h"
+#include "sherlock/tattoo/tattoo_map.h"
+
+namespace Sherlock {
+
+Map *Map::init(SherlockEngine *vm) {
+ if (vm->getGameID() == GType_SerratedScalpel)
+ return new Scalpel::ScalpelMap(vm);
+ else
+ return new Tattoo::TattooMap(vm);
+}
+
+Map::Map(SherlockEngine *vm) : _vm(vm) {
+ _charPoint = _oldCharPoint = 0;
+ _active = _frameChangeFlag = false;
+}
+
+void Map::synchronize(Serializer &s) {
+ s.syncAsSint32LE(_bigPos.x);
+ s.syncAsSint32LE(_bigPos.y);
+ s.syncAsSint32LE(_overPos.x);
+ s.syncAsSint16LE(_overPos.y);
+ s.syncAsSint16LE(_oldCharPoint);
+}
+
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/map.h b/engines/sherlock/map.h
new file mode 100644
index 0000000000..104f5e9c8a
--- /dev/null
+++ b/engines/sherlock/map.h
@@ -0,0 +1,61 @@
+/* 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 SHERLOCK_MAP_H
+#define SHERLOCK_MAP_H
+
+#include "sherlock/objects.h"
+#include "sherlock/saveload.h"
+
+namespace Sherlock {
+
+class SherlockEngine;
+
+class Map {
+protected:
+ SherlockEngine *_vm;
+
+ Map(SherlockEngine *vm);
+public:
+ Point32 _overPos;
+ Point32 _bigPos;
+ int _charPoint, _oldCharPoint;
+ bool _active;
+ bool _frameChangeFlag;
+public:
+ static Map *init(SherlockEngine *vm);
+ virtual ~Map() {}
+
+ /**
+ * Show the map
+ */
+ virtual int show() = 0;
+
+ /**
+ * Synchronize the data for a savegame
+ */
+ void synchronize(Serializer &s);
+};
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/module.mk b/engines/sherlock/module.mk
new file mode 100644
index 0000000000..32c5d3acc3
--- /dev/null
+++ b/engines/sherlock/module.mk
@@ -0,0 +1,71 @@
+MODULE := engines/sherlock
+
+MODULE_OBJS = \
+ scalpel/darts.o \
+ scalpel/scalpel.o \
+ scalpel/3do/movie_decoder.o \
+ scalpel/drivers/adlib.o \
+ scalpel/drivers/mt32.o \
+ scalpel/tsage/logo.o \
+ scalpel/tsage/resources.o \
+ scalpel/scalpel_debugger.o \
+ scalpel/scalpel_fixed_text.o \
+ scalpel/scalpel_inventory.o \
+ scalpel/scalpel_journal.o \
+ scalpel/scalpel_map.o \
+ scalpel/scalpel_people.o \
+ scalpel/scalpel_saveload.o \
+ scalpel/scalpel_scene.o \
+ scalpel/scalpel_screen.o \
+ scalpel/scalpel_talk.o \
+ scalpel/scalpel_user_interface.o \
+ scalpel/settings.o \
+ tattoo/tattoo.o \
+ tattoo/tattoo_darts.o \
+ tattoo/tattoo_debugger.o \
+ tattoo/tattoo_fixed_text.o \
+ tattoo/tattoo_inventory.o \
+ tattoo/tattoo_journal.o \
+ tattoo/tattoo_map.o \
+ tattoo/tattoo_people.o \
+ tattoo/tattoo_resources.o \
+ tattoo/tattoo_scene.o \
+ tattoo/tattoo_talk.o \
+ tattoo/tattoo_user_interface.o \
+ tattoo/widget_base.o \
+ tattoo/widget_inventory.o \
+ tattoo/widget_lab.o \
+ tattoo/widget_talk.o \
+ tattoo/widget_text.o \
+ tattoo/widget_tooltip.o \
+ tattoo/widget_verbs.o \
+ animation.o \
+ debugger.o \
+ detection.o \
+ events.o \
+ fixed_text.o \
+ fonts.o \
+ image_file.o \
+ inventory.o \
+ journal.o \
+ map.o \
+ music.o \
+ objects.o \
+ people.o \
+ resources.o \
+ saveload.o \
+ scene.o \
+ screen.o \
+ sherlock.o \
+ sound.o \
+ surface.o \
+ talk.o \
+ user_interface.o
+
+# This module can be built as a plugin
+ifeq ($(ENABLE_SHERLOCK), DYNAMIC_PLUGIN)
+PLUGIN := 1
+endif
+
+# Include common rules
+include $(srcdir)/rules.mk
diff --git a/engines/sherlock/music.cpp b/engines/sherlock/music.cpp
new file mode 100644
index 0000000000..49c48126f4
--- /dev/null
+++ b/engines/sherlock/music.cpp
@@ -0,0 +1,598 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/config-manager.h"
+#include "common/mutex.h"
+#include "sherlock/sherlock.h"
+#include "sherlock/music.h"
+#include "sherlock/scalpel/drivers/mididriver.h"
+// for Miles Audio (Sherlock Holmes 2)
+#include "audio/miles.h"
+// for 3DO digital music
+#include "audio/decoders/aiff.h"
+
+namespace Sherlock {
+
+#define NUM_SONGS 45
+
+/* This tells which song to play in each room, 0 = no song played */
+static const char ROOM_SONG[62] = {
+ 0, 20, 43, 6, 11, 2, 8, 15, 6, 28,
+ 6, 38, 7, 32, 16, 5, 8, 41, 9, 22,
+ 10, 23, 4, 39, 19, 24, 13, 27, 0, 30,
+ 3, 21, 26, 25, 16, 29, 1, 1, 18, 12,
+ 1, 17, 17, 31, 17, 34, 36, 7, 20, 20,
+ 33, 8, 44, 40, 42, 35, 0, 0, 0, 12,
+ 12
+};
+
+static const char *const SONG_NAMES[NUM_SONGS] = {
+ "SINGERF", "CHEMIST", "TOBAC", "EQUEST", "MORTUARY", "DOCKS", "LSTUDY",
+ "LORD", "BOY", "PERFUM1", "BAKER1", "BAKER2", "OPERA1", "HOLMES",
+ "FFLAT", "OP1FLAT", "ZOO", "SROOM", "FLOWERS", "YARD", "TAXID",
+ "PUB1", "VICTIM", "RUGBY", "DORM", "SHERMAN", "LAWYER", "THEATRE",
+ "DETECT", "OPERA4", "POOL", "SOOTH", "ANNA1", "ANNA2", "PROLOG3",
+ "PAWNSHOP", "MUSICBOX", "MOZART1", "ROBHUNT", "PANCRAS1", "PANCRAS2", "LORDKILL",
+ "BLACKWEL", "RESCUE", "MAP"
+};
+
+MidiParser_SH::MidiParser_SH() {
+ _ppqn = 1;
+ setTempo(16667);
+ _data = nullptr;
+ _beats = 0;
+ _lastEvent = 0;
+ _trackEnd = nullptr;
+
+ _musData = nullptr;
+ _musDataSize = 0;
+}
+
+MidiParser_SH::~MidiParser_SH() {
+ Common::StackLock lock(_mutex);
+ unloadMusic();
+ _driver = NULL;
+}
+
+void MidiParser_SH::parseNextEvent(EventInfo &info) {
+ Common::StackLock lock(_mutex);
+
+// warning("parseNextEvent");
+
+ // there is no delta right at the start of the music data
+ // this order is essential, otherwise notes will get delayed or even go missing
+ if (_position._playPos != _tracks[0]) {
+ info.delta = *(_position._playPos++);
+ } else {
+ info.delta = 0;
+ }
+
+ info.start = _position._playPos;
+
+ info.event = *_position._playPos++;
+ //warning("Event %x", info.event);
+ _position._runningStatus = info.event;
+
+ switch (info.command()) {
+ case 0xC: { // program change
+ int idx = *_position._playPos++;
+ info.basic.param1 = idx & 0x7f;
+ info.basic.param2 = 0;
+ }
+ break;
+ case 0xD:
+ info.basic.param1 = *_position._playPos++;
+ info.basic.param2 = 0;
+ break;
+
+ case 0xB:
+ info.basic.param1 = *_position._playPos++;
+ info.basic.param2 = *_position._playPos++;
+ info.length = 0;
+ break;
+
+ case 0x8:
+ case 0x9:
+ case 0xA:
+ case 0xE:
+ info.basic.param1 = *(_position._playPos++);
+ info.basic.param2 = *(_position._playPos++);
+ if (info.command() == 0x9 && info.basic.param2 == 0) {
+ // NoteOn with param2==0 is a NoteOff
+ info.event = info.channel() | 0x80;
+ }
+ info.length = 0;
+ break;
+ case 0xF:
+ if (info.event == 0xFF) {
+ error("SysEx META event 0xFF");
+
+ byte type = *(_position._playPos++);
+ switch(type) {
+ case 0x2F:
+ // End of Track
+ allNotesOff();
+ stopPlaying();
+ unloadMusic();
+ return;
+ case 0x51:
+ warning("TODO: 0xFF / 0x51");
+ return;
+ default:
+ warning("TODO: 0xFF / %x Unknown", type);
+ break;
+ }
+ } else if (info.event == 0xFC) {
+ // Official End-Of-Track signal
+ debugC(kDebugLevelMusic, "Music: System META event 0xFC");
+
+ byte type = *(_position._playPos++);
+ switch (type) {
+ case 0x80: // end of track, triggers looping
+ debugC(kDebugLevelMusic, "Music: META event triggered looping");
+ jumpToTick(0, true, true, false);
+ break;
+ case 0x81: // end of track, stop playing
+ debugC(kDebugLevelMusic, "Music: META event triggered music stop");
+ stopPlaying();
+ unloadMusic();
+ break;
+ default:
+ error("MidiParser_SH::parseNextEvent: Unknown META event 0xFC type %x", type);
+ break;
+ }
+ } else {
+ warning("TODO: %x / Unknown", info.event);
+ break;
+ }
+ break;
+ default:
+ warning("MidiParser_SH::parseNextEvent: Unsupported event code %x", info.event);
+ break;
+ }// switch (info.command())
+}
+
+bool MidiParser_SH::loadMusic(byte *musData, uint32 musDataSize) {
+ Common::StackLock lock(_mutex);
+
+ debugC(kDebugLevelMusic, "Music: loadMusic()");
+ unloadMusic();
+
+ _musData = musData;
+ _musDataSize = musDataSize;
+
+ 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
+
+ // Skip over header
+ pos += headerSize;
+
+ _lastEvent = 0;
+ _trackEnd = _musData + _musDataSize;
+
+ _numTracks = 1;
+ _tracks[0] = pos;
+
+ _ppqn = 1;
+ setTempo(16667);
+ setTrack(0);
+
+ return true;
+}
+
+void MidiParser_SH::unloadMusic() {
+ Common::StackLock lock(_mutex);
+
+ if (_musData) {
+ delete[] _musData;
+ _musData = NULL;
+ _musDataSize = 0;
+ }
+
+ MidiParser::unloadMusic();
+}
+
+/*----------------------------------------------------------------*/
+
+Music::Music(SherlockEngine *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer) {
+ _midiDriver = NULL;
+ _midiParser = NULL;
+ _musicType = MT_NULL;
+ _musicPlaying = false;
+ _musicOn = false;
+ _midiOption = false;
+ _musicVolume = 0;
+
+ if (IS_3DO) {
+ // 3DO - uses digital samples for music
+ _musicOn = true;
+ return;
+ }
+
+ if (_vm->_interactiveFl)
+ _vm->_res->addToCache("MUSIC.LIB");
+
+ MidiDriver::DeviceHandle dev;
+
+ if (IS_SERRATED_SCALPEL) {
+ // Serrated Scalpel: used an internal Electronic Arts .MUS music engine
+ _midiParser = new MidiParser_SH();
+ dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MT32);
+ _musicType = MidiDriver::getMusicType(dev);
+
+ switch (_musicType) {
+ case MT_ADLIB:
+ _midiDriver = MidiDriver_SH_AdLib_create();
+ break;
+ case MT_MT32:
+ _midiDriver = MidiDriver_MT32_create();
+ break;
+ case MT_GM:
+ if (ConfMan.getBool("native_mt32")) {
+ _midiDriver = MidiDriver_MT32_create();
+ _musicType = MT_MT32;
+ }
+ break;
+ default:
+ // Create default one
+ // I guess we shouldn't do this anymore
+ //_midiDriver = MidiDriver::createMidi(dev);
+ break;
+ }
+ } else {
+ // Rose Tattooo: seems to use Miles Audio 3
+ _midiParser = MidiParser::createParser_XMIDI();
+ dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
+ _musicType = MidiDriver::getMusicType(dev);
+
+ switch (_musicType) {
+ case MT_ADLIB:
+ // SAMPLE.AD -> regular AdLib instrument data
+ // SAMPLE.OPL -> OPL-3 instrument data
+ // although in case of Rose Tattoo both files are exactly the same
+ _midiDriver = Audio::MidiDriver_Miles_AdLib_create("SAMPLE.AD", "SAMPLE.OPL");
+ break;
+ case MT_MT32:
+ // Sherlock Holmes 2 does not have a MT32 timbre file
+ _midiDriver = Audio::MidiDriver_Miles_MT32_create("");
+ break;
+ case MT_GM:
+ if (ConfMan.getBool("native_mt32")) {
+ _midiDriver = Audio::MidiDriver_Miles_MT32_create("");
+ _musicType = MT_MT32;
+ } else {
+ _midiDriver = MidiDriver::createMidi(dev);
+ _musicType = MT_GM;
+ }
+ break;
+ default:
+ // Do not create anything
+ break;
+ }
+ }
+
+ if (_midiDriver) {
+ int ret = _midiDriver->open();
+ if (ret == 0) {
+ // Reset is done inside our MIDI driver
+ _midiDriver->setTimerCallback(_midiParser, &_midiParser->timerCallback);
+ }
+ _midiParser->setMidiDriver(_midiDriver);
+ _midiParser->setTimerRate(_midiDriver->getBaseTempo());
+
+ if (IS_SERRATED_SCALPEL) {
+ if (_musicType == MT_MT32) {
+ // Upload patches
+ Common::SeekableReadStream *MT32driverStream = _vm->_res->load("MTHOM.DRV", "MUSIC.LIB");
+
+ if (!MT32driverStream)
+ error("Music: could not load MTHOM.DRV, critical");
+
+ byte *MT32driverData = new byte[MT32driverStream->size()];
+ int32 MT32driverDataSize = MT32driverStream->size();
+ assert(MT32driverData);
+
+ MT32driverStream->read(MT32driverData, MT32driverDataSize);
+ delete MT32driverStream;
+
+ assert(MT32driverDataSize > 12);
+ byte *MT32driverDataPtr = MT32driverData + 12;
+ MT32driverDataSize -= 12;
+
+ MidiDriver_MT32_uploadPatches(_midiDriver, MT32driverDataPtr, MT32driverDataSize);
+ delete[] MT32driverData;
+ }
+ }
+
+ _musicOn = true;
+ }
+}
+
+Music::~Music() {
+ stopMusic();
+ if (_midiDriver) {
+ _midiDriver->setTimerCallback(this, NULL);
+ }
+ if (_midiParser) {
+ _midiParser->stopPlaying();
+ delete _midiParser;
+ _midiParser = nullptr;
+ }
+ if (_midiDriver) {
+ _midiDriver->close();
+ delete _midiDriver;
+ }
+}
+
+bool Music::loadSong(int songNumber) {
+ debugC(kDebugLevelMusic, "Music: loadSong()");
+
+ if(songNumber == 100)
+ songNumber = 55;
+ else if(songNumber == 70)
+ songNumber = 54;
+
+ if((songNumber > 60) || (songNumber < 1))
+ return false;
+
+ songNumber = ROOM_SONG[songNumber];
+
+ if(songNumber == 0)
+ songNumber = 12;
+
+ if((songNumber > NUM_SONGS) || (songNumber < 1))
+ return false;
+
+ Common::String songName = Common::String(SONG_NAMES[songNumber - 1]);
+
+ freeSong(); // free any song that is currently loaded
+ stopMusic();
+
+ if (!playMusic(songName))
+ return false;
+
+ startSong();
+ return true;
+}
+
+bool Music::loadSong(const Common::String &songName) {
+ freeSong(); // free any song that is currently loaded
+ stopMusic();
+
+ if (!playMusic(songName))
+ return false;
+
+ startSong();
+ return true;
+}
+
+void Music::syncMusicSettings() {
+ _musicOn = !ConfMan.getBool("mute") && !ConfMan.getBool("music_mute");
+}
+
+bool Music::playMusic(const Common::String &name) {
+ if (!_musicOn)
+ return false;
+
+ debugC(kDebugLevelMusic, "Music: playMusic('%s')", name.c_str());
+
+ if (!IS_3DO) {
+ // MIDI based
+ if (!_midiDriver)
+ return false;
+
+ Common::String midiMusicName = (IS_SERRATED_SCALPEL) ? name + ".MUS" : name + ".XMI";
+ Common::SeekableReadStream *stream = _vm->_res->load(midiMusicName, "MUSIC.LIB");
+
+ byte *midiMusicData = new byte[stream->size()];
+ int32 midiMusicDataSize = stream->size();
+
+ stream->read(midiMusicData, midiMusicDataSize);
+ delete stream;
+
+ // for dumping the music tracks
+#if 0
+ Common::DumpFile outFile;
+ outFile.open(name + ".RAW");
+ outFile.write(data, stream->size());
+ outFile.flush();
+ outFile.close();
+#endif
+
+ if (midiMusicDataSize < 14) {
+ warning("Music: not enough data in music file");
+ delete[] midiMusicData;
+ return false;
+ }
+
+ byte *dataPos = midiMusicData;
+ uint32 dataSize = midiMusicDataSize;
+
+ if (IS_SERRATED_SCALPEL) {
+ if (memcmp(" ", dataPos, 12)) {
+ warning("Music: expected header not found in music file");
+ delete[] midiMusicData;
+ return false;
+ }
+ dataPos += 12;
+ dataSize -= 12;
+
+ if (dataSize < 0x7F) {
+ warning("Music: expected music header not found in music file");
+ delete[] midiMusicData;
+ return false;
+ }
+
+ uint16 headerSize = READ_LE_UINT16(dataPos);
+ if (headerSize != 0x7F) {
+ warning("Music: header is not as expected");
+ delete[] midiMusicData;
+ return false;
+ }
+ } else {
+ if (memcmp("FORM", dataPos, 4)) {
+ warning("Music: expected header not found in music file");
+ delete[] midiMusicData;
+ return false;
+ }
+ }
+
+ if (IS_SERRATED_SCALPEL) {
+ // Pass the music data to the driver as well
+ // because channel mapping and a few other things inside the header
+ switch (_musicType) {
+ case MT_ADLIB:
+ MidiDriver_SH_AdLib_newMusicData(_midiDriver, dataPos, dataSize);
+ break;
+
+ case MT_MT32:
+ MidiDriver_MT32_newMusicData(_midiDriver, dataPos, dataSize);
+ break;
+
+ default:
+ // should never happen
+ break;
+ }
+ }
+
+ _midiParser->loadMusic(midiMusicData, midiMusicDataSize);
+
+ } else {
+ // 3DO: sample based
+ Audio::AudioStream *musicStream;
+ Common::String digitalMusicName = "music/" + name + "_MW22.aifc";
+
+ if (isPlaying()) {
+ _mixer->stopHandle(_digitalMusicHandle);
+ }
+
+ Common::File *digitalMusicFile = new Common::File();
+ if (!digitalMusicFile->open(digitalMusicName)) {
+ warning("playMusic: can not open 3DO music '%s'", digitalMusicName.c_str());
+ return false;
+ }
+
+ // Try to load the given file as AIFF/AIFC
+ musicStream = Audio::makeAIFFStream(digitalMusicFile, DisposeAfterUse::YES);
+ if (!musicStream) {
+ warning("playMusic: can not load 3DO music '%s'", digitalMusicName.c_str());
+ return false;
+ }
+ _mixer->playStream(Audio::Mixer::kMusicSoundType, &_digitalMusicHandle, musicStream);
+ }
+ return true;
+}
+
+void Music::stopMusic() {
+ freeSong();
+}
+
+void Music::startSong() {
+ if (!_musicOn)
+ return;
+
+ // TODO
+ warning("TODO: Sound::startSong");
+ _musicPlaying = true;
+}
+
+void Music::freeSong() {
+ if (!IS_3DO) {
+ if (_midiParser->isPlaying())
+ _midiParser->stopPlaying();
+
+ // Free the MIDI MUS data buffer
+ _midiParser->unloadMusic();
+ }
+
+ _musicPlaying = false;
+}
+
+void Music::waitTimerRoland(uint time) {
+ // TODO
+ warning("TODO: Sound::waitTimerRoland");
+}
+
+bool Music::isPlaying() {
+ if (!IS_3DO) {
+ // MIDI based
+ return _midiParser->isPlaying();
+ } else {
+ // 3DO: sample based
+ return _mixer->isSoundHandleActive(_digitalMusicHandle);
+ }
+}
+
+// Returns the current music position in milliseconds
+uint32 Music::getCurrentPosition() {
+ if (!IS_3DO) {
+ // MIDI based
+ return (_midiParser->getTick() * 1000) / 60; // translate tick to millisecond
+ } else {
+ // 3DO: sample based
+ return _mixer->getSoundElapsedTime(_digitalMusicHandle);
+ }
+}
+
+// This is used to wait for the music in certain situations like especially the intro
+// Note: the original game didn't do this, instead it just waited for certain amounts of time
+// We do this, so that the intro graphics + music work together even on faster/slower hardware.
+bool Music::waitUntilMSec(uint32 msecTarget, uint32 msecMax, uint32 additionalDelay, uint32 noMusicDelay) {
+ uint32 msecCurrent = 0;
+
+ if (!isPlaying()) {
+ return _vm->_events->delay(noMusicDelay, true);
+ }
+ while (1) {
+ if (!isPlaying()) { // Music is not playing anymore -> we are done
+ if (additionalDelay > 0) {
+ if (!_vm->_events->delay(additionalDelay, true))
+ return false;
+ }
+ return true;
+ }
+
+ msecCurrent = getCurrentPosition();
+ //warning("waitUntilMSec: %lx", msecCurrent);
+
+ if ((!msecMax) || (msecCurrent <= msecMax)) {
+ if (msecCurrent >= msecTarget) {
+ if (additionalDelay > 0) {
+ if (!_vm->_events->delay(additionalDelay, true))
+ return false;
+ }
+ return true;
+ }
+ }
+ if (!_vm->_events->delay(10, true))
+ return false;
+ }
+}
+
+void Music::setMIDIVolume(int volume) {
+ warning("TODO: Music::setMIDIVolume");
+}
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/music.h b/engines/sherlock/music.h
new file mode 100644
index 0000000000..93c565c162
--- /dev/null
+++ b/engines/sherlock/music.h
@@ -0,0 +1,131 @@
+/* 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 SHERLOCK_MUSIC_H
+#define SHERLOCK_MUSIC_H
+
+#include "audio/midiplayer.h"
+#include "audio/midiparser.h"
+//#include "audio/mididrv.h"
+#include "sherlock/scalpel/drivers/mididriver.h"
+// for 3DO digital music
+#include "audio/audiostream.h"
+#include "audio/mixer.h"
+#include "common/mutex.h"
+
+namespace Sherlock {
+
+class SherlockEngine;
+
+class MidiParser_SH : public MidiParser {
+public:
+ MidiParser_SH();
+ ~MidiParser_SH();
+
+protected:
+ Common::Mutex _mutex;
+ void parseNextEvent(EventInfo &info);
+
+ uint8 _beats;
+ uint8 _lastEvent;
+ byte *_data;
+ byte *_trackEnd;
+
+public:
+ bool loadMusic(byte *musData, uint32 musSize);
+ virtual void unloadMusic();
+
+private:
+ byte *_musData;
+ uint32 _musDataSize;
+};
+
+class Music {
+private:
+ SherlockEngine *_vm;
+ Audio::Mixer *_mixer;
+ MidiParser *_midiParser;
+ MidiDriver *_midiDriver;
+ Audio::SoundHandle _digitalMusicHandle;
+ MusicType _musicType;
+
+ /**
+ * Play the specified music resource
+ */
+ bool playMusic(const Common::String &name);
+public:
+ bool _musicPlaying;
+ bool _musicOn;
+ int _musicVolume;
+ bool _midiOption;
+ Common::String _currentSongName, _nextSongName;
+public:
+ Music(SherlockEngine *vm, Audio::Mixer *mixer);
+ ~Music();
+
+ /**
+ * Saves sound-related settings
+ */
+ void syncMusicSettings();
+
+ /**
+ * Load a specified song
+ */
+ bool loadSong(int songNumber);
+
+ /**
+ * Load a specified song
+ */
+ bool loadSong(const Common::String &songName);
+
+ /**
+ * Start playing a song
+ */
+ void startSong();
+
+ /**
+ * Free any currently loaded song
+ */
+ void freeSong();
+
+ /**
+ * Stop playing the music
+ */
+ void stopMusic();
+
+ void waitTimerRoland(uint time);
+
+ bool isPlaying();
+ uint32 getCurrentPosition();
+
+ bool waitUntilMSec(uint32 msecTarget, uint32 maxMSec, uint32 additionalDelay, uint32 noMusicDelay);
+
+ /**
+ * Sets the volume of the MIDI music with a value ranging from 0 to 127
+ */
+ void setMIDIVolume(int volume);
+};
+
+} // End of namespace Sherlock
+
+#endif
+
diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp
new file mode 100644
index 0000000000..6ef08c28cc
--- /dev/null
+++ b/engines/sherlock/objects.cpp
@@ -0,0 +1,1533 @@
+/* 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/util.h"
+#include "sherlock/objects.h"
+#include "sherlock/people.h"
+#include "sherlock/scene.h"
+#include "sherlock/scalpel/scalpel.h"
+#include "sherlock/scalpel/scalpel_map.h"
+#include "sherlock/scalpel/scalpel_people.h"
+#include "sherlock/tattoo/tattoo.h"
+
+namespace Sherlock {
+
+#define START_FRAME 0
+
+#define NUM_ADJUSTED_WALKS 21
+
+// Distance to walk around WALK_AROUND boxes
+#define CLEAR_DIST_X 5
+#define CLEAR_DIST_Y 0
+
+#define ADJUST_COORD(COORD) \
+ if (COORD.x != -1) \
+ COORD.x *= FIXED_INT_MULTIPLIER; \
+ if (COORD.y != -1) \
+ COORD.y *= FIXED_INT_MULTIPLIER
+
+SherlockEngine *BaseObject::_vm;
+bool BaseObject::_countCAnimFrames;
+
+/*----------------------------------------------------------------*/
+
+void BaseObject::setVm(SherlockEngine *vm) {
+ _vm = vm;
+ _countCAnimFrames = false;
+}
+
+BaseObject::BaseObject() {
+ _type = INVALID;
+ _sequences = nullptr;
+ _images = nullptr;
+ _imageFrame = nullptr;
+ _walkCount = 0;
+ _allow = 0;
+ _frameNumber = 0;
+ _lookFlag = 0;
+ _requiredFlag[0] = _requiredFlag[1] = 0;
+ _status = 0;
+ _misc = 0;
+ _maxFrames = 0;
+ _flags = 0;
+ _aType = OBJECT;
+ _lookFrames = 0;
+ _seqCounter = 0;
+ _lookcAnim = 0;
+ _seqStack = 0;
+ _seqTo = 0;
+ _descOffset = 0;
+ _seqCounter2 = 0;
+ _seqSize = 0;
+ _quickDraw = 0;
+ _scaleVal = 0;
+ _gotoSeq = 0;
+ _talkSeq = 0;
+ _restoreSlot = 0;
+}
+
+bool BaseObject::hasAborts() const {
+ int seqNum = _talkSeq;
+
+ // See if the object is in it's regular sequence
+ bool startChecking = !seqNum || _type == CHARACTER;
+
+ uint idx = 0;
+ do
+ {
+ // Get the Frame value
+ int v = _sequences[idx++];
+
+ // See if we found an Allow Talk Interrupt Code
+ if (startChecking && v == ALLOW_TALK_CODE)
+ return true;
+
+ // If we've started checking and we've encountered another Talk or Listen Sequence Code,
+ // then we're done checking this sequence because this is where it would repeat
+ if (startChecking && (v == TALK_SEQ_CODE || v == TALK_LISTEN_CODE))
+ return false;
+
+ // See if we've found the beginning of a Talk Sequence
+ if ((v == TALK_SEQ_CODE && seqNum < 128) || (v == TALK_LISTEN_CODE && seqNum >= 128)) {
+ // If checking was already on and we came across one of these codes, then there couldn't
+ // have been an Allow Talk Interrupt code in the sequence we were checking, so we're done.
+ if (startChecking)
+ return false;
+
+ seqNum--;
+ // See if we're at the correct Talk Sequence Number
+ if (!(seqNum & 127))
+ {
+ // Correct Sequence, Start Checking Now
+ startChecking = true;
+ }
+ } else {
+ // Move ahead any extra because of special control codes
+ switch (v) {
+ case 0: idx++; break;
+ case MOVE_CODE:
+ case TELEPORT_CODE: idx += 4; break;
+ case CALL_TALK_CODE:idx += 8; break;
+ case HIDE_CODE: idx += 2; break;
+ }
+ }
+ } while (idx < _seqSize);
+
+ return true;
+}
+
+void BaseObject::checkObject() {
+ Scene &scene = *_vm->_scene;
+ Sound &sound = *_vm->_sound;
+ Talk &talk = *_vm->_talk;
+ int checkFrame = _allow ? MAX_FRAME : FRAMES_END;
+ bool codeFound;
+
+ if (_seqTo) {
+ byte *ptr = &_sequences[_frameNumber];
+ if (*ptr == _seqTo) {
+ // The sequence is completed. Reset to normal
+ *ptr = _seqTo + (IS_ROSE_TATTOO ? 0 : SEQ_TO_CODE + 128);
+ _seqTo = 0;
+ } else {
+ // Continue doing sequence
+ if (*ptr > _seqTo)
+ *ptr -= 1;
+ else
+ *ptr += 1;
+
+ return;
+ }
+ }
+
+ ++_frameNumber;
+
+ do {
+ if (!_sequences) {
+ warning("checkObject: _sequences is not set");
+ break;
+ }
+
+ // Check for end of sequence
+ codeFound = checkEndOfSequence();
+
+ if (_sequences[_frameNumber] >= 128 && _frameNumber < checkFrame) {
+ codeFound = true;
+ int v = _sequences[_frameNumber];
+
+ // Check for a Talk or Listen Sequence
+ if (IS_ROSE_TATTOO && v == ALLOW_TALK_CODE) {
+ if (_gotoSeq) {
+ setObjTalkSequence(_gotoSeq);
+ } else {
+ ++_frameNumber;
+ }
+ } else if (IS_ROSE_TATTOO && (v == TALK_SEQ_CODE || v == TALK_LISTEN_CODE)) {
+ if (_talkSeq)
+ setObjTalkSequence(_talkSeq);
+ else
+ setObjSequence(0, false);
+ } else if (v >= GOTO_CODE) {
+ // Goto code found
+ v -= GOTO_CODE;
+ _seqCounter2 = _seqCounter;
+ _seqStack = _frameNumber + 1;
+ setObjSequence(v, false);
+ } else if (v >= SOUND_CODE && (v < (SOUND_CODE + 30))) {
+ codeFound = true;
+ ++_frameNumber;
+ v -= SOUND_CODE + (IS_SERRATED_SCALPEL ? 1 : 0);
+
+ if (sound._soundOn && !_countCAnimFrames) {
+ if (!scene._sounds[v]._name.empty() && sound._digitized)
+ sound.playLoadedSound(v, WAIT_RETURN_IMMEDIATELY);
+ }
+ } else if (v >= FLIP_CODE && v < (FLIP_CODE + 3)) {
+ // Flip code
+ codeFound = true;
+ ++_frameNumber;
+ v -= FLIP_CODE;
+
+ // Alter the flipped status
+ switch (v) {
+ case 0:
+ // Clear the flag
+ _flags &= ~OBJ_FLIPPED;
+ break;
+ case 1:
+ // Set the flag
+ _flags |= OBJ_FLIPPED;
+ break;
+ case 2:
+ // Toggle the flag
+ _flags ^= OBJ_FLIPPED;
+ break;
+ default:
+ break;
+ }
+ } else if (IS_ROSE_TATTOO && v == TELEPORT_CODE) {
+ _position.x = READ_LE_UINT16(&_sequences[_frameNumber + 1]);
+ _position.y = READ_LE_UINT16(&_sequences[_frameNumber + 3]);
+
+ _frameNumber += 5;
+ } else if (IS_ROSE_TATTOO && v == CALL_TALK_CODE) {
+ Common::String filename;
+ for (int idx = 0; idx < 8; ++idx) {
+ if (_sequences[_frameNumber + 1 + idx] != 1)
+ filename += (char)_sequences[_frameNumber + 1 + idx];
+ else
+ break;
+ }
+
+ _frameNumber += 8;
+ talk.talkTo(filename);
+
+ } else if (IS_ROSE_TATTOO && v == HIDE_CODE) {
+ switch (_sequences[_frameNumber + 2]) {
+ case 1:
+ // Hide Object
+ if (scene._bgShapes[_sequences[_frameNumber + 1] - 1]._type != HIDDEN)
+ scene._bgShapes[_sequences[_frameNumber + 1] - 1].toggleHidden();
+ break;
+
+ case 2:
+ // Activate Object
+ if (scene._bgShapes[_sequences[_frameNumber + 1] - 1]._type == HIDDEN)
+ scene._bgShapes[_sequences[_frameNumber + 1] - 1].toggleHidden();
+ break;
+
+ case 3:
+ // Toggle Object
+ scene._bgShapes[_sequences[_frameNumber + 1] - 1].toggleHidden();
+ break;
+
+ default:
+ break;
+ }
+ _frameNumber += 3;
+
+ } else {
+ v -= 128;
+
+ // 68-99 is a sequence code
+ if (v > SEQ_TO_CODE) {
+ if (IS_ROSE_TATTOO) {
+ ++_frameNumber;
+ byte *p = &_sequences[_frameNumber];
+ _seqTo = *p;
+ *p = *(p - 2);
+
+ if (*p > _seqTo)
+ *p -= 1;
+ else
+ *p += 1;
+
+ --_frameNumber;
+ } else {
+ byte *p = &_sequences[_frameNumber];
+ v -= SEQ_TO_CODE; // # from 1-32
+ _seqTo = v;
+ *p = *(p - 1);
+
+ if (*p > 128)
+ // If the high bit is set, convert to a real frame
+ *p -= (byte)(SEQ_TO_CODE - 128);
+
+ if (*p > _seqTo)
+ *p -= 1;
+ else
+ *p += 1;
+
+ // Will be incremented below to return back to original value
+ --_frameNumber;
+ v = 0;
+ }
+ } else if (IS_ROSE_TATTOO && v == 10) {
+ // Set delta for objects
+ _delta = Common::Point(READ_LE_UINT16(&_sequences[_frameNumber + 1]),
+ READ_LE_UINT16(&_sequences[_frameNumber + 3]));
+ _noShapeSize = Common::Point(0, 0);
+ _frameNumber += 4;
+
+ } else if (v == 10) {
+ // Set delta for objects
+ Common::Point pt(_sequences[_frameNumber + 1], _sequences[_frameNumber + 2]);
+ if (pt.x > 128)
+ pt.x = (pt.x - 128) * -1;
+ else
+ pt.x--;
+
+ if (pt.y > 128)
+ pt.y = (pt.y - 128) * -1;
+ else
+ pt.y--;
+
+ _delta = pt;
+ _frameNumber += 2;
+
+ } else if (v < USE_COUNT) {
+ for (int idx = 0; idx < NAMES_COUNT; ++idx) {
+ checkNameForCodes(_use[v]._names[idx]);
+ }
+
+ if (_use[v]._useFlag)
+ _vm->setFlags(_use[v]._useFlag);
+ }
+
+ ++_frameNumber;
+ }
+ }
+ } while (codeFound);
+}
+
+bool BaseObject::checkEndOfSequence() {
+ Screen &screen = *_vm->_screen;
+ int checkFrame = _allow ? MAX_FRAME : FRAMES_END;
+ bool result = false;
+
+ if (_type == REMOVE || _type == INVALID)
+ return false;
+
+ if (_sequences[_frameNumber] == 0 || _frameNumber >= checkFrame) {
+ result = true;
+
+ if (_frameNumber >= (checkFrame - 1)) {
+ _frameNumber = START_FRAME;
+ } else {
+ // Determine next sequence to use
+ int seq = _sequences[_frameNumber + 1];
+
+ if (seq == 99) {
+ --_frameNumber;
+ screen._backBuffer1.transBlitFrom(*_imageFrame, _position);
+ screen._backBuffer2.transBlitFrom(*_imageFrame, _position);
+ _type = INVALID;
+ } else if (IS_ROSE_TATTOO && _talkSeq && seq == 0) {
+ setObjTalkSequence(_talkSeq);
+ } else {
+ setObjSequence(seq, false);
+ }
+ }
+
+ if (_allow && _frameNumber == 0) {
+ // canimation just ended
+ if (_type != NO_SHAPE && _type != REMOVE) {
+ _type = REMOVE;
+
+ if (!_countCAnimFrames) {
+ // Save details before shape is removed
+ _delta.x = _imageFrame->_frame.w;
+ _delta.y = _imageFrame->_frame.h;
+ _position += _imageFrame->_offset;
+
+ // Free the images
+ delete _images;
+ _images = nullptr;
+ _imageFrame = nullptr;
+ }
+ } else {
+ _type = INVALID;
+ }
+ }
+ }
+
+ return result;
+}
+
+void BaseObject::setObjSequence(int seq, bool wait) {
+ Scene &scene = *_vm->_scene;
+ int checkFrame = _allow ? MAX_FRAME : FRAMES_END;
+
+ if (seq >= 128) {
+ // Loop the sequence until the count exceeded
+ seq -= 128;
+
+ ++_seqCounter;
+ if (_seqCounter >= seq) {
+ // Go to next sequence
+ if (_seqStack) {
+ _frameNumber = _seqStack;
+ _seqStack = 0;
+ _seqCounter = _seqCounter2;
+ _seqCounter2 = 0;
+ if (_frameNumber >= checkFrame)
+ _frameNumber = START_FRAME;
+
+ return;
+ }
+
+ _frameNumber += 2;
+ if (_frameNumber >= checkFrame)
+ _frameNumber = 0;
+
+ _seqCounter = 0;
+ if (_sequences[_frameNumber] == 0)
+ seq = _sequences[_frameNumber + 1];
+ else
+ return;
+ } else {
+ // Find beginning of sequence
+ do {
+ --_frameNumber;
+ } while (_frameNumber > 0 && _sequences[_frameNumber] != 0);
+
+ if (_frameNumber != 0)
+ _frameNumber += 2;
+
+ return;
+ }
+ } else {
+ // Reset sequence counter
+ _seqCounter = 0;
+ }
+
+ int idx = 0;
+ int seqCc = 0;
+
+ while (seqCc < seq && idx < checkFrame) {
+ ++idx;
+ if (_sequences[idx] == 0) {
+ ++seqCc;
+ idx += 2;
+ }
+ }
+
+ if (idx >= checkFrame)
+ idx = 0;
+ _frameNumber = idx;
+
+ if (wait) {
+ seqCc = idx;
+ while (_sequences[idx] != 0)
+ ++idx;
+
+ idx = idx - seqCc + 2;
+ for (; idx > 0; --idx)
+ scene.doBgAnim();
+ }
+}
+
+int BaseObject::checkNameForCodes(const Common::String &name, FixedTextActionId fixedTextActionId) {
+ FixedText &fixedText = *_vm->_fixedText;
+ People &people = *_vm->_people;
+ Scene &scene = *_vm->_scene;
+ Screen &screen = *_vm->_screen;
+ Talk &talk = *_vm->_talk;
+ UserInterface &ui = *_vm->_ui;
+ bool printed = false;
+
+ scene.toggleObject(name);
+
+ if (name.hasPrefix("*")) {
+ // A code was found
+ printed = true;
+ char ch = (name == "*") ? 0 : toupper(name[1]);
+
+ switch (ch) {
+ case 'C':
+ talk.talkTo(name.c_str() + 2);
+ break;
+
+ case 'T':
+ case 'B':
+ case 'F':
+ case 'W':
+ // Nothing: action was already done before canimation
+ break;
+
+ case 'G':
+ case 'A': {
+ // G: Have object go somewhere
+ // A: Add onto existing co-ordinates
+ Common::String sx(name.c_str() + 2, name.c_str() + 5);
+ Common::String sy(name.c_str() + 6, name.c_str() + 9);
+
+ if (ch == 'G')
+ _position = Common::Point(atoi(sx.c_str()), atoi(sy.c_str()));
+ else
+ _position += Common::Point(atoi(sx.c_str()), atoi(sy.c_str()));
+ break;
+ }
+
+ case 'V':
+ // Do nothing for Verb codes. This is only a flag for Inventory syntax
+ break;
+
+ default:
+ if (ch >= '0' && ch <= '9') {
+ scene._goToScene = atoi(name.c_str() + 1);
+
+ if (IS_SERRATED_SCALPEL && scene._goToScene < 97) {
+ Scalpel::ScalpelMap &map = *(Scalpel::ScalpelMap *)_vm->_map;
+ if (map[scene._goToScene].x) {
+ map._overPos.x = (map[scene._goToScene].x - 6) * FIXED_INT_MULTIPLIER;
+ map._overPos.y = (map[scene._goToScene].y + 9) * FIXED_INT_MULTIPLIER;
+ }
+ }
+
+ const char *p;
+ if ((p = strchr(name.c_str(), ',')) != nullptr) {
+ ++p;
+
+ Common::String s(p, p + 3);
+ people._savedPos.x = atoi(s.c_str());
+
+ s = Common::String(p + 3, p + 6);
+ people._savedPos.y = atoi(s.c_str());
+
+ s = Common::String(p + 6, p + 9);
+ people._savedPos._facing = atoi(s.c_str());
+ if (people._savedPos._facing == 0)
+ people._savedPos._facing = 10;
+ } else if ((p = strchr(name.c_str(), '/')) != nullptr) {
+ people._savedPos = PositionFacing(1, 0, 100 + atoi(p + 1));
+ }
+ } else {
+ scene._goToScene = 100;
+ }
+
+ people[HOLMES]._position = Point32(0, 0);
+ break;
+ }
+ } else if (name.hasPrefix("!")) {
+ // Message attached to canimation
+ int messageNum = atoi(name.c_str() + 1);
+ ui._infoFlag = true;
+ ui.clearInfo();
+ Common::String errorMessage = fixedText.getActionMessage(fixedTextActionId, messageNum);
+ screen.print(Common::Point(0, INFO_LINE + 1), COL_INFO_FOREGROUND, "%s", errorMessage.c_str());
+ ui._menuCounter = 25;
+ } else if (name.hasPrefix("@")) {
+ // Message attached to canimation
+ ui._infoFlag = true;
+ ui.clearInfo();
+ screen.print(Common::Point(0, INFO_LINE + 1), COL_INFO_FOREGROUND, "%s", name.c_str() + 1);
+ printed = true;
+ ui._menuCounter = 25;
+ }
+
+ return printed;
+}
+
+/*----------------------------------------------------------------*/
+
+void Sprite::clear() {
+ _name = "";
+ _description = "";
+ _examine.clear();
+ _pickUp = "";
+ _walkSequences.clear();
+ _sequences = nullptr;
+ _images = nullptr;
+ _imageFrame = nullptr;
+ _walkCount = 0;
+ _allow = 0;
+ _frameNumber = _sequenceNumber = 0;
+ _position.x = _position.y = 0;
+ _delta.x = _delta.y = 0;
+ _oldPosition.x = _oldPosition.y = 0;
+ _oldSize.x = _oldSize.y = 0;
+ _goto.x = _goto.y = 0;
+ _type = INVALID;
+ _pickUp.clear();
+ _noShapeSize.x = _noShapeSize.y = 0;
+ _status = 0;
+ _misc = 0;
+ _altImages = nullptr;
+ _altSeq = 0;
+ Common::fill(&_stopFrames[0], &_stopFrames[8], (ImageFrame *)nullptr);
+}
+
+void Sprite::setImageFrame() {
+ int frameNum = MAX(_frameNumber, 0);
+ int imageNumber = _walkSequences[_sequenceNumber][frameNum];
+
+ if (IS_SERRATED_SCALPEL)
+ imageNumber = imageNumber + _walkSequences[_sequenceNumber][0] - 2;
+ else if (imageNumber > _maxFrames)
+ imageNumber = 1;
+
+ // Get the images to use
+ ImageFile *images = _altSeq ? _altImages : _images;
+ assert(images);
+
+ if (IS_3DO) {
+ // only do this to the image-array with 110 entries
+ // map uses another image-array and this code
+ if (images->size() == 110) {
+ // 3DO has 110 animation frames inside walk.anim
+ // PC has 55
+ // this adjusts the framenumber accordingly
+ // sort of HACK
+ imageNumber *= 2;
+ }
+ } else if (IS_ROSE_TATTOO) {
+ --imageNumber;
+ }
+
+ // Set the frame pointer
+ _imageFrame = &(*images)[imageNumber];
+}
+
+void Sprite::checkSprite() {
+ Events &events = *_vm->_events;
+ People &people = *_vm->_people;
+ Scene &scene = *_vm->_scene;
+ Screen &screen = *_vm->_screen;
+ Talk &talk = *_vm->_talk;
+ Point32 pt;
+ Common::Rect objBounds;
+ Common::Point spritePt(_position.x / FIXED_INT_MULTIPLIER, _position.y / FIXED_INT_MULTIPLIER);
+
+ if (_type != CHARACTER || (IS_SERRATED_SCALPEL && talk._talkCounter))
+ return;
+
+ pt = _walkCount ? _position + _delta : _position;
+ pt.x /= FIXED_INT_MULTIPLIER;
+ pt.y /= FIXED_INT_MULTIPLIER;
+
+ if (IS_ROSE_TATTOO) {
+ checkObject();
+
+ // For Rose Tattoo, we only do the further processing for Sherlock
+ if (this != &people[HOLMES])
+ return;
+ }
+
+ for (uint idx = 0; idx < scene._bgShapes.size() && !talk._talkToAbort; ++idx) {
+ Object &obj = scene._bgShapes[idx];
+ if (obj._aType <= PERSON || obj._type == INVALID || obj._type == HIDDEN)
+ continue;
+
+ if (obj._type == NO_SHAPE) {
+ objBounds = Common::Rect(obj._position.x, obj._position.y,
+ obj._position.x + obj._noShapeSize.x + 1, obj._position.y + obj._noShapeSize.y + 1);
+ } else {
+ int xp = obj._position.x + obj._imageFrame->_offset.x;
+ int yp = obj._position.y + obj._imageFrame->_offset.y;
+ objBounds = Common::Rect(xp, yp,
+ xp + obj._imageFrame->_frame.w + 1, yp + obj._imageFrame->_frame.h + 1);
+ }
+
+ if (objBounds.contains(pt)) {
+ if (objBounds.contains(spritePt)) {
+ // Current point is already inside the the bounds, so impact occurred
+ // on a previous call. So simply do nothing until we're clear of the box
+ switch (obj._aType) {
+ case TALK_MOVE:
+ if (_walkCount) {
+ // Holmes is moving
+ obj._type = HIDDEN;
+ obj.setFlagsAndToggles();
+ talk.talkTo(obj._use[0]._target);
+ }
+ break;
+
+ case PAL_CHANGE:
+ case PAL_CHANGE2:
+ if (_walkCount) {
+ int palStart = atoi(obj._use[0]._names[0].c_str()) * 3;
+ int palLength = atoi(obj._use[0]._names[1].c_str()) * 3;
+ int templ = atoi(obj._use[0]._names[2].c_str()) * 3;
+ if (templ == 0)
+ templ = 100;
+
+ // Ensure only valid palette change data found
+ if (palLength > 0) {
+ // Figure out how far into the shape Holmes is so that we
+ // can figure out what percentage of the original palette
+ // to set the current palette to
+ int palPercent = (pt.x - objBounds.left) * 100 / objBounds.width();
+ palPercent = palPercent * templ / 100;
+ if (obj._aType == PAL_CHANGE)
+ // Invert percentage
+ palPercent = 100 - palPercent;
+
+ for (int i = palStart; i < (palStart + palLength); ++i)
+ screen._sMap[i] = screen._cMap[i] * palPercent / 100;
+
+ events.pollEvents();
+ screen.setPalette(screen._sMap);
+ }
+ }
+ break;
+
+ case TALK:
+ case TALK_EVERY:
+ obj._type = HIDDEN;
+ obj.setFlagsAndToggles();
+ talk.talkTo(obj._use[0]._target);
+ break;
+
+ default:
+ break;
+ }
+ } else {
+ // New impact just occurred
+ switch (obj._aType) {
+ case BLANK_ZONE:
+ // A blank zone masks out all other remaining zones underneath it.
+ // If this zone is hit, exit the outer loop so we do not check anymore
+ return;
+
+ case SOLID:
+ case TALK:
+ // Stop walking
+ if (obj._aType == TALK) {
+ obj.setFlagsAndToggles();
+ talk.talkTo(obj._use[0]._target);
+ } else {
+ gotoStand();
+ }
+ break;
+
+ case TALK_EVERY:
+ if (obj._aType == TALK_EVERY) {
+ obj._type = HIDDEN;
+ obj.setFlagsAndToggles();
+ talk.talkTo(obj._use[0]._target);
+ } else {
+ gotoStand();
+ }
+ break;
+
+ case FLAG_SET:
+ obj.setFlagsAndToggles();
+ obj._type = HIDDEN;
+ break;
+
+ case WALK_AROUND:
+ if (objBounds.contains(people[HOLMES]._walkTo.front())) {
+ // Reached zone
+ gotoStand();
+ } else {
+ // Destination not within box, walk to best corner
+ Common::Point walkPos;
+
+ if (spritePt.x >= objBounds.left && spritePt.x < objBounds.right) {
+ // Impact occurred due to vertical movement. Determine whether to
+ // travel to the left or right side
+ if (_delta.x > 0)
+ // Go to right side
+ walkPos.x = objBounds.right + CLEAR_DIST_X;
+ else if (_delta.x < 0) {
+ // Go to left side
+ walkPos.x = objBounds.left - CLEAR_DIST_X;
+ } else {
+ // Going straight up or down. So choose best side
+ if (spritePt.x >= (objBounds.left + objBounds.width() / 2))
+ walkPos.x = objBounds.right + CLEAR_DIST_X;
+ else
+ walkPos.x = objBounds.left - CLEAR_DIST_X;
+ }
+
+ walkPos.y = (_delta.y >= 0) ? objBounds.top - CLEAR_DIST_Y :
+ objBounds.bottom + CLEAR_DIST_Y;
+ } else {
+ // Impact occurred due to horizontal movement
+ if (_delta.y > 0)
+ // Go to bottom of box
+ walkPos.y = objBounds.bottom + CLEAR_DIST_Y;
+ else if (_delta.y < 0)
+ // Go to top of box
+ walkPos.y = objBounds.top - CLEAR_DIST_Y;
+ else {
+ // Going straight horizontal, so choose best side
+ if (spritePt.y >= (objBounds.top + objBounds.height() / 2))
+ walkPos.y = objBounds.bottom + CLEAR_DIST_Y;
+ else
+ walkPos.y = objBounds.top - CLEAR_DIST_Y;
+ }
+
+ walkPos.x = (_delta.x >= 0) ? objBounds.left - CLEAR_DIST_X :
+ objBounds.right + CLEAR_DIST_X;
+ }
+
+ walkPos.x += people[HOLMES]._imageFrame->_frame.w / 2;
+ people[HOLMES]._walkDest = walkPos;
+ people[HOLMES]._walkTo.push(walkPos);
+ people[HOLMES].setWalking();
+ }
+ break;
+
+ case DELTA:
+ _position.x += 200;
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+}
+
+const Common::Rect Sprite::getOldBounds() const {
+ return Common::Rect(_oldPosition.x, _oldPosition.y, _oldPosition.x + _oldSize.x, _oldPosition.y + _oldSize.y);
+}
+
+/*----------------------------------------------------------------*/
+
+void WalkSequence::load(Common::SeekableReadStream &s) {
+ char buffer[9];
+ s.read(buffer, 9);
+ _vgsName = Common::String(buffer);
+ _horizFlip = s.readByte() != 0;
+
+ _sequences.resize(s.readUint16LE());
+ s.skip(4); // Skip over pointer field of structure
+
+ s.read(&_sequences[0], _sequences.size());
+}
+
+/*----------------------------------------------------------------*/
+
+WalkSequences &WalkSequences::operator=(const WalkSequences &src) {
+ resize(src.size());
+ for (uint idx = 0; idx < size(); ++idx) {
+ const WalkSequence &wSrc = src[idx];
+ WalkSequence &wDest = (*this)[idx];
+ wDest._horizFlip = wSrc._horizFlip;
+
+ wDest._sequences.resize(wSrc._sequences.size());
+ Common::copy(&wSrc._sequences[0], &wSrc._sequences[0] + wSrc._sequences.size(), &wDest._sequences[0]);
+ }
+
+ return *this;
+}
+
+/*----------------------------------------------------------------*/
+
+ActionType::ActionType() {
+ _cAnimNum = _cAnimSpeed = 0;
+ _useFlag = 0;
+}
+
+void ActionType::load(Common::SeekableReadStream &s) {
+ char buffer[12];
+
+ _cAnimNum = s.readByte();
+ _cAnimSpeed = s.readByte();
+ if (_cAnimSpeed & 0x80)
+ _cAnimSpeed = -(_cAnimSpeed & 0x7f);
+
+ for (int idx = 0; idx < NAMES_COUNT; ++idx) {
+ s.read(buffer, 12);
+ _names[idx] = Common::String(buffer);
+ }
+}
+
+/*----------------------------------------------------------------*/
+
+UseType::UseType(): ActionType() {
+}
+
+void UseType::load(Common::SeekableReadStream &s, bool isRoseTattoo) {
+ char buffer[12];
+
+ if (isRoseTattoo) {
+ s.read(buffer, 12);
+ _verb = Common::String(buffer);
+ }
+
+ ActionType::load(s);
+
+ _useFlag = s.readSint16LE();
+
+ if (!isRoseTattoo)
+ s.skip(6);
+
+ s.read(buffer, 12);
+ _target = Common::String(buffer);
+}
+
+void UseType::load3DO(Common::SeekableReadStream &s) {
+ char buffer[12];
+
+ _cAnimNum = s.readByte();
+ _cAnimSpeed = s.readByte();
+ if (_cAnimSpeed & 0x80)
+ _cAnimSpeed = -(_cAnimSpeed & 0x7f);
+
+ for (int idx = 0; idx < NAMES_COUNT; ++idx) {
+ s.read(buffer, 12);
+ _names[idx] = Common::String(buffer);
+ }
+
+ _useFlag = s.readSint16BE();
+
+ s.skip(6);
+
+ s.read(buffer, 12);
+ _target = Common::String(buffer);
+}
+
+void UseType::synchronize(Serializer &s) {
+ s.syncString(_verb);
+ s.syncAsSint16LE(_cAnimNum);
+ s.syncAsSint16LE(_cAnimSpeed);
+ s.syncAsSint16LE(_useFlag);
+
+ for (int idx = 0; idx < 4; ++idx)
+ s.syncString(_names[idx]);
+ s.syncString(_target);
+}
+
+/*----------------------------------------------------------------*/
+
+Object::Object(): BaseObject() {
+ _sequenceNumber = 0;
+ _sequenceOffset = 0;
+ _pickup = 0;
+ _defaultCommand = 0;
+ _pickupFlag = 0;
+}
+
+void Object::load(Common::SeekableReadStream &s, bool isRoseTattoo) {
+ char buffer[41];
+ s.read(buffer, 12);
+ _name = Common::String(buffer);
+ s.read(buffer, 41);
+ _description = Common::String(buffer);
+
+ _examine.clear();
+ _sequences = nullptr;
+ _images = nullptr;
+ _imageFrame = nullptr;
+
+ s.skip(4);
+ _sequenceOffset = s.readUint16LE();
+ s.seek(10, SEEK_CUR);
+
+ _walkCount = s.readByte();
+ _allow = s.readByte();
+ _frameNumber = s.readSint16LE();
+ _sequenceNumber = s.readSint16LE();
+ _position.x = s.readSint16LE();
+ _position.y = s.readSint16LE();
+ _delta.x = s.readSint16LE();
+ _delta.y = s.readSint16LE();
+ _type = (SpriteType)s.readUint16LE();
+ _oldPosition.x = s.readSint16LE();
+ _oldPosition.y = s.readSint16LE();
+ _oldSize.x = s.readUint16LE();
+ _oldSize.y = s.readUint16LE();
+
+ _goto.x = s.readSint16LE();
+ _goto.y = s.readSint16LE();
+ if (!isRoseTattoo) {
+ _goto.x = _goto.x * FIXED_INT_MULTIPLIER / 100;
+ _goto.y = _goto.y * FIXED_INT_MULTIPLIER / 100;
+ }
+
+ _pickup = isRoseTattoo ? 0 : s.readByte();
+ _defaultCommand = isRoseTattoo ? 0 : s.readByte();
+ _lookFlag = s.readSint16LE();
+ _pickupFlag = isRoseTattoo ? 0 : s.readSint16LE();
+ _requiredFlag[0] = s.readSint16LE();
+ _noShapeSize.x = s.readUint16LE();
+ _noShapeSize.y = s.readUint16LE();
+ _status = s.readUint16LE();
+ _misc = s.readByte();
+ _maxFrames = s.readUint16LE();
+ _flags = s.readByte();
+
+ if (!isRoseTattoo)
+ _aOpen.load(s);
+
+ _aType = (AType)s.readByte();
+ _lookFrames = s.readByte();
+ _seqCounter = s.readByte();
+ if (isRoseTattoo) {
+ _lookPosition.x = s.readUint16LE() * FIXED_INT_MULTIPLIER;
+ _lookPosition.y = s.readSint16LE() * FIXED_INT_MULTIPLIER;
+ } else {
+ _lookPosition.x = s.readUint16LE() * FIXED_INT_MULTIPLIER / 100;
+ _lookPosition.y = s.readByte() * FIXED_INT_MULTIPLIER;
+ }
+ _lookPosition._facing = s.readByte();
+ _lookcAnim = s.readByte();
+
+ if (!isRoseTattoo)
+ _aClose.load(s);
+
+ _seqStack = s.readByte();
+ _seqTo = s.readByte();
+ _descOffset = s.readUint16LE();
+ _seqCounter2 = s.readByte();
+ _seqSize = s.readUint16LE();
+
+ if (isRoseTattoo) {
+ for (int idx = 0; idx < 6; ++idx)
+ _use[idx].load(s, true);
+
+ _quickDraw = s.readByte();
+ _scaleVal = s.readUint16LE();
+ _requiredFlag[1] = s.readSint16LE();
+ _gotoSeq = s.readByte();
+ _talkSeq = s.readByte();
+ _restoreSlot = s.readByte();
+ } else {
+ s.skip(1);
+ _aMove.load(s);
+ s.skip(8);
+
+ for (int idx = 0; idx < 4; ++idx)
+ _use[idx].load(s, false);
+ }
+ //warning("object %s, useAnim %d", _name.c_str(), _use[0]._cAnimNum);
+}
+
+void Object::load3DO(Common::SeekableReadStream &s) {
+ int32 streamStartPos = s.pos();
+ char buffer[41];
+
+ _examine.clear();
+ _sequences = nullptr;
+ _images = nullptr;
+ _imageFrame = nullptr;
+
+ // on 3DO all of this data is reordered!!!
+ // it seems that possibly the 3DO compiler reordered the global struct
+ // 3DO size for 1 object is 588 bytes
+ s.skip(4);
+ _sequenceOffset = s.readUint16LE(); // weird that this seems to be LE
+ s.seek(10, SEEK_CUR);
+
+ // Offset 16
+ _frameNumber = s.readSint16BE();
+ _sequenceNumber = s.readSint16BE();
+ _position.x = s.readSint16BE();
+ _position.y = s.readSint16BE();
+ _delta.x = s.readSint16BE();
+ _delta.y = s.readSint16BE();
+ _type = (SpriteType)s.readUint16BE();
+ _oldPosition.x = s.readSint16BE();
+ _oldPosition.y = s.readSint16BE();
+ _oldSize.x = s.readUint16BE();
+ _oldSize.y = s.readUint16BE();
+
+ _goto.x = s.readSint16BE();
+ _goto.y = s.readSint16BE();
+ _goto.x = _goto.x * FIXED_INT_MULTIPLIER / 100;
+ _goto.y = _goto.y * FIXED_INT_MULTIPLIER / 100;
+
+ // Offset 42
+ warning("pos %d", s.pos());
+
+ // Unverified
+ _lookFlag = s.readSint16BE();
+ _pickupFlag = s.readSint16BE();
+ _requiredFlag[0] = s.readSint16BE();
+ _noShapeSize.x = s.readUint16BE();
+ _noShapeSize.y = s.readUint16BE();
+ _status = s.readUint16BE();
+ // Unverified END
+
+ _maxFrames = s.readUint16BE();
+ // offset 56
+ _lookPosition.x = s.readUint16BE() * FIXED_INT_MULTIPLIER / 100;
+ // offset 58
+ _descOffset = s.readUint16BE();
+ _seqSize = s.readUint16BE();
+
+ s.skip(2); // boundary filler
+
+ // 288 bytes
+ for (int idx = 0; idx < 4; ++idx) {
+ _use[idx].load3DO(s);
+ s.skip(2); // Filler
+ }
+
+ // 158 bytes
+ _aOpen.load(s); // 2 + 12*4 bytes = 50 bytes
+ s.skip(2); // Boundary filler
+ _aClose.load(s);
+ s.skip(2); // Filler
+ _aMove.load(s);
+ s.skip(2); // Filler
+
+ // offset 508
+ // 3DO: name is at the end
+ s.read(buffer, 12);
+ _name = Common::String(buffer);
+ s.read(buffer, 41);
+ _description = Common::String(buffer);
+
+ // Unverified
+ _walkCount = s.readByte();
+ _allow = s.readByte();
+ _pickup = s.readByte();
+ _defaultCommand = s.readByte();
+ // Unverified END
+
+ // Probably those here?!?!
+ _misc = s.readByte();
+ _flags = s.readByte();
+
+ // Unverified
+ _aType = (AType)s.readByte();
+ _lookFrames = s.readByte();
+ _seqCounter = s.readByte();
+ // Unverified END
+
+ _lookPosition.y = s.readByte() * FIXED_INT_MULTIPLIER;
+ _lookPosition._facing = s.readByte();
+
+ // Unverified
+ _lookcAnim = s.readByte();
+ _seqStack = s.readByte();
+ _seqTo = s.readByte();
+ _seqCounter2 = s.readByte();
+ // Unverified END
+
+ s.skip(12); // Unknown
+
+ //warning("object %s, offset %d", _name.c_str(), streamPos);
+ //warning("object %s, lookPosX %d, lookPosY %d", _name.c_str(), _lookPosition.x, _lookPosition.y);
+ //warning("object %s, defCmd %d", _name.c_str(), _defaultCommand);
+ int32 dataSize = s.pos() - streamStartPos;
+ assert(dataSize == 588);
+}
+
+void Object::toggleHidden() {
+ if (_type != HIDDEN && _type != HIDE_SHAPE && _type != INVALID) {
+ if (_seqTo != 0)
+ _sequences[_frameNumber] = _seqTo + SEQ_TO_CODE + 128;
+ _seqTo = 0;
+
+ if (_images == nullptr || _images->size() == 0)
+ // No shape to erase, so flag as hidden
+ _type = HIDDEN;
+ else
+ // Otherwise, flag it to be hidden after it gets erased
+ _type = HIDE_SHAPE;
+ } else if (_type != INVALID) {
+ if (_seqTo != 0)
+ _sequences[_frameNumber] = _seqTo + SEQ_TO_CODE + 128;
+ _seqTo = 0;
+
+ _seqCounter = _seqCounter2 = 0;
+ _seqStack = 0;
+ _frameNumber = -1;
+
+ if (_images == nullptr || _images->size() == 0) {
+ _type = NO_SHAPE;
+ } else {
+ _type = ACTIVE_BG_SHAPE;
+ int idx = _sequences[0];
+ if (idx >= _maxFrames)
+ // Turn on: set up first frame
+ idx = 0;
+
+ _imageFrame = &(*_images)[idx];
+ }
+ }
+}
+
+void Object::setObjTalkSequence(int seq) {
+ Talk &talk = *_vm->_talk;
+
+ // See if we're supposed to restore the object's sequence from the talk sequence stack
+ if (seq == -1) {
+ TalkSequence &ts = talk._talkSequenceStack[_restoreSlot];
+ if (_seqTo != 0)
+ _sequences[_frameNumber] = _seqTo;
+ _frameNumber = ts._frameNumber;
+ _sequenceNumber = ts._sequenceNumber;
+ _seqStack = ts._seqStack;
+ _seqTo = ts._seqTo;
+ _seqCounter = ts._seqCounter;
+ _seqCounter2 = ts._seqCounter2;
+ _talkSeq = 0;
+
+ // Flag this slot as free again
+ ts._obj = nullptr;
+
+ return;
+ }
+
+ assert(_type != CHARACTER);
+
+ talk.pushTalkSequence(this);
+ int talkSeqNum = seq;
+
+ // Find where the talk sequence data begins in the object
+ int idx = 0;
+ for (;;) {
+ // Get the Frame value
+ byte f = _sequences[idx++];
+
+ // See if we've found the beginning of a Talk Sequence
+ if ((f == TALK_SEQ_CODE && seq < 128) || (f == TALK_LISTEN_CODE && seq > 128)) {
+ --seq;
+
+ // See if we're at the correct Talk Sequence Number
+ if (!(seq & 127))
+ {
+ // Correct Sequence, Start Talking Here
+ if (_seqTo != 0)
+ _sequences[_frameNumber] = _seqTo;
+ _frameNumber = idx;
+ _seqTo = 0;
+ _seqStack = 0;
+ _seqCounter = 0;
+ _seqCounter2 = 0;
+ _talkSeq = talkSeqNum;
+ break;
+ }
+ } else {
+ // Move ahead any extra because of special control codes
+ switch (f) {
+ case 0: idx++; break;
+ case MOVE_CODE:
+ case TELEPORT_CODE: idx += 4; break;
+ case CALL_TALK_CODE: idx += 8; break;
+ case HIDE_CODE: idx += 2; break;
+ }
+ }
+
+ // See if we're out of sequence data
+ if (idx >= (int)_seqSize)
+ break;
+ }
+}
+
+void Object::setFlagsAndToggles() {
+ Scene &scene = *_vm->_scene;
+ Talk &talk = *_vm->_talk;
+
+ for (int useIdx = 0; useIdx < USE_COUNT; ++useIdx) {
+ if (_use[useIdx]._useFlag) {
+ if (!_vm->readFlags(_use[useIdx]._useFlag))
+ _vm->setFlags(_use[useIdx]._useFlag);
+ }
+
+ if (_use[useIdx]._cAnimSpeed) {
+ if (_use[useIdx]._cAnimNum == 0)
+ // 0 is really a 10
+ scene.startCAnim(9, _use[useIdx]._cAnimSpeed);
+ else
+ scene.startCAnim(_use[useIdx]._cAnimNum - 1, _use[useIdx]._cAnimSpeed);
+ }
+
+ if (!talk._talkToAbort) {
+ for (int idx = 0; idx < NAMES_COUNT; ++idx)
+ scene.toggleObject(_use[useIdx]._names[idx]);
+ }
+ }
+}
+
+void Object::adjustObject() {
+ if (_type == REMOVE)
+ return;
+
+ if (IS_ROSE_TATTOO && (_delta.x || _delta.y)) {
+ // The shape position is in pixels, and the delta is in fixed integer amounts
+ int t;
+ _noShapeSize.x += _delta.x;
+ t = _noShapeSize.x / (FIXED_INT_MULTIPLIER / 10);
+ _noShapeSize.x -= t * (FIXED_INT_MULTIPLIER / 10);
+ _position.x += t;
+
+ _noShapeSize.y += _delta.y;
+ t = _noShapeSize.y / (FIXED_INT_MULTIPLIER / 10);
+ _noShapeSize.y -= t * (FIXED_INT_MULTIPLIER / 10);
+ _position.y += t;
+ } else if (IS_SERRATED_SCALPEL) {
+ // The delta is in whole pixels, so simply adjust the position with it
+ _position += _delta;
+ }
+
+ if (_position.y > LOWER_LIMIT)
+ _position.y = LOWER_LIMIT;
+
+ if (_type != NO_SHAPE) {
+ int frame = _frameNumber;
+ if (frame == -1)
+ frame = 0;
+
+ int imgNum = _sequences[frame];
+ if (imgNum > _maxFrames)
+ imgNum = 1;
+
+ _imageFrame = &(*_images)[imgNum - 1];
+ }
+}
+
+int Object::pickUpObject(FixedTextActionId fixedTextActionId) {
+ FixedText &fixedText = *_vm->_fixedText;
+ Inventory &inv = *_vm->_inventory;
+ People &people = *_vm->_people;
+ Scene &scene = *_vm->_scene;
+ Screen &screen = *_vm->_screen;
+ Talk &talk = *_vm->_talk;
+ UserInterface &ui = *_vm->_ui;
+ int pickup = _pickup & 0x7f;
+ bool printed = false;
+ int numObjects = 0;
+
+ if (pickup == 99) {
+ for (int idx = 0; idx < NAMES_COUNT && !talk._talkToAbort; ++idx) {
+ if (checkNameForCodes(_use[0]._names[idx], kFixedTextAction_Invalid)) {
+ if (!talk._talkToAbort)
+ printed = true;
+ }
+ }
+
+ return 0;
+ }
+
+ if (!pickup || (pickup > 50 && pickup <= 80)) {
+ int message = _pickup;
+ if (message > 50)
+ message -= 50;
+
+ ui._infoFlag = true;
+ ui.clearInfo();
+ Common::String errorMessage = fixedText.getActionMessage(fixedTextActionId, message);
+ screen.print(Common::Point(0, INFO_LINE + 1), COL_INFO_FOREGROUND, "%s", errorMessage.c_str());
+ ui._menuCounter = 30;
+ } else {
+ // Pick it up
+ bool takeFlag = true;
+ if ((_pickup & 0x80) == 0) {
+ // Play an animation
+ if (pickup > 80) {
+ takeFlag = false; // Don't pick it up
+ scene.startCAnim(pickup - 81, 1);
+ if (_pickupFlag)
+ _vm->setFlags(_pickupFlag);
+ } else {
+ scene.startCAnim(pickup - 1, 1);
+ if (!talk._talkToAbort) {
+ // Erase the shape
+ _type = _type == NO_SHAPE ? INVALID : REMOVE;
+ }
+ }
+
+ if (talk._talkToAbort)
+ return 0;
+ } else {
+ // Play generic pickup sequence
+ // Original moved cursor position here
+ people[HOLMES].goAllTheWay();
+ ui._menuCounter = 25;
+ ui._temp1 = 1;
+ }
+
+ for (int idx = 0; idx < NAMES_COUNT && !talk._talkToAbort; ++idx) {
+ if (checkNameForCodes(_use[0]._names[idx], kFixedTextAction_Invalid)) {
+ if (!talk._talkToAbort)
+ printed = true;
+ }
+ }
+ if (talk._talkToAbort)
+ return 0;
+
+ // Add the item to the player's inventory
+ if (takeFlag)
+ numObjects = inv.putItemInInventory(*this);
+
+ if (!printed) {
+ ui._infoFlag = true;
+ ui.clearInfo();
+
+ Common::String itemName = _description;
+ itemName.setChar(tolower(itemName[0]), 0);
+ screen.print(Common::Point(0, INFO_LINE + 1), COL_INFO_FOREGROUND, "Picked up %s", itemName.c_str());
+ ui._menuCounter = 25;
+ }
+ }
+
+ return numObjects;
+}
+
+const Common::Rect Object::getNewBounds() const {
+ Point32 pt = _position;
+ if (_imageFrame)
+ pt += _imageFrame->_offset;
+
+ return Common::Rect(pt.x, pt.y, pt.x + frameWidth(), pt.y + frameHeight());
+}
+
+const Common::Rect Object::getNoShapeBounds() const {
+ return Common::Rect(_position.x, _position.y,
+ _position.x + _noShapeSize.x, _position.y + _noShapeSize.y);
+}
+
+const Common::Rect Object::getOldBounds() const {
+ return Common::Rect(_oldPosition.x, _oldPosition.y,
+ _oldPosition.x + _oldSize.x, _oldPosition.y + _oldSize.y);
+}
+
+/*----------------------------------------------------------------*/
+
+void CAnim::load(Common::SeekableReadStream &s, bool isRoseTattoo, uint32 dataOffset) {
+ char buffer[12];
+ s.read(buffer, 12);
+ _name = Common::String(buffer);
+
+ if (isRoseTattoo) {
+ Common::fill(&_sequences[0], &_sequences[30], 0);
+ _dataSize = s.readUint32LE();
+ } else {
+ s.read(_sequences, 30);
+ }
+
+ _position.x = s.readSint16LE();
+ _position.y = s.readSint16LE();
+
+ if (isRoseTattoo) {
+ _flags = s.readByte();
+ _scaleVal = s.readSint16LE();
+ } else {
+ _dataSize = s.readUint32LE();
+ _type = (SpriteType)s.readUint16LE();
+ _flags = s.readByte();
+ }
+
+ _goto[0].x = s.readSint16LE();
+ _goto[0].y = s.readSint16LE();
+ _goto[0]._facing = s.readSint16LE();
+ ADJUST_COORD(_goto[0]);
+
+ if (isRoseTattoo) {
+ // Get Goto position and facing for second NPC
+ _goto[1].x = s.readSint16LE();
+ _goto[1].y = s.readSint16LE();
+ _goto[1]._facing = s.readSint16LE();
+ ADJUST_COORD(_goto[1]);
+ } else if (_goto[0].x != -1) {
+ // For Serrated Scalpel, adjust the loaded co-ordinates
+ _goto[0].x = _goto[0].x / 100;
+ _goto[0].y = _goto[0].y / 100;
+ }
+
+ _teleport[0].x = s.readSint16LE();
+ _teleport[0].y = s.readSint16LE();
+ _teleport[0]._facing = s.readSint16LE();
+ ADJUST_COORD(_teleport[0]);
+
+ if (isRoseTattoo) {
+ // Get Teleport position and facing for second NPC
+ _teleport[1].x = s.readSint16LE();
+ _teleport[1].y = s.readSint16LE();
+ _teleport[1]._facing = s.readSint16LE();
+ ADJUST_COORD(_teleport[1]);
+ } else if (_teleport[0].x != -1) {
+ // For Serrated Scalpel, adjust the loaded co-ordinates
+ _teleport[0].x = _teleport[0].x / 100;
+ _teleport[0].y = _teleport[0].y / 100;
+ }
+
+ // Save offset of data, which is actually inside another table inside the room data file
+ // This table is at offset 44 for Serrated Scalpel
+ // TODO: find it for the other game
+ _dataOffset = dataOffset;
+}
+
+void CAnim::load3DO(Common::SeekableReadStream &s, uint32 dataOffset) {
+ // this got reordered on 3DO
+ // maybe it was the 3DO compiler
+
+ _dataSize = s.readUint32BE();
+ // Save offset of data, which is inside another table inside the room data file
+ _dataOffset = dataOffset;
+
+ _position.x = s.readSint16BE();
+ _position.y = s.readSint16BE();
+
+ _type = (SpriteType)s.readUint16BE();
+
+ _goto[0].x = s.readSint16BE();
+ _goto[0].y = s.readSint16BE();
+ _goto[0]._facing = s.readSint16BE();
+
+ _teleport[0].x = s.readSint16BE();
+ _teleport[0].y = s.readSint16BE();
+ _teleport[0]._facing = s.readSint16BE();
+
+ char buffer[12];
+ s.read(buffer, 12);
+ _name = Common::String(buffer);
+
+ s.read(_sequences, 30);
+ _flags = s.readByte();
+
+ s.skip(3); // Filler
+
+ _goto[0].x = _goto[0].x * FIXED_INT_MULTIPLIER / 100;
+ _goto[0].y = _goto[0].y * FIXED_INT_MULTIPLIER / 100;
+ _teleport[0].x = _teleport[0].x * FIXED_INT_MULTIPLIER / 100;
+ _teleport[0].y = _teleport[0].y * FIXED_INT_MULTIPLIER / 100;
+}
+
+/*----------------------------------------------------------------*/
+
+SceneImage::SceneImage() {
+ _images = nullptr;
+ _maxFrames = 0;
+ _filesize = 0;
+}
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h
new file mode 100644
index 0000000000..996054be43
--- /dev/null
+++ b/engines/sherlock/objects.h
@@ -0,0 +1,478 @@
+/* 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 SHERLOCK_OBJECTS_H
+#define SHERLOCK_OBJECTS_H
+
+#include "common/scummsys.h"
+#include "common/rect.h"
+#include "common/str-array.h"
+#include "common/str.h"
+#include "sherlock/image_file.h"
+#include "sherlock/fixed_text.h"
+#include "sherlock/saveload.h"
+
+namespace Sherlock {
+
+class SherlockEngine;
+
+enum ObjectAllow {
+ ALLOW_MOVE = 1, ALLOW_OPEN = 2, ALLOW_CLOSE = 4
+};
+
+enum SpriteType {
+ INVALID = 0,
+ CHARACTER = 1,
+ CURSOR = 2,
+ STATIC_BG_SHAPE = 3, // Background shape that doesn't animate
+ ACTIVE_BG_SHAPE = 4, // Background shape that animates
+ REMOVE = 5, // Object should be removed next frame
+ NO_SHAPE = 6, // Background object with no shape
+ HIDDEN = 7, // Hidden backgruond object
+ HIDE_SHAPE = 8, // Object needs to be hidden
+
+ // Rose Tattoo
+ HIDDEN_CHARACTER = 128
+};
+
+enum AType {
+ OBJECT = 0,
+ PERSON = 1,
+ SOLID = 2,
+ TALK = 3, // Standard talk zone
+ FLAG_SET = 4,
+ DELTA = 5,
+ WALK_AROUND = 6,
+ TALK_EVERY = 7, // Talk zone that turns on every room visit
+ TALK_MOVE = 8, // Talk zone that only activates when Holmes moves
+ PAL_CHANGE = 9, // Changes the palette down so that it gets darker
+ PAL_CHANGE2 = 10, // Same as PAL_CHANGE, except that it goes up
+ SCRIPT_ZONE = 11, // If this is clicked in, it is activated
+ BLANK_ZONE = 12, // This masks out other objects when entered
+ NOWALK_ZONE = 13 // Player cannot walk here
+};
+
+// Different levels for sprites to be at
+enum {
+ BEHIND = 0, NORMAL_BEHIND = 1, NORMAL_FORWARD = 2, FORWARD = 3
+};
+
+#define MAX_HOLMES_SEQUENCE 16
+#define MAX_FRAME 30
+#define FIXED_INT_MULTIPLIER 1000
+
+// code put into sequences to defines 1-10 type seqs
+#define SEQ_TO_CODE 67
+#define FLIP_CODE (64 + 128)
+#define SOUND_CODE (34 + 128)
+#define HIDE_CODE (7+128) // Code for hiding/unhiding an object from a Sequence
+#define CALL_TALK_CODE (8+128) // Code for call a Talk File from a Sequence
+#define TELEPORT_CODE (9+128) // Code for setting Teleport Data (X,Y)
+#define MOVE_CODE (10+128) // Code for setting Movement Delta (X,Y)
+
+#define GOTO_CODE 228
+#define TALK_SEQ_CODE 252 // Code specifying start of talk sequence frames in a Sequence
+#define TALK_LISTEN_CODE 251 // Code specifying start of talk listen frames in a Sequence
+#define ALLOW_TALK_CODE 250
+
+#define UPPER_LIMIT 0
+#define LOWER_LIMIT (IS_SERRATED_SCALPEL ? CONTROLS_Y : SHERLOCK_SCREEN_HEIGHT)
+#define LEFT_LIMIT 0
+#define RIGHT_LIMIT SHERLOCK_SCREEN_WIDTH
+
+class Point32 {
+public:
+ int x;
+ int y;
+
+ Point32() : x(0), y(0) {}
+ Point32(int x1, int y1) : x(x1), y(y1) {}
+ Point32(const Common::Point &pt) : x(pt.x), y(pt.y) {}
+
+ bool operator==(const Point32 &p) const { return x == p.x && y == p.y; }
+ bool operator!=(const Point32 &p) const { return x != p.x || y != p.y; }
+ Point32 operator+(const Point32 &delta) const { return Point32(x + delta.x, y + delta.y); }
+ Point32 operator-(const Point32 &delta) const { return Point32(x - delta.x, y - delta.y); }
+ operator Common::Point() { return Common::Point(x, y); }
+
+ void operator+=(const Point32 &delta) { x += delta.x; y += delta.y; }
+ void operator-=(const Point32 &delta) { x -= delta.x; y -= delta.y; }
+};
+
+class PositionFacing : public Point32 {
+public:
+ int _facing;
+
+ PositionFacing() : Point32(), _facing(0) {}
+ PositionFacing(int xp, int yp, int theFacing) : Point32(xp, yp), _facing(theFacing) {}
+ PositionFacing &operator=(const Point32 &pt) {
+ x = pt.x; y = pt.y;
+ return *this;
+ }
+};
+
+struct WalkSequence {
+ Common::String _vgsName;
+ bool _horizFlip;
+ Common::Array<byte> _sequences;
+
+ WalkSequence() : _horizFlip(false) {}
+ const byte &operator[](int idx) { return _sequences[idx]; }
+
+ /**
+ * Load data for the sequence from a stream
+ */
+ void load(Common::SeekableReadStream &s);
+};
+
+class WalkSequences : public Common::Array < WalkSequence > {
+public:
+ WalkSequences &operator=(const WalkSequences &src);
+};
+
+enum { REVERSE_DIRECTION = 0x80 };
+#define NAMES_COUNT 4
+
+struct ActionType {
+ int _cAnimNum;
+ int _cAnimSpeed;
+ Common::String _names[NAMES_COUNT];
+ int _useFlag; // Which flag USE will set (if any)
+
+ ActionType();
+
+ /**
+ * Load the data for the action
+ */
+ void load(Common::SeekableReadStream &s);
+};
+
+struct UseType: public ActionType {
+ Common::String _target;
+ Common::String _verb;
+
+ UseType();
+
+ /**
+ * Load the data for the UseType
+ */
+ void load(Common::SeekableReadStream &s, bool isRoseTattoo);
+ void load3DO(Common::SeekableReadStream &s);
+
+ /**
+ * Synchronize the data for a savegame
+ */
+ void synchronize(Serializer &s);
+};
+
+class BaseObject {
+protected:
+ static SherlockEngine *_vm;
+protected:
+ /**
+ * This will check to see if the object has reached the end of a sequence.
+ * If it has, it switch to whichever next sequence should be started.
+ * @returns true if the end of a sequence was reached
+ */
+ bool checkEndOfSequence();
+
+ /**
+ * Scans through the sequences array and finds the designated sequence.
+ * It then sets the frame number of the start of that sequence
+ */
+ void setObjSequence(int seq, bool wait);
+public:
+ static bool _countCAnimFrames;
+public:
+ SpriteType _type; // Type of object/sprite
+ Common::String _description; // Description lines
+ byte *_sequences; // Holds animation sequences
+ ImageFile *_images; // Sprite images
+ ImageFrame *_imageFrame; // Pointer to shape in the images
+ int _walkCount; // Walk counter
+ int _allow; // Allowed UI commands
+ int _frameNumber; // Frame number in rame sequence to draw
+ Point32 _position; // Current position
+ Point32 _delta; // Momvement amount
+ Common::Point _oldPosition; // Old position
+ Common::Point _oldSize; // Image's old size
+ Point32 _goto; // Walk destination
+
+ int _lookFlag; // Which flag LOOK will set (if any)
+ int _requiredFlag[2]; // Object will be hidden if not set
+ Common::Point _noShapeSize; // Size of a NO_SHAPE
+ int _status; // Status (open/closed, moved/not)
+ int8 _misc; // Misc field -- use varies with type
+ int _maxFrames; // Number of frames
+ int _flags; // Tells if object can be walked behind
+ AType _aType; // Tells if this is an object, person, talk, etc.
+ int _lookFrames; // How many frames to play of the look anim before pausing
+ int _seqCounter; // How many times this sequence has been executed
+ PositionFacing _lookPosition; // Where to walk when examining object
+ int _lookcAnim;
+ int _seqStack; // Allows gosubs to return to calling frame
+ int _seqTo; // Allows 1-5, 8-3 type sequences encoded in 2 bytes
+ uint _descOffset; // Tells where description starts in DescText
+ int _seqCounter2; // Counter of calling frame sequence
+ uint _seqSize; // Tells where description starts
+ UseType _use[6]; // Serrated Scalpel uses 4, Rose Tattoo 6
+ int _quickDraw; // Flag telling whether to use quick draw routine or not
+ int _scaleVal; // Tells how to scale the sprite
+ int _gotoSeq; // Used by Talk to tell which sequence to goto when able
+ int _talkSeq; // Tells which talk sequence currently in use (Talk or Listen)
+ int _restoreSlot; // Used when talk returns to the previous sequence
+public:
+ BaseObject();
+ virtual ~BaseObject() {}
+ static void setVm(SherlockEngine *vm);
+
+ /**
+ * Returns true if the the object has an Allow Talk Code in the sequence that it's
+ * currently running, specified by the _talkSeq field of the object. If it's 0,
+ * then it's a regular sequence. If it's not 0 but below 128, then it's a Talk Sequence.
+ * If it's above 128, then it's one of the Listen sequences.
+ */
+ bool hasAborts() const;
+
+ /**
+ * Check the state of the object
+ */
+ void checkObject();
+
+ /**
+ * Checks for codes
+ * @param name The name to check for codes
+ * @param messages Provides a lookup list of messages that can be printed
+ * @returns 0 if no codes are found, 1 if codes were found
+ */
+ int checkNameForCodes(const Common::String &name, FixedTextActionId fixedTextActionId = kFixedTextAction_Invalid);
+
+ /**
+ * Adjusts the frame and sequence variables of a sprite that corresponds to the current speaker
+ * so that it points to the beginning of the sequence number's talk sequence in the object's
+ * sequence buffer
+ * @param seq Which sequence to use (if there's more than 1)
+ * @remarks 1: First talk seq, 2: second talk seq, etc.
+ */
+ virtual void setObjTalkSequence(int seq) {}
+};
+
+class Sprite: public BaseObject {
+public:
+ Common::String _name;
+ Common::String _examine; // Examine in-depth description
+ Common::String _pickUp; // Message for if you can't pick up object
+
+ WalkSequences _walkSequences; // Holds animation sequences
+ int _sequenceNumber; // Sequence being used
+ Common::Point _noShapeSize; // Size of a NO_SHAPE
+ int _status; // Status: open/closed, moved/not moved
+ int8 _misc; // Miscellaneous use
+
+ // Rose Tattoo fields
+ int _startSeq; // Frame sequence starts at
+ ImageFrame *_stopFrames[8]; // Stop/rest frame for each direction
+ ImageFile *_altImages; // Images used for alternate NPC sequences
+ int _altSeq; // Which of the sequences the alt graphics apply to (0: main, 1=NPC seq)
+ int _centerWalk; // Flag telling the walk code to offset the walk destination
+ Common::Point _adjust; // Fine tuning adjustment to position when drawn
+ int _oldWalkSequence;
+public:
+ Sprite(): BaseObject() { clear(); }
+ virtual ~Sprite() {}
+
+ static void setVm(SherlockEngine *vm) { _vm = vm; }
+
+ /**
+ * Reset the data for the sprite
+ */
+ void clear();
+
+ /**
+ * Updates the image frame poiner for the sprite
+ */
+ void setImageFrame();
+
+ /**
+ * Checks the sprite's position to see if it's collided with any special objects
+ */
+ void checkSprite();
+
+ /**
+ * Adjusts the frame and sequence variables of a sprite that corresponds to the current speaker
+ * so that it points to the beginning of the sequence number's talk sequence in the object's
+ * sequence buffer
+ * @param seq Which sequence to use (if there's more than 1)
+ * @remarks 1: First talk seq, 2: second talk seq, etc.
+ */
+ virtual void setObjTalkSequence(int seq) {}
+
+ /**
+ * Return frame width
+ */
+ int frameWidth() const { return _imageFrame ? _imageFrame->_frame.w : 0; }
+
+ /**
+ * Return frame height
+ */
+ int frameHeight() const { return _imageFrame ? _imageFrame->_frame.h : 0; }
+
+ /**
+ * Returns the old bounsd for the sprite from the previous frame
+ */
+ const Common::Rect getOldBounds() const;
+
+ /**
+ * This adjusts the sprites position, as well as it's animation sequence:
+ */
+ virtual void adjustSprite() = 0;
+
+ /**
+ * Bring a moving character using the sprite to a standing position
+ */
+ virtual void gotoStand() = 0;
+
+ /**
+ * Set the variables for moving a character from one poisition to another
+ * in a straight line
+ */
+ virtual void setWalking() = 0;
+};
+
+enum { OBJ_BEHIND = 1, OBJ_FLIPPED = 2, OBJ_FORWARD = 4, TURNON_OBJ = 0x20, TURNOFF_OBJ = 0x40 };
+#define USE_COUNT 4
+
+class Object: public BaseObject {
+public:
+ Common::String _name; // Name
+ Common::String _examine; // Examine in-depth description
+ int _sequenceNumber;
+ int _sequenceOffset;
+ int _pickup;
+ int _defaultCommand; // Default right-click command
+
+ // Serrated Scalpel fields
+ int _pickupFlag; // Which flag PICKUP will set (if any)
+ ActionType _aOpen; // Holds data for moving object
+ ActionType _aClose;
+ ActionType _aMove;
+
+ Object();
+ virtual ~Object() {}
+
+ /**
+ * Load the data for the object
+ */
+ void load(Common::SeekableReadStream &s, bool isRoseTattoo);
+ void load3DO(Common::SeekableReadStream &s);
+
+ /**
+ * Toggle the type of an object between hidden and active
+ */
+ void toggleHidden();
+
+ /**
+ * Handle setting any flags associated with the object
+ */
+ void setFlagsAndToggles();
+
+ /**
+ * Adjusts the sprite's position and animation sequence, advancing by 1 frame.
+ * If the end of the sequence is reached, the appropriate action is taken.
+ */
+ void adjustObject();
+
+ /**
+ * Handles trying to pick up an object. If allowed, plays an y necessary animation for picking
+ * up the item, and then adds it to the player's inventory
+ */
+ int pickUpObject(FixedTextActionId fixedTextActionId = kFixedTextAction_Invalid);
+
+ /**
+ * Return the frame width
+ */
+ int frameWidth() const { return _imageFrame ? _imageFrame->_frame.w : 0; }
+
+ /**
+ * Return the frame height
+ */
+ int frameHeight() const { return _imageFrame ? _imageFrame->_frame.h : 0; }
+
+ /**
+ * Returns the current bounds for the sprite
+ */
+ const Common::Rect getNewBounds() const;
+
+ /**
+ * Returns the bounds for a sprite without a shape
+ */
+ const Common::Rect getNoShapeBounds() const;
+
+ /**
+ * Returns the old bounsd for the sprite from the previous frame
+ */
+ const Common::Rect getOldBounds() const;
+
+ /**
+ * Adjusts the frame and sequence variables of a sprite that corresponds to the current speaker
+ * so that it points to the beginning of the sequence number's talk sequence in the object's
+ * sequence buffer
+ * @param seq Which sequence to use (if there's more than 1)
+ * @remarks 1: First talk seq, 2: second talk seq, etc.
+ */
+ virtual void setObjTalkSequence(int seq);
+};
+
+struct CAnim {
+ Common::String _name; // Name
+ Common::Point _position; // Position
+ int _dataSize; // Size of uncompressed animation data
+ uint32 _dataOffset; // offset within room file of animation data
+ int _flags; // Tells if can be walked behind
+ PositionFacing _goto[2]; // Position Holmes (and NPC in Rose Tattoo) should walk to before anim starts
+ PositionFacing _teleport[2]; // Location Holmes (and NPC) shoul teleport to after playing canim
+
+ // Scalpel specific
+ byte _sequences[MAX_FRAME]; // Animation sequences
+ SpriteType _type;
+
+ // Rose Tattoo specific
+ int _scaleVal; // How much the canim is scaled
+
+ /**
+ * Load the data for the animation
+ */
+ void load(Common::SeekableReadStream &s, bool isRoseTattoo, uint32 dataOffset);
+ void load3DO(Common::SeekableReadStream &s, uint32 dataOffset);
+};
+
+struct SceneImage {
+ ImageFile *_images; // Object images
+ int _maxFrames; // How many frames in object
+ int _filesize; // File size
+
+ SceneImage();
+} ;
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp
new file mode 100644
index 0000000000..1e19dccb32
--- /dev/null
+++ b/engines/sherlock/people.cpp
@@ -0,0 +1,332 @@
+/* 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 "sherlock/people.h"
+#include "sherlock/sherlock.h"
+#include "sherlock/scalpel/scalpel_people.h"
+#include "sherlock/tattoo/tattoo_people.h"
+
+namespace Sherlock {
+
+// Characer animation sequences
+static const uint8 CHARACTER_SEQUENCES[MAX_HOLMES_SEQUENCE][MAX_FRAME] = {
+ { 29, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Right
+ { 22, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Down
+ { 29, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Left
+ { 15, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Up
+ { 42, 1, 2, 3, 4, 5, 0 }, // Goto Stand Right
+ { 47, 1, 2, 3, 4, 5, 0 }, // Goto Stand Down
+ { 42, 1, 2, 3, 4, 5, 0 }, // Goto Stand Left
+ { 36, 1, 0 }, // Goto Stand Up
+ { 8, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Up Right
+ { 1, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Down Right
+ { 8, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Up Left
+ { 1, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Down Left
+ { 37, 1, 2, 3, 4, 5, 0 }, // Goto Stand Up Right
+ { 37, 1, 2, 3, 4, 5, 0 }, // Goto Stand Up Left
+ { 52, 1, 2, 3, 4, 0 }, // Goto Stand Down Right
+ { 52, 1, 2, 3, 4, 0 } // Goto Stand Down Left
+};
+
+// Rose Tattoo walk image libraries
+// Walk resources within WALK.LIB
+const char *const WALK_LIB_NAMES[NUM_IN_WALK_LIB] = {
+ "SVGAWALK.VGS",
+ "COATWALK.VGS",
+ "WATSON.VGS",
+ "NOHAT.VGS",
+ "TUPRIGHT.VGS",
+ "TRIGHT.VGS",
+ "TDOWNRG.VGS",
+ "TWUPRIGH.VGS",
+ "TWRIGHT.VGS",
+ "TWDOWNRG.VGS"
+};
+
+/*----------------------------------------------------------------*/
+
+Person::Person() : Sprite() {
+ _walkLoaded = false;
+ _oldWalkSequence = -1;
+ _srcZone = _destZone = 0;
+}
+
+void Person::goAllTheWay() {
+ Scene &scene = *_vm->_scene;
+ Common::Point srcPt = getSourcePoint();
+
+ // Get the zone the player is currently in
+ _srcZone = scene.whichZone(srcPt);
+ if (_srcZone == -1)
+ _srcZone = scene.closestZone(srcPt);
+
+ // Get the zone of the destination
+ _destZone = scene.whichZone(_walkDest);
+ if (_destZone == -1) {
+ _destZone = scene.closestZone(_walkDest);
+
+ // Check for any restriction of final destination position
+ _walkDest = _vm->_people->restrictToZone(_destZone, _walkDest);
+ }
+
+ // Only do a walk if both zones are acceptable
+ if (_srcZone == -2 || _destZone == -2)
+ return;
+
+ // If the start and dest zones are the same, walk directly to the dest point
+ if (_srcZone == _destZone) {
+ setWalking();
+ } else {
+ // Otherwise a path needs to be formed from the path information
+ int i = scene._walkDirectory[_srcZone][_destZone];
+
+ // See if we need to use a reverse path
+ if (i == -1)
+ i = scene._walkDirectory[_destZone][_srcZone];
+
+ const WalkArray &points = scene._walkPoints[i];
+
+ // See how many points there are between the src and dest zones
+ if (!points._pointsCount || points._pointsCount == -1) {
+ // There are none, so just walk to the new zone
+ setWalking();
+ } else {
+ // There are points, so set up a multi-step path between points
+ // to reach the given destination
+ _walkTo.clear();
+
+ if (scene._walkDirectory[_srcZone][_destZone] != -1) {
+ for (int idx = (int)points.size() - 1; idx >= 0; --idx)
+ _walkTo.push(points[idx]);
+ } else {
+ for (int idx = 0; idx < (int)points.size(); ++idx) {
+ _walkTo.push(points[idx]);
+ }
+ }
+
+ // Final position
+ _walkTo.push(_walkDest);
+
+ // Start walking
+ _walkDest = _walkTo.pop();
+ setWalking();
+ }
+ }
+}
+
+/*----------------------------------------------------------------*/
+
+People *People::init(SherlockEngine *vm) {
+ if (vm->getGameID() == GType_SerratedScalpel)
+ return new Scalpel::ScalpelPeople(vm);
+ else
+ return new Tattoo::TattooPeople(vm);
+}
+
+People::People(SherlockEngine *vm) : _vm(vm) {
+ _holmesOn = true;
+ _allowWalkAbort = true;
+ _portraitLoaded = false;
+ _portraitsOn = true;
+ _clearingThePortrait = false;
+ _talkPics = nullptr;
+ _portraitSide = 0;
+ _speakerFlip = false;
+ _holmesFlip = false;
+ _holmesQuotient = 0;
+ _savedPos = Point32(-1, -1);
+ _savedPos._facing = -1;
+ _forceWalkReload = false;
+ _useWalkLib = false;
+ _walkControl = 0;
+
+ _portrait._sequences = new byte[32];
+}
+
+People::~People() {
+ for (uint idx = 0; idx < _data.size(); ++idx) {
+ if (_data[idx]->_walkLoaded)
+ delete _data[idx]->_images;
+ delete _data[idx];
+ }
+
+ delete _talkPics;
+ delete[] _portrait._sequences;
+}
+
+void People::reset() {
+ SaveManager &saves = *_vm->_saves;
+ Talk &talk = *_vm->_talk;
+ _data[HOLMES]->_description = "Sherlock Holmes!";
+
+ // Note: Serrated Scalpel only uses a single Person slot for Sherlock.. Watson is handled by scene sprites
+ int count = IS_SERRATED_SCALPEL ? 1 : MAX_CHARACTERS;
+ for (int idx = 0; idx < count; ++idx) {
+ Person &p = *_data[idx];
+
+ if (IS_SERRATED_SCALPEL) {
+ p._type = CHARACTER;
+ p._sequenceNumber = (int)Tattoo::STOP_DOWNRIGHT;
+ p._position = Point32(100 * FIXED_INT_MULTIPLIER, 110 * FIXED_INT_MULTIPLIER);
+ } else if (!talk._scriptMoreFlag && !saves._justLoaded) {
+ p._type = (idx == 0) ? CHARACTER : INVALID;
+ p._sequenceNumber = (int)Scalpel::STOP_DOWNRIGHT;
+ p._position = Point32(36 * FIXED_INT_MULTIPLIER, 29 * FIXED_INT_MULTIPLIER);
+ p._use[0]._verb = "";
+ p._use[1]._verb = "";
+ }
+
+ p._imageFrame = nullptr;
+ p._frameNumber = 1;
+ p._delta = Point32(0, 0);
+ p._oldPosition = Common::Point(0, 0);
+ p._oldSize = Common::Point(0, 0);
+ p._misc = 0;
+ p._walkCount = 0;
+ p._pickUp = "";
+ p._allow = 0;
+ p._noShapeSize = Common::Point(0, 0);
+ p._goto = Common::Point(0, 0);
+ p._status = 0;
+ p._seqTo = 0;
+ p._seqCounter = p._seqCounter2 = 0;
+ p._seqStack = 0;
+ p._gotoSeq = p._talkSeq = 0;
+ p._restoreSlot = 0;
+ p._startSeq = 0;
+ p._altImages = nullptr;
+ p._altSeq = 0;
+ p._centerWalk = true;
+ p._adjust = Common::Point(0, 0);
+
+ // Load the default walk sequences
+ p._walkTo.clear();
+ p._oldWalkSequence = -1;
+ p._walkSequences.clear();
+ if (IS_SERRATED_SCALPEL) {
+ p._walkSequences.resize(MAX_HOLMES_SEQUENCE);
+ for (int seqIdx = 0; seqIdx < MAX_HOLMES_SEQUENCE; ++seqIdx) {
+ p._walkSequences[seqIdx]._sequences.clear();
+
+ const byte *pSrc = &CHARACTER_SEQUENCES[seqIdx][0];
+ do {
+ p._walkSequences[seqIdx]._sequences.push_back(*pSrc);
+ } while (*pSrc++);
+ }
+ }
+ }
+}
+
+bool People::freeWalk() {
+ bool result = false;
+
+ for (int idx = 0; idx < MAX_CHARACTERS; ++idx) {
+ if (_data[idx]->_walkLoaded) {
+ delete _data[idx]->_images;
+ _data[idx]->_images = nullptr;
+
+ _data[idx]->_walkLoaded = false;
+ result = true;
+ }
+ }
+
+ return result;
+}
+
+int People::findSpeaker(int speaker) {
+ Scene &scene = *_vm->_scene;
+ const char *portrait = _characters[speaker]._portrait;
+
+ for (int idx = 0; idx < (int)scene._bgShapes.size(); ++idx) {
+ Object &obj = scene._bgShapes[idx];
+
+ if (obj._type == ACTIVE_BG_SHAPE) {
+ Common::String name(obj._name.c_str(), obj._name.c_str() + 4);
+
+ if (name.equalsIgnoreCase(portrait)
+ && obj._name[4] >= '0' && obj._name[4] <= '9')
+ return idx;
+ }
+ }
+
+ return -1;
+}
+
+void People::clearTalking() {
+ Scene &scene = *_vm->_scene;
+ Screen &screen = *_vm->_screen;
+ Talk &talk = *_vm->_talk;
+
+ if (_portraitsOn) {
+ Common::Point pt = _portrait._position;
+ int width, height;
+ _portrait._imageFrame = _talkPics ? &(*_talkPics)[0] : (ImageFrame *)nullptr;
+
+ // Flag portrait for removal, and save the size of the frame to use erasing it
+ _portrait._type = REMOVE;
+ _portrait._delta.x = width = _portrait.frameWidth();
+ _portrait._delta.y = height = _portrait.frameHeight();
+
+ delete _talkPics;
+ _talkPics = nullptr;
+
+ // Flag to let the talk code know not to interrupt on the next doBgAnim
+ _clearingThePortrait = true;
+ scene.doBgAnim();
+ _clearingThePortrait = false;
+
+ screen.slamArea(pt.x, pt.y, width, height);
+
+ if (!talk._talkToAbort)
+ _portraitLoaded = false;
+ }
+}
+
+void People::synchronize(Serializer &s) {
+ s.syncAsByte(_holmesOn);
+
+ if (IS_SERRATED_SCALPEL) {
+ s.syncAsSint16LE(_data[HOLMES]->_position.x);
+ s.syncAsSint16LE(_data[HOLMES]->_position.y);
+ s.syncAsSint16LE(_data[HOLMES]->_sequenceNumber);
+ } else {
+ for (uint idx = 0; idx < _data.size(); ++idx) {
+ Person &p = *_data[idx];
+ s.syncAsSint16LE(p._position.x);
+ s.syncAsSint16LE(p._position.y);
+ s.syncAsSint16LE(p._sequenceNumber);
+ s.syncAsSint16LE(p._type);
+ s.syncString(p._walkVGSName);
+ s.syncString(p._description);
+ s.syncString(p._examine);
+ }
+ }
+
+ s.syncAsSint16LE(_holmesQuotient);
+
+ if (s.isLoading()) {
+ _savedPos = _data[HOLMES]->_position;
+ _savedPos._facing = _data[HOLMES]->_sequenceNumber;
+ }
+}
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h
new file mode 100644
index 0000000000..b59522e4b8
--- /dev/null
+++ b/engines/sherlock/people.h
@@ -0,0 +1,168 @@
+/* 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 SHERLOCK_PEOPLE_H
+#define SHERLOCK_PEOPLE_H
+
+#include "common/scummsys.h"
+#include "common/queue.h"
+#include "sherlock/objects.h"
+#include "sherlock/saveload.h"
+
+namespace Sherlock {
+
+enum PeopleId {
+ HOLMES = 0,
+ WATSON = 1,
+ MAX_NPC_PATH = 200
+};
+
+enum {
+ MAP_UP = 1, MAP_UPRIGHT = 2, MAP_RIGHT = 1, MAP_DOWNRIGHT = 4,
+ MAP_DOWN = 5, MAP_DOWNLEFT = 6, MAP_LEFT = 2, MAP_UPLEFT = 8
+};
+
+#define NUM_IN_WALK_LIB 10
+extern const char *const WALK_LIB_NAMES[10];
+
+#define MAX_CHARACTERS (IS_SERRATED_SCALPEL ? 1 : 6)
+
+struct PersonData {
+ const char *_name;
+ const char *_portrait;
+ const byte *_stillSequences;
+ const byte *_talkSequences;
+
+ PersonData(const char *name, const char *portrait, const byte *stillSequences, const byte *talkSequences) :
+ _name(name), _portrait(portrait), _stillSequences(stillSequences), _talkSequences(talkSequences) {}
+};
+
+class Person : public Sprite {
+protected:
+ /**
+ * Get the source position for a character potentially affected by scaling
+ */
+ virtual Common::Point getSourcePoint() const = 0;
+public:
+ Common::Queue<Common::Point> _walkTo;
+ int _srcZone, _destZone;
+ bool _walkLoaded;
+ Common::String _portrait;
+ Common::Point _walkDest;
+ Common::String _npcName;
+
+ // Rose Tattoo fields
+ Common::String _walkVGSName; // Name of walk library person is using
+public:
+ Person();
+ virtual ~Person() {}
+
+ /**
+ * Called to set the character walking to the current cursor location.
+ * It uses the zones and the inter-zone points to determine a series
+ * of steps to walk to get to that position.
+ */
+ void goAllTheWay();
+
+ /**
+ * Walk to the co-ordinates passed, and then face the given direction
+ */
+ virtual void walkToCoords(const Point32 &destPos, int destDir) = 0;
+};
+
+class SherlockEngine;
+
+class People {
+protected:
+ SherlockEngine *_vm;
+ Common::Array<Person *> _data;
+
+ People(SherlockEngine *vm);
+public:
+ Common::Array<PersonData> _characters;
+ ImageFile *_talkPics;
+ PositionFacing _savedPos;
+ bool _holmesOn;
+ bool _portraitLoaded;
+ bool _portraitsOn;
+ Object _portrait;
+ bool _clearingThePortrait;
+ bool _allowWalkAbort;
+ int _portraitSide;
+ bool _speakerFlip;
+ bool _holmesFlip;
+ int _holmesQuotient;
+ bool _forceWalkReload;
+ bool _useWalkLib;
+
+ int _walkControl;
+public:
+ static People *init(SherlockEngine *vm);
+ virtual ~People();
+
+ Person &operator[](PeopleId id) { return *_data[id]; }
+ Person &operator[](int idx) { return *_data[idx]; }
+
+ /**
+ * Reset the player data
+ */
+ void reset();
+
+ /**
+ * If the walk data has been loaded, then it will be freed
+ */
+ bool freeWalk();
+
+ /**
+ * Turn off any currently active portraits, and removes them from being drawn
+ */
+ void clearTalking();
+
+ /**
+ * Finds the scene background object corresponding to a specified speaker
+ */
+ virtual int findSpeaker(int speaker);
+
+ /**
+ * Synchronize the data for a savegame
+ */
+ virtual void synchronize(Serializer &s) = 0;
+
+ /**
+ * Change the sequence of the scene background object associated with the current speaker.
+ */
+ virtual void setTalkSequence(int speaker, int sequenceNum = 1) = 0;
+
+ /**
+ * Load the walking images for Sherlock
+ */
+ virtual bool loadWalk() = 0;
+
+ /**
+ * Restrict passed point to zone using Sherlock's positioning rules
+ */
+ virtual const Common::Point restrictToZone(int zoneId, const Common::Point &destPos) = 0;
+};
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp
new file mode 100644
index 0000000000..206d7173ac
--- /dev/null
+++ b/engines/sherlock/resources.cpp
@@ -0,0 +1,372 @@
+/* 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 "sherlock/resources.h"
+#include "sherlock/screen.h"
+#include "sherlock/sherlock.h"
+#include "common/debug.h"
+#include "common/memstream.h"
+
+namespace Sherlock {
+
+Cache::Cache(SherlockEngine *vm) : _vm(vm) {
+}
+
+bool Cache::isCached(const Common::String &filename) const {
+ return _resources.contains(filename);
+}
+
+void Cache::load(const Common::String &name) {
+ // First check if the entry already exists
+ if (_resources.contains(name))
+ return;
+
+ // Open the file for reading
+ Common::File f;
+ if (!f.open(name))
+ error("Could not read file - %s", name.c_str());
+
+ load(name, f);
+
+ f.close();
+}
+
+void Cache::load(const Common::String &name, Common::SeekableReadStream &stream) {
+ // First check if the entry already exists
+ if (_resources.contains(name))
+ return;
+
+ int32 signature = stream.readUint32BE();
+ stream.seek(0);
+
+ // Allocate a new cache entry
+ _resources[name] = CacheEntry();
+ CacheEntry &cacheEntry = _resources[name];
+
+ // Check whether the file is compressed
+ if (signature == MKTAG('L', 'Z', 'V', 26)) {
+ // It's compressed, so decompress the file and store it's data in the cache entry
+ Common::SeekableReadStream *decompressed = _vm->_res->decompress(stream);
+ cacheEntry.resize(decompressed->size());
+ decompressed->read(&cacheEntry[0], decompressed->size());
+
+ delete decompressed;
+ } else {
+ // It's not, so read the raw data of the file into the cache entry
+ cacheEntry.resize(stream.size());
+ stream.read(&cacheEntry[0], stream.size());
+ }
+}
+
+Common::SeekableReadStream *Cache::get(const Common::String &filename) const {
+ // Return a memory stream that encapsulates the data
+ const CacheEntry &cacheEntry = _resources[filename];
+ return new Common::MemoryReadStream(&cacheEntry[0], cacheEntry.size());
+}
+
+/*----------------------------------------------------------------*/
+
+Resources::Resources(SherlockEngine *vm) : _vm(vm), _cache(vm) {
+ _resourceIndex = -1;
+
+ if (_vm->_interactiveFl) {
+ if (!IS_3DO) {
+ addToCache("vgs.lib");
+ addToCache("talk.lib");
+ addToCache("journal.txt");
+
+ if (IS_SERRATED_SCALPEL) {
+ addToCache("sequence.txt");
+ addToCache("portrait.lib");
+ } else {
+ addToCache("walk.lib");
+ }
+ } else {
+ // 3DO
+
+ // ITEM data from VGS.LIB is in ITEM.LIB
+ addToCache("item.lib");
+
+ // talk.lib - resources themselves seem to be the same, although a few texts were slightly changed
+ addToCache("talk.lib");
+
+ // remaining files are missing
+ // portraits were replaced with FMV
+ }
+ }
+}
+
+void Resources::addToCache(const Common::String &filename) {
+ _cache.load(filename);
+
+ // Check to see if the file is a library
+ Common::SeekableReadStream *stream = load(filename);
+ uint32 header = stream->readUint32BE();
+
+ if (header == MKTAG('L', 'I', 'B', 26))
+ loadLibraryIndex(filename, stream, false);
+ else if (header == MKTAG('L', 'I', 'C', 26))
+ loadLibraryIndex(filename, stream, true);
+
+ delete stream;
+}
+
+void Resources::addToCache(const Common::String &filename, const Common::String &libFilename) {
+ // Get the resource
+ Common::SeekableReadStream *stream = load(filename, libFilename);
+
+ _cache.load(filename, *stream);
+
+ delete stream;
+}
+
+void Resources::addToCache(const Common::String &filename, Common::SeekableReadStream &stream) {
+ _cache.load(filename, stream);
+}
+
+Common::SeekableReadStream *Resources::load(const Common::String &filename) {
+ // First check if the file is directly in the cache
+ if (_cache.isCached(filename))
+ return _cache.get(filename);
+
+ // Secondly, iterate through any loaded library file looking for a resource
+ // that has the same name
+ for (LibraryIndexes::iterator i = _indexes.begin(); i != _indexes.end(); ++i) {
+ if (i->_value.contains(filename)) {
+ // Get a stream reference to the given library file
+ Common::SeekableReadStream *stream = load(i->_key);
+ LibraryEntry &entry = i->_value[filename];
+ _resourceIndex = entry._index;
+
+ stream->seek(entry._offset);
+ Common::SeekableReadStream *resStream = stream->readStream(entry._size);
+ decompressIfNecessary(resStream);
+
+ delete stream;
+ return resStream;
+ }
+ }
+
+ // At this point, fall back on a physical file with the given name
+ Common::File f;
+ if (!f.open(filename))
+ error("Could not load file - %s", filename.c_str());
+
+ Common::SeekableReadStream *stream = f.readStream(f.size());
+ f.close();
+ decompressIfNecessary(stream);
+
+ return stream;
+}
+
+void Resources::decompressIfNecessary(Common::SeekableReadStream *&stream) {
+ bool isCompressed = stream->readUint32BE() == MKTAG('L', 'Z', 'V', 26);
+
+ if (isCompressed) {
+ int outSize = stream->readUint32LE();
+ Common::SeekableReadStream *newStream = decompressLZ(*stream, outSize);
+ delete stream;
+ stream = newStream;
+ } else {
+ stream->seek(-4, SEEK_CUR);
+ }
+}
+
+Common::SeekableReadStream *Resources::load(const Common::String &filename, const Common::String &libraryFile) {
+ // Open up the library for access
+ Common::SeekableReadStream *libStream = load(libraryFile);
+
+ // Check if the library has already had it's index read, and if not, load it
+ if (!_indexes.contains(libraryFile))
+ loadLibraryIndex(libraryFile, libStream, false);
+
+ // Extract the data for the specified resource and return it
+ LibraryEntry &entry = _indexes[libraryFile][filename];
+ libStream->seek(entry._offset);
+ Common::SeekableReadStream *stream = libStream->readStream(entry._size);
+ decompressIfNecessary(stream);
+
+ delete libStream;
+ return stream;
+}
+
+bool Resources::exists(const Common::String &filename) const {
+ Common::File f;
+ return f.exists(filename) || _cache.isCached(filename);
+}
+
+void Resources::loadLibraryIndex(const Common::String &libFilename,
+ Common::SeekableReadStream *stream, bool isNewStyle) {
+ uint32 offset, nextOffset;
+
+ // Create an index entry
+ _indexes[libFilename] = LibraryIndex();
+ LibraryIndex &index = _indexes[libFilename];
+
+ // Read in the number of resources
+ stream->seek(4);
+ int count = 0;
+
+ if (!IS_3DO) {
+ // PC
+ count = stream->readUint16LE();
+
+ if (isNewStyle)
+ stream->seek((count + 1) * 8, SEEK_CUR);
+
+ // Loop through reading in the entries
+ for (int idx = 0; idx < count; ++idx) {
+ // Read the name of the resource
+ char resName[13];
+ stream->read(resName, 13);
+ resName[12] = '\0';
+
+ // Read the offset
+ offset = stream->readUint32LE();
+
+ if (idx == (count - 1)) {
+ nextOffset = stream->size();
+ } else {
+ // Read the size by jumping forward to read the next entry's offset
+ stream->seek(13, SEEK_CUR);
+ nextOffset = stream->readUint32LE();
+ stream->seek(-17, SEEK_CUR);
+ }
+
+ // Add the entry to the index
+ index[resName] = LibraryEntry(idx, offset, nextOffset - offset);
+ }
+
+ } else {
+ // 3DO
+ count = stream->readUint16BE();
+
+ // 3DO header
+ // Loop through reading in the entries
+
+ // Read offset of first entry
+ offset = stream->readUint32BE();
+
+ for (int idx = 0; idx < count; ++idx) {
+
+ // Read the name of the resource
+ char resName[13];
+ stream->read(resName, 13);
+ resName[12] = '\0';
+
+ stream->skip(3); // filler
+
+ if (idx == (count - 1)) {
+ nextOffset = stream->size();
+ } else {
+ // Read the offset of the next entry
+ nextOffset = stream->readUint32BE();
+ }
+
+ // Add the entry to the index
+ index[resName] = LibraryEntry(idx, offset, nextOffset - offset);
+
+ // use next offset as current offset
+ offset = nextOffset;
+ }
+ }
+}
+
+int Resources::resourceIndex() const {
+ return _resourceIndex;
+}
+
+Common::SeekableReadStream *Resources::decompress(Common::SeekableReadStream &source) {
+ // This variation can't be used by Rose Tattoo, since compressed resources include the input size,
+ // not the output size. Which means their decompression has to be done via passed buffers
+ assert(IS_SERRATED_SCALPEL);
+
+ uint32 id = source.readUint32BE();
+ assert(id == MKTAG('L', 'Z', 'V', 0x1A));
+
+ uint32 outputSize = source.readUint32LE();
+ return decompressLZ(source, outputSize);
+}
+
+Common::SeekableReadStream *Resources::decompress(Common::SeekableReadStream &source, uint32 outSize) {
+ int inSize = IS_ROSE_TATTOO ? source.readSint32LE() : -1;
+ byte *outBuffer = (byte *)malloc(outSize);
+ Common::MemoryReadStream *outStream = new Common::MemoryReadStream(outBuffer, outSize, DisposeAfterUse::YES);
+
+ decompressLZ(source, outBuffer, outSize, inSize);
+
+ return outStream;
+}
+
+void Resources::decompress(Common::SeekableReadStream &source, byte *buffer, uint32 outSize) {
+ int inputSize = IS_ROSE_TATTOO ? source.readSint32LE() : -1;
+
+ decompressLZ(source, buffer, outSize, inputSize);
+}
+
+Common::SeekableReadStream *Resources::decompressLZ(Common::SeekableReadStream &source, uint32 outSize) {
+ byte *dataOut = (byte *)malloc(outSize);
+ decompressLZ(source, dataOut, outSize, -1);
+
+ return new Common::MemoryReadStream(dataOut, outSize, DisposeAfterUse::YES);
+}
+
+void Resources::decompressLZ(Common::SeekableReadStream &source, byte *outBuffer, int32 outSize, int32 inSize) {
+ byte lzWindow[4096];
+ uint16 lzWindowPos;
+ uint16 cmd;
+
+ byte *outBufferEnd = outBuffer + outSize;
+ int endPos = source.pos() + inSize;
+
+ memset(lzWindow, 0xFF, 0xFEE);
+ lzWindowPos = 0xFEE;
+ cmd = 0;
+
+ do {
+ cmd >>= 1;
+ if (!(cmd & 0x100))
+ cmd = source.readByte() | 0xFF00;
+
+ if (cmd & 1) {
+ byte literal = source.readByte();
+ *outBuffer++ = literal;
+ lzWindow[lzWindowPos] = literal;
+ lzWindowPos = (lzWindowPos + 1) & 0x0FFF;
+ } else {
+ int copyPos, copyLen;
+ copyPos = source.readByte();
+ copyLen = source.readByte();
+ copyPos = copyPos | ((copyLen & 0xF0) << 4);
+ copyLen = (copyLen & 0x0F) + 3;
+ while (copyLen--) {
+ byte literal = lzWindow[copyPos];
+ copyPos = (copyPos + 1) & 0x0FFF;
+ *outBuffer++ = literal;
+ lzWindow[lzWindowPos] = literal;
+ lzWindowPos = (lzWindowPos + 1) & 0x0FFF;
+ }
+ }
+ } while ((outSize == -1 || outBuffer < outBufferEnd) && (inSize == -1 || source.pos() < endPos));
+}
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/resources.h b/engines/sherlock/resources.h
new file mode 100644
index 0000000000..8e0216d69d
--- /dev/null
+++ b/engines/sherlock/resources.h
@@ -0,0 +1,170 @@
+/* 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 SHERLOCK_RESOURCES_H
+#define SHERLOCK_RESOURCES_H
+
+#include "common/array.h"
+#include "common/file.h"
+#include "common/hashmap.h"
+#include "common/hash-str.h"
+#include "common/rect.h"
+#include "common/str.h"
+#include "common/stream.h"
+#include "graphics/surface.h"
+
+namespace Sherlock {
+
+typedef Common::Array<byte> CacheEntry;
+typedef Common::HashMap<Common::String, CacheEntry, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> CacheHash;
+
+struct LibraryEntry {
+ uint32 _offset, _size;
+ int _index;
+
+ LibraryEntry() : _index(0), _offset(0), _size(0) {}
+ LibraryEntry(int index, uint32 offset, uint32 size) :
+ _index(index), _offset(offset), _size(size) {}
+};
+typedef Common::HashMap<Common::String, LibraryEntry, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> LibraryIndex;
+typedef Common::HashMap<Common::String, LibraryIndex, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> LibraryIndexes;
+
+class SherlockEngine;
+
+class Cache {
+private:
+ SherlockEngine *_vm;
+ CacheHash _resources;
+public:
+ Cache(SherlockEngine *_vm);
+
+ /**
+ * Returns true if a given file is currently being cached
+ */
+ bool isCached(const Common::String &filename) const;
+
+ /**
+ * Loads a file into the cache if it's not already present, and returns it.
+ * If the file is LZW compressed, automatically decompresses it and loads
+ * the uncompressed version into memory
+ */
+ void load(const Common::String &name);
+
+ /**
+ * Load a cache entry based on a passed stream
+ */
+ void load(const Common::String &name, Common::SeekableReadStream &stream);
+
+ /**
+ * Get a file from the cache
+ */
+ Common::SeekableReadStream *get(const Common::String &filename) const;
+};
+
+class Resources {
+private:
+ SherlockEngine *_vm;
+ Cache _cache;
+ LibraryIndexes _indexes;
+ int _resourceIndex;
+
+ /**
+ * Reads in the index from a library file, and caches it's index for later use
+ */
+ void loadLibraryIndex(const Common::String &libFilename, Common::SeekableReadStream *stream, bool isNewStyle);
+public:
+ Resources(SherlockEngine *vm);
+
+ /**
+ * Adds the specified file to the cache. If it's a library file, takes care of
+ * loading it's index for future use
+ */
+ void addToCache(const Common::String &filename);
+
+ /**
+ * Adds a resource from a library file to the cache
+ */
+ void addToCache(const Common::String &filename, const Common::String &libFilename);
+
+ /**
+ * Adds a given stream to the cache under the given name
+ */
+ void addToCache(const Common::String &filename, Common::SeekableReadStream &stream);
+
+ bool isInCache(const Common::String &filename) const { return _cache.isCached(filename); }
+
+ /**
+ * Checks the passed stream, and if is compressed, deletes it and replaces it with it's uncompressed data
+ */
+ void decompressIfNecessary(Common::SeekableReadStream *&stream);
+
+ /**
+ * Returns a stream for a given file
+ */
+ Common::SeekableReadStream *load(const Common::String &filename);
+
+ /**
+ * Loads a specific resource from a given library file
+ */
+ Common::SeekableReadStream *load(const Common::String &filename, const Common::String &libraryFile);
+
+ /**
+ * Returns true if the given file exists on disk or in the cache
+ */
+ bool exists(const Common::String &filename) const;
+
+ /**
+ * Returns the index of the last loaded resource in it's given library file.
+ * This will be used primarily when loading talk files, so the engine can
+ * update the given conversation number in the journal
+ */
+ int resourceIndex() const;
+
+ /**
+ * Decompresses LZW compressed data
+ */
+ Common::SeekableReadStream *decompress(Common::SeekableReadStream &source);
+
+ /**
+ * Decompresses LZW compressed data
+ */
+ Common::SeekableReadStream *decompress(Common::SeekableReadStream &source, uint32 outSize);
+
+ /**
+ * Decompresses LZW compressed data
+ */
+ void decompress(Common::SeekableReadStream &source, byte *buffer, uint32 outSize);
+
+ /**
+ * Decompresses LZW compressed data
+ */
+ static Common::SeekableReadStream *decompressLZ(Common::SeekableReadStream &source, uint32 outSize);
+
+ /**
+ * Decompresses LZW compressed data
+ */
+ static void decompressLZ(Common::SeekableReadStream &source, byte *outBuffer, int32 outSize, int32 inSize);
+};
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp
new file mode 100644
index 0000000000..fae8196dc1
--- /dev/null
+++ b/engines/sherlock/saveload.cpp
@@ -0,0 +1,278 @@
+/* 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 "sherlock/saveload.h"
+#include "sherlock/surface.h"
+#include "sherlock/sherlock.h"
+#include "sherlock/scalpel/scalpel_saveload.h"
+#include "common/system.h"
+#include "graphics/scaler.h"
+#include "graphics/thumbnail.h"
+
+namespace Sherlock {
+
+const char *const EMPTY_SAVEGAME_SLOT = "-EMPTY-";
+static const char *const SAVEGAME_STR = "SHLK";
+#define SAVEGAME_STR_SIZE 4
+
+/*----------------------------------------------------------------*/
+
+SaveManager *SaveManager::init(SherlockEngine *vm, const Common::String &target) {
+ if (vm->getGameID() == GType_SerratedScalpel)
+ return new Scalpel::ScalpelSaveManager(vm, target);
+ else
+ return new SaveManager(vm, target);
+}
+
+SaveManager::SaveManager(SherlockEngine *vm, const Common::String &target) :
+ _vm(vm), _target(target) {
+ _saveThumb = nullptr;
+ _envMode = SAVEMODE_NONE;
+ _justLoaded = false;
+ _savegameIndex = 0;
+}
+
+SaveManager::~SaveManager() {
+ if (_saveThumb) {
+ _saveThumb->free();
+ delete _saveThumb;
+ }
+}
+
+void SaveManager::createSavegameList() {
+ Screen &screen = *_vm->_screen;
+
+ _savegames.clear();
+ for (int idx = 0; idx < MAX_SAVEGAME_SLOTS; ++idx)
+ _savegames.push_back(EMPTY_SAVEGAME_SLOT);
+
+ SaveStateList saveList = getSavegameList(_target);
+ for (uint idx = 0; idx < saveList.size(); ++idx) {
+ int slot = saveList[idx].getSaveSlot() - 1;
+ if (slot >= 0 && slot < MAX_SAVEGAME_SLOTS)
+ _savegames[slot] = saveList[idx].getDescription();
+ }
+
+ // Ensure the names will fit on the screen
+ for (uint idx = 0; idx < _savegames.size(); ++idx) {
+ int width = screen.stringWidth(_savegames[idx]) + 24;
+ if (width > 308) {
+ // It won't fit in, so remove characters until it does
+ do {
+ width -= screen.charWidth(_savegames[idx].lastChar());
+ _savegames[idx].deleteLastChar();
+ } while (width > 300);
+ }
+ }
+}
+
+SaveStateList SaveManager::getSavegameList(const Common::String &target) {
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ Common::StringArray filenames;
+ Common::String saveDesc;
+ Common::String pattern = Common::String::format("%s.0??", target.c_str());
+ SherlockSavegameHeader header;
+
+ filenames = saveFileMan->listSavefiles(pattern);
+ sort(filenames.begin(), filenames.end()); // Sort to get the files in numerical order
+
+ SaveStateList saveList;
+ for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
+ const char *ext = strrchr(file->c_str(), '.');
+ int slot = ext ? atoi(ext + 1) : -1;
+
+ if (slot >= 0 && slot < MAX_SAVEGAME_SLOTS) {
+ Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file);
+
+ if (in) {
+ if (!readSavegameHeader(in, header))
+ continue;
+
+ saveList.push_back(SaveStateDescriptor(slot, header._saveName));
+
+ header._thumbnail->free();
+ delete header._thumbnail;
+ delete in;
+ }
+ }
+ }
+
+ return saveList;
+}
+
+bool SaveManager::readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHeader &header) {
+ char saveIdentBuffer[SAVEGAME_STR_SIZE + 1];
+ header._thumbnail = nullptr;
+
+ // Validate the header Id
+ in->read(saveIdentBuffer, SAVEGAME_STR_SIZE + 1);
+ if (strncmp(saveIdentBuffer, SAVEGAME_STR, SAVEGAME_STR_SIZE))
+ return false;
+
+ header._version = in->readByte();
+ if (header._version < MINIMUM_SAVEGAME_VERSION || header._version > CURRENT_SAVEGAME_VERSION)
+ return false;
+
+ // Read in the string
+ 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)
+ return false;
+
+ // Read in save date/time
+ header._year = in->readSint16LE();
+ header._month = in->readSint16LE();
+ header._day = in->readSint16LE();
+ header._hour = in->readSint16LE();
+ header._minute = in->readSint16LE();
+ header._totalFrames = in->readUint32LE();
+
+ return true;
+}
+
+void SaveManager::writeSavegameHeader(Common::OutSaveFile *out, SherlockSavegameHeader &header) {
+ // Write out a savegame header
+ out->write(SAVEGAME_STR, SAVEGAME_STR_SIZE + 1);
+
+ out->writeByte(CURRENT_SAVEGAME_VERSION);
+
+ // Write savegame name
+ out->write(header._saveName.c_str(), header._saveName.size());
+ out->writeByte('\0');
+
+ // Handle the thumbnail. If there's already one set by the game, create one
+ if (!_saveThumb)
+ createThumbnail();
+ Graphics::saveThumbnail(*out, *_saveThumb);
+
+ _saveThumb->free();
+ delete _saveThumb;
+ _saveThumb = nullptr;
+
+ // Write out the save date/time
+ TimeDate td;
+ g_system->getTimeAndDate(td);
+ out->writeSint16LE(td.tm_year + 1900);
+ out->writeSint16LE(td.tm_mon + 1);
+ out->writeSint16LE(td.tm_mday);
+ out->writeSint16LE(td.tm_hour);
+ out->writeSint16LE(td.tm_min);
+ out->writeUint32LE(_vm->_events->getFrameCounter());
+}
+
+void SaveManager::createThumbnail() {
+ if (_saveThumb) {
+ _saveThumb->free();
+ delete _saveThumb;
+ }
+
+ _saveThumb = new Graphics::Surface();
+
+ if (!IS_3DO) {
+ uint8 thumbPalette[PALETTE_SIZE];
+ _vm->_screen->getPalette(thumbPalette);
+ ::createThumbnail(_saveThumb, (const byte *)_vm->_screen->getPixels(), SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT, thumbPalette);
+ } else {
+ ::createThumbnailFromScreen(_saveThumb);
+ }
+}
+
+void SaveManager::loadGame(int slot) {
+ Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(
+ generateSaveName(slot));
+ if (!saveFile)
+ return;
+
+ // Load the savaegame header
+ SherlockSavegameHeader header;
+ 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.setSaveVersion(header._version);
+ synchronize(s);
+
+ delete saveFile;
+}
+
+void SaveManager::saveGame(int slot, const Common::String &name) {
+ Common::OutSaveFile *out = g_system->getSavefileManager()->openForSaving(
+ generateSaveName(slot));
+
+ SherlockSavegameHeader header;
+ header._saveName = name;
+ writeSavegameHeader(out, header);
+
+ // Synchronize the savegame data
+ Serializer s(nullptr, out);
+ s.setSaveVersion(CURRENT_SAVEGAME_VERSION);
+ synchronize(s);
+
+ out->finalize();
+ delete out;
+}
+
+Common::String SaveManager::generateSaveName(int slot) {
+ return Common::String::format("%s.%03d", _target.c_str(), slot);
+}
+
+void SaveManager::synchronize(Serializer &s) {
+ Inventory &inv = *_vm->_inventory;
+ Journal &journal = *_vm->_journal;
+ Map &map = *_vm->_map;
+ People &people = *_vm->_people;
+ Scene &scene = *_vm->_scene;
+ Screen &screen = *_vm->_screen;
+ Talk &talk = *_vm->_talk;
+
+ int oldFont = screen.fontNumber();
+
+ inv.synchronize(s);
+ journal.synchronize(s);
+ people.synchronize(s);
+ map.synchronize(s);
+ scene.synchronize(s);
+ screen.synchronize(s);
+ talk.synchronize(s);
+ _vm->synchronize(s);
+
+ if (screen.fontNumber() != oldFont)
+ journal.resetPosition();
+
+ _justLoaded = true;
+}
+
+bool SaveManager::isSlotEmpty(int slot) const {
+ return _savegames[slot].equalsIgnoreCase(EMPTY_SAVEGAME_SLOT);
+}
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/saveload.h b/engines/sherlock/saveload.h
new file mode 100644
index 0000000000..0aaa9cf801
--- /dev/null
+++ b/engines/sherlock/saveload.h
@@ -0,0 +1,151 @@
+/* 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 SHERLOCK_SAVELOAD_H
+#define SHERLOCK_SAVELOAD_H
+
+#include "common/scummsys.h"
+#include "common/savefile.h"
+#include "common/serializer.h"
+#include "common/str-array.h"
+#include "engines/savestate.h"
+#include "graphics/surface.h"
+
+namespace Sherlock {
+
+#define MAX_SAVEGAME_SLOTS 99
+#define ONSCREEN_FILES_COUNT 5
+
+enum {
+ CURRENT_SAVEGAME_VERSION = 2,
+ MINIMUM_SAVEGAME_VERSION = 2
+};
+
+enum SaveMode { SAVEMODE_NONE = 0, SAVEMODE_LOAD = 1, SAVEMODE_SAVE = 2 };
+
+extern const char *const EMPTY_SAVEGAME_SLOT;
+
+struct SherlockSavegameHeader {
+ uint8 _version;
+ Common::String _saveName;
+ Graphics::Surface *_thumbnail;
+ int _year, _month, _day;
+ int _hour, _minute;
+ int _totalFrames;
+};
+
+class SherlockEngine;
+
+
+/**
+ * Derived serializer class with extra synchronization types
+ */
+class Serializer : public Common::Serializer {
+public:
+ Serializer(Common::SeekableReadStream *in, Common::WriteStream *out) : Common::Serializer(in, out) {}
+
+ /**
+ * New method to allow setting the version
+ */
+ void setSaveVersion(byte version) { _version = version; }
+};
+
+class SaveManager {
+protected:
+ SherlockEngine *_vm;
+ Common::String _target;
+ Graphics::Surface *_saveThumb;
+
+ /**
+ * Build up a savegame list, with empty slots given an explicit Empty message
+ */
+ void createSavegameList();
+
+ /**
+ * Synchronize the data for a savegame
+ */
+ void synchronize(Serializer &s);
+public:
+ Common::StringArray _savegames;
+ int _savegameIndex;
+ SaveMode _envMode;
+ bool _justLoaded;
+public:
+ static SaveManager *init(SherlockEngine *vm, const Common::String &target);
+ SaveManager(SherlockEngine *vm, const Common::String &target);
+ virtual ~SaveManager();
+
+ /**
+ * Creates a thumbnail for the current on-screen contents
+ */
+ void createThumbnail();
+
+ /**
+ * Load a list of savegames
+ */
+ static SaveStateList getSavegameList(const Common::String &target);
+
+ /**
+ * Support method that generates a savegame name
+ * @param slot Slot number
+ */
+ Common::String generateSaveName(int slot);
+
+ /**
+ * Write out the header information for a savegame
+ */
+ void writeSavegameHeader(Common::OutSaveFile *out, SherlockSavegameHeader &header);
+
+ /**
+ * Read in the header information for a savegame
+ */
+ static bool readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHeader &header);
+
+ /**
+ * Return the index of the button the mouse is over, if any
+ */
+ int getHighlightedButton() const;
+
+ /**
+ * Handle highlighting buttons
+ */
+ void highlightButtons(int btnIndex);
+
+ /**
+ * Load the game in the specified slot
+ */
+ void loadGame(int slot);
+
+ /**
+ * Save the game in the specified slot with the given name
+ */
+ void saveGame(int slot, const Common::String &name);
+
+ /**
+ * Returns true if the given save slot is empty
+ */
+ bool isSlotEmpty(int slot) const;
+};
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/scalpel/3do/movie_decoder.cpp b/engines/sherlock/scalpel/3do/movie_decoder.cpp
new file mode 100644
index 0000000000..8e8f99bc19
--- /dev/null
+++ b/engines/sherlock/scalpel/3do/movie_decoder.cpp
@@ -0,0 +1,510 @@
+/* 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/scummsys.h"
+#include "common/stream.h"
+#include "common/textconsole.h"
+
+#include "audio/audiostream.h"
+#include "audio/decoders/raw.h"
+#include "audio/decoders/3do.h"
+
+#include "sherlock/scalpel/3do/movie_decoder.h"
+#include "image/codecs/cinepak.h"
+
+// for Test-Code
+#include "common/system.h"
+#include "common/events.h"
+#include "common/keyboard.h"
+#include "engines/engine.h"
+#include "engines/util.h"
+#include "graphics/palette.h"
+#include "graphics/pixelformat.h"
+#include "graphics/surface.h"
+
+namespace Sherlock {
+
+Scalpel3DOMovieDecoder::Scalpel3DOMovieDecoder()
+ : _stream(0), _videoTrack(0), _audioTrack(0) {
+ _streamVideoOffset = 0;
+ _streamAudioOffset = 0;
+}
+
+Scalpel3DOMovieDecoder::~Scalpel3DOMovieDecoder() {
+ close();
+}
+
+bool Scalpel3DOMovieDecoder::loadStream(Common::SeekableReadStream *stream) {
+ uint32 videoSubType = 0;
+ uint32 videoCodecTag = 0;
+ uint32 videoHeight = 0;
+ uint32 videoWidth = 0;
+ uint32 videoFrameCount = 0;
+ uint32 audioSubType = 0;
+ uint32 audioCodecTag = 0;
+ uint32 audioChannels = 0;
+ uint32 audioSampleRate = 0;
+
+ close();
+
+ _stream = stream;
+ _streamVideoOffset = 0;
+ _streamAudioOffset = 0;
+
+ // Look for packets that we care about
+ static const int maxPacketCheckCount = 20;
+ for (int i = 0; i < maxPacketCheckCount; i++) {
+ uint32 chunkTag = _stream->readUint32BE();
+ uint32 chunkSize = _stream->readUint32BE() - 8;
+
+ // Bail out if done
+ if (_stream->eos())
+ break;
+
+ uint32 dataStartOffset = _stream->pos();
+
+ switch (chunkTag) {
+ case MKTAG('F','I','L','M'): {
+ // See if this is a FILM header
+ _stream->skip(4); // time stamp (based on 240 per second)
+ _stream->skip(4); // Unknown 0x00000000
+ videoSubType = _stream->readUint32BE();
+
+ switch (videoSubType) {
+ case MKTAG('F', 'H', 'D', 'R'):
+ // FILM header found
+ if (_videoTrack) {
+ warning("Sherlock 3DO movie: Multiple FILM headers found");
+ close();
+ return false;
+ }
+ _stream->readUint32BE();
+ videoCodecTag = _stream->readUint32BE();
+ videoHeight = _stream->readUint32BE();
+ videoWidth = _stream->readUint32BE();
+ _stream->skip(4); // time scale
+ videoFrameCount = _stream->readUint32BE();
+
+ _videoTrack = new StreamVideoTrack(videoWidth, videoHeight, videoCodecTag, videoFrameCount);
+ addTrack(_videoTrack);
+ break;
+
+ case MKTAG('F', 'R', 'M', 'E'):
+ break;
+
+ default:
+ warning("Sherlock 3DO movie: Unknown subtype inside FILM packet");
+ close();
+ return false;
+ }
+ break;
+ }
+
+ case MKTAG('S','N','D','S'): {
+ _stream->skip(8);
+ audioSubType = _stream->readUint32BE();
+
+ switch (audioSubType) {
+ case MKTAG('S', 'H', 'D', 'R'):
+ // Audio header
+
+ // Bail if we already have a track
+ if (_audioTrack) {
+ warning("Sherlock 3DO movie: Multiple SNDS headers found");
+ close();
+ return false;
+ }
+
+ // OK, this is the start of a audio stream
+ _stream->readUint32BE(); // Version, always 0x00000000
+ _stream->readUint32BE(); // Unknown 0x00000008 ?!
+ _stream->readUint32BE(); // Unknown 0x00007500
+ _stream->readUint32BE(); // Unknown 0x00004000
+ _stream->readUint32BE(); // Unknown 0x00000000
+ _stream->readUint32BE(); // Unknown 0x00000010
+ audioSampleRate = _stream->readUint32BE();
+ audioChannels = _stream->readUint32BE();
+ audioCodecTag = _stream->readUint32BE();
+ _stream->readUint32BE(); // Unknown 0x00000004 compression ratio?
+ _stream->readUint32BE(); // Unknown 0x00000A2C
+
+ _audioTrack = new StreamAudioTrack(audioCodecTag, audioSampleRate, audioChannels);
+ addTrack(_audioTrack);
+ break;
+
+ case MKTAG('S', 'S', 'M', 'P'):
+ // Audio data
+ break;
+ default:
+ warning("Sherlock 3DO movie: Unknown subtype inside FILM packet");
+ close();
+ return false;
+ }
+ break;
+ }
+
+ case MKTAG('C','T','R','L'):
+ case MKTAG('F','I','L','L'): // filler chunk, fills to certain boundary
+ case MKTAG('D','A','C','Q'):
+ case MKTAG('J','O','I','N'): // add cel data (not used in sherlock)
+ // Ignore these chunks
+ break;
+
+ case MKTAG('S','H','D','R'):
+ // Happens for EA logo, seems to be garbage data right at the start of the file
+ break;
+
+ default:
+ warning("Unknown chunk-tag '%s' inside Sherlock 3DO movie", tag2str(chunkTag));
+ close();
+ return false;
+ }
+
+ if ((_videoTrack) && (_audioTrack))
+ break;
+
+ // Seek to next chunk
+ _stream->seek(dataStartOffset + chunkSize);
+ }
+
+ // Bail if we didn't find video + audio
+ if ((!_videoTrack) || (!_audioTrack)) {
+ close();
+ return false;
+ }
+
+ // Rewind back to the beginning
+ _stream->seek(0);
+
+ return true;
+}
+
+void Scalpel3DOMovieDecoder::close() {
+ Video::VideoDecoder::close();
+
+ delete _stream; _stream = 0;
+ _videoTrack = 0;
+}
+
+// We try to at least decode 1 frame
+// and also try to get at least 0.5 seconds of audio queued up
+void Scalpel3DOMovieDecoder::readNextPacket() {
+ uint32 currentMovieTime = getTime();
+ uint32 wantedAudioQueued = currentMovieTime + 500; // always try to be 0.500 seconds in front of movie time
+
+ int32 chunkOffset = 0;
+ int32 dataStartOffset = 0;
+ int32 nextChunkOffset = 0;
+ uint32 chunkTag = 0;
+ uint32 chunkSize = 0;
+
+ uint32 videoSubType = 0;
+ uint32 videoTimeStamp = 0;
+ uint32 videoFrameSize = 0;
+ uint32 audioSubType = 0;
+ uint32 audioBytes = 0;
+ bool videoGotFrame = false;
+ bool videoDone = false;
+ bool audioDone = false;
+
+ // Seek to smallest stream offset
+ if (_streamVideoOffset <= _streamAudioOffset) {
+ _stream->seek(_streamVideoOffset);
+ } else {
+ _stream->seek(_streamAudioOffset);
+ }
+
+ if (wantedAudioQueued <= _audioTrack->getTotalAudioQueued()) {
+ // already got enough audio queued up
+ audioDone = true;
+ }
+
+ while (1) {
+ chunkOffset = _stream->pos();
+ assert(chunkOffset >= 0);
+
+ // Read chunk header
+ chunkTag = _stream->readUint32BE();
+ chunkSize = _stream->readUint32BE() - 8;
+
+ // Calculate offsets
+ dataStartOffset = _stream->pos();
+ assert(dataStartOffset >= 0);
+ nextChunkOffset = dataStartOffset + chunkSize;
+
+ //warning("offset %lx - tag %lx", dataStartOffset, tag);
+
+ if (_stream->eos())
+ break;
+
+ switch (chunkTag) {
+ case MKTAG('F','I','L','M'):
+ videoTimeStamp = _stream->readUint32BE();
+ _stream->skip(4); // Unknown
+ videoSubType = _stream->readUint32BE();
+
+ switch (videoSubType) {
+ case MKTAG('F', 'H', 'D', 'R'):
+ // Ignore video header
+ break;
+
+ case MKTAG('F', 'R', 'M', 'E'):
+ // Found frame data
+ if (_streamVideoOffset <= chunkOffset) {
+ // We are at an offset that is still relevant to video decoding
+ if (!videoDone) {
+ if (!videoGotFrame) {
+ // We haven't decoded any frame yet, so do so now
+ _stream->readUint32BE();
+ videoFrameSize = _stream->readUint32BE();
+ _videoTrack->decodeFrame(_stream->readStream(videoFrameSize), videoTimeStamp);
+
+ _streamVideoOffset = nextChunkOffset;
+ videoGotFrame = true;
+
+ } else {
+ // Already decoded a frame, so get timestamp of follow-up frame
+ // and then we are done with video
+
+ // Calculate next frame time
+ // 3DO clock time for movies runs at 240Hh, that's why timestamps are based on 240.
+ uint32 currentFrameStartTime = _videoTrack->getNextFrameStartTime();
+ uint32 nextFrameStartTime = videoTimeStamp * 1000 / 240;
+ assert(currentFrameStartTime <= nextFrameStartTime);
+ _videoTrack->setNextFrameStartTime(nextFrameStartTime);
+
+ // next time we want to start at the current chunk
+ _streamVideoOffset = chunkOffset;
+ videoDone = true;
+ }
+ }
+ }
+ break;
+
+ default:
+ error("Sherlock 3DO movie: Unknown subtype inside FILM packet");
+ break;
+ }
+ break;
+
+ case MKTAG('S','N','D','S'):
+ _stream->skip(8);
+ audioSubType = _stream->readUint32BE();
+
+ switch (audioSubType) {
+ case MKTAG('S', 'H', 'D', 'R'):
+ // Ignore the audio header
+ break;
+
+ case MKTAG('S', 'S', 'M', 'P'):
+ // Got audio chunk
+ if (_streamAudioOffset <= chunkOffset) {
+ // We are at an offset that is still relevant to audio decoding
+ if (!audioDone) {
+ audioBytes = _stream->readUint32BE();
+ _audioTrack->queueAudio(_stream, audioBytes);
+
+ _streamAudioOffset = nextChunkOffset;
+ if (wantedAudioQueued <= _audioTrack->getTotalAudioQueued()) {
+ // Got enough audio
+ audioDone = true;
+ }
+ }
+ }
+ break;
+
+ default:
+ error("Sherlock 3DO movie: Unknown subtype inside SNDS packet");
+ break;
+ }
+ break;
+
+ case MKTAG('C','T','R','L'):
+ case MKTAG('F','I','L','L'): // filler chunk, fills to certain boundary
+ case MKTAG('D','A','C','Q'):
+ case MKTAG('J','O','I','N'): // add cel data (not used in sherlock)
+ // Ignore these chunks
+ break;
+
+ case MKTAG('S','H','D','R'):
+ // Happens for EA logo, seems to be garbage data right at the start of the file
+ break;
+
+ default:
+ error("Unknown chunk-tag '%s' inside Sherlock 3DO movie", tag2str(chunkTag));
+ }
+
+ // Always seek to end of chunk
+ // Sometimes not all of the chunk is filled with audio
+ _stream->seek(nextChunkOffset);
+
+ if ((videoDone) && (audioDone)) {
+ return;
+ }
+ }
+}
+
+Scalpel3DOMovieDecoder::StreamVideoTrack::StreamVideoTrack(uint32 width, uint32 height, uint32 codecTag, uint32 frameCount) {
+ _width = width;
+ _height = height;
+ _frameCount = frameCount;
+ _curFrame = -1;
+ _nextFrameStartTime = 0;
+
+ // Create the Cinepak decoder, if we're using it
+ if (codecTag == MKTAG('c', 'v', 'i', 'd'))
+ _codec = new Image::CinepakDecoder();
+ else
+ error("Unsupported Sherlock 3DO movie video codec tag '%s'", tag2str(codecTag));
+}
+
+Scalpel3DOMovieDecoder::StreamVideoTrack::~StreamVideoTrack() {
+ delete _codec;
+}
+
+bool Scalpel3DOMovieDecoder::StreamVideoTrack::endOfTrack() const {
+ return getCurFrame() >= getFrameCount() - 1;
+}
+
+Graphics::PixelFormat Scalpel3DOMovieDecoder::StreamVideoTrack::getPixelFormat() const {
+ return _codec->getPixelFormat();
+}
+
+void Scalpel3DOMovieDecoder::StreamVideoTrack::decodeFrame(Common::SeekableReadStream *stream, uint32 videoTimeStamp) {
+ _surface = _codec->decodeFrame(*stream);
+ _curFrame++;
+}
+
+Scalpel3DOMovieDecoder::StreamAudioTrack::StreamAudioTrack(uint32 codecTag, uint32 sampleRate, uint32 channels) {
+ switch (codecTag) {
+ case MKTAG('A','D','P','4'):
+ case MKTAG('S','D','X','2'):
+ // ADP4 + SDX2 are both allowed
+ break;
+
+ default:
+ error("Unsupported Sherlock 3DO movie audio codec tag '%s'", tag2str(codecTag));
+ }
+
+ _totalAudioQueued = 0; // currently 0 milliseconds queued
+
+ _codecTag = codecTag;
+ _sampleRate = sampleRate;
+ switch (channels) {
+ case 1:
+ _stereo = false;
+ break;
+ case 2:
+ _stereo = true;
+ break;
+ default:
+ error("Unsupported Sherlock 3DO movie audio channels %d", channels);
+ }
+
+ _audioStream = Audio::makeQueuingAudioStream(sampleRate, _stereo);
+
+ // reset audio decoder persistent spaces
+ memset(&_ADP4_PersistentSpace, 0, sizeof(_ADP4_PersistentSpace));
+ memset(&_SDX2_PersistentSpace, 0, sizeof(_SDX2_PersistentSpace));
+}
+
+Scalpel3DOMovieDecoder::StreamAudioTrack::~StreamAudioTrack() {
+ delete _audioStream;
+// free(_ADP4_PersistentSpace);
+// free(_SDX2_PersistentSpace);
+}
+
+void Scalpel3DOMovieDecoder::StreamAudioTrack::queueAudio(Common::SeekableReadStream *stream, uint32 size) {
+ Common::SeekableReadStream *compressedAudioStream = 0;
+ Audio::RewindableAudioStream *audioStream = 0;
+ uint32 audioLengthMSecs = 0;
+
+ // Read the specified chunk into memory
+ compressedAudioStream = stream->readStream(size);
+
+ switch(_codecTag) {
+ case MKTAG('A','D','P','4'):
+ audioStream = Audio::make3DO_ADP4AudioStream(compressedAudioStream, _sampleRate, _stereo, &audioLengthMSecs, DisposeAfterUse::YES, &_ADP4_PersistentSpace);
+ break;
+ case MKTAG('S','D','X','2'):
+ audioStream = Audio::make3DO_SDX2AudioStream(compressedAudioStream, _sampleRate, _stereo, &audioLengthMSecs, DisposeAfterUse::YES, &_SDX2_PersistentSpace);
+ break;
+ default:
+ break;
+ }
+ if (audioStream) {
+ _totalAudioQueued += audioLengthMSecs;
+ _audioStream->queueAudioStream(audioStream, DisposeAfterUse::YES);
+ } else {
+ // in case there was an error
+ delete compressedAudioStream;
+ }
+}
+
+Audio::AudioStream *Scalpel3DOMovieDecoder::StreamAudioTrack::getAudioStream() const {
+ return _audioStream;
+}
+
+// Test-code
+
+// Code for showing a movie. Only meant for testing/debug purposes
+bool Scalpel3DOMoviePlay(const char *filename, Common::Point pos) {
+ Scalpel3DOMovieDecoder *videoDecoder = new Scalpel3DOMovieDecoder();
+
+ if (!videoDecoder->loadFile(filename)) {
+ warning("Scalpel3DOMoviePlay: could not open '%s'", filename);
+ return false;
+ }
+
+ bool skipVideo = false;
+ //byte bytesPerPixel = videoDecoder->getPixelFormat().bytesPerPixel;
+ uint16 width = videoDecoder->getWidth();
+ uint16 height = videoDecoder->getHeight();
+ //uint16 pitch = videoDecoder->getWidth() * bytesPerPixel;
+
+ videoDecoder->start();
+
+ while (!g_engine->shouldQuit() && !videoDecoder->endOfVideo() && (!skipVideo)) {
+ if (videoDecoder->needsUpdate()) {
+ const Graphics::Surface *frame = videoDecoder->decodeNextFrame();
+
+ if (frame) {
+ g_system->copyRectToScreen(frame->getPixels(), frame->pitch, pos.x, pos.y, width, height);
+ g_system->updateScreen();
+ }
+ }
+
+ Common::Event event;
+ while (g_system->getEventManager()->pollEvent(event)) {
+ if ((event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE))
+ skipVideo = true;
+ }
+
+ g_system->delayMillis(10);
+ }
+ videoDecoder->close();
+ delete videoDecoder;
+
+ return !skipVideo;
+}
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/scalpel/3do/movie_decoder.h b/engines/sherlock/scalpel/3do/movie_decoder.h
new file mode 100644
index 0000000000..9f1670fc6c
--- /dev/null
+++ b/engines/sherlock/scalpel/3do/movie_decoder.h
@@ -0,0 +1,127 @@
+/* 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 SHERLOCK_SCALPEL_3DO_MOVIE_DECODER_H
+#define SHERLOCK_SCALPEL_3DO_MOVIE_DECODER_H
+
+#include "common/rect.h"
+#include "video/video_decoder.h"
+#include "audio/decoders/3do.h"
+
+namespace Audio {
+class QueuingAudioStream;
+}
+
+namespace Common {
+class SeekableReadStream;
+}
+
+namespace Image {
+class Codec;
+}
+
+namespace Sherlock {
+
+class Scalpel3DOMovieDecoder : public Video::VideoDecoder {
+public:
+ Scalpel3DOMovieDecoder();
+ ~Scalpel3DOMovieDecoder();
+
+ bool loadStream(Common::SeekableReadStream *stream);
+ void close();
+
+protected:
+ void readNextPacket();
+
+private:
+ int32 _streamVideoOffset; /* current stream offset for video decoding */
+ int32 _streamAudioOffset; /* current stream offset for audio decoding */
+
+private:
+ class StreamVideoTrack : public VideoTrack {
+ public:
+ StreamVideoTrack(uint32 width, uint32 height, uint32 codecTag, uint32 frameCount);
+ ~StreamVideoTrack();
+
+ bool endOfTrack() const;
+
+ uint16 getWidth() const { return _width; }
+ uint16 getHeight() const { return _height; }
+ Graphics::PixelFormat getPixelFormat() const;
+ int getCurFrame() const { return _curFrame; }
+ int getFrameCount() const { return _frameCount; }
+ void setNextFrameStartTime(uint32 nextFrameStartTime) { _nextFrameStartTime = nextFrameStartTime; }
+ uint32 getNextFrameStartTime() const { return _nextFrameStartTime; }
+ const Graphics::Surface *decodeNextFrame() { return _surface; }
+
+ void decodeFrame(Common::SeekableReadStream *stream, uint32 videoTimeStamp);
+
+ private:
+ const Graphics::Surface *_surface;
+
+ int _curFrame;
+ uint32 _frameCount;
+ uint32 _nextFrameStartTime;
+
+ Image::Codec *_codec;
+ uint16 _width, _height;
+ };
+
+ class StreamAudioTrack : public AudioTrack {
+ public:
+ StreamAudioTrack(uint32 codecTag, uint32 sampleRate, uint32 channels);
+ ~StreamAudioTrack();
+
+ void queueAudio(Common::SeekableReadStream *stream, uint32 size);
+
+ protected:
+ Audio::AudioStream *getAudioStream() const;
+
+ private:
+ Audio::QueuingAudioStream *_audioStream;
+ uint32 _totalAudioQueued; /* total amount of milliseconds of audio, that we queued up already */
+
+ public:
+ uint32 getTotalAudioQueued() const { return _totalAudioQueued; }
+
+ private:
+ int16 decodeSample(uint8 dataNibble);
+
+ uint32 _codecTag;
+ uint16 _sampleRate;
+ bool _stereo;
+
+ Audio::audio_3DO_ADP4_PersistentSpace _ADP4_PersistentSpace;
+ Audio::audio_3DO_SDX2_PersistentSpace _SDX2_PersistentSpace;
+ };
+
+ Common::SeekableReadStream *_stream;
+ StreamVideoTrack *_videoTrack;
+ StreamAudioTrack *_audioTrack;
+};
+
+// Testing
+extern bool Scalpel3DOMoviePlay(const char *filename, Common::Point pos);
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/scalpel/darts.cpp b/engines/sherlock/scalpel/darts.cpp
new file mode 100644
index 0000000000..a24af4e444
--- /dev/null
+++ b/engines/sherlock/scalpel/darts.cpp
@@ -0,0 +1,553 @@
+/* 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 "sherlock/scalpel/darts.h"
+#include "sherlock/scalpel/scalpel.h"
+
+namespace Sherlock {
+
+namespace Scalpel {
+
+enum {
+ STATUS_INFO_X = 218,
+ STATUS_INFO_Y = 53,
+ DART_INFO_X = 218,
+ DART_INFO_Y = 103,
+ DARTBARHX = 35,
+ DARTHORIZY = 190,
+ DARTBARVX = 1,
+ DARTHEIGHTY = 25,
+ DARTBARSIZE = 150,
+ DART_BAR_FORE = 8
+};
+
+enum {
+ DART_COL_FORE = 5,
+ PLAYER_COLOR = 11
+};
+#define OPPONENTS_COUNT 4
+
+const char *const OPPONENT_NAMES[OPPONENTS_COUNT] = {
+ "Skipper", "Willy", "Micky", "Tom"
+};
+
+/*----------------------------------------------------------------*/
+
+Darts::Darts(ScalpelEngine *vm) : _vm(vm) {
+ _dartImages = nullptr;
+ _level = 0;
+ _computerPlayer = 1;
+ _playerDartMode = false;
+ _dartScore1 = _dartScore2 = 0;
+ _roundNumber = 0;
+ _playerDartMode = false;
+ _roundScore = 0;
+ _oldDartButtons = false;
+}
+
+void Darts::playDarts() {
+ Events &events = *_vm->_events;
+ Screen &screen = *_vm->_screen;
+ int playerNumber = 0;
+ int lastDart;
+
+ // Change the font
+ int oldFont = screen.fontNumber();
+ screen.setFont(2);
+
+ loadDarts();
+ initDarts();
+
+ bool done = false;
+ do {
+ int score, roundStartScore;
+ roundStartScore = score = playerNumber == 0 ? _dartScore1 : _dartScore2;
+
+ // Show player details
+ showNames(playerNumber);
+ showStatus(playerNumber);
+ _roundScore = 0;
+
+ if (_vm->shouldQuit())
+ return;
+
+ for (int idx = 0; idx < 3; ++idx) {
+ // Throw a single dart
+ if (_computerPlayer == 1)
+ lastDart = throwDart(idx + 1, playerNumber * 2);
+ else if (_computerPlayer == 2)
+ lastDart = throwDart(idx + 1, playerNumber + 1);
+ else
+ lastDart = throwDart(idx + 1, 0);
+
+ score -= lastDart;
+ _roundScore += lastDart;
+
+ screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(DART_INFO_X, DART_INFO_Y - 1),
+ Common::Rect(DART_INFO_X, DART_INFO_Y - 1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
+ screen.print(Common::Point(DART_INFO_X, DART_INFO_Y), DART_COL_FORE, "Dart # %d", idx + 1);
+ screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 10), DART_COL_FORE, "Scored %d points", lastDart);
+
+ if (score != 0 && playerNumber == 0)
+ screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 30), DART_COL_FORE, "Press a key");
+
+ if (score == 0) {
+ // Some-one has won
+ screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 20), PLAYER_COLOR, "GAME OVER!");
+
+ if (playerNumber == 0) {
+ screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 30), PLAYER_COLOR, "Holmes Wins!");
+ if (_level < OPPONENTS_COUNT)
+ _vm->setFlagsDirect(318 + _level);
+ } else {
+ screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 30), PLAYER_COLOR, "%s Wins!", _opponent.c_str());
+ }
+
+ screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 4), DART_COL_FORE, "Press a key");
+
+ idx = 10;
+ done = true;
+ } else if (score < 0) {
+ screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 20), PLAYER_COLOR, "BUSTED!");
+
+ idx = 10;
+ score = roundStartScore;
+ }
+
+ if (playerNumber == 0)
+ _dartScore1 = score;
+ else
+ _dartScore2 = score;
+
+ showStatus(playerNumber);
+ events.clearKeyboard();
+
+ if ((playerNumber == 0 && _computerPlayer == 1) || _computerPlayer == 0 || done) {
+ int dartKey;
+ while (!(dartKey = dartHit()) && !_vm->shouldQuit())
+ events.delay(10);
+
+ if (dartKey == Common::KEYCODE_ESCAPE) {
+ idx = 10;
+ done = true;
+ }
+ } else {
+ events.wait(20);
+ }
+
+ screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(DART_INFO_X, DART_INFO_Y - 1),
+ Common::Rect(DART_INFO_X, DART_INFO_Y - 1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+ }
+
+ playerNumber ^= 1;
+ if (!playerNumber)
+ ++_roundNumber;
+
+ done |= _vm->shouldQuit();
+
+ if (!done) {
+ screen._backBuffer2.blitFrom((*_dartImages)[0], Common::Point(0, 0));
+ screen._backBuffer1.blitFrom(screen._backBuffer2);
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+ }
+ } while (!done);
+
+ closeDarts();
+ screen.fadeToBlack();
+
+ // Restore font
+ screen.setFont(oldFont);
+}
+
+void Darts::loadDarts() {
+ Screen &screen = *_vm->_screen;
+
+ _dartImages = new ImageFile("darts.vgs");
+ screen.setPalette(_dartImages->_palette);
+
+ screen._backBuffer1.blitFrom((*_dartImages)[0], Common::Point(0, 0));
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+}
+
+void Darts::initDarts() {
+ _dartScore1 = _dartScore2 = 301;
+ _roundNumber = 1;
+
+ if (_level == 9) {
+ // No computer players
+ _computerPlayer = 0;
+ _level = 0;
+ } else if (_level == 8) {
+ _level = _vm->getRandomNumber(3);
+ _computerPlayer = 2;
+ } else {
+ // Check flags for opponents
+ for (int idx = 0; idx < OPPONENTS_COUNT; ++idx) {
+ if (_vm->readFlags(314 + idx))
+ _level = idx;
+ }
+ }
+
+ _opponent = OPPONENT_NAMES[_level];
+}
+
+void Darts::closeDarts() {
+ delete _dartImages;
+ _dartImages = nullptr;
+}
+
+void Darts::showNames(int playerNum) {
+ Screen &screen = *_vm->_screen;
+ byte color = playerNum == 0 ? PLAYER_COLOR : DART_COL_FORE;
+
+ // Print Holmes first
+ if (playerNum == 0)
+ screen.print(Common::Point(STATUS_INFO_X, STATUS_INFO_Y), PLAYER_COLOR + 3, "Holmes");
+ else
+ screen.print(Common::Point(STATUS_INFO_X, STATUS_INFO_Y), color, "Holmes");
+
+ screen._backBuffer1.fillRect(Common::Rect(STATUS_INFO_X, STATUS_INFO_Y + 10,
+ STATUS_INFO_X + 31, STATUS_INFO_Y + 12), color);
+ screen.slamArea(STATUS_INFO_X, STATUS_INFO_Y + 10, 31, 12);
+
+ // Second player
+ color = playerNum == 1 ? PLAYER_COLOR : DART_COL_FORE;
+
+ if (playerNum != 0)
+ screen.print(Common::Point(STATUS_INFO_X + 50, STATUS_INFO_Y), PLAYER_COLOR + 3,
+ "%s", _opponent.c_str());
+ else
+ screen.print(Common::Point(STATUS_INFO_X + 50, STATUS_INFO_Y), color,
+ "%s", _opponent.c_str());
+
+ screen._backBuffer1.fillRect(Common::Rect(STATUS_INFO_X + 50, STATUS_INFO_Y + 10,
+ STATUS_INFO_X + 81, STATUS_INFO_Y + 12), color);
+ screen.slamArea(STATUS_INFO_X + 50, STATUS_INFO_Y + 10, 81, 12);
+
+ // Make a copy of the back buffer to the secondary one
+ screen._backBuffer2.blitFrom(screen._backBuffer1);
+}
+
+void Darts::showStatus(int playerNum) {
+ Screen &screen = *_vm->_screen;
+ byte color;
+
+ // Copy scoring screen from secondary back buffer. This will erase any previously displayed status/score info
+ screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(STATUS_INFO_X, STATUS_INFO_Y + 10),
+ Common::Rect(STATUS_INFO_X, STATUS_INFO_Y + 10, SHERLOCK_SCREEN_WIDTH, STATUS_INFO_Y + 48));
+
+ color = (playerNum == 0) ? PLAYER_COLOR : DART_COL_FORE;
+ screen.print(Common::Point(STATUS_INFO_X + 6, STATUS_INFO_Y + 13), color, "%d", _dartScore1);
+
+ color = (playerNum == 1) ? PLAYER_COLOR : DART_COL_FORE;
+ screen.print(Common::Point(STATUS_INFO_X + 56, STATUS_INFO_Y + 13), color, "%d", _dartScore2);
+ screen.print(Common::Point(STATUS_INFO_X, STATUS_INFO_Y + 25), PLAYER_COLOR, "Round: %d", _roundNumber);
+ screen.print(Common::Point(STATUS_INFO_X, STATUS_INFO_Y + 35), PLAYER_COLOR, "Turn Total: %d", _roundScore);
+ screen.slamRect(Common::Rect(STATUS_INFO_X, STATUS_INFO_Y + 10, SHERLOCK_SCREEN_WIDTH, STATUS_INFO_Y + 48));
+}
+
+int Darts::throwDart(int dartNum, int computer) {
+ Events &events = *_vm->_events;
+ Screen &screen = *_vm->_screen;
+ Common::Point targetNum;
+ int width, height;
+
+ events.clearKeyboard();
+
+ erasePowerBars();
+ screen.print(Common::Point(DART_INFO_X, DART_INFO_Y), DART_COL_FORE, "Dart # %d", dartNum);
+
+ if (!computer) {
+ screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 10), DART_COL_FORE, "Hit a key");
+ screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 18), DART_COL_FORE, "to start");
+ }
+
+ if (!computer) {
+ while (!_vm->shouldQuit() && !dartHit())
+ ;
+ } else {
+ events.delay(10);
+ }
+
+ if (_vm->shouldQuit())
+ return 0;
+
+ screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(DART_INFO_X, DART_INFO_Y - 1),
+ Common::Rect(DART_INFO_X, DART_INFO_Y - 1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
+ screen.slamRect(Common::Rect(DART_INFO_X, DART_INFO_Y - 1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
+
+ // If it's a computer player, choose a dart destination
+ if (computer)
+ targetNum = getComputerDartDest(computer - 1);
+
+ width = doPowerBar(Common::Point(DARTBARHX, DARTHORIZY), DART_BAR_FORE, targetNum.x, false);
+ height = 101 - doPowerBar(Common::Point(DARTBARVX, DARTHEIGHTY), DART_BAR_FORE, targetNum.y, true);
+
+ // For human players, slight y adjustment
+ if (computer == 0)
+ height += 2;
+
+ // Copy the bars to the secondary back buffer so that they remain fixed at their selected values
+ // whilst the dart is being animated at being thrown at the board
+ screen._backBuffer2.blitFrom(screen._backBuffer1, Common::Point(DARTBARHX - 1, DARTHORIZY - 1),
+ Common::Rect(DARTBARHX - 1, DARTHORIZY - 1, DARTBARHX + DARTBARSIZE + 3, DARTHORIZY + 10));
+ screen._backBuffer2.blitFrom(screen._backBuffer1, Common::Point(DARTBARVX - 1, DARTHEIGHTY - 1),
+ Common::Rect(DARTBARVX - 1, DARTHEIGHTY - 1, DARTBARVX + 11, DARTHEIGHTY + DARTBARSIZE + 3));
+
+ // Convert height and width to relative range of -50 to 50, where 0,0 is the exact centre of the board
+ height -= 50;
+ width -= 50;
+
+ Common::Point dartPos(111 + width * 2, 99 + height * 2);
+ drawDartThrow(dartPos);
+
+ return dartScore(dartPos);
+}
+
+void Darts::drawDartThrow(const Common::Point &pt) {
+ Events &events = *_vm->_events;
+ Screen &screen = *_vm->_screen;
+ Common::Point pos(pt.x, pt.y + 2);
+ Common::Rect oldDrawBounds;
+ int delta = 9;
+
+ for (int idx = 4; idx < 23; ++idx) {
+ ImageFrame &frame = (*_dartImages)[idx];
+
+ // Adjust draw position for animating dart
+ if (idx < 13)
+ pos.y -= delta--;
+ else if (idx == 13)
+ delta = 1;
+ else
+ pos.y += delta++;
+
+ // Draw the dart
+ Common::Point drawPos(pos.x - frame._width / 2, pos.y - frame._height);
+ screen._backBuffer1.transBlitFrom(frame, drawPos);
+ screen.slamArea(drawPos.x, drawPos.y, frame._width, frame._height);
+
+ // Handle erasing old dart frame area
+ if (!oldDrawBounds.isEmpty())
+ screen.slamRect(oldDrawBounds);
+
+ oldDrawBounds = Common::Rect(drawPos.x, drawPos.y, drawPos.x + frame._width, drawPos.y + frame._height);
+ screen._backBuffer1.blitFrom(screen._backBuffer2, drawPos, oldDrawBounds);
+
+ events.wait(2);
+ }
+
+ // Draw dart in final "stuck to board" form
+ screen._backBuffer1.transBlitFrom((*_dartImages)[22], Common::Point(oldDrawBounds.left, oldDrawBounds.top));
+ screen._backBuffer2.transBlitFrom((*_dartImages)[22], Common::Point(oldDrawBounds.left, oldDrawBounds.top));
+ screen.slamRect(oldDrawBounds);
+}
+
+void Darts::erasePowerBars() {
+ Screen &screen = *_vm->_screen;
+
+ screen._backBuffer1.fillRect(Common::Rect(DARTBARHX, DARTHORIZY, DARTBARHX + DARTBARSIZE, DARTHORIZY + 10), BLACK);
+ screen._backBuffer1.fillRect(Common::Rect(DARTBARVX, DARTHEIGHTY, DARTBARVX + 10, DARTHEIGHTY + DARTBARSIZE), BLACK);
+ screen._backBuffer1.transBlitFrom((*_dartImages)[2], Common::Point(DARTBARHX - 1, DARTHORIZY - 1));
+ screen._backBuffer1.transBlitFrom((*_dartImages)[3], Common::Point(DARTBARVX - 1, DARTHEIGHTY - 1));
+ screen.slamArea(DARTBARHX - 1, DARTHORIZY - 1, DARTBARSIZE + 3, 11);
+ screen.slamArea(DARTBARVX - 1, DARTHEIGHTY - 1, 11, DARTBARSIZE + 3);
+}
+
+int Darts::doPowerBar(const Common::Point &pt, byte color, int goToPower, bool isVertical) {
+ Events &events = *_vm->_events;
+ Screen &screen = *_vm->_screen;
+ Music &music = *_vm->_music;
+ bool done;
+ int idx = 0;
+
+ events.clearEvents();
+ if (music._musicOn)
+ music.waitTimerRoland(10);
+ else
+ events.delay(100);
+
+ // Display loop
+ do {
+ done = _vm->shouldQuit() || idx >= DARTBARSIZE;
+
+ if (idx == (goToPower - 1))
+ // Reached target power for a computer player
+ done = true;
+ else if (goToPower == 0) {
+ // Check for pres
+ if (dartHit())
+ done = true;
+ }
+
+ if (isVertical) {
+ screen._backBuffer1.hLine(pt.x, pt.y + DARTBARSIZE - 1 - idx, pt.x + 8, color);
+ screen._backBuffer1.transBlitFrom((*_dartImages)[3], Common::Point(pt.x - 1, pt.y - 1));
+ screen.slamArea(pt.x, pt.y + DARTBARSIZE - 1 - idx, 8, 2);
+ } else {
+ screen._backBuffer1.vLine(pt.x + idx, pt.y, pt.y + 8, color);
+ screen._backBuffer1.transBlitFrom((*_dartImages)[2], Common::Point(pt.x - 1, pt.y - 1));
+ screen.slamArea(pt.x + idx, pt.y, 1, 8);
+ }
+
+ if (music._musicOn) {
+ if (!(idx % 3))
+ music.waitTimerRoland(1);
+ } else if (!(idx % 8))
+ events.wait(1);
+
+ ++idx;
+ } while (!done);
+
+ return MIN(idx * 100 / DARTBARSIZE, 100);
+}
+
+bool Darts::dartHit() {
+ Events &events = *_vm->_events;
+
+ // Process pending events
+ events.pollEventsAndWait();
+
+ if (events.kbHit()) {
+ // Key was pressed, so discard it and return true
+ events.clearKeyboard();
+ return true;
+ }
+
+ _oldDartButtons = events._pressed;
+ events.setButtonState();
+
+ // Only return true if the mouse button is newly pressed
+ return (events._pressed && !_oldDartButtons) ? 1 : 0;
+}
+
+int Darts::dartScore(const Common::Point &pt) {
+ Common::Point pos(pt.x - 37, pt.y - 33);
+ Graphics::Surface &scoreImg = (*_dartImages)[1]._frame;
+
+ if (pos.x < 0 || pos.y < 0 || pos.x >= scoreImg.w || pos.y >= scoreImg.h)
+ // Not on the board
+ return 0;
+
+ // On board, so get the score from the pixel at that position
+ int score = *(const byte *)scoreImg.getBasePtr(pos.x, pos.y);
+ return score;
+}
+
+Common::Point Darts::getComputerDartDest(int playerNum) {
+ Common::Point target;
+ int score = playerNum == 0 ? _dartScore1 : _dartScore2;
+
+ if (score > 50) {
+ // Aim for the bullseye
+ target.x = target.y = 76;
+
+ if (_level <= 1 && _vm->getRandomNumber(1) == 1) {
+ // Introduce margin of error
+ target.x += _vm->getRandomNumber(21) - 10;
+ target.y += _vm->getRandomNumber(21) - 10;
+ }
+ } else {
+ int aim = score;
+
+ bool done;
+ Common::Point pt;
+ do {
+ done = findNumberOnBoard(aim, pt);
+ --aim;
+ } while (!done);
+
+ target.x = 75 + ((target.x - 75) * 20 / 27);
+ target.y = 75 + ((target.y - 75) * 2 / 3);
+ }
+
+ // Pick a level of accuracy. The higher the level, the more accurate their throw will be
+ int accuracy = _vm->getRandomNumber(10) + _level * 2;
+
+ if (accuracy <= 2) {
+ target.x += _vm->getRandomNumber(71) - 35;
+ target.y += _vm->getRandomNumber(71) - 35;
+ } else if (accuracy <= 4) {
+ target.x += _vm->getRandomNumber(51) - 25;
+ target.y += _vm->getRandomNumber(51) - 25;
+ } else if (accuracy <= 6) {
+ target.x += _vm->getRandomNumber(31) - 15;
+ target.y += _vm->getRandomNumber(31) - 15;
+ } else if (accuracy <= 8) {
+ target.x += _vm->getRandomNumber(21) - 10;
+ target.y += _vm->getRandomNumber(21) - 10;
+ } else if (accuracy <= 10) {
+ target.x += _vm->getRandomNumber(11) - 5;
+ target.y += _vm->getRandomNumber(11) - 5;
+ }
+
+ if (target.x < 1)
+ target.x = 1;
+ if (target.y < 1)
+ target.y = 1;
+
+ return target;
+}
+
+bool Darts::findNumberOnBoard(int aim, Common::Point &pt) {
+ ImageFrame &board = (*_dartImages)[1];
+
+ // Scan board image for the special "center" pixels
+ bool done = false;
+ for (int yp = 0; yp < 132 && !done; ++yp) {
+ const byte *srcP = (const byte *)board._frame.getBasePtr(0, yp);
+ for (int xp = 0; xp < 147 && !done; ++xp, ++srcP) {
+ int score = *srcP;
+
+ // Check for match
+ if (score == aim) {
+ done = true;
+
+ // Aim at non-double/triple numbers where possible
+ if (aim < 21) {
+ pt.x = xp + 5;
+ pt.y = yp + 5;
+
+ score = *(const byte *)board._frame.getBasePtr(xp + 10, yp + 10);
+ if (score != aim)
+ // Not aiming at non-double/triple number yet
+ done = false;
+ } else {
+ // Aiming at a double or triple
+ pt.x = xp + 3;
+ pt.y = yp + 3;
+ }
+ }
+ }
+ }
+
+ if (aim == 3)
+ pt.x += 15;
+ pt.y = 132 - pt.y;
+
+ return done;
+}
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/scalpel/darts.h b/engines/sherlock/scalpel/darts.h
new file mode 100644
index 0000000000..4368954814
--- /dev/null
+++ b/engines/sherlock/scalpel/darts.h
@@ -0,0 +1,130 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SHERLOCK_DARTS_H
+#define SHERLOCK_DARTS_H
+
+#include "sherlock/image_file.h"
+
+namespace Sherlock {
+
+namespace Scalpel {
+
+class ScalpelEngine;
+
+class Darts {
+private:
+ ScalpelEngine *_vm;
+ ImageFile *_dartImages;
+ int _dartScore1, _dartScore2;
+ int _roundNumber;
+ int _level;
+ int _computerPlayer;
+ Common::String _opponent;
+ bool _playerDartMode;
+ int _roundScore;
+ bool _oldDartButtons;
+
+ /**
+ * Load the graphics needed for the dart game
+ */
+ void loadDarts();
+
+ /**
+ * Initializes the variables needed for the dart game
+ */
+ void initDarts();
+
+ /**
+ * Frees the images used by the dart game
+ */
+ void closeDarts();
+
+ /**
+ * Show the names of the people playing, Holmes and his opponent
+ */
+ void showNames(int playerNum);
+
+ /**
+ * Show the player score and game status
+ */
+ void showStatus(int playerNum);
+
+ /**
+ * Throws a single dart.
+ * @param dartNum Dart number
+ * @param computer 0 = Player, 1 = 1st player computer, 2 = 2nd player computer
+ * @returns Score for what dart hit
+ */
+ int throwDart(int dartNum, int computer);
+
+ /**
+ * Draw a dart moving towards the board
+ */
+ void drawDartThrow(const Common::Point &pt);
+
+ /**
+ * Erases the power bars
+ */
+ void erasePowerBars();
+
+ /**
+ * Show a gradually incrementing incrementing power that bar. If goToPower is provided, it will
+ * increment to that power level ignoring all keyboard input (ie. for computer throws).
+ * Otherwise, it will increment until either a key/mouse button is pressed, or it reaches the end
+ */
+ int doPowerBar(const Common::Point &pt, byte color, int goToPower, bool isVertical);
+
+ /**
+ * Returns true if a mouse button or key is pressed.
+ */
+ bool dartHit();
+
+ /**
+ * Return the score of the given location on the dart-board
+ */
+ int dartScore(const Common::Point &pt);
+
+ /**
+ * Calculates where a computer player is trying to throw their dart, and choose the actual
+ * point that was hit with some margin of error
+ */
+ Common::Point getComputerDartDest(int playerNum);
+
+ /**
+ * Returns the center position for the area of the dartboard with a given number
+ */
+ bool findNumberOnBoard(int aim, Common::Point &pt);
+public:
+ Darts(ScalpelEngine *vm);
+
+ /**
+ * Main method for playing darts game
+ */
+ void playDarts();
+};
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/scalpel/drivers/adlib.cpp b/engines/sherlock/scalpel/drivers/adlib.cpp
new file mode 100644
index 0000000000..29a39f0c39
--- /dev/null
+++ b/engines/sherlock/scalpel/drivers/adlib.cpp
@@ -0,0 +1,646 @@
+/* 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 "sherlock/sherlock.h"
+#include "sherlock/scalpel/drivers/mididriver.h"
+
+#include "common/file.h"
+#include "common/system.h"
+#include "common/textconsole.h"
+
+#include "audio/fmopl.h"
+#include "audio/softsynth/emumidi.h"
+
+namespace Sherlock {
+
+#define SHERLOCK_ADLIB_VOICES_COUNT 9
+#define SHERLOCK_ADLIB_NOTES_COUNT 96
+
+byte operator1Register[SHERLOCK_ADLIB_VOICES_COUNT] = {
+ 0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12
+};
+
+byte operator2Register[SHERLOCK_ADLIB_VOICES_COUNT] = {
+ 0x03, 0x04, 0x05, 0x0B, 0x0C, 0x0D, 0x13, 0x14, 0x15
+};
+
+struct percussionChannelEntry {
+ byte requiredNote;
+ byte replacementNote;
+};
+
+// hardcoded, dumped from ADHOM.DRV
+const percussionChannelEntry percussionChannelTable[SHERLOCK_ADLIB_VOICES_COUNT] = {
+ { 0x00, 0x00 },
+ { 0x00, 0x00 },
+ { 0x00, 0x00 },
+ { 0x00, 0x00 },
+ { 0x00, 0x00 },
+ { 0x00, 0x00 },
+ { 0x24, 0x0C },
+ { 0x38, 0x01 },
+ { 0x26, 0x1E }
+};
+
+struct InstrumentEntry {
+ byte reg20op1;
+ byte reg40op1;
+ byte reg60op1;
+ byte reg80op1;
+ byte regE0op1;
+ byte reg20op2;
+ byte reg40op2;
+ byte reg60op2;
+ byte reg80op2;
+ byte regE0op2;
+ byte regC0;
+ byte frequencyAdjust;
+};
+
+// hardcoded, dumped from ADHOM.DRV
+const InstrumentEntry instrumentTable[] = {
+ { 0x71, 0x89, 0x51, 0x11, 0x00, 0x61, 0x23, 0x42, 0x15, 0x01, 0x02, 0xF4 },
+ { 0x22, 0x20, 0x97, 0x89, 0x00, 0xA2, 0x1F, 0x70, 0x07, 0x00, 0x0A, 0xF4 },
+ { 0x70, 0x1A, 0x64, 0x13, 0x00, 0x20, 0x1F, 0x53, 0x46, 0x00, 0x0E, 0xF4 },
+ { 0xB6, 0x4A, 0xB6, 0x32, 0x00, 0x11, 0x2B, 0xD1, 0x31, 0x00, 0x0E, 0xE8 },
+ { 0x71, 0x8B, 0x51, 0x11, 0x00, 0x61, 0x20, 0x32, 0x35, 0x01, 0x02, 0xF4 },
+ { 0x71, 0x8A, 0x51, 0x11, 0x00, 0x61, 0x20, 0x32, 0x25, 0x01, 0x02, 0xF4 },
+ { 0x23, 0x0F, 0xF4, 0x04, 0x02, 0x2F, 0x25, 0xF0, 0x43, 0x00, 0x06, 0xE8 },
+ { 0x71, 0x1C, 0x71, 0x03, 0x00, 0x21, 0x1F, 0x54, 0x17, 0x00, 0x0E, 0xF4 },
+ { 0x71, 0x8A, 0x6E, 0x17, 0x00, 0x25, 0x27, 0x6B, 0x0E, 0x00, 0x02, 0xF4 },
+ { 0x71, 0x1D, 0x81, 0x03, 0x00, 0x21, 0x1F, 0x64, 0x17, 0x00, 0x0E, 0xF4 },
+ { 0x01, 0x4B, 0xF1, 0x50, 0x00, 0x01, 0x23, 0xD2, 0x76, 0x00, 0x06, 0xF4 },
+ { 0x2F, 0xCA, 0xF8, 0xE5, 0x00, 0x21, 0x1F, 0xC0, 0xFF, 0x00, 0x00, 0xF4 },
+ { 0x29, 0xCD, 0xF0, 0x91, 0x00, 0x21, 0x1F, 0xE0, 0x86, 0x00, 0x02, 0xF4 },
+ { 0x24, 0xD0, 0xF0, 0x01, 0x00, 0x21, 0x1F, 0xE0, 0x86, 0x00, 0x02, 0xF4 },
+ { 0x23, 0xC8, 0xF0, 0x01, 0x00, 0x21, 0x1F, 0xE0, 0x86, 0x00, 0x02, 0xF4 },
+ { 0x64, 0xC9, 0xB0, 0x01, 0x00, 0x61, 0x1F, 0xF0, 0x86, 0x00, 0x02, 0xF4 },
+ { 0x33, 0x85, 0xA1, 0x10, 0x00, 0x15, 0x9F, 0x72, 0x23, 0x00, 0x08, 0xF4 },
+ { 0x31, 0x85, 0xA1, 0x10, 0x00, 0x15, 0x9F, 0x73, 0x33, 0x00, 0x08, 0xF4 },
+ { 0x31, 0x81, 0xA1, 0x30, 0x00, 0x16, 0x9F, 0xC2, 0x74, 0x00, 0x08, 0xF4 },
+ { 0x03, 0x8A, 0xF0, 0x7B, 0x00, 0x02, 0x9F, 0xF4, 0x7B, 0x00, 0x08, 0xF4 },
+ { 0x03, 0x8A, 0xF0, 0x7B, 0x00, 0x01, 0x9F, 0xF4, 0x7B, 0x00, 0x08, 0xF4 },
+ { 0x23, 0x8A, 0xF2, 0x7B, 0x00, 0x01, 0x9F, 0xF4, 0x7B, 0x00, 0x08, 0xF4 },
+ { 0x32, 0x80, 0x01, 0x10, 0x00, 0x12, 0x9F, 0x72, 0x33, 0x00, 0x08, 0xF4 },
+ { 0x32, 0x80, 0x01, 0x10, 0x00, 0x14, 0x9F, 0x73, 0x33, 0x00, 0x08, 0xF4 },
+ { 0x31, 0x16, 0x73, 0x8E, 0x00, 0x21, 0x1F, 0x80, 0x9E, 0x00, 0x0E, 0xF4 },
+ { 0x30, 0x16, 0x73, 0x7E, 0x00, 0x21, 0x1F, 0x80, 0x9E, 0x00, 0x0E, 0x00 },
+ { 0x31, 0x94, 0x33, 0x73, 0x00, 0x21, 0x1F, 0xA0, 0x97, 0x00, 0x0E, 0xF4 },
+ { 0x31, 0x94, 0xD3, 0x73, 0x00, 0x21, 0x20, 0xA0, 0x97, 0x00, 0x0E, 0xF4 },
+ { 0x31, 0x45, 0xF1, 0x53, 0x00, 0x32, 0x1F, 0xF2, 0x27, 0x00, 0x06, 0xF4 },
+ { 0x13, 0x0C, 0xF2, 0x01, 0x00, 0x15, 0x2F, 0xF2, 0xB6, 0x00, 0x08, 0xF4 },
+ { 0x11, 0x0C, 0xF2, 0x01, 0x00, 0x11, 0x1F, 0xF2, 0xB6, 0x00, 0x08, 0xF4 },
+ { 0x11, 0x0A, 0xFE, 0x04, 0x00, 0x11, 0x1F, 0xF2, 0xBD, 0x00, 0x08, 0xF4 },
+ { 0x16, 0x4D, 0xFA, 0x11, 0x00, 0xE1, 0x20, 0xF1, 0xF1, 0x00, 0x08, 0xF4 },
+ { 0x16, 0x40, 0xBA, 0x11, 0x00, 0xF1, 0x20, 0x24, 0x31, 0x00, 0x08, 0xF4 },
+ { 0x61, 0xA7, 0x72, 0x8E, 0x00, 0xE1, 0x9F, 0x50, 0x1A, 0x00, 0x02, 0xF4 },
+ { 0x18, 0x4D, 0x32, 0x13, 0x00, 0xE1, 0x20, 0x51, 0xE3, 0x00, 0x08, 0xF4 },
+ { 0x17, 0xC0, 0x12, 0x41, 0x00, 0x31, 0x9F, 0x13, 0x31, 0x00, 0x06, 0xF4 },
+ { 0x03, 0x8F, 0xF5, 0x55, 0x00, 0x21, 0x9F, 0xF3, 0x33, 0x00, 0x00, 0xF4 },
+ { 0x13, 0x4D, 0xFA, 0x11, 0x00, 0xE1, 0x20, 0xF1, 0xF1, 0x00, 0x08, 0xF4 },
+ { 0x11, 0x43, 0x20, 0x15, 0x00, 0xF1, 0x20, 0x31, 0xF8, 0x00, 0x08, 0xF4 },
+ { 0x11, 0x03, 0x82, 0x97, 0x00, 0xE4, 0x60, 0xF0, 0xF2, 0x00, 0x08, 0xF4 },
+ { 0x05, 0x40, 0xD1, 0x53, 0x00, 0x14, 0x1F, 0x51, 0x71, 0x00, 0x06, 0xF4 },
+ { 0xF1, 0x01, 0x77, 0x17, 0x00, 0x21, 0x1F, 0x81, 0x18, 0x00, 0x02, 0xF4 },
+ { 0xF1, 0x18, 0x32, 0x11, 0x00, 0xE1, 0x1F, 0xF1, 0x13, 0x00, 0x00, 0xF4 },
+ { 0x73, 0x48, 0xF1, 0x53, 0x00, 0x71, 0x1F, 0xF1, 0x06, 0x00, 0x08, 0xF4 },
+ { 0x71, 0x8D, 0x71, 0x11, 0x00, 0x61, 0x5F, 0x72, 0x15, 0x00, 0x06, 0xF4 },
+ { 0xD7, 0x4F, 0xF2, 0x61, 0x00, 0xD2, 0x1F, 0xF1, 0xB2, 0x00, 0x08, 0xF4 },
+ { 0x01, 0x11, 0xF0, 0xFF, 0x00, 0x01, 0x1F, 0xF0, 0xF8, 0x00, 0x0A, 0xF4 },
+ { 0x31, 0x8B, 0x41, 0x11, 0x00, 0x61, 0x1F, 0x22, 0x13, 0x00, 0x06, 0xF4 },
+ { 0x71, 0x1C, 0x71, 0x03, 0x00, 0x21, 0x1F, 0x64, 0x07, 0x00, 0x0E, 0xF4 },
+ { 0x31, 0x8B, 0x41, 0x11, 0x00, 0x61, 0x1F, 0x32, 0x15, 0x00, 0x02, 0xF4 },
+ { 0x71, 0x1C, 0xFD, 0x13, 0x00, 0x21, 0x1F, 0xE7, 0xD6, 0x00, 0x0E, 0xF4 },
+ { 0x71, 0x1C, 0x51, 0x03, 0x00, 0x21, 0x1F, 0x54, 0x67, 0x00, 0x0E, 0xF4 },
+ { 0x71, 0x1C, 0x51, 0x03, 0x00, 0x21, 0x1F, 0x54, 0x17, 0x00, 0x0E, 0xF4 },
+ { 0x71, 0x1C, 0x54, 0x15, 0x00, 0x21, 0x1F, 0x53, 0x49, 0x00, 0x0E, 0xF4 },
+ { 0x71, 0x56, 0x51, 0x03, 0x00, 0x61, 0x1F, 0x54, 0x17, 0x00, 0x0E, 0xF4 },
+ { 0x71, 0x1C, 0x51, 0x03, 0x00, 0x21, 0x1F, 0x54, 0x17, 0x00, 0x0E, 0xF4 },
+ { 0x02, 0x29, 0xF5, 0x75, 0x00, 0x01, 0x9F, 0xF2, 0xF3, 0x00, 0x00, 0xF4 },
+ { 0x02, 0x29, 0xF0, 0x75, 0x00, 0x01, 0x9F, 0xF4, 0x33, 0x00, 0x00, 0xF4 },
+ { 0x01, 0x49, 0xF1, 0x53, 0x00, 0x11, 0x1F, 0xF1, 0x74, 0x00, 0x06, 0xF4 },
+ { 0x01, 0x89, 0xF1, 0x53, 0x00, 0x11, 0x1F, 0xF1, 0x74, 0x00, 0x06, 0xF4 },
+ { 0x02, 0x89, 0xF1, 0x53, 0x00, 0x11, 0x1F, 0xF1, 0x74, 0x00, 0x06, 0xF4 },
+ { 0x02, 0x80, 0xF1, 0x53, 0x00, 0x11, 0x1F, 0xF1, 0x74, 0x00, 0x06, 0xF4 },
+ { 0x01, 0x40, 0xF1, 0x53, 0x00, 0x08, 0x5F, 0xF1, 0x53, 0x00, 0x00, 0xF4 },
+ { 0x21, 0x15, 0xD3, 0x2C, 0x00, 0x21, 0x9F, 0xC3, 0x2C, 0x00, 0x0A, 0xF4 },
+ { 0x01, 0x18, 0xD4, 0xF2, 0x00, 0x21, 0x9F, 0xC4, 0x8A, 0x00, 0x0A, 0xF4 },
+ { 0x01, 0x4E, 0xF0, 0x7B, 0x00, 0x11, 0x1F, 0xF4, 0xC8, 0x00, 0x04, 0xF4 },
+ { 0x01, 0x44, 0xF0, 0xAB, 0x00, 0x11, 0x1F, 0xF3, 0xAB, 0x00, 0x04, 0xF4 },
+ { 0x53, 0x0E, 0xF4, 0xC8, 0x00, 0x11, 0x1F, 0xF1, 0xBB, 0x00, 0x04, 0xF4 },
+ { 0x53, 0x0B, 0xF2, 0xC8, 0x00, 0x11, 0x1F, 0xF2, 0xC5, 0x00, 0x04, 0xF4 },
+ { 0x21, 0x15, 0xB4, 0x4C, 0x00, 0x21, 0x1F, 0x94, 0xAC, 0x00, 0x0A, 0xF4 },
+ { 0x21, 0x15, 0x94, 0x1C, 0x00, 0x21, 0x1F, 0x64, 0xAC, 0x00, 0x0A, 0xF4 },
+ { 0x22, 0x1B, 0x97, 0x89, 0x00, 0xA2, 0x1F, 0x70, 0x07, 0x00, 0x0A, 0xF4 },
+ { 0x21, 0x19, 0x77, 0xBF, 0x00, 0xA1, 0x9F, 0x60, 0x2A, 0x00, 0x06, 0xF4 },
+ { 0xA1, 0x13, 0xD6, 0xAF, 0x00, 0xE2, 0x9F, 0x60, 0x2A, 0x00, 0x02, 0xF4 },
+ { 0xA2, 0x1D, 0x95, 0x24, 0x00, 0xE2, 0x9F, 0x60, 0x2A, 0x00, 0x02, 0xF4 },
+ { 0x32, 0x9A, 0x51, 0x19, 0x00, 0x61, 0x9F, 0x60, 0x39, 0x00, 0x0C, 0xF4 },
+ { 0xA4, 0x12, 0xF4, 0x30, 0x00, 0xE2, 0x9F, 0x60, 0x2A, 0x00, 0x02, 0xF4 },
+ { 0x21, 0x16, 0x63, 0x0E, 0x00, 0x21, 0x1F, 0x63, 0x0E, 0x00, 0x0C, 0xF4 },
+ { 0x31, 0x16, 0x63, 0x0A, 0x00, 0x21, 0x1F, 0x63, 0x0B, 0x00, 0x0C, 0xF4 },
+ { 0x21, 0x1B, 0x63, 0x0A, 0x00, 0x21, 0x1F, 0x63, 0x0B, 0x00, 0x0C, 0xF4 },
+ { 0x20, 0x1B, 0x63, 0x0A, 0x00, 0x21, 0x1F, 0x63, 0x0B, 0x00, 0x0C, 0xF4 },
+ { 0x32, 0x1C, 0x82, 0x18, 0x00, 0x61, 0x9F, 0x60, 0x07, 0x00, 0x0C, 0xF4 },
+ { 0x32, 0x18, 0x61, 0x14, 0x00, 0xE1, 0x9F, 0x72, 0x16, 0x00, 0x0C, 0xF4 },
+ { 0x31, 0xC0, 0x77, 0x17, 0x00, 0x22, 0x1F, 0x6B, 0x09, 0x00, 0x02, 0xF4 },
+ { 0x71, 0xC3, 0x8E, 0x17, 0x00, 0x22, 0x24, 0x8B, 0x0E, 0x00, 0x02, 0xF4 },
+ { 0x70, 0x8D, 0x6E, 0x17, 0x00, 0x22, 0x1F, 0x6B, 0x0E, 0x00, 0x02, 0xF4 },
+ { 0x24, 0x4F, 0xF2, 0x06, 0x00, 0x31, 0x1F, 0x52, 0x06, 0x00, 0x0E, 0xF4 },
+ { 0x31, 0x1B, 0x64, 0x07, 0x00, 0x61, 0x1F, 0xD0, 0x67, 0x00, 0x0E, 0xF4 },
+ { 0x31, 0x1B, 0x61, 0x06, 0x00, 0x61, 0x1F, 0xD2, 0x36, 0x00, 0x0C, 0xF4 },
+ { 0x31, 0x1F, 0x31, 0x06, 0x00, 0x61, 0x1F, 0x50, 0x36, 0x00, 0x0C, 0xF4 },
+ { 0x31, 0x1F, 0x41, 0x06, 0x00, 0x61, 0x1F, 0xA0, 0x36, 0x00, 0x0C, 0xF4 },
+ { 0x21, 0x9A, 0x53, 0x56, 0x00, 0x21, 0x9F, 0xA0, 0x16, 0x00, 0x0E, 0xF4 },
+ { 0x21, 0x9A, 0x53, 0x56, 0x00, 0x21, 0x9F, 0xA0, 0x16, 0x00, 0x0E, 0xF4 },
+ { 0x61, 0x19, 0x53, 0x58, 0x00, 0x21, 0x1F, 0xA0, 0x18, 0x00, 0x0C, 0xF4 },
+ { 0x61, 0x19, 0x73, 0x57, 0x00, 0x21, 0x1F, 0xA0, 0x17, 0x00, 0x0C, 0xF4 },
+ { 0x21, 0x1B, 0x71, 0xA6, 0x00, 0x21, 0x1F, 0xA1, 0x96, 0x00, 0x0E, 0xF4 },
+ { 0x85, 0x91, 0xF5, 0x44, 0x00, 0xA1, 0x1F, 0xF0, 0x45, 0x00, 0x06, 0xF4 },
+ { 0x07, 0x51, 0xF5, 0x33, 0x00, 0x61, 0x1F, 0xF0, 0x25, 0x00, 0x06, 0xF4 },
+ { 0x13, 0x8C, 0xFF, 0x21, 0x00, 0x11, 0x9F, 0xFF, 0x03, 0x00, 0x0E, 0xF4 },
+ { 0x38, 0x8C, 0xF3, 0x0D, 0x00, 0xB1, 0x5F, 0xF5, 0x33, 0x00, 0x0E, 0xF4 },
+ { 0x87, 0x91, 0xF5, 0x55, 0x00, 0x22, 0x1F, 0xF0, 0x54, 0x00, 0x06, 0xF4 },
+ { 0xB6, 0x4A, 0xB6, 0x32, 0x00, 0x11, 0x2B, 0xD1, 0x31, 0x00, 0x0E, 0xF4 },
+ { 0x04, 0x00, 0xFE, 0xF0, 0x00, 0xC2, 0x1F, 0xF6, 0xB5, 0x00, 0x0E, 0xF4 },
+ { 0x05, 0x4E, 0xDA, 0x15, 0x00, 0x01, 0x9F, 0xF0, 0x13, 0x00, 0x0A, 0xF4 },
+ { 0x31, 0x44, 0xF2, 0x9A, 0x00, 0x32, 0x1F, 0xF0, 0x27, 0x00, 0x06, 0xF4 },
+ { 0xB0, 0xC4, 0xA4, 0x02, 0x00, 0xD7, 0x9F, 0x40, 0x42, 0x00, 0x00, 0xF4 },
+ { 0xCA, 0x84, 0xF0, 0xF0, 0x00, 0xCF, 0x1F, 0x59, 0x62, 0x00, 0x0C, 0xF4 },
+ { 0x30, 0x35, 0xF5, 0xF0, 0x00, 0x35, 0x1F, 0xF0, 0x9B, 0x00, 0x02, 0xF4 },
+ { 0x63, 0x0F, 0xF4, 0x04, 0x02, 0x6F, 0x1F, 0xF0, 0x43, 0x00, 0x06, 0xF4 },
+ { 0x07, 0x40, 0x09, 0x53, 0x00, 0x05, 0x1F, 0xF6, 0x94, 0x00, 0x0E, 0xF4 },
+ { 0x09, 0x4E, 0xDA, 0x25, 0x00, 0x01, 0x1F, 0xF1, 0x15, 0x00, 0x0A, 0xF4 },
+ { 0x04, 0x00, 0xF3, 0xA0, 0x02, 0x04, 0x1F, 0xF8, 0x46, 0x00, 0x0E, 0xF4 },
+ { 0x07, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x1F, 0x5C, 0xDC, 0x00, 0x0E, 0xF4 },
+ { 0x1F, 0x1E, 0xE5, 0x5B, 0x00, 0x0F, 0x1F, 0x5D, 0xFA, 0x00, 0x0E, 0xF4 },
+ { 0x11, 0x8A, 0xF1, 0x11, 0x00, 0x01, 0x5F, 0xF1, 0xB3, 0x00, 0x06, 0xF4 },
+ { 0x00, 0x40, 0xD1, 0x53, 0x00, 0x00, 0x1F, 0xF2, 0x56, 0x00, 0x0E, 0xF4 },
+ { 0x32, 0x44, 0xF8, 0xFF, 0x00, 0x11, 0x1F, 0xF5, 0x7F, 0x00, 0x0E, 0xF4 },
+ { 0x00, 0x40, 0x09, 0x53, 0x00, 0x02, 0x1F, 0xF7, 0x94, 0x00, 0x0E, 0xF4 },
+ { 0x11, 0x86, 0xF2, 0xA8, 0x00, 0x01, 0x9F, 0xA0, 0xA8, 0x00, 0x08, 0xF4 },
+ { 0x00, 0x50, 0xF2, 0x70, 0x00, 0x13, 0x1F, 0xF2, 0x72, 0x00, 0x0E, 0xF4 },
+ { 0xF0, 0x00, 0x11, 0x11, 0x00, 0xE0, 0xDF, 0x11, 0x11, 0x00, 0x0E, 0xF4 }
+};
+
+// hardcoded, dumped from ADHOM.DRV
+uint16 frequencyLookUpTable[SHERLOCK_ADLIB_NOTES_COUNT] = {
+ 0x0158, 0x016C, 0x0182, 0x0199, 0x01B1, 0x01CB, 0x01E6, 0x0203, 0x0222, 0x0242,
+ 0x0265, 0x0289, 0x0558, 0x056C, 0x0582, 0x0599, 0x05B1, 0x05CB, 0x05E6, 0x0603,
+ 0x0622, 0x0642, 0x0665, 0x0689, 0x0958, 0x096C, 0x0982, 0x0999, 0x09B1, 0x09CB,
+ 0x09E6, 0x0A03, 0x0A22, 0x0A42, 0x0A65, 0x0A89, 0x0D58, 0x0D6C, 0x0D82, 0x0D99,
+ 0x0DB1, 0x0DCB, 0x0DE6, 0x0E03, 0x0E22, 0x0E42, 0x0E65, 0x0E89, 0x1158, 0x116C,
+ 0x1182, 0x1199, 0x11B1, 0x11CB, 0x11E6, 0x1203, 0x1222, 0x1242, 0x1265, 0x1289,
+ 0x1558, 0x156C, 0x1582, 0x1599, 0x15B1, 0x15CB, 0x15E6, 0x1603, 0x1622, 0x1642,
+ 0x1665, 0x1689, 0x1958, 0x196C, 0x1982, 0x1999, 0x19B1, 0x19CB, 0x19E6, 0x1A03,
+ 0x1A22, 0x1A42, 0x1A65, 0x1A89, 0x1D58, 0x1D6C, 0x1D82, 0x1D99, 0x1DB1, 0x1DCB,
+ 0x1DE6, 0x1E03, 0x1E22, 0x1E42, 0x1E65, 0x1E89
+};
+
+class MidiDriver_SH_AdLib : public MidiDriver {
+public:
+ MidiDriver_SH_AdLib(Audio::Mixer *mixer)
+ : _masterVolume(15), _opl(0),
+ _adlibTimerProc(0), _adlibTimerParam(0), _isOpen(false) {
+ memset(_voiceChannelMapping, 0, sizeof(_voiceChannelMapping));
+ }
+ virtual ~MidiDriver_SH_AdLib() { }
+
+ // MidiDriver
+ int open();
+ void close();
+ void send(uint32 b);
+ MidiChannel *allocateChannel() { return NULL; }
+ MidiChannel *getPercussionChannel() { return NULL; }
+ bool isOpen() const { return _isOpen; }
+ uint32 getBaseTempo() { return 1000000 / OPL::OPL::kDefaultCallbackFrequency; }
+
+ int getPolyphony() const { return SHERLOCK_ADLIB_VOICES_COUNT; }
+ bool hasRhythmChannel() const { return false; }
+
+ virtual void setTimerCallback(void *timerParam, Common::TimerManager::TimerProc timerProc);
+
+ void setVolume(byte volume);
+ virtual uint32 property(int prop, uint32 param);
+
+ void newMusicData(byte *musicData, int32 musicDataSize);
+
+private:
+ struct adlib_ChannelEntry {
+ bool inUse;
+ uint16 inUseTimer;
+ const InstrumentEntry *currentInstrumentPtr;
+ byte currentNote;
+ byte currentA0hReg;
+ byte currentB0hReg;
+
+ adlib_ChannelEntry() : inUse(false), inUseTimer(0), currentInstrumentPtr(NULL), currentNote(0),
+ currentA0hReg(0), currentB0hReg(0) { }
+ };
+
+ OPL::OPL *_opl;
+ int _masterVolume;
+
+ Common::TimerManager::TimerProc _adlibTimerProc;
+ void *_adlibTimerParam;
+
+ bool _isOpen;
+
+ // points to a MIDI channel for each of the new voice channels
+ byte _voiceChannelMapping[SHERLOCK_ADLIB_VOICES_COUNT];
+
+ // stores information about all FM voice channels
+ adlib_ChannelEntry _channels[SHERLOCK_ADLIB_VOICES_COUNT];
+
+ void onTimer();
+
+ void resetAdLib();
+ void resetAdLibOperatorRegisters(byte baseRegister, byte value);
+ void resetAdLibFMVoiceChannelRegisters(byte baseRegister, byte value);
+
+ void programChange(byte MIDIchannel, byte parameter);
+ void setRegister(int reg, int value);
+ void noteOn(byte MIDIchannel, byte note, byte velocity);
+ void noteOff(byte MIDIchannel, byte note);
+ void voiceOnOff(byte FMVoiceChannel, bool KeyOn, byte note, byte velocity);
+
+ void pitchBendChange(byte MIDIchannel, byte parameter1, byte parameter2);
+};
+
+int MidiDriver_SH_AdLib::open() {
+ debugC(kDebugLevelAdLibDriver, "AdLib: starting driver");
+
+ _opl = OPL::Config::create(OPL::Config::kOpl2);
+
+ if (!_opl)
+ return -1;
+
+ _opl->init();
+
+ _isOpen = true;
+
+ _opl->start(new Common::Functor0Mem<void, MidiDriver_SH_AdLib>(this, &MidiDriver_SH_AdLib::onTimer));
+
+ return 0;
+}
+
+void MidiDriver_SH_AdLib::close() {
+ // Stop the OPL timer
+ _opl->stop();
+
+ delete _opl;
+}
+
+void MidiDriver_SH_AdLib::setVolume(byte volume) {
+ _masterVolume = volume;
+ //renewNotes(-1, true);
+}
+
+// this should/must get called per tick
+// original driver did this before MIDI data processing on each tick
+// we do it atm after MIDI data processing
+void MidiDriver_SH_AdLib::onTimer() {
+ if (_adlibTimerProc)
+ (*_adlibTimerProc)(_adlibTimerParam);
+
+ // this should/must get called per tick
+ // original driver did this before MIDI data processing on each tick
+ // we do it atm after MIDI data processing
+ for (byte FMvoiceChannel = 0; FMvoiceChannel < SHERLOCK_ADLIB_VOICES_COUNT; FMvoiceChannel++) {
+ if (_channels[FMvoiceChannel].inUse) {
+ _channels[FMvoiceChannel].inUseTimer++;
+ }
+ }
+}
+
+// Called when a music track got loaded into memory
+void MidiDriver_SH_AdLib::newMusicData(byte *musicData, int32 musicDataSize) {
+ assert(musicDataSize >= 0x7F);
+ // MIDI Channel <-> FM Voice Channel mapping at offset 0x22 of music data
+ memcpy(&_voiceChannelMapping, musicData + 0x22, 9);
+
+ // reset OPL
+ resetAdLib();
+
+ // reset current channel data
+ memset(&_channels, 0, sizeof(_channels));
+}
+
+void MidiDriver_SH_AdLib::resetAdLib() {
+
+ setRegister(0x01, 0x20); // enable waveform control on both operators
+ setRegister(0x04, 0xE0); // Timer control
+
+ setRegister(0x08, 0); // select FM music mode
+ setRegister(0xBD, 0); // disable Rhythm
+
+ // reset FM voice instrument data
+ resetAdLibOperatorRegisters(0x20, 0);
+ resetAdLibOperatorRegisters(0x60, 0);
+ resetAdLibOperatorRegisters(0x80, 0);
+ resetAdLibFMVoiceChannelRegisters(0xA0, 0);
+ resetAdLibFMVoiceChannelRegisters(0xB0, 0);
+ resetAdLibFMVoiceChannelRegisters(0xC0, 0);
+ resetAdLibOperatorRegisters(0xE0, 0);
+ resetAdLibOperatorRegisters(0x40, 0x3F);
+}
+
+void MidiDriver_SH_AdLib::resetAdLibOperatorRegisters(byte baseRegister, byte value) {
+ byte operatorIndex;
+
+ for (operatorIndex = 0; operatorIndex < 0x16; operatorIndex++) {
+ switch (operatorIndex) {
+ case 0x06:
+ case 0x07:
+ case 0x0E:
+ case 0x0F:
+ break;
+ default:
+ setRegister(baseRegister + operatorIndex, value);
+ }
+ }
+}
+
+void MidiDriver_SH_AdLib::resetAdLibFMVoiceChannelRegisters(byte baseRegister, byte value) {
+ byte FMvoiceChannel;
+
+ for (FMvoiceChannel = 0; FMvoiceChannel < SHERLOCK_ADLIB_VOICES_COUNT; FMvoiceChannel++) {
+ setRegister(baseRegister + FMvoiceChannel, value);
+ }
+}
+
+// MIDI messages can be found at http://www.midi.org/techspecs/midimessages.php
+void MidiDriver_SH_AdLib::send(uint32 b) {
+ byte command = b & 0xf0;
+ byte channel = b & 0xf;
+ byte op1 = (b >> 8) & 0xff;
+ byte op2 = (b >> 16) & 0xff;
+
+ switch (command) {
+ case 0x80:
+ noteOff(channel, op1);
+ break;
+ case 0x90:
+ noteOn(channel, op1, op2);
+ break;
+ case 0xb0: // Control change
+ // Doesn't seem to be implemented in the Sherlock Holmes adlib driver
+ break;
+ case 0xc0: // Program Change
+ programChange(channel, op1);
+ break;
+ case 0xa0: // Polyphonic key pressure (aftertouch)
+ case 0xd0: // Channel pressure (aftertouch)
+ // Aftertouch doesn't seem to be implemented in the Sherlock Holmes adlib driver
+ break;
+ case 0xe0:
+ debugC(kDebugLevelAdLibDriver, "AdLib: pitch bend change");
+ pitchBendChange(channel, op1, op2);
+ break;
+ case 0xf0: // SysEx
+ warning("ADLIB: SysEx: %x", b);
+ break;
+ default:
+ warning("ADLIB: Unknown event %02x", command);
+ }
+}
+
+void MidiDriver_SH_AdLib::noteOn(byte MIDIchannel, byte note, byte velocity) {
+ int16 oldestInUseChannel = -1;
+ uint16 oldestInUseTimer = 0;
+
+ if (velocity == 0)
+ return noteOff(MIDIchannel, note);
+
+ if (MIDIchannel != 9) {
+ // Not Percussion
+ for (byte FMvoiceChannel = 0; FMvoiceChannel < SHERLOCK_ADLIB_VOICES_COUNT; FMvoiceChannel++) {
+ if (_voiceChannelMapping[FMvoiceChannel] == MIDIchannel) {
+ if (!_channels[FMvoiceChannel].inUse) {
+ _channels[FMvoiceChannel].inUse = true;
+ _channels[FMvoiceChannel].currentNote = note;
+
+ voiceOnOff(FMvoiceChannel, true, note, velocity);
+ return;
+ }
+ }
+ }
+
+ // Look for oldest in-use channel
+ for (byte FMvoiceChannel = 0; FMvoiceChannel < SHERLOCK_ADLIB_VOICES_COUNT; FMvoiceChannel++) {
+ if (_voiceChannelMapping[FMvoiceChannel] == MIDIchannel) {
+ if (_channels[FMvoiceChannel].inUseTimer > oldestInUseTimer) {
+ oldestInUseTimer = _channels[FMvoiceChannel].inUseTimer;
+ oldestInUseChannel = FMvoiceChannel;
+ }
+ }
+ }
+ if (oldestInUseChannel >= 0) {
+ // channel found
+ debugC(kDebugLevelAdLibDriver, "AdLib: used In-Use channel");
+ // original driver used note 0, we use the current note
+ // because using note 0 could create a bad note (out of index) and we check that. Original driver didn't.
+ voiceOnOff(oldestInUseChannel, false, _channels[oldestInUseChannel].currentNote, 0);
+
+ _channels[oldestInUseChannel].inUse = true;
+ _channels[oldestInUseChannel].inUseTimer = 0; // safety, original driver also did this
+ _channels[oldestInUseChannel].currentNote = note;
+ voiceOnOff(oldestInUseChannel, true, note, velocity);
+ return;
+ }
+ debugC(kDebugLevelAdLibDriver, "AdLib: MIDI channel not mapped/all FM voice channels busy %d", MIDIchannel);
+
+ } else {
+ // Percussion channel
+ for (byte FMvoiceChannel = 0; FMvoiceChannel < SHERLOCK_ADLIB_VOICES_COUNT; FMvoiceChannel++) {
+ if (_voiceChannelMapping[FMvoiceChannel] == MIDIchannel) {
+ if (note == percussionChannelTable[FMvoiceChannel].requiredNote) {
+ _channels[FMvoiceChannel].inUse = true;
+ _channels[FMvoiceChannel].currentNote = note;
+
+ voiceOnOff(FMvoiceChannel, true, percussionChannelTable[FMvoiceChannel].replacementNote, velocity);
+ return;
+ }
+ }
+ }
+ debugC(kDebugLevelAdLibDriver, "AdLib: percussion MIDI channel not mapped/all FM voice channels busy");
+ }
+}
+
+void MidiDriver_SH_AdLib::noteOff(byte MIDIchannel, byte note) {
+ for (byte FMvoiceChannel = 0; FMvoiceChannel < SHERLOCK_ADLIB_VOICES_COUNT; FMvoiceChannel++) {
+ if (_voiceChannelMapping[FMvoiceChannel] == MIDIchannel) {
+ if (_channels[FMvoiceChannel].currentNote == note) {
+ _channels[FMvoiceChannel].inUse = false;
+ _channels[FMvoiceChannel].inUseTimer = 0;
+ _channels[FMvoiceChannel].currentNote = 0;
+
+ if (MIDIchannel != 9) {
+ // not-percussion
+ voiceOnOff(FMvoiceChannel, false, note, 0);
+ } else {
+ voiceOnOff(FMvoiceChannel, false, percussionChannelTable[FMvoiceChannel].replacementNote, 0);
+ }
+ return;
+ }
+ }
+ }
+}
+
+void MidiDriver_SH_AdLib::voiceOnOff(byte FMvoiceChannel, bool keyOn, byte note, byte velocity) {
+ byte frequencyOffset = 0;
+ uint16 frequency = 0;
+ byte op2RegAdjust = 0;
+ byte regValue40h = 0;
+ byte regValueA0h = 0;
+ byte regValueB0h = 0;
+
+ // Look up frequency
+ if (_channels[FMvoiceChannel].currentInstrumentPtr) {
+ frequencyOffset = note + _channels[FMvoiceChannel].currentInstrumentPtr->frequencyAdjust;
+ } else {
+ frequencyOffset = note;
+ }
+ if (frequencyOffset >= SHERLOCK_ADLIB_NOTES_COUNT) {
+ warning("CRITICAL - AdLib driver: bad note!!!");
+ return;
+ }
+ frequency = frequencyLookUpTable[frequencyOffset];
+
+ if (keyOn) {
+ // adjust register 40h
+ if (_channels[FMvoiceChannel].currentInstrumentPtr) {
+ regValue40h = _channels[FMvoiceChannel].currentInstrumentPtr->reg40op2;
+ }
+ regValue40h = regValue40h - (velocity >> 3);
+ op2RegAdjust = operator2Register[FMvoiceChannel];
+ setRegister(0x40 + op2RegAdjust, regValue40h);
+ }
+
+ regValueA0h = frequency & 0xFF;
+ regValueB0h = frequency >> 8;
+ if (keyOn) {
+ regValueB0h |= 0x20; // set Key-On flag
+ }
+
+ setRegister(0xA0 + FMvoiceChannel, regValueA0h);
+ setRegister(0xB0 + FMvoiceChannel, regValueB0h);
+ _channels[FMvoiceChannel].currentA0hReg = regValueA0h;
+ _channels[FMvoiceChannel].currentB0hReg = regValueB0h;
+}
+
+void MidiDriver_SH_AdLib::pitchBendChange(byte MIDIchannel, byte parameter1, byte parameter2) {
+ uint16 channelFrequency = 0;
+ byte channelRegB0hWithoutFrequency = 0;
+ uint16 parameter = 0;
+ byte regValueA0h = 0;
+ byte regValueB0h = 0;
+
+ for (byte FMvoiceChannel = 0; FMvoiceChannel < SHERLOCK_ADLIB_VOICES_COUNT; FMvoiceChannel++) {
+ if (_voiceChannelMapping[FMvoiceChannel] == MIDIchannel) {
+ if (_channels[FMvoiceChannel].inUse) {
+ // FM voice channel found and it's currently in use -> apply pitch bend change
+
+ // Remove frequency bits from current channel B0h-register
+ channelFrequency = ((_channels[FMvoiceChannel].currentB0hReg << 8) | (_channels[FMvoiceChannel].currentA0hReg)) & 0x3FF;
+ channelRegB0hWithoutFrequency = _channels[FMvoiceChannel].currentB0hReg & 0xFC;
+
+ if (parameter2 < 0x40) {
+ channelFrequency = channelFrequency / 2;
+ } else {
+ parameter2 = parameter2 - 0x40;
+ }
+ parameter1 = parameter1 * 2;
+ parameter = parameter1 | (parameter2 << 8);
+ parameter = parameter * 4;
+
+ parameter = (parameter >> 8) + 0xFF;
+ channelFrequency = channelFrequency * parameter;
+ channelFrequency = (channelFrequency >> 8) | (parameter << 8);
+
+ regValueA0h = channelFrequency & 0xFF;
+ regValueB0h = (channelFrequency >> 8) | channelRegB0hWithoutFrequency;
+
+ setRegister(0xA0 + FMvoiceChannel, regValueA0h);
+ setRegister(0xB0 + FMvoiceChannel, regValueB0h);
+ }
+ }
+ }
+}
+
+void MidiDriver_SH_AdLib::programChange(byte MIDIchannel, byte op1) {
+ const InstrumentEntry *instrumentPtr;
+ byte op1Reg = 0;
+ byte op2Reg = 0;
+
+ // setup instrument
+ instrumentPtr = &instrumentTable[op1];
+ //warning("program change for MIDI channel %d, instrument id %d", MIDIchannel, op1);
+
+ for (byte FMvoiceChannel = 0; FMvoiceChannel < SHERLOCK_ADLIB_VOICES_COUNT; FMvoiceChannel++) {
+ if (_voiceChannelMapping[FMvoiceChannel] == MIDIchannel) {
+
+ op1Reg = operator1Register[FMvoiceChannel];
+ op2Reg = operator2Register[FMvoiceChannel];
+
+ setRegister(0x20 + op1Reg, instrumentPtr->reg20op1);
+ setRegister(0x40 + op1Reg, instrumentPtr->reg40op1);
+ setRegister(0x60 + op1Reg, instrumentPtr->reg60op1);
+ setRegister(0x80 + op1Reg, instrumentPtr->reg80op1);
+ setRegister(0xE0 + op1Reg, instrumentPtr->regE0op1);
+
+ setRegister(0x20 + op2Reg, instrumentPtr->reg20op2);
+ setRegister(0x40 + op2Reg, instrumentPtr->reg40op2);
+ setRegister(0x60 + op2Reg, instrumentPtr->reg60op2);
+ setRegister(0x80 + op2Reg, instrumentPtr->reg80op2);
+ setRegister(0xE0 + op2Reg, instrumentPtr->regE0op2);
+
+ setRegister(0xC0 + FMvoiceChannel, instrumentPtr->regC0);
+
+ // Remember instrument
+ _channels[FMvoiceChannel].currentInstrumentPtr = instrumentPtr;
+ }
+ }
+}
+void MidiDriver_SH_AdLib::setRegister(int reg, int value) {
+ _opl->write(0x220, reg);
+ _opl->write(0x221, value);
+}
+
+uint32 MidiDriver_SH_AdLib::property(int prop, uint32 param) {
+ return 0;
+}
+
+void MidiDriver_SH_AdLib::setTimerCallback(void *timerParam, Common::TimerManager::TimerProc timerProc) {
+ _adlibTimerProc = timerProc;
+ _adlibTimerParam = timerParam;
+}
+
+MidiDriver *MidiDriver_SH_AdLib_create() {
+ return new MidiDriver_SH_AdLib(g_system->getMixer());
+}
+
+void MidiDriver_SH_AdLib_newMusicData(MidiDriver *driver, byte *musicData, int32 musicDataSize) {
+ static_cast<MidiDriver_SH_AdLib *>(driver)->newMusicData(musicData, musicDataSize);
+}
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/scalpel/drivers/mididriver.h b/engines/sherlock/scalpel/drivers/mididriver.h
new file mode 100644
index 0000000000..1b8ceeda3d
--- /dev/null
+++ b/engines/sherlock/scalpel/drivers/mididriver.h
@@ -0,0 +1,41 @@
+/* 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 SHERLOCK_SCALPEL_DRIVERS_MIDIDRIVER_H
+#define SHERLOCK_SCALPEL_DRIVERS_MIDIDRIVER_H
+
+#include "sherlock/sherlock.h"
+#include "audio/mididrv.h"
+#include "common/error.h"
+
+namespace Sherlock {
+
+extern MidiDriver *MidiDriver_SH_AdLib_create();
+extern void MidiDriver_SH_AdLib_newMusicData(MidiDriver *driver, byte *musicData, int32 musicDataSize);
+
+extern MidiDriver *MidiDriver_MT32_create();
+extern void MidiDriver_MT32_uploadPatches(MidiDriver *driver, byte *driverData, int32 driverSize);
+extern void MidiDriver_MT32_newMusicData(MidiDriver *driver, byte *musicData, int32 musicDataSize);
+
+} // End of namespace Sherlock
+
+#endif // SHERLOCK_SCALPEL_DRIVERS_MIDIDRIVER_H
diff --git a/engines/sherlock/scalpel/drivers/mt32.cpp b/engines/sherlock/scalpel/drivers/mt32.cpp
new file mode 100644
index 0000000000..33e7671719
--- /dev/null
+++ b/engines/sherlock/scalpel/drivers/mt32.cpp
@@ -0,0 +1,282 @@
+/* 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 "sherlock/sherlock.h"
+#include "sherlock/scalpel/drivers/mididriver.h"
+
+#include "common/config-manager.h"
+#include "common/file.h"
+#include "common/system.h"
+#include "common/textconsole.h"
+
+//#include "audio/mididrv.h"
+
+namespace Sherlock {
+
+#define SHERLOCK_MT32_CHANNEL_COUNT 16
+
+const byte mt32ReverbDataSysEx[] = {
+ 0x10, 0x00, 0x01, 0x01, 0x05, 0x05, 0xFF
+};
+
+class MidiDriver_MT32 : public MidiDriver {
+public:
+ MidiDriver_MT32() {
+ _driver = NULL;
+ _isOpen = false;
+ _nativeMT32 = false;
+ _baseFreq = 250;
+
+ memset(_MIDIchannelActive, 1, sizeof(_MIDIchannelActive));
+ }
+ virtual ~MidiDriver_MT32();
+
+ // MidiDriver
+ int open();
+ void close();
+ bool isOpen() const { return _isOpen; }
+
+ void send(uint32 b);
+
+ void newMusicData(byte *musicData, int32 musicDataSize);
+
+ MidiChannel *allocateChannel() {
+ if (_driver)
+ return _driver->allocateChannel();
+ return NULL;
+ }
+ MidiChannel *getPercussionChannel() {
+ if (_driver)
+ return _driver->getPercussionChannel();
+ return NULL;
+ }
+
+ void setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc) {
+ if (_driver)
+ _driver->setTimerCallback(timer_param, timer_proc);
+ }
+
+ uint32 getBaseTempo() {
+ if (_driver) {
+ return _driver->getBaseTempo();
+ }
+ return 1000000 / _baseFreq;
+ }
+
+protected:
+ Common::Mutex _mutex;
+ MidiDriver *_driver;
+ bool _nativeMT32;
+
+ bool _isOpen;
+ int _baseFreq;
+
+private:
+ // points to a MIDI channel for each of the new voice channels
+ byte _MIDIchannelActive[SHERLOCK_MT32_CHANNEL_COUNT];
+
+public:
+ void uploadMT32Patches(byte *driverData, int32 driverSize);
+
+ void mt32SysEx(const byte *&dataPtr, int32 &bytesLeft);
+};
+
+MidiDriver_MT32::~MidiDriver_MT32() {
+ Common::StackLock lock(_mutex);
+ if (_driver) {
+ _driver->setTimerCallback(0, 0);
+ _driver->close();
+ delete _driver;
+ }
+ _driver = NULL;
+}
+
+int MidiDriver_MT32::open() {
+ assert(!_driver);
+
+ debugC(kDebugLevelMT32Driver, "MT32: starting driver");
+
+ // Setup midi driver
+ MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_PREFER_MT32);
+ MusicType musicType = MidiDriver::getMusicType(dev);
+
+ switch (musicType) {
+ case MT_MT32:
+ _nativeMT32 = true;
+ break;
+ case MT_GM:
+ if (ConfMan.getBool("native_mt32")) {
+ _nativeMT32 = true;
+ }
+ break;
+ default:
+ break;
+ }
+
+ _driver = MidiDriver::createMidi(dev);
+ if (!_driver)
+ return 255;
+
+ if (_nativeMT32)
+ _driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
+
+ int ret = _driver->open();
+ if (ret)
+ return ret;
+
+ if (_nativeMT32)
+ _driver->sendMT32Reset();
+ else
+ _driver->sendGMReset();
+
+ return 0;
+}
+
+void MidiDriver_MT32::close() {
+ if (_driver) {
+ _driver->close();
+ }
+}
+
+// Called when a music track got loaded into memory
+void MidiDriver_MT32::newMusicData(byte *musicData, int32 musicDataSize) {
+ assert(musicDataSize >= 0x7F); // Security check
+
+ // MIDI Channel Enable/Disable bytes at offset 0x2 of music data
+ memcpy(&_MIDIchannelActive, musicData + 0x2, SHERLOCK_MT32_CHANNEL_COUNT);
+
+ // Send 16 bytes from offset 0x12 to MT32
+ // All the music tracks of Sherlock seem to contain dummy data
+ // probably a feature, that was used in the game "Ski or Die"
+ // that's why we don't implement this
+
+ // Also send these bytes to MT32 (SysEx) - seems to be reverb configuration
+ if (_nativeMT32) {
+ const byte *reverbData = mt32ReverbDataSysEx;
+ int32 reverbDataSize = sizeof(mt32ReverbDataSysEx);
+ mt32SysEx(reverbData, reverbDataSize);
+ }
+}
+
+void MidiDriver_MT32::uploadMT32Patches(byte *driverData, int32 driverSize) {
+ if (!_driver)
+ return;
+
+ if (!_nativeMT32)
+ return;
+
+ // patch data starts at offset 0x863
+ assert(driverSize == 0x13B9); // Security check
+ assert(driverData[0x863] == 0x7F); // another security check
+
+ const byte *patchPtr = driverData + 0x863;
+ int32 bytesLeft = driverSize - 0x863;
+
+ while(1) {
+ mt32SysEx(patchPtr, bytesLeft);
+
+ assert(bytesLeft);
+ if (*patchPtr == 0x80) // List terminator
+ break;
+ }
+}
+
+void MidiDriver_MT32::mt32SysEx(const byte *&dataPtr, int32 &bytesLeft) {
+ byte sysExMessage[270];
+ uint16 sysExPos = 0;
+ byte sysExByte = 0;
+ uint16 sysExChecksum = 0;
+
+ memset(&sysExMessage, 0, sizeof(sysExMessage));
+
+ sysExMessage[0] = 0x41; // Roland
+ sysExMessage[1] = 0x10;
+ sysExMessage[2] = 0x16; // Model MT32
+ sysExMessage[3] = 0x12; // Command DT1
+
+ sysExPos = 4;
+ sysExChecksum = 0;
+ while (1) {
+ assert(bytesLeft);
+
+ sysExByte = *dataPtr++;
+ bytesLeft--;
+ if (sysExByte == 0xff)
+ break; // Message done
+
+ assert(sysExPos < sizeof(sysExMessage));
+ sysExMessage[sysExPos++] = sysExByte;
+ sysExChecksum -= sysExByte;
+ }
+
+ // Calculate checksum
+ assert(sysExPos < sizeof(sysExMessage));
+ sysExMessage[sysExPos++] = sysExChecksum & 0x7f;
+
+ debugC(kDebugLevelMT32Driver, "MT32: uploading patch data, size %d", sysExPos);
+
+ // Send SysEx
+ _driver->sysEx(sysExMessage, sysExPos);
+
+ // Wait the time it takes to send the SysEx data
+ uint32 delay = (sysExPos + 2) * 1000 / 3125;
+
+ // Plus an additional delay for the MT-32 rev00
+ if (_nativeMT32)
+ delay += 40;
+
+ g_system->delayMillis(delay);
+}
+
+// MIDI messages can be found at http://www.midi.org/techspecs/midimessages.php
+void MidiDriver_MT32::send(uint32 b) {
+ byte command = b & 0xf0;
+ byte channel = b & 0xf;
+
+ if (command == 0xF0) {
+ if (_driver) {
+ _driver->send(b);
+ }
+ return;
+ }
+
+ if (_MIDIchannelActive[channel]) {
+ // Only forward MIDI-data in case the channel is currently enabled via music-data
+ if (_driver) {
+ _driver->send(b);
+ }
+ }
+}
+
+MidiDriver *MidiDriver_MT32_create() {
+ return new MidiDriver_MT32();
+}
+
+void MidiDriver_MT32_newMusicData(MidiDriver *driver, byte *musicData, int32 musicDataSize) {
+ static_cast<MidiDriver_MT32 *>(driver)->newMusicData(musicData, musicDataSize);
+}
+
+void MidiDriver_MT32_uploadPatches(MidiDriver *driver, byte *driverData, int32 driverSize) {
+ static_cast<MidiDriver_MT32 *>(driver)->uploadMT32Patches(driverData, driverSize);
+}
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp
new file mode 100644
index 0000000000..af9d613cce
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel.cpp
@@ -0,0 +1,1160 @@
+/* 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 "engines/util.h"
+#include "sherlock/scalpel/scalpel.h"
+#include "sherlock/scalpel/scalpel_fixed_text.h"
+#include "sherlock/scalpel/scalpel_map.h"
+#include "sherlock/scalpel/scalpel_people.h"
+#include "sherlock/scalpel/scalpel_scene.h"
+#include "sherlock/scalpel/tsage/logo.h"
+#include "sherlock/sherlock.h"
+#include "sherlock/music.h"
+#include "sherlock/animation.h"
+// for 3DO
+#include "sherlock/scalpel/3do/movie_decoder.h"
+
+namespace Sherlock {
+
+namespace Scalpel {
+
+#define PROLOGUE_NAMES_COUNT 6
+
+// The following are a list of filenames played in the prologue that have
+// special effects associated with them at specific frames
+static const char *const PROLOGUE_NAMES[PROLOGUE_NAMES_COUNT] = {
+ "subway1", "subway2", "finale2", "suicid", "coff3", "coff4"
+};
+
+static const int PROLOGUE_FRAMES[6][9] = {
+ { 4, 26, 54, 72, 92, 134, FRAMES_END },
+ { 2, 80, 95, 117, 166, FRAMES_END },
+ { 1, FRAMES_END },
+ { 42, FRAMES_END },
+ { FRAMES_END },
+ { FRAMES_END }
+};
+
+#define TITLE_NAMES_COUNT 7
+
+// Title animations file list
+static const char *const TITLE_NAMES[TITLE_NAMES_COUNT] = {
+ "27pro1", "14note", "coff1", "coff2", "coff3", "coff4", "14kick"
+};
+
+static const int TITLE_FRAMES[7][9] = {
+ { 29, 131, FRAMES_END },
+ { 55, 80, 95, 117, 166, FRAMES_END },
+ { 15, FRAMES_END },
+ { 4, 37, 92, FRAMES_END },
+ { 2, 43, FRAMES_END },
+ { 2, FRAMES_END },
+ { 10, 50, FRAMES_END }
+};
+
+#define NUM_PLACES 100
+
+static const int MAP_X[NUM_PLACES] = {
+ 0, 368, 0, 219, 0, 282, 0, 43, 0, 0, 396, 408, 0, 0, 0, 568, 37, 325,
+ 28, 0, 263, 36, 148, 469, 342, 143, 443, 229, 298, 0, 157, 260, 432,
+ 174, 0, 351, 0, 528, 0, 136, 0, 0, 0, 555, 165, 0, 506, 0, 0, 344, 0, 0
+};
+static const int MAP_Y[NUM_PLACES] = {
+ 0, 147, 0, 166, 0, 109, 0, 61, 0, 0, 264, 70, 0, 0, 0, 266, 341, 30, 275,
+ 0, 294, 146, 311, 230, 184, 268, 133, 94, 207, 0, 142, 142, 330, 255, 0,
+ 37, 0, 70, 0, 116, 0, 0, 0, 50, 21, 0, 303, 0, 0, 229, 0, 0
+};
+
+static const int MAP_TRANSLATE[NUM_PLACES] = {
+ 0, 0, 0, 1, 0, 2, 0, 3, 4, 0, 4, 6, 0, 0, 0, 8, 9, 10, 11, 0, 12, 13, 14, 7,
+ 15, 16, 17, 18, 19, 0, 20, 21, 22, 23, 0, 24, 0, 25, 0, 26, 0, 0, 0, 27,
+ 28, 0, 29, 0, 0, 30, 0
+};
+
+static const byte MAP_SEQUENCES[3][MAX_FRAME] = {
+ { 1, 1, 2, 3, 4, 0 }, // Overview Still
+ { 5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 0 },
+ { 5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 0 }
+};
+
+#define MAX_PEOPLE 66
+
+struct PeopleData {
+ const char *portrait;
+ const char *name;
+ byte stillSequences[MAX_TALK_SEQUENCES];
+ byte talkSequences[MAX_TALK_SEQUENCES];
+};
+
+const PeopleData PEOPLE_DATA[MAX_PEOPLE] = {
+ { "HOLM", "Sherlock Holmes", { 1, 0, 0 }, { 1, 0, 0 } },
+ { "WATS", "Dr. Watson", { 6, 0, 0 }, { 5, 5, 6, 7, 8, 7, 8, 6, 0, 0 } },
+ { "LEST", "Inspector Lestrade", { 4, 0, 0 }, { 2, 0, 0 } },
+ { "CON1", "Constable O'Brien", { 2, 0, 0 }, { 1, 0, 0 } },
+ { "CON2", "Constable Lewis", { 2, 0, 0 }, { 1, 0, 0 } },
+ { "SHEI", "Sheila Parker", { 2, 0, 0 }, { 2, 3, 0, 0 } },
+ { "HENR", "Henry Carruthers", { 3, 0, 0 }, { 3, 0, 0 } },
+ { "LESL", "Lesley", { 9, 0, 0 }, { 1, 2, 3, 2, 1, 2, 3, 0, 0 } },
+ { "USH1", "An Usher", { 13, 0, 0 }, { 13, 14, 0, 0 } },
+ { "USH2", "An Usher", { 2, 0, 0 }, { 2, 0, 0 } },
+ { "FRED", "Fredrick Epstein", { 4, 0, 0 }, { 1, 2, 3, 4, 3, 4, 3, 2, 0, 0 } },
+ { "WORT", "Mrs. Worthington", { 9, 0, 0 }, { 8, 0, 0 } },
+ { "COAC", "The Coach", { 2, 0, 0 }, { 1, 2, 3, 4, 5, 4, 3, 2, 0, 0 } },
+ { "PLAY", "A Player", { 8, 0, 0 }, { 7, 8, 0, 0 } },
+ { "WBOY", "Tim", { 13, 0, 0 }, { 12, 13, 0, 0 } },
+ { "JAME", "James Sanders", { 6, 0, 0 }, { 3, 4, 0, 0 } },
+ { "BELL", "Belle", { 1, 0, 0 }, { 4, 5, 0, 0 } },
+ { "GIRL", "Cleaning Girl", { 20, 0, 0 }, { 14, 15, 16, 17, 18, 19, 20, 20, 20, 0, 0 } },
+ { "EPST", "Fredrick Epstein", { 17, 0, 0 }, { 16, 17, 18, 18, 18, 17, 17, 0, 0 } },
+ { "WIGG", "Wiggins", { 3, 0, 0 }, { 2, 3, 0, 0 } },
+ { "PAUL", "Paul", { 2, 0, 0 }, { 1, 2, 0, 0 } },
+ { "BART", "The Bartender", { 1, 0, 0 }, { 1, 0, 0 } },
+ { "DIRT", "A Dirty Drunk", { 1, 0, 0 }, { 1, 0, 0 } },
+ { "SHOU", "A Shouting Drunk", { 1, 0, 0 }, { 1, 0, 0 } },
+ { "STAG", "A Staggering Drunk", { 1, 0, 0 }, { 1, 0, 0 } },
+ { "BOUN", "The Bouncer", { 1, 0, 0 }, { 1, 0, 0 } },
+ { "SAND", "James Sanders", { 6, 0, 0 }, { 5, 6, 0, 0 } },
+ { "CORO", "The Coroner", { 6, 0, 0 }, { 4, 5, 0, 0 } },
+ { "EQUE", "Reginald Snipes", { 1, 0, 0 }, { 1, 0, 0 } },
+ { "GEOR", "George Blackwood", { 1, 0, 0 }, { 1, 0, 0 } },
+ { "LARS", "Lars", { 7, 0, 0 }, { 5, 6, 0, 0 } },
+ { "PARK", "Sheila Parker", { 1, 0, 0 }, { 1, 0, 0 } },
+ { "CHEM", "The Chemist", { 8, 0, 0 }, { 8, 9, 0, 0 } },
+ { "GREG", "Inspector Gregson", { 6, 0, 0 }, { 5, 6, 0, 0 } },
+ { "LAWY", "Jacob Farthington", { 1, 0, 0 }, { 1, 0, 0 } },
+ { "MYCR", "Mycroft", { 1, 0, 0 }, { 1, 0, 0 } },
+ { "SHER", "Old Sherman", { 7, 0, 0 }, { 7, 8, 0, 0 } },
+ { "CHMB", "Richard", { 1, 0, 0 }, { 1, 0, 0 } },
+ { "BARM", "The Barman", { 1, 0, 0 }, { 1, 0, 0 } },
+ { "DAND", "A Dandy Player", { 1, 0, 0 }, { 1, 0, 0 } },
+ { "ROUG", "A Rough-looking Player", { 1, 0, 0 }, { 1, 0, 0 } },
+ { "SPEC", "A Spectator", { 1, 0, 0 }, { 1, 0, 0 } },
+ { "HUNT", "Robert Hunt", { 1, 0, 0 }, { 1, 0, 0 } },
+ { "VIOL", "Violet", { 3, 0, 0 }, { 3, 4, 0, 0 } },
+ { "PETT", "Pettigrew", { 1, 0, 0 }, { 1, 0, 0 } },
+ { "APPL", "Augie", { 8, 0, 0 }, { 14, 15, 0, 0 } },
+ { "ANNA", "Anna Carroway", { 16, 0, 0 }, { 3, 4, 5, 6, 0, 0 } },
+ { "GUAR", "A Guard", { 1, 0, 0 }, { 4, 5, 6, 0, 0 } },
+ { "ANTO", "Antonio Caruso", { 8, 0, 0 }, { 7, 8, 0, 0 } },
+ { "TOBY", "Toby the Dog", { 1, 0, 0 }, { 1, 0, 0 } },
+ { "KING", "Simon Kingsley", { 13, 0, 0 }, { 13, 14, 0, 0 } },
+ { "ALFR", "Alfred", { 2, 0, 0 }, { 2, 3, 0, 0 } },
+ { "LADY", "Lady Brumwell", { 1, 0, 0 }, { 3, 4, 0, 0 } },
+ { "ROSA", "Madame Rosa", { 1, 0, 0 }, { 1, 30, 0, 0 } },
+ { "LADB", "Lady Brumwell", { 1, 0, 0 }, { 3, 4, 0, 0 } },
+ { "MOOR", "Joseph Moorehead", { 1, 0, 0 }, { 1, 0, 0 } },
+ { "BEAL", "Mrs. Beale", { 5, 0, 0 }, { 14, 15, 16, 17, 18, 19, 20, 0, 0 } },
+ { "LION", "Felix", { 1, 0, 0 }, { 1, 0, 0 } },
+ { "HOLL", "Hollingston", { 1, 0, 0 }, { 1, 0, 0 } },
+ { "CALL", "Constable Callaghan", { 1, 0, 0 }, { 1, 0, 0 } },
+ { "JERE", "Sergeant Duncan", { 2, 0, 0 }, { 1, 1, 2, 2, 0, 0 } },
+ { "LORD", "Lord Brumwell", { 1, 0, 0 }, { 9, 10, 0, 0 } },
+ { "NIGE", "Nigel Jaimeson", { 1, 0, 0 }, { 1, 2, 0, 138, 3, 4, 0, 138, 0, 0 } },
+ { "JONA", "Jonas", { 1, 0, 0 }, { 1, 8, 0, 0 } },
+ { "DUGA", "Constable Dugan", { 1, 0, 0 }, { 1, 0, 0 } },
+ { "INSP", "Inspector Lestrade", { 4, 0, 0 }, { 2, 0, 0 } }
+};
+
+/*----------------------------------------------------------------*/
+
+ScalpelEngine::ScalpelEngine(OSystem *syst, const SherlockGameDescription *gameDesc) :
+ SherlockEngine(syst, gameDesc) {
+ _darts = nullptr;
+ _mapResult = 0;
+}
+
+ScalpelEngine::~ScalpelEngine() {
+ delete _darts;
+}
+
+void ScalpelEngine::initialize() {
+ // 3DO actually uses RGB555, but some platforms of ours only support RGB565, so we use that
+
+ if (getPlatform() == Common::kPlatform3DO) {
+ const Graphics::PixelFormat pixelFormatRGB565 = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
+ // 320x200 16-bit RGB565 for 3DO support
+ initGraphics(320, 200, false, &pixelFormatRGB565);
+ } else {
+ // 320x200 palettized
+ initGraphics(320, 200, false);
+ }
+
+ // Let the base engine intialize
+ SherlockEngine::initialize();
+
+ _darts = new Darts(this);
+
+ _flags.resize(100 * 8);
+ _flags[3] = true; // Turn on Alley
+ _flags[39] = true; // Turn on Baker Street
+
+ if (!isDemo()) {
+ // Load the map co-ordinates for each scene and sequence data
+ ScalpelMap &map = *(ScalpelMap *)_map;
+ map.loadPoints(NUM_PLACES, &MAP_X[0], &MAP_Y[0], &MAP_TRANSLATE[0]);
+ map.loadSequences(3, &MAP_SEQUENCES[0][0]);
+ map._oldCharPoint = BAKER_ST_EXTERIOR;
+ }
+
+ // Load the inventory
+ loadInventory();
+
+ // Set up list of people
+ for (int idx = 0; idx < MAX_PEOPLE; ++idx)
+ _people->_characters.push_back(PersonData(PEOPLE_DATA[idx].name, PEOPLE_DATA[idx].portrait,
+ PEOPLE_DATA[idx].stillSequences, PEOPLE_DATA[idx].talkSequences));
+
+ _animation->setPrologueNames(&PROLOGUE_NAMES[0], PROLOGUE_NAMES_COUNT);
+ _animation->setPrologueFrames(&PROLOGUE_FRAMES[0][0], 6, 9);
+
+ _animation->setTitleNames(&TITLE_NAMES[0], TITLE_NAMES_COUNT);
+ _animation->setTitleFrames(&TITLE_FRAMES[0][0], 7, 9);
+
+ // Starting scene
+ if (isDemo() && _interactiveFl)
+ _scene->_goToScene = 3;
+ else
+ _scene->_goToScene = 4;
+}
+
+void ScalpelEngine::showOpening() {
+ bool finished = true;
+
+ if (isDemo() && _interactiveFl)
+ return;
+
+ if (getPlatform() == Common::kPlatform3DO) {
+ show3DOSplash();
+
+ finished = showCityCutscene3DO();
+ if (finished)
+ finished = showAlleyCutscene3DO();
+ if (finished)
+ finished = showStreetCutscene3DO();
+ if (finished)
+ showOfficeCutscene3DO();
+
+ _events->clearEvents();
+ _music->stopMusic();
+ return;
+ }
+
+ TsAGE::Logo::show(this);
+ finished = showCityCutscene();
+ if (finished)
+ finished = showAlleyCutscene();
+ if (finished)
+ finished = showStreetCutscene();
+ if (finished)
+ showOfficeCutscene();
+
+ _events->clearEvents();
+ _music->stopMusic();
+}
+
+bool ScalpelEngine::showCityCutscene() {
+ byte greyPalette[PALETTE_SIZE];
+ byte palette[PALETTE_SIZE];
+
+ // Demo fades from black into grey and then fades from grey into the scene
+ Common::fill(&greyPalette[0], &greyPalette[PALETTE_SIZE], 142);
+ _screen->fadeIn((const byte *)greyPalette, 3);
+
+ _music->loadSong("prolog1");
+ _animation->_gfxLibraryFilename = "title.lib";
+ _animation->_soundLibraryFilename = "title.snd";
+ bool finished = _animation->play("26open1", true, 1, 255, true, 2);
+
+ if (finished) {
+ ImageFile titleImages_LondonNovember("title2.vgs", true);
+ _screen->_backBuffer1.blitFrom(*_screen);
+ _screen->_backBuffer2.blitFrom(*_screen);
+
+ Common::Point londonPosition;
+
+ if ((titleImages_LondonNovember[0]._width == 302) && (titleImages_LondonNovember[0]._height == 39)) {
+ // Spanish
+ londonPosition = Common::Point(9, 8);
+ } else {
+ // English (German uses the same English graphics), width 272, height 37
+ // In the German version this is placed differently, check against German floppy version TODO
+ londonPosition = Common::Point(30, 50);
+ }
+
+ // London, England
+ _screen->_backBuffer1.transBlitFrom(titleImages_LondonNovember[0], londonPosition);
+ _screen->randomTransition();
+ finished = _events->delay(1000, true);
+
+ // November, 1888
+ if (finished) {
+ _screen->_backBuffer1.transBlitFrom(titleImages_LondonNovember[1], Common::Point(100, 100));
+ _screen->randomTransition();
+ finished = _events->delay(5000, true);
+ }
+
+ // Transition out the title
+ _screen->_backBuffer1.blitFrom(_screen->_backBuffer2);
+ _screen->randomTransition();
+ }
+
+ if (finished)
+ finished = _animation->play("26open2", true, 1, 0, false, 2);
+
+ if (finished) {
+ ImageFile titleImages_SherlockHolmesTitle("title.vgs", true);
+ _screen->_backBuffer1.blitFrom(*_screen);
+ _screen->_backBuffer2.blitFrom(*_screen);
+
+ Common::Point lostFilesPosition;
+ Common::Point sherlockHolmesPosition;
+ Common::Point copyrightPosition;
+
+ if ((titleImages_SherlockHolmesTitle[0]._width == 306) && (titleImages_SherlockHolmesTitle[0]._height == 39)) {
+ // Spanish
+ lostFilesPosition = Common::Point(5, 5);
+ sherlockHolmesPosition = Common::Point(24, 40);
+ copyrightPosition = Common::Point(3, 190);
+ } else {
+ // English (German uses the same English graphics), width 208, height 39
+ lostFilesPosition = Common::Point(75, 6);
+ sherlockHolmesPosition = Common::Point(34, 21);
+ copyrightPosition = Common::Point(4, 190);
+ }
+
+ // The Lost Files of
+ _screen->_backBuffer1.transBlitFrom(titleImages_SherlockHolmesTitle[0], lostFilesPosition);
+ // Sherlock Holmes
+ _screen->_backBuffer1.transBlitFrom(titleImages_SherlockHolmesTitle[1], sherlockHolmesPosition);
+ // copyright
+ _screen->_backBuffer1.transBlitFrom(titleImages_SherlockHolmesTitle[2], copyrightPosition);
+
+ _screen->verticalTransition();
+ finished = _events->delay(4000, true);
+
+ if (finished) {
+ _screen->_backBuffer1.blitFrom(_screen->_backBuffer2);
+ _screen->randomTransition();
+ finished = _events->delay(2000);
+ }
+
+ if (finished) {
+ _screen->getPalette(palette);
+ _screen->fadeToBlack(2);
+ }
+
+ if (finished) {
+ // In the alley...
+ Common::Point alleyPosition;
+
+ if ((titleImages_SherlockHolmesTitle[3]._width == 105) && (titleImages_SherlockHolmesTitle[3]._height == 16)) {
+ // German
+ alleyPosition = Common::Point(72, 50);
+ } else if ((titleImages_SherlockHolmesTitle[3]._width == 166) && (titleImages_SherlockHolmesTitle[3]._height == 36)) {
+ // Spanish
+ alleyPosition = Common::Point(71, 50);
+ } else {
+ // English, width 175, height 38
+ alleyPosition = Common::Point(72, 51);
+ }
+ _screen->transBlitFrom(titleImages_SherlockHolmesTitle[3], alleyPosition);
+ _screen->fadeIn(palette, 3);
+
+ // Wait until the track got looped and the first few notes were played
+ finished = _music->waitUntilMSec(4300, 21300, 0, 2500); // ticks 0x104 / ticks 0x500
+ }
+ }
+
+ _animation->_gfxLibraryFilename = "";
+ _animation->_soundLibraryFilename = "";
+ return finished;
+}
+
+bool ScalpelEngine::showAlleyCutscene() {
+ byte palette[PALETTE_SIZE];
+ _music->loadSong("prolog2");
+
+ _animation->_gfxLibraryFilename = "TITLE.LIB";
+ _animation->_soundLibraryFilename = "TITLE.SND";
+
+ // Fade "In The Alley..." text to black
+ _screen->fadeToBlack(2);
+
+ bool finished = _animation->play("27PRO1", true, 1, 3, true, 2);
+ if (finished) {
+ _screen->getPalette(palette);
+ _screen->fadeToBlack(2);
+
+ // wait until second lower main note
+ finished = _music->waitUntilMSec(26800, 0xFFFFFFFF, 0, 1000); // ticks 0x64A
+ }
+
+ if (finished) {
+ _screen->setPalette(palette);
+ finished = _animation->play("27PRO2", true, 1, 0, false, 2);
+ }
+
+ if (finished) {
+ showLBV("scream.lbv");
+
+ // wait until first "scream" in music happened
+ finished = _music->waitUntilMSec(45800, 0xFFFFFFFF, 0, 6000); // ticks 0xABE
+ }
+
+ if (finished) {
+ // quick fade out
+ _screen->fadeToBlack(1);
+
+ // wait until after third "scream" in music happened
+ finished = _music->waitUntilMSec(49000, 0xFFFFFFFF, 0, 2000); // ticks 0xB80
+ }
+
+ if (finished)
+ finished = _animation->play("27PRO3", true, 1, 0, true, 2);
+
+ if (finished) {
+ _screen->getPalette(palette);
+ _screen->fadeToBlack(2);
+ }
+
+ if (finished) {
+ ImageFile titleImages_EarlyTheFollowingMorning("title3.vgs", true);
+ // "Early the following morning on Baker Street..."
+ Common::Point earlyTheFollowingMorningPosition;
+
+ if ((titleImages_EarlyTheFollowingMorning[0]._width == 164) && (titleImages_EarlyTheFollowingMorning[0]._height == 19)) {
+ // German
+ earlyTheFollowingMorningPosition = Common::Point(35, 50);
+ } else if ((titleImages_EarlyTheFollowingMorning[0]._width == 171) && (titleImages_EarlyTheFollowingMorning[0]._height == 32)) {
+ // Spanish
+ earlyTheFollowingMorningPosition = Common::Point(35, 50);
+ } else {
+ // English, width 218, height 31
+ earlyTheFollowingMorningPosition = Common::Point(35, 52);
+ }
+
+ _screen->transBlitFrom(titleImages_EarlyTheFollowingMorning[0], earlyTheFollowingMorningPosition);
+
+ // fast fade-in
+ _screen->fadeIn(palette, 1);
+
+ // wait for music to end and wait an additional 2.5 seconds
+ finished = _music->waitUntilMSec(0xFFFFFFFF, 0xFFFFFFFF, 2500, 3000);
+ }
+
+ _animation->_gfxLibraryFilename = "";
+ _animation->_soundLibraryFilename = "";
+ return finished;
+}
+
+bool ScalpelEngine::showStreetCutscene() {
+ _animation->_gfxLibraryFilename = "TITLE.LIB";
+ _animation->_soundLibraryFilename = "TITLE.SND";
+
+ _music->loadSong("prolog3");
+
+ // wait a bit
+ bool finished = _events->delay(500);
+
+ if (finished) {
+ // fade out "Early the following morning..."
+ _screen->fadeToBlack(2);
+
+ // wait for music a bit
+ finished = _music->waitUntilMSec(3800, 0xFFFFFFFF, 0, 1000); // ticks 0xE4
+ }
+
+ if (finished)
+ finished = _animation->play("14KICK", true, 1, 3, true, 2);
+
+ // Constable animation plays slower than speed 2
+ // If we play it with speed 2, music gets obviously out of sync
+ if (finished)
+ finished = _animation->play("14NOTE", true, 1, 0, false, 3);
+
+ // Fade to black
+ if (finished)
+ _screen->fadeToBlack(1);
+
+ _animation->_gfxLibraryFilename = "";
+ _animation->_soundLibraryFilename = "";
+ return finished;
+}
+
+bool ScalpelEngine::showOfficeCutscene() {
+ _music->loadSong("prolog4");
+ _animation->_gfxLibraryFilename = "TITLE2.LIB";
+ _animation->_soundLibraryFilename = "TITLE.SND";
+
+ bool finished = _animation->play("COFF1", true, 1, 3, true, 3);
+ if (finished)
+ finished = _animation->play("COFF2", true, 1, 0, false, 3);
+ if (finished) {
+ showLBV("note.lbv");
+
+ if (_sound->_voices) {
+ finished = _sound->playSound("NOTE1", WAIT_KBD_OR_FINISH);
+ if (finished)
+ finished = _sound->playSound("NOTE2", WAIT_KBD_OR_FINISH);
+ if (finished)
+ finished = _sound->playSound("NOTE3", WAIT_KBD_OR_FINISH);
+ if (finished)
+ finished = _sound->playSound("NOTE4", WAIT_KBD_OR_FINISH);
+ } else
+ finished = _events->delay(19000);
+
+ if (finished) {
+ _events->clearEvents();
+ finished = _events->delay(500);
+ }
+ }
+
+ if (finished)
+ finished = _animation->play("COFF3", true, 1, 0, true, 3);
+
+ if (finished)
+ finished = _animation->play("COFF4", true, 1, 0, false, 3);
+
+ if (finished)
+ finished = scrollCredits();
+
+ if (finished)
+ _screen->fadeToBlack(3);
+
+ _animation->_gfxLibraryFilename = "";
+ _animation->_soundLibraryFilename = "";
+ return finished;
+}
+
+bool ScalpelEngine::scrollCredits() {
+ // Load the images for displaying credit text
+ Common::SeekableReadStream *stream = _res->load("credits.vgs", "title.lib");
+ ImageFile creditsImages(*stream);
+
+ // Demo fades slowly from the scene into credits palette
+ _screen->fadeIn(creditsImages._palette, 3);
+
+ delete stream;
+
+ // Save a copy of the screen background for use in drawing each credit frame
+ _screen->_backBuffer1.blitFrom(*_screen);
+
+ // Loop for showing the credits
+ for(int idx = 0; idx < 600 && !_events->kbHit() && !shouldQuit(); ++idx) {
+ // Copy the entire screen background before writing text
+ _screen->blitFrom(_screen->_backBuffer1);
+
+ // Write the text appropriate for the next frame
+ if (idx < 400)
+ _screen->transBlitFrom(creditsImages[0], Common::Point(10, 200 - idx), false, 0);
+ if (idx > 200)
+ _screen->transBlitFrom(creditsImages[1], Common::Point(10, 400 - idx), false, 0);
+
+ // Don't show credit text on the top and bottom ten rows of the screen
+ _screen->blitFrom(_screen->_backBuffer1, Common::Point(0, 0), Common::Rect(0, 0, _screen->w(), 10));
+ _screen->blitFrom(_screen->_backBuffer1, Common::Point(0, _screen->h() - 10),
+ Common::Rect(0, _screen->h() - 10, _screen->w(), _screen->h()));
+
+ _events->delay(100);
+ }
+
+ return true;
+}
+
+// 3DO variant
+bool ScalpelEngine::show3DOSplash() {
+ // 3DO EA Splash screen
+ ImageFile3DO titleImage_3DOSplash("3DOSplash.cel", kImageFile3DOType_Cel);
+
+ _screen->transBlitFrom(titleImage_3DOSplash[0]._frame, Common::Point(0, -20));
+ bool finished = _events->delay(3000, true);
+
+ if (finished) {
+ _screen->clear();
+ finished = _events->delay(500, true);
+ }
+
+ if (finished) {
+ // EA logo movie
+ Scalpel3DOMoviePlay("EAlogo.stream", Common::Point(20, 0));
+ }
+
+ // Always clear screen
+ _screen->clear();
+ return finished;
+}
+
+bool ScalpelEngine::showCityCutscene3DO() {
+ _animation->_soundLibraryFilename = "TITLE.SND";
+
+ _screen->clear();
+ bool finished = _events->delay(2500, true);
+
+ // rain.aiff seems to be playing in an endless loop until
+ // sherlock logo fades away TODO
+
+ if (finished) {
+ finished = _events->delay(2500, true);
+
+ // Play intro music
+ _music->loadSong("prolog");
+
+ // Fade screen to grey
+ _screen->_backBuffer1.fill(0xCE59); // RGB565: 25, 50, 25 (grey)
+ _screen->fadeIntoScreen3DO(2);
+ }
+
+ if (finished) {
+ finished = _music->waitUntilMSec(3400, 0, 0, 3400);
+ }
+
+ if (finished) {
+ _screen->_backBuffer1.fill(0); // fill backbuffer with black to avoid issues during fade from white
+ finished = _animation->play3DO("26open1", true, 1, true, 2);
+ }
+
+ if (finished) {
+ _screen->_backBuffer1.blitFrom(*_screen); // save into backbuffer 1, used for fade
+ _screen->_backBuffer2.blitFrom(*_screen); // save into backbuffer 2, for restoring later
+
+ // "London, England"
+ ImageFile3DO titleImage_London("title2a.cel", kImageFile3DOType_Cel);
+ _screen->_backBuffer1.transBlitFrom(titleImage_London[0]._frame, Common::Point(30, 50));
+
+ _screen->fadeIntoScreen3DO(1);
+ finished = _events->delay(1500, true);
+
+ if (finished) {
+ // "November, 1888"
+ ImageFile3DO titleImage_November("title2b.cel", kImageFile3DOType_Cel);
+ _screen->_backBuffer1.transBlitFrom(titleImage_November[0]._frame, Common::Point(100, 100));
+
+ _screen->fadeIntoScreen3DO(1);
+ finished = _music->waitUntilMSec(14700, 0, 0, 5000);
+ }
+
+ if (finished) {
+ // Restore screen
+ _screen->blitFrom(_screen->_backBuffer2);
+ }
+ }
+
+ if (finished)
+ finished = _animation->play3DO("26open2", true, 1, false, 2);
+
+ if (finished) {
+ _screen->_backBuffer1.blitFrom(*_screen); // save into backbuffer 1, used for fade
+
+ // "Sherlock Holmes" (title)
+ ImageFile3DO titleImage_SherlockHolmesTitle("title1ab.cel", kImageFile3DOType_Cel);
+ _screen->_backBuffer1.transBlitFrom(titleImage_SherlockHolmesTitle[0]._frame, Common::Point(34, 5));
+
+ // Blend in
+ _screen->fadeIntoScreen3DO(2);
+ finished = _events->delay(500, true);
+
+ // Title should fade in, Copyright should be displayed a bit after that
+ if (finished) {
+ ImageFile3DO titleImage_Copyright("title1c.cel", kImageFile3DOType_Cel);
+
+ _screen->transBlitFrom(titleImage_Copyright[0]._frame, Common::Point(20, 190));
+ finished = _events->delay(3500, true);
+ }
+ }
+
+ if (finished)
+ finished = _music->waitUntilMSec(33600, 0, 0, 2000);
+
+ if (finished) {
+ // Fade to black
+ _screen->_backBuffer1.clear();
+ _screen->fadeIntoScreen3DO(3);
+ }
+
+ if (finished) {
+ // "In the alley behind the Regency Theatre..."
+ ImageFile3DO titleImage_InTheAlley("title1d.cel", kImageFile3DOType_Cel);
+ _screen->_backBuffer1.transBlitFrom(titleImage_InTheAlley[0]._frame, Common::Point(72, 51));
+
+ // Fade in
+ _screen->fadeIntoScreen3DO(4);
+ finished = _music->waitUntilMSec(39900, 0, 0, 2500);
+
+ // Fade out
+ _screen->_backBuffer1.clear();
+ _screen->fadeIntoScreen3DO(4);
+ }
+ return finished;
+}
+
+bool ScalpelEngine::showAlleyCutscene3DO() {
+ bool finished = _music->waitUntilMSec(43500, 0, 0, 1000);
+
+ if (finished)
+ finished = _animation->play3DO("27PRO1", true, 1, false, 2);
+
+ if (finished) {
+ // Fade out...
+ _screen->_backBuffer1.clear();
+ _screen->fadeIntoScreen3DO(3);
+
+ finished = _music->waitUntilMSec(67100, 0, 0, 1000); // 66700
+ }
+
+ if (finished)
+ finished = _animation->play3DO("27PRO2", true, 1, false, 2);
+
+ if (finished)
+ finished = _music->waitUntilMSec(76000, 0, 0, 1000);
+
+ if (finished) {
+ // Show screaming victim
+ ImageFile3DO titleImage_ScreamingVictim("scream.cel", kImageFile3DOType_Cel);
+
+ _screen->clear();
+ _screen->transBlitFrom(titleImage_ScreamingVictim[0]._frame, Common::Point(0, 0));
+
+ // Play "scream.aiff"
+ if (_sound->_voices)
+ _sound->playSound("prologue/sounds/scream.aiff", WAIT_RETURN_IMMEDIATELY, 100);
+
+ finished = _music->waitUntilMSec(81600, 0, 0, 6000);
+ }
+
+ if (finished) {
+ // Fade out
+ _screen->_backBuffer1.clear();
+ _screen->fadeIntoScreen3DO(5);
+
+ finished = _music->waitUntilMSec(84400, 0, 0, 2000);
+ }
+
+ if (finished)
+ finished = _animation->play3DO("27PRO3", true, 1, false, 2);
+
+ if (finished) {
+ // Fade out
+ _screen->_backBuffer1.clear();
+ _screen->fadeIntoScreen3DO(5);
+ }
+
+ if (finished) {
+ // "Early the following morning on Baker Street..."
+ ImageFile3DO titleImage_EarlyTheFollowingMorning("title3.cel", kImageFile3DOType_Cel);
+ _screen->_backBuffer1.transBlitFrom(titleImage_EarlyTheFollowingMorning[0]._frame, Common::Point(35, 51));
+
+ // Fade in
+ _screen->fadeIntoScreen3DO(4);
+ finished = _music->waitUntilMSec(96700, 0, 0, 3000);
+ }
+
+ return finished;
+}
+
+bool ScalpelEngine::showStreetCutscene3DO() {
+ bool finished = true;
+
+ if (finished) {
+ // fade out "Early the following morning..."
+ _screen->_backBuffer1.clear();
+ _screen->fadeIntoScreen3DO(4);
+
+ // wait for music a bit
+ finished = _music->waitUntilMSec(100300, 0, 0, 1000);
+ }
+
+ if (finished)
+ finished = _animation->play3DO("14KICK", true, 1, false, 2);
+
+ // note: part of the constable is sticking to the door during the following
+ // animation, when he walks away. This is a bug of course, but it actually happened on 3DO!
+ // I'm not sure if it happens because the door is pure black (0, 0, 0) and it's because
+ // of transparency - or if the animation itself is bad. We will definitely have to adjust
+ // the animation data to fix it.
+ if (finished)
+ finished = _animation->play3DO("14NOTE", true, 1, false, 3);
+
+ if (finished) {
+ // Fade out
+ _screen->_backBuffer1.clear();
+ _screen->fadeIntoScreen3DO(4);
+ }
+
+ return finished;
+}
+
+bool ScalpelEngine::showOfficeCutscene3DO() {
+ bool finished = _music->waitUntilMSec(151000, 0, 0, 1000);
+
+ if (finished)
+ finished = _animation->play3DO("COFF1", true, 1, false, 3);
+
+ if (finished)
+ finished = _animation->play3DO("COFF2", true, 1, false, 3);
+
+ if (finished)
+ finished = _music->waitUntilMSec(182400, 0, 0, 1000);
+
+ if (finished) {
+ // Show the note
+ ImageFile3DO titleImage_CoffeeNote("note.cel", kImageFile3DOType_Cel);
+
+ _screen->clear();
+ _screen->transBlitFrom(titleImage_CoffeeNote[0]._frame, Common::Point(0, 0));
+
+ if (_sound->_voices) {
+ finished = _sound->playSound("prologue/sounds/note.aiff", WAIT_KBD_OR_FINISH);
+ } else
+ finished = _events->delay(19000);
+
+ if (finished)
+ finished = _music->waitUntilMSec(218800, 0, 0, 1000);
+
+ // Fade out
+ _screen->clear();
+ }
+
+ if (finished)
+ finished = _music->waitUntilMSec(222200, 0, 0, 1000);
+
+ if (finished)
+ finished = _animation->play3DO("COFF3", true, 1, false, 3);
+
+ if (finished)
+ finished = _animation->play3DO("COFF4", true, 1, false, 3);
+
+ if (finished) {
+ finished = _music->waitUntilMSec(244500, 0, 0, 2000);
+
+ // TODO: Brighten the image, possibly by doing a partial fade
+ // to white.
+
+ _screen->_backBuffer1.blitFrom(*_screen);
+
+ for (int nr = 1; finished && nr <= 4; nr++) {
+ char filename[15];
+ sprintf(filename, "credits%d.cel", nr);
+ ImageFile3DO *creditsImage = new ImageFile3DO(filename, kImageFile3DOType_Cel);
+ ImageFrame *creditsFrame = &(*creditsImage)[0];
+ for (int i = 0; finished && i < 200 + creditsFrame->_height; i++) {
+ _screen->blitFrom(_screen->_backBuffer1);
+ _screen->transBlitFrom(creditsFrame->_frame, Common::Point((320 - creditsFrame->_width) / 2, 200 - i));
+ if (!_events->delay(70, true))
+ finished = false;
+ }
+ delete creditsImage;
+ }
+ }
+
+ return finished;
+}
+
+void ScalpelEngine::loadInventory() {
+ ScalpelFixedText &fixedText = *(ScalpelFixedText *)_fixedText;
+ Inventory &inv = *_inventory;
+
+ Common::String fixedText_Message = fixedText.getText(kFixedText_InitInventory_Message);
+ Common::String fixedText_HolmesCard = fixedText.getText(kFixedText_InitInventory_HolmesCard);
+ Common::String fixedText_Tickets = fixedText.getText(kFixedText_InitInventory_Tickets);
+ Common::String fixedText_CuffLink = fixedText.getText(kFixedText_InitInventory_CuffLink);
+ Common::String fixedText_WireHook = fixedText.getText(kFixedText_InitInventory_WireHook);
+ Common::String fixedText_Note = fixedText.getText(kFixedText_InitInventory_Note);
+ Common::String fixedText_OpenWatch = fixedText.getText(kFixedText_InitInventory_OpenWatch);
+ Common::String fixedText_Paper = fixedText.getText(kFixedText_InitInventory_Paper);
+ Common::String fixedText_Letter = fixedText.getText(kFixedText_InitInventory_Letter);
+ Common::String fixedText_Tarot = fixedText.getText(kFixedText_InitInventory_Tarot);
+ Common::String fixedText_OrnateKey = fixedText.getText(kFixedText_InitInventory_OrnateKey);
+ Common::String fixedText_PawnTicket = fixedText.getText(kFixedText_InitInventory_PawnTicket);
+
+ // Initial inventory
+ inv._holdings = 2;
+ inv.push_back(InventoryItem(0, "Message", fixedText_Message, "_ITEM03A"));
+ inv.push_back(InventoryItem(0, "Holmes Card", fixedText_HolmesCard, "_ITEM07A"));
+
+ // Hidden items
+ inv.push_back(InventoryItem(95, "Tickets", fixedText_Tickets, "_ITEM10A"));
+ inv.push_back(InventoryItem(138, "Cuff Link", fixedText_CuffLink, "_ITEM04A"));
+ inv.push_back(InventoryItem(138, "Wire Hook", fixedText_WireHook, "_ITEM06A"));
+ inv.push_back(InventoryItem(150, "Note", fixedText_Note, "_ITEM13A"));
+ inv.push_back(InventoryItem(481, "Open Watch", fixedText_OpenWatch, "_ITEM62A"));
+ inv.push_back(InventoryItem(481, "Paper", fixedText_Paper, "_ITEM44A"));
+ inv.push_back(InventoryItem(532, "Letter", fixedText_Letter, "_ITEM68A"));
+ inv.push_back(InventoryItem(544, "Tarot", fixedText_Tarot, "_ITEM71A"));
+ inv.push_back(InventoryItem(544, "Ornate Key", fixedText_OrnateKey, "_ITEM70A"));
+ inv.push_back(InventoryItem(586, "Pawn ticket", fixedText_PawnTicket, "_ITEM16A"));
+}
+
+void ScalpelEngine::showLBV(const Common::String &filename) {
+ Common::SeekableReadStream *stream = _res->load(filename, "title.lib");
+ ImageFile images(*stream);
+ delete stream;
+
+ _screen->setPalette(images._palette);
+ _screen->_backBuffer1.blitFrom(images[0]);
+ _screen->verticalTransition();
+}
+
+void ScalpelEngine::startScene() {
+ if (_scene->_goToScene == OVERHEAD_MAP || _scene->_goToScene == OVERHEAD_MAP2) {
+ // Show the map
+ if (_music->_musicOn && _music->loadSong(100))
+ _music->startSong();
+
+ _scene->_goToScene = _map->show();
+
+ _music->freeSong();
+ _people->_savedPos = Common::Point(-1, -1);
+ _people->_savedPos._facing = -1;
+ }
+
+ // Some rooms are prologue cutscenes, rather than normal game scenes. These are:
+ // 2: Blackwood's capture
+ // 52: Rescuing Anna
+ // 53: Moorehead's death / subway train
+ // 55: Fade out and exit
+ // 70: Brumwell suicide
+ switch (_scene->_goToScene) {
+ case BLACKWOOD_CAPTURE:
+ case RESCUE_ANNA:
+ case MOOREHEAD_DEATH:
+ case BRUMWELL_SUICIDE:
+ if (_music->_musicOn && _music->loadSong(_scene->_goToScene))
+ _music->startSong();
+
+ switch (_scene->_goToScene) {
+ case BLACKWOOD_CAPTURE:
+ // Blackwood's capture
+ _res->addToCache("final2.vda", "epilogue.lib");
+ _res->addToCache("final2.vdx", "epilogue.lib");
+ _animation->play("final1", false, 1, 3, true, 4);
+ _animation->play("final2", false, 1, 0, false, 4);
+ break;
+
+ case RESCUE_ANNA:
+ // Rescuing Anna
+ _res->addToCache("finalr2.vda", "epilogue.lib");
+ _res->addToCache("finalr2.vdx", "epilogue.lib");
+ _res->addToCache("finale1.vda", "epilogue.lib");
+ _res->addToCache("finale1.vdx", "epilogue.lib");
+ _res->addToCache("finale2.vda", "epilogue.lib");
+ _res->addToCache("finale2.vdx", "epilogue.lib");
+ _res->addToCache("finale3.vda", "epilogue.lib");
+ _res->addToCache("finale3.vdx", "epilogue.lib");
+ _res->addToCache("finale4.vda", "EPILOG2.lib");
+ _res->addToCache("finale4.vdx", "EPILOG2.lib");
+
+ _animation->play("finalr1", false, 1, 3, true, 4);
+ _animation->play("finalr2", false, 1, 0, false, 4);
+
+ if (!_res->isInCache("finale2.vda")) {
+ // Finale file isn't cached
+ _res->addToCache("finale2.vda", "epilogue.lib");
+ _res->addToCache("finale2.vdx", "epilogue.lib");
+ _res->addToCache("finale3.vda", "epilogue.lib");
+ _res->addToCache("finale3.vdx", "epilogue.lib");
+ _res->addToCache("finale4.vda", "EPILOG2.lib");
+ _res->addToCache("finale4.vdx", "EPILOG2.lib");
+ }
+
+ _animation->play("finale1", false, 1, 0, false, 4);
+ _animation->play("finale2", false, 1, 0, false, 4);
+ _animation->play("finale3", false, 1, 0, false, 4);
+
+ _useEpilogue2 = true;
+ _animation->play("finale4", false, 1, 0, false, 4);
+ _useEpilogue2 = false;
+ break;
+
+ case MOOREHEAD_DEATH:
+ // Moorehead's death / subway train
+ _res->addToCache("SUBWAY2.vda", "epilogue.lib");
+ _res->addToCache("SUBWAY2.vdx", "epilogue.lib");
+ _res->addToCache("SUBWAY3.vda", "epilogue.lib");
+ _res->addToCache("SUBWAY3.vdx", "epilogue.lib");
+
+ _animation->play("SUBWAY1", false, 1, 3, true, 4);
+ _animation->play("SUBWAY2", false, 1, 0, false, 4);
+ _animation->play("SUBWAY3", false, 1, 0, false, 4);
+
+ // Set fading to direct fade temporary so the transition goes quickly.
+ _scene->_tempFadeStyle = _screen->_fadeStyle ? 257 : 256;
+ _screen->_fadeStyle = false;
+ break;
+
+ case BRUMWELL_SUICIDE:
+ // Brumwell suicide
+ _animation->play("suicid", false, 1, 3, true, 4);
+ break;
+ default:
+ break;
+ }
+
+ // Except for the Moorehead Murder scene, fade to black first
+ if (_scene->_goToScene != MOOREHEAD_DEATH) {
+ _events->wait(40);
+ _screen->fadeToBlack(3);
+ }
+
+ switch (_scene->_goToScene) {
+ case 52:
+ _scene->_goToScene = LAWYER_OFFICE; // Go to the Lawyer's Office
+ _map->_bigPos = Common::Point(0, 0); // Overland scroll position
+ _map->_overPos = Common::Point(22900 - 600, 9400 + 900); // Overland position
+ _map->_oldCharPoint = LAWYER_OFFICE;
+ break;
+
+ case 53:
+ _scene->_goToScene = STATION; // Go to St. Pancras Station
+ _map->_bigPos = Common::Point(0, 0); // Overland scroll position
+ _map->_overPos = Common::Point(32500 - 600, 3000 + 900); // Overland position
+ _map->_oldCharPoint = STATION;
+ break;
+
+ default:
+ _scene->_goToScene = BAKER_STREET; // Back to Baker st.
+ _map->_bigPos = Common::Point(0, 0); // Overland scroll position
+ _map->_overPos = Common::Point(14500 - 600, 8400 + 900); // Overland position
+ _map->_oldCharPoint = BAKER_STREET;
+ break;
+ }
+
+ // Free any song from the previous scene
+ _music->freeSong();
+ break;
+
+ case EXIT_GAME:
+ // Exit game
+ _screen->fadeToBlack(3);
+ quitGame();
+ return;
+
+ default:
+ break;
+ }
+
+ _events->setCursor(ARROW);
+
+ if (_scene->_goToScene == 99) {
+ // Darts Board minigame
+ _darts->playDarts();
+ _mapResult = _scene->_goToScene = PUB_INTERIOR;
+ }
+
+ _mapResult = _scene->_goToScene;
+}
+
+void ScalpelEngine::eraseMirror12() {
+ Common::Point pt((*_people)[HOLMES]._position.x / FIXED_INT_MULTIPLIER, (*_people)[HOLMES]._position.y / FIXED_INT_MULTIPLIER);
+
+ // If player is in range of the mirror, then restore background from the secondary back buffer
+ if (Common::Rect(70, 100, 200, 200).contains(pt)) {
+ _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(137, 18),
+ Common::Rect(137, 18, 184, 74));
+ }
+}
+
+void ScalpelEngine::doMirror12() {
+ People &people = *_people;
+ Person &player = people[HOLMES];
+
+ Common::Point pt((*_people)[HOLMES]._position.x / FIXED_INT_MULTIPLIER, (*_people)[HOLMES]._position.y / FIXED_INT_MULTIPLIER);
+ int frameNum = player._walkSequences[player._sequenceNumber][player._frameNumber] +
+ player._walkSequences[player._sequenceNumber][0] - 2;
+
+ switch ((*_people)[HOLMES]._sequenceNumber) {
+ case WALK_DOWN:
+ frameNum -= 7;
+ break;
+ case WALK_UP:
+ frameNum += 7;
+ break;
+ case WALK_DOWNRIGHT:
+ frameNum += 7;
+ break;
+ case WALK_UPRIGHT:
+ frameNum -= 7;
+ break;
+ case WALK_DOWNLEFT:
+ frameNum += 7;
+ break;
+ case WALK_UPLEFT:
+ frameNum -= 7;
+ break;
+ case STOP_DOWN:
+ frameNum -= 10;
+ break;
+ case STOP_UP:
+ frameNum += 11;
+ break;
+ case STOP_DOWNRIGHT:
+ frameNum -= 15;
+ break;
+ case STOP_DOWNLEFT:
+ frameNum -= 15;
+ break;
+ case STOP_UPRIGHT:
+ case STOP_UPLEFT:
+ frameNum += 15;
+ if (frameNum == 55)
+ frameNum = 54;
+ break;
+ default:
+ break;
+ }
+
+ if (Common::Rect(80, 100, 145, 138).contains(pt)) {
+ // Get the frame of Sherlock to draw
+ ImageFrame &imageFrame = (*people[HOLMES]._images)[frameNum];
+
+ // Draw the mirror image of Holmes
+ bool flipped = people[HOLMES]._sequenceNumber == WALK_LEFT || people[HOLMES]._sequenceNumber == STOP_LEFT
+ || people[HOLMES]._sequenceNumber == WALK_UPRIGHT || people[HOLMES]._sequenceNumber == STOP_UPRIGHT
+ || people[HOLMES]._sequenceNumber == WALK_DOWNLEFT || people[HOLMES]._sequenceNumber == STOP_DOWNLEFT;
+ _screen->_backBuffer1.transBlitFrom(imageFrame, pt + Common::Point(38, -imageFrame._frame.h - 25), flipped);
+
+ // Redraw the mirror borders to prevent the drawn image of Holmes from appearing outside of the mirror
+ _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(114, 18),
+ Common::Rect(114, 18, 137, 114));
+ _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(137, 70),
+ Common::Rect(137, 70, 142, 114));
+ _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(142, 71),
+ Common::Rect(142, 71, 159, 114));
+ _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(159, 72),
+ Common::Rect(159, 72, 170, 116));
+ _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(170, 73),
+ Common::Rect(170, 73, 184, 114));
+ _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(184, 18),
+ Common::Rect(184, 18, 212, 114));
+ }
+}
+
+void ScalpelEngine::flushMirror12() {
+ Common::Point pt((*_people)[HOLMES]._position.x / FIXED_INT_MULTIPLIER, (*_people)[HOLMES]._position.y / FIXED_INT_MULTIPLIER);
+
+ // If player is in range of the mirror, then draw the entire mirror area to the screen
+ if (Common::Rect(70, 100, 200, 200).contains(pt))
+ _screen->slamArea(137, 18, 47, 56);
+}
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/scalpel/scalpel.h b/engines/sherlock/scalpel/scalpel.h
new file mode 100644
index 0000000000..d2524ccbc7
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel.h
@@ -0,0 +1,133 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SHERLOCK_SCALPEL_H
+#define SHERLOCK_SCALPEL_H
+
+#include "sherlock/sherlock.h"
+#include "sherlock/scalpel/darts.h"
+
+namespace Sherlock {
+
+namespace Scalpel {
+
+enum {
+ BUTTON_TOP = 233,
+ BUTTON_MIDDLE = 244,
+ BUTTON_BOTTOM = 248,
+ COMMAND_FOREGROUND = 15,
+ COMMAND_HIGHLIGHTED = 10,
+ COMMAND_NULL = 248,
+ INFO_FOREGROUND = 11,
+ INFO_BACKGROUND = 1,
+ INV_FOREGROUND = 14,
+ INV_BACKGROUND = 1,
+ PEN_COLOR = 250
+};
+
+class ScalpelEngine : public SherlockEngine {
+private:
+ Darts *_darts;
+ int _mapResult;
+
+ bool show3DOSplash();
+
+ /**
+ * Show the starting city cutscene which shows the game title
+ */
+ bool showCityCutscene();
+ bool showCityCutscene3DO();
+
+ /**
+ * Show the back alley where the initial murder takes place
+ */
+ bool showAlleyCutscene();
+ bool showAlleyCutscene3DO();
+
+ /**
+ * Show the Baker Street outside cutscene
+ */
+ bool showStreetCutscene();
+ bool showStreetCutscene3DO();
+
+ /**
+ * Show Holmes and Watson at the breakfast table, lestrade's note, and then the scrolling credits
+ */
+ bool showOfficeCutscene();
+ bool showOfficeCutscene3DO();
+
+ /**
+ * Show the game credits
+ */
+ bool scrollCredits();
+
+ /**
+ * Load the default inventory for the game, which includes both the initial active inventory,
+ * as well as special pending inventory items which can appear automatically in the player's
+ * inventory once given required flags are set
+ */
+ void loadInventory();
+
+ /**
+ * Transition to show an image
+ */
+ void showLBV(const Common::String &filename);
+protected:
+ /**
+ * Game initialization
+ */
+ virtual void initialize();
+
+ /**
+ * Show the opening sequence
+ */
+ virtual void showOpening();
+
+ /**
+ * Starting a scene within the game
+ */
+ virtual void startScene();
+public:
+ ScalpelEngine(OSystem *syst, const SherlockGameDescription *gameDesc);
+ virtual ~ScalpelEngine();
+
+ /**
+ * Takes care of clearing the mirror in scene 12 (mansion drawing room), in case anything drew over it
+ */
+ void eraseMirror12();
+
+ /**
+ * Takes care of drawing Holme's reflection onto the mirror in scene 12 (mansion drawing room)
+ */
+ void doMirror12();
+
+ /**
+ * This clears the mirror in scene 12 (mansion drawing room) in case anything messed draw over it
+ */
+ void flushMirror12();
+};
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/scalpel/scalpel_debugger.cpp b/engines/sherlock/scalpel/scalpel_debugger.cpp
new file mode 100644
index 0000000000..7f5e1efa69
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_debugger.cpp
@@ -0,0 +1,91 @@
+/* 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 "sherlock/scalpel/scalpel_debugger.h"
+#include "sherlock/sherlock.h"
+#include "audio/mixer.h"
+#include "audio/decoders/3do.h"
+#include "audio/decoders/aiff.h"
+#include "audio/decoders/wave.h"
+
+namespace Sherlock {
+
+namespace Scalpel {
+
+ScalpelDebugger::ScalpelDebugger(SherlockEngine *vm) : Debugger(vm) {
+ registerCmd("3do_playmovie", WRAP_METHOD(ScalpelDebugger, cmd3DO_PlayMovie));
+ registerCmd("3do_playaudio", WRAP_METHOD(ScalpelDebugger, cmd3DO_PlayAudio));
+}
+
+bool ScalpelDebugger::cmd3DO_PlayMovie(int argc, const char **argv) {
+ if (argc != 2) {
+ debugPrintf("Format: 3do_playmovie <3do-movie-file>\n");
+ return true;
+ }
+
+ // play gets postboned until debugger is closed
+ Common::String filename = argv[1];
+ _3doPlayMovieFile = filename;
+
+ return cmdExit(0, 0);
+}
+
+bool ScalpelDebugger::cmd3DO_PlayAudio(int argc, const char **argv) {
+ if (argc != 2) {
+ debugPrintf("Format: 3do_playaudio <3do-audio-file>\n");
+ return true;
+ }
+
+ Common::File *file = new Common::File();
+ if (!file->open(argv[1])) {
+ debugPrintf("can not open specified audio file\n");
+ return true;
+ }
+
+ Audio::AudioStream *testStream;
+ Audio::SoundHandle testHandle;
+
+ // Try to load the given file as AIFF/AIFC
+ testStream = Audio::makeAIFFStream(file, DisposeAfterUse::YES);
+
+ if (testStream) {
+ g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &testHandle, testStream);
+ _vm->_events->clearEvents();
+
+ while ((!_vm->shouldQuit()) && g_system->getMixer()->isSoundHandleActive(testHandle)) {
+ _vm->_events->pollEvents();
+ g_system->delayMillis(10);
+ if (_vm->_events->kbHit()) {
+ break;
+ }
+ }
+
+ debugPrintf("playing completed\n");
+ g_system->getMixer()->stopHandle(testHandle);
+ }
+
+ return true;
+}
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/scalpel/scalpel_debugger.h b/engines/sherlock/scalpel/scalpel_debugger.h
new file mode 100644
index 0000000000..17a84779f0
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_debugger.h
@@ -0,0 +1,54 @@
+/* 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 SHERLOCK_SCALPEL_DEBUGGER_H
+#define SHERLOCK_SCALPEL_DEBUGGER_H
+
+#include "sherlock/debugger.h"
+
+namespace Sherlock {
+
+class SherlockEngine;
+
+namespace Scalpel {
+
+class ScalpelDebugger : public Debugger {
+private:
+ /**
+ * Plays a 3DO movie
+ */
+ bool cmd3DO_PlayMovie(int argc, const char **argv);
+
+ /**
+ * Plays a 3DO audio
+ */
+ bool cmd3DO_PlayAudio(int argc, const char **argv);
+public:
+ ScalpelDebugger(SherlockEngine *vm);
+ virtual ~ScalpelDebugger() {}
+};
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
+
+#endif /* SHERLOCK_DEBUGGER_H */
diff --git a/engines/sherlock/scalpel/scalpel_fixed_text.cpp b/engines/sherlock/scalpel/scalpel_fixed_text.cpp
new file mode 100644
index 0000000000..63f84d68c6
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_fixed_text.cpp
@@ -0,0 +1,377 @@
+/* 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 "sherlock/scalpel/scalpel_fixed_text.h"
+#include "sherlock/sherlock.h"
+
+namespace Sherlock {
+
+namespace Scalpel {
+
+static const char *const fixedTextEN[] = {
+ // SH1: Window buttons
+ "Exit",
+ "Up",
+ "Down",
+ // SH1: Inventory buttons
+ "Exit",
+ "Look",
+ "Use",
+ "Give",
+ // SH1: Journal text
+ "Watson's Journal",
+ "Page %d",
+ // SH1: Journal buttons
+ "Exit",
+ "Back 10",
+ "Up",
+ "Down",
+ "Ahead 10",
+ "Search",
+ "First Page",
+ "Last Page",
+ "Print Text",
+ // SH1: Journal search
+ "Exit",
+ "Backward",
+ "Forward",
+ "Text Not Found !",
+ // SH1: Initial Inventory
+ "A message requesting help",
+ "A number of business cards",
+ "Opera Tickets",
+ "Cuff Link",
+ "Wire Hook",
+ "Note",
+ "An open pocket watch",
+ "A piece of paper with numbers on it",
+ "A letter folded many times",
+ "Tarot Cards",
+ "An ornate key",
+ "A pawn ticket",
+ // SH2: Verbs
+ "Open",
+ "Look",
+ "Talk",
+ "Journal"
+};
+
+// sharp-s : 0xE1 / octal 341
+// small a-umlaut: 0x84 / octal 204
+// small o-umlaut: 0x94 / octal 224
+// small u-umlaut: 0x81 / octal 201
+static const char *const fixedTextDE[] = {
+ // SH1: Window buttons
+ "Zur\201ck",
+ "Hoch",
+ "Runter",
+ // SH1: Inventory buttons
+ "Zur\201ck",
+ "Schau",
+ "Benutze",
+ "Gib",
+ // SH1: Journal text
+ "Watsons Tagebuch",
+ "Seite %d",
+ // SH1: Journal buttons
+ "Zur\201ck",
+ "10 hoch",
+ "Hoch",
+ "Runter",
+ "10 runter",
+ "Suche",
+ "Erste Seite",
+ "Letzte Seite",
+ "Drucke Text",
+ // SH1: Journal search
+ "Zur\201ck",
+ "R\201ckw\204rts", // original: "Backward"
+ "Vorw\204rts", // original: "Forward"
+ "Text nicht gefunden!",
+ // SH1: Initial Inventory
+ "Ein Hilferuf von Lestrade",
+ "Holmes' Visitenkarten",
+ "Karten f\201rs Opernhaus",
+ "Manschettenkn\224pfe",
+ "Zum Haken verbogener Drahtkorb",
+ "Mitteilung am Epstein",
+ "Eine offene Taschenuhr",
+ "Ein Zettel mit Zahlen drauf",
+ "Ein mehrfach gefalteter Briefbogen",
+ "Ein Tarock-Kartenspiel", // [sic]
+ "Ein verzierter Schl\201ssel",
+ "Ein Pfandschein",
+ // SH2: Verbs
+ "\231ffne",
+ "Schau",
+ "Rede",
+ "Tagebuch"
+};
+
+// up-side down exclamation mark - 0xAD / octal 255
+// up-side down question mark - 0xA8 / octal 250
+// n with a wave on top - 0xA4 / octal 244
+static const char *const fixedTextES[] = {
+ // SH1: Window buttons
+ "Exit",
+ "Subir",
+ "Bajar",
+ // SH1: Inventory buttons
+ "Exit",
+ "Mirar",
+ "Usar",
+ "Dar",
+ // SH1: Journal text
+ "Diario de Watson",
+ "Pagina %d",
+ // SH1: Journal buttons
+ "Exit",
+ "Retroceder",
+ "Subir",
+ "baJar",
+ "Adelante",
+ "Buscar",
+ "1a pagina",
+ "Ult pagina",
+ "Imprimir",
+ // SH1: Journal search
+ "Exit",
+ "Retroceder",
+ "Avanzar",
+ "Texto no encontrado!",
+ // SH1: Initial Inventory
+ "Un mensaje solicitando ayuda",
+ "Unas cuantas tarjetas de visita",
+ "Entradas para la opera",
+ "Unos gemelos",
+ "Un gancho de alambre",
+ "Una nota",
+ "Un reloj de bolsillo abierto",
+ "Un trozo de papel con unos numeros",
+ "Un carta muy plegada",
+ "Unas cartas de Tarot",
+ "Una llave muy vistosa",
+ "Una papeleta de empe\244o",
+};
+
+// =========================================
+
+// === Sherlock Holmes 1: Serrated Scalpel ===
+static const char *const fixedTextEN_ActionOpen[] = {
+ "This cannot be opened",
+ "It is already open",
+ "It is locked",
+ "Wait for Watson",
+ " ",
+ "."
+};
+
+static const char *const fixedTextDE_ActionOpen[] = {
+ "Das kann man nicht \224ffnen",
+ "Ist doch schon offen!",
+ "Leider verschlossen",
+ "Warte auf Watson",
+ " ",
+ "."
+};
+
+static const char *const fixedTextES_ActionOpen[] = {
+ "No puede ser abierto",
+ "Ya esta abierto",
+ "Esta cerrado",
+ "Espera a Watson",
+ " ",
+ "."
+};
+
+static const char *const fixedTextEN_ActionClose[] = {
+ "This cannot be closed",
+ "It is already closed",
+ "The safe door is in the way"
+};
+
+static const char *const fixedTextDE_ActionClose[] = {
+ "Das kann man nicht schlie\341en",
+ "Ist doch schon zu!",
+ "Die safet\201r ist Weg"
+};
+
+static const char *const fixedTextES_ActionClose[] = {
+ "No puede ser cerrado",
+ "Ya esta cerrado",
+ "La puerta de seguridad esta entre medias"
+};
+
+static const char *const fixedTextEN_ActionMove[] = {
+ "This cannot be moved",
+ "It is bolted to the floor",
+ "It is too heavy",
+ "The other crate is in the way"
+};
+
+
+static const char *const fixedTextDE_ActionMove[] = {
+ "L\204\341t sich nicht bewegen",
+ "Festged\201belt in der Erde...",
+ "Oha, VIEL zu schwer",
+ "Der andere Kiste ist im Weg" // [sic]
+};
+
+static const char *const fixedTextES_ActionMove[] = {
+ "No puede moverse",
+ "Esta sujeto a la pared",
+ "Es demasiado pesado",
+ "El otro cajon esta en mitad"
+};
+
+static const char *const fixedTextEN_ActionPick[] = {
+ "Nothing of interest here",
+ "It is bolted down",
+ "It is too big to carry",
+ "It is too heavy",
+ "I think a girl would be more your type",
+ "Those flowers belong to Penny",
+ "She's far too young for you!",
+ "I think a girl would be more your type!",
+ "Government property for official use only"
+};
+
+static const char *const fixedTextDE_ActionPick[] = {
+ "Nichts Interessantes da",
+ "Zu gut befestigt",
+ "Ist ja wohl ein bi\341chen zu gro\341, oder ?",
+ "Oha, VIEL zu schwer",
+ "Ich denke, Du stehst mehr auf M\204dchen ?",
+ "Diese Blumen geh\224ren Penny",
+ "Sie ist doch viel zu jung f\201r Dich!",
+ "Ich denke, Du stehst mehr auf M\204dchen ?",
+ "Staatseigentum - Nur f\201r den Dienstgebrauch !"
+};
+
+static const char *const fixedTextES_ActionPick[] = {
+ "No hay nada interesante",
+ "Esta anclado al suelo",
+ "Es muy grande para llevarlo",
+ "Pesa demasiado",
+ "Creo que una chica sera mas tu tipo",
+ "Esas flores pertenecen a Penny",
+ "\255Es demasiado joven para ti!",
+ "\255Creo que una chica sera mas tu tipo!",
+ "Propiedad del gobierno para uso oficial"
+};
+
+static const char *const fixedTextEN_ActionUse[] = {
+ "You can't do that",
+ "It had no effect",
+ "You can't reach it",
+ "OK, the door looks bigger! Happy?",
+ "Doors don't smoke"
+};
+
+static const char *const fixedTextDE_ActionUse[] = {
+ "Nein, das geht wirklich nicht",
+ "Tja keinerlei Wirkung",
+ "Da kommst du nicht dran",
+ "Na gut, die T\201r sieht jetzt gr\224\341er aus. Zufrieden?",
+ "T\201ren sind Nichtraucher!"
+};
+
+static const char *const fixedTextES_ActionUse[] = {
+ "No puedes hacerlo",
+ "No tuvo ningun efecto",
+ "No puedes alcanzarlo",
+ "Bien, \255es enorme! \250Feliz?",
+ "Las puertas no fuman"
+};
+
+#define FIXEDTEXT_GETCOUNT(_name_) sizeof(_name_) / sizeof(byte *)
+#define FIXEDTEXT_ENTRY(_name_) _name_, FIXEDTEXT_GETCOUNT(_name_)
+
+static const FixedTextActionEntry fixedTextEN_Actions[] = {
+ { FIXEDTEXT_ENTRY(fixedTextEN_ActionOpen) },
+ { FIXEDTEXT_ENTRY(fixedTextEN_ActionClose) },
+ { FIXEDTEXT_ENTRY(fixedTextEN_ActionMove) },
+ { FIXEDTEXT_ENTRY(fixedTextEN_ActionPick) },
+ { FIXEDTEXT_ENTRY(fixedTextEN_ActionUse) }
+};
+
+static const FixedTextActionEntry fixedTextDE_Actions[] = {
+ { FIXEDTEXT_ENTRY(fixedTextDE_ActionOpen) },
+ { FIXEDTEXT_ENTRY(fixedTextDE_ActionClose) },
+ { FIXEDTEXT_ENTRY(fixedTextDE_ActionMove) },
+ { FIXEDTEXT_ENTRY(fixedTextDE_ActionPick) },
+ { FIXEDTEXT_ENTRY(fixedTextDE_ActionUse) }
+};
+
+static const FixedTextActionEntry fixedTextES_Actions[] = {
+ { FIXEDTEXT_ENTRY(fixedTextES_ActionOpen) },
+ { FIXEDTEXT_ENTRY(fixedTextES_ActionClose) },
+ { FIXEDTEXT_ENTRY(fixedTextES_ActionMove) },
+ { FIXEDTEXT_ENTRY(fixedTextES_ActionPick) },
+ { FIXEDTEXT_ENTRY(fixedTextES_ActionUse) }
+};
+
+// =========================================
+
+// TODO:
+// It seems there was a French version of Sherlock Holmes 2
+static const FixedTextLanguageEntry fixedTextLanguages[] = {
+ { Common::DE_DEU, fixedTextDE, fixedTextDE_Actions },
+ { Common::ES_ESP, fixedTextES, fixedTextES_Actions },
+ { Common::EN_ANY, fixedTextEN, fixedTextEN_Actions },
+ { Common::UNK_LANG, fixedTextEN, fixedTextEN_Actions }
+};
+
+// =========================================
+
+// =========================================
+
+ScalpelFixedText::ScalpelFixedText(SherlockEngine *vm) : FixedText(vm) {
+ // Figure out which fixed texts to use
+ Common::Language curLanguage = _vm->getLanguage();
+
+ const FixedTextLanguageEntry *curLanguageEntry = fixedTextLanguages;
+
+ while (curLanguageEntry->language != Common::UNK_LANG) {
+ if (curLanguageEntry->language == curLanguage)
+ break; // found current language
+ curLanguageEntry++;
+ }
+ _curLanguageEntry = curLanguageEntry;
+}
+
+const char *ScalpelFixedText::getText(int fixedTextId) {
+ return _curLanguageEntry->fixedTextArray[fixedTextId];
+}
+
+const Common::String ScalpelFixedText::getActionMessage(FixedTextActionId actionId, int messageIndex) {
+ assert(actionId >= 0);
+ assert(messageIndex >= 0);
+ const FixedTextActionEntry *curActionEntry = &_curLanguageEntry->actionArray[actionId];
+
+ assert(messageIndex < curActionEntry->fixedTextArrayCount);
+ return Common::String(curActionEntry->fixedTextArray[messageIndex]);
+}
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/scalpel/scalpel_fixed_text.h b/engines/sherlock/scalpel/scalpel_fixed_text.h
new file mode 100644
index 0000000000..eae86b8f27
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_fixed_text.h
@@ -0,0 +1,108 @@
+/* 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 SHERLOCK_SCALPEL_FIXED_TEXT_H
+#define SHERLOCK_SCALPEL_FIXED_TEXT_H
+
+#include "sherlock/fixed_text.h"
+
+namespace Sherlock {
+
+namespace Scalpel {
+
+enum FixedTextId {
+ // Window buttons
+ kFixedText_Window_Exit = 0,
+ kFixedText_Window_Up,
+ kFixedText_Window_Down,
+ // Inventory buttons
+ kFixedText_Inventory_Exit,
+ kFixedText_Inventory_Look,
+ kFixedText_Inventory_Use,
+ kFixedText_Inventory_Give,
+ // Journal text
+ kFixedText_Journal_WatsonsJournal,
+ kFixedText_Journal_Page,
+ // Journal buttons
+ kFixedText_Journal_Exit,
+ kFixedText_Journal_Back10,
+ kFixedText_Journal_Up,
+ kFixedText_Journal_Down,
+ kFixedText_Journal_Ahead10,
+ kFixedText_Journal_Search,
+ kFixedText_Journal_FirstPage,
+ kFixedText_Journal_LastPage,
+ kFixedText_Journal_PrintText,
+ // Journal search
+ kFixedText_JournalSearch_Exit,
+ kFixedText_JournalSearch_Backward,
+ kFixedText_JournalSearch_Forward,
+ kFixedText_JournalSearch_NotFound,
+ // Initial inventory
+ kFixedText_InitInventory_Message,
+ kFixedText_InitInventory_HolmesCard,
+ kFixedText_InitInventory_Tickets,
+ kFixedText_InitInventory_CuffLink,
+ kFixedText_InitInventory_WireHook,
+ kFixedText_InitInventory_Note,
+ kFixedText_InitInventory_OpenWatch,
+ kFixedText_InitInventory_Paper,
+ kFixedText_InitInventory_Letter,
+ kFixedText_InitInventory_Tarot,
+ kFixedText_InitInventory_OrnateKey,
+ kFixedText_InitInventory_PawnTicket
+};
+
+struct FixedTextActionEntry {
+ const char *const *fixedTextArray;
+ int fixedTextArrayCount;
+};
+
+struct FixedTextLanguageEntry {
+ Common::Language language;
+ const char *const *fixedTextArray;
+ const FixedTextActionEntry *actionArray;
+};
+
+class ScalpelFixedText: public FixedText {
+private:
+ const FixedTextLanguageEntry *_curLanguageEntry;
+public:
+ ScalpelFixedText(SherlockEngine *vm);
+ virtual ~ScalpelFixedText() {}
+
+ /**
+ * Gets text
+ */
+ virtual const char *getText(int fixedTextId);
+
+ /**
+ * Get action message
+ */
+ virtual const Common::String getActionMessage(FixedTextActionId actionId, int messageIndex);
+};
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/scalpel/scalpel_inventory.cpp b/engines/sherlock/scalpel/scalpel_inventory.cpp
new file mode 100644
index 0000000000..e19a43238c
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_inventory.cpp
@@ -0,0 +1,296 @@
+/* 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 "sherlock/scalpel/scalpel_inventory.h"
+#include "sherlock/scalpel/scalpel_fixed_text.h"
+#include "sherlock/scalpel/scalpel_screen.h"
+#include "sherlock/scalpel/scalpel_user_interface.h"
+#include "sherlock/scalpel/scalpel.h"
+
+namespace Sherlock {
+
+namespace Scalpel {
+
+ScalpelInventory::ScalpelInventory(SherlockEngine *vm) : Inventory(vm) {
+ _invShapes.resize(6);
+}
+
+ScalpelInventory::~ScalpelInventory() {
+}
+
+void ScalpelInventory::drawInventory(InvNewMode mode) {
+ FixedText &fixedText = *_vm->_fixedText;
+ ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+ UserInterface &ui = *_vm->_ui;
+ InvNewMode tempMode = mode;
+
+ loadInv();
+
+ if (mode == INVENTORY_DONT_DISPLAY) {
+ screen._backBuffer = &screen._backBuffer2;
+ }
+
+ // Draw the window background
+ Surface &bb = *screen._backBuffer;
+ bb.fillRect(Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y1 + 10), BORDER_COLOR);
+ bb.fillRect(Common::Rect(0, CONTROLS_Y1 + 10, 2, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR);
+ bb.fillRect(Common::Rect(SHERLOCK_SCREEN_WIDTH - 2, CONTROLS_Y1 + 10,
+ SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR);
+ bb.fillRect(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - 2, SHERLOCK_SCREEN_WIDTH,
+ SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR);
+ bb.fillRect(Common::Rect(2, CONTROLS_Y1 + 10, SHERLOCK_SCREEN_WIDTH - 2, SHERLOCK_SCREEN_HEIGHT - 2),
+ INV_BACKGROUND);
+
+ // Draw the buttons
+ Common::String fixedText_Exit = fixedText.getText(kFixedText_Inventory_Exit);
+ Common::String fixedText_Look = fixedText.getText(kFixedText_Inventory_Look);
+ Common::String fixedText_Use = fixedText.getText(kFixedText_Inventory_Use);
+ Common::String fixedText_Give = fixedText.getText(kFixedText_Inventory_Give);
+
+ screen.makeButton(Common::Rect(INVENTORY_POINTS[0][0], CONTROLS_Y1, INVENTORY_POINTS[0][1],
+ CONTROLS_Y1 + 10), INVENTORY_POINTS[0][2] - screen.stringWidth(fixedText_Exit) / 2, fixedText_Exit);
+ screen.makeButton(Common::Rect(INVENTORY_POINTS[1][0], CONTROLS_Y1, INVENTORY_POINTS[1][1],
+ CONTROLS_Y1 + 10), INVENTORY_POINTS[1][2] - screen.stringWidth(fixedText_Look) / 2, fixedText_Look);
+ screen.makeButton(Common::Rect(INVENTORY_POINTS[2][0], CONTROLS_Y1, INVENTORY_POINTS[2][1],
+ CONTROLS_Y1 + 10), INVENTORY_POINTS[2][2] - screen.stringWidth(fixedText_Use) / 2, fixedText_Use);
+ screen.makeButton(Common::Rect(INVENTORY_POINTS[3][0], CONTROLS_Y1, INVENTORY_POINTS[3][1],
+ CONTROLS_Y1 + 10), INVENTORY_POINTS[3][2] - screen.stringWidth(fixedText_Give) / 2, fixedText_Give);
+ screen.makeButton(Common::Rect(INVENTORY_POINTS[4][0], CONTROLS_Y1, INVENTORY_POINTS[4][1],
+ CONTROLS_Y1 + 10), INVENTORY_POINTS[4][2], "^^"); // 2 arrows pointing to the left
+ screen.makeButton(Common::Rect(INVENTORY_POINTS[5][0], CONTROLS_Y1, INVENTORY_POINTS[5][1],
+ CONTROLS_Y1 + 10), INVENTORY_POINTS[5][2], "^"); // 1 arrow pointing to the left
+ screen.makeButton(Common::Rect(INVENTORY_POINTS[6][0], CONTROLS_Y1, INVENTORY_POINTS[6][1],
+ CONTROLS_Y1 + 10), INVENTORY_POINTS[6][2], "_"); // 1 arrow pointing to the right
+ screen.makeButton(Common::Rect(INVENTORY_POINTS[7][0], CONTROLS_Y1, INVENTORY_POINTS[7][1],
+ CONTROLS_Y1 + 10), INVENTORY_POINTS[7][2], "__"); // 2 arrows pointing to the right
+
+ if (tempMode == INVENTORY_DONT_DISPLAY)
+ mode = LOOK_INVENTORY_MODE;
+ _invMode = (InvMode)((int)mode);
+
+ if (mode != PLAIN_INVENTORY) {
+ ui._oldKey = INVENTORY_COMMANDS[(int)mode];
+ } else {
+ ui._oldKey = -1;
+ }
+
+ invCommands(0);
+ putInv(SLAM_DONT_DISPLAY);
+
+ if (tempMode != INVENTORY_DONT_DISPLAY) {
+ if (!ui._slideWindows) {
+ screen.slamRect(Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
+ } else {
+ ui.summonWindow(false, CONTROLS_Y1);
+ }
+
+ ui._windowOpen = true;
+ } else {
+ // Reset the screen back buffer to the first buffer now that drawing is done
+ screen._backBuffer = &screen._backBuffer1;
+ }
+
+ assert(IS_SERRATED_SCALPEL);
+ ((ScalpelUserInterface *)_vm->_ui)->_oldUse = -1;
+}
+
+void ScalpelInventory::invCommands(bool slamIt) {
+ FixedText &fixedText = *_vm->_fixedText;
+ ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+ UserInterface &ui = *_vm->_ui;
+
+ Common::String fixedText_Exit = fixedText.getText(kFixedText_Inventory_Exit);
+ Common::String fixedText_Look = fixedText.getText(kFixedText_Inventory_Look);
+ Common::String fixedText_Use = fixedText.getText(kFixedText_Inventory_Use);
+ Common::String fixedText_Give = fixedText.getText(kFixedText_Inventory_Give);
+
+ if (slamIt) {
+ screen.buttonPrint(Common::Point(INVENTORY_POINTS[0][2], CONTROLS_Y1),
+ _invMode == INVMODE_EXIT ? COMMAND_HIGHLIGHTED :COMMAND_FOREGROUND,
+ true, fixedText_Exit);
+ screen.buttonPrint(Common::Point(INVENTORY_POINTS[1][2], CONTROLS_Y1),
+ _invMode == INVMODE_LOOK ? COMMAND_HIGHLIGHTED :COMMAND_FOREGROUND,
+ true, fixedText_Look);
+ screen.buttonPrint(Common::Point(INVENTORY_POINTS[2][2], CONTROLS_Y1),
+ _invMode == INVMODE_USE ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND,
+ true, fixedText_Use);
+ screen.buttonPrint(Common::Point(INVENTORY_POINTS[3][2], CONTROLS_Y1),
+ _invMode == INVMODE_GIVE ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND,
+ true, fixedText_Give);
+ screen.print(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1 + 1),
+ _invIndex == 0 ? COMMAND_NULL : COMMAND_FOREGROUND,
+ "^^"); // 2 arrows pointing to the left
+ screen.print(Common::Point(INVENTORY_POINTS[5][2], CONTROLS_Y1 + 1),
+ _invIndex == 0 ? COMMAND_NULL : COMMAND_FOREGROUND,
+ "^"); // 2 arrows pointing to the left
+ screen.print(Common::Point(INVENTORY_POINTS[6][2], CONTROLS_Y1 + 1),
+ (_holdings - _invIndex <= 6) ? COMMAND_NULL : COMMAND_FOREGROUND,
+ "_"); // 1 arrow pointing to the right
+ screen.print(Common::Point(INVENTORY_POINTS[7][2], CONTROLS_Y1 + 1),
+ (_holdings - _invIndex <= 6) ? COMMAND_NULL : COMMAND_FOREGROUND,
+ "__"); // 2 arrows pointing to the right
+ if (_invMode != INVMODE_LOOK)
+ ui.clearInfo();
+ } else {
+ screen.buttonPrint(Common::Point(INVENTORY_POINTS[0][2], CONTROLS_Y1),
+ _invMode == INVMODE_EXIT ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND,
+ false, fixedText_Exit);
+ screen.buttonPrint(Common::Point(INVENTORY_POINTS[1][2], CONTROLS_Y1),
+ _invMode == INVMODE_LOOK ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND,
+ false, fixedText_Look);
+ screen.buttonPrint(Common::Point(INVENTORY_POINTS[2][2], CONTROLS_Y1),
+ _invMode == INVMODE_USE ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND,
+ false, fixedText_Use);
+ screen.buttonPrint(Common::Point(INVENTORY_POINTS[3][2], CONTROLS_Y1),
+ _invMode == INVMODE_GIVE ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND,
+ false, fixedText_Give);
+ screen.gPrint(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1),
+ _invIndex == 0 ? COMMAND_NULL : COMMAND_FOREGROUND,
+ "^^"); // 2 arrows pointing to the left
+ screen.gPrint(Common::Point(INVENTORY_POINTS[5][2], CONTROLS_Y1),
+ _invIndex == 0 ? COMMAND_NULL : COMMAND_FOREGROUND,
+ "^"); // 1 arrow pointing to the left
+ screen.gPrint(Common::Point(INVENTORY_POINTS[6][2], CONTROLS_Y1),
+ (_holdings - _invIndex < 7) ? COMMAND_NULL : COMMAND_FOREGROUND,
+ "_"); // 1 arrow pointing to the right
+ screen.gPrint(Common::Point(INVENTORY_POINTS[7][2], CONTROLS_Y1),
+ (_holdings - _invIndex < 7) ? COMMAND_NULL : COMMAND_FOREGROUND,
+ "__"); // 2 arrows pointing to the right
+ }
+}
+
+void ScalpelInventory::highlight(int index, byte color) {
+ Screen &screen = *_vm->_screen;
+ Surface &bb = *screen._backBuffer;
+ int slot = index - _invIndex;
+ ImageFrame &frame = (*_invShapes[slot])[0];
+
+ bb.fillRect(Common::Rect(8 + slot * 52, 165, (slot + 1) * 52, 194), color);
+ bb.transBlitFrom(frame, Common::Point(6 + slot * 52 + ((47 - frame._width) / 2),
+ 163 + ((33 - frame._height) / 2)));
+ screen.slamArea(8 + slot * 52, 165, 44, 30);
+}
+
+void ScalpelInventory::refreshInv() {
+ Screen &screen = *_vm->_screen;
+ Talk &talk = *_vm->_talk;
+ ScalpelUserInterface &ui = *(ScalpelUserInterface *)_vm->_ui;
+
+ ui._invLookFlag = true;
+ freeInv();
+
+ ui._infoFlag = true;
+ ui.clearInfo();
+
+ screen._backBuffer2.blitFrom(screen._backBuffer1, Common::Point(0, CONTROLS_Y),
+ Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
+ ui.examine();
+
+ if (!talk._talkToAbort) {
+ screen._backBuffer2.blitFrom((*ui._controlPanel)[0], Common::Point(0, CONTROLS_Y));
+ loadInv();
+ }
+}
+
+void ScalpelInventory::putInv(InvSlamMode slamIt) {
+ ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+ UserInterface &ui = *_vm->_ui;
+
+ // If an inventory item has disappeared (due to using it or giving it),
+ // a blank space slot may have appeared. If so, adjust the inventory
+ if (_invIndex > 0 && _invIndex > (_holdings - (int)_invShapes.size())) {
+ --_invIndex;
+ freeGraphics();
+ loadGraphics();
+ }
+
+ if (slamIt != SLAM_SECONDARY_BUFFER) {
+ screen.makePanel(Common::Rect(6, 163, 54, 197));
+ screen.makePanel(Common::Rect(58, 163, 106, 197));
+ screen.makePanel(Common::Rect(110, 163, 158, 197));
+ screen.makePanel(Common::Rect(162, 163, 210, 197));
+ screen.makePanel(Common::Rect(214, 163, 262, 197));
+ screen.makePanel(Common::Rect(266, 163, 314, 197));
+ }
+
+ // Iterate through displaying up to 6 objects at a time
+ for (int idx = _invIndex; idx < _holdings && (idx - _invIndex) < (int)_invShapes.size(); ++idx) {
+ int itemNum = idx - _invIndex;
+ Surface &bb = slamIt == SLAM_SECONDARY_BUFFER ? screen._backBuffer2 : screen._backBuffer1;
+ Common::Rect r(8 + itemNum * 52, 165, 51 + itemNum * 52, 194);
+
+ // Draw the background
+ if (idx == ui._selector) {
+ bb.fillRect(r, BUTTON_BACKGROUND);
+ }
+ else if (slamIt == SLAM_SECONDARY_BUFFER) {
+ bb.fillRect(r, BUTTON_MIDDLE);
+ }
+
+ // Draw the item image
+ ImageFrame &frame = (*_invShapes[itemNum])[0];
+ bb.transBlitFrom(frame, Common::Point(6 + itemNum * 52 + ((47 - frame._width) / 2),
+ 163 + ((33 - frame._height) / 2)));
+ }
+
+ if (slamIt == SLAM_DISPLAY)
+ screen.slamArea(6, 163, 308, 34);
+
+ if (slamIt != SLAM_SECONDARY_BUFFER)
+ ui.clearInfo();
+
+ if (slamIt == 0) {
+ invCommands(0);
+ }
+ else if (slamIt == SLAM_SECONDARY_BUFFER) {
+ screen._backBuffer = &screen._backBuffer2;
+ invCommands(0);
+ screen._backBuffer = &screen._backBuffer1;
+ }
+}
+
+void ScalpelInventory::loadInv() {
+ // Exit if the inventory names are already loaded
+ if (_names.size() > 0)
+ return;
+
+ // Load the inventory names
+ Common::SeekableReadStream *stream = _vm->_res->load("invent.txt");
+
+ int streamSize = stream->size();
+ while (stream->pos() < streamSize) {
+ Common::String name;
+ char c;
+ while ((c = stream->readByte()) != 0)
+ name += c;
+
+ _names.push_back(name);
+ }
+
+ delete stream;
+
+ loadGraphics();
+}
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/scalpel/scalpel_inventory.h b/engines/sherlock/scalpel/scalpel_inventory.h
new file mode 100644
index 0000000000..afafb0b94a
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_inventory.h
@@ -0,0 +1,74 @@
+/* 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 SHERLOCK_SCALPEL_INVENTORY_H
+#define SHERLOCK_SCALPEL_INVENTORY_H
+
+#include "sherlock/inventory.h"
+
+namespace Sherlock {
+
+namespace Scalpel {
+
+class ScalpelInventory : public Inventory {
+public:
+ ScalpelInventory(SherlockEngine *vm);
+ ~ScalpelInventory();
+
+ /**
+ * Put the game into inventory mode and open the interface window.
+ */
+ void drawInventory(InvNewMode flag);
+
+ /**
+ * Prints the line of inventory commands at the top of an inventory window with
+ * the correct highlighting
+ */
+ void invCommands(bool slamIt);
+
+ /**
+ * Set the highlighting color of a given inventory item
+ */
+ void highlight(int index, byte color);
+
+ /**
+ * Support method for refreshing the display of the inventory
+ */
+ void refreshInv();
+
+ /**
+ * Display the character's inventory. The slamIt parameter specifies:
+ */
+ void putInv(InvSlamMode slamIt);
+
+ /**
+ * Load the list of names the inventory items correspond to, if not already loaded,
+ * and then calls loadGraphics to load the associated graphics
+ */
+ virtual void loadInv();
+};
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/scalpel/scalpel_journal.cpp b/engines/sherlock/scalpel/scalpel_journal.cpp
new file mode 100644
index 0000000000..8e356c0f65
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_journal.cpp
@@ -0,0 +1,667 @@
+/* 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 "sherlock/journal.h"
+#include "sherlock/sherlock.h"
+#include "sherlock/scalpel/scalpel_fixed_text.h"
+#include "sherlock/scalpel/scalpel_journal.h"
+#include "sherlock/scalpel/scalpel_screen.h"
+#include "sherlock/scalpel/scalpel.h"
+#include "sherlock/tattoo/tattoo_journal.h"
+
+namespace Sherlock {
+
+namespace Scalpel {
+
+#define JOURNAL_BUTTONS_Y 178
+#define JOURNAL_SEARCH_LEFT 15
+#define JOURNAL_SEARCH_TOP 186
+#define JOURNAL_SEARCH_RIGHT 296
+#define JOURNAL_SEACRH_MAX_CHARS 50
+
+// Positioning of buttons in the journal view
+static const int JOURNAL_POINTS[9][3] = {
+ { 6, 68, 37 },
+ { 69, 131, 100 },
+ { 132, 192, 162 },
+ { 193, 250, 221 },
+ { 251, 313, 281 },
+ { 6, 82, 44 },
+ { 83, 159, 121 },
+ { 160, 236, 198 },
+ { 237, 313, 275 }
+};
+
+static const int SEARCH_POINTS[3][3] = {
+ { 51, 123, 86 },
+ { 124, 196, 159 },
+ { 197, 269, 232 }
+};
+
+/*----------------------------------------------------------------*/
+
+ScalpelJournal::ScalpelJournal(SherlockEngine *vm) : Journal(vm) {
+ // Initialize fields
+ _maxPage = 0;
+ _index = 0;
+ _sub = 0;
+ _up = _down = false;
+ _page = 1;
+
+ if (_vm->_interactiveFl) {
+ // Load the journal directory and location names
+ loadLocations();
+ }
+}
+
+void ScalpelJournal::record(int converseNum, int statementNum, bool replyOnly) {
+ int saveIndex = _index;
+ int saveSub = _sub;
+
+ if (IS_3DO) {
+ // there seems to be no journal in the 3DO version
+ return;
+ }
+
+ // Record the entry into the list
+ _journal.push_back(JournalEntry(converseNum, statementNum, replyOnly));
+ _index = _journal.size() - 1;
+
+ // Load the text for the new entry to get the number of lines it will have
+ loadJournalFile(true);
+
+ // Restore old state
+ _index = saveIndex;
+ _sub = saveSub;
+
+ // If new lines were added to the ournal, update the total number of lines
+ // the journal continues
+ if (!_lines.empty()) {
+ _maxPage += _lines.size();
+ } else {
+ // No lines in entry, so remove the new entry from the journal
+ _journal.remove_at(_journal.size() - 1);
+ }
+}
+
+void ScalpelJournal::loadLocations() {
+ Resources &res = *_vm->_res;
+
+ _directory.clear();
+ _locations.clear();
+
+
+ Common::SeekableReadStream *dir = res.load("talk.lib");
+ dir->skip(4); // Skip header
+
+ // Get the numer of entries
+ _directory.resize(dir->readUint16LE());
+
+ // Read in each entry
+ char buffer[17];
+ for (uint idx = 0; idx < _directory.size(); ++idx) {
+ dir->read(buffer, 17);
+ buffer[16] = '\0';
+
+ _directory[idx] = Common::String(buffer);
+ }
+
+ delete dir;
+
+ if (IS_3DO) {
+ // 3DO: storage of locations is currently unknown TODO
+ return;
+ }
+
+ // Load in the locations stored in journal.txt
+ Common::SeekableReadStream *loc = res.load("journal.txt");
+
+ while (loc->pos() < loc->size()) {
+ Common::String line;
+ char c;
+ while ((c = loc->readByte()) != 0)
+ line += c;
+
+ _locations.push_back(line);
+ }
+
+ delete loc;
+}
+
+void ScalpelJournal::drawFrame() {
+ FixedText &fixedText = *_vm->_fixedText;
+ Resources &res = *_vm->_res;
+ ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+ byte palette[PALETTE_SIZE];
+
+ // Load in the journal background
+ Common::SeekableReadStream *bg = res.load("journal.lbv");
+ bg->read(screen._backBuffer1.getPixels(), SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCREEN_HEIGHT);
+ bg->read(palette, PALETTE_SIZE);
+ delete bg;
+
+ // Translate the palette for display
+ for (int idx = 0; idx < PALETTE_SIZE; ++idx)
+ palette[idx] = VGA_COLOR_TRANS(palette[idx]);
+
+ Common::String fixedText_WatsonsJournal = fixedText.getText(kFixedText_Journal_WatsonsJournal);
+ Common::String fixedText_Exit = fixedText.getText(kFixedText_Journal_Exit);
+ Common::String fixedText_Back10 = fixedText.getText(kFixedText_Journal_Back10);
+ Common::String fixedText_Up = fixedText.getText(kFixedText_Journal_Up);
+ Common::String fixedText_Down = fixedText.getText(kFixedText_Journal_Down);
+ Common::String fixedText_Ahead10 = fixedText.getText(kFixedText_Journal_Ahead10);
+ Common::String fixedText_Search = fixedText.getText(kFixedText_Journal_Search);
+ Common::String fixedText_FirstPage = fixedText.getText(kFixedText_Journal_FirstPage);
+ Common::String fixedText_LastPage = fixedText.getText(kFixedText_Journal_LastPage);
+ Common::String fixedText_PrintText = fixedText.getText(kFixedText_Journal_PrintText);
+
+ // Set the palette and print the title
+ screen.setPalette(palette);
+ screen.gPrint(Common::Point(111, 18), BUTTON_BOTTOM, "%s", fixedText_WatsonsJournal.c_str());
+ screen.gPrint(Common::Point(110, 17), INV_FOREGROUND, "%s", fixedText_WatsonsJournal.c_str());
+
+ // Draw the buttons
+ screen.makeButton(Common::Rect(JOURNAL_POINTS[0][0], JOURNAL_BUTTONS_Y,
+ JOURNAL_POINTS[0][1], JOURNAL_BUTTONS_Y + 10),
+ JOURNAL_POINTS[0][2] - screen.stringWidth(fixedText_Exit) / 2, fixedText_Exit);
+ screen.makeButton(Common::Rect(JOURNAL_POINTS[1][0], JOURNAL_BUTTONS_Y,
+ JOURNAL_POINTS[1][1], JOURNAL_BUTTONS_Y + 10),
+ JOURNAL_POINTS[1][2] - screen.stringWidth(fixedText_Back10) / 2, fixedText_Back10);
+ screen.makeButton(Common::Rect(JOURNAL_POINTS[2][0], JOURNAL_BUTTONS_Y,
+ JOURNAL_POINTS[2][1], JOURNAL_BUTTONS_Y + 10),
+ JOURNAL_POINTS[2][2] - screen.stringWidth(fixedText_Up) / 2, fixedText_Up);
+ screen.makeButton(Common::Rect(JOURNAL_POINTS[3][0], JOURNAL_BUTTONS_Y,
+ JOURNAL_POINTS[3][1], JOURNAL_BUTTONS_Y + 10),
+ JOURNAL_POINTS[3][2] - screen.stringWidth(fixedText_Down) / 2, fixedText_Down);
+ screen.makeButton(Common::Rect(JOURNAL_POINTS[4][0], JOURNAL_BUTTONS_Y,
+ JOURNAL_POINTS[4][1], JOURNAL_BUTTONS_Y + 10),
+ JOURNAL_POINTS[4][2] - screen.stringWidth(fixedText_Ahead10) / 2, fixedText_Ahead10);
+ screen.makeButton(Common::Rect(JOURNAL_POINTS[5][0], JOURNAL_BUTTONS_Y + 11,
+ JOURNAL_POINTS[5][1], JOURNAL_BUTTONS_Y + 21),
+ JOURNAL_POINTS[5][2] - screen.stringWidth(fixedText_Search) / 2, fixedText_Search);
+ screen.makeButton(Common::Rect(JOURNAL_POINTS[6][0], JOURNAL_BUTTONS_Y + 11,
+ JOURNAL_POINTS[6][1], JOURNAL_BUTTONS_Y + 21),
+ JOURNAL_POINTS[6][2] - screen.stringWidth(fixedText_FirstPage) / 2, fixedText_FirstPage);
+ screen.makeButton(Common::Rect(JOURNAL_POINTS[7][0], JOURNAL_BUTTONS_Y + 11,
+ JOURNAL_POINTS[7][1], JOURNAL_BUTTONS_Y + 21),
+ JOURNAL_POINTS[7][2] - screen.stringWidth(fixedText_LastPage) / 2, fixedText_LastPage);
+
+ // WORKAROUND: Draw Print Text button as disabled, since we don't support it in ScummVM
+ screen.makeButton(Common::Rect(JOURNAL_POINTS[8][0], JOURNAL_BUTTONS_Y + 11,
+ JOURNAL_POINTS[8][1], JOURNAL_BUTTONS_Y + 21),
+ JOURNAL_POINTS[8][2] - screen.stringWidth(fixedText_PrintText) / 2, fixedText_PrintText);
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[8][2], JOURNAL_BUTTONS_Y + 11),
+ COMMAND_NULL, false, fixedText_PrintText);
+}
+
+void ScalpelJournal::drawInterface() {
+ ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+
+ drawFrame();
+
+ if (_journal.empty()) {
+ _up = _down = 0;
+ } else {
+ drawJournal(0, 0);
+ }
+
+ doArrows();
+
+ // Show the entire screen
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+}
+
+void ScalpelJournal::doArrows() {
+ FixedText &fixedText = *_vm->_fixedText;
+ ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+ byte color;
+
+ Common::String fixedText_Back10 = fixedText.getText(kFixedText_Journal_Back10);
+ Common::String fixedText_Up = fixedText.getText(kFixedText_Journal_Up);
+ Common::String fixedText_Down = fixedText.getText(kFixedText_Journal_Down);
+ Common::String fixedText_Ahead10 = fixedText.getText(kFixedText_Journal_Ahead10);
+ Common::String fixedText_Search = fixedText.getText(kFixedText_Journal_Search);
+ Common::String fixedText_FirstPage = fixedText.getText(kFixedText_Journal_FirstPage);
+ Common::String fixedText_LastPage = fixedText.getText(kFixedText_Journal_LastPage);
+ Common::String fixedText_PrintText = fixedText.getText(kFixedText_Journal_PrintText);
+
+ color = (_page > 1) ? COMMAND_FOREGROUND : COMMAND_NULL;
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[1][2], JOURNAL_BUTTONS_Y), color, false, fixedText_Back10);
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[2][2], JOURNAL_BUTTONS_Y), color, false, fixedText_Up);
+
+ color = _down ? COMMAND_FOREGROUND : COMMAND_NULL;
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[3][2], JOURNAL_BUTTONS_Y), color, false, fixedText_Down);
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[4][2], JOURNAL_BUTTONS_Y), color, false, fixedText_Ahead10);
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[7][2], JOURNAL_BUTTONS_Y + 11), color, false, fixedText_LastPage);
+
+ color = _journal.size() > 0 ? COMMAND_FOREGROUND : COMMAND_NULL;
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[5][2], JOURNAL_BUTTONS_Y + 11), color, false, fixedText_Search);
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[8][2], JOURNAL_BUTTONS_Y + 11), COMMAND_NULL, false, fixedText_PrintText);
+
+ color = _page > 1 ? COMMAND_FOREGROUND : COMMAND_NULL;
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[6][2], JOURNAL_BUTTONS_Y + 11), color, false, fixedText_FirstPage);
+}
+
+JournalButton ScalpelJournal::getHighlightedButton(const Common::Point &pt) {
+ if (pt.x > JOURNAL_POINTS[0][0] && pt.x < JOURNAL_POINTS[0][1] && pt.y >= JOURNAL_BUTTONS_Y &&
+ pt.y < (JOURNAL_BUTTONS_Y + 10))
+ return BTN_EXIT;
+
+ if (pt.x > JOURNAL_POINTS[1][0] && pt.x < JOURNAL_POINTS[1][1] && pt.y >= JOURNAL_BUTTONS_Y &&
+ pt.y < (JOURNAL_BUTTONS_Y + 10) && _page > 1)
+ return BTN_BACK10;
+
+ if (pt.x > JOURNAL_POINTS[2][0] && pt.x < JOURNAL_POINTS[2][1] && pt.y >= JOURNAL_BUTTONS_Y &&
+ pt.y < (JOURNAL_BUTTONS_Y + 10) && _up)
+ return BTN_UP;
+
+ if (pt.x > JOURNAL_POINTS[3][0] && pt.x < JOURNAL_POINTS[3][1] && pt.y >= JOURNAL_BUTTONS_Y &&
+ pt.y < (JOURNAL_BUTTONS_Y + 10) && _down)
+ return BTN_DOWN;
+
+ if (pt.x > JOURNAL_POINTS[4][0] && pt.x < JOURNAL_POINTS[4][1] && pt.y >= JOURNAL_BUTTONS_Y &&
+ pt.y < (JOURNAL_BUTTONS_Y + 10) && _down)
+ return BTN_AHEAD110;
+
+ if (pt.x > JOURNAL_POINTS[5][0] && pt.x < JOURNAL_POINTS[5][1] && pt.y >= (JOURNAL_BUTTONS_Y + 11) &&
+ pt.y < (JOURNAL_BUTTONS_Y + 20) && !_journal.empty())
+ return BTN_SEARCH;
+
+ if (pt.x > JOURNAL_POINTS[6][0] && pt.x < JOURNAL_POINTS[6][1] && pt.y >= (JOURNAL_BUTTONS_Y + 11) &&
+ pt.y < (JOURNAL_BUTTONS_Y + 20) && _up)
+ return BTN_FIRST_PAGE;
+
+ if (pt.x > JOURNAL_POINTS[7][0] && pt.x < JOURNAL_POINTS[7][1] && pt.y >= (JOURNAL_BUTTONS_Y + 11) &&
+ pt.y < (JOURNAL_BUTTONS_Y + 20) && _down)
+ return BTN_LAST_PAGE;
+
+ if (pt.x > JOURNAL_POINTS[8][0] && pt.x < JOURNAL_POINTS[8][1] && pt.y >= (JOURNAL_BUTTONS_Y + 11) &&
+ pt.y < (JOURNAL_BUTTONS_Y + 20) && !_journal.empty())
+ return BTN_PRINT_TEXT;
+
+ return BTN_NONE;
+}
+
+bool ScalpelJournal::handleEvents(int key) {
+ Events &events = *_vm->_events;
+ FixedText &fixedText = *_vm->_fixedText;
+ ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+ bool doneFlag = false;
+
+ Common::Point pt = events.mousePos();
+ JournalButton btn = getHighlightedButton(pt);
+ byte color;
+
+ if (events._pressed || events._released) {
+ Common::String fixedText_Exit = fixedText.getText(kFixedText_Journal_Exit);
+ Common::String fixedText_Back10 = fixedText.getText(kFixedText_Journal_Back10);
+ Common::String fixedText_Up = fixedText.getText(kFixedText_Journal_Up);
+ Common::String fixedText_Down = fixedText.getText(kFixedText_Journal_Down);
+ Common::String fixedText_Ahead10 = fixedText.getText(kFixedText_Journal_Ahead10);
+ Common::String fixedText_Search = fixedText.getText(kFixedText_Journal_Search);
+ Common::String fixedText_FirstPage = fixedText.getText(kFixedText_Journal_FirstPage);
+ Common::String fixedText_LastPage = fixedText.getText(kFixedText_Journal_LastPage);
+ Common::String fixedText_PrintText = fixedText.getText(kFixedText_Journal_PrintText);
+
+ // Exit button
+ color = (btn == BTN_EXIT) ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND;
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[0][2], JOURNAL_BUTTONS_Y), color, true, fixedText_Exit);
+
+ // Back 10 button
+ if (btn == BTN_BACK10) {
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[1][2], JOURNAL_BUTTONS_Y), COMMAND_HIGHLIGHTED, true, fixedText_Back10);
+ } else if (_page > 1) {
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[1][2], JOURNAL_BUTTONS_Y), COMMAND_FOREGROUND, true, fixedText_Back10);
+ }
+
+ // Up button
+ if (btn == BTN_UP) {
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[2][2], JOURNAL_BUTTONS_Y), COMMAND_HIGHLIGHTED, true, fixedText_Up);
+ } else if (_up) {
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[2][2], JOURNAL_BUTTONS_Y), COMMAND_FOREGROUND, true, fixedText_Up);
+ }
+
+ // Down button
+ if (btn == BTN_DOWN) {
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[3][2], JOURNAL_BUTTONS_Y), COMMAND_HIGHLIGHTED, true, fixedText_Down);
+ } else if (_down) {
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[3][2], JOURNAL_BUTTONS_Y), COMMAND_FOREGROUND, true, fixedText_Down);
+ }
+
+ // Ahead 10 button
+ if (btn == BTN_AHEAD110) {
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[4][2], JOURNAL_BUTTONS_Y), COMMAND_HIGHLIGHTED, true, fixedText_Ahead10);
+ } else if (_down) {
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[4][2], JOURNAL_BUTTONS_Y), COMMAND_FOREGROUND, true, fixedText_Ahead10);
+ }
+
+ // Search button
+ if (btn == BTN_SEARCH) {
+ color = COMMAND_HIGHLIGHTED;
+ } else if (_journal.empty()) {
+ color = COMMAND_NULL;
+ } else {
+ color = COMMAND_FOREGROUND;
+ }
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[5][2], JOURNAL_BUTTONS_Y + 11), color, true, fixedText_Search);
+
+ // First Page button
+ if (btn == BTN_FIRST_PAGE) {
+ color = COMMAND_HIGHLIGHTED;
+ } else if (_up) {
+ color = COMMAND_FOREGROUND;
+ } else {
+ color = COMMAND_NULL;
+ }
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[6][2], JOURNAL_BUTTONS_Y + 11), color, true, fixedText_FirstPage);
+
+ // Last Page button
+ if (btn == BTN_LAST_PAGE) {
+ color = COMMAND_HIGHLIGHTED;
+ } else if (_down) {
+ color = COMMAND_FOREGROUND;
+ } else {
+ color = COMMAND_NULL;
+ }
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[7][2], JOURNAL_BUTTONS_Y + 11), color, true, fixedText_LastPage);
+
+ // Print Text button
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[8][2], JOURNAL_BUTTONS_Y + 11), COMMAND_NULL, true, fixedText_PrintText);
+ }
+
+ if (btn == BTN_EXIT && events._released) {
+ // Exit button pressed
+ doneFlag = true;
+
+ } else if (((btn == BTN_BACK10 && events._released) || key == 'B') && (_page > 1)) {
+ // Scrolll up 10 pages
+ if (_page < 11)
+ drawJournal(1, (_page - 1) * LINES_PER_PAGE);
+ else
+ drawJournal(1, 10 * LINES_PER_PAGE);
+
+ doArrows();
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+
+ } else if (((btn == BTN_UP && events._released) || key == 'U') && _up) {
+ // Scroll up
+ drawJournal(1, LINES_PER_PAGE);
+ doArrows();
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+
+ } else if (((btn == BTN_DOWN && events._released) || key == 'D') && _down) {
+ // Scroll down
+ drawJournal(2, LINES_PER_PAGE);
+ doArrows();
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+
+ } else if (((btn == BTN_AHEAD110 && events._released) || key == 'A') && _down) {
+ // Scroll down 10 pages
+ if ((_page + 10) > _maxPage)
+ drawJournal(2, (_maxPage - _page) * LINES_PER_PAGE);
+ else
+ drawJournal(2, 10 * LINES_PER_PAGE);
+
+ doArrows();
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+
+ } else if (((btn == BTN_SEARCH && events._released) || key == 'S') && !_journal.empty()) {
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[5][2], JOURNAL_BUTTONS_Y + 11), COMMAND_FOREGROUND, true, "Search");
+ bool notFound = false;
+
+ do {
+ int dir;
+ if ((dir = getSearchString(notFound)) != 0) {
+ int savedIndex = _index;
+ int savedSub = _sub;
+ int savedPage = _page;
+
+ if (drawJournal(dir + 2, 1000 * LINES_PER_PAGE) == 0) {
+ _index = savedIndex;
+ _sub = savedSub;
+ _page = savedPage;
+
+ drawFrame();
+ drawJournal(0, 0);
+ notFound = true;
+ } else {
+ doneFlag = true;
+ }
+
+ doArrows();
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+ } else {
+ doneFlag = true;
+ }
+ } while (!doneFlag);
+ doneFlag = false;
+
+ } else if (((btn == BTN_FIRST_PAGE && events._released) || key == 'F') && _up) {
+ // First page
+ _index = _sub = 0;
+ _up = _down = false;
+ _page = 1;
+
+ drawFrame();
+ drawJournal(0, 0);
+ doArrows();
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+
+ } else if (((btn == BTN_LAST_PAGE && events._released) || key == 'L') && _down) {
+ // Last page
+ if ((_page + 10) > _maxPage)
+ drawJournal(2, (_maxPage - _page) * LINES_PER_PAGE);
+ else
+ drawJournal(2, 1000 * LINES_PER_PAGE);
+
+ doArrows();
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+ }
+
+ events.wait(2);
+
+ return doneFlag;
+}
+
+int ScalpelJournal::getSearchString(bool printError) {
+ enum Button { BTN_NONE, BTN_EXIT, BTN_BACKWARD, BTN_FORWARD };
+
+ Events &events = *_vm->_events;
+ FixedText &fixedText = *_vm->_fixedText;
+ ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+ Talk &talk = *_vm->_talk;
+ int xp;
+ int yp = 174;
+ bool flag = false;
+ Common::String name;
+ int done = 0;
+ byte color;
+
+ Common::String fixedText_Exit = fixedText.getText(kFixedText_JournalSearch_Exit);
+ Common::String fixedText_Backward = fixedText.getText(kFixedText_JournalSearch_Backward);
+ Common::String fixedText_Forward = fixedText.getText(kFixedText_JournalSearch_Forward);
+ Common::String fixedText_NotFound = fixedText.getText(kFixedText_JournalSearch_NotFound);
+
+ // Draw search panel
+ screen.makePanel(Common::Rect(6, 171, 313, 199));
+ screen.makeButton(Common::Rect(SEARCH_POINTS[0][0], yp, SEARCH_POINTS[0][1], yp + 10),
+ SEARCH_POINTS[0][2] - screen.stringWidth(fixedText_Exit) / 2, fixedText_Exit);
+ screen.makeButton(Common::Rect(SEARCH_POINTS[1][0], yp, SEARCH_POINTS[1][1], yp + 10),
+ SEARCH_POINTS[1][2] - screen.stringWidth(fixedText_Backward) / 2, fixedText_Backward);
+ screen.makeButton(Common::Rect(SEARCH_POINTS[2][0], yp, SEARCH_POINTS[2][1], yp + 10),
+ SEARCH_POINTS[2][2] - screen.stringWidth(fixedText_Forward) / 2, fixedText_Forward);
+
+ screen.gPrint(Common::Point(SEARCH_POINTS[0][2] - screen.stringWidth(fixedText_Exit) / 2, yp),
+ COMMAND_HIGHLIGHTED, "%c", fixedText_Exit[0]);
+ screen.gPrint(Common::Point(SEARCH_POINTS[1][2] - screen.stringWidth(fixedText_Backward) / 2, yp),
+ COMMAND_HIGHLIGHTED, "%c", fixedText_Backward[0]);
+ screen.gPrint(Common::Point(SEARCH_POINTS[2][2] - screen.stringWidth(fixedText_Forward) / 2, yp),
+ COMMAND_HIGHLIGHTED, "%c", fixedText_Forward[0]);
+
+ screen.makeField(Common::Rect(12, 185, 307, 196));
+
+ screen.fillRect(Common::Rect(12, 185, 307, 186), BUTTON_BOTTOM);
+ screen.vLine(12, 185, 195, BUTTON_BOTTOM);
+ screen.hLine(13, 195, 306, BUTTON_TOP);
+ screen.hLine(306, 186, 195, BUTTON_TOP);
+
+ if (printError) {
+ screen.gPrint(Common::Point((SHERLOCK_SCREEN_WIDTH - screen.stringWidth(fixedText_NotFound)) / 2, 185),
+ INV_FOREGROUND, "%s", fixedText_NotFound.c_str());
+ } else if (!_find.empty()) {
+ // There's already a search term, display it already
+ screen.gPrint(Common::Point(15, 185), TALK_FOREGROUND, "%s", _find.c_str());
+ name = _find;
+ }
+
+ screen.slamArea(6, 171, 307, 28);
+
+ if (printError) {
+ // Give time for user to see the message
+ events.setButtonState();
+ for (int idx = 0; idx < 40 && !_vm->shouldQuit() && !events.kbHit() && !events._released; ++idx) {
+ events.pollEvents();
+ events.setButtonState();
+ events.wait(2);
+ }
+
+ events.clearKeyboard();
+ screen._backBuffer1.fillRect(Common::Rect(13, 186, 306, 195), BUTTON_MIDDLE);
+
+ if (!_find.empty()) {
+ screen.gPrint(Common::Point(15, 185), TALK_FOREGROUND, "%s", _find.c_str());
+ name = _find;
+ }
+
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+ }
+
+ xp = JOURNAL_SEARCH_LEFT + screen.stringWidth(name);
+ yp = JOURNAL_SEARCH_TOP;
+
+ do {
+ events._released = false;
+ Button found = BTN_NONE;
+
+ while (!_vm->shouldQuit() && !events.kbHit() && !events._released) {
+ found = BTN_NONE;
+ if (talk._talkToAbort)
+ return 0;
+
+ // Check if key or mouse button press has occurred
+ events.setButtonState();
+ Common::Point pt = events.mousePos();
+
+ flag = !flag;
+ screen.vgaBar(Common::Rect(xp, yp, xp + 8, yp + 9), flag ? INV_FOREGROUND : BUTTON_MIDDLE);
+
+ if (events._pressed || events._released) {
+ if (pt.x > SEARCH_POINTS[0][0] && pt.x < SEARCH_POINTS[0][1] && pt.y > 174 && pt.y < 183) {
+ found = BTN_EXIT;
+ color = COMMAND_HIGHLIGHTED;
+ } else {
+ color = COMMAND_FOREGROUND;
+ }
+ screen.print(Common::Point(SEARCH_POINTS[0][2] - screen.stringWidth(fixedText_Exit) / 2, 175), color, "%s", fixedText_Exit.c_str());
+
+ if (pt.x > SEARCH_POINTS[1][0] && pt.x < SEARCH_POINTS[1][1] && pt.y > 174 && pt.y < 183) {
+ found = BTN_BACKWARD;
+ color = COMMAND_HIGHLIGHTED;
+ } else {
+ color = COMMAND_FOREGROUND;
+ }
+ screen.print(Common::Point(SEARCH_POINTS[1][2] - screen.stringWidth(fixedText_Backward) / 2, 175), color, "%s", fixedText_Backward.c_str());
+
+ if (pt.x > SEARCH_POINTS[2][0] && pt.x < SEARCH_POINTS[2][1] && pt.y > 174 && pt.y < 183) {
+ found = BTN_FORWARD;
+ color = COMMAND_HIGHLIGHTED;
+ } else {
+ color = COMMAND_FOREGROUND;
+ }
+ screen.print(Common::Point(SEARCH_POINTS[2][2] - screen.stringWidth(fixedText_Forward) / 2, 175), color, "%s", fixedText_Forward.c_str());
+ }
+
+ events.wait(2);
+ }
+
+ if (events.kbHit()) {
+ Common::KeyState keyState = events.getKey();
+
+ if ((keyState.keycode == Common::KEYCODE_BACKSPACE) && (name.size() > 0)) {
+ screen.vgaBar(Common::Rect(xp - screen.charWidth(name.lastChar()), yp, xp + 8, yp + 9), BUTTON_MIDDLE);
+ xp -= screen.charWidth(name.lastChar());
+ screen.vgaBar(Common::Rect(xp, yp, xp + 8, yp + 9), INV_FOREGROUND);
+ name.deleteLastChar();
+
+ } else if (keyState.keycode == Common::KEYCODE_RETURN) {
+ done = 1;
+
+ } else if (keyState.keycode == Common::KEYCODE_ESCAPE) {
+ screen.vgaBar(Common::Rect(xp, yp, xp + 8, yp + 9), BUTTON_MIDDLE);
+ done = -1;
+
+ } else if (keyState.ascii >= ' ' && keyState.ascii <= 'z' && keyState.keycode != Common::KEYCODE_AT &&
+ name.size() < JOURNAL_SEACRH_MAX_CHARS && (xp + screen.charWidth(keyState.ascii)) < JOURNAL_SEARCH_RIGHT) {
+ char ch = toupper(keyState.ascii);
+ screen.vgaBar(Common::Rect(xp, yp, xp + 8, yp + 9), BUTTON_MIDDLE);
+ screen.print(Common::Point(xp, yp), TALK_FOREGROUND, "%c", ch);
+ xp += screen.charWidth(ch);
+ name += ch;
+ }
+ }
+
+ if (events._released) {
+ switch (found) {
+ case BTN_EXIT:
+ done = -1; break;
+ case BTN_BACKWARD:
+ done = 2; break;
+ case BTN_FORWARD:
+ done = 1; break;
+ default:
+ break;
+ }
+ }
+ } while (!done && !_vm->shouldQuit());
+
+ if (done != -1) {
+ _find = name;
+ } else {
+ done = 0;
+ }
+
+ // Redisplay the journal screen
+ drawFrame();
+ drawJournal(0, 0);
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+
+ return done;
+}
+
+void ScalpelJournal::resetPosition() {
+ _index = _sub = _up = _down = 0;
+ _page = 1;
+}
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/scalpel/scalpel_journal.h b/engines/sherlock/scalpel/scalpel_journal.h
new file mode 100644
index 0000000000..6bc0aa012c
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_journal.h
@@ -0,0 +1,102 @@
+/* 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 SHERLOCK_SCALPEL_JOURNAL_H
+#define SHERLOCK_SCALPEL_JOURNAL_H
+
+#include "sherlock/journal.h"
+#include "sherlock/saveload.h"
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/rect.h"
+#include "common/str-array.h"
+#include "common/stream.h"
+
+namespace Sherlock {
+
+namespace Scalpel {
+
+#define JOURNAL_MAX_WIDTH 230
+#define JOURNAL_MAX_CHARS 80
+
+enum JournalButton {
+ BTN_NONE, BTN_EXIT, BTN_BACK10, BTN_UP, BTN_DOWN, BTN_AHEAD110, BTN_SEARCH,
+ BTN_FIRST_PAGE, BTN_LAST_PAGE, BTN_PRINT_TEXT
+};
+
+class ScalpelJournal: public Journal {
+private:
+ /**
+ * Load the list of journal locations
+ */
+ void loadLocations();
+
+ /**
+ * Display the arrows that can be used to scroll up and down pages
+ */
+ void doArrows();
+
+ /**
+ * Show the search submenu and allow the player to enter a search string
+ */
+ int getSearchString(bool printError);
+
+ /**
+ * Returns the button, if any, that is under the specified position
+ */
+ JournalButton getHighlightedButton(const Common::Point &pt);
+public:
+ ScalpelJournal(SherlockEngine *vm);
+ virtual ~ScalpelJournal() {}
+
+ /**
+ * Display the journal
+ */
+ void drawInterface();
+
+ /**
+ * Handle events whilst the journal is being displayed
+ */
+ bool handleEvents(int key);
+public:
+ /**
+ * Draw the journal background, frame, and interface buttons
+ */
+ virtual void drawFrame();
+
+ /**
+ * Records statements that are said, in the order which they are said. The player
+ * can then read the journal to review them
+ */
+ virtual void record(int converseNum, int statementNum, bool replyOnly = false);
+
+ /**
+ * Reset viewing position to the start of the journal
+ */
+ virtual void resetPosition();
+};
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/scalpel/scalpel_map.cpp b/engines/sherlock/scalpel/scalpel_map.cpp
new file mode 100644
index 0000000000..369822ba02
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_map.cpp
@@ -0,0 +1,596 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/system.h"
+#include "sherlock/scalpel/scalpel_map.h"
+#include "sherlock/events.h"
+#include "sherlock/people.h"
+#include "sherlock/screen.h"
+#include "sherlock/sherlock.h"
+
+namespace Sherlock {
+
+namespace Scalpel {
+
+MapPaths::MapPaths() {
+ _numLocations = 0;
+}
+
+void MapPaths::load(int numLocations, Common::SeekableReadStream &s) {
+ _numLocations = numLocations;
+ _paths.resize(_numLocations * _numLocations);
+
+ for (int idx = 0; idx < (numLocations * numLocations); ++idx) {
+ Common::Array<byte> &path = _paths[idx];
+ int v;
+
+ do {
+ v = s.readByte();
+ path.push_back(v);
+ } while (v && v < 254);
+ }
+}
+
+const byte *MapPaths::getPath(int srcLocation, int destLocation) {
+ return &_paths[srcLocation * _numLocations + destLocation][0];
+}
+
+/*----------------------------------------------------------------*/
+
+ScalpelMap::ScalpelMap(SherlockEngine *vm): Map(vm), _topLine(g_system->getWidth(), 12) {
+ _mapCursors = nullptr;
+ _shapes = nullptr;
+ _iconShapes = nullptr;
+ _point = 0;
+ _placesShown = false;
+ _cursorIndex = -1;
+ _drawMap = false;
+ _overPos = Point32(130 * FIXED_INT_MULTIPLIER, 126 * FIXED_INT_MULTIPLIER);
+ _frameChangeFlag = false;
+
+ // Initialise the initial walk sequence set
+ _walkSequences.resize(MAX_HOLMES_SEQUENCE);
+ for (int idx = 0; idx < MAX_HOLMES_SEQUENCE; ++idx) {
+ _walkSequences[idx]._sequences.resize(MAX_FRAME);
+ Common::fill(&_walkSequences[idx]._sequences[0], &_walkSequences[idx]._sequences[0] + MAX_FRAME, 0);
+ }
+
+ if (!_vm->isDemo())
+ loadData();
+}
+
+void ScalpelMap::loadPoints(int count, const int *xList, const int *yList, const int *transList) {
+ for (int idx = 0; idx < count; ++idx, ++xList, ++yList, ++transList) {
+ _points.push_back(MapEntry(*xList, *yList, *transList));
+ }
+}
+
+void ScalpelMap::loadSequences(int count, const byte *seq) {
+ for (int idx = 0; idx < count; ++idx, seq += MAX_FRAME)
+ Common::copy(seq, seq + MAX_FRAME, &_walkSequences[idx]._sequences[0]);
+}
+
+void ScalpelMap::loadData() {
+ // Load the list of location names
+ Common::SeekableReadStream *txtStream = _vm->_res->load("chess.txt");
+
+ int streamSize = txtStream->size();
+ while (txtStream->pos() < streamSize) {
+ Common::String line;
+ char c;
+ while ((c = txtStream->readByte()) != '\0')
+ line += c;
+
+ _locationNames.push_back(line);
+ }
+
+ delete txtStream;
+
+ // Load the path data
+ Common::SeekableReadStream *pathStream = _vm->_res->load("chess.pth");
+
+ // Get routes between different locations on the map
+ _paths.load(31, *pathStream);
+
+ // Load in the co-ordinates that the paths refer to
+ _pathPoints.resize(208);
+ for (uint idx = 0; idx < _pathPoints.size(); ++idx) {
+ _pathPoints[idx].x = pathStream->readSint16LE();
+ _pathPoints[idx].y = pathStream->readSint16LE();
+ }
+
+ delete pathStream;
+}
+
+int ScalpelMap::show() {
+ Debugger &debugger = *_vm->_debugger;
+ Events &events = *_vm->_events;
+ People &people = *_vm->_people;
+ Screen &screen = *_vm->_screen;
+ bool changed = false, exitFlag = false;
+ _active = true;
+
+ // Set font and custom cursor for the map
+ int oldFont = screen.fontNumber();
+ screen.setFont(0);
+
+ // Initial screen clear
+ screen._backBuffer1.clear();
+ screen.clear();
+
+ // Load the entire map
+ ImageFile *bigMap = NULL;
+ if (!IS_3DO) {
+ // PC
+ bigMap = new ImageFile("bigmap.vgs");
+ screen.setPalette(bigMap->_palette);
+ } else {
+ // 3DO
+ bigMap = new ImageFile3DO("overland.cel", kImageFile3DOType_Cel);
+ }
+
+ // Load need sprites
+ setupSprites();
+
+ if (!IS_3DO) {
+ screen._backBuffer1.blitFrom((*bigMap)[0], Common::Point(-_bigPos.x, -_bigPos.y));
+ screen._backBuffer1.blitFrom((*bigMap)[1], Common::Point(-_bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y));
+ screen._backBuffer1.blitFrom((*bigMap)[2], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, -_bigPos.y));
+ screen._backBuffer1.blitFrom((*bigMap)[3], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y));
+ } else {
+ screen._backBuffer1.blitFrom((*bigMap)[0], Common::Point(-_bigPos.x, -_bigPos.y));
+ screen.blitFrom((*bigMap)[0], Common::Point(-_bigPos.x, -_bigPos.y));
+ }
+
+ _drawMap = true;
+ _charPoint = -1;
+ _point = -1;
+ people[HOLMES]._position = _lDrawnPos = _overPos;
+
+ // Show place icons
+ showPlaces();
+ saveTopLine();
+ _placesShown = true;
+
+ // Keep looping until either a location is picked, or the game is ended
+ while (!_vm->shouldQuit() && !exitFlag) {
+ events.pollEventsAndWait();
+ events.setButtonState();
+
+ if (debugger._showAllLocations == LOC_REFRESH) {
+ showPlaces();
+ screen.slamArea(screen._currentScroll.x, screen._currentScroll.y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_WIDTH);
+ }
+
+ // Keyboard handling
+ if (events.kbHit()) {
+ Common::KeyState keyState = events.getKey();
+
+ if (keyState.keycode == Common::KEYCODE_RETURN || keyState.keycode == Common::KEYCODE_SPACE) {
+ // Both space and enter simulate a mouse release
+ events._pressed = false;
+ events._released = true;
+ events._oldButtons = 0;
+ }
+ }
+
+ // Ignore scrolling attempts until the screen is drawn
+ if (!_drawMap) {
+ Common::Point pt = events.mousePos();
+
+ // Check for vertical map scrolling
+ if ((pt.y > (SHERLOCK_SCREEN_HEIGHT - 10) && _bigPos.y < 200) || (pt.y < 10 && _bigPos.y > 0)) {
+ if (pt.y > (SHERLOCK_SCREEN_HEIGHT - 10))
+ _bigPos.y += 10;
+ else
+ _bigPos.y -= 10;
+
+ changed = true;
+ }
+
+ // Check for horizontal map scrolling
+ if ((pt.x > (SHERLOCK_SCREEN_WIDTH - 10) && _bigPos.x < 315) || (pt.x < 10 && _bigPos.x > 0)) {
+ if (pt.x > (SHERLOCK_SCREEN_WIDTH - 10))
+ _bigPos.x += 15;
+ else
+ _bigPos.x -= 15;
+
+ changed = true;
+ }
+ }
+
+ if (changed) {
+ // Map has scrolled, so redraw new map view
+ changed = false;
+
+ if (!IS_3DO) {
+ screen._backBuffer1.blitFrom((*bigMap)[0], Common::Point(-_bigPos.x, -_bigPos.y));
+ screen._backBuffer1.blitFrom((*bigMap)[1], Common::Point(-_bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y));
+ screen._backBuffer1.blitFrom((*bigMap)[2], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, -_bigPos.y));
+ screen._backBuffer1.blitFrom((*bigMap)[3], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y));
+ } else {
+ screen._backBuffer1.blitFrom((*bigMap)[0], Common::Point(-_bigPos.x, -_bigPos.y));
+ }
+
+ showPlaces();
+ _placesShown = false;
+
+ saveTopLine();
+ _savedPos.x = -1;
+ updateMap(true);
+ } else if (!_drawMap) {
+ if (!_placesShown) {
+ showPlaces();
+ _placesShown = true;
+ }
+
+ if (_cursorIndex == 0) {
+ Common::Point pt = events.mousePos();
+ highlightIcon(Common::Point(pt.x - 4 + _bigPos.x, pt.y + _bigPos.y));
+ }
+ updateMap(false);
+ }
+
+ if ((events._released || events._rightReleased) && _point != -1) {
+ if (people[HOLMES]._walkCount == 0) {
+ people[HOLMES]._walkDest = _points[_point] + Common::Point(4, 9);
+ _charPoint = _point;
+
+ // Start walking to selected location
+ walkTheStreets();
+
+ // Show wait cursor
+ _cursorIndex = 1;
+ events.setCursor((*_mapCursors)[_cursorIndex]._frame);
+ }
+ }
+
+ // Check if a scene has beeen selected and we've finished "moving" to it
+ if (people[HOLMES]._walkCount == 0) {
+ if (_charPoint >= 1 && _charPoint < (int)_points.size())
+ exitFlag = true;
+ }
+
+ if (_drawMap) {
+ _drawMap = false;
+
+ if (screen._fadeStyle)
+ screen.randomTransition();
+ else
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+ }
+
+ // Wait for a frame
+ events.wait(1);
+ }
+
+ freeSprites();
+ _overPos = people[HOLMES]._position;
+
+ // Reset font
+ screen.setFont(oldFont);
+
+ // Free map graphic
+ delete bigMap;
+
+ _active = false;
+ return _charPoint;
+}
+
+void ScalpelMap::setupSprites() {
+ Events &events = *_vm->_events;
+ People &people = *_vm->_people;
+ Scene &scene = *_vm->_scene;
+ _savedPos.x = -1;
+
+ if (!IS_3DO) {
+ // PC
+ _mapCursors = new ImageFile("omouse.vgs");
+ _shapes = new ImageFile("mapicon.vgs");
+ _iconShapes = new ImageFile("overicon.vgs");
+ } else {
+ // 3DO
+ _mapCursors = new ImageFile3DO("omouse.vgs", kImageFile3DOType_RoomFormat);
+ _shapes = new ImageFile3DO("mapicon.vgs", kImageFile3DOType_RoomFormat);
+ _iconShapes = new ImageFile3DO("overicon.vgs", kImageFile3DOType_RoomFormat);
+ }
+
+ _cursorIndex = 0;
+ events.setCursor((*_mapCursors)[_cursorIndex]._frame);
+
+ _iconSave.create((*_shapes)[4]._width, (*_shapes)[4]._height);
+ Person &p = people[HOLMES];
+ p._description = " ";
+ p._type = CHARACTER;
+ p._position = Common::Point(12400, 5000);
+ p._sequenceNumber = 0;
+ p._images = _shapes;
+ p._imageFrame = nullptr;
+ p._frameNumber = 0;
+ p._delta = Common::Point(0, 0);
+ p._oldSize = Common::Point(0, 0);
+ p._oldSize = Common::Point(0, 0);
+ p._misc = 0;
+ p._walkCount = 0;
+ p._allow = 0;
+ p._noShapeSize = Common::Point(0, 0);
+ p._goto = Common::Point(28000, 15000);
+ p._status = 0;
+ p._walkSequences = _walkSequences;
+ p.setImageFrame();
+ scene._bgShapes.clear();
+}
+
+void ScalpelMap::freeSprites() {
+ delete _mapCursors;
+ delete _shapes;
+ delete _iconShapes;
+ _iconSave.free();
+}
+
+void ScalpelMap::showPlaces() {
+ Debugger &debugger = *_vm->_debugger;
+ Screen &screen = *_vm->_screen;
+
+ for (uint idx = 0; idx < _points.size(); ++idx) {
+ const MapEntry &pt = _points[idx];
+
+ if (pt.x != 0 && pt.y != 0) {
+ if (debugger._showAllLocations != LOC_DISABLED)
+ _vm->setFlagsDirect(idx);
+
+ if (pt.x >= _bigPos.x && (pt.x - _bigPos.x) < SHERLOCK_SCREEN_WIDTH
+ && pt.y >= _bigPos.y && (pt.y - _bigPos.y) < SHERLOCK_SCREEN_HEIGHT) {
+ if (_vm->readFlags(idx)) {
+ screen._backBuffer1.transBlitFrom((*_iconShapes)[pt._translate],
+ Common::Point(pt.x - _bigPos.x - 6, pt.y - _bigPos.y - 12));
+ }
+ }
+ }
+ }
+
+ if (debugger._showAllLocations == LOC_REFRESH)
+ debugger._showAllLocations = LOC_ALL;
+}
+
+void ScalpelMap::saveTopLine() {
+ _topLine.blitFrom(_vm->_screen->_backBuffer1, Common::Point(0, 0), Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, 12));
+}
+
+void ScalpelMap::eraseTopLine() {
+ Screen &screen = *_vm->_screen;
+ screen._backBuffer1.blitFrom(_topLine, Common::Point(0, 0));
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, _topLine.h());
+}
+
+void ScalpelMap::showPlaceName(int idx, bool highlighted) {
+ People &people = *_vm->_people;
+ Screen &screen = *_vm->_screen;
+
+ Common::String name = _locationNames[idx];
+ int width = screen.stringWidth(name);
+
+ if (!_cursorIndex) {
+ saveIcon(people[HOLMES]._imageFrame, _lDrawnPos);
+
+ bool flipped = people[HOLMES]._sequenceNumber == MAP_DOWNLEFT || people[HOLMES]._sequenceNumber == MAP_LEFT
+ || people[HOLMES]._sequenceNumber == MAP_UPLEFT;
+ screen._backBuffer1.transBlitFrom(*people[HOLMES]._imageFrame, _lDrawnPos, flipped);
+ }
+
+ if (highlighted) {
+ int xp = (SHERLOCK_SCREEN_WIDTH - screen.stringWidth(name)) / 2;
+ screen.gPrint(Common::Point(xp + 2, 2), BLACK, "%s", name.c_str());
+ screen.gPrint(Common::Point(xp + 1, 1), BLACK, "%s", name.c_str());
+ screen.gPrint(Common::Point(xp, 0), 12, "%s", name.c_str());
+
+ screen.slamArea(xp, 0, width + 2, 15);
+ }
+}
+
+void ScalpelMap::updateMap(bool flushScreen) {
+ Events &events = *_vm->_events;
+ People &people = *_vm->_people;
+ Screen &screen = *_vm->_screen;
+ Common::Point osPos = _savedPos;
+ Common::Point osSize = _savedSize;
+ Common::Point hPos;
+
+ if (_cursorIndex >= 1) {
+ if (++_cursorIndex > (1 + 8))
+ _cursorIndex = 1;
+
+ events.setCursor((*_mapCursors)[(_cursorIndex + 1) / 2]._frame);
+ }
+
+ if (!_drawMap && !flushScreen)
+ restoreIcon();
+ else
+ _savedPos.x = -1;
+
+ people[HOLMES].adjustSprite();
+
+ _lDrawnPos.x = hPos.x = people[HOLMES]._position.x / FIXED_INT_MULTIPLIER - _bigPos.x;
+ _lDrawnPos.y = hPos.y = people[HOLMES]._position.y / FIXED_INT_MULTIPLIER - people[HOLMES].frameHeight() - _bigPos.y;
+
+ // Draw the person icon
+ saveIcon(people[HOLMES]._imageFrame, hPos);
+ if (people[HOLMES]._sequenceNumber == MAP_DOWNLEFT || people[HOLMES]._sequenceNumber == MAP_LEFT
+ || people[HOLMES]._sequenceNumber == MAP_UPLEFT)
+ screen._backBuffer1.transBlitFrom(*people[HOLMES]._imageFrame, hPos, true);
+ else
+ screen._backBuffer1.transBlitFrom(*people[HOLMES]._imageFrame, hPos, false);
+
+ if (flushScreen) {
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+ } else if (!_drawMap) {
+ if (hPos.x > 0 && hPos.y >= 0 && hPos.x < SHERLOCK_SCREEN_WIDTH && hPos.y < SHERLOCK_SCREEN_HEIGHT)
+ screen.flushImage(people[HOLMES]._imageFrame, Common::Point(people[HOLMES]._position.x / FIXED_INT_MULTIPLIER - _bigPos.x,
+ people[HOLMES]._position.y / FIXED_INT_MULTIPLIER - people[HOLMES].frameHeight() - _bigPos.y),
+ &people[HOLMES]._oldPosition.x, &people[HOLMES]._oldPosition.y, &people[HOLMES]._oldSize.x, &people[HOLMES]._oldSize.y);
+
+ if (osPos.x != -1)
+ screen.slamArea(osPos.x, osPos.y, osSize.x, osSize.y);
+ }
+}
+
+void ScalpelMap::walkTheStreets() {
+ People &people = *_vm->_people;
+ Common::Array<Common::Point> tempPath;
+
+ // Get indexes into the path lists for the start and destination scenes
+ int start = _points[_oldCharPoint]._translate;
+ int dest = _points[_charPoint]._translate;
+
+ // Get pointer to start of path
+ const byte *path = _paths.getPath(start, dest);
+
+ // Add in destination position
+ people[HOLMES]._walkTo.clear();
+ Common::Point destPos = people[HOLMES]._walkDest;
+
+ // Check for any intermediate points between the two locations
+ if (path[0] || _charPoint > 50 || _oldCharPoint > 50) {
+ people[HOLMES]._sequenceNumber = -1;
+
+ if (_charPoint == 51 || _oldCharPoint == 51) {
+ people[HOLMES].setWalking();
+ } else {
+ bool reversePath = false;
+
+ // Check for moving the path backwards or forwards
+ if (path[0] == 255) {
+ reversePath = true;
+ SWAP(start, dest);
+ path = _paths.getPath(start, dest);
+ }
+
+ do {
+ int idx = *path++;
+ tempPath.push_back(_pathPoints[idx - 1] + Common::Point(4, 4));
+ } while (*path != 254);
+
+ // Load up the path to use
+ people[HOLMES]._walkTo.clear();
+
+ if (reversePath) {
+ for (int idx = (int)tempPath.size() - 1; idx >= 0; --idx)
+ people[HOLMES]._walkTo.push(tempPath[idx]);
+ } else {
+ for (int idx = 0; idx < (int)tempPath.size(); ++idx)
+ people[HOLMES]._walkTo.push(tempPath[idx]);
+ }
+
+ people[HOLMES]._walkDest = people[HOLMES]._walkTo.pop() + Common::Point(12, 6);
+ people[HOLMES].setWalking();
+ }
+ } else {
+ people[HOLMES]._walkCount = 0;
+ }
+
+ // Store the final destination icon position
+ people[HOLMES]._walkTo.push(destPos);
+}
+
+void ScalpelMap::saveIcon(ImageFrame *src, const Common::Point &pt) {
+ Screen &screen = *_vm->_screen;
+ Common::Point size(src->_width, src->_height);
+ Common::Point pos = pt;
+
+ if (pos.x < 0) {
+ size.x += pos.x;
+ pos.x = 0;
+ }
+
+ if (pos.y < 0) {
+ size.y += pos.y;
+ pos.y = 0;
+ }
+
+ if ((pos.x + size.x) > SHERLOCK_SCREEN_WIDTH)
+ size.x -= (pos.x + size.x) - SHERLOCK_SCREEN_WIDTH;
+
+ if ((pos.y + size.y) > SHERLOCK_SCREEN_HEIGHT)
+ size.y -= (pos.y + size.y) - SHERLOCK_SCREEN_HEIGHT;
+
+ if (size.x < 1 || size.y < 1 || pos.x >= SHERLOCK_SCREEN_WIDTH || pos.y >= SHERLOCK_SCREEN_HEIGHT || _drawMap) {
+ // Flag as the area not needing to be saved
+ _savedPos.x = -1;
+ return;
+ }
+
+ assert(size.x <= _iconSave.w() && size.y <= _iconSave.h());
+ _iconSave.blitFrom(screen._backBuffer1, Common::Point(0, 0),
+ Common::Rect(pos.x, pos.y, pos.x + size.x, pos.y + size.y));
+ _savedPos = pos;
+ _savedSize = size;
+}
+
+void ScalpelMap::restoreIcon() {
+ Screen &screen = *_vm->_screen;
+
+ if (_savedPos.x >= 0 && _savedPos.y >= 0 && _savedPos.x <= SHERLOCK_SCREEN_WIDTH
+ && _savedPos.y < SHERLOCK_SCREEN_HEIGHT)
+ screen._backBuffer1.blitFrom(_iconSave, _savedPos, Common::Rect(0, 0, _savedSize.x, _savedSize.y));
+}
+
+void ScalpelMap::highlightIcon(const Common::Point &pt) {
+ int oldPoint = _point;
+
+ // Iterate through the icon list
+ bool done = false;
+ for (int idx = 0; idx < (int)_points.size(); ++idx) {
+ const MapEntry &entry = _points[idx];
+
+ // Check whether the mouse is over a given icon
+ if (entry.x != 0 && entry.y != 0) {
+ if (Common::Rect(entry.x - 8, entry.y - 8, entry.x + 9, entry.y + 9).contains(pt)) {
+ done = true;
+
+ if (_point != idx && _vm->readFlags(idx)) {
+ // Changed to a new valid (visible) location
+ eraseTopLine();
+ showPlaceName(idx, true);
+ _point = idx;
+ }
+ }
+ }
+ }
+
+ if (!done) {
+ // No icon was highlighted
+ if (_point != -1) {
+ // No longer highlighting previously highlighted icon, so erase it
+ showPlaceName(_point, false);
+ eraseTopLine();
+ }
+
+ _point = -1;
+ } else if (oldPoint != -1 && oldPoint != _point) {
+ showPlaceName(oldPoint, false);
+ eraseTopLine();
+ }
+}
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/scalpel/scalpel_map.h b/engines/sherlock/scalpel/scalpel_map.h
new file mode 100644
index 0000000000..b17677725c
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_map.h
@@ -0,0 +1,173 @@
+/* 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 SHERLOCK_SCALPEL_MAP_H
+#define SHERLOCK_SCALPEL_MAP_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/rect.h"
+#include "common/str-array.h"
+#include "sherlock/surface.h"
+#include "sherlock/map.h"
+#include "sherlock/resources.h"
+
+namespace Sherlock {
+
+class SherlockEngine;
+
+namespace Scalpel {
+
+
+struct MapEntry : Common::Point {
+ int _translate;
+
+ MapEntry() : Common::Point(), _translate(-1) {}
+
+ MapEntry(int posX, int posY, int translate) : Common::Point(posX, posY), _translate(translate) {}
+};
+
+class MapPaths {
+private:
+ int _numLocations;
+ Common::Array< Common::Array<byte> > _paths;
+
+public:
+ MapPaths();
+
+ /**
+ * Load the data for the paths between locations on the map
+ */
+ void load(int numLocations, Common::SeekableReadStream &s);
+
+ /**
+ * Get the path between two locations on the map
+ */
+ const byte *getPath(int srcLocation, int destLocation);
+};
+
+class ScalpelMap: public Map {
+private:
+ Common::Array<MapEntry> _points; // Map locations for each scene
+ Common::StringArray _locationNames;
+ MapPaths _paths;
+ Common::Array<Common::Point> _pathPoints;
+ Common::Point _savedPos;
+ Common::Point _savedSize;
+ Surface _topLine;
+ ImageFile *_mapCursors;
+ ImageFile *_shapes;
+ ImageFile *_iconShapes;
+ WalkSequences _walkSequences;
+ Point32 _lDrawnPos;
+ int _point;
+ bool _placesShown;
+ int _cursorIndex;
+ bool _drawMap;
+ Surface _iconSave;
+protected:
+ /**
+ * Load data needed for the map
+ */
+ void loadData();
+
+ /**
+ * Load and initialize all the sprites that are needed for the map display
+ */
+ void setupSprites();
+
+ /**
+ * Free the sprites and data used by the map
+ */
+ void freeSprites();
+
+ /**
+ * Draws an icon for every place that's currently known
+ */
+ void showPlaces();
+
+ /**
+ * Makes a copy of the top rows of the screen that are used to display location names
+ */
+ void saveTopLine();
+
+ /**
+ * Erases anything shown in the top line by restoring the previously saved original map background
+ */
+ void eraseTopLine();
+
+ /**
+ * Prints the name of the specified icon
+ */
+ void showPlaceName(int idx, bool highlighted);
+
+ /**
+ * Update all on-screen sprites to account for any scrolling of the map
+ */
+ void updateMap(bool flushScreen);
+
+ /**
+ * Handle moving icon for player from their previous location on the map to a destination location
+ */
+ void walkTheStreets();
+
+ /**
+ * Save the area under the player's icon
+ */
+ void saveIcon(ImageFrame *src, const Common::Point &pt);
+
+ /**
+ * Restore the area under the player's icon
+ */
+ void restoreIcon();
+
+ /**
+ * Handles highlighting map icons, showing their names
+ */
+ void highlightIcon(const Common::Point &pt);
+public:
+ ScalpelMap(SherlockEngine *vm);
+ virtual ~ScalpelMap() {}
+
+ const MapEntry &operator[](int idx) { return _points[idx]; }
+
+ /**
+ * Loads the list of points for locations on the map for each scene
+ */
+ void loadPoints(int count, const int *xList, const int *yList, const int *transList);
+
+ /**
+ * Load the sequence data for player icon animations
+ */
+ void loadSequences(int count, const byte *seq);
+
+ /**
+ * Show the map
+ */
+ virtual int show();
+};
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/scalpel/scalpel_people.cpp b/engines/sherlock/scalpel/scalpel_people.cpp
new file mode 100644
index 0000000000..53876f8f1c
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_people.cpp
@@ -0,0 +1,532 @@
+/* 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 "sherlock/scalpel/scalpel_people.h"
+#include "sherlock/scalpel/scalpel_map.h"
+#include "sherlock/sherlock.h"
+
+namespace Sherlock {
+
+namespace Scalpel {
+
+// Walk speeds
+#define MWALK_SPEED 2
+#define XWALK_SPEED 4
+#define YWALK_SPEED 1
+
+/*----------------------------------------------------------------*/
+
+void ScalpelPerson::adjustSprite() {
+ Map &map = *_vm->_map;
+ People &people = *_vm->_people;
+ Scene &scene = *_vm->_scene;
+ Talk &talk = *_vm->_talk;
+
+ if (_type == INVALID || (_type == CHARACTER && scene._animating))
+ return;
+
+ if (!talk._talkCounter && _type == CHARACTER && _walkCount) {
+ // Handle active movement for the sprite
+ _position += _delta;
+ --_walkCount;
+
+ if (!_walkCount) {
+ // If there any points left for the character to walk to along the
+ // route to a destination, then move to the next point
+ if (!people[HOLMES]._walkTo.empty()) {
+ _walkDest = people[HOLMES]._walkTo.pop();
+ setWalking();
+ } else {
+ gotoStand();
+ }
+ }
+ }
+
+ if (_type == CHARACTER && !map._active) {
+ if ((_position.y / FIXED_INT_MULTIPLIER) > LOWER_LIMIT) {
+ _position.y = LOWER_LIMIT * FIXED_INT_MULTIPLIER;
+ gotoStand();
+ }
+
+ if ((_position.y / FIXED_INT_MULTIPLIER) < UPPER_LIMIT) {
+ _position.y = UPPER_LIMIT * FIXED_INT_MULTIPLIER;
+ gotoStand();
+ }
+
+ if ((_position.x / FIXED_INT_MULTIPLIER) < LEFT_LIMIT) {
+ _position.x = LEFT_LIMIT * FIXED_INT_MULTIPLIER;
+ gotoStand();
+ }
+
+ if ((_position.x / FIXED_INT_MULTIPLIER) > RIGHT_LIMIT) {
+ _position.x = RIGHT_LIMIT * FIXED_INT_MULTIPLIER;
+ gotoStand();
+ }
+ } else if (!map._active) {
+ _position.y = CLIP((int)_position.y, (int)UPPER_LIMIT, (int)LOWER_LIMIT);
+ _position.x = CLIP((int)_position.x, (int)LEFT_LIMIT, (int)RIGHT_LIMIT);
+ }
+
+ if (!map._active || (map._frameChangeFlag = !map._frameChangeFlag))
+ ++_frameNumber;
+
+ if (_frameNumber >= (int)_walkSequences[_sequenceNumber]._sequences.size() ||
+ _walkSequences[_sequenceNumber][_frameNumber] == 0) {
+ switch (_sequenceNumber) {
+ case STOP_UP:
+ case STOP_DOWN:
+ case STOP_LEFT:
+ case STOP_RIGHT:
+ case STOP_UPRIGHT:
+ case STOP_UPLEFT:
+ case STOP_DOWNRIGHT:
+ case STOP_DOWNLEFT:
+ // We're in a stop sequence, so reset back to the last frame, so
+ // the character is shown as standing still
+ --_frameNumber;
+ break;
+
+ default:
+ // Move 1 past the first frame - we need to compensate, since we
+ // already passed the frame increment
+ _frameNumber = 1;
+ break;
+ }
+ }
+
+ // Update the _imageFrame to point to the new frame's image
+ setImageFrame();
+
+ // Check to see if character has entered an exit zone
+ if (!_walkCount && scene._walkedInScene && scene._goToScene == -1) {
+ Common::Rect charRect(_position.x / FIXED_INT_MULTIPLIER - 5, _position.y / FIXED_INT_MULTIPLIER - 2,
+ _position.x / FIXED_INT_MULTIPLIER + 5, _position.y / FIXED_INT_MULTIPLIER + 2);
+ Exit *exit = scene.checkForExit(charRect);
+
+ if (exit) {
+ scene._goToScene = exit->_scene;
+
+ if (exit->_newPosition.x != 0) {
+ people._savedPos = exit->_newPosition;
+
+ if (people._savedPos._facing > 100 && people._savedPos.x < 1)
+ people._savedPos.x = 100;
+ }
+ }
+ }
+}
+
+void ScalpelPerson::gotoStand() {
+ ScalpelMap &map = *(ScalpelMap *)_vm->_map;
+ People &people = *_vm->_people;
+ _walkTo.clear();
+ _walkCount = 0;
+
+ switch (_sequenceNumber) {
+ case Scalpel::WALK_UP:
+ _sequenceNumber = STOP_UP;
+ break;
+ case WALK_DOWN:
+ _sequenceNumber = STOP_DOWN;
+ break;
+ case TALK_LEFT:
+ case WALK_LEFT:
+ _sequenceNumber = STOP_LEFT;
+ break;
+ case TALK_RIGHT:
+ case WALK_RIGHT:
+ _sequenceNumber = STOP_RIGHT;
+ break;
+ case WALK_UPRIGHT:
+ _sequenceNumber = STOP_UPRIGHT;
+ break;
+ case WALK_UPLEFT:
+ _sequenceNumber = STOP_UPLEFT;
+ break;
+ case WALK_DOWNRIGHT:
+ _sequenceNumber = STOP_DOWNRIGHT;
+ break;
+ case WALK_DOWNLEFT:
+ _sequenceNumber = STOP_DOWNLEFT;
+ break;
+ default:
+ break;
+ }
+
+ // Only restart frame at 0 if the sequence number has changed
+ if (_oldWalkSequence != -1 || _sequenceNumber == Scalpel::STOP_UP)
+ _frameNumber = 0;
+
+ if (map._active) {
+ _sequenceNumber = 0;
+ people[HOLMES]._position.x = (map[map._charPoint].x - 6) * FIXED_INT_MULTIPLIER;
+ people[HOLMES]._position.y = (map[map._charPoint].y + 10) * FIXED_INT_MULTIPLIER;
+ }
+
+ _oldWalkSequence = -1;
+ people._allowWalkAbort = true;
+}
+
+void ScalpelPerson::setWalking() {
+ Map &map = *_vm->_map;
+ Scene &scene = *_vm->_scene;
+ int oldDirection, oldFrame;
+ Common::Point speed, delta;
+
+ // Flag that player has now walked in the scene
+ scene._walkedInScene = true;
+
+ // Stop any previous walking, since a new dest is being set
+ _walkCount = 0;
+ oldDirection = _sequenceNumber;
+ oldFrame = _frameNumber;
+
+ // Set speed to use horizontal and vertical movement
+ if (map._active) {
+ speed = Common::Point(MWALK_SPEED, MWALK_SPEED);
+ } else {
+ speed = Common::Point(XWALK_SPEED, YWALK_SPEED);
+ }
+
+ // If the player is already close to the given destination that no
+ // walking is needed, move to the next straight line segment in the
+ // overall walking route, if there is one
+ for (;;) {
+ // Since we want the player to be centered on the destination they
+ // clicked, but characters draw positions start at their left, move
+ // the destination half the character width to draw him centered
+ int temp;
+ if (_walkDest.x >= (temp = _imageFrame->_frame.w / 2))
+ _walkDest.x -= temp;
+
+ delta = Common::Point(
+ ABS(_position.x / FIXED_INT_MULTIPLIER - _walkDest.x),
+ ABS(_position.y / FIXED_INT_MULTIPLIER - _walkDest.y)
+ );
+
+ // If we're ready to move a sufficient distance, that's it. Otherwise,
+ // move onto the next portion of the walk path, if there is one
+ if ((delta.x > 3 || delta.y > 0) || _walkTo.empty())
+ break;
+
+ // Pop next walk segment off the walk route stack
+ _walkDest = _walkTo.pop();
+ }
+
+ // If a sufficient move is being done, then start the move
+ if (delta.x > 3 || delta.y) {
+ // See whether the major movement is horizontal or vertical
+ if (delta.x >= delta.y) {
+ // Set the initial frame sequence for the left and right, as well
+ // as setting the delta x depending on direction
+ if (_walkDest.x < (_position.x / FIXED_INT_MULTIPLIER)) {
+ _sequenceNumber = (map._active ? (int)MAP_LEFT : (int)WALK_LEFT);
+ _delta.x = speed.x * -FIXED_INT_MULTIPLIER;
+ } else {
+ _sequenceNumber = (map._active ? (int)MAP_RIGHT : (int)WALK_RIGHT);
+ _delta.x = speed.x * FIXED_INT_MULTIPLIER;
+ }
+
+ // See if the x delta is too small to be divided by the speed, since
+ // this would cause a divide by zero error
+ if (delta.x >= speed.x) {
+ // Det the delta y
+ _delta.y = (delta.y * FIXED_INT_MULTIPLIER) / (delta.x / speed.x);
+ if (_walkDest.y < (_position.y / FIXED_INT_MULTIPLIER))
+ _delta.y = -_delta.y;
+
+ // Set how many times we should add the delta to the player's position
+ _walkCount = delta.x / speed.x;
+ } else {
+ // The delta x was less than the speed (ie. we're really close to
+ // the destination). So set delta to 0 so the player won't move
+ _delta = Point32(0, 0);
+ _position = Point32(_walkDest.x * FIXED_INT_MULTIPLIER, _walkDest.y * FIXED_INT_MULTIPLIER);
+
+ _walkCount = 1;
+ }
+
+ // See if the sequence needs to be changed for diagonal walking
+ if (_delta.y > 150) {
+ if (!map._active) {
+ switch (_sequenceNumber) {
+ case WALK_LEFT:
+ _sequenceNumber = WALK_DOWNLEFT;
+ break;
+ case WALK_RIGHT:
+ _sequenceNumber = WALK_DOWNRIGHT;
+ break;
+ }
+ }
+ } else if (_delta.y < -150) {
+ if (!map._active) {
+ switch (_sequenceNumber) {
+ case WALK_LEFT:
+ _sequenceNumber = WALK_UPLEFT;
+ break;
+ case WALK_RIGHT:
+ _sequenceNumber = WALK_UPRIGHT;
+ break;
+ }
+ }
+ }
+ } else {
+ // Major movement is vertical, so set the sequence for up and down,
+ // and set the delta Y depending on the direction
+ if (_walkDest.y < (_position.y / FIXED_INT_MULTIPLIER)) {
+ _sequenceNumber = WALK_UP;
+ _delta.y = speed.y * -FIXED_INT_MULTIPLIER;
+ } else {
+ _sequenceNumber = WALK_DOWN;
+ _delta.y = speed.y * FIXED_INT_MULTIPLIER;
+ }
+
+ // If we're on the overhead map, set the sequence so we keep moving
+ // in the same direction
+ if (map._active)
+ _sequenceNumber = (oldDirection == -1) ? MAP_RIGHT : oldDirection;
+
+ // Set the delta x
+ _delta.x = (delta.x * FIXED_INT_MULTIPLIER) / (delta.y / speed.y);
+ if (_walkDest.x < (_position.x / FIXED_INT_MULTIPLIER))
+ _delta.x = -_delta.x;
+
+ _walkCount = delta.y / speed.y;
+ }
+ }
+
+ // See if the new walk sequence is the same as the old. If it's a new one,
+ // we need to reset the frame number to zero so it's animation starts at
+ // it's beginning. Otherwise, if it's the same sequence, we can leave it
+ // as is, so it keeps the animation going at wherever it was up to
+ if (_sequenceNumber != _oldWalkSequence)
+ _frameNumber = 0;
+ _oldWalkSequence = _sequenceNumber;
+
+ if (!_walkCount)
+ gotoStand();
+
+ // If the sequence is the same as when we started, then Holmes was
+ // standing still and we're trying to re-stand him, so reset Holmes'
+ // rame to the old frame number from before it was reset to 0
+ if (_sequenceNumber == oldDirection)
+ _frameNumber = oldFrame;
+}
+
+void ScalpelPerson::walkToCoords(const Point32 &destPos, int destDir) {
+ Events &events = *_vm->_events;
+ People &people = *_vm->_people;
+ Scene &scene = *_vm->_scene;
+ Talk &talk = *_vm->_talk;
+
+ CursorId oldCursor = events.getCursor();
+ events.setCursor(WAIT);
+
+ _walkDest = Common::Point(destPos.x / FIXED_INT_MULTIPLIER + 10, destPos.y / FIXED_INT_MULTIPLIER);
+ people._allowWalkAbort = true;
+ goAllTheWay();
+
+ // Keep calling doBgAnim until the walk is done
+ do {
+ events.pollEventsAndWait();
+ scene.doBgAnim();
+ } while (!_vm->shouldQuit() && _walkCount);
+
+ if (!talk._talkToAbort) {
+ // Put character exactly on destination position, and set direction
+ _position = destPos;
+ _sequenceNumber = destDir;
+ gotoStand();
+
+ // Draw Holmes facing the new direction
+ scene.doBgAnim();
+
+ if (!talk._talkToAbort)
+ events.setCursor(oldCursor);
+ }
+}
+
+Common::Point ScalpelPerson::getSourcePoint() const {
+ return Common::Point(_position.x / FIXED_INT_MULTIPLIER + frameWidth() / 2,
+ _position.y / FIXED_INT_MULTIPLIER);
+}
+
+/*----------------------------------------------------------------*/
+
+ScalpelPeople::ScalpelPeople(SherlockEngine *vm) : People(vm) {
+ _data.push_back(new ScalpelPerson());
+}
+
+void ScalpelPeople::setTalking(int speaker) {
+ Resources &res = *_vm->_res;
+
+ // If no speaker is specified, then we can exit immediately
+ if (speaker == -1)
+ return;
+
+ if (_portraitsOn) {
+ delete _talkPics;
+ Common::String filename = Common::String::format("%s.vgs", _characters[speaker]._portrait);
+ _talkPics = new ImageFile(filename);
+
+ // Load portrait sequences
+ Common::SeekableReadStream *stream = res.load("sequence.txt");
+ stream->seek(speaker * MAX_FRAME);
+
+ int idx = 0;
+ do {
+ _portrait._sequences[idx] = stream->readByte();
+ ++idx;
+ } while (idx < 2 || _portrait._sequences[idx - 2] || _portrait._sequences[idx - 1]);
+
+ delete stream;
+
+ _portrait._maxFrames = idx;
+ _portrait._frameNumber = 0;
+ _portrait._sequenceNumber = 0;
+ _portrait._images = _talkPics;
+ _portrait._imageFrame = &(*_talkPics)[0];
+ _portrait._position = Common::Point(_portraitSide, 10);
+ _portrait._delta = Common::Point(0, 0);
+ _portrait._oldPosition = Common::Point(0, 0);
+ _portrait._goto = Common::Point(0, 0);
+ _portrait._flags = 5;
+ _portrait._status = 0;
+ _portrait._misc = 0;
+ _portrait._allow = 0;
+ _portrait._type = ACTIVE_BG_SHAPE;
+ _portrait._name = " ";
+ _portrait._description = " ";
+ _portrait._examine = " ";
+ _portrait._walkCount = 0;
+
+ if (_holmesFlip || _speakerFlip) {
+ _portrait._flags |= 2;
+
+ _holmesFlip = false;
+ _speakerFlip = false;
+ }
+
+ if (_portraitSide == 20)
+ _portraitSide = 220;
+ else
+ _portraitSide = 20;
+
+ _portraitLoaded = true;
+ }
+}
+
+void ScalpelPeople::synchronize(Serializer &s) {
+ s.syncAsByte(_holmesOn);
+ s.syncAsSint32LE(_data[HOLMES]->_position.x);
+ s.syncAsSint32LE(_data[HOLMES]->_position.y);
+ s.syncAsSint16LE(_data[HOLMES]->_sequenceNumber);
+ s.syncAsSint16LE(_holmesQuotient);
+
+ if (s.isLoading()) {
+ _savedPos = _data[HOLMES]->_position;
+ _savedPos._facing = _data[HOLMES]->_sequenceNumber;
+ }
+}
+
+void ScalpelPeople::setTalkSequence(int speaker, int sequenceNum) {
+ People &people = *_vm->_people;
+ Scene &scene = *_vm->_scene;
+
+ // If no speaker is specified, then nothing needs to be done
+ if (speaker == -1)
+ return;
+
+ if (speaker) {
+ int objNum = people.findSpeaker(speaker);
+ if (objNum != -1) {
+ Object &obj = scene._bgShapes[objNum];
+
+ if (obj._seqSize < MAX_TALK_SEQUENCES) {
+ warning("Tried to copy too many talk frames");
+ }
+ else {
+ for (int idx = 0; idx < MAX_TALK_SEQUENCES; ++idx) {
+ obj._sequences[idx] = people._characters[speaker]._talkSequences[idx];
+ if (idx > 0 && !obj._sequences[idx] && !obj._sequences[idx - 1])
+ return;
+
+ obj._frameNumber = 0;
+ obj._sequenceNumber = 0;
+ }
+ }
+ }
+ }
+}
+
+bool ScalpelPeople::loadWalk() {
+ bool result = false;
+
+ if (_data[HOLMES]->_walkLoaded) {
+ return false;
+ } else {
+ if (!IS_3DO) {
+ _data[HOLMES]->_images = new ImageFile("walk.vgs");
+ } else {
+ // Load walk.anim on 3DO, which is a cel animation file
+ _data[HOLMES]->_images = new ImageFile3DO("walk.anim", kImageFile3DOType_CelAnimation);
+ }
+ _data[HOLMES]->setImageFrame();
+ _data[HOLMES]->_walkLoaded = true;
+
+ result = true;
+ }
+
+ _forceWalkReload = false;
+ return result;
+}
+
+const Common::Point ScalpelPeople::restrictToZone(int zoneId, const Common::Point &destPos) {
+ Scene &scene = *_vm->_scene;
+ Common::Point walkDest = destPos;
+
+ // The destination isn't in a zone
+ if (walkDest.x >= (SHERLOCK_SCREEN_WIDTH - 1))
+ walkDest.x = SHERLOCK_SCREEN_WIDTH - 2;
+
+ // Trace a line between the centroid of the found closest zone to
+ // the destination, to find the point at which the zone will be left
+ const Common::Rect &destRect = scene._zones[zoneId];
+ const Common::Point destCenter((destRect.left + destRect.right) / 2,
+ (destRect.top + destRect.bottom) / 2);
+ const Common::Point delta = walkDest - destCenter;
+ Point32 pt(destCenter.x * FIXED_INT_MULTIPLIER, destCenter.y * FIXED_INT_MULTIPLIER);
+
+ // Move along the line until the zone is left
+ do {
+ pt += delta;
+ } while (destRect.contains(pt.x / FIXED_INT_MULTIPLIER, pt.y / FIXED_INT_MULTIPLIER));
+
+ // Set the new walk destination to the last point that was in the
+ // zone just before it was left
+ return Common::Point((pt.x - delta.x * 2) / FIXED_INT_MULTIPLIER,
+ (pt.y - delta.y * 2) / FIXED_INT_MULTIPLIER);
+}
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/scalpel/scalpel_people.h b/engines/sherlock/scalpel/scalpel_people.h
new file mode 100644
index 0000000000..b53da2e6d8
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_people.h
@@ -0,0 +1,114 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SHERLOCK_SCALPEL_PEOPLE_H
+#define SHERLOCK_SCALPEL_PEOPLE_H
+
+#include "common/scummsys.h"
+#include "sherlock/people.h"
+
+namespace Sherlock {
+
+class SherlockEngine;
+
+namespace Scalpel {
+
+// Animation sequence identifiers for characters
+enum ScalpelSequences {
+ WALK_RIGHT = 0, WALK_DOWN = 1, WALK_LEFT = 2, WALK_UP = 3, STOP_LEFT = 4,
+ STOP_DOWN = 5, STOP_RIGHT = 6, STOP_UP = 7, WALK_UPRIGHT = 8,
+ WALK_DOWNRIGHT = 9, WALK_UPLEFT = 10, WALK_DOWNLEFT = 11,
+ STOP_UPRIGHT = 12, STOP_UPLEFT = 13, STOP_DOWNRIGHT = 14,
+ STOP_DOWNLEFT = 15, TALK_RIGHT = 6, TALK_LEFT = 4
+};
+
+class ScalpelPerson : public Person {
+public:
+ ScalpelPerson() : Person() {}
+ virtual ~ScalpelPerson() {}
+
+ /**
+ * This adjusts the sprites position, as well as it's animation sequence:
+ */
+ virtual void adjustSprite();
+
+ /**
+ * Bring a moving character to a standing position
+ */
+ virtual void gotoStand();
+
+ /**
+ * Set the variables for moving a character from one poisition to another
+ * in a straight line
+ */
+ virtual void setWalking();
+
+ /**
+ * Walk to the co-ordinates passed, and then face the given direction
+ */
+ virtual void walkToCoords(const Point32 &destPos, int destDir);
+
+ /**
+ * Get the source position for a character potentially affected by scaling
+ */
+ virtual Common::Point getSourcePoint() const;
+};
+
+class ScalpelPeople : public People {
+public:
+ ScalpelPeople(SherlockEngine *vm);
+ virtual ~ScalpelPeople() {}
+
+ ScalpelPerson &operator[](PeopleId id) { return *(ScalpelPerson *)_data[id]; }
+ ScalpelPerson &operator[](int idx) { return *(ScalpelPerson *)_data[idx]; }
+
+ /**
+ * Setup the data for an animating speaker portrait at the top of the screen
+ */
+ void setTalking(int speaker);
+
+ /**
+ * Synchronize the data for a savegame
+ */
+ virtual void synchronize(Serializer &s);
+
+ /**
+ * Change the sequence of the scene background object associated with the specified speaker.
+ */
+ virtual void setTalkSequence(int speaker, int sequenceNum = 1);
+
+ /**
+ * Restrict passed point to zone using Sherlock's positioning rules
+ */
+ virtual const Common::Point restrictToZone(int zoneId, const Common::Point &destPos);
+
+ /**
+ * Load the walking images for Sherlock
+ */
+ virtual bool loadWalk();
+};
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/scalpel/scalpel_saveload.cpp b/engines/sherlock/scalpel/scalpel_saveload.cpp
new file mode 100644
index 0000000000..01ba149813
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_saveload.cpp
@@ -0,0 +1,261 @@
+/* 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 "sherlock/scalpel/scalpel_saveload.h"
+#include "sherlock/scalpel/scalpel_screen.h"
+#include "sherlock/scalpel/scalpel.h"
+
+namespace Sherlock {
+
+namespace Scalpel {
+
+const int ENV_POINTS[6][3] = {
+ { 41, 80, 61 }, // Exit
+ { 81, 120, 101 }, // Load
+ { 121, 160, 141 }, // Save
+ { 161, 200, 181 }, // Up
+ { 201, 240, 221 }, // Down
+ { 241, 280, 261 } // Quit
+};
+
+/*----------------------------------------------------------------*/
+
+ScalpelSaveManager::ScalpelSaveManager(SherlockEngine *vm, const Common::String &target) : SaveManager(vm, target) {
+}
+
+void ScalpelSaveManager::drawInterface() {
+ ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+ UserInterface &ui = *_vm->_ui;
+
+ // Create a list of savegame slots
+ createSavegameList();
+
+ screen._backBuffer1.fillRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y + 10), BORDER_COLOR);
+ screen._backBuffer1.fillRect(Common::Rect(0, CONTROLS_Y + 10, 2, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR);
+ screen._backBuffer1.fillRect(Common::Rect(318, CONTROLS_Y + 10, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR);
+ screen._backBuffer1.fillRect(Common::Rect(0, 199, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR);
+ screen._backBuffer1.fillRect(Common::Rect(2, CONTROLS_Y + 10, SHERLOCK_SCREEN_WIDTH - 2, SHERLOCK_SCREEN_HEIGHT - 2), INV_BACKGROUND);
+
+ screen.makeButton(Common::Rect(ENV_POINTS[0][0], CONTROLS_Y, ENV_POINTS[0][1], CONTROLS_Y + 10),
+ ENV_POINTS[0][2] - screen.stringWidth("Exit") / 2, "Exit");
+ screen.makeButton(Common::Rect(ENV_POINTS[1][0], CONTROLS_Y, ENV_POINTS[1][1], CONTROLS_Y + 10),
+ ENV_POINTS[1][2] - screen.stringWidth("Load") / 2, "Load");
+ screen.makeButton(Common::Rect(ENV_POINTS[2][0], CONTROLS_Y, ENV_POINTS[2][1], CONTROLS_Y + 10),
+ ENV_POINTS[2][2] - screen.stringWidth("Save") / 2, "Save");
+ screen.makeButton(Common::Rect(ENV_POINTS[3][0], CONTROLS_Y, ENV_POINTS[3][1], CONTROLS_Y + 10),
+ ENV_POINTS[3][2] - screen.stringWidth("Up") / 2, "Up");
+ screen.makeButton(Common::Rect(ENV_POINTS[4][0], CONTROLS_Y, ENV_POINTS[4][1], CONTROLS_Y + 10),
+ ENV_POINTS[4][2] - screen.stringWidth("Down") / 2, "Down");
+ screen.makeButton(Common::Rect(ENV_POINTS[5][0], CONTROLS_Y, ENV_POINTS[5][1], CONTROLS_Y + 10),
+ ENV_POINTS[5][2] - screen.stringWidth("Quit") / 2, "Quit");
+
+ if (!_savegameIndex)
+ screen.buttonPrint(Common::Point(ENV_POINTS[3][2], CONTROLS_Y), COMMAND_NULL, 0, "Up");
+
+ if (_savegameIndex == MAX_SAVEGAME_SLOTS - ONSCREEN_FILES_COUNT)
+ screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), COMMAND_NULL, 0, "Down");
+
+ for (int idx = _savegameIndex; idx < _savegameIndex + ONSCREEN_FILES_COUNT; ++idx) {
+ screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (idx - _savegameIndex) * 10),
+ INV_FOREGROUND, "%d.", idx + 1);
+ screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (idx - _savegameIndex) * 10),
+ INV_FOREGROUND, "%s", _savegames[idx].c_str());
+ }
+
+ if (!ui._slideWindows) {
+ screen.slamRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
+ } else {
+ ui.summonWindow();
+ }
+
+ _envMode = SAVEMODE_NONE;
+}
+
+int ScalpelSaveManager::getHighlightedButton() const {
+ Common::Point pt = _vm->_events->mousePos();
+
+ for (int idx = 0; idx < 6; ++idx) {
+ if (pt.x > ENV_POINTS[idx][0] && pt.x < ENV_POINTS[idx][1] && pt.y > CONTROLS_Y
+ && pt.y < (CONTROLS_Y + 10))
+ return idx;
+ }
+
+ return -1;
+}
+
+void ScalpelSaveManager::highlightButtons(int btnIndex) {
+ ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+ byte color = (btnIndex == 0) ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND;
+
+ screen.buttonPrint(Common::Point(ENV_POINTS[0][2], CONTROLS_Y), color, 1, "Exit");
+
+ if ((btnIndex == 1) || ((_envMode == SAVEMODE_LOAD) && (btnIndex != 2)))
+ screen.buttonPrint(Common::Point(ENV_POINTS[1][2], CONTROLS_Y), COMMAND_HIGHLIGHTED, true, "Load");
+ else
+ screen.buttonPrint(Common::Point(ENV_POINTS[1][2], CONTROLS_Y), COMMAND_FOREGROUND, true, "Load");
+
+ if ((btnIndex == 2) || ((_envMode == SAVEMODE_SAVE) && (btnIndex != 1)))
+ screen.buttonPrint(Common::Point(ENV_POINTS[2][2], CONTROLS_Y), COMMAND_HIGHLIGHTED, true, "Save");
+ else
+ screen.buttonPrint(Common::Point(ENV_POINTS[2][2], CONTROLS_Y), COMMAND_FOREGROUND, true, "Save");
+
+ if (btnIndex == 3 && _savegameIndex)
+ screen.buttonPrint(Common::Point(ENV_POINTS[3][2], CONTROLS_Y), COMMAND_HIGHLIGHTED, true, "Up");
+ else
+ if (_savegameIndex)
+ screen.buttonPrint(Common::Point(ENV_POINTS[3][2], CONTROLS_Y), COMMAND_FOREGROUND, true, "Up");
+
+ if ((btnIndex == 4) && (_savegameIndex < MAX_SAVEGAME_SLOTS - 5))
+ screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), COMMAND_HIGHLIGHTED, true, "Down");
+ else if (_savegameIndex < (MAX_SAVEGAME_SLOTS - 5))
+ screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), COMMAND_FOREGROUND, true, "Down");
+
+ color = (btnIndex == 5) ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND;
+ screen.buttonPrint(Common::Point(ENV_POINTS[5][2], CONTROLS_Y), color, 1, "Quit");
+}
+
+bool ScalpelSaveManager::checkGameOnScreen(int slot) {
+ ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+
+ // Check if it's already on-screen
+ if (slot != -1 && (slot < _savegameIndex || slot >= (_savegameIndex + ONSCREEN_FILES_COUNT))) {
+ _savegameIndex = slot;
+
+ screen._backBuffer1.fillRect(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2,
+ SHERLOCK_SCREEN_HEIGHT - 1), INV_BACKGROUND);
+
+ for (int idx = _savegameIndex; idx < (_savegameIndex + 5); ++idx) {
+ screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (idx - _savegameIndex) * 10),
+ INV_FOREGROUND, "%d.", idx + 1);
+ screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (idx - _savegameIndex) * 10),
+ INV_FOREGROUND, "%s", _savegames[idx].c_str());
+ }
+
+ screen.slamRect(Common::Rect(3, CONTROLS_Y + 11, 318, SHERLOCK_SCREEN_HEIGHT));
+
+ byte color = !_savegameIndex ? COMMAND_NULL : COMMAND_FOREGROUND;
+ screen.buttonPrint(Common::Point(ENV_POINTS[3][2], CONTROLS_Y), color, 1, "Up");
+
+ color = (_savegameIndex == (MAX_SAVEGAME_SLOTS - 5)) ? COMMAND_NULL : COMMAND_FOREGROUND;
+ screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), color, 1, "Down");
+
+ return true;
+ }
+
+ return false;
+}
+
+bool ScalpelSaveManager::promptForDescription(int slot) {
+ Events &events = *_vm->_events;
+ Scene &scene = *_vm->_scene;
+ ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+ Talk &talk = *_vm->_talk;
+ int xp, yp;
+ bool flag = false;
+
+ screen.buttonPrint(Common::Point(ENV_POINTS[0][2], CONTROLS_Y), COMMAND_NULL, true, "Exit");
+ screen.buttonPrint(Common::Point(ENV_POINTS[1][2], CONTROLS_Y), COMMAND_NULL, true, "Load");
+ screen.buttonPrint(Common::Point(ENV_POINTS[2][2], CONTROLS_Y), COMMAND_NULL, true, "Save");
+ screen.buttonPrint(Common::Point(ENV_POINTS[3][2], CONTROLS_Y), COMMAND_NULL, true, "Up");
+ screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), COMMAND_NULL, true, "Down");
+ screen.buttonPrint(Common::Point(ENV_POINTS[5][2], CONTROLS_Y), COMMAND_NULL, true, "Quit");
+
+ Common::String saveName = _savegames[slot];
+ if (isSlotEmpty(slot)) {
+ // It's an empty slot, so start off with an empty save name
+ saveName = "";
+
+ yp = CONTROLS_Y + 12 + (slot - _savegameIndex) * 10;
+ screen.vgaBar(Common::Rect(24, yp, 85, yp + 9), INV_BACKGROUND);
+ }
+
+ screen.print(Common::Point(6, CONTROLS_Y + 12 + (slot - _savegameIndex) * 10), TALK_FOREGROUND, "%d.", slot + 1);
+ screen.print(Common::Point(24, CONTROLS_Y + 12 + (slot - _savegameIndex) * 10), TALK_FOREGROUND, "%s", saveName.c_str());
+ xp = 24 + screen.stringWidth(saveName);
+ yp = CONTROLS_Y + 12 + (slot - _savegameIndex) * 10;
+
+ int done = 0;
+ do {
+ while (!_vm->shouldQuit() && !events.kbHit()) {
+ scene.doBgAnim();
+
+ if (talk._talkToAbort)
+ return false;
+
+ // Allow event processing
+ events.pollEventsAndWait();
+ events.setButtonState();
+
+ flag = !flag;
+ if (flag)
+ screen.vgaBar(Common::Rect(xp, yp - 1, xp + 8, yp + 9), INV_FOREGROUND);
+ else
+ screen.vgaBar(Common::Rect(xp, yp - 1, xp + 8, yp + 9), INV_BACKGROUND);
+ }
+ if (_vm->shouldQuit())
+ return false;
+
+ // Get the next keypress
+ Common::KeyState keyState = events.getKey();
+
+ if (keyState.keycode == Common::KEYCODE_BACKSPACE && saveName.size() > 0) {
+ // Delete character of save name
+ screen.vgaBar(Common::Rect(xp - screen.charWidth(saveName.lastChar()), yp - 1,
+ xp + 8, yp + 9), INV_BACKGROUND);
+ xp -= screen.charWidth(saveName.lastChar());
+ screen.vgaBar(Common::Rect(xp, yp - 1, xp + 8, yp + 9), INV_FOREGROUND);
+ saveName.deleteLastChar();
+
+ } else if (keyState.keycode == Common::KEYCODE_RETURN && saveName.compareToIgnoreCase(EMPTY_SAVEGAME_SLOT)) {
+ done = 1;
+
+ } else if (keyState.keycode == Common::KEYCODE_ESCAPE) {
+ screen.vgaBar(Common::Rect(xp, yp - 1, xp + 8, yp + 9), INV_BACKGROUND);
+ done = -1;
+
+ } else if (keyState.ascii >= ' ' && keyState.ascii <= 'z' && saveName.size() < 50
+ && (xp + screen.charWidth(keyState.ascii)) < 308) {
+ char c = (char)keyState.ascii;
+
+ screen.vgaBar(Common::Rect(xp, yp - 1, xp + 8, yp + 9), INV_BACKGROUND);
+ screen.print(Common::Point(xp, yp), TALK_FOREGROUND, "%c", c);
+ xp += screen.charWidth(c);
+ screen.vgaBar(Common::Rect(xp, yp - 1, xp + 8, yp + 9), INV_FOREGROUND);
+ saveName += c;
+ }
+ } while (!done);
+
+ if (done == 1) {
+ // Enter key perssed
+ _savegames[slot] = saveName;
+ } else {
+ done = 0;
+ _envMode = SAVEMODE_NONE;
+ highlightButtons(-1);
+ }
+
+ return done == 1;
+}
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/scalpel/scalpel_saveload.h b/engines/sherlock/scalpel/scalpel_saveload.h
new file mode 100644
index 0000000000..db4fa1a2ab
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_saveload.h
@@ -0,0 +1,69 @@
+/* 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 SHERLOCK_SCALPEL_SAVELOAD_H
+#define SHERLOCK_SCALPEL_SAVELOAD_H
+
+#include "sherlock/saveload.h"
+
+namespace Sherlock {
+
+namespace Scalpel {
+
+extern const int ENV_POINTS[6][3];
+
+class ScalpelSaveManager: public SaveManager {
+public:
+ ScalpelSaveManager(SherlockEngine *vm, const Common::String &target);
+ virtual ~ScalpelSaveManager() {}
+
+ /**
+ * Shows the in-game dialog interface for loading and saving games
+ */
+ void drawInterface();
+
+ /**
+ * Return the index of the button the mouse is over, if any
+ */
+ int getHighlightedButton() const;
+
+ /**
+ * Handle highlighting buttons
+ */
+ void highlightButtons(int btnIndex);
+
+ /**
+ * Make sure that the selected savegame is on-screen
+ */
+ bool checkGameOnScreen(int slot);
+
+ /**
+ * Prompts the user to enter a description in a given slot
+ */
+ bool promptForDescription(int slot);
+};
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/scalpel/scalpel_scene.cpp b/engines/sherlock/scalpel/scalpel_scene.cpp
new file mode 100644
index 0000000000..4e6e9e4c7c
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_scene.cpp
@@ -0,0 +1,726 @@
+/* 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 "sherlock/scalpel/scalpel_scene.h"
+#include "sherlock/scalpel/scalpel_map.h"
+#include "sherlock/scalpel/scalpel_people.h"
+#include "sherlock/scalpel/scalpel_user_interface.h"
+#include "sherlock/scalpel/scalpel.h"
+#include "sherlock/events.h"
+#include "sherlock/people.h"
+#include "sherlock/screen.h"
+#include "sherlock/sherlock.h"
+
+namespace Sherlock {
+
+namespace Scalpel {
+
+bool ScalpelScene::loadScene(const Common::String &filename) {
+ ScalpelMap &map = *(ScalpelMap *)_vm->_map;
+ bool result = Scene::loadScene(filename);
+
+ if (!_vm->isDemo()) {
+ // Reset the previous map location and position on overhead map
+ map._oldCharPoint = _currentScene;
+
+ map._overPos.x = (map[_currentScene].x - 6) * FIXED_INT_MULTIPLIER;
+ map._overPos.y = (map[_currentScene].y + 9) * FIXED_INT_MULTIPLIER;
+
+ }
+
+ return result;
+}
+
+void ScalpelScene::drawAllShapes() {
+ People &people = *_vm->_people;
+ Screen &screen = *_vm->_screen;
+
+ // Restrict drawing window
+ screen.setDisplayBounds(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT));
+
+ // Draw all active shapes which are behind the person
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ if (_bgShapes[idx]._type == ACTIVE_BG_SHAPE && _bgShapes[idx]._misc == BEHIND)
+ screen._backBuffer->transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & OBJ_FLIPPED);
+ }
+
+ // Draw all canimations which are behind the person
+ for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
+ if (_canimShapes[idx]._type == ACTIVE_BG_SHAPE && _canimShapes[idx]._misc == BEHIND)
+ screen._backBuffer->transBlitFrom(*_canimShapes[idx]._imageFrame,
+ _canimShapes[idx]._position, _canimShapes[idx]._flags & OBJ_FLIPPED);
+ }
+
+ // Draw all active shapes which are normal and behind the person
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ if (_bgShapes[idx]._type == ACTIVE_BG_SHAPE && _bgShapes[idx]._misc == NORMAL_BEHIND)
+ screen._backBuffer->transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & OBJ_FLIPPED);
+ }
+
+ // Draw all canimations which are normal and behind the person
+ for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
+ if (_canimShapes[idx]._type == ACTIVE_BG_SHAPE && _canimShapes[idx]._misc == NORMAL_BEHIND)
+ screen._backBuffer->transBlitFrom(*_canimShapes[idx]._imageFrame, _canimShapes[idx]._position,
+ _canimShapes[idx]._flags & OBJ_FLIPPED);
+ }
+
+ // Draw any active characters
+ for (int idx = 0; idx < MAX_CHARACTERS; ++idx) {
+ Person &p = people[idx];
+ if (p._type == CHARACTER && p._walkLoaded) {
+ bool flipped = IS_SERRATED_SCALPEL && (
+ p._sequenceNumber == WALK_LEFT || p._sequenceNumber == STOP_LEFT ||
+ p._sequenceNumber == WALK_UPLEFT || p._sequenceNumber == STOP_UPLEFT ||
+ p._sequenceNumber == WALK_DOWNRIGHT || p._sequenceNumber == STOP_DOWNRIGHT);
+
+ screen._backBuffer->transBlitFrom(*p._imageFrame, Common::Point(p._position.x / FIXED_INT_MULTIPLIER,
+ p._position.y / FIXED_INT_MULTIPLIER - p.frameHeight()), flipped);
+ }
+ }
+
+ // Draw all static and active shapes that are NORMAL and are in front of the player
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ if ((_bgShapes[idx]._type == ACTIVE_BG_SHAPE || _bgShapes[idx]._type == STATIC_BG_SHAPE) &&
+ _bgShapes[idx]._misc == NORMAL_FORWARD)
+ screen._backBuffer->transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position,
+ _bgShapes[idx]._flags & OBJ_FLIPPED);
+ }
+
+ // Draw all static and active canimations that are NORMAL and are in front of the player
+ for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
+ if ((_canimShapes[idx]._type == ACTIVE_BG_SHAPE || _canimShapes[idx]._type == STATIC_BG_SHAPE) &&
+ _canimShapes[idx]._misc == NORMAL_FORWARD)
+ screen._backBuffer->transBlitFrom(*_canimShapes[idx]._imageFrame, _canimShapes[idx]._position,
+ _canimShapes[idx]._flags & OBJ_FLIPPED);
+ }
+
+ // Draw all static and active shapes that are FORWARD
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ _bgShapes[idx]._oldPosition = _bgShapes[idx]._position;
+ _bgShapes[idx]._oldSize = Common::Point(_bgShapes[idx].frameWidth(),
+ _bgShapes[idx].frameHeight());
+
+ if ((_bgShapes[idx]._type == ACTIVE_BG_SHAPE || _bgShapes[idx]._type == STATIC_BG_SHAPE) &&
+ _bgShapes[idx]._misc == FORWARD)
+ screen._backBuffer->transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position,
+ _bgShapes[idx]._flags & OBJ_FLIPPED);
+ }
+
+ // Draw all static and active canimations that are forward
+ for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
+ if ((_canimShapes[idx]._type == ACTIVE_BG_SHAPE || _canimShapes[idx]._type == STATIC_BG_SHAPE) &&
+ _canimShapes[idx]._misc == FORWARD)
+ screen._backBuffer->transBlitFrom(*_canimShapes[idx]._imageFrame, _canimShapes[idx]._position,
+ _canimShapes[idx]._flags & OBJ_FLIPPED);
+ }
+
+ screen.resetDisplayBounds();
+}
+
+void ScalpelScene::checkBgShapes() {
+ People &people = *_vm->_people;
+ Person &holmes = people[HOLMES];
+ Common::Point pt(holmes._position.x / FIXED_INT_MULTIPLIER, holmes._position.y / FIXED_INT_MULTIPLIER);
+
+ // Call the base scene method to handle bg shapes
+ Scene::checkBgShapes();
+
+ // Iterate through the canim list
+ for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
+ Object &obj = _canimShapes[idx];
+ if (obj._type == STATIC_BG_SHAPE || obj._type == ACTIVE_BG_SHAPE) {
+ if ((obj._flags & 5) == 1) {
+ obj._misc = (pt.y < (obj._position.y + obj._imageFrame->_frame.h - 1)) ?
+ NORMAL_FORWARD : NORMAL_BEHIND;
+ } else if (!(obj._flags & 1)) {
+ obj._misc = BEHIND;
+ } else if (obj._flags & 4) {
+ obj._misc = FORWARD;
+ }
+ }
+ }
+}
+
+void ScalpelScene::doBgAnimCheckCursor() {
+ Inventory &inv = *_vm->_inventory;
+ Events &events = *_vm->_events;
+ Sound &sound = *_vm->_sound;
+ UserInterface &ui = *_vm->_ui;
+ Common::Point mousePos = events.mousePos();
+ events.animateCursorIfNeeded();
+
+ if (ui._menuMode == LOOK_MODE) {
+ if (mousePos.y > CONTROLS_Y1)
+ events.setCursor(ARROW);
+ else if (mousePos.y < CONTROLS_Y)
+ events.setCursor(MAGNIFY);
+ }
+
+ // Check for setting magnifying glass cursor
+ if (ui._menuMode == INV_MODE || ui._menuMode == USE_MODE || ui._menuMode == GIVE_MODE) {
+ if (inv._invMode == INVMODE_LOOK) {
+ // Only show Magnifying glass cursor if it's not on the inventory command line
+ if (mousePos.y < CONTROLS_Y || mousePos.y >(CONTROLS_Y1 + 13))
+ events.setCursor(MAGNIFY);
+ else
+ events.setCursor(ARROW);
+ } else {
+ events.setCursor(ARROW);
+ }
+ }
+
+ if (sound._diskSoundPlaying && !*sound._soundIsOn) {
+ // Loaded sound just finished playing
+ sound.freeDigiSound();
+ }
+}
+
+void ScalpelScene::doBgAnim() {
+ ScalpelEngine &vm = *((ScalpelEngine *)_vm);
+ Events &events = *_vm->_events;
+ People &people = *_vm->_people;
+ Screen &screen = *_vm->_screen;
+ Talk &talk = *_vm->_talk;
+
+ doBgAnimCheckCursor();
+
+ screen.setDisplayBounds(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT));
+ talk._talkToAbort = false;
+
+ if (_restoreFlag) {
+ for (int idx = 0; idx < MAX_CHARACTERS; ++idx) {
+ if (people[idx]._type == CHARACTER)
+ people[idx].checkSprite();
+ }
+
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ if (_bgShapes[idx]._type == ACTIVE_BG_SHAPE)
+ _bgShapes[idx].checkObject();
+ }
+
+ if (people._portraitLoaded && people._portrait._type == ACTIVE_BG_SHAPE)
+ people._portrait.checkObject();
+
+ for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
+ if (_canimShapes[idx]._type != INVALID && _canimShapes[idx]._type != REMOVE)
+ _canimShapes[idx].checkObject();
+ }
+
+ if (_currentScene == 12)
+ vm.eraseMirror12();
+
+ // Restore the back buffer from the back buffer 2 in the changed area
+ Common::Rect bounds(people[HOLMES]._oldPosition.x, people[HOLMES]._oldPosition.y,
+ people[HOLMES]._oldPosition.x + people[HOLMES]._oldSize.x,
+ people[HOLMES]._oldPosition.y + people[HOLMES]._oldSize.y);
+ Common::Point pt(bounds.left, bounds.top);
+
+ if (people[HOLMES]._type == CHARACTER)
+ screen.restoreBackground(bounds);
+ else if (people[HOLMES]._type == REMOVE)
+ screen._backBuffer->blitFrom(screen._backBuffer2, pt, bounds);
+
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ Object &o = _bgShapes[idx];
+ if (o._type == ACTIVE_BG_SHAPE || o._type == HIDE_SHAPE || o._type == REMOVE)
+ screen.restoreBackground(o.getOldBounds());
+ }
+
+ if (people._portraitLoaded)
+ screen.restoreBackground(Common::Rect(
+ people._portrait._oldPosition.x, people._portrait._oldPosition.y,
+ people._portrait._oldPosition.x + people._portrait._oldSize.x,
+ people._portrait._oldPosition.y + people._portrait._oldSize.y
+ ));
+
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ Object &o = _bgShapes[idx];
+ if (o._type == NO_SHAPE && ((o._flags & OBJ_BEHIND) == 0)) {
+ // Restore screen area
+ screen._backBuffer->blitFrom(screen._backBuffer2, o._position,
+ Common::Rect(o._position.x, o._position.y,
+ o._position.x + o._noShapeSize.x, o._position.y + o._noShapeSize.y));
+
+ o._oldPosition = o._position;
+ o._oldSize = o._noShapeSize;
+ }
+ }
+
+ for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
+ Object &o = _canimShapes[idx];
+ if (o._type == ACTIVE_BG_SHAPE || o._type == HIDE_SHAPE || o._type == REMOVE)
+ screen.restoreBackground(Common::Rect(o._oldPosition.x, o._oldPosition.y,
+ o._oldPosition.x + o._oldSize.x, o._oldPosition.y + o._oldSize.y));
+ }
+ }
+
+ //
+ // Update the background objects and canimations
+ //
+
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ Object &o = _bgShapes[idx];
+ if (o._type == ACTIVE_BG_SHAPE || o._type == NO_SHAPE)
+ o.adjustObject();
+ }
+
+ if (people._portraitLoaded && people._portrait._type == ACTIVE_BG_SHAPE)
+ people._portrait.adjustObject();
+
+ for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
+ if (_canimShapes[idx]._type != INVALID)
+ _canimShapes[idx].adjustObject();
+ }
+
+ if (people[HOLMES]._type == CHARACTER && people._holmesOn)
+ people[HOLMES].adjustSprite();
+
+ // Flag the bg shapes which need to be redrawn
+ checkBgShapes();
+
+ if (_currentScene == 12)
+ vm.doMirror12();
+
+ // Draw all active shapes which are behind the person
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ Object &o = _bgShapes[idx];
+ if (o._type == ACTIVE_BG_SHAPE && o._misc == BEHIND)
+ screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED);
+ }
+
+ // Draw all canimations which are behind the person
+ for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
+ Object &o = _canimShapes[idx];
+ if (o._type == ACTIVE_BG_SHAPE && o._misc == BEHIND) {
+ screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED);
+ }
+ }
+
+ // Draw all active shapes which are HAPPEN and behind the person
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ Object &o = _bgShapes[idx];
+ if (o._type == ACTIVE_BG_SHAPE && o._misc == NORMAL_BEHIND)
+ screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED);
+ }
+
+ // Draw all canimations which are NORMAL and behind the person
+ for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
+ Object &o = _canimShapes[idx];
+ if (o._type == ACTIVE_BG_SHAPE && o._misc == NORMAL_BEHIND) {
+ screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED);
+ }
+ }
+
+ // Draw the person if not animating
+ if (people[HOLMES]._type == CHARACTER && people[HOLMES]._walkLoaded) {
+ // If Holmes is too far to the right, move him back so he's on-screen
+ int xRight = SHERLOCK_SCREEN_WIDTH - 2 - people[HOLMES]._imageFrame->_frame.w;
+ int tempX = MIN(people[HOLMES]._position.x / FIXED_INT_MULTIPLIER, xRight);
+
+ bool flipped = people[HOLMES]._sequenceNumber == WALK_LEFT || people[HOLMES]._sequenceNumber == STOP_LEFT ||
+ people[HOLMES]._sequenceNumber == WALK_UPLEFT || people[HOLMES]._sequenceNumber == STOP_UPLEFT ||
+ people[HOLMES]._sequenceNumber == WALK_DOWNRIGHT || people[HOLMES]._sequenceNumber == STOP_DOWNRIGHT;
+ screen._backBuffer->transBlitFrom(*people[HOLMES]._imageFrame,
+ Common::Point(tempX, people[HOLMES]._position.y / FIXED_INT_MULTIPLIER - people[HOLMES]._imageFrame->_frame.h), flipped);
+ }
+
+ // Draw all static and active shapes are NORMAL and are in front of the person
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ Object &o = _bgShapes[idx];
+ if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == NORMAL_FORWARD)
+ screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED);
+ }
+
+ // Draw all static and active canimations that are NORMAL and are in front of the person
+ for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
+ Object &o = _canimShapes[idx];
+ if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == NORMAL_FORWARD) {
+ screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED);
+ }
+ }
+
+ // Draw all static and active shapes that are in front of the person
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ Object &o = _bgShapes[idx];
+ if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == FORWARD)
+ screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED);
+ }
+
+ // Draw any active portrait
+ if (people._portraitLoaded && people._portrait._type == ACTIVE_BG_SHAPE)
+ screen._backBuffer->transBlitFrom(*people._portrait._imageFrame,
+ people._portrait._position, people._portrait._flags & OBJ_FLIPPED);
+
+ // Draw all static and active canimations that are in front of the person
+ for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
+ Object &o = _canimShapes[idx];
+ if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == FORWARD) {
+ screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED);
+ }
+ }
+
+ // Draw all NO_SHAPE shapes which have flag bit 0 clear
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ Object &o = _bgShapes[idx];
+ if (o._type == NO_SHAPE && (o._flags & OBJ_BEHIND) == 0)
+ screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED);
+ }
+
+ // Bring the newly built picture to the screen
+ if (_animating == 2) {
+ _animating = 0;
+ screen.slamRect(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT));
+ } else {
+ if (people[HOLMES]._type != INVALID && ((_goToScene == -1 || _canimShapes.empty()))) {
+ if (people[HOLMES]._type == REMOVE) {
+ screen.slamRect(Common::Rect(
+ people[HOLMES]._oldPosition.x, people[HOLMES]._oldPosition.y,
+ people[HOLMES]._oldPosition.x + people[HOLMES]._oldSize.x,
+ people[HOLMES]._oldPosition.y + people[HOLMES]._oldSize.y
+ ));
+ people[HOLMES]._type = INVALID;
+ } else {
+ screen.flushImage(people[HOLMES]._imageFrame,
+ Common::Point(people[HOLMES]._position.x / FIXED_INT_MULTIPLIER,
+ people[HOLMES]._position.y / FIXED_INT_MULTIPLIER - people[HOLMES].frameHeight()),
+ &people[HOLMES]._oldPosition.x, &people[HOLMES]._oldPosition.y,
+ &people[HOLMES]._oldSize.x, &people[HOLMES]._oldSize.y);
+ }
+ }
+
+ if (_currentScene == 12)
+ vm.flushMirror12();
+
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ Object &o = _bgShapes[idx];
+ if ((o._type == ACTIVE_BG_SHAPE || o._type == REMOVE) && _goToScene == -1) {
+ screen.flushImage(o._imageFrame, o._position,
+ &o._oldPosition.x, &o._oldPosition.y, &o._oldSize.x, &o._oldSize.y);
+ }
+ }
+
+ if (people._portraitLoaded) {
+ if (people._portrait._type == REMOVE)
+ screen.slamRect(Common::Rect(
+ people._portrait._position.x, people._portrait._position.y,
+ people._portrait._position.x + people._portrait._delta.x,
+ people._portrait._position.y + people._portrait._delta.y
+ ));
+ else
+ screen.flushImage(people._portrait._imageFrame, people._portrait._position,
+ &people._portrait._oldPosition.x, &people._portrait._oldPosition.y,
+ &people._portrait._oldSize.x, &people._portrait._oldSize.y);
+
+ if (people._portrait._type == REMOVE)
+ people._portrait._type = INVALID;
+ }
+
+ if (_goToScene == -1) {
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ Object &o = _bgShapes[idx];
+ if (o._type == NO_SHAPE && (o._flags & OBJ_BEHIND) == 0) {
+ screen.slamArea(o._position.x, o._position.y, o._oldSize.x, o._oldSize.y);
+ screen.slamArea(o._oldPosition.x, o._oldPosition.y, o._oldSize.x, o._oldSize.y);
+ } else if (o._type == HIDE_SHAPE) {
+ // Hiding shape, so flush it out and mark it as hidden
+ screen.flushImage(o._imageFrame, o._position,
+ &o._oldPosition.x, &o._oldPosition.y, &o._oldSize.x, &o._oldSize.y);
+ o._type = HIDDEN;
+ }
+ }
+ }
+
+ for (int idx = _canimShapes.size() - 1; idx >= 0; --idx) {
+ Object &o = _canimShapes[idx];
+
+ if (o._type == INVALID) {
+ // Anim shape was invalidated by checkEndOfSequence, so at this point we can remove it
+ _canimShapes.remove_at(idx);
+ } else if (o._type == REMOVE) {
+ if (_goToScene == -1)
+ screen.slamArea(o._position.x, o._position.y, o._delta.x, o._delta.y);
+
+ // Shape for an animation is no longer needed, so remove it completely
+ _canimShapes.remove_at(idx);
+ } else if (o._type == ACTIVE_BG_SHAPE) {
+ screen.flushImage(o._imageFrame, o._position,
+ &o._oldPosition.x, &o._oldPosition.y, &o._oldSize.x, &o._oldSize.y);
+ }
+ }
+ }
+
+ _restoreFlag = true;
+ _doBgAnimDone = true;
+
+ events.wait(3);
+ screen.resetDisplayBounds();
+
+ // Check if the method was called for calling a portrait, and a talk was
+ // interrupting it. This talk file would not have been executed at the time,
+ // since we needed to finish the 'doBgAnim' to finish clearing the portrait
+ if (people._clearingThePortrait && talk._scriptMoreFlag == 3) {
+ // Reset the flags and call to talk
+ people._clearingThePortrait = false;
+ talk._scriptMoreFlag = 0;
+ talk.talkTo(talk._scriptName);
+ }
+}
+
+int ScalpelScene::startCAnim(int cAnimNum, int playRate) {
+ Events &events = *_vm->_events;
+ ScalpelMap &map = *(ScalpelMap *)_vm->_map;
+ People &people = *_vm->_people;
+ Resources &res = *_vm->_res;
+ Talk &talk = *_vm->_talk;
+ ScalpelUserInterface &ui = *(ScalpelUserInterface *)_vm->_ui;
+ Point32 tpPos, walkPos;
+ int tpDir, walkDir;
+ int tFrames = 0;
+ int gotoCode = -1;
+
+ // Validation
+ if (cAnimNum >= (int)_cAnim.size())
+ // number out of bounds
+ return -1;
+ if (_canimShapes.size() >= 3 || playRate == 0)
+ // Too many active animations, or invalid play rate
+ return 0;
+
+ CAnim &cAnim = _cAnim[cAnimNum];
+ if (playRate < 0) {
+ // Reverse direction
+ walkPos = cAnim._teleport[0];
+ walkDir = cAnim._teleport[0]._facing;
+ tpPos = cAnim._goto[0];
+ tpDir = cAnim._goto[0]._facing;
+ } else {
+ // Forward direction
+ walkPos = cAnim._goto[0];
+ walkDir = cAnim._goto[0]._facing;
+ tpPos = cAnim._teleport[0];
+ tpDir = cAnim._teleport[0]._facing;
+ }
+
+ CursorId oldCursor = events.getCursor();
+ events.setCursor(WAIT);
+
+ if (walkPos.x != -1) {
+ // Holmes must walk to the walk point before the cAnimation is started
+ if (people[HOLMES]._position != walkPos)
+ people[HOLMES].walkToCoords(walkPos, walkDir);
+ }
+
+ if (talk._talkToAbort)
+ return 1;
+
+ // Add new anim shape entry for displaying the animation
+ _canimShapes.push_back(Object());
+ Object &cObj = _canimShapes[_canimShapes.size() - 1];
+
+ // Copy the canimation into the bgShapes type canimation structure so it can be played
+ cObj._allow = cAnimNum + 1; // Keep track of the parent structure
+ cObj._name = _cAnim[cAnimNum]._name; // Copy name
+
+ // Remove any attempt to draw object frame
+ if (cAnim._type == NO_SHAPE && cAnim._sequences[0] < 100)
+ cAnim._sequences[0] = 0;
+
+ cObj._sequences = cAnim._sequences;
+ cObj._images = nullptr;
+ cObj._position = cAnim._position;
+ cObj._delta = Common::Point(0, 0);
+ cObj._type = cAnim._type;
+ cObj._flags = cAnim._flags;
+
+ cObj._maxFrames = 0;
+ cObj._frameNumber = -1;
+ cObj._sequenceNumber = cAnimNum;
+ cObj._oldPosition = Common::Point(0, 0);
+ cObj._oldSize = Common::Point(0, 0);
+ cObj._goto = Common::Point(0, 0);
+ cObj._status = 0;
+ cObj._misc = 0;
+ cObj._imageFrame = nullptr;
+
+ if (cAnim._name.size() > 0 && cAnim._type != NO_SHAPE) {
+ if (tpPos.x != -1)
+ people[HOLMES]._type = REMOVE;
+
+ Common::String fname = cAnim._name + ".vgs";
+ if (!res.isInCache(fname)) {
+ // Set up RRM scene data
+ Common::SeekableReadStream *roomStream = res.load(_roomFilename);
+ roomStream->seek(cAnim._dataOffset);
+ //rrmStream->seek(44 + cAnimNum * 4);
+ //rrmStream->seek(rrmStream->readUint32LE());
+
+ // Load the canimation into the cache
+ Common::SeekableReadStream *imgStream = !_compressed ? roomStream->readStream(cAnim._dataSize) :
+ Resources::decompressLZ(*roomStream, cAnim._dataSize);
+ res.addToCache(fname, *imgStream);
+
+ delete imgStream;
+ delete roomStream;
+ }
+
+ // Now load the resource as an image
+ if (!IS_3DO) {
+ cObj._images = new ImageFile(fname);
+ } else {
+ cObj._images = new ImageFile3DO(fname, kImageFile3DOType_RoomFormat);
+ }
+ cObj._imageFrame = &(*cObj._images)[0];
+ cObj._maxFrames = cObj._images->size();
+
+ int frames = 0;
+ if (playRate < 0) {
+ // Reverse direction
+ // Count number of frames
+ while (frames < MAX_FRAME && cObj._sequences[frames])
+ ++frames;
+ } else {
+ // Forward direction
+ BaseObject::_countCAnimFrames = true;
+
+ while (cObj._type == ACTIVE_BG_SHAPE) {
+ cObj.checkObject();
+ ++frames;
+
+ if (frames >= 1000)
+ error("CAnim has infinite loop sequence");
+ }
+
+ if (frames > 1)
+ --frames;
+
+ BaseObject::_countCAnimFrames = false;
+
+ cObj._type = cAnim._type;
+ cObj._frameNumber = -1;
+ cObj._position = cAnim._position;
+ cObj._delta = Common::Point(0, 0);
+ }
+
+ // Return if animation has no frames in it
+ if (frames == 0)
+ return -2;
+
+ ++frames;
+ int repeat = ABS(playRate);
+ int dir;
+
+ if (playRate < 0) {
+ // Play in reverse
+ dir = -2;
+ cObj._frameNumber = frames - 3;
+ } else {
+ dir = 0;
+ }
+
+ tFrames = frames - 1;
+ int pauseFrame = (_cAnimFramePause) ? frames - _cAnimFramePause : -1;
+
+ while (--frames) {
+ if (frames == pauseFrame)
+ ui.printObjectDesc();
+
+ doBgAnim();
+
+ // Repeat same frame
+ int temp = repeat;
+ while (--temp > 0) {
+ cObj._frameNumber--;
+ doBgAnim();
+
+ if (_vm->shouldQuit())
+ return 0;
+ }
+
+ cObj._frameNumber += dir;
+ }
+
+ people[HOLMES]._type = CHARACTER;
+ }
+
+ // Teleport to ending coordinates if necessary
+ if (tpPos.x != -1) {
+ people[HOLMES]._position = tpPos; // Place the player
+ people[HOLMES]._sequenceNumber = tpDir;
+ people[HOLMES].gotoStand();
+ }
+
+ if (playRate < 0)
+ // Reverse direction - set to end sequence
+ cObj._frameNumber = tFrames - 1;
+
+ if (cObj._frameNumber <= 26)
+ gotoCode = cObj._sequences[cObj._frameNumber + 3];
+
+ // Unless anim shape has already been freed, set it to REMOVE so doBgAnim can free it
+ if (_canimShapes.indexOf(cObj) != -1)
+ cObj.checkObject();
+
+ if (gotoCode > 0 && !talk._talkToAbort) {
+ _goToScene = gotoCode;
+
+ if (_goToScene < 97 && map[_goToScene].x) {
+ map._overPos = map[_goToScene];
+ }
+ }
+
+ people.loadWalk();
+
+ if (tpPos.x != -1 && !talk._talkToAbort) {
+ // Teleport to ending coordinates
+ people[HOLMES]._position = tpPos;
+ people[HOLMES]._sequenceNumber = tpDir;
+
+ people[HOLMES].gotoStand();
+ }
+
+ events.setCursor(oldCursor);
+
+ return 1;
+}
+
+int ScalpelScene::closestZone(const Common::Point &pt) {
+ int dist = 1000;
+ int zone = -1;
+
+ for (uint idx = 0; idx < _zones.size(); ++idx) {
+ Common::Point zc((_zones[idx].left + _zones[idx].right) / 2,
+ (_zones[idx].top + _zones[idx].bottom) / 2);
+ int d = ABS(zc.x - pt.x) + ABS(zc.y - pt.y);
+
+ if (d < dist) {
+ // Found a closer zone
+ dist = d;
+ zone = idx;
+ }
+ }
+
+ return zone;
+}
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/scalpel/scalpel_scene.h b/engines/sherlock/scalpel/scalpel_scene.h
new file mode 100644
index 0000000000..fa65ecd95b
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_scene.h
@@ -0,0 +1,96 @@
+/* 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 SHERLOCK_SCALPEL_SCENE_H
+#define SHERLOCK_SCALPEL_SCENE_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/rect.h"
+#include "common/serializer.h"
+#include "sherlock/objects.h"
+#include "sherlock/scene.h"
+#include "sherlock/screen.h"
+
+namespace Sherlock {
+
+namespace Scalpel {
+
+enum { BLACKWOOD_CAPTURE = 2, BAKER_STREET = 4, DRAWING_ROOM = 12, STATION = 17, PUB_INTERIOR = 19,
+ LAWYER_OFFICE = 27, BAKER_ST_EXTERIOR = 39, RESCUE_ANNA = 52, MOOREHEAD_DEATH = 53, EXIT_GAME = 55,
+ BRUMWELL_SUICIDE = 70, OVERHEAD_MAP2 = 98, DARTS_GAME = 99, OVERHEAD_MAP = 100 };
+
+class ScalpelScene : public Scene {
+private:
+ void doBgAnimCheckCursor();
+protected:
+ /**
+ * Loads the data associated for a given scene. The room resource file's format is:
+ * BGHEADER: Holds an index for the rest of the file
+ * STRUCTS: The objects for the scene
+ * IMAGES: The graphic information for the structures
+ *
+ * The _misc field of the structures contains the number of the graphic image
+ * that it should point to after loading; _misc is then set to 0.
+ */
+ virtual bool loadScene(const Common::String &filename);
+
+ /**
+ * Checks all the background shapes. If a background shape is animating,
+ * it will flag it as needing to be drawn. If a non-animating shape is
+ * colliding with another shape, it will also flag it as needing drawing
+ */
+ virtual void checkBgShapes();
+
+ /**
+ * Draw all the shapes, people and NPCs in the correct order
+ */
+ virtual void drawAllShapes();
+
+ /**
+ * Returns the index of the closest zone to a given point.
+ */
+ virtual int closestZone(const Common::Point &pt);
+public:
+ ScalpelScene(SherlockEngine *vm) : Scene(vm) {}
+
+ /**
+ * Draw all objects and characters.
+ */
+ virtual void doBgAnim();
+
+ /**
+ * Attempt to start a canimation sequence. It will load the requisite graphics, and
+ * then copy the canim object into the _canimShapes array to start the animation.
+ *
+ * @param cAnimNum The canim object within the current scene
+ * @param playRate Play rate. 0 is invalid; 1=normal speed, 2=1/2 speed, etc.
+ * A negative playRate can also be specified to play the animation in reverse
+ */
+ virtual int startCAnim(int cAnimNum, int playRate = 1);
+};
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/scalpel/scalpel_screen.cpp b/engines/sherlock/scalpel/scalpel_screen.cpp
new file mode 100644
index 0000000000..2096dabcdf
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_screen.cpp
@@ -0,0 +1,93 @@
+/* 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 "sherlock/scalpel/scalpel_screen.h"
+#include "sherlock/scalpel/scalpel.h"
+
+namespace Sherlock {
+
+namespace Scalpel {
+
+ScalpelScreen::ScalpelScreen(SherlockEngine *vm) : Screen(vm) {
+}
+
+void ScalpelScreen::makeButton(const Common::Rect &bounds, int textX,
+ const Common::String &str) {
+
+ Surface &bb = *_backBuffer;
+ bb.fillRect(Common::Rect(bounds.left, bounds.top, bounds.right, bounds.top + 1), BUTTON_TOP);
+ bb.fillRect(Common::Rect(bounds.left, bounds.top, bounds.left + 1, bounds.bottom), BUTTON_TOP);
+ bb.fillRect(Common::Rect(bounds.right - 1, bounds.top, bounds.right, bounds.bottom), BUTTON_BOTTOM);
+ bb.fillRect(Common::Rect(bounds.left + 1, bounds.bottom - 1, bounds.right, bounds.bottom), BUTTON_BOTTOM);
+ bb.fillRect(Common::Rect(bounds.left + 1, bounds.top + 1, bounds.right - 1, bounds.bottom - 1), BUTTON_MIDDLE);
+
+ gPrint(Common::Point(textX, bounds.top), COMMAND_HIGHLIGHTED, "%c", str[0]);
+ gPrint(Common::Point(textX + charWidth(str[0]), bounds.top),
+ COMMAND_FOREGROUND, "%s", str.c_str() + 1);
+}
+
+void ScalpelScreen::buttonPrint(const Common::Point &pt, byte color, bool slamIt,
+ const Common::String &str) {
+ int xStart = pt.x - stringWidth(str) / 2;
+
+ if (color == COMMAND_FOREGROUND) {
+ // First character needs to be highlighted
+ if (slamIt) {
+ print(Common::Point(xStart, pt.y + 1), COMMAND_HIGHLIGHTED, "%c", str[0]);
+ print(Common::Point(xStart + charWidth(str[0]), pt.y + 1),
+ COMMAND_FOREGROUND, "%s", str.c_str() + 1);
+ } else {
+ gPrint(Common::Point(xStart, pt.y), COMMAND_HIGHLIGHTED, "%c", str[0]);
+ gPrint(Common::Point(xStart + charWidth(str[0]), pt.y),
+ COMMAND_FOREGROUND, "%s", str.c_str() + 1);
+ }
+ } else if (slamIt) {
+ print(Common::Point(xStart, pt.y + 1), color, "%s", str.c_str());
+ } else {
+ gPrint(Common::Point(xStart, pt.y), color, "%s", str.c_str());
+ }
+}
+
+void ScalpelScreen::makePanel(const Common::Rect &r) {
+ _backBuffer->fillRect(r, BUTTON_MIDDLE);
+ _backBuffer->hLine(r.left, r.top, r.right - 2, BUTTON_TOP);
+ _backBuffer->hLine(r.left + 1, r.top + 1, r.right - 3, BUTTON_TOP);
+ _backBuffer->vLine(r.left, r.top, r.bottom - 1, BUTTON_TOP);
+ _backBuffer->vLine(r.left + 1, r.top + 1, r.bottom - 2, BUTTON_TOP);
+
+ _backBuffer->vLine(r.right - 1, r.top, r.bottom - 1, BUTTON_BOTTOM);
+ _backBuffer->vLine(r.right - 2, r.top + 1, r.bottom - 2, BUTTON_BOTTOM);
+ _backBuffer->hLine(r.left, r.bottom - 1, r.right - 1, BUTTON_BOTTOM);
+ _backBuffer->hLine(r.left + 1, r.bottom - 2, r.right - 1, BUTTON_BOTTOM);
+}
+
+void ScalpelScreen::makeField(const Common::Rect &r) {
+ _backBuffer->fillRect(r, BUTTON_MIDDLE);
+ _backBuffer->hLine(r.left, r.top, r.right - 1, BUTTON_BOTTOM);
+ _backBuffer->hLine(r.left + 1, r.bottom - 1, r.right - 1, BUTTON_TOP);
+ _backBuffer->vLine(r.left, r.top + 1, r.bottom - 1, BUTTON_BOTTOM);
+ _backBuffer->vLine(r.right - 1, r.top + 1, r.bottom - 2, BUTTON_TOP);
+}
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/scalpel/scalpel_screen.h b/engines/sherlock/scalpel/scalpel_screen.h
new file mode 100644
index 0000000000..472fe9e220
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_screen.h
@@ -0,0 +1,66 @@
+/* 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 SHERLOCK_SCALPEL_SCREEN_H
+#define SHERLOCK_SCALPEL_SCREEN_H
+
+#include "sherlock/screen.h"
+
+namespace Sherlock {
+
+class SherlockEngine;
+
+namespace Scalpel {
+
+class ScalpelScreen : public Screen {
+public:
+ ScalpelScreen(SherlockEngine *vm);
+ virtual ~ScalpelScreen() {}
+
+ /**
+ * Draws a button for use in the inventory, talk, and examine dialogs.
+ */
+ void makeButton(const Common::Rect &bounds, int textX, const Common::String &str);
+
+ /**
+ * Prints an interface command with the first letter highlighted to indicate
+ * what keyboard shortcut is associated with it
+ */
+ void buttonPrint(const Common::Point &pt, byte color, bool slamIt, const Common::String &str);
+
+ /**
+ * Draw a panel in the back buffer with a raised area effect around the edges
+ */
+ void makePanel(const Common::Rect &r);
+
+ /**
+ * Draw a field in the back buffer with a raised area effect around the edges,
+ * suitable for text input.
+ */
+ void makeField(const Common::Rect &r);
+};
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/scalpel/scalpel_talk.cpp b/engines/sherlock/scalpel/scalpel_talk.cpp
new file mode 100644
index 0000000000..aa0a2f48b4
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_talk.cpp
@@ -0,0 +1,844 @@
+/* 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 "sherlock/scalpel/scalpel_talk.h"
+#include "sherlock/scalpel/scalpel_fixed_text.h"
+#include "sherlock/scalpel/scalpel_map.h"
+#include "sherlock/scalpel/scalpel_people.h"
+#include "sherlock/scalpel/scalpel_scene.h"
+#include "sherlock/scalpel/scalpel_screen.h"
+#include "sherlock/scalpel/scalpel_user_interface.h"
+#include "sherlock/scalpel/scalpel.h"
+#include "sherlock/screen.h"
+#include "sherlock/scalpel/3do/movie_decoder.h"
+
+namespace Sherlock {
+
+namespace Scalpel {
+
+const byte SCALPEL_OPCODES[] = {
+ 128, // OP_SWITCH_SPEAKER
+ 129, // OP_RUN_CANIMATION
+ 130, // OP_ASSIGN_PORTRAIT_LOCATION
+ 131, // OP_PAUSE
+ 132, // OP_REMOVE_PORTRAIT
+ 133, // OP_CLEAR_WINDOW
+ 134, // OP_ADJUST_OBJ_SEQUENCE
+ 135, // OP_WALK_TO_COORDS
+ 136, // OP_PAUSE_WITHOUT_CONTROL
+ 137, // OP_BANISH_WINDOW
+ 138, // OP_SUMMON_WINDOW
+ 139, // OP_SET_FLAG
+ 140, // OP_SFX_COMMAND
+ 141, // OP_TOGGLE_OBJECT
+ 142, // OP_STEALTH_MODE_ACTIVE
+ 143, // OP_IF_STATEMENT
+ 144, // OP_ELSE_STATEMENT
+ 145, // OP_END_IF_STATEMENT
+ 146, // OP_STEALTH_MODE_DEACTIVATE
+ 147, // OP_TURN_HOLMES_OFF
+ 148, // OP_TURN_HOLMES_ON
+ 149, // OP_GOTO_SCENE
+ 150, // OP_PLAY_PROLOGUE
+ 151, // OP_ADD_ITEM_TO_INVENTORY
+ 152, // OP_SET_OBJECT
+ 153, // OP_CALL_TALK_FILE
+ 143, // OP_MOVE_MOUSE
+ 155, // OP_DISPLAY_INFO_LINE
+ 156, // OP_CLEAR_INFO_LINE
+ 157, // OP_WALK_TO_CANIMATION
+ 158, // OP_REMOVE_ITEM_FROM_INVENTORY
+ 159, // OP_ENABLE_END_KEY
+ 160, // OP_DISABLE_END_KEY
+ 161, // OP_END_TEXT_WINDOW
+ 0, // OP_MOUSE_ON_OFF
+ 0, // OP_SET_WALK_CONTROL
+ 0, // OP_SET_TALK_SEQUENCE
+ 0, // OP_PLAY_SONG
+ 0, // OP_WALK_HOLMES_AND_NPC_TO_CANIM
+ 0, // OP_SET_NPC_PATH_DEST
+ 0, // OP_NEXT_SONG
+ 0, // OP_SET_NPC_PATH_PAUSE
+ 0, // OP_PASSWORD
+ 0, // OP_SET_SCENE_ENTRY_FLAG
+ 0, // OP_WALK_NPC_TO_CANIM
+ 0, // OP_WALK_HOLMES_AND_NPC_TO_COORDS
+ 0, // OP_WALK_HOLMES_AND_NPC_TO_COORDS
+ 0, // OP_SET_NPC_TALK_FILE
+ 0, // OP_TURN_NPC_OFF
+ 0, // OP_TURN_NPC_ON
+ 0, // OP_NPC_DESC_ON_OFF
+ 0, // OP_NPC_PATH_PAUSE_TAKING_NOTES
+ 0, // OP_NPC_PATH_PAUSE_LOOKING_HOLMES
+ 0, // OP_ENABLE_TALK_INTERRUPTS
+ 0, // OP_DISABLE_TALK_INTERRUPTS
+ 0, // OP_SET_NPC_INFO_LINE
+ 0, // OP_SET_NPC_POSITION
+ 0, // OP_NPC_PATH_LABEL
+ 0, // OP_PATH_GOTO_LABEL
+ 0, // OP_PATH_IF_FLAG_GOTO_LABEL
+ 0, // OP_NPC_WALK_GRAPHICS
+ 0, // OP_NPC_VERB
+ 0, // OP_NPC_VERB_CANIM
+ 0, // OP_NPC_VERB_SCRIPT
+ 0, // OP_RESTORE_PEOPLE_SEQUENCE
+ 0, // OP_NPC_VERB_TARGET
+ 0, // OP_TURN_SOUNDS_OFF
+ 0 // OP_NULL
+};
+
+/*----------------------------------------------------------------*/
+
+ScalpelTalk::ScalpelTalk(SherlockEngine *vm) : Talk(vm) {
+ static OpcodeMethod OPCODE_METHODS[] = {
+ (OpcodeMethod)&ScalpelTalk::cmdSwitchSpeaker,
+ (OpcodeMethod)&ScalpelTalk::cmdRunCAnimation,
+ (OpcodeMethod)&ScalpelTalk::cmdAssignPortraitLocation,
+
+ (OpcodeMethod)&ScalpelTalk::cmdPause,
+ (OpcodeMethod)&ScalpelTalk::cmdRemovePortrait,
+ (OpcodeMethod)&ScalpelTalk::cmdClearWindow,
+ (OpcodeMethod)&ScalpelTalk::cmdAdjustObjectSequence,
+ (OpcodeMethod)&ScalpelTalk::cmdWalkToCoords,
+ (OpcodeMethod)&ScalpelTalk::cmdPauseWithoutControl,
+ (OpcodeMethod)&ScalpelTalk::cmdBanishWindow,
+ (OpcodeMethod)&ScalpelTalk::cmdSummonWindow,
+ (OpcodeMethod)&ScalpelTalk::cmdSetFlag,
+ (OpcodeMethod)&ScalpelTalk::cmdSfxCommand,
+
+ (OpcodeMethod)&ScalpelTalk::cmdToggleObject,
+ (OpcodeMethod)&ScalpelTalk::cmdStealthModeActivate,
+ (OpcodeMethod)&ScalpelTalk::cmdIf,
+ (OpcodeMethod)&ScalpelTalk::cmdElse,
+ nullptr,
+ (OpcodeMethod)&ScalpelTalk::cmdStealthModeDeactivate,
+ (OpcodeMethod)&ScalpelTalk::cmdHolmesOff,
+ (OpcodeMethod)&ScalpelTalk::cmdHolmesOn,
+ (OpcodeMethod)&ScalpelTalk::cmdGotoScene,
+ (OpcodeMethod)&ScalpelTalk::cmdPlayPrologue,
+
+ (OpcodeMethod)&ScalpelTalk::cmdAddItemToInventory,
+ (OpcodeMethod)&ScalpelTalk::cmdSetObject,
+ (OpcodeMethod)&ScalpelTalk::cmdCallTalkFile,
+ (OpcodeMethod)&ScalpelTalk::cmdMoveMouse,
+ (OpcodeMethod)&ScalpelTalk::cmdDisplayInfoLine,
+ (OpcodeMethod)&ScalpelTalk::cmdClearInfoLine,
+ (OpcodeMethod)&ScalpelTalk::cmdWalkToCAnimation,
+ (OpcodeMethod)&ScalpelTalk::cmdRemoveItemFromInventory,
+ (OpcodeMethod)&ScalpelTalk::cmdEnableEndKey,
+ (OpcodeMethod)&ScalpelTalk::cmdDisableEndKey,
+
+ (OpcodeMethod)&ScalpelTalk::cmdEndTextWindow,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr
+ };
+
+ _opcodeTable = OPCODE_METHODS;
+ _opcodes = SCALPEL_OPCODES;
+
+ if (vm->getLanguage() == Common::DE_DEU || vm->getLanguage() == Common::ES_ESP) {
+ // The German and Spanish versions use a different opcode range
+ static byte opcodes[sizeof(SCALPEL_OPCODES)];
+ for (uint idx = 0; idx < sizeof(SCALPEL_OPCODES); ++idx)
+ opcodes[idx] = SCALPEL_OPCODES[idx] ? SCALPEL_OPCODES[idx] + 47 : 0;
+
+ _opcodes = opcodes;
+ }
+
+}
+
+void ScalpelTalk::talkInterface(const byte *&str) {
+ FixedText &fixedText = *_vm->_fixedText;
+ People &people = *_vm->_people;
+ ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+ UserInterface &ui = *_vm->_ui;
+
+ // If the window isn't yet open, draw the window before printing starts
+ if (!ui._windowOpen && _noTextYet) {
+ _noTextYet = false;
+ drawInterface();
+
+ if (_talkTo != -1) {
+ Common::String fixedText_Exit = fixedText.getText(kFixedText_Window_Exit);
+ Common::String fixedText_Up = fixedText.getText(kFixedText_Window_Up);
+ Common::String fixedText_Down = fixedText.getText(kFixedText_Window_Down);
+ screen.buttonPrint(Common::Point(119, CONTROLS_Y), COMMAND_NULL, false, fixedText_Exit);
+ screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_NULL, false, fixedText_Up);
+ screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_NULL, false, fixedText_Down);
+ }
+ }
+
+ // If it's the first line, display the speaker
+ if (!_line && _speaker >= 0 && _speaker < (int)people._characters.size()) {
+ // If the window is open, display the name directly on-screen.
+ // Otherwise, simply draw it on the back buffer
+ if (ui._windowOpen) {
+ screen.print(Common::Point(16, _yp), TALK_FOREGROUND, "%s",
+ people._characters[_speaker & 127]._name);
+ }
+ else {
+ screen.gPrint(Common::Point(16, _yp - 1), TALK_FOREGROUND, "%s",
+ people._characters[_speaker & 127]._name);
+ _openTalkWindow = true;
+ }
+
+ _yp += 9;
+ }
+
+ // Find amount of text that will fit on the line
+ int width = 0, idx = 0;
+ do {
+ width += screen.charWidth(str[idx]);
+ ++idx;
+ ++_charCount;
+ } while (width < 298 && str[idx] && str[idx] != '{' && (!isOpcode(str[idx])));
+
+ if (str[idx] || width >= 298) {
+ if ((!isOpcode(str[idx])) && str[idx] != '{') {
+ --idx;
+ --_charCount;
+ }
+ }
+ else {
+ _endStr = true;
+ }
+
+ // If word wrap is needed, find the start of the current word
+ if (width >= 298) {
+ while (str[idx] != ' ') {
+ --idx;
+ --_charCount;
+ }
+ }
+
+ // Print the line
+ Common::String lineStr((const char *)str, (const char *)str + idx);
+
+ // If the speaker indicates a description file, print it in yellow
+ if (_speaker != -1) {
+ if (ui._windowOpen) {
+ screen.print(Common::Point(16, _yp), COMMAND_FOREGROUND, "%s", lineStr.c_str());
+ }
+ else {
+ screen.gPrint(Common::Point(16, _yp - 1), COMMAND_FOREGROUND, "%s", lineStr.c_str());
+ _openTalkWindow = true;
+ }
+ }
+ else {
+ if (ui._windowOpen) {
+ screen.print(Common::Point(16, _yp), COMMAND_FOREGROUND, "%s", lineStr.c_str());
+ }
+ else {
+ screen.gPrint(Common::Point(16, _yp - 1), COMMAND_FOREGROUND, "%s", lineStr.c_str());
+ _openTalkWindow = true;
+ }
+ }
+
+ // Move to end of displayed line
+ str += idx;
+
+ // If line wrap occurred, then move to after the separating space between the words
+ if ((!isOpcode(str[0])) && str[0] != '{')
+ ++str;
+
+ _yp += 9;
+ ++_line;
+
+ // Certain different conditions require a wait
+ if ((_line == 4 && str < _scriptEnd && str[0] != _opcodes[OP_SFX_COMMAND] && str[0] != _opcodes[OP_PAUSE] && _speaker != -1) ||
+ (_line == 5 && str < _scriptEnd && str[0] != _opcodes[OP_PAUSE] && _speaker == -1) ||
+ _endStr) {
+ _wait = 1;
+ }
+
+ byte v = (str >= _scriptEnd ? 0 : str[0]);
+ if (v == _opcodes[OP_SWITCH_SPEAKER] || v == _opcodes[OP_ASSIGN_PORTRAIT_LOCATION] ||
+ v == _opcodes[OP_BANISH_WINDOW] || v == _opcodes[OP_IF_STATEMENT] ||
+ v == _opcodes[OP_ELSE_STATEMENT] || v == _opcodes[OP_END_IF_STATEMENT] ||
+ v == _opcodes[OP_GOTO_SCENE] || v == _opcodes[OP_CALL_TALK_FILE]) {
+ _wait = 1;
+ }
+}
+
+OpcodeReturn ScalpelTalk::cmdSwitchSpeaker(const byte *&str) {
+ ScalpelPeople &people = *(ScalpelPeople *)_vm->_people;
+ UserInterface &ui = *_vm->_ui;
+
+ if (!(_speaker & SPEAKER_REMOVE))
+ people.clearTalking();
+ if (_talkToAbort)
+ return RET_EXIT;
+
+ ui.clearWindow();
+ _yp = CONTROLS_Y + 12;
+ _charCount = _line = 0;
+
+ _speaker = *++str - 1;
+ people.setTalking(_speaker);
+ pullSequence();
+ pushSequence(_speaker);
+ people.setTalkSequence(_speaker);
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn ScalpelTalk::cmdGotoScene(const byte *&str) {
+ ScalpelMap &map = *(ScalpelMap *)_vm->_map;
+ People &people = *_vm->_people;
+ Scene &scene = *_vm->_scene;
+ scene._goToScene = str[1] - 1;
+
+ if (scene._goToScene != OVERHEAD_MAP) {
+ // Not going to the map overview
+ map._oldCharPoint = scene._goToScene;
+ map._overPos.x = (map[scene._goToScene].x - 6) * FIXED_INT_MULTIPLIER;
+ map._overPos.y = (map[scene._goToScene].y + 9) * FIXED_INT_MULTIPLIER;
+
+ // Run a canimation?
+ if (str[2] > 100) {
+ people._savedPos = PositionFacing(160, 100, str[2]);
+ } else {
+ int32 posX = (str[3] - 1) * 256 + str[4] - 1;
+ int32 posY = str[5] - 1;
+ people._savedPos = PositionFacing(posX, posY, str[2] - 1);
+ }
+ }
+
+ str += 6;
+
+ _scriptMoreFlag = (scene._goToScene == 100) ? 2 : 1;
+ _scriptSaveIndex = str - _scriptStart;
+ _endStr = true;
+ _wait = 0;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn ScalpelTalk::cmdAssignPortraitLocation(const byte *&str) {
+ People &people = *_vm->_people;
+
+ ++str;
+ switch (str[0] & 15) {
+ case 1:
+ people._portraitSide = 20;
+ break;
+ case 2:
+ people._portraitSide = 220;
+ break;
+ case 3:
+ people._portraitSide = 120;
+ break;
+ default:
+ break;
+ }
+
+ if (str[0] > 15)
+ people._speakerFlip = true;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn ScalpelTalk::cmdClearInfoLine(const byte *&str) {
+ UserInterface &ui = *_vm->_ui;
+
+ ui._infoFlag = true;
+ ui.clearInfo();
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn ScalpelTalk::cmdClearWindow(const byte *&str) {
+ UserInterface &ui = *_vm->_ui;
+
+ ui.clearWindow();
+ _yp = CONTROLS_Y + 12;
+ _charCount = _line = 0;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn ScalpelTalk::cmdDisplayInfoLine(const byte *&str) {
+ Screen &screen = *_vm->_screen;
+ UserInterface &ui = *_vm->_ui;
+ Common::String tempString;
+
+ ++str;
+ for (int idx = 0; idx < str[0]; ++idx)
+ tempString += str[idx + 1];
+ str += str[0];
+
+ screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", tempString.c_str());
+ ui._menuCounter = 30;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn ScalpelTalk::cmdElse(const byte *&str) {
+ // If this is encountered here, it means that a preceeding IF statement was found,
+ // and evaluated to true. Now all the statements for the true block are finished,
+ // so skip over the block of code that would have executed if the result was false
+ _wait = 0;
+ do {
+ ++str;
+ } while (str[0] && str[0] != _opcodes[OP_END_IF_STATEMENT]);
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn ScalpelTalk::cmdIf(const byte *&str) {
+ ++str;
+ int flag = (str[0] - 1) * 256 + str[1] - 1 - (str[1] == 1 ? 1 : 0);
+ ++str;
+ _wait = 0;
+
+ bool result = flag < 0x8000;
+ if (_vm->readFlags(flag & 0x7fff) != result) {
+ do {
+ ++str;
+ } while (str[0] && str[0] != _opcodes[OP_ELSE_STATEMENT] && str[0] != _opcodes[OP_END_IF_STATEMENT]);
+
+ if (!str[0])
+ _endStr = true;
+ }
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn ScalpelTalk::cmdMoveMouse(const byte *&str) {
+ Events &events = *_vm->_events;
+
+ ++str;
+ events.moveMouse(Common::Point((str[0] - 1) * 256 + str[1] - 1, str[2]));
+ if (_talkToAbort)
+ return RET_EXIT;
+ str += 3;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn ScalpelTalk::cmdPlayPrologue(const byte *&str) {
+ Animation &anim = *_vm->_animation;
+ Common::String tempString;
+
+ ++str;
+ for (int idx = 0; idx < 8 && str[idx] != '~'; ++idx)
+ tempString += str[idx];
+
+ anim.play(tempString, false, 1, 3, true, 4);
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn ScalpelTalk::cmdRemovePortrait(const byte *&str) {
+ People &people = *_vm->_people;
+
+ if (_speaker >= 0 && _speaker < SPEAKER_REMOVE)
+ people.clearTalking();
+ pullSequence();
+ if (_talkToAbort)
+ return RET_EXIT;
+
+ _speaker |= SPEAKER_REMOVE;
+ return RET_SUCCESS;
+}
+
+OpcodeReturn ScalpelTalk::cmdWalkToCoords(const byte *&str) {
+ People &people = *_vm->_people;
+ ++str;
+
+ people[HOLMES].walkToCoords(Point32(((str[0] - 1) * 256 + str[1] - 1) * FIXED_INT_MULTIPLIER,
+ str[2] * FIXED_INT_MULTIPLIER), str[3] - 1);
+ if (_talkToAbort)
+ return RET_EXIT;
+
+ str += 3;
+ return RET_SUCCESS;
+}
+
+OpcodeReturn ScalpelTalk::cmdSfxCommand(const byte *&str) {
+ Sound &sound = *_vm->_sound;
+ Common::String tempString;
+
+ ++str;
+ if (sound._voices) {
+ for (int idx = 0; idx < 8 && str[idx] != '~'; ++idx)
+ tempString += str[idx];
+ sound.playSound(tempString, WAIT_RETURN_IMMEDIATELY);
+
+ // Set voices to wait for more
+ sound._voices = 2;
+ sound._speechOn = (*sound._soundIsOn);
+ }
+
+ _wait = 1;
+ str += 7;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn ScalpelTalk::cmdSummonWindow(const byte *&str) {
+ Events &events = *_vm->_events;
+ FixedText &fixedText = *_vm->_fixedText;
+ ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+
+ drawInterface();
+ events._pressed = events._released = false;
+ events.clearKeyboard();
+ _noTextYet = false;
+
+ if (_speaker != -1) {
+ Common::String fixedText_Exit = fixedText.getText(kFixedText_Window_Exit);
+ Common::String fixedText_Up = fixedText.getText(kFixedText_Window_Up);
+ Common::String fixedText_Down = fixedText.getText(kFixedText_Window_Down);
+ screen.buttonPrint(Common::Point(119, CONTROLS_Y), COMMAND_NULL, false, fixedText_Exit);
+ screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_NULL, false, fixedText_Up);
+ screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_NULL, false, fixedText_Down);
+ }
+
+ return RET_SUCCESS;
+}
+
+void ScalpelTalk::talkWait(const byte *&str) {
+ UserInterface &ui = *_vm->_ui;
+ bool pauseFlag = _pauseFlag;
+
+ Talk::talkWait(str);
+
+ // Clear the window unless the wait was due to a PAUSE command
+ if (!pauseFlag && _wait != -1 && str < _scriptEnd && str[0] != _opcodes[OP_SFX_COMMAND]) {
+ if (!_talkStealth)
+ ui.clearWindow();
+ _yp = CONTROLS_Y + 12;
+ _charCount = _line = 0;
+ }
+}
+
+void ScalpelTalk::talk3DOMovieTrigger(int subIndex) {
+ if (!IS_3DO) {
+ // No 3DO? No movie!
+ return;
+ }
+
+ // Find out a few things that we need
+ int userSelector = _vm->_ui->_selector;
+ int scriptSelector = _scriptSelect;
+ int selector = 0;
+ int roomNr = _vm->_scene->_currentScene;
+
+ if (userSelector >= 0) {
+ // User-selected dialog
+ selector = userSelector;
+ } else {
+ if (scriptSelector >= 0) {
+ // Script-selected dialog
+ selector = scriptSelector;
+ subIndex--; // for scripts we adjust subIndex, b/c we won't get called from doTalkControl()
+ } else {
+ warning("talk3DOMovieTrigger: unable to find selector");
+ return;
+ }
+ }
+
+ // Make a quick update, so that current text is shown on screen
+ _vm->_screen->update();
+
+ // Figure out that movie filename
+ Common::String movieFilename;
+
+ movieFilename = _scriptName;
+ movieFilename.deleteChar(1); // remove 2nd character of scriptname
+ // cut scriptname to 6 characters
+ while (movieFilename.size() > 6) {
+ movieFilename.deleteChar(6);
+ }
+
+ movieFilename.insertChar(selector + 'a', movieFilename.size());
+ movieFilename.insertChar(subIndex + 'a', movieFilename.size());
+ movieFilename = Common::String::format("movies/%02d/%s.stream", roomNr, movieFilename.c_str());
+
+ warning("3DO movie player:");
+ warning("room: %d", roomNr);
+ warning("script: %s", _scriptName.c_str());
+ warning("selector: %d", selector);
+ warning("subindex: %d", subIndex);
+
+ Scalpel3DOMoviePlay(movieFilename.c_str(), Common::Point(5, 5));
+
+ // Restore screen HACK
+ _vm->_screen->makeAllDirty();
+}
+
+void ScalpelTalk::drawInterface() {
+ FixedText &fixedText = *_vm->_fixedText;
+ ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+ Surface &bb = *screen._backBuffer;
+
+ bb.fillRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y1 + 10), BORDER_COLOR);
+ bb.fillRect(Common::Rect(0, CONTROLS_Y + 10, 2, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR);
+ bb.fillRect(Common::Rect(SHERLOCK_SCREEN_WIDTH - 2, CONTROLS_Y + 10,
+ SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR);
+ bb.fillRect(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - 1, SHERLOCK_SCREEN_WIDTH - 2,
+ SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR);
+ bb.fillRect(Common::Rect(2, CONTROLS_Y + 10, SHERLOCK_SCREEN_WIDTH - 2,
+ SHERLOCK_SCREEN_HEIGHT - 2), INV_BACKGROUND);
+
+ if (_talkTo != -1) {
+ Common::String fixedText_Exit = fixedText.getText(kFixedText_Window_Exit);
+ Common::String fixedText_Up = fixedText.getText(kFixedText_Window_Up);
+ Common::String fixedText_Down = fixedText.getText(kFixedText_Window_Down);
+
+ screen.makeButton(Common::Rect(99, CONTROLS_Y, 139, CONTROLS_Y + 10),
+ 119 - screen.stringWidth(fixedText_Exit) / 2, fixedText_Exit);
+ screen.makeButton(Common::Rect(140, CONTROLS_Y, 180, CONTROLS_Y + 10),
+ 159 - screen.stringWidth(fixedText_Up) / 2, fixedText_Up);
+ screen.makeButton(Common::Rect(181, CONTROLS_Y, 221, CONTROLS_Y + 10),
+ 200 - screen.stringWidth(fixedText_Down) / 2, fixedText_Down);
+ } else {
+ int strWidth = screen.stringWidth(Scalpel::PRESS_KEY_TO_CONTINUE);
+ screen.makeButton(Common::Rect(46, CONTROLS_Y, 273, CONTROLS_Y + 10),
+ 160 - strWidth / 2, Scalpel::PRESS_KEY_TO_CONTINUE);
+ screen.gPrint(Common::Point(160 - strWidth / 2, CONTROLS_Y), COMMAND_FOREGROUND, "P");
+ }
+}
+
+bool ScalpelTalk::displayTalk(bool slamIt) {
+ FixedText &fixedText = *_vm->_fixedText;
+ ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+ int yp = CONTROLS_Y + 14;
+ int lineY = -1;
+ _moreTalkDown = _moreTalkUp = false;
+
+ for (uint idx = 0; idx < _statements.size(); ++idx) {
+ _statements[idx]._talkPos.top = _statements[idx]._talkPos.bottom = -1;
+ }
+
+ if (_talkIndex) {
+ for (int idx = 0; idx < _talkIndex && !_moreTalkUp; ++idx) {
+ if (_statements[idx]._talkMap != -1)
+ _moreTalkUp = true;
+ }
+ }
+
+ // Display the up arrow and enable Up button if the first option is scrolled off-screen
+ Common::String fixedText_Up = fixedText.getText(kFixedText_Window_Up);
+ Common::String fixedText_Down = fixedText.getText(kFixedText_Window_Down);
+ if (_moreTalkUp) {
+ if (slamIt) {
+ screen.print(Common::Point(5, CONTROLS_Y + 13), INV_FOREGROUND, "~");
+ screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_FOREGROUND, true, fixedText_Up);
+ } else {
+ screen.gPrint(Common::Point(5, CONTROLS_Y + 12), INV_FOREGROUND, "~");
+ screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_FOREGROUND, false, fixedText_Up);
+ }
+ } else {
+ if (slamIt) {
+ screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_NULL, true, fixedText_Up);
+ screen.vgaBar(Common::Rect(5, CONTROLS_Y + 11, 15, CONTROLS_Y + 22), INV_BACKGROUND);
+ } else {
+ screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_NULL, false, fixedText_Up);
+ screen._backBuffer1.fillRect(Common::Rect(5, CONTROLS_Y + 11,
+ 15, CONTROLS_Y + 22), INV_BACKGROUND);
+ }
+ }
+
+ // Loop through the statements
+ bool done = false;
+ for (uint idx = _talkIndex; idx < _statements.size() && !done; ++idx) {
+ Statement &statement = _statements[idx];
+
+ if (statement._talkMap != -1) {
+ bool flag = _talkHistory[_converseNum][idx];
+ lineY = talkLine(idx, statement._talkMap, flag ? (byte)TALK_NULL : (byte)INV_FOREGROUND,
+ yp, slamIt);
+
+ if (lineY != -1) {
+ statement._talkPos.top = yp;
+ yp = lineY;
+ statement._talkPos.bottom = yp;
+
+ if (yp == SHERLOCK_SCREEN_HEIGHT)
+ done = true;
+ } else {
+ done = true;
+ }
+ }
+ }
+
+ // Display the down arrow and enable down button if there are more statements available down off-screen
+ if (lineY == -1 || lineY == SHERLOCK_SCREEN_HEIGHT) {
+ _moreTalkDown = true;
+
+ if (slamIt) {
+ screen.print(Common::Point(5, 190), INV_FOREGROUND, "|");
+ screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_FOREGROUND, true, fixedText_Down);
+ } else {
+ screen.gPrint(Common::Point(5, 189), INV_FOREGROUND, "|");
+ screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_FOREGROUND, false, fixedText_Down);
+ }
+ } else {
+ if (slamIt) {
+ screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_NULL, true, fixedText_Down);
+ screen.vgaBar(Common::Rect(5, 189, 16, 199), INV_BACKGROUND);
+ } else {
+ screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_NULL, false, fixedText_Down);
+ screen._backBuffer1.fillRect(Common::Rect(5, 189, 16, 199), INV_BACKGROUND);
+ }
+ }
+
+ return done;
+}
+
+int ScalpelTalk::talkLine(int lineNum, int stateNum, byte color, int lineY, bool slamIt) {
+ Screen &screen = *_vm->_screen;
+ int idx = lineNum;
+ Common::String msg, number;
+ bool numberFlag = false;
+
+ // Get the statement to display as well as optional number prefix
+ if (idx < SPEAKER_REMOVE) {
+ number = Common::String::format("%d.", stateNum + 1);
+ numberFlag = true;
+ } else {
+ idx -= SPEAKER_REMOVE;
+ }
+ msg = _statements[idx]._statement;
+
+ // Handle potentially multiple lines needed to display entire statement
+ const char *lineStartP = msg.c_str();
+ int maxWidth = 298 - (numberFlag ? 18 : 0);
+ for (;;) {
+ // Get as much of the statement as possible will fit on the
+ Common::String sLine;
+ const char *lineEndP = lineStartP;
+ int width = 0;
+ do {
+ width += screen.charWidth(*lineEndP);
+ } while (*++lineEndP && width < maxWidth);
+
+ // Check if we need to wrap the line
+ if (width >= maxWidth) {
+ // Work backwards to the prior word's end
+ while (*--lineEndP != ' ')
+ ;
+
+ sLine = Common::String(lineStartP, lineEndP++);
+ } else {
+ // Can display remainder of the statement on the current line
+ sLine = Common::String(lineStartP);
+ }
+
+
+ if (lineY <= (SHERLOCK_SCREEN_HEIGHT - 10)) {
+ // Need to directly display on-screen?
+ if (slamIt) {
+ // See if a numer prefix is needed or not
+ if (numberFlag) {
+ // Are we drawing the first line?
+ if (lineStartP == msg.c_str()) {
+ // We are, so print the number and then the text
+ screen.print(Common::Point(16, lineY), color, "%s", number.c_str());
+ }
+
+ // Draw the line with an indent
+ screen.print(Common::Point(30, lineY), color, "%s", sLine.c_str());
+ } else {
+ screen.print(Common::Point(16, lineY), color, "%s", sLine.c_str());
+ }
+ } else {
+ if (numberFlag) {
+ if (lineStartP == msg.c_str()) {
+ screen.gPrint(Common::Point(16, lineY - 1), color, "%s", number.c_str());
+ }
+
+ screen.gPrint(Common::Point(30, lineY - 1), color, "%s", sLine.c_str());
+ } else {
+ screen.gPrint(Common::Point(16, lineY - 1), color, "%s", sLine.c_str());
+ }
+ }
+
+ // Move to next line, if any
+ lineY += 9;
+ lineStartP = lineEndP;
+
+ if (!*lineEndP)
+ break;
+ } else {
+ // We're close to the bottom of the screen, so stop display
+ lineY = -1;
+ break;
+ }
+ }
+
+ if (lineY == -1 && lineStartP != msg.c_str())
+ lineY = SHERLOCK_SCREEN_HEIGHT;
+
+ // Return the Y position of the next line to follow this one
+ return lineY;
+}
+
+void ScalpelTalk::showTalk() {
+ FixedText &fixedText = *_vm->_fixedText;
+ ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+ ScalpelUserInterface &ui = *(ScalpelUserInterface *)_vm->_ui;
+ Common::String fixedText_Exit = fixedText.getText(kFixedText_Window_Exit);
+ byte color = ui._endKeyActive ? COMMAND_FOREGROUND : COMMAND_NULL;
+
+ clearSequences();
+ pushSequence(_talkTo);
+ setStillSeq(_talkTo);
+
+ ui._selector = ui._oldSelector = -1;
+
+ if (!ui._windowOpen) {
+ // Draw the talk interface on the back buffer
+ drawInterface();
+ displayTalk(false);
+ } else {
+ displayTalk(true);
+ }
+
+ // If the window is already open, simply draw. Otherwise, do it
+ // to the back buffer and then summon the window
+ if (ui._windowOpen) {
+ screen.buttonPrint(Common::Point(119, CONTROLS_Y), color, true, fixedText_Exit);
+ } else {
+ screen.buttonPrint(Common::Point(119, CONTROLS_Y), color, false, fixedText_Exit);
+
+ if (!ui._slideWindows) {
+ screen.slamRect(Common::Rect(0, CONTROLS_Y,
+ SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
+ } else {
+ ui.summonWindow();
+ }
+
+ ui._windowOpen = true;
+ }
+}
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/scalpel/scalpel_talk.h b/engines/sherlock/scalpel/scalpel_talk.h
new file mode 100644
index 0000000000..24188d8fcd
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_talk.h
@@ -0,0 +1,99 @@
+/* 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 SHERLOCK_SCALPEL_TALK_H
+#define SHERLOCK_SCALPEL_TALK_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/rect.h"
+#include "common/serializer.h"
+#include "common/stream.h"
+#include "common/stack.h"
+#include "sherlock/talk.h"
+
+namespace Sherlock {
+
+namespace Scalpel {
+
+class ScalpelTalk : public Talk {
+private:
+ OpcodeReturn cmdSwitchSpeaker(const byte *&str);
+ OpcodeReturn cmdAssignPortraitLocation(const byte *&str);
+ OpcodeReturn cmdGotoScene(const byte *&str);
+ OpcodeReturn cmdClearInfoLine(const byte *&str);
+ OpcodeReturn cmdClearWindow(const byte *&str);
+ OpcodeReturn cmdDisplayInfoLine(const byte *&str);
+ OpcodeReturn cmdElse(const byte *&str);
+ OpcodeReturn cmdIf(const byte *&str);
+ OpcodeReturn cmdMoveMouse(const byte *&str);
+ OpcodeReturn cmdPlayPrologue(const byte *&str);
+ OpcodeReturn cmdRemovePortrait(const byte *&str);
+ OpcodeReturn cmdSfxCommand(const byte *&str);
+ OpcodeReturn cmdSummonWindow(const byte *&str);
+ OpcodeReturn cmdWalkToCoords(const byte *&str);
+protected:
+ /**
+ * Display the talk interface window
+ */
+ virtual void talkInterface(const byte *&str);
+
+ /**
+ * Pause when displaying a talk dialog on-screen
+ */
+ virtual void talkWait(const byte *&str);
+
+ /**
+ * Trigger to play a 3DO talk dialog movie
+ */
+ virtual void talk3DOMovieTrigger(int subIndex);
+
+ /**
+ * Show the talk display
+ */
+ virtual void showTalk();
+public:
+ ScalpelTalk(SherlockEngine *vm);
+ virtual ~ScalpelTalk() {}
+
+ /**
+ * Draws the interface for conversation display
+ */
+ void drawInterface();
+
+ /**
+ * Display a list of statements in a window at the bottom of the screen that the
+ * player can select from.
+ */
+ bool displayTalk(bool slamIt);
+
+ /**
+ * Prints a single conversation option in the interface window
+ */
+ int talkLine(int lineNum, int stateNum, byte color, int lineY, bool slamIt);
+};
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/scalpel/scalpel_user_interface.cpp b/engines/sherlock/scalpel/scalpel_user_interface.cpp
new file mode 100644
index 0000000000..8fcc92b2ac
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_user_interface.cpp
@@ -0,0 +1,2189 @@
+/* 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 "sherlock/scalpel/scalpel_user_interface.h"
+#include "sherlock/scalpel/scalpel_fixed_text.h"
+#include "sherlock/scalpel/scalpel_inventory.h"
+#include "sherlock/scalpel/scalpel_journal.h"
+#include "sherlock/scalpel/scalpel_people.h"
+#include "sherlock/scalpel/scalpel_saveload.h"
+#include "sherlock/scalpel/scalpel_screen.h"
+#include "sherlock/scalpel/settings.h"
+#include "sherlock/scalpel/scalpel.h"
+#include "sherlock/sherlock.h"
+
+namespace Sherlock {
+
+namespace Scalpel {
+
+// Main user interface menu control locations
+const int MENU_POINTS[12][4] = {
+ { 13, 153, 72, 165 },
+ { 13, 169, 72, 181 },
+ { 13, 185, 72, 197 },
+ { 88, 153, 152, 165 },
+ { 88, 169, 152, 181 },
+ { 88, 185, 152, 197 },
+ { 165, 153, 232, 165 },
+ { 165, 169, 232, 181 },
+ { 165, 185, 233, 197 },
+ { 249, 153, 305, 165 },
+ { 249, 169, 305, 181 },
+ { 249, 185, 305, 197 }
+};
+
+// Inventory control locations */
+const int INVENTORY_POINTS[8][3] = {
+ { 4, 50, 29 },
+ { 52, 99, 77 },
+ { 101, 140, 123 },
+ { 142, 187, 166 },
+ { 189, 219, 198 },
+ { 221, 251, 234 },
+ { 253, 283, 266 },
+ { 285, 315, 294 }
+};
+
+const char COMMANDS[13] = "LMTPOCIUGJFS";
+const char INVENTORY_COMMANDS[9] = { "ELUG-+,." };
+const char *const PRESS_KEY_FOR_MORE = "Press any Key for More.";
+const char *const PRESS_KEY_TO_CONTINUE = "Press any Key to Continue.";
+const int UI_OFFSET_3DO = 16; // (320 - 288) / 2
+
+/*----------------------------------------------------------------*/
+
+
+ScalpelUserInterface::ScalpelUserInterface(SherlockEngine *vm): UserInterface(vm) {
+ if (_vm->_interactiveFl) {
+ if (!IS_3DO) {
+ // PC
+ _controls = new ImageFile("menu.all");
+ _controlPanel = new ImageFile("controls.vgs");
+ } else {
+ // 3DO
+ _controls = new ImageFile3DO("menu.all", kImageFile3DOType_RoomFormat);
+ _controlPanel = new ImageFile3DO("controls.vgs", kImageFile3DOType_RoomFormat);
+ }
+ } else {
+ _controls = nullptr;
+ _controlPanel = nullptr;
+ }
+
+ _keyPress = '\0';
+ _lookHelp = 0;
+ _help = _oldHelp = 0;
+ _key = _oldKey = '\0';
+ _temp = _oldTemp = 0;
+ _oldLook = 0;
+ _keyboardInput = false;
+ _pause = false;
+ _cNum = 0;
+ _find = 0;
+ _oldUse = 0;
+}
+
+ScalpelUserInterface::~ScalpelUserInterface() {
+ delete _controls;
+ delete _controlPanel;
+}
+
+void ScalpelUserInterface::reset() {
+ UserInterface::reset();
+ _help = _oldHelp = -1;
+}
+
+void ScalpelUserInterface::drawInterface(int bufferNum) {
+ Screen &screen = *_vm->_screen;
+
+ const ImageFrame &src = (*_controlPanel)[0];
+ int16 x = (!IS_3DO) ? 0 : UI_OFFSET_3DO;
+
+ if (bufferNum & 1)
+ screen._backBuffer1.transBlitFrom(src, Common::Point(x, CONTROLS_Y));
+ if (bufferNum & 2)
+ screen._backBuffer2.transBlitFrom(src, Common::Point(x, CONTROLS_Y));
+ if (bufferNum == 3)
+ screen._backBuffer2.fillRect(0, INFO_LINE, SHERLOCK_SCREEN_WIDTH, INFO_LINE + 10, INFO_BLACK);
+}
+
+void ScalpelUserInterface::handleInput() {
+ Events &events = *_vm->_events;
+ Inventory &inv = *_vm->_inventory;
+ People &people = *_vm->_people;
+ Scene &scene = *_vm->_scene;
+ Screen &screen = *_vm->_screen;
+ Talk &talk = *_vm->_talk;
+
+ if (_menuCounter)
+ whileMenuCounter();
+
+ Common::Point pt = events.mousePos();
+ _bgFound = scene.findBgShape(pt);
+ _keyPress = '\0';
+
+ // Check kbd and set the mouse released flag if Enter or space is pressed.
+ // Otherwise, the pressed _key is stored for later use
+ if (events.kbHit()) {
+ Common::KeyState keyState = events.getKey();
+ _keyPress = keyState.ascii;
+
+ if (keyState.keycode == Common::KEYCODE_x && keyState.flags & Common::KBD_ALT) {
+ _vm->quitGame();
+ events.pollEvents();
+ return;
+ }
+ }
+
+ // Do button highlighting check
+ if (!talk._scriptMoreFlag) { // Don't if scripts are running
+ if (((events._rightPressed || events._rightReleased) && _helpStyle) ||
+ (!_helpStyle && !_menuCounter)) {
+ // Handle any default commands if we're in STD_MODE
+ if (_menuMode == STD_MODE) {
+ if (pt.y < CONTROLS_Y &&
+ (events._rightPressed || (!_helpStyle && !events._released)) &&
+ (_bgFound != -1) && (_bgFound < 1000) &&
+ (scene._bgShapes[_bgFound]._defaultCommand ||
+ !scene._bgShapes[_bgFound]._description.empty())) {
+ // If there is no default command, so set it to Look
+ if (scene._bgShapes[_bgFound]._defaultCommand)
+ _help = scene._bgShapes[_bgFound]._defaultCommand - 1;
+ else
+ _help = 0;
+
+ // Reset 'help' if it is an invalid command
+ if (_help > 5)
+ _help = -1;
+ } else if (pt.y < CONTROLS_Y &&
+ ((events._rightReleased && _helpStyle) || (events._released && !_helpStyle)) &&
+ (_bgFound != -1 && _bgFound < 1000) &&
+ (scene._bgShapes[_bgFound]._defaultCommand ||
+ !scene._bgShapes[_bgFound]._description.empty())) {
+ // If there is no default command, set it to Look
+ if (scene._bgShapes[_bgFound]._defaultCommand)
+ _menuMode = (MenuMode)scene._bgShapes[_bgFound]._defaultCommand;
+ else
+ _menuMode = LOOK_MODE;
+ events._released = true;
+ events._pressed = events._oldButtons = false;
+ _help = _oldHelp = -1;
+
+ if (_menuMode == LOOK_MODE) {
+ // Set the flag to tell the game that this was a right-click
+ // call to look and should exit without the look button being pressed
+ _lookHelp = true;
+ }
+ } else {
+ _help = -1;
+ }
+
+ // Check if highlighting a different button than last time
+ if (_help != _oldHelp) {
+ // If another button was highlighted previously, restore it
+ if (_oldHelp != -1)
+ restoreButton(_oldHelp);
+
+ // If we're highlighting a new button, then draw it pressed
+ if (_help != -1)
+ depressButton(_help);
+
+ _oldHelp = _help;
+ }
+
+ if (_bgFound != _oldBgFound || _oldBgFound == -1) {
+ _infoFlag = true;
+ clearInfo();
+
+ if (_help != -1 && !scene._bgShapes[_bgFound]._description.empty()
+ && scene._bgShapes[_bgFound]._description[0] != ' ')
+ screen.print(Common::Point(0, INFO_LINE + 1),
+ INFO_FOREGROUND, "%s", scene._bgShapes[_bgFound]._description.c_str());
+
+ _oldBgFound = _bgFound;
+ }
+ } else {
+ // We're not in STD_MODE
+ // If there isn't a window open, then revert back to STD_MODE
+ if (!_windowOpen && events._rightReleased) {
+ // Restore all buttons
+ for (int idx = 0; idx < 12; ++idx)
+ restoreButton(idx);
+
+ _menuMode = STD_MODE;
+ _key = _oldKey = -1;
+ _temp = _oldTemp = _lookHelp = _invLookFlag = 0;
+ events.clearEvents();
+ }
+ }
+ }
+ }
+
+ // Reset the old bgshape number if the mouse button is released, so that
+ // it can e re-highlighted when we come back here
+ if ((events._rightReleased && _helpStyle) || (events._released && !_helpStyle))
+ _oldBgFound = -1;
+
+ // Do routines that should be done before input processing
+ switch (_menuMode) {
+ case LOOK_MODE:
+ if (!_windowOpen) {
+ if (events._released && _bgFound >= 0 && _bgFound < 1000) {
+ if (!scene._bgShapes[_bgFound]._examine.empty())
+ examine();
+ } else {
+ lookScreen(pt);
+ }
+ }
+ break;
+
+ case MOVE_MODE:
+ case OPEN_MODE:
+ case CLOSE_MODE:
+ case PICKUP_MODE:
+ lookScreen(pt);
+ break;
+
+ case TALK_MODE:
+ if (!_windowOpen) {
+ bool personFound;
+
+ if (_bgFound >= 1000) {
+ personFound = false;
+ if (!events._released)
+ lookScreen(pt);
+ } else {
+ personFound = _bgFound != -1 && scene._bgShapes[_bgFound]._aType == PERSON;
+ }
+
+ if (events._released && personFound)
+ talk.talk(_bgFound);
+ else if (personFound)
+ lookScreen(pt);
+ else if (_bgFound < 1000)
+ clearInfo();
+ }
+ break;
+
+ case USE_MODE:
+ case GIVE_MODE:
+ case INV_MODE:
+ if (inv._invMode == INVMODE_LOOK || inv._invMode == INVMODE_USE || inv._invMode == INVMODE_GIVE) {
+ if (pt.y > CONTROLS_Y)
+ lookInv();
+ else
+ lookScreen(pt);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ //
+ // Do input processing
+ //
+ if (events._pressed || events._released || events._rightPressed || _keyPress || _pause) {
+ if (((events._released && (_helpStyle || _help == -1)) || (events._rightReleased && !_helpStyle)) &&
+ (pt.y <= CONTROLS_Y) && (_menuMode == STD_MODE)) {
+ // The mouse was clicked in the playing area with no action buttons down.
+ // Check if the mouse was clicked in a script zone. If it was,
+ // then execute the script. Otherwise, walk to the given position
+ if (scene.checkForZones(pt, SCRIPT_ZONE) != 0 ||
+ scene.checkForZones(pt, NOWALK_ZONE) != 0) {
+ // Mouse clicked in script zone
+ events._pressed = events._released = false;
+ } else {
+ people._allowWalkAbort = false;
+ people[HOLMES]._walkDest = pt;
+ people[HOLMES].goAllTheWay();
+ }
+
+ if (_oldKey != -1) {
+ restoreButton(_oldTemp);
+ _oldKey = -1;
+ }
+ }
+
+ // Handle action depending on selected mode
+ switch (_menuMode) {
+ case LOOK_MODE:
+ if (_windowOpen)
+ doLookControl();
+ break;
+
+ case MOVE_MODE:
+ doMiscControl(ALLOW_MOVE);
+ break;
+
+ case TALK_MODE:
+ if (_windowOpen)
+ doTalkControl();
+ break;
+
+ case OPEN_MODE:
+ doMiscControl(ALLOW_OPEN);
+ break;
+
+ case CLOSE_MODE:
+ doMiscControl(ALLOW_CLOSE);
+ break;
+
+ case PICKUP_MODE:
+ doPickControl();
+ break;
+
+ case USE_MODE:
+ case GIVE_MODE:
+ case INV_MODE:
+ doInvControl();
+ break;
+
+ case FILES_MODE:
+ doEnvControl();
+ break;
+
+ default:
+ break;
+ }
+
+ // As long as there isn't an open window, do main input processing.
+ // Windows are opened when in TALK, USE, INV, and GIVE modes
+ if ((!_windowOpen && !_menuCounter && pt.y > CONTROLS_Y) ||
+ _keyPress) {
+ if (events._pressed || events._released || _pause || _keyPress)
+ doMainControl();
+ }
+
+ if (pt.y < CONTROLS_Y && events._pressed && _oldTemp != (int)(_menuMode - 1) && _oldKey != -1)
+ restoreButton(_oldTemp);
+ }
+}
+
+void ScalpelUserInterface::depressButton(int num) {
+ Screen &screen = *_vm->_screen;
+ Common::Point pt(MENU_POINTS[num][0], MENU_POINTS[num][1]);
+ offsetButton3DO(pt, num);
+
+ ImageFrame &frame = (*_controls)[num];
+ screen._backBuffer1.transBlitFrom(frame, pt);
+ screen.slamArea(pt.x, pt.y, pt.x + frame._width, pt.y + frame._height);
+}
+
+void ScalpelUserInterface::restoreButton(int num) {
+ Events &events = *_vm->_events;
+ Screen &screen = *_vm->_screen;
+ Common::Point pt(MENU_POINTS[num][0], MENU_POINTS[num][1]);
+ offsetButton3DO(pt, num);
+
+ Graphics::Surface &frame = (*_controls)[num]._frame;
+
+ // Reset the cursor
+ events.setCursor(ARROW);
+
+ // Restore the UI on the back buffer
+ screen._backBuffer1.blitFrom(screen._backBuffer2, pt,
+ Common::Rect(pt.x, pt.y, pt.x + 90, pt.y + 19));
+ screen.slamArea(pt.x, pt.y, pt.x + frame.w, pt.y + frame.h);
+
+ if (!_menuCounter) {
+ _infoFlag = true;
+ clearInfo();
+ }
+}
+
+void ScalpelUserInterface::pushButton(int num) {
+ Events &events = *_vm->_events;
+ _oldKey = -1;
+
+ if (!events._released) {
+ if (_oldHelp != -1)
+ restoreButton(_oldHelp);
+ if (_help != -1)
+ restoreButton(_help);
+
+ depressButton(num);
+ events.wait(6);
+ }
+
+ restoreButton(num);
+}
+
+void ScalpelUserInterface::toggleButton(int num) {
+ Screen &screen = *_vm->_screen;
+
+ if (_menuMode != (MenuMode)(num + 1)) {
+ _menuMode = (MenuMode)(num + 1);
+ _oldKey = COMMANDS[num];
+ _oldTemp = num;
+
+ if (_keyboardInput) {
+ if (_oldHelp != -1 && _oldHelp != num)
+ restoreButton(_oldHelp);
+ if (_help != -1 && _help != num)
+ restoreButton(_help);
+
+ _keyboardInput = false;
+
+ ImageFrame &frame = (*_controls)[num];
+ Common::Point pt(MENU_POINTS[num][0], MENU_POINTS[num][1]);
+ offsetButton3DO(pt, num);
+ screen._backBuffer1.transBlitFrom(frame, pt);
+ screen.slamArea(pt.x, pt.y, pt.x + frame._width, pt.y + frame._height);
+ }
+ } else {
+ _menuMode = STD_MODE;
+ _oldKey = -1;
+ restoreButton(num);
+ }
+}
+
+void ScalpelUserInterface::clearInfo() {
+ if (_infoFlag) {
+ _vm->_screen->vgaBar(Common::Rect(16, INFO_LINE, SHERLOCK_SCREEN_WIDTH - 19,
+ INFO_LINE + 10), INFO_BLACK);
+ _infoFlag = false;
+ _oldLook = -1;
+ }
+}
+
+void ScalpelUserInterface::clearWindow() {
+ if (_windowOpen) {
+ _vm->_screen->vgaBar(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2,
+ SHERLOCK_SCREEN_HEIGHT - 2), INV_BACKGROUND);
+ }
+}
+
+void ScalpelUserInterface::whileMenuCounter() {
+ if (!(--_menuCounter) || _vm->_events->checkInput()) {
+ _menuCounter = 0;
+ _infoFlag = true;
+ clearInfo();
+ }
+}
+
+void ScalpelUserInterface::examine() {
+ Events &events = *_vm->_events;
+ Inventory &inv = *_vm->_inventory;
+ People &people = *_vm->_people;
+ Scene &scene = *_vm->_scene;
+ Talk &talk = *_vm->_talk;
+ Common::Point pt = events.mousePos();
+
+ if (pt.y < (CONTROLS_Y + 9)) {
+ Object &obj = scene._bgShapes[_bgFound];
+
+ if (obj._lookcAnim != 0) {
+ int canimSpeed = ((obj._lookcAnim & 0xe0) >> 5) + 1;
+ scene._cAnimFramePause = obj._lookFrames;
+ _cAnimStr = obj._examine;
+ _cNum = (obj._lookcAnim & 0x1f) - 1;
+
+ scene.startCAnim(_cNum, canimSpeed);
+ } else if (obj._lookPosition.y != 0) {
+ // Need to walk to the object to be examined
+ people[HOLMES].walkToCoords(obj._lookPosition, obj._lookPosition._facing);
+ }
+
+ if (!talk._talkToAbort) {
+ _cAnimStr = obj._examine;
+ if (obj._lookFlag)
+ _vm->setFlags(obj._lookFlag);
+ }
+ } else {
+ // Looking at an inventory item
+ _cAnimStr = inv[_selector]._examine;
+ if (inv[_selector]._lookFlag)
+ _vm->setFlags(inv[_selector]._lookFlag);
+ }
+
+ if (_invLookFlag) {
+ // Don't close the inventory window when starting an examine display, since its
+ // window will slide up to replace the inventory display
+ _windowOpen = false;
+ _menuMode = LOOK_MODE;
+ }
+
+ if (!talk._talkToAbort) {
+ if (!scene._cAnimFramePause)
+ printObjectDesc(_cAnimStr, true);
+ else
+ // description was already printed in startCAnimation
+ scene._cAnimFramePause = 0;
+ }
+}
+
+void ScalpelUserInterface::lookScreen(const Common::Point &pt) {
+ Events &events = *_vm->_events;
+ Inventory &inv = *_vm->_inventory;
+ Scene &scene = *_vm->_scene;
+ Screen &screen = *_vm->_screen;
+ Common::Point mousePos = events.mousePos();
+ int temp;
+ Common::String tempStr;
+
+ // Don't display anything for right button command
+ if ((events._rightPressed || events._rightReleased) && !events._pressed)
+ return;
+
+ if (mousePos.y < CONTROLS_Y && (temp = _bgFound) != -1) {
+ if (temp != _oldLook) {
+ _infoFlag = true;
+ clearInfo();
+
+ if (temp < 1000)
+ tempStr = scene._bgShapes[temp]._description;
+ else
+ tempStr = scene._bgShapes[temp - 1000]._description;
+
+ _infoFlag = true;
+ clearInfo();
+
+ // Only print description if there is one
+ if (!tempStr.empty() && tempStr[0] != ' ') {
+ // If inventory is active and an item is selected for a Use or Give action
+ if ((_menuMode == INV_MODE || _menuMode == USE_MODE || _menuMode == GIVE_MODE) &&
+ (inv._invMode == INVMODE_USE || inv._invMode == INVMODE_GIVE)) {
+ int width1 = 0, width2 = 0;
+ int x, width;
+ if (inv._invMode == INVMODE_USE) {
+ // Using an object
+ x = width = screen.stringWidth("Use ");
+
+ if (temp < 1000 && scene._bgShapes[temp]._aType != PERSON)
+ // It's not a person, so make it lowercase
+ tempStr.setChar(tolower(tempStr[0]), 0);
+
+ x += screen.stringWidth(tempStr);
+
+ // If we're using an inventory object, add in the width
+ // of the object name and the " on "
+ if (_selector != -1) {
+ width1 = screen.stringWidth(inv[_selector]._name);
+ x += width1;
+ width2 = screen.stringWidth(" on ");
+ x += width2;
+ }
+
+ // If the line will be too long, keep cutting off characters
+ // until the string will fit
+ while (x > 280) {
+ x -= screen.charWidth(tempStr.lastChar());
+ tempStr.deleteLastChar();
+ }
+
+ int xStart = (SHERLOCK_SCREEN_WIDTH - x) / 2;
+ screen.print(Common::Point(xStart, INFO_LINE + 1),
+ INFO_FOREGROUND, "Use ");
+
+ if (_selector != -1) {
+ screen.print(Common::Point(xStart + width, INFO_LINE + 1),
+ TALK_FOREGROUND, "%s", inv[_selector]._name.c_str());
+ screen.print(Common::Point(xStart + width + width1, INFO_LINE + 1),
+ INFO_FOREGROUND, " on ");
+ screen.print(Common::Point(xStart + width + width1 + width2, INFO_LINE + 1),
+ INFO_FOREGROUND, "%s", tempStr.c_str());
+ } else {
+ screen.print(Common::Point(xStart + width, INFO_LINE + 1),
+ INFO_FOREGROUND, "%s", tempStr.c_str());
+ }
+ } else if (temp >= 0 && temp < 1000 && _selector != -1 &&
+ scene._bgShapes[temp]._aType == PERSON) {
+ // Giving an object to a person
+ width1 = screen.stringWidth(inv[_selector]._name);
+ x = width = screen.stringWidth("Give ");
+ x += width1;
+ width2 = screen.stringWidth(" to ");
+ x += width2;
+ x += screen.stringWidth(tempStr);
+
+ // Ensure string will fit on-screen
+ while (x > 280) {
+ x -= screen.charWidth(tempStr.lastChar());
+ tempStr.deleteLastChar();
+ }
+
+ int xStart = (SHERLOCK_SCREEN_WIDTH - x) / 2;
+ screen.print(Common::Point(xStart, INFO_LINE + 1),
+ INFO_FOREGROUND, "Give ");
+ screen.print(Common::Point(xStart + width, INFO_LINE + 1),
+ TALK_FOREGROUND, "%s", inv[_selector]._name.c_str());
+ screen.print(Common::Point(xStart + width + width1, INFO_LINE + 1),
+ INFO_FOREGROUND, " to ");
+ screen.print(Common::Point(xStart + width + width1 + width2, INFO_LINE + 1),
+ INFO_FOREGROUND, "%s", tempStr.c_str());
+ }
+ } else {
+ screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", tempStr.c_str());
+ }
+
+ _infoFlag = true;
+ _oldLook = temp;
+ }
+ }
+ } else {
+ clearInfo();
+ }
+}
+
+void ScalpelUserInterface::lookInv() {
+ Events &events = *_vm->_events;
+ Inventory &inv = *_vm->_inventory;
+ Screen &screen = *_vm->_screen;
+ Common::Point mousePos = events.mousePos();
+
+ if (mousePos.x > 15 && mousePos.x < 314 && mousePos.y > (CONTROLS_Y1 + 11)
+ && mousePos.y < (SHERLOCK_SCREEN_HEIGHT - 2)) {
+ int temp = (mousePos.x - 6) / 52 + inv._invIndex;
+ if (temp < inv._holdings) {
+ if (temp < inv._holdings) {
+ clearInfo();
+ screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND,
+ "%s", inv[temp]._description.c_str());
+ _infoFlag = true;
+ _oldLook = temp;
+ }
+ } else {
+ clearInfo();
+ }
+ } else {
+ clearInfo();
+ }
+}
+
+void ScalpelUserInterface::doEnvControl() {
+ Events &events = *_vm->_events;
+ ScalpelSaveManager &saves = *(ScalpelSaveManager *)_vm->_saves;
+ Scene &scene = *_vm->_scene;
+ ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+ Talk &talk = *_vm->_talk;
+ Common::Point mousePos = events.mousePos();
+ static const char ENV_COMMANDS[7] = "ELSUDQ";
+
+ byte color;
+
+ _key = _oldKey = -1;
+ _keyboardInput = false;
+ int found = saves.getHighlightedButton();
+
+ if (events._pressed || events._released) {
+ events.clearKeyboard();
+
+ // Check for a filename entry being highlighted
+ if ((events._pressed || events._released) && mousePos.y > (CONTROLS_Y + 10)) {
+ int found1 = 0;
+ for (_selector = 0; (_selector < ONSCREEN_FILES_COUNT) && !found1; ++_selector)
+ if (mousePos.y > (CONTROLS_Y + 11 + _selector * 10) && mousePos.y < (CONTROLS_Y + 21 + _selector * 10))
+ found1 = 1;
+
+ if (_selector + saves._savegameIndex - 1 < MAX_SAVEGAME_SLOTS + (saves._envMode != SAVEMODE_LOAD))
+ _selector = _selector + saves._savegameIndex - 1;
+ else
+ _selector = -1;
+
+ if (!found1)
+ _selector = -1;
+ }
+
+ // Handle selecting buttons, if any
+ saves.highlightButtons(found);
+
+ if (found == 0 || found == 5)
+ saves._envMode = SAVEMODE_NONE;
+ }
+
+ if (_keyPress) {
+ _key = toupper(_keyPress);
+
+ // Escape _key will close the dialog
+ if (_key == Common::KEYCODE_ESCAPE)
+ _key = 'E';
+
+ if (_key == 'E' || _key == 'L' || _key == 'S' || _key == 'U' || _key == 'D' || _key == 'Q') {
+ const char *chP = strchr(ENV_COMMANDS, _key);
+ int btnIndex = !chP ? -1 : chP - ENV_COMMANDS;
+ saves.highlightButtons(btnIndex);
+ _keyboardInput = true;
+
+ if (_key == 'E' || _key == 'Q') {
+ saves._envMode = SAVEMODE_NONE;
+ } else if (_key >= '1' && _key <= '9') {
+ _keyboardInput = true;
+ _selector = _key - '1';
+ if (_selector >= MAX_SAVEGAME_SLOTS + (saves._envMode == SAVEMODE_LOAD ? 0 : 1))
+ _selector = -1;
+
+ if (saves.checkGameOnScreen(_selector))
+ _oldSelector = _selector;
+ } else {
+ _selector = -1;
+ }
+ }
+ }
+
+ if (_selector != _oldSelector) {
+ if (_oldSelector != -1 && _oldSelector >= saves._savegameIndex && _oldSelector < (saves._savegameIndex + ONSCREEN_FILES_COUNT)) {
+ screen.print(Common::Point(6, CONTROLS_Y + 12 + (_oldSelector - saves._savegameIndex) * 10),
+ INV_FOREGROUND, "%d.", _oldSelector + 1);
+ screen.print(Common::Point(24, CONTROLS_Y + 12 + (_oldSelector - saves._savegameIndex) * 10),
+ INV_FOREGROUND, "%s", saves._savegames[_oldSelector].c_str());
+ }
+
+ if (_selector != -1) {
+ screen.print(Common::Point(6, CONTROLS_Y + 12 + (_selector - saves._savegameIndex) * 10),
+ TALK_FOREGROUND, "%d.", _selector + 1);
+ screen.print(Common::Point(24, CONTROLS_Y + 12 + (_selector - saves._savegameIndex) * 10),
+ TALK_FOREGROUND, "%s", saves._savegames[_selector].c_str());
+ }
+
+ _oldSelector = _selector;
+ }
+
+ if (events._released || _keyboardInput) {
+ if ((found == 0 && events._released) || _key == 'E') {
+ banishWindow();
+ _windowBounds.top = CONTROLS_Y1;
+
+ events._pressed = events._released = _keyboardInput = false;
+ _keyPress = '\0';
+ } else if ((found == 1 && events._released) || _key == 'L') {
+ saves._envMode = SAVEMODE_LOAD;
+ if (_selector != -1) {
+ saves.loadGame(_selector + 1);
+ }
+ } else if ((found == 2 && events._released) || _key == 'S') {
+ saves._envMode = SAVEMODE_SAVE;
+ if (_selector != -1) {
+ if (saves.checkGameOnScreen(_selector))
+ _oldSelector = _selector;
+
+ if (saves.promptForDescription(_selector)) {
+ saves.saveGame(_selector + 1, saves._savegames[_selector]);
+
+ banishWindow(1);
+ _windowBounds.top = CONTROLS_Y1;
+ _key = _oldKey = -1;
+ _keyPress = '\0';
+ _keyboardInput = false;
+ } else {
+ if (!talk._talkToAbort) {
+ screen._backBuffer1.fillRect(Common::Rect(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10,
+ SHERLOCK_SCREEN_WIDTH - 2, CONTROLS_Y + 20 + (_selector - saves._savegameIndex) * 10), INV_BACKGROUND);
+ screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10), INV_FOREGROUND,
+ "%d.", _selector + 1);
+ screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10), INV_FOREGROUND,
+ "%s", saves._savegames[_selector].c_str());
+
+ screen.slamArea(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10, 311, 10);
+ _selector = _oldSelector = -1;
+ }
+ }
+ }
+ } else if (((found == 3 && events._released) || _key == 'U') && saves._savegameIndex) {
+ bool moreKeys;
+ do {
+ saves._savegameIndex--;
+ screen._backBuffer1.fillRect(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2,
+ SHERLOCK_SCREEN_HEIGHT - 1), INV_BACKGROUND);
+
+ for (int idx = saves._savegameIndex; idx < (saves._savegameIndex + ONSCREEN_FILES_COUNT); ++idx) {
+ color = INV_FOREGROUND;
+ if (idx == _selector && idx >= saves._savegameIndex && idx < (saves._savegameIndex + ONSCREEN_FILES_COUNT))
+ color = TALK_FOREGROUND;
+
+ screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (idx - saves._savegameIndex) * 10), color, "%d.", idx + 1);
+ screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (idx - saves._savegameIndex) * 10), color, "%s", saves._savegames[idx].c_str());
+ }
+
+ screen.slamRect(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2, SHERLOCK_SCREEN_HEIGHT));
+
+ color = !saves._savegameIndex ? COMMAND_NULL : COMMAND_FOREGROUND;
+ screen.buttonPrint(Common::Point(ENV_POINTS[3][2], CONTROLS_Y), color, true, "Up");
+ color = (saves._savegameIndex == MAX_SAVEGAME_SLOTS - ONSCREEN_FILES_COUNT) ? COMMAND_NULL : COMMAND_FOREGROUND;
+ screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), color, true, "Down");
+
+ // Check whether there are more pending U keys pressed
+ moreKeys = false;
+ if (events.kbHit()) {
+ Common::KeyState keyState = events.getKey();
+
+ _key = toupper(keyState.keycode);
+ moreKeys = _key == 'U';
+ }
+ } while ((saves._savegameIndex) && moreKeys);
+ } else if (((found == 4 && events._released) || _key == 'D') && saves._savegameIndex < (MAX_SAVEGAME_SLOTS - ONSCREEN_FILES_COUNT)) {
+ bool moreKeys;
+ do {
+ saves._savegameIndex++;
+ screen._backBuffer1.fillRect(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2,
+ SHERLOCK_SCREEN_HEIGHT - 1), INV_BACKGROUND);
+
+ for (int idx = saves._savegameIndex; idx < (saves._savegameIndex + ONSCREEN_FILES_COUNT); ++idx) {
+ if (idx == _selector && idx >= saves._savegameIndex && idx < (saves._savegameIndex + ONSCREEN_FILES_COUNT))
+ color = TALK_FOREGROUND;
+ else
+ color = INV_FOREGROUND;
+
+ screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (idx - saves._savegameIndex) * 10), color,
+ "%d.", idx + 1);
+ screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (idx - saves._savegameIndex) * 10), color,
+ "%s", saves._savegames[idx].c_str());
+ }
+
+ screen.slamRect(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2, SHERLOCK_SCREEN_HEIGHT));
+
+ color = (!saves._savegameIndex) ? COMMAND_NULL : COMMAND_FOREGROUND;
+ screen.buttonPrint(Common::Point(ENV_POINTS[3][2], CONTROLS_Y), color, true, "Up");
+
+ color = (saves._savegameIndex == MAX_SAVEGAME_SLOTS - ONSCREEN_FILES_COUNT) ? COMMAND_NULL : COMMAND_FOREGROUND;
+ screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), color, true, "Down");
+
+ // Check whether there are more pending D keys pressed
+ moreKeys = false;
+ if (events.kbHit()) {
+ Common::KeyState keyState;
+ _key = toupper(keyState.keycode);
+
+ moreKeys = _key == 'D';
+ }
+ } while (saves._savegameIndex < (MAX_SAVEGAME_SLOTS - ONSCREEN_FILES_COUNT) && moreKeys);
+ } else if ((found == 5 && events._released) || _key == 'Q') {
+ clearWindow();
+ screen.print(Common::Point(0, CONTROLS_Y + 20), INV_FOREGROUND, "Are you sure you wish to Quit ?");
+ screen.vgaBar(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y + 10), BORDER_COLOR);
+
+ screen.makeButton(Common::Rect(112, CONTROLS_Y, 160, CONTROLS_Y + 10), 136 - screen.stringWidth("Yes") / 2, "Yes");
+ screen.makeButton(Common::Rect(161, CONTROLS_Y, 209, CONTROLS_Y + 10), 184 - screen.stringWidth("No") / 2, "No");
+ screen.slamArea(112, CONTROLS_Y, 97, 10);
+
+ do {
+ scene.doBgAnim();
+
+ if (talk._talkToAbort)
+ return;
+
+ events.pollEventsAndWait();
+ events.setButtonState();
+ mousePos = events.mousePos();
+
+ if (events.kbHit()) {
+ Common::KeyState keyState = events.getKey();
+ _key = toupper(keyState.keycode);
+
+ if (_key == 'X' && (keyState.flags & Common::KBD_ALT) != 0) {
+ _vm->quitGame();
+ events.pollEvents();
+ return;
+ }
+
+ if (_key == Common::KEYCODE_ESCAPE)
+ _key = 'N';
+
+ if (_key == Common::KEYCODE_RETURN || _key == ' ') {
+ events._pressed = false;
+ events._released = true;
+ events._oldButtons = 0;
+ _keyPress = '\0';
+ }
+ }
+
+ if (events._pressed || events._released) {
+ if (mousePos.x > 112 && mousePos.x < 159 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 9))
+ color = COMMAND_HIGHLIGHTED;
+ else
+ color = COMMAND_FOREGROUND;
+ screen.buttonPrint(Common::Point(136, CONTROLS_Y), color, true, "Yes");
+
+ if (mousePos.x > 161 && mousePos.x < 208 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 9))
+ color = COMMAND_HIGHLIGHTED;
+ else
+ color = COMMAND_FOREGROUND;
+ screen.buttonPrint(Common::Point(184, CONTROLS_Y), color, true, "No");
+ }
+
+ if (mousePos.x > 112 && mousePos.x < 159 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 9) && events._released)
+ _key = 'Y';
+
+ if (mousePos.x > 161 && mousePos.x < 208 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 9) && events._released)
+ _key = 'N';
+ } while (!_vm->shouldQuit() && _key != 'Y' && _key != 'N');
+
+ if (_key == 'Y') {
+ _vm->quitGame();
+ events.pollEvents();
+ return;
+ } else {
+ screen.buttonPrint(Common::Point(184, CONTROLS_Y), COMMAND_HIGHLIGHTED, true, "No");
+ banishWindow(1);
+ _windowBounds.top = CONTROLS_Y1;
+ _key = -1;
+ }
+ } else {
+ if (_selector != -1) {
+ // Are we already in Load mode?
+ if (saves._envMode == SAVEMODE_LOAD) {
+ saves.loadGame(_selector + 1);
+ } else if (saves._envMode == SAVEMODE_SAVE || saves.isSlotEmpty(_selector)) {
+ // We're already in save mode, or pointing to an empty save slot
+ if (saves.checkGameOnScreen(_selector))
+ _oldSelector = _selector;
+
+ if (saves.promptForDescription(_selector)) {
+ saves.saveGame(_selector + 1, saves._savegames[_selector]);
+ banishWindow();
+ _windowBounds.top = CONTROLS_Y1;
+ _key = _oldKey = -1;
+ _keyPress = '\0';
+ _keyboardInput = false;
+ } else {
+ if (!talk._talkToAbort) {
+ screen._backBuffer1.fillRect(Common::Rect(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10,
+ 317, CONTROLS_Y + 20 + (_selector - saves._savegameIndex) * 10), INV_BACKGROUND);
+ screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10),
+ INV_FOREGROUND, "%d.", _selector + 1);
+ screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10),
+ INV_FOREGROUND, "%s", saves._savegames[_selector].c_str());
+ screen.slamArea(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10, 311, 10);
+ _selector = _oldSelector = -1;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void ScalpelUserInterface::doInvControl() {
+ Events &events = *_vm->_events;
+ FixedText &fixedText = *_vm->_fixedText;
+ ScalpelInventory &inv = *(ScalpelInventory *)_vm->_inventory;
+ Scene &scene = *_vm->_scene;
+ ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+ Talk &talk = *_vm->_talk;
+ int colors[8];
+ Common::Point mousePos = events.mousePos();
+
+ _key = _oldKey = -1;
+ _keyboardInput = false;
+
+ // Check whether any inventory slot is highlighted
+ int found = -1;
+ Common::fill(&colors[0], &colors[8], (int)COMMAND_FOREGROUND);
+ for (int idx = 0; idx < 8; ++idx) {
+ Common::Rect r(INVENTORY_POINTS[idx][0], CONTROLS_Y1,
+ INVENTORY_POINTS[idx][1], CONTROLS_Y1 + 10);
+ if (r.contains(mousePos)) {
+ found = idx;
+ break;
+ }
+ }
+
+ if (events._pressed || events._released) {
+ events.clearKeyboard();
+
+ Common::String fixedText_Exit = fixedText.getText(kFixedText_Inventory_Exit);
+ Common::String fixedText_Look = fixedText.getText(kFixedText_Inventory_Look);
+ Common::String fixedText_Use = fixedText.getText(kFixedText_Inventory_Use);
+ Common::String fixedText_Give = fixedText.getText(kFixedText_Inventory_Give);
+
+ if (found != -1)
+ // If a slot highlighted, set its color
+ colors[found] = COMMAND_HIGHLIGHTED;
+ screen.buttonPrint(Common::Point(INVENTORY_POINTS[0][2], CONTROLS_Y1), colors[0], true, fixedText_Exit);
+
+ if (found >= 0 && found <= 3) {
+ screen.buttonPrint(Common::Point(INVENTORY_POINTS[1][2], CONTROLS_Y1), colors[1], true, fixedText_Look);
+ screen.buttonPrint(Common::Point(INVENTORY_POINTS[2][2], CONTROLS_Y1), colors[2], true, fixedText_Use);
+ screen.buttonPrint(Common::Point(INVENTORY_POINTS[3][2], CONTROLS_Y1), colors[3], true, fixedText_Give);
+ inv._invMode = (InvMode)found;
+ _selector = -1;
+ }
+
+ if (inv._invIndex) {
+ screen.print(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1 + 1), colors[4], "^^");
+ screen.print(Common::Point(INVENTORY_POINTS[5][2], CONTROLS_Y1 + 1), colors[5], "^");
+ }
+
+ if ((inv._holdings - inv._invIndex) > 6) {
+ screen.print(Common::Point(INVENTORY_POINTS[6][2], CONTROLS_Y1 + 1), colors[6], "_");
+ screen.print(Common::Point(INVENTORY_POINTS[7][2], CONTROLS_Y1 + 1), colors[7], "__");
+ }
+
+ bool flag = false;
+ if (inv._invMode == INVMODE_LOOK || inv._invMode == INVMODE_USE || inv._invMode == INVMODE_GIVE) {
+ Common::Rect r(15, CONTROLS_Y1 + 11, 314, SHERLOCK_SCREEN_HEIGHT - 2);
+ if (r.contains(mousePos)) {
+ _selector = (mousePos.x - 6) / 52 + inv._invIndex;
+ if (_selector < inv._holdings)
+ flag = true;
+ }
+ }
+
+ if (!flag && mousePos.y >(CONTROLS_Y1 + 11))
+ _selector = -1;
+ }
+
+ if (_keyPress) {
+ _key = toupper(_keyPress);
+
+ if (_key == Common::KEYCODE_ESCAPE)
+ // Escape will also 'E'xit out of inventory display
+ _key = 'E';
+
+ if (_key == 'E' || _key == 'L' || _key == 'U' || _key == 'G'
+ || _key == '-' || _key == '+') {
+ InvMode temp = inv._invMode;
+
+ const char *chP = strchr(INVENTORY_COMMANDS, _key);
+ inv._invMode = !chP ? INVMODE_INVALID : (InvMode)(chP - INVENTORY_COMMANDS);
+ inv.invCommands(true);
+
+ inv._invMode = temp;
+ _keyboardInput = true;
+ if (_key == 'E')
+ inv._invMode = INVMODE_EXIT;
+ _selector = -1;
+ } else {
+ _selector = -1;
+ }
+ }
+
+ if (_selector != _oldSelector) {
+ if (_oldSelector != -1) {
+ // Un-highlight
+ if (_oldSelector >= inv._invIndex && _oldSelector < (inv._invIndex + 6))
+ inv.highlight(_oldSelector, BUTTON_MIDDLE);
+ }
+
+ if (_selector != -1)
+ inv.highlight(_selector, BUTTON_BACKGROUND);
+
+ _oldSelector = _selector;
+ }
+
+ if (events._released || _keyboardInput) {
+ if ((found == 0 && events._released) || _key == 'E') {
+ inv.freeInv();
+ _infoFlag = true;
+ clearInfo();
+ banishWindow(false);
+ _key = -1;
+ events.clearEvents();
+ events.setCursor(ARROW);
+ } else if ((found == 1 && events._released) || (_key == 'L')) {
+ inv._invMode = INVMODE_LOOK;
+ } else if ((found == 2 && events._released) || (_key == 'U')) {
+ inv._invMode = INVMODE_USE;
+ } else if ((found == 3 && events._released) || (_key == 'G')) {
+ inv._invMode = INVMODE_GIVE;
+ } else if (((found == 4 && events._released) || _key == ',') && inv._invIndex) {
+ if (inv._invIndex >= 6)
+ inv._invIndex -= 6;
+ else
+ inv._invIndex = 0;
+
+ screen.print(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1 + 1),
+ COMMAND_HIGHLIGHTED, "^^");
+ inv.freeGraphics();
+ inv.loadGraphics();
+ inv.putInv(SLAM_DISPLAY);
+ inv.invCommands(true);
+ } else if (((found == 5 && events._released) || _key == '-') && inv._invIndex > 0) {
+ --inv._invIndex;
+ screen.print(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1 + 1), COMMAND_HIGHLIGHTED, "^");
+ inv.freeGraphics();
+ inv.loadGraphics();
+ inv.putInv(SLAM_DISPLAY);
+ inv.invCommands(true);
+ } else if (((found == 6 && events._released) || _key == '+') && (inv._holdings - inv._invIndex) > 6) {
+ ++inv._invIndex;
+ screen.print(Common::Point(INVENTORY_POINTS[6][2], CONTROLS_Y1 + 1), COMMAND_HIGHLIGHTED, "_");
+ inv.freeGraphics();
+ inv.loadGraphics();
+ inv.putInv(SLAM_DISPLAY);
+ inv.invCommands(true);
+ } else if (((found == 7 && events._released) || _key == '.') && (inv._holdings - inv._invIndex) > 6) {
+ inv._invIndex += 6;
+ if ((inv._holdings - 6) < inv._invIndex)
+ inv._invIndex = inv._holdings - 6;
+
+ screen.print(Common::Point(INVENTORY_POINTS[7][2], CONTROLS_Y1 + 1), COMMAND_HIGHLIGHTED, "_");
+ inv.freeGraphics();
+ inv.loadGraphics();
+ inv.putInv(SLAM_DISPLAY);
+ inv.invCommands(true);
+ } else {
+ // If something is being given, make sure it's being given to a person
+ if (inv._invMode == INVMODE_GIVE) {
+ if (_bgFound != -1 && scene._bgShapes[_bgFound]._aType == PERSON)
+ _find = _bgFound;
+ else
+ _find = -1;
+ } else {
+ _find = _bgFound;
+ }
+
+ if ((mousePos.y < CONTROLS_Y1) && (inv._invMode == INVMODE_LOOK) && (_find >= 0) && (_find < 1000)) {
+ if (!scene._bgShapes[_find]._examine.empty() &&
+ scene._bgShapes[_find]._examine[0] >= ' ')
+ inv.refreshInv();
+ } else if (_selector != -1 || _find >= 0) {
+ // Selector is the inventory object that was clicked on, or selected.
+ // If it's -1, then no inventory item is highlighted yet. Otherwise,
+ // an object in the scene has been clicked.
+
+ if (_selector != -1 && inv._invMode == INVMODE_LOOK
+ && mousePos.y >(CONTROLS_Y1 + 11))
+ inv.refreshInv();
+
+ if (talk._talkToAbort)
+ return;
+
+ // Now check for the Use and Give actions. If inv_mode is INVMODE_GIVE,
+ // that means GIVE is in effect, _selector is the object being
+ // given, and _find is the target.
+ // The same applies to USE, except if _selector is -1, then USE
+ // is being tried on an object in the scene without an inventory
+ // object being highlighted first.
+
+ if ((inv._invMode == INVMODE_USE || (_selector != -1 && inv._invMode == INVMODE_GIVE)) && _find >= 0) {
+ events._pressed = events._released = false;
+ _infoFlag = true;
+ clearInfo();
+
+ int tempSel = _selector; // Save the selector
+ _selector = -1;
+
+ inv.putInv(SLAM_DISPLAY);
+ _selector = tempSel; // Restore it
+ InvMode tempMode = inv._invMode;
+ inv._invMode = INVMODE_USE55;
+ inv.invCommands(true);
+
+ _infoFlag = true;
+ clearInfo();
+ banishWindow(false);
+ _key = -1;
+
+ inv.freeInv();
+
+ bool giveFl = (tempMode >= INVMODE_GIVE);
+ if (_selector >= 0)
+ // Use/Give inv object with scene object
+ checkUseAction(&scene._bgShapes[_find]._use[0], inv[_selector]._name, kFixedTextAction_Use, _find, giveFl);
+ else
+ // Now inv object has been highlighted
+ checkUseAction(&scene._bgShapes[_find]._use[0], "*SELF*", kFixedTextAction_Use, _find, giveFl);
+
+ _selector = _oldSelector = -1;
+ }
+ }
+ }
+ }
+}
+
+void ScalpelUserInterface::doLookControl() {
+ Events &events = *_vm->_events;
+ ScalpelInventory &inv = *(ScalpelInventory *)_vm->_inventory;
+ Screen &screen = *_vm->_screen;
+
+ _key = _oldKey = -1;
+ _keyboardInput = (_keyPress != '\0');
+
+ if (events._released || events._rightReleased || _keyboardInput) {
+ // Is an inventory object being looked at?
+ if (!_invLookFlag) {
+ // Is there any remaining text to display?
+ if (!_descStr.empty()) {
+ printObjectDesc(_descStr, false);
+ } else if (!_lookHelp) {
+ // Need to close the window and depress the Look button
+ Common::Point pt(MENU_POINTS[0][0], MENU_POINTS[0][1]);
+ offsetButton3DO(pt, 0);
+ screen._backBuffer2.blitFrom((*_controls)[0], pt);
+ banishWindow(true);
+
+ _windowBounds.top = CONTROLS_Y1;
+ _key = _oldKey = COMMANDS[LOOK_MODE - 1];
+ _temp = _oldTemp = 0;
+ _menuMode = LOOK_MODE;
+ events.clearEvents();
+
+ // Restore UI
+ drawInterface();
+ } else {
+ events.setCursor(ARROW);
+ banishWindow(true);
+ _windowBounds.top = CONTROLS_Y1;
+ _key = _oldKey = -1;
+ _temp = _oldTemp = 0;
+ _menuMode = STD_MODE;
+ events.clearEvents();
+ }
+ } else {
+ // Looking at an inventory object
+ // Backup the user interface
+ Surface tempSurface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y1);
+ tempSurface.blitFrom(screen._backBuffer2, Common::Point(0, 0),
+ Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
+
+ inv.drawInventory(INVENTORY_DONT_DISPLAY);
+ banishWindow(true);
+
+ // Restore the ui
+ screen._backBuffer2.blitFrom(tempSurface, Common::Point(0, CONTROLS_Y1));
+
+ _windowBounds.top = CONTROLS_Y1;
+ _key = _oldKey = COMMANDS[LOOK_MODE - 1];
+ _temp = _oldTemp = 0;
+ events.clearEvents();
+ _invLookFlag = false;
+ _menuMode = INV_MODE;
+ _windowOpen = true;
+ }
+ }
+}
+
+void ScalpelUserInterface::doMainControl() {
+ Events &events = *_vm->_events;
+ ScalpelInventory &inv = *(ScalpelInventory *)_vm->_inventory;
+ ScalpelSaveManager &saves = *(ScalpelSaveManager *)_vm->_saves;
+ Common::Point pt = events.mousePos();
+
+ if ((events._pressed || events._released) && pt.y > CONTROLS_Y) {
+ events.clearKeyboard();
+ _key = -1;
+
+ // Check whether the mouse is in any of the command areas
+ for (_temp = 0; (_temp < 12) && (_key == -1); ++_temp) {
+ Common::Rect r(MENU_POINTS[_temp][0], MENU_POINTS[_temp][1],
+ MENU_POINTS[_temp][2], MENU_POINTS[_temp][3]);
+ if (IS_3DO && _temp >= 0 && _temp <= 2) {
+ r.left += UI_OFFSET_3DO - 1;
+ r.right += UI_OFFSET_3DO - 1;
+ }
+ if (r.contains(pt))
+ _key = COMMANDS[_temp];
+ }
+ --_temp;
+ } else if (_keyPress) {
+ // Keyboard control
+ _keyboardInput = true;
+
+ if (_keyPress >= 'A' && _keyPress <= 'Z') {
+ const char *c = strchr(COMMANDS, _keyPress);
+ _temp = !c ? 12 : c - COMMANDS;
+ } else {
+ _temp = 12;
+ }
+
+ if (_temp == 12)
+ _key = -1;
+
+ if (events._rightPressed) {
+ _temp = 12;
+ _key = -1;
+ }
+ } else if (!events._released) {
+ _key = -1;
+ }
+
+ // Check if the button being pointed to has changed
+ if (_oldKey != _key && !_windowOpen) {
+ // Clear the info line
+ _infoFlag = true;
+ clearInfo();
+
+ // If there was an old button selected, restore it
+ if (_oldKey != -1) {
+ _menuMode = STD_MODE;
+ restoreButton(_oldTemp);
+ }
+
+ // If a new button is being pointed to, highlight it
+ if (_key != -1 && _temp < 12 && !_keyboardInput)
+ depressButton(_temp);
+
+ // Save the new button selection
+ _oldKey = _key;
+ _oldTemp = _temp;
+ }
+
+ if (!events._pressed && !_windowOpen) {
+ switch (_key) {
+ case 'L':
+ toggleButton(0);
+ break;
+ case 'M':
+ toggleButton(1);
+ break;
+ case 'T':
+ toggleButton(2);
+ break;
+ case 'P':
+ toggleButton(3);
+ break;
+ case 'O':
+ toggleButton(4);
+ break;
+ case 'C':
+ toggleButton(5);
+ break;
+ case 'I':
+ pushButton(6);
+ _selector = _oldSelector = -1;
+ _menuMode = INV_MODE;
+ inv.drawInventory(PLAIN_INVENTORY);
+ break;
+ case 'U':
+ pushButton(7);
+ _selector = _oldSelector = -1;
+ _menuMode = USE_MODE;
+ inv.drawInventory(USE_INVENTORY_MODE);
+ break;
+ case 'G':
+ pushButton(8);
+ _selector = _oldSelector = -1;
+ _menuMode = GIVE_MODE;
+ inv.drawInventory(GIVE_INVENTORY_MODE);
+ break;
+ case 'J':
+ pushButton(9);
+ _menuMode = JOURNAL_MODE;
+ journalControl();
+ break;
+ case 'F':
+ pushButton(10);
+
+ // Create a thumbnail of the current screen before the files dialog is shown, in case
+ // the user saves the game
+ saves.createThumbnail();
+
+ _selector = _oldSelector = -1;
+
+ if (_vm->_showOriginalSavesDialog) {
+ // Show the original dialog
+ _menuMode = FILES_MODE;
+ saves.drawInterface();
+ _windowOpen = true;
+ } else {
+ // Show the ScummVM GMM instead
+ _vm->_canLoadSave = true;
+ _vm->openMainMenuDialog();
+ _vm->_canLoadSave = false;
+ }
+ break;
+ case 'S':
+ pushButton(11);
+ _menuMode = SETUP_MODE;
+ Settings::show(_vm);
+ break;
+ default:
+ break;
+ }
+
+ _help = _oldHelp = _oldBgFound = -1;
+ }
+}
+
+void ScalpelUserInterface::doMiscControl(int allowed) {
+ Events &events = *_vm->_events;
+ Scene &scene = *_vm->_scene;
+ Talk &talk = *_vm->_talk;
+
+ if (events._released) {
+ _temp = _bgFound;
+ if (_bgFound != -1) {
+ // Only allow pointing to objects, not people
+ if (_bgFound < 1000) {
+ events.clearEvents();
+ Object &obj = scene._bgShapes[_bgFound];
+
+ switch (allowed) {
+ case ALLOW_OPEN:
+ checkAction(obj._aOpen, _temp, kFixedTextAction_Open);
+ if (_menuMode != TALK_MODE && !talk._talkToAbort) {
+ _menuMode = STD_MODE;
+ restoreButton(OPEN_MODE - 1);
+ _key = _oldKey = -1;
+ }
+ break;
+
+ case ALLOW_CLOSE:
+ checkAction(obj._aClose, _temp, kFixedTextAction_Close);
+ if (_menuMode != TALK_MODE && !talk._talkToAbort) {
+ _menuMode = STD_MODE;
+ restoreButton(CLOSE_MODE - 1);
+ _key = _oldKey = -1;
+ }
+ break;
+
+ case ALLOW_MOVE:
+ checkAction(obj._aMove, _temp, kFixedTextAction_Move);
+ if (_menuMode != TALK_MODE && !talk._talkToAbort) {
+ _menuMode = STD_MODE;
+ restoreButton(MOVE_MODE - 1);
+ _key = _oldKey = -1;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+}
+
+void ScalpelUserInterface::doPickControl() {
+ Events &events = *_vm->_events;
+ Scene &scene = *_vm->_scene;
+ Talk &talk = *_vm->_talk;
+
+ if (events._released) {
+ if ((_temp = _bgFound) != -1) {
+ events.clearEvents();
+
+ // Don't allow characters to be picked up
+ if (_bgFound < 1000) {
+ scene._bgShapes[_bgFound].pickUpObject(kFixedTextAction_Pick);
+
+ if (!talk._talkToAbort && _menuMode != TALK_MODE) {
+ _key = _oldKey = -1;
+ _menuMode = STD_MODE;
+ restoreButton(PICKUP_MODE - 1);
+ }
+ }
+ }
+ }
+}
+
+void ScalpelUserInterface::doTalkControl() {
+ Events &events = *_vm->_events;
+ FixedText &fixedText = *_vm->_fixedText;
+ ScalpelJournal &journal = *(ScalpelJournal *)_vm->_journal;
+ ScalpelPeople &people = *(ScalpelPeople *)_vm->_people;
+ ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+ Sound &sound = *_vm->_sound;
+ Talk &talk = *_vm->_talk;
+ Common::Point mousePos = events.mousePos();
+
+ _key = _oldKey = -1;
+ _keyboardInput = false;
+
+ Common::String fixedText_Exit = fixedText.getText(kFixedText_Window_Exit);
+ Common::String fixedText_Up = fixedText.getText(kFixedText_Window_Up);
+ Common::String fixedText_Down = fixedText.getText(kFixedText_Window_Down);
+
+ if (events._pressed || events._released) {
+ events.clearKeyboard();
+
+ // Handle button printing
+ if (mousePos.x > 99 && mousePos.x < 138 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 10) && !_endKeyActive)
+ screen.buttonPrint(Common::Point(119, CONTROLS_Y), COMMAND_HIGHLIGHTED, true, fixedText_Exit);
+ else if (_endKeyActive)
+ screen.buttonPrint(Common::Point(119, CONTROLS_Y), COMMAND_FOREGROUND, true, fixedText_Exit);
+
+ if (mousePos.x > 140 && mousePos.x < 170 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 10) && talk._moreTalkUp)
+ screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_HIGHLIGHTED, true, fixedText_Up);
+ else if (talk._moreTalkUp)
+ screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_FOREGROUND, true, fixedText_Up);
+
+ if (mousePos.x > 181&& mousePos.x < 220 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 10) && talk._moreTalkDown)
+ screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_HIGHLIGHTED, true, fixedText_Down);
+ else if (talk._moreTalkDown)
+ screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_FOREGROUND, true, fixedText_Down);
+
+ bool found = false;
+ for (_selector = talk._talkIndex; _selector < (int)talk._statements.size() && !found; ++_selector) {
+ if (mousePos.y > talk._statements[_selector]._talkPos.top &&
+ mousePos.y < talk._statements[_selector]._talkPos.bottom)
+ found = true;
+ }
+ --_selector;
+ if (!found)
+ _selector = -1;
+ }
+
+ if (_keyPress) {
+ _key = toupper(_keyPress);
+ if (_key == Common::KEYCODE_ESCAPE)
+ _key = 'E';
+
+ // Check for number press indicating reply line
+ if (_key >= '1' && _key <= ('1' + (int)talk._statements.size() - 1)) {
+ for (uint idx = 0; idx < talk._statements.size(); ++idx) {
+ if (talk._statements[idx]._talkMap == (_key - '1')) {
+ // Found the given statement
+ _selector = idx;
+ _key = -1;
+ _keyboardInput = true;
+ break;
+ }
+ }
+ } else if (_key == 'E' || _key == 'U' || _key == 'D') {
+ _keyboardInput = true;
+ } else {
+ _selector = -1;
+ }
+ }
+
+ if (_selector != _oldSelector) {
+ // Remove highlighting from previous line, if any
+ if (_oldSelector != -1) {
+ if (!((talk._talkHistory[talk._converseNum][_oldSelector] >> (_oldSelector & 7)) & 1))
+ talk.talkLine(_oldSelector, talk._statements[_oldSelector]._talkMap, INV_FOREGROUND,
+ talk._statements[_oldSelector]._talkPos.top, true);
+ else
+ talk.talkLine(_oldSelector, talk._statements[_oldSelector]._talkMap, TALK_NULL,
+ talk._statements[_oldSelector]._talkPos.top, true);
+ }
+
+ // Add highlighting to new line, if any
+ if (_selector != -1)
+ talk.talkLine(_selector, talk._statements[_selector]._talkMap, TALK_FOREGROUND,
+ talk._statements[_selector]._talkPos.top, true);
+
+ _oldSelector = _selector;
+ }
+
+ if (events._released || _keyboardInput) {
+ if (((Common::Rect(99, CONTROLS_Y, 138, CONTROLS_Y + 10).contains(mousePos) && events._released)
+ || _key == 'E') && _endKeyActive) {
+ talk.freeTalkVars();
+ talk.pullSequence();
+
+ drawInterface(2);
+ banishWindow();
+ _windowBounds.top = CONTROLS_Y1;
+ } else if (((Common::Rect(140, CONTROLS_Y, 179, CONTROLS_Y + 10).contains(mousePos) && events._released)
+ || _key == 'U') && talk._moreTalkUp) {
+ while (talk._statements[--talk._talkIndex]._talkMap == -1)
+ ;
+ screen._backBuffer1.fillRect(Common::Rect(5, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2,
+ SHERLOCK_SCREEN_HEIGHT - 1), INV_BACKGROUND);
+ talk.displayTalk(false);
+
+ screen.slamRect(Common::Rect(5, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH - 5, SHERLOCK_SCREEN_HEIGHT - 2));
+ } else if (((Common::Rect(181, CONTROLS_Y, 220, CONTROLS_Y + 10).contains(mousePos) && events._released)
+ || _key == 'D') && talk._moreTalkDown) {
+ do {
+ ++talk._talkIndex;
+ } while (talk._talkIndex < (int)talk._statements.size() && talk._statements[talk._talkIndex]._talkMap == -1);
+
+ screen._backBuffer1.fillRect(Common::Rect(5, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2,
+ SHERLOCK_SCREEN_HEIGHT - 1), INV_BACKGROUND);
+ talk.displayTalk(false);
+
+ screen.slamRect(Common::Rect(5, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH - 5, SHERLOCK_SCREEN_HEIGHT - 2));
+ } else if (_selector != -1) {
+ screen.buttonPrint(Common::Point(119, CONTROLS_Y), COMMAND_NULL, true, fixedText_Exit);
+ screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_NULL, true, fixedText_Up);
+ screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_NULL, true, fixedText_Down);
+
+ // If the reply is new, add it to the journal
+ if (!talk._talkHistory[talk._converseNum][_selector]) {
+ journal.record(talk._converseNum, _selector);
+
+ // Add any Holmes point to Holmes' total, if any
+ if (talk._statements[_selector]._quotient)
+ people._holmesQuotient += talk._statements[_selector]._quotient;
+ }
+
+ // Flag the response as having been used
+ talk._talkHistory[talk._converseNum][_selector] = true;
+
+ clearWindow();
+ screen.print(Common::Point(16, CONTROLS_Y + 12), TALK_FOREGROUND, "Sherlock Holmes");
+ talk.talkLine(_selector + 128, talk._statements[_selector]._talkMap, COMMAND_FOREGROUND, CONTROLS_Y + 21, true);
+
+ switch (talk._statements[_selector]._portraitSide & 3) {
+ case 0:
+ case 1:
+ people._portraitSide = 20;
+ break;
+ case 2:
+ people._portraitSide = 220;
+ break;
+ case 3:
+ people._portraitSide = 120;
+ break;
+ }
+
+ // Check for flipping Holmes
+ if (talk._statements[_selector]._portraitSide & REVERSE_DIRECTION)
+ people._holmesFlip = true;
+
+ talk._speaker = 0;
+ people.setTalking(0);
+
+ if (!talk._statements[_selector]._voiceFile.empty() && sound._voices) {
+ sound.playSound(talk._statements[_selector]._voiceFile, WAIT_RETURN_IMMEDIATELY);
+
+ // Set voices as an indicator for waiting
+ sound._voices = 2;
+ sound._speechOn = *sound._soundIsOn;
+ } else {
+ sound._speechOn = false;
+ }
+
+ // Trigger to play 3DO movie
+ talk.talk3DOMovieTrigger(0);
+
+ talk.waitForMore(talk._statements[_selector]._statement.size());
+ if (talk._talkToAbort)
+ return;
+
+ people.clearTalking();
+ if (talk._talkToAbort)
+ return;
+
+ while (!_vm->shouldQuit()) {
+ talk._scriptSelect = _selector;
+ talk._speaker = talk._talkTo;
+ talk.doScript(talk._statements[_selector]._reply);
+
+ if (!talk._talkToAbort) {
+ if (!talk._talkStealth)
+ clearWindow();
+
+ if (!talk._statements[_selector]._modified.empty()) {
+ for (uint idx = 0; idx < talk._statements[_selector]._modified.size(); ++idx) {
+ _vm->setFlags(talk._statements[_selector]._modified[idx]);
+ }
+
+ talk.setTalkMap();
+ }
+
+ // Check for another linked talk file
+ Common::String linkFilename = talk._statements[_selector]._linkFile;
+ if (!linkFilename.empty() && !talk._scriptMoreFlag) {
+ talk.freeTalkVars();
+ talk.loadTalkFile(linkFilename);
+
+ // Find the first new statement
+ int select = _selector = _oldSelector = -1;
+ for (uint idx = 0; idx < talk._statements.size() && select == -1; ++idx) {
+ if (!talk._statements[idx]._talkMap)
+ select = talk._talkIndex = idx;
+ }
+
+ // See if the new statement is a stealth reply
+ talk._talkStealth = talk._statements[select]._statement.hasPrefix("^") ? 2 : 0;
+
+ // Is the new talk file a standard file, reply first file, or a stealth file
+ if (!talk._statements[select]._statement.hasPrefix("*") &&
+ !talk._statements[select]._statement.hasPrefix("^")) {
+ // Not a reply first file, so display the new selections
+ if (_endKeyActive)
+ screen.buttonPrint(Common::Point(119, CONTROLS_Y), COMMAND_FOREGROUND, true, fixedText_Exit);
+ else
+ screen.buttonPrint(Common::Point(119, CONTROLS_Y), COMMAND_NULL, true, fixedText_Exit);
+
+ talk.displayTalk(true);
+ events.setCursor(ARROW);
+ break;
+ } else {
+ _selector = select;
+
+ if (!talk._talkHistory[talk._converseNum][_selector])
+ journal.record(talk._converseNum, _selector);
+
+ talk._talkHistory[talk._converseNum][_selector] = true;
+ }
+ } else {
+ talk.freeTalkVars();
+ talk.pullSequence();
+ banishWindow();
+ _windowBounds.top = CONTROLS_Y1;
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+
+ events._pressed = events._released = false;
+ events._oldButtons = 0;
+ talk._talkStealth = 0;
+
+ // If a script was pushed onto the script stack, restore it
+ if (!talk._scriptStack.empty()) {
+ ScriptStackEntry stackEntry = talk._scriptStack.pop();
+ talk._scriptName = stackEntry._name;
+ talk._scriptSaveIndex = stackEntry._currentIndex;
+ talk._scriptSelect = stackEntry._select;
+ }
+ }
+ }
+}
+
+void ScalpelUserInterface::journalControl() {
+ Events &events = *_vm->_events;
+ ScalpelJournal &journal = *(ScalpelJournal *)_vm->_journal;
+ Scene &scene = *_vm->_scene;
+ Screen &screen = *_vm->_screen;
+ bool doneFlag = false;
+
+ // Draw the journal screen
+ journal.drawInterface();
+
+ // Handle journal events
+ do {
+ _key = -1;
+ events.setButtonState();
+
+ // Handle keypresses
+ if (events.kbHit()) {
+ Common::KeyState keyState = events.getKey();
+ if (keyState.keycode == Common::KEYCODE_x && (keyState.flags & Common::KBD_ALT)) {
+ _vm->quitGame();
+ return;
+ } else if (keyState.keycode == Common::KEYCODE_e || keyState.keycode == Common::KEYCODE_ESCAPE) {
+ doneFlag = true;
+ } else {
+ _key = toupper(keyState.keycode);
+ }
+ }
+
+ if (!doneFlag)
+ doneFlag = journal.handleEvents(_key);
+ } while (!_vm->shouldQuit() && !doneFlag);
+
+ // Finish up
+ _infoFlag = _keyboardInput = false;
+ _keyPress = '\0';
+ _windowOpen = false;
+ _windowBounds.top = CONTROLS_Y1;
+ _key = -1;
+ _menuMode = STD_MODE;
+
+ // Reset the palette
+ screen.setPalette(screen._cMap);
+
+ screen._backBuffer1.blitFrom(screen._backBuffer2);
+ scene.updateBackground();
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+}
+
+void ScalpelUserInterface::printObjectDesc(const Common::String &str, bool firstTime) {
+ Events &events = *_vm->_events;
+ ScalpelInventory &inv = *(ScalpelInventory *)_vm->_inventory;
+ ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+ Talk &talk = *_vm->_talk;
+
+ if (str.hasPrefix("_")) {
+ _lookScriptFlag = true;
+ events.setCursor(MAGNIFY);
+ int savedSelector = _selector;
+ talk.talkTo(str.c_str() + 1);
+ _lookScriptFlag = false;
+
+ if (talk._talkToAbort) {
+ events.setCursor(ARROW);
+ return;
+ }
+
+ // Check if looking at an inventory object
+ if (!_invLookFlag) {
+ // See if this look was called by a right button click or not
+ if (!_lookHelp) {
+ // If it wasn't a right button click, then we need depress
+ // the look button before we close the window. So save a copy of the
+ // menu area, and draw the controls onto it
+ Surface tempSurface((*_controls)[0]._frame.w, (*_controls)[0]._frame.h);
+ Common::Point pt(MENU_POINTS[0][0], MENU_POINTS[0][1]);
+ offsetButton3DO(pt, 0);
+
+ tempSurface.blitFrom(screen._backBuffer2, Common::Point(0, 0),
+ Common::Rect(pt.x, pt.y, pt.x + tempSurface.w(), pt.y + tempSurface.h()));
+ screen._backBuffer2.transBlitFrom((*_controls)[0], pt);
+
+ banishWindow(1);
+ events.setCursor(MAGNIFY);
+ _windowBounds.top = CONTROLS_Y1;
+ _key = _oldKey = COMMANDS[LOOK_MODE - 1];
+ _temp = _oldTemp = 0;
+ _menuMode = LOOK_MODE;
+ events.clearEvents();
+
+ screen._backBuffer2.blitFrom(tempSurface, pt);
+ } else {
+ events.setCursor(ARROW);
+ banishWindow(true);
+ _windowBounds.top = CONTROLS_Y1;
+ _key = _oldKey = -1;
+ _temp = _oldTemp = 0;
+ _menuMode = STD_MODE;
+ _lookHelp = 0;
+ events.clearEvents();
+ }
+ } else {
+ // Looking at an inventory object
+ _selector = _oldSelector = savedSelector;
+
+ // Reload the inventory graphics and draw the inventory
+ inv.loadInv();
+ inv.putInv(SLAM_SECONDARY_BUFFER);
+ inv.freeInv();
+ banishWindow(1);
+
+ _windowBounds.top = CONTROLS_Y1;
+ _key = _oldKey = COMMANDS[INV_MODE - 1];
+ _temp = _oldTemp = 0;
+ events.clearEvents();
+
+ _invLookFlag = 0;
+ _menuMode = INV_MODE;
+ _windowOpen = true;
+ }
+
+ return;
+ }
+
+ Surface &bb = *screen._backBuffer;
+ if (firstTime) {
+ // Only draw the border on the first call
+ _infoFlag = true;
+ clearInfo();
+
+ bb.fillRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH,
+ CONTROLS_Y1 + 10), BORDER_COLOR);
+ bb.fillRect(Common::Rect(0, CONTROLS_Y + 10, 1, SHERLOCK_SCREEN_HEIGHT - 1),
+ BORDER_COLOR);
+ bb.fillRect(Common::Rect(SHERLOCK_SCREEN_WIDTH - 2, CONTROLS_Y + 10,
+ SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR);
+ bb.fillRect(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - 1, SHERLOCK_SCREEN_WIDTH,
+ SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR);
+ }
+
+ // Clear background
+ bb.fillRect(Common::Rect(2, CONTROLS_Y + 10, SHERLOCK_SCREEN_WIDTH - 2,
+ SHERLOCK_SCREEN_HEIGHT - 2), INV_BACKGROUND);
+
+ _windowBounds.top = CONTROLS_Y;
+ events.clearEvents();
+
+ // Loop through displaying up to five lines
+ bool endOfStr = false;
+ const char *msgP = str.c_str();
+ for (int lineNum = 0; lineNum < ONSCREEN_FILES_COUNT && !endOfStr; ++lineNum) {
+ int width = 0;
+ const char *lineStartP = msgP;
+
+ // Determine how much can be displayed on the line
+ do {
+ width += screen.charWidth(*msgP++);
+ } while (width < 300 && *msgP);
+
+ if (*msgP)
+ --msgP;
+ else
+ endOfStr = true;
+
+ // If the line needs to be wrapped, scan backwards to find
+ // the end of the previous word as a splitting point
+ if (width >= 300) {
+ while (*msgP != ' ')
+ --msgP;
+ endOfStr = false;
+ }
+
+ // Print out the line
+ Common::String line(lineStartP, msgP);
+ screen.gPrint(Common::Point(16, CONTROLS_Y + 12 + lineNum * 9),
+ INV_FOREGROUND, "%s", line.c_str());
+
+ if (!endOfStr)
+ // Start next line at start of the nxet word after space
+ ++msgP;
+ }
+
+ // Handle display depending on whether all the message was shown
+ if (!endOfStr) {
+ screen.makeButton(Common::Rect(46, CONTROLS_Y, 272, CONTROLS_Y + 10),
+ (SHERLOCK_SCREEN_WIDTH - screen.stringWidth(PRESS_KEY_FOR_MORE)) / 2,
+ PRESS_KEY_FOR_MORE);
+ screen.gPrint(Common::Point((SHERLOCK_SCREEN_WIDTH -
+ screen.stringWidth(PRESS_KEY_FOR_MORE)) / 2, CONTROLS_Y),
+ COMMAND_FOREGROUND, "P");
+ _descStr = msgP;
+ } else {
+ screen.makeButton(Common::Rect(46, CONTROLS_Y, 272, CONTROLS_Y + 10),
+ (SHERLOCK_SCREEN_WIDTH - screen.stringWidth(PRESS_KEY_TO_CONTINUE)) / 2,
+ PRESS_KEY_TO_CONTINUE);
+ screen.gPrint(Common::Point((SHERLOCK_SCREEN_WIDTH -
+ screen.stringWidth(PRESS_KEY_TO_CONTINUE)) / 2, CONTROLS_Y),
+ COMMAND_FOREGROUND, "P");
+ _descStr = "";
+ }
+
+ if (firstTime) {
+ if (!_slideWindows) {
+ screen.slamRect(Common::Rect(0, CONTROLS_Y,
+ SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
+ } else {
+ // Display the window
+ summonWindow();
+ }
+
+ _selector = _oldSelector = -1;
+ _windowOpen = true;
+ } else {
+ screen.slamRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH,
+ SHERLOCK_SCREEN_HEIGHT));
+ }
+}
+
+void ScalpelUserInterface::printObjectDesc() {
+ printObjectDesc(_cAnimStr, true);
+}
+
+void ScalpelUserInterface::summonWindow(const Surface &bgSurface, bool slideUp) {
+ Events &events = *_vm->_events;
+ Screen &screen = *_vm->_screen;
+
+ if (_windowOpen)
+ // A window is already open, so can't open another one
+ return;
+
+ if (slideUp) {
+ // Gradually slide up the display of the window
+ for (int idx = 1; idx <= bgSurface.h(); idx += 2) {
+ screen._backBuffer->blitFrom(bgSurface, Common::Point(0, SHERLOCK_SCREEN_HEIGHT - idx),
+ Common::Rect(0, 0, bgSurface.w(), idx));
+ screen.slamRect(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - idx,
+ SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
+
+ events.delay(10);
+ }
+ } else {
+ // Gradually slide down the display of the window
+ for (int idx = 1; idx <= bgSurface.h(); idx += 2) {
+ screen._backBuffer->blitFrom(bgSurface,
+ Common::Point(0, SHERLOCK_SCREEN_HEIGHT - bgSurface.h()),
+ Common::Rect(0, bgSurface.h() - idx, bgSurface.w(), bgSurface.h()));
+ screen.slamRect(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - bgSurface.h(),
+ SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT - bgSurface.h() + idx));
+
+ events.delay(10);
+ }
+ }
+
+ // Final display of the entire window
+ screen._backBuffer->blitFrom(bgSurface, Common::Point(0, SHERLOCK_SCREEN_HEIGHT - bgSurface.h()),
+ Common::Rect(0, 0, bgSurface.w(), bgSurface.h()));
+ screen.slamArea(0, SHERLOCK_SCREEN_HEIGHT - bgSurface.h(), bgSurface.w(), bgSurface.h());
+
+ _windowOpen = true;
+}
+
+void ScalpelUserInterface::summonWindow(bool slideUp, int height) {
+ Screen &screen = *_vm->_screen;
+
+ // Extract the window that's been drawn on the back buffer
+ Surface tempSurface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT - height);
+ Common::Rect r(0, height, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+ tempSurface.blitFrom(screen._backBuffer1, Common::Point(0, 0), r);
+
+ // Remove drawn window with original user interface
+ screen._backBuffer1.blitFrom(screen._backBuffer2,
+ Common::Point(0, height), r);
+
+ // Display the window gradually on-screen
+ summonWindow(tempSurface, slideUp);
+}
+
+void ScalpelUserInterface::banishWindow(bool slideUp) {
+ Events &events = *_vm->_events;
+ Screen &screen = *_vm->_screen;
+
+ if (_windowOpen) {
+ if (slideUp || !_slideWindows) {
+ // Slide window down
+ // Only slide the window if the window style allows it
+ if (_slideWindows) {
+ for (int idx = 2; idx < (SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y); idx += 2) {
+ // Shift the window down by 2 lines
+ byte *pSrc = (byte *)screen._backBuffer1.getBasePtr(0, CONTROLS_Y + idx - 2);
+ byte *pSrcEnd = (byte *)screen._backBuffer1.getBasePtr(0, SHERLOCK_SCREEN_HEIGHT - 2);
+ byte *pDest = (byte *)screen._backBuffer1.getBasePtr(0, SHERLOCK_SCREEN_HEIGHT);
+ Common::copy_backward(pSrc, pSrcEnd, pDest);
+
+ // Restore lines from the ui in the secondary back buffer
+ screen._backBuffer1.blitFrom(screen._backBuffer2,
+ Common::Point(0, CONTROLS_Y),
+ Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y + idx));
+
+ screen.slamArea(0, CONTROLS_Y + idx - 2, SHERLOCK_SCREEN_WIDTH,
+ SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y - idx + 2);
+ events.delay(10);
+ }
+
+ // Restore final two old lines
+ screen._backBuffer1.blitFrom(screen._backBuffer2,
+ Common::Point(0, SHERLOCK_SCREEN_HEIGHT - 2),
+ Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - 2,
+ SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
+ screen.slamArea(0, SHERLOCK_SCREEN_HEIGHT - 2, SHERLOCK_SCREEN_WIDTH, 2);
+ } else {
+ // Restore old area to completely erase window
+ screen._backBuffer1.blitFrom(screen._backBuffer2,
+ Common::Point(0, CONTROLS_Y),
+ Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
+ screen.slamRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH,
+ SHERLOCK_SCREEN_HEIGHT));
+ }
+ } else {
+ // Slide the original user interface up to cover the dialog
+ for (int idx = 1; idx < (SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y1); idx += 2) {
+ byte *pSrc = (byte *)screen._backBuffer2.getBasePtr(0, CONTROLS_Y1);
+ byte *pSrcEnd = (byte *)screen._backBuffer2.getBasePtr(0, CONTROLS_Y1 + idx);
+ byte *pDest = (byte *)screen._backBuffer1.getBasePtr(0, SHERLOCK_SCREEN_HEIGHT - idx);
+ Common::copy(pSrc, pSrcEnd, pDest);
+
+ screen.slamArea(0, SHERLOCK_SCREEN_HEIGHT - idx, SHERLOCK_SCREEN_WIDTH,
+ SHERLOCK_SCREEN_HEIGHT);
+ events.delay(10);
+ }
+
+ // Show entire final area
+ screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(0, CONTROLS_Y1),
+ Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
+ screen.slamRect(Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
+ }
+
+ _infoFlag = false;
+ _windowOpen = false;
+ }
+
+ _menuMode = STD_MODE;
+}
+
+void ScalpelUserInterface::checkUseAction(const UseType *use, const Common::String &invName,
+ FixedTextActionId fixedTextActionId, int objNum, bool giveMode) {
+ Events &events = *_vm->_events;
+ FixedText &fixedText = *_vm->_fixedText;
+ Inventory &inv = *_vm->_inventory;
+ Scene &scene = *_vm->_scene;
+ Screen &screen = *_vm->_screen;
+ Talk &talk = *_vm->_talk;
+ bool printed = fixedTextActionId == kFixedTextAction_Invalid;
+
+ if (objNum >= 1000) {
+ // Holmes was specified, so do nothing
+ _infoFlag = true;
+ clearInfo();
+ _infoFlag = true;
+
+ // Display error message
+ _menuCounter = 30;
+ screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "You can't do that to yourself.");
+ return;
+ }
+
+ // Scan for target item
+ int targetNum = -1;
+ if (giveMode) {
+ for (int idx = 0; idx < USE_COUNT && targetNum == -1; ++idx) {
+ if ((use[idx]._target.equalsIgnoreCase("*GIVE*") || use[idx]._target.equalsIgnoreCase("*GIVEP*"))
+ && use[idx]._names[0].equalsIgnoreCase(invName)) {
+ // Found a match
+ targetNum = idx;
+ if (use[idx]._target.equalsIgnoreCase("*GIVE*"))
+ inv.deleteItemFromInventory(invName);
+ }
+ }
+ } else {
+ for (int idx = 0; idx < USE_COUNT && targetNum == -1; ++idx) {
+ if (use[idx]._target.equalsIgnoreCase(invName))
+ targetNum = idx;
+ }
+ }
+
+ if (targetNum != -1) {
+ // Found a target, so do the action
+ const UseType &action = use[targetNum];
+
+ events.setCursor(WAIT);
+
+ if (action._useFlag)
+ _vm->setFlags(action._useFlag);
+
+ if (action._cAnimNum != 99) {
+ if (action._cAnimNum == 0)
+ scene.startCAnim(9, action._cAnimSpeed);
+ else
+ scene.startCAnim(action._cAnimNum - 1, action._cAnimSpeed);
+ }
+
+ if (!talk._talkToAbort) {
+ Object &obj = scene._bgShapes[objNum];
+ for (int idx = 0; idx < NAMES_COUNT && !talk._talkToAbort; ++idx) {
+ if (obj.checkNameForCodes(action._names[idx], fixedTextActionId)) {
+ if (!talk._talkToAbort)
+ printed = true;
+ }
+ }
+
+ // Print "Done..." as an ending, unless flagged for leaving scene or otherwise flagged
+ if (scene._goToScene != 1 && !printed && !talk._talkToAbort) {
+ _infoFlag = true;
+ clearInfo();
+ screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "Done...");
+ _menuCounter = 25;
+ }
+ }
+ } else {
+ // Couldn't find target, so print error
+ _infoFlag = true;
+ clearInfo();
+
+ if (giveMode) {
+ screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "No, thank you.");
+ } else if (fixedTextActionId == kFixedTextAction_Invalid) {
+ screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "You can't do that.");
+ } else {
+ Common::String errorMessage = fixedText.getActionMessage(fixedTextActionId, 0);
+ screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", errorMessage.c_str());
+ }
+
+ _infoFlag = true;
+ _menuCounter = 30;
+ }
+
+ events.setCursor(ARROW);
+}
+
+void ScalpelUserInterface::offsetButton3DO(Common::Point &pt, int num) {
+ if (IS_3DO) {
+ if (num >= 0 && num <= 2)
+ pt.x += 15;
+ else if (num >= 6 && num <= 8)
+ pt.x -= 4;
+ else if (num >= 9 && num <= 11)
+ pt.x -= 8;
+ }
+}
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/scalpel/scalpel_user_interface.h b/engines/sherlock/scalpel/scalpel_user_interface.h
new file mode 100644
index 0000000000..7829ffca9f
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_user_interface.h
@@ -0,0 +1,223 @@
+/* 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 SHERLOCK_SCALPEL_UI_H
+#define SHERLOCK_SCALPEL_UI_H
+
+#include "common/scummsys.h"
+#include "sherlock/user_interface.h"
+
+namespace Sherlock {
+
+class Inventory;
+class Talk;
+
+namespace Scalpel {
+
+extern const char COMMANDS[13];
+extern const int MENU_POINTS[12][4];
+
+extern const int INVENTORY_POINTS[8][3];
+extern const char INVENTORY_COMMANDS[9];
+extern const char *const PRESS_KEY_FOR_MORE;
+extern const char *const PRESS_KEY_TO_CONTINUE;
+
+class Settings;
+
+class ScalpelUserInterface: public UserInterface {
+ friend class Settings;
+ friend class Talk;
+private:
+ char _keyPress;
+ int _lookHelp;
+ int _help, _oldHelp;
+ int _key, _oldKey;
+ int _temp, _oldTemp;
+ int _oldLook;
+ bool _keyboardInput;
+ bool _pause;
+ int _cNum;
+ Common::String _cAnimStr;
+ Common::String _descStr;
+ int _find;
+private:
+ /**
+ * Draws the image for a user interface button in the down/pressed state.
+ */
+ void depressButton(int num);
+
+ /**
+ * If he mouse button is pressed, then calls depressButton to draw the button
+ * as pressed; if not, it will show it as released with a call to "restoreButton".
+ */
+ void pushButton(int num);
+
+ /**
+ * By the time this method has been called, the graphics for the button change
+ * have already been drawn. This simply takes care of switching the mode around
+ * accordingly
+ */
+ void toggleButton(int num);
+
+ /**
+ * Print the name of an object in the scene
+ */
+ void lookScreen(const Common::Point &pt);
+
+ /**
+ * Gets the item in the inventory the mouse is on and display's it's description
+ */
+ void lookInv();
+
+ /**
+ * Handles input when the file list window is being displayed
+ */
+ void doEnvControl();
+
+ /**
+ * Handle input whilst the inventory is active
+ */
+ void doInvControl();
+
+ /**
+ * Handles waiting whilst an object's description window is open.
+ */
+ void doLookControl();
+
+ /**
+ * Handles input until one of the user interface buttons/commands is selected
+ */
+ void doMainControl();
+
+ /**
+ * Handles the input for the MOVE, OPEN, and CLOSE commands
+ */
+ void doMiscControl(int allowed);
+
+ /**
+ * Handles input for picking up items
+ */
+ void doPickControl();
+
+ /**
+ * Handles input when in talk mode. It highlights the buttons and available statements,
+ * and handles allowing the user to click on them
+ */
+ void doTalkControl();
+
+ /**
+ * Handles events when the Journal is active.
+ * @remarks Whilst this would in theory be better in the Journal class, since it displays in
+ * the user interface, it uses so many internal UI fields, that it sort of made some sense
+ * to put it in the UserInterface class.
+ */
+ void journalControl();
+
+ /**
+ * Checks to see whether a USE action is valid on the given object
+ */
+ void checkUseAction(const UseType *use, const Common::String &invName, FixedTextActionId fixedTextActionId,
+ int objNum, bool giveMode);
+
+ /**
+ * Print the previously selected object's decription
+ */
+ void printObjectDesc(const Common::String &str, bool firstTime);
+public:
+ ImageFile *_controlPanel;
+ ImageFile *_controls;
+ int _oldUse;
+public:
+ ScalpelUserInterface(SherlockEngine *vm);
+ virtual ~ScalpelUserInterface();
+
+ /**
+ * Handles counting down whilst checking for input, then clears the info line.
+ */
+ void whileMenuCounter();
+
+ /**
+ * Draws the image for the given user interface button in the up
+ * (not selected) position
+ */
+ void restoreButton(int num);
+
+ /**
+ * Creates a text window and uses it to display the in-depth description
+ * of the highlighted object
+ */
+ void examine();
+
+ void offsetButton3DO(Common::Point &pt, int num);
+public:
+ /**
+ * Resets the user interface
+ */
+ virtual void reset();
+
+ /**
+ * Main input handler for the user interface
+ */
+ virtual void handleInput();
+
+ /**
+ * Draw the user interface onto the screen's back buffers
+ */
+ virtual void drawInterface(int bufferNum = 3);
+
+ /**
+ * Displays a passed window by gradually scrolling it vertically on-screen
+ */
+ virtual void summonWindow(const Surface &bgSurface, bool slideUp = true);
+
+ /**
+ * Slide the window stored in the back buffer onto the screen
+ */
+ virtual void summonWindow(bool slideUp = true, int height = CONTROLS_Y);
+
+ /**
+ * Close a currently open window
+ * @param flag 0 = slide old window down, 1 = slide prior UI back up
+ */
+ virtual void banishWindow(bool slideUp = true);
+
+ /**
+ * Clears the info line of the screen
+ */
+ virtual void clearInfo();
+
+ /**
+ * Clear any active text window
+ */
+ virtual void clearWindow();
+
+ /**
+ * Print the previously selected object's decription
+ */
+ virtual void printObjectDesc();
+};
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/scalpel/settings.cpp b/engines/sherlock/scalpel/settings.cpp
new file mode 100644
index 0000000000..f6769a4b99
--- /dev/null
+++ b/engines/sherlock/scalpel/settings.cpp
@@ -0,0 +1,343 @@
+/* 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 "sherlock/sherlock.h"
+#include "sherlock/scalpel/settings.h"
+#include "sherlock/scalpel/scalpel_screen.h"
+#include "sherlock/scalpel/scalpel_user_interface.h"
+#include "sherlock/scalpel/scalpel.h"
+
+namespace Sherlock {
+
+namespace Scalpel {
+
+static const int SETUP_POINTS[12][4] = {
+ { 4, 154, 101, 53 }, // Exit
+ { 4, 165, 101, 53 }, // Music Toggle
+ { 219, 165, 316, 268 }, // Voice Toggle
+ { 103, 165, 217, 160 }, // Sound Effects Toggle
+ { 219, 154, 316, 268 }, // Help Button Left/Right
+ { 103, 154, 217, 160 }, // New Font Style
+ { 4, 187, 101, 53 }, // Joystick Toggle
+ { 103, 187, 217, 160 }, // Calibrate Joystick
+ { 219, 176, 316, 268 }, // Fade Style
+ { 103, 176, 217, 160 }, // Window Open Style
+ { 4, 176, 101, 53 }, // Portraits Toggle
+ { 219, 187, 316, 268 } // _key Pad Accel. Toggle
+};
+
+static const char *const SETUP_STRS0[2] = { "off", "on" };
+static const char *const SETUP_STRS1[2] = { "Directly", "by Pixel" };
+static const char *const SETUP_STRS2[2] = { "Left", "Right" };
+static const char *const SETUP_STRS3[2] = { "Appear", "Slide" };
+static const char *const SETUP_STRS5[2] = { "Left", "Right" };
+static const char *const SETUP_NAMES[12] = {
+ "Exit", "M", "V", "S", "B", "New Font Style", "J", "Calibrate Joystick", "F", "W", "P", "K"
+};
+
+/*----------------------------------------------------------------*/
+
+void Settings::drawInteface(bool flag) {
+ People &people = *_vm->_people;
+ ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+ Sound &sound = *_vm->_sound;
+ Music &music = *_vm->_music;
+ UserInterface &ui = *_vm->_ui;
+ Common::String tempStr;
+
+ if (!flag) {
+ screen._backBuffer1.fillRect(Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y1 + 1), BORDER_COLOR);
+ screen._backBuffer1.fillRect(Common::Rect(0, CONTROLS_Y1 + 1, 2, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR);
+ screen._backBuffer1.fillRect(Common::Rect(SHERLOCK_SCREEN_WIDTH - 2, CONTROLS_Y1 + 1, SHERLOCK_SCREEN_WIDTH,
+ SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR);
+ screen._backBuffer1.hLine(0, SHERLOCK_SCREEN_HEIGHT - 1, SHERLOCK_SCREEN_WIDTH - 1, BORDER_COLOR);
+ screen._backBuffer1.fillRect(Common::Rect(2, CONTROLS_Y1 + 1, SHERLOCK_SCREEN_WIDTH - 2,
+ SHERLOCK_SCREEN_HEIGHT - 2), INV_BACKGROUND);
+ }
+
+ screen.makeButton(Common::Rect(SETUP_POINTS[0][0], SETUP_POINTS[0][1], SETUP_POINTS[0][2], SETUP_POINTS[0][1] + 10),
+ SETUP_POINTS[0][3] - screen.stringWidth("Exit") / 2, "Exit");
+
+ tempStr = Common::String::format("Music %s", SETUP_STRS0[music._musicOn]);
+ screen.makeButton(Common::Rect(SETUP_POINTS[1][0], SETUP_POINTS[1][1], SETUP_POINTS[1][2], SETUP_POINTS[1][1] + 10),
+ SETUP_POINTS[1][3] - screen.stringWidth(tempStr) / 2, tempStr);
+
+ tempStr = Common::String::format("Voices %s", SETUP_STRS0[sound._voices]);
+ screen.makeButton(Common::Rect(SETUP_POINTS[2][0], SETUP_POINTS[2][1], SETUP_POINTS[2][2], SETUP_POINTS[2][1] + 10),
+ SETUP_POINTS[2][3] - screen.stringWidth(tempStr) / 2, tempStr);
+
+ tempStr = Common::String::format("Sound Effects %s", SETUP_STRS0[sound._digitized]);
+ screen.makeButton(Common::Rect(SETUP_POINTS[3][0], SETUP_POINTS[3][1], SETUP_POINTS[3][2], SETUP_POINTS[3][1] + 10),
+ SETUP_POINTS[3][3] - screen.stringWidth(tempStr) / 2, tempStr);
+
+ tempStr = Common::String::format("Auto Help %s", SETUP_STRS5[ui._helpStyle]);
+ screen.makeButton(Common::Rect(SETUP_POINTS[4][0], SETUP_POINTS[4][1], SETUP_POINTS[4][2], SETUP_POINTS[4][1] + 10),
+ SETUP_POINTS[4][3] - screen.stringWidth(tempStr) / 2, tempStr);
+ screen.makeButton(Common::Rect(SETUP_POINTS[5][0], SETUP_POINTS[5][1], SETUP_POINTS[5][2], SETUP_POINTS[5][1] + 10),
+ SETUP_POINTS[5][3] - screen.stringWidth("New Font Style") / 2, "New Font Style");
+
+ // WORKAROUND: We don't support the joystick in ScummVM, so draw the next two buttons as disabled
+ tempStr = "Joystick Off";
+ screen.makeButton(Common::Rect(SETUP_POINTS[6][0], SETUP_POINTS[6][1], SETUP_POINTS[6][2], SETUP_POINTS[6][1] + 10),
+ SETUP_POINTS[6][3] - screen.stringWidth(tempStr) / 2, tempStr);
+ screen.buttonPrint(Common::Point(SETUP_POINTS[6][3], SETUP_POINTS[6][1]), COMMAND_NULL, false, tempStr);
+
+ tempStr = "Calibrate Joystick";
+ screen.makeButton(Common::Rect(SETUP_POINTS[7][0], SETUP_POINTS[7][1], SETUP_POINTS[7][2], SETUP_POINTS[7][1] + 10),
+ SETUP_POINTS[7][3] - screen.stringWidth(tempStr) / 2, tempStr);
+ screen.buttonPrint(Common::Point(SETUP_POINTS[7][3], SETUP_POINTS[7][1]), COMMAND_NULL, false, tempStr);
+
+ tempStr = Common::String::format("Fade %s", screen._fadeStyle ? "by Pixel" : "Directly");
+ screen.makeButton(Common::Rect(SETUP_POINTS[8][0], SETUP_POINTS[8][1], SETUP_POINTS[8][2], SETUP_POINTS[8][1] + 10),
+ SETUP_POINTS[8][3] - screen.stringWidth(tempStr) / 2, tempStr);
+
+ tempStr = Common::String::format("Windows %s", ui._slideWindows ? "Slide" : "Appear");
+ screen.makeButton(Common::Rect(SETUP_POINTS[9][0], SETUP_POINTS[9][1], SETUP_POINTS[9][2], SETUP_POINTS[9][1] + 10),
+ SETUP_POINTS[9][3] - screen.stringWidth(tempStr) / 2, tempStr);
+
+ tempStr = Common::String::format("Portraits %s", SETUP_STRS0[people._portraitsOn]);
+ screen.makeButton(Common::Rect(SETUP_POINTS[10][0], SETUP_POINTS[10][1], SETUP_POINTS[10][2], SETUP_POINTS[10][1] + 10),
+ SETUP_POINTS[10][3] - screen.stringWidth(tempStr) / 2, tempStr);
+
+ tempStr = "Key Pad Slow";
+ screen.makeButton(Common::Rect(SETUP_POINTS[11][0], SETUP_POINTS[11][1], SETUP_POINTS[11][2], SETUP_POINTS[11][1] + 10),
+ SETUP_POINTS[11][3] - screen.stringWidth(tempStr) / 2, tempStr);
+ screen.buttonPrint(Common::Point(SETUP_POINTS[11][3], SETUP_POINTS[11][1]), COMMAND_NULL, false, tempStr);
+
+ // Show the window immediately, or slide it on-screen
+ if (!flag) {
+ if (!ui._slideWindows) {
+ screen.slamRect(Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
+ } else {
+ ui.summonWindow(true, CONTROLS_Y1);
+ }
+
+ ui._windowOpen = true;
+ } else {
+ screen.slamRect(Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
+ }
+}
+
+int Settings::drawButtons(const Common::Point &pt, int _key) {
+ Events &events = *_vm->_events;
+ People &people = *_vm->_people;
+ ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+ Music &music = *_vm->_music;
+ Sound &sound = *_vm->_sound;
+ UserInterface &ui = *_vm->_ui;
+ int found = -1;
+ byte color;
+ Common::String tempStr;
+
+ for (int idx = 0; idx < 12; ++idx) {
+ if ((pt.x > SETUP_POINTS[idx][0] && pt.x < SETUP_POINTS[idx][2] && pt.y > SETUP_POINTS[idx][1]
+ && pt.y < (SETUP_POINTS[idx][1] + 10) && (events._pressed || events._released))
+ || (_key == SETUP_NAMES[idx][0])) {
+ found = idx;
+ color = COMMAND_HIGHLIGHTED;
+ } else {
+ color = COMMAND_FOREGROUND;
+ }
+
+ // Print the button text
+ switch (idx) {
+ case 1:
+ tempStr = Common::String::format("Music %s", SETUP_STRS0[music._musicOn]);
+ screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr);
+ break;
+ case 2:
+ tempStr = Common::String::format("Voices %s", SETUP_STRS0[sound._voices]);
+ screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr);
+ break;
+ case 3:
+ tempStr = Common::String::format("Sound Effects %s", SETUP_STRS0[sound._digitized]);
+ screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr);
+ break;
+ case 4:
+ tempStr = Common::String::format("Auto Help %s", SETUP_STRS2[ui._helpStyle]);
+ screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr);
+ break;
+ case 6:
+ tempStr = "Joystick Off";
+ screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), COMMAND_NULL, true, tempStr);
+ break;
+ case 7:
+ tempStr = "Calibrate Joystick";
+ screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), COMMAND_NULL, true, tempStr);
+ break;
+ case 8:
+ tempStr = Common::String::format("Fade %s", SETUP_STRS1[screen._fadeStyle]);
+ screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr);
+ break;
+ case 9:
+ tempStr = Common::String::format("Windows %s", SETUP_STRS3[ui._slideWindows]);
+ screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr);
+ break;
+ case 10:
+ tempStr = Common::String::format("Portraits %s", SETUP_STRS0[people._portraitsOn]);
+ screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr);
+ break;
+ case 11:
+ tempStr = "Key Pad Slow";
+ screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), COMMAND_NULL, true, tempStr);
+ break;
+ default:
+ screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, SETUP_NAMES[idx]);
+ break;
+ }
+ }
+
+ return found;
+}
+
+void Settings::show(SherlockEngine *vm) {
+ Events &events = *vm->_events;
+ People &people = *vm->_people;
+ Scene &scene = *vm->_scene;
+ Screen &screen = *vm->_screen;
+ Sound &sound = *vm->_sound;
+ Music &music = *vm->_music;
+ Talk &talk = *vm->_talk;
+ ScalpelUserInterface &ui = *(ScalpelUserInterface *)vm->_ui;
+ bool updateConfig = false;
+
+ assert(vm->getGameID() == GType_SerratedScalpel);
+ Settings settings(vm);
+ settings.drawInteface(false);
+
+ do {
+ if (ui._menuCounter)
+ ui.whileMenuCounter();
+
+ int found = -1;
+ ui._key = -1;
+
+ scene.doBgAnim();
+ if (talk._talkToAbort)
+ return;
+
+ events.setButtonState();
+ Common::Point pt = events.mousePos();
+
+ if (events._pressed || events._released || events.kbHit()) {
+ ui.clearInfo();
+ ui._key = -1;
+
+ if (events.kbHit()) {
+ Common::KeyState keyState = events.getKey();
+ ui._key = toupper(keyState.keycode);
+
+ if (ui._key == Common::KEYCODE_RETURN || ui._key == Common::KEYCODE_SPACE) {
+ events._pressed = false;
+ events._oldButtons = 0;
+ ui._keyPress = '\0';
+ events._released = true;
+ }
+ }
+
+ // Handle highlighting button under mouse
+ found = settings.drawButtons(pt, ui._key);
+ }
+
+ if ((found == 0 && events._released) || (ui._key == 'E' || ui._key == Common::KEYCODE_ESCAPE))
+ // Exit
+ break;
+
+ if ((found == 1 && events._released) || ui._key == 'M') {
+ // Toggle music
+ music._musicOn = !music._musicOn;
+ if (!music._musicOn)
+ music.stopMusic();
+ else
+ music.startSong();
+
+ updateConfig = true;
+ settings.drawInteface(true);
+ }
+
+ if ((found == 2 && events._released) || ui._key == 'V') {
+ sound._voices = !sound._voices;
+ updateConfig = true;
+ settings.drawInteface(true);
+ }
+
+ if ((found == 3 && events._released) || ui._key == 'S') {
+ // Toggle sound effects
+ sound._digitized = !sound._digitized;
+ updateConfig = true;
+ settings.drawInteface(true);
+ }
+
+ if ((found == 4 && events._released) || ui._key == 'A') {
+ // Help button style
+ ui._helpStyle = !ui._helpStyle;
+ updateConfig = true;
+ settings.drawInteface(true);
+ }
+
+ if ((found == 5 && events._released) || ui._key == 'N') {
+ // New font style
+ int fontNum = screen.fontNumber() + 1;
+ if (fontNum == 3)
+ fontNum = 0;
+
+ screen.setFont(fontNum);
+ updateConfig = true;
+ settings.drawInteface(true);
+ }
+
+ if ((found == 8 && events._released) || ui._key == 'F') {
+ // Toggle fade style
+ screen._fadeStyle = !screen._fadeStyle;
+ updateConfig = true;
+ settings.drawInteface(true);
+ }
+
+ if ((found == 9 && events._released) || ui._key == 'W') {
+ // Window style
+ ui._slideWindows = !ui._slideWindows;
+ updateConfig = true;
+ settings.drawInteface(true);
+ }
+
+ if ((found == 10 && events._released) || ui._key == 'P') {
+ // Toggle portraits being shown
+ people._portraitsOn = !people._portraitsOn;
+ updateConfig = true;
+ settings.drawInteface(true);
+ }
+ } while (!vm->shouldQuit());
+
+ ui.banishWindow();
+
+ if (updateConfig)
+ vm->saveConfig();
+
+ ui._keyPress = '\0';
+ ui._keyboardInput = false;
+ ui._windowBounds.top = CONTROLS_Y1;
+ ui._key = -1;
+}
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/scalpel/settings.h b/engines/sherlock/scalpel/settings.h
new file mode 100644
index 0000000000..ff2e647a62
--- /dev/null
+++ b/engines/sherlock/scalpel/settings.h
@@ -0,0 +1,63 @@
+/* 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 SHERLOCK_SETTINGS_H
+#define SHERLOCK_SETTINGS_H
+
+#include "common/scummsys.h"
+
+namespace Sherlock {
+
+class SherlockEngine;
+
+namespace Scalpel {
+
+class Settings {
+private:
+ SherlockEngine *_vm;
+
+ Settings(SherlockEngine *vm) : _vm(vm) {}
+
+ /**
+ * Draws the interface for the settings window
+ */
+ void drawInteface(bool flag);
+
+ /**
+ * Draws the buttons for the settings dialog
+ */
+ int drawButtons(const Common::Point &pt, int key);
+public:
+ /**
+ * Handles input when the settings window is being shown
+ * @remarks Whilst this would in theory be better in the Journal class, since it displays in
+ * the user interface, it uses so many internal UI fields, that it sort of made some sense
+ * to put it in the UserInterface class.
+ */
+ static void show(SherlockEngine *vm);
+};
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/scalpel/tsage/logo.cpp b/engines/sherlock/scalpel/tsage/logo.cpp
new file mode 100644
index 0000000000..4eab01947a
--- /dev/null
+++ b/engines/sherlock/scalpel/tsage/logo.cpp
@@ -0,0 +1,684 @@
+/* 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/scummsys.h"
+#include "sherlock/scalpel/tsage/logo.h"
+#include "sherlock/scalpel/scalpel.h"
+
+namespace Sherlock {
+namespace Scalpel {
+namespace TsAGE {
+
+TLib *Visage::_tLib;
+
+Visage::Visage() {
+ _resNum = -1;
+ _rlbNum = -1;
+ _stream = nullptr;
+}
+
+void Visage::setVisage(int resNum, int rlbNum) {
+ if ((_resNum != resNum) || (_rlbNum != rlbNum)) {
+ _resNum = resNum;
+ _rlbNum = rlbNum;
+ delete _stream;
+
+ // Games after Ringworld have an extra indirection via the visage index file
+ Common::SeekableReadStream *stream = _tLib->getResource(RES_VISAGE, resNum, 9999);
+ if (rlbNum == 0)
+ rlbNum = 1;
+
+ // Check how many slots there are
+ uint16 count = stream->readUint16LE();
+ if (rlbNum > count)
+ rlbNum = count;
+
+ // Get the flags/rlbNum to use
+ stream->seek((rlbNum - 1) * 4 + 2);
+ uint32 v = stream->readUint32LE();
+ int flags = v >> 30;
+
+ if (flags & 3) {
+ rlbNum = (int)(v & 0xff);
+ }
+ assert((flags & 3) == 0);
+ delete stream;
+
+ _stream = _tLib->getResource(RES_VISAGE, resNum, rlbNum);
+ }
+}
+
+void Visage::clear() {
+ delete _stream;
+ _stream = nullptr;
+}
+
+Visage::~Visage() {
+ delete _stream;
+}
+
+void Visage::getFrame(ObjectSurface &s, int frameNum) {
+ _stream->seek(0);
+ int numFrames = _stream->readUint16LE();
+ if (frameNum > numFrames)
+ frameNum = numFrames;
+ if (frameNum > 0)
+ --frameNum;
+
+ _stream->seek(frameNum * 4 + 2);
+ int offset = _stream->readUint32LE();
+ _stream->seek(offset);
+
+ surfaceFromRes(s);
+}
+
+int Visage::getFrameCount() const {
+ _stream->seek(0);
+ return _stream->readUint16LE();
+}
+
+bool Visage::isLoaded() const {
+ return _stream != nullptr;
+}
+
+void Visage::surfaceFromRes(ObjectSurface &s) {
+ int frameWidth = _stream->readUint16LE();
+ int frameHeight = _stream->readUint16LE();
+ Common::Rect r(0, 0, frameWidth, frameHeight);
+ s.create(r.width(), r.height());
+
+ s._centroid.x = _stream->readSint16LE();
+ s._centroid.y = _stream->readSint16LE();
+
+ _stream->skip(1);
+ byte flags = _stream->readByte();
+ bool rleEncoded = (flags & 2) != 0;
+
+ byte *destP = (byte *)s.getPixels();
+
+ if (!rleEncoded) {
+ _stream->read(destP, r.width() * r.height());
+ } else {
+ Common::fill(destP, destP + (r.width() * r.height()), 0xff);
+
+ for (int yp = 0; yp < r.height(); ++yp) {
+ int width = r.width();
+ destP = (byte *)s.getBasePtr(0, yp);
+
+ while (width > 0) {
+ uint8 controlVal = _stream->readByte();
+ if ((controlVal & 0x80) == 0) {
+ // Copy specified number of bytes
+ _stream->read(destP, controlVal);
+ width -= controlVal;
+ destP += controlVal;
+ } else if ((controlVal & 0x40) == 0) {
+ // Skip a specified number of output pixels
+ destP += controlVal & 0x3f;
+ width -= controlVal & 0x3f;
+ } else {
+ // Copy a specified pixel a given number of times
+ controlVal &= 0x3f;
+ int pixel = _stream->readByte();
+
+ Common::fill(destP, destP + controlVal, pixel);
+ destP += controlVal;
+ width -= controlVal;
+ }
+ }
+ assert(width == 0);
+ }
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+ScalpelEngine *Object::_vm;
+
+Object::Object() {
+ _vm = nullptr;
+ _isAnimating = _finished = false;
+ _frame = 0;
+ _numFrames = 0;
+ _frameChange = 0;
+ _angle = _changeCtr = 0;
+ _walkStartFrame = 0;
+ _majorDiff = _minorDiff = 0;
+}
+
+void Object::setVisage(int visage, int strip) {
+ _visage.setVisage(visage, strip);
+}
+
+void Object::setAnimMode(bool isAnimating) {
+ _isAnimating = isAnimating;
+ _finished = false;
+
+ _updateStartFrame = _vm->_events->getFrameCounter();
+ if (_numFrames)
+ _updateStartFrame += 60 / _numFrames;
+ _frameChange = 1;
+}
+
+void Object::setDestination(const Common::Point &pt) {
+ _destination = pt;
+
+ int moveRate = 10;
+ _walkStartFrame = _vm->_events->getFrameCounter();
+ _walkStartFrame += 60 / moveRate;
+
+ calculateMoveAngle();
+
+ // Get the difference
+ int diffX = _destination.x - _position.x;
+ int diffY = _destination.y - _position.y;
+ int xSign = (diffX < 0) ? -1 : (diffX > 0 ? 1 : 0);
+ int ySign = (diffY < 0) ? -1 : (diffY > 0 ? 1 : 0);
+ diffX = ABS(diffX);
+ diffY = ABS(diffY);
+
+ if (diffX < diffY) {
+ _minorDiff = diffX / 2;
+ _majorDiff = diffY;
+ } else {
+ _minorDiff = diffY / 2;
+ _majorDiff = diffX;
+ }
+
+ // Set the destination position
+ _moveDelta = Common::Point(diffX, diffY);
+ _moveSign = Common::Point(xSign, ySign);
+ _changeCtr = 0;
+
+ assert(diffX || diffY);
+}
+
+void Object::erase() {
+ Screen &screen = *_vm->_screen;
+
+ if (_visage.isLoaded() && !_oldBounds.isEmpty())
+ screen.blitFrom(screen._backBuffer1, Common::Point(_oldBounds.left, _oldBounds.top), _oldBounds);
+}
+
+void Object::update() {
+ Screen &screen = *_vm->_screen;
+
+ if (_visage.isLoaded()) {
+ if (isMoving()) {
+ uint32 currTime = _vm->_events->getFrameCounter();
+ if (_walkStartFrame <= currTime) {
+ int moveRate = 10;
+ int frameInc = 60 / moveRate;
+ _walkStartFrame = currTime + frameInc;
+ move();
+ }
+ }
+
+ if (_isAnimating) {
+ if (_frame < _visage.getFrameCount())
+ _frame = changeFrame();
+ else
+ _finished = true;
+ }
+
+ // Get the new frame
+ ObjectSurface s;
+ _visage.getFrame(s, _frame);
+
+ // Display the frame
+ _oldBounds = Common::Rect(_position.x, _position.y, _position.x + s.w(), _position.y + s.h());
+ _oldBounds.translate(-s._centroid.x, -s._centroid.y);
+ screen.transBlitFrom(s, Common::Point(_oldBounds.left, _oldBounds.top));
+ }
+}
+
+int Object::changeFrame() {
+ int frameNum = _frame;
+ uint32 currentFrame = _vm->_events->getFrameCounter();
+
+ if (_updateStartFrame <= currentFrame) {
+ if (_numFrames > 0) {
+ int v = 60 / _numFrames;
+ _updateStartFrame = currentFrame + v;
+
+ frameNum = getNewFrame();
+ }
+ }
+
+ return frameNum;
+}
+
+int Object::getNewFrame() {
+ int frameNum = _frame + _frameChange;
+
+ if (_frameChange > 0) {
+ if (frameNum > _visage.getFrameCount()) {
+ frameNum = 1;
+ }
+ } else if (frameNum < 1) {
+ frameNum = _visage.getFrameCount();
+ }
+
+ return frameNum;
+}
+
+void Object::calculateMoveAngle() {
+ int xDiff = _destination.x - _position.x, yDiff = _position.y - _destination.y;
+
+ if (!xDiff && !yDiff)
+ _angle = 0;
+ else if (!xDiff)
+ _angle = (_destination.y >= _position.y) ? 180 : 0;
+ else if (!yDiff)
+ _angle = (_destination.x >= _position.x) ? 90 : 270;
+ else {
+ int result = (((xDiff * 100) / ((abs(xDiff) + abs(yDiff))) * 90) / 100);
+
+ if (yDiff < 0)
+ result = 180 - result;
+ else if (xDiff < 0)
+ result += 360;
+
+ _angle = result;
+ }
+}
+
+bool Object::isAnimEnded() const {
+ return _finished;
+}
+
+bool Object::isMoving() const {
+ return (_destination.x != 0) && (_destination != _position);
+}
+
+void Object::move() {
+ Common::Point currPos = _position;
+ Common::Point moveDiff(5, 3);
+ int percent = 100;
+
+ if (dontMove())
+ return;
+
+ if (_moveDelta.x >= _moveDelta.y) {
+ int xAmount = _moveSign.x * moveDiff.x * percent / 100;
+ if (!xAmount)
+ xAmount = _moveSign.x;
+ currPos.x += xAmount;
+
+ int yAmount = ABS(_destination.y - currPos.y);
+ int yChange = _majorDiff / ABS(xAmount);
+ int ySign;
+
+ if (!yChange)
+ ySign = _moveSign.y;
+ else {
+ int v = yAmount / yChange;
+ _changeCtr += yAmount % yChange;
+ if (_changeCtr >= yChange) {
+ ++v;
+ _changeCtr -= yChange;
+ }
+
+ ySign = _moveSign.y * v;
+ }
+
+ currPos.y += ySign;
+ _majorDiff -= ABS(xAmount);
+ } else {
+ int yAmount = _moveSign.y * moveDiff.y * percent / 100;
+ if (!yAmount)
+ yAmount = _moveSign.y;
+ currPos.y += yAmount;
+
+ int xAmount = ABS(_destination.x - currPos.x);
+ int xChange = _majorDiff / ABS(yAmount);
+ int xSign;
+
+ if (!xChange)
+ xSign = _moveSign.x;
+ else {
+ int v = xAmount / xChange;
+ _changeCtr += xAmount % xChange;
+ if (_changeCtr >= xChange) {
+ ++v;
+ _changeCtr -= xChange;
+ }
+
+ xSign = _moveSign.x * v;
+ }
+
+ currPos.x += xSign;
+ _majorDiff -= ABS(yAmount);
+ }
+
+ _position = currPos;
+ if (dontMove())
+ _position = _destination;
+}
+
+bool Object::dontMove() const {
+ return (_majorDiff <= 0);
+}
+
+void Object::endMove() {
+ _position = _destination;
+}
+
+/*----------------------------------------------------------------*/
+
+bool Logo::show(ScalpelEngine *vm) {
+ Events &events = *vm->_events;
+ Logo *logo = new Logo(vm);
+ bool interrupted = false;
+
+ while (!logo->finished()) {
+ logo->nextFrame();
+
+ // Erase areas from previous frame, and update and re-draw objects
+ for (int idx = 0; idx < 4; ++idx)
+ logo->_objects[idx].erase();
+ for (int idx = 0; idx < 4; ++idx)
+ logo->_objects[idx].update();
+
+ events.wait(2);
+ events.setButtonState();
+
+ interrupted = vm->shouldQuit() || events.kbHit() || events._pressed;
+ if (interrupted) {
+ // Keyboard or mouse button pressed, so break out of logo display
+ events.clearEvents();
+ break;
+ }
+ }
+
+ delete logo;
+ return !interrupted;
+}
+
+Logo::Logo(ScalpelEngine *vm) : _vm(vm), _lib("sf3.rlb") {
+ Object::_vm = vm;
+ Visage::_tLib = &_lib;
+
+ _finished = false;
+
+ // Initialize counter
+ _counter = 0;
+
+ // Initialize wait frame counters
+ _waitFrames = 0;
+ _waitStartFrame = 0;
+
+ // Initialize animation counters
+ _animateObject = 0;
+ _animateStartFrame = 0;
+ _animateFrameDelay = 0;
+ _animateFrames = NULL;
+ _animateFrame = 0;
+
+ // Save a copy of the original palette
+ _vm->_screen->getPalette(_originalPalette);
+
+ // Set up the palettes
+ Common::fill(&_palette1[0], &_palette1[PALETTE_SIZE], 0);
+ Common::fill(&_palette1[0], &_palette2[PALETTE_SIZE], 0);
+ Common::fill(&_palette1[0], &_palette3[PALETTE_SIZE], 0);
+
+ _lib.getPalette(_palette1, 1111);
+ _lib.getPalette(_palette1, 10);
+ _lib.getPalette(_palette2, 1111);
+ _lib.getPalette(_palette2, 1);
+ _lib.getPalette(_palette3, 1111);
+ _lib.getPalette(_palette3, 14);
+}
+
+Logo::~Logo() {
+ // Restore the original palette
+ _vm->_screen->setPalette(_originalPalette);
+}
+
+bool Logo::finished() const {
+ return _finished;
+}
+
+const AnimationFrame handFrames[] = {
+ { 1, 33, 91 }, { 2, 44, 124 }, { 3, 64, 153 }, { 4, 87, 174 },
+ { 5, 114, 191 }, { 6, 125, 184 }, { 7, 154, 187 }, { 8, 181, 182 },
+ { 9, 191, 167 }, { 10, 190, 150 }, { 11, 182, 139 }, { 11, 170, 130 },
+ { 11, 158, 121 }, { 0, 0, 0 }
+};
+
+const AnimationFrame companyFrames[] = {
+ { 1, 155, 94 }, { 2, 155, 94 }, { 3, 155, 94 }, { 4, 155, 94 },
+ { 5, 155, 94 }, { 6, 155, 94 }, { 7, 155, 94 }, { 8, 155, 94 },
+ { 0, 0, 0 }
+};
+
+void Logo::nextFrame() {
+ Screen &screen = *_vm->_screen;
+
+ if (_waitFrames) {
+ uint32 currFrame = _vm->_events->getFrameCounter();
+ if (currFrame - _waitStartFrame < _waitFrames) {
+ return;
+ }
+ _waitStartFrame = 0;
+ _waitFrames = 0;
+ }
+
+ if (_animateFrames) {
+ uint32 currFrame = _vm->_events->getFrameCounter();
+ if (currFrame > _animateStartFrame + _animateFrameDelay) {
+ AnimationFrame animationFrame = _animateFrames[_animateFrame];
+ if (animationFrame.frame) {
+ _objects[_animateObject]._frame = animationFrame.frame;
+ _objects[_animateObject]._position = Common::Point(animationFrame.x, animationFrame.y);
+ _animateStartFrame += _animateFrameDelay;
+ _animateFrame++;
+ } else {
+ _animateObject = 0;
+ _animateFrameDelay = 0;
+ _animateFrames = NULL;
+ _animateStartFrame = 0;
+ _animateFrame = 0;
+ }
+ }
+ if (_animateFrames)
+ return;
+ }
+
+ switch (_counter++) {
+ case 0:
+ // Load the background and fade it in
+ loadBackground();
+ fade(_palette1);
+ break;
+
+ case 1:
+ // First half of square, circle, and triangle arranging themselves
+ _objects[0].setVisage(16, 1);
+ _objects[0]._frame = 1;
+ _objects[0]._position = Common::Point(169, 107);
+ _objects[0]._numFrames = 7;
+ _objects[0].setAnimMode(true);
+ break;
+
+ case 2:
+ // Keep waiting until first animation ends
+ if (!_objects[0].isAnimEnded()) {
+ --_counter;
+ } else {
+ // Start second half of the shapes animation
+ _objects[0].setVisage(16, 2);
+ _objects[0]._frame = 1;
+ _objects[0]._numFrames = 11;
+ _objects[0].setAnimMode(true);
+ }
+ break;
+
+ case 3:
+ // Keep waiting until second animation of shapes ordering themselves ends
+ if (!_objects[0].isAnimEnded()) {
+ --_counter;
+ } else {
+ // Fade out the background but keep the shapes visible
+ fade(_palette2);
+ screen._backBuffer1.clear();
+ }
+ waitFrames(10);
+ break;
+
+ case 4:
+ // Load the new palette
+ byte palette[PALETTE_SIZE];
+ Common::copy(&_palette2[0], &_palette2[PALETTE_SIZE], &palette[0]);
+ _lib.getPalette(palette, 12);
+ screen.clear();
+ screen.setPalette(palette);
+
+ // Morph into the EA logo
+ _objects[0].setVisage(12, 1);
+ _objects[0]._frame = 1;
+ _objects[0]._numFrames = 7;
+ _objects[0].setAnimMode(true);
+ _objects[0]._position = Common::Point(170, 142);
+ _objects[0].setDestination(Common::Point(158, 71));
+ break;
+
+ case 5:
+ // Wait until the logo has expanded upwards to form EA logo
+ if (_objects[0].isMoving())
+ --_counter;
+ break;
+
+ case 6:
+ fade(_palette3, 40);
+ break;
+
+ case 7:
+ // Show the 'Electronic Arts' company name
+ _objects[1].setVisage(14, 1);
+ _objects[1]._frame = 1;
+ _objects[1]._position = Common::Point(152, 98);
+ waitFrames(120);
+ break;
+
+ case 8:
+ // Start sequence of positioning and size hand cursor in an arc
+ _objects[2].setVisage(18, 1);
+ startAnimation(2, 5, &handFrames[0]);
+ break;
+
+ case 9:
+ // Show a highlighting of the company name
+ _objects[1].remove();
+ _objects[2].erase();
+ _objects[2].remove();
+ _objects[3].setVisage(19, 1);
+ startAnimation(3, 8, &companyFrames[0]);
+ break;
+
+ case 10:
+ waitFrames(180);
+ break;
+
+ case 11:
+ _finished = true;
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Logo::waitFrames(uint frames) {
+ _waitFrames = frames;
+ _waitStartFrame = _vm->_events->getFrameCounter();
+}
+
+void Logo::startAnimation(uint object, uint frameDelay, const AnimationFrame *frames) {
+ _animateObject = object;
+ _animateFrameDelay = frameDelay;
+ _animateFrames = frames;
+ _animateStartFrame = _vm->_events->getFrameCounter();
+ _animateFrame = 1;
+
+ _objects[object]._frame = frames[0].frame;
+ _objects[object]._position = Common::Point(frames[0].x, frames[0].y);
+}
+
+void Logo::loadBackground() {
+ Screen &screen = *_vm->_screen;
+
+ for (int idx = 0; idx < 4; ++idx) {
+ // Get the portion of the screen
+ Common::SeekableReadStream *stream = _lib.getResource(RES_BITMAP, 10, idx);
+
+ // Load it onto the surface
+ Common::Point pt((idx / 2) * (SHERLOCK_SCREEN_WIDTH / 2), (idx % 2) * (SHERLOCK_SCREEN_HEIGHT / 2));
+ for (int y = 0; y < (SHERLOCK_SCREEN_HEIGHT / 2); ++y, ++pt.y) {
+ byte *pDest = (byte *)screen._backBuffer1.getBasePtr(pt.x, pt.y);
+ stream->read(pDest, SHERLOCK_SCREEN_WIDTH / 2);
+ }
+
+ // _backgroundBounds = Rect(0, 0, READ_LE_UINT16(data), READ_LE_UINT16(data + 2));
+ delete stream;
+ }
+
+ // Default to a blank palette
+ byte palette[PALETTE_SIZE];
+ Common::fill(&palette[0], &palette[PALETTE_SIZE], 0);
+ screen.setPalette(palette);
+
+ // Copy the surface to the screen
+ screen.blitFrom(screen._backBuffer1);
+}
+
+void Logo::fade(const byte palette[PALETTE_SIZE], int step) {
+ Events &events = *_vm->_events;
+ Screen &screen = *_vm->_screen;
+ byte startPalette[PALETTE_SIZE];
+ byte tempPalette[PALETTE_SIZE];
+
+ screen.getPalette(startPalette);
+
+ for (int percent = 0; percent < 100; percent += step) {
+ for (int palIndex = 0; palIndex < 256; ++palIndex) {
+ const byte *pal1P = (const byte *)&startPalette[palIndex * 3];
+ const byte *pal2P = (const byte *)&palette[palIndex * 3];
+ byte *destP = &tempPalette[palIndex * 3];
+
+ for (int rgbIndex = 0; rgbIndex < 3; ++rgbIndex, ++pal1P, ++pal2P, ++destP) {
+ *destP = (int)*pal1P + ((int)*pal2P - (int)*pal1P) * percent / 100;
+ }
+ }
+
+ screen.setPalette(tempPalette);
+ events.wait(1);
+ }
+
+ // Set final palette
+ screen.setPalette(palette);
+}
+
+} // end of namespace TsAGE
+} // end of namespace Scalpel
+} // end of namespace Sherlock
diff --git a/engines/sherlock/scalpel/tsage/logo.h b/engines/sherlock/scalpel/tsage/logo.h
new file mode 100644
index 0000000000..c9fac00d9c
--- /dev/null
+++ b/engines/sherlock/scalpel/tsage/logo.h
@@ -0,0 +1,250 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SHERLOCK_SCALPEL_TSAGE_LOGO_H
+#define SHERLOCK_SCALPEL_TSAGE_LOGO_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/file.h"
+#include "common/list.h"
+#include "common/str.h"
+#include "common/str-array.h"
+#include "common/util.h"
+#include "graphics/surface.h"
+#include "sherlock/scalpel/tsage/resources.h"
+#include "sherlock/screen.h"
+
+namespace Sherlock {
+namespace Scalpel {
+
+class ScalpelEngine;
+
+namespace TsAGE {
+
+class ObjectSurface : public Surface {
+public:
+ Common::Point _centroid;
+public:
+ ObjectSurface() : Surface() {}
+ virtual ~ObjectSurface() {}
+};
+
+class Visage {
+private:
+ Common::SeekableReadStream *_stream;
+
+ /**
+ * Translates a raw image resource into a graphics surface
+ */
+ void surfaceFromRes(ObjectSurface &s);
+public:
+ static TLib *_tLib;
+ int _resNum;
+ int _rlbNum;
+public:
+ Visage();
+ ~Visage();
+
+ /**
+ * Set the visage number
+ */
+ void setVisage(int resNum, int rlbNum = 9999);
+
+ /**
+ * Clear the visage
+ */
+ void clear();
+
+ /**
+ * Get a frame from the visage
+ */
+ void getFrame(ObjectSurface &s, int frameNum);
+
+ /**
+ * Return the number of frames
+ */
+ int getFrameCount() const;
+
+ /**
+ * Returns whether the visage is loaded
+ */
+ bool isLoaded() const;
+};
+
+class Object {
+private:
+ Visage _visage;
+ uint32 _updateStartFrame;
+ bool _isAnimating;
+ bool _finished;
+ uint32 _walkStartFrame;
+ int _angle;
+ int _changeCtr;
+ int _majorDiff, _minorDiff;
+ Common::Point _moveDelta;
+ Common::Point _moveSign;
+
+ /**
+ * Return the next frame when the object is animating
+ */
+ int changeFrame();
+
+ /**
+ * Gets the next frame in the sequence
+ */
+ int getNewFrame();
+
+ /**
+ * Calculate the angle between the current position and a designated destination
+ */
+ void calculateMoveAngle();
+
+ /**
+ * Handle any object movement
+ */
+ void move();
+
+ /**
+ * Returns whether not to make any movement
+ */
+ bool dontMove() const;
+
+ /**
+ * Ends any current movement
+ */
+ void endMove();
+public:
+ static ScalpelEngine *_vm;
+ Common::Point _position;
+ Common::Point _destination;
+ Common::Rect _oldBounds;
+ int _frame;
+ int _numFrames;
+ int _frameChange;
+public:
+ Object();
+
+ /**
+ * Load the data for the object
+ */
+ void setVisage(int visage, int strip);
+
+ /**
+ * Sets whether the object is animating
+ */
+ void setAnimMode(bool isAnimating);
+
+ /**
+ * Starts an object moving to a given destination
+ */
+ void setDestination(const Common::Point &pt);
+
+ /**
+ * Returns true if an animation is ended
+ */
+ bool isAnimEnded() const;
+
+ /**
+ * Return true if object is moving
+ */
+ bool isMoving() const;
+
+ /**
+ * Erase the area the object was previously drawn at, by restoring the background
+ */
+ void erase();
+
+ /**
+ * Update the frame
+ */
+ void update();
+
+ /**
+ * Remove an object from being displayed
+ */
+ void remove() { _visage.clear(); }
+};
+
+struct AnimationFrame {
+ int frame;
+ int x;
+ int y;
+};
+
+class Logo {
+private:
+ ScalpelEngine *_vm;
+ TLib _lib;
+ int _counter;
+ bool _finished;
+ byte _originalPalette[PALETTE_SIZE];
+ byte _palette1[PALETTE_SIZE];
+ byte _palette2[PALETTE_SIZE];
+ byte _palette3[PALETTE_SIZE];
+ Object _objects[4];
+ uint _waitFrames;
+ uint32 _waitStartFrame;
+ int _animateObject;
+ uint32 _animateStartFrame;
+ uint _animateFrameDelay;
+ const AnimationFrame *_animateFrames;
+ uint _animateFrame;
+
+ Logo(ScalpelEngine *vm);
+ ~Logo();
+
+ void nextFrame();
+
+ bool finished() const;
+
+ /**
+ * Wait for a number of frames. Note that the frame count in _events is
+ * not the same as the number of calls to nextFrame().
+ */
+ void waitFrames(uint frames);
+
+ /**
+ * Start an animation sequence. Used for sequences that are described
+ * one frame at a time because they do unusual things, or run at
+ * unusual rates.
+ */
+ void startAnimation(uint object, uint frameDelay, const AnimationFrame *frames);
+
+ /**
+ * Load the background for the scene
+ */
+ void loadBackground();
+
+ /**
+ * Fade from the current palette to a new one
+ */
+ void fade(const byte palette[PALETTE_SIZE], int step = 6);
+public:
+ static bool show(ScalpelEngine *vm);
+};
+
+} // end of namespace TsAGE
+} // end of namespace Scalpel
+} // end of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/scalpel/tsage/resources.cpp b/engines/sherlock/scalpel/tsage/resources.cpp
new file mode 100644
index 0000000000..56b7021563
--- /dev/null
+++ b/engines/sherlock/scalpel/tsage/resources.cpp
@@ -0,0 +1,373 @@
+/* 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/scummsys.h"
+#include "common/memstream.h"
+#include "common/stack.h"
+#include "sherlock/scalpel/tsage/resources.h"
+
+namespace Sherlock {
+namespace Scalpel {
+namespace TsAGE {
+
+static uint16 bitMasks[4] = {0x1ff, 0x3ff, 0x7ff, 0xfff};
+
+uint16 BitReader::readToken() {
+ assert((numBits >= 9) && (numBits <= 12));
+ uint16 result = _remainder;
+ int bitsLeft = numBits - _bitsLeft;
+ int bitOffset = _bitsLeft;
+ _bitsLeft = 0;
+
+ while (bitsLeft >= 0) {
+ _remainder = readByte();
+ result |= _remainder << bitOffset;
+ bitsLeft -= 8;
+ bitOffset += 8;
+ }
+
+ _bitsLeft = -bitsLeft;
+ _remainder >>= 8 - _bitsLeft;
+ return result & bitMasks[numBits - 9];
+}
+
+/*-------------------------------------------------------------------------*/
+
+TLib::TLib(const Common::String &filename) : _filename(filename) {
+
+ // If the resource strings list isn't yet loaded, load them
+ if (_resStrings.size() == 0) {
+ Common::File f;
+ if (f.open("tsage.cfg")) {
+ while (!f.eos()) {
+ _resStrings.push_back(f.readLine());
+ }
+ f.close();
+ }
+ }
+
+ if (!_file.open(filename))
+ error("Missing file %s", filename.c_str());
+
+ loadIndex();
+}
+
+TLib::~TLib() {
+ _resStrings.clear();
+}
+
+/**
+ * Load a section index from the given position in the file
+ */
+void TLib::loadSection(uint32 fileOffset) {
+ _resources.clear();
+ _file.seek(fileOffset);
+ _sections.fileOffset = fileOffset;
+
+ loadSection(_file, _resources);
+}
+
+struct DecodeReference {
+ uint16 vWord;
+ uint8 vByte;
+};
+
+/**
+ * Gets a resource from the currently loaded section
+ */
+Common::SeekableReadStream *TLib::getResource(uint16 id, bool suppressErrors) {
+ // Scan for an entry for the given Id
+ ResourceEntry *re = nullptr;
+ ResourceList::iterator iter;
+ for (iter = _resources.begin(); iter != _resources.end(); ++iter) {
+ if ((*iter).id == id) {
+ re = &(*iter);
+ break;
+ }
+ }
+ if (!re) {
+ if (suppressErrors)
+ return nullptr;
+ error("Could not find resource Id #%d", id);
+ }
+
+ if (!re->isCompressed) {
+ // Read in the resource data and return it
+ byte *dataP = (byte *)malloc(re->size);
+ _file.seek(_sections.fileOffset + re->fileOffset);
+ _file.read(dataP, re->size);
+
+ return new Common::MemoryReadStream(dataP, re->size, DisposeAfterUse::YES);
+ }
+
+ /*
+ * Decompress the data block
+ */
+
+ _file.seek(_sections.fileOffset + re->fileOffset);
+ Common::ReadStream *compStream = _file.readStream(re->size);
+ BitReader bitReader(*compStream);
+
+ byte *dataOut = (byte *)malloc(re->uncompressedSize);
+ byte *destP = dataOut;
+ uint bytesWritten = 0;
+
+ uint16 ctrCurrent = 0x102, ctrMax = 0x200;
+ uint16 word_48050 = 0, currentToken = 0, word_48054 =0;
+ byte byte_49068 = 0, byte_49069 = 0;
+
+ const uint tableSize = 0x1000;
+ DecodeReference *table = (DecodeReference *)malloc(tableSize * sizeof(DecodeReference));
+ if (!table)
+ error("[TLib::getResource] Cannot allocate table buffer");
+
+ for (uint i = 0; i < tableSize; ++i) {
+ table[i].vByte = table[i].vWord = 0;
+ }
+ Common::Stack<uint16> tokenList;
+
+ for (;;) {
+ // Get the next decode token
+ uint16 token = bitReader.readToken();
+
+ // Handle the token
+ if (token == 0x101) {
+ // End of compressed stream
+ break;
+ } else if (token == 0x100) {
+ // Reset bit-rate
+ bitReader.numBits = 9;
+ ctrMax = 0x200;
+ ctrCurrent = 0x102;
+
+ // Set variables with next token
+ currentToken = word_48050 = bitReader.readToken();
+ byte_49069 = byte_49068 = (byte)currentToken;
+
+ ++bytesWritten;
+ assert(bytesWritten <= re->uncompressedSize);
+ *destP++ = byte_49069;
+ } else {
+ word_48054 = word_48050 = token;
+
+ if (token >= ctrCurrent) {
+ word_48050 = currentToken;
+ tokenList.push(byte_49068);
+ }
+
+ while (word_48050 >= 0x100) {
+ assert(word_48050 < 0x1000);
+ tokenList.push(table[word_48050].vByte);
+ word_48050 = table[word_48050].vWord;
+ }
+
+ byte_49069 = byte_49068 = (byte)word_48050;
+ tokenList.push(word_48050);
+
+ // Write out any cached tokens
+ while (!tokenList.empty()) {
+ ++bytesWritten;
+ assert(bytesWritten <= re->uncompressedSize);
+ *destP++ = tokenList.pop();
+ }
+
+ assert(ctrCurrent < 0x1000);
+ table[ctrCurrent].vByte = byte_49069;
+ table[ctrCurrent].vWord = currentToken;
+ ++ctrCurrent;
+
+ currentToken = word_48054;
+ if ((ctrCurrent >= ctrMax) && (bitReader.numBits != 12)) {
+ // Move to the next higher bit-rate
+ ++bitReader.numBits;
+ ctrMax <<= 1;
+ }
+ }
+ }
+
+ free(table);
+
+ assert(bytesWritten == re->uncompressedSize);
+ delete compStream;
+ return new Common::MemoryReadStream(dataOut, re->uncompressedSize, DisposeAfterUse::YES);
+}
+
+/**
+ * Finds the correct section and loads the specified resource within it
+ */
+Common::SeekableReadStream *TLib::getResource(ResourceType resType, uint16 resNum, uint16 rlbNum, bool suppressErrors) {
+ SectionList::iterator i = _sections.begin();
+ while ((i != _sections.end()) && ((*i).resType != resType || (*i).resNum != resNum))
+ ++i;
+ if (i == _sections.end()) {
+ if (suppressErrors)
+ return nullptr;
+ error("Unknown resource type %d num %d", resType, resNum);
+ }
+
+ loadSection((*i).fileOffset);
+
+ return getResource(rlbNum, suppressErrors);
+}
+
+/**
+ * Gets the offset of the start of a resource in the resource file
+ */
+uint32 TLib::getResourceStart(ResourceType resType, uint16 resNum, uint16 rlbNum, ResourceEntry &entry) {
+ // Find the correct section
+ SectionList::iterator i = _sections.begin();
+ while ((i != _sections.end()) && ((*i).resType != resType || (*i).resNum != resNum))
+ ++i;
+ if (i == _sections.end()) {
+ error("Unknown resource type %d num %d", resType, resNum);
+ }
+
+ // Load in the section index
+ loadSection((*i).fileOffset);
+
+ // Scan for an entry for the given Id
+ ResourceEntry *re = nullptr;
+ ResourceList::iterator iter;
+ for (iter = _resources.begin(); iter != _resources.end(); ++iter) {
+ if ((*iter).id == rlbNum) {
+ re = &(*iter);
+ break;
+ }
+ }
+
+ // Throw an error if no resource was found, or the resource is compressed
+ if (!re || re->isCompressed)
+ error("Invalid resource Id #%d", rlbNum);
+
+ // Return the resource entry as well as the file offset
+ entry = *re;
+ return _sections.fileOffset + entry.fileOffset;
+}
+
+void TLib::loadIndex() {
+ uint16 resNum, configId, fileOffset;
+
+ // Load the root resources section
+ loadSection(0);
+
+ // Get the single resource from it
+ Common::SeekableReadStream *stream = getResource(0);
+
+ _sections.clear();
+
+ // Loop through reading the entries
+ while ((resNum = stream->readUint16LE()) != 0xffff) {
+ configId = stream->readUint16LE();
+ fileOffset = stream->readUint16LE();
+
+ SectionEntry se;
+ se.resNum = resNum;
+ se.resType = (ResourceType)(configId & 0x1f);
+ se.fileOffset = (((configId >> 5) & 0x7ff) << 16) | fileOffset;
+
+ _sections.push_back(se);
+ }
+
+ delete stream;
+}
+
+/**
+ * Retrieves the specified palette resource and returns it's data
+ *
+ * @paletteNum Specefies the palette number
+ */
+void TLib::getPalette(byte palette[PALETTE_SIZE], int paletteNum) {
+ // Get the specified palette
+ Common::SeekableReadStream *stream = getResource(RES_PALETTE, paletteNum, 0, true);
+ if (!stream)
+ return;
+
+ int startNum = stream->readUint16LE();
+ int numEntries = stream->readUint16LE();
+ assert((startNum < 256) && ((startNum + numEntries) <= 256));
+ stream->skip(2);
+
+ // Copy over the data
+ stream->read(&palette[startNum * 3], numEntries * 3);
+
+ delete stream;
+}
+
+/**
+ * Open up the given resource file using a passed file object. If the desired entry is found
+ * in the index, return the index entry for it, and move the file to the start of the resource
+ */
+bool TLib::scanIndex(Common::File &f, ResourceType resType, int rlbNum, int resNum,
+ ResourceEntry &resEntry) {
+ // Load the root section index
+ ResourceList resList;
+ loadSection(f, resList);
+
+ // Loop through the index for the desired entry
+ ResourceList::iterator iter;
+ for (iter = resList.begin(); iter != resList.end(); ++iter) {
+ ResourceEntry &re = *iter;
+ if (re.id == resNum) {
+ // Found it, so exit
+ resEntry = re;
+ f.seek(re.fileOffset);
+ return true;
+ }
+ }
+
+ // No matching entry found
+ return false;
+}
+
+/**
+ * Inner logic for decoding a section index into a passed resource list object
+ */
+void TLib::loadSection(Common::File &f, ResourceList &resources) {
+ if (f.readUint32BE() != 0x544D492D)
+ error("Data block is not valid Rlb data");
+
+ /*uint8 unknown1 = */f.readByte();
+ uint16 numEntries = f.readByte();
+
+ for (uint i = 0; i < numEntries; ++i) {
+ uint16 id = f.readUint16LE();
+ uint16 size = f.readUint16LE();
+ uint16 uncSize = f.readUint16LE();
+ uint8 sizeHi = f.readByte();
+ uint8 type = f.readByte() >> 5;
+ assert(type <= 1);
+ uint32 offset = f.readUint32LE();
+
+ ResourceEntry re;
+ re.id = id;
+ re.fileOffset = offset;
+ re.isCompressed = type != 0;
+ re.size = ((sizeHi & 0xF) << 16) | size;
+ re.uncompressedSize = ((sizeHi & 0xF0) << 12) | uncSize;
+
+ resources.push_back(re);
+ }
+}
+
+} // end of namespace TsAGE
+} // end of namespace Scalpel
+} // end of namespace Sherlock
diff --git a/engines/sherlock/scalpel/tsage/resources.h b/engines/sherlock/scalpel/tsage/resources.h
new file mode 100644
index 0000000000..3e09b6b0b1
--- /dev/null
+++ b/engines/sherlock/scalpel/tsage/resources.h
@@ -0,0 +1,139 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SHERLOCK_SCALPEL_TSAGE_RESOURCES_H
+#define SHERLOCK_SCALPEL_TSAGE_RESOURCES_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/file.h"
+#include "common/list.h"
+#include "common/str.h"
+#include "common/str-array.h"
+#include "common/util.h"
+#include "graphics/surface.h"
+#include "sherlock/screen.h"
+
+namespace Sherlock {
+namespace Scalpel {
+namespace TsAGE {
+
+// Magic number used by original game to identify valid memory blocks
+const uint32 MEMORY_ENTRY_ID = 0xE11DA722;
+
+const int MEMORY_POOL_SIZE = 1000;
+
+enum ResourceType { RES_LIBRARY, RES_STRIP, RES_IMAGE, RES_PALETTE, RES_VISAGE, RES_SOUND, RES_MESSAGE,
+ RES_FONT, RES_POINTER, RES_BANK, RES_SND_DRIVER, RES_PRIORITY, RES_CONTROL, RES_WALKRGNS,
+ RES_BITMAP, RES_SAVE, RES_SEQUENCE,
+ // Return to Ringworld specific resource types
+ RT17, RT18, RT19, RT20, RT21, RT22, RT23, RT24, RT25, RT26, RT27, RT28, RT29, RT30, RT31
+};
+
+class SectionEntry {
+public:
+ ResourceType resType;
+ uint16 resNum;
+ uint32 fileOffset;
+
+ SectionEntry() {
+ resType = RES_LIBRARY;
+ resNum = 0;
+ fileOffset = 0;
+ }
+};
+
+class ResourceEntry {
+public:
+ uint16 id;
+ bool isCompressed;
+ uint32 fileOffset;
+ uint32 size;
+ uint32 uncompressedSize;
+
+ ResourceEntry() {
+ id = 0;
+ isCompressed = false;
+ fileOffset = 0;
+ size = 0;
+ uncompressedSize = 0;
+ }
+};
+
+typedef Common::List<ResourceEntry> ResourceList;
+
+class SectionList : public Common::List<SectionEntry> {
+public:
+ uint32 fileOffset;
+
+ SectionList() {
+ fileOffset = 0;
+ }
+};
+
+class BitReader {
+private:
+ Common::ReadStream &_stream;
+ uint8 _remainder, _bitsLeft;
+ byte readByte() { return _stream.eos() ? 0 : _stream.readByte(); }
+public:
+ BitReader(Common::ReadStream &s) : _stream(s) {
+ numBits = 9;
+ _remainder = 0;
+ _bitsLeft = 0;
+ }
+ uint16 readToken();
+
+ int numBits;
+};
+
+class TLib {
+private:
+ Common::StringArray _resStrings;
+private:
+ Common::File _file;
+ Common::String _filename;
+ ResourceList _resources;
+ SectionList _sections;
+
+ void loadSection(uint32 fileOffset);
+ void loadIndex();
+
+ static bool scanIndex(Common::File &f, ResourceType resType, int rlbNum, int resNum, ResourceEntry &resEntry);
+ static void loadSection(Common::File &f, ResourceList &resources);
+public:
+ TLib(const Common::String &filename);
+ ~TLib();
+
+ const Common::String &getFilename() { return _filename; }
+ const SectionList &getSections() { return _sections; }
+ Common::SeekableReadStream *getResource(uint16 id, bool suppressErrors = false);
+ Common::SeekableReadStream *getResource(ResourceType resType, uint16 resNum, uint16 rlbNum, bool suppressErrors = false);
+ uint32 getResourceStart(ResourceType resType, uint16 resNum, uint16 rlbNum, ResourceEntry &entry);
+ void getPalette(byte palette[PALETTE_SIZE], int paletteNum);
+};
+
+} // end of namespace TsAGE
+} // end of namespace Scalpel
+} // end of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp
new file mode 100644
index 0000000000..328bf647d4
--- /dev/null
+++ b/engines/sherlock/scene.cpp
@@ -0,0 +1,1437 @@
+/* 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 "sherlock/scene.h"
+#include "sherlock/sherlock.h"
+#include "sherlock/screen.h"
+#include "sherlock/scalpel/scalpel.h"
+#include "sherlock/scalpel/scalpel_people.h"
+#include "sherlock/scalpel/scalpel_scene.h"
+#include "sherlock/tattoo/tattoo.h"
+#include "sherlock/tattoo/tattoo_scene.h"
+#include "sherlock/tattoo/tattoo_user_interface.h"
+
+namespace Sherlock {
+
+static const int FS_TRANS[8] = {
+ Scalpel::STOP_UP, Scalpel::STOP_UPRIGHT, Scalpel::STOP_RIGHT, Scalpel::STOP_DOWNRIGHT,
+ Scalpel::STOP_DOWN, Scalpel::STOP_DOWNLEFT, Scalpel::STOP_LEFT, Scalpel::STOP_UPLEFT
+};
+
+/*----------------------------------------------------------------*/
+
+BgFileHeader::BgFileHeader() {
+ _numStructs = -1;
+ _numImages = -1;
+ _numcAnimations = -1;
+ _descSize = -1;
+ _seqSize = -1;
+
+ // Serrated Scalpel
+ _fill = -1;
+
+ // Rose Tattoo
+ _scrollSize = -1;
+ _bytesWritten = -1;
+ _fadeStyle = -1;
+ Common::fill(&_palette[0], &_palette[PALETTE_SIZE], 0);
+}
+
+void BgFileHeader::load(Common::SeekableReadStream &s, bool isRoseTattoo) {
+ _numStructs = s.readUint16LE();
+ _numImages = s.readUint16LE();
+ _numcAnimations = s.readUint16LE();
+ _descSize = s.readUint16LE();
+ _seqSize = s.readUint16LE();
+
+ if (isRoseTattoo) {
+ _scrollSize = s.readUint16LE();
+ _bytesWritten = s.readUint32LE();
+ _fadeStyle = s.readByte();
+ } else {
+ _fill = s.readUint16LE();
+
+ }
+}
+
+/*----------------------------------------------------------------*/
+
+void BgFileHeaderInfo::load(Common::SeekableReadStream &s) {
+ _filesize = s.readUint32LE();
+ _maxFrames = s.readByte();
+
+ char buffer[9];
+ s.read(buffer, 9);
+ _filename = Common::String(buffer);
+}
+
+void BgFileHeaderInfo::load3DO(Common::SeekableReadStream &s) {
+ _filesize = s.readUint32BE();
+ _maxFrames = s.readByte();
+
+ char buffer[9];
+ s.read(buffer, 9);
+ _filename = Common::String(buffer);
+ s.skip(2); // only on 3DO!
+}
+
+/*----------------------------------------------------------------*/
+
+void Exit::load(Common::SeekableReadStream &s, bool isRoseTattoo) {
+ if (isRoseTattoo) {
+ char buffer[41];
+ s.read(buffer, 41);
+ _dest = Common::String(buffer);
+ }
+
+ left = s.readSint16LE();
+ top = s.readSint16LE();
+ setWidth(s.readUint16LE());
+ setHeight(s.readUint16LE());
+
+ _image = isRoseTattoo ? s.readByte() : 0;
+ _scene = s.readSint16LE();
+
+ if (!isRoseTattoo)
+ _allow = s.readSint16LE();
+
+ _newPosition.x = s.readSint16LE();
+ _newPosition.y = s.readSint16LE();
+ _newPosition._facing = s.readUint16LE();
+
+ if (isRoseTattoo)
+ _allow = s.readSint16LE();
+}
+
+void Exit::load3DO(Common::SeekableReadStream &s) {
+ left = s.readSint16BE();
+ top = s.readSint16BE();
+ setWidth(s.readUint16BE());
+ setHeight(s.readUint16BE());
+
+ _image = 0;
+ _scene = s.readSint16BE();
+
+ _allow = s.readSint16BE();
+
+ _newPosition.x = s.readSint16BE();
+ _newPosition.y = s.readSint16BE();
+ _newPosition._facing = s.readUint16BE();
+ s.skip(2); // Filler
+}
+
+/*----------------------------------------------------------------*/
+
+void SceneEntry::load(Common::SeekableReadStream &s) {
+ _startPosition.x = s.readSint16LE();
+ _startPosition.y = s.readSint16LE();
+ _startDir = s.readByte();
+ _allow = s.readByte();
+}
+
+void SceneEntry::load3DO(Common::SeekableReadStream &s) {
+ _startPosition.x = s.readSint16BE();
+ _startPosition.y = s.readSint16BE();
+ _startDir = s.readByte();
+ _allow = s.readByte();
+}
+
+void SceneSound::load(Common::SeekableReadStream &s) {
+ char buffer[9];
+ s.read(buffer, 8);
+ buffer[8] = '\0';
+
+ _name = Common::String(buffer);
+ _priority = s.readByte();
+}
+
+void SceneSound::load3DO(Common::SeekableReadStream &s) {
+ load(s);
+}
+
+/*----------------------------------------------------------------*/
+
+int ObjectArray::indexOf(const Object &obj) const {
+ for (uint idx = 0; idx < size(); ++idx) {
+ if (&(*this)[idx] == &obj)
+ return idx;
+ }
+
+ return -1;
+}
+
+/*----------------------------------------------------------------*/
+
+void ScaleZone::load(Common::SeekableReadStream &s) {
+ left = s.readSint16LE();
+ top = s.readSint16LE();
+ setWidth(s.readUint16LE());
+ setHeight(s.readUint16LE());
+
+ _topNumber = s.readByte();
+ _bottomNumber = s.readByte();
+}
+
+/*----------------------------------------------------------------*/
+
+void WalkArray::load(Common::SeekableReadStream &s, bool isRoseTattoo) {
+ _pointsCount = (int8)s.readByte();
+
+ for (int idx = 0; idx < _pointsCount; ++idx) {
+ int x = s.readSint16LE();
+ int y = isRoseTattoo ? s.readSint16LE() : s.readByte();
+ push_back(Common::Point(x, y));
+ }
+}
+
+/*----------------------------------------------------------------*/
+
+Scene *Scene::init(SherlockEngine *vm) {
+ if (vm->getGameID() == GType_SerratedScalpel)
+ return new Scalpel::ScalpelScene(vm);
+ else
+ return new Tattoo::TattooScene(vm);
+}
+
+Scene::Scene(SherlockEngine *vm): _vm(vm) {
+ _sceneStats = new bool *[SCENES_COUNT];
+ _sceneStats[0] = new bool[SCENES_COUNT * 65];
+ Common::fill(&_sceneStats[0][0], &_sceneStats[0][SCENES_COUNT * 65], false);
+ for (int idx = 1; idx < SCENES_COUNT; ++idx) {
+ _sceneStats[idx] = _sceneStats[idx - 1] + 65;
+ }
+ _currentScene = -1;
+ _goToScene = -1;
+ _loadingSavedGame = false;
+ _walkedInScene = false;
+ _version = 0;
+ _compressed = false;
+ _invGraphicItems = 0;
+ _cAnimFramePause = 0;
+ _restoreFlag = false;
+ _animating = 0;
+ _doBgAnimDone = true;
+ _tempFadeStyle = 0;
+ _doBgAnimDone = false;
+}
+
+Scene::~Scene() {
+ freeScene();
+ delete[] _sceneStats[0];
+ delete[] _sceneStats;
+}
+
+void Scene::selectScene() {
+ Events &events = *_vm->_events;
+ People &people = *_vm->_people;
+ Screen &screen = *_vm->_screen;
+ Talk &talk = *_vm->_talk;
+ UserInterface &ui = *_vm->_ui;
+
+ // Reset fields
+ ui._windowOpen = ui._infoFlag = false;
+ ui._menuMode = STD_MODE;
+
+ // Free any previous scene
+ freeScene();
+
+ // Load the scene
+ Common::String sceneFile = Common::String::format("res%02d", _goToScene);
+ // _rrmName gets set during loadScene()
+ // _rrmName is for ScalpelScene::startCAnim
+ _currentScene = _goToScene;
+ _goToScene = -1;
+
+ loadScene(sceneFile);
+
+ // If the fade style was changed from running a movie, then reset it
+ if (_tempFadeStyle) {
+ screen._fadeStyle = _tempFadeStyle;
+ _tempFadeStyle = 0;
+ }
+
+ people[HOLMES]._walkDest = Common::Point(people[HOLMES]._position.x / FIXED_INT_MULTIPLIER,
+ people[HOLMES]._position.y / FIXED_INT_MULTIPLIER);
+
+ _restoreFlag = true;
+ events.clearEvents();
+
+ // If there were any scripts waiting to be run, but were interrupt by a running
+ // canimation (probably the last scene's exit canim), clear the _scriptMoreFlag
+ if (talk._scriptMoreFlag == 3)
+ talk._scriptMoreFlag = 0;
+}
+
+void Scene::freeScene() {
+ if (_currentScene == -1)
+ return;
+
+ _vm->_ui->clearWindow();
+ _vm->_talk->freeTalkVars();
+ _vm->_inventory->freeInv();
+ _vm->_music->freeSong();
+ _vm->_sound->freeLoadedSounds();
+
+ if (!_loadingSavedGame)
+ saveSceneStatus();
+ else
+ _loadingSavedGame = false;
+
+ _sequenceBuffer.clear();
+ _descText.clear();
+ _walkPoints.clear();
+ _cAnim.clear();
+ _bgShapes.clear();
+ _zones.clear();
+ _canimShapes.clear();
+
+ for (uint idx = 0; idx < _images.size(); ++idx)
+ delete _images[idx]._images;
+ _images.clear();
+
+ _currentScene = -1;
+}
+
+bool Scene::loadScene(const Common::String &filename) {
+ Events &events = *_vm->_events;
+ Music &music = *_vm->_music;
+ People &people = *_vm->_people;
+ Resources &res = *_vm->_res;
+ SaveManager &saves = *_vm->_saves;
+ Screen &screen = *_vm->_screen;
+ UserInterface &ui = *_vm->_ui;
+ bool flag;
+
+ _walkedInScene = false;
+
+ // Reset the list of walkable areas
+ _zones.clear();
+ _zones.push_back(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
+
+ _descText.clear();
+ _comments = "";
+ _bgShapes.clear();
+ _cAnim.clear();
+ _sequenceBuffer.clear();
+
+ //
+ // Load the room resource file for the scene
+ //
+
+ if (!IS_3DO) {
+ // PC version
+ Common::String roomFilename = filename + ".rrm";
+ _roomFilename = roomFilename;
+
+ flag = _vm->_res->exists(roomFilename);
+ if (flag) {
+ Common::SeekableReadStream *rrmStream = _vm->_res->load(roomFilename);
+
+ rrmStream->seek(39);
+ if (IS_SERRATED_SCALPEL) {
+ _version = rrmStream->readByte();
+ _compressed = _version == 10;
+ } else {
+ _compressed = rrmStream->readByte() > 0;
+ }
+
+ // Go to header and read it in
+ rrmStream->seek(rrmStream->readUint32LE());
+
+ BgFileHeader bgHeader;
+ bgHeader.load(*rrmStream, IS_ROSE_TATTOO);
+ _invGraphicItems = bgHeader._numImages + 1;
+
+ if (IS_ROSE_TATTOO) {
+ // Resize the screen if necessary
+ int fullWidth = SHERLOCK_SCREEN_WIDTH + bgHeader._scrollSize;
+ if (screen._backBuffer1.w() != fullWidth) {
+ screen._backBuffer1.create(fullWidth, SHERLOCK_SCREEN_HEIGHT);
+ screen._backBuffer2.create(fullWidth, SHERLOCK_SCREEN_HEIGHT);
+ }
+
+ // Handle initializing the palette
+ screen.initPaletteFade(bgHeader._bytesWritten);
+ rrmStream->read(screen._cMap, PALETTE_SIZE);
+ screen.translatePalette(screen._cMap);
+
+ paletteLoaded();
+
+ // Read in background
+ if (_compressed) {
+ res.decompress(*rrmStream, (byte *)screen._backBuffer1.getPixels(), fullWidth * SHERLOCK_SCREEN_HEIGHT);
+ } else {
+ rrmStream->read(screen._backBuffer1.getPixels(), fullWidth * SHERLOCK_SCREEN_HEIGHT);
+ }
+ }
+
+ // Read in the shapes header info
+ Common::Array<BgFileHeaderInfo> bgInfo;
+ bgInfo.resize(bgHeader._numStructs);
+
+ for (uint idx = 0; idx < bgInfo.size(); ++idx)
+ bgInfo[idx].load(*rrmStream);
+
+ // Read information
+ if (IS_ROSE_TATTOO) {
+ // Load shapes
+ Common::SeekableReadStream *infoStream = !_compressed ? rrmStream : res.decompress(*rrmStream, bgHeader._numStructs * 625);
+
+ _bgShapes.resize(bgHeader._numStructs);
+ for (int idx = 0; idx < bgHeader._numStructs; ++idx)
+ _bgShapes[idx].load(*infoStream, true);
+
+ if (_compressed)
+ delete infoStream;
+
+ // Load description text
+ _descText.resize(bgHeader._descSize);
+ if (_compressed)
+ res.decompress(*rrmStream, (byte *)&_descText[0], bgHeader._descSize);
+ else
+ rrmStream->read(&_descText[0], bgHeader._descSize);
+
+ // Load sequences
+ _sequenceBuffer.resize(bgHeader._seqSize);
+ if (_compressed)
+ res.decompress(*rrmStream, &_sequenceBuffer[0], bgHeader._seqSize);
+ else
+ rrmStream->read(&_sequenceBuffer[0], bgHeader._seqSize);
+ } else if (!_compressed) {
+ // Serrated Scalpel uncompressed info
+ _bgShapes.resize(bgHeader._numStructs);
+ for (int idx = 0; idx < bgHeader._numStructs; ++idx)
+ _bgShapes[idx].load(*rrmStream, false);
+
+ if (bgHeader._descSize) {
+ _descText.resize(bgHeader._descSize);
+ rrmStream->read(&_descText[0], bgHeader._descSize);
+ }
+
+ if (bgHeader._seqSize) {
+ _sequenceBuffer.resize(bgHeader._seqSize);
+ rrmStream->read(&_sequenceBuffer[0], bgHeader._seqSize);
+ }
+ } else {
+ // Serrated Scalpel compressed info
+ Common::SeekableReadStream *infoStream;
+
+ // Read shapes
+ infoStream = Resources::decompressLZ(*rrmStream, bgHeader._numStructs * 569);
+
+ _bgShapes.resize(bgHeader._numStructs);
+ for (int idx = 0; idx < bgHeader._numStructs; ++idx)
+ _bgShapes[idx].load(*infoStream, false);
+
+ delete infoStream;
+
+ // Read description texts
+ if (bgHeader._descSize) {
+ infoStream = Resources::decompressLZ(*rrmStream, bgHeader._descSize);
+
+ _descText.resize(bgHeader._descSize);
+ infoStream->read(&_descText[0], bgHeader._descSize);
+
+ delete infoStream;
+ }
+
+ // Read sequences
+ if (bgHeader._seqSize) {
+ infoStream = Resources::decompressLZ(*rrmStream, bgHeader._seqSize);
+
+ _sequenceBuffer.resize(bgHeader._seqSize);
+ infoStream->read(&_sequenceBuffer[0], bgHeader._seqSize);
+
+ delete infoStream;
+ }
+ }
+
+ // Set up the list of images used by the scene
+ _images.resize(bgHeader._numImages + 1);
+ for (int idx = 0; idx < bgHeader._numImages; ++idx) {
+ _images[idx + 1]._filesize = bgInfo[idx]._filesize;
+ _images[idx + 1]._maxFrames = bgInfo[idx]._maxFrames;
+
+ // Read in the image data
+ Common::SeekableReadStream *imageStream = _compressed ?
+ res.decompress(*rrmStream, bgInfo[idx]._filesize) :
+ rrmStream->readStream(bgInfo[idx]._filesize);
+
+ _images[idx + 1]._images = new ImageFile(*imageStream);
+
+ delete imageStream;
+ }
+
+ // Set up the bgShapes
+ for (int idx = 0; idx < bgHeader._numStructs; ++idx) {
+ _bgShapes[idx]._images = _images[_bgShapes[idx]._misc]._images;
+ _bgShapes[idx]._imageFrame = !_bgShapes[idx]._images ? (ImageFrame *)nullptr :
+ &(*_bgShapes[idx]._images)[0];
+
+ _bgShapes[idx]._examine = Common::String(&_descText[_bgShapes[idx]._descOffset]);
+ _bgShapes[idx]._sequences = &_sequenceBuffer[_bgShapes[idx]._sequenceOffset];
+ _bgShapes[idx]._misc = 0;
+ _bgShapes[idx]._seqCounter = 0;
+ _bgShapes[idx]._seqCounter2 = 0;
+ _bgShapes[idx]._seqStack = 0;
+ _bgShapes[idx]._frameNumber = -1;
+ _bgShapes[idx]._oldPosition = Common::Point(0, 0);
+ _bgShapes[idx]._oldSize = Common::Point(1, 1);
+ }
+
+ // Load in cAnim list
+ _cAnim.clear();
+ if (bgHeader._numcAnimations) {
+ int animSize = IS_SERRATED_SCALPEL ? 65 : 47;
+ Common::SeekableReadStream *cAnimStream = _compressed ?
+ res.decompress(*rrmStream, animSize * bgHeader._numcAnimations) :
+ rrmStream->readStream(animSize * bgHeader._numcAnimations);
+
+ // Load cAnim offset table as well
+ uint32 *cAnimOffsetTablePtr = new uint32[bgHeader._numcAnimations];
+ uint32 *cAnimOffsetPtr = cAnimOffsetTablePtr;
+ memset(cAnimOffsetTablePtr, 0, bgHeader._numcAnimations * sizeof(uint32));
+ if (IS_SERRATED_SCALPEL) {
+ // Save current stream offset
+ int32 curOffset = rrmStream->pos();
+ rrmStream->seek(44); // Seek to cAnim-Offset-Table
+ for (uint16 curCAnim = 0; curCAnim < bgHeader._numcAnimations; curCAnim++) {
+ *cAnimOffsetPtr = rrmStream->readUint32LE();
+ cAnimOffsetPtr++;
+ }
+ // Seek back to original stream offset
+ rrmStream->seek(curOffset);
+ }
+ // TODO: load offset table for Rose Tattoo as well
+
+ // Go to the start of the cAnimOffsetTable
+ cAnimOffsetPtr = cAnimOffsetTablePtr;
+
+ _cAnim.resize(bgHeader._numcAnimations);
+ for (uint idx = 0; idx < _cAnim.size(); ++idx) {
+ _cAnim[idx].load(*cAnimStream, IS_ROSE_TATTOO, *cAnimOffsetPtr);
+ cAnimOffsetPtr++;
+ }
+
+ delete cAnimStream;
+ delete[] cAnimOffsetTablePtr;
+ }
+
+
+
+ // Read in the room bounding areas
+ int size = rrmStream->readUint16LE();
+ Common::SeekableReadStream *boundsStream = !_compressed ? rrmStream :
+ res.decompress(*rrmStream, size);
+
+ _zones.resize(size / 10);
+ for (uint idx = 0; idx < _zones.size(); ++idx) {
+ _zones[idx].left = boundsStream->readSint16LE();
+ _zones[idx].top = boundsStream->readSint16LE();
+ _zones[idx].setWidth(boundsStream->readSint16LE() + 1);
+ _zones[idx].setHeight(boundsStream->readSint16LE() + 1);
+ boundsStream->skip(2); // Skip unused scene number field
+ }
+
+ if (_compressed)
+ delete boundsStream;
+
+ // Ensure we've reached the path version byte
+ if (rrmStream->readByte() != (IS_SERRATED_SCALPEL ? 254 : 251))
+ error("Invalid scene path data");
+
+ // Load the walk directory and walk data
+ assert(_zones.size() < MAX_ZONES);
+
+
+ for (uint idx1 = 0; idx1 < _zones.size(); ++idx1) {
+ Common::fill(&_walkDirectory[idx1][0], &_walkDirectory[idx1][MAX_ZONES], 0);
+ for (uint idx2 = 0; idx2 < _zones.size(); ++idx2)
+ _walkDirectory[idx1][idx2] = rrmStream->readSint16LE();
+ }
+
+ // Read in the walk data
+ size = rrmStream->readUint16LE();
+ Common::SeekableReadStream *walkStream = !_compressed ? rrmStream :
+ res.decompress(*rrmStream, size);
+
+ int startPos = walkStream->pos();
+ while ((walkStream->pos() - startPos) < size) {
+ _walkPoints.push_back(WalkArray());
+ _walkPoints[_walkPoints.size() - 1]._fileOffset = walkStream->pos() - startPos;
+ _walkPoints[_walkPoints.size() - 1].load(*walkStream, IS_ROSE_TATTOO);
+ }
+
+ if (_compressed)
+ delete walkStream;
+
+ // Translate the file offsets of the walk directory to indexes in the loaded walk data
+ for (uint idx1 = 0; idx1 < _zones.size(); ++idx1) {
+ for (uint idx2 = 0; idx2 < _zones.size(); ++idx2) {
+ int fileOffset = _walkDirectory[idx1][idx2];
+ if (fileOffset == -1)
+ continue;
+
+ uint dataIndex = 0;
+ while (dataIndex < _walkPoints.size() && _walkPoints[dataIndex]._fileOffset != fileOffset)
+ ++dataIndex;
+ assert(dataIndex < _walkPoints.size());
+ _walkDirectory[idx1][idx2] = dataIndex;
+ }
+ }
+
+ if (IS_ROSE_TATTOO) {
+ // Read in the entrance
+ _entrance.load(*rrmStream);
+
+ // Load scale zones
+ _scaleZones.resize(rrmStream->readByte());
+ for (uint idx = 0; idx < _scaleZones.size(); ++idx)
+ _scaleZones[idx].load(*rrmStream);
+ }
+
+ // Read in the exits
+ int numExits = rrmStream->readByte();
+ _exits.resize(numExits);
+
+ for (int idx = 0; idx < numExits; ++idx)
+ _exits[idx].load(*rrmStream, IS_ROSE_TATTOO);
+
+ if (IS_SERRATED_SCALPEL)
+ // Read in the entrance
+ _entrance.load(*rrmStream);
+
+ // Initialize sound list
+ int numSounds = rrmStream->readByte();
+ _sounds.resize(numSounds);
+
+ for (int idx = 0; idx < numSounds; ++idx)
+ _sounds[idx].load(*rrmStream);
+
+ loadSceneSounds();
+
+ if (IS_ROSE_TATTOO) {
+ // Load the object sound list
+ char buffer[27];
+
+ _objSoundList.resize(rrmStream->readUint16LE());
+ for (uint idx = 0; idx < _objSoundList.size(); ++idx) {
+ rrmStream->read(buffer, 27);
+ _objSoundList[idx] = Common::String(buffer);
+ }
+ } else {
+ // Read in palette
+ rrmStream->read(screen._cMap, PALETTE_SIZE);
+ screen.translatePalette(screen._cMap);
+ Common::copy(screen._cMap, screen._cMap + PALETTE_SIZE, screen._sMap);
+
+ // Read in the background
+ Common::SeekableReadStream *bgStream = !_compressed ? rrmStream :
+ res.decompress(*rrmStream, SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT);
+
+ bgStream->read(screen._backBuffer1.getPixels(), SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT);
+
+ if (_compressed)
+ delete bgStream;
+ }
+
+ // Backup the image and set the palette
+ screen._backBuffer2.blitFrom(screen._backBuffer1);
+ screen.setPalette(screen._cMap);
+
+ delete rrmStream;
+ }
+
+ } else {
+ // === 3DO version ===
+ _roomFilename = "rooms/" + filename + ".rrm";
+ flag = _vm->_res->exists(_roomFilename);
+ if (!flag)
+ error("loadScene: 3DO room data file not found");
+
+ Common::SeekableReadStream *roomStream = _vm->_res->load(_roomFilename);
+ uint32 roomStreamSize = roomStream->size();
+
+ // there should be at least all bytes of the header data
+ if (roomStreamSize < 128)
+ error("loadScene: 3DO room data file is too small");
+
+ // Read 3DO header
+ roomStream->skip(4); // UINT32: offset graphic data?
+ uint16 header3DO_numStructs = roomStream->readUint16BE();
+ uint16 header3DO_numImages = roomStream->readUint16BE();
+ uint16 header3DO_numAnimations = roomStream->readUint16BE();
+ roomStream->skip(6);
+
+ uint32 header3DO_bgInfo_offset = roomStream->readUint32BE() + 0x80;
+ uint32 header3DO_bgInfo_size = roomStream->readUint32BE();
+ uint32 header3DO_bgShapes_offset = roomStream->readUint32BE() + 0x80;
+ uint32 header3DO_bgShapes_size = roomStream->readUint32BE();
+ uint32 header3DO_descriptions_offset = roomStream->readUint32BE() + 0x80;
+ uint32 header3DO_descriptions_size = roomStream->readUint32BE();
+ uint32 header3DO_sequence_offset = roomStream->readUint32BE() + 0x80;
+ uint32 header3DO_sequence_size = roomStream->readUint32BE();
+ uint32 header3DO_cAnim_offset = roomStream->readUint32BE() + 0x80;
+ uint32 header3DO_cAnim_size = roomStream->readUint32BE();
+ uint32 header3DO_roomBounding_offset = roomStream->readUint32BE() + 0x80;
+ uint32 header3DO_roomBounding_size = roomStream->readUint32BE();
+ uint32 header3DO_walkDirectory_offset = roomStream->readUint32BE() + 0x80;
+ uint32 header3DO_walkDirectory_size = roomStream->readUint32BE();
+ uint32 header3DO_walkData_offset = roomStream->readUint32BE() + 0x80;
+ uint32 header3DO_walkData_size = roomStream->readUint32BE();
+ uint32 header3DO_exits_offset = roomStream->readUint32BE() + 0x80;
+ uint32 header3DO_exits_size = roomStream->readUint32BE();
+ uint32 header3DO_entranceData_offset = roomStream->readUint32BE() + 0x80;
+ uint32 header3DO_entranceData_size = roomStream->readUint32BE();
+ uint32 header3DO_soundList_offset = roomStream->readUint32BE() + 0x80;
+ uint32 header3DO_soundList_size = roomStream->readUint32BE();
+ //uint32 header3DO_unknown_offset = roomStream->readUint32BE() + 0x80;
+ //uint32 header3DO_unknown_size = roomStream->readUint32BE();
+ roomStream->skip(8); // Skip over unknown offset+size
+ uint32 header3DO_bgGraphicData_offset = roomStream->readUint32BE() + 0x80;
+ uint32 header3DO_bgGraphicData_size = roomStream->readUint32BE();
+
+ // Calculate amount of entries
+ int32 header3DO_soundList_count = header3DO_soundList_size / 9;
+
+ _invGraphicItems = header3DO_numImages + 1;
+
+ // Verify all offsets
+ if (header3DO_bgInfo_offset >= roomStreamSize)
+ error("loadScene: 3DO bgInfo offset points outside of room file");
+ if (header3DO_bgInfo_size > (roomStreamSize - header3DO_bgInfo_offset))
+ error("loadScene: 3DO bgInfo size goes beyond room file");
+ if (header3DO_bgShapes_offset >= roomStreamSize)
+ error("loadScene: 3DO bgShapes offset points outside of room file");
+ if (header3DO_bgShapes_size > (roomStreamSize - header3DO_bgShapes_offset))
+ error("loadScene: 3DO bgShapes size goes beyond room file");
+ if (header3DO_descriptions_offset >= roomStreamSize)
+ error("loadScene: 3DO descriptions offset points outside of room file");
+ if (header3DO_descriptions_size > (roomStreamSize - header3DO_descriptions_offset))
+ error("loadScene: 3DO descriptions size goes beyond room file");
+ if (header3DO_sequence_offset >= roomStreamSize)
+ error("loadScene: 3DO sequence offset points outside of room file");
+ if (header3DO_sequence_size > (roomStreamSize - header3DO_sequence_offset))
+ error("loadScene: 3DO sequence size goes beyond room file");
+ if (header3DO_cAnim_offset >= roomStreamSize)
+ error("loadScene: 3DO cAnim offset points outside of room file");
+ if (header3DO_cAnim_size > (roomStreamSize - header3DO_cAnim_offset))
+ error("loadScene: 3DO cAnim size goes beyond room file");
+ if (header3DO_roomBounding_offset >= roomStreamSize)
+ error("loadScene: 3DO roomBounding offset points outside of room file");
+ if (header3DO_roomBounding_size > (roomStreamSize - header3DO_roomBounding_offset))
+ error("loadScene: 3DO roomBounding size goes beyond room file");
+ if (header3DO_walkDirectory_offset >= roomStreamSize)
+ error("loadScene: 3DO walkDirectory offset points outside of room file");
+ if (header3DO_walkDirectory_size > (roomStreamSize - header3DO_walkDirectory_offset))
+ error("loadScene: 3DO walkDirectory size goes beyond room file");
+ if (header3DO_walkData_offset >= roomStreamSize)
+ error("loadScene: 3DO walkData offset points outside of room file");
+ if (header3DO_walkData_size > (roomStreamSize - header3DO_walkData_offset))
+ error("loadScene: 3DO walkData size goes beyond room file");
+ if (header3DO_exits_offset >= roomStreamSize)
+ error("loadScene: 3DO exits offset points outside of room file");
+ if (header3DO_exits_size > (roomStreamSize - header3DO_exits_offset))
+ error("loadScene: 3DO exits size goes beyond room file");
+ if (header3DO_entranceData_offset >= roomStreamSize)
+ error("loadScene: 3DO entranceData offset points outside of room file");
+ if (header3DO_entranceData_size > (roomStreamSize - header3DO_entranceData_offset))
+ error("loadScene: 3DO entranceData size goes beyond room file");
+ if (header3DO_soundList_offset >= roomStreamSize)
+ error("loadScene: 3DO soundList offset points outside of room file");
+ if (header3DO_soundList_size > (roomStreamSize - header3DO_soundList_offset))
+ error("loadScene: 3DO soundList size goes beyond room file");
+ if (header3DO_bgGraphicData_offset >= roomStreamSize)
+ error("loadScene: 3DO bgGraphicData offset points outside of room file");
+ if (header3DO_bgGraphicData_size > (roomStreamSize - header3DO_bgGraphicData_offset))
+ error("loadScene: 3DO bgGraphicData size goes beyond room file");
+
+ // === BGINFO === read in the shapes header info
+ Common::Array<BgFileHeaderInfo> bgInfo;
+
+ uint32 expected3DO_bgInfo_size = header3DO_numStructs * 16;
+ if (expected3DO_bgInfo_size != header3DO_bgInfo_size) // Security check
+ error("loadScene: 3DO bgInfo size mismatch");
+
+ roomStream->seek(header3DO_bgInfo_offset);
+ bgInfo.resize(header3DO_numStructs);
+ for (uint idx = 0; idx < bgInfo.size(); ++idx)
+ bgInfo[idx].load3DO(*roomStream);
+
+ // === BGSHAPES === read in the shapes info
+ uint32 expected3DO_bgShapes_size = header3DO_numStructs * 588;
+ if (expected3DO_bgShapes_size != header3DO_bgShapes_size) // Security check
+ error("loadScene: 3DO bgShapes size mismatch");
+
+ roomStream->seek(header3DO_bgShapes_offset);
+ _bgShapes.resize(header3DO_numStructs);
+ for (int idx = 0; idx < header3DO_numStructs; ++idx)
+ _bgShapes[idx].load3DO(*roomStream);
+
+ // === DESCRIPTION === read description text
+ if (header3DO_descriptions_size) {
+ roomStream->seek(header3DO_descriptions_offset);
+ _descText.resize(header3DO_descriptions_size);
+ roomStream->read(&_descText[0], header3DO_descriptions_size);
+ }
+
+ // === SEQUENCE === read sequence buffer
+ if (header3DO_sequence_size) {
+ roomStream->seek(header3DO_sequence_offset);
+ _sequenceBuffer.resize(header3DO_sequence_size);
+ roomStream->read(&_sequenceBuffer[0], header3DO_sequence_size);
+ }
+
+ // === IMAGES === set up the list of images used by the scene
+ roomStream->seek(header3DO_bgGraphicData_offset);
+ _images.resize(header3DO_numImages + 1);
+ for (int idx = 0; idx < header3DO_numImages; ++idx) {
+ _images[idx + 1]._filesize = bgInfo[idx]._filesize;
+ _images[idx + 1]._maxFrames = bgInfo[idx]._maxFrames;
+
+ // Read image data into memory
+ Common::SeekableReadStream *imageStream = roomStream->readStream(bgInfo[idx]._filesize);
+
+ // Load image data into an ImageFile array as room file data
+ // which is basically a fixed header, followed by a raw cel header, followed by regular cel data
+ _images[idx + 1]._images = new ImageFile3DO(*imageStream, true);
+
+ delete imageStream;
+ }
+
+ // === BGSHAPES === Set up the bgShapes
+ for (int idx = 0; idx < header3DO_numStructs; ++idx) {
+ _bgShapes[idx]._images = _images[_bgShapes[idx]._misc]._images;
+ _bgShapes[idx]._imageFrame = !_bgShapes[idx]._images ? (ImageFrame *)nullptr :
+ &(*_bgShapes[idx]._images)[0];
+
+ _bgShapes[idx]._examine = Common::String(&_descText[_bgShapes[idx]._descOffset]);
+ _bgShapes[idx]._sequences = &_sequenceBuffer[_bgShapes[idx]._sequenceOffset];
+ _bgShapes[idx]._misc = 0;
+ _bgShapes[idx]._seqCounter = 0;
+ _bgShapes[idx]._seqCounter2 = 0;
+ _bgShapes[idx]._seqStack = 0;
+ _bgShapes[idx]._frameNumber = -1;
+ _bgShapes[idx]._oldPosition = Common::Point(0, 0);
+ _bgShapes[idx]._oldSize = Common::Point(1, 1);
+ }
+
+ // === CANIM === read cAnim list
+ _cAnim.clear();
+ if (header3DO_numAnimations) {
+ roomStream->seek(header3DO_cAnim_offset);
+ Common::SeekableReadStream *cAnimStream = roomStream->readStream(header3DO_cAnim_size);
+
+ uint32 *cAnimOffsetTablePtr = new uint32[header3DO_numAnimations];
+ uint32 *cAnimOffsetPtr = cAnimOffsetTablePtr;
+ uint32 cAnimOffset = 0;
+ memset(cAnimOffsetTablePtr, 0, header3DO_numAnimations * sizeof(uint32));
+
+ // Seek to end of graphics data and load cAnim offset table from there
+ roomStream->seek(header3DO_bgGraphicData_offset + header3DO_bgGraphicData_size);
+ for (uint16 curCAnim = 0; curCAnim < header3DO_numAnimations; curCAnim++) {
+ cAnimOffset = roomStream->readUint32BE();
+ if (cAnimOffset >= roomStreamSize)
+ error("loadScene: 3DO cAnim entry offset points outside of room file");
+
+ *cAnimOffsetPtr = cAnimOffset;
+ cAnimOffsetPtr++;
+ }
+
+ // Go to the start of the cAnimOffsetTable
+ cAnimOffsetPtr = cAnimOffsetTablePtr;
+
+ _cAnim.resize(header3DO_numAnimations);
+ for (uint idx = 0; idx < _cAnim.size(); ++idx) {
+ _cAnim[idx].load3DO(*cAnimStream, *cAnimOffsetPtr);
+ cAnimOffsetPtr++;
+ }
+
+ delete cAnimStream;
+ delete[] cAnimOffsetTablePtr;
+ }
+
+ // === BOUNDING AREAS === Read in the room bounding areas
+ int roomBoundingCount = header3DO_roomBounding_size / 12;
+ uint32 expected3DO_roomBounding_size = roomBoundingCount * 12;
+ if (expected3DO_roomBounding_size != header3DO_roomBounding_size)
+ error("loadScene: 3DO roomBounding size mismatch");
+
+ roomStream->seek(header3DO_roomBounding_offset);
+ _zones.resize(roomBoundingCount);
+ for (uint idx = 0; idx < _zones.size(); ++idx) {
+ _zones[idx].left = roomStream->readSint16BE();
+ _zones[idx].top = roomStream->readSint16BE();
+ _zones[idx].setWidth(roomStream->readSint16BE() + 1);
+ _zones[idx].setHeight(roomStream->readSint16BE() + 1);
+ roomStream->skip(4); // skip UINT32
+ }
+
+ // === WALK DIRECTORY === Load the walk directory
+ uint32 expected3DO_walkDirectory_size = _zones.size() * _zones.size() * 2;
+ if (expected3DO_walkDirectory_size != header3DO_walkDirectory_size)
+ error("loadScene: 3DO walkDirectory size mismatch");
+
+ roomStream->seek(header3DO_walkDirectory_offset);
+ assert(_zones.size() < MAX_ZONES);
+ for (uint idx1 = 0; idx1 < _zones.size(); ++idx1) {
+ for (uint idx2 = 0; idx2 < _zones.size(); ++idx2)
+ _walkDirectory[idx1][idx2] = roomStream->readSint16BE();
+ }
+
+ // === WALK DATA === Read in the walk data
+ roomStream->seek(header3DO_walkData_offset);
+
+ int startPos = roomStream->pos();
+ while ((roomStream->pos() - startPos) < (int)header3DO_walkData_size) {
+ _walkPoints.push_back(WalkArray());
+ _walkPoints[_walkPoints.size() - 1]._fileOffset = roomStream->pos() - startPos;
+ _walkPoints[_walkPoints.size() - 1].load(*roomStream, false);
+ }
+
+ // Translate the file offsets of the walk directory to indexes in the loaded walk data
+ for (uint idx1 = 0; idx1 < _zones.size(); ++idx1) {
+ for (uint idx2 = 0; idx2 < _zones.size(); ++idx2) {
+ int fileOffset = _walkDirectory[idx1][idx2];
+ if (fileOffset == -1)
+ continue;
+
+ uint dataIndex = 0;
+ while (dataIndex < _walkPoints.size() && _walkPoints[dataIndex]._fileOffset != fileOffset)
+ ++dataIndex;
+ assert(dataIndex < _walkPoints.size());
+ _walkDirectory[idx1][idx2] = dataIndex;
+ }
+ }
+
+ // === EXITS === Read in the exits
+ roomStream->seek(header3DO_exits_offset);
+
+ int exitsCount = header3DO_exits_size / 20;
+
+ _exits.resize(exitsCount);
+ for (int idx = 0; idx < exitsCount; ++idx)
+ _exits[idx].load3DO(*roomStream);
+
+ // === ENTRANCE === Read in the entrance
+ if (header3DO_entranceData_size != 8)
+ error("loadScene: 3DO entranceData size mismatch");
+
+ roomStream->seek(header3DO_entranceData_offset);
+ _entrance.load3DO(*roomStream);
+
+ // === SOUND LIST === Initialize sound list
+ roomStream->seek(header3DO_soundList_offset);
+ _sounds.resize(header3DO_soundList_count);
+ for (int idx = 0; idx < header3DO_soundList_count; ++idx)
+ _sounds[idx].load3DO(*roomStream);
+
+ delete roomStream;
+
+ // === BACKGROUND PICTURE ===
+ // load from file rooms\[filename].bg
+ // it's uncompressed 15-bit RGB555 data
+
+ Common::String roomBackgroundFilename = "rooms/" + filename + ".bg";
+ flag = _vm->_res->exists(roomBackgroundFilename);
+ if (!flag)
+ error("loadScene: 3DO room background file not found (%s)", roomBackgroundFilename.c_str());
+
+ Common::File roomBackgroundStream;
+ if (!roomBackgroundStream.open(roomBackgroundFilename))
+ error("Could not open file - %s", roomBackgroundFilename.c_str());
+
+ int totalPixelCount = SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT;
+ uint16 *roomBackgroundDataPtr = NULL;
+ uint16 *pixelSourcePtr = NULL;
+ uint16 *pixelDestPtr = (uint16 *)screen._backBuffer1.getPixels();
+ uint16 curPixel = 0;
+ uint32 roomBackgroundStreamSize = roomBackgroundStream.size();
+ uint32 expectedBackgroundSize = totalPixelCount * 2;
+
+ // Verify file size of background file
+ if (expectedBackgroundSize != roomBackgroundStreamSize)
+ error("loadScene: 3DO room background file not expected size");
+
+ roomBackgroundDataPtr = new uint16[totalPixelCount];
+ roomBackgroundStream.read(roomBackgroundDataPtr, roomBackgroundStreamSize);
+ roomBackgroundStream.close();
+
+ // Convert data from RGB555 to RGB565
+ pixelSourcePtr = roomBackgroundDataPtr;
+ for (int pixels = 0; pixels < totalPixelCount; pixels++) {
+ curPixel = READ_BE_UINT16(pixelSourcePtr++);
+
+ byte curPixelRed = (curPixel >> 10) & 0x1F;
+ byte curPixelGreen = (curPixel >> 5) & 0x1F;
+ byte curPixelBlue = curPixel & 0x1F;
+ *pixelDestPtr = ((curPixelRed << 11) | (curPixelGreen << 6) | (curPixelBlue));
+ pixelDestPtr++;
+ }
+
+ delete[] roomBackgroundDataPtr;
+
+#if 0
+ // code to show the background
+ screen.blitFrom(screen._backBuffer1);
+ _vm->_events->wait(10000);
+#endif
+
+ // Backup the image
+ screen._backBuffer2.blitFrom(screen._backBuffer1);
+ }
+
+ // Handle drawing any on-screen interface
+ ui.drawInterface();
+
+ checkSceneStatus();
+
+ if (!saves._justLoaded) {
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ if (_bgShapes[idx]._type == HIDDEN && _bgShapes[idx]._aType == TALK_EVERY)
+ _bgShapes[idx].toggleHidden();
+ }
+
+ // Check for TURNON objects
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ if (_bgShapes[idx]._type == HIDDEN && (_bgShapes[idx]._flags & TURNON_OBJ))
+ _bgShapes[idx].toggleHidden();
+ }
+
+ // Check for TURNOFF objects
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ if (_bgShapes[idx]._type != HIDDEN && (_bgShapes[idx]._flags & TURNOFF_OBJ) &&
+ _bgShapes[idx]._type != INVALID)
+ _bgShapes[idx].toggleHidden();
+ if (_bgShapes[idx]._type == HIDE_SHAPE)
+ // Hiding isn't needed, since objects aren't drawn yet
+ _bgShapes[idx]._type = HIDDEN;
+ }
+ }
+
+ checkSceneFlags(false);
+ checkInventory();
+
+ // Handle starting any music for the scene
+ if (IS_SERRATED_SCALPEL && music._musicOn && music.loadSong(_currentScene))
+ music.startSong();
+
+ // Load walking images if not already loaded
+ people.loadWalk();
+
+ // Transition to the scene and setup entrance co-ordinates and animations
+ transitionToScene();
+
+ // Player has not yet walked in this scene
+ _walkedInScene = false;
+ saves._justLoaded = false;
+
+ events.clearEvents();
+ return flag;
+}
+
+void Scene::loadSceneSounds() {
+ Sound &sound = *_vm->_sound;
+
+ for (uint idx = 0; idx < _sounds.size(); ++idx)
+ sound.loadSound(_sounds[idx]._name, _sounds[idx]._priority);
+}
+
+void Scene::checkSceneStatus() {
+ if (_sceneStats[_currentScene][64]) {
+ for (uint idx = 0; idx < 64; ++idx) {
+ bool flag = _sceneStats[_currentScene][idx];
+
+ if (idx < _bgShapes.size()) {
+ Object &obj = _bgShapes[idx];
+
+ if (flag) {
+ // No shape to erase, so flag as hidden
+ obj._type = HIDDEN;
+ } else if (obj._images == nullptr || obj._images->size() == 0) {
+ // No shape
+ obj._type = NO_SHAPE;
+ } else {
+ obj._type = ACTIVE_BG_SHAPE;
+ }
+ } else {
+ // Finished checks
+ return;
+ }
+ }
+ }
+}
+
+void Scene::saveSceneStatus() {
+ // Flag any objects for the scene that have been altered
+ int count = MIN((int)_bgShapes.size(), 64);
+ for (int idx = 0; idx < count; ++idx) {
+ Object &obj = _bgShapes[idx];
+ _sceneStats[_currentScene][idx] = obj._type == HIDDEN || obj._type == REMOVE
+ || obj._type == HIDE_SHAPE || obj._type == INVALID;
+ }
+
+ // Flag scene as having been visited
+ _sceneStats[_currentScene][64] = true;
+}
+
+void Scene::checkSceneFlags(bool flag) {
+ SpriteType mode = flag ? HIDE_SHAPE : HIDDEN;
+
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ Object &o = _bgShapes[idx];
+ bool objectFlag = true;
+
+ if (o._requiredFlag[0] || o._requiredFlag[1]) {
+ if (o._requiredFlag[0] != 0)
+ objectFlag = _vm->readFlags(o._requiredFlag[0]);
+ if (o._requiredFlag[1] != 0)
+ objectFlag &= _vm->readFlags(o._requiredFlag[1]);
+
+ if (!objectFlag) {
+ // Kill object
+ if (o._type != HIDDEN && o._type != INVALID) {
+ if (o._images == nullptr || o._images->size() == 0)
+ // No shape to erase, so flag as hidden
+ o._type = HIDDEN;
+ else
+ // Flag it as needing to be hidden after first erasing it
+ o._type = mode;
+ }
+ } else if (IS_ROSE_TATTOO || o._requiredFlag[0] > 0) {
+ // Restore object
+ if (o._images == nullptr || o._images->size() == 0)
+ o._type = NO_SHAPE;
+ else
+ o._type = ACTIVE_BG_SHAPE;
+ }
+ }
+ }
+
+ // Check inventory for items to remove based on flag changes
+ for (int idx = 0; idx < _vm->_inventory->_holdings; ++idx) {
+ InventoryItem &ii = (*_vm->_inventory)[idx];
+ if (ii._requiredFlag && !_vm->readFlags(ii._requiredFlag)) {
+ // Kill object: move it after the active holdings
+ InventoryItem tempItem = (*_vm->_inventory)[idx];
+ _vm->_inventory->insert_at(_vm->_inventory->_holdings, tempItem);
+ _vm->_inventory->remove_at(idx);
+ _vm->_inventory->_holdings--;
+ }
+ }
+
+ // Check inactive inventory items for ones to reactivate based on flag changes
+ for (uint idx = _vm->_inventory->_holdings; idx < _vm->_inventory->size(); ++idx) {
+ InventoryItem &ii = (*_vm->_inventory)[idx];
+ if (ii._requiredFlag && _vm->readFlags(ii._requiredFlag)) {
+ // Restore object: move it after the active holdings
+ InventoryItem tempItem = (*_vm->_inventory)[idx];
+ _vm->_inventory->remove_at(idx);
+ _vm->_inventory->insert_at(_vm->_inventory->_holdings, tempItem);
+ _vm->_inventory->_holdings++;
+ }
+ }
+}
+
+void Scene::checkInventory() {
+ for (uint shapeIdx = 0; shapeIdx < _bgShapes.size(); ++shapeIdx) {
+ for (int invIdx = 0; invIdx < _vm->_inventory->_holdings; ++invIdx) {
+ if (_bgShapes[shapeIdx]._name.equalsIgnoreCase((*_vm->_inventory)[invIdx]._name)) {
+ _bgShapes[shapeIdx]._type = INVALID;
+ break;
+ }
+ }
+ }
+}
+
+void Scene::transitionToScene() {
+ People &people = *_vm->_people;
+ SaveManager &saves = *_vm->_saves;
+ Screen &screen = *_vm->_screen;
+ Talk &talk = *_vm->_talk;
+ Point32 &hSavedPos = people._savedPos;
+ int &hSavedFacing = people._savedPos._facing;
+
+ if (hSavedPos.x < 1) {
+ // No exit information from last scene-check entrance info
+ if (_entrance._startPosition.x < 1) {
+ // No entrance info either, so use defaults
+ if (IS_SERRATED_SCALPEL) {
+ hSavedPos = Point32(160 * FIXED_INT_MULTIPLIER, 100 * FIXED_INT_MULTIPLIER);
+ hSavedFacing = 4;
+ } else {
+ hSavedPos = people[HOLMES]._position;
+ hSavedFacing = people[HOLMES]._sequenceNumber;
+ }
+ } else {
+ // setup entrance info
+ hSavedPos.x = _entrance._startPosition.x * FIXED_INT_MULTIPLIER;
+ hSavedPos.y = _entrance._startPosition.y * FIXED_INT_MULTIPLIER;
+ if (IS_SERRATED_SCALPEL) {
+ hSavedPos.x /= 100;
+ hSavedPos.y /= 100;
+ }
+
+ hSavedFacing = _entrance._startDir;
+ }
+ } else {
+ // Exit information exists, translate it to real sequence info
+ // Note: If a savegame was just loaded, then the data is already correct.
+ // Otherwise, this is a linked scene or entrance info, and must be translated
+ if (hSavedFacing < 8 && !saves._justLoaded) {
+ hSavedFacing = FS_TRANS[hSavedFacing];
+ hSavedPos.x *= FIXED_INT_MULTIPLIER;
+ hSavedPos.y *= FIXED_INT_MULTIPLIER;
+ }
+ }
+
+ int cAnimNum = -1;
+
+ if (hSavedFacing < 101) {
+ // Standard info, so set it
+ people[HOLMES]._position = hSavedPos;
+ people[HOLMES]._sequenceNumber = hSavedFacing;
+
+ if (saves._justLoaded && IS_ROSE_TATTOO) {
+ Tattoo::TattooUserInterface &ui = *(Tattoo::TattooUserInterface *)_vm->_ui;
+
+ // For scrolling scenes, make sure the player is on-screen
+ ui._targetScroll.x = CLIP(people[HOLMES]._position.x / FIXED_INT_MULTIPLIER -
+ SHERLOCK_SCREEN_WIDTH / 8 - 250, 0, screen._backBuffer1.w() - SHERLOCK_SCREEN_WIDTH);
+ screen._currentScroll = ui._targetScroll;
+ }
+ } else {
+ // It's canimation information
+ cAnimNum = hSavedFacing - 101;
+ }
+
+ // Reset positioning for next load
+ hSavedPos = Common::Point(-1, -1);
+ hSavedFacing = -1;
+
+ if (cAnimNum != -1) {
+ // Prevent Holmes from being drawn
+ people[HOLMES]._position = Common::Point(0, 0);
+ }
+
+ for (uint objIdx = 0; objIdx < _bgShapes.size(); ++objIdx) {
+ Object &obj = _bgShapes[objIdx];
+
+ if (obj._aType > 1 && obj._type != INVALID && obj._type != HIDDEN) {
+ Common::Point topLeft = obj._position;
+ Common::Point bottomRight;
+
+ if (obj._type != NO_SHAPE) {
+ topLeft += obj._imageFrame->_offset;
+ bottomRight.x = topLeft.x + obj._imageFrame->_frame.w;
+ bottomRight.y = topLeft.y + obj._imageFrame->_frame.h;
+ } else {
+ bottomRight = topLeft + obj._noShapeSize;
+ }
+
+ if (Common::Rect(topLeft.x, topLeft.y, bottomRight.x, bottomRight.y).contains(
+ Common::Point(people[HOLMES]._position.x / FIXED_INT_MULTIPLIER,
+ people[HOLMES]._position.y / FIXED_INT_MULTIPLIER))) {
+ // Current point is already inside box - impact occurred on
+ // a previous call. So simply do nothing except talk until the
+ // player is clear of the box
+ switch (obj._aType) {
+ case FLAG_SET:
+ for (int useNum = 0; useNum < USE_COUNT; ++useNum) {
+ if (obj._use[useNum]._useFlag) {
+ if (!_vm->readFlags(obj._use[useNum]._useFlag))
+ _vm->setFlags(obj._use[useNum]._useFlag);
+ }
+
+ if (!talk._talkToAbort) {
+ for (int nameIdx = 0; nameIdx < NAMES_COUNT; ++nameIdx) {
+ toggleObject(obj._use[useNum]._names[nameIdx]);
+ }
+ }
+ }
+
+ obj._type = HIDDEN;
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ updateBackground();
+
+ // Actually do the transition
+ if (screen._fadeStyle) {
+ if (!IS_3DO) {
+ // do pixel-transition for PC
+ screen.randomTransition();
+ } else {
+ // fade in for 3DO
+ screen.clear();
+ screen.fadeIntoScreen3DO(3);
+ }
+ } else {
+ screen.slamArea(screen._currentScroll.x, screen._currentScroll.y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+ }
+ screen.update();
+
+ // Start any initial animation for the scene
+ if (cAnimNum != -1) {
+ CAnim &c = _cAnim[cAnimNum];
+ PositionFacing pt = c._goto[0];
+
+ c._goto[0].x = c._goto[0].y = -1;
+ people[HOLMES]._position = Common::Point(0, 0);
+
+ startCAnim(cAnimNum, 1);
+ c._goto[0] = pt;
+ }
+}
+
+int Scene::toggleObject(const Common::String &name) {
+ int count = 0;
+
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ if (name.equalsIgnoreCase(_bgShapes[idx]._name)) {
+ ++count;
+ _bgShapes[idx].toggleHidden();
+ }
+ }
+
+ return count;
+}
+
+void Scene::updateBackground() {
+ People &people = *_vm->_people;
+
+ // Update Holmes if he's turned on
+ for (int idx = 0; idx < MAX_CHARACTERS; ++idx) {
+ if (people[idx]._type == CHARACTER)
+ people[idx].adjustSprite();
+ }
+
+ // Flag the bg shapes which need to be redrawn
+ checkBgShapes();
+
+ // Draw the shapes for the scene
+ drawAllShapes();
+}
+
+Exit *Scene::checkForExit(const Common::Rect &r) {
+ for (uint idx = 0; idx < _exits.size(); ++idx) {
+ if (_exits[idx].intersects(r))
+ return &_exits[idx];
+ }
+
+ return nullptr;
+}
+
+int Scene::findBgShape(const Common::Point &pt) {
+ if (!_doBgAnimDone)
+ // New frame hasn't been drawn yet
+ return -1;
+
+ for (int idx = (int)_bgShapes.size() - 1; idx >= 0; --idx) {
+ Object &o = _bgShapes[idx];
+ if (o._type != INVALID && o._type != NO_SHAPE && o._type != HIDDEN
+ && o._aType <= PERSON) {
+ if (o.getNewBounds().contains(pt))
+ return idx;
+ } else if (o._type == NO_SHAPE) {
+ if (o.getNoShapeBounds().contains(pt))
+ return idx;
+ }
+ }
+
+ return -1;
+}
+
+int Scene::checkForZones(const Common::Point &pt, int zoneType) {
+ int matches = 0;
+
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ Object &o = _bgShapes[idx];
+ if ((o._aType == zoneType && o._type != INVALID) && o._type != HIDDEN) {
+ Common::Rect r = o._type == NO_SHAPE ? o.getNoShapeBounds() : o.getNewBounds();
+
+ if (r.contains(pt)) {
+ ++matches;
+ o.setFlagsAndToggles();
+ _vm->_talk->talkTo(o._use[0]._target);
+ }
+ }
+ }
+
+ return matches;
+}
+
+int Scene::whichZone(const Common::Point &pt) {
+ for (uint idx = 0; idx < _zones.size(); ++idx) {
+ if (_zones[idx].contains(pt))
+ return idx;
+ }
+
+ return -1;
+}
+
+void Scene::synchronize(Serializer &s) {
+ if (s.isSaving())
+ saveSceneStatus();
+
+ if (s.isSaving()) {
+ s.syncAsSint16LE(_currentScene);
+ } else {
+ s.syncAsSint16LE(_goToScene);
+ _loadingSavedGame = true;
+ }
+
+ for (int sceneNum = 0; sceneNum < SCENES_COUNT; ++sceneNum) {
+ for (int flag = 0; flag < 65; ++flag) {
+ s.syncAsByte(_sceneStats[sceneNum][flag]);
+ }
+ }
+}
+
+void Scene::checkBgShapes() {
+ People &people = *_vm->_people;
+ Person &holmes = people[HOLMES];
+ Common::Point pt(holmes._position.x / FIXED_INT_MULTIPLIER, holmes._position.y / FIXED_INT_MULTIPLIER);
+
+ // Iterate through the shapes
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ Object &obj = _bgShapes[idx];
+ if (obj._type == ACTIVE_BG_SHAPE || (IS_SERRATED_SCALPEL && obj._type == STATIC_BG_SHAPE)) {
+ if ((obj._flags & 5) == 1) {
+ obj._misc = (pt.y < (obj._position.y + obj.frameHeight() - 1)) ?
+ NORMAL_FORWARD : NORMAL_BEHIND;
+ } else if (!(obj._flags & OBJ_BEHIND)) {
+ obj._misc = BEHIND;
+ } else if (obj._flags & OBJ_FORWARD) {
+ obj._misc = FORWARD;
+ }
+ }
+ }
+}
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h
new file mode 100644
index 0000000000..0fbda38fe8
--- /dev/null
+++ b/engines/sherlock/scene.h
@@ -0,0 +1,323 @@
+/* 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 SHERLOCK_SCENE_H
+#define SHERLOCK_SCENE_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/rect.h"
+#include "common/serializer.h"
+#include "sherlock/objects.h"
+#include "sherlock/resources.h"
+#include "sherlock/screen.h"
+
+namespace Sherlock {
+
+#define MAX_ZONES 40
+#define INFO_LINE 140
+
+class SherlockEngine;
+
+struct BgFileHeader {
+ int _numStructs;
+ int _numImages;
+ int _numcAnimations;
+ int _descSize;
+ int _seqSize;
+
+ // Serrated Scalpel
+ int _fill;
+
+ // Rose Tattoo
+ int _scrollSize;
+ int _bytesWritten; // Size of the main body of the RRM
+ int _fadeStyle; // Fade style
+ byte _palette[PALETTE_SIZE]; // Palette
+
+
+ BgFileHeader();
+
+ /**
+ * Load the data for the object
+ */
+ void load(Common::SeekableReadStream &s, bool isRoseTattoo);
+};
+
+struct BgFileHeaderInfo {
+ int _filesize; // How long images are
+ int _maxFrames; // How many unique frames in object
+ Common::String _filename; // Filename of object
+
+ /**
+ * Load the data for the object
+ */
+ void load(Common::SeekableReadStream &s);
+ void load3DO(Common::SeekableReadStream &s);
+};
+
+class Exit: public Common::Rect {
+public:
+ int _scene;
+ int _allow;
+ PositionFacing _newPosition;
+
+ Common::String _dest;
+ int _image; // Arrow image to use
+
+ /**
+ * Load the data for the object
+ */
+ void load(Common::SeekableReadStream &s, bool isRoseTattoo);
+ void load3DO(Common::SeekableReadStream &s);
+};
+
+struct SceneEntry {
+ Common::Point _startPosition;
+ int _startDir;
+ int _allow;
+
+ /**
+ * Load the data for the object
+ */
+ void load(Common::SeekableReadStream &s);
+ void load3DO(Common::SeekableReadStream &s);
+};
+
+struct SceneSound {
+ Common::String _name;
+ int _priority;
+
+ /**
+ * Load the data for the object
+ */
+ void load(Common::SeekableReadStream &s);
+ void load3DO(Common::SeekableReadStream &s);
+};
+
+class ObjectArray : public Common::Array<Object> {
+public:
+ /**
+ * Retuurn the index of the passed object in the array
+ */
+ int indexOf(const Object &obj) const;
+};
+
+class ScaleZone: public Common::Rect {
+public:
+ int _topNumber; // Numerator of scale size at the top of the zone
+ int _bottomNumber; // Numerator of scale size at the bottom of the zone
+
+ void load(Common::SeekableReadStream &s);
+};
+
+class WalkArray : public Common::Array < Common::Point > {
+public:
+ int _pointsCount;
+ int _fileOffset;
+
+ WalkArray() : _pointsCount(0), _fileOffset(-1) {}
+
+ /**
+ * Load data for the walk array entry
+ */
+ void load(Common::SeekableReadStream &s, bool isRoseTattoo);
+};
+
+class Scene {
+private:
+ bool _loadingSavedGame;
+
+ /**
+ * Loads sounds for the scene
+ */
+ void loadSceneSounds();
+
+ /**
+ * Set objects to their current persistent state. This includes things such as
+ * opening or moving them
+ */
+ void checkSceneStatus();
+
+ /**
+ * Checks scene objects against the player's inventory items. If there are any
+ * matching names, it means the given item has already been picked up, and should
+ * be hidden in the scene.
+ */
+ void checkInventory();
+
+ /**
+ * Set up any entrance co-ordinates or entrance canimations, and then transition
+ * in the scene
+ */
+ void transitionToScene();
+
+ /**
+ * Restores objects to the correct status. This ensures that things like being opened or moved
+ * will remain the same on future visits to the scene
+ */
+ void saveSceneStatus();
+protected:
+ SherlockEngine *_vm;
+ Common::String _roomFilename;
+
+ /**
+ * Loads the data associated for a given scene. The room resource file's format is:
+ * BGHEADER: Holds an index for the rest of the file
+ * STRUCTS: The objects for the scene
+ * IMAGES: The graphic information for the structures
+ *
+ * The _misc field of the structures contains the number of the graphic image
+ * that it should point to after loading; _misc is then set to 0.
+ */
+ virtual bool loadScene(const Common::String &filename);
+
+ /**
+ * Checks all the background shapes. If a background shape is animating,
+ * it will flag it as needing to be drawn. If a non-animating shape is
+ * colliding with another shape, it will also flag it as needing drawing
+ */
+ virtual void checkBgShapes();
+
+ /**
+ * Draw all the shapes, people and NPCs in the correct order
+ */
+ virtual void drawAllShapes() = 0;
+
+ /**
+ * Called by loadScene when the palette is loaded for Rose Tattoo
+ */
+ virtual void paletteLoaded() {}
+
+ Scene(SherlockEngine *vm);
+public:
+ int _currentScene;
+ int _goToScene;
+ bool **_sceneStats;
+ bool _walkedInScene;
+ int _version;
+ bool _compressed;
+ int _invGraphicItems;
+ Common::String _comments;
+ Common::Array<char> _descText;
+ Common::Array<Common::Rect> _zones;
+ Common::Array<Object> _bgShapes;
+ Common::Array<CAnim> _cAnim;
+ Common::Array<byte> _sequenceBuffer;
+ Common::Array<SceneImage> _images;
+ int _walkDirectory[MAX_ZONES][MAX_ZONES];
+ Common::Array<WalkArray> _walkPoints;
+ Common::Array<Exit> _exits;
+ SceneEntry _entrance;
+ Common::Array<SceneSound> _sounds;
+ ObjectArray _canimShapes;
+ Common::Array<ScaleZone> _scaleZones;
+ Common::StringArray _objSoundList;
+ bool _restoreFlag;
+ int _animating;
+ bool _doBgAnimDone;
+ int _tempFadeStyle;
+ int _cAnimFramePause;
+public:
+ static Scene *init(SherlockEngine *vm);
+ virtual ~Scene();
+
+ /**
+ * Handles loading the scene specified by _goToScene
+ */
+ void selectScene();
+
+ /**
+ * Fres all the graphics and other dynamically allocated data for the scene
+ */
+ void freeScene();
+
+ /**
+ * Check the scene's objects against the game flags. If false is passed,
+ * it means the scene has just been loaded. A value of true means that the scene
+ * is in use (ie. not just loaded)
+ */
+ void checkSceneFlags(bool mode);
+
+ /**
+ * Check whether the passed area intersects with one of the scene's exits
+ */
+ Exit *checkForExit(const Common::Rect &r);
+
+ /**
+ * Scans through the object list to find one with a matching name, and will
+ * call toggleHidden with all matches found. Returns the numer of matches found
+ */
+ int toggleObject(const Common::String &name);
+
+ /**
+ * Checks to see if the given position in the scene belongs to a given zone type.
+ * If it is, the zone is activated and used just like a TAKL zone or aFLAG_SET zone.
+ */
+ int checkForZones(const Common::Point &pt, int zoneType);
+
+ /**
+ * Check which zone the the given position is located in.
+ */
+ int whichZone(const Common::Point &pt);
+
+ /**
+ * Returns the index of the closest zone to a given point.
+ */
+ virtual int closestZone(const Common::Point &pt) = 0;
+
+ /**
+ * Attempts to find a background shape within the passed bounds. If found,
+ * it will return the shape number, or -1 on failure.
+ */
+ virtual int findBgShape(const Common::Point &pt);
+
+ /**
+ * Synchronize the data for a savegame
+ */
+ virtual void synchronize(Serializer &s);
+public:
+ /**
+ * Draw all objects and characters.
+ */
+ virtual void doBgAnim() = 0;
+
+ /**
+ * Update the screen back buffer with all of the scene objects which need
+ * to be drawn
+ */
+ virtual void updateBackground();
+
+ /**
+ * Attempt to start a canimation sequence. It will load the requisite graphics, and
+ * then copy the canim object into the _canimShapes array to start the animation.
+ *
+ * @param cAnimNum The canim object within the current scene
+ * @param playRate Play rate. 0 is invalid; 1=normal speed, 2=1/2 speed, etc.
+ * A negative playRate can also be specified to play the animation in reverse
+ */
+ virtual int startCAnim(int cAnimNum, int playRate = 1) = 0;
+};
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp
new file mode 100644
index 0000000000..782869d77e
--- /dev/null
+++ b/engines/sherlock/screen.cpp
@@ -0,0 +1,553 @@
+/* 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 "sherlock/screen.h"
+#include "sherlock/sherlock.h"
+#include "sherlock/scalpel/scalpel_screen.h"
+#include "common/system.h"
+#include "common/util.h"
+#include "graphics/palette.h"
+
+namespace Sherlock {
+
+Screen *Screen::init(SherlockEngine *vm) {
+ if (vm->getGameID() == GType_SerratedScalpel)
+ return new Scalpel::ScalpelScreen(vm);
+ else
+ return new Screen(vm);
+}
+
+Screen::Screen(SherlockEngine *vm) : Surface(g_system->getWidth(), g_system->getHeight()), _vm(vm),
+ _backBuffer1(g_system->getWidth(), g_system->getHeight()),
+ _backBuffer2(g_system->getWidth(), g_system->getHeight()),
+ _backBuffer(&_backBuffer1) {
+ _transitionSeed = 1;
+ _fadeStyle = false;
+ Common::fill(&_cMap[0], &_cMap[PALETTE_SIZE], 0);
+ Common::fill(&_sMap[0], &_sMap[PALETTE_SIZE], 0);
+ Common::fill(&_tMap[0], &_tMap[PALETTE_SIZE], 0);
+
+ // Set up the initial font
+ setFont(IS_SERRATED_SCALPEL ? 1 : 4);
+
+ // Rose Tattoo specific fields
+ _fadeBytesRead = _fadeBytesToRead = 0;
+ _oldFadePercent = 0;
+ _flushScreen = false;
+}
+
+Screen::~Screen() {
+ Fonts::free();
+}
+
+void Screen::update() {
+ // Merge the dirty rects
+ mergeDirtyRects();
+
+ // Loop through copying dirty areas to the physical screen
+ Common::List<Common::Rect>::iterator i;
+ for (i = _dirtyRects.begin(); i != _dirtyRects.end(); ++i) {
+ const Common::Rect &r = *i;
+ const byte *srcP = (const byte *)getBasePtr(r.left, r.top);
+ g_system->copyRectToScreen(srcP, _surface.pitch, r.left, r.top,
+ r.width(), r.height());
+ }
+
+ // Signal the physical screen to update
+ g_system->updateScreen();
+ _dirtyRects.clear();
+}
+
+void Screen::makeAllDirty() {
+ addDirtyRect(Common::Rect(0, 0, this->w(), this->h()));
+}
+
+void Screen::getPalette(byte palette[PALETTE_SIZE]) {
+ g_system->getPaletteManager()->grabPalette(palette, 0, PALETTE_COUNT);
+}
+
+void Screen::setPalette(const byte palette[PALETTE_SIZE]) {
+ g_system->getPaletteManager()->setPalette(palette, 0, PALETTE_COUNT);
+}
+
+int Screen::equalizePalette(const byte palette[PALETTE_SIZE]) {
+ int total = 0;
+ byte tempPalette[PALETTE_SIZE];
+ getPalette(tempPalette);
+
+ // For any palette component that doesn't already match the given destination
+ // palette, change by 1 towards the reference palette component
+ for (int idx = 0; idx < PALETTE_SIZE; ++idx) {
+ if (tempPalette[idx] > palette[idx]) {
+ tempPalette[idx] = MAX((int)palette[idx], (int)tempPalette[idx] - 4);
+ ++total;
+ } else if (tempPalette[idx] < palette[idx]) {
+ tempPalette[idx] = MIN((int)palette[idx], (int)tempPalette[idx] + 4);
+ ++total;
+ }
+ }
+
+ if (total > 0)
+ // Palette changed, so reload it
+ setPalette(tempPalette);
+
+ return total;
+}
+
+void Screen::fadeToBlack(int speed) {
+ byte tempPalette[PALETTE_SIZE];
+ Common::fill(&tempPalette[0], &tempPalette[PALETTE_SIZE], 0);
+
+ while (equalizePalette(tempPalette)) {
+ _vm->_events->delay(15 * speed);
+ }
+
+ setPalette(tempPalette);
+ fillRect(Common::Rect(0, 0, _surface.w, _surface.h), 0);
+}
+
+void Screen::fadeIn(const byte palette[PALETTE_SIZE], int speed) {
+ int count = 50;
+ while (equalizePalette(palette) && --count) {
+ _vm->_events->delay(15 * speed);
+ }
+
+ setPalette(palette);
+}
+
+void Screen::addDirtyRect(const Common::Rect &r) {
+ _dirtyRects.push_back(r);
+ assert(r.width() > 0 && r.height() > 0);
+}
+
+void Screen::mergeDirtyRects() {
+ Common::List<Common::Rect>::iterator rOuter, rInner;
+
+ // Process the dirty rect list to find any rects to merge
+ for (rOuter = _dirtyRects.begin(); rOuter != _dirtyRects.end(); ++rOuter) {
+ rInner = rOuter;
+ while (++rInner != _dirtyRects.end()) {
+
+ if ((*rOuter).intersects(*rInner)) {
+ // these two rectangles overlap or
+ // are next to each other - merge them
+
+ unionRectangle(*rOuter, *rOuter, *rInner);
+
+ // remove the inner rect from the list
+ _dirtyRects.erase(rInner);
+
+ // move back to beginning of list
+ rInner = rOuter;
+ }
+ }
+ }
+}
+
+bool Screen::unionRectangle(Common::Rect &destRect, const Common::Rect &src1, const Common::Rect &src2) {
+ destRect = src1;
+ destRect.extend(src2);
+
+ return !destRect.isEmpty();
+}
+
+void Screen::randomTransition() {
+ Events &events = *_vm->_events;
+ const int TRANSITION_MULTIPLIER = 0x15a4e35;
+ _dirtyRects.clear();
+ assert(IS_SERRATED_SCALPEL);
+
+ for (int idx = 0; idx <= 65535 && !_vm->shouldQuit(); ++idx) {
+ _transitionSeed = _transitionSeed * TRANSITION_MULTIPLIER + 1;
+ int offset = _transitionSeed & 0xFFFF;
+
+ if (offset < (this->w() * this->h()))
+ *((byte *)getPixels() + offset) = *((const byte *)_backBuffer->getPixels() + offset);
+
+ if (idx != 0 && (idx % 300) == 0) {
+ // Ensure there's a full screen dirty rect for the next frame update
+ if (_dirtyRects.empty())
+ addDirtyRect(Common::Rect(0, 0, _surface.w, _surface.h));
+
+ events.pollEvents();
+ events.delay(1);
+ }
+ }
+
+ // Make sure everything has been transferred
+ blitFrom(*_backBuffer);
+}
+
+void Screen::verticalTransition() {
+ Events &events = *_vm->_events;
+
+ byte table[640];
+ Common::fill(&table[0], &table[640], 0);
+
+ for (int yp = 0; yp < this->h(); ++yp) {
+ for (int xp = 0; xp < this->w(); ++xp) {
+ int temp = (table[xp] >= (this->h() - 3)) ? this->h() - table[xp] :
+ _vm->getRandomNumber(3) + 1;
+
+ if (temp) {
+ blitFrom(_backBuffer1, Common::Point(xp, table[xp]),
+ Common::Rect(xp, table[xp], xp + 1, table[xp] + temp));
+ table[xp] += temp;
+ }
+ }
+
+ events.delay(10);
+ }
+}
+
+void Screen::fadeIntoScreen3DO(int speed) {
+ Events &events = *_vm->_events;
+ uint16 *currentScreenBasePtr = (uint16 *)getPixels();
+ uint16 *targetScreenBasePtr = (uint16 *)_backBuffer->getPixels();
+ uint16 currentScreenPixel = 0;
+ uint16 targetScreenPixel = 0;
+
+ uint16 currentScreenPixelRed = 0;
+ uint16 currentScreenPixelGreen = 0;
+ uint16 currentScreenPixelBlue = 0;
+
+ uint16 targetScreenPixelRed = 0;
+ uint16 targetScreenPixelGreen = 0;
+ uint16 targetScreenPixelBlue = 0;
+
+ uint16 screenWidth = this->w();
+ uint16 screenHeight = this->h();
+ uint16 screenX = 0;
+ uint16 screenY = 0;
+ uint16 pixelsChanged = 0;
+
+ _dirtyRects.clear();
+
+ do {
+ pixelsChanged = 0;
+ uint16 *currentScreenPtr = currentScreenBasePtr;
+ uint16 *targetScreenPtr = targetScreenBasePtr;
+
+ for (screenY = 0; screenY < screenHeight; screenY++) {
+ for (screenX = 0; screenX < screenWidth; screenX++) {
+ currentScreenPixel = *currentScreenPtr;
+ targetScreenPixel = *targetScreenPtr;
+
+ if (currentScreenPixel != targetScreenPixel) {
+ // pixel doesn't match, adjust accordingly
+ currentScreenPixelRed = currentScreenPixel & 0xF800;
+ currentScreenPixelGreen = currentScreenPixel & 0x07E0;
+ currentScreenPixelBlue = currentScreenPixel & 0x001F;
+ targetScreenPixelRed = targetScreenPixel & 0xF800;
+ targetScreenPixelGreen = targetScreenPixel & 0x07E0;
+ targetScreenPixelBlue = targetScreenPixel & 0x001F;
+
+ if (currentScreenPixelRed != targetScreenPixelRed) {
+ if (currentScreenPixelRed < targetScreenPixelRed) {
+ currentScreenPixelRed += 0x0800;
+ } else {
+ currentScreenPixelRed -= 0x0800;
+ }
+ }
+ if (currentScreenPixelGreen != targetScreenPixelGreen) {
+ // Adjust +2/-2 because we are running RGB555 at RGB565
+ if (currentScreenPixelGreen < targetScreenPixelGreen) {
+ currentScreenPixelGreen += 0x0040;
+ } else {
+ currentScreenPixelGreen -= 0x0040;
+ }
+ }
+ if (currentScreenPixelBlue != targetScreenPixelBlue) {
+ if (currentScreenPixelBlue < targetScreenPixelBlue) {
+ currentScreenPixelBlue += 0x0001;
+ } else {
+ currentScreenPixelBlue -= 0x0001;
+ }
+ }
+ *currentScreenPtr = currentScreenPixelRed | currentScreenPixelGreen | currentScreenPixelBlue;
+ pixelsChanged++;
+ }
+
+ currentScreenPtr++;
+ targetScreenPtr++;
+ }
+ }
+
+ // Too much considered dirty at the moment
+ addDirtyRect(Common::Rect(0, 0, screenWidth, screenHeight));
+
+ events.pollEvents();
+ events.delay(10 * speed);
+ } while ((pixelsChanged) && (!_vm->shouldQuit()));
+}
+
+void Screen::blitFrom3DOcolorLimit(uint16 limitColor) {
+ uint16 *currentScreenPtr = (uint16 *)getPixels();
+ uint16 *targetScreenPtr = (uint16 *)_backBuffer->getPixels();
+ uint16 currentScreenPixel = 0;
+
+ uint16 screenWidth = this->w();
+ uint16 screenHeight = this->h();
+ uint16 screenX = 0;
+ uint16 screenY = 0;
+
+ uint16 currentScreenPixelRed = 0;
+ uint16 currentScreenPixelGreen = 0;
+ uint16 currentScreenPixelBlue = 0;
+
+ uint16 limitPixelRed = limitColor & 0xF800;
+ uint16 limitPixelGreen = limitColor & 0x07E0;
+ uint16 limitPixelBlue = limitColor & 0x001F;
+
+ for (screenY = 0; screenY < screenHeight; screenY++) {
+ for (screenX = 0; screenX < screenWidth; screenX++) {
+ currentScreenPixel = *targetScreenPtr;
+
+ currentScreenPixelRed = currentScreenPixel & 0xF800;
+ currentScreenPixelGreen = currentScreenPixel & 0x07E0;
+ currentScreenPixelBlue = currentScreenPixel & 0x001F;
+
+ if (currentScreenPixelRed < limitPixelRed)
+ currentScreenPixelRed = limitPixelRed;
+ if (currentScreenPixelGreen < limitPixelGreen)
+ currentScreenPixelGreen = limitPixelGreen;
+ if (currentScreenPixelBlue < limitPixelBlue)
+ currentScreenPixelBlue = limitPixelBlue;
+
+ *currentScreenPtr = currentScreenPixelRed | currentScreenPixelGreen | currentScreenPixelBlue;
+ currentScreenPtr++;
+ targetScreenPtr++;
+ }
+ }
+
+ // Too much considered dirty at the moment
+ addDirtyRect(Common::Rect(0, 0, screenWidth, screenHeight));
+}
+
+void Screen::restoreBackground(const Common::Rect &r) {
+ if (r.width() > 0 && r.height() > 0)
+ _backBuffer1.blitFrom(_backBuffer2, Common::Point(r.left, r.top), r);
+}
+
+void Screen::slamArea(int16 xp, int16 yp, int16 width, int16 height) {
+ slamRect(Common::Rect(xp, yp, xp + width, yp + height));
+}
+
+void Screen::slamRect(const Common::Rect &r) {
+ if (r.width() && r.height() > 0) {
+ Common::Rect srcRect = r, destRect = r;
+
+ destRect.translate(-_currentScroll.x, -_currentScroll.y);
+
+ if (destRect.left < 0) {
+ srcRect.left += -destRect.left;
+ destRect.left = 0;
+ }
+ if (destRect.top < 0) {
+ srcRect.top += -destRect.top;
+ destRect.top = 0;
+ }
+ if (destRect.right > SHERLOCK_SCREEN_WIDTH) {
+ srcRect.right -= (destRect.left - SHERLOCK_SCREEN_WIDTH);
+ destRect.right = SHERLOCK_SCREEN_WIDTH;
+ }
+ if (destRect.bottom > SHERLOCK_SCREEN_HEIGHT) {
+ srcRect.bottom -= (destRect.bottom - SHERLOCK_SCREEN_HEIGHT);
+ destRect.bottom = SHERLOCK_SCREEN_HEIGHT;
+ }
+
+ if (srcRect.isValidRect())
+ blitFrom(*_backBuffer, Common::Point(destRect.left, destRect.top), srcRect);
+ }
+}
+
+
+void Screen::flushImage(ImageFrame *frame, const Common::Point &pt, int16 *xp, int16 *yp,
+ int16 *width, int16 *height) {
+ Common::Point imgPos = pt + frame->_offset;
+ Common::Rect newBounds(imgPos.x, imgPos.y, imgPos.x + frame->_frame.w, imgPos.y + frame->_frame.h);
+ Common::Rect oldBounds(*xp, *yp, *xp + *width, *yp + *height);
+
+ if (!_flushScreen) {
+ // See if the areas of the old and new overlap, and if so combine the areas
+ if (newBounds.intersects(oldBounds)) {
+ Common::Rect mergedBounds = newBounds;
+ mergedBounds.extend(oldBounds);
+ mergedBounds.right += 1;
+ mergedBounds.bottom += 1;
+
+ slamRect(mergedBounds);
+ } else {
+ // The two areas are independent, so copy them both
+ slamRect(newBounds);
+ slamRect(oldBounds);
+ }
+ }
+
+ *xp = newBounds.left;
+ *yp = newBounds.top;
+ *width = newBounds.width();
+ *height = newBounds.height();
+}
+
+void Screen::flushScaleImage(ImageFrame *frame, const Common::Point &pt, int16 *xp, int16 *yp,
+ int16 *width, int16 *height, int scaleVal) {
+ Common::Point imgPos = pt + frame->_offset;
+ Common::Rect newBounds(imgPos.x, imgPos.y, imgPos.x + frame->sDrawXSize(scaleVal),
+ imgPos.y + frame->sDrawYSize(scaleVal));
+ Common::Rect oldBounds(*xp, *yp, *xp + *width, *yp + *height);
+
+ if (!_flushScreen) {
+ // See if the areas of the old and new overlap, and if so combine the areas
+ if (newBounds.intersects(oldBounds)) {
+ Common::Rect mergedBounds = newBounds;
+ mergedBounds.extend(oldBounds);
+ mergedBounds.right += 1;
+ mergedBounds.bottom += 1;
+
+ slamRect(mergedBounds);
+ } else {
+ // The two areas are independent, so copy them both
+ slamRect(newBounds);
+ slamRect(oldBounds);
+ }
+ }
+
+ *xp = newBounds.left;
+ *yp = newBounds.top;
+ *width = newBounds.width();
+ *height = newBounds.height();
+}
+
+void Screen::flushImage(ImageFrame *frame, const Common::Point &pt, Common::Rect &newBounds, int scaleVal) {
+ Common::Point newPos, newSize;
+
+ if (scaleVal == 256)
+ flushImage(frame, pt, &newPos.x, &newPos.y, &newSize.x, &newSize.y);
+ else
+ flushScaleImage(frame, pt, &newPos.x, &newPos.y, &newSize.x, &newSize.y, scaleVal);
+
+ // Transfer the pos and size amounts into a single bounds rect
+ newBounds = Common::Rect(newPos.x, newPos.y, newPos.x + newSize.x, newPos.y + newSize.y);
+}
+
+void Screen::blockMove(const Common::Rect &r) {
+ Common::Rect bounds = r;
+ slamRect(bounds);
+}
+
+void Screen::blockMove() {
+ blockMove(Common::Rect(0, 0, w(), h()));
+}
+
+void Screen::print(const Common::Point &pt, byte color, const char *formatStr, ...) {
+ // Create the string to display
+ va_list args;
+ va_start(args, formatStr);
+ Common::String str = Common::String::vformat(formatStr, args);
+ va_end(args);
+
+ // Figure out area to draw text in
+ Common::Point pos = pt;
+ int width = stringWidth(str);
+ pos.y--; // Font is always drawing one line higher
+ if (!pos.x)
+ // Center text horizontally
+ pos.x = (this->w() - width) / 2;
+
+ Common::Rect textBounds(pos.x, pos.y, pos.x + width, pos.y + _fontHeight);
+ if (textBounds.right > this->w())
+ textBounds.moveTo(this->w() - width, textBounds.top);
+ if (textBounds.bottom > this->h())
+ textBounds.moveTo(textBounds.left, this->h() - _fontHeight);
+
+ // Write out the string at the given position
+ writeString(str, Common::Point(textBounds.left, textBounds.top), color);
+
+ // Copy the affected area to the screen
+ slamRect(textBounds);
+}
+
+void Screen::gPrint(const Common::Point &pt, byte color, const char *formatStr, ...) {
+ // Create the string to display
+ va_list args;
+ va_start(args, formatStr);
+ Common::String str = Common::String::vformat(formatStr, args);
+ va_end(args);
+
+ // Print the text
+ writeString(str, pt, color);
+}
+
+void Screen::writeString(const Common::String &str, const Common::Point &pt, byte overrideColor) {
+ Fonts::writeString(_backBuffer, str, pt, overrideColor);
+}
+
+void Screen::vgaBar(const Common::Rect &r, int color) {
+ _backBuffer->fillRect(r, color);
+ slamRect(r);
+}
+
+void Screen::setDisplayBounds(const Common::Rect &r) {
+ _sceneSurface.setPixels(_backBuffer1.getBasePtr(r.left, r.top), r.width(), r.height(), _backBuffer1.getPixelFormat());
+
+ _backBuffer = &_sceneSurface;
+}
+
+void Screen::resetDisplayBounds() {
+ _backBuffer = &_backBuffer1;
+}
+
+Common::Rect Screen::getDisplayBounds() {
+ return (_backBuffer == &_sceneSurface) ? Common::Rect(0, 0, _sceneSurface.w(), _sceneSurface.h()) :
+ Common::Rect(0, 0, this->w(), this->h());
+}
+
+void Screen::synchronize(Serializer &s) {
+ int fontNumb = _fontNumber;
+ s.syncAsByte(fontNumb);
+ if (s.isLoading())
+ setFont(fontNumb);
+}
+
+void Screen::initPaletteFade(int bytesToRead) {
+ Common::copy(&_cMap[0], &_cMap[PALETTE_SIZE], &_sMap[0]);
+ Common::copy(&_cMap[0], &_cMap[PALETTE_SIZE], &_tMap[0]);
+
+ // Set how many bytes need to be read / have been read
+ _fadeBytesRead = 0;
+ _fadeBytesToRead = bytesToRead;
+ _oldFadePercent = 0;
+}
+
+int Screen::fadeRead(Common::SeekableReadStream &stream, byte *buf, int totalSize) {
+ warning("TODO: fadeRead");
+ stream.read(buf, totalSize);
+ return totalSize;
+}
+
+void Screen::translatePalette(byte palette[PALETTE_SIZE]) {
+ for (int idx = 0; idx < PALETTE_SIZE; ++idx)
+ palette[idx] = VGA_COLOR_TRANS(palette[idx]);
+}
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h
new file mode 100644
index 0000000000..2e0cef72ca
--- /dev/null
+++ b/engines/sherlock/screen.h
@@ -0,0 +1,243 @@
+/* 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 SHERLOCK_SCREEN_H
+#define SHERLOCK_SCREEN_H
+
+#include "common/list.h"
+#include "common/rect.h"
+#include "sherlock/surface.h"
+#include "sherlock/resources.h"
+#include "sherlock/saveload.h"
+
+namespace Sherlock {
+
+#define PALETTE_SIZE 768
+#define PALETTE_COUNT 256
+#define VGA_COLOR_TRANS(x) ((x) * 255 / 63)
+#define BG_GREYSCALE_RANGE_END 229
+
+enum {
+ BLACK = 0,
+ INFO_BLACK = 1,
+ BORDER_COLOR = 237,
+ COMMAND_BACKGROUND = 4,
+ BUTTON_BACKGROUND = 235,
+ TALK_FOREGROUND = 12,
+ TALK_NULL = 16
+};
+
+class SherlockEngine;
+
+class Screen : public Surface {
+private:
+ SherlockEngine *_vm;
+ Common::List<Common::Rect> _dirtyRects;
+ uint32 _transitionSeed;
+ Surface _sceneSurface;
+
+ // Rose Tattoo fields
+ int _fadeBytesRead, _fadeBytesToRead;
+ int _oldFadePercent;
+private:
+ /**
+ * Merges together overlapping dirty areas of the screen
+ */
+ void mergeDirtyRects();
+
+ /**
+ * Returns the union of two dirty area rectangles
+ */
+ bool unionRectangle(Common::Rect &destRect, const Common::Rect &src1, const Common::Rect &src2);
+protected:
+ /**
+ * Adds a rectangle to the list of modified areas of the screen during the
+ * current frame
+ */
+ virtual void addDirtyRect(const Common::Rect &r);
+public:
+ Surface _backBuffer1, _backBuffer2;
+ Surface *_backBuffer;
+ bool _fadeStyle;
+ byte _cMap[PALETTE_SIZE];
+ byte _sMap[PALETTE_SIZE];
+ byte _tMap[PALETTE_SIZE];
+ bool _flushScreen;
+ Common::Point _currentScroll;
+public:
+ static Screen *init(SherlockEngine *vm);
+ Screen(SherlockEngine *vm);
+ virtual ~Screen();
+
+ /**
+ * Handles updating any dirty areas of the screen Surface object to the physical screen
+ */
+ void update();
+
+ /**
+ * Makes the whole screen dirty, Hack for 3DO movie playing
+ */
+ void makeAllDirty();
+
+ /**
+ * Return the currently active palette
+ */
+ void getPalette(byte palette[PALETTE_SIZE]);
+
+ /**
+ * Set the palette
+ */
+ void setPalette(const byte palette[PALETTE_SIZE]);
+
+ /**
+ * Fades from the currently active palette to the passed palette
+ */
+ int equalizePalette(const byte palette[PALETTE_SIZE]);
+
+ /**
+ * Fade out the palette to black
+ */
+ void fadeToBlack(int speed = 2);
+
+ /**
+ * Fade in a given palette
+ */
+ void fadeIn(const byte palette[PALETTE_SIZE], int speed = 2);
+
+ /**
+ * Do a random pixel transition in from _backBuffer surface to the screen
+ */
+ void randomTransition();
+
+ /**
+ * Transition to the surface from _backBuffer using a vertical transition
+ */
+ void verticalTransition();
+
+ /**
+ * Fade backbuffer 1 into screen (3DO RGB!)
+ */
+ void fadeIntoScreen3DO(int speed);
+
+ void blitFrom3DOcolorLimit(uint16 color);
+
+ /**
+ * Prints the text passed onto the back buffer at the given position and color.
+ * The string is then blitted to the screen
+ */
+ void print(const Common::Point &pt, byte color, const char *formatStr, ...) GCC_PRINTF(4, 5);
+
+ /**
+ * Print a strings onto the back buffer without blitting it to the screen
+ */
+ void gPrint(const Common::Point &pt, byte color, const char *formatStr, ...) GCC_PRINTF(4, 5);
+
+ /**
+ * Copies a section of the second back buffer into the main back buffer
+ */
+ void restoreBackground(const Common::Rect &r);
+
+ /**
+ * Copies a given area to the screen
+ */
+ void slamArea(int16 xp, int16 yp, int16 width, int16 height);
+
+ /**
+ * Copies a given area to the screen
+ */
+ void slamRect(const Common::Rect &r);
+
+ /**
+ * Copy an image from the back buffer to the screen, taking care of both the
+ * new area covered by the shape as well as the old area, which must be restored
+ */
+ void flushImage(ImageFrame *frame, const Common::Point &pt, int16 *xp, int16 *yp,
+ int16 *width, int16 *height);
+
+ /**
+ * Similar to flushImage, this method takes in an extra parameter for the scale proporation,
+ * which affects the calculated bounds accordingly
+ */
+ void flushScaleImage(ImageFrame *frame, const Common::Point &pt, int16 *xp, int16 *yp,
+ int16 *width, int16 *height, int scaleVal);
+
+ /**
+ * Variation of flushImage/flushScaleImage that takes in and updates a rect
+ */
+ void flushImage(ImageFrame *frame, const Common::Point &pt, Common::Rect &newBounds, int scaleVal);
+
+ /**
+ * Copies data from the back buffer to the screen
+ */
+ void blockMove(const Common::Rect &r);
+
+ /**
+ * Copies the entire screen from the back buffer
+ */
+ void blockMove();
+
+ /**
+ * Fills an area on the back buffer, and then copies it to the screen
+ */
+ void vgaBar(const Common::Rect &r, int color);
+
+ /**
+ * Sets the active back buffer pointer to a restricted sub-area of the first back buffer
+ */
+ void setDisplayBounds(const Common::Rect &r);
+
+ /**
+ * Resets the active buffer pointer to point back to the full first back buffer
+ */
+ void resetDisplayBounds();
+
+ /**
+ * Return the size of the current display window
+ */
+ Common::Rect getDisplayBounds();
+
+ /**
+ * Synchronize the data for a savegame
+ */
+ void synchronize(Serializer &s);
+
+ /**
+ * Draws the given string into the back buffer using the images stored in _font
+ */
+ virtual void writeString(const Common::String &str, const Common::Point &pt, byte overrideColor);
+
+
+ // Rose Tattoo specific methods
+ void initPaletteFade(int bytesToRead);
+
+ int fadeRead(Common::SeekableReadStream &stream, byte *buf, int totalSize);
+
+ /**
+ * Translate a palette from 6-bit RGB values to full 8-bit values suitable for passing
+ * to the underlying palette manager
+ */
+ static void translatePalette(byte palette[PALETTE_SIZE]);
+};
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp
new file mode 100644
index 0000000000..18b9332867
--- /dev/null
+++ b/engines/sherlock/sherlock.cpp
@@ -0,0 +1,282 @@
+/* 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 "sherlock/sherlock.h"
+#include "sherlock/surface.h"
+#include "common/scummsys.h"
+#include "common/config-manager.h"
+#include "common/debug-channels.h"
+
+namespace Sherlock {
+
+SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc) :
+ Engine(syst), _gameDescription(gameDesc), _randomSource("Sherlock") {
+ _animation = nullptr;
+ _debugger = nullptr;
+ _events = nullptr;
+ _fixedText = nullptr;
+ _inventory = nullptr;
+ _journal = nullptr;
+ _map = nullptr;
+ _music = nullptr;
+ _people = nullptr;
+ _res = nullptr;
+ _saves = nullptr;
+ _scene = nullptr;
+ _screen = nullptr;
+ _sound = nullptr;
+ _talk = nullptr;
+ _ui = nullptr;
+ _useEpilogue2 = false;
+ _loadGameSlot = -1;
+ _canLoadSave = false;
+ _showOriginalSavesDialog = false;
+ _interactiveFl = true;
+}
+
+SherlockEngine::~SherlockEngine() {
+ delete _animation;
+ delete _debugger;
+ delete _events;
+ delete _fixedText;
+ delete _journal;
+ delete _map;
+ delete _people;
+ delete _saves;
+ delete _scene;
+ delete _screen;
+ delete _music;
+ delete _sound;
+ delete _talk;
+ delete _ui;
+ delete _inventory;
+ delete _res;
+}
+
+void SherlockEngine::initialize() {
+ DebugMan.addDebugChannel(kDebugLevelScript, "scripts", "Script debug level");
+ DebugMan.addDebugChannel(kDebugLevelAdLibDriver, "AdLib", "AdLib driver debugging");
+ DebugMan.addDebugChannel(kDebugLevelMT32Driver, "MT32", "MT32 driver debugging");
+ DebugMan.addDebugChannel(kDebugLevelMusic, "Music", "Music debugging");
+
+ Fonts::setVm(this);
+ ImageFile::setVm(this);
+ ImageFile3DO::setVm(this);
+ BaseObject::setVm(this);
+
+ if (isDemo()) {
+ Common::File f;
+ // The interactive demo doesn't have an intro thus doesn't include TITLE.SND
+ // At the opposite, the non-interactive demo is only the intro.
+ if (f.exists("TITLE.SND"))
+ _interactiveFl = false;
+ }
+
+ _res = new Resources(this);
+ _animation = new Animation(this);
+ _debugger = Debugger::init(this);
+ _events = new Events(this);
+ _fixedText = FixedText::init(this);
+ _inventory = Inventory::init(this);
+ _map = Map::init(this);
+ _music = new Music(this, _mixer);
+ _journal = Journal::init(this);
+ _people = People::init(this);
+ _saves = SaveManager::init(this, _targetName);
+ _scene = Scene::init(this);
+ _screen = Screen::init(this);
+ _sound = new Sound(this, _mixer);
+ _talk = Talk::init(this);
+ _ui = UserInterface::init(this);
+
+ // Load game settings
+ loadConfig();
+
+ if (getPlatform() == Common::kPlatform3DO) {
+ // Disable portraits on 3DO
+ // 3DO does not include portrait data
+ _people->_portraitsOn = false;
+ }
+}
+
+Common::Error SherlockEngine::run() {
+ // Initialize the engine
+ initialize();
+
+ // Flag for whether to show original saves dialog rather than the ScummVM GMM
+ _showOriginalSavesDialog = ConfMan.getBool("originalsaveload");
+
+ // If requested, load a savegame instead of showing the intro
+ if (ConfMan.hasKey("save_slot")) {
+ int saveSlot = ConfMan.getInt("save_slot");
+ if (saveSlot >= 0 && saveSlot <= MAX_SAVEGAME_SLOTS)
+ _loadGameSlot = saveSlot;
+ }
+
+ if (_loadGameSlot != -1) {
+ _saves->loadGame(_loadGameSlot);
+ _loadGameSlot = -1;
+ } else {
+ do
+ showOpening();
+ while (!shouldQuit() && !_interactiveFl);
+ }
+
+ while (!shouldQuit()) {
+ // Prepare for scene, and handle any game-specific scenes. This allows
+ // for game specific cutscenes or mini-games that aren't standard scenes
+ startScene();
+ if (shouldQuit())
+ break;
+
+ // Clear the screen
+ _screen->clear();
+
+ // Reset UI flags
+ _ui->reset();
+
+ // Reset the data for the player character (Sherlock)
+ _people->reset();
+
+ // Initialize and load the scene.
+ _scene->selectScene();
+
+ // Scene handling loop
+ sceneLoop();
+ }
+
+ return Common::kNoError;
+}
+
+void SherlockEngine::sceneLoop() {
+ while (!shouldQuit() && _scene->_goToScene == -1) {
+ // See if a script needs to be completed from either a goto room code,
+ // or a script that was interrupted by another script
+ if (_talk->_scriptMoreFlag == 1 || _talk->_scriptMoreFlag == 3)
+ _talk->talkTo(_talk->_scriptName);
+ else
+ _talk->_scriptMoreFlag = 0;
+
+ // Handle any input from the keyboard or mouse
+ handleInput();
+
+ if (_people->_savedPos.x == -1) {
+ _canLoadSave = true;
+ _scene->doBgAnim();
+ _canLoadSave = false;
+ }
+ }
+
+ _scene->freeScene();
+ _people->freeWalk();
+}
+
+void SherlockEngine::handleInput() {
+ _canLoadSave = _ui->_menuMode == STD_MODE;
+ _events->pollEventsAndWait();
+ _canLoadSave = false;
+
+ // See if a key or mouse button is pressed
+ _events->setButtonState();
+
+ _ui->handleInput();
+}
+
+bool SherlockEngine::readFlags(int flagNum) {
+ bool value = _flags[ABS(flagNum)];
+ if (flagNum < 0)
+ value = !value;
+
+ return value;
+}
+
+void SherlockEngine::setFlags(int flagNum) {
+ _flags[ABS(flagNum)] = flagNum >= 0;
+
+ _scene->checkSceneFlags(true);
+}
+
+void SherlockEngine::setFlagsDirect(int flagNum) {
+ _flags[ABS(flagNum)] = flagNum >= 0;
+}
+
+void SherlockEngine::loadConfig() {
+ // Load sound settings
+ syncSoundSettings();
+
+ ConfMan.registerDefault("font", getGameID() == GType_SerratedScalpel ? 1 : 4);
+
+ _screen->setFont(ConfMan.getInt("font"));
+ if (getGameID() == GType_SerratedScalpel)
+ _screen->_fadeStyle = ConfMan.getBool("fade_style");
+
+ _ui->_helpStyle = ConfMan.getBool("help_style");
+ _ui->_slideWindows = ConfMan.getBool("window_style");
+ _people->_portraitsOn = ConfMan.getBool("portraits_on");
+}
+
+void SherlockEngine::saveConfig() {
+ ConfMan.setBool("mute", !_sound->_digitized);
+ ConfMan.setBool("music_mute", !_music->_musicOn);
+ ConfMan.setBool("speech_mute", !_sound->_voices);
+
+ ConfMan.setInt("font", _screen->fontNumber());
+ ConfMan.setBool("fade_style", _screen->_fadeStyle);
+ ConfMan.setBool("help_style", _ui->_helpStyle);
+ ConfMan.setBool("window_style", _ui->_slideWindows);
+ ConfMan.setBool("portraits_on", _people->_portraitsOn);
+
+ ConfMan.flushToDisk();
+}
+
+void SherlockEngine::syncSoundSettings() {
+ Engine::syncSoundSettings();
+
+ // Load sound-related settings
+ _sound->syncSoundSettings();
+ _music->syncMusicSettings();
+}
+
+void SherlockEngine::synchronize(Serializer &s) {
+ for (uint idx = 0; idx < _flags.size(); ++idx)
+ s.syncAsByte(_flags[idx]);
+}
+
+bool SherlockEngine::canLoadGameStateCurrently() {
+ return _canLoadSave;
+}
+
+bool SherlockEngine::canSaveGameStateCurrently() {
+ return _canLoadSave;
+}
+
+Common::Error SherlockEngine::loadGameState(int slot) {
+ _saves->loadGame(slot);
+ return Common::kNoError;
+}
+
+Common::Error SherlockEngine::saveGameState(int slot, const Common::String &desc) {
+ _saves->saveGame(slot, desc);
+ return Common::kNoError;
+}
+
+} // End of namespace Comet
diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h
new file mode 100644
index 0000000000..69000e1fbc
--- /dev/null
+++ b/engines/sherlock/sherlock.h
@@ -0,0 +1,229 @@
+/* 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 SHERLOCK_HOLMES_H
+#define SHERLOCK_HOLMES_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/endian.h"
+#include "common/hash-str.h"
+#include "common/serializer.h"
+#include "common/random.h"
+#include "common/savefile.h"
+#include "common/util.h"
+#include "engines/engine.h"
+#include "sherlock/animation.h"
+#include "sherlock/debugger.h"
+#include "sherlock/events.h"
+#include "sherlock/fixed_text.h"
+#include "sherlock/inventory.h"
+#include "sherlock/journal.h"
+#include "sherlock/map.h"
+#include "sherlock/music.h"
+#include "sherlock/people.h"
+#include "sherlock/resources.h"
+#include "sherlock/saveload.h"
+#include "sherlock/scene.h"
+#include "sherlock/screen.h"
+#include "sherlock/sound.h"
+#include "sherlock/talk.h"
+#include "sherlock/user_interface.h"
+
+namespace Sherlock {
+
+enum {
+ kDebugLevelScript = 1 << 0,
+ kDebugLevelAdLibDriver = 2 << 0,
+ kDebugLevelMT32Driver = 3 << 0,
+ kDebugLevelMusic = 4 << 0
+};
+
+enum GameType {
+ GType_SerratedScalpel = 0,
+ GType_RoseTattoo = 1
+};
+
+#define SHERLOCK_SCREEN_WIDTH _vm->_screen->w()
+#define SHERLOCK_SCREEN_HEIGHT _vm->_screen->h()
+#define SHERLOCK_SCENE_WIDTH _vm->_screen->_backBuffer1.w()
+#define SHERLOCK_SCENE_HEIGHT (IS_SERRATED_SCALPEL ? 138 : 480)
+#define SCENES_COUNT (IS_SERRATED_SCALPEL ? 63 : 101)
+
+#define COL_INFO_FOREGROUND (IS_SERRATED_SCALPEL ? (byte)Scalpel::INFO_FOREGROUND : (byte)Tattoo::INFO_FOREGROUND)
+#define COL_PEN_COLOR (IS_SERRATED_SCALPEL ? (byte)Scalpel::PEN_COLOR : (byte)Tattoo::PEN_COLOR)
+
+struct SherlockGameDescription;
+
+class Resource;
+
+class SherlockEngine : public Engine {
+private:
+ /**
+ * Main loop for displaying a scene and handling all that occurs within it
+ */
+ void sceneLoop();
+
+ /**
+ * Handle all player input
+ */
+ void handleInput();
+
+ /**
+ * Load game configuration esttings
+ */
+ void loadConfig();
+protected:
+ /**
+ * Does basic initialization of the game engine
+ */
+ virtual void initialize();
+
+ virtual void showOpening() = 0;
+
+ virtual void startScene() {}
+
+ /**
+ * Returns a list of features the game itself supports
+ */
+ virtual bool hasFeature(EngineFeature f) const;
+public:
+ const SherlockGameDescription *_gameDescription;
+ Animation *_animation;
+ Debugger *_debugger;
+ Events *_events;
+ FixedText *_fixedText;
+ Inventory *_inventory;
+ Journal *_journal;
+ Map *_map;
+ Music *_music;
+ People *_people;
+ Resources *_res;
+ SaveManager *_saves;
+ Scene *_scene;
+ Screen *_screen;
+ Sound *_sound;
+ Talk *_talk;
+ UserInterface *_ui;
+ Common::RandomSource _randomSource;
+ Common::Array<bool> _flags;
+ bool _useEpilogue2;
+ int _loadGameSlot;
+ bool _canLoadSave;
+ bool _showOriginalSavesDialog;
+ bool _interactiveFl;
+public:
+ SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc);
+ virtual ~SherlockEngine();
+
+ /**
+ * Main method for running the game
+ */
+ virtual Common::Error run();
+
+ /**
+ * Returns true if a savegame can be loaded
+ */
+ virtual bool canLoadGameStateCurrently();
+
+ /**
+ * Returns true if the game can be saved
+ */
+ virtual bool canSaveGameStateCurrently();
+
+ /**
+ * Called by the GMM to load a savegame
+ */
+ virtual Common::Error loadGameState(int slot);
+
+ /**
+ * Called by the GMM to save the game
+ */
+ virtual Common::Error saveGameState(int slot, const Common::String &desc);
+
+ /**
+ * Called by the engine when sound settings are updated
+ */
+ virtual void syncSoundSettings();
+
+ /**
+ * Returns whether the version is a demo
+ */
+ virtual bool isDemo() const;
+
+ /**
+ * Returns the Id of the game
+ */
+ GameType getGameID() const;
+
+ /**
+ * Returns the platform the game's datafiles are for
+ */
+ Common::Platform getPlatform() const;
+
+ /**
+ * Return the game's language
+ */
+ Common::Language getLanguage() const;
+
+ /**
+ * Return a random number
+ */
+ int getRandomNumber(int limit) { return _randomSource.getRandomNumber(limit - 1); }
+
+ /**
+ * Read the state of a global flag
+ * @remarks If a negative value is specified, it will return the inverse value
+ * of the positive flag number
+ */
+ bool readFlags(int flagNum);
+
+ /**
+ * Sets a global flag to either true or false depending on whether the specified
+ * flag is positive or negative
+ */
+ void setFlags(int flagNum);
+
+ /**
+ * Set a global flag to 0 or 1 depending on whether the passed flag is negative or positive.
+ * @remarks We don't use the global setFlags method because we don't want to check scene flags
+ */
+ void setFlagsDirect(int flagNum);
+
+ /**
+ * Saves game configuration information
+ */
+ void saveConfig();
+
+ /**
+ * Synchronize the data for a savegame
+ */
+ void synchronize(Serializer &s);
+};
+
+#define IS_ROSE_TATTOO (_vm->getGameID() == GType_RoseTattoo)
+#define IS_SERRATED_SCALPEL (_vm->getGameID() == GType_SerratedScalpel)
+#define IS_3DO (_vm->getPlatform() == Common::kPlatform3DO)
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp
new file mode 100644
index 0000000000..b46eb67b50
--- /dev/null
+++ b/engines/sherlock/sound.cpp
@@ -0,0 +1,269 @@
+/* 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 "sherlock/sherlock.h"
+#include "sherlock/sound.h"
+#include "common/config-manager.h"
+#include "audio/audiostream.h"
+#include "common/algorithm.h"
+#include "audio/mixer.h"
+#include "audio/decoders/raw.h"
+#include "audio/decoders/aiff.h"
+#include "audio/decoders/wave.h"
+
+namespace Sherlock {
+
+static const int8 creativeADPCM_ScaleMap[64] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7,
+ 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15,
+ 2, 6, 10, 14, 18, 22, 26, 30, -2, -6, -10, -14, -18, -22, -26, -30,
+ 4, 12, 20, 28, 36, 44, 52, 60, -4, -12, -20, -28, -36, -44, -52, -60
+};
+
+static const uint8 creativeADPCM_AdjustMap[64] = {
+ 0, 0, 0, 0, 0, 16, 16, 16,
+ 0, 0, 0, 0, 0, 16, 16, 16,
+ 240, 0, 0, 0, 0, 16, 16, 16,
+ 240, 0, 0, 0, 0, 16, 16, 16,
+ 240, 0, 0, 0, 0, 16, 16, 16,
+ 240, 0, 0, 0, 0, 16, 16, 16,
+ 240, 0, 0, 0, 0, 0, 0, 0,
+ 240, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*----------------------------------------------------------------*/
+
+Sound::Sound(SherlockEngine *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer) {
+ _digitized = false;
+ _voices = 0;
+ _diskSoundPlaying = false;
+ _soundPlaying = false;
+ _soundIsOn = &_soundPlaying;
+ _curPriority = 0;
+ _digiBuf = nullptr;
+
+ _soundOn = true;
+ _speechOn = true;
+
+ if (IS_3DO) {
+ // 3DO: we don't need to prepare anything for sound
+ return;
+ }
+
+ _vm->_res->addToCache("MUSIC.LIB");
+ if (!_vm->_interactiveFl)
+ _vm->_res->addToCache("TITLE.SND");
+ else {
+ _vm->_res->addToCache("MUSIC.LIB");
+
+ if (IS_ROSE_TATTOO) {
+ _vm->_res->addToCache("SOUND.LIB");
+ } else {
+ _vm->_res->addToCache("SND.SND");
+
+ if (!_vm->isDemo()) {
+ _vm->_res->addToCache("TITLE.SND");
+ _vm->_res->addToCache("EPILOGUE.SND");
+ }
+ }
+ }
+}
+
+void Sound::syncSoundSettings() {
+ _digitized = !ConfMan.getBool("mute");
+ _voices = !ConfMan.getBool("mute") && !ConfMan.getBool("speech_mute") ? 1 : 0;
+}
+
+void Sound::loadSound(const Common::String &name, int priority) {
+ // No implementation required in ScummVM
+ //warning("loadSound");
+}
+
+byte Sound::decodeSample(byte sample, byte &reference, int16 &scale) {
+ int16 samp = sample + scale;
+ int16 ref = 0;
+
+ // clip bad ADPCM-4 sample
+ samp = CLIP<int16>(samp, 0, 63);
+
+ ref = reference + creativeADPCM_ScaleMap[samp];
+ if (ref > 0xff) {
+ reference = 0xff;
+ } else {
+ if (ref < 0x00) {
+ reference = 0;
+ } else {
+ reference = (uint8)(ref & 0xff);
+ }
+ }
+
+ scale = (scale + creativeADPCM_AdjustMap[samp]) & 0xff;
+ return reference;
+}
+
+bool Sound::playSound(const Common::String &name, WaitType waitType, int priority, const char *libraryFilename) {
+ Resources &res = *_vm->_res;
+ stopSound();
+
+ Common::String filename = name;
+ if (!filename.contains('.')) {
+ if (!IS_3DO) {
+ if (IS_SERRATED_SCALPEL) {
+ filename += ".SND";
+ } else {
+ filename += ".WAV";
+ }
+ } else {
+ // 3DO uses .aiff extension
+ filename += ".AIFF";
+ if (!filename.contains('/')) {
+ // if no directory was given, use the room sounds directory
+ filename = "rooms/sounds/" + filename;
+ }
+ }
+ }
+
+ Common::String libFilename(libraryFilename);
+ Common::SeekableReadStream *stream = libFilename.empty() ? res.load(filename) : res.load(filename, libFilename);
+
+ Audio::AudioStream *audioStream;
+
+ if (!IS_3DO) {
+ if (IS_SERRATED_SCALPEL) {
+ stream->skip(2);
+ int size = stream->readUint32BE();
+ int rate = stream->readUint16BE();
+ byte *data = (byte *)malloc(size);
+ byte *ptr = data;
+ stream->read(ptr, size);
+ delete stream;
+
+ assert(size > 2);
+
+ byte *decoded = (byte *)malloc((size - 1) * 2);
+
+ // Holmes uses Creative ADPCM 4-bit data
+ int counter = 0;
+ byte reference = ptr[0];
+ int16 scale = 0;
+
+ for(int i = 1; i < size; i++) {
+ decoded[counter++] = decodeSample((ptr[i]>>4)&0x0f, reference, scale);
+ decoded[counter++] = decodeSample((ptr[i]>>0)&0x0f, reference, scale);
+ }
+
+ free(data);
+
+#if 0
+ // Debug : used to dump files
+ Common::DumpFile outFile;
+ outFile.open(filename);
+ outFile.write(decoded, (size - 2) * 2);
+ outFile.flush();
+ outFile.close();
+#endif
+
+ audioStream = Audio::makeRawStream(decoded, (size - 2) * 2, rate, Audio::FLAG_UNSIGNED, DisposeAfterUse::YES);
+ } else {
+ audioStream = Audio::makeWAVStream(stream, DisposeAfterUse::YES);
+ }
+ } else {
+ // 3DO: AIFF file
+ audioStream = Audio::makeAIFFStream(stream, DisposeAfterUse::YES);
+ }
+
+ Audio::SoundHandle effectsHandle = (IS_SERRATED_SCALPEL) ? _scalpelEffectsHandle : getFreeSoundHandle();
+
+ _mixer->playStream(Audio::Mixer::kPlainSoundType, &effectsHandle, audioStream, -1, Audio::Mixer::kMaxChannelVolume);
+ _soundPlaying = true;
+ _curPriority = priority;
+
+ if (waitType == WAIT_RETURN_IMMEDIATELY) {
+ _diskSoundPlaying = true;
+ return true;
+ }
+
+ bool retval = true;
+ do {
+ _vm->_events->pollEvents();
+ g_system->delayMillis(10);
+ if ((waitType == WAIT_KBD_OR_FINISH) && _vm->_events->kbHit()) {
+ retval = false;
+ break;
+ }
+ } while (!_vm->shouldQuit() && _mixer->isSoundHandleActive(effectsHandle));
+
+ _soundPlaying = false;
+ _mixer->stopHandle(effectsHandle);
+
+ return retval;
+}
+
+void Sound::playLoadedSound(int bufNum, WaitType waitType) {
+ if (IS_SERRATED_SCALPEL) {
+ if (_mixer->isSoundHandleActive(_scalpelEffectsHandle) && (_curPriority > _vm->_scene->_sounds[bufNum]._priority))
+ return;
+
+ stopSound();
+ }
+
+ playSound(_vm->_scene->_sounds[bufNum]._name, waitType, _vm->_scene->_sounds[bufNum]._priority);
+}
+
+void Sound::freeLoadedSounds() {
+ // As sounds are played with DisposeAfterUse::YES, stopping the sounds also
+ // frees them
+ stopSound();
+}
+
+void Sound::stopSound() {
+ if (IS_SERRATED_SCALPEL) {
+ _mixer->stopHandle(_scalpelEffectsHandle);
+ } else {
+ for (int i = 0; i < MAX_MIXER_CHANNELS; i++)
+ _mixer->stopHandle(_tattooEffectsHandle[i]);
+ }
+}
+
+void Sound::stopSndFuncPtr(int v1, int v2) {
+ // TODO
+ warning("TODO: Sound::stopSndFuncPtr");
+}
+
+void Sound::freeDigiSound() {
+ delete[] _digiBuf;
+ _digiBuf = nullptr;
+ _diskSoundPlaying = false;
+ _soundPlaying = false;
+}
+
+Audio::SoundHandle Sound::getFreeSoundHandle() {
+ for (int i = 0; i < MAX_MIXER_CHANNELS; i++) {
+ if (!_mixer->isSoundHandleActive(_tattooEffectsHandle[i]))
+ return _tattooEffectsHandle[i];
+ }
+
+ error("getFreeSoundHandle: No sound handle found");
+}
+
+} // End of namespace Sherlock
+
diff --git a/engines/sherlock/sound.h b/engines/sherlock/sound.h
new file mode 100644
index 0000000000..414b1ef49b
--- /dev/null
+++ b/engines/sherlock/sound.h
@@ -0,0 +1,106 @@
+/* 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 SHERLOCK_SOUND_H
+#define SHERLOCK_SOUND_H
+
+#include "common/scummsys.h"
+#include "common/str.h"
+#include "audio/audiostream.h"
+#include "audio/mixer.h"
+#include "access/files.h"
+#include "audio/midiplayer.h"
+#include "audio/midiparser.h"
+
+namespace Sherlock {
+
+class SherlockEngine;
+
+enum WaitType {
+ WAIT_RETURN_IMMEDIATELY = 0, WAIT_FINISH = 1, WAIT_KBD_OR_FINISH = 2
+};
+
+#define MAX_MIXER_CHANNELS 10
+
+class Sound {
+private:
+ SherlockEngine *_vm;
+ Audio::Mixer *_mixer;
+ Audio::SoundHandle _scalpelEffectsHandle;
+ Audio::SoundHandle _tattooEffectsHandle[MAX_MIXER_CHANNELS];
+ int _curPriority;
+
+ byte decodeSample(byte sample, byte& reference, int16& scale);
+public:
+ bool _digitized;
+ int _voices;
+ bool _soundOn;
+ bool _speechOn;
+ bool _diskSoundPlaying;
+ bool _soundPlaying;
+ bool *_soundIsOn;
+ byte *_digiBuf;
+
+ Common::String _talkSoundFile;
+public:
+ Sound(SherlockEngine *vm, Audio::Mixer *mixer);
+
+ /**
+ * Saves sound-related settings
+ */
+ void syncSoundSettings();
+
+ /**
+ * Load a sound
+ */
+ void loadSound(const Common::String &name, int priority);
+
+ /**
+ * Play the sound in the specified resource
+ */
+ bool playSound(const Common::String &name, WaitType waitType, int priority = 100, const char *libraryFilename = nullptr);
+
+ /**
+ * Play a previously loaded sound
+ */
+ void playLoadedSound(int bufNum, WaitType waitType);
+
+ /**
+ * Free any previously loaded sounds
+ */
+ void freeLoadedSounds();
+
+ /**
+ * Stop playing any active sound
+ */
+ void stopSound();
+
+ void stopSndFuncPtr(int v1, int v2);
+ void freeDigiSound();
+
+ Audio::SoundHandle getFreeSoundHandle();
+};
+
+} // End of namespace Sherlock
+
+#endif
+
diff --git a/engines/sherlock/surface.cpp b/engines/sherlock/surface.cpp
new file mode 100644
index 0000000000..42194de7a3
--- /dev/null
+++ b/engines/sherlock/surface.cpp
@@ -0,0 +1,307 @@
+/* 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 "sherlock/surface.h"
+#include "sherlock/sherlock.h"
+#include "sherlock/resources.h"
+#include "common/system.h"
+#include "graphics/palette.h"
+
+namespace Sherlock {
+
+Surface::Surface(uint16 width, uint16 height) : Fonts(), _freePixels(true) {
+ create(width, height);
+}
+
+Surface::Surface() : Fonts(), _freePixels(false) {
+}
+
+Surface::~Surface() {
+ if (_freePixels)
+ _surface.free();
+}
+
+void Surface::create(uint16 width, uint16 height) {
+ if (_freePixels)
+ _surface.free();
+
+ if (_vm->getPlatform() == Common::kPlatform3DO) {
+ _surface.create(width, height, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));
+ } else {
+ _surface.create(width, height, Graphics::PixelFormat::createFormatCLUT8());
+ }
+ _freePixels = true;
+}
+
+Graphics::PixelFormat Surface::getPixelFormat() {
+ return _surface.format;
+}
+
+void Surface::blitFrom(const Surface &src) {
+ blitFrom(src, Common::Point(0, 0));
+}
+
+void Surface::blitFrom(const ImageFrame &src) {
+ blitFrom(src._frame, Common::Point(0, 0));
+}
+
+void Surface::blitFrom(const Graphics::Surface &src) {
+ blitFrom(src, Common::Point(0, 0));
+}
+
+void Surface::blitFrom(const Surface &src, const Common::Point &pt) {
+ blitFrom(src, pt, Common::Rect(0, 0, src._surface.w, src._surface.h));
+}
+
+void Surface::blitFrom(const ImageFrame &src, const Common::Point &pt) {
+ blitFrom(src._frame, pt, Common::Rect(0, 0, src._frame.w, src._frame.h));
+}
+
+void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt) {
+ blitFrom(src, pt, Common::Rect(0, 0, src.w, src.h));
+}
+
+void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt, const Common::Rect &srcBounds) {
+ Common::Rect srcRect = srcBounds;
+ Common::Rect destRect(pt.x, pt.y, pt.x + srcRect.width(), pt.y + srcRect.height());
+
+ if (srcRect.isValidRect() && clip(srcRect, destRect)) {
+ // Surface is at least partially or completely on-screen
+ addDirtyRect(destRect);
+ _surface.copyRectToSurface(src, destRect.left, destRect.top, srcRect);
+ }
+}
+
+void Surface::blitFrom(const ImageFrame &src, const Common::Point &pt, const Common::Rect &srcBounds) {
+ blitFrom(src._frame, pt, srcBounds);
+}
+
+void Surface::blitFrom(const Surface &src, const Common::Point &pt, const Common::Rect &srcBounds) {
+ blitFrom(src._surface, pt, srcBounds);
+}
+
+void Surface::transBlitFrom(const ImageFrame &src, const Common::Point &pt,
+ bool flipped, int overrideColor, int scaleVal) {
+ transBlitFrom(src._frame, pt + src._offset, flipped, overrideColor, scaleVal);
+}
+
+void Surface::transBlitFrom(const Surface &src, const Common::Point &pt,
+ bool flipped, int overrideColor, int scaleVal) {
+ const Graphics::Surface &s = src._surface;
+ transBlitFrom(s, pt, flipped, overrideColor, scaleVal);
+}
+
+void Surface::transBlitFrom(const Graphics::Surface &src, const Common::Point &pt,
+ bool flipped, int overrideColor, int scaleVal) {
+ if (scaleVal == SCALE_THRESHOLD) {
+ transBlitFromUnscaled(src, pt, flipped, overrideColor);
+ return;
+ }
+
+ int scaleX = SCALE_THRESHOLD * SCALE_THRESHOLD / scaleVal;
+ int scaleY = scaleX;
+ int scaleXCtr = 0, scaleYCtr = 0;
+ int destX, destY;
+ int xCtr, yCtr;
+ int maxX = pt.x;
+
+ for (yCtr = 0, destY = pt.y; yCtr < src.h && destY < this->h(); ++yCtr) {
+ // Handle skipping lines if Y scaling
+ scaleYCtr += scaleY;
+
+ while (scaleYCtr >= SCALE_THRESHOLD && destY < this->h()) {
+ scaleYCtr -= SCALE_THRESHOLD;
+
+ if (destY >= 0) {
+ // Handle drawing the line
+ const byte *pSrc = (const byte *)src.getBasePtr(flipped ? src.w - 1 : 0, yCtr);
+ byte *pDest = (byte *)getBasePtr(pt.x, destY);
+ scaleXCtr = 0;
+
+ for (xCtr = 0, destX = pt.x; xCtr < src.w && destX < this->w(); ++xCtr) {
+ // Handle horizontal scaling
+ scaleXCtr += scaleX;
+
+ while (scaleXCtr >= SCALE_THRESHOLD && destX < this->w()) {
+ scaleXCtr -= SCALE_THRESHOLD;
+
+ // Only handle on-screen pixels
+ if (destX >= 0 && *pSrc != TRANSPARENCY)
+ *pDest = *pSrc;
+
+ ++pDest;
+ ++destX;
+ }
+
+ maxX = MAX(maxX, destX);
+ pSrc = pSrc + (flipped ? -1 : 1);
+ }
+ }
+
+ ++destY;
+ }
+ }
+
+ // Mark the affected area
+ addDirtyRect(Common::Rect(pt.x, pt.y, maxX, destY));
+}
+
+void Surface::transBlitFromUnscaled(const Graphics::Surface &src, const Common::Point &pt,
+ bool flipped, int overrideColor) {
+ Common::Rect drawRect(0, 0, src.w, src.h);
+ Common::Rect destRect(pt.x, pt.y, pt.x + src.w, pt.y + src.h);
+
+ // Clip the display area to on-screen
+ if (!clip(drawRect, destRect))
+ // It's completely off-screen
+ return;
+
+ if (flipped)
+ drawRect = Common::Rect(src.w - drawRect.right, src.h - drawRect.bottom,
+ src.w - drawRect.left, src.h - drawRect.top);
+
+ Common::Point destPt(destRect.left, destRect.top);
+ addDirtyRect(Common::Rect(destPt.x, destPt.y, destPt.x + drawRect.width(),
+ destPt.y + drawRect.height()));
+
+ switch (src.format.bytesPerPixel) {
+ case 1:
+ // 8-bit palettized: Draw loop
+ assert(_surface.format.bytesPerPixel == 1); // Security check
+ for (int yp = 0; yp < drawRect.height(); ++yp) {
+ const byte *srcP = (const byte *)src.getBasePtr(
+ flipped ? drawRect.right - 1 : drawRect.left, drawRect.top + yp);
+ byte *destP = (byte *)getBasePtr(destPt.x, destPt.y + yp);
+
+ for (int xp = 0; xp < drawRect.width(); ++xp, ++destP) {
+ if (*srcP != TRANSPARENCY)
+ *destP = overrideColor ? overrideColor : *srcP;
+
+ srcP = flipped ? srcP - 1 : srcP + 1;
+ }
+ }
+ break;
+ case 2:
+ // 3DO 15-bit RGB565: Draw loop
+ assert(_surface.format.bytesPerPixel == 2); // Security check
+ for (int yp = 0; yp < drawRect.height(); ++yp) {
+ const uint16 *srcP = (const uint16 *)src.getBasePtr(
+ flipped ? drawRect.right - 1 : drawRect.left, drawRect.top + yp);
+ uint16 *destP = (uint16 *)getBasePtr(destPt.x, destPt.y + yp);
+
+ for (int xp = 0; xp < drawRect.width(); ++xp, ++destP) {
+ if (*srcP) // RGB 0, 0, 0 -> transparent on 3DO
+ *destP = *srcP; // overrideColor ? overrideColor : *srcP;
+
+ srcP = flipped ? srcP - 1 : srcP + 1;
+ }
+ }
+ break;
+ default:
+ error("Surface: unsupported bytesperpixel");
+ break;
+ }
+}
+
+void Surface::fillRect(int x1, int y1, int x2, int y2, byte color) {
+ fillRect(Common::Rect(x1, y1, x2, y2), color);
+}
+
+void Surface::fillRect(const Common::Rect &r, byte color) {
+ _surface.fillRect(r, color);
+ addDirtyRect(r);
+}
+
+void Surface::fill(uint16 color) {
+ _surface.fillRect(Common::Rect(_surface.w, _surface.h), color);
+}
+
+bool Surface::clip(Common::Rect &srcBounds, Common::Rect &destBounds) {
+ if (destBounds.left >= _surface.w || destBounds.top >= _surface.h ||
+ destBounds.right <= 0 || destBounds.bottom <= 0)
+ return false;
+
+ // Clip the bounds if necessary to fit on-screen
+ if (destBounds.right > _surface.w) {
+ srcBounds.right -= destBounds.right - _surface.w;
+ destBounds.right = _surface.w;
+ }
+
+ if (destBounds.bottom > _surface.h) {
+ srcBounds.bottom -= destBounds.bottom - _surface.h;
+ destBounds.bottom = _surface.h;
+ }
+
+ if (destBounds.top < 0) {
+ srcBounds.top += -destBounds.top;
+ destBounds.top = 0;
+ }
+
+ if (destBounds.left < 0) {
+ srcBounds.left += -destBounds.left;
+ destBounds.left = 0;
+ }
+
+ return true;
+}
+
+void Surface::clear() {
+ fillRect(Common::Rect(0, 0, _surface.w, _surface.h), 0);
+}
+
+void Surface::free() {
+ if (_freePixels) {
+ _surface.free();
+ _freePixels = false;
+ }
+}
+
+void Surface::setPixels(byte *pixels, int width, int height, Graphics::PixelFormat pixelFormat) {
+ _surface.format = pixelFormat;
+ _surface.w = width;
+ _surface.h = height;
+ _surface.pitch = width * pixelFormat.bytesPerPixel;
+ _surface.setPixels(pixels);
+}
+
+void Surface::writeString(const Common::String &str, const Common::Point &pt, byte overrideColor) {
+ Fonts::writeString(this, str, pt, overrideColor);
+}
+
+void Surface::writeFancyString(const Common::String &str, const Common::Point &pt, byte overrideColor1, byte overrideColor2) {
+ writeString(str, Common::Point(pt.x, pt.y), overrideColor1);
+ writeString(str, Common::Point(pt.x + 1, pt.y), overrideColor1);
+ writeString(str, Common::Point(pt.x + 2, pt.y), overrideColor1);
+ writeString(str, Common::Point(pt.x, pt.y + 1), overrideColor1);
+ writeString(str, Common::Point(pt.x + 2, pt.y + 1), overrideColor1);
+ writeString(str, Common::Point(pt.x, pt.y + 2), overrideColor1);
+ writeString(str, Common::Point(pt.x + 1, pt.y + 2), overrideColor1);
+ writeString(str, Common::Point(pt.x + 2, pt.y + 2), overrideColor1);
+ writeString(str, Common::Point(pt.x + 1, pt.y + 1), overrideColor2);
+}
+
+void Surface::maskArea(const ImageFrame &src, const Common::Point &pt) {
+ // TODO
+ error("TODO: maskArea");
+}
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/surface.h b/engines/sherlock/surface.h
new file mode 100644
index 0000000000..38e3339617
--- /dev/null
+++ b/engines/sherlock/surface.h
@@ -0,0 +1,185 @@
+/* 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 SHERLOCK_GRAPHICS_H
+#define SHERLOCK_GRAPHICS_H
+
+#include "common/rect.h"
+#include "common/platform.h"
+#include "graphics/surface.h"
+#include "sherlock/fonts.h"
+
+namespace Sherlock {
+
+#define SCALE_THRESHOLD 0x100
+#define TRANSPARENCY 255
+
+struct ImageFrame;
+
+class Surface: public Fonts {
+private:
+ bool _freePixels;
+
+ /**
+ * Clips the given source bounds so the passed destBounds will be entirely on-screen
+ */
+ bool clip(Common::Rect &srcBounds, Common::Rect &destBounds);
+
+ /**
+ * Copy a surface into this one
+ */
+ void blitFrom(const Graphics::Surface &src);
+
+ /**
+ * Draws a surface at a given position within this surface
+ */
+ void blitFrom(const Graphics::Surface &src, const Common::Point &pt);
+
+ /**
+ * Draws a sub-section of a surface at a given position within this surface
+ */
+ void blitFrom(const Graphics::Surface &src, const Common::Point &pt, const Common::Rect &srcBounds);
+
+ /**
+ * Draws a surface at a given position within this surface with transparency
+ */
+ void transBlitFromUnscaled(const Graphics::Surface &src, const Common::Point &pt, bool flipped,
+ int overrideColor);
+
+protected:
+ Graphics::Surface _surface;
+
+ virtual void addDirtyRect(const Common::Rect &r) {}
+public:
+ Surface(uint16 width, uint16 height);
+ Surface();
+ virtual ~Surface();
+
+ /**
+ * Sets up an internal surface with the specified dimensions that will be automatically freed
+ * when the surface object is destroyed
+ */
+ void create(uint16 width, uint16 height);
+
+ Graphics::PixelFormat getPixelFormat();
+
+ /**
+ * Copy a surface into this one
+ */
+ void blitFrom(const Surface &src);
+
+ /**
+ * Copy an image frame into this surface
+ */
+ void blitFrom(const ImageFrame &src);
+
+ /**
+ * Draws a surface at a given position within this surface
+ */
+ void blitFrom(const Surface &src, const Common::Point &pt);
+
+ /**
+ * Copy an image frame onto this surface at a given position
+ */
+ void blitFrom(const ImageFrame &src, const Common::Point &pt);
+
+ /**
+ * Draws a sub-section of a surface at a given position within this surface
+ */
+ void blitFrom(const Surface &src, const Common::Point &pt, const Common::Rect &srcBounds);
+
+ /**
+ * Copy a sub-area of a source image frame into this surface at a given position
+ */
+ void blitFrom(const ImageFrame &src, const Common::Point &pt, const Common::Rect &srcBounds);
+
+ /**
+ * Draws an image frame at a given position within this surface with transparency
+ */
+ void transBlitFrom(const ImageFrame &src, const Common::Point &pt,
+ bool flipped = false, int overrideColor = 0, int scaleVal = 256);
+
+ /**
+ * Draws a surface at a given position within this surface with transparency
+ */
+ void transBlitFrom(const Surface &src, const Common::Point &pt,
+ bool flipped = false, int overrideColor = 0, int scaleVal = 256);
+
+ /**
+ * Draws a surface at a given position within this surface with transparency
+ */
+ void transBlitFrom(const Graphics::Surface &src, const Common::Point &pt,
+ bool flipped = false, int overrideColor = 0, int scaleVal = 256);
+
+ /**
+ * Fill a given area of the surface with a given color
+ */
+ void fillRect(int x1, int y1, int x2, int y2, byte color);
+
+ /**
+ * Fill a given area of the surface with a given color
+ */
+ void fillRect(const Common::Rect &r, byte color);
+
+ void fill(uint16 color);
+
+ void maskArea(const ImageFrame &src, const Common::Point &pt);
+
+ /**
+ * Clear the surface
+ */
+ void clear();
+
+ /**
+ * Free the underlying surface
+ */
+ void free();
+
+ /**
+ * Returns true if the surface is empty
+ */
+ bool empty() const { return _surface.getPixels() == nullptr; }
+
+ /**
+ * Set the pixels for the surface to an existing data block
+ */
+ void setPixels(byte *pixels, int width, int height, Graphics::PixelFormat format);
+
+ /**
+ * Draws the given string into the back buffer using the images stored in _font
+ */
+ virtual void writeString(const Common::String &str, const Common::Point &pt, byte overrideColor);
+ void writeFancyString(const Common::String &str, const Common::Point &pt, byte overrideColor1, byte overrideColor2);
+
+ inline uint16 w() const { return _surface.w; }
+ inline uint16 h() const { return _surface.h; }
+ inline const byte *getPixels() const { return (const byte *)_surface.getPixels(); }
+ inline byte *getPixels() { return (byte *)_surface.getPixels(); }
+ inline byte *getBasePtr(int x, int y) { return (byte *)_surface.getBasePtr(x, y); }
+ inline const byte *getBasePtr(int x, int y) const { return (const byte *)_surface.getBasePtr(x, y); }
+ inline void hLine(int x, int y, int x2, uint32 color) { _surface.hLine(x, y, x2, color); }
+ inline void vLine(int x, int y, int y2, uint32 color) { _surface.vLine(x, y, y2, color); }
+};
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp
new file mode 100644
index 0000000000..a1a003d751
--- /dev/null
+++ b/engines/sherlock/talk.cpp
@@ -0,0 +1,1297 @@
+/* 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 "sherlock/talk.h"
+#include "sherlock/sherlock.h"
+#include "sherlock/screen.h"
+#include "sherlock/scalpel/scalpel.h"
+#include "sherlock/scalpel/scalpel_people.h"
+#include "sherlock/scalpel/scalpel_talk.h"
+#include "sherlock/scalpel/scalpel_user_interface.h"
+#include "sherlock/tattoo/tattoo.h"
+#include "sherlock/tattoo/tattoo_people.h"
+#include "sherlock/tattoo/tattoo_scene.h"
+#include "sherlock/tattoo/tattoo_talk.h"
+
+namespace Sherlock {
+
+SequenceEntry::SequenceEntry() {
+ _objNum = 0;
+ _frameNumber = 0;
+ _seqTo = 0;
+}
+
+/*----------------------------------------------------------------*/
+
+void Statement::load(Common::SeekableReadStream &s, bool isRoseTattoo) {
+ int length;
+
+ length = s.readUint16LE();
+ for (int idx = 0; idx < length - 1; ++idx)
+ _statement += (char)s.readByte();
+ s.readByte(); // Null ending
+
+ length = s.readUint16LE();
+ for (int idx = 0; idx < length - 1; ++idx)
+ _reply += (char)s.readByte();
+ s.readByte(); // Null ending
+
+ length = s.readUint16LE();
+ for (int idx = 0; idx < length - 1; ++idx)
+ _linkFile += (char)s.readByte();
+ s.readByte(); // Null ending
+
+ length = s.readUint16LE();
+ for (int idx = 0; idx < length - 1; ++idx)
+ _voiceFile += (char)s.readByte();
+ s.readByte(); // Null ending
+
+ _required.resize(s.readByte());
+ _modified.resize(s.readByte());
+
+ // Read in flag required/modified data
+ for (uint idx = 0; idx < _required.size(); ++idx)
+ _required[idx] = s.readSint16LE();
+ for (uint idx = 0; idx < _modified.size(); ++idx)
+ _modified[idx] = s.readSint16LE();
+
+ _portraitSide = s.readByte();
+ _quotient = s.readUint16LE();
+ _journal = isRoseTattoo ? s.readByte() : 0;
+}
+
+/*----------------------------------------------------------------*/
+
+TalkHistoryEntry::TalkHistoryEntry() {
+ Common::fill(&_data[0], &_data[16], false);
+}
+
+/*----------------------------------------------------------------*/
+
+TalkSequence::TalkSequence() {
+ _obj = nullptr;
+ _frameNumber = 0;
+ _sequenceNumber = 0;
+ _seqStack = 0;
+ _seqTo = 0;
+ _seqCounter = _seqCounter2 = 0;
+}
+
+/*----------------------------------------------------------------*/
+
+Talk *Talk::init(SherlockEngine *vm) {
+ if (vm->getGameID() == GType_SerratedScalpel)
+ return new Scalpel::ScalpelTalk(vm);
+ else
+ return new Tattoo::TattooTalk(vm);
+}
+
+Talk::Talk(SherlockEngine *vm) : _vm(vm) {
+ _talkCounter = 0;
+ _talkToAbort = false;
+ _openTalkWindow = false;
+ _speaker = 0;
+ _talkIndex = 0;
+ _talkTo = 0;
+ _scriptSelect = 0;
+ _converseNum = -1;
+ _talkStealth = 0;
+ _talkToFlag = -1;
+ _moreTalkDown = _moreTalkUp = false;
+ _scriptMoreFlag = 0;
+ _scriptSaveIndex = -1;
+ _opcodes = nullptr;
+ _opcodeTable = nullptr;
+
+ _charCount = 0;
+ _line = 0;
+ _yp = 0;
+ _wait = 0;
+ _pauseFlag = false;
+ _seqCount = 0;
+ _scriptStart = _scriptEnd = nullptr;
+ _endStr = _noTextYet = false;
+
+ _talkHistory.resize(IS_ROSE_TATTOO ? 1500 : 500);
+}
+
+void Talk::talkTo(const Common::String &filename) {
+ Events &events = *_vm->_events;
+ Inventory &inv = *_vm->_inventory;
+ Journal &journal = *_vm->_journal;
+ People &people = *_vm->_people;
+ Scene &scene = *_vm->_scene;
+ Screen &screen = *_vm->_screen;
+ UserInterface &ui = *_vm->_ui;
+ Common::Rect savedBounds = screen.getDisplayBounds();
+ bool abortFlag = false;
+
+ if (filename.empty())
+ // No filename passed, so exit
+ return;
+
+ // If there any canimations currently running, or a portrait is being cleared,
+ // save the filename for later executing when the canimation is done
+ bool ongoingAnim = scene._canimShapes.size() > 0;
+ if (IS_ROSE_TATTOO) {
+ ongoingAnim = static_cast<Tattoo::TattooScene *>(_vm->_scene)->_activeCAnim.active();
+ }
+ if (ongoingAnim || people._clearingThePortrait) {
+ // Make sure we're not in the middle of a script
+ if (!_scriptMoreFlag) {
+ _scriptName = filename;
+ _scriptSaveIndex = 0;
+
+ // Flag the selection, since we don't yet know which statement yet
+ _scriptSelect = 100;
+ _scriptMoreFlag = 3;
+ }
+
+ return;
+ }
+
+ // Save the ui mode temporarily and switch to talk mode
+ MenuMode savedMode = ui._menuMode;
+ ui._menuMode = TALK_MODE;
+
+ // Turn on the Exit option
+ ui._endKeyActive = true;
+
+ if (people[HOLMES]._walkCount || (people[HOLMES]._walkTo.size() > 0 &&
+ (IS_SERRATED_SCALPEL || people._allowWalkAbort))) {
+ // Only interrupt if trying to do an action, and not just if player is walking around the scene
+ if (people._allowWalkAbort)
+ abortFlag = true;
+
+ people[HOLMES].gotoStand();
+ }
+
+ if (_talkToAbort)
+ return;
+
+ freeTalkVars();
+
+ // If any sequences have changed in the prior talk file, restore them
+ if (_savedSequences.size() > 0) {
+ for (uint idx = 0; idx < _savedSequences.size(); ++idx) {
+ SequenceEntry &ss = _savedSequences[idx];
+ for (uint idx2 = 0; idx2 < ss._sequences.size(); ++idx2)
+ scene._bgShapes[ss._objNum]._sequences[idx2] = ss._sequences[idx2];
+
+ // Reset the object's frame to the beginning of the sequence
+ scene._bgShapes[ss._objNum]._frameNumber = 0;
+ }
+ }
+
+ while (!_sequenceStack.empty())
+ pullSequence();
+
+ if (IS_SERRATED_SCALPEL) {
+ // Restore any pressed button
+ if (!ui._windowOpen && savedMode != STD_MODE)
+ static_cast<Scalpel::ScalpelUserInterface *>(_vm->_ui)->restoreButton((int)(savedMode - 1));
+ } else {
+ static_cast<Tattoo::TattooPeople *>(_vm->_people)->pullNPCPaths();
+ }
+
+ // Clear the ui counter so that anything displayed on the info line
+ // before the window was opened isn't cleared
+ ui._menuCounter = 0;
+
+ // Close any previous window before starting the talk
+ if (ui._windowOpen) {
+ switch (savedMode) {
+ case LOOK_MODE:
+ events.setCursor(ARROW);
+
+ if (ui._invLookFlag) {
+ screen.resetDisplayBounds();
+ ui.drawInterface(2);
+ }
+
+ ui.banishWindow();
+ ui._windowBounds.top = CONTROLS_Y1;
+ ui._temp = ui._oldTemp = ui._lookHelp = 0;
+ ui._menuMode = STD_MODE;
+ events._pressed = events._released = events._oldButtons = 0;
+ ui._invLookFlag = false;
+ break;
+
+ case TALK_MODE:
+ if (_speaker < SPEAKER_REMOVE)
+ people.clearTalking();
+ if (_talkCounter)
+ return;
+
+ // If we were in inventory mode looking at an object, restore the
+ // back buffers before closing the window, so we get the ui restored
+ // rather than the inventory again
+ if (ui._invLookFlag) {
+ screen.resetDisplayBounds();
+ ui.drawInterface(2);
+ ui._invLookFlag = ui._lookScriptFlag = false;
+ }
+
+ ui.banishWindow();
+ ui._windowBounds.top = CONTROLS_Y1;
+ abortFlag = true;
+ break;
+
+ case INV_MODE:
+ case USE_MODE:
+ case GIVE_MODE:
+ inv.freeInv();
+ if (ui._invLookFlag) {
+ screen.resetDisplayBounds();
+ ui.drawInterface(2);
+ ui._invLookFlag = ui._lookScriptFlag = false;
+ }
+
+ ui._infoFlag = true;
+ ui.clearInfo();
+ ui.banishWindow(false);
+ ui._key = -1;
+ break;
+
+ case FILES_MODE:
+ ui.banishWindow(true);
+ ui._windowBounds.top = CONTROLS_Y1;
+ abortFlag = true;
+ break;
+
+ case SETUP_MODE:
+ ui.banishWindow(true);
+ ui._windowBounds.top = CONTROLS_Y1;
+ ui._temp = ui._oldTemp = ui._lookHelp = ui._invLookFlag = false;
+ ui._menuMode = STD_MODE;
+ events._pressed = events._released = events._oldButtons = 0;
+ abortFlag = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ screen.resetDisplayBounds();
+ events._pressed = events._released = false;
+ loadTalkFile(filename);
+ ui._selector = ui._oldSelector = ui._key = ui._oldKey = -1;
+
+ // Find the first statement that has the correct flags
+ int select = -1;
+ for (uint idx = 0; idx < _statements.size() && select == -1; ++idx) {
+ if (_statements[idx]._talkMap == 0)
+ select = _talkIndex = idx;
+ }
+
+ // If there's a pending automatic selection to be made, then use it
+ if (_scriptMoreFlag && _scriptSelect != 100)
+ select = _scriptSelect;
+
+ if (select == -1)
+ error("Couldn't find statement to display");
+
+ // Add the statement into the journal and talk history
+ if (_talkTo != -1 && !_talkHistory[_converseNum][select])
+ journal.record(_converseNum, select, true);
+ _talkHistory[_converseNum][select] = true;
+
+ // Check if the talk file is meant to be a non-seen comment
+ if (filename.size() < 8 || filename[7] != '*') {
+ // Should we start in stealth mode?
+ if (_statements[select]._statement.hasPrefix("^")) {
+ _talkStealth = 2;
+ } else {
+ // Not in stealth mode, so bring up the ui window
+ _talkStealth = 0;
+ ++_talkToFlag;
+ events.setCursor(WAIT);
+
+ ui._windowBounds.top = CONTROLS_Y;
+ ui._infoFlag = true;
+ ui.clearInfo();
+ }
+
+ // Handle replies until there's no further linked file,
+ // or the link file isn't a reply first cnversation
+ while (!_vm->shouldQuit()) {
+ clearSequences();
+ _scriptSelect = select;
+ _speaker = _talkTo;
+
+ Statement &statement = _statements[select];
+ doScript(_statements[select]._reply);
+
+ if (_talkToAbort)
+ return;
+
+ if (!_talkStealth)
+ ui.clearWindow();
+
+ if (statement._modified.size() > 0) {
+ for (uint idx = 0; idx < statement._modified.size(); ++idx)
+ _vm->setFlags(statement._modified[idx]);
+
+ setTalkMap();
+ }
+
+ // Check for a linked file
+ if (!statement._linkFile.empty() && !_scriptMoreFlag) {
+ Common::String linkFilename = statement._linkFile;
+ freeTalkVars();
+ loadTalkFile(linkFilename);
+
+ // Scan for the first valid statement in the newly loaded file
+ select = -1;
+ for (uint idx = 0; idx < _statements.size(); ++idx) {
+ if (_statements[idx]._talkMap == 0) {
+ select = idx;
+ break;
+ }
+ }
+
+ if (_talkToFlag == 1)
+ pullSequence();
+
+ // Set the stealth mode for the new talk file
+ Statement &newStatement = _statements[select];
+ _talkStealth = newStatement._statement.hasPrefix("^") ? 2 : 0;
+
+ // If the new conversion is a reply first, then we don't need
+ // to display any choices, since the reply needs to be shown
+ if (!newStatement._statement.hasPrefix("*") && !newStatement._statement.hasPrefix("^")) {
+ _talkIndex = select;
+ showTalk();
+
+ // Break out of loop now that we're waiting for player input
+ events.setCursor(ARROW);
+ break;
+ } else {
+ // Add the statement into the journal and talk history
+ if (_talkTo != -1 && !_talkHistory[_converseNum][select])
+ journal.record(_converseNum, select, true);
+ _talkHistory[_converseNum][select] = true;
+
+ }
+
+ ui._key = ui._oldKey = Scalpel::COMMANDS[TALK_MODE - 1];
+ ui._temp = ui._oldTemp = 0;
+ ui._menuMode = TALK_MODE;
+ _talkToFlag = 2;
+ } else {
+ freeTalkVars();
+
+ if (!ui._lookScriptFlag) {
+ ui.drawInterface(2);
+ ui._menuMode = STD_MODE;
+ ui._windowBounds.top = CONTROLS_Y1;
+
+ ui.banishWindow();
+ }
+
+ break;
+ }
+ }
+ }
+
+ _talkStealth = 0;
+ events._pressed = events._released = events._oldButtons = 0;
+ events.clearKeyboard();
+
+ if (savedBounds.bottom == SHERLOCK_SCREEN_HEIGHT)
+ screen.resetDisplayBounds();
+ else
+ screen.setDisplayBounds(savedBounds);
+
+ _talkToAbort = abortFlag;
+
+ // If a script was added to the script stack, restore state so that the
+ // previous script can continue
+ popStack();
+
+ if (IS_SERRATED_SCALPEL && filename == "Tube59c") {
+ // WORKAROUND: Original game bug causes the results of testing the powdery substance
+ // to disappear too quickly. Introduce a delay to allow it to be properly displayed
+ ui._menuCounter = 30;
+ }
+
+ events.setCursor(ARROW);
+}
+
+void Talk::talk(int objNum) {
+ Events &events = *_vm->_events;
+ People &people = *_vm->_people;
+ Scene &scene = *_vm->_scene;
+ UserInterface &ui = *_vm->_ui;
+
+ ui._windowBounds.top = CONTROLS_Y;
+ ui._infoFlag = true;
+ _speaker = SPEAKER_REMOVE;
+
+ Common::String talkFilename = (objNum >= 1000) ? people[objNum - 1000]._npcName : scene._bgShapes[objNum]._name;
+ loadTalkFile(talkFilename);
+
+ // Find the first statement with the correct flags
+ int select = -1;
+ for (uint idx = 0; idx < _statements.size(); ++idx) {
+ if (_statements[idx]._talkMap == 0) {
+ select = idx;
+ break;
+ }
+ }
+ if (select == -1)
+ error("No entry matched all required flags");
+
+ // See if the statement is a stealth mode reply
+ Statement &statement = _statements[select];
+ if (statement._statement.hasPrefix("^")) {
+ clearSequences();
+
+ // Start talk in stealth mode
+ _talkStealth = 2;
+
+ talkTo(talkFilename);
+ } else if (statement._statement.hasPrefix("*")) {
+ // Character being spoken to will speak first
+ if (objNum > 1000) {
+ (*static_cast<Tattoo::TattooPeople *>(_vm->_people))[objNum - 1000].walkHolmesToNPC();
+ } else {
+ Object &obj = scene._bgShapes[objNum];
+ clearSequences();
+ pushSequence(_talkTo);
+ setStillSeq(_talkTo);
+
+ events.setCursor(WAIT);
+ if (obj._lookPosition.y != 0)
+ // Need to walk to character first
+ people[HOLMES].walkToCoords(obj._lookPosition, obj._lookPosition._facing);
+ events.setCursor(ARROW);
+ }
+
+ if (!_talkToAbort)
+ talkTo(talkFilename);
+ } else {
+ // Holmes will be speaking first
+ _talkToFlag = false;
+
+ if (objNum > 1000) {
+ (*static_cast<Tattoo::TattooPeople *>(_vm->_people))[objNum - 1000].walkHolmesToNPC();
+ } else {
+ Object &obj = scene._bgShapes[objNum];
+ clearSequences();
+ pushSequence(_talkTo);
+ setStillSeq(_talkTo);
+
+ events.setCursor(WAIT);
+ if (obj._lookPosition.y != 0)
+ // Walk over to person to talk to
+ people[HOLMES].walkToCoords(obj._lookPosition, obj._lookPosition._facing);
+ events.setCursor(ARROW);
+ }
+
+ if (!_talkToAbort) {
+ // See if walking over triggered a conversation
+ if (_talkToFlag) {
+ if (_talkToFlag == 1) {
+ events.setCursor(ARROW);
+ // _sequenceStack._count = 1;
+ pullSequence();
+ }
+ } else {
+ _talkIndex = select;
+ showTalk();
+
+ // Break out of loop now that we're waiting for player input
+ events.setCursor(ARROW);
+ }
+
+ _talkToFlag = -1;
+ }
+ }
+}
+
+void Talk::freeTalkVars() {
+ _statements.clear();
+}
+
+void Talk::loadTalkFile(const Common::String &filename) {
+ People &people = *_vm->_people;
+ Resources &res = *_vm->_res;
+ Sound &sound = *_vm->_sound;
+
+ // Save a copy of the talk filename
+ _scriptName = filename;
+
+ // Check for an existing person being talked to
+ _talkTo = -1;
+ for (int idx = 0; idx < (int)people._characters.size(); ++idx) {
+ if (!scumm_strnicmp(filename.c_str(), people._characters[idx]._portrait, 4)) {
+ _talkTo = idx;
+ break;
+ }
+ }
+
+ const char *chP = strchr(filename.c_str(), '.');
+ Common::String talkFile = chP ? Common::String(filename.c_str(), chP) + ".tlk" :
+ Common::String(filename.c_str(), filename.c_str() + 7) + ".tlk";
+
+ // Open the talk file for reading
+ Common::SeekableReadStream *talkStream = res.load(talkFile);
+ _converseNum = res.resourceIndex();
+ talkStream->skip(2); // Skip talk file version num
+
+ _statements.resize(talkStream->readByte());
+ for (uint idx = 0; idx < _statements.size(); ++idx)
+ _statements[idx].load(*talkStream, IS_ROSE_TATTOO);
+
+ delete talkStream;
+
+ if (!sound._voices)
+ stripVoiceCommands();
+ setTalkMap();
+}
+
+void Talk::stripVoiceCommands() {
+ for (uint sIdx = 0; sIdx < _statements.size(); ++sIdx) {
+ Statement &statement = _statements[sIdx];
+
+ // Scan for an sound effect byte, which indicates to play a sound
+ for (uint idx = 0; idx < statement._reply.size(); ++idx) {
+ if (statement._reply[idx] == (char)_opcodes[OP_SFX_COMMAND]) {
+ // Replace instruction character with a space, and delete the
+ // rest of the name following it
+ statement._reply = Common::String(statement._reply.c_str(),
+ statement._reply.c_str() + idx) + " " +
+ Common::String(statement._reply.c_str() + 9);
+ }
+ }
+
+ // Ensure the last character of the reply is not a space from the prior
+ // conversion loop, to avoid any issues with the space ever causing a page
+ // wrap, and ending up displaying another empty page
+ while (statement._reply.lastChar() == ' ')
+ statement._reply.deleteLastChar();
+ }
+}
+
+void Talk::setTalkMap() {
+ int statementNum = 0;
+
+ for (uint sIdx = 0; sIdx < _statements.size(); ++sIdx) {
+ Statement &statement = _statements[sIdx];
+
+ // Set up talk map entry for the statement
+ bool valid = true;
+ for (uint idx = 0; idx < statement._required.size(); ++idx) {
+ if (!_vm->readFlags(statement._required[idx]))
+ valid = false;
+ }
+
+ statement._talkMap = valid ? statementNum++ : -1;
+ }
+}
+
+void Talk::clearSequences() {
+ _sequenceStack.clear();
+}
+
+void Talk::pullSequence() {
+ Scene &scene = *_vm->_scene;
+
+ if (_sequenceStack.empty() || IS_ROSE_TATTOO)
+ return;
+
+ SequenceEntry seq = _sequenceStack.pop();
+ if (seq._objNum != -1) {
+ Object &obj = scene._bgShapes[seq._objNum];
+
+ if (obj._seqSize < MAX_TALK_SEQUENCES) {
+ warning("Tried to restore too few frames");
+ } else {
+ for (int idx = 0; idx < MAX_TALK_SEQUENCES; ++idx)
+ obj._sequences[idx] = seq._sequences[idx];
+
+ obj._frameNumber = seq._frameNumber;
+ obj._seqTo = seq._seqTo;
+ }
+ }
+}
+
+void Talk::pushSequence(int speaker) {
+ People &people = *_vm->_people;
+ Scene &scene = *_vm->_scene;
+
+ // Only proceed if a speaker is specified
+ if (speaker == -1 || IS_ROSE_TATTOO)
+ return;
+
+ SequenceEntry seqEntry;
+ if (!speaker) {
+ seqEntry._objNum = -1;
+ } else {
+ seqEntry._objNum = people.findSpeaker(speaker);
+
+ if (seqEntry._objNum != -1) {
+ Object &obj = scene._bgShapes[seqEntry._objNum];
+ for (uint idx = 0; idx < MAX_TALK_SEQUENCES; ++idx)
+ seqEntry._sequences.push_back(obj._sequences[idx]);
+
+ seqEntry._frameNumber = obj._frameNumber;
+ seqEntry._seqTo = obj._seqTo;
+ }
+ }
+
+ _sequenceStack.push(seqEntry);
+ if (_scriptStack.size() >= 5)
+ error("script stack overflow");
+}
+
+void Talk::pushTalkSequence(Object *obj) {
+ // Check if the shape is already on the stack
+ for (uint idx = 0; idx < TALK_SEQUENCE_STACK_SIZE; ++idx) {
+ if (_talkSequenceStack[idx]._obj == obj)
+ return;
+ }
+
+ // Find a free slot and save the details in it
+ for (uint idx = 0; idx < TALK_SEQUENCE_STACK_SIZE; ++idx) {
+ TalkSequence &ts = _talkSequenceStack[idx];
+ if (ts._obj == nullptr) {
+ ts._obj = obj;
+ ts._frameNumber = obj->_frameNumber;
+ ts._sequenceNumber = obj->_sequenceNumber;
+ ts._seqStack = obj->_seqStack;
+ ts._seqTo = obj->_seqTo;
+ ts._seqCounter = obj->_seqCounter;
+ ts._seqCounter2 = obj->_seqCounter2;
+ return;
+ }
+ }
+
+ error("Ran out of talk sequence stack space");
+}
+
+void Talk::setStillSeq(int speaker) {
+ People &people = *_vm->_people;
+ Scene &scene = *_vm->_scene;
+
+ // Don't bother doing anything if no specific speaker is specified
+ if (speaker == -1)
+ return;
+
+ if (speaker) {
+ int objNum = people.findSpeaker(speaker);
+ if (objNum != -1) {
+ Object &obj = scene._bgShapes[objNum];
+
+ if (obj._seqSize < MAX_TALK_SEQUENCES) {
+ warning("Tried to copy too few still frames");
+ } else {
+ for (uint idx = 0; idx < MAX_TALK_SEQUENCES; ++idx) {
+ obj._sequences[idx] = people._characters[speaker]._stillSequences[idx];
+ if (idx > 0 && !people._characters[speaker]._talkSequences[idx] &&
+ !people._characters[speaker]._talkSequences[idx - 1])
+ break;
+ }
+
+ obj._frameNumber = 0;
+ obj._seqTo = 0;
+ }
+ }
+ }
+}
+
+void Talk::doScript(const Common::String &script) {
+ People &people = *_vm->_people;
+ Scene &scene = *_vm->_scene;
+ Screen &screen = *_vm->_screen;
+ UserInterface &ui = *_vm->_ui;
+
+ _savedSequences.clear();
+
+ _scriptStart = (const byte *)script.c_str();
+ _scriptEnd = _scriptStart + script.size();
+ const byte *str = _scriptStart;
+ _charCount = 0;
+ _line = 0;
+ _wait = 0;
+ _pauseFlag = false;
+ _seqCount = 0;
+ _noTextYet = true;
+ _endStr = false;
+ _openTalkWindow = false;
+
+ if (IS_SERRATED_SCALPEL)
+ _yp = CONTROLS_Y + 12;
+ else
+ _yp = (_talkTo == -1) ? 5 : screen.fontHeight() + 11;
+
+ if (IS_ROSE_TATTOO) {
+ for (int idx = 0; idx < MAX_CHARACTERS; ++idx) {
+ Tattoo::TattooPerson &p = (*(Tattoo::TattooPeople *)_vm->_people)[idx];
+ p._savedNpcSequence = p._sequenceNumber;
+ p._savedNpcFrame = p._frameNumber;
+ }
+ }
+
+ if (_scriptMoreFlag) {
+ _scriptMoreFlag = 0;
+ str = _scriptStart + _scriptSaveIndex;
+ }
+
+ // Check if the script begins with a Stealh Mode Active command
+ if (str[0] == _opcodes[OP_STEALTH_MODE_ACTIVE] || _talkStealth) {
+ _talkStealth = 2;
+ _speaker |= SPEAKER_REMOVE;
+ } else {
+ pushSequence(_speaker);
+ if (IS_SERRATED_SCALPEL || ui._windowOpen)
+ ui.clearWindow();
+
+ // Need to switch speakers?
+ if (str[0] == _opcodes[OP_SWITCH_SPEAKER]) {
+ _speaker = str[1] - 1;
+ str += IS_SERRATED_SCALPEL ? 2 : 3;
+
+ pullSequence();
+ pushSequence(_speaker);
+ people.setTalkSequence(_speaker);
+ } else {
+ people.setTalkSequence(_speaker);
+ }
+
+ if (IS_SERRATED_SCALPEL) {
+ // Assign portrait location?
+ if (str[0] == _opcodes[OP_ASSIGN_PORTRAIT_LOCATION]) {
+ switch (str[1] & 15) {
+ case 1:
+ people._portraitSide = 20;
+ break;
+ case 2:
+ people._portraitSide = 220;
+ break;
+ case 3:
+ people._portraitSide = 120;
+ break;
+ default:
+ break;
+
+ }
+
+ if (str[1] > 15)
+ people._speakerFlip = true;
+ str += 2;
+ }
+
+ if (IS_SERRATED_SCALPEL) {
+ // Remove portrait?
+ if ( str[0] == _opcodes[OP_REMOVE_PORTRAIT]) {
+ _speaker = -1;
+ } else {
+ // Nope, so set the first speaker
+ ((Scalpel::ScalpelPeople *)_vm->_people)->setTalking(_speaker);
+ }
+ }
+ }
+ }
+
+ bool trigger3DOMovie = true;
+ uint16 subIndex = 1;
+
+ do {
+ Common::String tempString;
+ _wait = 0;
+
+ byte c = str[0];
+ if (!c) {
+ _endStr = true;
+ } else if (c == '{') {
+ // Start of comment, so skip over it
+ while (*str++ != '}')
+ ;
+ } else if (isOpcode(c)) {
+ // Handle control code
+ switch ((this->*_opcodeTable[c - _opcodes[0]])(str)) {
+ case RET_EXIT:
+ return;
+ case RET_CONTINUE:
+ continue;
+ case OP_SWITCH_SPEAKER:
+ trigger3DOMovie = true;
+ break;
+ default:
+ break;
+ }
+
+ ++str;
+ } else {
+ // Handle drawing the talk interface with the text
+ talkInterface(str);
+ }
+
+ // Open window if it wasn't already open, and text has already been printed
+ if ((_openTalkWindow && _wait) || (_openTalkWindow && str[0] >= _opcodes[0] && str[0] != _opcodes[OP_END_TEXT_WINDOW])) {
+ if (!ui._slideWindows) {
+ screen.slamRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
+ } else {
+ ui.summonWindow();
+ }
+
+ ui._windowOpen = true;
+ _openTalkWindow = false;
+ }
+
+ if ((_wait) && (trigger3DOMovie)) {
+ // Trigger to play 3DO movie
+ talk3DOMovieTrigger(subIndex);
+
+ trigger3DOMovie = false; // wait for next switch speaker opcode
+ subIndex++;
+ }
+
+ if (_wait)
+ // Handling pausing
+ talkWait(str);
+ } while (!_vm->shouldQuit() && !_endStr);
+
+ if (_wait != -1) {
+ for (int ssIndex = 0; ssIndex < (int)_savedSequences.size(); ++ssIndex) {
+ SequenceEntry &seq = _savedSequences[ssIndex];
+ Object &object = scene._bgShapes[seq._objNum];
+
+ for (uint idx = 0; idx < seq._sequences.size(); ++idx)
+ object._sequences[idx] = seq._sequences[idx];
+ object._frameNumber = seq._frameNumber;
+ object._seqTo = seq._seqTo;
+ }
+
+ pullSequence();
+
+ if (IS_SERRATED_SCALPEL) {
+ if (_speaker >= 0 && _speaker < SPEAKER_REMOVE)
+ people.clearTalking();
+ } else {
+ static_cast<Tattoo::TattooPeople *>(_vm->_people)->pullNPCPaths();
+ }
+ }
+}
+
+int Talk::waitForMore(int delay) {
+ Events &events = *_vm->_events;
+ People &people = *_vm->_people;
+ Scene &scene = *_vm->_scene;
+ Sound &sound = *_vm->_sound;
+ UserInterface &ui = *_vm->_ui;
+ CursorId oldCursor = events.getCursor();
+ int key2 = 254;
+
+ // Unless we're in stealth mode, show the appropriate cursor
+ if (!_talkStealth) {
+ events.setCursor(ui._lookScriptFlag ? MAGNIFY : ARROW);
+ }
+
+ do {
+ if (sound._speechOn && !*sound._soundIsOn)
+ people._portrait._frameNumber = -1;
+
+ scene.doBgAnim();
+
+ // If talkTo call was done via doBgAnim, abort out of talk quietly
+ if (_talkToAbort) {
+ key2 = -1;
+ events._released = true;
+ } else {
+ // See if there's been a button press
+ events.setButtonState();
+
+ if (events.kbHit()) {
+ Common::KeyState keyState = events.getKey();
+ if (keyState.keycode == Common::KEYCODE_ESCAPE) {
+ if (IS_ROSE_TATTOO && static_cast<Tattoo::TattooEngine *>(_vm)->_runningProlog) {
+ // Skip out of the introduction
+ _vm->setFlags(-76);
+ _vm->setFlags(396);
+ scene._goToScene = 1;
+ }
+ break;
+
+ } else if (Common::isPrint(keyState.ascii))
+ key2 = keyState.keycode;
+ }
+
+ if (_talkStealth) {
+ key2 = 254;
+ events._released = false;
+ }
+ }
+
+ // Count down the delay
+ if ((delay > 0 && !ui._invLookFlag && !ui._lookScriptFlag) || _talkStealth)
+ --delay;
+
+ // If there are voices playing, reset delay so that they keep playing
+ if (sound._voices == 2 && *sound._soundIsOn)
+ delay = 0;
+ } while (!_vm->shouldQuit() && key2 == 254 && (delay || (sound._voices == 2 && *sound._soundIsOn))
+ && !events._released && !events._rightReleased);
+
+ // If voices was set 2 to indicate a voice file was place, then reset it back to 1
+ if (sound._voices == 2)
+ sound._voices = 1;
+
+ if (delay > 0 && sound._diskSoundPlaying)
+ sound.stopSndFuncPtr(0, 0);
+
+ // Adjust _talkStealth mode:
+ // mode 1 - It was by a pause without stealth being on before the pause, so reset back to 0
+ // mode 3 - It was set by a pause with stealth being on before the pause, to set it to active
+ // mode 0/2 (Inactive/active) No change
+ switch (_talkStealth) {
+ case 1:
+ _talkStealth = 0;
+ break;
+ case 2:
+ _talkStealth = 2;
+ break;
+ default:
+ break;
+ }
+
+ sound._speechOn = false;
+ events.setCursor(_talkToAbort ? ARROW : oldCursor);
+ events._pressed = events._released = false;
+
+ return key2;
+}
+
+bool Talk::isOpcode(byte checkCharacter) {
+ if ((checkCharacter < _opcodes[0]) || (checkCharacter >= (_opcodes[0] + 99)))
+ return false; // outside of range
+ if (_opcodeTable[checkCharacter - _opcodes[0]])
+ return true;
+ return false;
+}
+
+void Talk::popStack() {
+ if (!_scriptStack.empty()) {
+ ScriptStackEntry scriptEntry = _scriptStack.pop();
+ _scriptName = scriptEntry._name;
+ _scriptSaveIndex = scriptEntry._currentIndex;
+ _scriptSelect = scriptEntry._select;
+ _scriptMoreFlag = 1;
+ }
+}
+
+void Talk::synchronize(Serializer &s) {
+ for (uint idx = 0; idx < _talkHistory.size(); ++idx) {
+ TalkHistoryEntry &he = _talkHistory[idx];
+
+ for (int flag = 0; flag < 16; ++flag)
+ s.syncAsByte(he._data[flag]);
+ }
+}
+
+OpcodeReturn Talk::cmdAddItemToInventory(const byte *&str) {
+ Inventory &inv = *_vm->_inventory;
+ Common::String tempString;
+
+ ++str;
+ for (int idx = 0; idx < str[0]; ++idx)
+ tempString += str[idx + 1];
+ str += str[0];
+
+ inv.putNameInInventory(tempString);
+ return RET_SUCCESS;
+}
+
+OpcodeReturn Talk::cmdAdjustObjectSequence(const byte *&str) {
+ Scene &scene = *_vm->_scene;
+ Common::String tempString;
+
+ // Get the name of the object to adjust
+ ++str;
+ for (int idx = 0; idx < (str[0] & 127); ++idx)
+ tempString += str[idx + 2];
+
+ // Scan for object
+ int objId = -1;
+ for (uint idx = 0; idx < scene._bgShapes.size(); ++idx) {
+ if (tempString.equalsIgnoreCase(scene._bgShapes[idx]._name))
+ objId = idx;
+ }
+ if (objId == -1)
+ error("Could not find object %s to change", tempString.c_str());
+
+ // Should the script be overwritten?
+ if (str[0] > 0x80) {
+ // Save the current sequence
+ _savedSequences.push(SequenceEntry());
+ SequenceEntry &seqEntry = _savedSequences.top();
+ seqEntry._objNum = objId;
+ seqEntry._seqTo = scene._bgShapes[objId]._seqTo;
+ for (uint idx = 0; idx < scene._bgShapes[objId]._seqSize; ++idx)
+ seqEntry._sequences.push_back(scene._bgShapes[objId]._sequences[idx]);
+ }
+
+ // Get number of bytes to change
+ _seqCount = str[1];
+ str += (str[0] & 127) + 2;
+
+ // Copy in the new sequence
+ for (int idx = 0; idx < _seqCount; ++idx, ++str)
+ scene._bgShapes[objId]._sequences[idx] = str[0] - 1;
+
+ // Reset object back to beginning of new sequence
+ scene._bgShapes[objId]._frameNumber = 0;
+
+ return RET_CONTINUE;
+}
+
+OpcodeReturn Talk::cmdBanishWindow(const byte *&str) {
+ People &people = *_vm->_people;
+ UserInterface &ui = *_vm->_ui;
+
+ if (!(_speaker & SPEAKER_REMOVE))
+ people.clearTalking();
+ pullSequence();
+
+ if (_talkToAbort)
+ return RET_EXIT;
+
+ _speaker |= SPEAKER_REMOVE;
+ ui.banishWindow();
+ ui._menuMode = TALK_MODE;
+ _noTextYet = true;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn Talk::cmdCallTalkFile(const byte *&str) {
+ Common::String tempString;
+
+ ++str;
+ for (int idx = 0; idx < 8 && str[idx] != '~'; ++idx)
+ tempString += str[idx];
+ str += 8;
+
+ int scriptCurrentIndex = str - _scriptStart;
+
+ // Save the current script position and new talk file
+ if (_scriptStack.size() < 9) {
+ ScriptStackEntry rec1;
+ rec1._name = _scriptName;
+ rec1._currentIndex = scriptCurrentIndex;
+ rec1._select = _scriptSelect;
+ _scriptStack.push(rec1);
+
+ // Push the new talk file onto the stack
+ ScriptStackEntry rec2;
+ rec2._name = tempString;
+ rec2._currentIndex = 0;
+ rec2._select = 100;
+ _scriptStack.push(rec2);
+ }
+ else {
+ error("Script stack overflow");
+ }
+
+ _scriptMoreFlag = 1;
+ _endStr = true;
+ _wait = 0;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn Talk::cmdDisableEndKey(const byte *&str) {
+ _vm->_ui->_endKeyActive = false;
+ return RET_SUCCESS;
+}
+
+OpcodeReturn Talk::cmdEnableEndKey(const byte *&str) {
+ _vm->_ui->_endKeyActive = true;
+ return RET_SUCCESS;
+}
+
+OpcodeReturn Talk::cmdEndTextWindow(const byte *&str) {
+ return RET_SUCCESS;
+}
+
+OpcodeReturn Talk::cmdHolmesOff(const byte *&str) {
+ People &people = *_vm->_people;
+ people[HOLMES]._type = REMOVE;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn Talk::cmdHolmesOn(const byte *&str) {
+ People &people = *_vm->_people;
+ people[HOLMES]._type = CHARACTER;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn Talk::cmdPause(const byte *&str) {
+ _charCount = *++str;
+ _wait = _pauseFlag = true;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn Talk::cmdPauseWithoutControl(const byte *&str) {
+ Events &events = *_vm->_events;
+ Scene &scene = *_vm->_scene;
+ ++str;
+
+ for (int idx = 0; idx < (str[0] - 1); ++idx) {
+ scene.doBgAnim();
+ if (_talkToAbort)
+ return RET_EXIT;
+
+ // Check for button press
+ events.pollEvents();
+ events.setButtonState();
+ }
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn Talk::cmdRemoveItemFromInventory(const byte *&str) {
+ Inventory &inv = *_vm->_inventory;
+ Common::String tempString;
+
+ ++str;
+ for (int idx = 0; idx < str[0]; ++idx)
+ tempString += str[idx + 1];
+ str += str[0];
+
+ inv.deleteItemFromInventory(tempString);
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn Talk::cmdRunCAnimation(const byte *&str) {
+ Scene &scene = *_vm->_scene;
+
+ ++str;
+ scene.startCAnim((str[0] - 1) & 127, (str[0] & 0x80) ? -1 : 1);
+ if (_talkToAbort)
+ return RET_EXIT;
+
+ // Check if next character is changing side or changing portrait
+ if (_charCount && (str[1] == _opcodes[OP_SWITCH_SPEAKER] || str[1] == _opcodes[OP_ASSIGN_PORTRAIT_LOCATION]))
+ _wait = 1;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn Talk::cmdSetFlag(const byte *&str) {
+ ++str;
+ int flag1 = (str[0] - 1) * 256 + str[1] - 1 - (str[1] == 1 ? 1 : 0);
+ int flag = (flag1 & 0x3fff) * (flag1 >= 0x4000 ? -1 : 1);
+ _vm->setFlags(flag);
+ ++str;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn Talk::cmdSetObject(const byte *&str) {
+ Scene &scene = *_vm->_scene;
+ Common::String tempString;
+
+ ++str;
+ for (int idx = 0; idx < (str[0] & 127); ++idx)
+ tempString += str[idx + 1];
+
+ // Set comparison state according to if we want to hide or unhide
+ bool state = (str[0] >= SPEAKER_REMOVE);
+ str += str[0] & 127;
+
+ for (uint idx = 0; idx < scene._bgShapes.size(); ++idx) {
+ Object &object = scene._bgShapes[idx];
+ if (tempString.equalsIgnoreCase(object._name)) {
+ // Only toggle the object if it's not in the desired state already
+ if ((object._type == HIDDEN && state) || (object._type != HIDDEN && !state))
+ object.toggleHidden();
+ }
+ }
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn Talk::cmdStealthModeActivate(const byte *&str) {
+ _talkStealth = 2;
+ return RET_SUCCESS;
+}
+
+OpcodeReturn Talk::cmdStealthModeDeactivate(const byte *&str) {
+ Events &events = *_vm->_events;
+
+ _talkStealth = 0;
+ events.clearKeyboard();
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn Talk::cmdToggleObject(const byte *&str) {
+ Scene &scene = *_vm->_scene;
+ Common::String tempString;
+
+ ++str;
+ for (int idx = 0; idx < str[0]; ++idx)
+ tempString += str[idx + 1];
+
+ scene.toggleObject(tempString);
+ str += str[0];
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn Talk::cmdWalkToCAnimation(const byte *&str) {
+ People &people = *_vm->_people;
+ Scene &scene = *_vm->_scene;
+
+ ++str;
+ CAnim &animation = scene._cAnim[str[0] - 1];
+ people[HOLMES].walkToCoords(animation._goto[0], animation._goto[0]._facing);
+
+ return _talkToAbort ? RET_EXIT : RET_SUCCESS;
+}
+
+void Talk::talkWait(const byte *&str) {
+ if (!_pauseFlag && _charCount < 160)
+ _charCount = 160;
+
+ _wait = waitForMore(_charCount);
+ if (_wait == -1)
+ _endStr = true;
+
+ // If a key was pressed to finish the window, see if further voice files should be skipped
+ if (_wait >= 0 && _wait < 254) {
+ if (str[0] == _opcodes[OP_SFX_COMMAND])
+ str += 9;
+ }
+
+ _pauseFlag = false;
+}
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h
new file mode 100644
index 0000000000..ddb81f1b04
--- /dev/null
+++ b/engines/sherlock/talk.h
@@ -0,0 +1,381 @@
+/* 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 SHERLOCK_TALK_H
+#define SHERLOCK_TALK_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/rect.h"
+#include "common/stream.h"
+#include "common/stack.h"
+#include "sherlock/objects.h"
+#include "sherlock/saveload.h"
+
+namespace Sherlock {
+
+#define SPEAKER_REMOVE 0x80
+#define MAX_TALK_SEQUENCES 11
+#define TALK_SEQUENCE_STACK_SIZE 20
+
+enum {
+ OP_SWITCH_SPEAKER = 0,
+ OP_RUN_CANIMATION = 1,
+ OP_ASSIGN_PORTRAIT_LOCATION = 2,
+ OP_PAUSE = 3,
+ OP_REMOVE_PORTRAIT = 4,
+ OP_CLEAR_WINDOW = 5,
+ OP_ADJUST_OBJ_SEQUENCE = 6,
+ OP_WALK_TO_COORDS = 7,
+ OP_PAUSE_WITHOUT_CONTROL = 8,
+ OP_BANISH_WINDOW = 9,
+ OP_SUMMON_WINDOW = 10,
+ OP_SET_FLAG = 11,
+ OP_SFX_COMMAND = 12,
+ OP_TOGGLE_OBJECT = 13,
+ OP_STEALTH_MODE_ACTIVE = 14,
+ OP_IF_STATEMENT = 15,
+ OP_ELSE_STATEMENT = 16,
+ OP_END_IF_STATEMENT = 17,
+ OP_STEALTH_MODE_DEACTIVATE = 18,
+ OP_TURN_HOLMES_OFF = 19,
+ OP_TURN_HOLMES_ON = 20,
+ OP_GOTO_SCENE = 21,
+ OP_PLAY_PROLOGUE = 22,
+ OP_ADD_ITEM_TO_INVENTORY = 23,
+ OP_SET_OBJECT = 24,
+ OP_CALL_TALK_FILE = 25,
+ OP_MOVE_MOUSE = 26,
+ OP_DISPLAY_INFO_LINE = 27,
+ OP_CLEAR_INFO_LINE = 28,
+ OP_WALK_TO_CANIMATION = 29,
+ OP_REMOVE_ITEM_FROM_INVENTORY = 30,
+ OP_ENABLE_END_KEY = 31,
+ OP_DISABLE_END_KEY = 32,
+ OP_END_TEXT_WINDOW = 33,
+
+ OP_MOUSE_OFF_ON = 34,
+ OP_SET_WALK_CONTROL = 35,
+ OP_SET_TALK_SEQUENCE = 36,
+ OP_PLAY_SONG = 37,
+ OP_WALK_HOLMES_AND_NPC_TO_CANIM = 38,
+ OP_SET_NPC_PATH_DEST = 39,
+ OP_NEXT_SONG = 40,
+ OP_SET_NPC_PATH_PAUSE = 41,
+ OP_NEED_PASSWORD = 42,
+ OP_SET_SCENE_ENTRY_FLAG = 43,
+ OP_WALK_NPC_TO_CANIM = 44,
+ OP_WALK_NPC_TO_COORDS = 45,
+ OP_WALK_HOLMES_AND_NPC_TO_COORDS = 46,
+ OP_SET_NPC_TALK_FILE = 47,
+ OP_TURN_NPC_OFF = 48,
+ OP_TURN_NPC_ON = 49,
+ OP_NPC_DESC_ON_OFF = 50,
+ OP_NPC_PATH_PAUSE_TAKING_NOTES = 51,
+ OP_NPC_PATH_PAUSE_LOOKING_HOLMES = 52,
+ OP_ENABLE_TALK_INTERRUPTS = 53,
+ OP_DISABLE_TALK_INTERRUPTS = 54,
+ OP_SET_NPC_INFO_LINE = 55,
+ OP_SET_NPC_POSITION = 56,
+ OP_NPC_PATH_LABEL = 57,
+ OP_PATH_GOTO_LABEL = 58,
+ OP_PATH_IF_FLAG_GOTO_LABEL = 59,
+ OP_NPC_WALK_GRAPHICS = 60,
+ OP_NPC_VERB = 61,
+ OP_NPC_VERB_CANIM = 62,
+ OP_NPC_VERB_SCRIPT = 63,
+ OP_RESTORE_PEOPLE_SEQUENCE = 64,
+ OP_NPC_VERB_TARGET = 65,
+ OP_TURN_SOUNDS_OFF = 66,
+ OP_NULL = 67
+};
+
+enum OpcodeReturn { RET_EXIT = -1, RET_SUCCESS = 0, RET_CONTINUE = 1 };
+
+class SherlockEngine;
+class Talk;
+namespace Scalpel { class ScalpelUserInterface; }
+
+typedef OpcodeReturn(Talk::*OpcodeMethod)(const byte *&str);
+
+struct SequenceEntry {
+ int _objNum;
+ Common::Array<byte> _sequences;
+ int _frameNumber;
+ int _seqTo;
+
+ SequenceEntry();
+};
+
+struct ScriptStackEntry {
+ Common::String _name;
+ int _currentIndex;
+ int _select;
+};
+
+struct Statement {
+ Common::String _statement;
+ Common::String _reply;
+ Common::String _linkFile;
+ Common::String _voiceFile;
+ Common::Array<int> _required;
+ Common::Array<int> _modified;
+ int _portraitSide;
+ int _quotient;
+ int _talkMap;
+ Common::Rect _talkPos;
+ int _journal;
+
+ /**
+ * Load the data for a single statement within a talk file
+ */
+ void load(Common::SeekableReadStream &s, bool isRoseTattoo);
+};
+
+struct TalkHistoryEntry {
+ bool _data[16];
+
+ TalkHistoryEntry();
+ bool &operator[](int index) { return _data[index]; }
+};
+
+struct TalkSequence {
+ Object *_obj; // Pointer to the bgshape that these values go to
+ short _frameNumber; // Frame number in frame sequence to draw
+ short _sequenceNumber; // Start frame of sequences that are repeated
+ int _seqStack; // Allows gosubs to return to calling frame
+ int _seqTo; // Allows 1-5, 8-3 type sequences encoded
+ int _seqCounter; // How many times this sequence has been executed
+ int _seqCounter2;
+
+ TalkSequence();
+};
+
+
+class Talk {
+ friend class Scalpel::ScalpelUserInterface;
+private:
+ /**
+ * Remove any voice commands from a loaded statement list
+ */
+ void stripVoiceCommands();
+protected:
+ SherlockEngine *_vm;
+ OpcodeMethod *_opcodeTable;
+ Common::Stack<SequenceEntry> _savedSequences;
+ Common::Stack<SequenceEntry> _sequenceStack;
+ Common::Stack<ScriptStackEntry> _scriptStack;
+ Common::Array<TalkHistoryEntry> _talkHistory;
+ int _speaker;
+ int _talkIndex;
+ int _scriptSelect;
+ int _talkStealth;
+ int _talkToFlag;
+ int _scriptSaveIndex;
+
+ // These fields are used solely by doScript, but are fields because all the script opcodes are
+ // separate methods now, and need access to these fields
+ int _yp;
+ int _charCount;
+ int _line;
+ int _wait;
+ bool _pauseFlag;
+ bool _endStr, _noTextYet;
+ int _seqCount;
+ const byte *_scriptStart, *_scriptEnd;
+protected:
+ Talk(SherlockEngine *vm);
+
+ OpcodeReturn cmdAddItemToInventory(const byte *&str);
+ OpcodeReturn cmdAdjustObjectSequence(const byte *&str);
+ OpcodeReturn cmdBanishWindow(const byte *&str);
+ OpcodeReturn cmdCallTalkFile(const byte *&str);
+ OpcodeReturn cmdDisableEndKey(const byte *&str);
+ OpcodeReturn cmdEnableEndKey(const byte *&str);
+ OpcodeReturn cmdEndTextWindow(const byte *&str);
+ OpcodeReturn cmdHolmesOff(const byte *&str);
+ OpcodeReturn cmdHolmesOn(const byte *&str);
+ OpcodeReturn cmdPause(const byte *&str);
+ OpcodeReturn cmdPauseWithoutControl(const byte *&str);
+ OpcodeReturn cmdRemoveItemFromInventory(const byte *&str);
+ OpcodeReturn cmdRunCAnimation(const byte *&str);
+ OpcodeReturn cmdSetFlag(const byte *&str);
+ OpcodeReturn cmdSetObject(const byte *&str);
+ OpcodeReturn cmdStealthModeActivate(const byte *&str);
+ OpcodeReturn cmdStealthModeDeactivate(const byte *&str);
+ OpcodeReturn cmdToggleObject(const byte *&str);
+ OpcodeReturn cmdWalkToCAnimation(const byte *&str);
+protected:
+ /**
+ * Checks, if a character is an opcode
+ */
+ bool isOpcode(byte checkCharacter);
+
+ /**
+ * Form a table of the display indexes for statements
+ */
+ void setTalkMap();
+
+ /**
+ * When the talk window has been displayed, waits a period of time proportional to
+ * the amount of text that's been displayed
+ */
+ int waitForMore(int delay);
+
+ /**
+ * Display the talk interface window
+ */
+ virtual void talkInterface(const byte *&str) = 0;
+
+ /**
+ * Pause when displaying a talk dialog on-screen
+ */
+ virtual void talkWait(const byte *&str);
+
+ /**
+ * Trigger to play a 3DO talk dialog movie
+ */
+ virtual void talk3DOMovieTrigger(int subIndex) {};
+
+ /**
+ * Show the talk display
+ */
+ virtual void showTalk() = 0;
+public:
+ TalkSequence _talkSequenceStack[TALK_SEQUENCE_STACK_SIZE];
+ Common::Array<Statement> _statements;
+ bool _talkToAbort;
+ int _talkCounter;
+ int _talkTo;
+ int _scriptMoreFlag;
+ bool _openTalkWindow;
+ Common::String _scriptName;
+ bool _moreTalkUp, _moreTalkDown;
+ int _converseNum;
+ const byte *_opcodes;
+public:
+ static Talk *init(SherlockEngine *vm);
+ virtual ~Talk() {}
+
+ /**
+ * Return a given talk statement
+ */
+ Statement &operator[](int idx) { return _statements[idx]; }
+
+ /**
+ * Called whenever a conversation or item script needs to be run. For standard conversations,
+ * it opens up a description window similar to how 'talk' does, but shows a 'reply' directly
+ * instead of waiting for a statement option.
+ * @remarks It seems that at some point, all item scripts were set up to use this as well.
+ * In their case, the conversation display is simply suppressed, and control is passed on to
+ * doScript to implement whatever action is required.
+ */
+ void talkTo(const Common::String &filename);
+
+ /**
+ * Parses a reply for control codes and display text. The found text is printed within
+ * the text window, handles delays, animations, and animating portraits.
+ */
+ void doScript(const Common::String &script);
+
+ /**
+ * Main method for handling conversations when a character to talk to has been
+ * selected. It will make Holmes walk to the person to talk to, draws the
+ * interface window for the conversation and passes on control to give the
+ * player a list of options to make a selection from
+ */
+ void talk(int objNum);
+
+ /**
+ * Clear loaded talk data
+ */
+ void freeTalkVars();
+
+ /**
+ * Opens the talk file 'talk.tlk' and searches the index for the specified
+ * conversation. If found, the data for that conversation is loaded
+ */
+ void loadTalkFile(const Common::String &filename);
+
+ /**
+ * Change the sequence of a background object corresponding to a given speaker.
+ * The new sequence will display the character as "listening"
+ */
+ void setStillSeq(int speaker);
+
+ /**
+ * Clears the stack of pending object sequences associated with speakers in the scene
+ */
+ void clearSequences();
+
+ /**
+ * Pulls a background object sequence from the sequence stack and restore's the
+ * object's sequence
+ */
+ void pullSequence();
+
+ /**
+ * Push the sequence of a background object that's an NPC that needs to be
+ * saved onto the sequence stack.
+ */
+ void pushSequence(int speaker);
+
+ /**
+ * Push a given shape's sequence data onto the Rose Tattoo talk sequence stack
+ */
+ void pushTalkSequence(Object *obj);
+
+ /**
+ * Returns true if the script stack is empty
+ */
+ bool isSequencesEmpty() const { return _scriptStack.empty(); }
+
+ /**
+ * Pops an entry off of the script stack
+ */
+ void popStack();
+
+ /**
+ * Synchronize the data for a savegame
+ */
+ void synchronize(Serializer &s);
+
+ /**
+ * Draws the interface for conversation display
+ */
+ virtual void drawInterface() {}
+
+ /**
+ * Display a list of statements in a window at the bottom of the screen that the
+ * player can select from.
+ */
+ virtual bool displayTalk(bool slamIt) { return false; }
+
+ /**
+ * Prints a single conversation option in the interface window
+ */
+ virtual int talkLine(int lineNum, int stateNum, byte color, int lineY, bool slamIt) { return 0; }
+};
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/tattoo/tattoo.cpp b/engines/sherlock/tattoo/tattoo.cpp
new file mode 100644
index 0000000000..90d2e5d958
--- /dev/null
+++ b/engines/sherlock/tattoo/tattoo.cpp
@@ -0,0 +1,576 @@
+/* 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 "engines/util.h"
+#include "sherlock/tattoo/tattoo.h"
+#include "sherlock/tattoo/tattoo_fixed_text.h"
+#include "sherlock/tattoo/tattoo_resources.h"
+#include "sherlock/tattoo/tattoo_scene.h"
+#include "sherlock/tattoo/tattoo_user_interface.h"
+#include "sherlock/tattoo/widget_base.h"
+#include "sherlock/people.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+TattooEngine::TattooEngine(OSystem *syst, const SherlockGameDescription *gameDesc) :
+ SherlockEngine(syst, gameDesc), _darts(this) {
+ _creditsActive = false;
+ _runningProlog = false;
+ _fastMode = false;
+ _allowFastMode = true;
+ _transparentMenus = true;
+ _creditSpeed = 4;
+}
+
+TattooEngine::~TattooEngine() {
+}
+
+void TattooEngine::showOpening() {
+ // No implementation - opening is done using in-game scenes
+}
+
+void TattooEngine::initialize() {
+ initGraphics(640, 480, true);
+
+ // Initialize the base engine
+ SherlockEngine::initialize();
+
+ // Initialise the global flags
+ _flags.resize(3200);
+ _flags[1] = _flags[4] = _flags[76] = true;
+ _runningProlog = true;
+
+ // Add some more files to the cache
+ _res->addToCache("walk.lib");
+
+ // Set up list of people
+ for (int idx = 0; idx < TATTOO_MAX_PEOPLE; ++idx) {
+ _people->_characters.push_back(PersonData(
+ getLanguage() == Common::FR_FRA ? FRENCH_NAMES[idx] : ENGLISH_NAMES[idx],
+ PORTRAITS[idx], nullptr, nullptr));
+ }
+
+ // Load the inventory
+ loadInventory();
+
+ // Starting scene
+ _scene->_goToScene = STARTING_INTRO_SCENE;
+
+ // Load an initial palette
+ loadInitialPalette();
+}
+
+void TattooEngine::startScene() {
+ TattooUserInterface &ui = *(TattooUserInterface *)_ui;
+
+ switch (_scene->_goToScene) {
+ case 7:
+ case 8:
+ case 18:
+ case 53:
+ case 68:
+ // Load overlay mask(s) for the scene
+ ui._mask = new ImageFile(Common::String::format("res%02d.msk", _scene->_goToScene));
+ if (_scene->_goToScene == 8)
+ ui._mask1 = new ImageFile("res08a.msk");
+ else if (_scene->_goToScene == 18 || _scene->_goToScene == 68)
+ ui._mask1 = new ImageFile("res08a.msk");
+ break;
+
+ case OVERHEAD_MAP:
+ case OVERHEAD_MAP2:
+ // Show the map
+ _scene->_currentScene = OVERHEAD_MAP;
+ _scene->_goToScene = _map->show();
+
+ _people->_savedPos = Common::Point(-1, -1);
+ _people->_savedPos._facing = -1;
+ break;
+
+ case 101:
+ // Darts Board minigame
+ _darts.playDarts(GAME_CRICKET);
+ break;
+
+ case 102:
+ // Darts Board minigame
+ _darts.playDarts(GAME_301);
+ break;
+
+ case 103:
+ // Darts Board minigame
+ _darts.playDarts(GAME_501);
+ break;
+
+ default:
+ break;
+ }
+
+ _events->setCursor(ARROW);
+}
+
+void TattooEngine::loadInitialPalette() {
+ byte palette[768];
+ Common::SeekableReadStream *stream = _res->load("room.pal");
+ stream->read(palette, PALETTE_SIZE);
+ _screen->translatePalette(palette);
+ _screen->setPalette(palette);
+
+ delete stream;
+}
+
+void TattooEngine::loadInventory() {
+ Inventory &inv = *_inventory;
+
+ Common::String inv1 = _fixedText->getText(kFixedText_Inv1);
+ Common::String inv2 = _fixedText->getText(kFixedText_Inv2);
+ Common::String inv3 = _fixedText->getText(kFixedText_Inv3);
+ Common::String inv4 = _fixedText->getText(kFixedText_Inv4);
+ Common::String inv5 = _fixedText->getText(kFixedText_Inv5);
+ Common::String inv6 = _fixedText->getText(kFixedText_Inv6);
+ Common::String inv7 = _fixedText->getText(kFixedText_Inv7);
+ Common::String inv8 = _fixedText->getText(kFixedText_Inv8);
+ Common::String invDesc1 = _fixedText->getText(kFixedText_InvDesc1);
+ Common::String invDesc2 = _fixedText->getText(kFixedText_InvDesc2);
+ Common::String invDesc3 = _fixedText->getText(kFixedText_InvDesc3);
+ Common::String invDesc4 = _fixedText->getText(kFixedText_InvDesc4);
+ Common::String invDesc5 = _fixedText->getText(kFixedText_InvDesc5);
+ Common::String invDesc6 = _fixedText->getText(kFixedText_InvDesc6);
+ Common::String invDesc7 = _fixedText->getText(kFixedText_InvDesc7);
+ Common::String invDesc8 = _fixedText->getText(kFixedText_InvDesc8);
+ Common::String solve = _fixedText->getText(kFixedText_Solve);
+
+ // Initial inventory
+ inv._holdings = 5;
+ inv.push_back(InventoryItem(0, inv1, invDesc1, "_ITEM01A"));
+ inv.push_back(InventoryItem(0, inv2, invDesc2, "_ITEM02A"));
+ inv.push_back(InventoryItem(0, inv3, invDesc3, "_ITEM03A"));
+ inv.push_back(InventoryItem(0, inv4, invDesc4, "_ITEM04A"));
+ inv.push_back(InventoryItem(0, inv5, invDesc5, "_ITEM05A"));
+
+ // Hidden items
+ inv.push_back(InventoryItem(0, inv6, invDesc6, "_PAP212D", solve));
+ inv.push_back(InventoryItem(0, inv7, invDesc7, "_PAP212I"));
+ inv.push_back(InventoryItem(0, inv8, invDesc8, "_LANT02I"));
+}
+
+void TattooEngine::initCredits() {
+ Common::SeekableReadStream *stream = _res->load("credits.txt");
+ int spacing = _screen->fontHeight() * 2;
+ int yp = _screen->h();
+
+ _creditsActive = true;
+ _creditLines.clear();
+
+ while (stream->pos() < stream->size()) {
+ Common::String line = stream->readLine();
+
+ if (line.hasPrefix("Scroll Speed")) {
+ const char *p = line.c_str() + 12;
+ while ((*p < '0') || (*p > '9'))
+ p++;
+
+ _creditSpeed = atoi(p);
+ } else if (line.hasPrefix("Y Spacing")) {
+ const char *p = line.c_str() + 12;
+ while ((*p < '0') || (*p > '9'))
+ p++;
+
+ spacing = atoi(p) + _screen->fontHeight() + 1;
+ } else {
+ int width = _screen->stringWidth(line) + 2;
+
+ _creditLines.push_back(CreditLine(line, Common::Point((_screen->w() - width) / 2 + 1, yp), width));
+ yp += spacing;
+ }
+ }
+
+ // Post-processing for finding split lines
+ for (int l = 0; l < (int)_creditLines.size(); ++l) {
+ CreditLine &cl = _creditLines[l];
+ const char *p = strchr(cl._line.c_str(), '-');
+
+ if (p != nullptr && p[1] == '>') {
+ cl._line2 = Common::String(p + 3);
+ cl._line = Common::String(cl._line.c_str(), p);
+
+ int width = cl._width;
+ int width1 = _screen->stringWidth(cl._line);
+ int width2 = _screen->stringWidth(cl._line2);
+
+ int c = 1;
+ for (int l1 = l + 1; l1 < (int)_creditLines.size(); ++l1) {
+ if ((p = strchr(_creditLines[l1]._line.c_str(), '-')) != nullptr) {
+ if (p[1] == '>') {
+ Common::String line1 = Common::String(_creditLines[l1]._line.c_str(), p);
+ Common::String line2 = Common::String(p + 3);
+
+ width1 = MAX(width1, _screen->stringWidth(line1));
+
+ if (_screen->stringWidth(line2) > width2)
+ width2 = _screen->stringWidth(line2);
+ ++c;
+ } else {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+
+ width = width1 + width2 + _screen->widestChar();
+ width1 += _screen->widestChar();
+
+ for (int l1 = l; l1 < l + c; ++l1) {
+ _creditLines[l1]._width = width;
+ _creditLines[l1]._xOffset = width1;
+ }
+
+ l += c - 1;
+ }
+ }
+
+ delete stream;
+}
+
+void TattooEngine::drawCredits() {
+ Common::Rect screenRect(0, 0, _screen->w(), _screen->h());
+ Surface &bb1 = _screen->_backBuffer1;
+
+ for (uint idx = 0; idx < _creditLines.size() && _creditLines[idx]._position.y < _screen->h(); ++idx) {
+ if (screenRect.contains(_creditLines[idx]._position)) {
+ if (!_creditLines[idx]._line2.empty()) {
+ int x1 = _creditLines[idx]._position.x;
+ int x2 = x1 + _creditLines[idx]._xOffset;
+ const Common::String &line1 = _creditLines[idx]._line;
+ const Common::String &line2 = _creditLines[idx]._line2;
+
+ bb1.writeString(line1, Common::Point(x1 - 1, _creditLines[idx]._position.y - 1), 0);
+ bb1.writeString(line1, Common::Point(x1, _creditLines[idx]._position.y - 1), 0);
+ bb1.writeString(line1, Common::Point(x1 + 1, _creditLines[idx]._position.y - 1), 0);
+
+ bb1.writeString(line1, Common::Point(x1 - 1, _creditLines[idx]._position.y), 0);
+ bb1.writeString(line1, Common::Point(x1 + 1, _creditLines[idx]._position.y), 0);
+
+ bb1.writeString(line1, Common::Point(x1 - 1, _creditLines[idx]._position.y + 1), 0);
+ bb1.writeString(line1, Common::Point(x1, _creditLines[idx]._position.y + 1), 0);
+ bb1.writeString(line1, Common::Point(x1 + 1, _creditLines[idx]._position.y + 1), 0);
+
+ bb1.writeString(line1, Common::Point(x1, _creditLines[idx]._position.y), INFO_TOP);
+
+ bb1.writeString(line2, Common::Point(x2 - 1, _creditLines[idx]._position.y - 1), 0);
+ bb1.writeString(line2, Common::Point(x2, _creditLines[idx]._position.y - 1), 0);
+ bb1.writeString(line2, Common::Point(x2 + 1, _creditLines[idx]._position.y - 1), 0);
+
+ bb1.writeString(line2, Common::Point(x2 - 1, _creditLines[idx]._position.y), 0);
+ bb1.writeString(line2, Common::Point(x2 + 1, _creditLines[idx]._position.y), 0);
+
+ bb1.writeString(line2, Common::Point(x2 - 1, _creditLines[idx]._position.y + 1), 0);
+ bb1.writeString(line2, Common::Point(x2, _creditLines[idx]._position.y + 1), 0);
+ bb1.writeString(line2, Common::Point(x2 + 1, _creditLines[idx]._position.y + 1), 0);
+
+ bb1.writeString(line2, Common::Point(x2, _creditLines[idx]._position.y), INFO_TOP);
+ } else {
+ bb1.writeString(_creditLines[idx]._line, Common::Point(_creditLines[idx]._position.x - 1, _creditLines[idx]._position.y - 1), 0);
+ bb1.writeString(_creditLines[idx]._line, Common::Point(_creditLines[idx]._position.x, _creditLines[idx]._position.y - 1), 0);
+ bb1.writeString(_creditLines[idx]._line, Common::Point(_creditLines[idx]._position.x + 1, _creditLines[idx]._position.y - 1), 0);
+
+ bb1.writeString(_creditLines[idx]._line, Common::Point(_creditLines[idx]._position.x - 1, _creditLines[idx]._position.y), 0);
+ bb1.writeString(_creditLines[idx]._line, Common::Point(_creditLines[idx]._position.x + 1, _creditLines[idx]._position.y), 0);
+
+ bb1.writeString(_creditLines[idx]._line, Common::Point(_creditLines[idx]._position.x - 1, _creditLines[idx]._position.y + 1), 0);
+ bb1.writeString(_creditLines[idx]._line, Common::Point(_creditLines[idx]._position.x, _creditLines[idx]._position.y + 1), 0);
+ bb1.writeString(_creditLines[idx]._line, Common::Point(_creditLines[idx]._position.x + 1, _creditLines[idx]._position.y + 1), 0);
+
+ bb1.writeString(_creditLines[idx]._line, Common::Point(_creditLines[idx]._position.x, _creditLines[idx]._position.y), INFO_TOP);
+ }
+ }
+ }
+}
+
+void TattooEngine::blitCredits() {
+ Common::Rect screenRect(0, -_creditSpeed, _screen->w(), _screen->h() + _creditSpeed);
+
+ for (uint idx = 0; idx < _creditLines.size(); ++idx) {
+ if (screenRect.contains(_creditLines[idx]._position)) {
+ Common::Rect r(_creditLines[idx]._width, _screen->fontHeight() + 2);
+ r.moveTo(_creditLines[idx]._position.x, _creditLines[idx]._position.y - 1);
+
+ _screen->slamRect(r);
+ }
+
+ _creditLines[idx]._position.y -= _creditSpeed;
+ }
+}
+
+void TattooEngine::eraseCredits() {
+ Common::Rect screenRect(0, -_creditSpeed, _screen->w(), _screen->h() + _creditSpeed);
+
+ for (uint idx = 0; idx < _creditLines.size(); ++idx) {
+ if (screenRect.contains(_creditLines[idx]._position)) {
+ Common::Rect r(_creditLines[idx]._width, _screen->fontHeight() + 3);
+ r.moveTo(_creditLines[idx]._position.x, _creditLines[idx]._position.y - 1 + _creditSpeed);
+
+ _screen->restoreBackground(r);
+ }
+ }
+
+ if (_creditLines[_creditLines.size() - 1]._position.y < -_creditSpeed) {
+ _creditLines.clear();
+ _creditsActive = false;
+ setFlags(!3000);
+ }
+}
+
+void TattooEngine::doHangManPuzzle() {
+ char answers[3][10];
+ Common::Point lines[3];
+ const char *solutions[3];
+ int numWide, spacing;
+ ImageFile *paper;
+ Common::Point cursorPos;
+ byte cursorColor = 254;
+ bool solved = false;
+ bool done = false;
+ bool flag = false;
+ size_t i = 0;
+
+ switch (getLanguage()) {
+ case Common::FR_FRA:
+ lines[0] = Common::Point(34, 210);
+ lines[1] = Common::Point(72, 242);
+ lines[2] = Common::Point(34, 276);
+ numWide = 8;
+ spacing = 19;
+ paper = new ImageFile("paperf.vgs");
+ break;
+
+ case Common::DE_DEU:
+ lines[0] = Common::Point(44, 73);
+ lines[1] = Common::Point(56, 169);
+ lines[2] = Common::Point(47, 256);
+ numWide = 7;
+ spacing = 19;
+ paper = new ImageFile("paperg.vgs");
+ break;
+
+ default:
+ // English
+ lines[0] = Common::Point(65, 84);
+ lines[1] = Common::Point(65, 159);
+ lines[2] = Common::Point(75, 234);
+ numWide = 5;
+ spacing = 20;
+ paper = new ImageFile("paper.vgs");
+ break;
+ }
+
+ ImageFrame &paperFrame = (*paper)[0];
+ Common::Rect paperBounds(paperFrame._width, paperFrame._height);
+ paperBounds.moveTo((_screen->w() - paperFrame._width) / 2, (_screen->h() - paperFrame._height) / 2);
+
+ for (int line = 0; line<3; ++line) {
+ lines[line].x += paperBounds.left;
+ lines[line].y += paperBounds.top;
+
+ for (i = 0; i <= (size_t)numWide; ++i)
+ answers[line][i] = 0;
+ }
+
+ _screen->_backBuffer1.blitFrom(paperFrame, Common::Point(paperBounds.left + _screen->_currentScroll.x, 0));
+
+ // If they have already solved the puzzle, put the answer on the graphic
+ if (readFlags(299)) {
+ for (int line = 0; line < 3; ++line) {
+ cursorPos.y = lines[line].y - _screen->fontHeight() - 2;
+
+ for (i = 0; i < strlen(solutions[line]); ++i) {
+ cursorPos.x = lines[line].x + 8 - _screen->widestChar() / 2 + i * spacing;
+ _screen->gPrint(Common::Point(cursorPos.x + _screen->widestChar() / 2 -
+ _screen->charWidth(solutions[line][i]) / 2, cursorPos.y), 0, "%c", solutions[line][i]);
+ }
+ }
+ }
+
+ _screen->slamRect(paperBounds);
+ cursorPos = Common::Point(lines[0].x + 8 - _screen->widestChar() / 2, lines[0].y - _screen->fontHeight() - 2);
+ int line = 0;
+
+ // If they have not solved the puzzle, let them solve it here
+ if (!readFlags(299)) {
+ do {
+ while (!_events->kbHit()) {
+ // See if a key or a mouse button is pressed
+ _events->pollEventsAndWait();
+ _events->setButtonState();
+
+ flag = !flag;
+ if (flag) {
+ _screen->_backBuffer1.fillRect(Common::Rect(cursorPos.x + _screen->_currentScroll.x, cursorPos.y,
+ cursorPos.x + _screen->widestChar() + _screen->_currentScroll.x - 1, cursorPos.y + _screen->fontHeight() - 1), cursorColor);
+ if (answers[line][i])
+ _screen->gPrint(Common::Point(cursorPos.x + _screen->widestChar() / 2 - _screen->charWidth(answers[line][i]) / 2,
+ cursorPos.y), 0, "%c", answers[line][i]);
+ _screen->slamArea(cursorPos.x, cursorPos.y, _screen->widestChar(), _screen->fontHeight());
+ } else {
+ _screen->setDisplayBounds(Common::Rect(cursorPos.x + _screen->_currentScroll.x, cursorPos.y,
+ cursorPos.x + _screen->widestChar() + _screen->_currentScroll.x, cursorPos.y + _screen->fontHeight()));
+ _screen->_backBuffer->blitFrom(paperFrame, Common::Point(paperBounds.left + _screen->_currentScroll.x, paperBounds.top));
+ _screen->resetDisplayBounds();
+
+ if (answers[line][i])
+ _screen->gPrint(Common::Point(cursorPos.x + _screen->widestChar() / 2 - _screen->charWidth(answers[line][i]) / 2,
+ cursorPos.y), 0, "%c", answers[line][i]);
+ _screen->slamArea(cursorPos.x, cursorPos.y, _screen->widestChar(), _screen->fontHeight());
+ }
+
+ if (!_events->kbHit())
+ _events->wait(2);
+ }
+
+ if (_events->kbHit()) {
+ Common::KeyState keyState = _events->getKey();
+
+ if (((toupper(keyState.ascii) >= 'A') && (toupper(keyState.ascii) <= 'Z')) ||
+ ((keyState.ascii >= 128) && ((keyState.ascii <= 168) || (keyState.ascii == 225)))) {
+ answers[line][i] = keyState.ascii;
+ keyState.keycode = Common::KEYCODE_RIGHT;
+ }
+
+ _screen->setDisplayBounds(Common::Rect(cursorPos.x + _screen->_currentScroll.x, cursorPos.y,
+ cursorPos.x + _screen->widestChar() + _screen->_currentScroll.x, cursorPos.y + _screen->fontHeight()));
+ _screen->_backBuffer->blitFrom(paperFrame, Common::Point(paperBounds.left + _screen->_currentScroll.x, paperBounds.top));
+ _screen->resetDisplayBounds();
+
+ if (answers[line][i])
+ _screen->gPrint(Common::Point(cursorPos.x + _screen->widestChar() / 2 - _screen->charWidth(answers[line][i]) / 2,
+ cursorPos.y), 0, "%c", answers[line][i]);
+ _screen->slamArea(cursorPos.x, cursorPos.y, _screen->widestChar(), _screen->fontHeight());
+
+ switch (keyState.keycode) {
+ case Common::KEYCODE_ESCAPE:
+ done = true;
+ break;
+
+ case Common::KEYCODE_UP:
+ case Common::KEYCODE_KP8:
+ if (line) {
+ line--;
+ if (i >= strlen(solutions[line]))
+ i = strlen(solutions[line]) - 1;
+ }
+ break;
+
+ case Common::KEYCODE_DOWN:
+ case Common::KEYCODE_KP2:
+ if (line < 2) {
+ ++line;
+ if (i >= strlen(solutions[line]))
+ i = strlen(solutions[line]) - 1;
+ }
+ break;
+
+ case Common::KEYCODE_BACKSPACE:
+ case Common::KEYCODE_LEFT:
+ case Common::KEYCODE_KP4:
+ if (i)
+ --i;
+ else if (line) {
+ --line;
+
+ i = strlen(solutions[line]) - 1;
+ }
+
+ if (keyState.keycode == Common::KEYCODE_BACKSPACE)
+ answers[line][i] = ' ';
+ break;
+
+ case Common::KEYCODE_RIGHT:
+ case Common::KEYCODE_KP6:
+ if (i < strlen(solutions[line]) - 1)
+ i++;
+ else if (line < 2) {
+ ++line;
+ i = 0;
+ }
+ break;
+
+ case Common::KEYCODE_DELETE:
+ answers[line][i] = ' ';
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ cursorPos.x = lines[line].x + 8 - _screen->widestChar() / 2 + i * spacing;
+ cursorPos.y = lines[line].y - _screen->fontHeight() - 2;
+
+ // See if all of their anwers are correct
+ if (!scumm_stricmp(answers[0], solutions[0]) && !scumm_stricmp(answers[1], solutions[1]) &&
+ !scumm_stricmp(answers[2], solutions[2])) {
+ done = true;
+ solved = true;
+ }
+ } while (!done && !shouldQuit());
+ } else {
+ // They have already solved the puzzle, so just display the solution and wait for a mouse or key click
+ do {
+ _events->pollEventsAndWait();
+ _events->setButtonState();
+
+ if ((_events->kbHit()) || (_events->_released) || (_events->_rightReleased)) {
+ done = true;
+ _events->clearEvents();
+ }
+ } while (!done && !shouldQuit());
+ }
+
+ delete paper;
+ _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(paperBounds.left + _screen->_currentScroll.x, paperBounds.top),
+ Common::Rect(paperBounds.left + _screen->_currentScroll.x, paperBounds.top,
+ paperBounds.right + _screen->_currentScroll.x, paperBounds.bottom));
+ _scene->doBgAnim();
+
+ _screen->slamArea(paperBounds.left + _screen->_currentScroll.x, paperBounds.top,
+ paperBounds.width(), paperBounds.height());
+
+ // Don't call the talk files if the puzzle has already been solved
+ if (readFlags(299))
+ return;
+
+ // If they solved the puzzle correctly, set the solved flag and run the appropriate talk scripts
+ if (solved) {
+ _talk->talkTo("SLVE12S.TLK");
+ _talk->talkTo("WATS12X.TLK");
+ setFlags(299);
+ } else {
+ _talk->talkTo("HOLM12X.TLK");
+ }
+}
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/tattoo/tattoo.h b/engines/sherlock/tattoo/tattoo.h
new file mode 100644
index 0000000000..a9798dce41
--- /dev/null
+++ b/engines/sherlock/tattoo/tattoo.h
@@ -0,0 +1,127 @@
+/* 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 SHERLOCK_TATTOO_H
+#define SHERLOCK_TATTOO_H
+
+#include "sherlock/sherlock.h"
+#include "sherlock/tattoo/tattoo_darts.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+enum {
+ INV_FOREGROUND = 167,
+ INV_BACKGROUND = 1,
+ INFO_FOREGROUND = 233,
+ INFO_BACKGROUND = 239,
+ INFO_TOP = 185,
+ INFO_MIDDLE = 186,
+ INFO_BOTTOM = 188,
+ MENU_BACKGROUND = 225,
+ COMMAND_FOREGROUND = 15,
+ COMMAND_HIGHLIGHTED = 254,
+ COMMAND_NULL = 193,
+ PEN_COLOR = 248,
+ PEN_HIGHLIGHT_COLOR = 129
+};
+
+enum {
+ FLAG_PLAYER_IS_HOLMES = 76,
+ FLAG_ALT_MAP_MUSIC = 525
+};
+
+struct CreditLine {
+ Common::Point _position;
+ int _xOffset;
+ int _width;
+ Common::String _line, _line2;
+
+ CreditLine(const Common::String &line, const Common::Point &pt, int width) :
+ _line(line), _position(pt), _width(width), _xOffset(0) {}
+};
+
+class TattooEngine : public SherlockEngine {
+private:
+ Darts _darts;
+ Common::Array<CreditLine> _creditLines;
+ int _creditSpeed;
+
+ /**
+ * Loads the initial palette for the game
+ */
+ void loadInitialPalette();
+
+ /**
+ * Load the initial inventory
+ */
+ void loadInventory();
+protected:
+ /**
+ * Initialize the engine
+ */
+ virtual void initialize();
+
+ virtual void showOpening();
+
+ /**
+ * Starting a scene within the game
+ */
+ virtual void startScene();
+public:
+ bool _creditsActive;
+ bool _runningProlog;
+ bool _fastMode, _allowFastMode;
+ bool _transparentMenus;
+public:
+ TattooEngine(OSystem *syst, const SherlockGameDescription *gameDesc);
+ virtual ~TattooEngine();
+
+ /**
+ * Initialize and load credit data for display
+ */
+ void initCredits();
+
+ /**
+ * Draw credits on the screen
+ */
+ void drawCredits();
+
+ /**
+ * Blit the drawn credits to the screen
+ */
+ void blitCredits();
+
+ /**
+ * Erase any area of the screen covered by credits
+ */
+ void eraseCredits();
+
+ void doHangManPuzzle();
+};
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/tattoo/tattoo_darts.cpp b/engines/sherlock/tattoo/tattoo_darts.cpp
new file mode 100644
index 0000000000..842320e270
--- /dev/null
+++ b/engines/sherlock/tattoo/tattoo_darts.cpp
@@ -0,0 +1,967 @@
+/* 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 "sherlock/tattoo/tattoo_darts.h"
+#include "sherlock/tattoo/tattoo_fixed_text.h"
+#include "sherlock/tattoo/tattoo.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+enum {
+ DART_COLOR_FORE = 5,
+ PLAYER_COLOR = 11
+};
+
+static const int STATUS_INFO_X = 430;
+static const int STATUS_INFO_Y = 50;
+static const int STATUS_INFO_WIDTH = 205;
+static const int STATUS_INFO_HEIGHT = 330;
+static const int STATUS2_INFO_X = 510;
+static const int STATUS2_X_ADD = STATUS2_INFO_X - STATUS_INFO_X;
+static const int DART_BAR_VX = 10;
+static const int DART_HEIGHT_Y = 121;
+static const int DART_BAR_SIZE = 150;
+static const int DARTBOARD_LEFT = 73;
+static const int DARTBOARD_TOP = 68;
+static const int DARTBOARD_WIDTH = 257;
+static const int DARTBOARD_HEIGHT = 256;
+static const int DARTBOARD_TOTALX = DARTBOARD_WIDTH * 120 / 100;
+static const int DARTBOARD_TOTALY = DARTBOARD_HEIGHT * 120 / 100;
+static const int DARTBOARD_TOTALTOP = DARTBOARD_TOP - DARTBOARD_WIDTH / 10;
+static const int DARTBOARD_TOTALLEFT = DARTBOARD_LEFT - DARTBOARD_HEIGHT / 10;
+static const int CRICKET_VALUE[7] = { 20, 19, 18, 17, 16, 15, 25 };
+
+Darts::Darts(SherlockEngine *vm) : _vm(vm) {
+ _gameType = GAME_301;
+ _hand1 = _hand2 = nullptr;
+ _dartGraphics = nullptr;
+ _dartsLeft = nullptr;
+ _dartMap = nullptr;
+ _dartBoard = nullptr;
+ Common::fill(&_cricketScore[0][0], &_cricketScore[0][7], 0);
+ Common::fill(&_cricketScore[1][0], &_cricketScore[1][7], 0);
+ _score1 = _score2 = 0;
+ _roundNum = 0;
+ _roundScore = 0;
+ _level = 0;
+ _oldDartButtons = false;
+ _handX = 0;
+ _compPlay = 1;
+}
+
+void Darts::playDarts(GameType gameType) {
+ Events &events = *_vm->_events;
+ Screen &screen = *_vm->_screen;
+ int oldFontType = screen.fontNumber();
+ int playerNum = 0;
+ int roundStart, score;
+ int lastDart;
+ int numHits = 0;
+ bool gameOver = false;
+ bool done = false;
+ const char *const NUM_HITS_STR[3] = { "a", FIXED(Double), FIXED(Triple) };
+
+ screen.setFont(7);
+ _spacing = screen.fontHeight() + 2;
+
+ while (!_vm->shouldQuit()) {
+ roundStart = score = (playerNum == 0) ? _score1 : _score2;
+
+ showNames(playerNum);
+ showStatus(playerNum);
+ _roundScore = 0;
+
+ for (int idx = 0; idx < 3; ++idx) {
+ if (_compPlay == 1)
+ lastDart = throwDart(idx + 1, playerNum * 2); /* Throw one dart */
+ else
+ if (_compPlay == 2)
+ lastDart = throwDart(idx + 1, playerNum + 1); /* Throw one dart */
+ else
+ lastDart = throwDart(idx + 1, 0); /* Throw one dart */
+
+ if (_gameType == GAME_301) {
+ score -= lastDart;
+ _roundScore += lastDart;
+ } else {
+ numHits = lastDart >> 16;
+ if (numHits == 0)
+ numHits = 1;
+ if (numHits > 3)
+ numHits = 3;
+
+ lastDart = lastDart & 0xffff;
+ updateCricketScore(playerNum, lastDart, numHits);
+ score = (playerNum == 0) ? _score1 : _score2;
+ }
+
+ if (_gameType == GAME_301) {
+ if (playerNum == 0)
+ _score1 = score;
+ else
+ _score2 = score;
+
+ if (score == 0)
+ // Someone won
+ gameOver = true;
+ } else {
+ // check for cricket game over
+ bool allClosed = true;
+ int nOtherScore;
+
+ for (int y = 0; y < 7; y++) {
+ if (_cricketScore[playerNum][y] < 3)
+ allClosed = false;
+ }
+
+ if (allClosed) {
+ nOtherScore = (playerNum == 0) ? _score2 : _score1;
+ if (score >= nOtherScore)
+ gameOver = true;
+ }
+ }
+
+ // Show scores
+ showStatus(playerNum);
+ screen._backBuffer2.blitFrom(screen._backBuffer1, Common::Point(_dartInfo.left, _dartInfo.top - 1),
+ Common::Rect(_dartInfo.left, _dartInfo.top - 1, _dartInfo.right, _dartInfo.bottom - 1));
+ screen.print(Common::Point(_dartInfo.left, _dartInfo.top), 0, "%s # %d", FIXED(Dart), idx + 1);
+
+ if (_gameType == GAME_301) {
+ if (_vm->getLanguage() == Common::FR_FRA)
+ screen.print(Common::Point(_dartInfo.left, _dartInfo.top + _spacing), 0,
+ "%s %s: %d", FIXED(Scored), FIXED(Points), lastDart);
+ else
+ screen.print(Common::Point(_dartInfo.left, _dartInfo.top + _spacing), 0,
+ "%s %d %s", FIXED(Scored), lastDart, FIXED(Points));
+ } else {
+ if (lastDart != 25)
+ screen.print(Common::Point(_dartInfo.left, _dartInfo.top + _spacing), 0,
+ "%s %s %d", FIXED(Hit), NUM_HITS_STR[numHits - 1], lastDart);
+ else
+ screen.print(Common::Point(_dartInfo.left, _dartInfo.top + _spacing), 0,
+ "%s %s %s", FIXED(Hit), NUM_HITS_STR[numHits - 1], FIXED(Bullseye));
+ }
+
+ if (score != 0 && playerNum == 0 && !gameOver)
+ screen.print(Common::Point(_dartInfo.left, _dartInfo.top + _spacing * 3), 0,
+ "%s", FIXED(PressAKey));
+
+ if (gameOver) {
+ screen.print(Common::Point(_dartInfo.left, _dartInfo.top + _spacing * 3),
+ 0, "%s", FIXED(GameOver));
+ if (playerNum == 0) {
+ screen.print(Common::Point(_dartInfo.left, _dartInfo.top + _spacing * 4), 0,
+ "%s %s", FIXED(Holmes), FIXED(Wins));
+ _vm->setFlagsDirect(531);
+ } else {
+ screen.print(Common::Point(_dartInfo.left, _dartInfo.top + _spacing * 4), 0,
+ "%s %s!", _opponent.c_str(), FIXED(Wins));
+ _vm->setFlagsDirect(530);
+ }
+
+ screen.print(Common::Point(_dartInfo.left, _dartInfo.top + _spacing * 5), 0,
+ "%s", FIXED(PressAKey));
+
+ done = true;
+ idx = 10;
+ } else if (_gameType == GAME_301 && score < 0) {
+ screen.print(Common::Point(_dartInfo.left, _dartInfo.top + _spacing * 2), 0,
+ "%s!", FIXED(Busted));
+
+ // End turn
+ idx = 10;
+ score = roundStart;
+ if (playerNum == 0)
+ _score1 = score;
+ else
+ _score2 = score;
+ }
+
+ // Clear keyboard events
+ events.clearEvents();
+
+ if ((playerNum == 0 && _compPlay == 1) || _compPlay == 0 || done) {
+ if (events.kbHit()) {
+ Common::KeyState keyState = events.getKey();
+ if (keyState.keycode == Common::KEYCODE_ESCAPE) {
+ done = true;
+ idx = 10;
+ }
+ }
+ } else {
+ events.wait(20);
+ }
+
+ screen._backBuffer2.blitFrom(screen._backBuffer1, Common::Point(_dartInfo.left, _dartInfo.top - 1),
+ Common::Rect(_dartInfo.left, _dartInfo.top - 1, _dartInfo.right, _dartInfo.bottom - 1));
+ screen.blitFrom(screen._backBuffer1);
+ }
+
+ playerNum ^= 1;
+ if (!playerNum)
+ ++_roundNum;
+
+ if (!done) {
+ screen._backBuffer2.blitFrom((*_dartBoard)[0], Common::Point(0, 0));
+ screen._backBuffer1.blitFrom(screen._backBuffer2);
+ screen.blitFrom(screen._backBuffer2);
+ }
+ }
+
+ closeDarts();
+ screen.fadeToBlack();
+ screen.setFont(oldFontType);
+}
+
+void Darts::initDarts() {
+ _dartInfo = Common::Rect(430, 50, 430 + 205, 50 + 330);
+
+ if (_gameType == GAME_CRICKET) {
+ _dartInfo = Common::Rect(430, 245, 430 + 205, 245 + 150);
+ }
+
+ Common::fill(&_cricketScore[0][0], &_cricketScore[0][7], 0);
+ Common::fill(&_cricketScore[1][0], &_cricketScore[1][7], 0);
+
+ switch (_gameType) {
+ case GAME_501:
+ _score1 = _score2 = 501;
+ _gameType = GAME_301;
+ break;
+
+ case GAME_301:
+ _score1 = _score2 = 301;
+ break;
+
+ default:
+ // Cricket
+ _score1 = _score2 = 0;
+ break;
+ }
+
+ _roundNum = 1;
+
+ if (_level == 9) {
+ // No computer players
+ _compPlay = 0;
+ _level = 0;
+ } else if (_level == 8) {
+ _level = _vm->getRandomNumber(3);
+ _compPlay = 2;
+ } else {
+ // Check for opponent flags
+ for (int idx = 0; idx < 4; ++idx) {
+ if (_vm->readFlags(314 + idx))
+ _level = idx;
+ }
+ }
+
+ _opponent = FIXED(Jock);
+}
+
+void Darts::loadDarts() {
+ Resources &res = *_vm->_res;
+ Screen &screen = *_vm->_screen;
+ byte palette[PALETTE_SIZE];
+
+ // Load images
+ _hand1 = new ImageFile("hand1.vgs");
+ _hand2 = new ImageFile("hand2.vgs");
+ _dartGraphics = new ImageFile("darts.vgs");
+ _dartsLeft = new ImageFile("DartsLft.vgs");
+ _dartMap = new ImageFile("DartMap.vgs");
+ _dartBoard = new ImageFile("DartBd.vgs");
+
+ // Load and set the palette
+ Common::SeekableReadStream *stream = res.load("DartBoard.pal");
+ stream->read(palette, PALETTE_SIZE);
+ screen.translatePalette(palette);
+ screen.setPalette(palette);
+ delete stream;
+
+ // Load the initial background
+ screen._backBuffer1.blitFrom((*_dartBoard)[0], Common::Point(0, 0));
+ screen._backBuffer2.blitFrom(screen._backBuffer1);
+ screen.blitFrom(screen._backBuffer1);
+}
+
+void Darts::closeDarts() {
+ delete _dartBoard;
+ delete _dartsLeft;
+ delete _dartGraphics;
+ delete _dartMap;
+ delete _hand1;
+ delete _hand2;
+}
+
+void Darts::showNames(int playerNum) {
+ Screen &screen = *_vm->_screen;
+ byte color;
+
+ color = playerNum == 0 ? PLAYER_COLOR : DART_COLOR_FORE;
+ screen.print(Common::Point(STATUS_INFO_X, STATUS_INFO_Y), 0, "%s", FIXED(Holmes));
+ screen._backBuffer1.fillRect(Common::Rect(STATUS_INFO_X, STATUS_INFO_Y + _spacing + 1,
+ STATUS_INFO_X + 50, STATUS_INFO_Y + _spacing + 3), color);
+ screen.fillRect(Common::Rect(STATUS_INFO_X, STATUS_INFO_Y + _spacing + 1,
+ STATUS_INFO_X + 50, STATUS_INFO_Y + _spacing + 3), color);
+
+ color = playerNum == 1 ? PLAYER_COLOR : DART_COLOR_FORE;
+ screen.print(Common::Point(STATUS_INFO_X, STATUS_INFO_Y), 0, "%s", _opponent.c_str());
+ screen._backBuffer1.fillRect(Common::Rect(STATUS2_INFO_X, STATUS_INFO_Y + _spacing + 1,
+ STATUS2_INFO_X + 50, STATUS_INFO_Y + _spacing + 3), color);
+ screen.fillRect(Common::Rect(STATUS2_INFO_X, STATUS_INFO_Y + _spacing + 1,
+ STATUS2_INFO_X + 50, STATUS_INFO_Y + _spacing + 3), color);
+
+ screen._backBuffer2.blitFrom(screen._backBuffer1);
+}
+
+void Darts::showStatus(int playerNum) {
+ Screen &screen = *_vm->_screen;
+ const char *const CRICKET_SCORE_NAME[7] = { "20", "19", "18", "17", "16", "15", FIXED(Bull) };
+
+ screen._backBuffer2.blitFrom(screen._backBuffer1, Common::Point(STATUS_INFO_X, STATUS_INFO_Y + 10),
+ Common::Rect(STATUS_INFO_X, STATUS_INFO_Y + 10, STATUS_INFO_X + STATUS_INFO_WIDTH,
+ STATUS_INFO_Y + STATUS_INFO_HEIGHT - 10));
+ screen.print(Common::Point(STATUS_INFO_X + 30, STATUS_INFO_Y + _spacing + 4), 0, "%d", _score1);
+
+ screen.print(Common::Point(STATUS2_INFO_X + 30, STATUS_INFO_Y + _spacing + 4), 0, "%d", _score2);
+
+ int temp = (_gameType == GAME_CRICKET) ? STATUS_INFO_Y + 10 * _spacing + 5 : STATUS_INFO_Y + 55;
+ screen.print(Common::Point(STATUS_INFO_X, temp), 0, "%s: %d", FIXED(Round), _roundNum);
+
+ if (_gameType == GAME_301) {
+ screen.print(Common::Point(STATUS_INFO_X, STATUS_INFO_Y + 75), 0, "%s: %d", FIXED(TurnTotal), _roundScore);
+ } else {
+ // Show cricket scores
+ for (int x = 0; x < 7; ++x) {
+ screen.print(Common::Point(STATUS_INFO_X, STATUS_INFO_Y + 40 + x * _spacing), 0, "%s:", CRICKET_SCORE_NAME[x]);
+
+ for (int y = 0; y < 2; ++y) {
+ switch (CRICKET_SCORE_NAME[y][x]) {
+ case 1:
+ screen.print(Common::Point(STATUS_INFO_X + 38 + y*STATUS2_X_ADD, STATUS_INFO_Y + 40 + x * _spacing), 0, "/");
+ break;
+ case 2:
+ screen.print(Common::Point(STATUS_INFO_X + 38 + y*STATUS2_X_ADD, STATUS_INFO_Y + 40 + x * _spacing), 0, "X");
+ break;
+ case 3:
+ screen.print(Common::Point(STATUS_INFO_X + 38 + y * STATUS2_X_ADD - 1, STATUS_INFO_Y + 40 + x * _spacing), 0, "X");
+ screen.print(Common::Point(STATUS_INFO_X + 37 + y * STATUS2_X_ADD, STATUS_INFO_Y + 40 + x * _spacing), 0, "O");
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ screen.blitFrom(screen._backBuffer1, Common::Point(STATUS_INFO_X, STATUS_INFO_Y + 10),
+ Common::Rect(STATUS_INFO_X, STATUS_INFO_Y + 10, STATUS_INFO_X + STATUS_INFO_WIDTH,
+ STATUS_INFO_Y + STATUS_INFO_HEIGHT - 10));
+}
+
+void Darts::erasePowerBars() {
+ Screen &screen = *_vm->_screen;
+
+ // Erase the old power bars and replace them with empty ones
+ screen.fillRect(Common::Rect(DART_BAR_VX, DART_HEIGHT_Y, DART_BAR_VX + 9, DART_HEIGHT_Y + DART_BAR_SIZE), 0);
+ screen._backBuffer1.transBlitFrom((*_dartGraphics)[0], Common::Point(DART_BAR_VX - 1, DART_HEIGHT_Y - 1));
+ screen.slamArea(DART_BAR_VX - 1, DART_HEIGHT_Y - 1, 10, DART_BAR_SIZE + 2);
+}
+
+bool Darts::dartHit() {
+ Events &events = *_vm->_events;
+ events.pollEventsAndWait();
+
+ // Keyboard check
+ if (events.kbHit()) {
+ events.clearEvents();
+ return true;
+ }
+
+ bool result = events._pressed && !_oldDartButtons;
+ _oldDartButtons = events._pressed;
+ return result;
+}
+
+int Darts::doPowerBar(const Common::Point &pt, byte color, int goToPower, int orientation) {
+ Events &events = *_vm->_events;
+ Screen &screen = *_vm->_screen;
+ int x = 0;
+
+ events.clearEvents();
+ events.delay(100);
+
+ while (!_vm->shouldQuit()) {
+ if (x >= DART_BAR_SIZE)
+ break;
+
+ if ((goToPower - 1) == x)
+ break;
+ else if (goToPower == 0) {
+ if (dartHit())
+ break;
+ }
+
+ screen._backBuffer1.fillRect(Common::Rect(pt.x, pt.y + DART_BAR_SIZE - 1 - x,
+ pt.x + 8, pt.y + DART_BAR_SIZE - 2 - x), color);
+ screen._backBuffer1.transBlitFrom((*_dartGraphics)[0], Common::Point(pt.x - 1, pt.y - 1));
+ screen.slamArea(pt.x, pt.y + DART_BAR_SIZE - 1 - x, 8, 2);
+
+ if (!(x % 8))
+ events.wait(1);
+
+ x += 1;
+ }
+
+ return MIN(x * 100 / DART_BAR_SIZE, 100);
+}
+
+int Darts::drawHand(int goToPower, int computer) {
+ Events &events = *_vm->_events;
+ Screen &screen = *_vm->_screen;
+ const int HAND_OFFSET[2] = { 72, 44 };
+ ImageFile *hands;
+ int hand;
+
+ goToPower = (goToPower * DARTBOARD_WIDTH) / 150;
+
+ if (!computer) {
+ hand = 0;
+ hands = _hand1;
+ } else {
+ hand = 1;
+ hands = _hand2;
+ }
+
+ _handSize.x = (*hands)[0]._offset.x + (*hands)[0]._width;
+ _handSize.y = (*hands)[0]._offset.y + (*hands)[0]._height;
+
+ // Clear keyboard buffer
+ events.clearEvents();
+ events.delay(100);
+
+ Common::Point pt(DARTBOARD_LEFT - HAND_OFFSET[hand], SHERLOCK_SCREEN_HEIGHT - _handSize.y);
+ int x = 0;
+
+ while (!_vm->shouldQuit()) {
+ if (x >= DARTBOARD_WIDTH)
+ break;
+
+ if ((goToPower - 1) == x)
+ break;
+ else if (goToPower == 0) {
+ if (dartHit())
+ break;
+ }
+
+ screen._backBuffer1.transBlitFrom((*hands)[0], pt);
+ screen.slamArea(pt.x - 1, pt.y, _handSize.x + 1, _handSize.y);
+ screen.restoreBackground(Common::Rect(pt.x, pt.y, pt.x + _handSize.x, pt.y + _handSize.y));
+
+ if (!(x % 8))
+ events.wait(1);
+
+ ++x;
+ ++pt.x;
+ }
+
+ _handX = pt.x - 1;
+
+ return MIN(x * 100 / DARTBOARD_WIDTH, 100);
+}
+
+Common::Point Darts::convertFromScreenToScoreCoords(const Common::Point &pt) const {
+ return Common::Point(CLIP((int)pt.x, 0, DARTBOARD_WIDTH), CLIP((int)pt.y, 0, DARTBOARD_HEIGHT));
+}
+
+int Darts::dartScore(const Common::Point &pt) {
+ Common::Point pos(pt.x - DARTBOARD_LEFT, pt.y - DARTBOARD_TOP);
+ if (pos.x < 0 || pos.y < 0)
+ return 0;
+ int score;
+
+ if (pos.x < DARTBOARD_WIDTH && pos.y < DARTBOARD_HEIGHT) {
+ pos = convertFromScreenToScoreCoords(pos);
+ score = *(const byte *)(*_dartMap)[0]._frame.getBasePtr(pos.x, pos.y);
+
+ if (_gameType == GAME_301) {
+ if (score >= 100) {
+ if (score <= 120)
+ // Hit a double
+ score = (score - 100) * 2;
+ else
+ // Hit a triple
+ score = (score - 120) * 3;
+ }
+ } else if (score >= 100) {
+ if (score >= 120)
+ // Hit a double
+ score = (2 << 16) + (score - 100);
+ else
+ // Hit a triple
+ score = (3 << 16) + (score - 120);
+ }
+ } else {
+ score = 0;
+ }
+
+ return score;
+}
+
+void Darts::drawDartThrow(const Common::Point &dartPos, int computer) {
+ Events &events = *_vm->_events;
+ Screen &screen = *_vm->_screen;
+ int cx, cy;
+ int handCy;
+ int drawX = 0, drawY = 0, oldDrawX = 0, oldDrawY = 0;
+ int xSize = 0, ySize = 0, oldxSize = 0, oldySize = 0;
+ int handOCx, handOCy;
+ int ocx, ocy;
+ int handOldxSize, handOldySize;
+ int delta = 9;
+ int dartNum;
+ int hddy;
+
+ // Draw the animation of the hand throwing the dart first
+ // See which hand animation to use
+ ImageFile &hands = !computer ? *_hand1 : *_hand2;
+ int numFrames = !computer ? 14 : 13;
+
+ ocx = ocy = handOCx = handOCy = 0;
+ oldxSize = oldySize = handOldxSize = handOldySize = 1;
+ cx = dartPos.x;
+ cy = SHERLOCK_SCREEN_HEIGHT - _handSize.y - 20;
+
+ hddy = (cy - dartPos.y) / (numFrames - 7);
+ hddy += 2;
+ hddy = hddy * 10 / 8;
+ if (dartPos.y > 275)
+ hddy += 3;
+
+ for (int idx = 0; idx < numFrames; ++idx) {
+ _handSize.x = hands[idx]._offset.x + hands[idx]._width;
+ _handSize.y = hands[idx]._offset.y + hands[idx]._height;
+ handCy = SHERLOCK_SCREEN_HEIGHT - _handSize.y;
+
+ screen._backBuffer1.transBlitFrom(hands[idx], Common::Point(_handX, handCy));
+ screen.slamArea(_handX, handCy, _handSize.x + 1, _handSize.y);
+ screen.slamArea(handOCx, handOCy, handOldxSize, handOldySize);
+ screen.restoreBackground(Common::Rect(_handX, handCy, _handX + _handSize.x, handCy + _handSize.y));
+
+ handOCx = _handX;
+ handOCy = handCy;
+ handOldxSize = _handSize.x;
+ handOldySize = _handSize.y;
+
+ if (idx > 6) {
+ dartNum = idx - 6;
+ if (computer)
+ dartNum += 19;
+
+ xSize = (*_dartGraphics)[dartNum]._width;
+ ySize = (*_dartGraphics)[dartNum]._height;
+
+ ocx = drawX = cx - (*_dartGraphics)[dartNum]._width / 2;
+ ocy = drawY = cy - (*_dartGraphics)[dartNum]._height;
+
+ // Draw dart
+ screen._backBuffer1.transBlitFrom((*_dartGraphics)[dartNum], dartPos);
+
+ if (drawX < 0) {
+ xSize += drawX;
+ if (xSize < 0)
+ xSize = 1;
+ drawX = 0;
+ }
+
+ if (drawY < 0) {
+ ySize += drawY;
+ if (ySize < 0)
+ ySize = 1;
+ drawY = 0;
+ }
+
+ // Flush the drawn dart to the screen
+ screen.slamArea(drawX, drawY, xSize, ySize);
+ if (oldDrawX != -1)
+ // Flush the erased dart area
+ screen.slamArea(oldDrawX, oldDrawY, oldxSize, oldySize);
+
+ screen._backBuffer2.blitFrom(screen._backBuffer1, Common::Point(drawX, drawY),
+ Common::Rect(drawX, drawY, drawX + xSize, drawY + ySize));
+
+ oldDrawX = drawX;
+ oldDrawY = drawY;
+ oldxSize = xSize;
+ oldySize = ySize;
+
+ cy -= hddy;
+ }
+
+ events.wait(1);
+ }
+
+ // Clear the last little bit of the hand from the screen
+ screen.slamArea(handOCx, handOCy, handOldxSize, handOldySize);
+
+ // Erase the old dart
+ if (oldDrawX != -1)
+ screen.slamArea(oldDrawX, oldDrawY, oldxSize, oldySize);
+
+ screen._backBuffer2.blitFrom(screen._backBuffer1, Common::Point(drawX, drawY),
+ Common::Rect(drawX, drawY, drawX + xSize, drawY + ySize));
+
+ cx = dartPos.x;
+ cy = dartPos.y + 2;
+ oldDrawX = oldDrawY = -1;
+
+ for (int idx = 5; idx <= 23; ++idx) {
+ dartNum = idx - 4;
+ if (computer)
+ dartNum += 19;
+
+ if (idx < 14)
+ cy -= delta--;
+ else
+ if (idx == 14)
+ delta = 1;
+ if (idx > 14)
+ cy += delta++;
+
+ xSize = (*_dartGraphics)[dartNum]._width;
+ ySize = (*_dartGraphics)[dartNum]._height;
+
+ ocx = drawX = cx - (*_dartGraphics)[dartNum]._width / 2;
+ ocy = drawY = cy - (*_dartGraphics)[dartNum]._height;
+
+ screen._backBuffer1.transBlitFrom((*_dartGraphics)[dartNum], Common::Point(drawX, drawY));
+
+ if (drawX < 0) {
+ xSize += drawX;
+ if (xSize < 0)
+ xSize = 1;
+ drawX = 0;
+ }
+
+ if (drawY < 0) {
+ ySize += drawY;
+ if (ySize < 0)
+ ySize = 1;
+ drawY = 0;
+ }
+
+ // flush the dart
+ screen.slamArea(drawX, drawY, xSize, ySize);
+ if (oldDrawX != -1)
+ screen.slamArea(oldDrawX, oldDrawY, oldxSize, oldySize);
+
+ if (idx != 23)
+ screen._backBuffer2.blitFrom(screen._backBuffer1, Common::Point(drawX, drawY),
+ Common::Rect(drawX, drawY, drawX + xSize, drawY + ySize)); // erase dart
+
+ events.wait(1);
+
+ oldDrawX = drawX;
+ oldDrawY = drawY;
+ oldxSize = xSize;
+ oldySize = ySize;
+ }
+
+ dartNum = 19;
+ if (computer)
+ dartNum += 19;
+ xSize = (*_dartGraphics)[dartNum]._width;
+ ySize = (*_dartGraphics)[dartNum]._height;
+
+ // Draw final dart on the board
+ screen._backBuffer1.transBlitFrom((*_dartGraphics)[dartNum], Common::Point(ocx, ocy));
+ screen._backBuffer2.transBlitFrom((*_dartGraphics)[dartNum], Common::Point(ocx, ocy));
+ screen.slamArea(ocx, ocy, xSize, ySize);
+}
+
+int Darts::findNumberOnBoard(int aim, Common::Point &pt) {
+ ImageFrame &img = (*_dartMap)[0];
+
+ if ((aim > 20) && ((aim != 25) && (aim != 50))) {
+ if ((aim <= 40) && ((aim & 1) == 0)) {
+ aim /= 2;
+ aim += 100;
+ } else {
+ aim /= 3;
+ aim += 120;
+ }
+ }
+
+ bool done = false;
+ for (int y = 0; y < img._width && !done; ++y) {
+ for (int x = 0; x < img._height && !done; ++x) {
+ byte score = *(const byte *)img._frame.getBasePtr(x, y);
+
+ if (score == aim) {
+ // Found a match. Aim at non-double/triple numbers whenever possible.
+ // ie. Aim at 18 instead of triple 6 or double 9
+ done = true;
+
+ if (aim < 21) {
+ pt.x = x + 10;
+ pt.y = y + 10;
+
+ score = *(const byte *)img._frame.getBasePtr(x, y);
+ if (score != aim)
+ done = false;
+ } else {
+ // Aiming at double or triple
+ pt.x = x + 3;
+ pt.y = y + 3;
+ }
+ }
+ }
+ }
+
+ pt = convertFromScreenToScoreCoords(pt);
+
+ if (aim == 3)
+ pt.y += 30;
+ if (aim == 17)
+ pt.y += 10;
+
+ if (aim == 15) {
+ pt.y += 5;
+ pt.x += 5;
+ }
+
+ pt.y = DARTBOARD_HEIGHT - pt.y;
+ return done;
+}
+
+void Darts::getComputerNumber(int playerNum, Common::Point &targetPos) {
+ int score;
+ int aim = 0;
+ Common::Point pt;
+ bool done = false;
+ int cricketaimset = false;
+ bool shootBull = false;
+
+ score = (playerNum == 0) ? _score1 : _score2;
+
+ if (_gameType == GAME_301) {
+ // Try to hit number
+ aim = score;
+ if(score > 60)
+ shootBull = true;
+ } else {
+ if (_cricketScore[playerNum][6] < 3) {
+ // shoot at bull first
+ aim = CRICKET_VALUE[6];
+ cricketaimset = true;
+ } else {
+ // Now check and shoot in this order: 20,19,18,17,16,15
+ for (int idx = 0; idx < 7; ++idx) {
+ if (_cricketScore[playerNum][idx] < 3) {
+ aim = CRICKET_VALUE[idx];
+ cricketaimset = true;
+ break;
+ }
+ }
+ }
+
+ if (!cricketaimset) {
+ // Everything is closed
+ // just in case we don't get set in loop below, which should never happen
+ aim = 14;
+ for (int idx = 0; idx < 7; ++idx) {
+ if (_cricketScore[playerNum^1][idx] < 3) {
+ // Opponent has this open
+ aim = CRICKET_VALUE[idx];
+
+ if (idx == 6)
+ shootBull = true;
+ }
+ }
+ }
+ }
+
+ if (shootBull) {
+ // Aim at bulls eye
+ targetPos.x = targetPos.y = 75;
+
+ if (_level <= 1) {
+ if (_vm->getRandomNumber(1) == 1) {
+ targetPos.x += (_vm->getRandomNumber(20)-10);
+ targetPos.y += (_vm->getRandomNumber(20)-10);
+ }
+ }
+ } else {
+ // Loop in case number does not exist on board
+ do {
+ done = findNumberOnBoard(aim, pt);
+ --aim;
+ } while (!done);
+
+ pt.x += DARTBOARD_TOTALLEFT * 70 / 100;
+ pt.y += DARTBOARD_TOTALTOP * 70 / 100;
+
+ // old * 3/2
+ targetPos.x = pt.x * 100 / DARTBOARD_TOTALX * 3 / 2;
+ targetPos.y = pt.y * 100 / DARTBOARD_TOTALY * 3 / 2;
+ }
+
+ // the higher the level, the more accurate the throw
+ int v = _vm->getRandomNumber(9);
+ v += _level * 2;
+
+ if (v <= 2) {
+ targetPos.x += _vm->getRandomNumber(70) - 35;
+ targetPos.y += _vm->getRandomNumber(70) - 35;
+ } else if (v <= 4) {
+ targetPos.x += _vm->getRandomNumber(50) - 25;
+ targetPos.y += _vm->getRandomNumber(50) - 25;
+ } else if (v <= 6) {
+ targetPos.x += _vm->getRandomNumber(30) - 15;
+ targetPos.y += _vm->getRandomNumber(30) - 15;
+ } else if (v <= 8) {
+ targetPos.x += _vm->getRandomNumber(20) -10;
+ targetPos.y += _vm->getRandomNumber(20) -10;
+ } else if (v <= 10) {
+ targetPos.x += _vm->getRandomNumber(11) - 5;
+ targetPos.y += _vm->getRandomNumber(11) - 5;
+ }
+
+ if (targetPos.x < 1)
+ targetPos.x = 1;
+ if (targetPos.y < 1)
+ targetPos.y = 1;
+}
+
+int Darts::throwDart(int dartNum, int computer) {
+ Events &events = *_vm->_events;
+ Screen &screen = *_vm->_screen;
+ int height;
+ int horiz;
+ Common::Point targetPos;
+ Common::String temp;
+
+ /* clear keyboard buffer */
+ events.clearEvents();
+
+ erasePowerBars();
+ screen.print(Common::Point(_dartInfo.left, _dartInfo.top), 0, "%s # %d", FIXED(Dart), dartNum);
+
+ drawDartsLeft(dartNum, computer);
+
+ if (!computer) {
+ screen.print(Common::Point(_dartInfo.left, _dartInfo.top + _spacing), 0, "%s", FIXED(HitAKey));
+ screen.print(Common::Point(_dartInfo.left, _dartInfo.top + _spacing * 2), 0, "%s", FIXED(ToStart));
+ }
+
+ if (!computer) {
+ // Wait for a hit
+ while (!dartHit())
+ ;
+ } else {
+ events.wait(1);
+ }
+
+ drawDartsLeft(dartNum + 1, computer);
+ screen._backBuffer2.blitFrom(screen._backBuffer1, Common::Point(_dartInfo.left, _dartInfo.top - 1),
+ Common::Rect(_dartInfo.left, _dartInfo.top - 1, _dartInfo.right, _dartInfo.bottom - 1));
+ screen.blitFrom(screen._backBuffer1, Common::Point(_dartInfo.left, _dartInfo.top - 1),
+ Common::Rect(_dartInfo.left, _dartInfo.top - 1, _dartInfo.right, _dartInfo.bottom - 1));
+
+ if (computer) {
+ getComputerNumber(computer - 1, targetPos);
+ } else {
+ // Keyboard control
+ targetPos = Common::Point(0, 0);
+ }
+
+ horiz = drawHand(targetPos.x, computer);
+ height = doPowerBar(Common::Point(DART_BAR_VX, DART_HEIGHT_Y), DART_COLOR_FORE, targetPos.y, 1);
+
+ // Invert height
+ height = 101 - height;
+
+ // Copy power bars to the secondary back buffer
+ screen._backBuffer2.blitFrom(screen._backBuffer1, Common::Point(DART_BAR_VX - 1, DART_HEIGHT_Y - 1),
+ Common::Rect(DART_BAR_VX - 1, DART_HEIGHT_Y - 1, DART_BAR_VX - 1 + 10,
+ DART_HEIGHT_Y - 1 + DART_BAR_SIZE + 2));
+
+ Common::Point dartPos(DARTBOARD_TOTALLEFT + horiz*DARTBOARD_TOTALX / 100,
+ DARTBOARD_TOTALTOP + height * DARTBOARD_TOTALY / 100);
+
+ dartPos.x += 2 - _vm->getRandomNumber(4);
+ dartPos.y += 2 - _vm->getRandomNumber(4);
+
+ drawDartThrow(dartPos, computer);
+ return dartScore(dartPos);
+}
+
+void Darts::doCricketScoreHits(int player, int scoreIndex, int numHits) {
+ while (numHits--) {
+ if (_cricketScore[player][scoreIndex] < 3)
+ _cricketScore[player][scoreIndex]++;
+ else if (_cricketScore[player ^ 1][scoreIndex] < 3) {
+ if (player == 0)
+ _score1 += CRICKET_VALUE[scoreIndex];
+ else
+ _score2 += CRICKET_VALUE[scoreIndex];
+ }
+ }
+}
+
+void Darts::updateCricketScore(int player, int dartVal, int multiplier) {
+ if (dartVal < 15)
+ return;
+
+ if (dartVal <= 20)
+ doCricketScoreHits(player, 20 - dartVal, multiplier);
+ else if (dartVal == 25)
+ doCricketScoreHits(player, 6, multiplier);
+}
+
+void Darts::drawDartsLeft(int dartNum, int computer) {
+ Screen &screen = *_vm->_screen;
+ const int DART_X1[3] = { 391, 451, 507 };
+ const int DART_Y1[3] = { 373, 373, 373 };
+ const int DART_X2[3] = { 393, 441, 502 };
+ const int DART_Y2[3] = { 373, 373, 373 };
+
+ screen._backBuffer2.blitFrom(screen._backBuffer1, Common::Point(DART_X1[0], DART_Y1[0]),
+ Common::Rect(DART_X1[0], DART_Y1[0], SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
+
+ for (int idx = 2; idx >= dartNum - 1; --idx) {
+ if (computer)
+ screen._backBuffer1.transBlitFrom((*_dartsLeft)[idx + 3], Common::Point(DART_X2[idx], DART_Y2[idx]));
+ else
+ screen._backBuffer1.transBlitFrom((*_dartsLeft)[idx], Common::Point(DART_X1[idx], DART_Y1[idx]));
+ }
+
+ screen.slamArea(DART_X1[0], DART_Y1[0], SHERLOCK_SCREEN_WIDTH - DART_X1[0], SHERLOCK_SCREEN_HEIGHT - DART_Y1[0]);
+}
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/tattoo/tattoo_darts.h b/engines/sherlock/tattoo/tattoo_darts.h
new file mode 100644
index 0000000000..f65ec19d10
--- /dev/null
+++ b/engines/sherlock/tattoo/tattoo_darts.h
@@ -0,0 +1,172 @@
+/* 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 SHERLOCK_TATTOO_DARTS_H
+#define SHERLOCK_TATTOO_DARTS_H
+
+#include "common/scummsys.h"
+#include "sherlock/image_file.h"
+
+namespace Sherlock {
+
+class SherlockEngine;
+
+namespace Tattoo {
+
+enum GameType { GAME_301, GAME_CRICKET, GAME_501 };
+
+class Darts {
+private:
+ SherlockEngine *_vm;
+ GameType _gameType;
+ ImageFile *_hand1, *_hand2;
+ ImageFile *_dartGraphics;
+ ImageFile *_dartsLeft;
+ ImageFile *_dartMap;
+ ImageFile *_dartBoard;
+ Common::Rect _dartInfo;
+ int _cricketScore[2][7];
+ int _score1, _score2;
+ int _roundNum;
+ int _roundScore;
+ int _level;
+ int _compPlay;
+ Common::String _opponent;
+ int _spacing;
+ bool _oldDartButtons;
+ int _handX;
+ Common::Point _handSize;
+
+ /**
+ * Initialize game variables
+ */
+ void initDarts();
+
+ /**
+ * Load dartboard graphics
+ */
+ void loadDarts();
+
+ /**
+ * Free loaded dart images
+ */
+ void closeDarts();
+
+ /**
+ * Show the player names
+ */
+ void showNames(int playerNum);
+
+ /**
+ * Show the current scores
+ */
+ void showStatus(int playerNum);
+
+ /**
+ * Erases the power bars
+ */
+ void erasePowerBars();
+
+ /**
+ * Returns true if a mouse button or key is pressed
+ */
+ bool dartHit();
+
+ /**
+ * Shows a power bar and increments it until a key or mouse button is pressed. If the bar
+ * reaches the end, it will also end. The reached power bar number is returned.
+ * @param pt Bar position
+ * @param color draw color
+ * @param goToPower If provided, input is ignored, and the bar is increased up to the specified level
+ * @param orientation 0=Horizontal, 1=Vertical
+ */
+ int doPowerBar(const Common::Point &pt, byte color, int goToPower, int orientation);
+
+ /**
+ * This is similar to doPowerBar, except it draws the player's hand moving across the
+ * bottom of the screen to indicate the positioning of the darts
+ */
+ int drawHand(int goToPower, int computer);
+
+ /**
+ * Converts a passed co-ordinates from screen co-ordinates to an offset within the dartboard
+ */
+ Common::Point convertFromScreenToScoreCoords(const Common::Point &pt) const;
+
+ /**
+ * Return the score a dart at the given position will get
+ */
+ int dartScore(const Common::Point &pt);
+
+ /**
+ * Draw a dart travelling to the board
+ */
+ void drawDartThrow(const Common::Point &dartPos, int computer);
+
+ /**
+ * Looks for the passed number on the dartboard. If it finds it, it will return
+ * the co-ordinates of the center of the number
+ */
+ int findNumberOnBoard(int aim, Common::Point &pt);
+
+ /**
+ * Calculates a position for the comptuer wants to throw, and then calculates where they
+ * actually did throw. The computer will not always hit what it's aiming it.
+ */
+ void getComputerNumber(int playerNum, Common::Point &targetPos);
+
+ /**
+ * Throw one dart. If computer is 1 or 2, the computer will throw the dart, and user input
+ * will be ignored.
+ * @param computer 1=1st computer player, 2=2nd computer player
+ */
+ int throwDart(int dartNum, int computer);
+
+ /**
+ * This will update the number of hits for the target score, as well as updating the
+ * score if it's closed
+ */
+ void doCricketScoreHits(int player, int scoreIndex, int numHits);
+
+ /**
+ * Updates the score based upon what the dart hit
+ */
+ void updateCricketScore(int player, int dartVal, int multiplier);
+
+ /**
+ * Draw the darts left
+ */
+ void drawDartsLeft(int dartNum, int computer);
+public:
+ Darts(SherlockEngine *vm);
+
+ /**
+ * Play the darts game
+ */
+ void playDarts(GameType gameType);
+};
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/tattoo/tattoo_debugger.cpp b/engines/sherlock/tattoo/tattoo_debugger.cpp
new file mode 100644
index 0000000000..8d59b4c592
--- /dev/null
+++ b/engines/sherlock/tattoo/tattoo_debugger.cpp
@@ -0,0 +1,35 @@
+/* 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 "sherlock/tattoo/tattoo_debugger.h"
+#include "sherlock/sherlock.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+TattooDebugger::TattooDebugger(SherlockEngine *vm) : Debugger(vm) {
+}
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/tattoo/tattoo_debugger.h b/engines/sherlock/tattoo/tattoo_debugger.h
new file mode 100644
index 0000000000..e729262b11
--- /dev/null
+++ b/engines/sherlock/tattoo/tattoo_debugger.h
@@ -0,0 +1,44 @@
+/* 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 SHERLOCK_TATTOO_DEBUGGER_H
+#define SHERLOCK_TATTOO_DEBUGGER_H
+
+#include "sherlock/debugger.h"
+
+namespace Sherlock {
+
+class SherlockEngine;
+
+namespace Tattoo {
+
+class TattooDebugger : public Debugger {
+public:
+ TattooDebugger(SherlockEngine *vm);
+ virtual ~TattooDebugger() {}
+};
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
+
+#endif /* SHERLOCK_TATTOO_DEBUGGER_H */
diff --git a/engines/sherlock/tattoo/tattoo_fixed_text.cpp b/engines/sherlock/tattoo/tattoo_fixed_text.cpp
new file mode 100644
index 0000000000..72c67570de
--- /dev/null
+++ b/engines/sherlock/tattoo/tattoo_fixed_text.cpp
@@ -0,0 +1,107 @@
+/* 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 "sherlock/tattoo/tattoo_fixed_text.h"
+#include "sherlock/sherlock.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+static const char *const FIXED_TEXT_ENGLISH[] = {
+ "Money",
+ "Card",
+ "Tobacco",
+ "Timetable",
+ "Summons",
+ "Foolscap",
+ "Damp Paper",
+ "Bull's Eye",
+
+ "Money",
+ "Card",
+ "Tobacco",
+ "Timetable",
+ "Summons",
+ "Foolscap",
+ "Foolscap",
+ "Bull's Eye Lantern",
+
+ "Open",
+ "Look",
+ "Talk",
+ "Use",
+ "Journal",
+ "Inventory",
+ "Options",
+ "Solve",
+ "with",
+ "No effect...",
+ "This person has nothing to say at the moment",
+
+ "Close Journal",
+ "Search Journal",
+ "Save Journal",
+ "Abort Search",
+ "Search Backwards",
+ "Search Forwards",
+ "Text Not Found !",
+
+ "Holmes",
+ "Jock",
+ "Bull",
+ "Round",
+ "Turn Total",
+ "Dart",
+ "to start",
+ "Hit a key",
+ "Press a key",
+ "bullseye",
+ "GAME OVER",
+ "BUSTED",
+ "Wins",
+ "Scored",
+ "points",
+ "Hit",
+ "Double",
+ "Triple",
+
+ "Apply",
+ "Water",
+ "Heat"
+};
+
+TattooFixedText::TattooFixedText(SherlockEngine *vm) : FixedText(vm) {
+}
+
+const char *TattooFixedText::getText(int fixedTextId) {
+ return FIXED_TEXT_ENGLISH[fixedTextId];
+}
+
+const Common::String TattooFixedText::getActionMessage(FixedTextActionId actionId, int messageIndex) {
+ return Common::String();
+}
+
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/tattoo/tattoo_fixed_text.h b/engines/sherlock/tattoo/tattoo_fixed_text.h
new file mode 100644
index 0000000000..c26d787095
--- /dev/null
+++ b/engines/sherlock/tattoo/tattoo_fixed_text.h
@@ -0,0 +1,114 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SHERLOCK_TATTOO_FIXED_TEXT_H
+#define SHERLOCK_TATTOO_FIXED_TEXT_H
+
+#include "sherlock/fixed_text.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+enum FixedTextId {
+ kFixedText_Inv1,
+ kFixedText_Inv2,
+ kFixedText_Inv3,
+ kFixedText_Inv4,
+ kFixedText_Inv5,
+ kFixedText_Inv6,
+ kFixedText_Inv7,
+ kFixedText_Inv8,
+ kFixedText_InvDesc1,
+ kFixedText_InvDesc2,
+ kFixedText_InvDesc3,
+ kFixedText_InvDesc4,
+ kFixedText_InvDesc5,
+ kFixedText_InvDesc6,
+ kFixedText_InvDesc7,
+ kFixedText_InvDesc8,
+ kFixedText_Open,
+ kFixedText_Look,
+ kFixedText_Talk,
+ kFixedText_Use,
+ kFixedText_Journal,
+ kFixedText_Inventory,
+ kFixedText_Options,
+ kFixedText_Solve,
+ kFixedText_With,
+ kFixedText_NoEffect,
+ kFixedText_NothingToSay,
+
+ kFixedText_CloseJournal,
+ kFixedText_SearchJournal,
+ kFixedText_SaveJournal,
+ kFixedText_AbortSearch,
+ kFixedText_SearchBackwards,
+ kFixedText_SearchForwards,
+ kFixedText_TextNotFound,
+
+ kFixedText_Holmes,
+ kFixedText_Jock,
+ kFixedText_Bull,
+ kFixedText_Round,
+ kFixedText_TurnTotal,
+ kFixedText_Dart,
+ kFixedText_ToStart,
+ kFixedText_HitAKey,
+ kFixedText_PressAKey,
+ kFixedText_Bullseye,
+ kFixedText_GameOver,
+ kFixedText_Busted,
+ kFixedText_Wins,
+ kFixedText_Scored,
+ kFixedText_Points,
+ kFixedText_Hit,
+ kFixedText_Double,
+ kFixedText_Triple,
+
+ kFixedText_Apply,
+ kFixedText_Water,
+ kFixedText_Heat
+};
+
+class TattooFixedText: public FixedText {
+private:
+public:
+ TattooFixedText(SherlockEngine *vm);
+ virtual ~TattooFixedText() {}
+
+ /**
+ * Gets text
+ */
+ virtual const char *getText(int fixedTextId);
+
+ /**
+ * Get action message
+ */
+ virtual const Common::String getActionMessage(FixedTextActionId actionId, int messageIndex);
+};
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/tattoo/tattoo_inventory.cpp b/engines/sherlock/tattoo/tattoo_inventory.cpp
new file mode 100644
index 0000000000..6bd1822c10
--- /dev/null
+++ b/engines/sherlock/tattoo/tattoo_inventory.cpp
@@ -0,0 +1,63 @@
+/* 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 "sherlock/tattoo/tattoo_inventory.h"
+#include "sherlock/tattoo/tattoo.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+TattooInventory::TattooInventory(SherlockEngine *vm) : Inventory(vm) {
+ _invShapes.resize(8);
+}
+
+TattooInventory::~TattooInventory() {
+}
+
+void TattooInventory::loadInv() {
+ // Exit if the inventory names are already loaded
+ if (_names.size() > 0)
+ return;
+
+ // Load the inventory names
+ Common::SeekableReadStream *stream = _vm->_res->load("invent.txt");
+
+ int count = stream->readByte();
+ char c;
+
+ for (int idx = 0; idx < count; ++idx) {
+ Common::String name;
+ while ((c = stream->readByte()) != 0)
+ name += c;
+
+ _names.push_back(name);
+ }
+
+ delete stream;
+
+ loadGraphics();
+}
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/tattoo/tattoo_inventory.h b/engines/sherlock/tattoo/tattoo_inventory.h
new file mode 100644
index 0000000000..a18324b785
--- /dev/null
+++ b/engines/sherlock/tattoo/tattoo_inventory.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 SHERLOCK_TATTOO_INVENTORY_H
+#define SHERLOCK_TATTOO_INVENTORY_H
+
+#include "sherlock/inventory.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+class TattooInventory : public Inventory {
+public:
+ TattooInventory(SherlockEngine *vm);
+ ~TattooInventory();
+
+ /**
+ * Load the list of names the inventory items correspond to, if not already loaded,
+ * and then calls loadGraphics to load the associated graphics
+ */
+ virtual void loadInv();
+};
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/tattoo/tattoo_journal.cpp b/engines/sherlock/tattoo/tattoo_journal.cpp
new file mode 100644
index 0000000000..6df5ee7458
--- /dev/null
+++ b/engines/sherlock/tattoo/tattoo_journal.cpp
@@ -0,0 +1,900 @@
+/* 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 "sherlock/tattoo/tattoo_journal.h"
+#include "sherlock/tattoo/tattoo_fixed_text.h"
+#include "sherlock/tattoo/tattoo_scene.h"
+#include "sherlock/tattoo/tattoo_user_interface.h"
+#include "sherlock/tattoo/tattoo.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+#define JOURNAL_BAR_WIDTH 450
+
+TattooJournal::TattooJournal(SherlockEngine *vm) : Journal(vm) {
+ _journalImages = nullptr;
+ _selector = _oldSelector = 0;
+ _wait = false;
+ _exitJournal = false;
+ _scrollingTimer = 0;
+ _savedIndex = _savedSub = _savedPage = 0;
+
+ loadLocations();
+}
+
+void TattooJournal::show() {
+ Events &events = *_vm->_events;
+ Resources &res = *_vm->_res;
+ Screen &screen = *_vm->_screen;
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+ byte palette[PALETTE_SIZE];
+
+ // Load journal images
+ _journalImages = new ImageFile("journal.vgs");
+
+ // Load palette
+ Common::SeekableReadStream *stream = res.load("journal.pal");
+ stream->read(palette, PALETTE_SIZE);
+ screen.translatePalette(palette);
+ ui.setupBGArea(palette);
+
+ // Set screen to black, and set background
+ screen._backBuffer1.blitFrom((*_journalImages)[0], Common::Point(0, 0));
+ screen.empty();
+ screen.setPalette(palette);
+
+ if (_journal.empty()) {
+ _up = _down = false;
+ } else {
+ drawJournal(0, 0);
+ }
+ drawControls(0);
+ screen.slamRect(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
+
+ _exitJournal = false;
+ _scrollingTimer = 0;
+
+ do {
+ events.pollEventsAndWait();
+ events.setButtonState();
+ _wait = true;
+
+ handleKeyboardEvents();
+ highlightJournalControls(true);
+
+ handleButtons();
+
+ if (_wait)
+ events.wait(2);
+
+ } while (!_vm->shouldQuit() && !_exitJournal);
+
+ // Clear events
+ events.clearEvents();
+
+ // Free the images
+ delete _journalImages;
+}
+
+void TattooJournal::handleKeyboardEvents() {
+ Events &events = *_vm->_events;
+ Screen &screen = *_vm->_screen;
+ Common::Point mousePos = events.mousePos();
+
+ if (!events.kbHit())
+ return;
+
+ Common::KeyState keyState = events.getKey();
+
+ if (keyState.keycode == Common::KEYCODE_TAB && (keyState.flags & Common::KBD_SHIFT)) {
+ // Shift tab
+ Common::Rect r(JOURNAL_BAR_WIDTH, BUTTON_SIZE + screen.fontHeight() + 13);
+ r.moveTo((SHERLOCK_SCREEN_WIDTH - r.width()) / 2, SHERLOCK_SCREEN_HEIGHT - r.height());
+
+ // See if mouse is over any of the journal controls
+ _selector = -1;
+ if (Common::Rect(r.left + 3, r.top + 3, r.right - 3, r.top + screen.fontHeight() + 4).contains(mousePos))
+ _selector = (mousePos.x - r.left) / (r.width() / 3);
+
+ // If the mouse is not over an option, move the mouse to that it points to the first option
+ if (_selector == -1) {
+ events.warpMouse(Common::Point(r.left + r.width() / 3 - 10, r.top + screen.fontHeight() + 2));
+ } else {
+ if (_selector == 0)
+ _selector = 2;
+ else
+ --_selector;
+
+ events.warpMouse(Common::Point(r.left + (r.width() / 3) * (_selector + 1) - 10, mousePos.y));
+ }
+
+ } else if (keyState.keycode == Common::KEYCODE_PAGEUP || keyState.keycode == Common::KEYCODE_KP9) {
+ // See if they have Shift held down to go forward 10 pages
+ if (keyState.flags & Common::KBD_SHIFT) {
+ if (_page > 1) {
+ // Scroll Up 10 pages if possible
+ if (_page < 11)
+ drawJournal(1, (_page - 1) * LINES_PER_PAGE);
+ else
+ drawJournal(1, 10 * LINES_PER_PAGE);
+
+ drawScrollBar();
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+ _wait = false;
+ }
+ } else {
+ if (_page > 1) {
+ // Scroll Up 1 page
+ drawJournal(1, LINES_PER_PAGE);
+ drawScrollBar();
+ show();
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+ _wait = false;
+ }
+ }
+
+ } else if (keyState.keycode == Common::KEYCODE_PAGEDOWN || keyState.keycode == Common::KEYCODE_KP3) {
+ if (keyState.flags & Common::KBD_SHIFT) {
+ if (_down) {
+ // Scroll down 10 Pages
+ if (_page + 10 > _maxPage)
+ drawJournal(2, (_maxPage - _page) * LINES_PER_PAGE);
+ else
+ drawJournal(2, 10 * LINES_PER_PAGE);
+ drawScrollBar();
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+
+ _wait = false;
+ }
+ } else {
+ if (_down) {
+ // Scroll down 1 page
+ drawJournal(2, LINES_PER_PAGE);
+ drawScrollBar();
+ show();
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+
+ _wait = false;
+ }
+ }
+
+ } else if (keyState.keycode == Common::KEYCODE_HOME || keyState.keycode == Common::KEYCODE_KP7) {
+ // Scroll to start of journal
+ if (_page > 1) {
+ // Go to the beginning of the journal
+ _index = _sub = _up = _down = 0;
+ _page = 1;
+
+ drawFrame();
+ drawJournal(0, 0);
+
+ drawScrollBar();
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+
+ _wait = false;
+ }
+
+ } else if (keyState.keycode == Common::KEYCODE_END || keyState.keycode == Common::KEYCODE_KP1) {
+ // Scroll to end of journal
+ if (_down) {
+ // Go to the end of the journal
+ drawJournal(2, 100000);
+ drawScrollBar();
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+
+ _wait = false;
+ }
+ } else if (keyState.keycode == Common::KEYCODE_RETURN || keyState.keycode == Common::KEYCODE_KP_ENTER) {
+ events._pressed = false;
+ events._released = true;
+ events._oldButtons = 0;
+ } else if (keyState.keycode == Common::KEYCODE_ESCAPE) {
+ _exitJournal = true;
+ } else if (keyState.keycode == Common::KEYCODE_TAB) {
+ Common::Rect r(JOURNAL_BAR_WIDTH, BUTTON_SIZE + screen.fontHeight() + 13);
+ r.moveTo((SHERLOCK_SCREEN_WIDTH - r.width()) / 2, SHERLOCK_SCENE_HEIGHT - r.height());
+
+ // See if the mouse is over any of the journal controls
+ _selector = -1;
+ if (Common::Rect(r.left + 3, r.top + 3, r.right - 3, r.top + screen.fontHeight() + 4).contains(mousePos))
+ _selector = (mousePos.x - r.left) / (r.width() / 3);
+
+ // If the mouse is not over any of the options, move the mouse so that it points to the first option
+ if (_selector == -1) {
+ events.warpMouse(Common::Point(r.left + r.width() / 3 - 10, r.top + screen.fontHeight() + 2));
+ } else {
+ if (_selector == 2)
+ _selector = 0;
+ else
+ ++_selector;
+
+ events.warpMouse(Common::Point(r.left + (r.width() / 3) * (_selector + 1) - 10, mousePos.y));
+ }
+ }
+}
+
+void TattooJournal::handleButtons() {
+ Events &events = *_vm->_events;
+ Screen &screen = *_vm->_screen;
+ uint32 frameCounter = events.getFrameCounter();
+
+ if (_selector != -1 && events._pressed) {
+ if (frameCounter >= _scrollingTimer) {
+ // Set next scrolling time
+ _scrollingTimer = frameCounter + 6;
+
+ // Handle different scrolling actions
+ switch (_selector) {
+ case 3:
+ // Scroll left (1 page back)
+ if (_page > 1) {
+ // Scroll Up
+ drawJournal(1, LINES_PER_PAGE);
+ drawScrollBar();
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+ _wait = false;
+ }
+ break;
+
+ case 4:
+ // Page left (10 pages back)
+ if (_page > 1) {
+ // Scroll Up 10 Pages if possible
+ if (_page < 11)
+ drawJournal(1, (_page - 1) * LINES_PER_PAGE);
+ else
+ drawJournal(1, 10 * LINES_PER_PAGE);
+ drawScrollBar();
+ show();
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+ _wait = false;
+ }
+ break;
+
+ case 5:
+ // Page right (10 pages ahead)
+ if (_down) {
+ // Scroll Down 10 Pages
+ if (_page + 10 > _maxPage)
+ drawJournal(2, (_maxPage - _page) * LINES_PER_PAGE);
+ else
+ drawJournal(2, 10 * LINES_PER_PAGE);
+ drawScrollBar();
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+ _wait = false;
+ }
+ break;
+
+ case 6:
+ // Scroll right (1 Page Ahead)
+ if (_down) {
+ // Scroll Down
+ drawJournal(2, LINES_PER_PAGE);
+ drawScrollBar();
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+ _wait = false;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ if (events._released || events._rightReleased) {
+ _scrollingTimer = 0;
+
+ switch (_selector) {
+ case 0:
+ _exitJournal = true;
+ break;
+
+ case 1: {
+ // Search Journal
+ disableControls();
+
+ bool notFound = false;
+ int dir;
+
+ do {
+ if ((dir = getFindName(notFound)) != 0) {
+ _savedIndex = _index;
+ _savedSub = _sub;
+ _savedPage = _page;
+
+ if (drawJournal(dir + 2, 1000 * LINES_PER_PAGE) == 0)
+ {
+ _index = _savedIndex;
+ _sub = _savedSub;
+ _page = _savedPage;
+
+ drawFrame();
+ drawJournal(0, 0);
+ notFound = true;
+ } else {
+ break;
+ }
+
+ highlightJournalControls(false);
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+ } else {
+ break;
+ }
+ } while (!_vm->shouldQuit());
+ break;
+ }
+
+ case 2:
+ // Print Journal - not implemented in ScummVM
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+void TattooJournal::loadLocations() {
+ Resources &res = *_vm->_res;
+
+ _directory.clear();
+ _locations.clear();
+
+ Common::SeekableReadStream *dir = res.load("talk.lib");
+ dir->skip(4); // Skip header
+
+ // Get the numer of entries
+ _directory.resize(dir->readUint16LE());
+ dir->seek((_directory.size() + 1) * 8, SEEK_CUR);
+
+ // Read in each entry
+ char buffer[17];
+ for (uint idx = 0; idx < _directory.size(); ++idx) {
+ dir->read(buffer, 17);
+ buffer[16] = '\0';
+
+ _directory[idx] = Common::String(buffer);
+ }
+
+ delete dir;
+
+ // Load in the locations stored in journal.txt
+ Common::SeekableReadStream *loc = res.load("journal.txt");
+
+ // Initialize locations
+ _locations.resize(100);
+ for (int idx = 0; idx < 100; ++idx)
+ _locations[idx] = "No Description";
+
+ while (loc->pos() < loc->size()) {
+ // In Rose Tattoo, each location line starts with the location
+ // number, followed by a dot, some spaces and its description
+ // in quotes
+ Common::String line = loc->readLine();
+ Common::String locNumStr;
+ int locNum = 0;
+ int i = 0;
+ Common::String locDesc;
+
+ // Get the location
+ while (Common::isDigit(line[i])) {
+ locNumStr += line[i];
+ i++;
+ }
+ locNum = atoi(locNumStr.c_str());
+
+ // Skip the dot, spaces and initial quotation mark
+ while (line[i] == ' ' || line[i] == '.' || line[i] == '\"')
+ i++;
+
+ do {
+ locDesc += line[i];
+ i++;
+ } while (line[i] != '\"');
+
+ _locations[locNum] = locDesc;
+ }
+
+ delete loc;
+}
+
+void TattooJournal::drawFrame() {
+ Screen &screen = *_vm->_screen;
+
+ screen._backBuffer1.blitFrom((*_journalImages)[0], Common::Point(0, 0));
+ drawControls(0);
+
+}
+
+void TattooJournal::drawControls(int mode) {
+ TattooEngine &vm = *(TattooEngine *)_vm;
+ Screen &screen = *_vm->_screen;
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+ ImageFile &images = *ui._interfaceImages;
+
+ Common::Rect r(JOURNAL_BAR_WIDTH, !mode ? (BUTTON_SIZE + screen.fontHeight() + 13) :
+ (screen.fontHeight() + 4) * 2 + 9);
+ r.moveTo((SHERLOCK_SCREEN_WIDTH - r.width()) / 2, !mode ? (SHERLOCK_SCREEN_HEIGHT - r.height()) :
+ (SHERLOCK_SCREEN_HEIGHT - r.height()) / 2);
+
+ Common::Rect inner = r;
+ inner.grow(-3);
+
+ if (vm._transparentMenus)
+ ui.makeBGArea(inner);
+ else
+ screen._backBuffer1.fillRect(inner, MENU_BACKGROUND);
+
+ // Draw the four corners of the info box
+ screen._backBuffer1.transBlitFrom(images[0], Common::Point(r.left, r.top));
+ screen._backBuffer1.transBlitFrom(images[1], Common::Point(r.right - images[1]._width, r.top));
+ screen._backBuffer1.transBlitFrom(images[1], Common::Point(r.left, r.bottom - images[1]._height));
+ screen._backBuffer1.transBlitFrom(images[1], Common::Point(r.right - images[1]._width, r.bottom - images[1]._height));
+
+ // Draw the top of the info box
+ screen._backBuffer1.hLine(r.left + images[0]._width, r.top, r.right - images[0]._height, INFO_TOP);
+ screen._backBuffer1.hLine(r.left + images[0]._width, r.top + 1, r.right - images[0]._height, INFO_MIDDLE);
+ screen._backBuffer1.hLine(r.left + images[0]._width, r.top + 2, r.right - images[0]._height, INFO_BOTTOM);
+
+ // Draw the bottom of the info box
+ screen._backBuffer1.hLine(r.left + images[0]._width, r.bottom - 3, r.right - images[0]._height, INFO_TOP);
+ screen._backBuffer1.hLine(r.left + images[0]._width, r.bottom - 2, r.right - images[0]._height, INFO_MIDDLE);
+ screen._backBuffer1.hLine(r.left + images[0]._width, r.bottom - 1, r.right - images[0]._height, INFO_BOTTOM);
+
+ // Draw the left side of the info box
+ screen._backBuffer1.vLine(r.left, r.top + images[0]._height, r.bottom - images[2]._height, INFO_TOP);
+ screen._backBuffer1.vLine(r.left + 1, r.top + images[0]._height, r.bottom - images[2]._height, INFO_MIDDLE);
+ screen._backBuffer1.vLine(r.left + 2, r.top + images[0]._height, r.bottom - images[2]._height, INFO_BOTTOM);
+
+ // Draw the right side of the info box
+ screen._backBuffer1.vLine(r.right - 3, r.top + images[0]._height, r.bottom - images[2]._height, INFO_TOP);
+ screen._backBuffer1.vLine(r.right - 2, r.top + images[0]._height, r.bottom - images[2]._height, INFO_MIDDLE);
+ screen._backBuffer1.vLine(r.right - 1, r.top + images[0]._height, r.bottom - images[2]._height, INFO_BOTTOM);
+
+ // Draw the sides of the separator bar above the scroll bar
+ int yp = r.top + screen.fontHeight() + 7;
+ screen._backBuffer1.transBlitFrom(images[4], Common::Point(r.left, yp - 1));
+ screen._backBuffer1.transBlitFrom(images[5], Common::Point(r.right - images[5]._width, yp - 1));
+
+ // Draw the bar above the scroll bar
+ screen._backBuffer1.hLine(r.left + images[4]._width, yp, r.right - images[5]._width, INFO_TOP);
+ screen._backBuffer1.hLine(r.left + images[4]._width, yp + 1, r.right - images[5]._width, INFO_MIDDLE);
+ screen._backBuffer1.hLine(r.left + images[4]._width, yp + 2, r.right - images[5]._width, INFO_BOTTOM);
+
+ if (mode != 2) {
+ // Draw the Bars separating the Journal Commands
+ int xp = r.right / 3;
+ for (int idx = 0; idx < 2; ++idx) {
+ screen._backBuffer1.transBlitFrom(images[6], Common::Point(xp - 2, r.top + 1));
+ screen._backBuffer1.transBlitFrom(images[7], Common::Point(xp - 2, yp - 1));
+
+ screen._backBuffer1.hLine(xp - 1, r.top + 4, yp - 2, INFO_TOP);
+ screen._backBuffer1.hLine(xp, r.top + 4, yp - 2, INFO_MIDDLE);
+ screen._backBuffer1.hLine(xp + 1, r.top + 4, yp - 2, INFO_BOTTOM);
+ xp = r.right / 3 * 2;
+ }
+ }
+
+ int savedSelector = _oldSelector;
+ _oldSelector = 100;
+
+ switch (mode) {
+ case 0:
+ highlightJournalControls(false);
+ break;
+ case 1:
+ highlightSearchControls(false);
+ break;
+ default:
+ break;
+ }
+
+ _oldSelector = savedSelector;
+}
+
+void TattooJournal::highlightJournalControls(bool slamIt) {
+ Events &events = *_vm->_events;
+ Screen &screen = *_vm->_screen;
+ Common::Point mousePos = events.mousePos();
+ Common::Rect r(JOURNAL_BAR_WIDTH, BUTTON_SIZE + screen.fontHeight() + 13);
+ r.moveTo((SHERLOCK_SCREEN_WIDTH - r.width()) / 2, SHERLOCK_SCREEN_HEIGHT - r.height());
+
+ // Calculate the Scroll Position Bar
+ int numPages = (_maxPage + LINES_PER_PAGE) / LINES_PER_PAGE;
+ int barWidth = (r.width() - BUTTON_SIZE * 2 - 6) / numPages;
+ barWidth = CLIP(barWidth, BUTTON_SIZE, r.width() - BUTTON_SIZE * 2 - 6);
+
+ int barX = (numPages <= 1) ? r.left + 3 + BUTTON_SIZE : (r.width() - BUTTON_SIZE * 2 - 6 - barWidth)
+ * FIXED_INT_MULTIPLIER / (numPages - 1) * (_page - 1) / FIXED_INT_MULTIPLIER + r.left + 3 + BUTTON_SIZE;
+
+ // See if the mouse is over any of the Journal Controls
+ Common::Rect bounds(r.left, r.top, r.right - 3, r.top + screen.fontHeight() + 7);
+ _selector = -1;
+ if (bounds.contains(mousePos))
+ _selector = (mousePos.x - r.left) / (r.width() / 3);
+
+ else if (events._pressed) {
+ if (Common::Rect(r.left, r.top + screen.fontHeight() + 10, r.left + BUTTON_SIZE, r.top +
+ screen.fontHeight() + 10 + BUTTON_SIZE).contains(mousePos))
+ // Press on the Scroll Left button
+ _selector = 3;
+ else if (Common::Rect(r.left + BUTTON_SIZE + 3, r.top + screen.fontHeight() + 10,
+ r.left + BUTTON_SIZE + 3 + (barX - r.left - BUTTON_SIZE - 3), r.top + screen.fontHeight() +
+ 10 + BUTTON_SIZE).contains(mousePos))
+ // Press on the Page Left button
+ _selector = 4;
+ else if (Common::Rect(barX + barWidth, r.top + screen.fontHeight() + 10,
+ barX + barWidth + (r.right - BUTTON_SIZE - 3 - barX - barWidth),
+ r.top + screen.fontHeight() + 10 + BUTTON_SIZE).contains(mousePos))
+ // Press on the Page Right button
+ _selector = 5;
+ else if (Common::Rect(r.right - BUTTON_SIZE - 3, r.top + screen.fontHeight() + 10, r.right - 3,
+ r.top + screen.fontHeight() + 10 + BUTTON_SIZE).contains(mousePos))
+ // Press of the Scroll Right button
+ _selector = 6;
+ }
+
+ // See if the Search was selected, but is not available
+ if (_journal.empty() && (_selector == 1 || _selector == 2))
+ _selector = -1;
+
+ if (_selector == 4 && _oldSelector == 5)
+ _selector = 5;
+ else if (_selector == 5 && _oldSelector == 4)
+ _selector = 4;
+
+ // See if they're pointing at a different control
+ if (_selector != _oldSelector) {
+ // Print the Journal commands
+ int xp = r.left + r.width() / 6;
+ byte color = (_selector == 0) ? COMMAND_HIGHLIGHTED : INFO_TOP;
+
+ screen.gPrint(Common::Point(xp - screen.stringWidth(FIXED(CloseJournal)) / 2, r.top + 5),
+ color, "%s", FIXED(CloseJournal));
+ xp += r.width() / 3;
+
+ if (!_journal.empty())
+ color = (_selector == 1) ? COMMAND_HIGHLIGHTED : INFO_TOP;
+ else
+ color = INFO_BOTTOM;
+ screen.gPrint(Common::Point(xp - screen.stringWidth(FIXED(SearchJournal)) / 2, r.top + 5),
+ color, "%s", FIXED(SearchJournal));
+ xp += r.width() / 3;
+
+ color = INFO_BOTTOM;
+ screen.gPrint(Common::Point(xp - screen.stringWidth(FIXED(SaveJournal)) / 2, r.top + 5),
+ color, "%s", FIXED(SaveJournal));
+
+ // Draw the horizontal scrollbar
+ drawScrollBar();
+
+ if (slamIt)
+ screen.slamRect(r);
+
+ _oldSelector = _selector;
+ }
+}
+
+void TattooJournal::highlightSearchControls(bool slamIt) {
+ Events &events = *_vm->_events;
+ Screen &screen = *_vm->_screen;
+ Common::Point mousePos = events.mousePos();
+ Common::Rect r(JOURNAL_BAR_WIDTH, (screen.fontHeight() + 4) * 2 + 9);
+ r.moveTo((SHERLOCK_SCREEN_WIDTH - r.width()) / 2, (SHERLOCK_SCREEN_HEIGHT - r.height()) / 2);
+ const char *SEARCH_COMMANDS[3] = { FIXED(AbortSearch), FIXED(SearchBackwards), FIXED(SearchForwards) };
+
+ // See if the mouse is over any of the Journal Controls
+ _selector = -1;
+ if (Common::Rect(r.left + 3, r.top + 3, r.right - 3, r.top + 7 + screen.fontHeight()).contains(mousePos))
+ _selector = (mousePos.x - r.left) / (r.width() / 3);
+
+ // See if they're pointing at a different control
+ if (_selector != _oldSelector) {
+ // Print the search commands
+ int xp = r.left + r.width() / 6;
+
+ for (int idx = 0; idx < 3; ++idx) {
+ byte color = (_selector == idx) ? COMMAND_HIGHLIGHTED : INFO_TOP;
+ screen.gPrint(Common::Point(xp - screen.stringWidth(SEARCH_COMMANDS[idx]) / 2,
+ r.top + 5), color, "%s", SEARCH_COMMANDS[idx]);
+ xp += r.width() / 3;
+ }
+
+ if (slamIt)
+ screen.slamRect(r);
+
+ _oldSelector = _selector;
+ }
+}
+
+void TattooJournal::drawScrollBar() {
+ Screen &screen = *_vm->_screen;
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+ bool raised;
+ byte color;
+
+ Common::Rect r(JOURNAL_BAR_WIDTH, BUTTON_SIZE + screen.fontHeight() + 13);
+ r.moveTo((SHERLOCK_SCREEN_WIDTH - r.width()) / 2, SHERLOCK_SCREEN_HEIGHT - r.height());
+
+ // Calculate the Scroll Position Bar
+ int numPages = (_maxPage + LINES_PER_PAGE) / LINES_PER_PAGE;
+ int barWidth = (r.width() - BUTTON_SIZE * 2 - 6) / numPages;
+ barWidth = CLIP(barWidth, BUTTON_SIZE, r.width() - BUTTON_SIZE * 2 - 6);
+ int barX;
+ if (numPages <= 1) {
+ barX = r.left + 3 + BUTTON_SIZE;
+ } else {
+ barX = (r.width() - BUTTON_SIZE * 2 - 6 - barWidth) * FIXED_INT_MULTIPLIER / (numPages - 1) *
+ (_page - 1) / FIXED_INT_MULTIPLIER + r.left + 3 + BUTTON_SIZE;
+ if (barX + BUTTON_SIZE > r.left + r.width() - BUTTON_SIZE - 3)
+ barX = r.right - BUTTON_SIZE * 2 - 3;
+ }
+
+ // Draw the scroll bar here
+ // Draw the Scroll Left button
+ raised = _selector != 3;
+ screen._backBuffer1.fillRect(Common::Rect(r.left, r.top + screen.fontHeight() + 12, r.left + BUTTON_SIZE,
+ r.top + screen.fontHeight() + BUTTON_SIZE + 9), INFO_MIDDLE);
+ ui.drawDialogRect(screen._backBuffer1, Common::Rect(r.left + 3, r.top + screen.fontHeight() + 10, r.left + 3 + BUTTON_SIZE,
+ r.top + screen.fontHeight() + 10 + BUTTON_SIZE), raised);
+
+ color = (_page > 1) ? INFO_BOTTOM + 2 : INFO_BOTTOM;
+ screen._backBuffer1.vLine(r.left + 1 + BUTTON_SIZE / 2, r.top + screen.fontHeight() + 10 + BUTTON_SIZE / 2,
+ r.top + screen.fontHeight() + 10 + BUTTON_SIZE / 2, color);
+ screen._backBuffer1.vLine(r.left + 2 + BUTTON_SIZE / 2, r.top + screen.fontHeight() + 9 + BUTTON_SIZE / 2,
+ r.top + screen.fontHeight() + 11 + BUTTON_SIZE / 2, color);
+ screen._backBuffer1.vLine(r.left + 3 + BUTTON_SIZE / 2, r.top + screen.fontHeight() + 8 + BUTTON_SIZE / 2,
+ r.top + screen.fontHeight() + 12 + BUTTON_SIZE / 2, color);
+ screen._backBuffer1.vLine(r.left + 4 + BUTTON_SIZE / 2, r.top + screen.fontHeight() + 7 + BUTTON_SIZE / 2,
+ r.top + screen.fontHeight() + 13 + BUTTON_SIZE / 2, color);
+
+ // Draw the Scroll Right button
+ raised = _selector != 6;
+ screen._backBuffer1.fillRect(Common::Rect(r.right - BUTTON_SIZE - 1, r.top + screen.fontHeight() + 12,
+ r.right - 5, r.top + screen.fontHeight() + BUTTON_SIZE + 9), INFO_MIDDLE);
+ ui.drawDialogRect(screen._backBuffer1, Common::Rect(r.right - BUTTON_SIZE - 3, r.top + screen.fontHeight() + 10, r.right - 3,
+ r.top + screen.fontHeight() + BUTTON_SIZE + 9), raised);
+
+ color = _down ? INFO_BOTTOM + 2 : INFO_BOTTOM;
+ screen._backBuffer1.vLine(r.right - 1 - BUTTON_SIZE + BUTTON_SIZE / 2, r.top + screen.fontHeight() + 10 + BUTTON_SIZE / 2,
+ r.top + screen.fontHeight() + 10 + BUTTON_SIZE / 2, color);
+ screen._backBuffer1.vLine(r.right - 2 - BUTTON_SIZE + BUTTON_SIZE / 2, r.top + screen.fontHeight() + 9 + BUTTON_SIZE / 2,
+ r.top + screen.fontHeight() + 11 + BUTTON_SIZE / 2, color);
+ screen._backBuffer1.vLine(r.right - 3 - BUTTON_SIZE + BUTTON_SIZE / 2, r.top + screen.fontHeight() + 8 + BUTTON_SIZE / 2,
+ r.top + screen.fontHeight() + 12 + BUTTON_SIZE / 2, color);
+ screen._backBuffer1.vLine(r.right - 4 - BUTTON_SIZE + BUTTON_SIZE / 2, r.top + screen.fontHeight() + 7 + BUTTON_SIZE / 2,
+ r.top + screen.fontHeight() + 13 + BUTTON_SIZE / 2, color);
+
+ // Draw the scroll bar
+ screen._backBuffer1.fillRect(Common::Rect(barX + 2, r.top + screen.fontHeight() + 12, barX + barWidth - 3,
+ r.top + screen.fontHeight() + BUTTON_SIZE + 9), INFO_MIDDLE);
+ ui.drawDialogRect(screen._backBuffer1, Common::Rect(barX, r.top + screen.fontHeight() + 10, barX + barWidth,
+ r.top + screen.fontHeight() + 10 + BUTTON_SIZE), true);
+}
+
+void TattooJournal::disableControls() {
+ Screen &screen = *_vm->_screen;
+ Common::Rect r(JOURNAL_BAR_WIDTH, BUTTON_SIZE + screen.fontHeight() + 13);
+ r.moveTo((SHERLOCK_SCREEN_HEIGHT - r.width()) / 2, SHERLOCK_SCREEN_HEIGHT - r.height());
+ const char *JOURNAL_COMMANDS[3] = { FIXED(CloseJournal), FIXED(SearchJournal), FIXED(SaveJournal) };
+
+ // Print the Journal commands
+ int xp = r.left + r.width() / 6;
+ for (int idx = 0; idx < 2; ++idx) {
+ screen.gPrint(Common::Point(xp - screen.stringWidth(JOURNAL_COMMANDS[idx]) / 2, r.top + 5),
+ INFO_BOTTOM, "%s", JOURNAL_COMMANDS[idx]);
+
+ xp += r.width() / 3;
+ }
+
+ screen.slamRect(r);
+}
+
+int TattooJournal::getFindName(bool printError) {
+ Events &events = *_vm->_events;
+ Screen &screen = *_vm->_screen;
+ Talk &talk = *_vm->_talk;
+ int result = 0;
+ int done = 0;
+ Common::String name;
+ int cursorX, cursorY;
+ bool flag = false;
+
+ Common::Rect r(JOURNAL_BAR_WIDTH, (screen.fontHeight() + 4) * 2 + 9);
+ r.moveTo((SHERLOCK_SCREEN_WIDTH - r.width()) / 2, (SHERLOCK_SCREEN_HEIGHT - r.height()) / 2);
+
+ // Set the cursors Y position
+ cursorY = r.top + screen.fontHeight() + 12;
+
+ drawControls(1);
+
+ // Backup the area under the text entry
+ Surface bgSurface(r.width() - 6, screen.fontHeight());
+ bgSurface.blitFrom(screen._backBuffer1, Common::Point(0, 0), Common::Rect(r.left + 3, cursorY,
+ r.right - 3, cursorY + screen.fontHeight()));
+
+ if (printError) {
+ screen.gPrint(Common::Point(0, cursorY), INFO_TOP, "%s", FIXED(TextNotFound));
+ } else {
+ // If there was a name already entered, copy it to name and display it
+ if (!_find.empty()) {
+ screen.gPrint(Common::Point(r.left + screen.widestChar() + 3, cursorY), COMMAND_HIGHLIGHTED, "%s", _find.c_str());
+ name = _find;
+ }
+ }
+
+ screen.slamRect(r);
+
+ if (printError) {
+ // Pause to allow error to be shown
+ int timer = 0;
+
+ do {
+ events.pollEvents();
+ events.setButtonState();
+
+ ++timer;
+ events.wait(2);
+ } while (!_vm->shouldQuit() && !events.kbHit() && !events._released && !events._rightReleased && timer < 40);
+
+ events.clearEvents();
+
+ // Restore the text background
+ screen._backBuffer1.blitFrom(bgSurface, Common::Point(r.left, cursorY));
+
+ // If there was a name already entered, copy it to name and display it
+ if (!_find.empty()) {
+ screen.gPrint(Common::Point(r.left + screen.widestChar() + 3, cursorY), COMMAND_HIGHLIGHTED, "%s", _find.c_str());
+ name = _find;
+ }
+
+ screen.slamArea(r.left + 3, cursorY, r.width() - 6, screen.fontHeight());
+ }
+
+ // Set the cursors X position
+ cursorX = r.left + screen.widestChar() + 3 + screen.stringWidth(name);
+
+ do {
+ events._released = events._rightReleased = false;
+
+ while (!events.kbHit() && !events._released && !events._rightReleased) {
+ if (talk._talkToAbort)
+ return 0;
+
+ // See if a key or a mouse button is pressed
+ events.pollEventsAndWait();
+ events.setButtonState();
+
+ // Handle blinking cursor
+ flag = !flag;
+ if (flag) {
+ // Draw cursor
+ screen._backBuffer1.fillRect(Common::Rect(cursorX, cursorY, cursorX + 7, cursorY + 8), COMMAND_HIGHLIGHTED);
+ screen.slamArea(cursorX, cursorY, 8, 9);
+ } else {
+ // Erase cursor by restoring background and writing current text
+ screen._backBuffer1.blitFrom(bgSurface, Common::Point(r.left + 3, cursorY));
+ screen.gPrint(Common::Point(r.left + screen.widestChar() + 3, cursorY), COMMAND_HIGHLIGHTED, "%s", name.c_str());
+ screen.slamArea(r.left + 3, r.top, r.width() - 3, screen.fontHeight());
+ }
+
+ highlightSearchControls(true);
+
+ events.wait(2);
+ }
+
+ if (events.kbHit()) {
+ Common::KeyState keyState = events.getKey();
+ Common::Point mousePos = events.mousePos();
+
+ if (keyState.keycode == Common::KEYCODE_BACKSPACE && !name.empty()) {
+ cursorX -= screen.charWidth(name.lastChar());
+ name.deleteLastChar();
+ }
+
+ if (keyState.keycode == Common::KEYCODE_RETURN)
+ done = 1;
+
+ else if (keyState.keycode == Common::KEYCODE_ESCAPE)
+ done = -1;
+
+ if (keyState.keycode == Common::KEYCODE_TAB) {
+ r = Common::Rect(JOURNAL_BAR_WIDTH, BUTTON_SIZE + screen.fontHeight() + 13);
+ r.moveTo((SHERLOCK_SCREEN_WIDTH - r.width()) / 2, (SHERLOCK_SCREEN_HEIGHT - r.height()) / 2);
+
+ // See if the mouse is over any of the journal controls
+ _selector = -1;
+ if (Common::Rect(r.left + 3, r.top + 3, r.right - 3, r.top + screen.fontHeight() + 4).contains(mousePos))
+ _selector = (mousePos.x - r.left) / (r.width() / 3);
+
+ // If the mouse is not over any of the options, move the mouse so that it points to the first option
+ if (_selector == -1) {
+ events.warpMouse(Common::Point(r.left + r.width() / 3, r.top + screen.fontHeight() + 2));
+ } else {
+ if (keyState.keycode & Common::KBD_SHIFT) {
+ if (_selector == 0)
+ _selector = 2;
+ else
+ --_selector;
+ } else {
+ if (_selector == 2)
+ _selector = 0;
+ else
+ ++_selector;
+ }
+
+ events.warpMouse(Common::Point(r.left + (r.width() / 3) * (_selector + 1) - 10, mousePos.y));
+ }
+ }
+
+ if (keyState.ascii && keyState.ascii != '@' && name.size() < 50) {
+ if ((cursorX + screen.charWidth(keyState.ascii)) < (r.right - screen.widestChar() * 3)) {
+ cursorX += screen.charWidth(keyState.ascii);
+ name += toupper(keyState.ascii);
+ }
+ }
+
+ // Redraw the text
+ screen._backBuffer1.blitFrom(bgSurface, Common::Point(r.left + 3, cursorY));
+ screen.gPrint(Common::Point(r.left + screen.widestChar() + 3, cursorY), COMMAND_HIGHLIGHTED,
+ "%s", name.c_str());
+ screen.slamArea(r.left + 3, cursorY, r.right - 3, screen.fontHeight());
+ }
+
+ if (events._released || events._rightReleased) {
+ switch (_selector)
+ {
+ case 0:
+ done = -1;
+ break;
+ case 1:
+ done = 2;
+ break;
+ case 2:
+ done = 1;
+ break;
+ default:
+ break;
+ }
+ }
+ } while (!done);
+
+ if (done != -1) {
+ _find = name;
+ result = done;
+ } else {
+ result = 0;
+ }
+
+ drawFrame();
+ drawJournal(0, 0);
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+
+ return result;
+}
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/tattoo/tattoo_journal.h b/engines/sherlock/tattoo/tattoo_journal.h
new file mode 100644
index 0000000000..5e5cfda8c2
--- /dev/null
+++ b/engines/sherlock/tattoo/tattoo_journal.h
@@ -0,0 +1,103 @@
+/* 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 SHERLOCK_TATTOO_JOURNAL_H
+#define SHERLOCK_TATTOO_JOURNAL_H
+
+#include "sherlock/journal.h"
+#include "sherlock/image_file.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+class TattooJournal : public Journal {
+private:
+ ImageFile *_journalImages;
+ int _selector, _oldSelector;
+ bool _wait;
+ bool _exitJournal;
+ uint32 _scrollingTimer;
+ int _savedIndex, _savedSub, _savedPage;
+
+ /**
+ * Load the list of journal locations
+ */
+ void loadLocations();
+
+ /**
+ * Displays the controls used by the journal
+ * @param mode 0: Normal journal buttons, 1: Search interface
+ */
+ void drawControls(int mode);
+
+ /**
+ * Draw the journal controls used by the journal
+ */
+ void highlightJournalControls(bool slamIt);
+
+ /**
+ * Draw the journal controls used in search mode
+ */
+ void highlightSearchControls(bool slamIt);
+
+ void drawScrollBar();
+
+ /**
+ * Check for and handle any pending keyboard events
+ */
+ void handleKeyboardEvents();
+
+ /**
+ * Handle mouse presses on interface buttons
+ */
+ void handleButtons();
+
+ /**
+ * Disable the journal controls
+ */
+ void disableControls();
+
+ /**
+ * Get in a name to search through the journal for
+ */
+ int getFindName(bool printError);
+public:
+ TattooJournal(SherlockEngine *vm);
+ virtual ~TattooJournal() {}
+
+ /**
+ * Show the journal
+ */
+ void show();
+public:
+ /**
+ * Draw the journal background, frame, and interface buttons
+ */
+ virtual void drawFrame();
+};
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/tattoo/tattoo_map.cpp b/engines/sherlock/tattoo/tattoo_map.cpp
new file mode 100644
index 0000000000..21abf7d3c0
--- /dev/null
+++ b/engines/sherlock/tattoo/tattoo_map.cpp
@@ -0,0 +1,439 @@
+/* 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 "sherlock/tattoo/tattoo_map.h"
+#include "sherlock/tattoo/tattoo_scene.h"
+#include "sherlock/tattoo/tattoo.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+#define MAP_NAME_COLOR 131
+#define CLOSEUP_STEPS 30
+#define SCROLL_SPEED 16
+
+/*-------------------------------------------------------------------------*/
+
+void MapEntry::clear() {
+ _iconNum = -1;
+ _description = "";
+}
+
+/*-------------------------------------------------------------------------*/
+
+TattooMap::TattooMap(SherlockEngine *vm) : Map(vm), _mapTooltip(vm) {
+ _iconImages = nullptr;
+ _bgFound = _oldBgFound = 0;
+
+ loadData();
+}
+
+int TattooMap::show() {
+ Debugger &debugger = *_vm->_debugger;
+ Events &events = *_vm->_events;
+ Music &music = *_vm->_music;
+ Resources &res = *_vm->_res;
+ TattooScene &scene = *(TattooScene *)_vm->_scene;
+ Screen &screen = *_vm->_screen;
+ int result = 0;
+
+ // Check if we need to keep track of how many times player has been to the map
+ for (uint idx = 0; idx < scene._sceneTripCounters.size(); ++idx) {
+ SceneTripEntry &entry = scene._sceneTripCounters[idx];
+
+ if (entry._sceneNumber == OVERHEAD_MAP || entry._sceneNumber == OVERHEAD_MAP2) {
+ if (--entry._numTimes == 0) {
+ _vm->setFlagsDirect(entry._flag);
+ scene._sceneTripCounters.remove_at(idx);
+ }
+ }
+ }
+
+ if (music._midiOption) {
+ // See if Holmes or Watson is the active character
+ Common::String song;
+ if (_vm->readFlags(FLAG_PLAYER_IS_HOLMES))
+ // Player is Holmes
+ song = "Cue9";
+ else if (_vm->readFlags(FLAG_ALT_MAP_MUSIC))
+ song = "Cue8";
+ else
+ song = "Cue7";
+
+ if (music.loadSong(song)) {
+ music.setMIDIVolume(music._musicVolume);
+ if (music._musicOn)
+ music.startSong();
+ }
+ }
+
+ screen.initPaletteFade(1364485);
+
+ // Load the custom mouse cursors for the map
+ ImageFile cursors("omouse.vgs");
+ events.setCursor(cursors[0]._frame);
+ events.warpMouse(Common::Point(SHERLOCK_SCREEN_WIDTH / 2, SHERLOCK_SCREEN_HEIGHT / 2));
+
+ // Load the data for the map
+ _iconImages = new ImageFile("mapicons.vgs");
+ loadData();
+
+ // Load the palette
+ Common::SeekableReadStream *stream = res.load("map.pal");
+ stream->read(screen._cMap, PALETTE_SIZE);
+ screen.translatePalette(screen._cMap);
+ delete stream;
+
+ // Load the map image and draw it to the back buffer
+ ImageFile *map = new ImageFile("map.vgs");
+ screen._backBuffer1.create(SHERLOCK_SCREEN_WIDTH * 2, SHERLOCK_SCREEN_HEIGHT * 2);
+ screen._backBuffer1.blitFrom((*map)[0], Common::Point(0, 0));
+ delete map;
+
+ screen.clear();
+ screen.setPalette(screen._cMap);
+ drawMapIcons();
+
+ // Copy the map drawn in the back buffer to the secondary back buffer
+ screen._backBuffer2.create(SHERLOCK_SCREEN_WIDTH * 2, SHERLOCK_SCREEN_HEIGHT * 2);
+ screen._backBuffer2.blitFrom(screen._backBuffer1);
+
+ // Display the built map to the screen
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+
+ // Set initial scroll position
+ _targetScroll = _bigPos;
+ screen._currentScroll = Common::Point(-1, -1);
+
+ do {
+ // Allow for event processing and get the current mouse position
+ events.pollEventsAndWait();
+ events.setButtonState();
+ Common::Point mousePos = events.screenMousePos();
+
+ if (debugger._showAllLocations == LOC_REFRESH) {
+ drawMapIcons();
+ screen.slamArea(screen._currentScroll.x, screen._currentScroll.y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_WIDTH);
+ }
+
+ checkMapNames(true);
+
+ if (mousePos.x < (SHERLOCK_SCREEN_WIDTH / 6))
+ _targetScroll.x -= 2 * SCROLL_SPEED * (SHERLOCK_SCREEN_WIDTH / 6 - mousePos.x) / (SHERLOCK_SCREEN_WIDTH / 6);
+ if (mousePos.x > (SHERLOCK_SCREEN_WIDTH * 5 / 6))
+ _targetScroll.x += 2 * SCROLL_SPEED * (mousePos.x - (SHERLOCK_SCREEN_WIDTH * 5 / 6)) / (SHERLOCK_SCREEN_WIDTH / 6);
+ if (mousePos.y < (SHERLOCK_SCREEN_HEIGHT / 6))
+ _targetScroll.y -= 2 * SCROLL_SPEED * (SHERLOCK_SCREEN_HEIGHT / 6 - mousePos.y) / (SHERLOCK_SCREEN_HEIGHT / 6);
+ if (mousePos.y > (SHERLOCK_SCREEN_HEIGHT * 5 / 6))
+ _targetScroll.y += 2 * SCROLL_SPEED * (mousePos.y - SHERLOCK_SCREEN_HEIGHT * 5 / 6) / (SHERLOCK_SCREEN_HEIGHT / 6);
+
+ if (_targetScroll.x < 0)
+ _targetScroll.x = 0;
+ if ((_targetScroll.x + SHERLOCK_SCREEN_WIDTH) > screen._backBuffer1.w())
+ _targetScroll.x = screen._backBuffer1.w() - SHERLOCK_SCREEN_WIDTH;
+ if (_targetScroll.y < 0)
+ _targetScroll.y = 0;
+ if ((_targetScroll.y + SHERLOCK_SCREEN_HEIGHT) > screen._backBuffer1.h())
+ _targetScroll.y = screen._backBuffer1.h() - SHERLOCK_SCREEN_HEIGHT;
+
+ // Check the keyboard
+ if (events.kbHit()) {
+ Common::KeyState keyState = events.getKey();
+
+ switch (keyState.keycode) {
+ case Common::KEYCODE_HOME:
+ case Common::KEYCODE_KP7:
+ _targetScroll.x = 0;
+ _targetScroll.y = 0;
+ break;
+
+ case Common::KEYCODE_END:
+ case Common::KEYCODE_KP1:
+ _targetScroll.x = screen._backBuffer1.w() - SHERLOCK_SCREEN_WIDTH;
+ _targetScroll.y = screen._backBuffer1.h() - SHERLOCK_SCREEN_HEIGHT;
+ break;
+
+ case Common::KEYCODE_PAGEUP:
+ case Common::KEYCODE_KP9:
+ _targetScroll.y -= SHERLOCK_SCREEN_HEIGHT;
+ if (_targetScroll.y < 0)
+ _targetScroll.y = 0;
+ break;
+
+ case Common::KEYCODE_PAGEDOWN:
+ case Common::KEYCODE_KP3:
+ _targetScroll.y += SHERLOCK_SCREEN_HEIGHT;
+ if (_targetScroll.y > (screen._backBuffer1.h() - SHERLOCK_SCREEN_HEIGHT))
+ _targetScroll.y = screen._backBuffer1.h() - SHERLOCK_SCREEN_HEIGHT;
+ break;
+
+ case Common::KEYCODE_SPACE:
+ events._pressed = false;
+ events._oldButtons = 0;
+ events._released = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ // Handle any scrolling of the map
+ if (screen._currentScroll != _targetScroll) {
+ // If there is a Text description being displayed, restore the area under it
+ _mapTooltip.erase();
+
+ screen._currentScroll = _targetScroll;
+
+ checkMapNames(false);
+ screen.slamArea(_targetScroll.x, _targetScroll.y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+ }
+
+ // Handling if a location has been clicked on
+ if (events._released && _bgFound != -1) {
+ // If there is a Text description being displayed, restore the area under it
+ _mapTooltip.erase();
+
+ // Save the current scroll position on the map
+ _bigPos = screen._currentScroll;
+
+ showCloseUp(_bgFound);
+ result = _bgFound + 1;
+ }
+ } while (!result && !_vm->shouldQuit());
+
+ music.stopMusic();
+ events.clearEvents();
+ _mapTooltip.banishWindow();
+
+ // Reset the back buffers back to standard size
+ screen._backBuffer1.create(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+ screen._backBuffer2.create(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+
+ return result;
+}
+
+void TattooMap::loadData() {
+ Resources &res = *_vm->_res;
+ char c;
+
+ Common::SeekableReadStream *stream = res.load("map.txt");
+
+ _data.resize(100);
+ for (uint idx = 0; idx < _data.size(); ++idx)
+ _data[idx].clear();
+
+ do
+ {
+ // Find the start of the number
+ do {
+ c = stream->readByte();
+ if (stream->pos() >= stream->size())
+ return;
+ } while (c < '0' || c > '9');
+
+ // Get the scene number
+ Common::String locStr;
+ locStr += c;
+ while ((c = stream->readByte()) != '.')
+ locStr += c;
+ MapEntry &mapEntry = _data[atoi(locStr.c_str()) - 1];
+
+ // Get the location name
+ while (stream->readByte() != '"')
+ ;
+
+ while ((c = stream->readByte()) != '"')
+ mapEntry._description += c;
+
+ // Find the ( specifying the (X,Y) position of the Icon
+ while (stream->readByte() != '(')
+ ;
+
+ // Get the X Position of the icon
+ Common::String numStr;
+ while ((c = stream->readByte()) != ',')
+ numStr += c;
+ mapEntry.x = atoi(numStr.c_str());
+
+ // Get the Y position of the icon
+ numStr = "";
+ while ((c = stream->readByte()) != ')')
+ numStr += c;
+ mapEntry.y = atoi(numStr.c_str());
+
+ // Find and get the location's icon number
+ while (stream->readByte() != '#')
+ ;
+
+ Common::String iconStr;
+ while (stream->pos() < stream->size() && (c = stream->readByte()) != '\r')
+ iconStr += c;
+
+ mapEntry._iconNum = atoi(iconStr.c_str()) - 1;
+ } while (stream->pos() < stream->size());
+
+ delete stream;
+}
+
+void TattooMap::drawMapIcons() {
+ Debugger &debugger = *_vm->_debugger;
+ Screen &screen = *_vm->_screen;
+
+ for (uint idx = 0; idx < _data.size(); ++idx) {
+ if (debugger._showAllLocations != LOC_DISABLED)
+ _vm->setFlagsDirect(idx + 1);
+
+ if (_data[idx]._iconNum != -1 && _vm->readFlags(idx + 1)) {
+ MapEntry &mapEntry = _data[idx];
+ ImageFrame &img = (*_iconImages)[mapEntry._iconNum];
+ screen._backBuffer1.transBlitFrom(img._frame, Common::Point(mapEntry.x - img._width / 2,
+ mapEntry.y - img._height / 2));
+ }
+ }
+
+ if (debugger._showAllLocations == LOC_REFRESH)
+ debugger._showAllLocations = LOC_ALL;
+}
+
+void TattooMap::checkMapNames(bool slamIt) {
+ Events &events = *_vm->_events;
+ Common::Point mapPos = events.mousePos();
+
+ // See if the mouse is pointing at any of the map locations
+ _bgFound = -1;
+
+ for (uint idx = 0; idx < _data.size(); ++idx) {
+ if (_data[idx]._iconNum != -1 && _vm->readFlags(idx + 1)) {
+ MapEntry &mapEntry = _data[idx];
+ ImageFrame &img = (*_iconImages)[mapEntry._iconNum];
+ Common::Rect r(mapEntry.x - img._width / 2, mapEntry.y - img._height / 2,
+ mapEntry.x + img._width / 2, mapEntry.y + img._height / 2);
+
+ if (r.contains(mapPos)) {
+ _bgFound = idx;
+ break;
+ }
+ }
+ }
+
+ // Handle updating the tooltip
+ if (_bgFound != _oldBgFound) {
+ if (_bgFound == -1) {
+ _mapTooltip.setText("");
+ } else {
+ const Common::String &desc = _data[_bgFound]._description;
+ _mapTooltip.setText(desc);
+ }
+
+ _oldBgFound = _bgFound;
+ }
+
+ _mapTooltip.handleEvents();
+ if (slamIt)
+ _mapTooltip.draw();
+}
+
+void TattooMap::restoreArea(const Common::Rect &bounds) {
+ Screen &screen = *_vm->_screen;
+
+ Common::Rect r = bounds;
+ r.clip(Common::Rect(0, 0, screen._backBuffer1.w(), screen._backBuffer1.h()));
+
+ if (!r.isEmpty())
+ screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(r.left, r.top), r);
+}
+
+void TattooMap::showCloseUp(int closeUpNum) {
+ Events &events = *_vm->_events;
+ Screen &screen = *_vm->_screen;
+
+ // Reset scroll position
+ screen._currentScroll = Common::Point(0, 0);
+
+ // Get the closeup images
+ Common::String fname = Common::String::format("res%02d.vgs", closeUpNum + 1);
+ ImageFile pic(fname);
+
+ Point32 closeUp(_data[closeUpNum].x * 100, _data[closeUpNum].y * 100);
+ Point32 delta((SHERLOCK_SCREEN_WIDTH / 2 - closeUp.x / 100) * 100 / CLOSEUP_STEPS,
+ (SHERLOCK_SCREEN_HEIGHT / 2 - closeUp.y / 100) * 100 / CLOSEUP_STEPS);
+ Common::Rect oldBounds(closeUp.x / 100, closeUp.y / 100, closeUp.x / 100 + 1, closeUp.y / 100 + 1);
+ int size = 64;
+ int n = 256;
+ int deltaVal = 512;
+ bool minimize = false;
+ int scaleVal, newSize;
+
+ do {
+ scaleVal = n;
+ newSize = pic[0].sDrawXSize(n);
+
+ if (newSize > size) {
+ if (minimize)
+ deltaVal /= 2;
+ n += deltaVal;
+ } else {
+ minimize = true;
+ deltaVal /= 2;
+ n -= deltaVal;
+ if (n < 1)
+ n = 1;
+ }
+ } while (deltaVal && size != newSize);
+
+ int deltaScale = (SCALE_THRESHOLD - scaleVal) / CLOSEUP_STEPS;
+
+ for (int step = 0; step < CLOSEUP_STEPS; ++step) {
+ Common::Point picSize(pic[0].sDrawXSize(scaleVal), pic[0].sDrawYSize(scaleVal));
+ Common::Point pt(closeUp.x / 100 - picSize.x / 2, closeUp.y / 100 - picSize.y / 2);
+
+ restoreArea(oldBounds);
+ screen._backBuffer1.transBlitFrom(pic[0], pt, false, 0, scaleVal);
+
+ screen.slamRect(oldBounds);
+ screen.slamArea(pt.x, pt.y, picSize.x, picSize.y);
+
+ oldBounds = Common::Rect(pt.x, pt.y, pt.x + picSize.x + 1, pt.y + picSize.y + 1);
+ closeUp += delta;
+ scaleVal += deltaScale;
+
+ events.wait(1);
+ }
+
+ // Handle final drawing of closeup
+ // TODO: Handle scrolling
+ Common::Rect r(SHERLOCK_SCREEN_WIDTH / 2 - pic[0]._width / 2, SHERLOCK_SCREEN_HEIGHT / 2 - pic[0]._height / 2,
+ SHERLOCK_SCREEN_WIDTH / 2 - pic[0]._width / 2 + pic[0]._width,
+ SHERLOCK_SCREEN_HEIGHT / 2 - pic[0]._height / 2 + pic[0]._height);
+
+ restoreArea(oldBounds);
+ screen._backBuffer1.transBlitFrom(pic[0], Common::Point(r.left, r.top));
+ screen.slamRect(oldBounds);
+ screen.slamRect(r);
+ events.wait(2);
+}
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/tattoo/tattoo_map.h b/engines/sherlock/tattoo/tattoo_map.h
new file mode 100644
index 0000000000..1c7173bdb0
--- /dev/null
+++ b/engines/sherlock/tattoo/tattoo_map.h
@@ -0,0 +1,93 @@
+/* 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 SHERLOCK_TATTOO_MAP_H
+#define SHERLOCK_TATTOO_MAP_H
+
+#include "common/scummsys.h"
+#include "sherlock/map.h"
+#include "sherlock/resources.h"
+#include "sherlock/surface.h"
+#include "sherlock/tattoo/widget_tooltip.h"
+
+namespace Sherlock {
+
+class SherlockEngine;
+
+namespace Tattoo {
+
+struct MapEntry : Common::Point {
+ int _iconNum;
+ Common::String _description;
+
+ MapEntry() : Common::Point(), _iconNum(-1) {}
+ MapEntry(int posX, int posY, int iconNum) : Common::Point(posX, posY), _iconNum(iconNum) {}
+ void clear();
+};
+
+class TattooMap : public Map {
+private:
+ Common::Array<MapEntry> _data;
+ ImageFile *_iconImages;
+ int _bgFound, _oldBgFound;
+ WidgetMapTooltip _mapTooltip;
+ Common::Point _targetScroll;
+
+ /**
+ * Load data needed for the map
+ */
+ void loadData();
+
+ /**
+ * Draws all available location icons onto the back buffer
+ */
+ void drawMapIcons();
+
+ /**
+ * Draws the location names of whatever the mouse moves over on the map
+ */
+ void checkMapNames(bool slamIt);
+
+ /**
+ * Restores an area of the map background
+ */
+ void restoreArea(const Common::Rect &bounds);
+
+ /**
+ * This will load a specified close up and zoom it up to the middle of the screen
+ */
+ void showCloseUp(int closeUpNum);
+public:
+ TattooMap(SherlockEngine *vm);
+ virtual ~TattooMap() {}
+
+ /**
+ * Show the map
+ */
+ virtual int show();
+};
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp
new file mode 100644
index 0000000000..7aaa0a082c
--- /dev/null
+++ b/engines/sherlock/tattoo/tattoo_people.cpp
@@ -0,0 +1,1432 @@
+/* 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 "sherlock/tattoo/tattoo_people.h"
+#include "sherlock/tattoo/tattoo_scene.h"
+#include "sherlock/tattoo/tattoo_talk.h"
+#include "sherlock/tattoo/tattoo_user_interface.h"
+#include "sherlock/tattoo/tattoo.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+#define FACING_PLAYER 16
+#define NUM_ADJUSTED_WALKS 21
+
+struct AdjustWalk {
+ char _vgsName[9];
+ int _xAdjust;
+ int _flipXAdjust;
+ int _yAdjust;
+} ;
+
+static const AdjustWalk ADJUST_WALKS[NUM_ADJUSTED_WALKS] = {
+ { "TUPRIGHT", -7, -19, 6 },
+ { "TRIGHT", 8, -14, 0 },
+ { "TDOWNRG", 14, -12, 0 },
+ { "TWUPRIGH", 12, 4, 2 },
+ { "TWRIGHT", 31, -14, 0 },
+ { "TWDOWNRG", 6, -24, 0 },
+ { "HTUPRIGH", 2, -20, 0 },
+ { "HTRIGHT", 28, -20, 0 },
+ { "HTDOWNRG", 8, -2, 0 },
+ { "GTUPRIGH", 4, -12, 0 },
+ { "GTRIGHT", 12, -16, 0 },
+ { "GTDOWNRG", 10, -18, 0 },
+ { "JTUPRIGH", 8, -10, 0 },
+ { "JTRIGHT", 22, -6, 0 },
+ { "JTDOWNRG", 4, -20, 0 },
+ { "CTUPRIGH", 10, 0, 0 },
+ { "CTRIGHT", 26, -22, 0 },
+ { "CTDOWNRI", 16, 4, 0 },
+ { "ITUPRIGH", 0, 0, 0 },
+ { "ITRIGHT", 20, 0, 0 },
+ { "ITDOWNRG", 8, 0, 0 }
+};
+
+static const int WALK_SPEED_X[99] = {
+ 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 98, 90, 90, 90, 90, 90, 91, 90, 90,
+ 90, 90,100, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90,100, 90,
+ 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90,103, 90, 90, 90, 90, 90, 90, 90,
+ 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90,
+ 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90
+};
+
+static const int WALK_SPEED_Y[99] = {
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 32, 32, 32, 28, 28, 28, 28, 28, 26, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 32, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 31, 28, 28, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28
+};
+
+static const int WALK_SPEED_DIAG_X[99] = {
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 90, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50
+};
+
+/*----------------------------------------------------------------*/
+
+SavedNPCPath::SavedNPCPath() {
+ Common::fill(&_path[0], &_path[MAX_NPC_PATH], 0);
+ _npcIndex = 0;
+ _npcPause = 0;
+ _npcFacing = 0;
+ _lookHolmes = false;
+}
+
+SavedNPCPath::SavedNPCPath(byte path[MAX_NPC_PATH], int npcIndex, int npcPause, const Common::Point &walkDest,
+ int npcFacing, bool lookHolmes) : _npcIndex(npcIndex), _npcPause(npcPause), _walkDest(walkDest),
+ _npcFacing(npcFacing), _lookHolmes(lookHolmes) {
+ Common::copy(&path[0], &path[MAX_NPC_PATH], &_path[0]);
+}
+
+/*----------------------------------------------------------------*/
+
+TattooPerson::TattooPerson() : Person() {
+ Common::fill(&_npcPath[0], &_npcPath[MAX_NPC_PATH], 0);
+ _tempX = _tempScaleVal = 0;
+ _npcIndex = 0;
+ _npcMoved = false;
+ _npcFacing = -1;
+ _resetNPCPath = true;
+ _savedNpcSequence = 0;
+ _savedNpcFrame = 0;
+ _updateNPCPath = true;
+ _npcPause = 0;
+ _lookHolmes = false;
+}
+
+void TattooPerson::freeAltGraphics() {
+ if (_altImages != nullptr) {
+ delete _altImages;
+ _altImages = nullptr;
+ }
+
+ _altSeq = 0;
+}
+
+void TattooPerson::adjustSprite() {
+ People &people = *_vm->_people;
+ TattooScene &scene = *(TattooScene *)_vm->_scene;
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+
+ if (_type == INVALID)
+ return;
+
+ if (_type == CHARACTER && _status) {
+ // Sprite waiting to move, so restart walk
+ _walkCount = _status;
+ _status = 0;
+
+ _walkDest = _walkTo.front();
+ setWalking();
+ } else if (_type == CHARACTER && _walkCount) {
+ if (_walkCount > 10) {
+ _walkDest = _nextDest;
+ setWalking();
+ }
+
+ _position += _delta;
+ if (_walkCount)
+ --_walkCount;
+
+ if (!_walkCount) {
+ // If there are remaining points to walk, move to the next one
+ if (!_walkTo.empty()) {
+ _walkDest = _walkTo.pop();
+ setWalking();
+ } else {
+ gotoStand();
+ }
+ }
+ }
+
+ if (_type != CHARACTER) {
+ if (_position.y > SHERLOCK_SCREEN_HEIGHT)
+ _position.y = SHERLOCK_SCREEN_HEIGHT;
+
+ if (_position.y < UPPER_LIMIT)
+ _position.y = UPPER_LIMIT;
+
+ if (_position.x < LEFT_LIMIT)
+ _position.x = LEFT_LIMIT;
+
+ if (_position.x > RIGHT_LIMIT)
+ _position.x = RIGHT_LIMIT;
+ }
+
+ int frameNum = _frameNumber;
+ if (frameNum == -1)
+ frameNum = 0;
+ int idx = _walkSequences[_sequenceNumber][frameNum];
+ if (idx > _maxFrames)
+ idx = 1;
+
+ // Set the image frame
+ if (_altSeq)
+ _imageFrame = &(*_altImages)[idx - 1];
+ else
+ _imageFrame = &(*_images)[idx - 1];
+
+ // See if the player has come to a stop after clicking on an Arrow zone to leave the scene.
+ // If so, this will set up the exit information for the scene transition
+ if (!_walkCount && ui._exitZone != -1 && scene._walkedInScene && scene._goToScene == -1 &&
+ !_description.compareToIgnoreCase(people[HOLMES]._description)) {
+ Exit &exit = scene._exits[ui._exitZone];
+ scene._goToScene = exit._scene;
+
+ if (exit._newPosition.x != 0) {
+ people._savedPos = exit._newPosition;
+
+ if (people._savedPos._facing > 100 && people._savedPos.x < 1)
+ people._savedPos.x = 100;
+ }
+ }
+}
+
+void TattooPerson::gotoStand() {
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+
+ // If the misc field is set, then we're running a special talk sequence, so don't interrupt it.
+ if (_misc)
+ return;
+
+ _walkTo.clear();
+ _walkCount = 0;
+ int oldFacing = _sequenceNumber;
+
+ // If the person was talking or listening, just return it to the standing sequence
+ // in the direction they were pointing
+ if (_sequenceNumber >= TALK_UPRIGHT && _sequenceNumber <= LISTEN_UPLEFT) {
+ switch (_sequenceNumber) {
+ case TALK_UPRIGHT:
+ case LISTEN_UPRIGHT:
+ _sequenceNumber = STOP_UPRIGHT;
+ break;
+ case TALK_RIGHT:
+ case LISTEN_RIGHT:
+ _sequenceNumber = STOP_RIGHT;
+ break;
+ case TALK_DOWNRIGHT:
+ case LISTEN_DOWNRIGHT:
+ _sequenceNumber = STOP_DOWNRIGHT;
+ break;
+ case TALK_DOWNLEFT:
+ case LISTEN_DOWNLEFT:
+ _sequenceNumber = STOP_DOWNLEFT;
+ break;
+ case TALK_LEFT:
+ case LISTEN_LEFT:
+ _sequenceNumber = STOP_LEFT;
+ break;
+ case TALK_UPLEFT:
+ case LISTEN_UPLEFT:
+ _sequenceNumber = STOP_UPLEFT;
+ break;
+ default:
+ break;
+ }
+
+ if (_seqTo) {
+ // Reset to previous value
+ _walkSequences[oldFacing]._sequences[_frameNumber] = _seqTo;
+ _seqTo = 0;
+ }
+
+ // Set the Frame number to the last frame so we don't move
+ _frameNumber = 0;
+
+ checkWalkGraphics();
+
+ _oldWalkSequence = -1;
+ people._allowWalkAbort = true;
+ return;
+ }
+
+ // If the sprite that is stopping is an NPC and he is supposed to face a certain direction
+ // when he stops, set that direction here
+ int npc = -1;
+ for (int idx = 1; idx < MAX_CHARACTERS; ++idx) {
+ if (_imageFrame == people[idx]._imageFrame)
+ npc = idx;
+ }
+
+ if (npc != -1 && people[npc]._npcFacing != -1) {
+ if (people[npc]._npcFacing == FACING_PLAYER) {
+ // See where Holmes is with respect to the NPC (x coords)
+ if (people[HOLMES]._position.x < people[npc]._position.x)
+ people[npc]._npcFacing = STOP_LEFT;
+ else
+ people[npc]._npcFacing = STOP_RIGHT;
+
+ // See where Holmes is with respect to the NPC (y coords)
+ if (people[HOLMES]._position.y < people[npc]._position.y - (10 * FIXED_INT_MULTIPLIER)) {
+ // Holmes is above the NPC so reset the facing to the diagonal ups
+ if (people[npc]._npcFacing == STOP_RIGHT)
+ people[npc]._npcFacing = STOP_UPRIGHT;
+ else
+ people[npc]._npcFacing = STOP_UPLEFT;
+ } else {
+ if (people[HOLMES]._position.y > people[npc]._position.y + (10 * FIXED_INT_MULTIPLIER)) {
+ // Holmes is below the NPC so reset the facing to the diagonal downs
+ if (people[npc]._npcFacing == STOP_RIGHT)
+ people[npc]._npcFacing = STOP_DOWNRIGHT;
+ else
+ people[npc]._npcFacing = STOP_DOWNLEFT;
+ }
+ }
+ }
+
+ _sequenceNumber = people[npc]._npcFacing;
+ } else {
+ switch (_sequenceNumber) {
+ case WALK_UP: _sequenceNumber = STOP_UP; break;
+ case WALK_UPRIGHT: _sequenceNumber = STOP_UPRIGHT; break;
+ case WALK_RIGHT: _sequenceNumber = STOP_RIGHT; break;
+ case WALK_DOWNRIGHT: _sequenceNumber = STOP_DOWNRIGHT; break;
+ case WALK_DOWN: _sequenceNumber = STOP_DOWN; break;
+ case WALK_DOWNLEFT: _sequenceNumber = STOP_DOWNLEFT;break;
+ case WALK_LEFT: _sequenceNumber = STOP_LEFT; break;
+ case WALK_UPLEFT: _sequenceNumber = STOP_UPLEFT; break;
+ }
+ }
+
+ // Only restart the frame number at 0 if the new sequence is different from the last sequence
+ // so we don't let Holmes repeat standing.
+ if (_oldWalkSequence != -1) {
+ if (_seqTo) {
+ // Reset to previous value
+ _walkSequences[oldFacing]._sequences[_frameNumber] = _seqTo;
+ _seqTo = 0;
+ }
+
+ _frameNumber = 0;
+ }
+
+ checkWalkGraphics();
+
+ _oldWalkSequence = -1;
+ people._allowWalkAbort = true;
+}
+
+void TattooPerson::setWalking() {
+ TattooScene &scene = *(TattooScene *)_vm->_scene;
+ int oldDirection, oldFrame;
+ Common::Point delta;
+ _nextDest = _walkDest;
+
+ // Flag that player has now walked in the scene
+ scene._walkedInScene = true;
+
+ // Stop any previous walking, since a new dest is being set
+ _walkCount = 0;
+ oldDirection = _sequenceNumber;
+ oldFrame = _frameNumber;
+
+ // Set speed to use horizontal and vertical movement
+ int scaleVal = scene.getScaleVal(_position);
+ Common::Point speed(MAX(WALK_SPEED_X[scene._currentScene - 1] * SCALE_THRESHOLD / scaleVal, 2),
+ MAX(WALK_SPEED_Y[scene._currentScene - 1] * SCALE_THRESHOLD / scaleVal, 2));
+ Common::Point diagSpeed(MAX(WALK_SPEED_DIAG_X[scene._currentScene - 1] * SCALE_THRESHOLD / scaleVal, 2),
+ MAX((WALK_SPEED_Y[scene._currentScene - 1] - 2) * SCALE_THRESHOLD / scaleVal, 2));
+
+ // If the player is already close to the given destination that no walking is needed,
+ // move to the next straight line segment in the overall walking route, if there is one
+ for (;;) {
+ if (_centerWalk || !_walkTo.empty()) {
+ // Since we want the player to be centered on the ultimate destination, and the player
+ // is drawn from the left side, move the cursor half the width of the player to center it
+ delta = Common::Point(_position.x / FIXED_INT_MULTIPLIER - _walkDest.x,
+ _position.y / FIXED_INT_MULTIPLIER - _walkDest.y);
+
+ int dir;
+ if (ABS(delta.x) > ABS(delta.y))
+ dir = (delta.x < 0) ? WALK_LEFT : WALK_RIGHT;
+ else
+ dir = (delta.y < 0) ? WALK_UP : WALK_DOWN;
+
+ scaleVal = scene.getScaleVal(Point32(_walkDest.x * FIXED_INT_MULTIPLIER,
+ _walkDest.y * FIXED_INT_MULTIPLIER));
+ _walkDest.x -= _stopFrames[dir]->sDrawXSize(scaleVal) / 2;
+ }
+
+ delta = Common::Point(
+ ABS(_position.x / FIXED_INT_MULTIPLIER - _walkDest.x),
+ ABS(_position.y / FIXED_INT_MULTIPLIER - _walkDest.y)
+ );
+
+ // If we're ready to move a sufficient distance, that's it. Otherwise,
+ // move onto the next portion of the walk path, if there is one
+ if ((delta.x > 3 || delta.y > 0) || _walkTo.empty())
+ break;
+
+ // Pop next walk segment off the walk route stack
+ _walkDest = _walkTo.pop();
+ }
+
+ // If a sufficient move is being done, then start the move
+ if (delta.x > 3 || delta.y) {
+ // See whether the major movement is horizontal or vertical
+ if (delta.x >= delta.y) {
+ // Set the initial frame sequence for the left and right, as well
+ // as setting the delta x depending on direction
+ if (_walkDest.x < (_position.x / FIXED_INT_MULTIPLIER)) {
+ _sequenceNumber = WALK_LEFT;
+ _delta.x = speed.x * -(FIXED_INT_MULTIPLIER / 10);
+ } else {
+ _sequenceNumber = WALK_RIGHT;
+ _delta.x = speed.x * (FIXED_INT_MULTIPLIER / 10);
+ }
+
+ // See if the x delta is too small to be divided by the speed, since
+ // this would cause a divide by zero error
+ if ((delta.x * 10) >= speed.x) {
+ // Det the delta y
+ _delta.y = (delta.y * FIXED_INT_MULTIPLIER) / ((delta.x * 10) / speed.x);
+ if (_walkDest.y < (_position.y / FIXED_INT_MULTIPLIER))
+ _delta.y = -_delta.y;
+
+ // Set how many times we should add the delta to the player's position
+ _walkCount = (delta.x * 10) / speed.x;
+ } else {
+ // The delta x was less than the speed (ie. we're really close to
+ // the destination). So set delta to 0 so the player won't move
+ _delta = Point32(0, 0);
+ _position = Point32(_walkDest.x * FIXED_INT_MULTIPLIER, _walkDest.y * FIXED_INT_MULTIPLIER);
+
+ _walkCount = 1;
+ }
+
+ // See if the sequence needs to be changed for diagonal walking
+ if (_delta.y > 1500) {
+ if (_sequenceNumber == WALK_LEFT || _sequenceNumber == WALK_RIGHT) {
+ _delta.x = _delta.x / speed.x * diagSpeed.x;
+ _delta.y = (delta.y * FIXED_INT_MULTIPLIER) / (delta.x * 10 / diagSpeed.x);
+
+ _walkCount = delta.x * 10 / diagSpeed.x;
+ }
+
+ switch (_sequenceNumber) {
+ case WALK_LEFT:
+ _sequenceNumber = WALK_DOWNLEFT;
+ break;
+ case WALK_RIGHT:
+ _sequenceNumber = WALK_DOWNRIGHT;
+ break;
+ }
+ } else if (_delta.y < -1500) {
+ if (_sequenceNumber == WALK_LEFT || _sequenceNumber == WALK_RIGHT) {
+ _delta.x = _delta.x / speed.x * diagSpeed.x;
+ _delta.y = -1 * (delta.y * FIXED_INT_MULTIPLIER) / (delta.x * 10 / diagSpeed.x);
+
+ _walkCount = (delta.x * 10) / diagSpeed.x;
+ }
+
+ switch (_sequenceNumber) {
+ case WALK_LEFT:
+ _sequenceNumber = WALK_UPLEFT;
+ break;
+ case WALK_RIGHT:
+ _sequenceNumber = WALK_UPRIGHT;
+ break;
+ }
+ }
+ } else {
+ // Major movement is vertical, so set the sequence for up and down,
+ // and set the delta Y depending on the direction
+ if (_walkDest.y < (_position.y / FIXED_INT_MULTIPLIER)) {
+ _sequenceNumber = WALK_UP;
+ _delta.y = speed.y * -(FIXED_INT_MULTIPLIER / 10);
+ } else {
+ speed.y = diagSpeed.y;
+ _sequenceNumber = WALK_DOWN;
+ _delta.y = speed.y * (FIXED_INT_MULTIPLIER / 10);
+ }
+
+ // Set the delta x
+ if (delta.y * 10 / speed.y)
+ _delta.x = (delta.x * FIXED_INT_MULTIPLIER) / (delta.y * 10 / speed.y);
+ else
+ _delta.x = (delta.x * FIXED_INT_MULTIPLIER) / delta.y;
+
+ if (_walkDest.x < _position.y / FIXED_INT_MULTIPLIER)
+ _delta.x = -_delta.x;
+
+ // Set how many times we should add the delta's to the players position
+ if (delta.y * 10 / speed.y)
+ _walkCount = delta.y * 10 / speed.y;
+ else
+ _walkCount = delta.y;
+ }
+ }
+
+ // See if the new walk sequence is the same as the old. If it's a new one,
+ // we need to reset the frame number to zero so it's animation starts at
+ // it's beginning. Otherwise, if it's the same sequence, we can leave it
+ // as is, so it keeps the animation going at wherever it was up to
+ if (_sequenceNumber != _oldWalkSequence) {
+ if (_seqTo) {
+ // Reset to previous value
+ _walkSequences[oldDirection]._sequences[_frameNumber] = _seqTo;
+ _seqTo = 0;
+ }
+ _frameNumber = 0;
+ }
+
+ checkWalkGraphics();
+ _oldWalkSequence = _sequenceNumber;
+
+ if (!_walkCount && _walkTo.empty())
+ gotoStand();
+
+ // If the sequence is the same as when we started, then Holmes was standing still and we're trying
+ // to re-stand him, so reset Holmes' rame to the old frame number from before it was reset to 0
+ if (_sequenceNumber == oldDirection)
+ _frameNumber = oldFrame;
+}
+
+void TattooPerson::walkToCoords(const Point32 &destPos, int destDir) {
+ TattooEngine &vm = *(TattooEngine *)_vm;
+ Events &events = *_vm->_events;
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ TattooScene &scene = *(TattooScene *)_vm->_scene;
+ Talk &talk = *_vm->_talk;
+
+ CursorId oldCursor = events.getCursor();
+ events.setCursor(WAIT);
+
+ _walkDest = Common::Point(destPos.x / FIXED_INT_MULTIPLIER, destPos.y / FIXED_INT_MULTIPLIER);
+
+ bool isHolmes = this == &people[HOLMES];
+ if (isHolmes) {
+ people._allowWalkAbort = true;
+ } else {
+ // Clear the path Variables
+ _npcIndex = _npcPause;
+ Common::fill(_npcPath, _npcPath + 100, 0);
+ _npcFacing = destDir;
+ }
+
+ _centerWalk = false;
+
+ // Only move the person if they're going an appreciable distance
+ if (ABS(_walkDest.x - (_position.x / FIXED_INT_MULTIPLIER)) > 8 ||
+ ABS(_walkDest.y - (_position.y / FIXED_INT_MULTIPLIER)) > 4) {
+ goAllTheWay();
+
+ do {
+ // Keep doing animations whilst walk is in progress
+ events.wait(1);
+ scene.doBgAnim();
+
+ if (events.kbHit()) {
+ Common::KeyState keyState = events.getKey();
+
+ if (keyState.keycode == Common::KEYCODE_ESCAPE && vm._runningProlog) {
+ vm.setFlags(-76);
+ vm.setFlags(396);
+ scene._goToScene = 1;
+ talk._talkToAbort = true;
+ }
+ }
+ } while (!_vm->shouldQuit() && _walkCount && !talk._talkToAbort);
+ }
+
+ _centerWalk = true;
+ if (!isHolmes)
+ _updateNPCPath = true;
+
+ if (!talk._talkToAbort) {
+ // put character exactly on right spot
+ _position = destPos;
+
+ if (_sequenceNumber != destDir) {
+ // Facing character to correct ending direction
+ _sequenceNumber = destDir;
+ gotoStand();
+ }
+
+ if (!isHolmes)
+ _updateNPCPath = false;
+
+ // Secondary walking wait loop
+ bool done = false;
+ while (!done && !_vm->shouldQuit()) {
+ events.wait(1);
+ scene.doBgAnim();
+
+ // See if we're past the initial goto stand sequence
+ for (int idx = 0; idx < _frameNumber; ++idx) {
+ if (_walkSequences[_sequenceNumber][idx] == 0) {
+ done = true;
+ break;
+ }
+ }
+
+ if (events.kbHit()) {
+ Common::KeyState keyState = events.getKey();
+
+ if (keyState.keycode == Common::KEYCODE_ESCAPE && vm._runningProlog) {
+ vm.setFlags(-76);
+ vm.setFlags(396);
+ scene._goToScene = 1;
+ talk._talkToAbort = true;
+ }
+ }
+ }
+
+ if (!isHolmes)
+ _updateNPCPath = true;
+
+ if (!talk._talkToAbort)
+ events.setCursor(oldCursor);
+ }
+}
+
+void TattooPerson::clearNPC() {
+ Common::fill(&_npcPath[0], &_npcPath[MAX_NPC_PATH], 0);
+ _npcIndex = 0;
+ _pathStack.clear();
+ _npcName = "";
+}
+
+void TattooPerson::updateNPC() {
+ People &people = *_vm->_people;
+ Talk &talk = *_vm->_talk;
+
+ // If the NPC isn't on, or it's in Talk or Listen Mode, then return without doing anything
+ if (_type != CHARACTER || _sequenceNumber >= TALK_UPRIGHT)
+ return;
+
+ // If the NPC is paused, just decrement his pause counter and exit
+ if (_npcPause) {
+ // Decrement counter
+ --_npcPause;
+
+ // Now see if we need to update the NPC's frame sequence so that he faces Holmes
+ if (_lookHolmes) {
+ // See where Holmes is with respect to the NPC (x coordinate)
+ _npcFacing = (people[HOLMES]._position.x < _position.x) ? STOP_LEFT : STOP_RIGHT;
+
+ // See where Holmes is with respect to the NPC (y coordinate)
+ if (people[HOLMES]._position.y < (_position.y - 10 * FIXED_INT_MULTIPLIER)) {
+ // Holmes is above the NPC so reset the facing to a diagonal up
+ _npcFacing = (_npcFacing == STOP_RIGHT) ? STOP_UPRIGHT : STOP_UPLEFT;
+ } else if (people[HOLMES]._position.y > (_position.y + 10 * FIXED_INT_MULTIPLIER)) {
+ // Holmes is below the NPC so reset the facing to a diagonal down
+ _npcFacing = (_npcFacing == STOP_RIGHT) ? STOP_DOWNRIGHT : STOP_DOWNLEFT;
+ }
+
+ // See if we need to set the old_walk_sequence so the NPC will put his arms
+ // up if he turns another way
+ if (_sequenceNumber != _npcFacing)
+ _oldWalkSequence = _sequenceNumber;
+
+ gotoStand();
+ }
+ } else {
+ // Reset the look flag so the NPC won't face Holmes anymore
+ _lookHolmes = false;
+
+ // See if the NPC is stopped or not. Don't do anything if he's moving
+ if (!_walkCount) {
+ // If there is no new command, reset the path back to the beginning
+ if (!_npcPath[_npcIndex])
+ _npcIndex = 0;
+
+ // The NPC is stopped and any pause he was doing is done. We can now see what
+ // the next command in the NPC path is.
+
+ // Scan Past any NPC Path Labels since they do nothing except mark places for If's and Goto's
+ while (_npcPath[_npcIndex] == NPCPATH_PATH_LABEL)
+ _npcIndex += 2;
+
+ if (_npcPath[_npcIndex]) {
+ _npcFacing = -1;
+
+ switch (_npcPath[_npcIndex]) {
+ case NPCPATH_SET_DEST: {
+ // Set the NPC's new destination
+ int xp = (_npcPath[_npcIndex + 1] - 1) * 256 + _npcPath[_npcIndex + 2] - 1;
+ if (xp > 16384)
+ xp = -1 * (xp - 16384);
+ _walkDest.x = xp;
+ _walkDest.y = (_npcPath[_npcIndex + 3] - 1) * 256 + _npcPath[_npcIndex + 4] - 1;
+ _npcFacing = _npcPath[_npcIndex + 5] - 1;
+
+ goAllTheWay();
+ _npcIndex += 6;
+ break;
+ }
+
+ case NPCPATH_PAUSE:
+ // Set the NPC to pause where he is
+ _npcPause = (_npcPath[_npcIndex + 1] - 1) * 256 + _npcPath[_npcIndex + 2] - 1;
+ _npcIndex += 3;
+ break;
+
+ case NPCPATH_SET_TALK_FILE: {
+ // Set the NPC's Talk File to use if Holmes talks to them
+ ++_npcIndex;
+
+ _npcName = "";
+ for (int idx = 0; idx < 8; ++idx) {
+ if (_npcPath[_npcIndex + idx] != '~')
+ _npcName += _npcPath[_npcIndex + idx];
+ else
+ break;
+ }
+
+ _npcIndex += 8;
+ break;
+ }
+
+ case NPCPATH_CALL_TALK_FILE: {
+ // Call a Talk File
+ ++_npcIndex;
+
+ Common::String name;
+ for (int idx = 0; idx < 8; ++idx) {
+ if (_npcPath[_npcIndex + idx] != '~')
+ name += _npcPath[_npcIndex + idx];
+ else
+ break;
+ }
+
+ _npcIndex += 8;
+ talk.talkTo(name);
+ break;
+ }
+
+ case NPCPATH_TAKE_NOTES:
+ // Set the NPC to Pause where he is and set his frame sequences
+ // so he takes notes while he's paused
+ _npcPause = (_npcPath[_npcIndex + 1] - 1) * 256 + _npcPath[_npcIndex + 2] - 1;
+ _npcIndex += 3;
+ break;
+
+ case NPCPATH_FACE_HOLMES:
+ // Set the NPC to Pause where he is and set his look flag so he will always face Holmes
+ // while he is paused
+ _npcPause = (_npcPath[_npcIndex + 1] - 1) * 256 + _npcPath[_npcIndex + 2] - 1;
+ _lookHolmes = true;
+ _npcIndex += 3;
+ break;
+
+ //case NPCPATH_PATH_LABEL: // No implementation needed here
+
+ case NPCPATH_GOTO_LABEL: {
+ // Goto NPC Path Label
+ int label = _npcPath[_npcIndex + 1];
+ _npcIndex = 0;
+
+ // Scan through NPC path data to find the label
+ bool found = false;
+ while (!found) {
+ switch (_npcPath[_npcIndex]) {
+ case NPCPATH_SET_DEST:
+ _npcIndex += 6;
+ break;
+ case NPCPATH_PAUSE:
+ case NPCPATH_TAKE_NOTES:
+ case NPCPATH_FACE_HOLMES:
+ _npcIndex += 3;
+ break;
+ case NPCPATH_SET_TALK_FILE:
+ case NPCPATH_CALL_TALK_FILE:
+ _npcIndex += 8;
+ break;
+ case NPCPATH_PATH_LABEL:
+ if (_npcPath[_npcIndex + 1] == label)
+ found = true;
+ _npcIndex += 2;
+ break;
+ case NPCPATH_GOTO_LABEL:
+ _npcIndex += 2;
+ break;
+ case NPCPATH_IFFLAG_GOTO_LABEL:
+ _npcIndex += 4;
+ break;
+ }
+ }
+ break;
+ }
+
+ case NPCPATH_IFFLAG_GOTO_LABEL: {
+ // If FLAG then Goto Label
+ int flag = (_npcPath[_npcIndex + 1] - 1) * 256 + _npcPath[_npcIndex + 2] - 1 - (_npcPath[_npcIndex + 2] == 1 ? 1 : 0);
+
+ // Set the value the flag should be for the if statement to succeed
+ bool flagVal = flag < 16384;
+
+ int label = _npcPath[_npcIndex + 3];
+ _npcIndex += 4;
+
+ // If the flag is set Correctly, move the NPC Index to the given label
+ if (_vm->readFlags(flag & 16383) == flagVal) {
+ _npcIndex = 0;
+ bool found = false;
+ while (!found)
+ {
+ switch (_npcPath[_npcIndex])
+ {
+ case NPCPATH_SET_DEST:
+ _npcIndex += 6;
+ break;
+ case NPCPATH_PAUSE:
+ case NPCPATH_TAKE_NOTES:
+ case NPCPATH_FACE_HOLMES:
+ _npcIndex += 3;
+ break;
+ case NPCPATH_SET_TALK_FILE:
+ case NPCPATH_CALL_TALK_FILE:
+ _npcIndex += 8;
+ break;
+ case NPCPATH_PATH_LABEL:
+ if (_npcPath[_npcIndex + 1] == label)
+ found = true;
+ _npcIndex += 2;
+ break;
+ case NPCPATH_GOTO_LABEL:
+ _npcIndex += 2;
+ break;
+ case NPCPATH_IFFLAG_GOTO_LABEL:
+ _npcIndex += 4;
+ break;
+ }
+ }
+ }
+
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+}
+
+void TattooPerson::pushNPCPath() {
+ assert(_pathStack.size() < 2);
+ SavedNPCPath savedPath(_npcPath, _npcIndex, _npcPause, _position, _sequenceNumber, _lookHolmes);
+ _pathStack.push(savedPath);
+}
+
+void TattooPerson::pullNPCPath() {
+ // Pop the stack entry and restore the fields
+ SavedNPCPath path = _pathStack.pop();
+ Common::copy(&path._path[0], &path._path[MAX_NPC_PATH], &_npcPath[0]);
+ _npcIndex = path._npcIndex;
+ _npcPause = path._npcPause;
+
+ // Handle the first case if the NPC was paused
+ if (_npcPause) {
+ _walkDest = Common::Point(path._walkDest.x / FIXED_INT_MULTIPLIER, path._walkDest.y / FIXED_INT_MULTIPLIER);
+ _npcFacing = path._npcFacing;
+ _lookHolmes = path._lookHolmes;
+
+ // See if the NPC was moved
+ if (_walkDest.x != (_position.x / FIXED_INT_MULTIPLIER) ||
+ _walkDest.y != (_position.y / FIXED_INT_MULTIPLIER)) {
+ goAllTheWay();
+ _npcPause = 0;
+ _npcIndex -= 3;
+ } else {
+ // See if we need to set the old walk sequence so the NPC will put his arms up if he turns another way
+ if (_npcFacing != _sequenceNumber)
+ _oldWalkSequence = _sequenceNumber;
+
+ gotoStand();
+ }
+ } else {
+ // Handle the second case if the NPC was in motion
+ _npcIndex -= 6;
+ }
+}
+
+Common::Point TattooPerson::getSourcePoint() const {
+ TattooScene &scene = *(TattooScene *)_vm->_scene;
+ int scaleVal = scene.getScaleVal(_position);
+
+ return Common::Point(_position.x / FIXED_INT_MULTIPLIER + _imageFrame->sDrawXSize(scaleVal) / 2,
+ _position.y / FIXED_INT_MULTIPLIER);
+}
+
+void TattooPerson::setObjTalkSequence(int seq) {
+ assert(seq != -1 && _type == CHARACTER);
+
+ if (_seqTo) {
+ // reset to previous value
+ _walkSequences[_sequenceNumber]._sequences[_frameNumber] = _seqTo;
+ _seqTo = 0;
+ }
+
+ _sequenceNumber = _gotoSeq;
+ _frameNumber = 0;
+ checkWalkGraphics();
+}
+
+void TattooPerson::checkWalkGraphics() {
+ People &people = *_vm->_people;
+
+ if (_images == nullptr) {
+ freeAltGraphics();
+ return;
+ }
+
+ Common::String filename = Common::String::format("%s.vgs", _walkSequences[_sequenceNumber]._vgsName.c_str());
+
+ // Set the adjust depending on if we have to fine tune the x position of this particular graphic
+ _adjust.x = _adjust.y = 0;
+
+ for (int idx = 0; idx < NUM_ADJUSTED_WALKS; ++idx) {
+ if (!scumm_strnicmp(_walkSequences[_sequenceNumber]._vgsName.c_str(), ADJUST_WALKS[idx]._vgsName,
+ strlen(ADJUST_WALKS[idx]._vgsName))) {
+ if (_walkSequences[_sequenceNumber]._horizFlip)
+ _adjust.x = ADJUST_WALKS[idx]._flipXAdjust;
+ else
+ _adjust.x = ADJUST_WALKS[idx]._xAdjust;
+
+ _adjust.y = ADJUST_WALKS[idx]._yAdjust;
+ break;
+ }
+ }
+
+ // See if we're already using Alternate Graphics
+ if (_altSeq) {
+ // See if the VGS file called for is different than the alternate graphics already loaded
+ if (!_walkSequences[_sequenceNumber]._vgsName.compareToIgnoreCase(_walkSequences[_altSeq - 1]._vgsName)) {
+ // Different AltGraphics, Free the old ones
+ freeAltGraphics();
+ }
+ }
+
+ // If there is no Alternate Sequence set, see if we need to load a new one
+ if (!_altSeq) {
+ int npcNum = -1;
+ // Find which NPC this is so we can check the name of the graphics loaded
+ for (int idx = 0; idx < MAX_CHARACTERS; ++idx) {
+ if (this == &people[idx]) {
+ npcNum = idx;
+ break;
+ }
+ }
+
+ if (npcNum != -1) {
+ // See if the VGS file called for is different than the main graphics which are already loaded
+ if (filename.compareToIgnoreCase(people[npcNum]._walkVGSName) != 0) {
+ // See if this is one of the more used Walk Graphics stored in WALK.LIB
+ for (int idx = 0; idx < NUM_IN_WALK_LIB; ++idx) {
+ if (!scumm_stricmp(filename.c_str(), WALK_LIB_NAMES[idx])) {
+ people._useWalkLib = true;
+ break;
+ }
+ }
+
+ _altImages = new ImageFile(filename);
+ people._useWalkLib = false;
+
+ _altSeq = _sequenceNumber + 1;
+ }
+ }
+ }
+
+ // If this is a different seqeunce from the current sequence, reset the appropriate variables
+ if (_sequences != &_walkSequences[_sequenceNumber]._sequences[0]) {
+ _seqTo = _seqCounter = _seqCounter2 = _seqStack = _startSeq = 0;
+ _sequences = &_walkSequences[_sequenceNumber]._sequences[0];
+ _seqSize = _walkSequences[_sequenceNumber]._sequences.size();
+ }
+
+ setImageFrame();
+}
+
+void TattooPerson::synchronize(Serializer &s) {
+ s.syncAsSint32LE(_position.x);
+ s.syncAsSint32LE(_position.y);
+ s.syncAsSint16LE(_sequenceNumber);
+ s.syncAsSint16LE(_type);
+ s.syncString(_walkVGSName);
+ s.syncString(_description);
+ s.syncString(_examine);
+
+ // NPC specific properties
+ s.syncBytes(&_npcPath[0], MAX_NPC_PATH);
+ s.syncString(_npcName);
+ s.syncAsSint32LE(_npcPause);
+ s.syncAsByte(_lookHolmes);
+ s.syncAsByte(_updateNPCPath);
+
+ // Walk to list
+ uint count = _walkTo.size();
+ s.syncAsUint16LE(count);
+ if (s.isLoading()) {
+ // Load path
+ for (uint idx = 0; idx < count; ++idx) {
+ int xp = 0, yp = 0;
+ s.syncAsSint16LE(xp);
+ s.syncAsSint16LE(yp);
+ _walkTo.push(Common::Point(xp, yp));
+ }
+ } else {
+ // Save path
+ Common::Array<Common::Point> path;
+
+ // Save the points of the path
+ for (uint idx = 0; idx < count; ++idx) {
+ Common::Point pt = _walkTo.pop();
+ s.syncAsSint16LE(pt.x);
+ s.syncAsSint16LE(pt.y);
+ path.push_back(pt);
+ }
+
+ // Re-add the pending points back to the _walkTo queue
+ for (uint idx = 0; idx < count; ++idx)
+ _walkTo.push(path[idx]);
+ }
+
+ // Verbs
+ for (int idx = 0; idx < 2; ++idx)
+ _use[idx].synchronize(s);
+}
+
+void TattooPerson::walkHolmesToNPC() {
+ Events &events = *_vm->_events;
+ TattooScene &scene = *(TattooScene *)_vm->_scene;
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ Screen &screen = *_vm->_screen;
+ Talk &talk = *_vm->_talk;
+ TattooPerson &holmes = people[HOLMES];
+ int facing;
+
+ // If the NPC is moving, stop him at his current position
+ if (_walkCount) {
+ // Reset the facing so the NPC will stop facing the direction he was going,
+ // rather than the direction he was supposed to when he finished wlaking
+ _npcFacing = -1;
+ gotoStand();
+ }
+
+ int scaleVal = scene.getScaleVal(_position);
+ ImageFrame &imgFrame = (*holmes._images)[0];
+
+ // Clear the path variables
+ memset(_npcPath, 0, 100);
+
+ // Set the NPC path so he pauses for 250 while looking at Holmes
+ _npcPath[0] = 6;
+ _npcPath[1] = 1;
+ _npcPath[2] = 251;
+ _npcIndex = 0;
+ _npcPause = 250;
+ _lookHolmes = true;
+
+ // See where Holmes is with respect to the NPC (x coords)
+ if (holmes._position.x < _position.x) {
+ holmes._walkDest.x = MAX(_position.x / FIXED_INT_MULTIPLIER - imgFrame.sDrawXSize(scaleVal), 0);
+ } else {
+ holmes._walkDest.x = MIN(_position.x / FIXED_INT_MULTIPLIER + imgFrame.sDrawXSize(scaleVal) * 2,
+ screen._backBuffer1.w() - 1);
+ }
+
+ // See where Holmes is with respect to the NPC (y coords)
+ if (holmes._position.y < (_position.y - imgFrame.sDrawXSize(scaleVal) * 500)) {
+ holmes._walkDest.y = MAX(_position.y / FIXED_INT_MULTIPLIER - imgFrame.sDrawXSize(scaleVal) / 2, 0);
+ } else {
+ if (holmes._position.y > (_position.y + imgFrame.sDrawXSize(scaleVal) * 500)) {
+ // Holmes is below the NPC
+ holmes._walkDest.y = MIN(_position.y / FIXED_INT_MULTIPLIER + imgFrame.sDrawXSize(scaleVal) / 2,
+ SHERLOCK_SCREEN_HEIGHT - 1);
+ } else {
+ // Holmes is roughly on the same Y as the NPC
+ holmes._walkDest.y = _position.y / FIXED_INT_MULTIPLIER;
+ }
+ }
+
+ events.setCursor(WAIT);
+
+ _walkDest.x += 10;
+ people._allowWalkAbort = true;
+ holmes.goAllTheWay();
+
+ // Do doBgAnim should be called over and over until walk is done
+ do {
+ events.wait(1);
+ scene.doBgAnim();
+ } while (holmes._walkCount);
+
+ if (!talk._talkToAbort) {
+ // Setup correct direction for Holmes to face
+
+ // See where Holmes is with respect to the NPC (x coords)
+ facing = (holmes._position.x < _position.x) ? STOP_RIGHT : STOP_LEFT;
+
+ // See where Holmes is with respect to the NPC (y coords)
+ if (holmes._position.y < (_position.y - (10 * FIXED_INT_MULTIPLIER))) {
+ // Holmes is above the NPC. Reset the facing to the diagonal downs
+ facing = (facing == STOP_RIGHT) ? STOP_DOWNRIGHT : STOP_DOWNLEFT;
+ } else {
+ if (holmes._position.y > (_position.y + 10 * FIXED_INT_MULTIPLIER)) {
+ // Holmes is below the NPC. Reset the facing to the diagonal ups
+ facing = (facing == STOP_RIGHT) ? STOP_UPRIGHT : STOP_UPLEFT;
+ }
+ }
+
+ holmes._sequenceNumber = facing;
+ holmes.gotoStand();
+
+ events.setCursor(ARROW);
+ }
+}
+
+/*----------------------------------------------------------------*/
+
+TattooPeople::TattooPeople(SherlockEngine *vm) : People(vm) {
+ for (int idx = 0; idx < 6; ++idx)
+ _data.push_back(new TattooPerson());
+}
+
+void TattooPeople::setListenSequence(int speaker, int sequenceNum) {
+ Scene &scene = *_vm->_scene;
+
+ // If no speaker is specified, then nothing needs to be done
+ if (speaker == -1)
+ return;
+
+ int objNum = findSpeaker(speaker);
+ if (objNum < 256 && objNum != -1) {
+ // See if the Object has to wait for an Abort Talk Code
+ Object &obj = scene._bgShapes[objNum];
+ if (obj.hasAborts())
+ obj._gotoSeq = sequenceNum;
+ else
+ obj.setObjTalkSequence(sequenceNum);
+ } else if (objNum != -1) {
+ objNum -= 256;
+ TattooPerson &person = (*this)[objNum];
+
+ int newDir = person._sequenceNumber;
+ switch (person._sequenceNumber) {
+ case WALK_UP:
+ case STOP_UP:
+ case WALK_UPRIGHT:
+ case STOP_UPRIGHT:
+ case TALK_UPRIGHT:
+ case LISTEN_UPRIGHT:
+ newDir = LISTEN_UPRIGHT;
+ break;
+ case WALK_RIGHT:
+ case STOP_RIGHT:
+ case TALK_RIGHT:
+ case LISTEN_RIGHT:
+ newDir = LISTEN_RIGHT;
+ break;
+ case WALK_DOWNRIGHT:
+ case STOP_DOWNRIGHT:
+ case TALK_DOWNRIGHT:
+ case LISTEN_DOWNRIGHT:
+ newDir = LISTEN_DOWNRIGHT;
+ break;
+ case WALK_DOWN:
+ case STOP_DOWN:
+ case WALK_DOWNLEFT:
+ case STOP_DOWNLEFT:
+ case TALK_DOWNLEFT:
+ case LISTEN_DOWNLEFT:
+ newDir = LISTEN_DOWNLEFT;
+ break;
+ case WALK_LEFT:
+ case STOP_LEFT:
+ case TALK_LEFT:
+ case LISTEN_LEFT:
+ newDir = LISTEN_LEFT;
+ break;
+ case WALK_UPLEFT:
+ case STOP_UPLEFT:
+ case TALK_UPLEFT:
+ case LISTEN_UPLEFT:
+ newDir = LISTEN_UPLEFT;
+ break;
+
+ default:
+ break;
+ }
+
+ // See if the NPC's Seq has to wait for an Abort Talk Code
+ if (person.hasAborts()) {
+ person._gotoSeq = newDir;
+ } else {
+ if (person._seqTo) {
+ // Reset to previous value
+ person._walkSequences[person._sequenceNumber]._sequences[person._frameNumber] = person._seqTo;
+ person._seqTo = 0;
+ }
+
+ person._sequenceNumber = newDir;
+ person._frameNumber = 0;
+ person.checkWalkGraphics();
+ }
+ }
+}
+
+void TattooPeople::setTalkSequence(int speaker, int sequenceNum) {
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ Scene &scene = *_vm->_scene;
+ TattooTalk &talk = *(TattooTalk *)_vm->_talk;
+
+ // If no speaker is specified, then nothing needs to be done
+ if (speaker == -1)
+ return;
+
+ int objNum = people.findSpeaker(speaker);
+ if (objNum != -1 && objNum < 256) {
+ Object &obj = scene._bgShapes[objNum];
+
+ // See if the Object has to wait for an Abort Talk Code
+ if (obj.hasAborts()) {
+ talk.pushTalkSequence(&obj);
+ obj._gotoSeq = sequenceNum;
+ }
+ else {
+ obj.setObjTalkSequence(sequenceNum);
+ }
+ }
+ else if (objNum != -1) {
+ objNum -= 256;
+ TattooPerson &person = people[objNum];
+ int newDir = person._sequenceNumber;
+
+ switch (newDir) {
+ case WALK_UP:
+ case STOP_UP:
+ case WALK_UPRIGHT:
+ case STOP_UPRIGHT:
+ case TALK_UPRIGHT:
+ case LISTEN_UPRIGHT:
+ newDir = TALK_UPRIGHT;
+ break;
+ case WALK_RIGHT:
+ case STOP_RIGHT:
+ case TALK_RIGHT:
+ case LISTEN_RIGHT:
+ newDir = TALK_RIGHT;
+ break;
+ case WALK_DOWNRIGHT:
+ case STOP_DOWNRIGHT:
+ case TALK_DOWNRIGHT:
+ case LISTEN_DOWNRIGHT:
+ newDir = TALK_DOWNRIGHT;
+ break;
+ case WALK_DOWN:
+ case STOP_DOWN:
+ case WALK_DOWNLEFT:
+ case STOP_DOWNLEFT:
+ case TALK_DOWNLEFT:
+ case LISTEN_DOWNLEFT:
+ newDir = TALK_DOWNLEFT;
+ break;
+ case WALK_LEFT:
+ case STOP_LEFT:
+ case TALK_LEFT:
+ case LISTEN_LEFT:
+ newDir = TALK_LEFT;
+ break;
+ case WALK_UPLEFT:
+ case STOP_UPLEFT:
+ case TALK_UPLEFT:
+ case LISTEN_UPLEFT:
+ newDir = TALK_UPLEFT;
+ break;
+ default:
+ break;
+ }
+
+ // See if the NPC's sequence has to wait for an Abort Talk Code
+ if (person.hasAborts()) {
+ person._gotoSeq = newDir;
+ } else {
+ if (person._seqTo) {
+ // Reset to previous value
+ person._walkSequences[person._sequenceNumber]._sequences[person._frameNumber] = person._seqTo;
+ person._seqTo = 0;
+ }
+
+ person._sequenceNumber = newDir;
+ person._frameNumber = 0;
+ person.checkWalkGraphics();
+ }
+ }
+}
+
+
+int TattooPeople::findSpeaker(int speaker) {
+ int result = People::findSpeaker(speaker);
+ const char *portrait = _characters[speaker]._portrait;
+
+ // Fallback that Rose Tattoo uses if no speaker was found
+ if (result == -1) {
+ bool flag = _vm->readFlags(FLAG_PLAYER_IS_HOLMES);
+
+ if (_data[HOLMES]->_type == CHARACTER && ((speaker == HOLMES && flag) || (speaker == WATSON && !flag)))
+ return -1;
+
+ for (uint idx = 1; idx < _data.size(); ++idx) {
+ TattooPerson &p = (*this)[idx];
+
+ if (p._type == CHARACTER) {
+ Common::String name(p._name.c_str(), p._name.c_str() + 4);
+
+ if (name.equalsIgnoreCase(portrait) && p._npcName[4] >= '0' && p._npcName[4] <= '9')
+ return idx + 256;
+ }
+ }
+ }
+
+ return -1;
+}
+
+void TattooPeople::synchronize(Serializer &s) {
+ s.syncAsByte(_holmesOn);
+
+ for (uint idx = 0; idx < _data.size(); ++idx)
+ (*this)[idx].synchronize(s);
+
+ s.syncAsSint16LE(_holmesQuotient);
+
+ if (s.isLoading()) {
+ _savedPos.x = _data[HOLMES]->_position.x;
+ _savedPos.y = _data[HOLMES]->_position.y;
+ _savedPos._facing = _data[HOLMES]->_sequenceNumber;
+ }
+}
+
+bool TattooPeople::loadWalk() {
+ Resources &res = *_vm->_res;
+ bool result = false;
+
+ for (int idx = 0; idx < MAX_CHARACTERS; ++idx) {
+ Person &person = *_data[idx];
+
+ if (!person._walkLoaded && (person._type == CHARACTER || person._type == HIDDEN_CHARACTER)) {
+ if (person._type == HIDDEN_CHARACTER)
+ person._type = INVALID;
+
+ // See if this is one of the more used Walk Graphics stored in WALK.LIB
+ for (int libNum = 0; libNum < NUM_IN_WALK_LIB; ++libNum) {
+ if (!person._walkVGSName.compareToIgnoreCase(WALK_LIB_NAMES[libNum])) {
+ _useWalkLib = true;
+ break;
+ }
+ }
+
+ // Load the images for the character
+ person._images = new ImageFile(person._walkVGSName, false);
+ person._maxFrames = person._images->size();
+
+ // Load walk sequence data
+ Common::String fname = Common::String(person._walkVGSName.c_str(), strchr(person._walkVGSName.c_str(), '.'));
+ fname += ".SEQ";
+
+ // Load the walk sequence data
+ Common::SeekableReadStream *stream = res.load(fname, _useWalkLib ? "walk.lib" : "vgs.lib");
+
+ person._walkSequences.resize(stream->readByte());
+
+ for (uint seqNum = 0; seqNum < person._walkSequences.size(); ++seqNum)
+ person._walkSequences[seqNum].load(*stream);
+
+ // Close the sequences resource
+ delete stream;
+ _useWalkLib = false;
+
+ person._sequences = &person._walkSequences[person._sequenceNumber]._sequences[0];
+ person._seqSize = person._walkSequences[person._sequenceNumber]._sequences.size();
+ person._frameNumber = 0;
+ person.setImageFrame();
+
+ // Set the stop Frames pointers
+ for (int dirNum = 0; dirNum < 8; ++dirNum) {
+ int count = 0;
+ while (person._walkSequences[dirNum + 8][count] != 0)
+ ++count;
+ count += 2;
+ count = person._walkSequences[dirNum + 8][count] - 1;
+ person._stopFrames[dirNum] = &(*person._images)[count];
+ }
+
+ result = true;
+ person._walkLoaded = true;
+ } else if (person._type != CHARACTER) {
+ person._walkLoaded = false;
+ }
+ }
+
+ _forceWalkReload = false;
+ return result;
+}
+
+
+void TattooPeople::pullNPCPaths() {
+ for (int idx = 1; idx < MAX_CHARACTERS; ++idx) {
+ TattooPerson &p = (*this)[idx];
+ if (p._npcMoved) {
+ while (!p._pathStack.empty())
+ p.pullNPCPath();
+ }
+ }
+}
+
+const Common::Point TattooPeople::restrictToZone(int zoneId, const Common::Point &destPos) {
+ Scene &scene = *_vm->_scene;
+ Screen &screen = *_vm->_screen;
+ Common::Rect &r = scene._zones[zoneId];
+
+ if (destPos.x < 0 || destPos.x > screen._backBuffer1.w())
+ return destPos;
+ else if (destPos.y < r.top && r.left < destPos.x && destPos.x < r.right)
+ return Common::Point(destPos.x, r.top);
+ else if (destPos.y > r.bottom && r.left < destPos.x && destPos.x < r.right)
+ return Common::Point(destPos.x, r.bottom);
+ else if (destPos.x < r.left && r.top < destPos.y && destPos.y < r.bottom)
+ return Common::Point(r.left, destPos.y);
+ else if (destPos.x > r.right && r.top < destPos.y && destPos.y < r.bottom)
+ return Common::Point(r.bottom, destPos.y);
+
+ // Find which corner of the zone the point is closet to
+ if (destPos.x <= r.left) {
+ return Common::Point(r.left, (destPos.y <= r.top) ? r.top : r.bottom);
+ } else {
+ return Common::Point(r.right, (destPos.y <= r.top) ? r.top : r.bottom);
+ }
+}
+
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/tattoo/tattoo_people.h b/engines/sherlock/tattoo/tattoo_people.h
new file mode 100644
index 0000000000..fb3f6e7628
--- /dev/null
+++ b/engines/sherlock/tattoo/tattoo_people.h
@@ -0,0 +1,270 @@
+/* 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 SHERLOCK_TATTOO_PEOPLE_H
+#define SHERLOCK_TATTOO_PEOPLE_H
+
+#include "common/scummsys.h"
+#include "common/stack.h"
+#include "sherlock/people.h"
+
+namespace Sherlock {
+
+class SherlockEngine;
+
+namespace Tattoo {
+
+// Animation sequence identifiers for characters
+enum TattooSequences {
+ // Walk Sequences Numbers for NPCs
+ WALK_UP = 0,
+ WALK_UPRIGHT = 1,
+ WALK_RIGHT = 2,
+ WALK_DOWNRIGHT = 3,
+ WALK_DOWN = 4,
+ WALK_DOWNLEFT = 5,
+ WALK_LEFT = 6,
+ WALK_UPLEFT = 7,
+
+ // Stop Sequences Numbers for NPCs
+ STOP_UP = 8,
+ STOP_UPRIGHT = 9,
+ STOP_RIGHT = 10,
+ STOP_DOWNRIGHT = 11,
+ STOP_DOWN = 12,
+ STOP_DOWNLEFT = 13,
+ STOP_LEFT = 14,
+ STOP_UPLEFT = 15,
+
+ // NPC Talk Sequence Numbers
+ TALK_UPRIGHT = 16,
+ TALK_RIGHT = 17,
+ TALK_DOWNRIGHT = 18,
+ TALK_DOWNLEFT = 19,
+ TALK_LEFT = 20,
+ TALK_UPLEFT = 21,
+
+ // NPC Listen Sequence Numbers
+ LISTEN_UPRIGHT = 22,
+ LISTEN_RIGHT = 23,
+ LISTEN_DOWNRIGHT = 24,
+ LISTEN_DOWNLEFT = 25,
+ LISTEN_LEFT = 26,
+ LISTEN_UPLEFT = 27
+};
+
+enum NpcPath {
+ NPCPATH_SET_DEST = 1,
+ NPCPATH_PAUSE = 2,
+ NPCPATH_SET_TALK_FILE = 3,
+ NPCPATH_CALL_TALK_FILE = 4,
+ NPCPATH_TAKE_NOTES = 5,
+ NPCPATH_FACE_HOLMES = 6,
+ NPCPATH_PATH_LABEL = 7,
+ NPCPATH_GOTO_LABEL = 8,
+ NPCPATH_IFFLAG_GOTO_LABEL = 9
+};
+
+struct SavedNPCPath {
+ byte _path[MAX_NPC_PATH];
+ int _npcIndex;
+ int _npcPause;
+ Common::Point _walkDest;
+ int _npcFacing;
+ bool _lookHolmes;
+
+ SavedNPCPath();
+ SavedNPCPath(byte path[MAX_NPC_PATH], int npcIndex, int npcPause, const Common::Point &walkDest,
+ int npcFacing, bool lookHolmes);
+};
+
+class TattooPerson: public Person {
+private:
+ Point32 _nextDest;
+private:
+ bool checkCollision() const;
+
+ /**
+ * Free the alternate graphics used by NPCs
+ */
+ void freeAltGraphics();
+protected:
+ /**
+ * Get the source position for a character potentially affected by scaling
+ */
+ virtual Common::Point getSourcePoint() const;
+public:
+ Common::Stack<SavedNPCPath> _pathStack;
+ int _npcIndex;
+ int _npcPause;
+ byte _npcPath[MAX_NPC_PATH];
+ bool _npcMoved;
+ int _npcFacing;
+ bool _resetNPCPath;
+ int _savedNpcSequence;
+ int _savedNpcFrame;
+ int _tempX;
+ int _tempScaleVal;
+ bool _updateNPCPath;
+ bool _lookHolmes;
+public:
+ TattooPerson();
+ virtual ~TattooPerson() {}
+
+ /**
+ * Clear the NPC related data
+ */
+ void clearNPC();
+
+ /**
+ * Called from doBgAnim to move NPCs along any set paths. If an NPC is paused in his path,
+ * he will remain paused until his pause timer runs out. If he is walking somewhere,
+ * he will continue walking there until he reaches the dest position. When an NPC stops moving,
+ * the next element of his path is processed.
+ *
+ * The path is an array of bytes with control codes followed by their parameters as needed.
+ */
+ void updateNPC();
+
+ /**
+ * Push the NPC's path data onto the path stack for when a talk file moves the NPC that
+ * has some control codes.
+ */
+ void pushNPCPath();
+
+ /**
+ * Pull an NPC's path data that has been previously saved on the path stack for that character.
+ * There are two possibilities for when the NPC was interrupted, and both are handled differently:
+ * 1) The NPC was paused at a position
+ * If the NPC didn't move, we can just restore his pause counter and exit. But if he did move,
+ * he must return to that position, and the path index must be reset to the pause he was executing.
+ * This means that the index must be decremented by 3
+ * 2) The NPC was in route to a position
+ * He must be set to walk to that position again. This is done by moving the path index
+ * so that it points to the code that set the NPC walking there in the first place.
+ * The regular calls to updateNPC will handle the rest
+ */
+ void pullNPCPath();
+
+ /**
+ * Checks a sprite associated with an NPC to see if the frame sequence specified
+ * in the sequence number uses alternate graphics, and if so if they need to be loaded
+ */
+ void checkWalkGraphics();
+
+ /**
+ * Synchronize the data for a savegame
+ */
+ void synchronize(Serializer &s);
+
+ /**
+ * This adjusts the sprites position, as well as it's animation sequence:
+ */
+ virtual void adjustSprite();
+
+ /**
+ * Bring a moving character to a standing position
+ */
+ virtual void gotoStand();
+
+ /**
+ * Set the variables for moving a character from one poisition to another
+ * in a straight line
+ */
+ virtual void setWalking();
+
+ /**
+ * Walk to the co-ordinates passed, and then face the given direction
+ */
+ virtual void walkToCoords(const Point32 &destPos, int destDir);
+
+ /**
+ * Adjusts the frame and sequence variables of a sprite that corresponds to the current speaker
+ * so that it points to the beginning of the sequence number's talk sequence in the object's
+ * sequence buffer
+ * @param seq Which sequence to use (if there's more than 1)
+ * @remarks 1: First talk seq, 2: second talk seq, etc.
+ */
+ virtual void setObjTalkSequence(int seq);
+
+ /**
+ * Walk Holmes to the NPC
+ */
+ void walkHolmesToNPC();
+};
+
+class TattooPeople : public People {
+public:
+ TattooPeople(SherlockEngine *vm);
+ virtual ~TattooPeople() {}
+
+ TattooPerson &operator[](PeopleId id) { return *(TattooPerson *)_data[id]; }
+ TattooPerson &operator[](int idx) { return *(TattooPerson *)_data[idx]; }
+
+ /**
+ * If the specified speaker is a background object, it will set it so that it uses
+ * the Listen Sequence (specified by the sequence number). If the current sequence
+ * has an Allow Talk Code in it, the _gotoSeq field will be set so that the object
+ * begins listening as soon as it hits the Allow Talk Code. If there is no Abort Code,
+ * the Listen Sequence will begin immediately.
+ * @param speaker Who is speaking
+ * @param sequenceNum Which listen sequence to use
+ */
+ void setListenSequence(int speaker, int sequenceNum = 1);
+
+ /**
+ * Restore any saved NPC walk path data from any of the NPCs
+ */
+ void pullNPCPaths();
+
+ /**
+ * Finds the scene background object corresponding to a specified speaker
+ */
+ virtual int findSpeaker(int speaker);
+
+ /**
+ * Synchronize the data for a savegame
+ */
+ virtual void synchronize(Serializer &s);
+
+ /**
+ * Change the sequence of the scene background object associated with the specified speaker.
+ */
+ virtual void setTalkSequence(int speaker, int sequenceNum = 1);
+
+ /**
+ * Load the walking images for Sherlock
+ */
+ virtual bool loadWalk();
+
+ /**
+ * Restrict passed point to zone using Sherlock's positioning rules
+ */
+ virtual const Common::Point restrictToZone(int zoneId, const Common::Point &destPos);
+};
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
+
+
+#endif
diff --git a/engines/sherlock/tattoo/tattoo_resources.cpp b/engines/sherlock/tattoo/tattoo_resources.cpp
new file mode 100644
index 0000000000..3be41e2650
--- /dev/null
+++ b/engines/sherlock/tattoo/tattoo_resources.cpp
@@ -0,0 +1,329 @@
+/* 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 "sherlock/tattoo/tattoo_resources.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+const char PORTRAITS[TATTOO_MAX_PEOPLE][5] = {
+ { "HOLM" }, // Sherlock Holmes
+ { "WATS" }, // Dr. Watson
+ { "HUDS" }, // Mrs. Hudson
+ { "FORB" }, // Stanley Forbes
+ { "MYCR" }, // Mycroft Holmes
+ { "WIGG" }, // Wiggins
+ { "BURN" }, // Police Constable Burns
+ { "TRIM" }, // Augustus Trimble
+ { "DALE" }, // Police Constable Daley
+ { "MATR" }, // Matron
+ { "GRAC" }, // Sister Grace
+ { "MCCA" }, // Preston McCabe
+ { "COLL" }, // Bob Colleran
+ { "JONA" }, // Jonas Rigby
+ { "ROAC" }, // Police Constable Roach
+ { "DEWA" }, // James Dewar
+ { "JERE" }, // Sergeant Jeremy Duncan
+ { "GREG" }, // Inspector Gregson
+ { "LEST" }, // Inspector Lestrade
+ { "NEED" }, // Jesse Needhem
+ { "FLEM" }, // Arthur Fleming
+ { "PRAT" }, // Mr. Thomas Pratt
+ { "TILL" }, // Mathilda (Tillie) Mason
+ { "RUSS" }, // Adrian Russell
+ { "WHIT" }, // Eldridge Whitney
+ { "HEPP" }, // Hepplethwaite
+ { "HORA" }, // Horace Silverbridge
+ { "SHER" }, // Old Sherman
+ { "VERN" }, // Maxwell Verner
+ { "REDD" }, // Millicent Redding
+ { "VIRG" }, // Virgil Silverbridge
+ { "GEOR" }, // George O'Keeffe
+ { "LAWT" }, // Lord Denys Lawton
+ { "JENK" }, // Jenkins
+ { "JOCK" }, // Jock Mahoney
+ { "BART" }, // Bartender
+ { "LADY" }, // Lady Cordelia Lockridge
+ { "PETT" }, // Pettigrew
+ { "FANS" }, // Sir Avery Fanshawe
+ { "HODG" }, // Hodgkins
+ { "WILB" }, // Wilbur "Birdy" Heywood
+ { "JACO" }, // Jacob Farthington
+ { "BLED" }, // Philip Bledsoe
+ { "FOWL" }, // Sidney Fowler
+ { "PROF" }, // Professor Theodore Totman
+ { "ROSE" }, // Rose Hinchem
+ { "TALL" }, // Tallboy
+ { "STIT" }, // Ethlebert "Stitch" Rumsey
+ { "FREE" }, // Charles Freedman
+ { "HEMM" }, // Nigel Hemmings
+ { "CART" }, // Fairfax Carter
+ { "WILH" }, // Wilhelm II
+ { "WACH" }, // Wachthund
+ { "WILS" }, // Jonathan Wilson
+ { "DAVE" }, // David Lloyd-Jones
+ { "HARG" }, // Edward Hargrove
+ { "MORI" }, // Professor James Moriarty
+ { "LASC" }, // The Lascar
+ { "PARR" }, // Parrot
+ { "SCAR" }, // Vincent Scarrett
+ { "ALEX" }, // Alexandra
+ { "QUEE" }, // Queen Victoria
+ { "JOHN" }, // John Brown
+ { "PAT1" }, // Patient #1
+ { "PAT2" }, // Patient #2
+ { "PATR" }, // Patron
+ { "QUEN" }, // Queen Victoria
+ { "WITE" }, // Patient in White
+ { "LUSH" }, // Lush
+ { "DRNK" }, // Drunk
+ { "PROS" }, // Prostitute
+ { "MUDL" }, // Mudlark
+ { "GRIN" }, // Grinder
+ { "BOUN" }, // Bouncer
+ { "RATC" }, // Agnes Ratchet
+ { "ALOY" }, // Aloysius Ratchet
+ { "REAL" }, // Real Estate Agent
+ { "CAND" }, // Candy Clerk
+ { "BEAD" }, // Beadle
+ { "PRUS" }, // Prussian
+ { "ROWB" }, // Mrs. Rowbottom
+ { "MSLJ" }, // Miss Lloyd-Jones
+ { "TPAT" }, // Tavern patron
+ { "USER" }, // User
+ { "TOBY" }, // Toby
+ { "STAT" }, // Stationer
+ { "CLRK" }, // Law Clerk
+ { "CLER" }, // Ministry Clerk
+ { "BATH" }, // Bather
+ { "MAID" }, // Maid
+ { "LADF" }, // Lady Fanshawe
+ { "SIDN" }, // Sidney Ratchet
+ { "BOYO" }, // Boy
+ { "PTR2" }, // Second Patron
+ { "BRIT" }, // Constable Brit
+ { "DROV" } // Wagon Driver
+};
+
+const char *const FRENCH_NAMES[TATTOO_MAX_PEOPLE] = {
+ "Sherlock Holmes",
+ "Dr. Watson",
+ "Mme. Hudson",
+ "Stanley Forbes",
+ "Mycroft Holmes",
+ "Wiggins",
+ "Sergent Burns",
+ "Augustus Trimble",
+ "Sergent Daley",
+ "Infirmi?re chef",
+ "Mme. Grace",
+ "Preston McCabe",
+ "Bob Colleran",
+ "Jonas Rigby",
+ "Sergent Roach",
+ "James Dewar",
+ "Sergent Jeremy Duncan",
+ "Inspecteur Gregson",
+ "Inspecteur Lestrade",
+ "Jesse Needhem",
+ "Arthur Fleming",
+ "M. Thomas Pratt",
+ "Mathilda (Tillie) Mason",
+ "Adrian Russell",
+ "Eldridge Whitney",
+ "Hepplethwaite",
+ "Horace Silverbridge",
+ "Sherman",
+ "Maxwell Verner",
+ "Millicent Redding",
+ "Virgil Silverbridge",
+ "George O'Keeffe",
+ "Lord Denys Lawton",
+ "Jenkins",
+ "Jock Mahoney",
+ "Serveur",
+ "Lady Cordelia Lockridge",
+ "Pettigrew",
+ "Sir Avery Fanshawe",
+ "Hodgkins",
+ "Wilbur \"Birdy\" Heywood",
+ "Jacob Farthington",
+ "Philip Bledsoe",
+ "Sidney Fowler",
+ "Professeur Theodore Totman",
+ "Rose Hinchem",
+ "Tallboy",
+ "Ethlebert \"Stitch\" Rumsey",
+ "Charles Freedman",
+ "Nigel Hemmings",
+ "Fairfax Carter",
+ "Wilhelm II",
+ "Wachthund",
+ "Jonathan Wilson",
+ "David Lloyd-Jones",
+ "Edward Hargrove",
+ "Misteray",
+ "Le Lascar",
+ "Oiseau",
+ "Vincent Scarrett",
+ "Alexandra",
+ "Queen Victoria",
+ "John Brown",
+ "Patient",
+ "Patient",
+ "Client",
+ "Queen Victoria",
+ "Patient en blanc",
+ "Ivrogne",
+ "Ivrogne",
+ "Belle femme",
+ "Mudlark",
+ "Broyeur",
+ "Videur",
+ "Agnes Ratchet",
+ "Aloysius Ratchet",
+ "Immobilier",
+ "Gar?on",
+ "Beadle",
+ "Prussian",
+ "Mme. Rowbottom",
+ "Mme Lloyd-Jones",
+ "Tavern Client",
+ "User",
+ "Toby",
+ "Papeterie",
+ "Law Clerc",
+ "Ministry Employ?",
+ "Clint du thermes",
+ "Bonne",
+ "Lady Fanshawe",
+ "Sidney Ratchet",
+ "Gar?on",
+ "Client",
+ "Sergent Brit",
+ "Wagon Driver"
+};
+
+const char *const ENGLISH_NAMES[TATTOO_MAX_PEOPLE] = {
+ "Sherlock Holmes",
+ "Dr. Watson",
+ "Mrs. Hudson",
+ "Stanley Forbes",
+ "Mycroft Holmes",
+ "Wiggins",
+ "Police Constable Burns",
+ "Augustus Trimble",
+ "Police Constable Daley",
+ "Matron",
+ "Sister Grace",
+ "Preston McCabe",
+ "Bob Colleran",
+ "Jonas Rigby",
+ "Police Constable Roach",
+ "James Dewar",
+ "Sergeant Jeremy Duncan",
+ "Inspector Gregson",
+ "Inspector Lestrade",
+ "Jesse Needhem",
+ "Arthur Fleming",
+ "Mr. Thomas Pratt",
+ "Mathilda (Tillie) Mason",
+ "Adrian Russell",
+ "Eldridge Whitney",
+ "Hepplethwaite",
+ "Horace Silverbridge",
+ "Old Sherman",
+ "Maxwell Verner",
+ "Millicent Redding",
+ "Virgil Silverbridge",
+ "George O'Keeffe",
+ "Lord Denys Lawton",
+ "Jenkins",
+ "Jock Mahoney",
+ "Bartender",
+ "Lady Cordelia Lockridge",
+ "Pettigrew",
+ "Sir Avery Fanshawe",
+ "Hodgkins",
+ "Wilbur \"Birdy\" Heywood",
+ "Jacob Farthington",
+ "Philip Bledsoe",
+ "Sidney Fowler",
+ "Professor Theodore Totman",
+ "Rose Hinchem",
+ "Tallboy",
+ "Ethlebert \"Stitch\" Rumsey",
+ "Charles Freedman",
+ "Nigel Hemmings",
+ "Fairfax Carter",
+ "Wilhelm II",
+ "Wachthund",
+ "Jonathan Wilson",
+ "David Lloyd-Jones",
+ "Edward Hargrove",
+ "Misteray",
+ "The Lascar",
+ "Parrot",
+ "Vincent Scarrett",
+ "Alexandra",
+ "Queen Victoria",
+ "John Brown",
+ "A Patient",
+ "A Patient",
+ "Patron",
+ "Queen Victoria",
+ "Patient in white",
+ "Lush",
+ "Drunk",
+ "Prostitute",
+ "Mudlark",
+ "Grinder",
+ "Bouncer",
+ "Agnes Ratchet",
+ "Aloysius Ratchet",
+ "Real Estate Agent",
+ "Candy Clerk",
+ "Beadle",
+ "Prussian",
+ "Mrs. Rowbottom",
+ "Miss Lloyd-Jones",
+ "Tavern patron",
+ "User",
+ "Toby",
+ "Stationer",
+ "Law Clerk",
+ "Ministry Clerk",
+ "Bather",
+ "Maid",
+ "Lady Fanshawe",
+ "Sidney Ratchet",
+ "Boy",
+ "Patron",
+ "Constable Brit",
+ "Wagon Driver"
+};
+
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/tattoo/tattoo_resources.h b/engines/sherlock/tattoo/tattoo_resources.h
new file mode 100644
index 0000000000..b706d90f2d
--- /dev/null
+++ b/engines/sherlock/tattoo/tattoo_resources.h
@@ -0,0 +1,42 @@
+/* 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 SHERLOCK_TATTOO_RESOURCES_H
+#define SHERLOCK_TATTOO_RESOURCES_H
+
+#include "common/scummsys.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+#define TATTOO_MAX_PEOPLE 96
+
+extern const char PORTRAITS[TATTOO_MAX_PEOPLE][5];
+extern const char *const FRENCH_NAMES[TATTOO_MAX_PEOPLE];
+extern const char *const ENGLISH_NAMES[TATTOO_MAX_PEOPLE];
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/tattoo/tattoo_scene.cpp b/engines/sherlock/tattoo/tattoo_scene.cpp
new file mode 100644
index 0000000000..ba462ca255
--- /dev/null
+++ b/engines/sherlock/tattoo/tattoo_scene.cpp
@@ -0,0 +1,821 @@
+/* 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 "sherlock/tattoo/tattoo_scene.h"
+#include "sherlock/tattoo/tattoo_people.h"
+#include "sherlock/tattoo/tattoo_user_interface.h"
+#include "sherlock/tattoo/tattoo.h"
+#include "sherlock/events.h"
+#include "sherlock/people.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+struct ShapeEntry {
+ Object *_shape;
+ TattooPerson *_person;
+ bool _isAnimation;
+ int _yp;
+
+ ShapeEntry(TattooPerson *person, int yp) : _shape(nullptr), _person(person), _yp(yp), _isAnimation(false) {}
+ ShapeEntry(Object *shape, int yp) : _shape(shape), _person(nullptr), _yp(yp), _isAnimation(false) {}
+ ShapeEntry(int yp) : _shape(nullptr), _person(nullptr), _yp(yp), _isAnimation(true) {}
+};
+typedef Common::List<ShapeEntry> ShapeList;
+
+static bool sortImagesY(const ShapeEntry &s1, const ShapeEntry &s2) {
+ return s1._yp <= s2._yp;
+}
+
+/*----------------------------------------------------------------*/
+
+TattooScene::TattooScene(SherlockEngine *vm) : Scene(vm) {
+ _labTableScene = false;
+}
+
+bool TattooScene::loadScene(const Common::String &filename) {
+ TattooEngine &vm = *(TattooEngine *)_vm;
+ Events &events = *_vm->_events;
+ Music &music = *_vm->_music;
+ Talk &talk = *_vm->_talk;
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+
+ // If we're going to the first game scene after the intro sequence, flag it as finished
+ if (vm._runningProlog && _currentScene == STARTING_GAME_SCENE) {
+ vm._runningProlog = false;
+ events.showCursor();
+ talk._talkToAbort = false;
+ }
+
+ // Check if it's a scene we need to keep trakc track of how many times we've visited
+ for (int idx = (int)_sceneTripCounters.size() - 1; idx >= 0; --idx) {
+ if (_sceneTripCounters[idx]._sceneNumber == _currentScene) {
+ if (--_sceneTripCounters[idx]._numTimes == 0) {
+ _vm->setFlags(_sceneTripCounters[idx]._flag);
+ _sceneTripCounters.remove_at(idx);
+ }
+ }
+ }
+
+ // Set the NPC paths for the scene
+ setNPCPath(0);
+
+ // Handle loading music for the scene
+ if (music._musicOn) {
+ if (talk._scriptMoreFlag != 1 && talk._scriptMoreFlag != 3)
+ music._nextSongName = Common::String::format("res%02d", _currentScene);
+
+ // If it's a new song, then start it up
+ if (music._currentSongName.compareToIgnoreCase(music._nextSongName)) {
+ if (music.loadSong(music._nextSongName)) {
+ music.setMIDIVolume(music._musicVolume);
+ if (music._musicOn)
+ music.startSong();
+ }
+ }
+ }
+
+ bool result = Scene::loadScene(filename);
+
+ if (_currentScene != STARTING_INTRO_SCENE) {
+ // Set the menu/ui mode and whether we're in a lab table close-up scene
+ _labTableScene = _currentScene > 91 && _currentScene < 100;
+ ui._menuMode = _labTableScene ? LAB_MODE : STD_MODE;
+
+ if (_labTableScene)
+ ui._labWidget.summonWindow();
+ }
+
+ return result;
+}
+
+void TattooScene::drawAllShapes() {
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ Screen &screen = *_vm->_screen;
+ ShapeList shapeList;
+
+ // Draw all objects and animations that are set to behind
+ screen.setDisplayBounds(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
+
+ // Draw all active shapes which are behind the person
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ Object &obj = _bgShapes[idx];
+
+ if (obj._type == ACTIVE_BG_SHAPE && obj._misc == BEHIND) {
+ if (obj._quickDraw && obj._scaleVal == SCALE_THRESHOLD)
+ screen._backBuffer1.blitFrom(*obj._imageFrame, obj._position);
+ else
+ screen._backBuffer1.transBlitFrom(*obj._imageFrame, obj._position, obj._flags & OBJ_FLIPPED, 0, obj._scaleVal);
+ }
+ }
+
+ // Draw the animation if it is behind the person
+ if (_activeCAnim.active() && _activeCAnim._zPlacement == BEHIND)
+ screen._backBuffer1.transBlitFrom(_activeCAnim._imageFrame, _activeCAnim._position,
+ (_activeCAnim._flags & 4) >> 1, 0, _activeCAnim._scaleVal);
+
+ screen.resetDisplayBounds();
+
+ // Queue drawing of all objects that are set to NORMAL.
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ Object &obj = _bgShapes[idx];
+
+ if (obj._type == ACTIVE_BG_SHAPE && (obj._misc == NORMAL_BEHIND || obj._misc == NORMAL_FORWARD)) {
+ if (obj._scaleVal == SCALE_THRESHOLD)
+ shapeList.push_back(ShapeEntry(&obj, obj._position.y + obj._imageFrame->_offset.y +
+ obj._imageFrame->_height));
+ else
+ shapeList.push_back(ShapeEntry(&obj, obj._position.y + obj._imageFrame->sDrawYOffset(obj._scaleVal) +
+ obj._imageFrame->sDrawYSize(obj._scaleVal)));
+ }
+ }
+
+ // Queue drawing the animation if it is NORMAL and can fall in front of, or behind the people
+ if (_activeCAnim.active() && (_activeCAnim._zPlacement == NORMAL_BEHIND || _activeCAnim._zPlacement == NORMAL_FORWARD)) {
+ if (_activeCAnim._scaleVal == SCALE_THRESHOLD)
+ shapeList.push_back(ShapeEntry(_activeCAnim._position.y + _activeCAnim._imageFrame._offset.y +
+ _activeCAnim._imageFrame._height));
+ else
+ shapeList.push_back(ShapeEntry(_activeCAnim._position.y + _activeCAnim._imageFrame.sDrawYOffset(_activeCAnim._scaleVal) +
+ _activeCAnim._imageFrame.sDrawYSize(_activeCAnim._scaleVal)));
+ }
+
+ // Queue all active characters for drawing
+ for (int idx = 0; idx < MAX_CHARACTERS; ++idx) {
+ if (people[idx]._type == CHARACTER && people[idx]._walkLoaded)
+ shapeList.push_back(ShapeEntry(&people[idx], people[idx]._position.y / FIXED_INT_MULTIPLIER));
+ }
+
+ // Sort the list
+ Common::sort(shapeList.begin(), shapeList.end(), sortImagesY);
+
+ // Draw the list of shapes in order
+ for (ShapeList::iterator i = shapeList.begin(); i != shapeList.end(); ++i) {
+ ShapeEntry &se = *i;
+
+ if (se._shape) {
+ // it's a bg shape
+ if (se._shape->_quickDraw && se._shape->_scaleVal == SCALE_THRESHOLD)
+ screen._backBuffer1.blitFrom(*se._shape->_imageFrame, se._shape->_position);
+ else
+ screen._backBuffer1.transBlitFrom(*se._shape->_imageFrame, se._shape->_position,
+ se._shape->_flags & OBJ_FLIPPED, 0, se._shape->_scaleVal);
+ } else if (se._isAnimation) {
+ // It's an active animation
+ screen._backBuffer1.transBlitFrom(_activeCAnim._imageFrame, _activeCAnim._position,
+ (_activeCAnim._flags & 4) >> 1, 0, _activeCAnim._scaleVal);
+ } else {
+ // Drawing person
+ TattooPerson &p = *se._person;
+
+ p._tempX = p._position.x / FIXED_INT_MULTIPLIER;
+ p._tempScaleVal = getScaleVal(p._position);
+ Common::Point adjust = p._adjust;
+
+ if (p._tempScaleVal == SCALE_THRESHOLD) {
+ p._tempX += adjust.x;
+ screen._backBuffer1.transBlitFrom(*p._imageFrame, Common::Point(p._tempX, p._position.y / FIXED_INT_MULTIPLIER
+ - p.frameHeight() - adjust.y), p._walkSequences[p._sequenceNumber]._horizFlip, 0, p._tempScaleVal);
+ } else {
+ if (adjust.x) {
+ if (!p._tempScaleVal)
+ ++p._tempScaleVal;
+
+ if (p._tempScaleVal >= SCALE_THRESHOLD && adjust.x)
+ --adjust.x;
+
+ adjust.x = adjust.x * SCALE_THRESHOLD / p._tempScaleVal;
+
+ if (p._tempScaleVal >= SCALE_THRESHOLD)
+ ++adjust.x;
+ p._tempX += adjust.x;
+ }
+
+ if (adjust.y) {
+ if (!p._tempScaleVal)
+ p._tempScaleVal++;
+
+ if (p._tempScaleVal >= SCALE_THRESHOLD && adjust.y)
+ --adjust.y;
+
+ adjust.y = adjust.y * SCALE_THRESHOLD / p._tempScaleVal;
+
+ if (p._tempScaleVal >= SCALE_THRESHOLD)
+ ++adjust.y;
+ }
+
+ screen._backBuffer1.transBlitFrom(*p._imageFrame, Common::Point(p._tempX, p._position.y / FIXED_INT_MULTIPLIER
+ - p._imageFrame->sDrawYSize(p._tempScaleVal) - adjust.y), p._walkSequences[p._sequenceNumber]._horizFlip, 0, p._tempScaleVal);
+ }
+ }
+ }
+
+ // Draw all objects & canimations that are set to FORWARD.
+ // Draw all static and active shapes that are FORWARD
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ Object &obj = _bgShapes[idx];
+
+ if (obj._type == ACTIVE_BG_SHAPE && obj._misc == FORWARD) {
+ if (obj._quickDraw && obj._scaleVal == SCALE_THRESHOLD)
+ screen._backBuffer1.blitFrom(*obj._imageFrame, obj._position);
+ else
+ screen._backBuffer1.transBlitFrom(*obj._imageFrame, obj._position, obj._flags & OBJ_FLIPPED, 0, obj._scaleVal);
+ }
+ }
+
+ // Draw the canimation if it is set as FORWARD
+ if (_activeCAnim.active() && _activeCAnim._zPlacement == FORWARD)
+ screen._backBuffer1.transBlitFrom(_activeCAnim._imageFrame, _activeCAnim._position, (_activeCAnim._flags & 4) >> 1, 0, _activeCAnim._scaleVal);
+
+ // Draw all NO_SHAPE shapes which have their flag bits clear
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ Object &obj = _bgShapes[idx];
+ if (obj._type == NO_SHAPE && (obj._flags & 1) == 0)
+ screen._backBuffer1.fillRect(obj.getNoShapeBounds(), 15);
+ }
+}
+
+void TattooScene::paletteLoaded() {
+ Screen &screen = *_vm->_screen;
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+
+ ui.setupBGArea(screen._cMap);
+ ui.initScrollVars();
+}
+
+void TattooScene::checkBgShapes() {
+ // Call the base scene method to handle bg shapes
+ Scene::checkBgShapes();
+
+ // Check for any active playing animation
+ if (_activeCAnim.active() && _activeCAnim._zPlacement != REMOVE) {
+ switch (_activeCAnim._flags & 3) {
+ case 0:
+ _activeCAnim._zPlacement = BEHIND;
+ break;
+ case 1:
+ _activeCAnim._zPlacement = ((_activeCAnim._position.y + _activeCAnim._imageFrame._frame.h - 1)) ?
+ NORMAL_FORWARD : NORMAL_BEHIND;
+ break;
+ case 2:
+ _activeCAnim._zPlacement = FORWARD;
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void TattooScene::doBgAnimCheckCursor() {
+ Events &events = *_vm->_events;
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+ Common::Point mousePos = events.mousePos();
+
+ // If we're in Look Mode, make sure the cursor is the magnifying glass
+ if (ui._menuMode == LOOK_MODE && events.getCursor() != MAGNIFY)
+ events.setCursor(MAGNIFY);
+
+ // See if the mouse is over any of the arrow zones, and if so, change the cursor to the correct
+ // arrow cursor indicating the direcetion of the exit
+ if (events.getCursor() == ARROW || events.getCursor() >= EXIT_ZONES_START) {
+ CursorId cursorId = ARROW;
+
+ if (ui._menuMode == STD_MODE && ui._arrowZone != -1 && _currentScene != 90) {
+ for (uint idx = 0; idx < _exits.size(); ++idx) {
+ Exit &exit = _exits[idx];
+ if (exit.contains(mousePos))
+ cursorId = (CursorId)(exit._image + EXIT_ZONES_START);
+ }
+ }
+
+ events.setCursor(cursorId);
+ } else {
+ events.animateCursorIfNeeded();
+ }
+}
+
+void TattooScene::doBgAnim() {
+ TattooEngine &vm = *(TattooEngine *)_vm;
+ Events &events = *_vm->_events;
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ Screen &screen = *_vm->_screen;
+ Talk &talk = *_vm->_talk;
+ TattooUserInterface &ui = *((TattooUserInterface *)_vm->_ui);
+
+ doBgAnimCheckCursor();
+
+ talk._talkToAbort = false;
+
+ // Check the characters and sprites for updates
+ for (int idx = 0; idx < MAX_CHARACTERS; ++idx) {
+ if (people[idx]._type == CHARACTER)
+ people[idx].checkSprite();
+ }
+
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ if (_bgShapes[idx]._type == ACTIVE_BG_SHAPE)
+ _bgShapes[idx].checkObject();
+ }
+
+ // If one of the objects has signalled a call to a talk file, to go to another scene, exit immediately
+ if (_goToScene != -1)
+ return;
+
+ // Erase any affected background areas
+ ui.doBgAnimEraseBackground();
+
+ doBgAnimUpdateBgObjectsAndAnim();
+
+ doBgAnimDrawSprites();
+
+ ui.drawInterface();
+
+ if (vm._creditsActive)
+ vm.blitCredits();
+
+ if (!vm._fastMode)
+ events.wait(3);
+
+ if (screen._flushScreen) {
+ screen.slamArea(screen._currentScroll.x, screen._currentScroll.y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+ screen._flushScreen = false;
+ }
+
+ screen._flushScreen = false;
+ _doBgAnimDone = true;
+ ui._drawMenu = false;
+
+ for (int idx = 1; idx < MAX_CHARACTERS; ++idx) {
+ if (people[idx]._updateNPCPath)
+ people[idx].updateNPC();
+ }
+}
+
+void TattooScene::doBgAnimUpdateBgObjectsAndAnim() {
+ People &people = *_vm->_people;
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ Object &obj = _bgShapes[idx];
+ if (obj._type == ACTIVE_BG_SHAPE || obj._type == NO_SHAPE)
+ obj.adjustObject();
+ }
+
+ for (int idx = 0; idx < MAX_CHARACTERS; ++idx) {
+ if (people[idx]._type == CHARACTER)
+ people[idx].adjustSprite();
+ }
+
+ // Flag the bg shapes which need to be redrawn
+ checkBgShapes();
+ drawAllShapes();
+
+ ui.drawMaskArea(true);
+}
+
+void TattooScene::updateBackground() {
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ Screen &screen = *_vm->_screen;
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+
+ Scene::updateBackground();
+
+ ui.drawMaskArea(false);
+
+ screen._flushScreen = true;
+
+ for (int idx = 0; idx < MAX_CHARACTERS; ++idx) {
+ TattooPerson &p = people[idx];
+
+ if (p._type != INVALID) {
+ if (_goToScene == -1 || _cAnim.size() == 0) {
+ if (p._type == REMOVE) {
+ screen.slamArea(p._oldPosition.x, p._oldPosition.y, p._oldSize.x, p._oldSize.y);
+ p._type = INVALID;
+ } else {
+ if (p._tempScaleVal == SCALE_THRESHOLD) {
+ screen.flushImage(p._imageFrame, Common::Point(p._tempX, p._position.y / FIXED_INT_MULTIPLIER
+ - p._imageFrame->_width), &p._oldPosition.x, &p._oldPosition.y, &p._oldSize.x, &p._oldSize.y);
+ } else {
+ int ts = p._imageFrame->sDrawYSize(p._tempScaleVal);
+ int ty = p._position.y / FIXED_INT_MULTIPLIER - ts;
+ screen.flushScaleImage(p._imageFrame, Common::Point(p._tempX, ty),
+ &p._oldPosition.x, &p._oldPosition.y, &p._oldSize.x, &p._oldSize.y, p._tempScaleVal);
+ }
+ }
+ }
+ }
+ }
+
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ Object &obj = _bgShapes[idx];
+
+ if (obj._type == ACTIVE_BG_SHAPE || obj._type == REMOVE) {
+ if (_goToScene == -1) {
+ if (obj._scaleVal == SCALE_THRESHOLD)
+ screen.flushImage(obj._imageFrame, obj._position, &obj._oldPosition.x, &obj._oldPosition.y,
+ &obj._oldSize.x, &obj._oldSize.y);
+ else
+ screen.flushScaleImage(obj._imageFrame, obj._position, &obj._oldPosition.x, &obj._oldPosition.y,
+ &obj._oldSize.x, &obj._oldSize.y, obj._scaleVal);
+
+ if (obj._type == REMOVE)
+ obj._type = INVALID;
+ }
+ }
+ }
+
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ Object &obj = _bgShapes[idx];
+
+ if (_goToScene == -1) {
+ if (obj._type == NO_SHAPE && (obj._flags & 1) == 0) {
+ screen.slamRect(obj.getNoShapeBounds());
+ screen.slamRect(obj.getOldBounds());
+ } else if (obj._type == HIDE_SHAPE) {
+ if (obj._scaleVal == SCALE_THRESHOLD)
+ screen.flushImage(obj._imageFrame, obj._position, &obj._oldPosition.x, &obj._oldPosition.y,
+ &obj._oldSize.x, &obj._oldSize.y);
+ else
+ screen.flushScaleImage(obj._imageFrame, obj._position, &obj._oldPosition.x, &obj._oldPosition.y,
+ &obj._oldSize.x, &obj._oldSize.y, obj._scaleVal);
+ obj._type = HIDDEN;
+ }
+ }
+ }
+
+ screen._flushScreen = false;
+}
+
+void TattooScene::doBgAnimDrawSprites() {
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ Screen &screen = *_vm->_screen;
+
+ for (int idx = 0; idx < MAX_CHARACTERS; ++idx) {
+ TattooPerson &person = people[idx];
+
+ if (person._type != INVALID) {
+ if (_goToScene == -1 || _cAnim.size() == 0) {
+ if (person._type == REMOVE) {
+ screen.slamRect(person.getOldBounds());
+ person._type = INVALID;
+ } else {
+ if (person._tempScaleVal == SCALE_THRESHOLD) {
+ screen.flushImage(person._imageFrame, Common::Point(person._tempX, person._position.y / FIXED_INT_MULTIPLIER
+ - person.frameHeight()), &person._oldPosition.x, &person._oldPosition.y, &person._oldSize.x, &person._oldSize.y);
+ } else {
+ int ts = person._imageFrame->sDrawYSize(person._tempScaleVal);
+ int ty = person._position.y / FIXED_INT_MULTIPLIER - ts;
+ screen.flushScaleImage(person._imageFrame, Common::Point(person._tempX, ty),
+ &person._oldPosition.x, &person._oldPosition.y, &person._oldSize.x, &person._oldSize.y, person._tempScaleVal);
+ }
+ }
+ }
+ }
+ }
+
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ Object &obj = _bgShapes[idx];
+
+ if (obj._type == ACTIVE_BG_SHAPE || obj._type == REMOVE) {
+ if (_goToScene == -1) {
+ if (obj._scaleVal == SCALE_THRESHOLD)
+ screen.flushImage(obj._imageFrame, obj._position, &obj._oldPosition.x, &obj._oldPosition.y,
+ &obj._oldSize.x, &obj._oldSize.y);
+ else
+ screen.flushScaleImage(obj._imageFrame, obj._position, &obj._oldPosition.x, &obj._oldPosition.y,
+ &obj._oldSize.x, &obj._oldSize.y, obj._scaleVal);
+
+ if (obj._type == REMOVE)
+ obj._type = INVALID;
+ }
+ }
+ }
+
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ Object &obj = _bgShapes[idx];
+
+ if (_goToScene == -1) {
+ if (obj._type == NO_SHAPE && (obj._flags & 1) == 0) {
+ screen.slamRect(obj.getNoShapeBounds());
+ screen.slamRect(obj.getOldBounds());
+ } else if (obj._type == HIDE_SHAPE) {
+ if (obj._scaleVal == SCALE_THRESHOLD)
+ screen.flushImage(obj._imageFrame, obj._position, &obj._oldPosition.x, &obj._oldPosition.y,
+ &obj._oldSize.x, &obj._oldSize.y);
+ else
+ screen.flushScaleImage(obj._imageFrame, obj._position, &obj._oldPosition.x, &obj._oldPosition.y,
+ &obj._oldSize.x, &obj._oldSize.y, obj._scaleVal);
+ obj._type = HIDDEN;
+ }
+ }
+ }
+
+ if (_activeCAnim.active() || _activeCAnim._zPlacement == REMOVE) {
+ if (_activeCAnim._zPlacement != REMOVE) {
+ screen.flushImage(&_activeCAnim._imageFrame, _activeCAnim._position, _activeCAnim._oldBounds, _activeCAnim._scaleVal);
+ } else {
+ screen.slamRect(_activeCAnim._removeBounds);
+ _activeCAnim._removeBounds = Common::Rect(0, 0, 0, 0);
+ _activeCAnim._zPlacement = -1; // Reset _zPlacement so we don't REMOVE again
+ }
+ }
+}
+
+int TattooScene::getScaleVal(const Point32 &pt) {
+ bool found = false;
+ int result = SCALE_THRESHOLD;
+ Common::Point pos(pt.x / FIXED_INT_MULTIPLIER, pt.y / FIXED_INT_MULTIPLIER);
+
+ for (uint idx = 0; idx < _scaleZones.size() && !found; ++idx) {
+ ScaleZone &sz = _scaleZones[idx];
+ if (sz.contains(pos)) {
+ int n = (sz._bottomNumber - sz._topNumber) * 100 / sz.height() * (pos.y - sz.top) / 100 + sz._topNumber;
+ result = 25600L / n;
+ // CHECKME: Shouldn't we set 'found' at this place?
+ }
+ }
+
+ // If it wasn't found, we may be off screen to the left or right, so find the scale zone
+ // that would apply to the y val passed in disregarding the x
+ if (!found) {
+ for (uint idx = 0; idx < _scaleZones.size() && !found; ++idx) {
+ ScaleZone &sz = _scaleZones[idx];
+ if (pos.y >= sz.top && pos.y < sz.bottom) {
+ int n = (sz._bottomNumber - sz._topNumber) * 100 / sz.height() * (pos.y - sz.top) / 100 + sz._topNumber;
+ result = 25600L / n;
+ }
+ }
+ }
+
+ return result;
+}
+
+int TattooScene::startCAnim(int cAnimNum, int playRate) {
+ TattooEngine &vm = *(TattooEngine *)_vm;
+ Events &events = *_vm->_events;
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ Resources &res = *_vm->_res;
+ Talk &talk = *_vm->_talk;
+ UserInterface &ui = *_vm->_ui;
+
+ // Exit immediately if the anim number is out of range, or the anim doesn't have a position specified
+ if (cAnimNum < 0 || cAnimNum >= (int)_cAnim.size() || _cAnim[cAnimNum]._position.x == -1)
+ // Return out of range error
+ return -1;
+
+ // Get the co-ordinates that the Player & NPC #1 must walk to and end on
+ CAnim &cAnim = _cAnim[cAnimNum];
+ PositionFacing goto1 = cAnim._goto[0];
+ PositionFacing goto2 = cAnim._goto[1];
+ PositionFacing teleport1 = cAnim._teleport[0];
+ PositionFacing teleport2 = cAnim._teleport[1];
+
+ // See if the Player must walk to a position before the animation starts
+ SpriteType savedPlayerType = people[HOLMES]._type;
+ if (goto1.x != -1 && people[HOLMES]._type == CHARACTER) {
+ if (people[HOLMES]._position != goto1)
+ people[HOLMES].walkToCoords(goto1, goto1._facing);
+ }
+
+ if (talk._talkToAbort)
+ return 1;
+
+ // See if NPC #1 must walk to a position before the animation starts
+ SpriteType savedNPCType = people[WATSON]._type;
+ if (goto2.x != -1 && people[WATSON]._type == CHARACTER) {
+ if (people[WATSON]._position != goto2)
+ people[WATSON].walkToCoords(goto2, goto2._facing);
+ }
+
+ if (talk._talkToAbort)
+ return 1;
+
+ // Turn the player (and NPC #1 if neccessary) off before running the canimation
+ if (teleport1.x != -1 && savedPlayerType == CHARACTER)
+ people[HOLMES]._type = REMOVE;
+
+ if (teleport2.x != -1 && savedNPCType == CHARACTER)
+ people[WATSON]._type = REMOVE;
+
+ if (ui._windowOpen)
+ ui.banishWindow();
+
+ //_activeCAnim._filesize = cAnim._size;
+
+ // Open up the room resource file and get the data for the animation
+ Common::SeekableReadStream *stream = res.load(_roomFilename);
+ stream->seek(44 + cAnimNum * 4);
+ stream->seek(stream->readUint32LE());
+ Common::SeekableReadStream *animStream = stream->readStream(cAnim._dataSize);
+ delete stream;
+
+ // Set up the active animation
+ _activeCAnim._position = cAnim._position;
+ _activeCAnim._oldBounds = Common::Rect(0, 0, 0, 0);
+ _activeCAnim._flags = cAnim._flags;
+ _activeCAnim._scaleVal = cAnim._scaleVal;
+ _activeCAnim._zPlacement = 0;
+
+ _activeCAnim.load(animStream, _compressed);
+
+ while (_activeCAnim.active() && !_vm->shouldQuit()) {
+ // Get the next frame
+ _activeCAnim.getNextFrame();
+
+ // Draw the frame
+ doBgAnim();
+
+ // Check for Escape key being pressed to abort animation
+ events.pollEvents();
+ if (events.kbHit()) {
+ Common::KeyState keyState = events.getKey();
+
+ if (keyState.keycode == Common::KEYCODE_ESCAPE && vm._runningProlog) {
+ _vm->setFlags(-76);
+ _vm->setFlags(396);
+ _goToScene = STARTING_GAME_SCENE;
+ talk._talkToAbort = true;
+ _activeCAnim.close();
+ }
+ }
+ }
+
+ // Turn the people back on
+ people[HOLMES]._type = savedPlayerType;
+ if (teleport2.x != -1)
+ people[WATSON]._type = savedNPCType;
+
+ // Teleport the Player to the ending coordinates if necessary
+ if (teleport1.x != -1 && savedPlayerType == CHARACTER) {
+ people[HOLMES]._position = teleport1;
+ people[HOLMES]._sequenceNumber = teleport1._facing;
+ people[HOLMES].gotoStand();
+ }
+
+ // Teleport Watson to the ending coordinates if necessary
+ if (teleport2.x != -1 && savedNPCType == CHARACTER) {
+ people[WATSON]._position = teleport2;
+ people[WATSON]._sequenceNumber = teleport2._facing;
+ people[WATSON].gotoStand();
+ }
+
+ // Flag the Canimation to be cleared
+ _activeCAnim._zPlacement = REMOVE;
+ _activeCAnim._removeBounds = _activeCAnim._oldBounds;
+
+ // Free up the animation
+ _activeCAnim.close();
+
+ return 1;
+}
+
+void TattooScene::setNPCPath(int npc) {
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ SaveManager &saves = *_vm->_saves;
+ Talk &talk = *_vm->_talk;
+
+ // Don't do initial scene setup if a savegame has just been loaded
+ if (saves._justLoaded)
+ return;
+
+ people[npc].clearNPC();
+ people[npc]._name = Common::String::format("WATS%.2dA", _currentScene);
+
+ // If we're in the middle of a script that will continue once the scene is loaded,
+ // return without calling the path script
+ if (talk._scriptMoreFlag == 1 || talk._scriptMoreFlag == 3)
+ return;
+
+ // Turn off all the NPCs, since the talk script will turn them back on as needed
+ for (int idx = 1; idx < MAX_CHARACTERS; ++idx)
+ people[idx]._type = INVALID;
+
+ // Call the path script for the scene
+ Common::String pathFile = Common::String::format("PATH%.2dA", _currentScene);
+ talk.talkTo(pathFile);
+}
+
+int TattooScene::findBgShape(const Common::Point &pt) {
+ People &people = *_vm->_people;
+
+ if (!_doBgAnimDone)
+ // New frame hasn't been drawn yet
+ return -1;
+
+ int result = Scene::findBgShape(pt);
+ if (result == -1) {
+ if (_labTableScene) {
+ // Check for SOLID objects in the lab scene
+ for (int idx = (int)_bgShapes.size() - 1; idx >= 0; --idx) {
+ Object &o = _bgShapes[idx];
+ if (o._type != INVALID && o._type != NO_SHAPE && o._type != HIDDEN && o._aType == SOLID) {
+ if (o.getNewBounds().contains(pt))
+ return idx;
+ }
+ }
+ }
+
+ // No shape found, so check whether a character is highlighted
+ for (int idx = 1; idx < MAX_CHARACTERS && result == -1; ++idx) {
+ Person &person = people[idx];
+
+ if (person._type == CHARACTER) {
+ int scaleVal = getScaleVal(person._position);
+ Common::Rect charRect;
+
+ if (scaleVal == SCALE_THRESHOLD)
+ charRect = Common::Rect(person.frameWidth(), person.frameHeight());
+ else
+ charRect = Common::Rect(person._imageFrame->sDrawXSize(scaleVal), person._imageFrame->sDrawYSize(scaleVal));
+ charRect.moveTo(person._position.x / FIXED_INT_MULTIPLIER, person._position.y / FIXED_INT_MULTIPLIER
+ - charRect.height());
+
+ if (charRect.contains(pt))
+ result = 1000 + idx;
+ }
+ }
+ }
+
+ return result;
+}
+
+void TattooScene::synchronize(Serializer &s) {
+ TattooEngine &vm = *(TattooEngine *)_vm;
+ Scene::synchronize(s);
+
+ if (s.isLoading())
+ vm._runningProlog = false;
+}
+
+int TattooScene::closestZone(const Common::Point &pt) {
+ int zone = -1;
+ int dist = 9999;
+ int d;
+
+ for (uint idx = 0; idx < _zones.size(); ++idx) {
+ Common::Rect &r = _zones[idx];
+
+ // Check the distance from the point to the center of the zone
+ d = ABS(r.left + (r.width() / 2) - pt.x) + ABS(r.top + (r.height() / 2) - pt.y);
+ if (d < dist) {
+ dist = d;
+ zone = idx;
+ }
+
+ // Check the distance from the point to the upper left of the zone
+ d = ABS((int)(r.left - pt.x)) + ABS((int)(r.top - pt.y));
+ if (d < dist)
+ {
+ dist = d;
+ zone = idx;
+ }
+
+ // Check the distance from the point to the upper right of the zone
+ d = ABS(r.left + r.width() - pt.x) + ABS(r.top - pt.y);
+ if (d < dist) {
+ dist = d;
+ zone = idx;
+ }
+
+ // Check the distance from the point to the lower left of the zone
+ d = ABS(r.left - pt.x) + ABS(r.top + r.height() - pt.y);
+ if (d < dist) {
+ dist = d;
+ zone = idx;
+ }
+
+ // Check the distance from the point to the lower right of the zone
+ d = ABS(r.left + r.width() - pt.x) + ABS(r.top + r.height() - pt.y);
+ if (d < dist) {
+ dist = d;
+ zone = idx;
+ }
+ }
+
+ return zone;
+}
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/tattoo/tattoo_scene.h b/engines/sherlock/tattoo/tattoo_scene.h
new file mode 100644
index 0000000000..c432849bed
--- /dev/null
+++ b/engines/sherlock/tattoo/tattoo_scene.h
@@ -0,0 +1,147 @@
+/* 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 SHERLOCK_TATTOO_SCENE_H
+#define SHERLOCK_TATTOO_SCENE_H
+
+#include "common/scummsys.h"
+#include "sherlock/scene.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+enum {
+ STARTING_GAME_SCENE = 1, STARTING_INTRO_SCENE = 91, OVERHEAD_MAP2 = 90, OVERHEAD_MAP = 100
+};
+
+struct SceneTripEntry {
+ int _flag;
+ int _sceneNumber;
+ int _numTimes;
+
+ SceneTripEntry() : _flag(0), _sceneNumber(0), _numTimes(0) {}
+ SceneTripEntry(int flag, int sceneNumber, int numTimes) : _flag(flag),
+ _sceneNumber(sceneNumber), _numTimes(numTimes) {}
+};
+
+class TattooScene : public Scene {
+private:
+ void doBgAnimCheckCursor();
+
+ /**
+ * Update the background objects and canimations as part of doBgAnim
+ */
+ void doBgAnimUpdateBgObjectsAndAnim();
+
+ void doBgAnimDrawSprites();
+
+ /**
+ * Resets the NPC path information when entering a new scene.
+ * @remarks The default talk file for the given NPC is set to WATS##A, where ## is
+ * the scene number being entered
+ */
+ void setNPCPath(int npc);
+protected:
+ /**
+ * Loads the data associated for a given scene. The room resource file's format is:
+ * BGHEADER: Holds an index for the rest of the file
+ * STRUCTS: The objects for the scene
+ * IMAGES: The graphic information for the structures
+ *
+ * The _misc field of the structures contains the number of the graphic image
+ * that it should point to after loading; _misc is then set to 0.
+ */
+ virtual bool loadScene(const Common::String &filename);
+
+ /**
+ * Checks all the background shapes. If a background shape is animating,
+ * it will flag it as needing to be drawn. If a non-animating shape is
+ * colliding with another shape, it will also flag it as needing drawing
+ */
+ virtual void checkBgShapes();
+
+ /**
+ * Draw all the shapes, people and NPCs in the correct order
+ */
+ virtual void drawAllShapes();
+
+ /**
+ * Called by loadScene when the palette is loaded for Rose Tattoo
+ */
+ virtual void paletteLoaded();
+
+ /**
+ * Synchronize the data for a savegame
+ */
+ virtual void synchronize(Serializer &s);
+
+ /**
+ * Returns the index of the closest zone to a given point.
+ */
+ virtual int closestZone(const Common::Point &pt);
+public:
+ StreamingImageFile _activeCAnim;
+ Common::Array<SceneTripEntry> _sceneTripCounters;
+ bool _labTableScene;
+public:
+ TattooScene(SherlockEngine *vm);
+
+ /**
+ * Returns the scale value for the passed co-ordinates. This is taken from the scene's
+ * scale zones, interpolating inbetween the top and bottom values of the zones as needed
+ */
+ int getScaleVal(const Point32 &pt);
+
+ /**
+ * Draw all objects and characters.
+ */
+ virtual void doBgAnim();
+
+ /**
+ * Update the screen back buffer with all of the scene objects which need
+ * to be drawn
+ */
+ virtual void updateBackground();
+
+ /**
+ * Attempt to start a canimation sequence. It will load the requisite graphics, and
+ * then copy the canim object into the _canimShapes array to start the animation.
+ *
+ * @param cAnimNum The canim object within the current scene
+ * @param playRate Play rate. 0 is invalid; 1=normal speed, 2=1/2 speed, etc.
+ * A negative playRate can also be specified to play the animation in reverse
+ */
+ virtual int startCAnim(int cAnimNum, int playRate = 1);
+
+ /**
+ * Attempts to find a background shape within the passed bounds. If found,
+ * it will return the shape number, or -1 on failure.
+ */
+ virtual int findBgShape(const Common::Point &pt);
+};
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/tattoo/tattoo_talk.cpp b/engines/sherlock/tattoo/tattoo_talk.cpp
new file mode 100644
index 0000000000..dbeeaf8918
--- /dev/null
+++ b/engines/sherlock/tattoo/tattoo_talk.cpp
@@ -0,0 +1,882 @@
+/* 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 "sherlock/tattoo/tattoo_talk.h"
+#include "sherlock/tattoo/tattoo_people.h"
+#include "sherlock/tattoo/tattoo_scene.h"
+#include "sherlock/tattoo/tattoo_user_interface.h"
+#include "sherlock/sherlock.h"
+#include "sherlock/screen.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+static const uint8 DIRECTION_CONVERSION[] = {
+ WALK_RIGHT, WALK_DOWN, WALK_LEFT, WALK_UP, STOP_RIGHT, STOP_DOWN, STOP_LEFT, STOP_UP,
+ WALK_UPRIGHT, WALK_DOWNRIGHT, WALK_UPLEFT, WALK_DOWNLEFT, STOP_UPRIGHT, STOP_UPLEFT,
+ STOP_DOWNRIGHT, STOP_DOWNLEFT
+};
+
+const byte TATTOO_OPCODES[] = {
+ 170, // OP_SWITCH_SPEAKER
+ 171, // OP_RUN_CANIMATION
+ 0, // OP_ASSIGN_PORTRAIT_LOCATION
+ 173, // OP_PAUSE
+ 0, // OP_REMOVE_PORTRAIT
+ 0, // OP_CLEAR_WINDOW
+ 176, // OP_ADJUST_OBJ_SEQUENCE
+ 177, // OP_WALK_HOlMES_TO_COORDS
+ 178, // OP_PAUSE_WITHOUT_CONTROL
+ 179, // OP_BANISH_WINDOW
+ 0, // OP_SUMMON_WINDOW
+ 181, // OP_SET_FLAG
+ 0, // OP_SFX_COMMAND
+ 183, // OP_TOGGLE_OBJECT
+ 184, // OP_STEALTH_MODE_ACTIVE
+ 0, // OP_IF_STATEMENT
+ 0, // OP_ELSE_STATEMENT
+ 0, // OP_END_IF_STATEMENT
+ 188, // OP_STEALTH_MODE_DEACTIVATE
+ 189, // OP_TURN_HOLMES_OFF
+ 190, // OP_TURN_HOLMES_ON
+ 191, // OP_GOTO_SCENE
+ 0, // OP_PLAY_PROLOGUE
+ 193, // OP_ADD_ITEM_TO_INVENTORY
+ 194, // OP_SET_OBJECT
+ 172, // OP_CALL_TALK_FILE
+ 0, // OP_MOVE_MOUSE
+ 0, // OP_DISPLAY_INFO_LINE
+ 0, // OP_CLEAR_INFO_LINE
+ 199, // OP_WALK_TO_CANIMATION
+ 200, // OP_REMOVE_ITEM_FROM_INVENTORY
+ 201, // OP_ENABLE_END_KEY
+ 202, // OP_DISABLE_END_KEY
+ 203, // OP_END_TEXT_WINDOW
+ 174, // OP_MOUSE_ON_OFF
+ 175, // OP_SET_WALK_CONTROL
+ 180, // OP_SET_TALK_SEQUENCE
+ 182, // OP_PLAY_SONG
+ 187, // OP_WALK_HOLMES_AND_NPC_TO_CANIM
+ 192, // OP_SET_NPC_PATH_DEST
+ 195, // OP_NEXT_SONG
+ 196, // OP_SET_NPC_PATH_PAUSE
+ 197, // OP_PASSWORD
+ 198, // OP_SET_SCENE_ENTRY_FLAG
+ 185, // OP_WALK_NPC_TO_CANIM
+ 186, // OP_WALK_NPC_TO_COORDS
+ 204, // OP_WALK_HOLMES_AND_NPC_TO_COORDS
+ 205, // OP_SET_NPC_TALK_FILE
+ 206, // OP_TURN_NPC_OFF
+ 207, // OP_TURN_NPC_ON
+ 208, // OP_NPC_DESC_ON_OFF
+ 209, // OP_NPC_PATH_PAUSE_TAKING_NOTES
+ 210, // OP_NPC_PATH_PAUSE_LOOKING_HOLMES
+ 211, // OP_ENABLE_TALK_INTERRUPTS
+ 212, // OP_DISABLE_TALK_INTERRUPTS
+ 213, // OP_SET_NPC_INFO_LINE
+ 214, // OP_SET_NPC_POSITION
+ 215, // OP_NPC_PATH_LABEL
+ 216, // OP_PATH_GOTO_LABEL
+ 217, // OP_PATH_IF_FLAG_GOTO_LABEL
+ 218, // OP_NPC_WALK_GRAPHICS
+ 220, // OP_NPC_VERB
+ 221, // OP_NPC_VERB_CANIM
+ 222, // OP_NPC_VERB_SCRIPT
+ 224, // OP_RESTORE_PEOPLE_SEQUENCE
+ 226, // OP_NPC_VERB_TARGET
+ 227, // OP_TURN_SOUNDS_OFF
+ 225 // OP_NULL
+};
+
+/*----------------------------------------------------------------*/
+
+TattooTalk::TattooTalk(SherlockEngine *vm) : Talk(vm), _talkWidget(vm) {
+ static OpcodeMethod OPCODE_METHODS[] = {
+ (OpcodeMethod)&TattooTalk::cmdSwitchSpeaker,
+
+ (OpcodeMethod)&TattooTalk::cmdRunCAnimation,
+ (OpcodeMethod)&TattooTalk::cmdCallTalkFile,
+ (OpcodeMethod)&TattooTalk::cmdPause,
+ (OpcodeMethod)&TattooTalk::cmdMouseOnOff,
+ (OpcodeMethod)&TattooTalk::cmdSetWalkControl,
+ (OpcodeMethod)&TattooTalk::cmdAdjustObjectSequence,
+ (OpcodeMethod)&TattooTalk::cmdWalkHolmesToCoords,
+ (OpcodeMethod)&TattooTalk::cmdPauseWithoutControl,
+ (OpcodeMethod)&TattooTalk::cmdBanishWindow,
+ (OpcodeMethod)&TattooTalk::cmdSetTalkSequence,
+
+ (OpcodeMethod)&TattooTalk::cmdSetFlag,
+ (OpcodeMethod)&TattooTalk::cmdPlaySong,
+ (OpcodeMethod)&TattooTalk::cmdToggleObject,
+ (OpcodeMethod)&TattooTalk::cmdStealthModeActivate,
+ (OpcodeMethod)&TattooTalk::cmdWalkNPCToCAnimation,
+ (OpcodeMethod)&TattooTalk::cmdWalkNPCToCoords,
+ (OpcodeMethod)&TattooTalk::cmdWalkHomesAndNPCToCoords,
+ (OpcodeMethod)&TattooTalk::cmdStealthModeDeactivate,
+ (OpcodeMethod)&TattooTalk::cmdHolmesOff,
+ (OpcodeMethod)&TattooTalk::cmdHolmesOn,
+
+ (OpcodeMethod)&TattooTalk::cmdGotoScene,
+ (OpcodeMethod)&TattooTalk::cmdSetNPCPathDest,
+ (OpcodeMethod)&TattooTalk::cmdAddItemToInventory,
+ (OpcodeMethod)&TattooTalk::cmdSetObject,
+ (OpcodeMethod)&TattooTalk::cmdNextSong,
+ (OpcodeMethod)&TattooTalk::cmdSetNPCPathPause,
+ (OpcodeMethod)&TattooTalk::cmdPassword,
+ (OpcodeMethod)&TattooTalk::cmdSetSceneEntryFlag,
+ (OpcodeMethod)&TattooTalk::cmdWalkToCAnimation,
+ (OpcodeMethod)&TattooTalk::cmdRemoveItemFromInventory,
+
+ (OpcodeMethod)&TattooTalk::cmdEnableEndKey,
+ (OpcodeMethod)&TattooTalk::cmdDisableEndKey,
+ (OpcodeMethod)&TattooTalk::cmdEndTextWindow,
+ (OpcodeMethod)&TattooTalk::cmdWalkHomesAndNPCToCoords,
+ (OpcodeMethod)&TattooTalk::cmdSetNPCTalkFile,
+ (OpcodeMethod)&TattooTalk::cmdSetNPCOff,
+ (OpcodeMethod)&TattooTalk::cmdSetNPCOn,
+ (OpcodeMethod)&TattooTalk::cmdSetNPCDescOnOff,
+ (OpcodeMethod)&TattooTalk::cmdSetNPCPathPauseTakingNotes,
+ (OpcodeMethod)&TattooTalk::cmdSetNPCPathPauseLookingHolmes,
+
+ (OpcodeMethod)&TattooTalk::cmdTalkInterruptsEnable,
+ (OpcodeMethod)&TattooTalk::cmdTalkInterruptsDisable,
+ (OpcodeMethod)&TattooTalk::cmdSetNPCInfoLine,
+ (OpcodeMethod)&TattooTalk::cmdSetNPCPosition,
+ (OpcodeMethod)&TattooTalk::cmdNPCLabelSet,
+ (OpcodeMethod)&TattooTalk::cmdNPCLabelGoto,
+ (OpcodeMethod)&TattooTalk::cmdNPCLabelIfFlagGoto,
+ (OpcodeMethod)&TattooTalk::cmdSetNPCWalkGraphics,
+ nullptr,
+ (OpcodeMethod)&TattooTalk::cmdSetNPCVerb,
+
+ (OpcodeMethod)&TattooTalk::cmdSetNPCVerbCAnimation,
+ (OpcodeMethod)&TattooTalk::cmdSetNPCVerbScript,
+ nullptr,
+ (OpcodeMethod)&TattooTalk::cmdRestorePeopleSequence,
+ (OpcodeMethod)&TattooTalk::cmdSetNPCVerbTarget,
+ (OpcodeMethod)&TattooTalk::cmdTurnSoundsOff
+ };
+
+ _opcodes = TATTOO_OPCODES;
+ _opcodeTable = OPCODE_METHODS;
+}
+
+void TattooTalk::talkInterface(const byte *&str) {
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+ const byte *s = str;
+
+ // Move to past the end of the text string
+ _charCount = 0;
+ while ((*str < TATTOO_OPCODES[0] || *str == TATTOO_OPCODES[OP_NULL]) && *str) {
+ ++_charCount;
+ ++str;
+ }
+
+ // Display the text window
+// ui.banishWindow();
+ ui._textWidget.load(Common::String((const char *)s, (const char *)str), _speaker);
+ ui._textWidget.summonWindow();
+ _wait = true;
+}
+
+void TattooTalk::showTalk() {
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+
+ _sequenceStack.clear();
+ people.setListenSequence(_talkTo, 129);
+
+ _talkWidget.load();
+ _talkWidget.summonWindow();
+ _talkWidget.refresh();
+
+ if (ui._menuMode != MESSAGE_MODE)
+ ui._menuMode = TALK_MODE;
+}
+
+OpcodeReturn TattooTalk::cmdSwitchSpeaker(const byte *&str) {
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ Screen &screen = *_vm->_screen;
+ UserInterface &ui = *_vm->_ui;
+
+ if (_talkToAbort)
+ return RET_EXIT;
+
+ ui.clearWindow();
+
+ _yp = screen.fontHeight() + 11;
+ _charCount = _line = 0;
+
+ people.setListenSequence(_speaker, 129);
+ _speaker = *++str - 1;
+ ++str;
+
+ people.setTalkSequence(_speaker, 1);
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn TattooTalk::cmdMouseOnOff(const byte *&str) {
+ Events &events = *_vm->_events;
+ bool mouseOn = *++str == 2;
+ if (mouseOn)
+ events.showCursor();
+ else
+ events.hideCursor();
+ return RET_SUCCESS;
+}
+
+OpcodeReturn TattooTalk::cmdWalkHolmesToCoords(const byte *&str) {
+ People &people = *_vm->_people;
+ ++str;
+
+ int xp = (str[0] - 1) * 256 + str[1] - 1;
+ if (xp > 16384)
+ // Negative X
+ xp = -1 * (xp - 16384);
+ int yp = (str[2] - 1) * 256 + str[3] - 1;
+
+ people[HOLMES].walkToCoords(Point32(xp * FIXED_INT_MULTIPLIER, yp * FIXED_INT_MULTIPLIER),
+ DIRECTION_CONVERSION[str[4] - 1]);
+
+ if (_talkToAbort)
+ return RET_EXIT;
+
+ str += 4;
+ return RET_SUCCESS;
+}
+
+OpcodeReturn TattooTalk::cmdGotoScene(const byte *&str) {
+ Map &map = *_vm->_map;
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ Scene &scene = *_vm->_scene;
+ scene._goToScene = str[1] - 1;
+
+ if (scene._goToScene != OVERHEAD_MAP) {
+ // Not going to the map overview
+ map._oldCharPoint = scene._goToScene;
+
+ // Run a canimation?
+ if (str[2] > 100) {
+ people._savedPos = PositionFacing(160, 100, str[2]);
+ } else {
+ int32 posX = (str[3] - 1) * 256 + str[4] - 1;
+ if (posX > 16384)
+ posX = -1 * (posX - 16384);
+ int32 posY = (str[5] - 1) * 256 + str[6] - 1;
+ people._savedPos = PositionFacing(posX, posY, str[2] - 1);
+ }
+
+ _scriptMoreFlag = 1;
+ }
+
+ str += 7;
+ if (scene._goToScene != OVERHEAD_MAP)
+ _scriptSaveIndex = str - _scriptStart;
+
+ _endStr = true;
+ _wait = 0;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn TattooTalk::cmdNextSong(const byte *&str) {
+ Music &music = *_vm->_music;
+
+ // Get the name of the next song to play
+ ++str;
+ music._nextSongName = "";
+ for (int idx = 0; idx < 8; ++idx) {
+ if (str[idx] != '~')
+ music._nextSongName += str[idx];
+ else
+ break;
+ }
+ str += 7;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn TattooTalk::cmdNPCLabelGoto(const byte *&str) {
+ int npcNum = *++str;
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ TattooPerson &person = people[npcNum];
+
+ if (person._resetNPCPath) {
+ person._npcIndex = person._npcPause = 0;
+ person._resetNPCPath = false;
+ memset(person._npcPath, 0, 100);
+ }
+
+ person._npcPath[person._npcIndex] = 8;
+ person._npcPath[person._npcIndex + 1] = str[1];
+ person._npcIndex += 2;
+ str++;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn TattooTalk::cmdNPCLabelIfFlagGoto(const byte *&str) {
+ int npcNum = *++str;
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ TattooPerson &person = people[npcNum];
+
+ if (person._resetNPCPath) {
+ person._npcIndex = person._npcPause = 0;
+ person._resetNPCPath = false;
+ memset(person._npcPath, 0, 100);
+ }
+
+ person._npcPath[person._npcIndex] = 9;
+ for (int i = 1; i <= 3; i++)
+ person._npcPath[person._npcIndex + i] = str[i];
+
+ person._npcIndex += 4;
+ str += 3;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn TattooTalk::cmdNPCLabelSet(const byte *&str) {
+ int npcNum = *++str;
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ TattooPerson &person = people[npcNum];
+
+ if (person._resetNPCPath) {
+ person._npcIndex = person._npcPause = 0;
+ person._resetNPCPath = false;
+ memset(person._npcPath, 0, 100);
+ }
+
+ person._npcPath[person._npcIndex] = 7;
+ person._npcPath[person._npcIndex + 1] = str[1];
+ person._npcIndex += 2;
+ str++;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn TattooTalk::cmdPassword(const byte *&str) { error("TODO: script opcode (cmdPassword)"); }
+
+OpcodeReturn TattooTalk::cmdPlaySong(const byte *&str) {
+ Music &music = *_vm->_music;
+ Common::String currentSong = music._currentSongName;
+
+ // Get the name of the song to play
+ music._currentSongName = "";
+ str++;
+ for (int idx = 0; idx < 8; ++idx) {
+ if (str[idx] != '~')
+ music._currentSongName += str[idx];
+ else
+ break;
+ }
+ str += 7;
+
+ // Play the song
+ music.loadSong(music._currentSongName);
+
+ // Copy the old song name to _nextSongName so that when the new song is finished, the old song will restart
+ music._nextSongName = currentSong;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn TattooTalk::cmdRestorePeopleSequence(const byte *&str) {
+ int npcNum = *++str - 1;
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ TattooPerson &person = people[npcNum];
+ person._misc = 0;
+
+ if (person._seqTo) {
+ person._walkSequences[person._sequenceNumber]._sequences[person._frameNumber] = person._seqTo;
+ person._seqTo = 0;
+ }
+ person._sequenceNumber = person._savedNpcSequence;
+ person._frameNumber = person._savedNpcFrame;
+ person.checkWalkGraphics();
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn TattooTalk::cmdSetNPCDescOnOff(const byte *&str) {
+ int npcNum = *++str;
+ ++str;
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ Person &person = people[npcNum];
+
+ // Copy over the NPC examine text until we reach a stop marker, which is
+ // the same as a start marker, or we reach the end of the file
+ while (*str && *str != _opcodes[OP_NPC_DESC_ON_OFF])
+ person._examine += *str++;
+
+ // Move past any leftover text till we reach a stop marker
+ while (*str && *str != _opcodes[OP_NPC_DESC_ON_OFF])
+ str++;
+
+ if (!*str)
+ // Reached end of file, so decrement pointer so outer loop will terminate on NULL
+ --str;
+ else
+ // Move past the ending OP_NPC_DEST_ON_OFF opcode
+ ++str;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn TattooTalk::cmdSetNPCInfoLine(const byte *&str) {
+ int npcNum = *++str;
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ TattooPerson &person = people[npcNum];
+
+ person._description = "";
+ int len = *++str;
+ for (int idx = 0; idx < len; ++idx)
+ person._description += str[idx + 1];
+
+ str += len;
+ return RET_SUCCESS;
+}
+
+OpcodeReturn TattooTalk::cmdSetNPCOff(const byte *&str) {
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ int npcNum = *++str;
+ people[npcNum]._type = REMOVE;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn TattooTalk::cmdSetNPCOn(const byte *&str) {
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ int npcNum = *++str;
+ people[npcNum]._type = CHARACTER;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn TattooTalk::cmdSetNPCPathDest(const byte *&str) {
+ int npcNum = *++str;
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ TattooPerson &person = people[npcNum];
+
+ if (person._resetNPCPath) {
+ person._npcIndex = person._npcPause = 0;
+ person._resetNPCPath = false;
+ memset(person._npcPath, 0, 100);
+ }
+
+ person._npcPath[person._npcIndex] = 1;
+ for (int i = 1; i <= 4; i++)
+ person._npcPath[person._npcIndex + i] = str[i];
+ person._npcPath[person._npcIndex + 5] = DIRECTION_CONVERSION[str[5] - 1] + 1;
+
+ person._npcIndex += 6;
+ str += 5;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn TattooTalk::cmdSetNPCPathPause(const byte *&str) {
+ int npcNum = *++str;
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ TattooPerson &person = people[npcNum];
+
+ if (person._resetNPCPath) {
+ person._npcIndex = person._npcPause = 0;
+ person._resetNPCPath = false;
+ memset(person._npcPath, 0, 100);
+ }
+
+ person._npcPath[person._npcIndex] = 2;
+ for (int i = 1; i <= 2; i++)
+ person._npcPath[person._npcIndex + i] = str[i];
+
+ person._npcIndex += 3;
+ str += 2;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn TattooTalk::cmdSetNPCPathPauseTakingNotes(const byte *&str) {
+ int npcNum = *++str;
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ TattooPerson &person = people[npcNum];
+
+ if (person._resetNPCPath) {
+ person._npcIndex = person._npcPause = 0;
+ person._resetNPCPath = false;
+ memset(person._npcPath, 0, 100);
+ }
+
+ person._npcPath[person._npcIndex] = 5;
+ for (int i = 1; i <= 2; i++)
+ person._npcPath[person._npcIndex + i] = str[i];
+
+ person._npcIndex += 3;
+ str += 2;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn TattooTalk::cmdSetNPCPathPauseLookingHolmes(const byte *&str) {
+ int npcNum = *++str;
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ TattooPerson &person = people[npcNum];
+
+ if (person._resetNPCPath) {
+ person._npcIndex = person._npcPause = 0;
+ person._resetNPCPath = false;
+ memset(person._npcPath, 0, 100);
+ }
+
+ person._npcPath[person._npcIndex] = 6;
+ for (int i = 1; i <= 2; i++)
+ person._npcPath[person._npcIndex + i] = str[i];
+
+ person._npcIndex += 3;
+ str += 2;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn TattooTalk::cmdSetNPCPosition(const byte *&str) {
+ int npcNum = *++str - 1;
+ ++str;
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ TattooPerson &person = people[npcNum];
+ int32 posX = (str[0] - 1) * 256 + str[1] - 1;
+ if (posX > 16384)
+ posX = -1 * (posX - 16384);
+ int32 posY = (str[2] - 1) * 256 + str[3] - 1;
+
+ people[npcNum]._position = Point32(posX * FIXED_INT_MULTIPLIER, posY * FIXED_INT_MULTIPLIER);
+ if (person._seqTo && person._walkLoaded) {
+ person._walkSequences[person._sequenceNumber]._sequences[person._frameNumber] = person._seqTo;
+ person._seqTo = 0;
+ }
+
+ assert(str[4] - 1 < 16);
+ person._sequenceNumber = DIRECTION_CONVERSION[str[4] - 1];
+ person._frameNumber = 0;
+
+ if (person._walkLoaded)
+ person.checkWalkGraphics();
+
+ if (person._walkLoaded && person._type == CHARACTER &&
+ person._sequenceNumber >= STOP_UP && person._sequenceNumber <= STOP_UPLEFT) {
+ bool done = false;
+ do {
+ person.checkSprite();
+ for (int x = 0; x < person._frameNumber; x++) {
+ if (person._walkSequences[person._sequenceNumber]._sequences[x] == 0) {
+ done = true;
+ break;
+ }
+ }
+ } while(!done);
+ }
+
+ str += 4;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn TattooTalk::cmdSetNPCTalkFile(const byte *&str) {
+ int npcNum = *++str;
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ TattooPerson &person = people[npcNum];
+
+ if (person._resetNPCPath) {
+ person._npcIndex = person._npcPause = 0;
+ person._resetNPCPath = false;
+ memset(person._npcPath, 0, 100);
+ }
+
+ person._npcPath[person._npcIndex] = 3;
+ for (int i = 1; i <= 8; i++)
+ person._npcPath[person._npcIndex + i] = str[i];
+
+ person._npcIndex += 9;
+ str += 8;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn TattooTalk::cmdSetNPCVerb(const byte *&str) {
+ int npcNum = *++str;
+ int verbNum = *++str - 1;
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ Common::String &verb = people[npcNum]._use[verbNum]._verb;
+
+ for (int x = 0; x < 12; x++) {
+ if (str[x + 1] != '~')
+ verb.setChar(str[x + 1], x);
+ else
+ verb.setChar(0, x);
+ }
+
+ verb.setChar(0, 11);
+
+ uint len = verb.size() - 1;
+ while (verb[len] == ' ' && len)
+ len--;
+ verb.setChar(0, len + 1);
+ if (verb != " ")
+ verb.clear();
+ str += 12;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn TattooTalk::cmdSetNPCVerbCAnimation(const byte *&str) {
+ int npcNum = *++str;
+ int verbNum = *++str - 1;
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ UseType &useType = people[npcNum]._use[verbNum];
+
+ useType._cAnimNum = (str[1] - 1) & 127;
+ useType._cAnimSpeed = 1 + 128 * (str[1] >= 128);
+ str++;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn TattooTalk::cmdSetNPCVerbScript(const byte *&str) {
+ int npcNum = *++str;
+ int verbNum = *++str - 1;
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ UseType &useType = people[npcNum]._use[verbNum];
+ Common::String &name = useType._names[0];
+ name.setChar('*', 0);
+ name.setChar('C', 1);
+
+ for (int x = 0; x < 8; x++) {
+ if (str[x + 1] != '~')
+ name.setChar(str[x + 1], x + 2);
+ else
+ name.setChar(0, x + 2);
+ }
+
+ name.setChar(0, 11);
+ useType._cAnimNum = 99;
+ useType._cAnimSpeed = 1;
+ str += 8;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn TattooTalk::cmdSetNPCVerbTarget(const byte *&str) {
+ int npcNum = *++str;
+ int verbNum = *++str - 1;
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ Common::String &target = people[npcNum]._use[verbNum]._target;
+
+ for (int x = 0; x < 12; x++) {
+ if (str[x + 1] != '~')
+ target.setChar(str[x + 1], x);
+ else
+ target.setChar(0, x);
+ }
+
+ target.setChar(0, 11);
+
+ uint len = target.size() - 1;
+ while (target[len] == ' ' && len)
+ len--;
+ target.setChar(0, len + 1);
+ str += 12;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn TattooTalk::cmdSetNPCWalkGraphics(const byte *&str) {
+ int npcNum = *++str - 1;
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ Person &person = people[npcNum];
+
+ // Build up walk library name for the given NPC
+ person._walkVGSName = "";
+ for (int idx = 0; idx < 8; ++idx) {
+ if (str[idx + 1] != '~')
+ person._walkVGSName += str[idx + 1];
+ else
+ break;
+ }
+ person._walkVGSName += ".VGS";
+
+ people._forceWalkReload = true;
+ str += 8;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn TattooTalk::cmdSetSceneEntryFlag(const byte *&str) {
+ TattooScene &scene = *(TattooScene *)_vm->_scene;
+ ++str;
+ int flag = (str[0] - 1) * 256 + str[1] - 1 - (str[1] == 1);
+
+ int flag1 = flag & 16383;
+ if (flag > 16383)
+ flag1 *= -1;
+
+ str += 2;
+
+ // Make sure that this instance is not already being tracked
+ bool found = false;
+ for (uint idx = 0; idx < scene._sceneTripCounters.size() && !found; ++idx) {
+ SceneTripEntry &entry = scene._sceneTripCounters[idx];
+ if (entry._flag == flag1 && entry._sceneNumber == str[0] - 1)
+ found = true;
+ }
+
+ // Only add it if it's not being tracked already
+ if (!found)
+ scene._sceneTripCounters.push_back(SceneTripEntry(flag1, str[0] - 1, str[1] - 1));
+
+ ++str;
+ return RET_SUCCESS;
+}
+
+OpcodeReturn TattooTalk::cmdSetTalkSequence(const byte *&str) {
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ int speaker = str[1] - 1;
+ int sequenceNumber = str[2];
+
+ if (sequenceNumber < 128)
+ people.setTalkSequence(speaker, sequenceNumber);
+ else
+ people.setListenSequence(speaker, sequenceNumber);
+
+ str += 2;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn TattooTalk::cmdSetWalkControl(const byte *&str) {
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ ++str;
+ people._walkControl = str[0] - 1;
+
+ return RET_SUCCESS;
+}
+
+// Dummy opcode
+OpcodeReturn TattooTalk::cmdTalkInterruptsDisable(const byte *&str) { error("Dummy opcode cmdTalkInterruptsDisable called"); }
+
+// Dummy opcode
+OpcodeReturn TattooTalk::cmdTalkInterruptsEnable(const byte *&str) { error("Dummy opcode cmdTalkInterruptsEnable called"); }
+
+OpcodeReturn TattooTalk::cmdTurnSoundsOff(const byte *&str) { error("TODO: script opcode (cmdTurnSoundsOff)"); }
+
+OpcodeReturn TattooTalk::cmdWalkHolmesAndNPCToCAnimation(const byte *&str) {
+ int npcNum = *++str;
+ int cAnimNum = *++str;
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ TattooPerson &person = people[npcNum];
+ Scene &scene = *_vm->_scene;
+ CAnim &anim = scene._cAnim[cAnimNum];
+
+ if (person._pathStack.empty())
+ person.pushNPCPath();
+ person._npcMoved = true;
+
+ person.walkToCoords(anim._goto[1], anim._goto[1]._facing);
+
+ if (_talkToAbort)
+ return RET_EXIT;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn TattooTalk::cmdWalkNPCToCAnimation(const byte *&str) {
+ int npcNum = *++str;
+ int cAnimNum = *++str;
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ TattooPerson &person = people[npcNum];
+ Scene &scene = *_vm->_scene;
+ CAnim &anim = scene._cAnim[cAnimNum];
+
+ if (person._pathStack.empty())
+ person.pushNPCPath();
+ person._npcMoved = true;
+
+ person.walkToCoords(anim._goto[1], anim._goto[1]._facing);
+
+ if (_talkToAbort)
+ return RET_EXIT;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn TattooTalk::cmdWalkNPCToCoords(const byte *&str) {
+ int npcNum = *++str;
+ str++;
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ TattooPerson &person = people[npcNum];
+
+ if (person._pathStack.empty())
+ person.pushNPCPath();
+ person._npcMoved = true;
+
+ int xp = (str[0] - 1) * 256 + str[1] - 1;
+ if (xp > 16384)
+ xp = -1 * (xp - 16384);
+ int yp = (str[2] - 1) * 256 + str[3] - 1;
+
+ person.walkToCoords(Point32(xp * FIXED_INT_MULTIPLIER, yp * FIXED_INT_MULTIPLIER),
+ DIRECTION_CONVERSION[str[4] - 1]);
+ if (_talkToAbort)
+ return RET_EXIT;
+
+ str += 4;
+ return RET_SUCCESS;
+}
+
+OpcodeReturn TattooTalk::cmdWalkHomesAndNPCToCoords(const byte *&str) {
+ int npcNum = *++str;
+ str++;
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ TattooPerson &person = people[npcNum];
+
+ if (person._pathStack.empty())
+ person.pushNPCPath();
+ person._npcMoved = true;
+
+ int xp = (str[0] - 1) * 256 + str[1] - 1;
+ if (xp > 16384)
+ xp = -1 * (xp - 16384);
+ int yp = (str[2] - 1) * 256 + str[3] - 1;
+
+ person.walkToCoords(Point32(xp * FIXED_INT_MULTIPLIER, yp * FIXED_INT_MULTIPLIER),
+ DIRECTION_CONVERSION[str[4] - 1]);
+
+ if (_talkToAbort)
+ return RET_EXIT;
+
+ str += 9;
+ return RET_SUCCESS;
+}
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/tattoo/tattoo_talk.h b/engines/sherlock/tattoo/tattoo_talk.h
new file mode 100644
index 0000000000..8abbb1b8be
--- /dev/null
+++ b/engines/sherlock/tattoo/tattoo_talk.h
@@ -0,0 +1,101 @@
+/* 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 SHERLOCK_TATTOO_TALK_H
+#define SHERLOCK_TATTOO_TALK_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/rect.h"
+#include "common/serializer.h"
+#include "common/stream.h"
+#include "common/stack.h"
+#include "sherlock/talk.h"
+#include "sherlock/tattoo/widget_talk.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+class WidgetTalk;
+
+class TattooTalk : public Talk {
+ friend class WidgetTalk;
+private:
+ WidgetTalk _talkWidget;
+
+ OpcodeReturn cmdSwitchSpeaker(const byte *&str);
+ OpcodeReturn cmdMouseOnOff(const byte *&str);
+ OpcodeReturn cmdGotoScene(const byte *&str);
+ OpcodeReturn cmdWalkHolmesToCoords(const byte *&str);
+ OpcodeReturn cmdNextSong(const byte *&str);
+ OpcodeReturn cmdPassword(const byte *&str);
+ OpcodeReturn cmdPlaySong(const byte *&str);
+ OpcodeReturn cmdRestorePeopleSequence(const byte *&str);
+ OpcodeReturn cmdSetNPCDescOnOff(const byte *&str);
+ OpcodeReturn cmdSetNPCInfoLine(const byte *&str);
+ OpcodeReturn cmdNPCLabelGoto(const byte *&str);
+ OpcodeReturn cmdNPCLabelIfFlagGoto(const byte *&str);
+ OpcodeReturn cmdNPCLabelSet(const byte *&str);
+ OpcodeReturn cmdSetNPCOff(const byte *&str);
+ OpcodeReturn cmdSetNPCOn(const byte *&str);
+ OpcodeReturn cmdSetNPCPathDest(const byte *&str);
+ OpcodeReturn cmdSetNPCPathPause(const byte *&str);
+ OpcodeReturn cmdSetNPCPathPauseTakingNotes(const byte *&str);
+ OpcodeReturn cmdSetNPCPathPauseLookingHolmes(const byte *&str);
+ OpcodeReturn cmdSetNPCPosition(const byte *&str);
+ OpcodeReturn cmdSetNPCTalkFile(const byte *&str);
+ OpcodeReturn cmdSetNPCVerb(const byte *&str);
+ OpcodeReturn cmdSetNPCVerbCAnimation(const byte *&str);
+ OpcodeReturn cmdSetNPCVerbScript(const byte *&str);
+ OpcodeReturn cmdSetNPCVerbTarget(const byte *&str);
+ OpcodeReturn cmdSetNPCWalkGraphics(const byte *&str);
+ OpcodeReturn cmdSetSceneEntryFlag(const byte *&str);
+ OpcodeReturn cmdSetTalkSequence(const byte *&str);
+ OpcodeReturn cmdSetWalkControl(const byte *&str);
+ OpcodeReturn cmdTalkInterruptsDisable(const byte *&str);
+ OpcodeReturn cmdTalkInterruptsEnable(const byte *&str);
+ OpcodeReturn cmdTurnSoundsOff(const byte *&str);
+ OpcodeReturn cmdWalkHolmesAndNPCToCAnimation(const byte *&str);
+ OpcodeReturn cmdWalkNPCToCAnimation(const byte *&str);
+ OpcodeReturn cmdWalkNPCToCoords(const byte *&str);
+ OpcodeReturn cmdWalkHomesAndNPCToCoords(const byte *&str);
+protected:
+ /**
+ * Display the talk interface window
+ */
+ virtual void talkInterface(const byte *&str);
+
+ /**
+ * Show the talk display
+ */
+ virtual void showTalk();
+public:
+ TattooTalk(SherlockEngine *vm);
+ virtual ~TattooTalk() {}
+};
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/tattoo/tattoo_user_interface.cpp b/engines/sherlock/tattoo/tattoo_user_interface.cpp
new file mode 100644
index 0000000000..ae09ba5fc7
--- /dev/null
+++ b/engines/sherlock/tattoo/tattoo_user_interface.cpp
@@ -0,0 +1,862 @@
+/* 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 "sherlock/tattoo/tattoo_user_interface.h"
+#include "sherlock/tattoo/tattoo_journal.h"
+#include "sherlock/tattoo/tattoo_scene.h"
+#include "sherlock/tattoo/tattoo.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+TattooUserInterface::TattooUserInterface(SherlockEngine *vm): UserInterface(vm),
+ _inventoryWidget(vm), _messageWidget(vm), _textWidget(vm), _tooltipWidget(vm), _verbsWidget(vm),
+ _labWidget(vm) {
+ Common::fill(&_lookupTable[0], &_lookupTable[PALETTE_COUNT], 0);
+ Common::fill(&_lookupTable1[0], &_lookupTable1[PALETTE_COUNT], 0);
+ _scrollSize = 0;
+ _scrollSpeed = 16;
+ _drawMenu = false;
+ _bgShape = nullptr;
+ _personFound = false;
+ _lockoutTimer = 0;
+ _fileMode = SAVEMODE_NONE;
+ _exitZone = -1;
+ _scriptZone = -1;
+ _arrowZone = _oldArrowZone = -1;
+ _activeObj = -1;
+ _cAnimFramePause = 0;
+ _scrollHighlight = SH_NONE;
+ _mask = _mask1 = nullptr;
+ _maskCounter = 0;
+
+ _interfaceImages = new ImageFile("intrface.vgs");
+}
+
+TattooUserInterface::~TattooUserInterface() {
+ delete _interfaceImages;
+}
+
+void TattooUserInterface::initScrollVars() {
+ Screen &screen = *_vm->_screen;
+ _scrollSize = screen._backBuffer1.w() - SHERLOCK_SCREEN_WIDTH;
+ _targetScroll = Common::Point(0, 0);
+ screen._currentScroll = Common::Point(0, 0);
+}
+
+void TattooUserInterface::lookAtObject() {
+ Events &events = *_vm->_events;
+ People &people = *_vm->_people;
+ Scene &scene = *_vm->_scene;
+ Sound &sound = *_vm->_sound;
+ Talk &talk = *_vm->_talk;
+ Common::Point mousePos = events.mousePos();
+ Common::String desc;
+ int cAnimSpeed = 0;
+
+ _lookPos = mousePos;
+ _menuMode = LOOK_MODE;
+
+ if (_personFound) {
+ desc = people[_bgFound - 1000]._examine;
+ } else {
+ // Check if there is a Look animation
+ if (_bgShape->_lookcAnim != 0) {
+ cAnimSpeed = _bgShape->_lookcAnim & 0xe0;
+ cAnimSpeed >>= 5;
+ ++cAnimSpeed;
+
+ _cAnimFramePause = _bgShape->_lookFrames;
+ desc = _bgShape->_examine;
+
+ int cNum = (_bgShape->_lookcAnim & 0x1f) - 1;
+ scene.startCAnim(cNum);
+ } else if (_bgShape->_lookPosition.y != 0) {
+ // Need to walk to object before looking at it
+ people[HOLMES].walkToCoords(_bgShape->_lookPosition, _bgShape->_lookPosition._facing);
+ }
+
+ if (!talk._talkToAbort) {
+ desc = _bgShape->_examine;
+
+ if (_bgShape->_lookFlag)
+ _vm->setFlags(_bgShape->_lookFlag);
+
+ // Find the Sound File to Play if there is one
+ if (!desc.hasPrefix("_")) {
+ for (uint idx = 0; idx < scene._objSoundList.size(); ++idx) {
+ // Get the object name up to the equals
+ const char *p = strchr(scene._objSoundList[idx].c_str(), '=');
+
+ // Form the name and remove any trailing spaces
+ Common::String name(scene._objSoundList[idx].c_str(), p);
+ while (name.hasSuffix(" "))
+ name.deleteLastChar();
+
+ // See if this Object Sound List entry matches the object's name
+ if (!_bgShape->_name.compareToIgnoreCase(name)) {
+ // Move forward to get the sound filename
+ while ((*p == ' ') || (*p == '='))
+ ++p;
+
+ // If it's not "NONE", play the Sound File
+ Common::String soundName(p);
+ if (soundName.compareToIgnoreCase("NONE")) {
+ soundName.toLowercase();
+ if (!soundName.contains('.'))
+ soundName += ".wav";
+
+ sound.playSound(soundName, WAIT_RETURN_IMMEDIATELY);
+ }
+
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // Only show the desciption if the object has one, and if no talk file interrupted while walking to it
+ if (!talk._talkToAbort && !desc.empty()) {
+ if (_cAnimFramePause == 0)
+ printObjectDesc(desc, true);
+ else
+ // The description was already printed by an animation
+ _cAnimFramePause = 0;
+ } else if (desc.empty()) {
+ // There was no description to display, so reset back to STD_MODE
+ _menuMode = STD_MODE;
+ }
+}
+
+void TattooUserInterface::printObjectDesc(const Common::String &str, bool firstTime) {
+ Events &events = *_vm->_events;
+ TattooScene &scene = *(TattooScene *)_vm->_scene;
+ Talk &talk = *_vm->_talk;
+
+ if (str.hasPrefix("_")) {
+ // The passed string specifies a talk file
+ _lookScriptFlag = true;
+ events.setCursor(MAGNIFY);
+ int savedSelector = _selector;
+
+ if (!_invLookFlag)
+ _windowOpen = false;
+
+ talk.talkTo(str.c_str() + 1);
+ _lookScriptFlag = false;
+
+ if (talk._talkToAbort) {
+ events.setCursor(ARROW);
+ return;
+ }
+
+ // See if we're looking at an inventory item
+ if (_invLookFlag) {
+ _selector = _oldSelector = savedSelector;
+ doInventory(0);
+ _invLookFlag = false;
+
+ } else {
+ // Nope
+ events.setCursor(ARROW);
+ _key = -1;
+ _menuMode = scene._labTableScene ? LAB_MODE : STD_MODE;
+ events._pressed = events._released = events._rightReleased = false;
+ events._oldButtons = 0;
+ }
+ } else {
+ events._pressed = events._released = events._rightReleased = false;
+
+ // Show text dialog
+ _textWidget.load(str);
+ _textWidget.summonWindow();
+
+ if (firstTime)
+ _selector = _oldSelector = -1;
+
+ _drawMenu = _windowOpen = true;
+ }
+}
+
+void TattooUserInterface::doJournal() {
+ TattooJournal &journal = *(TattooJournal *)_vm->_journal;
+ TattooScene &scene = *(TattooScene *)_vm->_scene;
+ Screen &screen = *_vm->_screen;
+
+ _menuMode = JOURNAL_MODE;
+ journal.show();
+
+ _menuMode = STD_MODE;
+ _windowOpen = false;
+ _key = -1;
+
+ setupBGArea(screen._cMap);
+ screen.clear();
+ screen.setPalette(screen._cMap);
+
+ screen._backBuffer1.blitFrom(screen._backBuffer2);
+ scene.updateBackground();
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+}
+
+void TattooUserInterface::reset() {
+ UserInterface::reset();
+ _lookPos = Common::Point(SHERLOCK_SCREEN_WIDTH / 2, SHERLOCK_SCREEN_HEIGHT / 2);
+ _tooltipWidget.setText("");
+ _widgets.clear();
+}
+
+void TattooUserInterface::handleInput() {
+ TattooEngine &vm = *(TattooEngine *)_vm;
+ Events &events = *_vm->_events;
+ TattooScene &scene = *(TattooScene *)_vm->_scene;
+ Common::Point mousePos = events.mousePos();
+
+ _vm->_canLoadSave = _menuMode == STD_MODE;
+ events.pollEventsAndWait();
+ _vm->_canLoadSave = false;
+ _keyState.keycode = Common::KEYCODE_INVALID;
+
+ // Check for credits starting
+ if (_vm->readFlags(3000) && !vm._creditsActive)
+ vm.initCredits();
+
+ // Check the mouse positioning
+ if (events.isCursorVisible())
+ _bgFound = scene.findBgShape(mousePos);
+ _personFound = _bgFound >= 1000;
+ _bgShape = (_bgFound != -1 && _bgFound < 1000) ? &scene._bgShapes[_bgFound] : nullptr;
+
+ if (_lockoutTimer)
+ --_lockoutTimer;
+
+ // Key handling
+ if (events.kbHit()) {
+ _keyState = events.getKey();
+
+ if (_keyState.keycode == Common::KEYCODE_s && vm._allowFastMode)
+ vm._fastMode = !vm._fastMode;
+
+ else if (_keyState.keycode == Common::KEYCODE_l && _bgFound != -1) {
+ // Beging used for testing that Look dialogs work
+ lookAtObject();
+
+ } else if (_keyState.keycode == Common::KEYCODE_ESCAPE && vm._runningProlog && !_lockoutTimer) {
+ vm.setFlags(-76);
+ vm.setFlags(396);
+ scene._goToScene = STARTING_GAME_SCENE;
+ }
+ }
+
+ if (!events.isCursorVisible())
+ _keyState.keycode = Common::KEYCODE_INVALID;
+
+ // If there's any active widgets/windows, let the most recently open one do event processing
+ if (!_widgets.empty())
+ _widgets.back()->handleEvents();
+
+ // Handle input depending on what mode we're in
+ switch (_menuMode) {
+ case STD_MODE:
+ doStandardControl();
+ break;
+ case LOOK_MODE:
+ doLookControl();
+ break;
+ case FILES_MODE:
+ doFileControl();
+ break;
+ default:
+ break;
+ }
+}
+
+void TattooUserInterface::drawInterface(int bufferNum) {
+ Screen &screen = *_vm->_screen;
+ TattooEngine &vm = *(TattooEngine *)_vm;
+
+ // Draw any active on-screen widgets
+ for (Common::List<WidgetBase *>::iterator i = _widgets.begin(); i != _widgets.end(); ++i)
+ (*i)->draw();
+
+ // Handle drawing credits
+ if (vm._creditsActive)
+ vm.drawCredits();
+
+ // Bring the widgets to the screen
+ if (_mask != nullptr)
+ screen._flushScreen = true;
+
+ if (screen._flushScreen)
+ screen.blockMove();
+
+ // Handle drawing the text tooltip if necessary
+ if (_menuMode == STD_MODE || _menuMode == LAB_MODE)
+ _tooltipWidget.draw();
+}
+
+void TattooUserInterface::doBgAnimRestoreUI() {
+ TattooScene &scene = *((TattooScene *)_vm->_scene);
+ Screen &screen = *_vm->_screen;
+
+ // If there are any on-screen widgets, then erase them
+ for (Common::List<WidgetBase *>::iterator i = _widgets.begin(); i != _widgets.end(); ++i)
+ (*i)->erase();
+
+ // If there is a Text Tag being display, restore the area underneath it
+ _tooltipWidget.erase();
+
+ // If a canimation is active, restore the graphics underneath it
+ if (scene._activeCAnim.active())
+ screen.restoreBackground(scene._activeCAnim._oldBounds);
+
+ // If a canimation just ended, remove it's graphics from the backbuffer
+ if (scene._activeCAnim._removeBounds.width() > 0)
+ screen.restoreBackground(scene._activeCAnim._removeBounds);
+}
+
+void TattooUserInterface::doScroll() {
+ Screen &screen = *_vm->_screen;
+
+ // If we're already at the target scroll position, nothing needs to be done
+ if (_targetScroll.x == screen._currentScroll.x)
+ return;
+
+ screen._flushScreen = true;
+ if (_targetScroll.x > screen._currentScroll.x) {
+ screen._currentScroll.x += _scrollSpeed;
+ if (screen._currentScroll.x > _targetScroll.x)
+ screen._currentScroll.x = _targetScroll.x;
+ } else if (_targetScroll.x < screen._currentScroll.x) {
+ screen._currentScroll.x -= _scrollSpeed;
+ if (screen._currentScroll.x < _targetScroll.x)
+ screen._currentScroll.x = _targetScroll.x;
+ }
+}
+
+void TattooUserInterface::doStandardControl() {
+ TattooEngine &vm = *(TattooEngine *)_vm;
+ Events &events = *_vm->_events;
+ People &people = *_vm->_people;
+ TattooScene &scene = *(TattooScene *)_vm->_scene;
+ Talk &talk = *_vm->_talk;
+ Common::Point mousePos = events.mousePos();
+ bool noDesc = false;
+
+ // Don't do any input processing whilst the prolog is running
+ if (vm._runningProlog)
+ return;
+
+ // Display the names of any Objects the cursor is pointing at
+ displayObjectNames();
+
+ switch (_keyState.keycode) {
+ case Common::KEYCODE_F5:
+ // Save game
+ freeMenu();
+ _fileMode = SAVEMODE_SAVE;
+ initFileMenu();
+ return;
+
+ case Common::KEYCODE_F7:
+ // Load game
+ freeMenu();
+ _fileMode = SAVEMODE_LOAD;
+ initFileMenu();
+ return;
+
+ case Common::KEYCODE_F1:
+ // Display journal
+ if (vm.readFlags(FLAG_PLAYER_IS_HOLMES)) {
+ freeMenu();
+ doJournal();
+
+ // See if we're in a Lab Table Room
+ _menuMode = (scene._labTableScene) ? LAB_MODE : STD_MODE;
+ return;
+ }
+ break;
+
+ case Common::KEYCODE_TAB:
+ case Common::KEYCODE_F3:
+ // Display inventory
+ freeMenu();
+ doInventory(3);
+ return;
+
+ case Common::KEYCODE_F4:
+ // Display options
+ freeMenu();
+ doControls();
+ return;
+
+ case Common::KEYCODE_F10:
+ // Quit menu
+ freeMenu();
+ doQuitMenu();
+ return;
+
+ default:
+ break;
+ }
+
+ // See if a mouse button was released
+ if (events._released || events._rightReleased) {
+ // See if the mouse was released in an exit (Arrow) zone. Unless it's also pointing at an object
+ // within the zone, in which case the object gets precedence
+ _exitZone = -1;
+ if (_arrowZone != -1 && events._released)
+ _exitZone = _arrowZone;
+
+ // Turn any Text display off
+ if (_arrowZone == -1 || events._rightReleased)
+ freeMenu();
+
+ if (_personFound) {
+ if (people[_bgFound - 1000]._description.empty() || people[_bgFound - 1000]._description.hasPrefix(" "))
+ noDesc = true;
+ } else if (_bgFound != -1) {
+ if (_bgShape->_description.empty() || _bgShape->_description.hasPrefix(" "))
+ noDesc = true;
+ } else {
+ noDesc = true;
+ }
+
+ if (events._rightReleased) {
+ // Show the verbs menu for the highlighted object
+ _tooltipWidget.banishWindow();
+ _verbsWidget.load(!noDesc);
+ _verbsWidget.summonWindow();
+
+ _selector = _oldSelector = -1;
+ _activeObj = _bgFound;
+ _menuMode = VERB_MODE;
+ } else if (_personFound || (_bgFound != -1 && _bgFound < 1000 && _bgShape->_aType == PERSON)) {
+ // The object found is a person (the default for people is TALK)
+ talk.talk(_bgFound);
+ _activeObj = -1;
+ } else if (!noDesc) {
+ // Either call the code to Look at it's Examine Field or call the Exit animation
+ // if the object is an exit, specified by the first four characters of the name being "EXIT"
+ Common::String name = _personFound ? people[_bgFound - 1000]._name : _bgShape->_name;
+ if (!name.hasPrefix("EXIT")) {
+ lookAtObject();
+ } else {
+ // Run the Exit animation and set which scene to go to next
+ for (int idx = 0; idx < 6; ++idx) {
+ if (!_bgShape->_use[idx]._verb.compareToIgnoreCase("Open")) {
+ checkAction(_bgShape->_use[idx], _bgFound);
+ _activeObj = -1;
+ }
+ }
+ }
+ } else {
+ // See if there are any Script Zones where they clicked
+ if (scene.checkForZones(mousePos, _scriptZone) != 0) {
+ // Mouse click in a script zone
+ events._pressed = events._released = false;
+ } else if (scene.checkForZones(mousePos, NOWALK_ZONE) != 0) {
+ events._pressed = events._released = false;
+ } else {
+ // Walk to where the mouse was clicked
+ people[HOLMES]._walkDest = mousePos;
+ people[HOLMES].goAllTheWay();
+ }
+ }
+ }
+}
+
+void TattooUserInterface::doLookControl() {
+ Events &events = *_vm->_events;
+ TattooScene &scene = *(TattooScene *)_vm->_scene;
+ Sound &sound = *_vm->_sound;
+
+ // See if a mouse button was released or a key pressed, and we want to initiate an action
+ // TODO: Not sure about _soundOn.. should be check for speaking voice for text being complete
+ if (events._released || events._rightReleased || _keyState.keycode || (sound._voices && !sound._soundOn)) {
+ // See if we were looking at an inventory object
+ if (!_invLookFlag) {
+ // See if there is any more text to display
+ if (!_textWidget._remainingText.empty()) {
+ printObjectDesc(_textWidget._remainingText, false);
+ } else {
+ // Otherwise restore the background and go back into STD_MODE
+ freeMenu();
+ _key = -1;
+ _menuMode = scene._labTableScene ? LAB_MODE : STD_MODE;
+
+ events.setCursor(ARROW);
+ events._pressed = events._released = events._rightReleased = false;
+ events._oldButtons = 0;
+ }
+ } else {
+ // We were looking at a Inventory object
+ // Erase the text window, and then redraw the inventory window
+ _textWidget.banishWindow();
+ doInventory(0);
+
+ _invLookFlag = false;
+ _key = -1;
+
+ events.setCursor(ARROW);
+ events._pressed = events._released = events._rightReleased = false;
+ events._oldButtons = 0;
+ }
+ }
+}
+
+void TattooUserInterface::doFileControl() {
+ warning("TODO: ui control (file)");
+}
+
+void TattooUserInterface::displayObjectNames() {
+ Events &events = *_vm->_events;
+ Scene &scene = *_vm->_scene;
+ Common::Point mousePos = events.mousePos();
+ _arrowZone = -1;
+
+ if (_bgFound == -1 || scene._currentScene == 90) {
+ for (uint idx = 0; idx < scene._exits.size() && _arrowZone == -1; ++idx) {
+ Exit &exit = scene._exits[idx];
+ if (exit.contains(mousePos))
+ _arrowZone = idx;
+ }
+ }
+
+ _tooltipWidget.handleEvents();
+ _oldArrowZone = _arrowZone;
+}
+
+void TattooUserInterface::initFileMenu() {
+ // TODO
+}
+
+void TattooUserInterface::doInventory(int mode) {
+ People &people = *_vm->_people;
+ people[HOLMES].gotoStand();
+
+ _inventoryWidget.load(mode);
+ _inventoryWidget.summonWindow();
+
+ _menuMode = INV_MODE;
+}
+
+void TattooUserInterface::doControls() {
+ // TODO
+}
+
+void TattooUserInterface::pickUpObject(int objNum) {
+ // TOOD
+}
+
+void TattooUserInterface::doQuitMenu() {
+ // TODO
+}
+
+void TattooUserInterface::putMessage(const char *formatStr, ...) {
+ // Create the string to display
+ va_list args;
+ va_start(args, formatStr);
+ Common::String str = Common::String::vformat(formatStr, args);
+ va_end(args);
+
+ // Open the message widget
+ _menuMode = MESSAGE_MODE;
+ _messageWidget.load(str, 25);
+ _messageWidget.summonWindow();
+}
+
+void TattooUserInterface::setupBGArea(const byte cMap[PALETTE_SIZE]) {
+ Scene &scene = *_vm->_scene;
+
+ // This requires that there is a 16 grayscale palette sequence in the palette that goes from lighter
+ // to darker as the palette numbers go up. The last palette entry in that run is specified by _bgColor
+ byte *p = &_lookupTable[0];
+ for (int idx = 0; idx < PALETTE_COUNT; ++idx)
+ *p++ = BG_GREYSCALE_RANGE_END - ((cMap[idx * 3] / 4) * 30 + (cMap[idx * 3 + 1] / 4) * 59 +
+ (cMap[idx * 3 + 2] / 4) * 11) / 480;
+
+ // If we're going to a scene with a haze special effect, initialize the translate table to lighten the colors
+ if (_mask != nullptr) {
+ p = &_lookupTable1[0];
+
+ for (int idx = 0; idx < PALETTE_COUNT; ++idx) {
+ int r, g, b;
+ switch (scene._currentScene) {
+ case 8:
+ r = cMap[idx * 3] * 4 / 5;
+ g = cMap[idx * 3 + 1] * 3 / 4;
+ b = cMap[idx * 3 + 2] * 3 / 4;
+ break;
+
+ case 18:
+ case 68:
+ r = cMap[idx * 3] * 4 / 3;
+ g = cMap[idx * 3 + 1] * 4 / 3;
+ b = cMap[idx * 3 + 2] * 4 / 3;
+ break;
+
+ case 7:
+ case 53:
+ r = cMap[idx * 3] * 4 / 3;
+ g = cMap[idx * 3 + 1] * 4 / 3;
+ b = cMap[idx * 3 + 2] * 4 / 3;
+ break;
+
+ default:
+ r = g = b = 0;
+ break;
+ }
+
+ byte c = 0;
+ int cd = (r - cMap[0]) * (r - cMap[0]) + (g - cMap[1]) * (g - cMap[1]) + (b - cMap[2]) * (b - cMap[2]);
+
+ for (int pal = 0; pal < PALETTE_COUNT; ++pal) {
+ int d = (r - cMap[pal * 3]) * (r - cMap[pal * 3]) + (g - cMap[pal * 3 + 1]) * (g - cMap[pal * 3 + 1])
+ + (b - cMap[pal * 3 + 2])*(b - cMap[pal * 3 + 2]);
+
+ if (d < cd) {
+ c = pal;
+ cd = d;
+ if (!d)
+ break;
+ }
+ }
+ *p++ = c;
+ }
+ }
+}
+
+void TattooUserInterface::doBgAnimEraseBackground() {
+ TattooEngine &vm = *((TattooEngine *)_vm);
+ People &people = *_vm->_people;
+ Scene &scene = *_vm->_scene;
+ Screen &screen = *_vm->_screen;
+
+ static const int16 OFFSETS[16] = { -1, -2, -3, -3, -2, -1, -1, 0, 1, 2, 3, 3, 2, 1, 0, 0 };
+
+ if (_mask != nullptr) {
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+
+ switch (scene._currentScene) {
+ case 7:
+ if (++_maskCounter == 2) {
+ _maskCounter = 0;
+ if (--_maskOffset.x < 0)
+ _maskOffset.x = SHERLOCK_SCREEN_WIDTH - 1;
+ }
+ break;
+
+ case 8:
+ _maskOffset.x += 2;
+ if (_maskOffset.x >= SHERLOCK_SCREEN_WIDTH)
+ _maskOffset.x = 0;
+ break;
+
+ case 18:
+ case 68:
+ ++_maskCounter;
+ if (_maskCounter / 4 >= 16)
+ _maskCounter = 0;
+
+ _maskOffset.x = OFFSETS[_maskCounter / 4];
+ break;
+
+ case 53:
+ if (++_maskCounter == 2) {
+ _maskCounter = 0;
+ if (++_maskOffset.x == screen._backBuffer1.w())
+ _maskOffset.x = 0;
+ }
+ break;
+
+ default:
+ break;
+ }
+ } else {
+ // Standard scene without mask, so call user interface to erase any UI elements as necessary
+ doBgAnimRestoreUI();
+
+ // Restore background for any areas covered by characters and shapes
+ for (int idx = 0; idx < MAX_CHARACTERS; ++idx)
+ screen.restoreBackground(Common::Rect(people[idx]._oldPosition.x, people[idx]._oldPosition.y,
+ people[idx]._oldPosition.x + people[idx]._oldSize.x, people[idx]._oldPosition.y + people[idx]._oldSize.y));
+
+ for (uint idx = 0; idx < scene._bgShapes.size(); ++idx) {
+ Object &obj = scene._bgShapes[idx];
+
+ if ((obj._type == ACTIVE_BG_SHAPE && (obj._maxFrames > 1 || obj._delta.x != 0 || obj._delta.y != 0)) ||
+ obj._type == HIDE_SHAPE || obj._type == REMOVE)
+ screen._backBuffer1.blitFrom(screen._backBuffer2, obj._oldPosition,
+ Common::Rect(obj._oldPosition.x, obj._oldPosition.y, obj._oldPosition.x + obj._oldSize.x,
+ obj._oldPosition.y + obj._oldSize.y));
+ }
+
+ // If credits are active, erase the area they cover
+ if (vm._creditsActive)
+ vm.eraseCredits();
+ }
+
+ for (uint idx = 0; idx < scene._bgShapes.size(); ++idx) {
+ Object &obj = scene._bgShapes[idx];
+
+ if (obj._type == NO_SHAPE && (obj._flags & 1) == 0) {
+ screen._backBuffer1.blitFrom(screen._backBuffer2, obj._position, obj.getNoShapeBounds());
+
+ obj._oldPosition = obj._position;
+ obj._oldSize = obj._noShapeSize;
+ }
+ }
+
+ // Adjust the Target Scroll if needed
+ if ((people[people._walkControl]._position.x / FIXED_INT_MULTIPLIER - screen._currentScroll.x) <
+ (SHERLOCK_SCREEN_WIDTH / 8) && people[people._walkControl]._delta.x < 0) {
+
+ _targetScroll.x = (short)(people[people._walkControl]._position.x / FIXED_INT_MULTIPLIER -
+ SHERLOCK_SCREEN_WIDTH / 8 - 250);
+ if (_targetScroll.x < 0)
+ _targetScroll.x = 0;
+ }
+
+ if ((people[people._walkControl]._position.x / FIXED_INT_MULTIPLIER - screen._currentScroll.x) >
+ (SHERLOCK_SCREEN_WIDTH / 4 * 3) && people[people._walkControl]._delta.x > 0)
+ _targetScroll.x = (short)(people[people._walkControl]._position.x / FIXED_INT_MULTIPLIER -
+ SHERLOCK_SCREEN_WIDTH / 4 * 3 + 250);
+
+ if (_targetScroll.x > _scrollSize)
+ _targetScroll.x = _scrollSize;
+
+ doScroll();
+}
+
+void TattooUserInterface::drawMaskArea(bool mode) {
+ Scene &scene = *_vm->_scene;
+ Screen &screen = *_vm->_screen;
+ int xp = mode ? _maskOffset.x : 0;
+
+ if (_mask != nullptr) {
+ switch (scene._currentScene) {
+ case 7:
+ screen._backBuffer1.maskArea((*_mask)[0], Common::Point(_maskOffset.x - SHERLOCK_SCREEN_WIDTH, 110));
+ screen._backBuffer1.maskArea((*_mask)[0], Common::Point(_maskOffset.x, 110));
+ screen._backBuffer1.maskArea((*_mask)[0], Common::Point(_maskOffset.x + SHERLOCK_SCREEN_WIDTH, 110));
+ break;
+
+ case 8:
+ screen._backBuffer1.maskArea((*_mask)[0], Common::Point(_maskOffset.x - SHERLOCK_SCREEN_WIDTH, 180));
+ screen._backBuffer1.maskArea((*_mask)[0], Common::Point(_maskOffset.x, 180));
+ screen._backBuffer1.maskArea((*_mask)[0], Common::Point(_maskOffset.x + SHERLOCK_SCREEN_WIDTH, 180));
+ if (!_vm->readFlags(880))
+ screen._backBuffer1.maskArea((*_mask1)[0], Common::Point(940, 300));
+ break;
+
+ case 18:
+ screen._backBuffer1.maskArea((*_mask)[0], Common::Point(xp, 203));
+ if (!_vm->readFlags(189))
+ screen._backBuffer1.maskArea((*_mask1)[0], Common::Point(124 + xp, 239));
+ break;
+
+ case 53:
+ screen._backBuffer1.maskArea((*_mask)[0], Common::Point(_maskOffset.x, 110));
+ if (mode)
+ screen._backBuffer1.maskArea((*_mask)[0], Common::Point(_maskOffset.x - SHERLOCK_SCREEN_WIDTH, 110));
+ break;
+
+ case 68:
+ screen._backBuffer1.maskArea((*_mask)[0], Common::Point(xp, 203));
+ screen._backBuffer1.maskArea((*_mask1)[0], Common::Point(124 + xp, 239));
+ break;
+ }
+ }
+}
+
+void TattooUserInterface::makeBGArea(const Common::Rect &r) {
+ Screen &screen = *_vm->_screen;
+
+ for (int yp = r.top; yp < r.bottom; ++yp) {
+ byte *ptr = screen._backBuffer1.getBasePtr(r.left, yp);
+
+ for (int xp = r.left; xp < r.right; ++xp, ++ptr)
+ *ptr = _lookupTable[*ptr];
+ }
+
+ screen.slamRect(r);
+}
+
+void TattooUserInterface::drawDialogRect(Surface &s, const Common::Rect &r, bool raised) {
+ if (raised) {
+ // Draw Left
+ s.vLine(r.left, r.top, r.bottom - 1, INFO_TOP);
+ s.vLine(r.left + 1, r.top, r.bottom - 2, INFO_TOP);
+ // Draw Top
+ s.hLine(r.left + 2, r.top, r.right - 1, INFO_TOP);
+ s.hLine(r.left + 2, r.top + 1, r.right - 2, INFO_TOP);
+ // Draw Right
+ s.vLine(r.right - 1, r.top + 1, r.bottom - 1, INFO_BOTTOM);
+ s.vLine(r.right - 2, r.top + 2, r.bottom - 1, INFO_BOTTOM);
+ // Draw Bottom
+ s.hLine(r.left + 1, r.bottom - 1, r.right - 3, INFO_BOTTOM);
+ s.hLine(r.left + 2, r.bottom - 2, r.right - 3, INFO_BOTTOM);
+
+ } else {
+ // Draw Left
+ s.vLine(r.left, r.top, r.bottom - 1, INFO_BOTTOM);
+ s.vLine(r.left + 1, r.top, r.bottom - 2, INFO_BOTTOM);
+ // Draw Top
+ s.hLine(r.left + 2, r.top, r.right - 1, INFO_BOTTOM);
+ s.hLine(r.left + 2, r.top + 1, r.right - 2, INFO_BOTTOM);
+ // Draw Right
+ s.vLine(r.right - 1, r.top + 1, r.bottom - 1, INFO_TOP);
+ s.vLine(r.right - 2, r.top + 2, r.bottom - 1, INFO_TOP);
+ // Draw Bottom
+ s.hLine(r.left + 1, r.bottom - 1, r.right - 3, INFO_TOP);
+ s.hLine(r.left + 2, r.bottom - 2, r.right - 3, INFO_TOP);
+ }
+}
+
+void TattooUserInterface::banishWindow(bool slideUp) {
+ TattooScene &scene = *(TattooScene *)_vm->_scene;
+ if (!_widgets.empty())
+ _widgets.back()->banishWindow();
+
+ if (scene._labTableScene && !_labWidget.active()) {
+ // In the lab table scene, so ensure
+ _labWidget.summonWindow();
+ _menuMode = LAB_MODE;
+ }
+}
+
+void TattooUserInterface::freeMenu() {
+ for (Common::List<WidgetBase *>::iterator i = _widgets.begin(); i != _widgets.end(); ++i)
+ (*i)->erase();
+ _widgets.clear();
+}
+
+void TattooUserInterface::clearWindow() {
+ banishWindow();
+}
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/tattoo/tattoo_user_interface.h b/engines/sherlock/tattoo/tattoo_user_interface.h
new file mode 100644
index 0000000000..1cefec688d
--- /dev/null
+++ b/engines/sherlock/tattoo/tattoo_user_interface.h
@@ -0,0 +1,229 @@
+/* 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 SHERLOCK_TATTOO_UI_H
+#define SHERLOCK_TATTOO_UI_H
+
+#include "common/scummsys.h"
+#include "common/list.h"
+#include "sherlock/saveload.h"
+#include "sherlock/screen.h"
+#include "sherlock/user_interface.h"
+#include "sherlock/tattoo/widget_inventory.h"
+#include "sherlock/tattoo/widget_lab.h"
+#include "sherlock/tattoo/widget_text.h"
+#include "sherlock/tattoo/widget_tooltip.h"
+#include "sherlock/tattoo/widget_verbs.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+#define BUTTON_SIZE 15 // Button width/height
+
+class WidgetBase;
+
+enum ScrollHighlight { SH_NONE = 0, SH_SCROLL_UP = 1, SH_PAGE_UP = 2, SH_THUMBNAIL = 3, SH_PAGE_DOWN = 4, SH_SCROLL_DOWN = 5 };
+
+class TattooUserInterface : public UserInterface {
+ friend class WidgetBase;
+private:
+ int _lockoutTimer;
+ SaveMode _fileMode;
+ int _scriptZone;
+ int _cAnimFramePause;
+ WidgetInventory _inventoryWidget;
+ WidgetMessage _messageWidget;
+ Common::List<WidgetBase *> _widgets;
+ byte _lookupTable[PALETTE_COUNT];
+ byte _lookupTable1[PALETTE_COUNT];
+private:
+ /**
+ * Handle any input when we're in standard mode (with no windows open)
+ */
+ void doStandardControl();
+
+ /**
+ * Handle input when in look mode
+ */
+ void doLookControl();
+
+ /**
+ * Handle input when the File window is open
+ */
+ void doFileControl();
+
+ /**
+ * Handle input while the verb menu is open
+ */
+ void doVerbControl();
+
+ /**
+ * Set up to display the Files menu
+ */
+ void initFileMenu();
+
+ /**
+ * Handle displaying the quit menu
+ */
+ void doQuitMenu();
+
+ /**
+ * Free any active menu
+ */
+ void freeMenu();
+public:
+ Common::Point _targetScroll;
+ int _scrollSize, _scrollSpeed;
+ bool _drawMenu;
+ int _arrowZone, _oldArrowZone;
+ Object *_bgShape;
+ bool _personFound;
+ int _activeObj;
+ Common::KeyState _keyState;
+ Common::Point _lookPos;
+ ScrollHighlight _scrollHighlight;
+ ImageFile *_mask, *_mask1;
+ Common::Point _maskOffset;
+ int _maskCounter;
+ ImageFile *_interfaceImages;
+ WidgetText _textWidget;
+ WidgetLab _labWidget;
+ WidgetVerbs _verbsWidget;
+ WidgetSceneTooltip _tooltipWidget;
+public:
+ TattooUserInterface(SherlockEngine *vm);
+ virtual ~TattooUserInterface();
+
+ /**
+ * Handles restoring any areas of the back buffer that were/are covered by UI elements
+ */
+ void doBgAnimRestoreUI();
+
+ /**
+ * Checks to see if the screen needs to be scrolled. If so, scrolls it towards the target position
+ */
+ void doScroll();
+
+ /**
+ * Initializes scroll variables
+ */
+ void initScrollVars();
+
+ /**
+ * Display the long description for an object in a window
+ */
+ void lookAtObject();
+
+ /**
+ * Display the passed long description for an object. If the flag firstTime is set,
+ * the window will be opened to accomodate the text. Otherwise, the remaining text
+ * will be printed in an already open window
+ */
+ void printObjectDesc(const Common::String &str, bool firstTime);
+
+ /**
+ * Handles displaying the journal
+ */
+ void doJournal();
+
+ /**
+ * Put the game in inventory mode by opening the inventory dialog
+ */
+ void doInventory(int mode);
+
+ /**
+ * Handle the display of the options/setup menu
+ */
+ void doControls();
+
+ /**
+ * Pick up the selected object
+ */
+ void pickUpObject(int objNum);
+
+ /**
+ * This will display a text message in a dialog at the bottom of the screen
+ */
+ void putMessage(const char *formatStr, ...) GCC_PRINTF(2, 3);
+
+ /**
+ * Makes a greyscale translation table for each palette entry in the table
+ */
+ void setupBGArea(const byte cMap[PALETTE_SIZE]);
+
+ /**
+ * Erase any background as needed before drawing frame
+ */
+ void doBgAnimEraseBackground();
+
+ void drawMaskArea(bool mode);
+
+ /**
+ * Translate a given area of the back buffer to greyscale shading
+ */
+ void makeBGArea(const Common::Rect &r);
+
+ /**
+ * Draws all the dialog rectangles for any items that need them
+ */
+ void drawDialogRect(Surface &s, const Common::Rect &r, bool raised);
+
+ /**
+ * If the mouse cursor is point at the cursor, then display the name of the object on the screen.
+ * If there is no object being pointed it, clear any previously displayed name
+ */
+ void displayObjectNames();
+public:
+ /**
+ * Resets the user interface
+ */
+ virtual void reset();
+
+ /**
+ * Main input handler for the user interface
+ */
+ virtual void handleInput();
+
+ /**
+ * Draw the user interface onto the screen's back buffers
+ */
+ virtual void drawInterface(int bufferNum = 3);
+
+ /**
+ * Clear any active text window
+ */
+ virtual void clearWindow();
+
+ /**
+ * Banish any active window
+ * @remarks Tattoo doesn't use sliding windows, but the parameter is in the base
+ * UserInterface class as a convenience for Scalpel UI code
+ */
+ virtual void banishWindow(bool slideUp = true);
+};
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/tattoo/widget_base.cpp b/engines/sherlock/tattoo/widget_base.cpp
new file mode 100644
index 0000000000..9d95fed9bf
--- /dev/null
+++ b/engines/sherlock/tattoo/widget_base.cpp
@@ -0,0 +1,299 @@
+/* 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 "sherlock/tattoo/widget_base.h"
+#include "sherlock/tattoo/tattoo.h"
+#include "sherlock/tattoo/tattoo_talk.h"
+#include "sherlock/tattoo/tattoo_user_interface.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+WidgetBase::WidgetBase(SherlockEngine *vm) : _vm(vm) {
+ _scroll = false;
+}
+
+void WidgetBase::summonWindow() {
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+
+ // Double-check that the same widget isn't added twice
+ for (Common::List<WidgetBase *>::iterator i = ui._widgets.begin(); i != ui._widgets.end(); ++i) {
+ if ((*i) == this)
+ error("Tried to add a widget twice");
+ }
+
+ // Add widget to the screen
+ ui._widgets.push_back(this);
+ _outsideMenu = false;
+
+ draw();
+}
+
+void WidgetBase::banishWindow() {
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+
+ erase();
+ _surface.free();
+ ui._widgets.remove(this);
+}
+
+bool WidgetBase::active() const {
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+ for (Common::List<WidgetBase *>::iterator i = ui._widgets.begin(); i != ui._widgets.end(); ++i) {
+ if ((*i) == this)
+ return true;
+ }
+
+ return false;
+}
+
+
+void WidgetBase::erase() {
+ Screen &screen = *_vm->_screen;
+
+ if (_oldBounds.width() > 0) {
+ // Restore the affected area from the secondary back buffer into the first one, and then copy to screen
+ screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(_oldBounds.left, _oldBounds.top), _oldBounds);
+ screen.slamRect(_oldBounds);
+
+ // Reset the old bounds so it won't be erased again
+ _oldBounds = Common::Rect(0, 0, 0, 0);
+ }
+}
+
+void WidgetBase::draw() {
+ Screen &screen = *_vm->_screen;
+
+ // If there was a previously drawn frame in a different position that hasn't yet been erased, then erase it
+ if (_oldBounds.width() > 0 && _oldBounds != _bounds)
+ erase();
+
+ if (_bounds.width() > 0 && !_surface.empty()) {
+ // Get the area to draw, adjusted for scroll position
+ restrictToScreen();
+
+ // Draw the background for the widget
+ drawBackground();
+
+ // Draw the widget onto the back buffer and then slam it to the screen
+ screen._backBuffer1.transBlitFrom(_surface, Common::Point(_bounds.left, _bounds.top));
+ screen.slamRect(_bounds);
+
+ // Store a copy of the drawn area for later erasing
+ _oldBounds = _bounds;
+ }
+}
+
+void WidgetBase::drawBackground() {
+ TattooEngine &vm = *(TattooEngine *)_vm;
+ Screen &screen = *_vm->_screen;
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+
+ Common::Rect bounds = _bounds;
+
+ if (vm._transparentMenus) {
+ ui.makeBGArea(bounds);
+ } else {
+ bounds.grow(-3);
+ screen._backBuffer1.fillRect(bounds, MENU_BACKGROUND);
+ }
+}
+
+Common::String WidgetBase::splitLines(const Common::String &str, Common::StringArray &lines, int maxWidth, uint maxLines) {
+ Talk &talk = *_vm->_talk;
+ const char *strP = str.c_str();
+
+ // Loop counting up lines
+ lines.clear();
+ do {
+ int width = 0;
+ const char *spaceP = nullptr;
+ const char *lineStartP = strP;
+
+ // Find how many characters will fit on the next line
+ while (width < maxWidth && *strP && ((byte)*strP < talk._opcodes[OP_SWITCH_SPEAKER] ||
+ (byte)*strP == talk._opcodes[OP_NULL])) {
+ width += _surface.charWidth(*strP);
+
+ // Keep track of the last space
+ if (*strP == ' ')
+ spaceP = strP;
+ ++strP;
+ }
+
+ // If the line was too wide to fit on a single line, go back to the last space
+ // if there was one, or otherwise simply break the line at this point
+ if (width >= maxWidth && spaceP != nullptr)
+ strP = spaceP;
+
+ // Add the line to the output array
+ lines.push_back(Common::String(lineStartP, strP));
+
+ // Move the string ahead to the next line
+ if (*strP == ' ' || *strP == 13)
+ ++strP;
+ } while (*strP && (lines.size() < maxLines) && ((byte)*strP < talk._opcodes[OP_SWITCH_SPEAKER]
+ || (byte)*strP == talk._opcodes[OP_NULL]));
+
+ // Return any remaining text left over
+ return *strP ? Common::String(strP) : Common::String();
+}
+
+void WidgetBase::restrictToScreen() {
+ Screen &screen = *_vm->_screen;
+
+ if (_bounds.left < screen._currentScroll.x)
+ _bounds.moveTo(screen._currentScroll.x, _bounds.top);
+ if (_bounds.top < 0)
+ _bounds.moveTo(_bounds.left, 0);
+ if (_bounds.right > screen._backBuffer1.w())
+ _bounds.moveTo(screen._backBuffer1.w() - _bounds.width(), _bounds.top);
+ if (_bounds.bottom > screen._backBuffer1.h())
+ _bounds.moveTo(_bounds.left, screen._backBuffer1.h() - _bounds.height());
+}
+
+void WidgetBase::makeInfoArea(Surface &s) {
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+ ImageFile &images = *ui._interfaceImages;
+
+ // Draw the four corners of the Info Box
+ s.transBlitFrom(images[0], Common::Point(0, 0));
+ s.transBlitFrom(images[1], Common::Point(s.w() - images[1]._width, 0));
+ s.transBlitFrom(images[2], Common::Point(0, s.h() - images[2]._height));
+ s.transBlitFrom(images[3], Common::Point(s.w() - images[3]._width, s.h()));
+
+ // Draw the top of the Info Box
+ s.hLine(images[0]._width, 0, s.w() - images[1]._width, INFO_TOP);
+ s.hLine(images[0]._width, 1, s.w() - images[1]._width, INFO_MIDDLE);
+ s.hLine(images[0]._width, 2, s.w() - images[1]._width, INFO_BOTTOM);
+
+ // Draw the bottom of the Info Box
+ s.hLine(images[0]._width, s.h()- 3, s.w() - images[1]._width, INFO_TOP);
+ s.hLine(images[0]._width, s.h()- 2, s.w() - images[1]._width, INFO_MIDDLE);
+ s.hLine(images[0]._width, s.h()- 1, s.w() - images[1]._width, INFO_BOTTOM);
+
+ // Draw the left Side of the Info Box
+ s.vLine(0, images[0]._height, s.h()- images[2]._height, INFO_TOP);
+ s.vLine(1, images[0]._height, s.h()- images[2]._height, INFO_MIDDLE);
+ s.vLine(2, images[0]._height, s.h()- images[2]._height, INFO_BOTTOM);
+
+ // Draw the right Side of the Info Box
+ s.vLine(s.w() - 3, images[0]._height, s.h()- images[2]._height, INFO_TOP);
+ s.vLine(s.w() - 2, images[0]._height, s.h()- images[2]._height, INFO_MIDDLE);
+ s.vLine(s.w() - 1, images[0]._height, s.h()- images[2]._height, INFO_BOTTOM);
+}
+
+void WidgetBase::makeInfoArea() {
+ makeInfoArea(_surface);
+}
+
+void WidgetBase::checkTabbingKeys(int numOptions) {
+}
+
+void WidgetBase::drawScrollBar(int index, int pageSize, int count) {
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+ bool raised;
+
+ // Fill the area with transparency
+ Common::Rect r(BUTTON_SIZE, _bounds.height() - 6);
+ r.moveTo(_bounds.width() - BUTTON_SIZE - 3, 3);
+ _surface.fillRect(r, TRANSPARENCY);
+
+ raised = ui._scrollHighlight != 1;
+ _surface.fillRect(Common::Rect(r.left + 2, r.top + 2, r.right - 2, r.top + BUTTON_SIZE - 2), INFO_MIDDLE);
+ ui.drawDialogRect(_surface, Common::Rect(r.left, r.top, r.left + BUTTON_SIZE, r.top + BUTTON_SIZE), raised);
+
+ raised = ui._scrollHighlight != 5;
+ _surface.fillRect(Common::Rect(r.left + 2, r.bottom - BUTTON_SIZE + 2, r.right - 2, r.bottom - 2), INFO_MIDDLE);
+ ui.drawDialogRect(_surface, Common::Rect(r.left, r.bottom - BUTTON_SIZE, r.right, r.bottom), raised);
+
+ // Draw the arrows on the scroll buttons
+ byte color = index ? INFO_BOTTOM + 2 : INFO_BOTTOM;
+ _surface.hLine(r.right / 2, r.top - 2 + BUTTON_SIZE / 2, r.right / 2, color);
+ _surface.fillRect(Common::Rect(r.right / 2 - 1, r.top - 1 + BUTTON_SIZE / 2,
+ r.right / 2 + 1, r.top - 1 + BUTTON_SIZE / 2), color);
+ _surface.fillRect(Common::Rect(r.right / 2 - 2, r.top + BUTTON_SIZE / 2,
+ r.right / 2 + 2, r.top + BUTTON_SIZE / 2), color);
+ _surface.fillRect(Common::Rect(r.right / 2 - 3, r.top + 1 + BUTTON_SIZE / 2,
+ r.right / 2 + 3, r.top + 1 + BUTTON_SIZE / 2), color);
+
+ color = (index + pageSize) < count ? INFO_BOTTOM + 2 : INFO_BOTTOM;
+ _surface.fillRect(Common::Rect(r.right / 2 - 3, r.bottom - 1 - BUTTON_SIZE + BUTTON_SIZE / 2,
+ r.right / 2 + 3, r.bottom - 1 - BUTTON_SIZE + BUTTON_SIZE / 2), color);
+ _surface.fillRect(Common::Rect(r.right / 2 - 2, r.bottom - 1 - BUTTON_SIZE + 1 + BUTTON_SIZE / 2,
+ r.right / 2 + 2, r.bottom - 1 - BUTTON_SIZE + 1 + BUTTON_SIZE / 2), color);
+ _surface.fillRect(Common::Rect(r.right / 2 - 1, r.bottom - 1 - BUTTON_SIZE + 2 + BUTTON_SIZE / 2,
+ r.right / 2 + 1, r.bottom - 1 - BUTTON_SIZE + 2 + BUTTON_SIZE / 2), color);
+ _surface.fillRect(Common::Rect(r.right / 2, r.bottom - 1 - BUTTON_SIZE + 3 + BUTTON_SIZE / 2,
+ r.right / 2, r.bottom - 1 - BUTTON_SIZE + 3 + BUTTON_SIZE / 2), color);
+
+ // Draw the scroll position bar
+ int barHeight = (_bounds.height() - BUTTON_SIZE * 2) * pageSize / count;
+ barHeight = CLIP(barHeight, BUTTON_SIZE, _bounds.height() - BUTTON_SIZE * 2);
+ int barY = (r.height() - BUTTON_SIZE * 2 - barHeight) * index / pageSize + r.top + BUTTON_SIZE;
+
+ _surface.fillRect(Common::Rect(r.left + 2, barY + 2, r.right - 2, barY + barHeight - 3), INFO_MIDDLE);
+ ui.drawDialogRect(_surface, Common::Rect(r.left, barY, r.right, barY + barHeight), true);
+}
+
+void WidgetBase::handleScrollbarEvents(int index, int pageSize, int count) {
+ Events &events = *_vm->_events;
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+ Common::Point mousePos = events.mousePos();
+
+ // If they have selected the sollbar, return with the Scroll Bar Still selected
+ if (ui._scrollHighlight == 3)
+ return;
+
+ ui._scrollHighlight = SH_NONE;
+
+ if ((!events._pressed && !events._rightReleased) || !_scroll)
+ return;
+
+ Common::Rect r(_bounds.right - BUTTON_SIZE - 3, _bounds.top + 3, _bounds.right - 3, _bounds.bottom - 3);
+
+ // Calculate the Scroll Position bar
+ int barHeight = (_bounds.height() - BUTTON_SIZE * 2) * pageSize / count;
+ barHeight = CLIP(barHeight, BUTTON_SIZE, _bounds.height() - BUTTON_SIZE * 2);
+ int barY = (r.height() - BUTTON_SIZE * 2 - barHeight) * index / pageSize + r.top + BUTTON_SIZE;
+
+ if (Common::Rect(r.left, r.top, r.right, r.top + BUTTON_SIZE).contains(mousePos))
+ // Mouse on scroll up button
+ ui._scrollHighlight = SH_SCROLL_UP;
+ else if (Common::Rect(r.left, r.top + BUTTON_SIZE, r.right, barY).contains(mousePos))
+ // Mouse on paging up area (the area of the vertical bar above the thumbnail)
+ ui._scrollHighlight = SH_PAGE_UP;
+ else if (Common::Rect(r.left, barY, r.right, barY + barHeight).contains(mousePos))
+ // Mouse on scrollbar thumb
+ ui._scrollHighlight = SH_THUMBNAIL;
+ else if (Common::Rect(r.left, barY + barHeight, r.right, r.bottom - BUTTON_SIZE).contains(mousePos))
+ // Mouse on paging down area (the area of the vertical bar below the thumbnail)
+ ui._scrollHighlight = SH_PAGE_DOWN;
+ else if (Common::Rect(r.left, r.bottom - BUTTON_SIZE, r.right, r.bottom).contains(mousePos))
+ // Mouse on scroll down button
+ ui._scrollHighlight = SH_SCROLL_DOWN;
+}
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/tattoo/widget_base.h b/engines/sherlock/tattoo/widget_base.h
new file mode 100644
index 0000000000..fcf22cee8e
--- /dev/null
+++ b/engines/sherlock/tattoo/widget_base.h
@@ -0,0 +1,125 @@
+/* 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 SHERLOCK_TATTOO_WIDGET_BASE_H
+#define SHERLOCK_TATTOO_WIDGET_BASE_H
+
+#include "common/scummsys.h"
+#include "common/rect.h"
+#include "common/str-array.h"
+#include "sherlock/surface.h"
+
+namespace Sherlock {
+
+class SherlockEngine;
+class ImageFile;
+
+namespace Tattoo {
+
+class WidgetBase {
+protected:
+ SherlockEngine *_vm;
+ Common::Rect _bounds;
+ Common::Rect _oldBounds;
+ Surface _surface;
+ bool _outsideMenu;
+ bool _scroll;
+
+ /**
+ * Used by descendent classes to split up long text for display across multiple lines
+ */
+ Common::String splitLines(const Common::String &str, Common::StringArray &lines, int maxWidth, uint maxLines);
+
+ /**
+ * Ensure that menu is drawn entirely on-screen
+ */
+ void restrictToScreen();
+
+ /**
+ * Draw a window frame around the dges of the passed surface
+ */
+ void makeInfoArea(Surface &s);
+
+ /**
+ * Draw a window frame around the widget's surface
+ */
+ void makeInfoArea();
+
+ /**
+ * Draw the scrollbar for the dialog
+ */
+ void drawScrollBar(int index, int pageSize, int count);
+
+ /**
+ * Handles any events when the mouse is on the scrollbar
+ */
+ void handleScrollbarEvents(int index, int pageSize, int count);
+
+ /**
+ * Handle drawing the background on the area the widget is going to cover
+ */
+ virtual void drawBackground();
+public:
+ WidgetBase(SherlockEngine *vm);
+ virtual ~WidgetBase() {}
+
+ /**
+ * Returns true if the given widget is active in the user interface's widget list
+ */
+ bool active() const;
+
+ /**
+ * Erase any previous display of the widget on the screen
+ */
+ virtual void erase();
+
+ /**
+ * Update the display of the widget on the screen
+ */
+ virtual void draw();
+
+ /**
+ * Used by some descendents to check for keys to mouse the mouse within the dialog
+ */
+ void checkTabbingKeys(int numOptions);
+
+ /**
+ * Summon the window
+ */
+ virtual void summonWindow();
+
+ /**
+ * Close a currently active menu
+ */
+ virtual void banishWindow();
+
+ /**
+ * Handle event processing
+ */
+ virtual void handleEvents() {}
+};
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/tattoo/widget_inventory.cpp b/engines/sherlock/tattoo/widget_inventory.cpp
new file mode 100644
index 0000000000..170fb02481
--- /dev/null
+++ b/engines/sherlock/tattoo/widget_inventory.cpp
@@ -0,0 +1,762 @@
+/* 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 "sherlock/tattoo/widget_inventory.h"
+#include "sherlock/tattoo/tattoo_fixed_text.h"
+#include "sherlock/tattoo/tattoo_people.h"
+#include "sherlock/tattoo/tattoo_scene.h"
+#include "sherlock/tattoo/tattoo_user_interface.h"
+#include "sherlock/tattoo/tattoo.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+#define INVENTORY_XSIZE 70 // Width of the box that surrounds inventory items
+#define INVENTORY_YSIZE 70 // Height of the box that surrounds inventory items
+#define MAX_INV_COMMANDS 10 // Maximum elements in dialog
+
+WidgetInventoryTooltip::WidgetInventoryTooltip(SherlockEngine *vm, WidgetInventory *owner) :
+ WidgetTooltipBase(vm), _owner(owner) {
+}
+
+void WidgetInventoryTooltip::setText(const Common::String &str) {
+ // If no text specified, erase any previously displayed tooltip and free it's surface
+ if (str.empty()) {
+ erase();
+ _surface.free();
+ return;
+ }
+
+ int width = _surface.stringWidth(str) + 2;
+ int height = 0;
+ Common::String line1 = str, line2;
+
+ // See if we need to split it into two lines
+ if (width > 150) {
+ // Yes, we do
+ const char *s = str.c_str();
+ const char *space = nullptr;
+ int dif = 10000;
+
+ while (*s) {
+ s = strchr(s, ' ');
+
+ if (!s) {
+ if (!space) {
+ height = _surface.stringHeight(str) + 2;
+ } else {
+ line1 = Common::String(str.c_str(), space);
+ line2 = Common::String(space + 1);
+ height = _surface.stringHeight(line1) + _surface.stringHeight(line2) + 4;
+ }
+ break;
+ } else {
+ line1 = Common::String(str.c_str(), s);
+ line2 = Common::String(s + 1);
+ int width1 = _surface.stringWidth(line1);
+ int width2 = _surface.stringWidth(line2);
+
+ if (ABS(width1 - width2) < dif) {
+ // Found a split point that results in less overall width
+ space = s;
+ dif = ABS(width1 - width2);
+ width = MAX(width1, width2);
+ }
+
+ s++;
+ }
+ }
+ } else {
+ height = _surface.stringHeight(str) + 2;
+ }
+
+ // Allocate a fresh surface for the new string
+ _bounds = Common::Rect(width, height);
+ _surface.create(width, height);
+ _surface.fill(TRANSPARENCY);
+
+ if (line2.empty()) {
+ _surface.writeFancyString(str, Common::Point(0, 0), BLACK, INFO_TOP);
+ } else {
+ int xp, yp;
+
+ xp = (_bounds.width() - _surface.stringWidth(line1) - 2) / 2;
+ _surface.writeFancyString(line1, Common::Point(xp, 0), BLACK, INFO_TOP);
+
+ xp = (_bounds.width() - _surface.stringWidth(line2) - 2) / 2;
+ yp = _surface.stringHeight(line2) + 2;
+ _surface.writeFancyString(line2, Common::Point(xp, yp), BLACK, INFO_TOP);
+ }
+}
+
+void WidgetInventoryTooltip::handleEvents() {
+ Events &events = *_vm->_events;
+ FixedText &fixedText = *_vm->_fixedText;
+ Inventory &inv = *_vm->_inventory;
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ Scene &scene = *_vm->_scene;
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+ Common::Point mousePos = events.mousePos();
+ Common::String str;
+ int select = -1, oldSelect = 999;
+ Common::String strWith = fixedText.getText(kFixedText_With);
+ Common::String strUse = fixedText.getText(kFixedText_Use);
+
+ // If we are using an inventory item on an object in the room, display the appropriate text above the mouse cursor
+ if (_owner->_invVerbMode == 3) {
+ select = ui._bgFound;
+ oldSelect = ui._oldBgFound;
+
+ if (select != -1 && (select != oldSelect || (select != -1 && _surface.empty()))) {
+ // See if we're pointing at a shape or a sprite
+ if (select < 1000) {
+ Object &obj = scene._bgShapes[select];
+
+ if (!obj._description.empty() && !obj._description.hasPrefix(" ")) {
+ if (_vm->getLanguage() == Common::GR_GRE) {
+
+ if (!_owner->_swapItems)
+ str = Common::String::format("%s %s %s %s", _owner->_action.c_str(), obj._description.c_str(),
+ inv[_owner->_invSelect]._name.c_str(), _owner->_verb.c_str());
+ else
+ str = Common::String::format("%s %s %s %s", _owner->_action.c_str(), inv[_owner->_invSelect]._name.c_str(),
+ obj._description.c_str(), _owner->_verb.c_str());
+ } else {
+ if (_owner->_swapItems)
+ str = Common::String::format("%s %s %s %s", _owner->_verb.c_str(), obj._description.c_str(), _owner->_action.c_str(),
+ inv[_owner->_invSelect]._name.c_str());
+ else
+ str = Common::String::format("%s %s %s %s", _owner->_verb.c_str(), inv[_owner->_invSelect]._name.c_str(),
+ _owner->_action.c_str(), obj._description.c_str());
+ }
+ }
+ } else {
+ Person &person = people[ui._bgFound - 1000];
+
+ if (!person._description.empty() && !person._description.hasPrefix(" ")) {
+ if (_vm->getLanguage() == Common::GR_GRE) {
+ if (!_owner->_swapItems)
+ str = Common::String::format("%s %s %s %s", _owner->_action.c_str(), person._description.c_str(),
+ inv[_owner->_invSelect]._name.c_str(), _owner->_verb.c_str());
+ else
+ str = Common::String::format("%s %s %s %s", _owner->_action.c_str(), inv[_owner->_invSelect]._name.c_str(),
+ person._description.c_str(), _owner->_verb.c_str());
+ } else {
+
+ if (_owner->_swapItems)
+ str = Common::String::format("%s %s %s %s", _owner->_verb.c_str(), person._description.c_str(),
+ _owner->_action.c_str(), inv[_owner->_invSelect]._name.c_str());
+ else
+ str = Common::String::format("%s %s %s %s", _owner->_verb.c_str(),
+ inv[_owner->_invSelect]._name.c_str(), _owner->_action.c_str(), person._description.c_str());
+ }
+ }
+ }
+ }
+ } else {
+ Common::Rect r = _owner->_bounds;
+ r.grow(-3);
+
+ if (r.contains(mousePos)) {
+ select = (mousePos.x - r.left) / (INVENTORY_XSIZE + 3) + NUM_INVENTORY_SHOWN / 2 *
+ ((mousePos.y - r.top) / (INVENTORY_YSIZE + 3)) + inv._invIndex;
+
+ if (select >= inv._holdings) {
+ select = -1;
+ } else {
+ oldSelect = _owner->_invSelect;
+
+ if (select != _owner->_invSelect || _surface.empty()) {
+
+ if (_owner->_invMode == 1) {
+ // See if we were pointing at a shapre or sprite
+ if (ui._activeObj < 1000) {
+ Object &obj = scene._bgShapes[ui._activeObj];
+
+ if (!obj._description.empty() && !obj._description.hasPrefix(" "))
+ str = Common::String::format("%s %s %s %s", strUse.c_str(), inv[select]._name.c_str(),
+ strWith.c_str(), obj._description.c_str());
+ } else {
+ Person &person = people[ui._activeObj - 1000];
+
+ if (!person._description.empty() && !person._description.hasPrefix(" "))
+ str = Common::String::format("%s %s %s %s", strUse.c_str(), inv[select]._name.c_str(),
+ strWith.c_str(), person._description.c_str());
+ }
+ } else {
+ if (_owner->_invVerbMode == 2)
+ str = Common::String::format("%s %s %s %s", strUse.c_str(), inv[_owner->_invSelect]._name.c_str(),
+ strWith.c_str(), inv[select]._name.c_str());
+ else
+ str = inv[select]._description.c_str();
+ }
+ }
+ }
+ }
+ }
+
+ // See if they are pointing at a different inventory object and we need to
+ // change the graphics of the Text Tag
+ if (select != oldSelect || (select != -1 && _surface.empty())) {
+ // Set the text
+ setText(str);
+
+ if (_owner->_invVerbMode != 3)
+ _owner->_invSelect = select;
+ else
+ ui._oldBgFound = select;
+ } else if (select == -1 && oldSelect != -1) {
+ setText(Common::String());
+ return;
+ }
+
+ if (_owner->_invVerbMode == 3)
+ // Adjust tooltip to be above the inventory item being shown above the standard cursor
+ mousePos.y -= events._hotspotPos.y;
+
+ // Update the position of the tooltip
+ int xs = CLIP(mousePos.x - _bounds.width() / 2, 0, SHERLOCK_SCENE_WIDTH - _bounds.width());
+ int ys = CLIP(mousePos.y - _bounds.height(), 0, SHERLOCK_SCREEN_HEIGHT - _bounds.height());
+ _bounds.moveTo(xs, ys);
+}
+
+/*----------------------------------------------------------------*/
+
+WidgetInventoryVerbs::WidgetInventoryVerbs(SherlockEngine *vm, WidgetInventory *owner) :
+ WidgetBase(vm), _owner(owner) {
+ _invVerbSelect = _oldInvVerbSelect = -1;
+}
+
+void WidgetInventoryVerbs::load() {
+ Events &events = *_vm->_events;
+ Inventory &inv = *_vm->_inventory;
+ People &people = *_vm->_people;
+ Scene &scene = *_vm->_scene;
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+ Common::Point mousePos = events.mousePos();
+
+ // Make the Verb List for this Inventory Item
+ _inventCommands.clear();
+ _inventCommands.push_back(FIXED(Look));
+
+ // Default the Action word to "with"
+ _owner->_action = _vm->getLanguage() == Common::GR_GRE ? "" : FIXED(With);
+
+ // Search all the bgshapes for any matching Target Fields
+ for (uint idx = 0; idx < scene._bgShapes.size(); ++idx) {
+ Object &obj = scene._bgShapes[idx];
+
+ if (obj._type != INVALID && obj._type != HIDDEN) {
+ for (int useNum = 0; useNum < 6; ++useNum) {
+ if (!obj._use[useNum]._verb.hasPrefix("*") &&
+ !obj._use[useNum]._target.compareToIgnoreCase(inv[_owner->_invSelect]._name)) {
+ // Make sure the Verb is not already in the list
+ bool found1 = false;
+ for (uint cmdNum = 0; cmdNum < _inventCommands.size() && !found1; ++cmdNum) {
+ if (!_inventCommands[cmdNum].compareToIgnoreCase(obj._use[useNum]._verb))
+ found1 = true;
+ }
+
+ if (!found1) {
+ _inventCommands.push_back(obj._use[useNum]._verb);
+
+ // Check for any Special Action commands
+ for (int nameNum = 0; nameNum < 4; ++nameNum) {
+ if (!scumm_strnicmp(obj._use[useNum]._names[nameNum].c_str(), "*V", 2)) {
+ if (!scumm_strnicmp(obj._use[useNum]._names[nameNum].c_str(), "*VSWAP", 6))
+ _owner->_swapItems = true;
+ else
+ _owner->_action = Common::String(obj._use[useNum]._names[nameNum].c_str() + 2);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Search the NPCs for matches as well
+ for (int idx = 1; idx < MAX_CHARACTERS; ++idx) {
+ for (int useNum = 0; useNum < 2; ++useNum) {
+ if (!people[idx]._use[useNum]._target.compareToIgnoreCase(inv[_owner->_invSelect]._name) &&
+ !people[idx]._use[useNum]._verb.empty() && !people[idx]._use[useNum]._verb.hasPrefix(" ")) {
+ bool found1 = false;
+ for (uint cmdNum = 0; cmdNum < _inventCommands.size() && !found1; ++cmdNum) {
+ if (!_inventCommands[cmdNum].compareToIgnoreCase(people[idx]._use[cmdNum]._verb))
+ found1 = true;
+ }
+
+ if (!found1)
+ _inventCommands.push_back(people[idx]._use[useNum]._verb);
+ }
+ }
+ }
+
+ // Finally see if the item itself has a verb
+ if (!inv[_owner->_invSelect]._verb._verb.empty()) {
+ // Don't add "Solve" to the Foolscap if it's already been "Solved"
+ if (inv[_owner->_invSelect]._verb._verb.compareToIgnoreCase(FIXED(Solve)) || !_vm->readFlags(299))
+ _inventCommands.push_back(inv[_owner->_invSelect]._verb._verb);
+ }
+
+ // Now find the widest command in the _inventCommands array
+ int width = 0;
+ for (uint idx = 0; idx < _inventCommands.size(); ++idx)
+ width = MAX(width, _surface.stringWidth(_inventCommands[idx]));
+
+ // Set up bounds for the menu
+ _bounds = Common::Rect(width + _surface.widestChar() * 2 + 6,
+ (_surface.fontHeight() + 7) * _inventCommands.size() + 3);
+ _bounds.moveTo(mousePos.x - _bounds.width() / 2, mousePos.y - _bounds.height() / 2);
+
+ // Create the surface
+ _surface.create(_bounds.width(), _bounds.height());
+ _surface.fill(TRANSPARENCY);
+ makeInfoArea();
+
+ // Draw the Verb commands and the lines separating them
+ ImageFile &images = *ui._interfaceImages;
+ for (int idx = 0; idx < (int)_inventCommands.size(); ++idx) {
+ _surface.writeString(_inventCommands[idx], Common::Point((_bounds.width() -
+ _surface.stringWidth(_inventCommands[idx])) / 2, (_surface.fontHeight() + 7) * idx + 5), INFO_TOP);
+
+ if (idx < (int)_inventCommands.size() - 1) {
+ _surface.vLine(3, (_surface.fontHeight() + 7) * (idx + 1), _bounds.right - 4, INFO_TOP);
+ _surface.vLine(3, (_surface.fontHeight() + 7) * (idx + 1) + 1, _bounds.right - 4, INFO_MIDDLE);
+ _surface.vLine(3, (_surface.fontHeight() + 7) * (idx + 1) + 2, _bounds.right - 4, INFO_BOTTOM);
+
+ _surface.transBlitFrom(images[4], Common::Point(0, (_surface.fontHeight() + 7) * (idx + 1)));
+ _surface.transBlitFrom(images[5], Common::Point(_bounds.width() - images[5]._width,
+ (_surface.fontHeight() + 7) * (idx + 1) - 1));
+ }
+ }
+
+ summonWindow();
+}
+
+void WidgetInventoryVerbs::handleEvents() {
+ Events &events = *_vm->_events;
+ Inventory &inv = *_vm->_inventory;
+ TattooScene &scene = *(TattooScene *)_vm->_scene;
+ Common::Point mousePos = events.mousePos();
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+ TattooEngine &vm = *(TattooEngine *)_vm;
+
+ // Handle changing highlighted verb entry
+ highlightControls();
+
+ // See if they want to close the menu (by clicking outside the menu)
+ Common::Rect innerBounds = _bounds;
+ innerBounds.grow(-3);
+
+ // Flag is they started pressing outside of the menu
+ if (events._firstPress && !_bounds.contains(mousePos))
+ _outsideMenu = true;
+
+ if (events._released || events._rightReleased || ui._keyState.keycode == Common::KEYCODE_ESCAPE) {
+ ui._scrollHighlight = SH_NONE;
+ banishWindow();
+
+ if ((_outsideMenu && !innerBounds.contains(mousePos)) || ui._keyState.keycode == Common::KEYCODE_ESCAPE) {
+ _owner->_invVerbMode = 0;
+ } else if (innerBounds.contains(mousePos)) {
+ _outsideMenu = false;
+
+ // Check if they are trying to solve the Foolscap puzzle, or looking at the completed puzzle
+ bool doHangman = !inv[_owner->_invSelect]._name.compareToIgnoreCase(FIXED(Inv6)) &&
+ !_inventCommands[_invVerbSelect].compareToIgnoreCase(FIXED(Solve));
+ doHangman |= (!inv[_owner->_invSelect]._name.compareToIgnoreCase(FIXED(Inv6)) || !inv[_owner->_invSelect]._name.compareToIgnoreCase(FIXED(Inv7)))
+ && _inventCommands[_invVerbSelect].compareToIgnoreCase(FIXED(Look)) && vm.readFlags(299);
+
+ if (doHangman) {
+ // Close the entire Inventory and return to Standard Mode
+ _owner->_invVerbMode = 0;
+
+ _owner->_tooltipWidget.banishWindow();
+ inv.freeInv();
+
+ events.clearEvents();
+ events.setCursor(ARROW);
+ ui._menuMode = scene._labTableScene ? LAB_MODE : STD_MODE;
+
+ scene.doBgAnim();
+ vm.doHangManPuzzle();
+ } else if (_invVerbSelect == 0) {
+ // They have released the mouse on the Look Verb command, so Look at the inventory item
+ ui._invLookFlag = true;
+ inv.freeInv();
+ ui._windowOpen = false;
+ ui._lookPos = mousePos;
+ ui.printObjectDesc(inv[_owner->_invSelect]._examine, true);
+ } else {
+ _owner->_invVerbMode = 3;
+ ui._oldBgFound = -1;
+
+ // See if the selected Verb with the selected Iventory Item, is to be used by itself
+ if (!_inventCommands[_invVerbSelect].compareToIgnoreCase(inv[_owner->_invSelect]._verb._verb) ||
+ !inv[_owner->_invSelect]._verb._target.compareToIgnoreCase("*SELF")) {
+ inv.freeInv();
+
+ ui._menuMode = scene._labTableScene ? LAB_MODE : STD_MODE;
+ events.clearEvents();
+ ui.checkAction(inv[_owner->_invSelect]._verb, 2000);
+ } else {
+ _owner->_verb = _inventCommands[_invVerbSelect];
+ }
+
+ // If we are still in Inventory Mode, setup the graphic to float in front of the mouse cursor
+ if (ui._menuMode == INV_MODE) {
+ // Add the inventory item to the cursor
+ ImageFrame &imgFrame = (*inv._invShapes[_owner->_invSelect - inv._invIndex])[0];
+ events.setCursor(ARROW, imgFrame._frame);
+
+ // Close the inventory dialog without banishing it, so it can keep getting events
+ // to handle tooltips and actually making the selection of what object to use them item on
+ inv.freeInv();
+ _owner->_surface.free();
+ }
+ }
+ }
+ }
+}
+
+void WidgetInventoryVerbs::highlightControls() {
+ Events &events = *_vm->_events;
+ Common::Point mousePos = events.mousePos();
+
+ Common::Rect innerBounds = _bounds;
+ innerBounds.grow(-3);
+
+ // Set the highlighted verb
+ _invVerbSelect = -1;
+ if (innerBounds.contains(mousePos))
+ _invVerbSelect = (mousePos.y - _bounds.top - 3) / (_surface.fontHeight() + 7);
+
+ // See if the highlighted verb has changed
+ if (_invVerbSelect != _oldInvVerbSelect) {
+ // Draw the list again, with the new highlighting
+ for (int idx = 0; idx < (int)_inventCommands.size(); ++idx) {
+ byte color = (idx == _invVerbSelect) ? COMMAND_HIGHLIGHTED : INFO_TOP;
+ _surface.writeString(_inventCommands[idx], Common::Point(
+ (_bounds.width() - _surface.stringWidth(_inventCommands[idx])) / 2,
+ (_surface.fontHeight() + 7) * idx + 5), color);
+ }
+
+ _oldInvVerbSelect = _invVerbSelect;
+ }
+}
+
+/*----------------------------------------------------------------*/
+
+WidgetInventory::WidgetInventory(SherlockEngine *vm) : WidgetBase(vm),
+ _tooltipWidget(vm, this), _verbList(vm, this) {
+ _invMode = 0;
+ _invVerbMode = 0;
+ _invSelect = _oldInvSelect = -1;
+ _selector = _oldSelector = -1;
+ _dialogTimer = -1;
+ _swapItems = false;
+}
+
+void WidgetInventory::load(int mode) {
+ Events &events = *_vm->_events;
+ Inventory &inv = *_vm->_inventory;
+ Screen &screen = *_vm->_screen;
+ Common::Point mousePos = events.mousePos();
+
+ if (mode == 3) {
+ mode = 2;
+ mousePos = Common::Point(screen._currentScroll.x + SHERLOCK_SCREEN_WIDTH / 2, SHERLOCK_SCREEN_HEIGHT / 2);
+ }
+
+ if (mode != 0)
+ _invMode = mode;
+ _invVerbMode = 0;
+ _invSelect = _oldInvSelect = -1;
+ _selector = _oldSelector = -1;
+ _dialogTimer = -1;
+
+ if (mode == 0) {
+ banishWindow();
+ } else {
+ _bounds = Common::Rect((INVENTORY_XSIZE + 3) * NUM_INVENTORY_SHOWN / 2 + BUTTON_SIZE + 6,
+ (INVENTORY_YSIZE + 3) * 2 + 3);
+ _bounds.moveTo(mousePos.x - _bounds.width() / 2, mousePos.y - _bounds.height() / 2);
+ }
+
+ // Ensure menu will be on-screen
+ restrictToScreen();
+
+ // Load the inventory data
+ inv.loadInv();
+
+ // Redraw the inventory menu on the widget surface
+ _surface.create(_bounds.width(), _bounds.height());
+ _surface.fill(TRANSPARENCY);
+
+ // Draw the window background and then the inventory on top of it
+ makeInfoArea(_surface);
+ drawBars();
+ drawInventory();
+}
+
+void WidgetInventory::drawBars() {
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+ ImageFile &images = *ui._interfaceImages;
+ int x;
+
+ _surface.hLine(3, INVENTORY_YSIZE + 3, _bounds.width() - 4, INFO_TOP);
+ _surface.hLine(3, INVENTORY_YSIZE + 4, _bounds.width() - 4, INFO_MIDDLE);
+ _surface.hLine(3, INVENTORY_YSIZE + 5, _bounds.width() - 4, INFO_BOTTOM);
+ _surface.transBlitFrom(images[4], Common::Point(0, INVENTORY_YSIZE + 2));
+
+ for (int idx = 1; idx <= NUM_INVENTORY_SHOWN / 2; ++idx) {
+ x = idx * (INVENTORY_XSIZE + 3);
+
+ _surface.vLine(x, 3, _bounds.height() - 4, INFO_TOP);
+ _surface.vLine(x + 1, 3, _bounds.height() - 4, INFO_MIDDLE);
+ _surface.vLine(x + 2, 3, _bounds.height() - 4, INFO_BOTTOM);
+
+ _surface.transBlitFrom(images[6], Common::Point(x - 1, 1));
+ _surface.transBlitFrom(images[7], Common::Point(x - 1, _bounds.height() - 4));
+ _surface.transBlitFrom(images[6], Common::Point(x - 1, INVENTORY_YSIZE + 5));
+ _surface.transBlitFrom(images[7], Common::Point(x - 1, INVENTORY_YSIZE + 2));
+ }
+
+ _surface.hLine(x + 2, INVENTORY_YSIZE + 2, INVENTORY_YSIZE + 8, INFO_BOTTOM);
+}
+
+void WidgetInventory::drawInventory() {
+ Inventory &inv = *_vm->_inventory;
+
+ // TODO: Refactor _invIndex into this widget class
+ for (int idx = 0, itemId = inv._invIndex; idx < NUM_INVENTORY_SHOWN; ++idx, ++itemId) {
+ // Figure out the drawing position
+ Common::Point pt(3 + (INVENTORY_XSIZE + 3) * (idx % (NUM_INVENTORY_SHOWN / 2)),
+ 3 + (INVENTORY_YSIZE + 3) * (idx / (NUM_INVENTORY_SHOWN / 2)));
+
+ // Draw the box to serve as the background for the item
+ _surface.hLine(pt.x + 1, pt.y, pt.x + INVENTORY_XSIZE - 2, TRANSPARENCY);
+ _surface.fillRect(Common::Rect(pt.x, pt.y + 1, pt.x + INVENTORY_XSIZE, pt.y + INVENTORY_YSIZE - 1), TRANSPARENCY);
+ _surface.hLine(pt.x + 1, pt.y + INVENTORY_YSIZE - 1, pt.x + INVENTORY_XSIZE - 2, TRANSPARENCY);
+
+ // Draw the item
+ if (itemId < inv._holdings) {
+ ImageFrame &img = (*inv._invShapes[idx])[0];
+ _surface.transBlitFrom(img, Common::Point(pt.x + (INVENTORY_XSIZE - img._width) / 2,
+ pt.y + (INVENTORY_YSIZE - img._height) / 2));
+ }
+ }
+
+ drawScrollBar(inv._invIndex, NUM_INVENTORY_SHOWN, inv._holdings);
+}
+
+void WidgetInventory::handleEvents() {
+ TattooEngine &vm = *(TattooEngine *)_vm;
+ Events &events = *_vm->_events;
+ Inventory &inv = *_vm->_inventory;
+ People &people = *_vm->_people;
+ TattooScene &scene = *(TattooScene *)_vm->_scene;
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+ Common::Point mousePos = events.mousePos();
+
+ if (_invVerbMode == 1)
+ checkTabbingKeys(MAX_INV_COMMANDS);
+ else if (_invVerbMode == 0)
+ checkInvTabbingKeys();
+
+ if (_invVerbMode != 1)
+ _tooltipWidget.handleEvents();
+
+ // Flag is they started pressing outside of the menu
+ if (events._firstPress && !_bounds.contains(mousePos))
+ _outsideMenu = true;
+
+ if (_invVerbMode != 3)
+ highlightControls();
+
+ // See if they released a mouse button button
+ if (events._released || events._rightReleased || ui._keyState.keycode == Common::KEYCODE_ESCAPE) {
+ _dialogTimer = -1;
+ ui._scrollHighlight = SH_NONE;
+
+ // See if they have a Verb List open for an Inventry Item
+ if (_invVerbMode == 1)
+ return;
+
+ if (_invVerbMode == 3) {
+ // Selecting object after inventory verb has been selected
+ _tooltipWidget.banishWindow();
+ close();
+
+ if (ui._keyState.keycode != Common::KEYCODE_ESCAPE) {
+ // If user pointed at an item, use the selected inventory item with this item
+ bool found = false;
+ if (ui._bgFound != -1) {
+ if (ui._personFound) {
+ for (int idx = 0; idx < 2; ++idx) {
+ if (!people[ui._bgFound - 1000]._use[idx]._verb.compareToIgnoreCase(_verb) &&
+ !people[ui._bgFound - 1000]._use[idx]._target.compareToIgnoreCase(_invTarget)) {
+ ui.checkAction(people[ui._bgFound - 1000]._use[idx], ui._bgFound);
+ found = true;
+ }
+ }
+ } else {
+ for (int idx = 0; idx < 6; ++idx) {
+ if (!ui._bgShape->_use[idx]._verb.compareToIgnoreCase(_verb) &&
+ !ui._bgShape->_use[idx]._target.compareToIgnoreCase(_invTarget)) {
+ ui.checkAction(ui._bgShape->_use[idx], ui._bgFound);
+ found = true;
+ }
+ }
+ }
+ }
+
+ if (!found)
+ ui.putMessage("%s", FIXED(NoEffect));
+ }
+ } else if ((_outsideMenu && !_bounds.contains(mousePos)) || ui._keyState.keycode == Common::KEYCODE_ESCAPE) {
+ // Want to close the window (clicked outside of it). So close the window and return to Standard
+ close();
+
+ } else if (_bounds.contains(mousePos)) {
+ // Mouse button was released inside the inventory window
+ _outsideMenu = false;
+
+ // See if they are pointing at one of the inventory items
+ if (_invSelect != -1) {
+ // See if they are in Use Obj with Inv. Mode (they right clicked on an item
+ // in the room and selected "Use with Inv.")
+ if (_invMode == 1) {
+ _tooltipWidget.banishWindow();
+ banishWindow();
+
+ // See if the item in the room that they started with was a person
+ bool found = false;
+ if (ui._activeObj >= 1000) {
+ // Object was a person, activate anything in his two verb fields
+ for (int idx = 0; idx < 2; ++idx) {
+ if (!people[ui._activeObj - 1000]._use[idx]._target.compareToIgnoreCase(inv[_invSelect]._name)) {
+ ui.checkAction(people[ui._activeObj - 1000]._use[idx], ui._activeObj);
+ found = true;
+ }
+ }
+ } else {
+ // Object was a regular object, activate anything in its verb fields
+ for (int idx = 0; idx < 6; ++idx) {
+ if (!scene._bgShapes[ui._activeObj]._use[idx]._target.compareToIgnoreCase(inv[_invSelect]._name)) {
+ ui.checkAction(scene._bgShapes[ui._activeObj]._use[idx], ui._activeObj);
+ found = true;
+ }
+ }
+ }
+ if (!found)
+ ui.putMessage("%s", FIXED(NoEffect));
+
+ } else {
+ // See if they right clicked on an item
+ if (events._rightReleased) {
+ _invVerbMode = 1;
+ _verbList._oldInvVerbSelect = -1;
+ _tooltipWidget.banishWindow();
+
+ // Keep track of the name of the inventory object so we can check it against the target fields
+ // of verbs when we activate it
+ _invTarget = inv[_invSelect]._name;
+ _swapItems = false;
+
+ _verbList.load();
+ } else {
+ // They left clicked on an inventory item, so Look at it
+
+ // Check if they are looking at the solved Foolscap
+ if ((!inv[_invSelect]._name.compareToIgnoreCase(FIXED(Inv6)) || !inv[_invSelect]._name.compareToIgnoreCase(FIXED(Inv7)))
+ && vm.readFlags(299)) {
+ banishWindow();
+ _tooltipWidget.erase();
+
+ _invVerbMode = 0;
+ inv.freeInv();
+
+ events.clearEvents();
+ events.setCursor(ARROW);
+ ui._menuMode = scene._labTableScene ? LAB_MODE : STD_MODE;
+
+ scene.doBgAnim();
+ vm.doHangManPuzzle();
+ } else {
+ ui._invLookFlag = true;
+ inv.freeInv();
+
+ _tooltipWidget.banishWindow();
+ ui._windowOpen = false;
+ ui._lookPos = mousePos;
+ ui.printObjectDesc(inv[_invSelect]._examine, true);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void WidgetInventory::checkInvTabbingKeys() {
+}
+
+void WidgetInventory::highlightControls() {
+ // TODO
+}
+
+void WidgetInventory::banishWindow() {
+ WidgetBase::banishWindow();
+
+ _verbList.banishWindow();
+}
+
+void WidgetInventory::draw() {
+ WidgetBase::draw();
+ _tooltipWidget.draw();
+}
+
+void WidgetInventory::erase() {
+ WidgetBase::erase();
+ _tooltipWidget.erase();
+}
+
+void WidgetInventory::close() {
+ Events &events = *_vm->_events;
+ Inventory &inv = *_vm->_inventory;
+ TattooScene &scene = *(TattooScene *)_vm->_scene;
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+
+ banishWindow();
+ inv.freeInv();
+ events.clearEvents();
+
+ events.setCursor(ARROW);
+ ui._menuMode = scene._labTableScene ? LAB_MODE : STD_MODE;
+}
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/tattoo/widget_inventory.h b/engines/sherlock/tattoo/widget_inventory.h
new file mode 100644
index 0000000000..53bc2038e0
--- /dev/null
+++ b/engines/sherlock/tattoo/widget_inventory.h
@@ -0,0 +1,159 @@
+/* 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 SHERLOCK_TATTOO_WIDGET_INVENTORY_H
+#define SHERLOCK_TATTOO_WIDGET_INVENTORY_H
+
+#include "common/scummsys.h"
+#include "sherlock/tattoo/widget_base.h"
+#include "sherlock/tattoo/widget_tooltip.h"
+
+namespace Sherlock {
+
+class SherlockEngine;
+
+namespace Tattoo {
+
+#define NUM_INVENTORY_SHOWN 8 // Number of Inventory Items Shown
+
+class WidgetInventory;
+
+class WidgetInventoryTooltip: public WidgetTooltipBase {
+private:
+ WidgetInventory *_owner;
+protected:
+ /**
+ * Overriden from base class, since tooltips have a completely transparent background
+ */
+ virtual void drawBackground() {}
+public:
+ WidgetInventoryTooltip(SherlockEngine *vm, WidgetInventory *owner);
+ virtual ~WidgetInventoryTooltip() {}
+
+ /**
+ * Set the text for the tooltip
+ */
+ void setText(const Common::String &str);
+
+ /**
+ * Handle updating the tooltip state
+ */
+ virtual void handleEvents();
+};
+
+class WidgetInventoryVerbs : public WidgetBase {
+private:
+ WidgetInventory *_owner;
+ Common::StringArray _inventCommands;
+
+ void highlightControls();
+public:
+ int _invVerbSelect, _oldInvVerbSelect;
+public:
+ WidgetInventoryVerbs(SherlockEngine *vm, WidgetInventory *owner);
+ virtual ~WidgetInventoryVerbs() {}
+
+ void load();
+
+ /**
+ * Handle updating the tooltip state
+ */
+ virtual void handleEvents();
+};
+
+class WidgetInventory: public WidgetBase {
+ friend class WidgetInventoryTooltip;
+ friend class WidgetInventoryVerbs;
+private:
+ int _invVerbMode;
+ int _selector, _oldSelector;
+ int _invSelect, _oldInvSelect;
+ int _dialogTimer;
+ WidgetInventoryTooltip _tooltipWidget;
+ WidgetInventoryVerbs _verbList;
+ bool _swapItems;
+ Surface _menuSurface;
+ Common::String _invTarget;
+
+ /**
+ * Draw the bars within the dialog
+ */
+ void drawBars();
+
+ /**
+ * Check for keys to mouse the mouse within the inventory dialog
+ */
+ void checkInvTabbingKeys();
+
+ /**
+ * Highlights the controls
+ */
+ void highlightControls();
+public:
+ int _invMode;
+ Common::String _action;
+ Common::String _verb;
+public:
+ WidgetInventory(SherlockEngine *vm);
+ virtual ~WidgetInventory() {}
+
+ /**
+ * Load the inventory window
+ */
+ void load(int mode);
+
+ /**
+ * Draw the inventory on the surface
+ */
+ void drawInventory();
+
+ /**
+ * Close the window
+ */
+ void close();
+
+ /**
+ * Handle events whilst the widget is on-screen
+ */
+ virtual void handleEvents();
+
+ /**
+ * Close a currently active menu
+ */
+ virtual void banishWindow();
+
+ /**
+ * Erase any previous display of the widget on the screen
+ */
+ virtual void erase();
+
+ /**
+ * Update the display of the widget on the screen
+ */
+ virtual void draw();
+};
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/tattoo/widget_lab.cpp b/engines/sherlock/tattoo/widget_lab.cpp
new file mode 100644
index 0000000000..cc0bae0e90
--- /dev/null
+++ b/engines/sherlock/tattoo/widget_lab.cpp
@@ -0,0 +1,193 @@
+/* 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 "sherlock/tattoo/widget_lab.h"
+#include "sherlock/tattoo/tattoo_fixed_text.h"
+#include "sherlock/tattoo/tattoo_user_interface.h"
+#include "sherlock/tattoo/tattoo.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+WidgetLab::WidgetLab(SherlockEngine *vm) : WidgetBase(vm) {
+ _labObject = nullptr;
+}
+
+void WidgetLab::summonWindow() {
+ WidgetBase::summonWindow();
+ _labObject = nullptr;
+}
+
+void WidgetLab::handleEvents() {
+ Events &events = *_vm->_events;
+ Scene &scene = *_vm->_scene;
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+ WidgetBase::handleEvents();
+ bool noDesc = false;
+
+ // Handle drawing tooltips. If the user is dragging a lab item, display a tooltip for using the item
+ // on another. Otherwise, fall back on showing standard tooltips
+ if (events.getCursor() == INVALID_CURSOR)
+ displayLabNames();
+ else
+ ui.displayObjectNames();
+
+ // See if they've released a mouse button to do an action
+ if (events._released || events._rightReleased) {
+ // See if the mouse was released in an exit/arrow zone (ie. the "Exit" button)
+ ui._exitZone = -1;
+ if (ui._arrowZone != -1 && events._released)
+ ui._exitZone = ui._arrowZone;
+
+ // Turn any current tooltip off
+ if (ui._arrowZone == -1 || events._rightReleased)
+ ui._tooltipWidget.setText("");
+
+ if (ui._bgFound != -1) {
+ if (ui._bgShape->_description.hasPrefix(" ") || ui._bgShape->_description.empty())
+ noDesc = true;
+ } else {
+ noDesc = true;
+ }
+
+ if (events._rightReleased) {
+ // If the player is dragging an object around, restore it to its previous location and reset the cursor
+ if (_labObject) {
+ _labObject->toggleHidden();
+
+ // Toggle any other objects (like shadows) tied to this object
+ for (int idx = 0; idx < 6; ++idx) {
+ if (!_labObject->_use[idx]._target.compareToIgnoreCase("Toggle")) {
+ for (int nameNum = 0; nameNum < 4; ++nameNum)
+ scene.toggleObject(_labObject->_use[idx]._names[nameNum]);
+ }
+ }
+
+ events.setCursor(ARROW);
+ }
+
+ // Show the command list for this object
+ ui._verbsWidget.load(!noDesc);
+ } else if (!noDesc) {
+ // The player has released on an object, see if they had an object selected
+ // that will be used with this new object
+ if (_labObject) {
+ // See if the dragged object can be used with the new object
+ for (int idx = 0; idx < 6; ++idx) {
+ // See if the name of the dragged object is in any of the Target
+ // fields of the verbs for the new object
+ if (!_labObject->_name.compareToIgnoreCase(ui._bgShape->_use[idx]._target.c_str())) {
+ // This object can be used, so use it
+ ui.checkAction(ui._bgShape->_use[idx], ui._bgFound);
+ ui._activeObj = -1;
+ }
+ }
+
+ // Restore the dragged object to its previous location
+ _labObject->toggleHidden();
+
+ // Toggle any other objects (like shadows) tied to this object
+ for (int idx = 0; idx < 6; ++idx) {
+ if (!_labObject->_use[idx]._target.compareToIgnoreCase("Toggle")) {
+ for (int nameNum = 0; nameNum < 4; ++nameNum)
+ scene.toggleObject(_labObject->_use[idx]._names[nameNum]);
+ }
+ }
+ } else if (!ui._bgShape->_name.compareToIgnoreCase("Exit")) {
+ // Eexecut the Exit button's script, which will leave the scene
+ ui.lookAtObject();
+ }
+ } else {
+ // The player has released the mouse while NOT over an object. If theu were dragging an object
+ // around with the mouse, restore it to its previous location and reset the cursor
+ if (_labObject) {
+ _labObject->toggleHidden();
+
+ // Toggle any other objects (like shadows) tied to this object
+ for (int idx = 0; idx < 6; ++idx) {
+ if (!_labObject->_use[idx]._target.compareToIgnoreCase("Toggle")) {
+ for (int nameNum = 0; nameNum < 4; ++nameNum)
+ scene.toggleObject(_labObject->_use[idx]._names[nameNum]);
+ }
+ }
+
+ events.setCursor(ARROW);
+ }
+ }
+ } else if (events._pressed) {
+ if (!_labObject) {
+ // If the mouse is over an object and the object is not SOLID, then we need to pick this object
+ // up so the player can move it around
+ if (ui._bgFound != -1) {
+ // Check if the object is set as SOLID, you can't pick up Solid items
+ if (ui._bgShape->_aType != SOLID && ui._bgShape->_type != NO_SHAPE) {
+ // Save a reference to the object about to be dragged
+ _labObject = ui._bgShape;
+
+ // Set the mouse cursor to the object
+ Graphics::Surface &img = _labObject->_imageFrame->_frame;
+ events.setCursor(img, img.w / 2, img.h / 2);
+
+ // Hide this object until they are done with it (releasing it)
+ _labObject->toggleHidden();
+
+ // Toggle any other objects (like shadows) tied to this object
+ for (int idx = 0; idx < 6; ++idx) {
+ if (!_labObject->_use[idx]._target.compareToIgnoreCase("Toggle")) {
+ for (int nameNum = 0; nameNum < 4; ++nameNum)
+ scene.toggleObject(_labObject->_use[idx]._names[nameNum]);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void WidgetLab::displayLabNames() {
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+
+ // See if thay are pointing at a different object and we need to change the tooltip
+ if (ui._bgFound != ui._oldBgFound) {
+ // See if there is a new object to be displayed
+ if (ui._bgFound == -1) {
+ ui._tooltipWidget.setText("");
+ } else {
+ Common::String str = Common::String::format("%s %s %s %s", FIXED(Use), _labObject->_description.c_str(),
+ FIXED(With), ui._bgShape->_description.c_str());
+
+ // Make sure that the Object has a name
+ if (!ui._bgShape->_description.empty() && !ui._bgShape->_description.hasPrefix(" ")) {
+ ui._tooltipWidget.setText(str);
+ } else {
+ ui._tooltipWidget.setText("");
+ }
+ }
+ }
+
+ ui._oldArrowZone = ui._arrowZone;
+}
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/tattoo/widget_lab.h b/engines/sherlock/tattoo/widget_lab.h
new file mode 100644
index 0000000000..2f19200b81
--- /dev/null
+++ b/engines/sherlock/tattoo/widget_lab.h
@@ -0,0 +1,66 @@
+/* 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 SHERLOCK_TATTOO_WIDGET_LAB_H
+#define SHERLOCK_TATTOO_WIDGET_LAB_H
+
+#include "common/scummsys.h"
+#include "sherlock/tattoo/widget_base.h"
+#include "sherlock/objects.h"
+
+namespace Sherlock {
+
+class SherlockEngine;
+
+namespace Tattoo {
+
+class WidgetLab: public WidgetBase {
+private:
+ Object *_labObject;
+
+ /**
+ * Display tooltips of an object being dragged along with any object the dragged
+ * object is currently over
+ */
+ void displayLabNames();
+public:
+ Common::String _remainingText;
+public:
+ WidgetLab(SherlockEngine *vm);
+ virtual ~WidgetLab() {}
+
+ /**
+ * Summon the window
+ */
+ virtual void summonWindow();
+
+ /**
+ * Handle event processing
+ */
+ virtual void handleEvents();
+};
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/tattoo/widget_talk.cpp b/engines/sherlock/tattoo/widget_talk.cpp
new file mode 100644
index 0000000000..5190773dd1
--- /dev/null
+++ b/engines/sherlock/tattoo/widget_talk.cpp
@@ -0,0 +1,529 @@
+/* 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 "sherlock/tattoo/widget_talk.h"
+#include "sherlock/tattoo/tattoo_fixed_text.h"
+#include "sherlock/tattoo/tattoo_journal.h"
+#include "sherlock/tattoo/tattoo_people.h"
+#include "sherlock/tattoo/tattoo_talk.h"
+#include "sherlock/tattoo/tattoo_scene.h"
+#include "sherlock/tattoo/tattoo_user_interface.h"
+#include "sherlock/tattoo/tattoo.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+#define STATEMENT_NUM_X 6
+#define NUM_VISIBLE_TALK_LINES 6
+
+WidgetTalk::WidgetTalk(SherlockEngine *vm) : WidgetBase(vm) {
+ _talkScrollIndex = 0;
+ _selector = _oldSelector = -1;
+ _talkTextX = 0;
+ _dialogTimer = 0;
+}
+
+void WidgetTalk::getTalkWindowSize() {
+ TattooTalk &talk = *(TattooTalk *)_vm->_talk;
+ int width, height;
+
+ // See how many statements are going to be available
+ int numStatements = 0;
+ for (uint idx = 0; idx < talk._statements.size(); ++idx) {
+ if (talk._statements[idx]._talkMap != -1)
+ ++numStatements;
+ }
+
+ width = SHERLOCK_SCREEN_WIDTH * 2 / 3;
+
+ // Split up the questions into separate strings for each line
+ _bounds = Common::Rect(width, 1);
+ setStatementLines();
+
+ // Make sure that the window does not get too big
+ if (_statementLines.size() < 7) {
+ height = (_surface.fontHeight() + 1) * _statementLines.size() + 9;
+ _scroll = false;
+ } else {
+ // Set up the height to a constrained amount, and add extra width for the scrollbar
+ width += BUTTON_SIZE + 3;
+ height = (_surface.fontHeight() + 1) * 6 + 9;
+ _scroll = true;
+ }
+
+ _bounds = Common::Rect(width, height);
+}
+
+void WidgetTalk::load() {
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ TattooScene &scene = *(TattooScene *)_vm->_scene;
+
+ // Figure out the window size
+ getTalkWindowSize();
+
+ // Place the window centered above the player
+ Common::Point pt;
+ int scaleVal = scene.getScaleVal(people[HOLMES]._position);
+ pt.x = people[HOLMES]._position.x / FIXED_INT_MULTIPLIER - _bounds.width() / 2;
+
+ if (scaleVal == SCALE_THRESHOLD) {
+ pt.x += people[0].frameWidth() / 2;
+ pt.y = people[HOLMES]._position.y / FIXED_INT_MULTIPLIER - people[HOLMES].frameHeight()
+ - _bounds.height() - _surface.fontHeight();
+ } else {
+ pt.x += people[HOLMES]._imageFrame->sDrawXSize(scaleVal) / 2;
+ pt.y = people[HOLMES]._position.y / FIXED_INT_MULTIPLIER - people[HOLMES]._imageFrame->sDrawYSize(scaleVal)
+ - _bounds.height() - _surface.fontHeight();
+ }
+
+ _bounds.moveTo(pt);
+
+ // Set up the surface
+ _surface.create(_bounds.width(), _bounds.height());
+ _surface.fill(TRANSPARENCY);
+
+ // Form the background for the new window
+ makeInfoArea();
+}
+
+void WidgetTalk::handleEvents() {
+ Events &events = *_vm->_events;
+ TattooJournal &journal = *(TattooJournal *)_vm->_journal;
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ TattooScene &scene = *(TattooScene *)_vm->_scene;
+ Sound &sound = *_vm->_sound;
+ TattooTalk &talk = *(TattooTalk *)_vm->_talk;
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+ Common::Point mousePos = events.mousePos();
+ Common::KeyCode keycode = ui._keyState.keycode;
+ bool hotkey = false;
+ bool callParrotFile = false;
+
+ // Handle scrollbar events
+ ScrollHighlight oldHighlight = ui._scrollHighlight;
+ handleScrollbarEvents(_talkScrollIndex, NUM_VISIBLE_TALK_LINES, _statementLines.size());
+
+ // If the highlight has changed, redraw the scrollbar
+ if (ui._scrollHighlight != oldHighlight)
+ render(HL_SCROLLBAR_ONLY);
+
+ if (ui._scrollHighlight != SH_NONE || keycode == Common::KEYCODE_HOME || keycode == Common::KEYCODE_END
+ || keycode == Common::KEYCODE_PAGEUP || keycode == Common::KEYCODE_PAGEDOWN) {
+ int scrollIndex = _talkScrollIndex;
+
+ // Check for the scrollbar
+ if (ui._scrollHighlight == SH_THUMBNAIL) {
+ int yp = mousePos.y;
+ yp = CLIP(yp, _bounds.top + BUTTON_SIZE + 3, _bounds.bottom - BUTTON_SIZE - 3);
+
+ // Calculate the line number that corresponds to the position that the mouse is on the scrollbar
+ int lineNum = (yp - _bounds.top - BUTTON_SIZE - 3) * 100 / (_bounds.height() - BUTTON_SIZE * 2 - 6)
+ * _statementLines.size() / 100 - 3;
+
+ // If the new position would place part of the text outsidethe text window, adjust it so it doesn't
+ if (lineNum < 0)
+ lineNum = 0;
+ else if (lineNum + NUM_VISIBLE_TALK_LINES > (int)_statementLines.size()) {
+ lineNum = (int)_statementLines.size() - NUM_VISIBLE_TALK_LINES;
+
+ // Make sure it's not below zero now
+ if (lineNum < 0)
+ lineNum = 0;
+ }
+
+ _talkScrollIndex = lineNum;
+ }
+
+ // Get the current frame so we can check the scroll timer against it
+ uint32 frameNum = events.getFrameCounter();
+
+ if (frameNum > _dialogTimer) {
+ // Set the timeout for the next scroll if the mouse button remains held down
+ _dialogTimer = (_dialogTimer == 0) ? frameNum + NUM_VISIBLE_TALK_LINES : frameNum + 1;
+
+ // Check for Scroll Up
+ if (ui._scrollHighlight == SH_SCROLL_UP && _talkScrollIndex)
+ --_talkScrollIndex;
+
+ // Check for Page Up
+ if ((ui._scrollHighlight == SH_PAGE_UP || keycode == Common::KEYCODE_PAGEUP) && _talkScrollIndex)
+ _talkScrollIndex -= NUM_VISIBLE_TALK_LINES;
+
+ // Check for Page Down
+ if ((ui._scrollHighlight == SH_PAGE_DOWN || keycode == Common::KEYCODE_PAGEDOWN)
+ && (_talkScrollIndex + NUM_VISIBLE_TALK_LINES < (int)_statementLines.size())) {
+ _talkScrollIndex += 6;
+ if (_talkScrollIndex + NUM_VISIBLE_TALK_LINES >(int)_statementLines.size())
+ _talkScrollIndex = _statementLines.size() - NUM_VISIBLE_TALK_LINES;
+ }
+
+ // Check for Scroll Down
+ if (ui._scrollHighlight == SH_SCROLL_DOWN && (_talkScrollIndex + NUM_VISIBLE_TALK_LINES < (int)_statementLines.size()))
+ _talkScrollIndex++;
+ }
+
+ if (keycode == Common::KEYCODE_END)
+ _talkScrollIndex = _statementLines.size() - NUM_VISIBLE_TALK_LINES;
+
+ if (_talkScrollIndex < 0 || keycode == Common::KEYCODE_HOME)
+ _talkScrollIndex = 0;
+
+ // Only redraw the window if the the scrollbar position has changed
+ if (scrollIndex != _talkScrollIndex) {
+ _surface.fillRect(Common::Rect(4, 5, _surface.w() - BUTTON_SIZE - 8, _surface.h() - 4), TRANSPARENCY);
+ render(HL_NO_HIGHLIGHTING);
+ }
+ }
+
+ // Flag if they started pressing outside of the window
+ if (events._firstPress && !_bounds.contains(mousePos))
+ _outsideMenu = true;
+
+ // Check for which statement they are pointing at
+ _selector = -1;
+ if (ui._scrollHighlight == SH_NONE) {
+ if (Common::Rect(_bounds.left, _bounds.top + 5, _bounds.right - 3, _bounds.bottom - 5).contains(mousePos)) {
+ if (_scroll) {
+ // Disregard the scrollbar when setting the statement number
+ if (!Common::Rect(_bounds.right - BUTTON_SIZE, _bounds.top, _bounds.right, _bounds.bottom).contains(mousePos))
+ _selector = (mousePos.y - _bounds.top - 5) / (_surface.fontHeight() + 1) + _talkScrollIndex;
+ } else {
+ _selector = (mousePos.y - _bounds.top - 5) / (_surface.fontHeight() + 1);
+ }
+
+ // Now translate the line number of the displayed line into the appropriate
+ // Statement number or set it to 255 to indicate no Statement selected
+ if (_selector >= 0 && _selector < (int)_statementLines.size())
+ _selector = _statementLines[_selector]._num;
+ else
+ _selector = -1;
+ }
+ }
+
+ // Check for the tab keys
+ if (keycode == Common::KEYCODE_TAB && ui._scrollHighlight == SH_NONE) {
+ if (_selector == -1) {
+ _selector = _statementLines[_scroll ? _talkScrollIndex : 0]._num;
+
+ events.warpMouse(Common::Point(_bounds.right - BUTTON_SIZE - 10, _bounds.top + _surface.fontHeight() + 2));
+ } else {
+ if (ui._keyState.flags & Common::KBD_SHIFT) {
+ _selector = (mousePos.y - _bounds.top - 5) / (_surface.fontHeight() + 1) + _talkScrollIndex;
+ if (_statementLines[_selector]._num == _statementLines[_talkScrollIndex]._num) {
+ _selector = (_bounds.height() - 10) / (_surface.fontHeight() + 1) + _talkScrollIndex;
+ } else {
+ int idx = _selector;
+ do {
+ --_selector;
+ } while (_selector > 0 && _statementLines[idx]._num == _statementLines[_selector]._num);
+ }
+
+ int idx = _selector;
+ while ((_statementLines[idx]._num == _statementLines[_selector - 1]._num) && (_selector > _talkScrollIndex))
+ --_selector;
+ } else {
+ _selector = (mousePos.y - _bounds.top - 5) / (_surface.fontHeight() + 1) + _talkScrollIndex;
+ if (_statementLines[_selector]._num == _statementLines[(_bounds.height() - 10) / (_surface.fontHeight() + 1) + _talkScrollIndex]._num) {
+ _selector = _talkScrollIndex;
+ } else {
+ int idx = _selector;
+ do {
+ ++_selector;
+ } while (_selector < (int)_statementLines.size() && _statementLines[idx]._num == _statementLines[_selector]._num);
+ }
+ }
+
+ events.warpMouse(Common::Point(mousePos.x, _bounds.top + _surface.fontHeight() + 2 + (_surface.fontHeight() + 1)
+ * (_selector - _talkScrollIndex)));
+ _selector = _statementLines[_selector]._num;
+ }
+ }
+
+ // Handle selecting a talk entry if a numeric key has been pressed
+ if (keycode >= Common::KEYCODE_1 && keycode <= Common::KEYCODE_9) {
+ int x = 0, t = 0, y = 0;
+
+ do {
+ if (y == (keycode - Common::KEYCODE_1)) {
+ _selector = _statementLines[t]._num;
+ _outsideMenu = false;
+ hotkey = true;
+ break;
+ }
+
+ ++t;
+ if (_statementLines[x]._num != _statementLines[t]._num) {
+ x = t;
+ ++y;
+ }
+ } while (t < (int)_statementLines.size());
+ }
+
+ // Display the selected statement highlighted and reset the last statement.
+ if (_selector != _oldSelector) {
+ render(HL_CHANGED_HIGHLIGHTS);
+ _oldSelector = _selector;
+ }
+
+ if (events._released || events._rightReleased || keycode == Common::KEYCODE_ESCAPE || hotkey) {
+ events.clearEvents();
+ _dialogTimer = 0;
+ ui._scrollHighlight = SH_NONE;
+
+ // See if they want to close the menu (click outside the window or Escape pressed)
+ if ((_outsideMenu && !_bounds.contains(mousePos)) || keycode == Common::KEYCODE_ESCAPE) {
+ if (keycode == Common::KEYCODE_ESCAPE)
+ _selector = -1;
+
+ talk.freeTalkVars();
+ talk.pullSequence();
+
+ for (int idx = 1; idx < MAX_CHARACTERS; ++idx) {
+ if (people[idx]._type == CHARACTER) {
+ while (!people[idx]._pathStack.empty())
+ people[idx].pullNPCPath();
+ }
+ }
+
+ banishWindow();
+ ui._menuMode = scene._labTableScene ? LAB_MODE : STD_MODE;
+
+ if (scene._currentScene == 52)
+ callParrotFile = true;
+ }
+
+ _outsideMenu = false;
+
+ // See if they have selected a statement to say
+ if (_selector != -1) {
+ if (!talk._talkHistory[talk._converseNum][_selector] && talk._statements[_selector]._journal)
+ journal.record(talk._converseNum, _selector);
+ talk._talkHistory[talk._converseNum][_selector] = true;
+
+ banishWindow();
+ talk._speaker = _vm->readFlags(FLAG_PLAYER_IS_HOLMES) ? HOLMES : WATSON;
+ _scroll = false;
+ const byte *msg = (const byte *)talk._statements[_selector]._statement.c_str();
+ talk.talkInterface(msg);
+
+ if (sound._speechOn)
+ sound._talkSoundFile += Common::String::format("%02dA", _selector + 1);
+
+ int msgLen = MAX((int)talk._statements[_selector]._statement.size(), 160);
+ people.setTalkSequence(talk._speaker);
+
+ talk.waitForMore(msgLen);
+ if (talk._talkToAbort)
+ return;
+
+ people.setListenSequence(talk._speaker);
+
+ do {
+ talk._scriptSelect = _selector;
+ talk._speaker = talk._talkTo;
+
+ // Make a copy of the reply (since talkTo can reload the statements list), and call talkTo
+ Common::String reply = talk._statements[_selector]._reply;
+ talk.doScript(reply);
+
+ // Reset the misc field in case any people changed their sequences
+ for (int idx = 0; idx < MAX_CHARACTERS; ++idx)
+ people[idx]._misc = 0;
+
+ if (!talk._talkToAbort) {
+ if (!talk._statements[_selector]._modified.empty()) {
+ for (uint idx = 0; idx < talk._statements[_selector]._modified.size(); ++idx)
+ _vm->setFlags(talk._statements[_selector]._modified[idx]);
+
+ talk.setTalkMap();
+ }
+
+ // See if there is another talk file linked to this.
+ if (!talk._statements[_selector]._linkFile.empty() && !talk._scriptMoreFlag) {
+ Common::String linkFile = talk._statements[_selector]._linkFile;
+ talk.freeTalkVars();
+ talk.loadTalkFile(linkFile);
+
+ _talkScrollIndex = 0;
+ int select = -1;
+ _selector = _oldSelector = -1;
+
+ // Find the first statement that has all it's flags set correctly
+ for (uint idx = 0; idx < talk._statements.size() && select == -1; ++select) {
+ if (!talk._statements[idx]._talkMap)
+ select = idx;
+ }
+
+ if (select == -1) {
+ talk.freeTalkVars();
+ ui.putMessage("%s", FIXED(NothingToSay));
+ return;
+ }
+
+ // See is the new statement is in stealth mode
+ talk._talkStealth = (talk._statements[select]._statement.hasPrefix("^")) ? 2 : 0;
+
+ // See if the new file is a standard file, a reply first file, or a Stealth Mode file
+ if (!talk._statements[select]._statement.hasPrefix("*") && !talk._statements[select]._statement.hasPrefix("^")) {
+ load();
+ summonWindow();
+
+ setStatementLines();
+ render(HL_NO_HIGHLIGHTING);
+ break;
+ } else {
+ _selector = select;
+
+ if (!talk._talkHistory[talk._converseNum][_selector] && talk._statements[_selector]._journal)
+ journal.record(talk._converseNum, _selector);
+
+ talk._talkHistory[talk._converseNum][_selector] = true;
+ }
+ } else {
+ talk.freeTalkVars();
+ talk.pullSequence();
+
+ for (int idx = 1; idx < MAX_CHARACTERS; ++idx) {
+ if (people[idx]._type == CHARACTER)
+ while (!people[idx]._pathStack.empty())
+ people[idx].pullNPCPath();
+ }
+
+ ui.banishWindow();
+ ui._menuMode = scene._labTableScene ? LAB_MODE : STD_MODE;
+ break;
+ }
+ } else {
+ break;
+ }
+ } while (!_vm->shouldQuit());
+
+ events.clearEvents();
+
+ // Now, if a script was pushed onto the script stack, restore them to allow the previous script to continue.
+ talk.popStack();
+ }
+ }
+
+ if (callParrotFile)
+ talk.talkTo("POUT52A");
+}
+
+void WidgetTalk::render(Highlight highlightMode) {
+ TattooTalk &talk = *(TattooTalk *)_vm->_talk;
+ int yp = 5;
+ int statementNum = 1;
+ byte color;
+
+ if (highlightMode != HL_SCROLLBAR_ONLY) {
+ // Draw all the statements
+ // Check whether scrolling has occurred, and if so, figure out what the starting
+ // number for the first visible statement will be
+ if (_talkScrollIndex) {
+ for (int idx = 1; idx <= _talkScrollIndex; ++idx) {
+ if (_statementLines[idx - 1]._num != _statementLines[idx]._num)
+ ++statementNum;
+ }
+ }
+
+ // Main drawing loop
+ for (uint idx = _talkScrollIndex; idx < _statementLines.size() && yp < (_bounds.height() - _surface.fontHeight()); ++idx) {
+ if (highlightMode == HL_NO_HIGHLIGHTING || _statementLines[idx]._num == _selector ||
+ _statementLines[idx]._num == _oldSelector) {
+ // Different coloring based on whether the option has been previously chosen or not
+ color = (!talk._talkHistory[talk._converseNum][_statementLines[idx]._num]) ?
+ INFO_TOP : INFO_BOTTOM;
+
+ if (_statementLines[idx]._num == _selector && highlightMode == HL_CHANGED_HIGHLIGHTS)
+ color = COMMAND_HIGHLIGHTED;
+
+ // See if it's the start of a new statement, so needs the statement number to be displayed
+ if (!idx || _statementLines[idx]._num != _statementLines[idx - 1]._num) {
+ Common::String numStr = Common::String::format("%d.", statementNum);
+ _surface.writeString(numStr, Common::Point(STATEMENT_NUM_X, yp), color);
+ }
+
+ // Display the statement line
+ _surface.writeString(_statementLines[idx]._line, Common::Point(_talkTextX, yp), color);
+ }
+ yp += _surface.fontHeight() + 1;
+
+ // If the next line starts a new statement, then increment the statement number
+ if (idx == (_statementLines.size() - 1) || _statementLines[idx]._num != _statementLines[idx + 1]._num)
+ ++statementNum;
+ }
+ }
+
+ // See if the scroll bar needs to be drawn
+ if (_scroll && highlightMode != HL_CHANGED_HIGHLIGHTS)
+ drawScrollBar(_talkScrollIndex, NUM_VISIBLE_TALK_LINES, _statementLines.size());
+}
+
+void WidgetTalk::setStatementLines() {
+ TattooTalk &talk = *(TattooTalk *)_vm->_talk;
+ const char *numStr = "19.";
+
+ // See how many statements are going to be available
+ int numStatements = 0;
+ for (uint idx = 0; idx < talk._statements.size(); ++idx) {
+ if (talk._statements[idx]._talkMap != -1)
+ ++numStatements;
+ }
+
+ // If there are more lines than can be displayed in the interface window at one time, adjust the allowed
+ // width to take into account needing a scrollbar
+ int xSize = _scroll ? _bounds.width() - BUTTON_SIZE - 3 : _bounds.width();
+
+ // Also adjust the width to allow room for the statement numbers at the left edge of the display
+ int n = (numStatements < 10) ? 1 : 0;
+ xSize -= _surface.stringWidth(numStr + n) + _surface.widestChar() / 2 + 9;
+ _talkTextX = _surface.stringWidth(numStr + n) + _surface.widestChar() / 4 + 6;
+ _statementLines.clear();
+
+ for (uint statementNum = 0; statementNum < talk._statements.size(); ++statementNum) {
+ // See if this statment meets all of it's flag requirements
+ if (talk._statements[statementNum]._talkMap != -1) {
+ // Get the next statement text to process
+ Common::String str = talk._statements[statementNum]._statement;
+
+ Common::StringArray statementLines;
+ splitLines(str, statementLines, xSize, 999);
+
+ // Add the lines in
+ for (uint idx = 0; idx < statementLines.size(); ++idx)
+ _statementLines.push_back(StatementLine(statementLines[idx], statementNum));
+ }
+ }
+}
+
+void WidgetTalk::refresh() {
+ _talkScrollIndex = 0;
+ _selector = _oldSelector = -1;
+
+ setStatementLines();
+ render(HL_NO_HIGHLIGHTING);
+}
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/tattoo/widget_talk.h b/engines/sherlock/tattoo/widget_talk.h
new file mode 100644
index 0000000000..1dbbc22a69
--- /dev/null
+++ b/engines/sherlock/tattoo/widget_talk.h
@@ -0,0 +1,92 @@
+/* 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 SHERLOCK_TATTOO_WIDGET_TALK_H
+#define SHERLOCK_TATTOO_WIDGET_TALK_H
+
+#include "common/scummsys.h"
+#include "sherlock/tattoo/widget_base.h"
+
+namespace Sherlock {
+
+class SherlockEngine;
+
+namespace Tattoo {
+
+enum Highlight { HL_NO_HIGHLIGHTING, HL_CHANGED_HIGHLIGHTS, HL_SCROLLBAR_ONLY };
+
+/**
+ * Handles displaying a dialog with conversation options the player can select from
+ */
+class WidgetTalk: public WidgetBase {
+ struct StatementLine {
+ Common::String _line;
+ int _num;
+
+ StatementLine() : _num(0) {}
+ StatementLine(const Common::String &line, int num) : _line(line), _num(num) {}
+ };
+private:
+ int _talkScrollIndex;
+ Common::Array<StatementLine> _statementLines;
+ int _selector, _oldSelector;
+ int _talkTextX;
+ uint32 _dialogTimer;
+
+ void getTalkWindowSize();
+
+ /**
+ * Re-renders the contenst of the window to the widget's surface
+ */
+ void render(Highlight highlightMode);
+
+ /**
+ * This initializes the _statementLines array, which contains the talk options split up line
+ * by line, as well as which statement a particular line is part of.
+ */
+ void setStatementLines();
+public:
+ WidgetTalk(SherlockEngine *vm);
+ virtual ~WidgetTalk() {}
+
+ /**
+ * Figures out how many lines the available talk lines will take up, and opens a text window
+ * of appropriate size
+ */
+ void load();
+
+ /**
+ * Refresh the talk display
+ */
+ void refresh();
+
+ /**
+ * Handle event processing
+ */
+ virtual void handleEvents();
+};
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/tattoo/widget_text.cpp b/engines/sherlock/tattoo/widget_text.cpp
new file mode 100644
index 0000000000..33330df2e2
--- /dev/null
+++ b/engines/sherlock/tattoo/widget_text.cpp
@@ -0,0 +1,223 @@
+/* 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 "sherlock/tattoo/widget_text.h"
+#include "sherlock/tattoo/tattoo_people.h"
+#include "sherlock/tattoo/tattoo_scene.h"
+#include "sherlock/tattoo/tattoo_user_interface.h"
+#include "sherlock/tattoo/tattoo.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+WidgetText::WidgetText(SherlockEngine *vm) : WidgetBase(vm) {
+}
+
+void WidgetText::load(const Common::String &str, int speaker) {
+ Screen &screen = *_vm->_screen;
+ Talk &talk = *_vm->_talk;
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+ Common::StringArray lines;
+
+ int width = SHERLOCK_SCREEN_WIDTH / 3;
+ int height;
+
+ for (;;) {
+ splitLines(str, lines, width - _surface.widestChar() * 2, 100);
+ height = (screen.fontHeight() + 1) * lines.size() + 9;
+
+ if ((width - _surface.widestChar() * 2 > height * 3 / 2) || (width - _surface.widestChar() * 2
+ > SHERLOCK_SCREEN_WIDTH * 3 / 4))
+ break;
+
+ width += (width / 4);
+ }
+
+ // See if it's only a single line long
+ if (height == _surface.fontHeight() + 10) {
+ width = _surface.widestChar() * 2 + 6;
+
+ const char *strP = str.c_str();
+ while (*strP && (*strP < talk._opcodes[OP_SWITCH_SPEAKER] || *strP == talk._opcodes[OP_NULL]))
+ width += _surface.charWidth(*strP++);
+ }
+
+ _bounds = Common::Rect(width, height);
+
+ if (speaker == -1) {
+ // No speaker specified, so center window on look position
+ _bounds.translate(ui._lookPos.x - width / 2, ui._lookPos.y - height / 2);
+ } else {
+ // Speaker specified, so center the window above them
+ centerWindowOnSpeaker(speaker);
+ }
+
+ render(str);
+}
+
+void WidgetText::centerWindowOnSpeaker(int speaker) {
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ TattooScene &scene = *(TattooScene *)_vm->_scene;
+ Common::Point pt;
+
+ bool flag = _vm->readFlags(FLAG_PLAYER_IS_HOLMES);
+ if (people[HOLMES]._type == CHARACTER && ((speaker == HOLMES && flag) || (speaker == WATSON && !flag))) {
+ // Place the window centered above the player
+ pt.x = people[HOLMES]._position.x / FIXED_INT_MULTIPLIER - _bounds.width() / 2;
+
+ int scaleVal = scene.getScaleVal(people[HOLMES]._position);
+ if (scaleVal == SCALE_THRESHOLD) {
+ pt.x += people[HOLMES].frameWidth() / 2;
+ pt.y = people[HOLMES]._position.y / FIXED_INT_MULTIPLIER - people[HOLMES].frameHeight()
+ - _bounds.height() - _surface.fontHeight();
+ } else {
+ pt.x += people[HOLMES]._imageFrame->sDrawXSize(scaleVal) / 2;
+ pt.y = people[HOLMES]._position.y / FIXED_INT_MULTIPLIER - people[HOLMES]._imageFrame->sDrawYSize(scaleVal)
+ - _bounds.height() - _surface.fontHeight();
+ }
+ } else {
+ pt.y = -1;
+
+ // Check each NPC to see if they are the one that is talking
+ for (int idx = 1; idx < MAX_CHARACTERS; ++idx) {
+ if (people[idx]._type == CHARACTER) {
+ if (!scumm_strnicmp(people[idx]._npcName.c_str(), people._characters[speaker]._portrait, 4)) {
+ // Place the window above the player
+ pt.x = people[idx]._position.x / FIXED_INT_MULTIPLIER - _bounds.width() / 2;
+
+ int scaleVal = scene.getScaleVal(people[idx]._position);
+ if (scaleVal == SCALE_THRESHOLD) {
+ pt.x += people[idx].frameWidth() / 2;
+ pt.y = people[idx]._position.y / FIXED_INT_MULTIPLIER - people[idx].frameHeight()
+ - _bounds.height() - _surface.fontHeight();
+ }
+ else {
+ pt.x += people[idx]._imageFrame->sDrawXSize(scaleVal) / 2;
+ pt.y = people[idx]._position.y / FIXED_INT_MULTIPLIER - people[idx]._imageFrame->sDrawYSize(scaleVal)
+ - _bounds.height() - _surface.fontHeight();
+ }
+
+ if (pt.y < 0)
+ pt.y = 0;
+ break;
+ }
+ }
+ }
+
+ if (pt.y == -1) {
+ for (uint idx = 0; idx < scene._bgShapes.size(); ++idx) {
+ Object &obj = scene._bgShapes[idx];
+
+ if (obj._type == ACTIVE_BG_SHAPE && !scumm_strnicmp(obj._name.c_str(), people._characters[speaker]._portrait, 4)) {
+ // Place the window centered above the character
+ pt.x = obj._position.x - _bounds.width() / 2;
+ pt.y = obj._position.y - _bounds.height() - _surface.fontHeight();
+ if (pt.y < 0)
+ pt.y = 0;
+ if (obj._scaleVal == SCALE_THRESHOLD)
+ pt.x += obj.frameWidth() / 2;
+ else
+ pt.x += obj._imageFrame->sDrawXSize(obj._scaleVal) / 2;
+
+ break;
+ }
+ }
+ }
+
+ if (pt.y == -1) {
+ pt.x = SHERLOCK_SCREEN_WIDTH / 2 - _bounds.width() / 2;
+ pt.y = SHERLOCK_SCREEN_HEIGHT / 2 - _bounds.height() / 2;
+ }
+ }
+
+ _bounds.moveTo(pt);
+}
+
+void WidgetText::render(const Common::String &str) {
+ Common::StringArray lines;
+ _remainingText = splitLines(str, lines, _bounds.width() - _surface.widestChar() * 2,
+ _bounds.height() / (_surface.fontHeight() + 1));
+
+ // Allocate a surface for the window
+ _surface.create(_bounds.width(), _bounds.height());
+ _surface.fill(TRANSPARENCY);
+
+ // Form the background for the new window
+ makeInfoArea();
+
+ int yp = 5;
+ for (int lineNum = 0; yp < (_bounds.height() - _surface.fontHeight() / 2); ++lineNum) {
+ _surface.writeString(lines[lineNum], Common::Point(_surface.widestChar(), yp), INFO_TOP);
+ yp += _surface.fontHeight() + 1;
+ }
+}
+
+/*----------------------------------------------------------------*/
+
+WidgetMessage::WidgetMessage(SherlockEngine *vm) : WidgetBase(vm) {
+ _menuCounter = 0;
+}
+
+void WidgetMessage::load(const Common::String &str, int time) {
+ Events &events = *_vm->_events;
+ Common::Point mousePos = events.mousePos();
+ _menuCounter = time;
+
+ // Set up the bounds for the dialog to be a single line
+ _bounds = Common::Rect(_surface.stringWidth(str) + _surface.widestChar() * 2 + 6, _surface.fontHeight() + 10);
+ _bounds.moveTo(mousePos.x - _bounds.width() / 2, mousePos.y - _bounds.height() / 2);
+
+ // Allocate a surface for the window
+ _surface.create(_bounds.width(), _bounds.height());
+ _surface.fill(TRANSPARENCY);
+
+ // Form the background for the new window and write the line of text
+ makeInfoArea();
+ _surface.writeString(str, Common::Point(_surface.widestChar() + 3, 5), INFO_TOP);
+}
+
+void WidgetMessage::handleEvents() {
+ Events &events = *_vm->_events;
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+ WidgetBase::handleEvents();
+
+ --_menuCounter;
+
+ // Check if a mouse or keypress has occurred, or the display counter has expired
+ if (events._pressed || events._released || events._rightPressed || events._rightReleased ||
+ ui._keyState.keycode || !_menuCounter) {
+ // Close the window
+ banishWindow();
+
+ // Reset cursor and switch back to standard mode
+ events.setCursor(ARROW);
+ events.clearEvents();
+ ui._key = -1;
+ ui._oldBgFound = -1;
+ ui._menuMode = STD_MODE;
+ }
+}
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/tattoo/widget_text.h b/engines/sherlock/tattoo/widget_text.h
new file mode 100644
index 0000000000..f027bdae9f
--- /dev/null
+++ b/engines/sherlock/tattoo/widget_text.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 SHERLOCK_TATTOO_WIDGET_TEXT_H
+#define SHERLOCK_TATTOO_WIDGET_TEXT_H
+
+#include "common/scummsys.h"
+#include "sherlock/tattoo/widget_base.h"
+
+namespace Sherlock {
+
+class SherlockEngine;
+
+namespace Tattoo {
+
+class WidgetText: public WidgetBase {
+private:
+ /**
+ * Center the area the dialog will be drawn on above a given speaker
+ */
+ void centerWindowOnSpeaker(int speaker);
+
+ /**
+ * Build up the text dialog based on the previously set bounds
+ */
+ void render(const Common::String &str);
+public:
+ Common::String _remainingText;
+public:
+ WidgetText(SherlockEngine *vm);
+ virtual ~WidgetText() {}
+
+ /**
+ * Load the data for the text window
+ */
+ void load(const Common::String &str, int speaker = -1);
+};
+
+class WidgetMessage : public WidgetBase {
+private:
+ int _menuCounter;
+public:
+ WidgetMessage(SherlockEngine *vm);
+ virtual ~WidgetMessage() {}
+
+ /**
+ * Load the data for the text window
+ */
+ void load(const Common::String &str, int time);
+
+ /**
+ * Handle event processing
+ */
+ virtual void handleEvents();
+};
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/tattoo/widget_tooltip.cpp b/engines/sherlock/tattoo/widget_tooltip.cpp
new file mode 100644
index 0000000000..b1c13c7a29
--- /dev/null
+++ b/engines/sherlock/tattoo/widget_tooltip.cpp
@@ -0,0 +1,220 @@
+/* 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 "sherlock/tattoo/widget_tooltip.h"
+#include "sherlock/tattoo/tattoo_map.h"
+#include "sherlock/tattoo/tattoo_user_interface.h"
+#include "sherlock/tattoo/tattoo.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+#define MAX_TOOLTIP_WIDTH 150
+
+void WidgetTooltipBase::draw() {
+ Screen &screen = *_vm->_screen;
+
+ // If there was a previously drawn frame in a different position that hasn't yet been erased, then erase it
+ if (_oldBounds.width() > 0 && _oldBounds != _bounds)
+ erase();
+
+ if (_bounds.width() > 0 && !_surface.empty()) {
+ restrictToScreen();
+
+ // Blit the affected area to the screen
+ screen.slamRect(_bounds);
+
+ // Draw the widget directly onto the screen. Unlike other widgets, we don't draw to the back buffer,
+ // since nothing should be drawing on top of tooltips, so there's no need to store in the back buffer
+ screen.transBlitFrom(_surface, Common::Point(_bounds.left - screen._currentScroll.x,
+ _bounds.top - screen._currentScroll.y));
+
+ // Store a copy of the drawn area for later erasing
+ _oldBounds = _bounds;
+ }
+}
+
+void WidgetTooltipBase::erase() {
+ Screen &screen = *_vm->_screen;
+
+ if (_oldBounds.width() > 0) {
+ // Restore the affected area from the back buffer to the screen
+ screen.slamRect(_oldBounds);
+
+ // Reset the old bounds so it won't be erased again
+ _oldBounds = Common::Rect(0, 0, 0, 0);
+ }
+}
+
+/*----------------------------------------------------------------*/
+
+WidgetTooltip::WidgetTooltip(SherlockEngine *vm) : WidgetTooltipBase (vm) {
+}
+
+void WidgetTooltip::setText(const Common::String &str) {
+ Events &events = *_vm->_events;
+ Common::Point mousePos = events.mousePos();
+ bool reset = false;
+
+ // Make sure that the description is present
+ if (!str.empty()) {
+ int width = _surface.stringWidth(str) + 2;
+ int height = _surface.stringHeight(str) + 2;
+ Common::String line1 = str, line2 = "";
+
+ // See if we need to split it into two lines
+ if (width > MAX_TOOLTIP_WIDTH) {
+ // Go forward word by word to find out where to split the line
+ const char *s = str.c_str();
+ const char *space = nullptr;
+ int dif = 10000;
+
+ for (;;) {
+ // Find end of next word
+ s = strchr(s + 1, ' ');
+
+ if (s == nullptr) {
+ // Reached end of string
+ if (space != nullptr) {
+ line1 = Common::String(str.c_str(), space);
+ line2 = Common::String(space + 1);
+ height = _surface.stringHeight(line1) + _surface.stringHeight(line2) + 4;
+ }
+ break;
+ }
+
+ // Found space separating words, so see what width the string up to now is
+ Common::String tempLine1 = Common::String(str.c_str(), s);
+ Common::String tempLine2 = Common::String(s + 1);
+ int width1 = _surface.stringWidth(tempLine1);
+ int width2 = _surface.stringWidth(tempLine2);
+
+ // See if we've found a split point that results in a less overall width
+ if (ABS(width1 - width2) < dif) {
+ // Found a better split point
+ dif = ABS(width1 - width2);
+ space = s;
+ line1 = tempLine1;
+ line2 = tempLine2;
+ }
+ }
+ } else {
+ // No line split needed
+ height = _surface.stringHeight(str) + 2;
+ }
+
+ // Reallocate the text surface with the new size
+ _surface.create(width, height);
+ _surface.fill(TRANSPARENCY);
+
+ if (line2.empty()) {
+ // Only a single line
+ _surface.writeFancyString(str, Common::Point(0, 0), BLACK, INFO_TOP);
+ } else {
+ // Two lines to display
+ int xp, yp;
+ xp = (width - _surface.stringWidth(line1) - 2) / 2;
+ _surface.writeFancyString(line1, Common::Point(xp, 0), BLACK, INFO_TOP);
+
+ xp = (width - _surface.stringWidth(line2) - 2) / 2;
+ yp = _surface.stringHeight(line1) + 2;
+ _surface.writeFancyString(line2, Common::Point(xp, yp), BLACK, INFO_TOP);
+ }
+
+ // Set the initial display position for the tooltip text
+ int tagX = mousePos.x - width / 2;
+ int tagY = mousePos.y - height;
+
+ _bounds = Common::Rect(tagX, tagY, tagX + width, tagY + height);
+ } else {
+ reset = true;
+ }
+
+ if (reset && !_surface.empty()) {
+ _surface.free();
+ }
+}
+
+void WidgetTooltip::handleEvents() {
+ Events &events = *_vm->_events;
+ Common::Point mousePos = events.mousePos();
+
+ // Set the new position for the tooltip
+ int xp = mousePos.x - _bounds.width() / 2;
+ int yp = mousePos.y - _bounds.height();
+
+ _bounds.moveTo(xp, yp);
+}
+
+/*----------------------------------------------------------------*/
+
+void WidgetSceneTooltip::handleEvents() {
+ Events &events = *_vm->_events;
+ People &people = *_vm->_people;
+ Scene &scene = *_vm->_scene;
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+ Common::Point mousePos = events.mousePos();
+
+ // See if thay are pointing at a different object and we need to regenerate the tooltip text
+ if (ui._bgFound != ui._oldBgFound || (ui._bgFound != -1 && _surface.empty()) ||
+ ui._arrowZone != ui._oldArrowZone || (ui._arrowZone != -1 && _surface.empty())) {
+ // See if there is a new object to display text for
+ if ((ui._bgFound != -1 && (ui._bgFound != ui._oldBgFound || (ui._bgFound != -1 && _surface.empty()))) ||
+ (ui._arrowZone != -1 && (ui._arrowZone != ui._oldArrowZone || (ui._arrowZone != -1 && _surface.empty())))) {
+ Common::String str;
+ if (ui._bgFound != -1) {
+ // Clear the Arrow Zone fields so it won't think we're displaying an Arrow Zone cursor
+ if (scene._currentScene != 90) // RRR Take out the cludge for room 90
+ ui._arrowZone = ui._oldArrowZone = -1;
+
+ // Get the description string
+ str = (ui._bgFound < 1000) ? scene._bgShapes[ui._bgFound]._description :
+ people[ui._bgFound - 1000]._description;
+ } else {
+ // Get the exit zone description
+ str = scene._exits[ui._arrowZone]._dest;
+ }
+
+ setText(str.hasPrefix(" ") ? Common::String() : str);
+ } else if ((ui._bgFound == -1 && ui._oldBgFound != -1) || (ui._arrowZone == -1 && ui._oldArrowZone != -1)) {
+ setText("");
+ }
+
+ ui._oldBgFound = ui._bgFound;
+ } else {
+
+ // Set the new position for the tooltip
+ int tagX = CLIP(mousePos.x - _bounds.width() / 2, 0, SHERLOCK_SCREEN_WIDTH - _bounds.width());
+ int tagY = MAX(mousePos.y - _bounds.height(), 0);
+
+ _bounds.moveTo(tagX, tagY);
+ }
+
+ ui._oldArrowZone = ui._arrowZone;
+
+ WidgetTooltip::handleEvents();
+}
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/tattoo/widget_tooltip.h b/engines/sherlock/tattoo/widget_tooltip.h
new file mode 100644
index 0000000000..a7758d4863
--- /dev/null
+++ b/engines/sherlock/tattoo/widget_tooltip.h
@@ -0,0 +1,87 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SHERLOCK_TATTOO_WIDGET_TOOLTIP_H
+#define SHERLOCK_TATTOO_WIDGET_TOOLTIP_H
+
+#include "common/scummsys.h"
+#include "common/rect.h"
+#include "sherlock/tattoo/widget_base.h"
+
+namespace Sherlock {
+
+class SherlockEngine;
+
+namespace Tattoo {
+
+class WidgetTooltipBase : public WidgetBase {
+public:
+ WidgetTooltipBase(SherlockEngine *vm) : WidgetBase(vm) {}
+ virtual ~WidgetTooltipBase() {}
+
+ /**
+ * Erase any previous display of the widget on the screen
+ */
+ virtual void erase();
+
+ /**
+ * Update the display of the widget on the screen
+ */
+ virtual void draw();
+};
+
+class WidgetTooltip: public WidgetTooltipBase {
+public:
+ WidgetTooltip(SherlockEngine *vm);
+ virtual ~WidgetTooltip() {}
+
+ /**
+ * Set the text for the tooltip
+ */
+ void setText(const Common::String &str);
+
+ /**
+ * Handle updating the tooltip state
+ */
+ virtual void handleEvents();
+};
+
+class WidgetSceneTooltip : public WidgetTooltip {
+public:
+ WidgetSceneTooltip(SherlockEngine *vm) : WidgetTooltip(vm) {}
+
+ /**
+ * Handle updating the tooltip state
+ */
+ virtual void handleEvents();
+};
+
+class WidgetMapTooltip : public WidgetTooltip {
+public:
+ WidgetMapTooltip(SherlockEngine *vm) : WidgetTooltip(vm) {}
+};
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/tattoo/widget_verbs.cpp b/engines/sherlock/tattoo/widget_verbs.cpp
new file mode 100644
index 0000000000..3cdd1247c1
--- /dev/null
+++ b/engines/sherlock/tattoo/widget_verbs.cpp
@@ -0,0 +1,311 @@
+/* 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 "sherlock/tattoo/widget_verbs.h"
+#include "sherlock/tattoo/tattoo_fixed_text.h"
+#include "sherlock/tattoo/tattoo_scene.h"
+#include "sherlock/tattoo/tattoo_user_interface.h"
+#include "sherlock/tattoo/tattoo_people.h"
+#include "sherlock/tattoo/tattoo.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+WidgetVerbs::WidgetVerbs(SherlockEngine *vm) : WidgetBase(vm) {
+ _selector = _oldSelector = -1;
+ _outsideMenu = false;
+}
+
+void WidgetVerbs::load(bool objectsOn) {
+ Events &events = *_vm->_events;
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ Talk &talk = *_vm->_talk;
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+ Common::Point mousePos = events.mousePos();
+ bool isWatson = false;
+
+ if (talk._talkToAbort)
+ return;
+
+ ui._activeObj = ui._bgFound;
+ _outsideMenu = false;
+ _verbCommands.clear();
+ _selector = _oldSelector = -1;
+
+ // Check if we need to show options for the highlighted object
+ if (objectsOn) {
+ // Set the verb list accordingly, depending on the target being a
+ // person or an object
+ if (ui._personFound) {
+ TattooPerson &person = people[ui._activeObj - 1000];
+ TattooPerson &npc = people[ui._activeObj - 1001];
+
+ if (!scumm_strnicmp(npc._npcName.c_str(), "WATS", 4))
+ isWatson = true;
+
+
+ if (scumm_strnicmp(person._examine.c_str(), "_EXIT", 5))
+ _verbCommands.push_back(FIXED(Look));
+
+ _verbCommands.push_back(FIXED(Talk));
+
+ // Add any extra active verbs from the NPC's verb list
+ for (int idx = 0; idx < 2; ++idx) {
+ if (!person._use[idx]._verb.empty() && !person._use[idx]._verb.hasPrefix(" ") &&
+ (person._use[idx]._target.empty() || person._use[idx]._target.hasPrefix(" "))) {
+ _verbCommands.push_back(person._use[idx]._verb);
+ }
+ }
+ } else {
+ if (!scumm_strnicmp(ui._bgShape->_name.c_str(), "WATS", 4))
+ // Looking at Watson
+ isWatson = true;
+
+ if (scumm_strnicmp(ui._bgShape->_examine.c_str(), "_EXIT", 5))
+ // It's not an exit, so include Look as an option
+ _verbCommands.push_back(FIXED(Look));
+
+ if (ui._bgShape->_aType == PERSON)
+ _verbCommands.push_back(FIXED(Talk));
+
+ // Add any extra active verbs from the object's verb list
+ for (int idx = 0; idx < 6; ++idx) {
+ if (!ui._bgShape->_use[idx]._verb.empty() && !ui._bgShape->_use[idx]._verb.hasPrefix(" ") &&
+ (ui._bgShape->_use[idx]._target.empty() || ui._bgShape->_use[idx]._target.hasPrefix(" "))) {
+ _verbCommands.push_back(ui._bgShape->_use[idx]._verb);
+ }
+ }
+ }
+ }
+
+ // If clicked on Watson, have Journal as an option
+ if (isWatson)
+ _verbCommands.push_back(FIXED(Journal));
+
+ // Add the system commands
+ _verbCommands.push_back(FIXED(Inventory));
+ _verbCommands.push_back(FIXED(Options));
+
+ // Figure out the needed width to show the commands
+ int width = 0;
+ for (uint idx = 0; idx < _verbCommands.size(); ++idx)
+ width = MAX(width, _surface.stringWidth(_verbCommands[idx]));
+ width += _surface.widestChar() * 2 + 6;
+ int height = (_surface.fontHeight() + 7) * _verbCommands.size() + 3;
+
+ // Set the bounds
+ _bounds = Common::Rect(width, height);
+ _bounds.moveTo(mousePos.x - _bounds.width() / 2, mousePos.y - _bounds.height() / 2);
+
+ // Render the window on the internal surface
+ render();
+}
+
+void WidgetVerbs::render() {
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+ ImageFile &images = *ui._interfaceImages;
+
+ // Create the drawing surface
+ _surface.create(_bounds.width(), _bounds.height());
+ _surface.fill(TRANSPARENCY);
+
+ // Draw basic background
+ makeInfoArea();
+
+ // Draw the verb commands and the lines separating them
+ for (uint idx = 0; idx < _verbCommands.size(); ++idx) {
+ _surface.writeString(_verbCommands[idx], Common::Point((_bounds.width() - _surface.stringWidth(_verbCommands[idx])) / 2,
+ (_surface.fontHeight() + 7) * idx + 5), INFO_TOP);
+
+ if (idx < (_verbCommands.size() - 1)) {
+ _surface.hLine(3, (_surface.fontHeight() + 7) * (idx + 1), _bounds.width() - 4, INFO_TOP);
+ _surface.hLine(3, (_surface.fontHeight() + 7) * (idx + 1) + 1, _bounds.width() - 4, INFO_MIDDLE);
+ _surface.hLine(3, (_surface.fontHeight() + 7) * (idx + 1) + 2, _bounds.width() - 4, INFO_BOTTOM);
+
+ _surface.transBlitFrom(images[4], Common::Point(0, (_surface.fontHeight() + 7) * (idx + 1) - 1));
+ _surface.transBlitFrom(images[5], Common::Point(_bounds.width() - images[5]._width,
+ (_surface.fontHeight() + 7) * (idx + 1) - 1));
+ }
+ }
+}
+
+void WidgetVerbs::handleEvents() {
+ Events &events = *_vm->_events;
+ FixedText &fixedText = *_vm->_fixedText;
+ People &people = *_vm->_people;
+ TattooScene &scene = *(TattooScene *)_vm->_scene;
+ Talk &talk = *_vm->_talk;
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+ Common::Point mousePos = events.mousePos();
+ bool noDesc = false;
+
+ Common::String strLook = fixedText.getText(kFixedText_Look);
+ Common::String strTalk = fixedText.getText(kFixedText_Talk);
+ Common::String strJournal = fixedText.getText(kFixedText_Journal);
+
+ checkTabbingKeys(_verbCommands.size());
+
+ // Highlight verb display as necessary
+ highlightVerbControls();
+
+ // Flag if the user has started pressing the button with the cursor outsie the menu
+ if (events._firstPress && !_bounds.contains(mousePos))
+ _outsideMenu = true;
+
+ // See if they released the mouse button
+ if (events._released || events._rightReleased) {
+ // See if they want to close the menu (they clicked outside of the menu)
+ if (!_bounds.contains(mousePos)) {
+ if (_outsideMenu) {
+ if (events._rightReleased) {
+ // Change to the item (if any) that was right-clicked on, and re-draw the verb menu
+ ui._bgFound = scene.findBgShape(mousePos);
+ ui._personFound = ui._bgFound >= 1000;
+ ui._bgShape = ui._personFound || ui._bgFound == -1 ? nullptr : &scene._bgShapes[ui._bgFound];
+
+ if (ui._personFound) {
+ if (people[ui._bgFound - 1000]._description.empty() || people[ui._bgFound - 1000]._description.hasPrefix(" "))
+ noDesc = true;
+ } else if (ui._bgFound != -1) {
+ if (ui._bgShape->_description.empty() || ui._bgShape->_description.hasPrefix(" "))
+ noDesc = true;
+ } else {
+ noDesc = true;
+ }
+
+ // Call the Routine to turn on the Commands for this Object
+ load(!noDesc);
+ } else {
+ // Free the current menu graphics & erase the menu
+ banishWindow();
+
+ // See if we're in a Lab Table Room
+ ui._menuMode = scene._labTableScene ? LAB_MODE : STD_MODE;
+ }
+ }
+ } else if (_bounds.contains(mousePos) && _selector != -1) {
+ // Mouse is within the menu
+ // Erase the menu
+ banishWindow();
+
+ // See if they are activating the Look Command
+ if (!_verbCommands[_selector].compareToIgnoreCase(strLook)) {
+ ui._bgFound = ui._activeObj;
+ if (ui._activeObj >= 1000) {
+ ui._personFound = true;
+ } else {
+ ui._personFound = false;
+ ui._bgShape = &scene._bgShapes[ui._activeObj];
+ }
+
+ ui.lookAtObject();
+
+ } else if (!_verbCommands[_selector].compareToIgnoreCase(strTalk)) {
+ // Talk command is being activated
+ talk.talk(ui._activeObj);
+ ui._activeObj = -1;
+
+ } else if (!_verbCommands[_selector].compareToIgnoreCase(strJournal)) {
+ ui.doJournal();
+
+ // See if we're in a Lab Table scene
+ ui._menuMode = scene._labTableScene ? LAB_MODE : STD_MODE;
+ } else if (_selector >= ((int)_verbCommands.size() - 2)) {
+ switch (_selector - (int)_verbCommands.size() + 2) {
+ case 0:
+ // Inventory
+ ui.doInventory(2);
+ break;
+
+ case 1:
+ // Options
+ ui.doControls();
+ break;
+
+ default:
+ ui._menuMode = scene._labTableScene ? LAB_MODE : STD_MODE;
+ break;
+ }
+ } else {
+ // If they have selected anything else, process it
+ people[HOLMES].gotoStand();
+
+ if (ui._activeObj < 1000) {
+ for (int idx = 0; idx < 6; ++idx) {
+ if (!_verbCommands[_selector].compareToIgnoreCase(scene._bgShapes[ui._activeObj]._use[idx]._verb)) {
+ // See if they are Picking this object up
+ if (!scene._bgShapes[ui._activeObj]._use[idx]._target.compareToIgnoreCase("*PICKUP"))
+ ui.pickUpObject(ui._activeObj);
+ else
+ ui.checkAction(scene._bgShapes[ui._activeObj]._use[idx], ui._activeObj);
+ }
+ }
+ } else {
+ for (int idx = 0; idx < 2; ++idx) {
+ if (!_verbCommands[_selector].compareToIgnoreCase(people[ui._activeObj - 1000]._use[idx]._verb))
+ ui.checkAction(people[ui._activeObj - 1000]._use[idx], ui._activeObj);
+ }
+ }
+
+ ui._activeObj = -1;
+ if (ui._menuMode != MESSAGE_MODE) {
+ // See if we're in a Lab Table Room
+ ui._menuMode = scene._labTableScene ? LAB_MODE : STD_MODE;
+ }
+ }
+ }
+ } else if (ui._keyState.keycode == Common::KEYCODE_ESCAPE) {
+ // User closing the menu with the ESC key
+ banishWindow();
+ ui._menuMode = scene._labTableScene ? LAB_MODE : STD_MODE;
+ }
+}
+
+void WidgetVerbs::highlightVerbControls() {
+ Events &events = *_vm->_events;
+ Screen &screen = *_vm->_screen;
+ Common::Point mousePos = events.mousePos();
+
+ // Get highlighted verb
+ _selector = -1;
+ Common::Rect bounds = _bounds;
+ bounds.grow(-3);
+ if (bounds.contains(mousePos))
+ _selector = (mousePos.y - bounds.top) / (screen.fontHeight() + 7);
+
+ // See if a new verb is being pointed at
+ if (_selector != _oldSelector) {
+ // Redraw the verb list
+ for (int idx = 0; idx < (int)_verbCommands.size(); ++idx) {
+ byte color = (idx == _selector) ? (byte)COMMAND_HIGHLIGHTED : (byte)INFO_TOP;
+ _surface.writeString(_verbCommands[idx], Common::Point((_bounds.width() - screen.stringWidth(_verbCommands[idx])) / 2,
+ (screen.fontHeight() + 7) * idx + 5), color);
+ }
+
+ _oldSelector = _selector;
+ }
+}
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/tattoo/widget_verbs.h b/engines/sherlock/tattoo/widget_verbs.h
new file mode 100644
index 0000000000..ce67842409
--- /dev/null
+++ b/engines/sherlock/tattoo/widget_verbs.h
@@ -0,0 +1,72 @@
+/* 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 SHERLOCK_TATTOO_WIDGET_VERBS_H
+#define SHERLOCK_TATTOO_WIDGET_VERBS_H
+
+#include "common/scummsys.h"
+#include "common/rect.h"
+#include "common/str-array.h"
+#include "sherlock/tattoo/widget_base.h"
+
+namespace Sherlock {
+
+class SherlockEngine;
+
+namespace Tattoo {
+
+class WidgetVerbs: public WidgetBase {
+private:
+ int _selector, _oldSelector;
+ bool _outsideMenu;
+
+ /**
+ * Highlights the controls for the verb list
+ */
+ void highlightVerbControls();
+
+ /**
+ * Renders the window on an internal surface for later drawing on-screen
+ */
+ void render();
+public:
+ Common::StringArray _verbCommands;
+public:
+ WidgetVerbs(SherlockEngine *vm);
+ virtual ~WidgetVerbs() {}
+
+ /**
+ * Turns on the menu with all the verbs that are available for the given object
+ */
+ void load(bool objectsOn);
+
+ /**
+ * Process input for the dialog
+ */
+ virtual void handleEvents();
+};
+
+} // End of namespace Tattoo
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp
new file mode 100644
index 0000000000..9df3f1dc24
--- /dev/null
+++ b/engines/sherlock/user_interface.cpp
@@ -0,0 +1,205 @@
+/* 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 "sherlock/user_interface.h"
+#include "sherlock/scalpel/scalpel.h"
+#include "sherlock/scalpel/scalpel_user_interface.h"
+#include "sherlock/tattoo/tattoo.h"
+#include "sherlock/tattoo/tattoo_user_interface.h"
+
+namespace Sherlock {
+
+UserInterface *UserInterface::init(SherlockEngine *vm) {
+ if (vm->getGameID() == GType_SerratedScalpel)
+ return new Scalpel::ScalpelUserInterface(vm);
+ else
+ return new Tattoo::TattooUserInterface(vm);
+}
+
+UserInterface::UserInterface(SherlockEngine *vm) : _vm(vm) {
+ _menuMode = STD_MODE;
+ _menuCounter = 0;
+ _infoFlag = false;
+ _windowOpen = false;
+ _endKeyActive = true;
+ _invLookFlag = 0;
+ _slideWindows = true;
+ _helpStyle = false;
+ _windowBounds = Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH - 1, SHERLOCK_SCREEN_HEIGHT - 1);
+ _lookScriptFlag = false;
+ _exitZone = -1;
+
+ _bgFound = _oldBgFound = -1;
+ _key = _oldKey = '\0';
+ _selector = _oldSelector = -1;
+ _temp = _oldTemp = 0;
+ _temp1 = 0;
+ _lookHelp = 0;
+}
+
+void UserInterface::checkAction(ActionType &action, int objNum, FixedTextActionId fixedTextActionId) {
+ Events &events = *_vm->_events;
+ FixedText &fixedText = *_vm->_fixedText;
+ People &people = *_vm->_people;
+ Scene &scene = *_vm->_scene;
+ Screen &screen = *_vm->_screen;
+ Talk &talk = *_vm->_talk;
+ Point32 pt(-1, -1);
+
+ if (action._useFlag)
+ // Automatically set the given flag
+ _vm->setFlags(action._useFlag);
+
+ if (objNum >= 1000)
+ // Ignore actions done on characters
+ return;
+
+ if (!action._cAnimSpeed) {
+ // Invalid action, to print error message
+ _infoFlag = true;
+ clearInfo();
+ Common::String errorMessage = fixedText.getActionMessage(fixedTextActionId, action._cAnimNum);
+ screen.print(Common::Point(0, INFO_LINE + 1), COL_INFO_FOREGROUND, "%s", errorMessage.c_str());
+ _infoFlag = true;
+
+ // Set how long to show the message
+ _menuCounter = 30;
+ } else {
+ Object &obj = scene._bgShapes[objNum];
+
+ int cAnimNum;
+ if (action._cAnimNum == 0)
+ // Really a 10
+ cAnimNum = 9;
+ else
+ cAnimNum = action._cAnimNum - 1;
+
+ int dir = -1;
+ if (action._cAnimNum != 99) {
+ CAnim &anim = scene._cAnim[cAnimNum];
+
+ if (action._cAnimNum != 99) {
+ if (action._cAnimSpeed & REVERSE_DIRECTION) {
+ pt = anim._teleport[0];
+ dir = anim._teleport[0]._facing;
+ } else {
+ pt = anim._goto[0];
+ dir = anim._goto[0]._facing;
+ }
+ }
+ } else {
+ pt = Point32(-1, -1);
+ dir = -1;
+ }
+
+ // Has a value, so do action
+ // Show wait cursor whilst walking to object and doing action
+ events.setCursor(WAIT);
+ bool printed = false;
+
+ for (int nameIdx = 0; nameIdx < NAMES_COUNT; ++nameIdx) {
+ if (action._names[nameIdx].hasPrefix("*") && action._names[nameIdx].size() >= 2
+ && toupper(action._names[nameIdx][1]) == 'W') {
+ if (obj.checkNameForCodes(Common::String(action._names[nameIdx].c_str() + 2), fixedTextActionId)) {
+ if (!talk._talkToAbort)
+ printed = true;
+ }
+ }
+ }
+
+ bool doCAnim = true;
+ for (int nameIdx = 0; nameIdx < NAMES_COUNT; ++nameIdx) {
+ if (action._names[nameIdx].hasPrefix("*") && action._names[nameIdx].size() >= 2) {
+ char ch = toupper(action._names[nameIdx][1]);
+
+ if (ch == 'T' || ch == 'B') {
+ printed = true;
+ if (pt.x != -1)
+ // Holmes needs to walk to object before the action is done
+ people[HOLMES].walkToCoords(pt, dir);
+
+ if (!talk._talkToAbort) {
+ // Ensure Holmes is on the exact intended location
+ people[HOLMES]._position = pt;
+ people[HOLMES]._sequenceNumber = dir;
+ people[HOLMES].gotoStand();
+
+ talk.talkTo(action._names[nameIdx].c_str() + 2);
+ if (ch == 'T')
+ doCAnim = false;
+ }
+ }
+ }
+ }
+
+ if (doCAnim && !talk._talkToAbort) {
+ if (pt.x != -1)
+ // Holmes needs to walk to object before the action is done
+ people[HOLMES].walkToCoords(pt, dir);
+ }
+
+ for (int nameIdx = 0; nameIdx < NAMES_COUNT; ++nameIdx) {
+ if (action._names[nameIdx].hasPrefix("*") && action._names[nameIdx].size() >= 2
+ && toupper(action._names[nameIdx][1]) == 'F') {
+ if (obj.checkNameForCodes(action._names[nameIdx].c_str() + 2, fixedTextActionId)) {
+ if (!talk._talkToAbort)
+ printed = true;
+ }
+ }
+ }
+
+ if (doCAnim && !talk._talkToAbort && action._cAnimNum != 99)
+ scene.startCAnim(cAnimNum, action._cAnimSpeed);
+
+ if (!talk._talkToAbort) {
+ for (int nameIdx = 0; nameIdx < NAMES_COUNT && !talk._talkToAbort; ++nameIdx) {
+ if (obj.checkNameForCodes(action._names[nameIdx], fixedTextActionId)) {
+ if (!talk._talkToAbort)
+ printed = true;
+ }
+ }
+
+ // Unless we're leaving the scene, print a "Done" message unless the printed flag has been set
+ if (IS_SERRATED_SCALPEL && scene._goToScene != 1 && !printed && !talk._talkToAbort) {
+ _infoFlag = true;
+ clearInfo();
+ screen.print(Common::Point(0, INFO_LINE + 1), COL_INFO_FOREGROUND, "Done...");
+
+ // Set how long to show the message
+ _menuCounter = 30;
+ }
+ }
+ }
+
+ // Reset cursor back to arrow
+ events.setCursor(ARROW);
+}
+
+void UserInterface::reset() {
+ _bgFound = _oldBgFound = -1;
+ _oldKey = -1;
+ _oldTemp = _temp = -1;
+ _exitZone = -1;
+}
+
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h
new file mode 100644
index 0000000000..9af5ad5ae6
--- /dev/null
+++ b/engines/sherlock/user_interface.h
@@ -0,0 +1,138 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SHERLOCK_UI_H
+#define SHERLOCK_UI_H
+
+#include "common/scummsys.h"
+#include "common/events.h"
+#include "sherlock/surface.h"
+#include "sherlock/objects.h"
+#include "sherlock/resources.h"
+#include "sherlock/fixed_text.h"
+
+namespace Sherlock {
+
+#define CONTROLS_Y 138
+#define CONTROLS_Y1 151
+
+enum MenuMode {
+ STD_MODE = 0,
+ LOOK_MODE = 1,
+ MOVE_MODE = 2,
+ TALK_MODE = 3,
+ PICKUP_MODE = 4,
+ OPEN_MODE = 5,
+ CLOSE_MODE = 6,
+ INV_MODE = 7,
+ USE_MODE = 8,
+ GIVE_MODE = 9,
+ JOURNAL_MODE = 10,
+ FILES_MODE = 11,
+ SETUP_MODE = 12,
+
+ // Rose Tattoo specific
+ LAB_MODE = 20,
+ MESSAGE_MODE = 21,
+ VERB_MODE = 22
+};
+
+class UserInterface {
+protected:
+ SherlockEngine *_vm;
+
+ UserInterface(SherlockEngine *vm);
+public:
+ MenuMode _menuMode;
+ int _menuCounter;
+ bool _infoFlag;
+ bool _windowOpen;
+ bool _endKeyActive;
+ int _invLookFlag;
+ bool _slideWindows;
+ bool _helpStyle;
+ Common::Rect _windowBounds;
+ bool _lookScriptFlag;
+ int _bgFound, _oldBgFound;
+ int _exitZone;
+
+ // TODO: Not so sure these should be in the base class. May want to refactor them to SherlockEngine, or refactor
+ // various Scalpel dialogs to keep their own private state of key/selections
+ signed char _key, _oldKey;
+ int _selector, _oldSelector;
+ int _temp, _oldTemp;
+ int _temp1;
+ int _lookHelp;
+public:
+ static UserInterface *init(SherlockEngine *vm);
+ virtual ~UserInterface() {}
+
+ /**
+ * Called for OPEN, CLOSE, and MOVE actions are being done
+ */
+ void checkAction(ActionType &action, int objNum, FixedTextActionId fixedTextActionId = kFixedTextAction_Invalid);
+public:
+ /**
+ * Resets the user interface
+ */
+ virtual void reset();
+
+ /**
+ * Draw the user interface onto the screen's back buffers
+ */
+ virtual void drawInterface(int bufferNum = 3) {}
+
+ /**
+ * Main input handler for the user interface
+ */
+ virtual void handleInput() {}
+
+ /**
+ * Displays a passed window by gradually scrolling it vertically on-screen
+ */
+ virtual void summonWindow(const Surface &bgSurface, bool slideUp = true) {}
+
+ /**
+ * Slide the window stored in the back buffer onto the screen
+ */
+ virtual void summonWindow(bool slideUp = true, int height = CONTROLS_Y) {}
+
+ /**
+ * Close a currently open window
+ * @param flag 0 = slide old window down, 1 = slide prior UI back up
+ */
+ virtual void banishWindow(bool slideUp = true) {}
+
+ /**
+ * Clears the info line of the screen
+ */
+ virtual void clearInfo() {}
+
+ /**
+ * Clear any active text window
+ */
+ virtual void clearWindow() {}
+};
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sky/music/adlibchannel.cpp b/engines/sky/music/adlibchannel.cpp
index 8400fef6eb..c7acb9b6c1 100644
--- a/engines/sky/music/adlibchannel.cpp
+++ b/engines/sky/music/adlibchannel.cpp
@@ -29,7 +29,7 @@
namespace Sky {
-AdLibChannel::AdLibChannel(FM_OPL *opl, uint8 *pMusicData, uint16 startOfData) {
+AdLibChannel::AdLibChannel(OPL::OPL *opl, uint8 *pMusicData, uint16 startOfData) {
_opl = opl;
_musicData = pMusicData;
_channelData.loopPoint = startOfData;
@@ -45,6 +45,8 @@ AdLibChannel::AdLibChannel(FM_OPL *opl, uint8 *pMusicData, uint16 startOfData) {
_channelData.frequency = 0;
_channelData.instrumentData = NULL;
+ _musicVolume = 128;
+
uint16 instrumentDataLoc;
if (SkyEngine::_systemVars.gameVersion == 109) {
@@ -86,7 +88,7 @@ bool AdLibChannel::isActive() {
}
void AdLibChannel::updateVolume(uint16 pVolume) {
- // Do nothing. The mixer handles the music volume for us.
+ _musicVolume = pVolume;
}
/* This class uses the same area for the register mirror as the original
@@ -95,7 +97,7 @@ void AdLibChannel::updateVolume(uint16 pVolume) {
*/
void AdLibChannel::setRegister(uint8 regNum, uint8 value) {
if (_adlibRegMirror[regNum] != value) {
- OPLWriteReg (_opl, regNum, value);
+ _opl->writeReg(regNum, value);
_adlibRegMirror[regNum] = value;
}
}
@@ -208,6 +210,8 @@ void AdLibChannel::setupChannelVolume(uint8 volume) {
uint32 resVol = ((volume + 1) * (_channelData.instrumentData->totOutLev_Op2 + 1)) << 1;
resVol &= 0xFFFF;
resVol *= (_channelData.channelVolume + 1) << 1;
+ resVol >>= 8;
+ resVol *= _musicVolume << 1;
resVol >>= 16;
assert(resVol < 0x81);
resultOp = ((_channelData.instrumentData->scalingLevel << 6) & 0xC0) | _opOutputTable[resVol];
@@ -216,6 +220,8 @@ void AdLibChannel::setupChannelVolume(uint8 volume) {
resVol = ((volume + 1) * (_channelData.instrumentData->totOutLev_Op1 + 1)) << 1;
resVol &= 0xFFFF;
resVol *= (_channelData.channelVolume + 1) << 1;
+ resVol >>= 8;
+ resVol *= _musicVolume << 1;
resVol >>= 16;
} else
resVol = _channelData.instrumentData->totOutLev_Op1;
diff --git a/engines/sky/music/adlibchannel.h b/engines/sky/music/adlibchannel.h
index 80dae93b2c..4504e3b570 100644
--- a/engines/sky/music/adlibchannel.h
+++ b/engines/sky/music/adlibchannel.h
@@ -60,14 +60,15 @@ typedef struct {
class AdLibChannel : public ChannelBase {
public:
- AdLibChannel (FM_OPL *opl, uint8 *pMusicData, uint16 startOfData);
+ AdLibChannel (OPL::OPL *opl, uint8 *pMusicData, uint16 startOfData);
virtual ~AdLibChannel();
virtual uint8 process(uint16 aktTime);
virtual void updateVolume(uint16 pVolume);
virtual bool isActive();
private:
- FM_OPL *_opl;
+ OPL::OPL *_opl;
uint8 *_musicData;
+ uint16 _musicVolume;
AdLibChannelType _channelData;
InstrumentStruct *_instruments;
diff --git a/engines/sky/music/adlibmusic.cpp b/engines/sky/music/adlibmusic.cpp
index dd64c5bc81..be5e7b2353 100644
--- a/engines/sky/music/adlibmusic.cpp
+++ b/engines/sky/music/adlibmusic.cpp
@@ -22,6 +22,7 @@
#include "common/endian.h"
+#include "common/textconsole.h"
#include "sky/music/adlibmusic.h"
#include "sky/music/adlibchannel.h"
@@ -32,44 +33,21 @@ namespace Sky {
AdLibMusic::AdLibMusic(Audio::Mixer *pMixer, Disk *pDisk) : MusicBase(pMixer, pDisk) {
_driverFileBase = 60202;
- _sampleRate = pMixer->getOutputRate();
- _opl = makeAdLibOPL(_sampleRate);
+ _opl = OPL::Config::create();
+ if (!_opl || !_opl->init())
+ error("Failed to create OPL");
- _mixer->playStream(Audio::Mixer::kMusicSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
+ _opl->start(new Common::Functor0Mem<void, AdLibMusic>(this, &AdLibMusic::onTimer), 50);
}
AdLibMusic::~AdLibMusic() {
- OPLDestroy(_opl);
- _mixer->stopHandle(_soundHandle);
+ delete _opl;
}
-int AdLibMusic::readBuffer(int16 *data, const int numSamples) {
- if (_musicData == NULL) {
- // no music loaded
- memset(data, 0, numSamples * sizeof(int16));
- } else if ((_currentMusic == 0) || (_numberOfChannels == 0)) {
- // music loaded but not played as of yet
- memset(data, 0, numSamples * sizeof(int16));
- // poll anyways as pollMusic() can activate the music
+void AdLibMusic::onTimer() {
+ if (_musicData != NULL)
pollMusic();
- _nextMusicPoll = _sampleRate / 50;
- } else {
- uint32 render;
- uint remaining = numSamples;
- while (remaining) {
- render = (remaining > _nextMusicPoll) ? _nextMusicPoll : remaining;
- remaining -= render;
- _nextMusicPoll -= render;
- YM3812UpdateOne(_opl, data, render);
- data += render;
- if (_nextMusicPoll == 0) {
- pollMusic();
- _nextMusicPoll = _sampleRate / 50;
- }
- }
- }
- return numSamples;
}
void AdLibMusic::setupPointers() {
@@ -87,7 +65,6 @@ void AdLibMusic::setupPointers() {
_musicDataLoc = READ_LE_UINT16(_musicData + 0x1201);
_initSequence = _musicData + 0xE91;
}
- _nextMusicPoll = 0;
}
void AdLibMusic::setupChannels(uint8 *channelData) {
@@ -102,26 +79,15 @@ void AdLibMusic::setupChannels(uint8 *channelData) {
void AdLibMusic::startDriver() {
uint16 cnt = 0;
while (_initSequence[cnt] || _initSequence[cnt + 1]) {
- OPLWriteReg (_opl, _initSequence[cnt], _initSequence[cnt + 1]);
+ _opl->writeReg(_initSequence[cnt], _initSequence[cnt + 1]);
cnt += 2;
}
}
void AdLibMusic::setVolume(uint16 param) {
_musicVolume = param;
- _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, 2 * param);
-}
-
-bool AdLibMusic::isStereo() const {
- return false;
-}
-
-bool AdLibMusic::endOfData() const {
- return false;
-}
-
-int AdLibMusic::getRate() const {
- return _sampleRate;
+ for (uint8 cnt = 0; cnt < _numberOfChannels; cnt++)
+ _channels[cnt]->updateVolume(_musicVolume);
}
} // End of namespace Sky
diff --git a/engines/sky/music/adlibmusic.h b/engines/sky/music/adlibmusic.h
index 886eef026e..7b51f2d3a0 100644
--- a/engines/sky/music/adlibmusic.h
+++ b/engines/sky/music/adlibmusic.h
@@ -25,32 +25,32 @@
#include "sky/music/musicbase.h"
#include "audio/audiostream.h"
-#include "audio/fmopl.h"
+
+namespace OPL {
+class OPL;
+}
namespace Sky {
-class AdLibMusic : public Audio::AudioStream, public MusicBase {
+class AdLibMusic : public MusicBase {
public:
AdLibMusic(Audio::Mixer *pMixer, Disk *pDisk);
~AdLibMusic();
// AudioStream API
- int readBuffer(int16 *buffer, const int numSamples);
- bool isStereo() const;
- bool endOfData() const;
- int getRate() const;
virtual void setVolume(uint16 param);
private:
- FM_OPL *_opl;
- Audio::SoundHandle _soundHandle;
+ OPL::OPL *_opl;
uint8 *_initSequence;
- uint32 _sampleRate, _nextMusicPoll;
+ uint32 _sampleRate;
virtual void setupPointers();
virtual void setupChannels(uint8 *channelData);
virtual void startDriver();
void premixerCall(int16 *buf, uint len);
+
+ void onTimer();
};
} // End of namespace Sky
diff --git a/engines/sword25/fmv/movieplayer.cpp b/engines/sword25/fmv/movieplayer.cpp
index 5d7dcf2506..eb0f0390dc 100644
--- a/engines/sword25/fmv/movieplayer.cpp
+++ b/engines/sword25/fmv/movieplayer.cpp
@@ -123,7 +123,7 @@ void MoviePlayer::update() {
if (_decoder.endOfVideo()) {
// Movie complete, so unload the movie
unloadMovie();
- } else {
+ } else if (_decoder.needsUpdate()) {
const Graphics::Surface *s = _decoder.decodeNextFrame();
if (s) {
// Transfer the next frame
diff --git a/engines/sword25/kernel/outputpersistenceblock.cpp b/engines/sword25/kernel/outputpersistenceblock.cpp
index 9003b5d58a..3e25fce5c7 100644
--- a/engines/sword25/kernel/outputpersistenceblock.cpp
+++ b/engines/sword25/kernel/outputpersistenceblock.cpp
@@ -41,6 +41,13 @@ OutputPersistenceBlock::OutputPersistenceBlock() {
_data.reserve(INITIAL_BUFFER_SIZE);
}
+void OutputPersistenceBlock::write(const void *data, uint32 size) {
+ writeMarker(BLOCK_MARKER);
+
+ write(size);
+ rawWrite(data, size);
+}
+
void OutputPersistenceBlock::write(int32 value) {
writeMarker(SINT_MARKER);
value = TO_LE_32(value);
diff --git a/engines/sword25/kernel/outputpersistenceblock.h b/engines/sword25/kernel/outputpersistenceblock.h
index c7d8dfc6aa..bdbd20d3e0 100644
--- a/engines/sword25/kernel/outputpersistenceblock.h
+++ b/engines/sword25/kernel/outputpersistenceblock.h
@@ -41,6 +41,7 @@ class OutputPersistenceBlock : public PersistenceBlock {
public:
OutputPersistenceBlock();
+ void write(const void *data, uint32 size);
void write(int32 value);
void write(uint32 value);
void write(float value);
diff --git a/engines/sword25/module.mk b/engines/sword25/module.mk
index 234baec165..0842eb9aa8 100644
--- a/engines/sword25/module.mk
+++ b/engines/sword25/module.mk
@@ -82,9 +82,10 @@ MODULE_OBJS := \
util/lua/lvm.o \
util/lua/lzio.o \
util/lua/scummvm_file.o \
- util/pluto/pdep.o \
- util/pluto/pluto.o \
- util/pluto/plzio.o
+ util/double_serialization.o \
+ util/lua_persistence_util.o \
+ util/lua_persist.o \
+ util/lua_unpersist.o
# This module can be built as a plugin
ifeq ($(ENABLE_SWORD25), DYNAMIC_PLUGIN)
diff --git a/engines/sword25/script/luascript.cpp b/engines/sword25/script/luascript.cpp
index f62a08005b..e93289596b 100644
--- a/engines/sword25/script/luascript.cpp
+++ b/engines/sword25/script/luascript.cpp
@@ -29,7 +29,7 @@
*
*/
-#include "common/array.h"
+#include "common/memstream.h"
#include "common/debug-channels.h"
#include "sword25/sword25.h"
@@ -43,7 +43,7 @@
#include "sword25/util/lua/lua.h"
#include "sword25/util/lua/lualib.h"
#include "sword25/util/lua/lauxlib.h"
-#include "sword25/util/pluto/pluto.h"
+#include "sword25/util/lua_persistence.h"
namespace Sword25 {
@@ -112,10 +112,6 @@ bool LuaScriptEngine::init() {
// Place the error handler function in the Lua registry, and remember the index
_pcallErrorhandlerRegistryIndex = luaL_ref(_state, LUA_REGISTRYINDEX);
- // Initialize the Pluto-Persistence library
- luaopen_pluto(_state);
- lua_pop(_state, 1);
-
// Initialize debugging callback
if (DebugMan.isDebugChannelEnabled(kDebugScript)) {
int mask = 0;
@@ -383,19 +379,8 @@ bool pushPermanentsTable(lua_State *L, PERMANENT_TABLE_TYPE tableType) {
return true;
}
-}
-
-namespace {
-int chunkwriter(lua_State *L, const void *p, size_t sz, void *ud) {
- Common::Array<byte> & chunkData = *reinterpret_cast<Common::Array<byte> * >(ud);
- const byte *buffer = reinterpret_cast<const byte *>(p);
- while (sz--)
- chunkData.push_back(*buffer++);
-
- return 1;
-}
-}
+} // End of anonymous namespace
bool LuaScriptEngine::persist(OutputPersistenceBlock &writer) {
// Empty the Lua stack. pluto_persist() xepects that the stack is empty except for its parameters
@@ -409,12 +394,12 @@ bool LuaScriptEngine::persist(OutputPersistenceBlock &writer) {
pushPermanentsTable(_state, PTT_PERSIST);
lua_getglobal(_state, "_G");
- // Lua persists and stores the data in a Common::Array
- Common::Array<byte> chunkData;
- pluto_persist(_state, chunkwriter, &chunkData);
+ // Lua persists and stores the data in a WriteStream
+ Common::MemoryWriteStreamDynamic writeStream;
+ Lua::persistLua(_state, &writeStream);
// Persistenzdaten in den Writer schreiben.
- writer.writeByteArray(chunkData);
+ writer.write(writeStream.getData(), writeStream.size());
// Die beiden Tabellen vom Stack nehmen.
lua_pop(_state, 2);
@@ -424,24 +409,6 @@ bool LuaScriptEngine::persist(OutputPersistenceBlock &writer) {
namespace {
-struct ChunkreaderData {
- void *BufferPtr;
- size_t Size;
- bool BufferReturned;
-};
-
-const char *chunkreader(lua_State *L, void *ud, size_t *sz) {
- ChunkreaderData &cd = *reinterpret_cast<ChunkreaderData *>(ud);
-
- if (!cd.BufferReturned) {
- cd.BufferReturned = true;
- *sz = cd.Size;
- return reinterpret_cast<const char *>(cd.BufferPtr);
- } else {
- return 0;
- }
-}
-
void clearGlobalTable(lua_State *L, const char **exceptions) {
// Iterate over all elements of the global table
lua_pushvalue(L, LUA_GLOBALSINDEX);
@@ -479,7 +446,8 @@ void clearGlobalTable(lua_State *L, const char **exceptions) {
// Perform garbage collection, so that all removed elements are deleted
lua_gc(L, LUA_GCCOLLECT, 0);
}
-}
+
+} // End of anonymous namespace
bool LuaScriptEngine::unpersist(InputPersistenceBlock &reader) {
// Empty the Lua stack. pluto_persist() xepects that the stack is empty except for its parameters
@@ -512,14 +480,9 @@ bool LuaScriptEngine::unpersist(InputPersistenceBlock &reader) {
// Persisted Lua data
Common::Array<byte> chunkData;
reader.readByteArray(chunkData);
+ Common::MemoryReadStream readStream(&chunkData[0], chunkData.size(), DisposeAfterUse::NO);
- // Chunk-Reader initialisation. It is used with pluto_unpersist to restore read data
- ChunkreaderData cd;
- cd.BufferPtr = &chunkData[0];
- cd.Size = chunkData.size();
- cd.BufferReturned = false;
-
- pluto_unpersist(_state, chunkreader, &cd);
+ Lua::unpersistLua(_state, &readStream);
// Permanents-Table is removed from stack
lua_remove(_state, -2);
@@ -527,7 +490,7 @@ bool LuaScriptEngine::unpersist(InputPersistenceBlock &reader) {
// The read elements in the global table about
lua_pushnil(_state);
while (lua_next(_state, -2) != 0) {
- // The referenec to the global table (_G) must not be overwritten, or ticks from Lua total
+ // The reference to the global table (_G) must not be overwritten, or ticks from Lua total
bool isGlobalReference = lua_isstring(_state, -2) && strcmp(lua_tostring(_state, -2), "_G") == 0;
if (!isGlobalReference) {
lua_pushvalue(_state, -2);
diff --git a/engines/sword25/util/double_serialization.cpp b/engines/sword25/util/double_serialization.cpp
new file mode 100644
index 0000000000..13fa42b6be
--- /dev/null
+++ b/engines/sword25/util/double_serialization.cpp
@@ -0,0 +1,68 @@
+/* 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 "sword25/util/double_serialization.h"
+
+#include "common/scummsys.h"
+
+
+namespace Util {
+
+SerializedDouble encodeDouble(double value) {
+ // Split the value into its significand and exponent
+ int exponent;
+ double significand = frexp(value, &exponent);
+
+ // Shift the the first part of the significand into the integer range
+ double shiftedsignificandPart = ldexp(fabs(significand), 32);
+ uint32 significandOne = uint32(floor(shiftedsignificandPart));
+
+ // Shift the remainder of the significand into the integer range
+ shiftedsignificandPart -= significandOne;
+ uint32 significandTwo = (uint32)(ldexp(shiftedsignificandPart, 31));
+
+ SerializedDouble returnValue;
+ returnValue.significandOne = significandOne; // SignificandOne
+ returnValue.signAndSignificandTwo = ((uint32)(value < 0 ? 1 : 0) << 31) | // Sign
+ significandTwo; // SignificandTwo
+ returnValue.exponent = (int16)exponent;
+ return returnValue;
+}
+
+double decodeDouble(SerializedDouble value) {
+ // Expand the exponent and the parts of the significand
+ int exponent = (int)value.exponent;
+ double expandedsignificandOne = (double)value.significandOne;
+ double expandedsignificandTwo = (double)(value.signAndSignificandTwo & 0x7FFFFFFF);
+
+ // Deflate the significand
+ double shiftedsignificand = ldexp(expandedsignificandTwo, -21);
+ double significand = ldexp(expandedsignificandOne + shiftedsignificand, -32);
+
+ // Re-calculate the actual double
+ double returnValue = ldexp(significand, exponent);
+
+ // Check the sign bit and return
+ return ((value.signAndSignificandTwo & 0x80000000) == 0x80000000) ? -returnValue : returnValue;
+}
+
+} // End of namespace Sword25
diff --git a/engines/sword25/util/double_serialization.h b/engines/sword25/util/double_serialization.h
new file mode 100644
index 0000000000..af58d03c17
--- /dev/null
+++ b/engines/sword25/util/double_serialization.h
@@ -0,0 +1,61 @@
+/* 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 DOUBLE_SERIALIZATION_H
+#define DOUBLE_SERIALIZATION_H
+
+#include "common/types.h"
+
+
+namespace Util {
+
+struct SerializedDouble {
+ uint32 significandOne;
+ uint32 signAndSignificandTwo;
+ int16 exponent;
+};
+
+struct CompactSerializedDouble {
+ uint32 signAndSignificandOne;
+ uint32 exponentAndSignificandTwo;
+};
+
+/**
+ * Encodes a double as two uint32 and a one int16
+ *
+ * Supports denormalized numbers. Does NOT support NaN, or Inf
+ *
+ * @param value The value to encode
+ * @return The encoded value
+ */
+SerializedDouble encodeDouble(double value);
+/**
+ * Decodes a previously encoded double
+ *
+ * @param value The value to decode
+ * @return The decoded value
+ */
+double decodeDouble(SerializedDouble value);
+
+} // End of namespace Sword25
+
+#endif
diff --git a/engines/sword25/util/lua_persist.cpp b/engines/sword25/util/lua_persist.cpp
new file mode 100644
index 0000000000..03f305b2c5
--- /dev/null
+++ b/engines/sword25/util/lua_persist.cpp
@@ -0,0 +1,802 @@
+/* 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.
+ *
+ */
+
+/**
+ * This code is heavily based on the Pluto code base. Copyright below
+ */
+
+/* Tamed Pluto - Heavy-duty persistence for Lua
+ * Copyright (C) 2004 by Ben Sunshine-Hill, and released into the public
+ * domain. People making use of this software as part of an application
+ * are politely requested to email the author at sneftel@gmail.com
+ * with a brief description of the application, primarily to satisfy his
+ * curiosity.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Instrumented by Stefan Reich (info@luaos.net)
+ * for Mobile Lua (http://luaos.net/pages/mobile-lua.php)
+ */
+
+
+#include "sword25/util/lua_persistence.h"
+
+#include "sword25/util/double_serialization.h"
+#include "sword25/util/lua_persistence_util.h"
+
+#include "common/stream.h"
+
+#include "lua/lobject.h"
+#include "lua/lstate.h"
+#include "lua/lgc.h"
+
+
+namespace Lua {
+
+#define PERMANENT_TYPE 101
+
+struct SerializationInfo {
+ lua_State *luaState;
+ Common::WriteStream *writeStream;
+ uint counter;
+};
+
+static void persist(SerializationInfo *info);
+
+static void persistBoolean(SerializationInfo *info);
+static void persistNumber(SerializationInfo *info);
+static void persistString(SerializationInfo *info);
+static void persistTable(SerializationInfo *info);
+static void persistFunction(SerializationInfo *info);
+static void persistThread(SerializationInfo *info);
+static void persistProto(SerializationInfo *info);
+static void persistUpValue(SerializationInfo *info);
+static void persistUserData(SerializationInfo *info);
+
+
+void persistLua(lua_State *luaState, Common::WriteStream *writeStream) {
+ SerializationInfo info;
+ info.luaState = luaState;
+ info.writeStream = writeStream;
+ info.counter = 1u;
+
+ // The process starts with the lua stack as follows:
+ // >>>>> permTbl rootObj
+ // That's the table of permanents and the root object to be serialized
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(luaState, 4);
+ assert(lua_gettop(luaState) == 2);
+ // And that the root isn't nil
+ assert(!lua_isnil(luaState, 2));
+
+ // Create a table to hold indexes of everything that's serialized
+ // This allows us to only serialize an object once
+ // Every other time, just reference the index
+ lua_newtable(luaState);
+ // >>>>> permTbl rootObj indexTbl
+
+ // Now we're going to make the table weakly keyed. This prevents the
+ // GC from visiting it and trying to mark things it doesn't want to
+ // mark in tables, e.g. upvalues. All objects in the table are
+ // a priori reachable, so it doesn't matter that we do this.
+
+ // Create the metatable
+ lua_newtable(luaState);
+ // >>>>> permTbl rootObj indexTbl metaTbl
+
+ lua_pushstring(luaState, "__mode");
+ // >>>>> permTbl rootObj indexTbl metaTbl "__mode"
+
+ lua_pushstring(luaState, "k");
+ // >>>>> permTbl rootObj indexTbl metaTbl "__mode" "k"
+
+ lua_settable(luaState, 4);
+ // >>>>> permTbl rootObj indexTbl metaTbl
+
+ lua_setmetatable(luaState, 3);
+ // >>>>> permTbl rootObj indexTbl
+
+ // Swap the indexTable and the rootObj
+ lua_insert(luaState, 2);
+ // >>>>> permTbl indexTbl rootObj
+
+ // Serialize the root recursively
+ persist(&info);
+
+ // Return the stack back to the original state
+ lua_remove(luaState, 2);
+ // >>>>> permTbl rootObj
+}
+
+static void persist(SerializationInfo *info) {
+ // The stack can potentially have many things on it
+ // The object we want to serialize is the item on the top of the stack
+ // >>>>> permTbl indexTbl rootObj ...... obj
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 2);
+
+ // If the object has already been written, don't write it again
+ // Instead write the index of the object from the indexTbl
+
+ // Check the indexTbl
+ lua_pushvalue(info->luaState, -1);
+ // >>>>> permTbl indexTbl rootObj ...... obj obj
+
+ lua_rawget(info->luaState, 2);
+ // >>>>> permTbl indexTbl rootObj ...... obj ?index?
+
+ // If the index isn't nil, the object has already been written
+ if (!lua_isnil(info->luaState, -1)) {
+ // Write out a flag that indicates that it's an index
+ info->writeStream->writeByte(0);
+
+ // Retrieve the index from the stack
+ uint *index = (uint *)lua_touserdata(info->luaState, -1);
+
+ // Write out the index
+ info->writeStream->writeUint32LE(*index);
+
+ // Pop the index off the stack
+ lua_pop(info->luaState, 1);
+
+ return;
+ }
+
+ // Pop the index/nil off the stack
+ lua_pop(info->luaState, 1);
+
+ // If the obj itself is nil, we represent it as an index of 0
+ if (lua_isnil(info->luaState, -1)) {
+ // Write out a flag that indicates that it's an index
+ info->writeStream->writeByte(0);
+ // Write out the index
+ info->writeStream->writeUint32LE(0);
+
+ return;
+ }
+
+ // Write out a flag that indicates that this is a real object
+ info->writeStream->writeByte(1);
+
+ // Add the object to the indexTbl
+
+ lua_pushvalue(info->luaState, -1);
+ // >>>>> permTbl indexTbl rootObj ...... obj obj
+
+ uint *ref = (uint *)lua_newuserdata(info->luaState, sizeof(uint));
+ *ref = ++(info->counter);
+ // >>>>> permTbl indexTbl rootObj ...... obj obj index
+
+ lua_rawset(info->luaState, 2);
+ // >>>>> permTbl indexTbl rootObj ...... obj
+
+
+ // Write out the index
+ info->writeStream->writeUint32LE(info->counter);
+
+
+ // Objects that are in the permanents table are serialized in a special way
+
+ lua_pushvalue(info->luaState, -1);
+ // >>>>> permTbl indexTbl rootObj ...... obj obj
+
+ lua_gettable(info->luaState, 1);
+ // >>>>> permTbl indexTbl rootObj ...... obj obj ?permKey?
+
+ if (!lua_isnil(info->luaState, -1)) {
+ // Write out the type
+ info->writeStream->writeSint32LE(PERMANENT_TYPE);
+
+ // Serialize the key
+ persist(info);
+
+ // Pop the key off the stack
+ lua_pop(info->luaState, 1);
+
+ return;
+ }
+
+ // Pop the nil off the stack
+ lua_pop(info->luaState, 1);
+
+ // Query the type of the object
+ int objType = lua_type(info->luaState, -1);
+
+ // Write it out
+ info->writeStream->writeSint32LE(objType);
+
+ // Serialize the object by its type
+
+ switch (objType) {
+ case LUA_TBOOLEAN:
+ persistBoolean(info);
+ break;
+ case LUA_TLIGHTUSERDATA:
+ // You can't serialize a pointer
+ // It would be meaningless on the next run
+ assert(0);
+ break;
+ case LUA_TNUMBER:
+ persistNumber(info);
+ break;
+ case LUA_TSTRING:
+ persistString(info);
+ break;
+ case LUA_TTABLE:
+ persistTable(info);
+ break;
+ case LUA_TFUNCTION:
+ persistFunction(info);
+ break;
+ case LUA_TTHREAD:
+ persistThread(info);
+ break;
+ case LUA_TPROTO:
+ persistProto(info);
+ break;
+ case LUA_TUPVAL:
+ persistUpValue(info);
+ break;
+ case LUA_TUSERDATA:
+ persistUserData(info);
+ break;
+ default:
+ assert(0);
+ }
+}
+
+static void persistBoolean(SerializationInfo *info) {
+ int value = lua_toboolean(info->luaState, -1);
+
+ info->writeStream->writeSint32LE(value);
+}
+
+static void persistNumber(SerializationInfo *info) {
+ lua_Number value = lua_tonumber(info->luaState, -1);
+
+ Util::SerializedDouble serializedValue(Util::encodeDouble(value));
+
+ info->writeStream->writeUint32LE(serializedValue.significandOne);
+ info->writeStream->writeUint32LE(serializedValue.signAndSignificandTwo);
+ info->writeStream->writeSint16LE(serializedValue.exponent);
+}
+
+static void persistString(SerializationInfo *info) {
+ // Hard cast to a uint32 to force size_t to an explicit size
+ // *Theoretically* this could truncate, but if we have a 4gb string, we have bigger problems
+ uint32 length = static_cast<uint32>(lua_strlen(info->luaState, -1));
+ info->writeStream->writeUint32LE(length);
+
+ const char *str = lua_tostring(info->luaState, -1);
+ info->writeStream->write(str, length);
+}
+
+/* Choose whether to do a regular or special persistence based on an object's
+ * metatable. "default" is whether the object, if it doesn't have a __persist
+ * entry, is literally persistable or not.
+ * Pushes the unpersist closure and returns true if special persistence is
+ * used. */
+static bool serializeSpecialObject(SerializationInfo *info, bool defaction) {
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 4);
+
+ // Check whether we should persist literally, or via the __persist metafunction
+ if (!lua_getmetatable(info->luaState, -1)) {
+ if (defaction) {
+ // Write out a flag declaring that the object isn't special and should be persisted normally
+ info->writeStream->writeSint32LE(0);
+
+ return false;
+ } else {
+ lua_pushstring(info->luaState, "Type not literally persistable by default");
+ lua_error(info->luaState);
+
+ return false; // Not reached
+ }
+ }
+
+ // >>>>> permTbl indexTbl ...... obj metaTbl
+ lua_pushstring(info->luaState, "__persist");
+ // >>>>> permTbl indexTbl rootObj ...... obj metaTbl "__persist"
+
+ lua_rawget(info->luaState, -2);
+ // >>>>> permTbl indexTbl ...... obj metaTbl ?__persist?
+
+ if (lua_isnil(info->luaState, -1)) {
+ // >>>>> permTbl indexTbl ...... obj metaTbl nil
+ lua_pop(info->luaState, 2);
+ // >>>>> permTbl indexTbl ...... obj
+
+ if (defaction) {
+ // Write out a flag declaring that the object isn't special and should be persisted normally
+ info->writeStream->writeSint32LE(0);
+
+ return false;
+ } else {
+ lua_pushstring(info->luaState, "Type not literally persistable by default");
+ lua_error(info->luaState);
+
+ return false; // Return false
+ }
+
+ } else if (lua_isboolean(info->luaState, -1)) {
+ // >>>>> permTbl indexTbl ...... obj metaTbl bool
+ if (lua_toboolean(info->luaState, -1)) {
+ // Write out a flag declaring that the object isn't special and should be persisted normally
+ info->writeStream->writeSint32LE(0);
+
+ // >>>>> permTbl indexTbl ...... obj metaTbl true */
+ lua_pop(info->luaState, 2);
+ // >>>>> permTbl indexTbl ...... obj
+
+ return false;
+ } else {
+ lua_pushstring(info->luaState, "Metatable forbade persistence");
+ lua_error(info->luaState);
+
+ return false; // Not reached
+ }
+ } else if (!lua_isfunction(info->luaState, -1)) {
+ lua_pushstring(info->luaState, "__persist not nil, boolean, or function");
+ lua_error(info->luaState);
+ }
+
+ // >>>>> permTbl indexTbl ...... obj metaTbl __persist
+ lua_pushvalue(info->luaState, -3);
+ // >>>>> permTbl indexTbl ...... obj metaTbl __persist obj
+
+ // >>>>> permTbl indexTbl ...... obj metaTbl ?func?
+
+ if (!lua_isfunction(info->luaState, -1)) {
+ lua_pushstring(info->luaState, "__persist function did not return a function");
+ lua_error(info->luaState);
+ }
+
+ // >>>>> permTbl indexTbl ...... obj metaTbl func
+
+ // Write out a flag that the function exists
+ info->writeStream->writeSint32LE(1);
+
+ // Serialize the function
+ persist(info);
+
+ lua_pop(info->luaState, 2);
+ // >>>>> permTbl indexTbl ...... obj
+
+ return true;
+}
+
+static void persistTable(SerializationInfo *info) {
+ // >>>>> permTbl indexTbl ...... tbl
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 3);
+
+ // Test if the object needs special serialization
+ if (serializeSpecialObject(info, 1)) {
+ return;
+ }
+
+ // >>>>> permTbl indexTbl ...... tbl
+
+ // First, serialize the metatable (if any)
+ if (!lua_getmetatable(info->luaState, -1)) {
+ lua_pushnil(info->luaState);
+ }
+
+ // >>>>> permTbl indexTbl ...... tbl metaTbl/nil */
+ persist(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... tbl
+
+
+ lua_pushnil(info->luaState);
+ // >>>>> permTbl indexTbl ...... tbl nil
+
+ // Now, persist all k/v pairs
+ while (lua_next(info->luaState, -2)) {
+ // >>>>> permTbl indexTbl ...... tbl k v */
+
+ lua_pushvalue(info->luaState, -2);
+ // >>>>> permTbl indexTbl ...... tbl k v k */
+
+ // Serialize the key
+ persist(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... tbl k v */
+
+ // Serialize the value
+ persist(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... tbl k */
+ }
+
+ // >>>>> permTbl indexTbl ...... tbl
+
+ // Terminate the list with a nil
+ lua_pushnil(info->luaState);
+ // >>>>> permTbl indexTbl ...... tbl
+
+ persist(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... tbl
+}
+
+static void persistFunction(SerializationInfo *info) {
+ // >>>>> permTbl indexTbl ...... func
+ Closure *cl = clvalue(getObject(info->luaState, -1));
+ lua_checkstack(info->luaState, 2);
+
+ if (cl->c.isC) {
+ /* It's a C function. For now, we aren't going to allow
+ * persistence of C closures, even if the "C proto" is
+ * already in the permanents table. */
+ lua_pushstring(info->luaState, "Attempt to persist a C function");
+ lua_error(info->luaState);
+ } else {
+ // It's a Lua closure
+
+ // We don't really _NEED_ the number of upvals, but it'll simplify things a bit
+ info->writeStream->writeByte(cl->l.p->nups);
+
+ // Serialize the prototype
+ pushProto(info->luaState, cl->l.p);
+ // >>>>> permTbl indexTbl ...... func proto */
+
+ persist(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... func
+
+ // Serialize upvalue values (not the upvalue objects themselves)
+ for (byte i = 0; i < cl->l.p->nups; i++) {
+ // >>>>> permTbl indexTbl ...... func
+ pushUpValue(info->luaState, cl->l.upvals[i]);
+ // >>>>> permTbl indexTbl ...... func upval
+
+ persist(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... func
+ }
+
+ // >>>>> permTbl indexTbl ...... func
+
+ // Serialize function environment
+ lua_getfenv(info->luaState, -1);
+ // >>>>> permTbl indexTbl ...... func fenv
+
+ if (lua_equal(info->luaState, -1, LUA_GLOBALSINDEX)) {
+ // Function has the default fenv
+
+ // >>>>> permTbl indexTbl ...... func _G
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... func
+
+ lua_pushnil(info->luaState);
+ // >>>>> permTbl indexTbl ...... func nil
+ }
+
+ // >>>>> permTbl indexTbl ...... func fenv/nil
+ persist(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... func
+ }
+}
+
+static void persistThread(SerializationInfo *info) {
+ // >>>>> permTbl indexTbl ...... thread
+ lua_State *threadState = lua_tothread(info->luaState, -1);
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, threadState->top - threadState->stack + 1);
+
+ if (info->luaState == threadState) {
+ lua_pushstring(info->luaState, "Can't persist currently running thread");
+ lua_error(info->luaState);
+ return; /* not reached */
+ }
+
+ // Persist the stack
+
+ // We *could* have truncation here, but if we have more than 4 billion items on a stack, we have bigger problems
+ uint32 stackSize = static_cast<uint32>(appendStackToStack_reverse(threadState, info->luaState));
+ info->writeStream->writeUint32LE(stackSize);
+
+ // >>>>> permTbl indexTbl ...... thread (reversed contents of thread stack) */
+ for (; stackSize > 0; --stackSize) {
+ persist(info);
+
+ lua_pop(info->luaState, 1);
+ }
+
+ // >>>>> permTbl indexTbl ...... thread
+
+ // Now, serialize the CallInfo stack
+
+ // Again, we *could* have truncation here, but if we have more than 4 billion items on a stack, we have bigger problems
+ uint32 numFrames = static_cast<uint32>((threadState->ci - threadState->base_ci) + 1);
+ info->writeStream->writeUint32LE(numFrames);
+
+ for (uint32 i = 0; i < numFrames; i++) {
+ CallInfo *ci = threadState->base_ci + i;
+
+ // Same argument as above about truncation
+ uint32 stackBase = static_cast<uint32>(ci->base - threadState->stack);
+ uint32 stackFunc = static_cast<uint32>(ci->func - threadState->stack);
+ uint32 stackTop = static_cast<uint32>(ci->top - threadState->stack);
+
+ info->writeStream->writeUint32LE(stackBase);
+ info->writeStream->writeUint32LE(stackFunc);
+ info->writeStream->writeUint32LE(stackTop);
+
+ info->writeStream->writeSint32LE(ci->nresults);
+
+ uint32 savedpc = (ci != threadState->base_ci) ? static_cast<uint32>(ci->savedpc - ci_func(ci)->l.p->code) : 0u;
+ info->writeStream->writeUint32LE(savedpc);
+ }
+
+
+ // Serialize the state's other parameters, with the exception of upval stuff
+
+ assert(threadState->nCcalls <= 1);
+ info->writeStream->writeByte(threadState->status);
+
+ // Same argument as above about truncation
+ uint32 stackBase = static_cast<uint32>(threadState->base - threadState->stack);
+ uint32 stackFunc = static_cast<uint32>(threadState->top - threadState->stack);
+ info->writeStream->writeUint32LE(stackBase);
+ info->writeStream->writeUint32LE(stackFunc);
+
+ // Same argument as above about truncation
+ uint32 stackOffset = static_cast<uint32>(threadState->errfunc);
+ info->writeStream->writeUint32LE(stackOffset);
+
+ // Finally, record upvalues which need to be reopened
+ // See the comment above serializeUpVal() for why we do this
+
+ UpVal *upVal;
+
+ // >>>>> permTbl indexTbl ...... thread
+ for (GCObject *gcObject = threadState->openupval; gcObject != NULL; gcObject = upVal->next) {
+ upVal = gco2uv(gcObject);
+
+ /* Make sure upvalue is really open */
+ assert(upVal->v != &upVal->u.value);
+
+ pushUpValue(info->luaState, upVal);
+ // >>>>> permTbl indexTbl ...... thread upVal
+
+ persist(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... thread
+
+ // Same argument as above about truncation
+ uint32 stackpos = static_cast<uint32>(upVal->v - threadState->stack);
+ info->writeStream->writeUint32LE(stackpos);
+ }
+
+ // >>>>> permTbl indexTbl ...... thread
+ lua_pushnil(info->luaState);
+ // >>>>> permTbl indexTbl ...... thread nil
+
+ // Use nil as a terminator
+ persist(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... thread
+}
+
+static void persistProto(SerializationInfo *info) {
+ // >>>>> permTbl indexTbl ...... proto
+ Proto *proto = gco2p(getObject(info->luaState, -1)->value.gc);
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 2);
+
+ // Serialize constant refs */
+ info->writeStream->writeSint32LE(proto->sizek);
+
+ for (int i = 0; i < proto->sizek; ++i) {
+ pushObject(info->luaState, &proto->k[i]);
+ // >>>>> permTbl indexTbl ...... proto const
+
+ persist(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... proto
+ }
+
+ // >>>>> permTbl indexTbl ...... proto
+
+ // Serialize inner Proto refs
+ info->writeStream->writeSint32LE(proto->sizep);
+
+ for (int i = 0; i < proto->sizep; ++i) {
+ pushProto(info->luaState, proto->p[i]);
+ // >>>>> permTbl indexTbl ...... proto subProto */
+
+ persist(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... proto
+ }
+
+ // >>>>> permTbl indexTbl ...... proto
+
+ // Serialize the code
+ info->writeStream->writeSint32LE(proto->sizecode);
+
+ uint32 len = static_cast<uint32>(sizeof(Instruction) * proto->sizecode);
+ info->writeStream->write(proto->code, len);
+
+
+ // Serialize upvalue names
+ info->writeStream->writeSint32LE(proto->sizeupvalues);
+
+ for (int i = 0; i < proto->sizeupvalues; ++i) {
+ pushString(info->luaState, proto->upvalues[i]);
+ // >>>>> permTbl indexTbl ...... proto str
+
+ persist(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... proto
+ }
+
+
+ // Serialize local variable infos
+ info->writeStream->writeSint32LE(proto->sizelocvars);
+
+ for (int i = 0; i < proto->sizelocvars; ++i) {
+ pushString(info->luaState, proto->locvars[i].varname);
+ // >>>>> permTbl indexTbl ...... proto str
+
+ persist(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... proto
+
+ info->writeStream->writeSint32LE(proto->locvars[i].startpc);
+ info->writeStream->writeSint32LE(proto->locvars[i].endpc);
+ }
+
+
+ // Serialize source string
+ pushString(info->luaState, proto->source);
+ // >>>>> permTbl indexTbl ...... proto sourceStr
+
+ persist(info);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... proto
+
+ // Serialize line numbers
+ info->writeStream->writeSint32LE(proto->sizelineinfo);
+
+ if (proto->sizelineinfo) {
+ len = static_cast<uint32>(sizeof(int) * proto->sizelineinfo);
+ info->writeStream->write(proto->lineinfo, len);
+ }
+
+ // Serialize linedefined and lastlinedefined
+ info->writeStream->writeSint32LE(proto->linedefined);
+ info->writeStream->writeSint32LE(proto->lastlinedefined);
+
+
+ // Serialize misc values
+ info->writeStream->writeByte(proto->nups);
+ info->writeStream->writeByte(proto->numparams);
+ info->writeStream->writeByte(proto->is_vararg);
+ info->writeStream->writeByte(proto->maxstacksize);
+}
+
+/* Upvalues are tricky. Here's why.
+ *
+ * A particular upvalue may be either "open", in which case its member v
+ * points into a thread's stack, or "closed" in which case it points to the
+ * upvalue itself. An upvalue is closed under any of the following conditions:
+ * -- The function that initially declared the variable "local" returns
+ * -- The thread in which the closure was created is garbage collected
+ *
+ * To make things wackier, just because a thread is reachable by Lua doesn't
+ * mean it's in our root set. We need to be able to treat an open upvalue
+ * from an unreachable thread as a closed upvalue.
+ *
+ * The solution:
+ * (a) For the purposes of serializing, don't indicate whether an upvalue is
+ * closed or not.
+ * (b) When unserializing, pretend that all upvalues are closed.
+ * (c) When serializing, persist all open upvalues referenced by a thread
+ * that is persisted, and tag each one with the corresponding stack position
+ * (d) When unserializing, "reopen" each of these upvalues as the thread is
+ * unserialized
+ */
+static void persistUpValue(SerializationInfo *info) {
+ // >>>>> permTbl indexTbl ...... upval
+ assert(ttype(getObject(info->luaState, -1)) == LUA_TUPVAL);
+ UpVal *upValue = gco2uv(getObject(info->luaState, -1)->value.gc);
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 1);
+
+ // We can't permit the upValue to linger around on the stack, as Lua
+ // will bail if its GC finds it.
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ......
+
+ pushObject(info->luaState, upValue->v);
+ // >>>>> permTbl indexTbl ...... obj
+
+ persist(info);
+ // >>>>> permTbl indexTbl ...... obj
+}
+
+static void persistUserData(SerializationInfo *info) {
+ // >>>>> permTbl rootObj ...... udata
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 2);
+
+ // Test if the object needs special serialization
+ if (serializeSpecialObject(info, 0)) {
+ return;
+ }
+
+ // Use literal persistence
+
+ // Hard cast to a uint32 length
+ // This could lead to truncation, but if we have a 4gb block of data, we have bigger problems
+ uint32 length = static_cast<uint32>(uvalue(getObject(info->luaState, -1))->len);
+ info->writeStream->writeUint32LE(length);
+
+ info->writeStream->write(lua_touserdata(info->luaState, -1), length);
+
+ // Serialize the metatable (if any)
+ if (!lua_getmetatable(info->luaState, -1)) {
+ lua_pushnil(info->luaState);
+ }
+
+ // >>>>> permTbl rootObj ...... udata metaTbl/nil
+ persist(info);
+
+ lua_pop(info->luaState, 1);
+ /* perms reftbl ... udata */
+}
+
+
+} // End of namespace Lua
diff --git a/engines/sword25/util/lua_persistence.h b/engines/sword25/util/lua_persistence.h
new file mode 100644
index 0000000000..53e3dee02e
--- /dev/null
+++ b/engines/sword25/util/lua_persistence.h
@@ -0,0 +1,67 @@
+/* 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.
+ *
+ */
+
+/**
+ * This code is heavily based on the Pluto code base. Copyright below
+ */
+
+/* Tamed Pluto - Heavy-duty persistence for Lua
+ * Copyright (C) 2004 by Ben Sunshine-Hill, and released into the public
+ * domain. People making use of this software as part of an application
+ * are politely requested to email the author at sneftel@gmail.com
+ * with a brief description of the application, primarily to satisfy his
+ * curiosity.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Instrumented by Stefan Reich (info@luaos.net)
+ * for Mobile Lua (http://luaos.net/pages/mobile-lua.php)
+ */
+
+#ifndef LUA_PERSISTENCE_H
+#define LUA_PERSISTENCE_H
+
+#include "sword25/util/lua/lua.h"
+
+
+namespace Common {
+class WriteStream;
+class ReadStream;
+}
+
+
+namespace Lua {
+
+#define PERMANENT_TYPE 101
+
+void persistLua(lua_State *luaState, Common::WriteStream *writeStream);
+void unpersistLua(lua_State *luaState, Common::ReadStream *readStream);
+
+} // End of namespace Lua
+
+#endif
diff --git a/engines/sword25/util/lua_persistence_util.cpp b/engines/sword25/util/lua_persistence_util.cpp
new file mode 100644
index 0000000000..958fb7ac3c
--- /dev/null
+++ b/engines/sword25/util/lua_persistence_util.cpp
@@ -0,0 +1,393 @@
+/* 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 distri8buted 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.
+ *
+ */
+
+/**
+ * This code is heavily based on the pluto code base. Copyright below
+ */
+
+/* Tamed Pluto - Heavy-duty persistence for Lua
+ * Copyright (C) 2004 by Ben Sunshine-Hill, and released into the public
+ * domain. People making use of this software as part of an application
+ * are politely requested to email the author at sneftel@gmail.com
+ * with a brief description of the application, primarily to satisfy his
+ * curiosity.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Instrumented by Stefan Reich (info@luaos.net)
+ * for Mobile Lua (http://luaos.net/pages/mobile-lua.php)
+ */
+
+/**
+ * This code is heavily based on the Pluto code base. Copyright below
+ */
+
+/* Tamed Pluto - Heavy-duty persistence for Lua
+ * Copyright (C) 2004 by Ben Sunshine-Hill, and released into the public
+ * domain. People making use of this software as part of an application
+ * are politely requested to email the author at sneftel@gmail.com
+ * with a brief description of the application, primarily to satisfy his
+ * curiosity.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Instrumented by Stefan Reich (info@luaos.net)
+ * for Mobile Lua (http://luaos.net/pages/mobile-lua.php)
+ */
+
+
+#include "sword25/util/lua_persistence_util.h"
+
+#include "common/scummsys.h"
+
+#include "lua/lobject.h"
+#include "lua/lstate.h"
+#include "lua/lgc.h"
+#include "lua/lopcodes.h"
+
+
+namespace Lua {
+
+void *lua_realloc(lua_State *luaState, void *block, size_t osize, size_t nsize) {
+ global_State *globalState = G(luaState);
+
+ block = (*globalState->frealloc)(globalState->ud, block, osize, nsize);
+ globalState->totalbytes = (globalState->totalbytes - osize) + nsize;
+
+ return block;
+}
+
+void pushObject(lua_State *luaState, TValue *obj) {
+ setobj2s(luaState, luaState->top, obj);
+
+ api_check(luaState, luaState->top < luaState->ci->top);
+ luaState->top++;
+}
+
+void pushProto(lua_State *luaState, Proto *proto) {
+ TValue obj;
+ setptvalue(luaState, &obj, proto);
+
+ pushObject(luaState, &obj);
+}
+
+void pushUpValue(lua_State *luaState, UpVal *upval) {
+ TValue obj;
+
+ obj.value.gc = cast(GCObject *, upval);
+ obj.tt = LUA_TUPVAL;
+ checkliveness(G(L), obj);
+
+ pushObject(luaState, &obj);
+}
+
+void pushString(lua_State *luaState, TString *str) {
+ TValue o;
+ setsvalue(luaState, &o, str);
+
+ pushObject(luaState, &o);
+}
+
+/* A simple reimplementation of the unfortunately static function luaA_index.
+ * Does not support the global table, registry, or upvalues. */
+StkId getObject(lua_State *luaState, int stackpos) {
+ if (stackpos > 0) {
+ lua_assert(luaState->base + stackpos - 1 < luaState->top);
+ return luaState->base + stackpos - 1;
+ } else {
+ lua_assert(L->top - stackpos >= L->base);
+ return luaState->top + stackpos;
+ }
+}
+
+void lua_linkObjToGC(lua_State *luaState, GCObject *obj, lu_byte type) {
+ global_State *globalState = G(luaState);
+
+ obj->gch.next = globalState->rootgc;
+ globalState->rootgc = obj;
+ obj->gch.marked = luaC_white(globalState);
+ obj->gch.tt = type;
+}
+
+Closure *lua_newLclosure(lua_State *luaState, int numElements, Table *elementTable) {
+ Closure *c = (Closure *)lua_malloc(luaState, sizeLclosure(numElements));
+ lua_linkObjToGC(luaState, obj2gco(c), LUA_TFUNCTION);
+
+ c->l.isC = 0;
+ c->l.env = elementTable;
+ c->l.nupvalues = cast_byte(numElements);
+
+ while (numElements--) {
+ c->l.upvals[numElements] = NULL;
+ }
+
+ return c;
+}
+
+void pushClosure(lua_State *luaState, Closure *closure) {
+ TValue obj;
+ setclvalue(luaState, &obj, closure);
+ pushObject(luaState, &obj);
+}
+
+Proto *createProto(lua_State *luaState) {
+ Proto *newProto = (Proto *)lua_malloc(luaState, sizeof(Proto));
+ lua_linkObjToGC(luaState, obj2gco(newProto), LUA_TPROTO);
+
+ newProto->k = NULL;
+ newProto->sizek = 0;
+ newProto->p = NULL;
+ newProto->sizep = 0;
+ newProto->code = NULL;
+ newProto->sizecode = 0;
+ newProto->sizelineinfo = 0;
+ newProto->sizeupvalues = 0;
+ newProto->nups = 0;
+ newProto->upvalues = NULL;
+ newProto->numparams = 0;
+ newProto->is_vararg = 0;
+ newProto->maxstacksize = 0;
+ newProto->lineinfo = NULL;
+ newProto->sizelocvars = 0;
+ newProto->locvars = NULL;
+ newProto->linedefined = 0;
+ newProto->lastlinedefined = 0;
+ newProto->source = NULL;
+
+ return newProto;
+}
+
+TString *createString(lua_State *luaState, const char *str, size_t len) {
+ TString *res;
+ lua_pushlstring(luaState, str, len);
+
+ res = rawtsvalue(luaState->top - 1);
+ lua_pop(luaState, 1);
+
+ return res;
+}
+
+Proto *makeFakeProto(lua_State *L, lu_byte nups) {
+ Proto *p = createProto(L);
+
+ p->sizelineinfo = 1;
+ p->lineinfo = lua_newVector(L, 1, int);
+ p->lineinfo[0] = 1;
+ p->sizecode = 1;
+ p->code = lua_newVector(L, 1, Instruction);
+ p->code[0] = CREATE_ABC(OP_RETURN, 0, 1, 0);
+ p->source = createString(L, "", 0);
+ p->maxstacksize = 2;
+ p->nups = nups;
+ p->sizek = 0;
+ p->sizep = 0;
+
+ return p;
+}
+
+UpVal *createUpValue(lua_State *luaState, int stackpos) {
+ UpVal *upValue = (UpVal *)lua_malloc(luaState, sizeof(UpVal));
+ lua_linkObjToGC(luaState, (GCObject *)upValue, LUA_TUPVAL);
+ upValue->tt = LUA_TUPVAL;
+ upValue->v = &upValue->u.value;
+ upValue->u.l.prev = NULL;
+ upValue->u.l.next = NULL;
+
+ const TValue *o2 = (TValue *)getObject(luaState, stackpos);
+ upValue->v->value = o2->value;
+ upValue->v->tt = o2->tt;
+ checkliveness(G(L), upValue->v);
+
+ return upValue;
+}
+
+void unboxUpValue(lua_State *luaState) {
+ // >>>>> ...... func
+ LClosure *lcl;
+ UpVal *uv;
+
+ lcl = (LClosure *)clvalue(getObject(luaState, -1));
+ uv = lcl->upvals[0];
+
+ lua_pop(luaState, 1);
+ // >>>>> ......
+
+ pushUpValue(luaState, uv);
+ // >>>>> ...... upValue
+}
+
+size_t appendStackToStack_reverse(lua_State *from, lua_State *to) {
+ for (StkId id = from->top - 1; id >= from->stack; --id) {
+ setobj2s(to, to->top, id);
+ to->top++;
+ }
+
+ return from->top - from->stack;
+}
+
+void correctStack(lua_State *L, TValue *oldstack) {
+ CallInfo *ci;
+ GCObject *up;
+ L->top = (L->top - oldstack) + L->stack;
+ for (up = L->openupval; up != NULL; up = up->gch.next)
+ gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack;
+ for (ci = L->base_ci; ci <= L->ci; ci++) {
+ ci->top = (ci->top - oldstack) + L->stack;
+ ci->base = (ci->base - oldstack) + L->stack;
+ ci->func = (ci->func - oldstack) + L->stack;
+ }
+ L->base = (L->base - oldstack) + L->stack;
+}
+
+void lua_reallocstack(lua_State *L, int newsize) {
+ TValue *oldstack = L->stack;
+ int realsize = newsize + 1 + EXTRA_STACK;
+
+ lua_reallocvector(L, L->stack, L->stacksize, realsize, TValue);
+ L->stacksize = realsize;
+ L->stack_last = L->stack + newsize;
+ correctStack(L, oldstack);
+}
+
+void lua_growstack(lua_State *L, int n) {
+ // Double size is enough?
+ if (n <= L->stacksize) {
+ lua_reallocstack(L, 2 * L->stacksize);
+ } else {
+ lua_reallocstack(L, L->stacksize + n);
+ }
+}
+
+void lua_reallocCallInfo(lua_State *lauState, int newsize) {
+ CallInfo *oldci = lauState->base_ci;
+ lua_reallocvector(lauState, lauState->base_ci, lauState->size_ci, newsize, CallInfo);
+
+ lauState->size_ci = newsize;
+ lauState->ci = (lauState->ci - oldci) + lauState->base_ci;
+ lauState->end_ci = lauState->base_ci + lauState->size_ci - 1;
+}
+
+void GCUnlink(lua_State *luaState, GCObject *gco) {
+ GCObject *prevslot;
+ if (G(luaState)->rootgc == gco) {
+ G(luaState)->rootgc = G(luaState)->rootgc->gch.next;
+ return;
+ }
+
+ prevslot = G(luaState)->rootgc;
+ while (prevslot->gch.next != gco) {
+ prevslot = prevslot->gch.next;
+ }
+
+ prevslot->gch.next = prevslot->gch.next->gch.next;
+}
+
+TString *lua_newlstr(lua_State *luaState, const char *str, size_t len) {
+ lua_pushlstring(luaState, str, len);
+ TString *luaStr = &(luaState->top - 1)->value.gc->ts;
+
+ lua_pop(luaState, 1);
+
+ return luaStr;
+}
+
+void lua_link(lua_State *luaState, GCObject *o, lu_byte tt) {
+ global_State *g = G(luaState);
+ o->gch.next = g->rootgc;
+ g->rootgc = o;
+ o->gch.marked = luaC_white(g);
+ o->gch.tt = tt;
+}
+
+Proto *lua_newproto(lua_State *luaState) {
+ Proto *f = (Proto *)lua_malloc(luaState, sizeof(Proto));
+ lua_link(luaState, obj2gco(f), LUA_TPROTO);
+ f->k = NULL;
+ f->sizek = 0;
+ f->p = NULL;
+ f->sizep = 0;
+ f->code = NULL;
+ f->sizecode = 0;
+ f->sizelineinfo = 0;
+ f->sizeupvalues = 0;
+ f->nups = 0;
+ f->upvalues = NULL;
+ f->numparams = 0;
+ f->is_vararg = 0;
+ f->maxstacksize = 0;
+ f->lineinfo = NULL;
+ f->sizelocvars = 0;
+ f->locvars = NULL;
+ f->linedefined = 0;
+ f->lastlinedefined = 0;
+ f->source = NULL;
+ return f;
+}
+
+UpVal *makeUpValue(lua_State *luaState, int stackPos) {
+ UpVal *uv = lua_new(luaState, UpVal);
+ lua_link(luaState, (GCObject *)uv, LUA_TUPVAL);
+ uv->tt = LUA_TUPVAL;
+ uv->v = &uv->u.value;
+ uv->u.l.prev = NULL;
+ uv->u.l.next = NULL;
+
+ setobj(luaState, uv->v, getObject(luaState, stackPos));
+
+ return uv;
+}
+
+void boxUpValue_start(lua_State *luaState) {
+ LClosure *closure;
+ closure = (LClosure *)lua_newLclosure(luaState, 1, hvalue(&luaState->l_gt));
+ pushClosure(luaState, (Closure *)closure);
+ // >>>>> ...... func
+ closure->p = makeFakeProto(luaState, 1);
+
+ // Temporarily initialize the upvalue to nil
+ lua_pushnil(luaState);
+ closure->upvals[0] = makeUpValue(luaState, -1);
+ lua_pop(luaState, 1);
+}
+
+void boxUpValue_finish(lua_State *luaState) {
+ // >>>>> ...... func obj
+ LClosure *lcl = (LClosure *)clvalue(getObject(luaState, -2));
+
+ lcl->upvals[0]->u.value = *getObject(luaState, -1);
+ lua_pop(luaState, 1);
+ // >>>>> ...... func
+}
+
+} // End of namespace Lua
diff --git a/engines/sword25/util/lua_persistence_util.h b/engines/sword25/util/lua_persistence_util.h
new file mode 100644
index 0000000000..4d0085e242
--- /dev/null
+++ b/engines/sword25/util/lua_persistence_util.h
@@ -0,0 +1,122 @@
+/* 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 distri8buted 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.
+ *
+ */
+
+/**
+ * This code is heavily based on the Pluto code base. Copyright below
+ */
+
+/* Tamed Pluto - Heavy-duty persistence for Lua
+ * Copyright (C) 2004 by Ben Sunshine-Hill, and released into the public
+ * domain. People making use of this software as part of an application
+ * are politely requested to email the author at sneftel@gmail.com
+ * with a brief description of the application, primarily to satisfy his
+ * curiosity.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Instrumented by Stefan Reich (info@luaos.net)
+ * for Mobile Lua (http://luaos.net/pages/mobile-lua.php)
+ */
+
+
+#ifndef LUA_PERISTENCE_UTIL_H
+#define LUA_PERISTENCE_UTIL_H
+
+
+struct lua_State;
+
+#include "lua/lobject.h"
+
+typedef TValue *StkId;
+
+namespace Lua {
+
+#define lua_malloc(luaState, nsize) lua_realloc(luaState, nullptr, 0, nsize)
+#define lua_reallocv(luaState, block, on, n, e) lua_realloc(luaState, block, (on) * (e), (n) * (e))
+#define lua_reallocvector(luaState, vec, oldn, n, T) ((vec) = (T *)(lua_reallocv(luaState, vec, oldn, n, sizeof(T))))
+#define lua_newVector(luaState, num, T) ((T *)lua_reallocv(luaState, nullptr, 0, num, sizeof(T)))
+#define lua_new(luaState,T) (T *)lua_malloc(luaState, sizeof(T))
+
+void *lua_realloc(lua_State *luaState, void *block, size_t osize, size_t nsize);
+
+void pushObject(lua_State *luaState, TValue *obj);
+void pushProto(lua_State *luaState, Proto *proto);
+void pushUpValue(lua_State *luaState, UpVal *upval);
+void pushString(lua_State *luaState, TString *str);
+
+StkId getObject(lua_State *luaState, int stackpos);
+
+void lua_linkObjToGC(lua_State *luaState, GCObject *obj, lu_byte type);
+
+#define sizeLclosure(n) ((sizeof(LClosure)) + sizeof(TValue *) * ((n) - 1))
+
+Closure *lua_newLclosure(lua_State *luaState, int numElements, Table *elementTable);
+void pushClosure(lua_State *luaState, Closure *closure);
+
+Proto *createProto(lua_State *luaState);
+Proto *makeFakeProto(lua_State *L, lu_byte nups);
+
+TString *createString(lua_State *luaState, const char *str, size_t len);
+
+UpVal *createUpValue(lua_State *luaState, int stackpos);
+void unboxUpValue(lua_State *luaState);
+
+/* Appends one stack to another stack, but the stack is reversed in the process */
+size_t appendStackToStack_reverse(lua_State *from, lua_State *to);
+void correctStack(lua_State *L, TValue *oldstack);
+void lua_reallocstack(lua_State *L, int newsize);
+void lua_growstack(lua_State *L, int n);
+
+void lua_reallocCallInfo(lua_State *lauState, int newsize);
+
+/* Does basically the opposite of luaC_link().
+ * Right now this function is rather inefficient; it requires traversing the
+ * entire root GC set in order to find one object. If the GC list were doubly
+ * linked this would be much easier, but there's no reason for Lua to have
+ * that. */
+void GCUnlink(lua_State *luaState, GCObject *gco);
+
+TString *lua_newlstr(lua_State *luaState, const char *str, size_t len);
+void lua_link(lua_State *luaState, GCObject *o, lu_byte tt);
+Proto *lua_newproto(lua_State *luaState) ;
+
+UpVal *makeUpValue(lua_State *luaState, int stackPos);
+/**
+ * The GC is not fond of finding upvalues in tables. We get around this
+ * during persistence using a weakly keyed table, so that the GC doesn't
+ * bother to mark them. This won't work in unpersisting, however, since
+ * if we make the values weak they'll be collected (since nothing else
+ * references them). Our solution, during unpersisting, is to represent
+ * upvalues as dummy functions, each with one upvalue.
+ */
+void boxUpValue_start(lua_State *luaState);
+void boxUpValue_finish(lua_State *luaState);
+
+} // End of namespace Lua
+
+#endif
diff --git a/engines/sword25/util/lua_unpersist.cpp b/engines/sword25/util/lua_unpersist.cpp
new file mode 100644
index 0000000000..ef0ef31041
--- /dev/null
+++ b/engines/sword25/util/lua_unpersist.cpp
@@ -0,0 +1,722 @@
+/* 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.
+ *
+ */
+
+/**
+ * This code is heavily based on the Pluto code base. Copyright below
+ */
+
+/* Tamed Pluto - Heavy-duty persistence for Lua
+ * Copyright (C) 2004 by Ben Sunshine-Hill, and released into the public
+ * domain. People making use of this software as part of an application
+ * are politely requested to email the author at sneftel@gmail.com
+ * with a brief description of the application, primarily to satisfy his
+ * curiosity.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Instrumented by Stefan Reich (info@luaos.net)
+ * for Mobile Lua (http://luaos.net/pages/mobile-lua.php)
+ */
+
+
+#include "sword25/util/lua_persistence.h"
+
+#include "sword25/util/double_serialization.h"
+#include "sword25/util/lua_persistence_util.h"
+
+#include "common/stream.h"
+
+#include "lua/lobject.h"
+#include "lua/lstate.h"
+#include "lua/lgc.h"
+#include "lua/lopcodes.h"
+
+
+namespace Lua {
+
+struct UnSerializationInfo {
+ lua_State *luaState;
+ Common::ReadStream *readStream;
+};
+
+static void unpersist(UnSerializationInfo *info);
+
+static void unpersistBoolean(UnSerializationInfo *info);
+static void unpersistNumber(UnSerializationInfo *info);
+static void unpersistString(UnSerializationInfo *info);
+static void unpersistTable(UnSerializationInfo *info, int index);
+static void unpersistFunction(UnSerializationInfo *info, int index);
+static void unpersistThread(UnSerializationInfo *info, int index);
+static void unpersistProto(UnSerializationInfo *info, int index);
+static void unpersistUpValue(UnSerializationInfo *info, int index);
+static void unpersistUserData(UnSerializationInfo *info, int index);
+static void unpersistPermanent(UnSerializationInfo *info, int index);
+
+
+void unpersistLua(lua_State *luaState, Common::ReadStream *readStream) {
+ UnSerializationInfo info;
+ info.luaState = luaState;
+ info.readStream = readStream;
+
+ // The process starts with the lua stack as follows:
+ // >>>>> permTbl
+ // That's the table of permanents
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(luaState, 3);
+
+ // Create a table to hold indexes of everything thats already been read
+ lua_newtable(luaState);
+ // >>>>> permTbl indexTbl
+
+ // Prevent garbage collection while we unserialize
+ lua_gc(luaState, LUA_GCSTOP, 0);
+
+ // Unserialize the root object
+ unpersist(&info);
+ // >>>>> permTbl indexTbl rootObj
+
+ // Re-start garbage collection
+ lua_gc(luaState, LUA_GCRESTART, 0);
+
+ // Remove the indexTbl
+ lua_replace(luaState, 2);
+ // >>>>> permTbl rootObj
+}
+
+/* The object is left on the stack. This is primarily used by unserialize, but
+ * may be used by GCed objects that may incur cycles in order to preregister
+ * the object. */
+static void registerObjectInIndexTable(UnSerializationInfo *info, int index) {
+ // >>>>> permTbl indexTbl ...... obj
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 2);
+
+ lua_pushlightuserdata(info->luaState, (void *)index);
+ // >>>>> permTbl indexTbl ...... obj index
+
+ lua_pushvalue(info->luaState, -2);
+ // >>>>> permTbl indexTbl ...... obj index obj
+
+ // Push the k/v pair into the indexTbl
+ lua_settable(info->luaState, 2);
+ // >>>>> permTbl indexTbl ...... obj
+}
+
+static void unpersist(UnSerializationInfo *info) {
+ // >>>>> permTbl indexTbl ......
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 2);
+
+ byte isARealValue = info->readStream->readByte();
+ if (isARealValue) {
+ int index = info->readStream->readSint32LE();
+ int type = info->readStream->readSint32LE();
+
+ switch (type) {
+ case LUA_TBOOLEAN:
+ unpersistBoolean(info);
+ break;
+ case LUA_TLIGHTUSERDATA:
+ // You can't serialize a pointer
+ // It would be meaningless on the next run
+ assert(0);
+ break;
+ case LUA_TNUMBER:
+ unpersistNumber(info);
+ break;
+ case LUA_TSTRING:
+ unpersistString(info);
+ break;
+ case LUA_TTABLE:
+ unpersistTable(info, index);
+ break;
+ case LUA_TFUNCTION:
+ unpersistFunction(info, index);
+ break;
+ case LUA_TTHREAD:
+ unpersistThread(info, index);
+ break;
+ case LUA_TPROTO:
+ unpersistProto(info, index);
+ break;
+ case LUA_TUPVAL:
+ unpersistUpValue(info, index);
+ break;
+ case LUA_TUSERDATA:
+ unpersistUserData(info, index);
+ break;
+ case PERMANENT_TYPE:
+ unpersistPermanent(info, index);
+ break;
+ default:
+ assert(0);
+ }
+
+
+ // >>>>> permTbl indexTbl ...... obj
+ assert(lua_type(info->luaState, -1) == type ||
+ type == PERMANENT_TYPE ||
+ // Remember, upvalues get a special dispensation, as described in boxUpValue
+ (lua_type(info->luaState, -1) == LUA_TFUNCTION && type == LUA_TUPVAL));
+
+ registerObjectInIndexTable(info, index);
+ // >>>>> permTbl indexTbl ...... obj
+ } else {
+ int index = info->readStream->readSint32LE();
+
+ if (index == 0) {
+ lua_pushnil(info->luaState);
+ // >>>>> permTbl indexTbl ...... nil
+ } else {
+ // Fetch the object from the indexTbl
+
+ lua_pushlightuserdata(info->luaState, (void *)index);
+ // >>>>> permTbl indexTbl ...... index
+
+ lua_gettable(info->luaState, 2);
+ // >>>>> permTbl indexTbl ...... ?obj?
+
+ assert(!lua_isnil(info->luaState, -1));
+ }
+ // >>>>> permTbl indexTbl ...... obj/nil
+ }
+
+ // >>>>> permTbl indexTbl ...... obj/nil
+}
+
+static void unpersistBoolean(UnSerializationInfo *info) {
+ // >>>>> permTbl indexTbl ......
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 1);
+
+ int value = info->readStream->readSint32LE();
+
+ lua_pushboolean(info->luaState, value);
+ // >>>>> permTbl indexTbl ...... bool
+}
+
+static void unpersistNumber(UnSerializationInfo *info) {
+ // >>>>> permTbl indexTbl ......
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 1);
+
+ // Read the serialized double
+ Util::SerializedDouble serializedValue;
+ serializedValue.significandOne = info->readStream->readUint32LE();
+ serializedValue.signAndSignificandTwo = info->readStream->readUint32LE();
+ serializedValue.exponent = info->readStream->readSint16LE();
+
+ lua_Number value = Util::decodeDouble(serializedValue);
+
+ lua_pushnumber(info->luaState, value);
+ // >>>>> permTbl indexTbl ...... num
+}
+
+static void unpersistString(UnSerializationInfo *info) {
+ // >>>>> permTbl indexTbl ......
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 1);
+
+ uint32 length = info->readStream->readUint32LE();
+ char *string = new char[length];
+
+ info->readStream->read(string, length);
+ lua_pushlstring(info->luaState, string, length);
+
+ // >>>>> permTbl indexTbl ...... string
+
+ delete[] string;
+}
+
+static void unserializeSpecialTable(UnSerializationInfo *info, int index) {
+ // >>>>> permTbl indexTbl ......
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 1);
+
+ unpersist(info);
+
+ // >>>>> permTbl indexTbl ...... spfunc
+ lua_call(info->luaState, 0, 1);
+ // >>>>> permTbl indexTbl ...... tbl
+}
+
+static void unserializeLiteralTable(UnSerializationInfo *info, int index) {
+ // >>>>> permTbl indexTbl ......
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 3);
+
+ // Preregister table for handling of cycles
+ lua_newtable(info->luaState);
+
+ // >>>>> permTbl indexTbl ...... tbl
+ registerObjectInIndexTable(info, index);
+ // >>>>> permTbl indexTbl ...... tbl
+
+ // Unserialize metatable
+ unpersist(info);
+ // >>>>> permTbl indexTbl ...... tbl ?metaTbl/nil?
+
+ if (lua_istable(info->luaState, -1)) {
+ // >>>>> permTbl indexTbl ...... tbl metaTbl
+ lua_setmetatable(info->luaState, -2);
+ // >>>>> permTbl indexTbl ...... tbl
+ } else {
+ // >>>>> permTbl indexTbl ...... tbl nil
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... tbl
+ }
+ // >>>>> permTbl indexTbl ...... tbl
+
+
+ while (1) {
+ // >>>>> permTbl indexTbl ...... tbl
+ unpersist(info);
+ // >>>>> permTbl indexTbl ...... tbl key/nil
+
+ // The table serialization is nil terminated
+ if (lua_isnil(info->luaState, -1)) {
+ // >>>>> permTbl indexTbl ...... tbl nil
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... tbl
+
+ break;
+ }
+
+ // >>>>> permTbl indexTbl ...... tbl key
+ unpersist(info);
+ // >>>>> permTbl indexTbl ...... tbl value
+
+ lua_rawset(info->luaState, -3);
+ // >>>>> permTbl indexTbl ...... tbl
+ }
+}
+
+void unpersistTable(UnSerializationInfo *info, int index) {
+ // >>>>> permTbl indexTbl ......
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 1);
+
+ int isSpecial = info->readStream->readSint32LE();
+
+ if (isSpecial) {
+ unserializeSpecialTable(info, index);
+ // >>>>> permTbl indexTbl ...... tbl
+ } else {
+ unserializeLiteralTable(info, index);
+ // >>>>> permTbl indexTbl ...... tbl
+ }
+}
+
+void unpersistFunction(UnSerializationInfo *info, int index) {
+ // >>>>> permTbl indexTbl ......
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 2);
+
+ byte numUpValues = info->readStream->readByte();
+
+ LClosure *lclosure = (LClosure *)lua_newLclosure(info->luaState, numUpValues, hvalue(&info->luaState->l_gt));
+ pushClosure(info->luaState, (Closure *)lclosure);
+ // >>>>> permTbl indexTbl ...... func
+
+ // Put *some* proto in the closure, before the GC can find it
+ lclosure->p = makeFakeProto(info->luaState, numUpValues);
+
+ //Also, we need to temporarily fill the upvalues
+ lua_pushnil(info->luaState);
+ // >>>>> permTbl indexTbl ...... func nil
+
+ for (byte i = 0; i < numUpValues; ++i) {
+ lclosure->upvals[i] = createUpValue(info->luaState, -1);
+ }
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... func
+
+ // I can't see offhand how a function would ever get to be self-
+ // referential, but just in case let's register it early
+ registerObjectInIndexTable(info, index);
+
+ // Now that it's safe, we can get the real proto
+ unpersist(info);
+ // >>>>> permTbl indexTbl ...... func proto
+
+ lclosure->p = gco2p(getObject(info->luaState, -1)->value.gc);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... func
+
+ for (byte i = 0; i < numUpValues; ++i) {
+ // >>>>> permTbl indexTbl ...... func
+ unpersist(info);
+ // >>>>> permTbl indexTbl ...... func func2
+
+ unboxUpValue(info->luaState);
+ // >>>>> permTbl indexTbl ...... func upValue
+ lclosure->upvals[i] = gco2uv(getObject(info->luaState, -1)->value.gc);
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... func
+ }
+
+ // Finally, the fenv
+ unpersist(info);
+
+ // >>>>> permTbl indexTbl ...... func ?fenv/nil?
+ if (!lua_isnil(info->luaState, -1)) {
+ // >>>>> permTbl indexTbl ...... func fenv
+ lua_setfenv(info->luaState, -2);
+ // >>>>> permTbl indexTbl ...... func
+ } else {
+ // >>>>> permTbl indexTbl ...... func nil
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... func
+ }
+
+ // >>>>> permTbl indexTbl ...... func
+}
+
+void unpersistThread(UnSerializationInfo *info, int index) {
+ // >>>>> permTbl indexTbl ......
+
+ lua_State *L2;
+ uint32 stacklimit = 0;
+
+ L2 = lua_newthread(info->luaState);
+ lua_checkstack(info->luaState, 3);
+
+ // L1: permTbl indexTbl ...... thread
+ // L2: (empty)
+ registerObjectInIndexTable(info, index);
+
+ // First, deserialize the object stack
+ uint32 stackSize = info->readStream->readUint32LE();
+ lua_growstack(info->luaState, (int)stackSize);
+
+ // Make sure that the first stack element (a nil, representing
+ // the imaginary top-level C function) is written to the very,
+ // very bottom of the stack
+ L2->top--;
+ for (uint32 i = 0; i < stackSize; ++i) {
+ unpersist(info);
+ // L1: permTbl indexTbl ...... thread obj*
+ }
+
+ lua_xmove(info->luaState, L2, stackSize);
+ // L1: permTbl indexTbl ...... thread
+ // L2: obj*
+
+ // Hereafter, stacks refer to L1
+
+
+ // Now, deserialize the CallInfo stack
+
+ uint32 numFrames = info->readStream->readUint32LE();
+
+ lua_reallocCallInfo(L2, numFrames * 2);
+ for (uint32 i = 0; i < numFrames; ++i) {
+ CallInfo *ci = L2->base_ci + i;
+ uint32 stackbase = info->readStream->readUint32LE();
+ uint32 stackfunc = info->readStream->readUint32LE();
+ uint32 stacktop = info->readStream->readUint32LE();
+
+ ci->nresults = info->readStream->readSint32LE();
+
+ uint32 savedpc = info->readStream->readUint32LE();
+
+ if (stacklimit < stacktop) {
+ stacklimit = stacktop;
+ }
+
+ ci->base = L2->stack + stackbase;
+ ci->func = L2->stack + stackfunc;
+ ci->top = L2->stack + stacktop;
+ ci->savedpc = (ci != L2->base_ci) ? ci_func(ci)->l.p->code + savedpc : 0;
+ ci->tailcalls = 0;
+
+ // Update the pointer each time, to keep the GC happy
+ L2->ci = ci;
+ }
+
+ // >>>>> permTbl indexTbl ...... thread
+ // Deserialize the state's other parameters, with the exception of upval stuff
+
+ L2->savedpc = L2->ci->savedpc;
+ L2->status = info->readStream->readByte();
+ uint32 stackbase = info->readStream->readUint32LE();
+ uint32 stacktop = info->readStream->readUint32LE();
+
+
+ L2->errfunc = info->readStream->readUint32LE();
+
+ L2->base = L2->stack + stackbase;
+ L2->top = L2->stack + stacktop;
+
+ // Finally, "reopen" upvalues. See serializeUpVal() for why we do this
+ UpVal *uv;
+ GCObject **nextslot = &L2->openupval;
+ global_State *g = G(L2);
+
+ while (true) {
+ unpersist(info);
+ // >>>>> permTbl indexTbl ...... thread upVal/nil
+
+ // The list is terminated by a nil
+ if (lua_isnil(info->luaState, -1)) {
+ // >>>>> permTbl indexTbl ...... thread nil
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... thread
+ break;
+ }
+
+ // >>>>> permTbl indexTbl ...... thread boxedUpVal
+ unboxUpValue(info->luaState);
+ // >>>>> permTbl indexTbl ...... thread boxedUpVal
+
+ uv = &(getObject(info->luaState, -1)->value.gc->uv);
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... thread
+
+ uint32 stackpos = info->readStream->readUint32LE();
+ uv->v = L2->stack + stackpos;
+
+ GCUnlink(info->luaState, (GCObject *)uv);
+
+ uv->marked = luaC_white(g);
+ *nextslot = (GCObject *)uv;
+ nextslot = &uv->next;
+ uv->u.l.prev = &G(L2)->uvhead;
+ uv->u.l.next = G(L2)->uvhead.u.l.next;
+ uv->u.l.next->u.l.prev = uv;
+ G(L2)->uvhead.u.l.next = uv;
+ lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
+ }
+ *nextslot = NULL;
+
+ // The stack must be valid at least to the highest value among the CallInfos
+ // 'top' and the values up to there must be filled with 'nil'
+ lua_checkstack(L2, (int)stacklimit);
+ for (StkId o = L2->top; o <= L2->top + stacklimit; ++o) {
+ setnilvalue(o);
+ }
+}
+
+void unpersistProto(UnSerializationInfo *info, int index) {
+ // >>>>> permTbl indexTbl ......
+
+ // We have to be careful. The GC expects a lot out of protos. In particular, we need
+ // to give the function a valid string for its source, and valid code, even before we
+ // actually read in the real code.
+ TString *source = lua_newlstr(info->luaState, "", 0);
+ Proto *p = lua_newproto(info->luaState);
+ p->source = source;
+ p->sizecode = 1;
+ p->code = (Instruction *)lua_reallocv(info->luaState, NULL, 0, 1, sizeof(Instruction));
+ p->code[0] = CREATE_ABC(OP_RETURN, 0, 1, 0);
+ p->maxstacksize = 2;
+ p->sizek = 0;
+ p->sizep = 0;
+
+ lua_checkstack(info->luaState, 2);
+
+ pushProto(info->luaState, p);
+ // >>>>> permTbl indexTbl ...... proto
+
+ // We don't need to register early, since protos can never ever be
+ // involved in cyclic references
+
+ // Read in constant references
+ int sizek = info->readStream->readSint32LE();
+ lua_reallocvector(info->luaState, p->k, 0, sizek, TValue);
+ for (int i = 0; i < sizek; ++i) {
+ // >>>>> permTbl indexTbl ...... proto
+ unpersist(info);
+ // >>>>> permTbl indexTbl ...... proto k
+
+ setobj2s(info->luaState, &p->k[i], getObject(info->luaState, -1));
+ p->sizek++;
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... proto
+ }
+ // >>>>> permTbl indexTbl ...... proto
+
+ // Read in sub-proto references
+
+ int sizep = info->readStream->readSint32LE();
+ lua_reallocvector(info->luaState, p->p, 0, sizep, Proto *);
+ for (int i = 0; i < sizep; ++i) {
+ // >>>>> permTbl indexTbl ...... proto
+ unpersist(info);
+ // >>>>> permTbl indexTbl ...... proto subproto
+
+ p->p[i] = (Proto *)getObject(info->luaState, -1)->value.gc;
+ p->sizep++;
+
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... proto
+ }
+ // >>>>> permTbl indexTbl ...... proto
+
+
+ // Read in code
+ p->sizecode = info->readStream->readSint32LE();
+ lua_reallocvector(info->luaState, p->code, 1, p->sizecode, Instruction);
+ info->readStream->read(p->code, sizeof(Instruction) * p->sizecode);
+
+
+ /* Read in upvalue names */
+ p->sizeupvalues = info->readStream->readSint32LE();
+ if (p->sizeupvalues) {
+ lua_reallocvector(info->luaState, p->upvalues, 0, p->sizeupvalues, TString *);
+ for (int i = 0; i < p->sizeupvalues; ++i) {
+ // >>>>> permTbl indexTbl ...... proto
+ unpersist(info);
+ // >>>>> permTbl indexTbl ...... proto str
+
+ p->upvalues[i] = lua_newlstr(info->luaState, lua_tostring(info->luaState, -1), strlen(lua_tostring(info->luaState, -1)));
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... proto
+ }
+ }
+ // >>>>> permTbl indexTbl ...... proto
+
+ // Read in local variable infos
+ p->sizelocvars = info->readStream->readSint32LE();
+ if (p->sizelocvars) {
+ lua_reallocvector(info->luaState, p->locvars, 0, p->sizelocvars, LocVar);
+ for (int i = 0; i < p->sizelocvars; ++i) {
+ // >>>>> permTbl indexTbl ...... proto
+ unpersist(info);
+ // >>>>> permTbl indexTbl ...... proto str
+
+ p->locvars[i].varname = lua_newlstr(info->luaState, lua_tostring(info->luaState, -1), strlen(lua_tostring(info->luaState, -1)));
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... proto
+
+ p->locvars[i].startpc = info->readStream->readSint32LE();
+ p->locvars[i].endpc = info->readStream->readSint32LE();
+ }
+ }
+ // >>>>> permTbl indexTbl ...... proto
+
+ // Read in source string
+ unpersist(info);
+ // >>>>> permTbl indexTbl ...... proto sourceStr
+
+ p->source = lua_newlstr(info->luaState, lua_tostring(info->luaState, -1), strlen(lua_tostring(info->luaState, -1)));
+ lua_pop(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... proto
+
+ // Read in line numbers
+ p->sizelineinfo = info->readStream->readSint32LE();
+ if (p->sizelineinfo) {
+ lua_reallocvector(info->luaState, p->lineinfo, 0, p->sizelineinfo, int);
+ info->readStream->read(p->lineinfo, sizeof(int) * p->sizelineinfo);
+ }
+
+
+ /* Read in linedefined and lastlinedefined */
+ p->linedefined = info->readStream->readSint32LE();
+ p->lastlinedefined = info->readStream->readSint32LE();
+
+ // Read in misc values
+ p->nups = info->readStream->readByte();
+ p->numparams = info->readStream->readByte();
+ p->is_vararg = info->readStream->readByte();
+ p->maxstacksize = info->readStream->readByte();
+}
+
+void unpersistUpValue(UnSerializationInfo *info, int index) {
+ // >>>>> permTbl indexTbl ......
+ lua_checkstack(info->luaState, 2);
+
+ boxUpValue_start(info->luaState);
+ // >>>>> permTbl indexTbl ...... func
+ registerObjectInIndexTable(info, index);
+
+ unpersist(info);
+ // >>>>> permTbl indexTbl ...... func obj
+
+ boxUpValue_finish(info->luaState);
+ // >>>>> permTbl indexTbl ...... func
+}
+
+void unpersistUserData(UnSerializationInfo *info, int index) {
+ // >>>>> permTbl indexTbl ......
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 2);
+
+ int isspecial = info->readStream->readSint32LE();
+ if (isspecial) {
+ unpersist(info);
+ // >>>>> permTbl indexTbl ...... specialFunc
+
+ lua_call(info->luaState, 0, 1);
+ // >>>>> permTbl indexTbl ...... udata
+ } else {
+ uint32 length = info->readStream->readUint32LE();
+ lua_newuserdata(info->luaState, length);
+ // >>>>> permTbl indexTbl ...... udata
+ registerObjectInIndexTable(info, index);
+
+ info->readStream->read(lua_touserdata(info->luaState, -1), length);
+
+ unpersist(info);
+ // >>>>> permTbl indexTbl ...... udata metaTable/nil
+
+ lua_setmetatable(info->luaState, -2);
+ // >>>>> permTbl indexTbl ...... udata
+ }
+ // >>>>> permTbl indexTbl ...... udata
+}
+
+void unpersistPermanent(UnSerializationInfo *info, int index) {
+ // >>>>> permTbl indexTbl ......
+
+ // Make sure there is enough room on the stack
+ lua_checkstack(info->luaState, 2);
+
+ unpersist(info);
+ // >>>>> permTbl indexTbl ...... permKey
+
+ lua_gettable(info->luaState, 1);
+ // >>>>> permTbl indexTbl ...... perm
+}
+
+} // End of namespace Lua
diff --git a/engines/sword25/util/pluto/CHANGELOG b/engines/sword25/util/pluto/CHANGELOG
deleted file mode 100644
index 1be321f898..0000000000
--- a/engines/sword25/util/pluto/CHANGELOG
+++ /dev/null
@@ -1,37 +0,0 @@
-$Id$
-
--- 2.4 --
-* Changed upval unboxing to allow upvals which contain func-housed cycles
-* Added stack checking to all stack-growing functions
-* Serialized debug information for functions
-
--- 2.3 --
-* Added LUALIB_API declaration for luaopen_pluto
-
--- 2.2 --
-* Rolled all internal Lua dependencies into the Pluto distribution
-* Made the unit tests depend on dynamically loading Pluto
-
--- 2.1 --
-* Various fixes to make the GC happy
-* stack size always expanded where necessary
-* fixed some memory leaks
-* GC disabled during unpersist
-* callstack initialized for traversal
-
-This changelog is maintained as of version 2.0alpha1.
-Earlier versions are changelogged on the LuaForge site.
-
--- 2.0 --
-* Fixed a few format changes to 5.1.3
-* Fixed myriad warnings
-* GCC compliance: not incrementing cast results
-* Fix for self-referring upvals
-* Renamed loading function to work with Lua module system
-* Loading tables with __newindex works
-* unpersist makes buffer copy
-
--- 2.0alpha1 --
-* Fixed all outstanding 5.0->5.1 conversion issues
-* Made heavier use of size_t in preference to int
-* Fixed GC/Upval issue (thanks to Eric Jacobs)
diff --git a/engines/sword25/util/pluto/FILEFORMAT b/engines/sword25/util/pluto/FILEFORMAT
deleted file mode 100644
index e7716675c7..0000000000
--- a/engines/sword25/util/pluto/FILEFORMAT
+++ /dev/null
@@ -1,168 +0,0 @@
-$Id$
-
-pluto_persist() produces a "hunk" of objects. Here's the file format adhered
-to by the function, and expected by pluto_unpersist().
-
-As a developer, I feel that where file format information is given it is of
-utmost importance that that information precisely and accurately reflects the
-actual operation of the application. Therefore, if you find any discrepancy
-between this and actual operation, please lambast me thoroughly over email.
-
-Pseudo-C is used to express the file format. Padding is assumed to be
-nonexistent. The keyword "one_of" is used to express a concept similar to
-"union", except that its size is the size of the actual datatype chosen. Thus,
-objects which contain, directly or indirectly, a one_of, may vary in size.
-
-
-struct Object {
- int firstTime; /* Whether this is the first time the object
- is being referenced */
- one_of {
- RealObject o; /* if firstTime == 1 */
- Reference r; /* if firstTime == 0 */
- };
-};
-
-struct Reference {
- int ref; /* The index the object was registered with */
-};
-
-struct RealObject {
- int type; /* The type of the object */
- one_of {
- Boolean b; /* If type == LUA_TBOOLEAN */
- LightUserData l; /* If type == LUA_TLIGHTUSERDATA */
- Number n; /* If type == LUA_TNUMBER */
- String s; /* If type == LUA_TSTRING */
- Table t; /* If type == LUA_TTABLE */
- Function f; /* If type == LUA_TFUNCTION */
- Userdata u; /* If type == LUA_TUSERDATA */
- Thread th; /* If type == LUA_TTHREAD */
- Proto p; /* If type == LUA_TPROTO (from lobject.h) */
- Upval uv; /* If type == LUA_TUPVAL (from lobject.h) */
- }; /* The actual object */
-};
-
-struct Boolean {
- int32 bvalue; /* 0 for false, 1 for true */
-};
-
-struct LightUserData {
- void* luvalue; /* The actual, literal pointer */
-};
-
-struct Number {
- lua_Number nvalue; /* The actual number */
-};
-
-struct String {
- int length; /* The length of the string */
- char str[length]; /* The actual string (not null terminated) */
-};
-
-struct Table {
- int isspecial; /* 1 if SP is used; 0 otherwise */
- one_of {
- Closure c; /* if isspecial == 1; closure to refill the table */
- LiteralTable t; /* if isspecial == 0; literal table info */
- };
-};
-
-struct LiteralTable {
- Object metatable; /* nil for default metatable */
- Pair p[]; /* key/value pairs */
- Object nil = nil; /* Nil reference to terminate */
-};
-
-struct Pair {
- Object key;
- Object value;
-};
-
-struct Function { /* Actually a closure */
- lu_byte nups; /* Number of upvalues the function uses */
- Object proto; /* The proto this function uses */
- Object upvals[nups]; /* All upvalues */
- Object fenv; /* The FEnv (nil for the global table)
-};
-
-struct Upval {
- Object obj; /* The object this upval refers to */
-}
-
-struct Userdata {
- int isSpecial; /* 1 for special persistence, 0 for literal
- one_of {
- LiteralUserdata lu; /* if is_special is 0 */
- SpecialUserdata su; /* if is_special is 1 */
- };
-};
-
-struct LiteralUserdata {
- Object metatable; /* The metatable (nil for default) */
- int length; /* Size of the data */
- char data[length]; /* The actual data */
-};
-
-struct SpecialUserdata {
- int length; /* The size of the data */
- Object func; /* The closure used to fill the userdata */
-};
-
-struct Thread {
- int stacksize; /* The size of the stack filled with objects,
- * including the "nil" that is hidden below
- * the bottom of the stack visible to C */
- Object stack[stacksize];/* Indices of all stack values, bottom up */
- int callinfosize; /* Number of elements in the CallInfo stack */
- CallInfo callinfostack[callinfosize]; /* The CallInfo stack */
- int base; /* base = L->base - L->stack; */
- int top; /* top = L->top - L->stack; */
- OpenUpval openupvals[]; /* Upvalues to open */
- Object nil = nil; /* To terminate the open upvalues list */
-};
-
-struct OpenUpval {
- Object upval; /* The upvalue */
- int stackpos; /* The stack position to "reopen" it to */
-
-};
-
-struct CallInfo {
- int base; /* base = ci->base - L->stack; */
- int top; /* top = ci->top - L->stack; */
- int pc; /* pc = ci->pc - proto->code; */
- int state; /* flags used by the CallInfo */
-};
-
-struct Proto {
- int sizek; /* Number of constants referenced */
- Object k[sizek]; /* Constants referenced */
- int sizep; /* Number of inner Protos referenced */
- Object p[sizep]; /* Inner Protos referenced */
- int sizecode; /* Number of instructions in code */
- Instruction code[sizecode]; /* The proto's code */
- ProtoDebug debuginfo; /* Debug information for the proto */
- lu_byte nups; /* Number of upvalues used */
- lu_byte numparams; /* Number of parameters taken */
- lu_byte is_vararg; /* 1 if function accepts varargs, 0 otherwise */
- lu_byte maxstacksize; /* Size of stack reserved for the function */
-};
-
-struct ProtoDebug {
- int sizeupvals; /* Number of upvalue names */
- Object upvals; /* Upvalue names */
- int sizelocvars; /* Number of local variable names */
- LocVar[sizelocvars]; /* Local variable names */
- Object source; /* The source code */
- int sizelineinfo; /* Number of opcode-line mappings */
- int lineinfo[sizelineinfo]; /* opcode-line mappings */
- int linedefined; /* Start of line range */
- int lastlinedefined; /* End of line range */
-};
-
-struct LocVar {
- Object name; /* Name of the local variable */
- int startpc; /* Point where variable is active */
- int endpc; /* Point where variable is dead */
-};
diff --git a/engines/sword25/util/pluto/README b/engines/sword25/util/pluto/README
deleted file mode 100644
index 838fce498b..0000000000
--- a/engines/sword25/util/pluto/README
+++ /dev/null
@@ -1,133 +0,0 @@
-$Id$
-
-PLUTO - Heavy duty persistence for Lua
-
-Pluto is a library which allows users to write arbitrarily large portions
-of the "Lua universe" into a flat file, and later read them back into the
-same or a different Lua universe. Object references are appropriately
-handled, such that the file contains everything needed to recreate the
-objects in question.
-
-Pluto has the following major features:
-* Can persist any Lua function
-* Can persist threads
-* Works with any Lua chunkreader/chunkwriter
-* Support for "invariant" permanent objects, of all datatypes
-* Can invoke metafunctions for custom persistence of tables and userdata
-
-Pluto 2.2 requires Lua 5.1.3. If you need to use Pluto with Lua
-5.0, please use version 1.2 of Pluto.
-
-Starting with version 2.2, Pluto no longer depends on the Lua sources.
-Instead, it subsumes the required headers into its own codebase.
-As a result, it may not work properly with Lua version 5.1.4 or later.
-
-Pluto may have bugs. Users are advised to define lua_assert in
-luaconf.h to something useful when compiling in debug mode, to catch
-assertions by Pluto and Lua.
-
-The Pluto library consists of two public functions.
-
-int pluto_persist(lua_State *L, lua_Chunkwriter writer, void *ud)
-
-This function recursively persists the Lua object in stack position 2
-and all other objects which are directly or indirectly referenced by
-it, except those referenced in the permanent object table. The data
-is written using the chunk-writer given, and that writer is passed
-the arbitrary pointer value ud.
-
-The Lua stack must contain exactly and only these two items, in order:
-
-1. A table of permanent objects, that should not be persisted. For each
-permanent object, the object itself should be the key, and a unique
-object of any type should be the value. Likely candidates for this table
-include Lua functions (including those in the Lua libraries) that are
-loaded at load-time. It must include all non-persistable objects that
-are referenced by the object to be persisted. The table is not modified
-by the function. Objects in this table are considered "opaque" and are
-not examined or descended into. Objects should not appear in the table
-multiple times; the result of doing this is undefined (though probably
-harmless). NOTE: If you are planning to persist threads, keep in mind
-that all yielded threads have coroutine.yield on the tops of their
-stacks. Since it's a C function, it should be put here. For complex
-permanents, it may be a good idea to use the __index meta-function of
-the permanents table to "search" for permanents.
-
-2. The single object to be persisted. In many cases, this will be the
-global table. For more flexibility, however, it may be something like a
-table built for the occasion, with various values to keep track of. The
-object may not be nil.
-
-
-int pluto_unpersist(lua_State *L, lua_Chunkreader reader, void *ud)
-
-This function loads in a Lua object and places it on top of the stack. All
-objects directly or indirectly referenced by it are also loaded.
-
-The Lua stack must contain, as its top value, a table of permanent
-objects. This table should be like the permanent object table used when
-persisting, but with the key and value of each pair reversed. These
-objects are used as substitutes for those referenced in their positions
-when persisting, and under most circumstances should be identical objects
-to those referenced in the permanents table used for persisting. It's
-okay for multiple keys to refer to the same object.
-
-
-RUNNING PLUTO FROM LUA:
-It is also possible to invoke pluto from a Lua script. The C function
-pluto_open() will register pluto.persist and pluto.unpersist, lua functions
-which operate on strings. The first takes a permanents table and a root
-object, and returns a string; the second takes a permanents table and a
-string, and returns the root object.
-
-An error will be raised if pluto.persist is called from a thread which is
-itself referenced by the root object.
-
-SPECIAL PERSISTENCE:
-Tables and userdata have special persistence semantics. These semantics are
-keyed to the value of the object's metatable's __persist member, if any. This
-member may be any of the following four values:
-1. Boolean "true": The table or userdata is persisted literally; tables are
-persisted member-by-member, and userdata are written out as literal data.
-2. Boolean "false": An error is returned, indicating that the object cannot
-be persisted.
-3. A function: This function should take one argument, the object in question,
-and return one result, a closure. This "fixup closure", in turn, will be
-persisted, and during unpersistence will be called. The closure will be
-responsible for recreating the object with the appropriate data, based on
-its upvalues.
-4. Nil, or no metatable. In the case of tables, the table is literally
-persisted. In the case of userdata, an error is returned.
-
-Here's an example of special persistence for a simple 3d vector object:
-
-vec = { x = 2, y = 1, z = 4 }
-setmetatable(vec, { __persist = function(oldtbl)
- local x = oldtbl.x
- local y = oldtbl.y
- local z = oldtbl.z
- local mt = getmetatable(oldtbl)
- return function()
- newtbl = {}
- newtbl.x = x
- newtbl.y = y
- newtbl.z = z
- setmetatable(newtbl, mt)
- return newtbl
- end
-end })
-
-Note how x, y, z, and the mt are explicitly pulled out of the table. It is
-important that the fixup closure returned not reference the original table
-directly, as that table would again be persisted as an upvalue, leading to an
-infinite loop. Also note that the object's metatable is NOT automatically
-persisted; it is necessary for the fixup closure to reset it, if it wants.
-
-LIMITATIONS/TODO:
-* Light userdata are persisted literally, as their pointer values. This
-may or may not be what you want.
-* Closures of C functions may not be persisted. Once it becomes possible
-to specify a C function "proto" as a permanent object, this restriction
-will be relaxed.
-
-BUGS: None known. Emphasis on the 'known'.
diff --git a/engines/sword25/util/pluto/THANKS b/engines/sword25/util/pluto/THANKS
deleted file mode 100644
index 443713fa61..0000000000
--- a/engines/sword25/util/pluto/THANKS
+++ /dev/null
@@ -1,9 +0,0 @@
-Pluto is surprisingly robust and useful. This would not be the case without
-the hard work and helpfulness of the following people, mentioned in no
-particular order:
-
-Ivko Stanilov
-Goran Adrinek
-Eric Jacobs
-Anolan Milanes
-Malte Thiesen
diff --git a/engines/sword25/util/pluto/pdep.cpp b/engines/sword25/util/pluto/pdep.cpp
deleted file mode 100644
index a32c43b42d..0000000000
--- a/engines/sword25/util/pluto/pdep.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/* This file is derived from the Lua source code. Please see lua.h for
-the copyright statement.
-*/
-
-#include "pdep/pdep.h"
-
-#define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;}
-
-void pdep_pushobject (lua_State *L, const TValue *o) {
- setobj2s(L, L->top, o);
- api_incr_top(L);
-}
-
-void *pdep_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
- global_State *g = G(L);
- lua_assert((osize == 0) == (block == NULL));
- block = (*g->frealloc)(g->ud, block, osize, nsize);
- lua_assert((nsize == 0) == (block == NULL));
- g->totalbytes = (g->totalbytes - osize) + nsize;
- return block;
-}
-
-void pdep_link (lua_State *L, GCObject *o, lu_byte tt) {
- global_State *g = G(L);
- o->gch.next = g->rootgc;
- g->rootgc = o;
- o->gch.marked = luaC_white(g);
- o->gch.tt = tt;
-}
-
-Proto *pdep_newproto (lua_State *L) {
- Proto *f = pdep_new(L, Proto);
- pdep_link(L, obj2gco(f), LUA_TPROTO);
- f->k = NULL;
- f->sizek = 0;
- f->p = NULL;
- f->sizep = 0;
- f->code = NULL;
- f->sizecode = 0;
- f->sizelineinfo = 0;
- f->sizeupvalues = 0;
- f->nups = 0;
- f->upvalues = NULL;
- f->numparams = 0;
- f->is_vararg = 0;
- f->maxstacksize = 0;
- f->lineinfo = NULL;
- f->sizelocvars = 0;
- f->locvars = NULL;
- f->linedefined = 0;
- f->lastlinedefined = 0;
- f->source = NULL;
- return f;
-}
-
-Closure *pdep_newLclosure (lua_State *L, int nelems, Table *e) {
- Closure *c = cast(Closure *, pdep_malloc(L, sizeLclosure(nelems)));
- pdep_link(L, obj2gco(c), LUA_TFUNCTION);
- c->l.isC = 0;
- c->l.env = e;
- c->l.nupvalues = cast_byte(nelems);
- while (nelems--) c->l.upvals[nelems] = NULL;
- return c;
-}
-
-static void correctstack (lua_State *L, TValue *oldstack) {
- CallInfo *ci;
- GCObject *up;
- L->top = (L->top - oldstack) + L->stack;
- for (up = L->openupval; up != NULL; up = up->gch.next)
- gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack;
- for (ci = L->base_ci; ci <= L->ci; ci++) {
- ci->top = (ci->top - oldstack) + L->stack;
- ci->base = (ci->base - oldstack) + L->stack;
- ci->func = (ci->func - oldstack) + L->stack;
- }
- L->base = (L->base - oldstack) + L->stack;
-}
-
-
-void pdep_reallocstack (lua_State *L, int newsize) {
- TValue *oldstack = L->stack;
- int realsize = newsize + 1 + EXTRA_STACK;
- lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1);
- pdep_reallocvector(L, L->stack, L->stacksize, realsize, TValue);
- L->stacksize = realsize;
- L->stack_last = L->stack+newsize;
- correctstack(L, oldstack);
-}
-
-void pdep_growstack (lua_State *L, int n) {
- if (n <= L->stacksize) /* double size is enough? */
- pdep_reallocstack(L, 2*L->stacksize);
- else
- pdep_reallocstack(L, L->stacksize + n);
-}
-
-void pdep_reallocCI (lua_State *L, int newsize) {
- CallInfo *oldci = L->base_ci;
- pdep_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo);
- L->size_ci = newsize;
- L->ci = (L->ci - oldci) + L->base_ci;
- L->end_ci = L->base_ci + L->size_ci - 1;
-}
-
-TString *pdep_newlstr (lua_State *L, const char *str, size_t l) {
- TString *res;
- lua_pushlstring(L, str, l);
- res = rawtsvalue(L->top-1);
- lua_pop(L, 1);
- return res;
-}
diff --git a/engines/sword25/util/pluto/pdep/README b/engines/sword25/util/pluto/pdep/README
deleted file mode 100644
index 3592754da0..0000000000
--- a/engines/sword25/util/pluto/pdep/README
+++ /dev/null
@@ -1,5 +0,0 @@
-These files are directly copied from the Lua distribution, with the
-exception of lzio.h, which is s/lua{ZM}/pdep/g and has an include removed.
-
-As such, unlike the rest of Pluto, they are released under the
-same terms as Lua. See "lua.h" for the copyright notice.
diff --git a/engines/sword25/util/pluto/pdep/lzio.h b/engines/sword25/util/pluto/pdep/lzio.h
deleted file mode 100644
index 2e37f8d202..0000000000
--- a/engines/sword25/util/pluto/pdep/lzio.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-** $Id$
-** Buffered streams
-** See Copyright Notice in lua.h
-*/
-
-
-#ifndef lzio_h
-#define lzio_h
-
-#include "sword25/util/lua/lua.h"
-
-
-#define EOZ (-1) /* end of stream */
-
-typedef struct Zio ZIO;
-
-#define char2int(c) cast(int, cast(unsigned char, (c)))
-
-#define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : pdep_fill(z))
-
-typedef struct Mbuffer {
- char *buffer;
- size_t n;
- size_t buffsize;
-} Mbuffer;
-
-#define pdep_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0)
-
-#define pdep_buffer(buff) ((buff)->buffer)
-#define pdep_sizebuffer(buff) ((buff)->buffsize)
-#define pdep_bufflen(buff) ((buff)->n)
-
-#define pdep_resetbuffer(buff) ((buff)->n = 0)
-
-
-#define pdep_resizebuffer(L, buff, size) \
- (pdep_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \
- (buff)->buffsize = size)
-
-#define pdep_freebuffer(L, buff) pdep_resizebuffer(L, buff, 0)
-
-
-LUAI_FUNC char *pdep_openspace (lua_State *L, Mbuffer *buff, size_t n);
-LUAI_FUNC void pdep_init (lua_State *L, ZIO *z, lua_Reader reader,
- void *data);
-LUAI_FUNC size_t pdep_read (ZIO* z, void* b, size_t n); /* read next n bytes */
-LUAI_FUNC int pdep_lookahead (ZIO *z);
-
-
-
-/* --------- Private Part ------------------ */
-
-struct Zio {
- size_t n; /* bytes still unread */
- const char *p; /* current position in buffer */
- lua_Reader reader;
- void* data; /* additional data */
- lua_State *L; /* Lua state (for reader) */
-};
-
-
-LUAI_FUNC int pdep_fill (ZIO *z);
-
-#endif
diff --git a/engines/sword25/util/pluto/pdep/pdep.h b/engines/sword25/util/pluto/pdep/pdep.h
deleted file mode 100644
index 664fc812b5..0000000000
--- a/engines/sword25/util/pluto/pdep/pdep.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef PDEP_H
-#define PDEP_H
-
-#include "sword25/util/lua/lua.h"
-#include "sword25/util/pluto/pdep/lzio.h"
-#include "sword25/util/lua/ldo.h"
-#include "sword25/util/lua/lfunc.h"
-#include "sword25/util/lua/lgc.h"
-#include "sword25/util/lua/llimits.h"
-#include "sword25/util/lua/lobject.h"
-#include "sword25/util/lua/lopcodes.h"
-#include "sword25/util/lua/lstate.h"
-#include "sword25/util/lua/lstring.h"
-#include "sword25/util/lua/lauxlib.h"
-
-
-#define pdep_reallocv(L,b,on,n,e) \
- pdep_realloc_(L, (b), (on)*(e), (n)*(e))
-#define pdep_reallocvector(L, v,oldn,n,t) \
- ((v)=cast(t *, pdep_reallocv(L, v, oldn, n, sizeof(t))))
-#define pdep_freearray(L, b, n, t) pdep_reallocv(L, (b), n, 0, sizeof(t))
-#define pdep_newvector(L,n,t) \
- cast(t *, pdep_reallocv(L, NULL, 0, n, sizeof(t)))
-#define pdep_new(L,t) cast(t *, pdep_malloc(L, sizeof(t)))
-#define pdep_malloc(L,t) pdep_realloc_(L, NULL, 0, (t))
-#define pdep_checkstack(L,n) \
- if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TValue)) \
- pdep_growstack(L, n); \
- else pdep_reallocstack(L, L->stacksize - EXTRA_STACK - 1);
-
-
-void pdep_pushobject (lua_State *L, const TValue *o);
-void *pdep_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize);
-void pdep_link (lua_State *L, GCObject *o, lu_byte tt);
-Proto *pdep_newproto (lua_State *L);
-Closure *pdep_newLclosure (lua_State *L, int nelems, Table *e);
-void pdep_reallocstack (lua_State *L, int newsize);
-void pdep_growstack (lua_State *L, int n);
-void pdep_reallocCI (lua_State *L, int newsize);
-TString *pdep_newlstr (lua_State *L, const char *str, size_t l);
-
-#endif
diff --git a/engines/sword25/util/pluto/pluto.cpp b/engines/sword25/util/pluto/pluto.cpp
deleted file mode 100644
index cbe16b0d5b..0000000000
--- a/engines/sword25/util/pluto/pluto.cpp
+++ /dev/null
@@ -1,2083 +0,0 @@
-/* $Id$ */
-
-/* Tamed Pluto - Heavy-duty persistence for Lua
- * Copyright (C) 2004 by Ben Sunshine-Hill, and released into the public
- * domain. People making use of this software as part of an application
- * are politely requested to email the author at sneftel@gmail.com
- * with a brief description of the application, primarily to satisfy his
- * curiosity.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Instrumented by Stefan Reich (info@luaos.net)
- * for Mobile Lua (http://luaos.net/pages/mobile-lua.php)
- */
-
-#include "sword25/util/lua/lua.h"
-#include "pluto.h"
-
-#undef TOTEXT
-
-#define USE_PDEP
-
-#ifdef USE_PDEP
-#include "pdep/pdep.h"
-#define LIF(prefix, name) pdep ## _ ## name
-#else
-#include "lapi.h"
-#include "ldo.h"
-#include "lfunc.h"
-#include "lgc.h"
-#include "llimits.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lopcodes.h"
-#include "lstate.h"
-#include "lstring.h"
-#include "lauxlib.h"
-#define LIF(prefix, name) lua ## prefix ## _ ## name
-#endif
-
-#include <string.h>
-
-
-/* Define this if you want size_t values to be written in 64-bit
- (even on 32-bit systems). Should eliminate at least one source of
- 32/64 bit incompatibility. */
-#define SIZES64
-
-
-/* #define PLUTO_DEBUG */
-
-
-#ifdef SIZES64
-#define VERSION "Tamed Pluto 1.0 with SIZES64 flag"
-#else
-#define VERSION "Tamed Pluto 1.0"
-#endif
-
-
-#ifdef PLUTO_DEBUG
-#include <stdio.h>
-#endif
-
-#define PLUTO_TPERMANENT 101
-
-#define verify(x) { int v = (int)((x)); v=v; lua_assert(v); }
-
-#define NUMTYPES 9
-static const char* typenames[] = {
- "nil",
- "boolean",
- "lightuserdata",
- "number",
- "string",
- "table",
- "function",
- "userdata",
- "thread"
-};
-
-static int humanReadable = 0;
-#define hrBufSize 200
-static char hrBuf[hrBufSize];
-
-typedef struct PersistInfo_t {
- lua_State *L;
- int counter;
- lua_Chunkwriter writer;
- void *ud;
-#ifdef PLUTO_DEBUG
- int level;
-#endif
-} PersistInfo;
-
-#ifdef PLUTO_DEBUG
-void printindent(int indent)
-{
- int il;
- for(il=0; il<indent; il++) {
- printf(" ");
- }
-}
-#endif
-
-/* lua_Chunkwriter signature: (lua_State *L, const void *p, size_t sz, void *ud).
- ud is a pointer to the WriterInfo struct (holds the buffer pointer)
-*/
-
-static void pi_write(PersistInfo *pi, const void *p, size_t size, void *ud) {
- if (humanReadable) {
- uint i;
- snprintf(hrBuf, hrBufSize, " pi_write %d ", (int) size);
- pi->writer(pi->L, hrBuf, strlen(hrBuf), ud);
- for (i = 0; i < size; i++) {
- char b = ((char *)p)[i];
- snprintf(hrBuf, hrBufSize, "%X%X", (b >> 4) & 0xF, b & 0xF);
- pi->writer(pi->L, hrBuf, strlen(hrBuf), ud);
- }
- snprintf(hrBuf, hrBufSize, "\n");
- pi->writer(pi->L, hrBuf, strlen(hrBuf), ud);
- } else {
- pi->writer(pi->L, p, size, ud);
- }
-#ifdef TOTEXT
- int i;
- printf(" pi_write %d ", (int) size);
- for (i = 0; i < size; i++) {
- char b = ((char *)p)[i];
- printf("%X%X", (b >> 4) & 0xF, b & 0xF);
- }
- printf("\n");
-#endif
-}
-
-static void hrOut(PersistInfo *pi) {
- pi->writer(pi->L, hrBuf, strlen(hrBuf), pi->ud);
-}
-
-static void write_size(PersistInfo *pi, size_t *val)
-{
-#ifdef SIZES64
- int64 longval; /* yeah, you really need long long to get 8 bytes on win32... duh. */
- longval = *val;
- pi_write(pi, &longval, 8, pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "write_size64 %ld\n", longval);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("write_size64 %ld\n", longval);
-#endif
-#else
- pi_write(pi, val, sizeof(size_t), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "write_size %ld\n", *((size_t *)val));
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("write_size %ld\n", *val);
-#endif
-#endif
-}
-
-static void read_size(ZIO *zio, size_t *val)
-{
-#ifdef SIZES64
- int64 longval;
- verify(LIF(Z,read)(zio, &longval, 8) == 0);
- *val = longval;
-#else
- verify(LIF(Z,read)(zio, val, sizeof(size_t)) == 0);
-#endif
-}
-
-
-/* Mutual recursion requires prototype */
-static void persist(PersistInfo *pi);
-
-/* A simple reimplementation of the unfortunately static function luaA_index.
- * Does not support the global table, registry, or upvalues. */
-static StkId getobject(lua_State *L, int stackpos)
-{
- if(stackpos > 0) {
- lua_assert(L->base+stackpos-1 < L->top);
- return L->base+stackpos-1;
- } else {
- lua_assert(L->top-stackpos >= L->base);
- return L->top+stackpos;
- }
-}
-
-/* Choose whether to do a regular or special persistence based on an object's
- * metatable. "default" is whether the object, if it doesn't have a __persist
- * entry, is literally persistable or not.
- * Pushes the unpersist closure and returns true if special persistence is
- * used. */
-static int persistspecialobject(PersistInfo *pi, int defaction)
-{
- /* perms reftbl ... obj */
- lua_checkstack(pi->L, 4);
- /* Check whether we should persist literally, or via the __persist
- * metafunction */
- if(!lua_getmetatable(pi->L, -1)) {
- if(defaction) {
- {
- int zero = 0;
- pi_write(pi, &zero, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistspecialobject_write_zero\n");
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistspecialobject_write_zero\n");
-#endif
- }
- return 0;
- } else {
- lua_pushstring(pi->L, "Type not literally persistable by default");
- lua_error(pi->L);
- }
- }
- /* perms reftbl sptbl ... obj mt */
- lua_pushstring(pi->L, "__persist");
- /* perms reftbl sptbl ... obj mt "__persist" */
- lua_rawget(pi->L, -2);
- /* perms reftbl sptbl ... obj mt __persist? */
- if(lua_isnil(pi->L, -1)) {
- /* perms reftbl sptbl ... obj mt nil */
- lua_pop(pi->L, 2);
- /* perms reftbl sptbl ... obj */
- if(defaction) {
- {
- int zero = 0;
- pi_write(pi, &zero, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistspecialobject_write_zero2\n");
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistspecialobject_write_zero2\n");
-#endif
- }
- return 0;
- } else {
- lua_pushstring(pi->L, "Type not literally persistable by default");
- lua_error(pi->L);
- return 0; /* not reached */
- }
- } else if(lua_isboolean(pi->L, -1)) {
- /* perms reftbl sptbl ... obj mt bool */
- if(lua_toboolean(pi->L, -1)) {
- /* perms reftbl sptbl ... obj mt true */
- lua_pop(pi->L, 2);
- /* perms reftbl sptbl ... obj */
- {
- int zero = 0;
- pi_write(pi, &zero, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistspecialobject_write_zero3\n");
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistspecialobject_write_zero3\n");
-#endif
- }
- return 0;
- } else {
- lua_pushstring(pi->L, "Metatable forbade persistence");
- lua_error(pi->L);
- return 0; /* not reached */
- }
- } else if(!lua_isfunction(pi->L, -1)) {
- lua_pushstring(pi->L, "__persist not nil, boolean, or function");
- lua_error(pi->L);
- }
- /* perms reftbl ... obj mt __persist */
- lua_pushvalue(pi->L, -3);
- /* perms reftbl ... obj mt __persist obj */
-#ifdef PLUTO_PASS_USERDATA_TO_PERSIST
- lua_pushlightuserdata(pi->L, (void *)pi->writer);
- lua_pushlightuserdata(pi->L, pi->ud);
- /* perms reftbl ... obj mt __persist obj ud */
- lua_call(pi->L, 3, 1);
- /* perms reftbl ... obj mt func? */
-#else
- lua_call(pi->L, 1, 1);
- /* perms reftbl ... obj mt func? */
-#endif
- /* perms reftbl ... obj mt func? */
- if(!lua_isfunction(pi->L, -1)) {
- lua_pushstring(pi->L, "__persist function did not return a function");
- lua_error(pi->L);
- }
- /* perms reftbl ... obj mt func */
- {
- int one = 1;
- pi_write(pi, &one, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistspecialobject_write_one\n");
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistspecialobject_write_one\n");
-#endif
- }
- persist(pi);
- /* perms reftbl ... obj mt func */
- lua_pop(pi->L, 2);
- /* perms reftbl ... obj */
- return 1;
-}
-
-static void persisttable(PersistInfo *pi)
-{
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persisttable\n");
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persisttable\n");
-#endif
-
- /* perms reftbl ... tbl */
- lua_checkstack(pi->L, 3);
- if(persistspecialobject(pi, 1)) {
- /* perms reftbl ... tbl */
- return;
- }
- /* perms reftbl ... tbl */
- /* First, persist the metatable (if any) */
- if(!lua_getmetatable(pi->L, -1)) {
- lua_pushnil(pi->L);
- }
- /* perms reftbl ... tbl mt/nil */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... tbl */
-
- /* Now, persist all k/v pairs */
- lua_pushnil(pi->L);
- /* perms reftbl ... tbl nil */
- while(lua_next(pi->L, -2)) {
- /* perms reftbl ... tbl k v */
- lua_pushvalue(pi->L, -2);
- /* perms reftbl ... tbl k v k */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... tbl k v */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... tbl k */
- }
- /* perms reftbl ... tbl */
- /* Terminate list */
- lua_pushnil(pi->L);
- /* perms reftbl ... tbl nil */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... tbl */
-}
-
-static void persistuserdata(PersistInfo *pi) {
- /* perms reftbl ... udata */
- lua_checkstack(pi->L, 2);
- if(persistspecialobject(pi, 0)) {
- /* perms reftbl ... udata */
- return;
- } else {
- /* Use literal persistence */
- size_t length = uvalue(getobject(pi->L, -1))->len;
- write_size(pi, &length);
- pi_write(pi, lua_touserdata(pi->L, -1), length, pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistuserdata %ld\n", (long) length);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistuserdata %ld\n", (long) length);
-#endif
- if(!lua_getmetatable(pi->L, -1)) {
- /* perms reftbl ... udata */
- lua_pushnil(pi->L);
- /* perms reftbl ... udata mt/nil */
- }
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... udata */
- }
-}
-
-
-static Proto *toproto(lua_State *L, int stackpos)
-{
- return gco2p(getobject(L, stackpos)->value.gc);
-}
-
-static UpVal *toupval(lua_State *L, int stackpos)
-{
- lua_assert(ttype(getobject(L, stackpos)) == LUA_TUPVAL);
- return gco2uv(getobject(L, stackpos)->value.gc);
-}
-
-static void pushproto(lua_State *L, Proto *proto)
-{
- TValue o;
- setptvalue(L, &o, proto);
- LIF(A,pushobject)(L, &o);
-}
-
-#define setuvvalue(L,obj,x) \
- { TValue *i_o=(obj); \
- i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUPVAL; \
- checkliveness(G(L),i_o); }
-
-static void pushupval(lua_State *L, UpVal *upval)
-{
- TValue o;
- setuvvalue(L, &o, upval);
- LIF(A,pushobject)(L, &o);
-}
-
-static void pushclosure(lua_State *L, Closure *closure)
-{
- TValue o;
- setclvalue(L, &o, closure);
- LIF(A,pushobject)(L, &o);
-}
-
-static void pushstring(lua_State *L, TString *s)
-{
- TValue o;
- setsvalue(L, &o, s);
- LIF(A,pushobject)(L, &o);
-}
-
-static void persistfunction(PersistInfo *pi)
-{
- /* perms reftbl ... func */
- Closure *cl = clvalue(getobject(pi->L, -1));
- lua_checkstack(pi->L, 2);
- if(cl->c.isC) {
- /* It's a C function. For now, we aren't going to allow
- * persistence of C closures, even if the "C proto" is
- * already in the permanents table. */
- lua_pushstring(pi->L, "Attempt to persist a C function");
- lua_error(pi->L);
- } else {
- /* It's a Lua closure. */
- {
- /* We don't really _NEED_ the number of upvals,
- * but it'll simplify things a bit */
- pi_write(pi, &cl->l.p->nups, sizeof(lu_byte), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistfunction_number_upvalues %d\n", (int) cl->l.p->nups);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistfunction_number_upvalues %d\n", (int) cl->l.p->nups);
-#endif
- }
- /* Persist prototype */
- {
- pushproto(pi->L, cl->l.p);
- /* perms reftbl ... func proto */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... func */
- }
- /* Persist upvalue values (not the upvalue objects
- * themselves) */
- {
- int i;
- for(i=0; i<cl->l.p->nups; i++) {
- /* perms reftbl ... func */
- pushupval(pi->L, cl->l.upvals[i]);
- /* perms reftbl ... func upval */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... func */
- }
- /* perms reftbl ... func */
- }
- /* Persist function environment */
- {
- lua_getfenv(pi->L, -1);
- /* perms reftbl ... func fenv */
- if(lua_equal(pi->L, -1, LUA_GLOBALSINDEX)) {
- /* Function has the default fenv */
- /* perms reftbl ... func _G */
- lua_pop(pi->L, 1);
- /* perms reftbl ... func */
- lua_pushnil(pi->L);
- /* perms reftbl ... func nil */
- }
- /* perms reftbl ... func fenv/nil */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... func */
- }
- }
-}
-
-
-/* Upvalues are tricky. Here's why.
- *
- * A particular upvalue may be either "open", in which case its member v
- * points into a thread's stack, or "closed" in which case it points to the
- * upvalue itself. An upvalue is closed under any of the following conditions:
- * -- The function that initially declared the variable "local" returns
- * -- The thread in which the closure was created is garbage collected
- *
- * To make things wackier, just because a thread is reachable by Lua doesn't
- * mean it's in our root set. We need to be able to treat an open upvalue
- * from an unreachable thread as a closed upvalue.
- *
- * The solution:
- * (a) For the purposes of persisting, don't indicate whether an upvalue is
- * closed or not.
- * (b) When unpersisting, pretend that all upvalues are closed.
- * (c) When persisting, persist all open upvalues referenced by a thread
- * that is persisted, and tag each one with the corresponding stack position
- * (d) When unpersisting, "reopen" each of these upvalues as the thread is
- * unpersisted
- */
-static void persistupval(PersistInfo *pi)
-{
- /* perms reftbl ... upval */
- UpVal *uv = toupval(pi->L, -1);
- lua_checkstack(pi->L, 1);
-
- /* We can't permit the upval to linger around on the stack, as Lua
- * will bail if its GC finds it. */
-
- lua_pop(pi->L, 1);
- /* perms reftbl ... */
- LIF(A,pushobject)(pi->L, uv->v);
- /* perms reftbl ... obj */
- persist(pi);
- /* perms reftbl ... obj */
-}
-
-static void persistproto(PersistInfo *pi)
-{
- /* perms reftbl ... proto */
- Proto *p = toproto(pi->L, -1);
- lua_checkstack(pi->L, 2);
-
- /* Persist constant refs */
- {
- int i;
- pi_write(pi, &p->sizek, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_sizek %d\n", p->sizek);
- hrOut(pi);
- }
- #ifdef TOTEXT
- printf("persistproto_sizek %d\n", p->sizek);
- #endif
- for(i=0; i<p->sizek; i++) {
- LIF(A,pushobject)(pi->L, &p->k[i]);
- /* perms reftbl ... proto const */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... proto */
- }
- }
- /* perms reftbl ... proto */
-
- /* serialize inner Proto refs */
- {
- int i;
- pi_write(pi, &p->sizep, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_sizep %d\n", p->sizep);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_sizep %d\n", p->sizep);
-#endif
- for(i=0; i<p->sizep; i++)
- {
- pushproto(pi->L, p->p[i]);
- /* perms reftbl ... proto subproto */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... proto */
- }
- }
- /* perms reftbl ... proto */
-
- /* Serialize code */
- {
- int len;
- pi_write(pi, &p->sizecode, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_sizecode %d\n", p->sizecode);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_sizecode %d\n", p->sizecode);
-#endif
- len = sizeof(Instruction) * p->sizecode;
- pi_write(pi, p->code, len, pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_code %d\n", len);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_code %d\n", len);
-#endif
- }
-
- /* Serialize upvalue names */
- {
- int i;
- pi_write(pi, &p->sizeupvalues, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_upvalues %d\n", p->sizeupvalues);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_upvalues %d\n", p->sizeupvalues);
-#endif
- for(i=0; i<p->sizeupvalues; i++)
- {
- pushstring(pi->L, p->upvalues[i]);
- persist(pi);
- lua_pop(pi->L, 1);
- }
- }
- /* Serialize local variable infos */
- {
- int i;
- pi_write(pi, &p->sizelocvars, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_sizelocvars %d\n", p->sizelocvars);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_sizelocvars %d\n", p->sizelocvars);
-#endif
- for(i=0; i<p->sizelocvars; i++)
- {
- pushstring(pi->L, p->locvars[i].varname);
- persist(pi);
- lua_pop(pi->L, 1);
-
- pi_write(pi, &p->locvars[i].startpc, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_startpc %d\n", p->locvars[i].startpc);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_startpc %d\n", p->locvars[i].startpc);
-#endif
- pi_write(pi, &p->locvars[i].endpc, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_endpc %d\n", p->locvars[i].endpc);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_endpc %d\n", p->locvars[i].endpc);
-#endif
- }
- }
-
- /* Serialize source string */
- pushstring(pi->L, p->source);
- persist(pi);
- lua_pop(pi->L, 1);
-
- /* Serialize line numbers */
- {
- pi_write(pi, &p->sizelineinfo, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_sizelineinfo %d\n", p->sizelineinfo);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_sizelineinfo %d\n", p->sizelineinfo);
-#endif
- if (p->sizelineinfo)
- {
- int len;
- len = sizeof(int) * p->sizelineinfo;
- pi_write(pi, p->lineinfo, len, pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_lineinfo %d\n", len);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_lineinfo %d\n", len);
-#endif
- }
- }
-
- /* Serialize linedefined and lastlinedefined */
- pi_write(pi, &p->linedefined, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_linedefined %d\n", p->linedefined);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_linedefined %d\n", p->linedefined);
-#endif
- pi_write(pi, &p->lastlinedefined, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_lastlinedefined %d\n", p->lastlinedefined);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_lastlinedefined %d\n", p->lastlinedefined);
-#endif
-
- /* Serialize misc values */
- {
- pi_write(pi, &p->nups, sizeof(lu_byte), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_nups %d\n", (int) p->nups);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_nups %d\n", (int) p->nups);
-#endif
- pi_write(pi, &p->numparams, sizeof(lu_byte), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_numparams %d\n", (int) p->numparams);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_numparams %d\n", (int) p->numparams);
-#endif
- pi_write(pi, &p->is_vararg, sizeof(lu_byte), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_is_vararg %d\n", (int) p->is_vararg);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_is_vararg %d\n", (int) p->is_vararg);
-#endif
- pi_write(pi, &p->maxstacksize, sizeof(lu_byte), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistproto_maxstacksize %d\n", (int) p->maxstacksize);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistproto_maxstacksize %d\n", (int) p->maxstacksize);
-#endif
- }
- /* We do not currently persist upvalue names, local variable names,
- * variable lifetimes, line info, or source code. */
-}
-
-/* Copies a stack, but the stack is reversed in the process
- */
-static size_t revappendstack(lua_State *from, lua_State *to)
-{
- StkId o;
- for(o=from->top-1; o>=from->stack; o--) {
- setobj2s(to, to->top, o);
- to->top++;
- }
- return from->top - from->stack;
-}
-
-/* Persist all stack members
- */
-static void persistthread(PersistInfo *pi)
-{
- size_t posremaining;
- lua_State *L2;
- /* perms reftbl ... thr */
- L2 = lua_tothread(pi->L, -1);
- lua_checkstack(pi->L, L2->top - L2->stack + 1);
- if(pi->L == L2) {
- lua_pushstring(pi->L, "Can't persist currently running thread");
- lua_error(pi->L);
- return; /* not reached */
- }
-
- /* Persist the stack */
- posremaining = revappendstack(L2, pi->L);
- /* perms reftbl ... thr (rev'ed contents of L2) */
- write_size(pi, &posremaining);
- for(; posremaining > 0; posremaining--) {
- persist(pi);
- lua_pop(pi->L, 1);
- }
- /* perms reftbl ... thr */
- /* Now, persist the CallInfo stack. */
- {
- size_t i, numframes = (L2->ci - L2->base_ci) + 1;
- write_size(pi, &numframes);
- for(i=0; i<numframes; i++) {
- CallInfo *ci = L2->base_ci + i;
- size_t stackbase = ci->base - L2->stack;
- size_t stackfunc = ci->func - L2->stack;
- size_t stacktop = ci->top - L2->stack;
- size_t savedpc = (ci != L2->base_ci) ?
- ci->savedpc - ci_func(ci)->l.p->code :
- 0;
- write_size(pi, &stackbase);
- write_size(pi, &stackfunc);
- write_size(pi, &stacktop);
- pi_write(pi, &ci->nresults, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistthread %d\n", ci->nresults);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistthread %d\n", ci->nresults);
-#endif
- write_size(pi, &savedpc);
- }
- }
-
- /* Serialize the state's other parameters, with the exception of upval stuff */
- {
- size_t stackbase = L2->base - L2->stack;
- size_t stacktop = L2->top - L2->stack;
- lua_assert(L2->nCcalls <= 1);
- pi_write(pi, &L2->status, sizeof(lu_byte), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistthread_status %d\n", (int) L2->status);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistthread_status %d\n", (int) L2->status);
-#endif
- write_size(pi, &stackbase);
- write_size(pi, &stacktop);
-
- // ptrdiff_t changes sizes based on 32/64 bit
- // Hard cast to 64 bit size if SIZE64 is defined
-#ifdef SIZES64
- uint64 ptrIndex = static_cast<uint64>(L2->errfunc);
- pi_write(pi, &ptrIndex, sizeof(uint64), pi->ud);
-#else
- pi_write(pi, &L2->errfunc, sizeof(ptrdiff_t), pi->ud);
-#endif
- //write_size(pi, (size_t *)&L2->errfunc);
- }
-
- /* Finally, record upvalues which need to be reopened */
- /* See the comment above persistupval() for why we do this */
- {
- GCObject *gco;
- UpVal *uv;
- /* perms reftbl ... thr */
- for(gco = L2->openupval; gco != NULL; gco = uv->next) {
- size_t stackpos;
- uv = gco2uv(gco);
-
- /* Make sure upvalue is really open */
- lua_assert(uv->v != &uv->u.value);
- pushupval(pi->L, uv);
- /* perms reftbl ... thr uv */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... thr */
- stackpos = uv->v - L2->stack;
- write_size(pi, &stackpos);
- }
- /* perms reftbl ... thr */
- lua_pushnil(pi->L);
- /* perms reftbl ... thr nil */
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... thr */
- }
- /* perms reftbl ... thr */
-}
-
-static void persistboolean(PersistInfo *pi)
-{
- int b = lua_toboolean(pi->L, -1);
- pi_write(pi, &b, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistboolean %d\n", b);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistboolean %d\n", b);
-#endif
-}
-
-static void persistlightuserdata(PersistInfo *pi)
-{
- void *p = lua_touserdata(pi->L, -1);
- pi_write(pi, &p, sizeof(void *), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistlightuserdata %p\n", p);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistlightuserdata %d\n", (int) p);
-#endif
-}
-
-static void persistnumber(PersistInfo *pi)
-{
- lua_Number n = lua_tonumber(pi->L, -1);
- pi_write(pi, &n, sizeof(lua_Number), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persistnumber %d (%d)\n", (int) n, (int) sizeof(lua_Number));
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persistnumber %d (%d)\n", (int) n, (int) sizeof(lua_Number));
-#endif
-}
-
-static void persiststring(PersistInfo *pi)
-{
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persiststring\n");
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persiststring\n");
-#endif
- size_t length = lua_strlen(pi->L, -1);
- write_size(pi, &length);
- const char* s = lua_tostring(pi->L, -1);
- pi_write(pi, s, length, pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persiststring %d \"%s\"\n", (int)length, s);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persiststring %d \"%s\"\n", length, s);
-#endif
-}
-
-/* Top-level delegating persist function
- */
-static void persist(PersistInfo *pi)
-{
- /* perms reftbl ... obj */
- lua_checkstack(pi->L, 2);
- /* If the object has already been written, write a reference to it */
- lua_pushvalue(pi->L, -1);
- /* perms reftbl ... obj obj */
- lua_rawget(pi->L, 2);
- /* perms reftbl ... obj ref? */
- if(!lua_isnil(pi->L, -1)) {
- /* perms reftbl ... obj ref */
- int zero = 0;
- pi_write(pi, &zero, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persist_seenobject\n");
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persist_seenobject\n");
-#endif
- int *ref = (int *)lua_touserdata(pi->L, -1);
- pi_write(pi, ref, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persist_touserdata_ref %d\n", ref);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persist_touserdata_ref %d\n", ref);
-#endif
- lua_pop(pi->L, 1);
- /* perms reftbl ... obj ref */
-#ifdef PLUTO_DEBUG
- printindent(pi->level);
- printf("0 %d\n", ref);
-#endif
- return;
- }
- /* perms reftbl ... obj nil */
- lua_pop(pi->L, 1);
- /* perms reftbl ... obj */
- /* If the object is nil, write the pseudoreference 0 */
- if(lua_isnil(pi->L, -1)) {
- int zero = 0;
- /* firsttime */
- pi_write(pi, &zero, sizeof(int), pi->ud);
- /* ref */
- pi_write(pi, &zero, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persist_nil (last 2 lines)\n");
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persist_nil (last 2 lines)\n");
-#endif
-#ifdef PLUTO_DEBUG
- printindent(pi->level);
- printf("0 0\n");
-#endif
- return;
- }
- {
- /* indicate that it's the first time */
- int one = 1;
- pi_write(pi, &one, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persist_newobject\n");
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persist_newobject\n");
-#endif
- }
- lua_pushvalue(pi->L, -1);
- /* perms reftbl ... obj obj */
- int *ref = (int *)lua_newuserdata(pi->L, sizeof(int));
- *ref = ++(pi->counter);
- /* perms reftbl ... obj obj ref */
- lua_rawset(pi->L, 2);
- /* perms reftbl ... obj */
-
- pi_write(pi, &pi->counter, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persist_counter %d\n", pi->counter);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persist_counter %d\n", pi->counter);
-#endif
-
-
- /* At this point, we'll give the permanents table a chance to play. */
- {
- lua_pushvalue(pi->L, -1);
- /* perms reftbl ... obj obj */
- lua_gettable(pi->L, 1);
- /* perms reftbl ... obj permkey? */
- if(!lua_isnil(pi->L, -1)) {
- /* perms reftbl ... obj permkey */
- int type = PLUTO_TPERMANENT;
-#ifdef PLUTO_DEBUG
- printindent(pi->level);
- printf("1 %d PERM\n", pi->counter);
- pi->level++;
-#endif
- pi_write(pi, &type, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persist_permtype %d\n", type);
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persist_permtype %d\n", type);
-#endif
- persist(pi);
- lua_pop(pi->L, 1);
- /* perms reftbl ... obj */
-#ifdef PLUTO_DEBUG
- pi->level--;
-#endif
- return;
- } else {
- /* perms reftbl ... obj nil */
- lua_pop(pi->L, 1);
- /* perms reftbl ... obj */
- }
- /* perms reftbl ... obj */
- }
- {
- int type = lua_type(pi->L, -1);
- pi_write(pi, &type, sizeof(int), pi->ud);
- if (humanReadable) {
- snprintf(hrBuf, hrBufSize, "persist %s\n", type >= 0 && type < NUMTYPES ? typenames[type] : "?");
- hrOut(pi);
- }
-#ifdef TOTEXT
- printf("persist %s\n", type >= 0 && type < NUMTYPES ? typenames[type] : "?");
-#endif
-
-#ifdef PLUTO_DEBUG
- printindent(pi->level);
- printf("1 %d %d\n", pi->counter, type);
- pi->level++;
-#endif
- }
-
- switch(lua_type(pi->L, -1)) {
- case LUA_TBOOLEAN:
- persistboolean(pi);
- break;
- case LUA_TLIGHTUSERDATA:
- persistlightuserdata(pi);
- break;
- case LUA_TNUMBER:
- persistnumber(pi);
- break;
- case LUA_TSTRING:
- persiststring(pi);
- break;
- case LUA_TTABLE:
- persisttable(pi);
- break;
- case LUA_TFUNCTION:
- persistfunction(pi);
- break;
- case LUA_TTHREAD:
- persistthread(pi);
- break;
- case LUA_TPROTO:
- persistproto(pi);
- break;
- case LUA_TUPVAL:
- persistupval(pi);
- break;
- case LUA_TUSERDATA:
- persistuserdata(pi);
- break;
- default:
- lua_assert(0);
- }
-#ifdef PLUTO_DEBUG
- pi->level--;
-#endif
-}
-
-void pluto_persist(lua_State *L, lua_Chunkwriter writer, void *ud)
-{
- PersistInfo pi;
-
- pi.counter = 0;
- pi.L = L;
- pi.writer = writer;
- pi.ud = ud;
-#ifdef PLUTO_DEBUG
- pi.level = 0;
-#endif
-
- lua_checkstack(L, 4);
- /* perms? rootobj? ...? */
- lua_assert(lua_gettop(L) == 2);
- /* perms rootobj */
- lua_assert(!lua_isnil(L, 2));
- /* perms rootobj */
- lua_newtable(L);
- /* perms rootobj reftbl */
-
- /* Now we're going to make the table weakly keyed. This prevents the
- * GC from visiting it and trying to mark things it doesn't want to
- * mark in tables, e.g. upvalues. All objects in the table are
- * a priori reachable, so it doesn't matter that we do this. */
- lua_newtable(L);
- /* perms rootobj reftbl mt */
- lua_pushstring(L, "__mode");
- /* perms rootobj reftbl mt "__mode" */
- lua_pushstring(L, "k");
- /* perms rootobj reftbl mt "__mode" "k" */
- lua_settable(L, 4);
- /* perms rootobj reftbl mt */
- lua_setmetatable(L, 3);
- /* perms rootobj reftbl */
- lua_insert(L, 2);
- /* perms reftbl rootobj */
- persist(&pi);
- /* perms reftbl rootobj */
- lua_remove(L, 2);
- /* perms rootobj */
-}
-
-typedef struct WriterInfo_t {
- char* buf;
- size_t buflen;
-} WriterInfo;
-
-static int bufwriter (lua_State *L, const void *p, size_t sz, void *ud) {
- const char *cp = (const char *)p;
- WriterInfo *wi = (WriterInfo *)ud;
-
- LIF(M,reallocvector)(L, wi->buf, wi->buflen, wi->buflen+sz, char);
- while(sz)
- {
- /* how dearly I love ugly C pointer twiddling */
- wi->buf[wi->buflen++] = *cp++;
- sz--;
- }
- return 0;
-}
-
-int persist_l(lua_State *L)
-{
- /* perms? rootobj? ...? */
- WriterInfo wi;
-
- wi.buf = NULL;
- wi.buflen = 0;
-
- lua_settop(L, 2);
- /* perms? rootobj? */
- luaL_checktype(L, 1, LUA_TTABLE);
- /* perms rootobj? */
- luaL_checktype(L, 1, LUA_TTABLE);
- /* perms rootobj */
-
- pluto_persist(L, bufwriter, &wi);
-
- lua_settop(L, 0);
- /* (empty) */
- lua_pushlstring(L, wi.buf, wi.buflen);
- /* str */
- pdep_freearray(L, wi.buf, wi.buflen, char);
- return 1;
-}
-
-typedef struct UnpersistInfo_t {
- lua_State *L;
- ZIO zio;
-#ifdef PLUTO_DEBUG
- int level;
-#endif
-} UnpersistInfo;
-
-static void unpersist(UnpersistInfo *upi);
-
-/* The object is left on the stack. This is primarily used by unpersist, but
- * may be used by GCed objects that may incur cycles in order to preregister
- * the object. */
-static void registerobject(int ref, UnpersistInfo *upi)
-{
- /* perms reftbl ... obj */
- lua_checkstack(upi->L, 2);
- lua_pushlightuserdata(upi->L, (void *)ref);
- /* perms reftbl ... obj ref */
- lua_pushvalue(upi->L, -2);
- /* perms reftbl ... obj ref obj */
- lua_settable(upi->L, 2);
- /* perms reftbl ... obj */
-}
-
-static void unpersistboolean(UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- int b;
- lua_checkstack(upi->L, 1);
- verify(LIF(Z,read)(&upi->zio, &b, sizeof(int)) == 0);
- lua_pushboolean(upi->L, b);
- /* perms reftbl ... bool */
-}
-
-static void unpersistlightuserdata(UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- void *p;
- lua_checkstack(upi->L, 1);
- verify(LIF(Z,read)(&upi->zio, &p, sizeof(void *)) == 0);
- lua_pushlightuserdata(upi->L, p);
- /* perms reftbl ... ludata */
-}
-
-static void unpersistnumber(UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- lua_Number n;
- lua_checkstack(upi->L, 1);
- verify(LIF(Z,read)(&upi->zio, &n, sizeof(lua_Number)) == 0);
- lua_pushnumber(upi->L, n);
- /* perms reftbl ... num */
-}
-
-static void unpersiststring(UnpersistInfo *upi)
-{
- /* perms reftbl sptbl ref */
- /*int length;*/
- size_t length;
- char* string;
- lua_checkstack(upi->L, 1);
- /*verify(LIF(Z,read)(&upi->zio, &length, sizeof(int)) == 0);*/
- /*verify(LIF(Z,read)(&upi->zio, &length, sizeof(size_t)) == 0);*/
- read_size(&upi->zio, &length);
- string = pdep_newvector(upi->L, length, char);
- verify(LIF(Z,read)(&upi->zio, string, length) == 0);
- lua_pushlstring(upi->L, string, length);
- /* perms reftbl sptbl ref str */
- pdep_freearray(upi->L, string, length, char);
-}
-
-static void unpersistspecialtable(int ref, UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- lua_checkstack(upi->L, 1);
- unpersist(upi);
- /* perms reftbl ... spfunc? */
- lua_assert(lua_isfunction(upi->L, -1));
- /* perms reftbl ... spfunc */
- lua_call(upi->L, 0, 1);
- /* perms reftbl ... tbl? */
- lua_assert(lua_istable(upi->L, -1));
- /* perms reftbl ... tbl */
-}
-
-static void unpersistliteraltable(int ref, UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- lua_checkstack(upi->L, 3);
- /* Preregister table for handling of cycles */
- lua_newtable(upi->L);
- /* perms reftbl ... tbl */
- registerobject(ref, upi);
- /* perms reftbl ... tbl */
- /* Unpersist metatable */
- {
- unpersist(upi);
- /* perms reftbl ... tbl mt/nil? */
- if(lua_istable(upi->L, -1)) {
- /* perms reftbl ... tbl mt */
- lua_setmetatable(upi->L, -2);
- /* perms reftbl ... tbl */
- } else {
- /* perms reftbl ... tbl nil? */
- lua_assert(lua_isnil(upi->L, -1));
- /* perms reftbl ... tbl nil */
- lua_pop(upi->L, 1);
- /* perms reftbl ... tbl */
- }
- /* perms reftbl ... tbl */
- }
-
- while(1)
- {
- /* perms reftbl ... tbl */
- unpersist(upi);
- /* perms reftbl ... tbl key/nil */
- if(lua_isnil(upi->L, -1)) {
- /* perms reftbl ... tbl nil */
- lua_pop(upi->L, 1);
- /* perms reftbl ... tbl */
- break;
- }
- /* perms reftbl ... tbl key */
- unpersist(upi);
- /* perms reftbl ... tbl key value? */
- lua_assert(!lua_isnil(upi->L, -1));
- /* perms reftbl ... tbl key value */
- lua_rawset(upi->L, -3);
- /* perms reftbl ... tbl */
- }
-}
-
-static void unpersisttable(int ref, UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- lua_checkstack(upi->L, 1);
- {
- int isspecial;
- verify(LIF(Z,read)(&upi->zio, &isspecial, sizeof(int)) == 0);
- if(isspecial) {
- unpersistspecialtable(ref, upi);
- /* perms reftbl ... tbl */
- } else {
- unpersistliteraltable(ref, upi);
- /* perms reftbl ... tbl */
- }
- /* perms reftbl ... tbl */
- }
-}
-
-static UpVal *makeupval(lua_State *L, int stackpos)
-{
- UpVal *uv = pdep_new(L, UpVal);
- pdep_link(L, (GCObject *)uv, LUA_TUPVAL);
- uv->tt = LUA_TUPVAL;
- uv->v = &uv->u.value;
- uv->u.l.prev = NULL;
- uv->u.l.next = NULL;
- setobj(L, uv->v, getobject(L, stackpos));
- return uv;
-}
-
-static Proto *makefakeproto(lua_State *L, lu_byte nups)
-{
- Proto *p = pdep_newproto(L);
- p->sizelineinfo = 1;
- p->lineinfo = pdep_newvector(L, 1, int);
- p->lineinfo[0] = 1;
- p->sizecode = 1;
- p->code = pdep_newvector(L, 1, Instruction);
- p->code[0] = CREATE_ABC(OP_RETURN, 0, 1, 0);
- p->source = pdep_newlstr(L, "", 0);
- p->maxstacksize = 2;
- p->nups = nups;
- p->sizek = 0;
- p->sizep = 0;
-
- return p;
-}
-
-/* The GC is not fond of finding upvalues in tables. We get around this
- * during persistence using a weakly keyed table, so that the GC doesn't
- * bother to mark them. This won't work in unpersisting, however, since
- * if we make the values weak they'll be collected (since nothing else
- * references them). Our solution, during unpersisting, is to represent
- * upvalues as dummy functions, each with one upvalue. */
-static void boxupval_start(lua_State *L)
-{
- LClosure *lcl;
- lcl = (LClosure *)pdep_newLclosure(L, 1, hvalue(&L->l_gt));
- pushclosure(L, (Closure *)lcl);
- /* ... func */
- lcl->p = makefakeproto(L, 1);
-
- /* Temporarily initialize the upvalue to nil */
-
- lua_pushnil(L);
- lcl->upvals[0] = makeupval(L, -1);
- lua_pop(L, 1);
-}
-
-static void boxupval_finish(lua_State *L)
-{
- /* ... func obj */
- LClosure *lcl = (LClosure *) clvalue(getobject(L, -2));
-
- lcl->upvals[0]->u.value = *getobject(L, -1);
- lua_pop(L, 1);
-}
-
-
-static void unboxupval(lua_State *L)
-{
- /* ... func */
- LClosure *lcl;
- UpVal *uv;
-
- lcl = (LClosure *)clvalue(getobject(L, -1));
- uv = lcl->upvals[0];
- lua_pop(L, 1);
- /* ... */
- pushupval(L, uv);
- /* ... upval */
-}
-
-static void unpersistfunction(int ref, UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- LClosure *lcl;
- int i;
- lu_byte nupvalues;
- lua_checkstack(upi->L, 2);
-
- verify(LIF(Z,read)(&upi->zio, &nupvalues, sizeof(lu_byte)) == 0);
-
- lcl = (LClosure *)pdep_newLclosure(upi->L, nupvalues, hvalue(&upi->L->l_gt));
- pushclosure(upi->L, (Closure *)lcl);
-
- /* perms reftbl ... func */
- /* Put *some* proto in the closure, before the GC can find it */
- lcl->p = makefakeproto(upi->L, nupvalues);
-
- /* Also, we need to temporarily fill the upvalues */
- lua_pushnil(upi->L);
- /* perms reftbl ... func nil */
- for(i=0; i<nupvalues; i++) {
- lcl->upvals[i] = makeupval(upi->L, -1);
- }
- lua_pop(upi->L, 1);
- /* perms reftbl ... func */
-
- /* I can't see offhand how a function would ever get to be self-
- * referential, but just in case let's register it early */
- registerobject(ref, upi);
-
- /* Now that it's safe, we can get the real proto */
- unpersist(upi);
- /* perms reftbl ... func proto? */
- lua_assert(lua_type(upi->L, -1) == LUA_TPROTO);
- /* perms reftbl ... func proto */
- lcl->p = toproto(upi->L, -1);
- lua_pop(upi->L, 1);
- /* perms reftbl ... func */
-
- for(i=0; i<nupvalues; i++) {
- /* perms reftbl ... func */
- unpersist(upi);
- /* perms reftbl ... func func2 */
- unboxupval(upi->L);
- /* perms reftbl ... func upval */
- lcl->upvals[i] = toupval(upi->L, -1);
- lua_pop(upi->L, 1);
- /* perms reftbl ... func */
- }
- /* perms reftbl ... func */
-
- /* Finally, the fenv */
- unpersist(upi);
- /* perms reftbl ... func fenv/nil? */
- lua_assert(lua_type(upi->L, -1) == LUA_TNIL ||
- lua_type(upi->L, -1) == LUA_TTABLE);
- /* perms reftbl ... func fenv/nil */
- if(!lua_isnil(upi->L, -1)) {
- /* perms reftbl ... func fenv */
- lua_setfenv(upi->L, -2);
- /* perms reftbl ... func */
- } else {
- /* perms reftbl ... func nil */
- lua_pop(upi->L, 1);
- /* perms reftbl ... func */
- }
- /* perms reftbl ... func */
-}
-
-static void unpersistupval(int ref, UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- lua_checkstack(upi->L, 2);
-
- boxupval_start(upi->L);
- /* perms reftbl ... func */
- registerobject(ref, upi);
-
- unpersist(upi);
- /* perms reftbl ... func obj */
- boxupval_finish(upi->L);
- /* perms reftbl ... func */
-}
-
-static void unpersistproto(int ref, UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- Proto *p;
- int i;
- int sizep, sizek;
-
- /* We have to be careful. The GC expects a lot out of protos. In
- * particular, we need to give the function a valid string for its
- * source, and valid code, even before we actually read in the real
- * code. */
- TString *source = pdep_newlstr(upi->L, "", 0);
- p = pdep_newproto(upi->L);
- p->source = source;
- p->sizecode=1;
- p->code = pdep_newvector(upi->L, 1, Instruction);
- p->code[0] = CREATE_ABC(OP_RETURN, 0, 1, 0);
- p->maxstacksize = 2;
- p->sizek = 0;
- p->sizep = 0;
-
- lua_checkstack(upi->L, 2);
-
- pushproto(upi->L, p);
- /* perms reftbl ... proto */
- /* We don't need to register early, since protos can never ever be
- * involved in cyclic references */
-
- /* Read in constant references */
- {
- verify(LIF(Z,read)(&upi->zio, &sizek, sizeof(int)) == 0);
- LIF(M,reallocvector)(upi->L, p->k, 0, sizek, TValue);
- for(i=0; i<sizek; i++) {
- /* perms reftbl ... proto */
- unpersist(upi);
- /* perms reftbl ... proto k */
- setobj2s(upi->L, &p->k[i], getobject(upi->L, -1));
- p->sizek++;
- lua_pop(upi->L, 1);
- /* perms reftbl ... proto */
- }
- /* perms reftbl ... proto */
- }
- /* Read in sub-proto references */
- {
- verify(LIF(Z,read)(&upi->zio, &sizep, sizeof(int)) == 0);
- LIF(M,reallocvector)(upi->L, p->p, 0, sizep, Proto*);
- for(i=0; i<sizep; i++) {
- /* perms reftbl ... proto */
- unpersist(upi);
- /* perms reftbl ... proto subproto */
- p->p[i] = toproto(upi->L, -1);
- p->sizep++;
- lua_pop(upi->L, 1);
- /* perms reftbl ... proto */
- }
- /* perms reftbl ... proto */
- }
-
- /* Read in code */
- {
- verify(LIF(Z,read)(&upi->zio, &p->sizecode, sizeof(int)) == 0);
- LIF(M,reallocvector)(upi->L, p->code, 1, p->sizecode, Instruction);
- verify(LIF(Z,read)(&upi->zio, p->code,
- sizeof(Instruction) * p->sizecode) == 0);
- }
-
- /* Read in upvalue names */
- {
- verify(LIF(Z,read)(&upi->zio, &p->sizeupvalues, sizeof(int)) == 0);
- if (p->sizeupvalues)
- {
- LIF(M,reallocvector)(upi->L, p->upvalues, 0, p->sizeupvalues, TString *);
- for(i=0; i<p->sizeupvalues; i++)
- {
- unpersist(upi);
- p->upvalues[i] = pdep_newlstr(upi->L, lua_tostring(upi->L, -1), strlen(lua_tostring(upi->L, -1)));
- lua_pop(upi->L, 1);
- }
- }
- }
-
- /* Read in local variable infos */
- {
- verify(LIF(Z,read)(&upi->zio, &p->sizelocvars, sizeof(int)) == 0);
- if (p->sizelocvars)
- {
- LIF(M,reallocvector)(upi->L, p->locvars, 0, p->sizelocvars, LocVar);
- for(i=0; i<p->sizelocvars; i++)
- {
- unpersist(upi);
- p->locvars[i].varname = pdep_newlstr(upi->L, lua_tostring(upi->L, -1), strlen(lua_tostring(upi->L, -1)));
- lua_pop(upi->L, 1);
-
- verify(LIF(Z,read)(&upi->zio, &p->locvars[i].startpc, sizeof(int)) == 0);
- verify(LIF(Z,read)(&upi->zio, &p->locvars[i].endpc, sizeof(int)) == 0);
- }
- }
- }
-
- /* Read in source string*/
- unpersist(upi);
- p->source = pdep_newlstr(upi->L, lua_tostring(upi->L, -1), strlen(lua_tostring(upi->L, -1)));
- lua_pop(upi->L, 1);
-
- /* Read in line numbers */
- {
- verify(LIF(Z,read)(&upi->zio, &p->sizelineinfo, sizeof(int)) == 0);
- if (p->sizelineinfo)
- {
- LIF(M,reallocvector)(upi->L, p->lineinfo, 0, p->sizelineinfo, int);
- verify(LIF(Z,read)(&upi->zio, p->lineinfo,
- sizeof(int) * p->sizelineinfo) == 0);
- }
- }
-
- /* Read in linedefined and lastlinedefined */
- verify(LIF(Z,read)(&upi->zio, &p->linedefined, sizeof(int)) == 0);
- verify(LIF(Z,read)(&upi->zio, &p->lastlinedefined, sizeof(int)) == 0);
-
- /* Read in misc values */
- {
- verify(LIF(Z,read)(&upi->zio, &p->nups, sizeof(lu_byte)) == 0);
- verify(LIF(Z,read)(&upi->zio, &p->numparams, sizeof(lu_byte)) == 0);
- verify(LIF(Z,read)(&upi->zio, &p->is_vararg, sizeof(lu_byte)) == 0);
- verify(LIF(Z,read)(&upi->zio, &p->maxstacksize, sizeof(lu_byte)) == 0);
- }
-}
-
-
-/* Does basically the opposite of luaC_link().
- * Right now this function is rather inefficient; it requires traversing the
- * entire root GC set in order to find one object. If the GC list were doubly
- * linked this would be much easier, but there's no reason for Lua to have
- * that. */
-static void gcunlink(lua_State *L, GCObject *gco)
-{
- GCObject *prevslot;
- if(G(L)->rootgc == gco) {
- G(L)->rootgc = G(L)->rootgc->gch.next;
- return;
- }
-
- prevslot = G(L)->rootgc;
- while(prevslot->gch.next != gco) {
- lua_assert(prevslot->gch.next != NULL);
- prevslot = prevslot->gch.next;
- }
-
- prevslot->gch.next = prevslot->gch.next->gch.next;
-}
-
-/* FIXME __ALL__ field ordering */
-static void unpersistthread(int ref, UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- lua_State *L2;
- size_t stacklimit = 0;
- L2 = lua_newthread(upi->L);
- lua_checkstack(upi->L, 3);
- /* L1: perms reftbl ... thr */
- /* L2: (empty) */
- registerobject(ref, upi);
-
- /* First, deserialize the object stack. */
- {
- size_t i, stacksize;
- read_size(&upi->zio, &stacksize);
- LIF(D,growstack)(L2, (int)stacksize);
- /* Make sure that the first stack element (a nil, representing
- * the imaginary top-level C function) is written to the very,
- * very bottom of the stack */
- L2->top--;
- for(i=0; i<stacksize; i++) {
- unpersist(upi);
- /* L1: perms reftbl ... thr obj* */
- }
- lua_xmove(upi->L, L2, stacksize);
- /* L1: perms reftbl ... thr */
- /* L2: obj* */
- }
- /* (hereafter, stacks refer to L1) */
-
- /* Now, deserialize the CallInfo stack. */
- {
- size_t i, numframes;
- read_size(&upi->zio, &numframes);
- LIF(D,reallocCI)(L2,numframes*2);
- for(i=0; i<numframes; i++) {
- CallInfo *ci = L2->base_ci + i;
- size_t stackbase, stackfunc, stacktop, savedpc;
- read_size(&upi->zio, &stackbase);
- read_size(&upi->zio, &stackfunc);
- read_size(&upi->zio, &stacktop);
- verify(LIF(Z,read)(&upi->zio, &ci->nresults, sizeof(int)) == 0);
- read_size(&upi->zio, &savedpc);
-
- if(stacklimit < stacktop)
- stacklimit = stacktop;
-
- ci->base = L2->stack+stackbase;
- ci->func = L2->stack+stackfunc;
- ci->top = L2->stack+stacktop;
- ci->savedpc = (ci != L2->base_ci) ?
- ci_func(ci)->l.p->code+savedpc :
- 0;
- ci->tailcalls = 0;
- /* Update the pointer each time, to keep the GC
- * happy*/
- L2->ci = ci;
- }
- }
- /* perms reftbl ... thr */
- /* Deserialize the state's other parameters, with the exception of upval stuff */
- {
- size_t stackbase, stacktop;
- L2->savedpc = L2->ci->savedpc;
- verify(LIF(Z,read)(&upi->zio, &L2->status, sizeof(lu_byte)) == 0);
- read_size(&upi->zio, &stackbase);
- read_size(&upi->zio, &stacktop);
-
-#ifdef SIZES64
- uint64 value;
- verify(LIF(Z,read)(&upi->zio, &value, sizeof(uint64)) == 0);
-
- L2->errfunc = static_cast<ptrdiff_t>(value);
-#else
- verify(LIF(Z,read)(&upi->zio, &L2->errfunc, sizeof(ptrdiff_t)) == 0);
-#endif
-
- //read_size(&upi->zio, (size_t *)&L2->errfunc);
- L2->base = L2->stack + stackbase;
- L2->top = L2->stack + stacktop;
- }
- /* Finally, "reopen" upvalues (see persistupval() for why) */
- {
- UpVal* uv;
- GCObject **nextslot = &L2->openupval;
- global_State *g = G(L2);
- while(1) {
- size_t stackpos;
- unpersist(upi);
- /* perms reftbl ... thr uv/nil */
- if(lua_isnil(upi->L, -1)) {
- /* perms reftbl ... thr nil */
- lua_pop(upi->L, 1);
- /* perms reftbl ... thr */
- break;
- }
- /* perms reftbl ... thr boxeduv */
- unboxupval(upi->L);
- /* perms reftbl ... thr uv */
- uv = toupval(upi->L, -1);
- lua_pop(upi->L, 1);
- /* perms reftbl ... thr */
-
- read_size(&upi->zio, &stackpos);
- uv->v = L2->stack + stackpos;
- gcunlink(upi->L, (GCObject *)uv);
- uv->marked = luaC_white(g);
- *nextslot = (GCObject *)uv;
- nextslot = &uv->next;
- uv->u.l.prev = &G(L2)->uvhead;
- uv->u.l.next = G(L2)->uvhead.u.l.next;
- uv->u.l.next->u.l.prev = uv;
- G(L2)->uvhead.u.l.next = uv;
- lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
- }
- *nextslot = NULL;
- }
-
- /* The stack must be valid at least to the highest value among the CallInfos */
- /* 'top' and the values up to there must be filled with 'nil' */
- {
- StkId o;
- LIF(D,checkstack)(L2, (int)stacklimit);
- for (o = L2->top; o <= L2->top + stacklimit; o++)
- setnilvalue(o);
- }
-}
-
-static void unpersistuserdata(int ref, UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- int isspecial;
- lua_checkstack(upi->L, 2);
- verify(LIF(Z,read)(&upi->zio, &isspecial, sizeof(int)) == 0);
- if(isspecial) {
- unpersist(upi);
- /* perms reftbl ... spfunc? */
- lua_assert(lua_isfunction(upi->L, -1));
- /* perms reftbl ... spfunc */
-#ifdef PLUTO_PASS_USERDATA_TO_PERSIST
- lua_pushlightuserdata(upi->L, &upi->zio);
- lua_call(upi->L, 1, 1);
-#else
- lua_call(upi->L, 0, 1);
-#endif
- /* perms reftbl ... udata? */
-/* This assertion might not be necessary; it's conceivable, for
- * example, that the SP function might decide to return a table
- * with equivalent functionality. For the time being, we'll
- * ignore this possibility in favor of stricter and more testable
- * requirements. */
- lua_assert(lua_isuserdata(upi->L, -1));
- /* perms reftbl ... udata */
- } else {
- size_t length;
- read_size(&upi->zio, &length);
-
- lua_newuserdata(upi->L, length);
- /* perms reftbl ... udata */
- registerobject(ref, upi);
- verify(LIF(Z,read)(&upi->zio, lua_touserdata(upi->L, -1), length) == 0);
-
- unpersist(upi);
- /* perms reftbl ... udata mt/nil? */
- lua_assert(lua_istable(upi->L, -1) || lua_isnil(upi->L, -1));
- /* perms reftbl ... udata mt/nil */
- lua_setmetatable(upi->L, -2);
- /* perms reftbl ... udata */
- }
- /* perms reftbl ... udata */
-}
-
-static void unpersistpermanent(int ref, UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- lua_checkstack(upi->L, 2);
- unpersist(upi);
- /* perms reftbl permkey */
- lua_gettable(upi->L, 1);
- /* perms reftbl perm? */
- /* We assume currently that the substituted permanent value
- * shouldn't be nil. This may be a bad assumption. Real-life
- * experience is needed to evaluate this. */
- lua_assert(!lua_isnil(upi->L, -1));
- /* perms reftbl perm */
-}
-
-#if 0
-/* For debugging only; not called when lua_assert is empty */
-static int inreftable(lua_State *L, int ref)
-{
- int res;
- lua_checkstack(L, 1);
- /* perms reftbl ... */
- lua_pushlightuserdata(L, (void *)ref);
- /* perms reftbl ... ref */
- lua_gettable(L, 2);
- /* perms reftbl ... obj? */
- res = !lua_isnil(L, -1);
- lua_pop(L, 1);
- /* perms reftbl ... */
- return res;
-}
-#endif
-
-static void unpersist(UnpersistInfo *upi)
-{
- /* perms reftbl ... */
- int firstTime;
- int stacksize = lua_gettop(upi->L); stacksize = stacksize; /* DEBUG */
- lua_checkstack(upi->L, 2);
- LIF(Z,read)(&upi->zio, &firstTime, sizeof(int));
- if(firstTime) {
- int ref;
- int type;
- LIF(Z,read)(&upi->zio, &ref, sizeof(int));
- lua_assert(!inreftable(upi->L, ref));
- LIF(Z,read)(&upi->zio, &type, sizeof(int));
-#ifdef PLUTO_DEBUG
- printindent(upi->level);
- printf("1 %d %d\n", ref, type);
- upi->level++;
-#endif
- switch(type) {
- case LUA_TBOOLEAN:
- unpersistboolean(upi);
- break;
- case LUA_TLIGHTUSERDATA:
- unpersistlightuserdata(upi);
- break;
- case LUA_TNUMBER:
- unpersistnumber(upi);
- break;
- case LUA_TSTRING:
- unpersiststring(upi);
- break;
- case LUA_TTABLE:
- unpersisttable(ref, upi);
- break;
- case LUA_TFUNCTION:
- unpersistfunction(ref, upi);
- break;
- case LUA_TTHREAD:
- unpersistthread(ref, upi);
- break;
- case LUA_TPROTO:
- unpersistproto(ref, upi);
- break;
- case LUA_TUPVAL:
- unpersistupval(ref, upi);
- break;
- case LUA_TUSERDATA:
- unpersistuserdata(ref, upi);
- break;
- case PLUTO_TPERMANENT:
- unpersistpermanent(ref, upi);
- break;
- default:
- lua_assert(0);
- }
- /* perms reftbl ... obj */
- lua_assert(lua_type(upi->L, -1) == type ||
- type == PLUTO_TPERMANENT ||
- /* Remember, upvalues get a special dispensation, as
- * described in boxupval */
- (lua_type(upi->L, -1) == LUA_TFUNCTION &&
- type == LUA_TUPVAL));
- registerobject(ref, upi);
- /* perms reftbl ... obj */
-#ifdef PLUTO_DEBUG
- upi->level--;
-#endif
- } else {
- int ref;
- LIF(Z,read)(&upi->zio, &ref, sizeof(int));
-#ifdef PLUTO_DEBUG
- printindent(upi->level);
- printf("0 %d\n", ref);
-#endif
- if(ref == 0) {
- lua_pushnil(upi->L);
- /* perms reftbl ... nil */
- } else {
- lua_pushlightuserdata(upi->L, (void *)ref);
- /* perms reftbl ... ref */
- lua_gettable(upi->L, 2);
- /* perms reftbl ... obj? */
- lua_assert(!lua_isnil(upi->L, -1));
- }
- /* perms reftbl ... obj/nil */
- }
- /* perms reftbl ... obj/nil */
- lua_assert(lua_gettop(upi->L) == stacksize + 1);
-}
-
-void pluto_unpersist(lua_State *L, lua_Chunkreader reader, void *ud)
-{
- /* We use the graciously provided ZIO (what the heck does the Z stand
- * for?) library so that we don't have to deal with the reader directly.
- * Letting the reader function decide how much data to return can be
- * very unpleasant.
- */
- UnpersistInfo upi;
- upi.L = L;
-#ifdef PLUTO_DEBUG
- upi.level = 0;
-#endif
-
- lua_checkstack(L, 3);
- LIF(Z,init)(L, &upi.zio, reader, ud);
-
- /* perms */
- lua_newtable(L);
- /* perms reftbl */
- lua_gc(L, LUA_GCSTOP, 0);
- unpersist(&upi);
- lua_gc(L, LUA_GCRESTART, 0);
- /* perms reftbl rootobj */
- lua_replace(L, 2);
- /* perms rootobj */
-}
-
-typedef struct LoadInfo_t {
- char *buf;
- size_t size;
-} LoadInfo;
-
-
-static const char *bufreader(lua_State *L, void *ud, size_t *sz) {
- LoadInfo *li = (LoadInfo *)ud;
- if(li->size == 0) {
- return NULL;
- }
- *sz = li->size;
- li->size = 0;
- return li->buf;
-}
-
-int unpersist_l(lua_State *L)
-{
- LoadInfo li;
- char const *origbuf;
- char *tempbuf;
- size_t bufsize;
- /* perms? str? ...? */
- lua_settop(L, 2);
- /* perms? str? */
- origbuf = luaL_checklstring(L, 2, &bufsize);
- tempbuf = LIF(M,newvector)(L, bufsize, char);
- memcpy(tempbuf, origbuf, bufsize);
-
- li.buf = tempbuf;
- li.size = bufsize;
-
- /* perms? str */
- lua_pop(L, 1);
- /* perms? */
- luaL_checktype(L, 1, LUA_TTABLE);
- /* perms */
- pluto_unpersist(L, bufreader, &li);
- /* perms rootobj */
- LIF(M,freearray)(L, tempbuf, bufsize, char);
- return 1;
-}
-
-/* Stefan's first C function for Lua! :)
- Returns a string describing the Pluto version you're using. */
-
-int version_l(lua_State *L)
-{
- const char *version = VERSION;
-
- lua_settop(L, 0);
- /* (empty) */
- lua_pushlstring(L, version, strlen(version));
- /* str */
- return 1;
-}
-
-/* Set human-readable output on or off. */
-int human_l(lua_State *L)
-{
- /* flag? ...? */
- lua_settop(L, 1);
- /* flag? */
- /*luaL_checktype(L, 1, LUA_TBOOLEAN);*/
- /* flag */
-
- humanReadable = lua_toboolean(L, 1);
-
- lua_settop(L, 0);
- /* (empty) */
- return 0;
-}
-
-static luaL_reg pluto_reg[] = {
- { "persist", persist_l },
- { "unpersist", unpersist_l },
- { "version", version_l },
- { "human", human_l },
- { NULL, NULL }
-};
-
-LUALIB_API int luaopen_pluto(lua_State *L) {
- luaL_openlib(L, "pluto", pluto_reg, 0);
- return 1;
-}
diff --git a/engines/sword25/util/pluto/pluto.h b/engines/sword25/util/pluto/pluto.h
deleted file mode 100644
index 3674842d44..0000000000
--- a/engines/sword25/util/pluto/pluto.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* $Id$ */
-
-/* Pluto - Heavy-duty persistence for Lua
- * Copyright (C) 2004 by Ben Sunshine-Hill, and released into the public
- * domain. People making use of this software as part of an application
- * are politely requested to email the author at sneftel@gmail.com
- * with a brief description of the application, primarily to satisfy his
- * curiosity.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/* lua.h must be included before this file */
-
-void pluto_persist(lua_State *L, lua_Chunkwriter writer, void *ud);
-
-void pluto_unpersist(lua_State *L, lua_Chunkreader reader, void *ud);
-
-LUALIB_API int luaopen_pluto(lua_State *L);
diff --git a/engines/sword25/util/pluto/plzio.cpp b/engines/sword25/util/pluto/plzio.cpp
deleted file mode 100644
index 21f69a9e8d..0000000000
--- a/engines/sword25/util/pluto/plzio.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
-** $Id$
-** a generic input stream interface
-** See Copyright Notice in lua.h
-*/
-
-
-#include <string.h>
-
-#define lzio_c
-#define LUA_CORE
-
-#include "pdep/pdep.h"
-
-int pdep_fill (ZIO *z) {
- size_t size;
- lua_State *L = z->L;
- const char *buff;
- lua_unlock(L);
- buff = z->reader(L, z->data, &size);
- lua_lock(L);
- if (buff == NULL || size == 0) return EOZ;
- z->n = size - 1;
- z->p = buff;
- return char2int(*(z->p++));
-}
-
-
-int pdep_lookahead (ZIO *z) {
- if (z->n == 0) {
- if (pdep_fill(z) == EOZ)
- return EOZ;
- else {
- z->n++; /* pdep_fill removed first byte; put back it */
- z->p--;
- }
- }
- return char2int(*z->p);
-}
-
-
-void pdep_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) {
- z->L = L;
- z->reader = reader;
- z->data = data;
- z->n = 0;
- z->p = NULL;
-}
-
-
-/* --------------------------------------------------------------- read --- */
-size_t pdep_read (ZIO *z, void *b, size_t n) {
- while (n) {
- size_t m;
- if (pdep_lookahead(z) == EOZ)
- return n; /* return number of missing bytes */
- m = (n <= z->n) ? n : z->n; /* min. between n and z->n */
- memcpy(b, z->p, m);
- z->n -= m;
- z->p += m;
- b = (char *)b + m;
- n -= m;
- }
- return 0;
-}
-
-/* ------------------------------------------------------------------------ */
-char *pdep_openspace (lua_State *L, Mbuffer *buff, size_t n) {
- if (n > buff->buffsize) {
- if (n < LUA_MINBUFFER) n = LUA_MINBUFFER;
- pdep_resizebuffer(L, buff, n);
- }
- return buff->buffer;
-}
diff --git a/engines/tinsel/music.cpp b/engines/tinsel/music.cpp
index 8a7305f63b..9b4e2494e0 100644
--- a/engines/tinsel/music.cpp
+++ b/engines/tinsel/music.cpp
@@ -27,6 +27,8 @@
#include "audio/audiostream.h"
#include "audio/mididrv.h"
#include "audio/midiparser.h"
+// Miles Audio for Discworld 1
+#include "audio/miles.h"
#include "audio/decoders/adpcm.h"
#include "backends/audiocd/audiocd.h"
@@ -373,8 +375,78 @@ void DeleteMidiBuffer() {
g_midiBuffer.pDat = NULL;
}
-MidiMusicPlayer::MidiMusicPlayer() {
- MidiPlayer::createDriver();
+MidiMusicPlayer::MidiMusicPlayer(TinselEngine *vm) {
+ _driver = NULL;
+ _milesAudioMode = false;
+ bool milesAudioEnabled = false;
+
+ if (vm->getPlatform() == Common::kPlatformDOS) {
+ // Enable Miles Audio for DOS only
+ milesAudioEnabled = true;
+ }
+
+ if ((vm->getGameId() == GID_DW1) && (milesAudioEnabled)) {
+ // Discworld 1 (DOS) uses Miles Audio 3
+ // use our own Miles Audio drivers
+ //
+ // It seems that there are multiple versions of Discworld 1
+ //
+ // Version 1:
+ // Has SAMPLE.AD for AdLib and SAMPLE.OPL for OPL-3
+ // Timbre files are inside a subdirectory of the CD called "/drivers". Main game files are in
+ // another subdirectory, which means the user has to copy those files over.
+ // Installer script copies all drivers directly to harddrive without name changes
+ //
+ // Version 2:
+ // Has FAT.OPL only (gets copied by the installer into MIDPAK.AD or MIDPAK.OPL)
+ // Timbre file is inside subdirectory "drivers" right in the main game directory.
+ // Installer copies FAT.OPL to MIDPAK.AD all the time, even when user selected AWE32
+ //
+ // Neither have timbre data for MT32
+
+ ::MidiDriver::DeviceHandle dev = ::MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
+ ::MusicType musicType = ::MidiDriver::getMusicType(dev);
+ Common::File fileClass;
+
+ switch (musicType) {
+ case MT_ADLIB:
+ if (fileClass.exists("FAT.OPL")) {
+ // Version 2: fat.opl, may be in drivers-subdirectory
+ _driver = Audio::MidiDriver_Miles_AdLib_create("", "FAT.OPL");
+ } else {
+ if (fileClass.exists("MIDPAK.AD")) {
+ // Version 2: drivers got installed and fat.opl got copied over by the user
+ _driver = Audio::MidiDriver_Miles_AdLib_create("MIDPAK.AD", "");
+ } else {
+ // Version 1: sample.ad / sample.opl, have to be copied over by the user for this version
+ // That's why we check those last, because then the user gets a proper error message for them
+ _driver = Audio::MidiDriver_Miles_AdLib_create("SAMPLE.AD", "SAMPLE.OPL");
+ }
+ }
+ break;
+ case MT_MT32:
+ // Discworld 1 doesn't have a MT32 timbre file
+ _driver = Audio::MidiDriver_Miles_MT32_create("");
+ break;
+ case MT_GM:
+ if (ConfMan.getBool("native_mt32")) {
+ _driver = Audio::MidiDriver_Miles_MT32_create("");
+ musicType = MT_MT32;
+ }
+ break;
+ default:
+ break;
+ }
+ if (!_driver) {
+ // nothing got created yet? -> create default driver
+ MidiPlayer::createDriver();
+ } else {
+ _milesAudioMode = true;
+ }
+
+ } else {
+ MidiPlayer::createDriver();
+ }
int ret = _driver->open();
if (ret == 0) {
@@ -394,6 +466,11 @@ void MidiMusicPlayer::setVolume(int volume) {
}
void MidiMusicPlayer::send(uint32 b) {
+ if (_milesAudioMode) {
+ _driver->send(b);
+ return;
+ }
+
Audio::MidiPlayer::send(b);
byte channel = (byte)(b & 0x0F);
diff --git a/engines/tinsel/music.h b/engines/tinsel/music.h
index 0a78c39a76..422d80ae30 100644
--- a/engines/tinsel/music.h
+++ b/engines/tinsel/music.h
@@ -60,7 +60,7 @@ void dumpMusic();
class MidiMusicPlayer : public Audio::MidiPlayer {
public:
- MidiMusicPlayer();
+ MidiMusicPlayer(TinselEngine *vm);
virtual void setVolume(int volume);
@@ -77,6 +77,8 @@ public:
// means. The default is 120.
uint32 getBaseTempo() { return _driver ? (109 * _driver->getBaseTempo()) / 120 : 0; }
+ bool _milesAudioMode;
+
private:
void playXMIDI(uint32 size, bool loop);
void playSEQ(uint32 size, bool loop);
diff --git a/engines/tinsel/tinsel.cpp b/engines/tinsel/tinsel.cpp
index 57d8432f0e..6dc8e3bb35 100644
--- a/engines/tinsel/tinsel.cpp
+++ b/engines/tinsel/tinsel.cpp
@@ -885,12 +885,15 @@ void TinselEngine::initializePath(const Common::FSNode &gamePath) {
} else {
// Add DW2 subfolder to search path in case user is running directly from the CDs
SearchMan.addSubDirectoryMatching(gamePath, "dw2");
+
+ // Location of Miles audio files (sample.ad and sample.opl) in Discworld 1
+ SearchMan.addSubDirectoryMatching(gamePath, "drivers");
Engine::initializePath(gamePath);
}
}
Common::Error TinselEngine::run() {
- _midiMusic = new MidiMusicPlayer();
+ _midiMusic = new MidiMusicPlayer(this);
_pcmMusic = new PCMMusicPlayer();
_sound = new SoundManager(this);
_bmv = new BMVPlayer();
diff --git a/engines/toltecs/music.cpp b/engines/toltecs/music.cpp
index e4e067de39..97d8b1aea2 100644
--- a/engines/toltecs/music.cpp
+++ b/engines/toltecs/music.cpp
@@ -21,6 +21,7 @@
*/
#include "audio/midiparser.h"
+#include "audio/miles.h"
#include "common/textconsole.h"
#include "toltecs/toltecs.h"
@@ -30,20 +31,47 @@
namespace Toltecs {
MusicPlayer::MusicPlayer(bool isGM) : _isGM(isGM), _buffer(NULL) {
- MidiPlayer::createDriver();
+ MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
+ MusicType musicType = MidiDriver::getMusicType(dev);
+
+ switch (musicType) {
+ case MT_ADLIB:
+ _milesAudioMode = true;
+ _driver = Audio::MidiDriver_Miles_AdLib_create("SAMPLE.AD", "SAMPLE.OPL");
+ break;
+ case MT_MT32:
+ // Not recommended since it sounds awful, but apparently the
+ // original sounded just as bad. I guess MT-32 support was
+ // added by default, not because anyone actually put any work
+ // into it.
+ _milesAudioMode = true;
+ _driver = Audio::MidiDriver_Miles_MT32_create("");
+ break;
+ default:
+ _milesAudioMode = false;
+ MidiPlayer::createDriver();
+ break;
+ }
int ret = _driver->open();
if (ret == 0) {
- if (_nativeMT32)
- _driver->sendMT32Reset();
- else
- _driver->sendGMReset();
+ if (musicType != MT_ADLIB) {
+ if (musicType == MT_MT32 || _nativeMT32)
+ _driver->sendMT32Reset();
+ else
+ _driver->sendGMReset();
+ }
_driver->setTimerCallback(this, &timerCallback);
}
}
void MusicPlayer::send(uint32 b) {
+ if (_milesAudioMode) {
+ _driver->send(b);
+ return;
+ }
+
if ((b & 0xF0) == 0xC0 && !_isGM && !_nativeMT32) {
b = (b & 0xFFFF00FF) | MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8;
}
diff --git a/engines/toltecs/music.h b/engines/toltecs/music.h
index e6dc3dd146..25d67e9334 100644
--- a/engines/toltecs/music.h
+++ b/engines/toltecs/music.h
@@ -47,6 +47,7 @@ protected:
private:
byte *_buffer;
+ bool _milesAudioMode;
};
class Music : public MusicPlayer {
diff --git a/engines/tony/mpal/mpal.cpp b/engines/tony/mpal/mpal.cpp
index c813b354b0..89cc28130d 100644
--- a/engines/tony/mpal/mpal.cpp
+++ b/engines/tony/mpal/mpal.cpp
@@ -709,6 +709,10 @@ void ActionThread(CORO_PARAM, const void *param) {
CORO_SLEEP(1);
}
+ // WORKAROUND: User interface sometimes remaining disabled after capturing guard on Ferris wheel
+ if (_ctx->item->_nObj == 3601 && _ctx->item->_dwRes == 9)
+ g_vm->getEngine()->enableInput();
+
globalDestroy(_ctx->item);
_ctx->item = NULL;
diff --git a/engines/tony/window.cpp b/engines/tony/window.cpp
index 3b3687419b..d312d58091 100644
--- a/engines/tony/window.cpp
+++ b/engines/tony/window.cpp
@@ -28,7 +28,7 @@
#include "common/scummsys.h"
#include "graphics/surface.h"
-#include "util.h"
+#include "engines/util.h"
#include "tony/window.h"
#include "tony/game.h"
#include "tony/tony.h"
diff --git a/engines/toon/anim.cpp b/engines/toon/anim.cpp
index ec23fea186..4788ba61a9 100644
--- a/engines/toon/anim.cpp
+++ b/engines/toon/anim.cpp
@@ -150,10 +150,12 @@ void Animation::drawFrame(Graphics::Surface &surface, int32 frame, int16 xx, int
if (_numFrames == 0)
return;
+ int16 dataFrame = frame;
+
if (_frames[frame]._ref != -1)
- frame = _frames[frame]._ref;
+ dataFrame = _frames[frame]._ref;
- if (!_frames[frame]._data)
+ if (!_frames[dataFrame]._data)
return;
int16 rectX = _frames[frame]._x2 - _frames[frame]._x1;
@@ -194,7 +196,7 @@ void Animation::drawFrame(Graphics::Surface &surface, int32 frame, int16 xx, int
return;
int32 destPitch = surface.pitch;
- uint8 *srcRow = _frames[frame]._data + offsX + (_frames[frame]._x2 - _frames[frame]._x1) * offsY;
+ uint8 *srcRow = _frames[dataFrame]._data + offsX + (_frames[frame]._x2 - _frames[frame]._x1) * offsY;
uint8 *curRow = (uint8 *)surface.getBasePtr(xx + _x1 + _frames[frame]._x1 + offsX, yy + _frames[frame]._y1 + _y1 + offsY);
for (int16 y = 0; y < rectY; y++) {
uint8 *cur = curRow;
@@ -216,8 +218,12 @@ void Animation::drawFrameWithMask(Graphics::Surface &surface, int32 frame, int16
void Animation::drawFrameWithMaskAndScale(Graphics::Surface &surface, int32 frame, int16 xx, int16 yy, int32 zz, Picture *mask, int32 scale) {
debugC(5, kDebugAnim, "drawFrameWithMaskAndScale(surface, %d, %d, %d, %d, mask, %d)", frame, xx, yy, zz, scale);
+
+ int16 dataFrame = frame;
+
if (_frames[frame]._ref != -1)
- frame = _frames[frame]._ref;
+ dataFrame = _frames[frame]._ref;
+
int16 rectX = _frames[frame]._x2 - _frames[frame]._x1;
int16 rectY = _frames[frame]._y2 - _frames[frame]._y1;
@@ -235,7 +241,7 @@ void Animation::drawFrameWithMaskAndScale(Graphics::Surface &surface, int32 fram
int32 destPitch = surface.pitch;
int32 destPitchMask = mask->getWidth();
- uint8 *c = _frames[frame]._data;
+ uint8 *c = _frames[dataFrame]._data;
uint8 *curRow = (uint8 *)surface.getPixels();
uint8 *curRowMask = mask->getDataPtr();
@@ -287,9 +293,6 @@ int16 Animation::getFrameWidth(int32 frame) {
if ((frame < 0) || (frame >= _numFrames))
return 0;
- if (_frames[frame]._ref != -1)
- frame = _frames[frame]._ref;
-
return _frames[frame]._x2 - _frames[frame]._x1;
}
@@ -298,9 +301,6 @@ int16 Animation::getFrameHeight(int32 frame) {
if (frame < 0 || frame >= _numFrames)
return 0;
- if (_frames[frame]._ref != -1)
- frame = _frames[frame]._ref;
-
return _frames[frame]._y2 - _frames[frame]._y1;
}
@@ -323,8 +323,10 @@ void Animation::drawFontFrame(Graphics::Surface &surface, int32 frame, int16 xx,
if (_numFrames == 0)
return;
+ int16 dataFrame = frame;
+
if (_frames[frame]._ref != -1)
- frame = _frames[frame]._ref;
+ dataFrame = _frames[frame]._ref;
int16 rectX = _frames[frame]._x2 - _frames[frame]._x1;
int16 rectY = _frames[frame]._y2 - _frames[frame]._y1;
@@ -345,7 +347,7 @@ void Animation::drawFontFrame(Graphics::Surface &surface, int32 frame, int16 xx,
return;
int32 destPitch = surface.pitch;
- uint8 *c = _frames[frame]._data;
+ uint8 *c = _frames[dataFrame]._data;
uint8 *curRow = (uint8 *)surface.getBasePtr(xx + _x1 + _frames[frame]._x1, yy + _frames[frame]._y1 + _y1);
for (int16 y = 0; y < rectY; y++) {
unsigned char *cur = curRow;
diff --git a/engines/toon/character.cpp b/engines/toon/character.cpp
index 686fe99beb..3d7beeeafe 100644
--- a/engines/toon/character.cpp
+++ b/engines/toon/character.cpp
@@ -226,6 +226,11 @@ bool Character::walkTo(int16 newPosX, int16 newPosY) {
}
setFacing(getFacingFromDirection(smoothDx, smoothDy));
+ if (_currentWalkStamp != localWalkStamp) {
+ // another walkTo was started in setFacing, we need to cancel this one.
+ return false;
+ }
+
playWalkAnim(0, 0);
}
diff --git a/engines/toon/font.cpp b/engines/toon/font.cpp
index ab941e5de9..9b08e432fc 100644
--- a/engines/toon/font.cpp
+++ b/engines/toon/font.cpp
@@ -99,7 +99,7 @@ void FontRenderer::renderText(int16 x, int16 y, const Common::String &origText,
} else {
curChar = textToFont(curChar);
_currentFont->drawFontFrame(_vm->getMainSurface(), curChar, curX, curY, _currentFontColor);
- curX = curX + _currentFont->getFrameWidth(curChar) - 1;
+ curX = curX + MAX<int32>(_currentFont->getFrameWidth(curChar) - 2, 0);
height = MAX<int32>(height, _currentFont->getFrameHeight(curChar));
}
text++;
@@ -138,8 +138,8 @@ void FontRenderer::computeSize(const Common::String &origText, int16 *retX, int1
// really tell how far it will stick out. For now,
// assume we only need to take the lower bound into
// consideration.
- Common::Rect charRect = _currentFont->getFrameRect(curChar);
- lastLineHeight = MAX(lastLineHeight, charRect.bottom);
+ //Common::Rect charRect = _currentFont->getFrameRect(curChar);
+ lastLineHeight = MAX(lastLineHeight, _currentFont->getHeight());
}
text++;
}
diff --git a/engines/toon/toon.cpp b/engines/toon/toon.cpp
index 2f5051c157..9e2905f454 100644
--- a/engines/toon/toon.cpp
+++ b/engines/toon/toon.cpp
@@ -210,6 +210,9 @@ void ToonEngine::parseInput() {
if (event.kbd.keycode == Common::KEYCODE_s && !hasModifier) {
_audioManager->muteSfx(!_audioManager->isSfxMuted());
}
+ if (event.kbd.keycode == Common::KEYCODE_F1 && !hasModifier && !_gameState->_inMenu) {
+ showOptions();
+ }
if (event.kbd.flags & Common::KBD_ALT) {
int slotNum = event.kbd.keycode - (event.kbd.keycode >= Common::KEYCODE_KP0 ? Common::KEYCODE_KP0 : Common::KEYCODE_0);
@@ -255,7 +258,7 @@ void ToonEngine::parseInput() {
}
}
- if (!_gameState->_inConversation && !_gameState->_mouseHidden && !_gameState->_inInventory) {
+ if (!_gameState->_inConversation && !_gameState->_mouseHidden && !_gameState->_inInventory && !_gameState->_inMenu) {
selectHotspot();
clickEvent();
}
@@ -576,7 +579,29 @@ enum MainMenuMasks {
MAINMENUMASK_EVERYWHERE = 3
};
-struct MainMenuFile {
+enum OptionMenuSelections {
+ OPTIONMENUHOTSPOT_NONE = 0,
+ OPTIONMENUHOTSPOT_PLAY = 1,
+ OPTIONMENUHOTSPOT_QUIT = 2,
+ OPTIONMENUHOTSPOT_TEXT = 3,
+ OPTIONMENUHOTSPOT_TEXTSPEED = 4,
+ OPTIONMENUHOTSPOT_VOLUMESFX = 5,
+ OPTIONMENUHOTSPOT_VOLUMESFXSLIDER = 6,
+ OPTIONMENUHOTSPOT_VOLUMEMUSIC = 7,
+ OPTIONMENUHOTSPOT_VOLUMEMUSICSLIDER = 8,
+ OPTIONMENUHOTSPOT_VOLUMEVOICE = 9,
+ OPTIONMENUHOTSPOT_VOLUMEVOICESLIDER = 10,
+ OPTIONMENUHOTSPOT_SPEAKERBUTTON = 11,
+ OPTIONMENUHOTSPOT_SPEAKERLEVER = 12,
+ OPTIONMENUHOTSPOT_VIDEO_MODE = 13
+};
+
+enum OptionMenuMasks {
+ OPTIONMENUMASK_EVERYWHERE = 1
+};
+
+
+struct MenuFile {
int menuMask;
int id;
const char *animationFile;
@@ -584,7 +609,7 @@ struct MainMenuFile {
};
#define MAINMENU_ENTRYCOUNT 12
-static const MainMenuFile mainMenuFiles[] = {
+static const MenuFile mainMenuFiles[] = {
{ MAINMENUMASK_BASE, MAINMENUHOTSPOT_START, "STARTBUT.CAF", 0 }, // "Start" button
{ MAINMENUMASK_BASE, MAINMENUHOTSPOT_INTRO, "INTROBUT.CAF", 0 }, // "Intro" button
{ MAINMENUMASK_BASE, MAINMENUHOTSPOT_LOADGAME, "LOADBUT.CAF", 0 }, // "Load Game" button
@@ -600,7 +625,38 @@ static const MainMenuFile mainMenuFiles[] = {
{ MAINMENUMASK_HOTKEYS, MAINMENUHOTSPOT_HOTKEYSCLOSE, "HOTKEYS.CAF", 0 } // Hotkeys display - clicking on it will close hotkeys
};
-struct MainMenuEntry {
+#define OPTIONMENU_ENTRYCOUNT 27
+static const MenuFile optionMenuFiles[] = {
+ { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_PLAY, "PLAYBUTN.CAF", 0 }, // "Start" button
+ { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_QUIT, "QUITBUTN.CAF", 0 }, // "Intro" button
+ { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_VIDEO_MODE, "VIDMODE.CAF", 0 }, // "Start" button
+ { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_TEXTSPEED, "TXTSPEED.CAF", 0 }, // "Intro" button
+ { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_TEXT, "TEXTDIAL.CAF", 0}, // "Intro" button
+ { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_VOLUMESFX, "SFXBUTN.CAF", 0 }, // "Start" button
+ { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_VOLUMESFXSLIDER, "SFXSLDR.CAF", 0 }, // "Intro" button
+ { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_VOLUMEVOICE, "VOICEBTN.CAF", 0 }, // "Start" button
+ { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_VOLUMEVOICESLIDER, "VOICESLD.CAF", 0 }, // "Intro" button
+ { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_VOLUMEMUSIC, "MUSICBTN.CAF", 0 }, // "Start" button
+ { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_VOLUMEMUSICSLIDER, "MUSICSLD.CAF", 0 }, // "Intro" button
+ { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_SPEAKERBUTTON, "XTRABUTN.CAF", 0 }, // "Start" button
+ { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_SPEAKERLEVER, "XTRALEVR.CAF", 0}, // "Intro" button
+ { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_NONE, "ANTENNAL.CAF", 6 }, // "Start" button
+ { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_NONE, "ANTENNAR.CAF", 6 }, // "Intro" button
+ { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_NONE, "BIGREDL.CAF", 6 }, // "Start" button
+ { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_NONE, "BIGREDR.CAF", 6 }, // "Intro" button
+ { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_NONE, "GRIDLTEL.CAF", 6 }, // "Start" button
+ { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_NONE, "GRIDLTER.CAF", 6 }, // "Intro" button
+ { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_NONE, "LSPEAKR.CAF", 0 }, // "Start" button
+ { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_NONE, "RSPEAKR.CAF", 0 }, // "Intro" button
+ { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_NONE, "STARLITL.CAF", 6 }, // "Start" button
+ { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_NONE, "STARLITR.CAF", 6 }, // "Intro" button
+ { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_NONE, "CHASE1.CAF", 6 }, // "Intro" button
+ { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_NONE, "CHASE2.CAF", 6 }, // "Intro" button
+ { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_NONE, "CHASE3.CAF", 6 }, // "Intro" button
+ { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_NONE, "CHASE4.CAF", 6 } // "Intro" button
+};
+
+struct MenuEntry {
int menuMask;
int id;
Animation *animation;
@@ -608,15 +664,291 @@ struct MainMenuEntry {
int animateOnFrame;
int animateCurFrame;
int activeFrame;
+ bool playOnce;
};
+bool ToonEngine::showOptions() {
+
+ storePalette();
+ fadeOut(5);
+ Picture* optionPicture = new Picture(this);
+ optionPicture->loadPicture("OPTIONS.CPS");
+ optionPicture->setupPalette();
+ flushPalette(true);
+
+ int16 oldScrollValue = _gameState->_currentScrollValue;
+ _gameState->_currentScrollValue = 0;
+
+ bool oldMouseHidden = _gameState->_mouseHidden;
+ _gameState->_mouseHidden = false;
+
+ MenuEntry entries[OPTIONMENU_ENTRYCOUNT];
+
+ for (int entryNr = 0; entryNr < OPTIONMENU_ENTRYCOUNT; entryNr++) {
+ entries[entryNr].menuMask = optionMenuFiles[entryNr].menuMask;
+ entries[entryNr].id = optionMenuFiles[entryNr].id;
+ entries[entryNr].animation = new Animation(this);
+ entries[entryNr].animation->loadAnimation(optionMenuFiles[entryNr].animationFile);
+ if (entries[entryNr].id != OPTIONMENUHOTSPOT_NONE)
+ entries[entryNr].rect = entries[entryNr].animation->getRect();
+ entries[entryNr].animateOnFrame = optionMenuFiles[entryNr].animateOnFrame;
+ entries[entryNr].animateCurFrame = 0;
+ entries[entryNr].activeFrame = 0;
+ entries[entryNr].playOnce = false;
+ }
+
+ entries[10].activeFrame = _audioManager->_mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType) * (entries[10].animation->_numFrames - 1) / 256;
+ entries[8].activeFrame = _audioManager->_mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType) * (entries[8].animation->_numFrames - 1) / 256;
+ entries[6].activeFrame = _audioManager->_mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType) * (entries[6].animation->_numFrames - 1) / 256;
+
+ entries[9].activeFrame = _audioManager->isMusicMuted() ? 0 : 3;
+ entries[7].activeFrame = _audioManager->isVoiceMuted() ? 0 : 3;
+ entries[5].activeFrame = _audioManager->isSfxMuted() ? 0 : 3;
+
+ entries[2].activeFrame = entries[2].animation->_numFrames - 1;
+
+ if (!_showConversationText) {
+ entries[4].activeFrame = 4;
+ } else if (_useAlternativeFont) {
+ entries[4].activeFrame = 8;
+ } else {
+ entries[4].activeFrame = 0;
+ }
+
+ setCursor(0);
+
+ int menuMask = OPTIONMENUMASK_EVERYWHERE;
+ int ratioX = 0;
+ bool doExit = false;
+ bool exitGame = false;
+ _gameState->_inMenu = true;
+ dirtyAllScreen();
+ _firstFrame = true;
+
+ while (!doExit) {
+
+ int clickingOn = OPTIONMENUHOTSPOT_NONE;
+ int clickingOnSprite = 0;
+ int clickRelease = false;
+
+ while (!clickRelease) {
+
+ if (_dirtyAll) {
+ optionPicture->draw(*_mainSurface, 0, 0, 0, 0);
+ addDirtyRect(0, 0, TOON_SCREEN_WIDTH, TOON_SCREEN_HEIGHT);
+ } else {
+ optionPicture->drawWithRectList(*_mainSurface, 0, 0, 0, 0, _dirtyRects);
+ }
+ clearDirtyRects();
+
+ for (int entryNr = 0; entryNr < OPTIONMENU_ENTRYCOUNT; entryNr++) {
+ if (entries[entryNr].menuMask & menuMask) {
+ if (entries[entryNr].animateOnFrame) {
+ entries[entryNr].animateCurFrame++;
+ if (entries[entryNr].animateOnFrame <= entries[entryNr].animateCurFrame) {
+ entries[entryNr].activeFrame++;
+ if (entries[entryNr].activeFrame >= entries[entryNr].animation->_numFrames) {
+ entries[entryNr].activeFrame = 0;
+ if (entries[entryNr].playOnce) {
+ entries[entryNr].animateOnFrame = 0;
+ entries[entryNr].playOnce = false;
+ }
+ if (entryNr == 20 && entries[entryNr].animateOnFrame > 0) {
+ playSFX(-3, 128);
+ }
+ }
+ entries[entryNr].animateCurFrame = 0;
+ }
+ }
+ int32 frameNr = entries[entryNr].activeFrame;
+ entries[entryNr].animation->drawFrame(*_mainSurface, frameNr, 0, 0);
+ }
+ }
+
+ parseInput();
+
+ copyToVirtualScreen(true);
+ if (_firstFrame) {
+ _firstFrame = false;
+ fadeIn(5);
+ }
+ _system->delayMillis(17);
+
+ if (_mouseButton & 1) {
+ // left mouse button pushed down
+ clickingOn = OPTIONMENUHOTSPOT_NONE;
+ for (int entryNr = 0; entryNr < OPTIONMENU_ENTRYCOUNT; entryNr++) {
+ if (entries[entryNr].menuMask & menuMask) {
+ if (entries[entryNr].id != OPTIONMENUHOTSPOT_NONE) {
+ if (entries[entryNr].rect.contains(_mouseX, _mouseY)) {
+ clickingOn = entries[entryNr].id;
+ clickingOnSprite = entryNr;
+ ratioX = (_mouseX - entries[entryNr].rect.left) * 256 / entries[entryNr].rect.width();
+ }
+ }
+ }
+ }
+ } else {
+ // left mouse button released/not pushed down
+ if (clickingOn != OPTIONMENUHOTSPOT_NONE)
+ clickRelease = true;
+ }
+
+ // handle sliders
+ if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEMUSICSLIDER) {
+ entries[clickingOnSprite].activeFrame = ratioX * (entries[clickingOnSprite].animation->_numFrames) / 256;
+ int vol = entries[clickingOnSprite].activeFrame * 256 / entries[clickingOnSprite].animation->_numFrames;
+ _audioManager->_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, vol);
+ }
+
+ if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEVOICESLIDER) {
+ entries[clickingOnSprite].activeFrame = ratioX * (entries[clickingOnSprite].animation->_numFrames) / 256;
+ int vol = entries[clickingOnSprite].activeFrame * 256 / entries[clickingOnSprite].animation->_numFrames;
+ _audioManager->_mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, vol);
+ }
+
+ if (clickingOn == OPTIONMENUHOTSPOT_VOLUMESFXSLIDER) {
+ entries[clickingOnSprite].activeFrame = ratioX * (entries[clickingOnSprite].animation->_numFrames) / 256;
+ int vol = entries[clickingOnSprite].activeFrame * 256 / entries[clickingOnSprite].animation->_numFrames;
+ _audioManager->_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, vol);
+ }
+
+ if (clickingOn == OPTIONMENUHOTSPOT_TEXTSPEED) {
+ entries[clickingOnSprite].activeFrame = ratioX * (entries[clickingOnSprite].animation->_numFrames) / 256;
+ }
+
+ if (clickingOn == OPTIONMENUHOTSPOT_PLAY) {
+ entries[0].activeFrame = entries[0].animation->_numFrames - 1;
+ } else {
+ entries[0].activeFrame = 0;
+ }
+
+ if (clickingOn == OPTIONMENUHOTSPOT_QUIT) {
+ entries[1].activeFrame = entries[1].animation->_numFrames - 1;
+ } else {
+ entries[1].activeFrame = 0;
+ }
+
+ if (_shouldQuit) {
+ clickingOn = OPTIONMENUHOTSPOT_NONE;
+ clickRelease = true;
+ doExit = true;
+ }
+ }
+
+ if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEMUSIC) {
+ if (entries[9].activeFrame == 0) {
+ entries[9].activeFrame = 3;
+ _audioManager->muteMusic(false);
+ } else {
+ entries[9].activeFrame = 0;
+ _audioManager->muteMusic(true);
+ }
+ playSFX(-7, 128);
+ }
+
+ if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEVOICE) {
+ if (entries[7].activeFrame == 0) {
+ entries[7].activeFrame = 3;
+ _audioManager->muteVoice(false);
+ } else {
+ entries[7].activeFrame = 0;
+ _audioManager->muteVoice(true);
+ }
+ playSFX(-7, 128);
+ }
+
+ if (clickingOn == OPTIONMENUHOTSPOT_VOLUMESFX) {
+ if (entries[5].activeFrame == 0) {
+ entries[5].activeFrame = 3;
+ _audioManager->muteSfx(false);
+ } else {
+ entries[5].activeFrame = 0;
+ _audioManager->muteSfx(true);
+ }
+ playSFX(-7, 128);
+ }
+
+ if (clickingOn == OPTIONMENUHOTSPOT_SPEAKERBUTTON) {
+ entries[11].animateOnFrame = 4;
+ entries[11].playOnce = true;
+
+ entries[19].animateOnFrame = 4;
+ entries[19].playOnce = true;
+
+ playSFX(-10, 128);
+ _audioManager->playVoice(316, true);
+ }
+
+ if (clickingOn == OPTIONMENUHOTSPOT_SPEAKERLEVER) {
+
+ entries[12].activeFrame = 1 - entries[12].activeFrame;
+ if(entries[12].activeFrame == 1) {
+ entries[20].animateOnFrame = 4;
+ entries[20].playOnce = false;
+ playSFX(-3, 128);
+ } else {
+ entries[20].playOnce = true;
+ }
+ playSFX(-9, 128);
+ }
+
+ if (clickingOn == OPTIONMENUHOTSPOT_TEXT) {
+
+ if (entries[4].activeFrame == 0) {
+ _showConversationText = false;
+ entries[4].activeFrame = 4;
+ } else if (entries[4].activeFrame == 4) {
+ _showConversationText = true;
+ setFont(true);
+ entries[4].activeFrame = 8;
+ } else if(entries[4].activeFrame == 8) {
+ _showConversationText = true;
+ setFont(false);
+ entries[4].activeFrame = 0;
+ }
+
+ playSFX(-9, 128);
+ }
+
+ // don't allow change to video mode
+ if (clickingOn == OPTIONMENUHOTSPOT_VIDEO_MODE) {
+ playSoundWrong();
+ }
+
+ if (clickingOn == OPTIONMENUHOTSPOT_PLAY) {
+ doExit = true;
+ exitGame = false;
+ _audioManager->playSFX(10, 128, true);
+ }
+
+ if (clickingOn == OPTIONMENUHOTSPOT_QUIT) {
+ doExit = true;
+ exitGame = true;
+ _shouldQuit = true;
+ _audioManager->playSFX(10, 128, true);
+ }
+ }
+
+ fadeOut(5);
+ _gameState->_mouseHidden = oldMouseHidden;
+ _gameState->_inMenu = false;
+ _firstFrame = true;
+ _gameState->_currentScrollValue = oldScrollValue;
+
+ restorePalette();
+ dirtyAllScreen();
+
+ return exitGame;
+}
+
bool ToonEngine::showMainmenu(bool &loadedGame) {
Picture *mainmenuPicture = new Picture(this);
mainmenuPicture->loadPicture("TITLESCR.CPS");
mainmenuPicture->setupPalette();
flushPalette(false);
- MainMenuEntry entries[MAINMENU_ENTRYCOUNT];
+ MenuEntry entries[MAINMENU_ENTRYCOUNT];
for (int entryNr = 0; entryNr < MAINMENU_ENTRYCOUNT; entryNr++) {
entries[entryNr].menuMask = mainMenuFiles[entryNr].menuMask;
@@ -630,7 +962,7 @@ bool ToonEngine::showMainmenu(bool &loadedGame) {
entries[entryNr].activeFrame = 0;
}
- setCursor(1);
+ setCursor(0);
bool doExit = false;
bool exitGame = false;
@@ -822,6 +1154,7 @@ ToonEngine::ToonEngine(OSystem *syst, const ADGameDescription *gameDescription)
_inventoryPicture = NULL;
_currentMask = NULL;
_showConversationText = true;
+ _useAlternativeFont = false;
_isDemo = _gameDescription->flags & ADGF_DEMO;
DebugMan.addDebugChannel(kDebugAnim, "Anim", "Animation debug level");
@@ -1452,7 +1785,7 @@ int32 ToonEngine::runEventScript(int32 x, int32 y, int32 mode, int32 id, int32 s
_currentScriptRegion++;
_script->start(status, 1);
- while (_script->run(status))
+ while (_script->run(status) && !_shouldQuit)
waitForScriptStep();
_currentScriptRegion--;
@@ -1853,6 +2186,17 @@ void ToonEngine::initFonts() {
_fontEZ = new Animation(this);
_fontEZ->loadAnimation("EZFONT.CAF");
+
+ setFont(false);
+}
+
+void ToonEngine::setFont(bool alternative) {
+ if (alternative) {
+ _currentFont = _fontEZ;
+ } else {
+ _currentFont = _fontToon;
+ }
+ _useAlternativeFont = alternative;
}
void ToonEngine::drawInfoLine() {
@@ -1870,7 +2214,7 @@ void ToonEngine::drawInfoLine() {
}
if (infoTool) {
_fontRenderer->setFontColor(0xc8, 0xdd, 0xe3);
- _fontRenderer->setFont(_fontToon);
+ _fontRenderer->setFont(_currentFont);
_fontRenderer->renderText(320 + _gameState->_currentScrollValue, 398, infoTool, 5);
}
}
@@ -1998,6 +2342,8 @@ int32 ToonEngine::simpleCharacterTalk(int32 dialogid) {
_audioManager->playVoice(myId, false);
} else {
myId = _genericTexts->getId(dialogid - 1000);
+ if (myId == -1)
+ return 0;
_audioManager->playVoice(myId, true);
}
@@ -2936,7 +3282,7 @@ Character *ToonEngine::getCharacterById(int32 charId) {
void ToonEngine::drawConversationLine() {
if (_currentTextLine && _showConversationText) {
_fontRenderer->setFontColorByCharacter(_currentTextLineCharacterId);
- _fontRenderer->setFont(_fontToon);
+ _fontRenderer->setFont(_currentFont);
_fontRenderer->renderMultiLineText(_currentTextLineX, _currentTextLineY, _currentTextLine, 0);
}
}
diff --git a/engines/toon/toon.h b/engines/toon/toon.h
index 6903e5de57..f419d491c6 100644
--- a/engines/toon/toon.h
+++ b/engines/toon/toon.h
@@ -111,6 +111,7 @@ public:
Common::Error run();
GUI::Debugger *getDebugger() { return _console; }
bool showMainmenu(bool &loadedGame);
+ bool showOptions();
void init();
bool loadToonDat();
char **loadTextsVariants(Common::File &in);
@@ -122,6 +123,7 @@ public:
void parseInput();
void initChapter();
void initFonts();
+ void setFont(bool alternative);
void loadScene(int32 SceneId, bool forGameLoad = false);
void exitScene();
void loadCursor();
@@ -421,6 +423,7 @@ protected:
FontRenderer *_fontRenderer;
Animation *_fontToon;
Animation *_fontEZ;
+ Animation *_currentFont;
AudioManager *_audioManager;
@@ -431,6 +434,7 @@ protected:
bool _firstFrame;
bool _isDemo;
bool _showConversationText;
+ bool _useAlternativeFont;
bool _needPaletteFlush;
private:
ToonConsole *_console;
diff --git a/engines/tsage/blue_force/blueforce_scenes8.cpp b/engines/tsage/blue_force/blueforce_scenes8.cpp
index 6855fd41b9..337e73dad0 100644
--- a/engines/tsage/blue_force/blueforce_scenes8.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes8.cpp
@@ -964,9 +964,10 @@ Scene810::Scene810(): SceneExt() {
}
void Scene810::synchronize(Serializer &s) {
+ int dummy = 0;
SceneExt::synchronize(s);
s.syncAsSint16LE(_fieldA70);
- s.syncAsSint16LE(_fieldA72);
+ s.syncAsSint16LE(dummy);
s.syncAsSint16LE(_fieldA74);
}
@@ -2220,6 +2221,7 @@ Scene840::Scene840(): PalettedScene() {
_field1AC2 = 0;
_field1AC4 = 0;
_field1AC6 = (BF_GLOBALS._dayNumber > 3) ? 1 : 0;
+ _field1ABA = 0;
}
void Scene840::synchronize(Serializer &s) {
diff --git a/engines/tsage/blue_force/blueforce_scenes8.h b/engines/tsage/blue_force/blueforce_scenes8.h
index 140327e85d..09de14f150 100644
--- a/engines/tsage/blue_force/blueforce_scenes8.h
+++ b/engines/tsage/blue_force/blueforce_scenes8.h
@@ -229,7 +229,7 @@ public:
Exit _exit;
ASoundExt _sound1;
Rect _rect1, _rect2, _rect3;
- int _fieldA70, _fieldA72, _fieldA74;
+ int _fieldA70, _fieldA74;
Scene810();
virtual void synchronize(Serializer &s);
diff --git a/engines/tsage/blue_force/blueforce_scenes9.cpp b/engines/tsage/blue_force/blueforce_scenes9.cpp
index 53000d6997..5ba82a4714 100644
--- a/engines/tsage/blue_force/blueforce_scenes9.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes9.cpp
@@ -3521,7 +3521,7 @@ void Scene935::Action1::signal() {
scene->_visualSpeaker.removeText();
scene->_visualSpeaker._textPos.y = scene->_sceneBounds.top + 80;
scene->_visualSpeaker._color1 = 252;
- scene->_visualSpeaker._color1 = 251;
+ scene->_visualSpeaker._color2 = 251;
scene->_visualSpeaker.setText("Jake! Hide in the closet!");
setDelay(3);
break;
@@ -3538,7 +3538,7 @@ void Scene935::Action1::signal() {
scene->_visualSpeaker.removeText();
scene->_visualSpeaker._textPos.y = scene->_sceneBounds.top + 150;
scene->_visualSpeaker._color1 = 250;
- scene->_visualSpeaker._color1 = 249;
+ scene->_visualSpeaker._color2 = 249;
scene->_visualSpeaker.setText("Jake! Hide in the closet!");
setDelay(3);
break;
diff --git a/engines/tsage/core.cpp b/engines/tsage/core.cpp
index f35aa583e2..d4068c25c9 100644
--- a/engines/tsage/core.cpp
+++ b/engines/tsage/core.cpp
@@ -56,6 +56,9 @@ InvObject::InvObject(int sceneNumber, int rlbNum, int cursorNum, CursorType curs
_bounds = s.getBounds();
DEALLOCATE(imgData);
+ _visage = 0;
+ _strip = 0;
+ _frame = 0;
}
InvObject::InvObject(int visage, int strip, int frame) {
@@ -1462,7 +1465,7 @@ void ScenePalette::fade(const byte *adjustData, bool fullAdjust, int percent) {
adjustData += 3;
}
- // Set the altered pale4tte
+ // Set the altered palette
g_system->getPaletteManager()->setPalette((const byte *)&tempPalette[0], 0, 256);
GLOBALS._screenSurface.updateScreen();
}
@@ -1518,7 +1521,7 @@ void ScenePalette::changeBackground(const Rect &bounds, FadeMode fadeMode) {
}
Rect tempRect = bounds;
- if (g_vm->getGameID() != GType_Ringworld)
+ if (g_vm->getGameID() != GType_Ringworld && g_vm->getGameID() != GType_Sherlock1)
tempRect.setHeight(T2_GLOBALS._interfaceY);
g_globals->_screenSurface.copyFrom(g_globals->_sceneManager._scene->_backSurface,
@@ -2803,7 +2806,7 @@ void SceneObject::updateScreen() {
srcRect.right = ((srcRect.right + 3) / 4) * 4;
srcRect.clip(g_globals->_sceneManager._scene->_sceneBounds);
- if (g_vm->getGameID() != GType_Ringworld) {
+ if (g_vm->getGameID() != GType_Ringworld && g_vm->getGameID() != GType_Sherlock1) {
if (T2_GLOBALS._uiElements._visible)
srcRect.bottom = MIN<int16>(srcRect.bottom, T2_GLOBALS._interfaceY);
}
diff --git a/engines/tsage/detection.cpp b/engines/tsage/detection.cpp
index 9d61b4d182..388967931d 100644
--- a/engines/tsage/detection.cpp
+++ b/engines/tsage/detection.cpp
@@ -62,6 +62,7 @@ static const PlainGameDescriptor tSageGameTitles[] = {
{ "ringworld", "Ringworld: Revenge of the Patriarch" },
{ "blueforce", "Blue Force" },
{ "ringworld2", "Return to Ringworld" },
+ { "sherlock-logo", "The Lost Files of Sherlock Holmes (Logo)" },
{ 0, 0 }
};
diff --git a/engines/tsage/detection_tables.h b/engines/tsage/detection_tables.h
index da283a27e7..1dfc3e6fd2 100644
--- a/engines/tsage/detection_tables.h
+++ b/engines/tsage/detection_tables.h
@@ -185,6 +185,22 @@ static const tSageGameDescription gameDescriptions[] = {
GType_Ringworld2,
GF_CD | GF_ALT_REGIONS | GF_DEMO
},
+
+ // The Lost Files of Sherlock Holmes - The Case of the Serrated Scalpel (Logo)
+ {
+ {
+ "sherlock-logo",
+ "",
+ AD_ENTRY1s("sf3.rlb", "153f9b93eda4e95578e31be30e69b5e5", 50419),
+ Common::EN_ANY,
+ Common::kPlatformDOS,
+ ADGF_NO_FLAGS,
+ GUIO0()
+ },
+ GType_Sherlock1,
+ GF_FLOPPY
+ },
+
{ AD_TABLE_END_MARKER, 0, 0 }
};
diff --git a/engines/tsage/globals.cpp b/engines/tsage/globals.cpp
index e75febfdbc..1be3e2b6da 100644
--- a/engines/tsage/globals.cpp
+++ b/engines/tsage/globals.cpp
@@ -27,6 +27,7 @@
#include "tsage/ringworld/ringworld_logic.h"
#include "tsage/ringworld2/ringworld2_logic.h"
#include "tsage/ringworld2/ringworld2_scenes0.h"
+#include "tsage/sherlock/sherlock_logo.h"
#include "tsage/staticres.h"
namespace TsAGE {
@@ -156,6 +157,12 @@ Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screenSurface
_game = new Ringworld2::Ringworld2Game();
_sceneHandler = new Ringworld2::SceneHandlerExt();
break;
+
+ case GType_Sherlock1:
+ _inventory = nullptr;
+ _sceneHandler = new Sherlock::SherlockSceneHandler();
+ _game = new Sherlock::SherlockLogo();
+ break;
}
}
diff --git a/engines/tsage/graphics.cpp b/engines/tsage/graphics.cpp
index ce24c76290..156503fb51 100644
--- a/engines/tsage/graphics.cpp
+++ b/engines/tsage/graphics.cpp
@@ -1289,7 +1289,8 @@ void GfxManager::setDefaults() {
_font._edgeSize = Common::Point(1, 1);
_font._colors = g_globals->_fontColors;
- _font.setFontNumber(g_globals->_gfxFontNumber);
+ if (g_globals->_gfxFontNumber >= 0)
+ _font.setFontNumber(g_globals->_gfxFontNumber);
}
void GfxManager::activate() {
diff --git a/engines/tsage/graphics.h b/engines/tsage/graphics.h
index d65d0bcf8b..25f7aea8cd 100644
--- a/engines/tsage/graphics.h
+++ b/engines/tsage/graphics.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef RING_GRAPHICS_H
-#define RING_GRAPHICS_H
+#ifndef TSAGE_GRAPHICS_H
+#define TSAGE_GRAPHICS_H
#include "tsage/events.h"
#include "tsage/saveload.h"
diff --git a/engines/tsage/module.mk b/engines/tsage/module.mk
index d62f398c20..e23b157a95 100644
--- a/engines/tsage/module.mk
+++ b/engines/tsage/module.mk
@@ -47,6 +47,7 @@ MODULE_OBJS := \
ringworld2/ringworld2_vampire.o \
saveload.o \
scenes.o \
+ sherlock/sherlock_logo.o \
sound.o \
staticres.o \
tsage.o \
diff --git a/engines/tsage/resources.h b/engines/tsage/resources.h
index a7536a3c2d..7aa0c49dd4 100644
--- a/engines/tsage/resources.h
+++ b/engines/tsage/resources.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef RING_RESOURCES_H
-#define RING_RESOURCES_H
+#ifndef TSAGE_RESOURCES_H
+#define TSAGE_RESOURCES_H
#include "common/scummsys.h"
#include "common/array.h"
diff --git a/engines/tsage/ringworld/ringworld_scenes3.cpp b/engines/tsage/ringworld/ringworld_scenes3.cpp
index d8556c691e..a515224964 100644
--- a/engines/tsage/ringworld/ringworld_scenes3.cpp
+++ b/engines/tsage/ringworld/ringworld_scenes3.cpp
@@ -494,7 +494,7 @@ void Scene2100::Action1::signal() {
setDelay(1);
else {
setAction(&scene->_sequenceManager, this, 2102, &g_globals->_player, NULL);
- scene->_sitFl = 0;
+ scene->_sitFl = false;
}
break;
case 1: {
@@ -1548,6 +1548,7 @@ Scene2100::Scene2100() :
_area3._pt = Common::Point(200, 75);
_area4.setup(2153, 1, 1, OBJECT_TRANSLATOR);
_area4._pt = Common::Point(237, 77);
+ _sitFl = false;
}
void Scene2100::postInit(SceneObjectList *OwnerList) {
@@ -1688,7 +1689,7 @@ void Scene2100::postInit(SceneObjectList *OwnerList) {
g_globals->_player._moveDiff.x = 4;
g_globals->_player.changeZoom(-1);
g_globals->_player.disableControl();
- _sitFl = 0;
+ _sitFl = false;
switch (g_globals->_sceneManager._previousScene) {
case 2120:
@@ -1824,7 +1825,7 @@ void Scene2100::postInit(SceneObjectList *OwnerList) {
g_globals->_player.fixPriority(152);
g_globals->_player.setStrip(2);
- _sitFl = 1;
+ _sitFl = true;
_object4.postInit();
_object4.setVisage(2102);
@@ -1858,7 +1859,7 @@ void Scene2100::postInit(SceneObjectList *OwnerList) {
g_globals->_player.fixPriority(152);
g_globals->_player.setStrip(2);
- _sitFl = 1;
+ _sitFl = true;
setAction(&_action16);
}
break;
@@ -1932,12 +1933,12 @@ void Scene2100::stripCallback(int v) {
void Scene2100::signal() {
switch (_sceneMode) {
case 2101:
- _sitFl = 1;
+ _sitFl = true;
g_globals->_player._uiEnabled = true;
g_globals->_events.setCursor(CURSOR_USE);
break;
case 2102:
- _sitFl = 0;
+ _sitFl = false;
g_globals->_player.enableControl();
break;
case 2103:
@@ -5789,6 +5790,7 @@ Scene2320::Scene2320() :
_area3._pt = Common::Point(200, 75);
_area4.setup(2153, 1, 1, 10);
_area4._pt = Common::Point(237, 77);
+ _hotspotPtr = nullptr;
}
void Scene2320::postInit(SceneObjectList *OwnerList) {
diff --git a/engines/tsage/ringworld/ringworld_scenes3.h b/engines/tsage/ringworld/ringworld_scenes3.h
index a371f800b9..752b6acd48 100644
--- a/engines/tsage/ringworld/ringworld_scenes3.h
+++ b/engines/tsage/ringworld/ringworld_scenes3.h
@@ -283,7 +283,7 @@ public:
Action15 _action15;
Action16 _action16;
Action17 _action17;
- int _sitFl;
+ bool _sitFl;
SceneArea _area1, _area2, _area3, _area4;
Scene2100();
diff --git a/engines/tsage/sherlock/sherlock_logo.cpp b/engines/tsage/sherlock/sherlock_logo.cpp
new file mode 100644
index 0000000000..2922a9938b
--- /dev/null
+++ b/engines/tsage/sherlock/sherlock_logo.cpp
@@ -0,0 +1,356 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "tsage/sherlock/sherlock_logo.h"
+#include "tsage/scenes.h"
+#include "tsage/tsage.h"
+
+namespace TsAGE {
+
+namespace Sherlock {
+
+void SherlockLogo::start() {
+ GLOBALS._gfxFontNumber = -1;
+ GLOBALS.gfxManager().setDefaults();
+
+ // Start the demo's single scene
+ g_globals->_sceneManager.changeScene(1);
+
+ g_globals->_events.setCursor(CURSOR_NONE);
+}
+
+Scene *SherlockLogo::createScene(int sceneNumber) {
+ // The demo only has a single scene, so ignore the scene number and always return it
+ return new SherlockLogoScene();
+}
+
+bool SherlockLogo::canLoadGameStateCurrently() {
+ return false;
+}
+
+bool SherlockLogo::canSaveGameStateCurrently() {
+ return false;
+}
+
+void SherlockLogo::processEvent(Event &event) {
+ if (event.eventType == EVENT_BUTTON_DOWN || (event.eventType == EVENT_KEYPRESS &&
+ event.kbd.keycode == Common::KEYCODE_ESCAPE))
+ quitGame();
+}
+
+void SherlockLogo::quitGame() {
+ g_vm->quitGame();
+}
+
+/*--------------------------------------------------------------------------*/
+
+void SherlockSceneHandler::postInit(SceneObjectList *OwnerList) {
+ _delayTicks = 2;
+
+ GLOBALS._soundManager.postInit();
+ GLOBALS._soundManager.buildDriverList(true);
+ GLOBALS._soundManager.installConfigDrivers();
+
+ GLOBALS._sceneManager.setNewScene(10);
+ GLOBALS._game->start();
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Object::setVisage(const Common::String &name) {
+ int visageNum = atoi(name.c_str());
+ SceneObject::setVisage(visageNum);
+}
+
+/*--------------------------------------------------------------------------*/
+
+void SherlockLogoScene::Action1::signal() {
+ SherlockLogoScene &scene = *(SherlockLogoScene *)GLOBALS._sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ // Load scene palette
+ GLOBALS._scenePalette.loadPalette(1111);
+ GLOBALS._scenePalette.loadPalette(1);
+ GLOBALS._scenePalette.refresh();
+ setDelay(1);
+ break;
+
+ case 1:
+ // Fade in the spotlight background
+ GLOBALS._scenePalette.addFader(scene._palette1._palette, 256, 6, this);
+ break;
+
+ case 2:
+ // First half of square, circle, and triangle bouncing
+ scene._object1.postInit();
+ scene._object1.setVisage("0016.vis");
+ scene._object1._strip = 1;
+ scene._object1._frame = 1;
+ scene._object1.setPosition(Common::Point(169, 107));
+ scene._object1.changeZoom(100);
+ scene._object1._numFrames = 7;
+ scene._object1.animate(ANIM_MODE_5, this);
+ break;
+
+ case 3:
+ // Remainder of bouncing square, circle, and triangle coming to rest
+ scene._object1._strip = 2;
+ scene._object1._frame = 1;
+ scene._object1.changeZoom(100);
+ scene._object1.animate(ANIM_MODE_4, 11, 1, this);
+ break;
+
+ case 4:
+ // Fade out background without fading out the shapes
+ GLOBALS._scenePalette.addFader(scene._palette2._palette, 256, 6, this);
+ break;
+
+ case 5:
+ scene._backSurface.fillRect(scene._sceneBounds, 0);
+ scene._gfxManager2.activate();
+ scene._gfxManager2.fillRect(scene._sceneBounds, 0);
+ scene._gfxManager2.deactivate();
+ //word_2B4AA = 3;
+ setDelay(10);
+ break;
+
+ case 6:
+ GLOBALS._scenePalette.loadPalette(12);
+ GLOBALS._scenePalette.refresh();
+ setDelay(1);
+ break;
+
+ case 7:
+ // Animation of shapes expanding upwards to form larger EA logo
+ scene._object1.setVisage("0012.vis");
+ scene._object1._strip = 1;
+ scene._object1._frame = 1;
+ scene._object1.changeZoom(100);
+ scene._object1.setPosition(Common::Point(170, 142));
+ scene._object1._numFrames = 7;
+ scene._object1.animate(ANIM_MODE_5, (const void *)nullptr);
+ ADD_MOVER(scene._object1, 158, 71);
+ break;
+
+ case 8:
+ GLOBALS._scenePalette.addFader(scene._palette3._palette, 256, 40, this);
+ break;
+
+ case 9:
+ // Show 'Electronic Arts' company name
+ scene._object2.postInit(nullptr);
+ scene._object2.setVisage("0014.vis");
+ scene._object2._strip = 1;
+ scene._object2._frame = 1;
+ scene._object2.setPosition(Common::Point(152, 98));
+ scene._object2.changeZoom(100);
+ scene._object2.animate(ANIM_MODE_NONE, (const void *)nullptr);
+ setDelay(120);
+ break;
+
+ case 10:
+ // Remainder of steps is positioning and sizing hand cursorin an arc
+ scene._object3.postInit();
+ scene._object3.setVisage("0018.vis");
+ scene._object3._strip = 1;
+ scene._object3._frame = 1;
+ scene._object3.setPosition(Common::Point(33, 91));
+ scene._object3.changeZoom(100);
+ scene._object3.animate(ANIM_MODE_NONE, (const void *)nullptr);
+ setDelay(5);
+ break;
+
+ case 11:
+ scene._object3._frame = 2;
+ scene._object3.setPosition(Common::Point(44, 124));
+ setDelay(5);
+ break;
+
+ case 12:
+ scene._object3._frame = 3;
+ scene._object3.setPosition(Common::Point(64, 153));
+ setDelay(5);
+ break;
+
+ case 13:
+ scene._object3._frame = 4;
+ scene._object3.setPosition(Common::Point(87, 174));
+ setDelay(5);
+ break;
+
+ case 14:
+ scene._object3._frame = 5;
+ scene._object3.setPosition(Common::Point(114, 191));
+ setDelay(5);
+ break;
+
+ case 15:
+ scene._object3._frame = 6;
+ scene._object3.setPosition(Common::Point(125, 184));
+ setDelay(5);
+ break;
+
+ case 16:
+ scene._object3._frame = 7;
+ scene._object3.setPosition(Common::Point(154, 187));
+ setDelay(5);
+ break;
+
+ case 17:
+ scene._object3._frame = 8;
+ scene._object3.setPosition(Common::Point(181, 182));
+ setDelay(5);
+ break;
+
+ case 18:
+ scene._object3._frame = 9;
+ scene._object3.setPosition(Common::Point(191, 167));
+ setDelay(5);
+ break;
+
+ case 19:
+ scene._object3._frame = 10;
+ scene._object3.setPosition(Common::Point(190, 150));
+ setDelay(5);
+ break;
+
+ case 20:
+ scene._object3._frame = 11;
+ scene._object3.setPosition(Common::Point(182, 139));
+ setDelay(5);
+ break;
+
+ case 21:
+ scene._object3._frame = 11;
+ scene._object3.setPosition(Common::Point(170, 130));
+ setDelay(5);
+ break;
+
+ case 22:
+ scene._object3._frame = 11;
+ scene._object3.setPosition(Common::Point(158, 121));
+ setDelay(8);
+ break;
+
+ case 23:
+ // Show a highlighting of the company name
+ scene._object3.hide();
+ scene._object4.show();
+ scene._object4.setPosition(Common::Point(155, 94));
+ setDelay(8);
+ break;
+
+ case 24:
+ scene._object4._frame = 2;
+ scene._object4.setPosition(Common::Point(155, 94));
+ setDelay(8);
+ break;
+
+ case 25:
+ scene._object2.remove();
+ setDelay(1);
+ break;
+
+ case 26:
+ scene._object4._frame = 3;
+ scene._object4.setPosition(Common::Point(155, 94));
+ setDelay(8);
+ break;
+
+ case 27:
+ scene._object4._frame = 4;
+ scene._object4.setPosition(Common::Point(155, 94));
+ setDelay(8);
+ break;
+ break;
+
+ case 28:
+ scene._object4._frame = 5;
+ scene._object4.setPosition(Common::Point(155, 94));
+ setDelay(8);
+ break;
+ break;
+
+ case 29:
+ scene._object4._frame = 6;
+ scene._object4.setPosition(Common::Point(155, 94));
+ setDelay(8);
+ break;
+ break;
+
+ case 30:
+ scene._object4._frame = 7;
+ scene._object4.setPosition(Common::Point(155, 94));
+ setDelay(8);
+ break;
+ break;
+
+ case 31:
+ scene._object4._frame = 8;
+ scene._object4.setPosition(Common::Point(155, 94));
+ setDelay(8);
+ break;
+
+ case 32:
+ setDelay(180);
+ break;
+
+ default:
+ scene.finish();
+ remove();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void SherlockLogoScene::postInit(SceneObjectList *OwnerList) {
+ loadScene(10);
+ Scene::postInit(OwnerList);
+
+ _palette1.loadPalette(1111);
+ _palette1.loadPalette(10);
+ _palette2.loadPalette(1111);
+ _palette2.loadPalette(1);
+ _palette3.loadPalette(1111);
+ _palette3.loadPalette(14);
+
+ _object4.postInit();
+ _object4.setVisage("0019.vis");
+ _object4._strip = 1;
+ _object4._frame = 1;
+ _object4.setPosition(Common::Point(155, 94));
+ _object4.changeZoom(100);
+ _object4.animate(ANIM_MODE_NONE, (const void *)nullptr);
+ _object4.hide();
+
+ setAction(&_action1);
+}
+
+void SherlockLogoScene::finish() {
+ g_vm->quitGame();
+}
+
+} // End of namespace Sherlock
+
+} // End of namespace TsAGE
diff --git a/engines/tsage/sherlock/sherlock_logo.h b/engines/tsage/sherlock/sherlock_logo.h
new file mode 100644
index 0000000000..95fc0e272f
--- /dev/null
+++ b/engines/tsage/sherlock/sherlock_logo.h
@@ -0,0 +1,78 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef TSAGE_SHERLOCK_LOGO_H
+#define TSAGE_SHERLOCK_LOGO_H
+
+#include "common/scummsys.h"
+#include "tsage/events.h"
+#include "tsage/core.h"
+#include "tsage/scenes.h"
+#include "tsage/globals.h"
+#include "tsage/sound.h"
+
+namespace TsAGE {
+
+namespace Sherlock {
+
+using namespace TsAGE;
+
+class Object : public SceneObject {
+public:
+ void setVisage(const Common::String &name);
+};
+
+class SherlockLogo: public Game {
+public:
+ virtual void start();
+ virtual Scene *createScene(int sceneNumber);
+ virtual void quitGame();
+ virtual void processEvent(Event &event);
+ virtual bool canSaveGameStateCurrently();
+ virtual bool canLoadGameStateCurrently();
+};
+
+class SherlockSceneHandler : public SceneHandler {
+public:
+ virtual void postInit(SceneObjectList *OwnerList);
+};
+
+class SherlockLogoScene: public Scene {
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+public:
+ ScenePalette _palette1, _palette2, _palette3;
+ Object _object1, _object2, _object3, _object4;
+ Action1 _action1;
+ GfxManager _gfxManager2;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ void finish();
+};
+
+} // End of namespace Sherlock
+
+} // End of namespace TsAGE
+
+#endif
diff --git a/engines/tsage/sound.cpp b/engines/tsage/sound.cpp
index b95b614f09..0d3fb55dd3 100644
--- a/engines/tsage/sound.cpp
+++ b/engines/tsage/sound.cpp
@@ -20,9 +20,9 @@
*
*/
+#include "audio/fmopl.h"
#include "audio/decoders/raw.h"
#include "common/config-manager.h"
-#include "audio/decoders/raw.h"
#include "audio/audiostream.h"
#include "tsage/core.h"
#include "tsage/globals.h"
@@ -2743,17 +2743,9 @@ AdlibSoundDriver::AdlibSoundDriver(): SoundDriver() {
_groupData._pData = &adlib_group_data[0];
_mixer = g_vm->_mixer;
- _sampleRate = _mixer->getOutputRate();
_opl = OPL::Config::create();
assert(_opl);
- _opl->init(_sampleRate);
-
- _samplesTillCallback = 0;
- _samplesTillCallbackRemainder = 0;
- _samplesPerCallback = getRate() / CALLBACKS_PER_SECOND;
- _samplesPerCallbackRemainder = getRate() % CALLBACKS_PER_SECOND;
-
- _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
+ _opl->init();
Common::fill(_channelVoiced, _channelVoiced + ADLIB_CHANNEL_COUNT, false);
memset(_channelVolume, 0, ADLIB_CHANNEL_COUNT * sizeof(int));
@@ -2772,11 +2764,12 @@ AdlibSoundDriver::AdlibSoundDriver(): SoundDriver() {
_channelVoiced[i] = false;
_pitchBlend[i] = 0;
}
+
+ _opl->start(new Common::Functor0Mem<void, AdlibSoundDriver>(this, &AdlibSoundDriver::onTimer), CALLBACKS_PER_SECOND);
}
AdlibSoundDriver::~AdlibSoundDriver() {
DEALLOCATE(_patchData);
- _mixer->stopHandle(_soundHandle);
delete _opl;
}
@@ -3019,33 +3012,12 @@ void AdlibSoundDriver::setFrequency(int channel) {
((dataWord >> 8) & 3) | (var2 << 2));
}
-int AdlibSoundDriver::readBuffer(int16 *buffer, const int numSamples) {
+void AdlibSoundDriver::onTimer() {
Common::StackLock slock1(SoundManager::sfManager()._serverDisabledMutex);
Common::StackLock slock2(SoundManager::sfManager()._serverSuspendedMutex);
- int32 samplesLeft = numSamples;
- memset(buffer, 0, sizeof(int16) * numSamples);
- while (samplesLeft) {
- if (!_samplesTillCallback) {
- SoundManager::sfUpdateCallback(NULL);
- flush();
-
- _samplesTillCallback = _samplesPerCallback;
- _samplesTillCallbackRemainder += _samplesPerCallbackRemainder;
- if (_samplesTillCallbackRemainder >= CALLBACKS_PER_SECOND) {
- _samplesTillCallback++;
- _samplesTillCallbackRemainder -= CALLBACKS_PER_SECOND;
- }
- }
-
- int32 render = MIN<int>(samplesLeft, _samplesTillCallback);
- samplesLeft -= render;
- _samplesTillCallback -= render;
-
- _opl->readBuffer(buffer, render);
- buffer += render;
- }
- return numSamples;
+ SoundManager::sfUpdateCallback(NULL);
+ flush();
}
/*--------------------------------------------------------------------------*/
diff --git a/engines/tsage/sound.h b/engines/tsage/sound.h
index 49558b4bca..68755a48c8 100644
--- a/engines/tsage/sound.h
+++ b/engines/tsage/sound.h
@@ -27,12 +27,15 @@
#include "common/mutex.h"
#include "common/queue.h"
#include "audio/audiostream.h"
-#include "audio/fmopl.h"
#include "audio/mixer.h"
#include "common/list.h"
#include "tsage/saveload.h"
#include "tsage/core.h"
+namespace OPL {
+class OPL;
+}
+
namespace TsAGE {
class Sound;
@@ -446,21 +449,15 @@ public:
#define ADLIB_CHANNEL_COUNT 9
-class AdlibSoundDriver: public SoundDriver, Audio::AudioStream {
+class AdlibSoundDriver: public SoundDriver {
private:
GroupData _groupData;
Audio::Mixer *_mixer;
- FM_OPL *_opl;
- Audio::SoundHandle _soundHandle;
- int _sampleRate;
+ OPL::OPL *_opl;
byte _portContents[256];
const byte *_patchData;
int _masterVolume;
Common::Queue<RegisterValue> _queue;
- int _samplesTillCallback;
- int _samplesTillCallbackRemainder;
- int _samplesPerCallback;
- int _samplesPerCallbackRemainder;
bool _channelVoiced[ADLIB_CHANNEL_COUNT];
int _channelVolume[ADLIB_CHANNEL_COUNT];
@@ -495,13 +492,8 @@ public:
virtual void proc38(int channel, int cmd, int value);
virtual void setPitch(int channel, int pitchBlend);
- // AudioStream interface
- virtual int readBuffer(int16 *buffer, const int numSamples);
- virtual bool isStereo() const { return false; }
- virtual bool endOfData() const { return false; }
- virtual int getRate() const { return _sampleRate; }
-
- void update(int16 *buf, int len);
+private:
+ void onTimer();
};
class SoundBlasterDriver: public SoundDriver {
diff --git a/engines/tsage/tsage.cpp b/engines/tsage/tsage.cpp
index 0b882d5cbf..4412d0670f 100644
--- a/engines/tsage/tsage.cpp
+++ b/engines/tsage/tsage.cpp
@@ -44,11 +44,12 @@ TSageEngine::TSageEngine(OSystem *system, const tSageGameDescription *gameDesc)
_debugger = new DemoDebugger();
else
_debugger = new RingworldDebugger();
- }
- else if (g_vm->getGameID() == GType_BlueForce)
+ } else if (g_vm->getGameID() == GType_BlueForce)
_debugger = new BlueForceDebugger();
else if (g_vm->getGameID() == GType_Ringworld2)
_debugger = new Ringworld2Debugger();
+ else if (g_vm->getGameID() == GType_Sherlock1)
+ _debugger = new DemoDebugger();
}
Common::Error TSageEngine::init() {
@@ -110,6 +111,11 @@ void TSageEngine::initialize() {
// Reset all global variables
R2_GLOBALS.reset();
+ } else if (g_vm->getGameID() == GType_Sherlock1) {
+ g_resourceManager->addLib("SF3.RLB");
+ g_globals = new Globals();
+
+ return;
}
g_globals->gfxManager().setDefaults();
diff --git a/engines/tsage/tsage.h b/engines/tsage/tsage.h
index ea4f5da6ea..667a8daa59 100644
--- a/engines/tsage/tsage.h
+++ b/engines/tsage/tsage.h
@@ -42,7 +42,8 @@ namespace TsAGE {
enum {
GType_Ringworld = 0,
GType_BlueForce = 1,
- GType_Ringworld2 = 2
+ GType_Ringworld2 = 2,
+ GType_Sherlock1 = 5
};
enum {
diff --git a/engines/voyeur/events.cpp b/engines/voyeur/events.cpp
index 7ce7351e65..34ef507ad3 100644
--- a/engines/voyeur/events.cpp
+++ b/engines/voyeur/events.cpp
@@ -76,7 +76,7 @@ EventsManager::EventsManager(VoyeurEngine *vm) : _intPtr(_gameData),
_leftClick = _rightClick = false;
_mouseClicked = _newMouseClicked = false;
- _newLeftClick = _newRightClick = false;;
+ _newLeftClick = _newRightClick = false;
_videoDead = 0;
@@ -403,7 +403,7 @@ void EventsManager::vDoCycleInt() {
int palIndex = READ_LE_UINT16(pSrc);
pPal[palIndex * 3] = pSrc[3];
pPal[palIndex * 3 + 1] = pSrc[4];
- pPal[palIndex * 3 + 1] = pSrc[5];
+ pPal[palIndex * 3 + 2] = pSrc[5];
pSrc += 6;
if ((int16)READ_LE_UINT16(pSrc) >= 0) {
diff --git a/engines/voyeur/files_threads.cpp b/engines/voyeur/files_threads.cpp
index 0615c67ba0..53eb5ce3c5 100644
--- a/engines/voyeur/files_threads.cpp
+++ b/engines/voyeur/files_threads.cpp
@@ -1082,6 +1082,7 @@ int ThreadResource::doApt() {
break;
case 2:
_vm->_voy->_aptLoadMode = 142;
+ break;
case 5:
_vm->_voy->_aptLoadMode = 141;
break;
diff --git a/engines/wintermute/base/base_file_manager.cpp b/engines/wintermute/base/base_file_manager.cpp
index 58684b66a0..05830ffcd8 100644
--- a/engines/wintermute/base/base_file_manager.cpp
+++ b/engines/wintermute/base/base_file_manager.cpp
@@ -227,7 +227,7 @@ bool BaseFileManager::registerPackages() {
// Again, make the parent's name all lowercase to avoid any case
// issues.
- Common::String parentName = fileIt->getParent().getName();
+ Common::String parentName = it->getName();
parentName.toLowercase();
// Avoid registering all the language files
diff --git a/engines/wintermute/base/base_keyboard_state.cpp b/engines/wintermute/base/base_keyboard_state.cpp
index 0babc07586..f672c83d39 100644
--- a/engines/wintermute/base/base_keyboard_state.cpp
+++ b/engines/wintermute/base/base_keyboard_state.cpp
@@ -262,41 +262,92 @@ bool BaseKeyboardState::isCurrentPrintable() const {
}
//////////////////////////////////////////////////////////////////////////
+enum VKeyCodes {
+ kVkReturn = 13,
+
+ kVkEscape = 27,
+
+ kVkSpace = 32,
+ kVkEnd = 35,
+ kVkHome = 36,
+ kVkLeft = 37,
+ kVkUp = 38,
+ kVkRight = 39,
+ kVkDown = 40,
+
+ kVkF1 = 112,
+ kVkF2 = 113,
+ kVkF3 = 114,
+ kVkF4 = 115,
+ kVkF5 = 116,
+ kVkF6 = 117,
+ kVkF7 = 118,
+ kVkF8 = 119,
+ kVkF9 = 120,
+ kVkF10 = 121,
+ kVkF11 = 122,
+ kVkF12 = 123
+
+};
+
+//////////////////////////////////////////////////////////////////////////
uint32 BaseKeyboardState::keyCodeToVKey(Common::Event *event) {
+ // todo
if (event->type != Common::EVENT_KEYDOWN) {
return 0;
}
switch (event->kbd.keycode) {
+ case Common::KEYCODE_RETURN:
case Common::KEYCODE_KP_ENTER:
- return Common::KEYCODE_RETURN;
+ return kVkReturn;
+ case Common::KEYCODE_ESCAPE:
+ return kVkEscape;
+ case Common::KEYCODE_SPACE:
+ return kVkSpace;
+ case Common::KEYCODE_END:
+ return kVkEnd;
+ case Common::KEYCODE_HOME:
+ return kVkHome;
+ case Common::KEYCODE_LEFT:
+ return kVkLeft;
+ case Common::KEYCODE_RIGHT:
+ return kVkRight;
+ case Common::KEYCODE_UP:
+ return kVkUp;
+ case Common::KEYCODE_DOWN:
+ return kVkDown;
+ case Common::KEYCODE_F1:
+ return kVkF1;
+ case Common::KEYCODE_F2:
+ return kVkF2;
+ case Common::KEYCODE_F3:
+ return kVkF3;
+ case Common::KEYCODE_F4:
+ return kVkF4;
+ case Common::KEYCODE_F5:
+ return kVkF5;
+ case Common::KEYCODE_F6:
+ return kVkF6;
+ case Common::KEYCODE_F7:
+ return kVkF7;
+ case Common::KEYCODE_F8:
+ return kVkF8;
+ case Common::KEYCODE_F9:
+ return kVkF9;
+ case Common::KEYCODE_F10:
+ return kVkF10;
+ case Common::KEYCODE_F11:
+ return kVkF11;
+ case Common::KEYCODE_F12:
+ return kVkF12;
default:
- return (uint32)event->kbd.ascii;
+ warning("Key not handled: %d '%c'", event->kbd.keycode, event->kbd.keycode);
+ return event->kbd.keycode;
+ break;
}
-}
-enum VKeyCodes {
- kVkEscape = 27,
- kVkSpace = 32,
- kVkHome = 36,
- kVkLeft = 37,
- kVkUp = 38,
- kVkRight = 39,
- kVkDown = 40,
-
- kVkF1 = 112,
- kVkF2 = 113,
- kVkF3 = 114,
- kVkF4 = 115,
- kVkF5 = 116,
- kVkF6 = 117,
- kVkF7 = 118,
- kVkF8 = 119,
- kVkF9 = 120,
- kVkF10 = 121,
- kVkF11 = 122,
- kVkF12 = 123
-};
+}
//////////////////////////////////////////////////////////////////////////
Common::KeyCode BaseKeyboardState::vKeyToKeyCode(uint32 vkey) {
diff --git a/engines/wintermute/base/base_keyboard_state.h b/engines/wintermute/base/base_keyboard_state.h
index c74bd5b0f7..32680b34c1 100644
--- a/engines/wintermute/base/base_keyboard_state.h
+++ b/engines/wintermute/base/base_keyboard_state.h
@@ -67,7 +67,7 @@ private:
bool _currentControl;
uint8 *_keyStates;
- uint32 keyCodeToVKey(Common::Event *event);
+ uint32 keyCodeToVKey(Common::Event *event); //TODO, add more mappings
Common::KeyCode vKeyToKeyCode(uint32 vkey); //TODO, reimplement using ScummVM-backend
};
diff --git a/engines/wintermute/base/base_script_holder.cpp b/engines/wintermute/base/base_script_holder.cpp
index 8383657239..5b1c961479 100644
--- a/engines/wintermute/base/base_script_holder.cpp
+++ b/engines/wintermute/base/base_script_holder.cpp
@@ -302,7 +302,7 @@ bool BaseScriptHolder::addScript(const char *filename) {
for (uint32 i = 0; i < _scripts.size(); i++) {
if (scumm_stricmp(_scripts[i]->_filename, filename) == 0) {
if (_scripts[i]->_state != SCRIPT_FINISHED) {
- BaseEngine::LOG(0, "BaseScriptHolder::AddScript - trying to add script '%s' mutiple times (obj: '%s')", filename, getName());
+ BaseEngine::LOG(0, "BaseScriptHolder::AddScript - trying to add script '%s' multiple times (obj: '%s')", filename, getName());
return STATUS_OK;
}
}
diff --git a/engines/wintermute/debugger.cpp b/engines/wintermute/debugger.cpp
index a313314a8b..5b617d9db9 100644
--- a/engines/wintermute/debugger.cpp
+++ b/engines/wintermute/debugger.cpp
@@ -42,7 +42,7 @@ bool Console::Cmd_ShowFps(int argc, const char **argv) {
if (Common::String(argv[1]) == "true") {
_engineRef->_game->setShowFPS(true);
} else if (Common::String(argv[1]) == "false") {
- _engineRef->_game->setShowFPS(false);;
+ _engineRef->_game->setShowFPS(false);
}
}
return true;
diff --git a/engines/zvision/configure.engine b/engines/zvision/configure.engine
index 02e31943af..226870c3fd 100644
--- a/engines/zvision/configure.engine
+++ b/engines/zvision/configure.engine
@@ -1,3 +1,3 @@
# This file is included from the main "configure" script
# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
-add_engine zvision "ZVision" no "" "" "freetype2 16bit"
+add_engine zvision "Z-Vision" yes "" "" "freetype2 16bit"
diff --git a/engines/zvision/core/clock.h b/engines/zvision/core/clock.h
index cbf52be560..ae8c968111 100644
--- a/engines/zvision/core/clock.h
+++ b/engines/zvision/core/clock.h
@@ -67,14 +67,14 @@ public:
}
/**
- * Pause the clock. Any future delta times will take this pause into account.
- * Has no effect if the clock is already paused.
- */
+ * Un-pause the clock.
+ * Has no effect if the clock is already un-paused.
+ */
void start();
/**
- * Un-pause the clock.
- * Has no effect if the clock is already un-paused.
+ * Pause the clock. Any future delta times will take this pause into account.
+ * Has no effect if the clock is already paused.
*/
void stop();
};
diff --git a/engines/zvision/core/console.cpp b/engines/zvision/core/console.cpp
index 4dd10d6f40..336541d82a 100644
--- a/engines/zvision/core/console.cpp
+++ b/engines/zvision/core/console.cpp
@@ -52,6 +52,10 @@ Console::Console(ZVision *engine) : GUI::Debugger(), _engine(engine) {
registerCmd("setpanoramascale", WRAP_METHOD(Console, cmdSetPanoramaScale));
registerCmd("location", WRAP_METHOD(Console, cmdLocation));
registerCmd("dumpfile", WRAP_METHOD(Console, cmdDumpFile));
+ registerCmd("dumpfiles", WRAP_METHOD(Console, cmdDumpFiles));
+ registerCmd("dumpimage", WRAP_METHOD(Console, cmdDumpImage));
+ registerCmd("statevalue", WRAP_METHOD(Console, cmdStateValue));
+ registerCmd("stateflag", WRAP_METHOD(Console, cmdStateFlag));
}
bool Console::cmdLoadVideo(int argc, const char **argv) {
@@ -78,12 +82,14 @@ bool Console::cmdLoadSound(int argc, const char **argv) {
Audio::AudioStream *soundStream = makeRawZorkStream(argv[1], _engine);
Audio::SoundHandle handle;
_engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &handle, soundStream, -1, 100, 0, DisposeAfterUse::YES, false, false);
-
} else if (argc == 4) {
int isStereo = atoi(argv[3]);
Common::File *file = new Common::File();
- file->open(argv[1]);
+ if (!_engine->getSearchManager()->openFile(*file, argv[1])) {
+ warning("File not found: %s", argv[1]);
+ return true;
+ }
Audio::AudioStream *soundStream = makeRawZorkStream(file, atoi(argv[2]), isStereo == 0 ? false : true);
Audio::SoundHandle handle;
@@ -103,8 +109,10 @@ bool Console::cmdRawToWav(int argc, const char **argv) {
}
Common::File file;
- if (!file.open(argv[1]))
+ if (!_engine->getSearchManager()->openFile(file, argv[1])) {
+ warning("File not found: %s", argv[1]);
return true;
+ }
Audio::AudioStream *audioStream = makeRawZorkStream(argv[1], _engine);
@@ -133,6 +141,10 @@ bool Console::cmdRawToWav(int argc, const char **argv) {
output.writeUint32LE(file.size() * 2);
int16 *buffer = new int16[file.size()];
audioStream->readBuffer(buffer, file.size());
+#ifndef SCUMM_LITTLE_ENDIAN
+ for (int i = 0; i < file.size(); ++i)
+ buffer[i] = TO_LE_16(buffer[i]);
+#endif
output.write(buffer, file.size() * 2);
delete[] buffer;
@@ -194,7 +206,7 @@ bool Console::cmdLocation(int argc, const char **argv) {
Common::String scrFile = Common::String::format("%c%c%c%c.scr", curLocation.world, curLocation.room, curLocation.node, curLocation.view);
debugPrintf("Current location: world '%c', room '%c', node '%c', view '%c', offset %d, script %s\n",
curLocation.world, curLocation.room, curLocation.node, curLocation.view, curLocation.offset, scrFile.c_str());
-
+
if (argc != 6) {
debugPrintf("Use %s <char: world> <char: room> <char:node> <char:view> <int: x offset> to change your location\n", argv[0]);
return true;
@@ -205,6 +217,20 @@ bool Console::cmdLocation(int argc, const char **argv) {
return true;
}
+void dumpFile(Common::SeekableReadStream *s, const char *outName) {
+ byte *buffer = new byte[s->size()];
+ s->read(buffer, s->size());
+
+ Common::DumpFile dumpFile;
+ dumpFile.open(outName);
+
+ dumpFile.write(buffer, s->size());
+ dumpFile.flush();
+ dumpFile.close();
+
+ delete[] buffer;
+}
+
bool Console::cmdDumpFile(int argc, const char **argv) {
if (argc != 2) {
debugPrintf("Use %s <fileName> to dump a file\n", argv[0]);
@@ -217,17 +243,126 @@ bool Console::cmdDumpFile(int argc, const char **argv) {
return true;
}
- byte *buffer = new byte[f.size()];
- f.read(buffer, f.size());
+ dumpFile(&f, argv[1]);
- Common::DumpFile dumpFile;
- dumpFile.open(argv[1]);
+ return true;
+}
- dumpFile.write(buffer, f.size());
- dumpFile.flush();
- dumpFile.close();
+bool Console::cmdDumpFiles(int argc, const char **argv) {
+ Common::String fileName;
+ Common::SeekableReadStream *in;
- delete[] buffer;
+ if (argc != 2) {
+ debugPrintf("Use %s <file extension> to dump all files with a specific extension\n", argv[0]);
+ return true;
+ }
+
+ SearchManager::MatchList fileList;
+ _engine->getSearchManager()->listMembersWithExtension(fileList, argv[1]);
+
+ for (SearchManager::MatchList::iterator iter = fileList.begin(); iter != fileList.end(); ++iter) {
+ fileName = iter->_value.name;
+ debugPrintf("Dumping %s\n", fileName.c_str());
+
+ in = iter->_value.arch->createReadStreamForMember(iter->_value.name);
+ if (in)
+ dumpFile(in, fileName.c_str());
+ delete in;
+ }
+
+ return true;
+}
+
+bool Console::cmdDumpImage(int argc, const char **argv) {
+ if (argc != 2) {
+ debugPrintf("Use %s <TGA/TGZ name> to dump a Z-Vision TGA/TGZ image into a regular BMP image\n", argv[0]);
+ return true;
+ }
+
+ Common::String fileName = argv[1];
+ if (!fileName.hasSuffix(".tga")) {
+ debugPrintf("%s is not an image file", argv[1]);
+ }
+
+ Common::File f;
+ if (!_engine->getSearchManager()->openFile(f, argv[1])) {
+ warning("File not found: %s", argv[1]);
+ return true;
+ }
+
+ Graphics::Surface surface;
+ _engine->getRenderManager()->readImageToSurface(argv[1], surface, false);
+
+ // Open file
+ Common::DumpFile out;
+
+ fileName.setChar('b', fileName.size() - 3);
+ fileName.setChar('m', fileName.size() - 2);
+ fileName.setChar('p', fileName.size() - 1);
+
+ out.open(fileName);
+
+ // Write BMP header
+ out.writeByte('B');
+ out.writeByte('M');
+ out.writeUint32LE(surface.h * surface.pitch + 54);
+ out.writeUint32LE(0);
+ out.writeUint32LE(54);
+ out.writeUint32LE(40);
+ out.writeUint32LE(surface.w);
+ out.writeUint32LE(surface.h);
+ out.writeUint16LE(1);
+ out.writeUint16LE(16);
+ out.writeUint32LE(0);
+ out.writeUint32LE(0);
+ out.writeUint32LE(0);
+ out.writeUint32LE(0);
+ out.writeUint32LE(0);
+ out.writeUint32LE(0);
+
+ // Write pixel data to BMP
+ out.write(surface.getPixels(), surface.pitch * surface.h);
+
+ out.flush();
+ out.close();
+
+ surface.free();
+
+ return true;
+}
+
+bool Console::cmdStateValue(int argc, const char **argv) {
+ if (argc < 2) {
+ debugPrintf("Use %s <valuenum> to show the value of a state variable\n", argv[0]);
+ debugPrintf("Use %s <valuenum> <newvalue> to set the value of a state variable\n", argv[0]);
+ return true;
+ }
+
+ int valueNum = atoi(argv[1]);
+ int newValue = (argc > 2) ? atoi(argv[2]) : -1;
+
+ if (argc == 2)
+ debugPrintf("[%d] = %d\n", valueNum, _engine->getScriptManager()->getStateValue(valueNum));
+ else if (argc == 3)
+ _engine->getScriptManager()->setStateValue(valueNum, newValue);
+
+ return true;
+}
+
+bool Console::cmdStateFlag(int argc, const char **argv) {
+ if (argc < 2) {
+ debugPrintf("Use %s <flagnum> to show the value of a state flag\n", argv[0]);
+ debugPrintf("Use %s <flagnum> <newvalue> to set the value of a state flag\n", argv[0]);
+ return true;
+ }
+
+ int valueNum = atoi(argv[1]);
+ int newValue = (argc > 2) ? atoi(argv[2]) : -1;
+
+ if (argc == 2)
+ debugPrintf("[%d] = %d\n", valueNum, _engine->getScriptManager()->getStateFlag(valueNum));
+ else if (argc == 3)
+ _engine->getScriptManager()->setStateFlag(valueNum, newValue);
return true;
}
diff --git a/engines/zvision/core/console.h b/engines/zvision/core/console.h
index 299bd6127f..ac834185a0 100644
--- a/engines/zvision/core/console.h
+++ b/engines/zvision/core/console.h
@@ -46,6 +46,10 @@ private:
bool cmdSetPanoramaScale(int argc, const char **argv);
bool cmdLocation(int argc, const char **argv);
bool cmdDumpFile(int argc, const char **argv);
+ bool cmdDumpFiles(int argc, const char **argv);
+ bool cmdDumpImage(int argc, const char **argv);
+ bool cmdStateValue(int argc, const char **argv);
+ bool cmdStateFlag(int argc, const char **argv);
};
} // End of namespace ZVision
diff --git a/engines/zvision/core/events.cpp b/engines/zvision/core/events.cpp
index c66e61a61a..cc1c00b6d0 100644
--- a/engines/zvision/core/events.cpp
+++ b/engines/zvision/core/events.cpp
@@ -28,8 +28,9 @@
#include "zvision/graphics/cursors/cursor_manager.h"
#include "zvision/graphics/render_manager.h"
#include "zvision/scripting/script_manager.h"
-#include "zvision/core/menu.h"
+#include "zvision/scripting/menu.h"
#include "zvision/sound/zork_raw.h"
+#include "zvision/text/string_manager.h"
#include "common/events.h"
#include "common/system.h"
@@ -39,23 +40,50 @@
namespace ZVision {
+void ZVision::pushKeyToCheatBuf(uint8 key) {
+ for (int i = 0; i < KEYBUF_SIZE - 1; i++)
+ _cheatBuffer[i] = _cheatBuffer[i + 1];
+
+ _cheatBuffer[KEYBUF_SIZE - 1] = key;
+}
+
+bool ZVision::checkCode(const char *code) {
+ int codeLen = strlen(code);
+
+ if (codeLen > KEYBUF_SIZE)
+ return false;
+
+ for (int i = 0; i < codeLen; i++)
+ if (code[i] != _cheatBuffer[KEYBUF_SIZE - codeLen + i] && code[i] != '?')
+ return false;
+
+ return true;
+}
+
+uint8 ZVision::getBufferedKey(uint8 pos) {
+ if (pos >= KEYBUF_SIZE)
+ return 0;
+ else
+ return _cheatBuffer[KEYBUF_SIZE - pos - 1];
+}
+
void ZVision::shortKeys(Common::Event event) {
if (event.kbd.hasFlags(Common::KBD_CTRL)) {
switch (event.kbd.keycode) {
case Common::KEYCODE_s:
- if (getMenuBarEnable() & menuBar_Save)
+ if (_menu->getEnable() & kMenubarSave)
_scriptManager->changeLocation('g', 'j', 's', 'e', 0);
break;
case Common::KEYCODE_r:
- if (getMenuBarEnable() & menuBar_Restore)
+ if (_menu->getEnable() & kMenubarRestore)
_scriptManager->changeLocation('g', 'j', 'r', 'e', 0);
break;
case Common::KEYCODE_p:
- if (getMenuBarEnable() & menuBar_Settings)
+ if (_menu->getEnable() & kMenubarSettings)
_scriptManager->changeLocation('g', 'j', 'p', 'e', 0);
break;
case Common::KEYCODE_q:
- if (getMenuBarEnable() & menuBar_Exit)
+ if (_menu->getEnable() & kMenubarExit)
ifQuit();
break;
default:
@@ -65,16 +93,21 @@ void ZVision::shortKeys(Common::Event event) {
}
void ZVision::cheatCodes(uint8 key) {
+ Location loc = _scriptManager->getCurrentLocation();
+ // Do not process cheat codes while in the game menus
+ if (loc.world == 'g' && loc.room == 'j')
+ return;
+
pushKeyToCheatBuf(key);
if (getGameId() == GID_GRANDINQUISITOR) {
if (checkCode("IMNOTDEAF")) {
// Unknown cheat
- showDebugMsg(Common::String::format("IMNOTDEAF cheat or debug, not implemented"));
+ _renderManager->showDebugMsg(Common::String::format("IMNOTDEAF cheat or debug, not implemented"));
}
if (checkCode("3100OPB")) {
- showDebugMsg(Common::String::format("Current location: %c%c%c%c",
+ _renderManager->showDebugMsg(Common::String::format("Current location: %c%c%c%c",
_scriptManager->getStateValue(StateKey_World),
_scriptManager->getStateValue(StateKey_Room),
_scriptManager->getStateValue(StateKey_Node),
@@ -91,9 +124,9 @@ void ZVision::cheatCodes(uint8 key) {
}
// There are 3 more cheats in script files:
- // - "EAT ME": gjcr.scr
- // - "WHOAMI": hp1e.scr
- // - "HUISOK": uh1f.scr
+ // - "WHOAMI": gjcr.scr
+ // - "HUISOK": hp1e.scr
+ // - "EAT ME": uh1f.scr
} else if (getGameId() == GID_NEMESIS) {
if (checkCode("CHLOE")) {
_scriptManager->changeLocation('t', 'm', '2', 'g', 0);
@@ -101,7 +134,7 @@ void ZVision::cheatCodes(uint8 key) {
}
if (checkCode("77MASSAVE")) {
- showDebugMsg(Common::String::format("Current location: %c%c%c%c",
+ _renderManager->showDebugMsg(Common::String::format("Current location: %c%c%c%c",
_scriptManager->getStateValue(StateKey_World),
_scriptManager->getStateValue(StateKey_Room),
_scriptManager->getStateValue(StateKey_Node),
@@ -118,9 +151,8 @@ void ZVision::cheatCodes(uint8 key) {
}
if (checkCode("HELLOSAILOR")) {
- Location loc = _scriptManager->getCurrentLocation();
Audio::AudioStream *soundStream;
- if (loc.world == 'v' && loc.room == 'b' && loc.node == '1' && loc.view == '0') {
+ if (loc == "vb10") {
soundStream = makeRawZorkStream("v000hpta.raw", this);
} else {
soundStream = makeRawZorkStream("v000hnta.raw", this);
@@ -130,21 +162,29 @@ void ZVision::cheatCodes(uint8 key) {
}
}
- if (checkCode("FRAME"))
- showDebugMsg(Common::String::format("FPS: ???, not implemented"));
+ if (checkCode("FRAME")) {
+ Common::String fpsStr = Common::String::format("FPS: %d", getFPS());
+ _renderManager->showDebugMsg(fpsStr);
+ }
+
+ if (checkCode("COMPUTERARCH"))
+ _renderManager->showDebugMsg("COMPUTERARCH: var-viewer not implemented");
+ // This cheat essentially toggles the GOxxxx cheat below
if (checkCode("XYZZY"))
_scriptManager->setStateValue(StateKey_DebugCheats, 1 - _scriptManager->getStateValue(StateKey_DebugCheats));
- if (checkCode("COMPUTERARCH"))
- showDebugMsg(Common::String::format("COMPUTERARCH: var-viewer not implemented"));
-
if (_scriptManager->getStateValue(StateKey_DebugCheats) == 1)
if (checkCode("GO????"))
_scriptManager->changeLocation(getBufferedKey(3),
getBufferedKey(2),
getBufferedKey(1),
getBufferedKey(0), 0);
+
+ // Show the Venus screen when "?" or "/" is pressed while inside the temple world
+ if (_scriptManager->getStateValue(StateKey_VenusEnable) == 1)
+ if (getBufferedKey(0) == 0xBF && _scriptManager->getStateValue(StateKey_World) == 't')
+ _scriptManager->changeLocation('g', 'j', 'h', 'e', 0);
}
void ZVision::processEvents() {
@@ -194,19 +234,24 @@ void ZVision::processEvents() {
case Common::KEYCODE_LEFT:
case Common::KEYCODE_RIGHT:
if (_renderManager->getRenderTable()->getRenderState() == RenderTable::PANORAMA)
- _kbdVelocity = (_event.kbd.keycode == Common::KEYCODE_LEFT ?
- -_scriptManager->getStateValue(StateKey_KbdRotateSpeed) :
- _scriptManager->getStateValue(StateKey_KbdRotateSpeed)) * 2;
+ _keyboardVelocity = (_event.kbd.keycode == Common::KEYCODE_LEFT ?
+ -_scriptManager->getStateValue(StateKey_KbdRotateSpeed) :
+ _scriptManager->getStateValue(StateKey_KbdRotateSpeed)) * 2;
break;
case Common::KEYCODE_UP:
case Common::KEYCODE_DOWN:
if (_renderManager->getRenderTable()->getRenderState() == RenderTable::TILT)
- _kbdVelocity = (_event.kbd.keycode == Common::KEYCODE_UP ?
- -_scriptManager->getStateValue(StateKey_KbdRotateSpeed) :
- _scriptManager->getStateValue(StateKey_KbdRotateSpeed)) * 2;
+ _keyboardVelocity = (_event.kbd.keycode == Common::KEYCODE_UP ?
+ -_scriptManager->getStateValue(StateKey_KbdRotateSpeed) :
+ _scriptManager->getStateValue(StateKey_KbdRotateSpeed)) * 2;
break;
+ case Common::KEYCODE_F10: {
+ Common::String fpsStr = Common::String::format("FPS: %d", getFPS());
+ _renderManager->showDebugMsg(fpsStr);
+ }
+ break;
default:
break;
}
@@ -226,12 +271,12 @@ void ZVision::processEvents() {
case Common::KEYCODE_LEFT:
case Common::KEYCODE_RIGHT:
if (_renderManager->getRenderTable()->getRenderState() == RenderTable::PANORAMA)
- _kbdVelocity = 0;
+ _keyboardVelocity = 0;
break;
case Common::KEYCODE_UP:
case Common::KEYCODE_DOWN:
if (_renderManager->getRenderTable()->getRenderState() == RenderTable::TILT)
- _kbdVelocity = 0;
+ _keyboardVelocity = 0;
break;
default:
break;
@@ -279,26 +324,33 @@ void ZVision::onMouseMove(const Common::Point &pos) {
// |
// ^
- if (_workingWindow.contains(pos)) {
- cursorWasChanged = _scriptManager->onMouseMove(pos, imageCoord);
+ // Clip the horizontal mouse position to the working window
+ Common::Point clippedPos = pos;
+ clippedPos.x = CLIP<int16>(pos.x, _workingWindow.left + 1, _workingWindow.right - 1);
+
+ if (_workingWindow.contains(clippedPos)) {
+ cursorWasChanged = _scriptManager->onMouseMove(clippedPos, imageCoord);
RenderTable::RenderState renderState = _renderManager->getRenderTable()->getRenderState();
if (renderState == RenderTable::PANORAMA) {
- if (pos.x >= _workingWindow.left && pos.x < _workingWindow.left + ROTATION_SCREEN_EDGE_OFFSET) {
+ if (clippedPos.x >= _workingWindow.left && clippedPos.x < _workingWindow.left + ROTATION_SCREEN_EDGE_OFFSET) {
int16 mspeed = _scriptManager->getStateValue(StateKey_RotateSpeed) >> 4;
- if (mspeed <= 0)
- mspeed = 400 >> 4;
- _mouseVelocity = (((pos.x - (ROTATION_SCREEN_EDGE_OFFSET + _workingWindow.left)) << 7) / ROTATION_SCREEN_EDGE_OFFSET * mspeed) >> 7;
+ if (mspeed <= 0) {
+ mspeed = 25;
+ }
+ _mouseVelocity = MIN(((Common::Rational(mspeed, ROTATION_SCREEN_EDGE_OFFSET) * (clippedPos.x - _workingWindow.left)) - mspeed).toInt(), -1);
+
_cursorManager->changeCursor(CursorIndex_Left);
cursorWasChanged = true;
- } else if (pos.x <= _workingWindow.right && pos.x > _workingWindow.right - ROTATION_SCREEN_EDGE_OFFSET) {
+ } else if (clippedPos.x <= _workingWindow.right && clippedPos.x > _workingWindow.right - ROTATION_SCREEN_EDGE_OFFSET) {
int16 mspeed = _scriptManager->getStateValue(StateKey_RotateSpeed) >> 4;
- if (mspeed <= 0)
- mspeed = 400 >> 4;
- _mouseVelocity = (((pos.x - (_workingWindow.right - ROTATION_SCREEN_EDGE_OFFSET)) << 7) / ROTATION_SCREEN_EDGE_OFFSET * mspeed) >> 7;
+ if (mspeed <= 0) {
+ mspeed = 25;
+ }
+ _mouseVelocity = MAX((Common::Rational(mspeed, ROTATION_SCREEN_EDGE_OFFSET) * (clippedPos.x - _workingWindow.right + ROTATION_SCREEN_EDGE_OFFSET)).toInt(), 1);
_cursorManager->changeCursor(CursorIndex_Right);
cursorWasChanged = true;
@@ -306,21 +358,23 @@ void ZVision::onMouseMove(const Common::Point &pos) {
_mouseVelocity = 0;
}
} else if (renderState == RenderTable::TILT) {
- if (pos.y >= _workingWindow.top && pos.y < _workingWindow.top + ROTATION_SCREEN_EDGE_OFFSET) {
+ if (clippedPos.y >= _workingWindow.top && clippedPos.y < _workingWindow.top + ROTATION_SCREEN_EDGE_OFFSET) {
int16 mspeed = _scriptManager->getStateValue(StateKey_RotateSpeed) >> 4;
- if (mspeed <= 0)
- mspeed = 400 >> 4;
- _mouseVelocity = (((pos.y - (_workingWindow.top + ROTATION_SCREEN_EDGE_OFFSET)) << 7) / ROTATION_SCREEN_EDGE_OFFSET * mspeed) >> 7;
+ if (mspeed <= 0) {
+ mspeed = 25;
+ }
+ _mouseVelocity = MIN(((Common::Rational(mspeed, ROTATION_SCREEN_EDGE_OFFSET) * (pos.y - _workingWindow.top)) - mspeed).toInt(), -1);
_cursorManager->changeCursor(CursorIndex_UpArr);
cursorWasChanged = true;
- } else if (pos.y <= _workingWindow.bottom && pos.y > _workingWindow.bottom - ROTATION_SCREEN_EDGE_OFFSET) {
+ } else if (clippedPos.y <= _workingWindow.bottom && clippedPos.y > _workingWindow.bottom - ROTATION_SCREEN_EDGE_OFFSET) {
int16 mspeed = _scriptManager->getStateValue(StateKey_RotateSpeed) >> 4;
- if (mspeed <= 0)
- mspeed = 400 >> 4;
- _mouseVelocity = (((pos.y - (_workingWindow.bottom - ROTATION_SCREEN_EDGE_OFFSET)) << 7) / ROTATION_SCREEN_EDGE_OFFSET * mspeed) >> 7;
+ if (mspeed <= 0) {
+ mspeed = 25;
+ }
+ _mouseVelocity = MAX((Common::Rational(MAX_ROTATION_SPEED, ROTATION_SCREEN_EDGE_OFFSET) * (pos.y - _workingWindow.bottom + ROTATION_SCREEN_EDGE_OFFSET)).toInt(), 1);
_cursorManager->changeCursor(CursorIndex_DownArr);
cursorWasChanged = true;
@@ -441,4 +495,12 @@ uint8 ZVision::getZvisionKey(Common::KeyCode scummKeyCode) {
return 0;
}
+bool ZVision::ifQuit() {
+ if (_renderManager->askQuestion(_stringManager->getTextLine(StringManager::ZVISION_STR_EXITPROMT))) {
+ quitGame();
+ return true;
+ }
+ return false;
+}
+
} // End of namespace ZVision
diff --git a/engines/zvision/detection.cpp b/engines/zvision/detection.cpp
index ebf5bdcfdd..f44e653c2a 100644
--- a/engines/zvision/detection.cpp
+++ b/engines/zvision/detection.cpp
@@ -24,9 +24,10 @@
#include "base/plugins.h"
+#include "engines/advancedDetector.h"
+
#include "zvision/zvision.h"
-#include "zvision/detection.h"
-#include "zvision/core/save_manager.h"
+#include "zvision/file/save_manager.h"
#include "zvision/scripting/script_manager.h"
#include "common/translation.h"
@@ -36,143 +37,43 @@
namespace ZVision {
-uint32 ZVision::getFeatures() const {
- return _gameDescription->desc.flags;
-}
+struct ZVisionGameDescription {
+ ADGameDescription desc;
+ ZVisionGameId gameId;
+};
+ZVisionGameId ZVision::getGameId() const {
+ return _gameDescription->gameId;
+}
Common::Language ZVision::getLanguage() const {
return _gameDescription->desc.language;
}
+uint32 ZVision::getFeatures() const {
+ return _gameDescription->desc.flags;
+}
} // End of namespace ZVision
-static const PlainGameDescriptor zVisionGames[] = {
- {"zvision", "ZVision Game"},
- {"znemesis", "Zork Nemesis: The Forbidden Lands"},
- {"zgi", "Zork: Grand Inquisitor"},
- {0, 0}
-};
-
-namespace ZVision {
-
-static const ZVisionGameDescription gameDescriptions[] = {
-
- {
- // Zork Nemesis English version
- {
- "znemesis",
- 0,
- AD_ENTRY1s("CSCR.ZFS", "88226e51a205d2e50c67a5237f3bd5f2", 2397741),
- Common::EN_ANY,
- Common::kPlatformDOS,
- ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
- },
- GID_NEMESIS
- },
-
- {
- // Zork Nemesis English demo version
- {
- "znemesis",
- "Demo",
- AD_ENTRY1s("SCRIPTS.ZFS", "64f1e881394e9462305104f99513c833", 380539),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_DEMO,
- GUIO1(GUIO_NONE)
- },
- GID_NEMESIS
- },
-
- {
- // Zork Grand Inquisitor English CD version
- {
- "zgi",
- "CD",
- AD_ENTRY1s("SCRIPTS.ZFS", "81efd40ecc3d22531e211368b779f17f", 8336944),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
- },
- GID_GRANDINQUISITOR
- },
-
- {
- // Zork Grand Inquisitor English demo version
- {
- "zgi",
- "Demo",
- AD_ENTRY1s("SCRIPTS.ZFS", "71a2494fd2fb999347deb13401e9b998", 304239),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_DEMO,
- GUIO1(GUIO_NONE)
- },
- GID_GRANDINQUISITOR
- },
-
- {
- // Zork Grand Inquisitor English DVD version
- {
- "zgi",
- "DVD",
- AD_ENTRY1s("SCRIPTS.ZFS", "03157a3399513bfaaf8dc6d5ab798b36", 8433326),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
- },
- GID_GRANDINQUISITOR
- },
-
- {
- AD_TABLE_END_MARKER,
- GID_NONE
- }
-};
-
-} // End of namespace ZVision
-
-static const char *directoryGlobs[] = {
- "znemscr",
- 0
-};
-
-static const ExtraGuiOption ZVisionExtraGuiOption = {
- _s("Use original save/load screens"),
- _s("Use the original save/load screens, instead of the ScummVM ones"),
- "originalsaveload",
- false
-};
-
-static const ExtraGuiOption ZVisionExtraGuiOption2 = {
- _s("Double FPS"),
- _s("Halve the update delay"),
- "doublefps",
- false
-};
+#include "zvision/detection_tables.h"
class ZVisionMetaEngine : public AdvancedMetaEngine {
public:
- ZVisionMetaEngine() : AdvancedMetaEngine(ZVision::gameDescriptions, sizeof(ZVision::ZVisionGameDescription), zVisionGames) {
+ ZVisionMetaEngine() : AdvancedMetaEngine(ZVision::gameDescriptions, sizeof(ZVision::ZVisionGameDescription), ZVision::zVisionGames, ZVision::optionsList) {
_maxScanDepth = 2;
- _directoryGlobs = directoryGlobs;
+ _directoryGlobs = ZVision::directoryGlobs;
_singleid = "zvision";
}
virtual const char *getName() const {
- return "ZVision";
+ return "Z-Vision";
}
virtual const char *getOriginalCopyright() const {
- return "ZVision Activision (C) 1996";
+ return "Z-Vision (C) 1996 Activision";
}
virtual bool hasFeature(MetaEngineFeature f) const;
virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
- virtual const ExtraGuiOptions getExtraGuiOptions(const Common::String &target) const;
SaveStateList listSaves(const char *target) const;
virtual int getMaximumSaveSlot() const;
void removeSaveState(const char *target, int slot) const;
@@ -202,7 +103,7 @@ Common::Error ZVision::ZVision::loadGameState(int slot) {
}
Common::Error ZVision::ZVision::saveGameState(int slot, const Common::String &desc) {
- _saveManager->saveGame(slot, desc);
+ _saveManager->saveGame(slot, desc, false);
return Common::kNoError;
}
@@ -223,13 +124,6 @@ bool ZVisionMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADG
return gd != 0;
}
-const ExtraGuiOptions ZVisionMetaEngine::getExtraGuiOptions(const Common::String &target) const {
- ExtraGuiOptions options;
- options.push_back(ZVisionExtraGuiOption);
- options.push_back(ZVisionExtraGuiOption2);
- return options;
-}
-
SaveStateList ZVisionMetaEngine::listSaves(const char *target) const {
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
ZVision::SaveGameHeader header;
@@ -308,6 +202,11 @@ SaveStateDescriptor ZVisionMetaEngine::querySaveMetaInfos(const char *target, in
if (successfulRead) {
SaveStateDescriptor desc(slot, header.saveName);
+ // Do not allow save slot 0 (used for auto-saving) to be deleted or
+ // overwritten.
+ desc.setDeletableFlag(slot != 0);
+ desc.setWriteProtectedFlag(slot == 0);
+
desc.setThumbnail(header.thumbnail);
if (header.version > 0) {
diff --git a/engines/zvision/detection_tables.h b/engines/zvision/detection_tables.h
new file mode 100644
index 0000000000..06bc58ee7f
--- /dev/null
+++ b/engines/zvision/detection_tables.h
@@ -0,0 +1,277 @@
+/* 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 ZVISION_DETECTION_TABLES_H
+#define ZVISION_DETECTION_TABLES_H
+
+namespace ZVision {
+
+static const PlainGameDescriptor zVisionGames[] = {
+ { "zvision", "Z-Vision Game" },
+ { "znemesis", "Zork Nemesis: The Forbidden Lands" },
+ { "zgi", "Zork: Grand Inquisitor" },
+ { 0, 0 }
+};
+
+static const char *directoryGlobs[] = {
+ "znemscr",
+ 0
+};
+
+#define GAMEOPTION_ORIGINAL_SAVELOAD GUIO_GAMEOPTIONS1
+#define GAMEOPTION_DOUBLE_FPS GUIO_GAMEOPTIONS2
+#define GAMEOPTION_ENABLE_VENUS GUIO_GAMEOPTIONS3
+#define GAMEOPTION_DISABLE_ANIM_WHILE_TURNING GUIO_GAMEOPTIONS4
+#define GAMEOPTION_USE_HIRES_MPEG_MOVIES GUIO_GAMEOPTIONS5
+
+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"),
+ "originalsaveload",
+ false
+ }
+ },
+
+ {
+ GAMEOPTION_DOUBLE_FPS,
+ {
+ _s("Double FPS"),
+ _s("Increase framerate from 30 to 60 FPS"),
+ "doublefps",
+ false
+ }
+ },
+
+ {
+ GAMEOPTION_ENABLE_VENUS,
+ {
+ _s("Enable Venus"),
+ _s("Enable the Venus help system"),
+ "venusenabled",
+ true
+ }
+ },
+
+ {
+ GAMEOPTION_DISABLE_ANIM_WHILE_TURNING,
+ {
+ _s("Disable animation while turning"),
+ _s("Disable animation while turning in panorama mode"),
+ "noanimwhileturning",
+ false
+ }
+ },
+
+ {
+ GAMEOPTION_USE_HIRES_MPEG_MOVIES,
+ {
+ _s("Use high resolution MPEG video"),
+ _s("Use MPEG video from the DVD version, instead of lower resolution AVI"),
+ "mpegmovies",
+ true
+ }
+ },
+
+ AD_EXTRA_GUI_OPTIONS_TERMINATOR
+};
+
+static const ZVisionGameDescription gameDescriptions[] = {
+
+ {
+ // Zork Nemesis English version
+ {
+ "znemesis",
+ 0,
+ AD_ENTRY1s("CSCR.ZFS", "88226e51a205d2e50c67a5237f3bd5f2", 2397741),
+ Common::EN_ANY,
+ Common::kPlatformDOS,
+ ADGF_NO_FLAGS,
+ GUIO4(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_DOUBLE_FPS, GAMEOPTION_ENABLE_VENUS, GAMEOPTION_DISABLE_ANIM_WHILE_TURNING)
+ },
+ GID_NEMESIS
+ },
+
+ {
+ // Zork Nemesis French version
+ {
+ "znemesis",
+ 0,
+ {
+ { "CSCR.ZFS", 0, "f04113357b4748c13efcb58b4629887c", 2577873 },
+ { "NEMESIS.STR", 0, "333bcb17bbb7f57cae742fbbe44f56f3", 9219 },
+ AD_LISTEND
+ },
+ Common::FR_FRA,
+ Common::kPlatformDOS,
+ ADGF_NO_FLAGS,
+ GUIO4(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_DOUBLE_FPS, GAMEOPTION_ENABLE_VENUS, GAMEOPTION_DISABLE_ANIM_WHILE_TURNING)
+ },
+ GID_NEMESIS
+ },
+
+ {
+ // Zork Nemesis German version
+ {
+ "znemesis",
+ 0,
+ {
+ { "CSCR.ZFS", 0, "f04113357b4748c13efcb58b4629887c", 2577873 },
+ { "NEMESIS.STR", 0, "3d1a12b907751653866cffc6d4dfb331", 9505 },
+ AD_LISTEND
+ },
+ Common::DE_DEU,
+ Common::kPlatformDOS,
+ ADGF_NO_FLAGS,
+ GUIO4(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_DOUBLE_FPS, GAMEOPTION_ENABLE_VENUS, GAMEOPTION_DISABLE_ANIM_WHILE_TURNING)
+ },
+ GID_NEMESIS
+ },
+
+ {
+ // Zork Nemesis Italian version
+ {
+ "znemesis",
+ 0,
+ {
+ { "CSCR.ZFS", 0, "f04113357b4748c13efcb58b4629887c", 2577873 },
+ { "NEMESIS.STR", 0, "7c568feca8d9f9ae855c47183612c305", 9061 },
+ AD_LISTEND
+ },
+ Common::IT_ITA,
+ Common::kPlatformDOS,
+ ADGF_NO_FLAGS,
+ GUIO4(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_DOUBLE_FPS, GAMEOPTION_ENABLE_VENUS, GAMEOPTION_DISABLE_ANIM_WHILE_TURNING)
+ },
+ GID_NEMESIS
+ },
+
+ {
+ // Zork Nemesis English demo version
+ {
+ "znemesis",
+ "Demo",
+ AD_ENTRY1s("SCRIPTS.ZFS", "64f1e881394e9462305104f99513c833", 380539),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_DEMO,
+ GUIO4(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_DOUBLE_FPS, GAMEOPTION_ENABLE_VENUS, GAMEOPTION_DISABLE_ANIM_WHILE_TURNING)
+ },
+ GID_NEMESIS
+ },
+
+ {
+ // Zork Grand Inquisitor English CD version
+ {
+ "zgi",
+ "CD",
+ AD_ENTRY1s("SCRIPTS.ZFS", "81efd40ecc3d22531e211368b779f17f", 8336944),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ GUIO3(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_DOUBLE_FPS, GAMEOPTION_DISABLE_ANIM_WHILE_TURNING)
+ },
+ GID_GRANDINQUISITOR
+ },
+
+ {
+ // Zork Grand Inquisitor French CD version, reported by ulrichh on IRC
+ {
+ "zgi",
+ "CD",
+ AD_ENTRY1s("SCRIPTS.ZFS", "4d1ec4ade7ecc9ee9ec591d43ca3d213", 8338133),
+ Common::FR_FRA,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ GUIO3(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_DOUBLE_FPS, GAMEOPTION_DISABLE_ANIM_WHILE_TURNING)
+ },
+ GID_GRANDINQUISITOR
+ },
+
+ {
+ // Zork Grand Inquisitor German CD version, reported by breit in bug #6760
+ {
+ "zgi",
+ "CD",
+ AD_ENTRY1s("SCRIPTS.ZFS", "b7ac7e331b9b7f884590b0b325b560c8", 8338133),
+ Common::DE_DEU,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ GUIO3(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_DOUBLE_FPS, GAMEOPTION_DISABLE_ANIM_WHILE_TURNING)
+ },
+ GID_GRANDINQUISITOR
+ },
+
+ {
+ // Zork Grand Inquisitor Spanish CD version, reported by dianiu in bug #6764
+ {
+ "zgi",
+ "CD",
+ AD_ENTRY1s("SCRIPTS.ZFS", "5cdc4b99c1134053af135aae71326fd1", 8338141),
+ Common::ES_ESP,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ GUIO3(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_DOUBLE_FPS, GAMEOPTION_DISABLE_ANIM_WHILE_TURNING)
+ },
+ GID_GRANDINQUISITOR
+ },
+
+ {
+ // Zork Grand Inquisitor English DVD version
+ {
+ "zgi",
+ "DVD",
+ AD_ENTRY1s("SCRIPTS.ZFS", "03157a3399513bfaaf8dc6d5ab798b36", 8433326),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ GUIO4(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_DOUBLE_FPS, GAMEOPTION_DISABLE_ANIM_WHILE_TURNING, GAMEOPTION_USE_HIRES_MPEG_MOVIES)
+ },
+ GID_GRANDINQUISITOR
+ },
+
+ {
+ // Zork Grand Inquisitor English demo version
+ {
+ "zgi",
+ "Demo",
+ AD_ENTRY1s("SCRIPTS.ZFS", "71a2494fd2fb999347deb13401e9b998", 304239),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_DEMO,
+ GUIO3(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_DOUBLE_FPS, GAMEOPTION_DISABLE_ANIM_WHILE_TURNING)
+ },
+ GID_GRANDINQUISITOR
+ },
+
+ {
+ AD_TABLE_END_MARKER,
+ GID_NONE
+ }
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/file/lzss_read_stream.cpp b/engines/zvision/file/lzss_read_stream.cpp
index 6f27eaa765..ca10af7d72 100644
--- a/engines/zvision/file/lzss_read_stream.cpp
+++ b/engines/zvision/file/lzss_read_stream.cpp
@@ -31,8 +31,9 @@ LzssReadStream::LzssReadStream(Common::SeekableReadStream *source)
// It's convention to set the starting cursor position to blockSize - 16
_windowCursor(0x0FEE),
_eosFlag(false) {
- // Clear the window to null
- memset(_window, 0, BLOCK_SIZE);
+ // All values up to _windowCursor inits by 0x20
+ memset(_window, 0x20, _windowCursor);
+ memset(_window + _windowCursor, 0, BLOCK_SIZE - _windowCursor);
}
uint32 LzssReadStream::decompressBytes(byte *destination, uint32 numberOfBytes) {
diff --git a/engines/zvision/core/save_manager.cpp b/engines/zvision/file/save_manager.cpp
index 20bd39fde5..d169679e28 100644
--- a/engines/zvision/core/save_manager.cpp
+++ b/engines/zvision/file/save_manager.cpp
@@ -22,8 +22,8 @@
#include "common/scummsys.h"
-#include "zvision/core/save_manager.h"
#include "zvision/zvision.h"
+#include "zvision/file/save_manager.h"
#include "zvision/scripting/script_manager.h"
#include "zvision/graphics/render_manager.h"
@@ -69,7 +69,7 @@ bool SaveManager::scummVMSaveLoadDialog(bool isSave) {
return false;
if (isSave) {
- saveGame(slot, desc);
+ saveGame(slot, desc, false);
return true;
} else {
Common::ErrorCode result = loadGame(slot).getCode();
@@ -77,54 +77,34 @@ bool SaveManager::scummVMSaveLoadDialog(bool isSave) {
}
}
-void SaveManager::saveGame(uint slot, const Common::String &saveName) {
- // The games only support 20 slots
- //assert(slot <= 1 && slot <= 20);
+void SaveManager::saveGame(uint slot, const Common::String &saveName, bool useSaveBuffer) {
+ if (!_tempSave && useSaveBuffer)
+ return;
Common::SaveFileManager *saveFileManager = g_system->getSavefileManager();
Common::OutSaveFile *file = saveFileManager->openForSaving(_engine->generateSaveFileName(slot));
- writeSaveGameHeader(file, saveName);
+ writeSaveGameHeader(file, saveName, useSaveBuffer);
- _engine->getScriptManager()->serialize(file);
+ if (useSaveBuffer)
+ file->write(_tempSave->getData(), _tempSave->size());
+ else
+ _engine->getScriptManager()->serialize(file);
file->finalize();
delete file;
-}
-
-void SaveManager::saveGame(uint slot, const Common::String &saveName, Common::MemoryWriteStreamDynamic *stream) {
- Common::SaveFileManager *saveFileManager = g_system->getSavefileManager();
- Common::OutSaveFile *file = saveFileManager->openForSaving(_engine->generateSaveFileName(slot));
-
- writeSaveGameHeader(file, saveName);
-
- file->write(stream->getData(), stream->size());
- file->finalize();
- delete file;
-}
-
-void SaveManager::saveGameBuffered(uint slot, const Common::String &saveName) {
- if (_tempSave) {
- saveGame(slot, saveName, _tempSave);
+ if (useSaveBuffer)
flushSaveBuffer();
- }
+
+ _lastSaveTime = g_system->getMillis();
}
void SaveManager::autoSave() {
- Common::OutSaveFile *file = g_system->getSavefileManager()->openForSaving(_engine->generateAutoSaveFileName());
-
- writeSaveGameHeader(file, "auto");
-
- _engine->getScriptManager()->serialize(file);
-
- // Cleanup
- file->finalize();
- delete file;
+ saveGame(0, "Auto save", false);
}
-void SaveManager::writeSaveGameHeader(Common::OutSaveFile *file, const Common::String &saveName) {
-
+void SaveManager::writeSaveGameHeader(Common::OutSaveFile *file, const Common::String &saveName, bool useSaveBuffer) {
file->writeUint32BE(SAVEGAME_ID);
// Write version
@@ -134,8 +114,11 @@ void SaveManager::writeSaveGameHeader(Common::OutSaveFile *file, const Common::S
file->writeString(saveName);
file->writeByte(0);
- // Create a thumbnail and save it
- Graphics::saveThumbnail(*file);
+ // Save the game thumbnail
+ if (useSaveBuffer)
+ file->write(_tempThumbnail->getData(), _tempThumbnail->size());
+ else
+ Graphics::saveThumbnail(*file);
// Write out the save date/time
TimeDate td;
@@ -147,15 +130,27 @@ void SaveManager::writeSaveGameHeader(Common::OutSaveFile *file, const Common::S
file->writeSint16LE(td.tm_min);
}
-Common::Error SaveManager::loadGame(uint slot) {
- // The games only support 20 slots
- //assert(slot <= 1 && slot <= 20);
+Common::Error SaveManager::loadGame(int slot) {
+ Common::SeekableReadStream *saveFile = NULL;
- Common::SeekableReadStream *saveFile = getSlotFile(slot);
- if (saveFile == 0) {
- return Common::kPathDoesNotExist;
+ if (slot >= 0) {
+ saveFile = getSlotFile(slot);
+ } else {
+ saveFile = _engine->getSearchManager()->openFile("r.svr");
+ if (!saveFile) {
+ Common::File *restoreFile = new Common::File();
+ if (!restoreFile->open("r.svr")) {
+ delete restoreFile;
+ return Common::kPathDoesNotExist;
+ }
+
+ saveFile = restoreFile;
+ }
}
+ if (!saveFile)
+ return Common::kPathDoesNotExist;
+
// Read the header
SaveGameHeader header;
if (!readSaveGameHeader(saveFile, header)) {
@@ -170,33 +165,27 @@ Common::Error SaveManager::loadGame(uint slot) {
if (header.thumbnail)
delete header.thumbnail;
- return Common::kNoError;
-}
-
-Common::Error SaveManager::loadGame(const Common::String &saveName) {
- Common::File *saveFile = _engine->getSearchManager()->openFile(saveName);
- if (saveFile == NULL) {
- saveFile = new Common::File;
- if (!saveFile->open(saveName)) {
- delete saveFile;
- return Common::kPathDoesNotExist;
+ if (_engine->getGameId() == GID_NEMESIS && scriptManager->getCurrentLocation() == "tv2f") {
+ // WORKAROUND for script bug #6793: location tv2f (stairs) has two states:
+ // one at the top of the stairs, and one at the bottom. When the player
+ // goes to the bottom of the stairs, the screen changes, and hotspot
+ // 4652 (exit opposite the stairs) is enabled. However, the variable that
+ // controls the state (2408) is reset when the player goes down the stairs.
+ // Furthermore, the room's initialization script disables the stair exit
+ // control (4652). This leads to an impossible situation, where all the
+ // exit controls are disabled, and the player can't more anywhere. Thus,
+ // when loading a game in that room, we check for that impossible
+ // situation, which only occurs after the player has moved down the stairs,
+ // and fix it here by setting the correct background, and enabling the
+ // stair exit hotspot.
+ if ((scriptManager->getStateFlag(2411) & Puzzle::DISABLED) &&
+ (scriptManager->getStateFlag(2408) & Puzzle::DISABLED) &&
+ (scriptManager->getStateFlag(4652) & Puzzle::DISABLED)) {
+ _engine->getRenderManager()->setBackgroundImage("tv2fb21c.tga");
+ scriptManager->unsetStateFlag(4652, Puzzle::DISABLED);
}
}
- // Read the header
- SaveGameHeader header;
- if (!readSaveGameHeader(saveFile, header)) {
- return Common::kUnknownError;
- }
-
- ScriptManager *scriptManager = _engine->getScriptManager();
- // Update the state table values
- scriptManager->deserialize(saveFile);
-
- delete saveFile;
- if (header.thumbnail)
- delete header.thumbnail;
-
return Common::kNoError;
}
@@ -216,7 +205,7 @@ bool SaveManager::readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &hea
return true;
}
if (tag != SAVEGAME_ID) {
- warning("File is not a ZVision save file. Aborting load");
+ warning("File is not a Z-Vision save file. Aborting load");
return false;
}
@@ -226,7 +215,13 @@ bool SaveManager::readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &hea
// Check that the save version isn't newer than this binary
if (header.version > SAVE_VERSION) {
uint tempVersion = header.version;
- GUI::MessageDialog dialog(Common::String::format("This save file uses version %u, but this engine only supports up to version %d. You will need an updated version of the engine to use this save file.", tempVersion, SAVE_VERSION), "OK");
+ GUI::MessageDialog dialog(
+ Common::String::format(
+ "This save file uses version %u, but this engine only "
+ "supports up to version %d. You will need an updated version "
+ "of the engine to use this save file.", tempVersion, SAVE_VERSION
+ ),
+ "OK");
dialog.runModal();
}
@@ -277,18 +272,20 @@ Common::SeekableReadStream *SaveManager::getSlotFile(uint slot) {
}
void SaveManager::prepareSaveBuffer() {
- if (_tempSave)
- delete _tempSave;
+ delete _tempThumbnail;
+ _tempThumbnail = new Common::MemoryWriteStreamDynamic;
+ Graphics::saveThumbnail(*_tempThumbnail);
+ delete _tempSave;
_tempSave = new Common::MemoryWriteStreamDynamic;
-
_engine->getScriptManager()->serialize(_tempSave);
}
void SaveManager::flushSaveBuffer() {
- if (_tempSave)
- delete _tempSave;
+ delete _tempThumbnail;
+ _tempThumbnail = NULL;
+ delete _tempSave;
_tempSave = NULL;
}
diff --git a/engines/zvision/core/save_manager.h b/engines/zvision/file/save_manager.h
index 75841331e7..9e816373ea 100644
--- a/engines/zvision/core/save_manager.h
+++ b/engines/zvision/file/save_manager.h
@@ -48,13 +48,18 @@ struct SaveGameHeader {
class SaveManager {
public:
- SaveManager(ZVision *engine) : _engine(engine), _tempSave(NULL) {}
+ SaveManager(ZVision *engine) : _engine(engine), _tempSave(NULL), _tempThumbnail(NULL), _lastSaveTime(0) {}
~SaveManager() {
flushSaveBuffer();
}
+ uint32 getLastSaveTime() const {
+ return _lastSaveTime;
+ }
+
private:
ZVision *_engine;
+ uint32 _lastSaveTime;
static const uint32 SAVEGAME_ID;
enum {
@@ -62,13 +67,13 @@ private:
SAVE_VERSION = 1
};
+ Common::MemoryWriteStreamDynamic *_tempThumbnail;
Common::MemoryWriteStreamDynamic *_tempSave;
public:
/**
* Called every room change. Saves the state of the room just before
- * we switched rooms. Uses ZVision::generateAutoSaveFileName() to
- * create the save file name.
+ * the room changes.
*/
void autoSave();
/**
@@ -79,17 +84,14 @@ public:
* @param slot The save slot this save pertains to. Must be [1, 20]
* @param saveName The internal name for this save. This is NOT the name of the actual save file.
*/
- void saveGame(uint slot, const Common::String &saveName);
- void saveGame(uint slot, const Common::String &saveName, Common::MemoryWriteStreamDynamic *stream);
- void saveGameBuffered(uint slot, const Common::String &saveName);
+ void saveGame(uint slot, const Common::String &saveName, bool useSaveBuffer);
/**
* Loads the state data from the save file that slot references. Uses
* ZVision::generateSaveFileName(slot) to get the save file name.
*
* @param slot The save slot to load. Must be [1, 20]
*/
- Common::Error loadGame(uint slot);
- Common::Error loadGame(const Common::String &saveName);
+ Common::Error loadGame(int slot);
Common::SeekableReadStream *getSlotFile(uint slot);
bool readSaveGameHeader(Common::SeekableReadStream *in, SaveGameHeader &header);
@@ -98,7 +100,7 @@ public:
void flushSaveBuffer();
bool scummVMSaveLoadDialog(bool isSave);
private:
- void writeSaveGameHeader(Common::OutSaveFile *file, const Common::String &saveName);
+ void writeSaveGameHeader(Common::OutSaveFile *file, const Common::String &saveName, bool useSaveBuffer);
};
} // End of namespace ZVision
diff --git a/engines/zvision/file/search_manager.cpp b/engines/zvision/file/search_manager.cpp
index 30c269c290..821b85b053 100644
--- a/engines/zvision/file/search_manager.cpp
+++ b/engines/zvision/file/search_manager.cpp
@@ -62,19 +62,6 @@ SearchManager::~SearchManager() {
_archList.clear();
}
-void SearchManager::addPatch(const Common::String &src, const Common::String &dst) {
- Common::String lowerCaseName = dst;
- lowerCaseName.toLowercase();
-
- SearchManager::MatchList::iterator it = _files.find(lowerCaseName);
-
- if (it != _files.end()) {
- lowerCaseName = src;
- lowerCaseName.toLowercase();
- _files[lowerCaseName] = it->_value;
- }
-}
-
void SearchManager::addFile(const Common::String &name, Common::Archive *arch) {
bool addArch = true;
Common::List<Common::Archive *>::iterator it = _archList.begin();
@@ -147,9 +134,10 @@ bool SearchManager::hasFile(const Common::String &name) {
return false;
}
-void SearchManager::loadZix(const Common::String &name) {
+bool SearchManager::loadZix(const Common::String &name) {
Common::File file;
- file.open(name);
+ if (!file.open(name))
+ return false;
Common::String line;
@@ -160,7 +148,7 @@ void SearchManager::loadZix(const Common::String &name) {
}
if (file.eos())
- return;
+ error("Corrupt ZIX file: %s", name.c_str());
Common::Array<Common::Archive *> archives;
@@ -169,37 +157,47 @@ void SearchManager::loadZix(const Common::String &name) {
line.trim();
if (line.matchString("----------*", true))
break;
- else if (line.matchString("DIR:*", true)) {
- Common::String path(line.c_str() + 5);
+ else if (line.matchString("DIR:*", true) || line.matchString("CD0:*", true) || line.matchString("CD1:*", true) || line.matchString("CD2:*", true)) {
Common::Archive *arc;
- char tempPath[128];
- strcpy(tempPath, path.c_str());
+
+ Common::String path(line.c_str() + 5);
for (uint i = 0; i < path.size(); i++)
- if (tempPath[i] == '\\')
- tempPath[i] = '/';
+ if (path[i] == '\\')
+ path.setChar('/', i);
+
+ // Check if NEMESIS.ZIX/MEDIUM.ZIX refers to the znemesis folder, and
+ // check the game root folder instead
+ if (path.hasPrefix("znemesis/"))
+ path = Common::String(path.c_str() + 9);
+
+ // Check if INQUIS.ZIX refers to the ZGI folder, and check the game
+ // root folder instead
+ if (path.hasPrefix("zgi/"))
+ path = Common::String(path.c_str() + 4);
+ if (path.hasPrefix("zgi_e/"))
+ path = Common::String(path.c_str() + 6);
- path = Common::String(tempPath);
if (path.size() && path[0] == '.')
path.deleteChar(0);
if (path.size() && path[0] == '/')
path.deleteChar(0);
-
- if (path.matchString("*.zfs", true))
- arc = new ZfsArchive(path);
- else {
- if (path.size()) {
- if (path[path.size() - 1] == '\\' || path[path.size() - 1] == '/')
- path.deleteLastChar();
- if (path.size())
- for (Common::List<Common::String>::iterator it = _dirList.begin(); it != _dirList.end(); ++it)
- if (path.equalsIgnoreCase(*it)) {
- path = *it;
- break;
- }
+ if (path.size() && path.hasSuffix("/"))
+ path.deleteLastChar();
+
+ // Handle paths in case-sensitive file systems (bug #6775)
+ if (path.size()) {
+ for (Common::List<Common::String>::iterator it = _dirList.begin(); it != _dirList.end(); ++it) {
+ if (path.equalsIgnoreCase(*it)) {
+ path = *it;
+ break;
+ }
}
+ }
+ if (path.matchString("*.zfs", true)) {
+ arc = new ZfsArchive(path);
+ } else {
path = Common::String::format("%s/%s", _root.c_str(), path.c_str());
-
arc = new Common::FSDirectory(path);
}
archives.push_back(arc);
@@ -207,7 +205,7 @@ void SearchManager::loadZix(const Common::String &name) {
}
if (file.eos())
- return;
+ error("Corrupt ZIX file: %s", name.c_str());
while (!file.eos()) {
line = file.readLine();
@@ -220,6 +218,8 @@ void SearchManager::loadZix(const Common::String &name) {
}
}
}
+
+ return true;
}
void SearchManager::addDir(const Common::String &name) {
@@ -265,7 +265,7 @@ void SearchManager::addDir(const Common::String &name) {
void SearchManager::listDirRecursive(Common::List<Common::String> &_list, const Common::FSNode &fsNode, int depth) {
Common::FSList fsList;
- if ( fsNode.getChildren(fsList) ) {
+ if (fsNode.getChildren(fsList)) {
_list.push_back(fsNode.getPath());
@@ -275,4 +275,11 @@ void SearchManager::listDirRecursive(Common::List<Common::String> &_list, const
}
}
+void SearchManager::listMembersWithExtension(MatchList &fileList, Common::String extension) {
+ for (SearchManager::MatchList::iterator it = _files.begin(); it != _files.end(); ++it) {
+ if (it->_key.hasSuffix(extension))
+ fileList[it->_key] = it->_value;
+ }
+}
+
} // End of namespace ZVision
diff --git a/engines/zvision/file/search_manager.h b/engines/zvision/file/search_manager.h
index fdd70fd381..0d0ab14d31 100644
--- a/engines/zvision/file/search_manager.h
+++ b/engines/zvision/file/search_manager.h
@@ -39,33 +39,30 @@ public:
void addFile(const Common::String &name, Common::Archive *arch);
void addDir(const Common::String &name);
- void addPatch(const Common::String &src, const Common::String &dst);
Common::File *openFile(const Common::String &name);
bool openFile(Common::File &file, const Common::String &name);
bool hasFile(const Common::String &name);
- void loadZix(const Common::String &name);
-
-private:
-
- void listDirRecursive(Common::List<Common::String> &dirList, const Common::FSNode &fsNode, int depth);
+ bool loadZix(const Common::String &name);
struct Node {
Common::String name;
Common::Archive *arch;
};
- Common::List<Common::String> _dirList;
-
typedef Common::HashMap<Common::String, Node, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> MatchList;
- Common::List<Common::Archive *> _archList;
- MatchList _files;
-
- Common::String _root;
+ void listMembersWithExtension(MatchList &fileList, Common::String extension);
private:
+
+ void listDirRecursive(Common::List<Common::String> &dirList, const Common::FSNode &fsNode, int depth);
+
+ Common::List<Common::String> _dirList;
+ Common::List<Common::Archive *> _archList;
+ Common::String _root;
+ MatchList _files;
};
}
diff --git a/engines/zvision/graphics/cursors/cursor.cpp b/engines/zvision/graphics/cursors/cursor.cpp
index 07323b45c4..2c011668ac 100644
--- a/engines/zvision/graphics/cursors/cursor.cpp
+++ b/engines/zvision/graphics/cursors/cursor.cpp
@@ -36,35 +36,6 @@ ZorkCursor::ZorkCursor()
_hotspotY(0) {
}
-ZorkCursor::ZorkCursor(const Common::String &fileName)
- : _width(0),
- _height(0),
- _hotspotX(0),
- _hotspotY(0) {
- Common::File file;
- if (!file.open(fileName))
- return;
-
- uint32 magic = file.readUint32BE();
- if (magic != MKTAG('Z', 'C', 'R', '1')) {
- warning("%s is not a Zork Cursor file", fileName.c_str());
- return;
- }
-
- _hotspotX = file.readUint16LE();
- _hotspotY = file.readUint16LE();
- _width = file.readUint16LE();
- _height = file.readUint16LE();
-
- uint dataSize = _width * _height * sizeof(uint16);
- _surface.create(_width, _height, Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0));
- uint32 bytesRead = file.read(_surface.getPixels(), dataSize);
- assert(bytesRead == dataSize);
-
- // Convert to RGB 565
- _surface.convertToInPlace(Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));
-}
-
ZorkCursor::ZorkCursor(ZVision *engine, const Common::String &fileName)
: _width(0),
_height(0),
@@ -72,7 +43,7 @@ ZorkCursor::ZorkCursor(ZVision *engine, const Common::String &fileName)
_hotspotY(0) {
Common::File file;
if (!engine->getSearchManager()->openFile(file, fileName))
- return;
+ error("Cursor file %s does not exist", fileName.c_str());
uint32 magic = file.readUint32BE();
if (magic != MKTAG('Z', 'C', 'R', '1')) {
@@ -86,12 +57,15 @@ ZorkCursor::ZorkCursor(ZVision *engine, const Common::String &fileName)
_height = file.readUint16LE();
uint dataSize = _width * _height * sizeof(uint16);
- _surface.create(_width, _height, Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0));
+ _surface.create(_width, _height, engine->_resourcePixelFormat);
uint32 bytesRead = file.read(_surface.getPixels(), dataSize);
assert(bytesRead == dataSize);
- // Convert to RGB 565
- _surface.convertToInPlace(Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));
+#ifndef SCUMM_LITTLE_ENDIAN
+ int16 *buffer = (int16 *)_surface.getPixels();
+ for (uint32 i = 0; i < dataSize / 2; ++i)
+ buffer[i] = FROM_LE_16(buffer[i]);
+#endif
}
ZorkCursor::ZorkCursor(const ZorkCursor &other) {
diff --git a/engines/zvision/graphics/cursors/cursor.h b/engines/zvision/graphics/cursors/cursor.h
index 0c1e99411f..6e0083520a 100644
--- a/engines/zvision/graphics/cursors/cursor.h
+++ b/engines/zvision/graphics/cursors/cursor.h
@@ -39,7 +39,6 @@ namespace ZVision {
class ZorkCursor {
public:
ZorkCursor();
- ZorkCursor(const Common::String &fileName);
ZorkCursor(ZVision *engine, const Common::String &fileName);
ZorkCursor(const ZorkCursor &other);
~ZorkCursor();
diff --git a/engines/zvision/graphics/cursors/cursor_manager.cpp b/engines/zvision/graphics/cursors/cursor_manager.cpp
index 92fd461c72..eeab18f4ba 100644
--- a/engines/zvision/graphics/cursors/cursor_manager.cpp
+++ b/engines/zvision/graphics/cursors/cursor_manager.cpp
@@ -37,7 +37,7 @@ const char *CursorManager::_cursorNames[NUM_CURSORS] = { "active", "arrow", "bac
"hright", "hup", "idle", "leftarrow", "rightarrow", "suggest_surround", "suggest_tilt", "turnaround", "zuparrow"
};
-const char *CursorManager::_zgiCursorFileNames[NUM_CURSORS] = { "g0gbc011.zcr", "g0gac001.zcr", "g0gac021.zcr", "g0gac031.zcr", "g0gac041.zcr", "g0gac051.zcr", "g0gac061.zcr", "g0gac071.zcr", "g0gac081.zcr",
+const char *CursorManager::_zgiCursorFileNames[NUM_CURSORS] = { "g0gbc011.zcr", "g0gac011.zcr", "g0gac021.zcr", "g0gac031.zcr", "g0gac041.zcr", "g0gac051.zcr", "g0gac061.zcr", "g0gac071.zcr", "g0gac081.zcr",
"g0gac091.zcr", "g0gac101.zcr", "g0gac011.zcr", "g0gac111.zcr", "g0gac121.zcr", "g0gac131.zcr", "g0gac141.zcr", "g0gac151.zcr", "g0gac161.zcr"
};
@@ -45,7 +45,7 @@ const char *CursorManager::_zNemCursorFileNames[NUM_CURSORS] = { "00act", "arrow
"hright", "hup", "00idle", "left", "right", "ssurr", "stilt", "turn", "up"
};
-CursorManager::CursorManager(ZVision *engine, const Graphics::PixelFormat *pixelFormat)
+CursorManager::CursorManager(ZVision *engine, const Graphics::PixelFormat pixelFormat)
: _engine(engine),
_pixelFormat(pixelFormat),
_cursorIsPushed(false),
@@ -55,6 +55,11 @@ CursorManager::CursorManager(ZVision *engine, const Graphics::PixelFormat *pixel
for (int i = 0; i < NUM_CURSORS; i++) {
if (_engine->getGameId() == GID_NEMESIS) {
Common::String name;
+ if (i == 1) {
+ // Cursors "arrowa.zcr" and "arrowb.zcr" are missing
+ _cursors[i][0] = _cursors[i][1] = ZorkCursor();
+ continue;
+ }
name = Common::String::format("%sa.zcr", _zNemCursorFileNames[i]);
_cursors[i][0] = ZorkCursor(_engine, name); // Up cursor
name = Common::String::format("%sb.zcr", _zNemCursorFileNames[i]);
@@ -106,7 +111,7 @@ void CursorManager::initialize() {
}
void CursorManager::changeCursor(const ZorkCursor &cursor) {
- CursorMan.replaceCursor(cursor.getSurface(), cursor.getWidth(), cursor.getHeight(), cursor.getHotspotX(), cursor.getHotspotY(), cursor.getKeyColor(), false, _pixelFormat);
+ CursorMan.replaceCursor(cursor.getSurface(), cursor.getWidth(), cursor.getHeight(), cursor.getHotspotX(), cursor.getHotspotY(), cursor.getKeyColor(), false, &_pixelFormat);
}
void CursorManager::cursorDown(bool pushed) {
@@ -119,31 +124,30 @@ void CursorManager::cursorDown(bool pushed) {
}
void CursorManager::changeCursor(int id) {
- int _id = id;
-
- if (_item &&
- (_id == CursorIndex_Active ||
- _id == CursorIndex_Idle ||
- _id == CursorIndex_HandPu)) {
-
- if (_id == CursorIndex_Idle)
- _id = CursorIndex_ItemIdle;
- else
- _id = CursorIndex_ItemAct;
+ if (_item && (id == CursorIndex_Active ||
+ id == CursorIndex_Idle ||
+ id == CursorIndex_HandPu)) {
+ if (id == CursorIndex_Idle) {
+ id = CursorIndex_ItemIdle;
+ } else {
+ id = CursorIndex_ItemAct;
+ }
}
- if (_currentCursor != _id ||
- ((_id == CursorIndex_ItemAct || _id == CursorIndex_ItemIdle) && _lastitem != _item)) {
- _currentCursor = _id;
+ if (_currentCursor != id || ((id == CursorIndex_ItemAct || id == CursorIndex_ItemIdle) && _lastitem != _item)) {
+ _currentCursor = id;
_lastitem = _item;
changeCursor(_cursors[_currentCursor][_cursorIsPushed]);
}
}
int CursorManager::getCursorId(const Common::String &name) {
- for (int i = 0; i < NUM_CURSORS; i++)
- if (name.equals(_cursorNames[i]))
+ for (int i = 0; i < NUM_CURSORS; i++) {
+ if (name.equals(_cursorNames[i])) {
return i;
+ }
+ }
+
return CursorIndex_Idle;
}
diff --git a/engines/zvision/graphics/cursors/cursor_manager.h b/engines/zvision/graphics/cursors/cursor_manager.h
index bbfa085c23..35c605baf8 100644
--- a/engines/zvision/graphics/cursors/cursor_manager.h
+++ b/engines/zvision/graphics/cursors/cursor_manager.h
@@ -58,7 +58,7 @@ enum CursorIndex {
*/
class CursorManager {
public:
- CursorManager(ZVision *engine, const Graphics::PixelFormat *pixelFormat);
+ CursorManager(ZVision *engine, const Graphics::PixelFormat pixelFormat);
private:
static const int NUM_CURSORS = 18;
@@ -67,7 +67,7 @@ private:
ZorkCursor _cursors[NUM_CURSORS + 2][2];
ZVision *_engine;
- const Graphics::PixelFormat *_pixelFormat;
+ const Graphics::PixelFormat _pixelFormat;
bool _cursorIsPushed;
int _item;
int _lastitem;
diff --git a/engines/zvision/graphics/effects/fog.cpp b/engines/zvision/graphics/effects/fog.cpp
index f59e82a4a0..7b65f60f24 100644
--- a/engines/zvision/graphics/effects/fog.cpp
+++ b/engines/zvision/graphics/effects/fog.cpp
@@ -31,7 +31,7 @@
namespace ZVision {
FogFx::FogFx(ZVision *engine, uint32 key, Common::Rect region, bool ported, EffectMap *Map, const Common::String &clouds):
- Effect(engine, key, region, ported) {
+ GraphicsEffect(engine, key, region, ported) {
_map = Map;
@@ -79,10 +79,10 @@ const Graphics::Surface *FogFx::draw(const Graphics::Surface &srcSubRect) {
if (it->inEffect) {
// Not 100% equivalent, but looks nice and not buggy
uint8 sr, sg, sb;
- _engine->_pixelFormat.colorToRGB(lineBuf[i], sr, sg, sb);
+ _engine->_resourcePixelFormat.colorToRGB(lineBuf[i], sr, sg, sb);
uint16 fogColor = *(uint16 *)_fog.getBasePtr((i + _pos) % _fog.w, j);
uint8 dr, dg, db;
- _engine->_pixelFormat.colorToRGB(_colorMap[fogColor & 0x1F], dr, dg, db);
+ _engine->_resourcePixelFormat.colorToRGB(_colorMap[fogColor & 0x1F], dr, dg, db);
uint16 fr = dr + sr;
if (fr > 255)
fr = 255;
@@ -92,7 +92,7 @@ const Graphics::Surface *FogFx::draw(const Graphics::Surface &srcSubRect) {
uint16 fb = db + sb;
if (fb > 255)
fb = 255;
- lineBuf[i] = _engine->_pixelFormat.RGBToColor(fr, fg, fb);
+ lineBuf[i] = _engine->_resourcePixelFormat.RGBToColor(fr, fg, fb);
}
cnt++;
if (cnt >= it->count) {
@@ -138,14 +138,14 @@ void FogFx::update() {
// Not 100% equivalent, but looks nice and not buggy
- _colorMap[31] = _engine->_pixelFormat.RGBToColor(_r << 3, _g << 3, _b << 3);
+ _colorMap[31] = _engine->_resourcePixelFormat.RGBToColor(_r << 3, _g << 3, _b << 3);
for (uint8 i = 0; i < 31; i++) {
float perc = (float)i / 31.0;
- uint8 cr = (float)_r * perc;
- uint8 cg = (float)_g * perc;
- uint8 cb = (float)_b * perc;
- _colorMap[i] = _engine->_pixelFormat.RGBToColor(cr << 3, cg << 3, cb << 3);
+ uint8 cr = (uint8)((float)_r * perc);
+ uint8 cg = (uint8)((float)_g * perc);
+ uint8 cb = (uint8)((float)_b * perc);
+ _colorMap[i] = _engine->_resourcePixelFormat.RGBToColor(cr << 3, cg << 3, cb << 3);
}
}
diff --git a/engines/zvision/graphics/effects/fog.h b/engines/zvision/graphics/effects/fog.h
index 45d6f9596d..498347609e 100644
--- a/engines/zvision/graphics/effects/fog.h
+++ b/engines/zvision/graphics/effects/fog.h
@@ -23,13 +23,14 @@
#ifndef ZVISION_FOG_H
#define ZVISION_FOG_H
-#include "zvision/graphics/effect.h"
+#include "zvision/graphics/graphics_effect.h"
namespace ZVision {
class ZVision;
-class FogFx : public Effect {
+// Used by Zork: Nemesis for the mixing chamber gas effect in the gas puzzle (location tt5e, when the blinds are down)
+class FogFx : public GraphicsEffect {
public:
FogFx(ZVision *engine, uint32 key, Common::Rect region, bool ported, EffectMap *Map, const Common::String &clouds);
diff --git a/engines/zvision/graphics/effects/light.cpp b/engines/zvision/graphics/effects/light.cpp
index 00b3811d65..39341687f8 100644
--- a/engines/zvision/graphics/effects/light.cpp
+++ b/engines/zvision/graphics/effects/light.cpp
@@ -30,7 +30,7 @@
namespace ZVision {
LightFx::LightFx(ZVision *engine, uint32 key, Common::Rect region, bool ported, EffectMap *Map, int8 delta, int8 minD, int8 maxD):
- Effect(engine, key, region, ported) {
+ GraphicsEffect(engine, key, region, ported) {
_map = Map;
_delta = delta;
_up = true;
@@ -59,10 +59,10 @@ const Graphics::Surface *LightFx::draw(const Graphics::Surface &srcSubRect) {
if (_pos < 0) {
uint8 cc = ((-_pos) & 0x1F) << 3;
- dcolor = _engine->_pixelFormat.RGBToColor(cc, cc, cc);
+ dcolor = _engine->_resourcePixelFormat.RGBToColor(cc, cc, cc);
} else {
uint8 cc = (_pos & 0x1F) << 3;
- dcolor = _engine->_pixelFormat.RGBToColor(cc, cc, cc);
+ dcolor = _engine->_resourcePixelFormat.RGBToColor(cc, cc, cc);
}
for (uint16 j = 0; j < _surface.h; j++) {
diff --git a/engines/zvision/graphics/effects/light.h b/engines/zvision/graphics/effects/light.h
index ae87d66cb3..cd73a585ec 100644
--- a/engines/zvision/graphics/effects/light.h
+++ b/engines/zvision/graphics/effects/light.h
@@ -23,13 +23,13 @@
#ifndef LIGHTFX_H_INCLUDED
#define LIGHTFX_H_INCLUDED
-#include "zvision/graphics/effect.h"
+#include "zvision/graphics/graphics_effect.h"
namespace ZVision {
class ZVision;
-class LightFx : public Effect {
+class LightFx : public GraphicsEffect {
public:
LightFx(ZVision *engine, uint32 key, Common::Rect region, bool ported, EffectMap *Map, int8 delta, int8 minD = -127, int8 maxD = 127);
diff --git a/engines/zvision/graphics/effects/wave.cpp b/engines/zvision/graphics/effects/wave.cpp
index 1b3aa040e8..d2887b3112 100644
--- a/engines/zvision/graphics/effects/wave.cpp
+++ b/engines/zvision/graphics/effects/wave.cpp
@@ -30,7 +30,7 @@
namespace ZVision {
WaveFx::WaveFx(ZVision *engine, uint32 key, Common::Rect region, bool ported, int16 frames, int16 centerX, int16 centerY, float ampl, float waveln, float spd):
- Effect(engine, key, region, ported) {
+ GraphicsEffect(engine, key, region, ported) {
_frame = 0;
_frameCount = frames;
@@ -54,7 +54,7 @@ WaveFx::WaveFx(ZVision *engine, uint32 key, Common::Rect region, bool ported, in
int16 dx = (x - quarterWidth);
int16 dy = (y - quarterHeight);
- _ampls[i][x + y * _halfWidth] = ampl * sin(sqrt(dx * dx / (float)centerX + dy * dy / (float)centerY) / (-waveln * 3.1415926) + phase);
+ _ampls[i][x + y * _halfWidth] = (int8)(ampl * sin(sqrt(dx * dx / (float)centerX + dy * dy / (float)centerY) / (-waveln * 3.1415926) + phase));
}
phase += spd;
}
diff --git a/engines/zvision/graphics/effects/wave.h b/engines/zvision/graphics/effects/wave.h
index 2e813ed5b6..8e912372d7 100644
--- a/engines/zvision/graphics/effects/wave.h
+++ b/engines/zvision/graphics/effects/wave.h
@@ -24,13 +24,13 @@
#define WAVEFX_H_INCLUDED
#include "common/array.h"
-#include "zvision/graphics/effect.h"
+#include "zvision/graphics/graphics_effect.h"
namespace ZVision {
class ZVision;
-class WaveFx : public Effect {
+class WaveFx : public GraphicsEffect {
public:
WaveFx(ZVision *engine, uint32 key, Common::Rect region, bool ported, int16 frames, int16 centerX, int16 centerY, float ampl, float waveln, float spd);
diff --git a/engines/zvision/graphics/effect.h b/engines/zvision/graphics/graphics_effect.h
index c6653c6037..bfa266b11d 100644
--- a/engines/zvision/graphics/effect.h
+++ b/engines/zvision/graphics/graphics_effect.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef EFFECT_H_INCLUDED
-#define EFFECT_H_INCLUDED
+#ifndef GRAPHICS_EFFECT_H_INCLUDED
+#define GRAPHICS_EFFECT_H_INCLUDED
#include "common/rect.h"
#include "common/list.h"
@@ -33,13 +33,13 @@ namespace ZVision {
class ZVision;
-class Effect {
+class GraphicsEffect {
public:
- Effect(ZVision *engine, uint32 key, Common::Rect region, bool ported) : _engine(engine), _key(key), _region(region), _ported(ported) {
- _surface.create(_region.width(), _region.height(), _engine->_pixelFormat);
+ GraphicsEffect(ZVision *engine, uint32 key, Common::Rect region, bool ported) : _engine(engine), _key(key), _region(region), _ported(ported) {
+ _surface.create(_region.width(), _region.height(), _engine->_resourcePixelFormat);
}
- virtual ~Effect() {}
+ virtual ~GraphicsEffect() {}
uint32 getKey() {
return _key;
@@ -80,4 +80,4 @@ typedef Common::List<EffectMapUnit> EffectMap;
} // End of namespace ZVision
-#endif // EFFECT_H_INCLUDED
+#endif // GRAPHICS_EFFECT_H_INCLUDED
diff --git a/engines/zvision/graphics/render_manager.cpp b/engines/zvision/graphics/render_manager.cpp
index e2ad13a330..f978ef7844 100644
--- a/engines/zvision/graphics/render_manager.cpp
+++ b/engines/zvision/graphics/render_manager.cpp
@@ -39,71 +39,75 @@
namespace ZVision {
-RenderManager::RenderManager(ZVision *engine, uint32 windowWidth, uint32 windowHeight, const Common::Rect workingWindow, const Graphics::PixelFormat pixelFormat)
+RenderManager::RenderManager(ZVision *engine, uint32 windowWidth, uint32 windowHeight, const Common::Rect workingWindow, const Graphics::PixelFormat pixelFormat, bool doubleFPS)
: _engine(engine),
_system(engine->_system),
- _wrkWidth(workingWindow.width()),
- _wrkHeight(workingWindow.height()),
- _screenCenterX(_wrkWidth / 2),
- _screenCenterY(_wrkHeight / 2),
+ _screenCenterX(_workingWindow.width() / 2),
+ _screenCenterY(_workingWindow.height() / 2),
_workingWindow(workingWindow),
_pixelFormat(pixelFormat),
- _bkgWidth(0),
- _bkgHeight(0),
- _bkgOff(0),
- _renderTable(_wrkWidth, _wrkHeight) {
+ _backgroundWidth(0),
+ _backgroundHeight(0),
+ _backgroundOffset(0),
+ _renderTable(_workingWindow.width(), _workingWindow.height()),
+ _doubleFPS(doubleFPS),
+ _subid(0) {
- _wrkWnd.create(_wrkWidth, _wrkHeight, _pixelFormat);
- _effectWnd.create(_wrkWidth, _wrkHeight, _pixelFormat);
- _outWnd.create(_wrkWidth, _wrkHeight, _pixelFormat);
- _menuWnd.create(windowWidth, workingWindow.top, _pixelFormat);
- _subWnd.create(windowWidth, windowHeight - workingWindow.bottom, _pixelFormat);
+ _backgroundSurface.create(_workingWindow.width(), _workingWindow.height(), _pixelFormat);
+ _effectSurface.create(_workingWindow.width(), _workingWindow.height(), _pixelFormat);
+ _warpedSceneSurface.create(_workingWindow.width(), _workingWindow.height(), _pixelFormat);
+ _menuSurface.create(windowWidth, workingWindow.top, _pixelFormat);
- _menuWndRect = Common::Rect(0, 0, windowWidth, workingWindow.top);
- _subWndRect = Common::Rect(0, workingWindow.bottom, windowWidth, windowHeight);
+ _menuArea = Common::Rect(0, 0, windowWidth, workingWindow.top);
- _subid = 0;
+ initSubArea(windowWidth, windowHeight, workingWindow);
}
RenderManager::~RenderManager() {
- _curBkg.free();
- _wrkWnd.free();
- _effectWnd.free();
- _outWnd.free();
- _menuWnd.free();
- _subWnd.free();
+ _currentBackgroundImage.free();
+ _backgroundSurface.free();
+ _effectSurface.free();
+ _warpedSceneSurface.free();
+ _menuSurface.free();
+ _subtitleSurface.free();
}
-void RenderManager::renderBackbufferToScreen() {
- Graphics::Surface *out = &_outWnd;
- Graphics::Surface *in = &_wrkWnd;
+void RenderManager::renderSceneToScreen() {
+ Graphics::Surface *out = &_warpedSceneSurface;
+ Graphics::Surface *in = &_backgroundSurface;
Common::Rect outWndDirtyRect;
+ // If we have graphical effects, we apply them using a temporary buffer
if (!_effects.empty()) {
bool copied = false;
- Common::Rect windRect(_wrkWidth, _wrkHeight);
- for (effectsList::iterator it = _effects.begin(); it != _effects.end(); it++) {
+ Common::Rect windowRect(_workingWindow.width(), _workingWindow.height());
+
+ for (EffectsList::iterator it = _effects.begin(); it != _effects.end(); it++) {
Common::Rect rect = (*it)->getRegion();
- Common::Rect scrPlace = rect;
- if ((*it)->isPort())
- scrPlace = bkgRectToScreen(scrPlace);
- if (windRect.intersects(scrPlace)) {
+ Common::Rect screenSpaceLocation = rect;
+
+ if ((*it)->isPort()) {
+ screenSpaceLocation = transformBackgroundSpaceRectToScreenSpace(screenSpaceLocation);
+ }
+
+ if (windowRect.intersects(screenSpaceLocation)) {
if (!copied) {
copied = true;
- _effectWnd.copyFrom(_wrkWnd);
- in = &_effectWnd;
+ _effectSurface.copyFrom(_backgroundSurface);
+ in = &_effectSurface;
}
const Graphics::Surface *post;
if ((*it)->isPort())
- post = (*it)->draw(_curBkg.getSubArea(rect));
+ post = (*it)->draw(_currentBackgroundImage.getSubArea(rect));
else
- post = (*it)->draw(_effectWnd.getSubArea(rect));
- blitSurfaceToSurface(*post, _effectWnd, scrPlace.left, scrPlace.top);
- scrPlace.clip(windRect);
- if (_wrkWndDirtyRect .isEmpty()) {
- _wrkWndDirtyRect = scrPlace;
+ post = (*it)->draw(_effectSurface.getSubArea(rect));
+ Common::Rect empty;
+ blitSurfaceToSurface(*post, empty, _effectSurface, screenSpaceLocation.left, screenSpaceLocation.top);
+ screenSpaceLocation.clip(windowRect);
+ if (_backgroundSurfaceDirtyRect .isEmpty()) {
+ _backgroundSurfaceDirtyRect = screenSpaceLocation;
} else {
- _wrkWndDirtyRect.extend(scrPlace);
+ _backgroundSurfaceDirtyRect.extend(screenSpaceLocation);
}
}
}
@@ -111,25 +115,40 @@ void RenderManager::renderBackbufferToScreen() {
RenderTable::RenderState state = _renderTable.getRenderState();
if (state == RenderTable::PANORAMA || state == RenderTable::TILT) {
- if (!_wrkWndDirtyRect.isEmpty()) {
- _renderTable.mutateImage(&_outWnd, in);
- out = &_outWnd;
- outWndDirtyRect = Common::Rect(_wrkWidth, _wrkHeight);
+ if (!_backgroundSurfaceDirtyRect.isEmpty()) {
+ _renderTable.mutateImage(&_warpedSceneSurface, in);
+ out = &_warpedSceneSurface;
+ outWndDirtyRect = Common::Rect(_workingWindow.width(), _workingWindow.height());
}
} else {
out = in;
- outWndDirtyRect = _wrkWndDirtyRect;
+ outWndDirtyRect = _backgroundSurfaceDirtyRect;
}
if (!outWndDirtyRect.isEmpty()) {
- _system->copyRectToScreen(out->getBasePtr(outWndDirtyRect.left, outWndDirtyRect.top), out->pitch,
- outWndDirtyRect.left + _workingWindow.left,
- outWndDirtyRect.top + _workingWindow.top,
- outWndDirtyRect.width(),
- outWndDirtyRect.height());
+ Common::Rect rect(
+ outWndDirtyRect.left + _workingWindow.left,
+ outWndDirtyRect.top + _workingWindow.top,
+ outWndDirtyRect.left + _workingWindow.left + outWndDirtyRect.width(),
+ outWndDirtyRect.top + _workingWindow.top + outWndDirtyRect.height()
+ );
+ copyToScreen(*out, rect, outWndDirtyRect.left, outWndDirtyRect.top);
}
}
+void RenderManager::copyToScreen(const Graphics::Surface &surface, Common::Rect &rect, int16 srcLeft, int16 srcTop) {
+ // Convert the surface to RGB565, if needed
+ Graphics::Surface *outSurface = surface.convertTo(_engine->_screenPixelFormat);
+ _system->copyRectToScreen(outSurface->getBasePtr(srcLeft, srcTop),
+ outSurface->pitch,
+ rect.left,
+ rect.top,
+ rect.width(),
+ rect.height());
+ outSurface->free();
+ delete outSurface;
+}
+
void RenderManager::renderImageToBackground(const Common::String &fileName, int16 destX, int16 destY) {
Graphics::Surface surface;
readImageToSurface(fileName, surface);
@@ -157,97 +176,8 @@ void RenderManager::renderImageToBackground(const Common::String &fileName, int1
}
void RenderManager::readImageToSurface(const Common::String &fileName, Graphics::Surface &destination) {
- Common::File file;
-
- if (!_engine->getSearchManager()->openFile(file, fileName)) {
- warning("Could not open file %s", fileName.c_str());
- return;
- }
-
- // Read the magic number
- // Some files are true TGA, while others are TGZ
- uint32 fileType = file.readUint32BE();
-
- uint32 imageWidth;
- uint32 imageHeight;
- Image::TGADecoder tga;
- uint16 *buffer;
bool isTransposed = _renderTable.getRenderState() == RenderTable::PANORAMA;
- // All ZVision images are in RGB 555
- Graphics::PixelFormat pixelFormat555 = Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0);
- destination.format = pixelFormat555;
-
- bool isTGZ;
-
- // Check for TGZ files
- if (fileType == MKTAG('T', 'G', 'Z', '\0')) {
- isTGZ = true;
-
- // TGZ files have a header and then Bitmap data that is compressed with LZSS
- uint32 decompressedSize = file.readSint32LE();
- imageWidth = file.readSint32LE();
- imageHeight = file.readSint32LE();
-
- LzssReadStream lzssStream(&file);
- buffer = (uint16 *)(new uint16[decompressedSize]);
- lzssStream.read(buffer, decompressedSize);
- } else {
- isTGZ = false;
-
- // Reset the cursor
- file.seek(0);
-
- // Decode
- if (!tga.loadStream(file)) {
- warning("Error while reading TGA image");
- return;
- }
-
- Graphics::Surface tgaSurface = *(tga.getSurface());
- imageWidth = tgaSurface.w;
- imageHeight = tgaSurface.h;
-
- buffer = (uint16 *)tgaSurface.getPixels();
- }
-
- // Flip the width and height if transposed
- if (isTransposed) {
- uint16 temp = imageHeight;
- imageHeight = imageWidth;
- imageWidth = temp;
- }
-
- // If the destination internal buffer is the same size as what we're copying into it,
- // there is no need to free() and re-create
- if (imageWidth != destination.w || imageHeight != destination.h) {
- destination.create(imageWidth, imageHeight, pixelFormat555);
- }
-
- // If transposed, 'un-transpose' the data while copying it to the destination
- // Otherwise, just do a simple copy
- if (isTransposed) {
- uint16 *dest = (uint16 *)destination.getPixels();
-
- for (uint32 y = 0; y < imageHeight; ++y) {
- uint32 columnIndex = y * imageWidth;
-
- for (uint32 x = 0; x < imageWidth; ++x) {
- dest[columnIndex + x] = buffer[x * imageHeight + y];
- }
- }
- } else {
- memcpy(destination.getPixels(), buffer, imageWidth * imageHeight * _pixelFormat.bytesPerPixel);
- }
-
- // Cleanup
- if (isTGZ) {
- delete[] buffer;
- } else {
- tga.destroy();
- }
-
- // Convert in place to RGB 565 from RGB 555
- destination.convertToInPlace(_pixelFormat);
+ readImageToSurface(fileName, destination, isTransposed);
}
void RenderManager::readImageToSurface(const Common::String &fileName, Graphics::Surface &destination, bool transposed) {
@@ -266,9 +196,8 @@ void RenderManager::readImageToSurface(const Common::String &fileName, Graphics:
uint32 imageHeight;
Image::TGADecoder tga;
uint16 *buffer;
- // All ZVision images are in RGB 555
- Graphics::PixelFormat pixelFormat555 = Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0);
- destination.format = pixelFormat555;
+ // All Z-Vision images are in RGB 555
+ destination.format = _engine->_resourcePixelFormat;
bool isTGZ;
@@ -277,13 +206,17 @@ void RenderManager::readImageToSurface(const Common::String &fileName, Graphics:
isTGZ = true;
// TGZ files have a header and then Bitmap data that is compressed with LZSS
- uint32 decompressedSize = file.readSint32LE();
+ uint32 decompressedSize = file.readSint32LE() / 2;
imageWidth = file.readSint32LE();
imageHeight = file.readSint32LE();
LzssReadStream lzssStream(&file);
buffer = (uint16 *)(new uint16[decompressedSize]);
- lzssStream.read(buffer, decompressedSize);
+ lzssStream.read(buffer, 2 * decompressedSize);
+#ifndef SCUMM_LITTLE_ENDIAN
+ for (uint32 i = 0; i < decompressedSize; ++i)
+ buffer[i] = FROM_LE_16(buffer[i]);
+#endif
} else {
isTGZ = false;
@@ -313,7 +246,7 @@ void RenderManager::readImageToSurface(const Common::String &fileName, Graphics:
// If the destination internal buffer is the same size as what we're copying into it,
// there is no need to free() and re-create
if (imageWidth != destination.w || imageHeight != destination.h) {
- destination.create(imageWidth, imageHeight, pixelFormat555);
+ destination.create(imageWidth, imageHeight, _engine->_resourcePixelFormat);
}
// If transposed, 'un-transpose' the data while copying it to the destination
@@ -329,7 +262,7 @@ void RenderManager::readImageToSurface(const Common::String &fileName, Graphics:
}
}
} else {
- memcpy(destination.getPixels(), buffer, imageWidth * imageHeight * _pixelFormat.bytesPerPixel);
+ memcpy(destination.getPixels(), buffer, imageWidth * imageHeight * destination.format.bytesPerPixel);
}
// Cleanup
@@ -338,9 +271,6 @@ void RenderManager::readImageToSurface(const Common::String &fileName, Graphics:
} else {
tga.destroy();
}
-
- // Convert in place to RGB 565 from RGB 555
- destination.convertToInPlace(_pixelFormat);
}
const Common::Point RenderManager::screenSpaceToImageSpace(const Common::Point &point) {
@@ -354,20 +284,20 @@ const Common::Point RenderManager::screenSpaceToImageSpace(const Common::Point &
}
if (state == RenderTable::PANORAMA) {
- newPoint += (Common::Point(_bkgOff - _screenCenterX, 0));
+ newPoint += (Common::Point(_backgroundOffset - _screenCenterX, 0));
} else if (state == RenderTable::TILT) {
- newPoint += (Common::Point(0, _bkgOff - _screenCenterY));
+ newPoint += (Common::Point(0, _backgroundOffset - _screenCenterY));
}
- if (_bkgWidth)
- newPoint.x %= _bkgWidth;
- if (_bkgHeight)
- newPoint.y %= _bkgHeight;
+ if (_backgroundWidth)
+ newPoint.x %= _backgroundWidth;
+ if (_backgroundHeight)
+ newPoint.y %= _backgroundHeight;
if (newPoint.x < 0)
- newPoint.x += _bkgWidth;
+ newPoint.x += _backgroundWidth;
if (newPoint.y < 0)
- newPoint.y += _bkgHeight;
+ newPoint.y += _backgroundHeight;
return newPoint;
} else {
@@ -380,18 +310,18 @@ RenderTable *RenderManager::getRenderTable() {
}
void RenderManager::setBackgroundImage(const Common::String &fileName) {
- readImageToSurface(fileName, _curBkg);
- _bkgWidth = _curBkg.w;
- _bkgHeight = _curBkg.h;
- _bkgDirtyRect = Common::Rect(_bkgWidth, _bkgHeight);
+ readImageToSurface(fileName, _currentBackgroundImage);
+ _backgroundWidth = _currentBackgroundImage.w;
+ _backgroundHeight = _currentBackgroundImage.h;
+ _backgroundDirtyRect = Common::Rect(_backgroundWidth, _backgroundHeight);
}
void RenderManager::setBackgroundPosition(int offset) {
RenderTable::RenderState state = _renderTable.getRenderState();
if (state == RenderTable::TILT || state == RenderTable::PANORAMA)
- if (_bkgOff != offset)
- _bkgDirtyRect = Common::Rect(_bkgWidth, _bkgHeight);
- _bkgOff = offset;
+ if (_backgroundOffset != offset)
+ _backgroundDirtyRect = Common::Rect(_backgroundWidth, _backgroundHeight);
+ _backgroundOffset = offset;
_engine->getScriptManager()->setStateValue(StateKey_ViewPos, offset);
}
@@ -400,9 +330,9 @@ uint32 RenderManager::getCurrentBackgroundOffset() {
RenderTable::RenderState state = _renderTable.getRenderState();
if (state == RenderTable::PANORAMA) {
- return _bkgOff;
+ return _backgroundOffset;
} else if (state == RenderTable::TILT) {
- return _bkgOff;
+ return _backgroundOffset;
} else {
return 0;
}
@@ -454,10 +384,6 @@ void RenderManager::scaleBuffer(const void *src, void *dst, uint32 srcWidth, uin
}
void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, const Common::Rect &_srcRect , Graphics::Surface &dst, int _x, int _y) {
-
- if (src.format != dst.format)
- return;
-
Common::Rect srcRect = _srcRect;
if (srcRect.isEmpty())
srcRect = Common::Rect(src.w, src.h);
@@ -468,8 +394,10 @@ void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, const Com
if (srcRect.isEmpty() || !srcRect.isValidRect())
return;
+ Graphics::Surface *srcAdapted = src.convertTo(dst.format);
+
// Copy srcRect from src surface to dst surface
- const byte *srcBuffer = (const byte *)src.getBasePtr(srcRect.left, srcRect.top);
+ const byte *srcBuffer = (const byte *)srcAdapted->getBasePtr(srcRect.left, srcRect.top);
int xx = _x;
int yy = _y;
@@ -479,8 +407,11 @@ void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, const Com
if (yy < 0)
yy = 0;
- if (_x >= dst.w || _y >= dst.h)
+ if (_x >= dst.w || _y >= dst.h) {
+ srcAdapted->free();
+ delete srcAdapted;
return;
+ }
byte *dstBuffer = (byte *)dst.getBasePtr(xx, yy);
@@ -488,17 +419,16 @@ void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, const Com
int32 h = srcRect.height();
for (int32 y = 0; y < h; y++) {
- memcpy(dstBuffer, srcBuffer, w * src.format.bytesPerPixel);
- srcBuffer += src.pitch;
+ memcpy(dstBuffer, srcBuffer, w * srcAdapted->format.bytesPerPixel);
+ srcBuffer += srcAdapted->pitch;
dstBuffer += dst.pitch;
}
+
+ srcAdapted->free();
+ delete srcAdapted;
}
void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, const Common::Rect &_srcRect , Graphics::Surface &dst, int _x, int _y, uint32 colorkey) {
-
- if (src.format != dst.format)
- return;
-
Common::Rect srcRect = _srcRect;
if (srcRect.isEmpty())
srcRect = Common::Rect(src.w, src.h);
@@ -509,10 +439,11 @@ void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, const Com
if (srcRect.isEmpty() || !srcRect.isValidRect())
return;
- uint32 _keycolor = colorkey & ((1 << (src.format.bytesPerPixel << 3)) - 1);
+ Graphics::Surface *srcAdapted = src.convertTo(dst.format);
+ uint32 keycolor = colorkey & ((1 << (src.format.bytesPerPixel << 3)) - 1);
// Copy srcRect from src surface to dst surface
- const byte *srcBuffer = (const byte *)src.getBasePtr(srcRect.left, srcRect.top);
+ const byte *srcBuffer = (const byte *)srcAdapted->getBasePtr(srcRect.left, srcRect.top);
int xx = _x;
int yy = _y;
@@ -522,8 +453,11 @@ void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, const Com
if (yy < 0)
yy = 0;
- if (_x >= dst.w || _y >= dst.h)
+ if (_x >= dst.w || _y >= dst.h) {
+ srcAdapted->free();
+ delete srcAdapted;
return;
+ }
byte *dstBuffer = (byte *)dst.getBasePtr(xx, yy);
@@ -531,12 +465,12 @@ void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, const Com
int32 h = srcRect.height();
for (int32 y = 0; y < h; y++) {
- switch (src.format.bytesPerPixel) {
+ switch (srcAdapted->format.bytesPerPixel) {
case 1: {
const uint *srcTemp = (const uint *)srcBuffer;
uint *dstTemp = (uint *)dstBuffer;
for (int32 x = 0; x < w; x++) {
- if (*srcTemp != _keycolor)
+ if (*srcTemp != keycolor)
*dstTemp = *srcTemp;
srcTemp++;
dstTemp++;
@@ -548,7 +482,7 @@ void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, const Com
const uint16 *srcTemp = (const uint16 *)srcBuffer;
uint16 *dstTemp = (uint16 *)dstBuffer;
for (int32 x = 0; x < w; x++) {
- if (*srcTemp != _keycolor)
+ if (*srcTemp != keycolor)
*dstTemp = *srcTemp;
srcTemp++;
dstTemp++;
@@ -560,7 +494,7 @@ void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, const Com
const uint32 *srcTemp = (const uint32 *)srcBuffer;
uint32 *dstTemp = (uint32 *)dstBuffer;
for (int32 x = 0; x < w; x++) {
- if (*srcTemp != _keycolor)
+ if (*srcTemp != keycolor)
*dstTemp = *srcTemp;
srcTemp++;
dstTemp++;
@@ -571,60 +505,32 @@ void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, const Com
default:
break;
}
- srcBuffer += src.pitch;
+ srcBuffer += srcAdapted->pitch;
dstBuffer += dst.pitch;
}
-}
-void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, Graphics::Surface &dst, int x, int y) {
- Common::Rect empt;
- blitSurfaceToSurface(src, empt, dst, x, y);
+ srcAdapted->free();
+ delete srcAdapted;
}
-void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, Graphics::Surface &dst, int x, int y, uint32 colorkey) {
+void RenderManager::blitSurfaceToBkg(const Graphics::Surface &src, int x, int y, int32 colorkey) {
Common::Rect empt;
- blitSurfaceToSurface(src, empt, dst, x, y, colorkey);
-}
-
-void RenderManager::blitSurfaceToBkg(const Graphics::Surface &src, int x, int y) {
- Common::Rect empt;
- blitSurfaceToSurface(src, empt, _curBkg, x, y);
- Common::Rect dirty(src.w, src.h);
- dirty.translate(x, y);
- if (_bkgDirtyRect.isEmpty())
- _bkgDirtyRect = dirty;
+ if (colorkey >= 0)
+ blitSurfaceToSurface(src, empt, _currentBackgroundImage, x, y, colorkey);
else
- _bkgDirtyRect.extend(dirty);
-}
-
-void RenderManager::blitSurfaceToBkg(const Graphics::Surface &src, int x, int y, uint32 colorkey) {
- Common::Rect empt;
- blitSurfaceToSurface(src, empt, _curBkg, x, y, colorkey);
+ blitSurfaceToSurface(src, empt, _currentBackgroundImage, x, y);
Common::Rect dirty(src.w, src.h);
dirty.translate(x, y);
- if (_bkgDirtyRect.isEmpty())
- _bkgDirtyRect = dirty;
+ if (_backgroundDirtyRect.isEmpty())
+ _backgroundDirtyRect = dirty;
else
- _bkgDirtyRect.extend(dirty);
-}
-
-void RenderManager::blitSurfaceToBkgScaled(const Graphics::Surface &src, const Common::Rect &_dstRect) {
- if (src.w == _dstRect.width() && src.h == _dstRect.height())
- blitSurfaceToBkg(src, _dstRect.left, _dstRect.top);
- else {
- Graphics::Surface *tmp = new Graphics::Surface;
- tmp->create(_dstRect.width(), _dstRect.height(), src.format);
- scaleBuffer(src.getPixels(), tmp->getPixels(), src.w, src.h, src.format.bytesPerPixel, _dstRect.width(), _dstRect.height());
- blitSurfaceToBkg(*tmp, _dstRect.left, _dstRect.top);
- tmp->free();
- delete tmp;
- }
+ _backgroundDirtyRect.extend(dirty);
}
-void RenderManager::blitSurfaceToBkgScaled(const Graphics::Surface &src, const Common::Rect &_dstRect, uint32 colorkey) {
- if (src.w == _dstRect.width() && src.h == _dstRect.height())
+void RenderManager::blitSurfaceToBkgScaled(const Graphics::Surface &src, const Common::Rect &_dstRect, int32 colorkey) {
+ if (src.w == _dstRect.width() && src.h == _dstRect.height()) {
blitSurfaceToBkg(src, _dstRect.left, _dstRect.top, colorkey);
- else {
+ } else {
Graphics::Surface *tmp = new Graphics::Surface;
tmp->create(_dstRect.width(), _dstRect.height(), src.format);
scaleBuffer(src.getPixels(), tmp->getPixels(), src.w, src.h, src.format.bytesPerPixel, _dstRect.width(), _dstRect.height());
@@ -634,160 +540,163 @@ void RenderManager::blitSurfaceToBkgScaled(const Graphics::Surface &src, const C
}
}
-void RenderManager::blitSurfaceToMenu(const Graphics::Surface &src, int x, int y) {
+void RenderManager::blitSurfaceToMenu(const Graphics::Surface &src, int x, int y, int32 colorkey) {
Common::Rect empt;
- blitSurfaceToSurface(src, empt, _menuWnd, x, y);
- Common::Rect dirty(src.w, src.h);
- dirty.translate(x, y);
- if (_menuWndDirtyRect.isEmpty())
- _menuWndDirtyRect = dirty;
+ if (colorkey >= 0)
+ blitSurfaceToSurface(src, empt, _menuSurface, x, y, colorkey);
else
- _menuWndDirtyRect.extend(dirty);
-}
-
-void RenderManager::blitSurfaceToMenu(const Graphics::Surface &src, int x, int y, uint32 colorkey) {
- Common::Rect empt;
- blitSurfaceToSurface(src, empt, _menuWnd, x, y, colorkey);
+ blitSurfaceToSurface(src, empt, _menuSurface, x, y);
Common::Rect dirty(src.w, src.h);
dirty.translate(x, y);
- if (_menuWndDirtyRect.isEmpty())
- _menuWndDirtyRect = dirty;
+ if (_menuSurfaceDirtyRect.isEmpty())
+ _menuSurfaceDirtyRect = dirty;
else
- _menuWndDirtyRect.extend(dirty);
+ _menuSurfaceDirtyRect.extend(dirty);
}
Graphics::Surface *RenderManager::getBkgRect(Common::Rect &rect) {
Common::Rect dst = rect;
- dst.clip(_bkgWidth, _bkgHeight);
+ dst.clip(_backgroundWidth, _backgroundHeight);
if (dst.isEmpty() || !dst.isValidRect())
return NULL;
Graphics::Surface *srf = new Graphics::Surface;
- srf->create(dst.width(), dst.height(), _curBkg.format);
+ srf->create(dst.width(), dst.height(), _currentBackgroundImage.format);
- srf->copyRectToSurface(_curBkg, 0, 0, Common::Rect(dst));
+ srf->copyRectToSurface(_currentBackgroundImage, 0, 0, Common::Rect(dst));
return srf;
}
-Graphics::Surface *RenderManager::loadImage(Common::String &file) {
+Graphics::Surface *RenderManager::loadImage(Common::String file) {
Graphics::Surface *tmp = new Graphics::Surface;
readImageToSurface(file, *tmp);
return tmp;
}
-Graphics::Surface *RenderManager::loadImage(const char *file) {
- Common::String str = Common::String(file);
- return loadImage(str);
-}
-
-Graphics::Surface *RenderManager::loadImage(Common::String &file, bool transposed) {
+Graphics::Surface *RenderManager::loadImage(Common::String file, bool transposed) {
Graphics::Surface *tmp = new Graphics::Surface;
readImageToSurface(file, *tmp, transposed);
return tmp;
}
-Graphics::Surface *RenderManager::loadImage(const char *file, bool transposed) {
- Common::String str = Common::String(file);
- return loadImage(str, transposed);
-}
-
-void RenderManager::prepareBkg() {
- _bkgDirtyRect.clip(_bkgWidth, _bkgHeight);
+void RenderManager::prepareBackground() {
+ _backgroundDirtyRect.clip(_backgroundWidth, _backgroundHeight);
RenderTable::RenderState state = _renderTable.getRenderState();
if (state == RenderTable::PANORAMA) {
- Common::Rect viewPort(_wrkWidth, _wrkHeight);
- viewPort.translate(-(_screenCenterX - _bkgOff), 0);
- Common::Rect drawRect = _bkgDirtyRect;
+ // Calculate the visible portion of the background
+ Common::Rect viewPort(_workingWindow.width(), _workingWindow.height());
+ viewPort.translate(-(_screenCenterX - _backgroundOffset), 0);
+ Common::Rect drawRect = _backgroundDirtyRect;
drawRect.clip(viewPort);
- if (!drawRect.isEmpty())
- blitSurfaceToSurface(_curBkg, drawRect, _wrkWnd, _screenCenterX - _bkgOff + drawRect.left, drawRect.top);
+ // Render the visible portion
+ if (!drawRect.isEmpty()) {
+ blitSurfaceToSurface(_currentBackgroundImage, drawRect, _backgroundSurface, _screenCenterX - _backgroundOffset + drawRect.left, drawRect.top);
+ }
- _wrkWndDirtyRect = _bkgDirtyRect;
- _wrkWndDirtyRect.translate(_screenCenterX - _bkgOff, 0);
+ // Mark the dirty portion of the surface
+ _backgroundSurfaceDirtyRect = _backgroundDirtyRect;
+ _backgroundSurfaceDirtyRect.translate(_screenCenterX - _backgroundOffset, 0);
- if (_bkgOff < _screenCenterX) {
- viewPort.moveTo(-(_screenCenterX - (_bkgOff + _bkgWidth)), 0);
- drawRect = _bkgDirtyRect;
+ // Panorama mode allows the user to spin in circles. Therefore, we need to render
+ // the portion of the image that wrapped to the other side of the screen
+ if (_backgroundOffset < _screenCenterX) {
+ viewPort.moveTo(-(_screenCenterX - (_backgroundOffset + _backgroundWidth)), 0);
+ drawRect = _backgroundDirtyRect;
drawRect.clip(viewPort);
if (!drawRect.isEmpty())
- blitSurfaceToSurface(_curBkg, drawRect, _wrkWnd, _screenCenterX - (_bkgOff + _bkgWidth) + drawRect.left, drawRect.top);
+ blitSurfaceToSurface(_currentBackgroundImage, drawRect, _backgroundSurface, _screenCenterX - (_backgroundOffset + _backgroundWidth) + drawRect.left, drawRect.top);
- Common::Rect tmp = _bkgDirtyRect;
- tmp.translate(_screenCenterX - (_bkgOff + _bkgWidth), 0);
+ Common::Rect tmp = _backgroundDirtyRect;
+ tmp.translate(_screenCenterX - (_backgroundOffset + _backgroundWidth), 0);
if (!tmp.isEmpty())
- _wrkWndDirtyRect.extend(tmp);
+ _backgroundSurfaceDirtyRect.extend(tmp);
- } else if (_bkgWidth - _bkgOff < _screenCenterX) {
- viewPort.moveTo(-(_screenCenterX + _bkgWidth - _bkgOff), 0);
- drawRect = _bkgDirtyRect;
+ } else if (_backgroundWidth - _backgroundOffset < _screenCenterX) {
+ viewPort.moveTo(-(_screenCenterX + _backgroundWidth - _backgroundOffset), 0);
+ drawRect = _backgroundDirtyRect;
drawRect.clip(viewPort);
if (!drawRect.isEmpty())
- blitSurfaceToSurface(_curBkg, drawRect, _wrkWnd, _screenCenterX + _bkgWidth - _bkgOff + drawRect.left, drawRect.top);
+ blitSurfaceToSurface(_currentBackgroundImage, drawRect, _backgroundSurface, _screenCenterX + _backgroundWidth - _backgroundOffset + drawRect.left, drawRect.top);
- Common::Rect tmp = _bkgDirtyRect;
- tmp.translate(_screenCenterX + _bkgWidth - _bkgOff, 0);
+ Common::Rect tmp = _backgroundDirtyRect;
+ tmp.translate(_screenCenterX + _backgroundWidth - _backgroundOffset, 0);
if (!tmp.isEmpty())
- _wrkWndDirtyRect.extend(tmp);
+ _backgroundSurfaceDirtyRect.extend(tmp);
}
} else if (state == RenderTable::TILT) {
- Common::Rect viewPort(_wrkWidth, _wrkHeight);
- viewPort.translate(0, -(_screenCenterY - _bkgOff));
- Common::Rect drawRect = _bkgDirtyRect;
+ // Tilt doesn't allow wrapping, so we just do a simple clip
+ Common::Rect viewPort(_workingWindow.width(), _workingWindow.height());
+ viewPort.translate(0, -(_screenCenterY - _backgroundOffset));
+ Common::Rect drawRect = _backgroundDirtyRect;
drawRect.clip(viewPort);
if (!drawRect.isEmpty())
- blitSurfaceToSurface(_curBkg, drawRect, _wrkWnd, drawRect.left, _screenCenterY - _bkgOff + drawRect.top);
+ blitSurfaceToSurface(_currentBackgroundImage, drawRect, _backgroundSurface, drawRect.left, _screenCenterY - _backgroundOffset + drawRect.top);
- _wrkWndDirtyRect = _bkgDirtyRect;
- _wrkWndDirtyRect.translate(0, _screenCenterY - _bkgOff);
+ // Mark the dirty portion of the surface
+ _backgroundSurfaceDirtyRect = _backgroundDirtyRect;
+ _backgroundSurfaceDirtyRect.translate(0, _screenCenterY - _backgroundOffset);
} else {
- if (!_bkgDirtyRect.isEmpty())
- blitSurfaceToSurface(_curBkg, _bkgDirtyRect, _wrkWnd, _bkgDirtyRect.left, _bkgDirtyRect.top);
- _wrkWndDirtyRect = _bkgDirtyRect;
+ if (!_backgroundDirtyRect.isEmpty())
+ blitSurfaceToSurface(_currentBackgroundImage, _backgroundDirtyRect, _backgroundSurface, _backgroundDirtyRect.left, _backgroundDirtyRect.top);
+ _backgroundSurfaceDirtyRect = _backgroundDirtyRect;
}
- _bkgDirtyRect = Common::Rect();
+ // Clear the dirty rect since everything is clean now
+ _backgroundDirtyRect = Common::Rect();
- _wrkWndDirtyRect.clip(_wrkWidth, _wrkHeight);
+ _backgroundSurfaceDirtyRect.clip(_workingWindow.width(), _workingWindow.height());
}
void RenderManager::clearMenuSurface() {
- _menuWndDirtyRect = Common::Rect(0, 0, _menuWnd.w, _menuWnd.h);
- _menuWnd.fillRect(_menuWndDirtyRect, 0);
+ _menuSurfaceDirtyRect = Common::Rect(0, 0, _menuSurface.w, _menuSurface.h);
+ _menuSurface.fillRect(_menuSurfaceDirtyRect, 0);
}
void RenderManager::clearMenuSurface(const Common::Rect &r) {
- if (_menuWndDirtyRect.isEmpty())
- _menuWndDirtyRect = r;
+ if (_menuSurfaceDirtyRect.isEmpty())
+ _menuSurfaceDirtyRect = r;
else
- _menuWndDirtyRect.extend(r);
- _menuWnd.fillRect(r, 0);
+ _menuSurfaceDirtyRect.extend(r);
+ _menuSurface.fillRect(r, 0);
}
void RenderManager::renderMenuToScreen() {
- if (!_menuWndDirtyRect.isEmpty()) {
- _menuWndDirtyRect.clip(Common::Rect(_menuWnd.w, _menuWnd.h));
- if (!_menuWndDirtyRect.isEmpty())
- _system->copyRectToScreen(_menuWnd.getBasePtr(_menuWndDirtyRect.left, _menuWndDirtyRect.top), _menuWnd.pitch,
- _menuWndDirtyRect.left + _menuWndRect.left,
- _menuWndDirtyRect.top + _menuWndRect.top,
- _menuWndDirtyRect.width(),
- _menuWndDirtyRect.height());
- _menuWndDirtyRect = Common::Rect();
+ if (!_menuSurfaceDirtyRect.isEmpty()) {
+ _menuSurfaceDirtyRect.clip(Common::Rect(_menuSurface.w, _menuSurface.h));
+ if (!_menuSurfaceDirtyRect.isEmpty()) {
+ Common::Rect rect(
+ _menuSurfaceDirtyRect.left + _menuArea.left,
+ _menuSurfaceDirtyRect.top + _menuArea.top,
+ _menuSurfaceDirtyRect.left + _menuArea.left + _menuSurfaceDirtyRect.width(),
+ _menuSurfaceDirtyRect.top + _menuArea.top + _menuSurfaceDirtyRect.height()
+ );
+ copyToScreen(_menuSurface, rect, _menuSurfaceDirtyRect.left, _menuSurfaceDirtyRect.top);
+ }
+ _menuSurfaceDirtyRect = Common::Rect();
}
}
+void RenderManager::initSubArea(uint32 windowWidth, uint32 windowHeight, const Common::Rect workingWindow) {
+ _workingWindow = workingWindow;
+
+ _subtitleSurface.free();
+
+ _subtitleSurface.create(windowWidth, windowHeight - workingWindow.bottom, _pixelFormat);
+ _subtitleArea = Common::Rect(0, workingWindow.bottom, windowWidth, windowHeight);
+}
+
uint16 RenderManager::createSubArea(const Common::Rect &area) {
_subid++;
- oneSub sub;
+ OneSubtitle sub;
sub.redraw = false;
sub.timer = -1;
sub.todelete = false;
@@ -799,18 +708,9 @@ uint16 RenderManager::createSubArea(const Common::Rect &area) {
}
uint16 RenderManager::createSubArea() {
- _subid++;
-
- oneSub sub;
- sub.redraw = false;
- sub.timer = -1;
- sub.todelete = false;
- sub.r = Common::Rect(_subWndRect.left, _subWndRect.top, _subWndRect.right, _subWndRect.bottom);
- sub.r.translate(-_workingWindow.left, -_workingWindow.top);
-
- _subsList[_subid] = sub;
-
- return _subid;
+ Common::Rect r(_subtitleArea.left, _subtitleArea.top, _subtitleArea.right, _subtitleArea.bottom);
+ r.translate(-_workingWindow.left, -_workingWindow.top);
+ return createSubArea(r);
}
void RenderManager::deleteSubArea(uint16 id) {
@@ -825,7 +725,7 @@ void RenderManager::deleteSubArea(uint16 id, int16 delay) {
void RenderManager::updateSubArea(uint16 id, const Common::String &txt) {
if (_subsList.contains(id)) {
- oneSub *sub = &_subsList[id];
+ OneSubtitle *sub = &_subsList[id];
sub->txt = txt;
sub->redraw = true;
}
@@ -833,7 +733,7 @@ void RenderManager::updateSubArea(uint16 id, const Common::String &txt) {
void RenderManager::processSubs(uint16 deltatime) {
bool redraw = false;
- for (subMap::iterator it = _subsList.begin(); it != _subsList.end(); it++) {
+ for (SubtitleMap::iterator it = _subsList.begin(); it != _subsList.end(); it++) {
if (it->_value.timer != -1) {
it->_value.timer -= deltatime;
if (it->_value.timer <= 0)
@@ -848,39 +748,41 @@ void RenderManager::processSubs(uint16 deltatime) {
}
if (redraw) {
- _subWnd.fillRect(Common::Rect(_subWnd.w, _subWnd.h), 0);
+ _subtitleSurface.fillRect(Common::Rect(_subtitleSurface.w, _subtitleSurface.h), 0);
- for (subMap::iterator it = _subsList.begin(); it != _subsList.end(); it++) {
- oneSub *sub = &it->_value;
+ for (SubtitleMap::iterator it = _subsList.begin(); it != _subsList.end(); it++) {
+ OneSubtitle *sub = &it->_value;
if (sub->txt.size()) {
- Graphics::Surface *rndr = new Graphics::Surface();
- rndr->create(sub->r.width(), sub->r.height(), _pixelFormat);
- _engine->getTextRenderer()->drawTxtInOneLine(sub->txt, *rndr);
- blitSurfaceToSurface(*rndr, _subWnd, sub->r.left - _subWndRect.left + _workingWindow.left, sub->r.top - _subWndRect.top + _workingWindow.top);
- rndr->free();
- delete rndr;
+ Graphics::Surface subtitleSurface;
+ subtitleSurface.create(sub->r.width(), sub->r.height(), _engine->_resourcePixelFormat);
+ _engine->getTextRenderer()->drawTextWithWordWrapping(sub->txt, subtitleSurface);
+ Common::Rect empty;
+ blitSurfaceToSurface(subtitleSurface, empty, _subtitleSurface, sub->r.left - _subtitleArea.left + _workingWindow.left, sub->r.top - _subtitleArea.top + _workingWindow.top);
+ subtitleSurface.free();
}
sub->redraw = false;
}
- _system->copyRectToScreen(_subWnd.getPixels(), _subWnd.pitch,
- _subWndRect.left,
- _subWndRect.top,
- _subWnd.w,
- _subWnd.h);
+ Common::Rect rect(
+ _subtitleArea.left,
+ _subtitleArea.top,
+ _subtitleArea.left + _subtitleSurface.w,
+ _subtitleArea.top + _subtitleSurface.h
+ );
+ copyToScreen(_subtitleSurface, rect, 0, 0);
}
}
Common::Point RenderManager::getBkgSize() {
- return Common::Point(_bkgWidth, _bkgHeight);
+ return Common::Point(_backgroundWidth, _backgroundHeight);
}
-void RenderManager::addEffect(Effect *_effect) {
+void RenderManager::addEffect(GraphicsEffect *_effect) {
_effects.push_back(_effect);
}
void RenderManager::deleteEffect(uint32 ID) {
- for (effectsList::iterator it = _effects.begin(); it != _effects.end(); it++) {
+ for (EffectsList::iterator it = _effects.begin(); it != _effects.end(); it++) {
if ((*it)->getKey() == ID) {
delete *it;
it = _effects.erase(it);
@@ -888,54 +790,54 @@ void RenderManager::deleteEffect(uint32 ID) {
}
}
-Common::Rect RenderManager::bkgRectToScreen(const Common::Rect &src) {
+Common::Rect RenderManager::transformBackgroundSpaceRectToScreenSpace(const Common::Rect &src) {
Common::Rect tmp = src;
RenderTable::RenderState state = _renderTable.getRenderState();
if (state == RenderTable::PANORAMA) {
- if (_bkgOff < _screenCenterX) {
- Common::Rect rScreen(_screenCenterX + _bkgOff, _wrkHeight);
- Common::Rect lScreen(_wrkWidth - rScreen.width(), _wrkHeight);
- lScreen.translate(_bkgWidth - lScreen.width(), 0);
+ if (_backgroundOffset < _screenCenterX) {
+ Common::Rect rScreen(_screenCenterX + _backgroundOffset, _workingWindow.height());
+ Common::Rect lScreen(_workingWindow.width() - rScreen.width(), _workingWindow.height());
+ lScreen.translate(_backgroundWidth - lScreen.width(), 0);
lScreen.clip(src);
rScreen.clip(src);
if (rScreen.width() < lScreen.width()) {
- tmp.translate(_screenCenterX - _bkgOff - _bkgWidth, 0);
+ tmp.translate(_screenCenterX - _backgroundOffset - _backgroundWidth, 0);
} else {
- tmp.translate(_screenCenterX - _bkgOff, 0);
+ tmp.translate(_screenCenterX - _backgroundOffset, 0);
}
- } else if (_bkgWidth - _bkgOff < _screenCenterX) {
- Common::Rect rScreen(_screenCenterX - (_bkgWidth - _bkgOff), _wrkHeight);
- Common::Rect lScreen(_wrkWidth - rScreen.width(), _wrkHeight);
- lScreen.translate(_bkgWidth - lScreen.width(), 0);
+ } else if (_backgroundWidth - _backgroundOffset < _screenCenterX) {
+ Common::Rect rScreen(_screenCenterX - (_backgroundWidth - _backgroundOffset), _workingWindow.height());
+ Common::Rect lScreen(_workingWindow.width() - rScreen.width(), _workingWindow.height());
+ lScreen.translate(_backgroundWidth - lScreen.width(), 0);
lScreen.clip(src);
rScreen.clip(src);
if (lScreen.width() < rScreen.width()) {
- tmp.translate(_screenCenterX + (_bkgWidth - _bkgOff), 0);
+ tmp.translate(_screenCenterX + (_backgroundWidth - _backgroundOffset), 0);
} else {
- tmp.translate(_screenCenterX - _bkgOff, 0);
+ tmp.translate(_screenCenterX - _backgroundOffset, 0);
}
} else {
- tmp.translate(_screenCenterX - _bkgOff, 0);
+ tmp.translate(_screenCenterX - _backgroundOffset, 0);
}
} else if (state == RenderTable::TILT) {
- tmp.translate(0, (_screenCenterY - _bkgOff));
+ tmp.translate(0, (_screenCenterY - _backgroundOffset));
}
return tmp;
}
EffectMap *RenderManager::makeEffectMap(const Common::Point &xy, int16 depth, const Common::Rect &rect, int8 *_minComp, int8 *_maxComp) {
- Common::Rect bkgRect(_bkgWidth, _bkgHeight);
+ Common::Rect bkgRect(_backgroundWidth, _backgroundHeight);
if (!bkgRect.contains(xy))
return NULL;
if (!bkgRect.intersects(rect))
return NULL;
- uint16 color = *(uint16 *)_curBkg.getBasePtr(xy.x, xy.y);
+ uint16 color = *(uint16 *)_currentBackgroundImage.getBasePtr(xy.x, xy.y);
uint8 stC1, stC2, stC3;
- _curBkg.format.colorToRGB(color, stC1, stC2, stC3);
+ _currentBackgroundImage.format.colorToRGB(color, stC1, stC2, stC3);
EffectMap *newMap = new EffectMap;
EffectMapUnit unit;
@@ -953,11 +855,11 @@ EffectMap *RenderManager::makeEffectMap(const Common::Point &xy, int16 depth, co
uint8 depth8 = depth << 3;
for (int16 j = 0; j < h; j++) {
- uint16 *pix = (uint16 *)_curBkg.getBasePtr(rect.left, rect.top + j);
+ uint16 *pix = (uint16 *)_currentBackgroundImage.getBasePtr(rect.left, rect.top + j);
for (int16 i = 0; i < w; i++) {
uint16 curClr = pix[i];
uint8 cC1, cC2, cC3;
- _curBkg.format.colorToRGB(curClr, cC1, cC2, cC3);
+ _currentBackgroundImage.format.colorToRGB(curClr, cC1, cC2, cC3);
bool use = false;
@@ -1055,12 +957,261 @@ EffectMap *RenderManager::makeEffectMap(const Graphics::Surface &surf, uint16 tr
}
void RenderManager::markDirty() {
- _bkgDirtyRect = Common::Rect(_bkgWidth, _bkgHeight);
+ _backgroundDirtyRect = Common::Rect(_backgroundWidth, _backgroundHeight);
}
+#if 0
void RenderManager::bkgFill(uint8 r, uint8 g, uint8 b) {
- _curBkg.fillRect(Common::Rect(_curBkg.w, _curBkg.h), _curBkg.format.RGBToColor(r, g, b));
+ _currentBackgroundImage.fillRect(Common::Rect(_currentBackgroundImage.w, _currentBackgroundImage.h), _currentBackgroundImage.format.RGBToColor(r, g, b));
markDirty();
}
+#endif
+
+void RenderManager::timedMessage(const Common::String &str, uint16 milsecs) {
+ uint16 msgid = createSubArea();
+ updateSubArea(msgid, str);
+ deleteSubArea(msgid, milsecs);
+}
+
+bool RenderManager::askQuestion(const Common::String &str) {
+ Graphics::Surface textSurface;
+ textSurface.create(_subtitleArea.width(), _subtitleArea.height(), _engine->_resourcePixelFormat);
+ _engine->getTextRenderer()->drawTextWithWordWrapping(str, textSurface);
+ copyToScreen(textSurface, _subtitleArea, 0, 0);
+
+ _engine->stopClock();
+
+ int result = 0;
+
+ while (result == 0) {
+ Common::Event evnt;
+ while (_engine->getEventManager()->pollEvent(evnt)) {
+ if (evnt.type == Common::EVENT_KEYDOWN) {
+ // English: yes/no
+ // German: ja/nein
+ // Spanish: si/no
+ // French Nemesis: F4/any other key
+ // French ZGI: oui/non
+ switch (evnt.kbd.keycode) {
+ case Common::KEYCODE_y:
+ if (_engine->getLanguage() == Common::EN_ANY)
+ result = 2;
+ break;
+ case Common::KEYCODE_j:
+ if (_engine->getLanguage() == Common::DE_DEU)
+ result = 2;
+ break;
+ case Common::KEYCODE_s:
+ if (_engine->getLanguage() == Common::ES_ESP)
+ result = 2;
+ break;
+ case Common::KEYCODE_o:
+ if (_engine->getLanguage() == Common::FR_FRA && _engine->getGameId() == GID_GRANDINQUISITOR)
+ result = 2;
+ break;
+ case Common::KEYCODE_F4:
+ if (_engine->getLanguage() == Common::FR_FRA && _engine->getGameId() == GID_NEMESIS)
+ result = 2;
+ break;
+ case Common::KEYCODE_n:
+ result = 1;
+ break;
+ default:
+ if (_engine->getLanguage() == Common::FR_FRA && _engine->getGameId() == GID_NEMESIS)
+ result = 1;
+ break;
+ }
+ }
+ }
+ _system->updateScreen();
+ if (_doubleFPS)
+ _system->delayMillis(33);
+ else
+ _system->delayMillis(66);
+ }
+
+ // Draw over the text in order to clear it
+ textSurface.fillRect(Common::Rect(_subtitleArea.width(), _subtitleArea.height()), 0);
+ copyToScreen(textSurface, _subtitleArea, 0, 0);
+
+ // Free the surface
+ textSurface.free();
+
+ _engine->startClock();
+ return result == 2;
+}
+
+void RenderManager::delayedMessage(const Common::String &str, uint16 milsecs) {
+ uint16 msgid = createSubArea();
+ updateSubArea(msgid, str);
+ processSubs(0);
+ renderSceneToScreen();
+ _engine->stopClock();
+
+ uint32 stopTime = _system->getMillis() + milsecs;
+ while (_system->getMillis() < stopTime) {
+ Common::Event evnt;
+ while (_engine->getEventManager()->pollEvent(evnt)) {
+ if (evnt.type == Common::EVENT_KEYDOWN &&
+ (evnt.kbd.keycode == Common::KEYCODE_SPACE ||
+ evnt.kbd.keycode == Common::KEYCODE_RETURN ||
+ evnt.kbd.keycode == Common::KEYCODE_ESCAPE))
+ break;
+ }
+ _system->updateScreen();
+ if (_doubleFPS)
+ _system->delayMillis(33);
+ else
+ _system->delayMillis(66);
+ }
+ deleteSubArea(msgid);
+ _engine->startClock();
+}
+
+void RenderManager::showDebugMsg(const Common::String &msg, int16 delay) {
+ uint16 msgid = createSubArea();
+ updateSubArea(msgid, msg);
+ deleteSubArea(msgid, delay);
+}
+
+void RenderManager::updateRotation() {
+ int16 _velocity = _engine->getMouseVelocity() + _engine->getKeyboardVelocity();
+ ScriptManager *scriptManager = _engine->getScriptManager();
+
+ if (_doubleFPS)
+ _velocity /= 2;
+
+ if (_velocity) {
+ RenderTable::RenderState renderState = _renderTable.getRenderState();
+ if (renderState == RenderTable::PANORAMA) {
+ int16 startPosition = scriptManager->getStateValue(StateKey_ViewPos);
+
+ int16 newPosition = startPosition + (_renderTable.getPanoramaReverse() ? -_velocity : _velocity);
+
+ int16 zeroPoint = _renderTable.getPanoramaZeroPoint();
+ if (startPosition >= zeroPoint && newPosition < zeroPoint)
+ scriptManager->setStateValue(StateKey_Rounds, scriptManager->getStateValue(StateKey_Rounds) - 1);
+ if (startPosition <= zeroPoint && newPosition > zeroPoint)
+ scriptManager->setStateValue(StateKey_Rounds, scriptManager->getStateValue(StateKey_Rounds) + 1);
+
+ int16 screenWidth = getBkgSize().x;
+ if (screenWidth)
+ newPosition %= screenWidth;
+
+ if (newPosition < 0)
+ newPosition += screenWidth;
+
+ setBackgroundPosition(newPosition);
+ } else if (renderState == RenderTable::TILT) {
+ int16 startPosition = scriptManager->getStateValue(StateKey_ViewPos);
+
+ int16 newPosition = startPosition + _velocity;
+
+ int16 screenHeight = getBkgSize().y;
+ int16 tiltGap = (int16)_renderTable.getTiltGap();
+
+ if (newPosition >= (screenHeight - tiltGap))
+ newPosition = screenHeight - tiltGap;
+ if (newPosition <= tiltGap)
+ newPosition = tiltGap;
+
+ setBackgroundPosition(newPosition);
+ }
+ }
+}
+
+void RenderManager::checkBorders() {
+ RenderTable::RenderState renderState = _renderTable.getRenderState();
+ if (renderState == RenderTable::PANORAMA) {
+ int16 startPosition = _engine->getScriptManager()->getStateValue(StateKey_ViewPos);
+
+ int16 newPosition = startPosition;
+
+ int16 screenWidth = getBkgSize().x;
+
+ if (screenWidth)
+ newPosition %= screenWidth;
+
+ if (newPosition < 0)
+ newPosition += screenWidth;
+
+ if (startPosition != newPosition)
+ setBackgroundPosition(newPosition);
+ } else if (renderState == RenderTable::TILT) {
+ int16 startPosition = _engine->getScriptManager()->getStateValue(StateKey_ViewPos);
+
+ int16 newPosition = startPosition;
+
+ int16 screenHeight = getBkgSize().y;
+ int16 tiltGap = (int16)_renderTable.getTiltGap();
+
+ if (newPosition >= (screenHeight - tiltGap))
+ newPosition = screenHeight - tiltGap;
+ if (newPosition <= tiltGap)
+ newPosition = tiltGap;
+
+ if (startPosition != newPosition)
+ setBackgroundPosition(newPosition);
+ }
+}
+
+void RenderManager::rotateTo(int16 _toPos, int16 _time) {
+ if (_renderTable.getRenderState() != RenderTable::PANORAMA)
+ return;
+
+ if (_time == 0)
+ _time = 1;
+
+ int32 maxX = getBkgSize().x;
+ int32 curX = getCurrentBackgroundOffset();
+ int32 dx = 0;
+
+ if (curX == _toPos)
+ return;
+
+ if (curX > _toPos) {
+ if (curX - _toPos > maxX / 2)
+ dx = (_toPos + (maxX - curX)) / _time;
+ else
+ dx = -(curX - _toPos) / _time;
+ } else {
+ if (_toPos - curX > maxX / 2)
+ dx = -((maxX - _toPos) + curX) / _time;
+ else
+ dx = (_toPos - curX) / _time;
+ }
+
+ _engine->stopClock();
+
+ for (int16 i = 0; i <= _time; i++) {
+ if (i == _time)
+ curX = _toPos;
+ else
+ curX += dx;
+
+ if (curX < 0)
+ curX = maxX - curX;
+ else if (curX >= maxX)
+ curX %= maxX;
+
+ setBackgroundPosition(curX);
+
+ prepareBackground();
+ renderSceneToScreen();
+
+ _system->updateScreen();
+
+ _system->delayMillis(500 / _time);
+ }
+
+ _engine->startClock();
+}
+
+void RenderManager::upscaleRect(Common::Rect &rect) {
+ rect.top = rect.top * HIRES_WINDOW_HEIGHT / WINDOW_HEIGHT;
+ rect.left = rect.left * HIRES_WINDOW_WIDTH / WINDOW_WIDTH;
+ rect.bottom = rect.bottom * HIRES_WINDOW_HEIGHT / WINDOW_HEIGHT;
+ rect.right = rect.right * HIRES_WINDOW_WIDTH / WINDOW_WIDTH;
+}
} // End of namespace ZVision
diff --git a/engines/zvision/graphics/render_manager.h b/engines/zvision/graphics/render_manager.h
index 879a8643ce..33d8a88e78 100644
--- a/engines/zvision/graphics/render_manager.h
+++ b/engines/zvision/graphics/render_manager.h
@@ -24,14 +24,14 @@
#define ZVISION_RENDER_MANAGER_H
#include "zvision/graphics/render_table.h"
-#include "zvision/graphics/truetype_font.h"
+#include "zvision/text/truetype_font.h"
#include "common/rect.h"
#include "common/hashmap.h"
#include "graphics/surface.h"
-#include "effect.h"
+#include "graphics_effect.h"
class OSystem;
@@ -48,11 +48,11 @@ namespace ZVision {
class RenderManager {
public:
- RenderManager(ZVision *engine, uint32 windowWidth, uint32 windowHeight, const Common::Rect workingWindow, const Graphics::PixelFormat pixelFormat);
+ RenderManager(ZVision *engine, uint32 windowWidth, uint32 windowHeight, const Common::Rect workingWindow, const Graphics::PixelFormat pixelFormat, bool doubleFPS);
~RenderManager();
private:
- struct oneSub {
+ struct OneSubtitle {
Common::Rect r;
Common::String txt;
int16 timer;
@@ -60,87 +60,89 @@ private:
bool redraw;
};
- typedef Common::HashMap<uint16, oneSub> subMap;
- typedef Common::List<Effect *> effectsList;
+ typedef Common::HashMap<uint16, OneSubtitle> SubtitleMap;
+ typedef Common::List<GraphicsEffect *> EffectsList;
private:
ZVision *_engine;
OSystem *_system;
const Graphics::PixelFormat _pixelFormat;
- // A buffer for blitting background image to working window
- Graphics::Surface _wrkWnd;
+ /**
+ * A Rectangle centered inside the actual window. All in-game coordinates
+ * are given in this coordinate space. Also, all images are clipped to the
+ * edges of this Rectangle
+ */
+ Common::Rect _workingWindow;
+
+ // Center of the screen in the x direction
+ const int _screenCenterX;
+ // Center of the screen in the y direction
+ const int _screenCenterY;
- Common::Rect _wrkWndDirtyRect;
+ /** A buffer for background image that's being used to create the background */
+ Graphics::Surface _currentBackgroundImage;
+ Common::Rect _backgroundDirtyRect;
- // A buffer for mutate image by tilt or panorama renderers
- Graphics::Surface _outWnd;
+ /**
+ * The x1 or y1 offset of the subRectangle of the background that is currently displayed on the screen
+ * It will be x1 if PANORAMA, or y1 if TILT
+ */
+ int16 _backgroundOffset;
+ /** The width of the current background image */
+ uint16 _backgroundWidth;
+ /** The height of the current background image */
+ uint16 _backgroundHeight;
- Common::Rect _bkgDirtyRect;
+ // A buffer that holds the portion of the background that is used to render the final image
+ // If it's a normal scene, the pixels will be blitted directly to the screen
+ // If it's a panorma / tilt scene, the pixels will be first warped to _warpedSceneSurface
+ Graphics::Surface _backgroundSurface;
+ Common::Rect _backgroundSurfaceDirtyRect;
// A buffer for subtitles
- Graphics::Surface _subWnd;
+ Graphics::Surface _subtitleSurface;
- Common::Rect _subWndDirtyRect;
+ // Rectangle for subtitles area
+ Common::Rect _subtitleArea;
// A buffer for menu drawing
- Graphics::Surface _menuWnd;
+ Graphics::Surface _menuSurface;
+ Common::Rect _menuSurfaceDirtyRect;
- Common::Rect _menuWndDirtyRect;
+ // Rectangle for menu area
+ Common::Rect _menuArea;
// A buffer used for apply graphics effects
- Graphics::Surface _effectWnd;
+ Graphics::Surface _effectSurface;
- /** Width of the working window. Saved to prevent extraneous calls to _workingWindow.width() */
- const int _wrkWidth;
- /** Height of the working window. Saved to prevent extraneous calls to _workingWindow.height() */
- const int _wrkHeight;
- /** Center of the screen in the x direction */
- const int _screenCenterX;
- /** Center of the screen in the y direction */
- const int _screenCenterY;
+ // A buffer to store the result of the panorama / tilt warps
+ Graphics::Surface _warpedSceneSurface;
- /**
- * A Rectangle centered inside the actual window. All in-game coordinates
- * are given in this coordinate space. Also, all images are clipped to the
- * edges of this Rectangle
- */
- const Common::Rect _workingWindow;
-
- // Recatangle for subtitles area
- Common::Rect _subWndRect;
-
- // Recatangle for menu area
- Common::Rect _menuWndRect;
/** Used to warp the background image */
RenderTable _renderTable;
- // A buffer for background image
- Graphics::Surface _curBkg;
- /** The (x1,y1) coordinates of the subRectangle of the background that is currently displayed on the screen */
- int16 _bkgOff;
- /** The width of the current background image */
- uint16 _bkgWidth;
- /** The height of the current background image */
- uint16 _bkgHeight;
-
// Internal subtitles counter
uint16 _subid;
// Subtitle list
- subMap _subsList;
+ SubtitleMap _subsList;
// Visual effects list
- effectsList _effects;
+ EffectsList _effects;
+
+ bool _doubleFPS;
public:
void initialize();
/**
- * Renders the current state of the backbuffer to the screen
+ * Renders the scene to the screen
*/
- void renderBackbufferToScreen();
+ void renderSceneToScreen();
+
+ void copyToScreen(const Graphics::Surface &surface, Common::Rect &rect, int16 srcLeft, int16 srcTop);
/**
* Blits the image or a portion of the image to the background.
@@ -223,23 +225,20 @@ public:
// Blitting surface-to-surface methods
void blitSurfaceToSurface(const Graphics::Surface &src, const Common::Rect &_srcRect , Graphics::Surface &dst, int x, int y);
void blitSurfaceToSurface(const Graphics::Surface &src, const Common::Rect &_srcRect , Graphics::Surface &dst, int _x, int _y, uint32 colorkey);
- void blitSurfaceToSurface(const Graphics::Surface &src, Graphics::Surface &dst, int x, int y);
- void blitSurfaceToSurface(const Graphics::Surface &src, Graphics::Surface &dst, int x, int y, uint32 colorkey);
// Blitting surface-to-background methods
- void blitSurfaceToBkg(const Graphics::Surface &src, int x, int y);
- void blitSurfaceToBkg(const Graphics::Surface &src, int x, int y, uint32 colorkey);
+ void blitSurfaceToBkg(const Graphics::Surface &src, int x, int y, int32 colorkey = -1);
// Blitting surface-to-background methods with scale
- void blitSurfaceToBkgScaled(const Graphics::Surface &src, const Common::Rect &_dstRect);
- void blitSurfaceToBkgScaled(const Graphics::Surface &src, const Common::Rect &_dstRect, uint32 colorkey);
+ void blitSurfaceToBkgScaled(const Graphics::Surface &src, const Common::Rect &_dstRect, int32 colorkey = -1);
// Blitting surface-to-menu methods
- void blitSurfaceToMenu(const Graphics::Surface &src, int x, int y);
- void blitSurfaceToMenu(const Graphics::Surface &src, int x, int y, uint32 colorkey);
+ void blitSurfaceToMenu(const Graphics::Surface &src, int x, int y, int32 colorkey = -1);
// Subtitles methods
+ void initSubArea(uint32 windowWidth, uint32 windowHeight, const Common::Rect workingWindow);
+
// Create subtitle area and return ID
uint16 createSubArea(const Common::Rect &area);
uint16 createSubArea();
@@ -261,10 +260,8 @@ public:
Graphics::Surface *getBkgRect(Common::Rect &rect);
// Load image into new surface
- Graphics::Surface *loadImage(const char *file);
- Graphics::Surface *loadImage(Common::String &file);
- Graphics::Surface *loadImage(const char *file, bool transposed);
- Graphics::Surface *loadImage(Common::String &file, bool transposed);
+ Graphics::Surface *loadImage(Common::String file);
+ Graphics::Surface *loadImage(Common::String file, bool transposed);
// Clear whole/area of menu surface
void clearMenuSurface();
@@ -274,11 +271,10 @@ public:
void renderMenuToScreen();
// Copy needed portion of background surface to workingWindow surface
- void prepareBkg();
+ void prepareBackground();
/**
- * Reads an image file pixel data into a Surface buffer. In the process
- * it converts the pixel data from RGB 555 to RGB 565. Also, if the image
+ * Reads an image file pixel data into a Surface buffer. Also, if the image
* is transposed, it will un-transpose the pixel data. The function will
* call destination::create() if the dimensions of destination do not match
* up with the dimensions of the image.
@@ -289,8 +285,7 @@ public:
void readImageToSurface(const Common::String &fileName, Graphics::Surface &destination);
/**
- * Reads an image file pixel data into a Surface buffer. In the process
- * it converts the pixel data from RGB 555 to RGB 565. Also, if the image
+ * Reads an image file pixel data into a Surface buffer. Also, if the image
* is transposed, it will un-transpose the pixel data. The function will
* call destination::create() if the dimensions of destination do not match
* up with the dimensions of the image.
@@ -302,7 +297,7 @@ public:
void readImageToSurface(const Common::String &fileName, Graphics::Surface &destination, bool transposed);
// Add visual effect to effects list
- void addEffect(Effect *_effect);
+ void addEffect(GraphicsEffect *_effect);
// Delete effect(s) by ID (ID equal to slot of action:region that create this effect)
void deleteEffect(uint32 ID);
@@ -319,13 +314,26 @@ public:
EffectMap *makeEffectMap(const Graphics::Surface &surf, uint16 transp);
// Return background rectangle in screen coordinates
- Common::Rect bkgRectToScreen(const Common::Rect &src);
+ Common::Rect transformBackgroundSpaceRectToScreenSpace(const Common::Rect &src);
// Mark whole background surface as dirty
void markDirty();
- // Fille background surface by color
+#if 0
+ // Fill background surface by color
void bkgFill(uint8 r, uint8 g, uint8 b);
+#endif
+
+ bool askQuestion(const Common::String &str);
+ void delayedMessage(const Common::String &str, uint16 milsecs);
+ void timedMessage(const Common::String &str, uint16 milsecs);
+ void showDebugMsg(const Common::String &msg, int16 delay = 3000);
+
+ void checkBorders();
+ void rotateTo(int16 to, int16 time);
+ void updateRotation();
+
+ void upscaleRect(Common::Rect &rect);
};
} // End of namespace ZVision
diff --git a/engines/zvision/graphics/render_table.cpp b/engines/zvision/graphics/render_table.cpp
index c30e0bd472..df73247344 100644
--- a/engines/zvision/graphics/render_table.cpp
+++ b/engines/zvision/graphics/render_table.cpp
@@ -81,27 +81,6 @@ const Common::Point RenderTable::convertWarpedCoordToFlatCoord(const Common::Poi
return newPoint;
}
-uint16 mixTwoRGB(uint16 colorOne, uint16 colorTwo, float percentColorOne) {
- assert(percentColorOne < 1.0f);
-
- float rOne = float((colorOne & Graphics::ColorMasks<555>::kRedMask) >> Graphics::ColorMasks<555>::kRedShift);
- float rTwo = float((colorTwo & Graphics::ColorMasks<555>::kRedMask) >> Graphics::ColorMasks<555>::kRedShift);
- float gOne = float((colorOne & Graphics::ColorMasks<555>::kGreenMask) >> Graphics::ColorMasks<555>::kGreenShift);
- float gTwo = float((colorTwo & Graphics::ColorMasks<555>::kGreenMask) >> Graphics::ColorMasks<555>::kGreenShift);
- float bOne = float((colorOne & Graphics::ColorMasks<555>::kBlueMask) >> Graphics::ColorMasks<555>::kBlueShift);
- float bTwo = float((colorTwo & Graphics::ColorMasks<555>::kBlueMask) >> Graphics::ColorMasks<555>::kBlueShift);
-
- float rFinal = rOne * percentColorOne + rTwo * (1.0f - percentColorOne);
- float gFinal = gOne * percentColorOne + gTwo * (1.0f - percentColorOne);
- float bFinal = bOne * percentColorOne + bTwo * (1.0f - percentColorOne);
-
- uint16 returnColor = (byte(rFinal + 0.5f) << Graphics::ColorMasks<555>::kRedShift) |
- (byte(gFinal + 0.5f) << Graphics::ColorMasks<555>::kGreenShift) |
- (byte(bFinal + 0.5f) << Graphics::ColorMasks<555>::kBlueShift);
-
- return returnColor;
-}
-
void RenderTable::mutateImage(uint16 *sourceBuffer, uint16 *destBuffer, uint32 destWidth, const Common::Rect &subRect) {
uint32 destOffset = 0;
diff --git a/engines/zvision/graphics/truetype_font.cpp b/engines/zvision/graphics/truetype_font.cpp
deleted file mode 100644
index 2dbd7ca358..0000000000
--- a/engines/zvision/graphics/truetype_font.cpp
+++ /dev/null
@@ -1,265 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/scummsys.h"
-#include "common/config-manager.h"
-#include "common/debug.h"
-#include "common/file.h"
-#include "common/system.h"
-#include "common/unzip.h"
-#include "graphics/font.h"
-#include "graphics/fonts/ttf.h"
-#include "graphics/surface.h"
-
-#include "zvision/zvision.h"
-#include "zvision/graphics/render_manager.h"
-#include "zvision/graphics/truetype_font.h"
-
-namespace ZVision {
-
-StyledTTFont::StyledTTFont(ZVision *engine) {
- _engine = engine;
- _style = 0;
- _font = NULL;
- _lineHeight = 0;
-}
-
-StyledTTFont::~StyledTTFont() {
- if (_font)
- delete _font;
-}
-
-bool StyledTTFont::loadFont(const Common::String &fontName, int32 point, uint style) {
- _style = style;
- return loadFont(fontName, point);
-}
-
-bool StyledTTFont::loadFont(const Common::String &fontName, int32 point) {
- Common::String newFontName;
- if (fontName.matchString("*times new roman*", true) || fontName.matchString("*times*", true)) {
- if ((_style & (STTF_BOLD | STTF_ITALIC)) == (STTF_BOLD | STTF_ITALIC))
- newFontName = "timesbi.ttf";
- else if (_style & STTF_BOLD)
- newFontName = "timesbd.ttf";
- else if (_style & STTF_ITALIC)
- newFontName = "timesi.ttf";
- else
- newFontName = "times.ttf";
-
- } else if (fontName.matchString("*courier new*", true) || fontName.matchString("*courier*", true) || fontName.matchString("*ZorkDeath*", true)) {
- if ((_style & (STTF_BOLD | STTF_ITALIC)) == (STTF_BOLD | STTF_ITALIC))
- newFontName = "courbi.ttf";
- else if (_style & STTF_BOLD)
- newFontName = "courbd.ttf";
- else if (_style & STTF_ITALIC)
- newFontName = "couri.ttf";
- else
- newFontName = "cour.ttf";
-
- } else if (fontName.matchString("*century schoolbook*", true)) {
- if ((_style & (STTF_BOLD | STTF_ITALIC)) == (STTF_BOLD | STTF_ITALIC))
- newFontName = "censcbkbi.ttf";
- else if (_style & STTF_BOLD)
- newFontName = "censcbkbd.ttf";
- else if (_style & STTF_ITALIC)
- newFontName = "censcbki.ttf";
- else
- newFontName = "censcbk.ttf";
-
- } else if (fontName.matchString("*garamond*", true)) {
- if ((_style & (STTF_BOLD | STTF_ITALIC)) == (STTF_BOLD | STTF_ITALIC))
- newFontName = "garabi.ttf";
- else if (_style & STTF_BOLD)
- newFontName = "garabd.ttf";
- else if (_style & STTF_ITALIC)
- newFontName = "garai.ttf";
- else
- newFontName = "gara.ttf";
-
- } else if (fontName.matchString("*arial*", true) || fontName.matchString("*ZorkNormal*", true)) {
- if ((_style & (STTF_BOLD | STTF_ITALIC)) == (STTF_BOLD | STTF_ITALIC))
- newFontName = "arialbi.ttf";
- else if (_style & STTF_BOLD)
- newFontName = "arialbd.ttf";
- else if (_style & STTF_ITALIC)
- newFontName = "ariali.ttf";
- else
- newFontName = "arial.ttf";
-
- } else {
- debug("Could not identify font: %s. Reverting to Arial", fontName.c_str());
- newFontName = "arial.ttf";
- }
-
- bool sharp = (_style & STTF_SHARP) == STTF_SHARP;
-
- Common::File *file = _engine->getSearchManager()->openFile(newFontName);
-
- if (!file) {
- Common::SeekableReadStream *themeFile = nullptr;
- if (ConfMan.hasKey("themepath")) {
- Common::FSNode themePath(ConfMan.get("themepath"));
- if (themePath.exists()) {
- Common::FSNode scummModern = themePath.getChild("scummmodern.zip");
- if (scummModern.exists()) {
- themeFile = scummModern.createReadStream();
- }
- }
- }
- if (!themeFile) { // Fallback : Search for ScummModern.zip in SearchMan.
- themeFile = SearchMan.createReadStreamForMember("scummmodern.zip");
- }
- if (themeFile) {
- Common::Archive *themeArchive = Common::makeZipArchive(themeFile);
- if (themeArchive->hasFile("FreeSans.ttf")) {
- Common::SeekableReadStream *stream = nullptr;
- stream = themeArchive->createReadStreamForMember("FreeSans.ttf");
- Graphics::Font *_newFont = Graphics::loadTTFFont(*stream, point, 60, (sharp ? Graphics::kTTFRenderModeMonochrome : Graphics::kTTFRenderModeNormal)); // 66 dpi for 640 x 480 on 14" display
- if (_newFont) {
- if (!_font)
- delete _font;
- _font = _newFont;
- }
- if (stream)
- delete stream;
- }
- delete themeArchive;
- themeArchive = nullptr;
- }
- } else {
- Graphics::Font *_newFont = Graphics::loadTTFFont(*file, point, 60, (sharp ? Graphics::kTTFRenderModeMonochrome : Graphics::kTTFRenderModeNormal)); // 66 dpi for 640 x 480 on 14" display
- if (_newFont) {
- if (!_font)
- delete _font;
- _font = _newFont;
- }
- delete file;
- }
-
- _fntName = fontName;
- _lineHeight = point;
-
- if (_font)
- return true;
- return false;
-}
-
-void StyledTTFont::setStyle(uint newStyle) {
- if ((_style & (STTF_BOLD | STTF_ITALIC | STTF_SHARP)) != (newStyle & (STTF_BOLD | STTF_ITALIC | STTF_SHARP))) {
- _style = newStyle;
- loadFont(_fntName, _lineHeight);
- } else {
- _style = newStyle;
- }
-}
-
-int StyledTTFont::getFontHeight() {
- if (_font)
- return _font->getFontHeight();
- return 0;
-}
-
-int StyledTTFont::getMaxCharWidth() {
- if (_font)
- return _font->getMaxCharWidth();
- return 0;
-}
-
-int StyledTTFont::getCharWidth(byte chr) {
- if (_font)
- return _font->getCharWidth(chr);
- return 0;
-}
-
-int StyledTTFont::getKerningOffset(byte left, byte right) {
- if (_font)
- return _font->getKerningOffset(left, right);
- return 0;
-}
-
-void StyledTTFont::drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) {
- if (_font) {
- _font->drawChar(dst, chr, x, y, color);
- if (_style & STTF_UNDERLINE) {
- int16 pos = floor(_font->getFontHeight() * 0.87);
- int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
- dst->fillRect(Common::Rect(x, y + pos, x + _font->getCharWidth(chr), y + pos + thk), color);
- }
- if (_style & STTF_STRIKEOUT) {
- int16 pos = floor(_font->getFontHeight() * 0.60);
- int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
- dst->fillRect(Common::Rect(x, y + pos, x + _font->getCharWidth(chr), y + pos + thk), color);
- }
- }
-}
-
-void StyledTTFont::drawString(Graphics::Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, Graphics::TextAlign align) {
- if (_font) {
- _font->drawString(dst, str, x, y, w, color, align);
- if (_style & STTF_UNDERLINE) {
- int16 pos = floor(_font->getFontHeight() * 0.87);
- int16 wd = MIN(_font->getStringWidth(str), w);
- int16 stX = x;
- if (align == Graphics::kTextAlignCenter)
- stX += (w - wd) / 2;
- else if (align == Graphics::kTextAlignRight)
- stX += (w - wd);
-
- int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
-
- dst->fillRect(Common::Rect(stX, y + pos, stX + wd, y + pos + thk), color);
- }
- if (_style & STTF_STRIKEOUT) {
- int16 pos = floor(_font->getFontHeight() * 0.60);
- int16 wd = MIN(_font->getStringWidth(str), w);
- int16 stX = x;
- if (align == Graphics::kTextAlignCenter)
- stX += (w - wd) / 2;
- else if (align == Graphics::kTextAlignRight)
- stX += (w - wd);
-
- int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
-
- dst->fillRect(Common::Rect(stX, y + pos, stX + wd, y + pos + thk), color);
- }
- }
-}
-
-int StyledTTFont::getStringWidth(const Common::String &str) {
- if (_font)
- return _font->getStringWidth(str);
- return 0;
-}
-
-Graphics::Surface *StyledTTFont::renderSolidText(const Common::String &str, uint32 color) {
- Graphics::Surface *tmp = new Graphics::Surface;
- if (_font) {
- int16 w = _font->getStringWidth(str);
- if (w && w < 1024) {
- tmp->create(w, _font->getFontHeight(), _engine->_pixelFormat);
- drawString(tmp, str, 0, 0, w, color);
- }
- }
- return tmp;
-}
-
-} // End of namespace ZVision
diff --git a/engines/zvision/module.mk b/engines/zvision/module.mk
index 00652f0824..93fba2879d 100644
--- a/engines/zvision/module.mk
+++ b/engines/zvision/module.mk
@@ -4,10 +4,9 @@ MODULE_OBJS := \
core/console.o \
core/clock.o \
core/events.o \
- core/menu.o \
- core/save_manager.o \
detection.o \
file/lzss_read_stream.o \
+ file/save_manager.o \
file/search_manager.o \
file/zfs_archive.o \
graphics/cursors/cursor_manager.o \
@@ -17,8 +16,6 @@ MODULE_OBJS := \
graphics/effects/wave.o \
graphics/render_manager.o \
graphics/render_table.o \
- graphics/subtitles.o \
- graphics/truetype_font.o \
scripting/actions.o \
scripting/control.o \
scripting/controls/fist_control.o \
@@ -32,19 +29,22 @@ MODULE_OBJS := \
scripting/controls/slot_control.o \
scripting/controls/titler_control.o \
scripting/inventory.o \
+ scripting/menu.o \
scripting/scr_file_handling.o \
scripting/script_manager.o \
- scripting/sidefx/animation_node.o \
- scripting/sidefx/distort_node.o \
- scripting/sidefx/music_node.o \
- scripting/sidefx/region_node.o \
- scripting/sidefx/syncsound_node.o \
- scripting/sidefx/timer_node.o \
- scripting/sidefx/ttytext_node.o \
+ scripting/effects/animation_effect.o \
+ scripting/effects/distort_effect.o \
+ scripting/effects/music_effect.o \
+ scripting/effects/region_effect.o \
+ scripting/effects/syncsound_effect.o \
+ scripting/effects/timer_effect.o \
+ scripting/effects/ttytext_effect.o \
sound/midi.o \
sound/zork_raw.o \
text/string_manager.o \
+ text/subtitles.o \
text/text.o \
+ text/truetype_font.o \
video/rlf_decoder.o \
video/video.o \
video/zork_avi_decoder.o \
diff --git a/engines/zvision/scripting/actions.cpp b/engines/zvision/scripting/actions.cpp
index 0422a2c028..e1380b0eb2 100644
--- a/engines/zvision/scripting/actions.cpp
+++ b/engines/zvision/scripting/actions.cpp
@@ -21,42 +21,44 @@
*/
#include "common/scummsys.h"
+#include "video/video_decoder.h"
#include "zvision/scripting/actions.h"
#include "zvision/zvision.h"
#include "zvision/scripting/script_manager.h"
#include "zvision/graphics/render_manager.h"
-#include "zvision/sound/zork_raw.h"
-#include "zvision/video/zork_avi_decoder.h"
-#include "zvision/scripting/sidefx/timer_node.h"
-#include "zvision/scripting/sidefx/music_node.h"
-#include "zvision/scripting/sidefx/syncsound_node.h"
-#include "zvision/scripting/sidefx/animation_node.h"
-#include "zvision/scripting/sidefx/distort_node.h"
-#include "zvision/scripting/sidefx/ttytext_node.h"
-#include "zvision/scripting/sidefx/region_node.h"
+#include "zvision/file/save_manager.h"
+#include "zvision/scripting/menu.h"
+#include "zvision/scripting/effects/timer_effect.h"
+#include "zvision/scripting/effects/music_effect.h"
+#include "zvision/scripting/effects/syncsound_effect.h"
+#include "zvision/scripting/effects/animation_effect.h"
+#include "zvision/scripting/effects/distort_effect.h"
+#include "zvision/scripting/effects/ttytext_effect.h"
+#include "zvision/scripting/effects/region_effect.h"
#include "zvision/scripting/controls/titler_control.h"
#include "zvision/graphics/render_table.h"
-#include "zvision/graphics/effect.h"
+#include "zvision/graphics/graphics_effect.h"
#include "zvision/graphics/effects/fog.h"
#include "zvision/graphics/effects/light.h"
#include "zvision/graphics/effects/wave.h"
-#include "zvision/core/save_manager.h"
#include "zvision/graphics/cursors/cursor_manager.h"
-#include "common/file.h"
-
-#include "audio/decoders/wave.h"
-
namespace ZVision {
+ResultAction::ResultAction(ZVision *engine, int32 slotKey) :
+ _engine(engine),
+ _slotKey(slotKey),
+ _scriptManager(engine->getScriptManager()) {
+}
+
//////////////////////////////////////////////////////////////////////////////
// ActionAdd
//////////////////////////////////////////////////////////////////////////////
-ActionAdd::ActionAdd(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
+ActionAdd::ActionAdd(ZVision *engine, int32 slotKey, const Common::String &line) :
+ ResultAction(engine, slotKey) {
_key = 0;
_value = 0;
@@ -64,7 +66,7 @@ ActionAdd::ActionAdd(ZVision *engine, int32 slotkey, const Common::String &line)
}
bool ActionAdd::execute() {
- _engine->getScriptManager()->setStateValue(_key, _engine->getScriptManager()->getStateValue(_key) + _value);
+ _scriptManager->setStateValue(_key, _scriptManager->getStateValue(_key) + _value);
return true;
}
@@ -72,23 +74,22 @@ bool ActionAdd::execute() {
// ActionAssign
//////////////////////////////////////////////////////////////////////////////
-ActionAssign::ActionAssign(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
+ActionAssign::ActionAssign(ZVision *engine, int32 slotKey, const Common::String &line) :
+ ResultAction(engine, slotKey) {
_key = 0;
char buf[64];
memset(buf, 0, 64);
sscanf(line.c_str(), "%u, %s", &_key, buf);
- _value = new ValueSlot(_engine->getScriptManager(), buf);
+ _value = new ValueSlot(_scriptManager, buf);
}
ActionAssign::~ActionAssign() {
- if (_value)
- delete _value;
+ delete _value;
}
bool ActionAssign::execute() {
- _engine->getScriptManager()->setStateValue(_key, _value->getValue());
+ _scriptManager->setStateValue(_key, _value->getValue());
return true;
}
@@ -96,8 +97,8 @@ bool ActionAssign::execute() {
// ActionAttenuate
//////////////////////////////////////////////////////////////////////////////
-ActionAttenuate::ActionAttenuate(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
+ActionAttenuate::ActionAttenuate(ZVision *engine, int32 slotKey, const Common::String &line) :
+ ResultAction(engine, slotKey) {
_key = 0;
_attenuation = 0;
@@ -105,10 +106,10 @@ ActionAttenuate::ActionAttenuate(ZVision *engine, int32 slotkey, const Common::S
}
bool ActionAttenuate::execute() {
- SideFX *fx = _engine->getScriptManager()->getSideFX(_key);
- if (fx && fx->getType() == SideFX::SIDEFX_AUDIO) {
- MusicNode *mus = (MusicNode *)fx;
- mus->setVolume(255 - (abs(_attenuation) >> 7));
+ ScriptingEffect *fx = _scriptManager->getSideFX(_key);
+ if (fx && fx->getType() == ScriptingEffect::SCRIPTING_EFFECT_AUDIO) {
+ MusicNodeBASE *mus = (MusicNodeBASE *)fx;
+ mus->setVolume(255 * (10000 - abs(_attenuation)) / 10000 );
}
return true;
}
@@ -117,8 +118,8 @@ bool ActionAttenuate::execute() {
// ActionChangeLocation
//////////////////////////////////////////////////////////////////////////////
-ActionChangeLocation::ActionChangeLocation(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
+ActionChangeLocation::ActionChangeLocation(ZVision *engine, int32 slotKey, const Common::String &line) :
+ ResultAction(engine, slotKey) {
_world = 'g';
_room = 'a';
_node = 'r';
@@ -130,7 +131,7 @@ ActionChangeLocation::ActionChangeLocation(ZVision *engine, int32 slotkey, const
bool ActionChangeLocation::execute() {
// We can't directly call ScriptManager::ChangeLocationIntern() because doing so clears all the Puzzles, and thus would corrupt the current puzzle checking
- _engine->getScriptManager()->changeLocation(_world, _room, _node, _view, _offset);
+ _scriptManager->changeLocation(_world, _room, _node, _view, _offset);
// Tell the puzzle system to stop checking any more puzzles
return false;
}
@@ -139,8 +140,8 @@ bool ActionChangeLocation::execute() {
// ActionCrossfade
//////////////////////////////////////////////////////////////////////////////
-ActionCrossfade::ActionCrossfade(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
+ActionCrossfade::ActionCrossfade(ZVision *engine, int32 slotKey, const Common::String &line) :
+ ResultAction(engine, slotKey) {
_keyOne = 0;
_keyTwo = 0;
_oneStartVolume = 0;
@@ -156,9 +157,9 @@ ActionCrossfade::ActionCrossfade(ZVision *engine, int32 slotkey, const Common::S
bool ActionCrossfade::execute() {
if (_keyOne) {
- SideFX *fx = _engine->getScriptManager()->getSideFX(_keyOne);
- if (fx && fx->getType() == SideFX::SIDEFX_AUDIO) {
- MusicNode *mus = (MusicNode *)fx;
+ ScriptingEffect *fx = _scriptManager->getSideFX(_keyOne);
+ if (fx && fx->getType() == ScriptingEffect::SCRIPTING_EFFECT_AUDIO) {
+ MusicNodeBASE *mus = (MusicNodeBASE *)fx;
if (_oneStartVolume >= 0)
mus->setVolume((_oneStartVolume * 255) / 100);
@@ -167,9 +168,9 @@ bool ActionCrossfade::execute() {
}
if (_keyTwo) {
- SideFX *fx = _engine->getScriptManager()->getSideFX(_keyTwo);
- if (fx && fx->getType() == SideFX::SIDEFX_AUDIO) {
- MusicNode *mus = (MusicNode *)fx;
+ ScriptingEffect *fx = _scriptManager->getSideFX(_keyTwo);
+ if (fx && fx->getType() == ScriptingEffect::SCRIPTING_EFFECT_AUDIO) {
+ MusicNodeBASE *mus = (MusicNodeBASE *)fx;
if (_twoStartVolume >= 0)
mus->setVolume((_twoStartVolume * 255) / 100);
@@ -183,8 +184,8 @@ bool ActionCrossfade::execute() {
// ActionCursor
//////////////////////////////////////////////////////////////////////////////
-ActionCursor::ActionCursor(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
+ActionCursor::ActionCursor(ZVision *engine, int32 slotKey, const Common::String &line) :
+ ResultAction(engine, slotKey) {
Common::String up = line;
up.toUppercase();
_action = 0;
@@ -215,10 +216,13 @@ bool ActionCursor::execute() {
// ActionDelayRender
//////////////////////////////////////////////////////////////////////////////
-ActionDelayRender::ActionDelayRender(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
+ActionDelayRender::ActionDelayRender(ZVision *engine, int32 slotKey, const Common::String &line) :
+ ResultAction(engine, slotKey) {
_framesToDelay = 0;
sscanf(line.c_str(), "%u", &_framesToDelay);
+ // Limit to 10 frames maximum. This fixes the script bug in ZGI scene px10
+ // (outside Frobozz Electric building), where this is set to 100 (bug #6791).
+ _framesToDelay = MIN<uint32>(_framesToDelay, 10);
}
bool ActionDelayRender::execute() {
@@ -230,32 +234,15 @@ bool ActionDelayRender::execute() {
// ActionDisableControl
//////////////////////////////////////////////////////////////////////////////
-ActionDisableControl::ActionDisableControl(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
+ActionDisableControl::ActionDisableControl(ZVision *engine, int32 slotKey, const Common::String &line) :
+ ResultAction(engine, slotKey) {
_key = 0;
sscanf(line.c_str(), "%u", &_key);
}
bool ActionDisableControl::execute() {
- _engine->getScriptManager()->setStateFlag(_key, Puzzle::DISABLED);
- return true;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// ActionDisableVenus
-//////////////////////////////////////////////////////////////////////////////
-
-ActionDisableVenus::ActionDisableVenus(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
- _key = 0;
-
- sscanf(line.c_str(), "%d", &_key);
-}
-
-bool ActionDisableVenus::execute() {
- _engine->getScriptManager()->setStateValue(_key, 0);
-
+ _scriptManager->setStateFlag(_key, Puzzle::DISABLED);
return true;
}
@@ -263,8 +250,8 @@ bool ActionDisableVenus::execute() {
// ActionDisplayMessage
//////////////////////////////////////////////////////////////////////////////
-ActionDisplayMessage::ActionDisplayMessage(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
+ActionDisplayMessage::ActionDisplayMessage(ZVision *engine, int32 slotKey, const Common::String &line) :
+ ResultAction(engine, slotKey) {
_control = 0;
_msgid = 0;
@@ -272,7 +259,7 @@ ActionDisplayMessage::ActionDisplayMessage(ZVision *engine, int32 slotkey, const
}
bool ActionDisplayMessage::execute() {
- Control *ctrl = _engine->getScriptManager()->getControl(_control);
+ Control *ctrl = _scriptManager->getControl(_control);
if (ctrl && ctrl->getType() == Control::CONTROL_TITLER) {
TitlerControl *titler = (TitlerControl *)ctrl;
titler->setString(_msgid);
@@ -295,11 +282,11 @@ bool ActionDissolve::execute() {
}
//////////////////////////////////////////////////////////////////////////////
-// ActionDistort
+// ActionDistort - only used by Zork: Nemesis for the "treatment" puzzle in the Sanitarium (aj30)
//////////////////////////////////////////////////////////////////////////////
-ActionDistort::ActionDistort(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
+ActionDistort::ActionDistort(ZVision *engine, int32 slotKey, const Common::String &line) :
+ ResultAction(engine, slotKey) {
_distSlot = 0;
_speed = 0;
_startAngle = 60.0;
@@ -311,14 +298,14 @@ ActionDistort::ActionDistort(ZVision *engine, int32 slotkey, const Common::Strin
}
ActionDistort::~ActionDistort() {
- _engine->getScriptManager()->killSideFx(_distSlot);
+ _scriptManager->killSideFx(_distSlot);
}
bool ActionDistort::execute() {
- if (_engine->getScriptManager()->getSideFX(_distSlot))
+ if (_scriptManager->getSideFX(_distSlot))
return true;
- _engine->getScriptManager()->addSideFX(new DistortNode(_engine, _distSlot, _speed, _startAngle, _endAngle, _startLineScale, _endLineScale));
+ _scriptManager->addSideFX(new DistortNode(_engine, _distSlot, _speed, _startAngle, _endAngle, _startLineScale, _endLineScale));
return true;
}
@@ -327,15 +314,15 @@ bool ActionDistort::execute() {
// ActionEnableControl
//////////////////////////////////////////////////////////////////////////////
-ActionEnableControl::ActionEnableControl(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
+ActionEnableControl::ActionEnableControl(ZVision *engine, int32 slotKey, const Common::String &line) :
+ ResultAction(engine, slotKey) {
_key = 0;
sscanf(line.c_str(), "%u", &_key);
}
bool ActionEnableControl::execute() {
- _engine->getScriptManager()->unsetStateFlag(_key, Puzzle::DISABLED);
+ _scriptManager->unsetStateFlag(_key, Puzzle::DISABLED);
return true;
}
@@ -343,13 +330,13 @@ bool ActionEnableControl::execute() {
// ActionFlushMouseEvents
//////////////////////////////////////////////////////////////////////////////
-ActionFlushMouseEvents::ActionFlushMouseEvents(ZVision *engine, int32 slotkey) :
- ResultAction(engine, slotkey) {
+ActionFlushMouseEvents::ActionFlushMouseEvents(ZVision *engine, int32 slotKey) :
+ ResultAction(engine, slotKey) {
}
bool ActionFlushMouseEvents::execute() {
- _engine->getScriptManager()->flushEvent(Common::EVENT_LBUTTONUP);
- _engine->getScriptManager()->flushEvent(Common::EVENT_LBUTTONDOWN);
+ _scriptManager->flushEvent(Common::EVENT_LBUTTONUP);
+ _scriptManager->flushEvent(Common::EVENT_LBUTTONDOWN);
return true;
}
@@ -357,13 +344,13 @@ bool ActionFlushMouseEvents::execute() {
// ActionInventory
//////////////////////////////////////////////////////////////////////////////
-ActionInventory::ActionInventory(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
+ActionInventory::ActionInventory(ZVision *engine, int32 slotKey, const Common::String &line) :
+ ResultAction(engine, slotKey) {
_type = -1;
_key = 0;
char buf[25];
- sscanf(line.c_str(), "%25s %d", buf, &_key);
+ sscanf(line.c_str(), "%24s %d", buf, &_key);
if (strcmp(buf, "add") == 0) {
_type = 0;
@@ -382,22 +369,22 @@ ActionInventory::ActionInventory(ZVision *engine, int32 slotkey, const Common::S
bool ActionInventory::execute() {
switch (_type) {
case 0: // add
- _engine->getScriptManager()->inventoryAdd(_key);
+ _scriptManager->inventoryAdd(_key);
break;
case 1: // addi
- _engine->getScriptManager()->inventoryAdd(_engine->getScriptManager()->getStateValue(_key));
+ _scriptManager->inventoryAdd(_scriptManager->getStateValue(_key));
break;
case 2: // drop
if (_key >= 0)
- _engine->getScriptManager()->inventoryDrop(_key);
+ _scriptManager->inventoryDrop(_key);
else
- _engine->getScriptManager()->inventoryDrop(_engine->getScriptManager()->getStateValue(StateKey_InventoryItem));
+ _scriptManager->inventoryDrop(_scriptManager->getStateValue(StateKey_InventoryItem));
break;
case 3: // dropi
- _engine->getScriptManager()->inventoryDrop(_engine->getScriptManager()->getStateValue(_key));
+ _scriptManager->inventoryDrop(_scriptManager->getStateValue(_key));
break;
case 4: // cycle
- _engine->getScriptManager()->inventoryCycle();
+ _scriptManager->inventoryCycle();
break;
default:
break;
@@ -406,41 +393,41 @@ bool ActionInventory::execute() {
}
//////////////////////////////////////////////////////////////////////////////
-// ActionKill
+// ActionKill - only used by ZGI
//////////////////////////////////////////////////////////////////////////////
-ActionKill::ActionKill(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
+ActionKill::ActionKill(ZVision *engine, int32 slotKey, const Common::String &line) :
+ ResultAction(engine, slotKey) {
_key = 0;
_type = 0;
char keytype[25];
- sscanf(line.c_str(), "%25s", keytype);
+ sscanf(line.c_str(), "%24s", keytype);
if (keytype[0] == '"') {
if (!scumm_stricmp(keytype, "\"ANIM\""))
- _type = SideFX::SIDEFX_ANIM;
+ _type = ScriptingEffect::SCRIPTING_EFFECT_ANIM;
else if (!scumm_stricmp(keytype, "\"AUDIO\""))
- _type = SideFX::SIDEFX_AUDIO;
+ _type = ScriptingEffect::SCRIPTING_EFFECT_AUDIO;
else if (!scumm_stricmp(keytype, "\"DISTORT\""))
- _type = SideFX::SIDEFX_DISTORT;
+ _type = ScriptingEffect::SCRIPTING_EFFECT_DISTORT;
else if (!scumm_stricmp(keytype, "\"PANTRACK\""))
- _type = SideFX::SIDEFX_PANTRACK;
+ _type = ScriptingEffect::SCRIPTING_EFFECT_PANTRACK;
else if (!scumm_stricmp(keytype, "\"REGION\""))
- _type = SideFX::SIDEFX_REGION;
+ _type = ScriptingEffect::SCRIPTING_EFFECT_REGION;
else if (!scumm_stricmp(keytype, "\"TIMER\""))
- _type = SideFX::SIDEFX_TIMER;
+ _type = ScriptingEffect::SCRIPTING_EFFECT_TIMER;
else if (!scumm_stricmp(keytype, "\"TTYTEXT\""))
- _type = SideFX::SIDEFX_TTYTXT;
+ _type = ScriptingEffect::SCRIPTING_EFFECT_TTYTXT;
else if (!scumm_stricmp(keytype, "\"ALL\""))
- _type = SideFX::SIDEFX_ALL;
+ _type = ScriptingEffect::SCRIPTING_EFFECT_ALL;
} else
_key = atoi(keytype);
}
bool ActionKill::execute() {
if (_type)
- _engine->getScriptManager()->killSideFxType((SideFX::SideFXType)_type);
+ _scriptManager->killSideFxType((ScriptingEffect::ScriptingEffectType)_type);
else
- _engine->getScriptManager()->killSideFx(_key);
+ _scriptManager->killSideFx(_key);
return true;
}
@@ -448,15 +435,15 @@ bool ActionKill::execute() {
// ActionMenuBarEnable
//////////////////////////////////////////////////////////////////////////////
-ActionMenuBarEnable::ActionMenuBarEnable(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
+ActionMenuBarEnable::ActionMenuBarEnable(ZVision *engine, int32 slotKey, const Common::String &line) :
+ ResultAction(engine, slotKey) {
_menus = 0xFFFF;
sscanf(line.c_str(), "%hu", &_menus);
}
bool ActionMenuBarEnable::execute() {
- _engine->menuBarEnable(_menus);
+ _engine->getMenuHandler()->setEnable(_menus);
return true;
}
@@ -464,57 +451,76 @@ bool ActionMenuBarEnable::execute() {
// ActionMusic
//////////////////////////////////////////////////////////////////////////////
-ActionMusic::ActionMusic(ZVision *engine, int32 slotkey, const Common::String &line, bool global) :
- ResultAction(engine, slotkey),
- _volume(255),
+ActionMusic::ActionMusic(ZVision *engine, int32 slotKey, const Common::String &line, bool global) :
+ ResultAction(engine, slotKey),
_note(0),
_prog(0),
_universe(global) {
uint type = 0;
char fileNameBuffer[25];
uint loop = 0;
- uint volume = 255;
+ char volumeBuffer[15];
- sscanf(line.c_str(), "%u %25s %u %u", &type, fileNameBuffer, &loop, &volume);
+ // Volume is optional. If it doesn't appear, assume full volume
+ strcpy(volumeBuffer, "100");
- // type 4 are midi sound effect files
+ sscanf(line.c_str(), "%u %24s %u %14s", &type, fileNameBuffer, &loop, volumeBuffer);
+
+ // Type 4 actions are MIDI commands, not files. These are only used by
+ // Zork: Nemesis, for the flute and piano puzzles (tj4e and ve6f, as well
+ // as vr)
if (type == 4) {
_midi = true;
int note;
int prog;
- sscanf(line.c_str(), "%u %d %d %u", &type, &prog, &note, &volume);
- _volume = volume;
+ sscanf(line.c_str(), "%u %d %d %14s", &type, &prog, &note, volumeBuffer);
+ _volume = new ValueSlot(_scriptManager, volumeBuffer);
_note = note;
_prog = prog;
} else {
_midi = false;
_fileName = Common::String(fileNameBuffer);
_loop = loop == 1 ? true : false;
-
- // Volume is optional. If it doesn't appear, assume full volume
- if (volume != 255) {
- // Volume in the script files is mapped to [0, 100], but the ScummVM mixer uses [0, 255]
- _volume = volume * 255 / 100;
+ if (volumeBuffer[0] != '[' && atoi(volumeBuffer) > 100) {
+ // I thought I saw a case like this in Zork Nemesis, so
+ // let's guard against it.
+ warning("ActionMusic: Adjusting volume for %s from %s to 100", _fileName.c_str(), volumeBuffer);
+ strcpy(volumeBuffer, "100");
}
+ _volume = new ValueSlot(_scriptManager, volumeBuffer);
}
+
+ // WORKAROUND for a script bug in Zork Nemesis, rooms mq70/mq80.
+ // Fixes an edge case where the player goes to the dark room with the grue
+ // without holding a torch, and then quickly runs away before the grue's
+ // sound effect finishes. Fixes script bug #6794.
+ if (engine->getGameId() == GID_NEMESIS && _slotKey == 14822 && _scriptManager->getStateValue(_slotKey) == 2)
+ _scriptManager->setStateValue(_slotKey, 0);
+
}
ActionMusic::~ActionMusic() {
if (!_universe)
- _engine->getScriptManager()->killSideFx(_slotKey);
+ _scriptManager->killSideFx(_slotKey);
+ delete _volume;
}
bool ActionMusic::execute() {
- if (_engine->getScriptManager()->getSideFX(_slotKey))
- return true;
+ if (_scriptManager->getSideFX(_slotKey)) {
+ _scriptManager->killSideFx(_slotKey);
+ _scriptManager->setStateValue(_slotKey, 2);
+ }
+
+ uint volume = _volume->getValue();
if (_midi) {
- _engine->getScriptManager()->addSideFX(new MusicMidiNode(_engine, _slotKey, _prog, _note, _volume));
+ _scriptManager->addSideFX(new MusicMidiNode(_engine, _slotKey, _prog, _note, volume));
} else {
if (!_engine->getSearchManager()->hasFile(_fileName))
return true;
- _engine->getScriptManager()->addSideFX(new MusicNode(_engine, _slotKey, _fileName, _loop, _volume));
+ // Volume in the script files is mapped to [0, 100], but the ScummVM mixer uses [0, 255]
+ _scriptManager->addSideFX(new MusicNode(_engine, _slotKey, _fileName, _loop, volume * 255 / 100));
}
return true;
@@ -524,8 +530,8 @@ bool ActionMusic::execute() {
// ActionPanTrack
//////////////////////////////////////////////////////////////////////////////
-ActionPanTrack::ActionPanTrack(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey),
+ActionPanTrack::ActionPanTrack(ZVision *engine, int32 slotKey, const Common::String &line) :
+ ResultAction(engine, slotKey),
_pos(0),
_musicSlot(0) {
@@ -533,14 +539,14 @@ ActionPanTrack::ActionPanTrack(ZVision *engine, int32 slotkey, const Common::Str
}
ActionPanTrack::~ActionPanTrack() {
- _engine->getScriptManager()->killSideFx(_slotKey);
+ _scriptManager->killSideFx(_slotKey);
}
bool ActionPanTrack::execute() {
- if (_engine->getScriptManager()->getSideFX(_slotKey))
+ if (_scriptManager->getSideFX(_slotKey))
return true;
- _engine->getScriptManager()->addSideFX(new PanTrackNode(_engine, _slotKey, _musicSlot, _pos));
+ _scriptManager->addSideFX(new PanTrackNode(_engine, _slotKey, _musicSlot, _pos));
return true;
}
@@ -549,8 +555,8 @@ bool ActionPanTrack::execute() {
// ActionPreferences
//////////////////////////////////////////////////////////////////////////////
-ActionPreferences::ActionPreferences(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
+ActionPreferences::ActionPreferences(ZVision *engine, int32 slotKey, const Common::String &line) :
+ ResultAction(engine, slotKey) {
if (line.compareToIgnoreCase("save") == 0)
_save = true;
else
@@ -570,38 +576,38 @@ bool ActionPreferences::execute() {
// ActionPreloadAnimation
//////////////////////////////////////////////////////////////////////////////
-ActionPreloadAnimation::ActionPreloadAnimation(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
+ActionPreloadAnimation::ActionPreloadAnimation(ZVision *engine, int32 slotKey, const Common::String &line) :
+ ResultAction(engine, slotKey) {
_mask = 0;
_framerate = 0;
char fileName[25];
- // The two %*u are always 0 and dont seem to have a use
- sscanf(line.c_str(), "%25s %*u %*u %d %d", fileName, &_mask, &_framerate);
+ // The two %*u are usually 0 and dont seem to have a use
+ sscanf(line.c_str(), "%24s %*u %*u %d %d", fileName, &_mask, &_framerate);
- if (_mask > 0) {
- byte r, g, b;
- Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0).colorToRGB(_mask, r, g, b);
- _mask = _engine->_pixelFormat.RGBToColor(r, g, b);
- }
+ // Mask 0 means "no transparency" in this case. Since we use a common blitting
+ // code for images and animations, we set it to -1 to avoid confusion with
+ // color 0, which is used as a mask in some images
+ if (_mask == 0)
+ _mask = -1;
_fileName = Common::String(fileName);
}
ActionPreloadAnimation::~ActionPreloadAnimation() {
- _engine->getScriptManager()->deleteSideFx(_slotKey);
+ _scriptManager->deleteSideFx(_slotKey);
}
bool ActionPreloadAnimation::execute() {
- AnimationNode *nod = (AnimationNode *)_engine->getScriptManager()->getSideFX(_slotKey);
+ AnimationEffect *nod = (AnimationEffect *)_scriptManager->getSideFX(_slotKey);
if (!nod) {
- nod = new AnimationNode(_engine, _slotKey, _fileName, _mask, _framerate, false);
- _engine->getScriptManager()->addSideFX(nod);
+ nod = new AnimationEffect(_engine, _slotKey, _fileName, _mask, _framerate, false);
+ _scriptManager->addSideFX(nod);
} else
nod->stop();
- _engine->getScriptManager()->setStateValue(_slotKey, 2);
+ _scriptManager->setStateValue(_slotKey, 2);
return true;
}
@@ -609,18 +615,18 @@ bool ActionPreloadAnimation::execute() {
// ActionUnloadAnimation
//////////////////////////////////////////////////////////////////////////////
-ActionUnloadAnimation::ActionUnloadAnimation(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
+ActionUnloadAnimation::ActionUnloadAnimation(ZVision *engine, int32 slotKey, const Common::String &line) :
+ ResultAction(engine, slotKey) {
_key = 0;
sscanf(line.c_str(), "%u", &_key);
}
bool ActionUnloadAnimation::execute() {
- AnimationNode *nod = (AnimationNode *)_engine->getScriptManager()->getSideFX(_key);
+ AnimationEffect *nod = (AnimationEffect *)_scriptManager->getSideFX(_key);
- if (nod && nod->getType() == SideFX::SIDEFX_ANIM)
- _engine->getScriptManager()->deleteSideFx(_key);
+ if (nod && nod->getType() == ScriptingEffect::SCRIPTING_EFFECT_ANIM)
+ _scriptManager->deleteSideFx(_key);
return true;
}
@@ -629,8 +635,8 @@ bool ActionUnloadAnimation::execute() {
// ActionPlayAnimation
//////////////////////////////////////////////////////////////////////////////
-ActionPlayAnimation::ActionPlayAnimation(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
+ActionPlayAnimation::ActionPlayAnimation(ZVision *engine, int32 slotKey, const Common::String &line) :
+ ResultAction(engine, slotKey) {
_x = 0;
_y = 0;
_x2 = 0;
@@ -645,28 +651,35 @@ ActionPlayAnimation::ActionPlayAnimation(ZVision *engine, int32 slotkey, const C
// The two %*u are always 0 and dont seem to have a use
sscanf(line.c_str(),
- "%25s %u %u %u %u %u %u %d %*u %*u %d %d",
+ "%24s %u %u %u %u %u %u %d %*u %*u %d %d",
fileName, &_x, &_y, &_x2, &_y2, &_start, &_end, &_loopCount, &_mask, &_framerate);
- if (_mask > 0) {
- byte r, g, b;
- Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0).colorToRGB(_mask, r, g, b);
- _mask = _engine->_pixelFormat.RGBToColor(r, g, b);
- }
+ // Mask 0 means "no transparency" in this case. Since we use a common blitting
+ // code for images and animations, we set it to -1 to avoid confusion with
+ // color 0, which is used as a mask in some images
+ if (_mask == 0)
+ _mask = -1;
_fileName = Common::String(fileName);
+
+ // WORKAROUND for bug #6769, location me1g.scr (the "Alchemical debacle"
+ // video in ZGI). We only scale up by 2x, in AnimationEffect::process(),
+ // but the dimensions of the target frame are off by 2 pixels. We fix that
+ // here, so that the video can be scaled.
+ if (_fileName == "me1ga011.avi" && _y2 == 213)
+ _y2 = 215;
}
ActionPlayAnimation::~ActionPlayAnimation() {
- _engine->getScriptManager()->deleteSideFx(_slotKey);
+ _scriptManager->deleteSideFx(_slotKey);
}
bool ActionPlayAnimation::execute() {
- AnimationNode *nod = (AnimationNode *)_engine->getScriptManager()->getSideFX(_slotKey);
+ AnimationEffect *nod = (AnimationEffect *)_scriptManager->getSideFX(_slotKey);
if (!nod) {
- nod = new AnimationNode(_engine, _slotKey, _fileName, _mask, _framerate);
- _engine->getScriptManager()->addSideFX(nod);
+ nod = new AnimationEffect(_engine, _slotKey, _fileName, _mask, _framerate);
+ _scriptManager->addSideFX(nod);
} else
nod->stop();
@@ -680,8 +693,8 @@ bool ActionPlayAnimation::execute() {
// ActionPlayPreloadAnimation
//////////////////////////////////////////////////////////////////////////////
-ActionPlayPreloadAnimation::ActionPlayPreloadAnimation(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
+ActionPlayPreloadAnimation::ActionPlayPreloadAnimation(ZVision *engine, int32 slotKey, const Common::String &line) :
+ ResultAction(engine, slotKey) {
_controlKey = 0;
_x1 = 0;
_y1 = 0;
@@ -697,7 +710,7 @@ ActionPlayPreloadAnimation::ActionPlayPreloadAnimation(ZVision *engine, int32 sl
}
bool ActionPlayPreloadAnimation::execute() {
- AnimationNode *nod = (AnimationNode *)_engine->getScriptManager()->getSideFX(_controlKey);
+ AnimationEffect *nod = (AnimationEffect *)_scriptManager->getSideFX(_controlKey);
if (nod)
nod->addPlayNode(_slotKey, _x1, _y1, _x2, _y2, _startFrame, _endFrame, _loopCount);
@@ -716,11 +729,11 @@ bool ActionQuit::execute() {
}
//////////////////////////////////////////////////////////////////////////////
-// ActionRegion
+// ActionRegion - only used by Zork: Nemesis
//////////////////////////////////////////////////////////////////////////////
-ActionRegion::ActionRegion(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
+ActionRegion::ActionRegion(ZVision *engine, int32 slotKey, const Common::String &line) :
+ ResultAction(engine, slotKey) {
_delay = 0;
_type = 0;
_unk1 = 0;
@@ -738,20 +751,20 @@ ActionRegion::ActionRegion(ZVision *engine, int32 slotkey, const Common::String
}
ActionRegion::~ActionRegion() {
- _engine->getScriptManager()->killSideFx(_slotKey);
+ _scriptManager->killSideFx(_slotKey);
}
bool ActionRegion::execute() {
- if (_engine->getScriptManager()->getSideFX(_slotKey))
+ if (_scriptManager->getSideFX(_slotKey))
return true;
- Effect *effct = NULL;
+ GraphicsEffect *effect = NULL;
switch (_type) {
case 0: {
uint16 centerX, centerY, frames;
double amplitude, waveln, speed;
sscanf(_custom.c_str(), "%hu,%hu,%hu,%lf,%lf,%lf,", &centerX, &centerY, &frames, &amplitude, &waveln, &speed);
- effct = new WaveFx(_engine, _slotKey, _rect, _unk1, frames, centerX, centerY, amplitude, waveln, speed);
+ effect = new WaveFx(_engine, _slotKey, _rect, _unk1, frames, centerX, centerY, amplitude, waveln, speed);
}
break;
case 1: {
@@ -763,7 +776,7 @@ bool ActionRegion::execute() {
int8 minD;
int8 maxD;
EffectMap *_map = _engine->getRenderManager()->makeEffectMap(Common::Point(aX, aY), aD, _rect, &minD, &maxD);
- effct = new LightFx(_engine, _slotKey, _rect, _unk1, _map, atoi(_custom.c_str()), minD, maxD);
+ effect = new LightFx(_engine, _slotKey, _rect, _unk1, _map, atoi(_custom.c_str()), minD, maxD);
}
break;
case 9: {
@@ -779,16 +792,16 @@ bool ActionRegion::execute() {
_rect.setHeight(tempMask.h);
EffectMap *_map = _engine->getRenderManager()->makeEffectMap(tempMask, 0);
- effct = new FogFx(_engine, _slotKey, _rect, _unk1, _map, Common::String(buf));
+ effect = new FogFx(_engine, _slotKey, _rect, _unk1, _map, Common::String(buf));
}
break;
default:
break;
}
- if (effct) {
- _engine->getScriptManager()->addSideFX(new RegionNode(_engine, _slotKey, effct, _delay));
- _engine->getRenderManager()->addEffect(effct);
+ if (effect) {
+ _scriptManager->addSideFX(new RegionNode(_engine, _slotKey, effect, _delay));
+ _engine->getRenderManager()->addEffect(effect);
}
return true;
@@ -798,22 +811,21 @@ bool ActionRegion::execute() {
// ActionRandom
//////////////////////////////////////////////////////////////////////////////
-ActionRandom::ActionRandom(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
+ActionRandom::ActionRandom(ZVision *engine, int32 slotKey, const Common::String &line) :
+ ResultAction(engine, slotKey) {
char maxBuffer[64];
memset(maxBuffer, 0, 64);
sscanf(line.c_str(), "%s", maxBuffer);
- _max = new ValueSlot(_engine->getScriptManager(), maxBuffer);
+ _max = new ValueSlot(_scriptManager, maxBuffer);
}
ActionRandom::~ActionRandom() {
- if (_max)
- delete _max;
+ delete _max;
}
bool ActionRandom::execute() {
uint randNumber = _engine->getRandomSource()->getRandomNumber(_max->getValue());
- _engine->getScriptManager()->setStateValue(_slotKey, randNumber);
+ _scriptManager->setStateValue(_slotKey, randNumber);
return true;
}
@@ -821,15 +833,15 @@ bool ActionRandom::execute() {
// ActionRestoreGame
//////////////////////////////////////////////////////////////////////////////
-ActionRestoreGame::ActionRestoreGame(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
+ActionRestoreGame::ActionRestoreGame(ZVision *engine, int32 slotKey, const Common::String &line) :
+ ResultAction(engine, slotKey) {
char buf[128];
sscanf(line.c_str(), "%s", buf);
_fileName = Common::String(buf);
}
bool ActionRestoreGame::execute() {
- _engine->getSaveManager()->loadGame(_fileName);
+ _engine->getSaveManager()->loadGame(-1);
return false;
}
@@ -837,8 +849,8 @@ bool ActionRestoreGame::execute() {
// ActionRotateTo
//////////////////////////////////////////////////////////////////////////////
-ActionRotateTo::ActionRotateTo(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
+ActionRotateTo::ActionRotateTo(ZVision *engine, int32 slotKey, const Common::String &line) :
+ ResultAction(engine, slotKey) {
_time = 0;
_toPos = 0;
@@ -846,7 +858,7 @@ ActionRotateTo::ActionRotateTo(ZVision *engine, int32 slotkey, const Common::Str
}
bool ActionRotateTo::execute() {
- _engine->rotateTo(_toPos, _time);
+ _engine->getRenderManager()->rotateTo(_toPos, _time);
return true;
}
@@ -855,27 +867,18 @@ bool ActionRotateTo::execute() {
// ActionSetPartialScreen
//////////////////////////////////////////////////////////////////////////////
-ActionSetPartialScreen::ActionSetPartialScreen(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
+ActionSetPartialScreen::ActionSetPartialScreen(ZVision *engine, int32 slotKey, const Common::String &line) :
+ ResultAction(engine, slotKey) {
_x = 0;
_y = 0;
char fileName[25];
- int color;
- sscanf(line.c_str(), "%u %u %25s %*u %d", &_x, &_y, fileName, &color);
+ sscanf(line.c_str(), "%u %u %24s %*u %d", &_x, &_y, fileName, &_backgroundColor);
_fileName = Common::String(fileName);
- if (color >= 0) {
- byte r, g, b;
- Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0).colorToRGB(color, r, g, b);
- _backgroundColor = _engine->_pixelFormat.RGBToColor(r, g, b);
- } else {
- _backgroundColor = color;
- }
-
- if (color > 65535) {
+ if (_backgroundColor > 65535) {
warning("Background color for ActionSetPartialScreen is bigger than a uint16");
}
}
@@ -904,10 +907,10 @@ bool ActionSetPartialScreen::execute() {
// ActionSetScreen
//////////////////////////////////////////////////////////////////////////////
-ActionSetScreen::ActionSetScreen(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
+ActionSetScreen::ActionSetScreen(ZVision *engine, int32 slotKey, const Common::String &line) :
+ ResultAction(engine, slotKey) {
char fileName[25];
- sscanf(line.c_str(), "%25s", fileName);
+ sscanf(line.c_str(), "%24s", fileName);
_fileName = Common::String(fileName);
}
@@ -919,35 +922,17 @@ bool ActionSetScreen::execute() {
}
//////////////////////////////////////////////////////////////////////////////
-// ActionSetVenus
-//////////////////////////////////////////////////////////////////////////////
-
-ActionSetVenus::ActionSetVenus(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
- _key = 0;
-
- sscanf(line.c_str(), "%d", &_key);
-}
-
-bool ActionSetVenus::execute() {
- if (_engine->getScriptManager()->getStateValue(_key))
- _engine->getScriptManager()->setStateValue(StateKey_Venus, _key);
-
- return true;
-}
-
-//////////////////////////////////////////////////////////////////////////////
// ActionStop
//////////////////////////////////////////////////////////////////////////////
-ActionStop::ActionStop(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
+ActionStop::ActionStop(ZVision *engine, int32 slotKey, const Common::String &line) :
+ ResultAction(engine, slotKey) {
_key = 0;
sscanf(line.c_str(), "%u", &_key);
}
bool ActionStop::execute() {
- _engine->getScriptManager()->stopSideFx(_key);
+ _scriptManager->stopSideFx(_key);
return true;
}
@@ -955,8 +940,8 @@ bool ActionStop::execute() {
// ActionStreamVideo
//////////////////////////////////////////////////////////////////////////////
-ActionStreamVideo::ActionStreamVideo(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
+ActionStreamVideo::ActionStreamVideo(ZVision *engine, int32 slotKey, const Common::String &line) :
+ ResultAction(engine, slotKey) {
_x1 = 0;
_x2 = 0;
_y1 = 0;
@@ -966,42 +951,69 @@ ActionStreamVideo::ActionStreamVideo(ZVision *engine, int32 slotkey, const Commo
char fileName[25];
uint skipline = 0; //skipline - render video with skip every second line, not skippable.
- sscanf(line.c_str(), "%25s %u %u %u %u %u %u", fileName, &_x1, &_y1, &_x2, &_y2, &_flags, &skipline);
+ sscanf(line.c_str(), "%24s %u %u %u %u %u %u", fileName, &_x1, &_y1, &_x2, &_y2, &_flags, &skipline);
_fileName = Common::String(fileName);
_skippable = true;
}
bool ActionStreamVideo::execute() {
- ZorkAVIDecoder decoder;
- Common::File *_file = _engine->getSearchManager()->openFile(_fileName);
-
- if (_file) {
- if (!decoder.loadStream(_file)) {
+ Video::VideoDecoder *decoder;
+ Common::Rect destRect = Common::Rect(_x1, _y1, _x2 + 1, _y2 + 1);
+ Common::String subname = _fileName;
+ subname.setChar('s', subname.size() - 3);
+ subname.setChar('u', subname.size() - 2);
+ subname.setChar('b', subname.size() - 1);
+ bool subtitleExists = _engine->getSearchManager()->hasFile(subname);
+ bool switchToHires = false;
+
+// NOTE: We only show the hires MPEG2 videos when libmpeg2 is compiled in,
+// otherwise we fall back to the lowres ones
+#ifdef USE_MPEG2
+ Common::String hiresFileName = _fileName;
+ hiresFileName.setChar('d', hiresFileName.size() - 8);
+ hiresFileName.setChar('v', hiresFileName.size() - 3);
+ hiresFileName.setChar('o', hiresFileName.size() - 2);
+ hiresFileName.setChar('b', hiresFileName.size() - 1);
+
+ if (_scriptManager->getStateValue(StateKey_MPEGMovies) == 1 &&_engine->getSearchManager()->hasFile(hiresFileName)) {
+ // TODO: Enable once AC3 support is implemented
+ if (!_engine->getSearchManager()->hasFile(_fileName)) // Check for the regular video
return true;
- }
-
- _engine->getCursorManager()->showMouse(false);
+ warning("The hires videos of the DVD version of ZGI aren't supported yet, using lowres");
+ //_fileName = hiresFileName;
+ //switchToHires = true;
+ } else if (!_engine->getSearchManager()->hasFile(_fileName))
+ return true;
+#else
+ if (!_engine->getSearchManager()->hasFile(_fileName))
+ return true;
+#endif
- Common::Rect destRect = Common::Rect(_x1, _y1, _x2 + 1, _y2 + 1);
+ decoder = _engine->loadAnimation(_fileName);
+ Subtitle *sub = (subtitleExists) ? new Subtitle(_engine, subname, switchToHires) : NULL;
- Common::String subname = _fileName;
- subname.setChar('s', subname.size() - 3);
- subname.setChar('u', subname.size() - 2);
- subname.setChar('b', subname.size() - 1);
+ _engine->getCursorManager()->showMouse(false);
- Subtitle *sub = NULL;
+ if (switchToHires) {
+ _engine->initHiresScreen();
+ destRect = Common::Rect(40, -40, 760, 440);
+ Common::Rect workingWindow = _engine->_workingWindow;
+ workingWindow.translate(0, -40);
+ _engine->getRenderManager()->initSubArea(HIRES_WINDOW_WIDTH, HIRES_WINDOW_HEIGHT, workingWindow);
+ }
- if (_engine->getSearchManager()->hasFile(subname))
- sub = new Subtitle(_engine, subname);
+ _engine->playVideo(*decoder, destRect, _skippable, sub);
- _engine->playVideo(decoder, destRect, _skippable, sub);
+ if (switchToHires) {
+ _engine->initScreen();
+ _engine->getRenderManager()->initSubArea(WINDOW_WIDTH, WINDOW_HEIGHT, _engine->_workingWindow);
+ }
- _engine->getCursorManager()->showMouse(true);
+ _engine->getCursorManager()->showMouse(true);
- if (sub)
- delete sub;
- }
+ delete decoder;
+ delete sub;
return true;
}
@@ -1010,31 +1022,27 @@ bool ActionStreamVideo::execute() {
// ActionSyncSound
//////////////////////////////////////////////////////////////////////////////
-ActionSyncSound::ActionSyncSound(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
+ActionSyncSound::ActionSyncSound(ZVision *engine, int32 slotKey, const Common::String &line) :
+ ResultAction(engine, slotKey) {
_syncto = 0;
char fileName[25];
int notUsed = 0;
- sscanf(line.c_str(), "%d %d %25s", &_syncto, &notUsed, fileName);
+ sscanf(line.c_str(), "%d %d %24s", &_syncto, &notUsed, fileName);
_fileName = Common::String(fileName);
}
bool ActionSyncSound::execute() {
- SideFX *fx = _engine->getScriptManager()->getSideFX(_syncto);
+ ScriptingEffect *fx = _scriptManager->getSideFX(_syncto);
if (!fx)
return true;
- if (!(fx->getType() & SideFX::SIDEFX_ANIM))
+ if (!(fx->getType() & ScriptingEffect::SCRIPTING_EFFECT_ANIM))
return true;
- AnimationNode *animnode = (AnimationNode *)fx;
- if (animnode->getFrameDelay() > 200) // Hack for fix incorrect framedelay in some animpreload
- animnode->setNewFrameDelay(66); // ~15fps
-
- _engine->getScriptManager()->addSideFX(new SyncSoundNode(_engine, _slotKey, _fileName, _syncto));
+ _scriptManager->addSideFX(new SyncSoundNode(_engine, _slotKey, _fileName, _syncto));
return true;
}
@@ -1042,24 +1050,23 @@ bool ActionSyncSound::execute() {
// ActionTimer
//////////////////////////////////////////////////////////////////////////////
-ActionTimer::ActionTimer(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
+ActionTimer::ActionTimer(ZVision *engine, int32 slotKey, const Common::String &line) :
+ ResultAction(engine, slotKey) {
char timeBuffer[64];
memset(timeBuffer, 0, 64);
sscanf(line.c_str(), "%s", timeBuffer);
- _time = new ValueSlot(_engine->getScriptManager(), timeBuffer);
+ _time = new ValueSlot(_scriptManager, timeBuffer);
}
ActionTimer::~ActionTimer() {
- if (_time)
- delete _time;
- _engine->getScriptManager()->killSideFx(_slotKey);
+ delete _time;
+ _scriptManager->killSideFx(_slotKey);
}
bool ActionTimer::execute() {
- if (_engine->getScriptManager()->getSideFX(_slotKey))
+ if (_scriptManager->getSideFX(_slotKey))
return true;
- _engine->getScriptManager()->addSideFX(new TimerNode(_engine, _slotKey, _time->getValue()));
+ _scriptManager->addSideFX(new TimerNode(_engine, _slotKey, _time->getValue()));
return true;
}
@@ -1067,25 +1074,25 @@ bool ActionTimer::execute() {
// ActionTtyText
//////////////////////////////////////////////////////////////////////////////
-ActionTtyText::ActionTtyText(ZVision *engine, int32 slotkey, const Common::String &line) :
- ResultAction(engine, slotkey) {
+ActionTtyText::ActionTtyText(ZVision *engine, int32 slotKey, const Common::String &line) :
+ ResultAction(engine, slotKey) {
_delay = 0;
char filename[64];
int32 x1 = 0, y1 = 0, x2 = 0, y2 = 0;
- sscanf(line.c_str(), "%d %d %d %d %64s %u", &x1, &y1, &x2, &y2, filename, &_delay);
+ sscanf(line.c_str(), "%d %d %d %d %63s %u", &x1, &y1, &x2, &y2, filename, &_delay);
_r = Common::Rect(x1, y1, x2, y2);
_filename = Common::String(filename);
}
ActionTtyText::~ActionTtyText() {
- _engine->getScriptManager()->killSideFx(_slotKey);
+ _scriptManager->killSideFx(_slotKey);
}
bool ActionTtyText::execute() {
- if (_engine->getScriptManager()->getSideFX(_slotKey))
+ if (_scriptManager->getSideFX(_slotKey))
return true;
- _engine->getScriptManager()->addSideFX(new ttyTextNode(_engine, _slotKey, _filename, _r, _delay));
+ _scriptManager->addSideFX(new ttyTextNode(_engine, _slotKey, _filename, _r, _delay));
return true;
}
diff --git a/engines/zvision/scripting/actions.h b/engines/zvision/scripting/actions.h
index 292e25e19c..bde1baa291 100644
--- a/engines/zvision/scripting/actions.h
+++ b/engines/zvision/scripting/actions.h
@@ -32,6 +32,7 @@ namespace ZVision {
// Forward declaration of ZVision. This file is included before ZVision is declared
class ZVision;
+class ScriptManager;
class ValueSlot;
/**
@@ -40,7 +41,7 @@ class ValueSlot;
*/
class ResultAction {
public:
- ResultAction(ZVision *engine, int32 slotkey) : _engine(engine), _slotKey(slotkey) {}
+ ResultAction(ZVision *engine, int32 slotkey);
virtual ~ResultAction() {}
/**
* This is called by the script system whenever a Puzzle's criteria are found to be true.
@@ -53,6 +54,7 @@ public:
virtual bool execute() = 0;
protected:
ZVision *_engine;
+ ScriptManager *_scriptManager;
int32 _slotKey;
};
@@ -124,14 +126,6 @@ private:
uint8 _action;
};
-class ActionDebug : public ResultAction {
-public:
- ActionDebug(ZVision *engine, int32 slotkey, const Common::String &line);
- bool execute();
-
-private:
-};
-
class ActionDelayRender : public ResultAction {
public:
ActionDelayRender(ZVision *engine, int32 slotkey, const Common::String &line);
@@ -150,15 +144,6 @@ private:
uint32 _key;
};
-class ActionDisableVenus : public ResultAction {
-public:
- ActionDisableVenus(ZVision *engine, int32 slotkey, const Common::String &line);
- bool execute();
-
-private:
- int32 _key;
-};
-
class ActionDisplayMessage : public ResultAction {
public:
ActionDisplayMessage(ZVision *engine, int32 slotkey, const Common::String &line);
@@ -241,7 +226,7 @@ public:
private:
Common::String _fileName;
bool _loop;
- byte _volume;
+ ValueSlot *_volume;
bool _universe;
bool _midi;
int8 _note;
@@ -284,7 +269,6 @@ public:
bool execute();
private:
- uint32 _animationKey;
uint32 _controlKey;
uint32 _x1;
uint32 _y1;
@@ -338,7 +322,7 @@ private:
uint16 _unk2;
};
-// TODO: See if this exists in ZGI. It doesn't in ZNem
+// Only used by ZGI (locations cd6e, cd6k, dg2f, dg4e, dv1j)
class ActionUnloadAnimation : public ResultAction {
public:
ActionUnloadAnimation(ZVision *engine, int32 slotkey, const Common::String &line);
@@ -397,15 +381,6 @@ private:
Common::String _fileName;
};
-class ActionSetVenus : public ResultAction {
-public:
- ActionSetVenus(ZVision *engine, int32 slotkey, const Common::String &line);
- bool execute();
-
-private:
- int32 _key;
-};
-
class ActionStop : public ResultAction {
public:
ActionStop(ZVision *engine, int32 slotkey, const Common::String &line);
diff --git a/engines/zvision/scripting/control.cpp b/engines/zvision/scripting/control.cpp
index 127f35ef12..81123eb99b 100644
--- a/engines/zvision/scripting/control.cpp
+++ b/engines/zvision/scripting/control.cpp
@@ -72,6 +72,7 @@ void Control::parsePanoramaControl(ZVision *engine, Common::SeekableReadStream &
renderTable->generateRenderTable();
}
+// Only used in Zork Nemesis, handles tilt controls (ZGI doesn't have a tilt view)
void Control::parseTiltControl(ZVision *engine, Common::SeekableReadStream &stream) {
RenderTable *renderTable = engine->getRenderManager()->getRenderTable();
renderTable->setRenderState(RenderTable::TILT);
diff --git a/engines/zvision/scripting/control.h b/engines/zvision/scripting/control.h
index 803d0cf1ce..108b83fd00 100644
--- a/engines/zvision/scripting/control.h
+++ b/engines/zvision/scripting/control.h
@@ -36,6 +36,11 @@ namespace ZVision {
class ZVision;
+/**
+ * The base class for all Controls.
+ *
+ * Controls are the things that the user interacts with. Ex: A lever on the door
+ */
class Control {
public:
diff --git a/engines/zvision/scripting/controls/fist_control.cpp b/engines/zvision/scripting/controls/fist_control.cpp
index 34a64b4298..f79c82dc79 100644
--- a/engines/zvision/scripting/controls/fist_control.cpp
+++ b/engines/zvision/scripting/controls/fist_control.cpp
@@ -46,10 +46,6 @@ FistControl::FistControl(ZVision *engine, uint32 key, Common::SeekableReadStream
_order = 0;
_fistnum = 0;
- _frameCur = -1;
- _frameEnd = -1;
- _frameTime = 0;
- _lastRenderedFrame = -1;
_animationId = 0;
clearFistArray(_fistsUp);
@@ -95,41 +91,28 @@ FistControl::~FistControl() {
_entries.clear();
}
-void FistControl::renderFrame(uint frameNumber) {
- if ((int32)frameNumber == _lastRenderedFrame)
- return;
-
- _lastRenderedFrame = frameNumber;
-
- const Graphics::Surface *frameData;
-
- if (_animation) {
- _animation->seekToFrame(frameNumber);
- frameData = _animation->decodeNextFrame();
- if (frameData)
- _engine->getRenderManager()->blitSurfaceToBkgScaled(*frameData, _anmRect);
- }
-}
-
bool FistControl::process(uint32 deltaTimeInMillis) {
if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
return false;
- if (_frameCur >= 0 && _frameEnd >= 0)
- if (_frameCur <= _frameEnd) {
- _frameTime -= deltaTimeInMillis;
-
- if (_frameTime <= 0) {
- _frameTime = 1000.0 / _animation->getDuration().framerate();
-
- renderFrame(_frameCur);
-
- _frameCur++;
+ if (_animation && _animation->isPlaying()) {
+ if (_animation->endOfVideo()) {
+ _animation->stop();
+ _engine->getScriptManager()->setStateValue(_animationId, 2);
+ return false;
+ }
- if (_frameCur > _frameEnd)
- _engine->getScriptManager()->setStateValue(_animationId, 2);
- }
+ if (_animation->needsUpdate()) {
+ const Graphics::Surface *frameData = _animation->decodeNextFrame();
+ if (frameData)
+ // WORKAROUND: Ignore the target frame dimensions for the finger animations.
+ // The target dimensions specify an area smaller than expected, thus if we
+ // scale the finger videos to fit these dimensions, they are not aligned
+ // correctly. Not scaling these videos yields a result identical to the
+ // original. Fixes bug #6784.
+ _engine->getRenderManager()->blitSurfaceToBkg(*frameData, _anmRect.left, _anmRect.top);
}
+ }
return false;
}
@@ -160,9 +143,12 @@ bool FistControl::onMouseUp(const Common::Point &screenSpacePos, const Common::P
for (int i = 0; i < _numEntries; i++)
if (_entries[i]._bitsStrt == oldStatus && _entries[i]._bitsEnd == _fiststatus) {
- _frameCur = _entries[i]._anmStrt;
- _frameEnd = _entries[i]._anmEnd;
- _frameTime = 0;
+ if (_animation) {
+ _animation->stop();
+ _animation->seekToFrame(_entries[i]._anmStrt);
+ _animation->setEndFrame(_entries[i]._anmEnd);
+ _animation->start();
+ }
_engine->getScriptManager()->setStateValue(_animationId, 1);
_engine->getScriptManager()->setStateValue(_soundKey, _entries[i]._sound);
diff --git a/engines/zvision/scripting/controls/fist_control.h b/engines/zvision/scripting/controls/fist_control.h
index 0a6b977ead..d7cbcb1f71 100644
--- a/engines/zvision/scripting/controls/fist_control.h
+++ b/engines/zvision/scripting/controls/fist_control.h
@@ -34,6 +34,7 @@ namespace Video {
namespace ZVision {
+// Only used in Zork Nemesis, handles the door lock puzzle with the skeletal fingers (td9e)
class FistControl : public Control {
public:
FistControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
@@ -63,10 +64,6 @@ private:
Video::VideoDecoder *_animation;
Common::Rect _anmRect;
int32 _soundKey;
- int32 _frameCur;
- int32 _frameEnd;
- int32 _frameTime;
- int32 _lastRenderedFrame;
int32 _animationId;
public:
@@ -75,7 +72,6 @@ public:
bool process(uint32 deltaTimeInMillis);
private:
- void renderFrame(uint frameNumber);
void readDescFile(const Common::String &fileName);
void clearFistArray(Common::Array< Common::Array<Common::Rect> > &arr);
uint32 readBits(const char *str);
diff --git a/engines/zvision/scripting/controls/hotmov_control.cpp b/engines/zvision/scripting/controls/hotmov_control.cpp
index e77272ec73..182447a990 100644
--- a/engines/zvision/scripting/controls/hotmov_control.cpp
+++ b/engines/zvision/scripting/controls/hotmov_control.cpp
@@ -41,10 +41,7 @@ HotMovControl::HotMovControl(ZVision *engine, uint32 key, Common::SeekableReadSt
: Control(engine, key, CONTROL_HOTMOV) {
_animation = NULL;
_cycle = 0;
- _curFrame = -1;
- _lastRenderedFrame = -1;
_frames.clear();
- _frameTime = 0;
_cyclesCount = 0;
_framesCount = 0;
@@ -78,6 +75,7 @@ HotMovControl::HotMovControl(ZVision *engine, uint32 key, Common::SeekableReadSt
sscanf(values.c_str(), "%s", filename);
values = Common::String(filename);
_animation = _engine->loadAnimation(values);
+ _animation->start();
} else if (param.matchString("venus_id", true)) {
_venusId = atoi(values.c_str());
}
@@ -95,41 +93,26 @@ HotMovControl::~HotMovControl() {
_frames.clear();
}
-void HotMovControl::renderFrame(uint frameNumber) {
- if ((int)frameNumber == _lastRenderedFrame)
- return;
-
- _lastRenderedFrame = frameNumber;
-
- const Graphics::Surface *frameData;
-
- if (_animation) {
- _animation->seekToFrame(frameNumber);
- frameData = _animation->decodeNextFrame();
- if (frameData)
- _engine->getRenderManager()->blitSurfaceToBkgScaled(*frameData, _rectangle);
- }
-}
-
bool HotMovControl::process(uint32 deltaTimeInMillis) {
if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
return false;
if (_cycle < _cyclesCount) {
- _frameTime -= deltaTimeInMillis;
+ if (_animation && _animation->endOfVideo()) {
+ _cycle++;
- if (_frameTime <= 0) {
- _curFrame++;
- if (_curFrame >= _framesCount) {
- _curFrame = 0;
- _cycle++;
- }
- if (_cycle != _cyclesCount)
- renderFrame(_curFrame);
- else
+ if (_cycle == _cyclesCount) {
_engine->getScriptManager()->setStateValue(_key, 2);
+ return false;
+ }
+
+ _animation->rewind();
+ }
- _frameTime = 1000.0 / _animation->getDuration().framerate();
+ if (_animation && _animation->needsUpdate()) {
+ const Graphics::Surface *frameData = _animation->decodeNextFrame();
+ if (frameData)
+ _engine->getRenderManager()->blitSurfaceToBkgScaled(*frameData, _rectangle);
}
}
@@ -140,8 +123,11 @@ bool HotMovControl::onMouseMove(const Common::Point &screenSpacePos, const Commo
if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
return false;
+ if (!_animation)
+ return false;
+
if (_cycle < _cyclesCount) {
- if (_frames[_curFrame].contains(backgroundImageSpacePos)) {
+ if (_frames[_animation->getCurFrame()].contains(backgroundImageSpacePos)) {
_engine->getCursorManager()->changeCursor(CursorIndex_Active);
return true;
}
@@ -154,8 +140,11 @@ bool HotMovControl::onMouseUp(const Common::Point &screenSpacePos, const Common:
if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
return false;
+ if (!_animation)
+ return false;
+
if (_cycle < _cyclesCount) {
- if (_frames[_curFrame].contains(backgroundImageSpacePos)) {
+ if (_frames[_animation->getCurFrame()].contains(backgroundImageSpacePos)) {
setVenus();
_engine->getScriptManager()->setStateValue(_key, 1);
return true;
diff --git a/engines/zvision/scripting/controls/hotmov_control.h b/engines/zvision/scripting/controls/hotmov_control.h
index b18d44c7a6..99d1fd0979 100644
--- a/engines/zvision/scripting/controls/hotmov_control.h
+++ b/engines/zvision/scripting/controls/hotmov_control.h
@@ -34,6 +34,7 @@ namespace Video {
namespace ZVision {
+// Only used in Zork Nemesis, handles movies where the player needs to click on something (mj7g, vw3g)
class HotMovControl : public Control {
public:
HotMovControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
@@ -41,9 +42,6 @@ public:
private:
int32 _framesCount;
- int32 _frameTime;
- int32 _curFrame;
- int32 _lastRenderedFrame;
int32 _cycle;
int32 _cyclesCount;
Video::VideoDecoder *_animation;
@@ -55,7 +53,6 @@ public:
bool process(uint32 deltaTimeInMillis);
private:
- void renderFrame(uint frameNumber);
void readHsFile(const Common::String &fileName);
};
diff --git a/engines/zvision/scripting/controls/input_control.cpp b/engines/zvision/scripting/controls/input_control.cpp
index e75cc15743..9525333ef0 100644
--- a/engines/zvision/scripting/controls/input_control.cpp
+++ b/engines/zvision/scripting/controls/input_control.cpp
@@ -39,16 +39,14 @@ namespace ZVision {
InputControl::InputControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
: Control(engine, key, CONTROL_INPUT),
+ _background(0),
_nextTabstop(0),
_focused(false),
_textChanged(false),
- _cursorOffset(0),
_enterPressed(false),
_readOnly(false),
_txtWidth(0),
- _animation(NULL),
- _frameDelay(0),
- _frame(-1) {
+ _animation(NULL) {
// Loop until we find the closing brace
Common::String line = stream.readLine();
_engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
@@ -80,13 +78,13 @@ InputControl::InputControl(ZVision *engine, uint32 key, Common::SeekableReadStre
sscanf(values.c_str(), "%u", &fontFormatNumber);
- _stringInit.readAllStyle(_engine->getStringManager()->getTextLine(fontFormatNumber));
+ _stringInit.readAllStyles(_engine->getStringManager()->getTextLine(fontFormatNumber));
} else if (param.matchString("chooser_init_string", true)) {
uint fontFormatNumber;
sscanf(values.c_str(), "%u", &fontFormatNumber);
- _stringChooserInit.readAllStyle(_engine->getStringManager()->getTextLine(fontFormatNumber));
+ _stringChooserInit.readAllStyles(_engine->getStringManager()->getTextLine(fontFormatNumber));
} else if (param.matchString("next_tabstop", true)) {
sscanf(values.c_str(), "%u", &_nextTabstop);
} else if (param.matchString("cursor_dimensions", true)) {
@@ -96,11 +94,10 @@ InputControl::InputControl(ZVision *engine, uint32 key, Common::SeekableReadStre
} else if (param.matchString("cursor_animation", true)) {
char fileName[25];
- sscanf(values.c_str(), "%25s %*u", fileName);
+ sscanf(values.c_str(), "%24s %*u", fileName);
_animation = _engine->loadAnimation(fileName);
- _frame = -1;
- _frameDelay = 0;
+ _animation->start();
} else if (param.matchString("focus", true)) {
_focused = true;
_engine->getScriptManager()->setFocusControlKey(_key);
@@ -112,6 +109,15 @@ InputControl::InputControl(ZVision *engine, uint32 key, Common::SeekableReadStre
_engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
getParams(line, param, values);
}
+
+ _maxTxtWidth = _textRectangle.width();
+ if (_animation)
+ _maxTxtWidth -= _animation->getWidth();
+}
+
+InputControl::~InputControl() {
+ _background->free();
+ delete _background;
}
bool InputControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
@@ -194,36 +200,42 @@ bool InputControl::process(uint32 deltaTimeInMillis) {
if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
return false;
+ if (!_background) {
+ _background = _engine->getRenderManager()->getBkgRect(_textRectangle);
+ }
+
// First see if we need to render the text
if (_textChanged) {
// Blit the text using the RenderManager
Graphics::Surface txt;
- txt.create(_textRectangle.width(), _textRectangle.height(), _engine->_pixelFormat);
+ txt.copyFrom(*_background);
+
+ int32 oldTxtWidth = _txtWidth;
if (!_readOnly || !_focused)
- _txtWidth = _engine->getTextRenderer()->drawTxt(_currentInputText, _stringInit, txt);
+ _txtWidth = _engine->getTextRenderer()->drawText(_currentInputText, _stringInit, txt);
else
- _txtWidth = _engine->getTextRenderer()->drawTxt(_currentInputText, _stringChooserInit, txt);
+ _txtWidth = _engine->getTextRenderer()->drawText(_currentInputText, _stringChooserInit, txt);
- _engine->getRenderManager()->blitSurfaceToBkg(txt, _textRectangle.left, _textRectangle.top);
+ if (_readOnly || _txtWidth <= _maxTxtWidth)
+ _engine->getRenderManager()->blitSurfaceToBkg(txt, _textRectangle.left, _textRectangle.top);
+ else {
+ // Assume the last character caused the overflow.
+ _currentInputText.deleteLastChar();
+ _txtWidth = oldTxtWidth;
+ }
txt.free();
}
if (_animation && !_readOnly && _focused) {
- bool needDraw = true;// = _textChanged;
- _frameDelay -= deltaTimeInMillis;
- if (_frameDelay <= 0) {
- _frame = (_frame + 1) % _animation->getFrameCount();
- _frameDelay = 1000.0 / _animation->getDuration().framerate();
- needDraw = true;
- }
+ if (_animation->endOfVideo())
+ _animation->rewind();
- if (needDraw) {
- _animation->seekToFrame(_frame);
+ if (_animation->needsUpdate()) {
const Graphics::Surface *srf = _animation->decodeNextFrame();
- uint32 xx = _textRectangle.left + _txtWidth;
+ int16 xx = _textRectangle.left + _txtWidth;
if (xx >= _textRectangle.left + (_textRectangle.width() - (int16)_animation->getWidth()))
xx = _textRectangle.left + _textRectangle.width() - (int16)_animation->getWidth();
_engine->getRenderManager()->blitSurfaceToBkg(*srf, xx, _textRectangle.top);
diff --git a/engines/zvision/scripting/controls/input_control.h b/engines/zvision/scripting/controls/input_control.h
index 99f7f5287d..6abdb3c692 100644
--- a/engines/zvision/scripting/controls/input_control.h
+++ b/engines/zvision/scripting/controls/input_control.h
@@ -38,25 +38,25 @@ namespace ZVision {
class InputControl : public Control {
public:
InputControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
+ ~InputControl();
private:
+ Graphics::Surface *_background;
Common::Rect _textRectangle;
Common::Rect _headerRectangle;
- cTxtStyle _stringInit;
- cTxtStyle _stringChooserInit;
+ TextStyleState _stringInit;
+ TextStyleState _stringChooserInit;
uint32 _nextTabstop;
bool _focused;
Common::String _currentInputText;
bool _textChanged;
- uint _cursorOffset;
bool _enterPressed;
bool _readOnly;
int16 _txtWidth;
+ int16 _maxTxtWidth;
Video::VideoDecoder *_animation;
- int32 _frameDelay;
- int16 _frame;
public:
void focus() {
diff --git a/engines/zvision/scripting/controls/lever_control.cpp b/engines/zvision/scripting/controls/lever_control.cpp
index 8faa18357c..0f105b424c 100644
--- a/engines/zvision/scripting/controls/lever_control.cpp
+++ b/engines/zvision/scripting/controls/lever_control.cpp
@@ -64,12 +64,12 @@ LeverControl::LeverControl(ZVision *engine, uint32 key, Common::SeekableReadStre
while (!stream.eos() && !line.contains('}')) {
if (param.matchString("descfile", true)) {
char levFileName[25];
- sscanf(values.c_str(), "%25s", levFileName);
+ sscanf(values.c_str(), "%24s", levFileName);
parseLevFile(levFileName);
} else if (param.matchString("cursor", true)) {
char cursorName[25];
- sscanf(values.c_str(), "%25s", cursorName);
+ sscanf(values.c_str(), "%24s", cursorName);
_cursor = _engine->getCursorManager()->getCursorId(Common::String(cursorName));
}
@@ -232,10 +232,13 @@ bool LeverControl::onMouseMove(const Common::Point &screenSpacePos, const Common
if (angle >= (int)iter->angle - ANGLE_DELTA && angle <= (int)iter->angle + ANGLE_DELTA) {
_currentFrame = iter->toFrame;
renderFrame(_currentFrame);
+ _engine->getScriptManager()->setStateValue(_key, _currentFrame);
break;
}
}
}
+ _engine->getCursorManager()->changeCursor(_cursor);
+ cursorWasChanged = true;
} else if (_frameInfo[_currentFrame].hotspot.contains(backgroundImageSpacePos)) {
_engine->getCursorManager()->changeCursor(_cursor);
cursorWasChanged = true;
diff --git a/engines/zvision/scripting/controls/lever_control.h b/engines/zvision/scripting/controls/lever_control.h
index fdf4a649dc..8787234c51 100644
--- a/engines/zvision/scripting/controls/lever_control.h
+++ b/engines/zvision/scripting/controls/lever_control.h
@@ -34,6 +34,7 @@ namespace Video {
namespace ZVision {
+// Only used in Zork Nemesis, handles draggable levers (te2e, tm7e, tp2e, tt2e, tz2e)
class LeverControl : public Control {
public:
LeverControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
diff --git a/engines/zvision/scripting/controls/paint_control.cpp b/engines/zvision/scripting/controls/paint_control.cpp
index df06bb814e..62dde3d170 100644
--- a/engines/zvision/scripting/controls/paint_control.cpp
+++ b/engines/zvision/scripting/controls/paint_control.cpp
@@ -114,12 +114,18 @@ PaintControl::PaintControl(ZVision *engine, uint32 key, Common::SeekableReadStre
PaintControl::~PaintControl() {
// Clear the state value back to 0
//_engine->getScriptManager()->setStateValue(_key, 0);
- if (_paint)
+ if (_paint) {
+ _paint->free();
delete _paint;
- if (_brush)
+ }
+ if (_brush) {
+ _brush->free();
delete _brush;
- if (_bkg)
+ }
+ if (_bkg) {
+ _bkg->free();
delete _bkg;
+ }
}
bool PaintControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
diff --git a/engines/zvision/scripting/controls/paint_control.h b/engines/zvision/scripting/controls/paint_control.h
index 8097290ac2..8c01f0e68a 100644
--- a/engines/zvision/scripting/controls/paint_control.h
+++ b/engines/zvision/scripting/controls/paint_control.h
@@ -32,6 +32,7 @@
namespace ZVision {
+// Only used in Zork Nemesis, handles the painting puzzle screen in Lucien's room in Irondune (ch4g)
class PaintControl : public Control {
public:
PaintControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
diff --git a/engines/zvision/scripting/controls/safe_control.cpp b/engines/zvision/scripting/controls/safe_control.cpp
index 71be692431..4d2a91a1ad 100644
--- a/engines/zvision/scripting/controls/safe_control.cpp
+++ b/engines/zvision/scripting/controls/safe_control.cpp
@@ -49,10 +49,7 @@ SafeControl::SafeControl(ZVision *engine, uint32 key, Common::SeekableReadStream
_outerRadiusSqr = 0;
_zeroPointer = 0;
_startPointer = 0;
- _curFrame = -1;
_targetFrame = 0;
- _frameTime = 0;
- _lastRenderedFrame = -1;
// Loop until we find the closing brace
Common::String line = stream.readLine();
@@ -64,6 +61,7 @@ SafeControl::SafeControl(ZVision *engine, uint32 key, Common::SeekableReadStream
while (!stream.eos() && !line.contains('}')) {
if (param.matchString("animation", true)) {
_animation = _engine->loadAnimation(values);
+ _animation->start();
} else if (param.matchString("rectangle", true)) {
int x;
int y;
@@ -104,7 +102,9 @@ SafeControl::SafeControl(ZVision *engine, uint32 key, Common::SeekableReadStream
_engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
getParams(line, param, values);
}
- renderFrame(_curState);
+
+ if (_animation)
+ _animation->seekToFrame(_curState);
}
SafeControl::~SafeControl() {
@@ -113,44 +113,22 @@ SafeControl::~SafeControl() {
}
-void SafeControl::renderFrame(uint frameNumber) {
- if (frameNumber == 0) {
- _lastRenderedFrame = frameNumber;
- } else if ((int16)frameNumber < _lastRenderedFrame) {
- _lastRenderedFrame = frameNumber;
- frameNumber = (_statesCount * 2) - frameNumber;
- } else {
- _lastRenderedFrame = frameNumber;
- }
-
- const Graphics::Surface *frameData;
- int x = _rectangle.left;
- int y = _rectangle.top;
-
- _animation->seekToFrame(frameNumber);
- frameData = _animation->decodeNextFrame();
- if (frameData)
- _engine->getRenderManager()->blitSurfaceToBkg(*frameData, x, y);
-}
-
bool SafeControl::process(uint32 deltaTimeInMillis) {
if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
return false;
- if (_curFrame != _targetFrame) {
- _frameTime -= deltaTimeInMillis;
-
- if (_frameTime <= 0) {
- if (_curFrame < _targetFrame) {
- _curFrame++;
- renderFrame(_curFrame);
- } else if (_curFrame > _targetFrame) {
- _curFrame--;
- renderFrame(_curFrame);
- }
- _frameTime = 1000.0 / _animation->getDuration().framerate();
- }
+ if (_animation && _animation->getCurFrame() != _targetFrame && _animation->needsUpdate()) {
+ // If we're past the target frame, move back one
+ if (_animation->getCurFrame() > _targetFrame)
+ _animation->seekToFrame(_animation->getCurFrame() - 1);
+
+ const Graphics::Surface *frameData = _animation->decodeNextFrame();
+ if (_animation->getCurFrame() == _targetFrame)
+ _engine->getScriptManager()->setStateValue(_key, _curState);
+ if (frameData)
+ _engine->getRenderManager()->blitSurfaceToBkg(*frameData, _rectangle.left, _rectangle.top);
}
+
return false;
}
@@ -187,13 +165,12 @@ bool SafeControl::onMouseUp(const Common::Point &screenSpacePos, const Common::P
int16 tmp2 = (m_state + _curState - _zeroPointer + _statesCount - 1) % _statesCount;
- _curFrame = (_curState + _statesCount - _startPointer) % _statesCount;
+ if (_animation)
+ _animation->seekToFrame((_curState + _statesCount - _startPointer) % _statesCount);
_curState = (_statesCount * 2 + tmp2) % _statesCount;
_targetFrame = (_curState + _statesCount - _startPointer) % _statesCount;
-
- _engine->getScriptManager()->setStateValue(_key, _curState);
return true;
}
}
diff --git a/engines/zvision/scripting/controls/safe_control.h b/engines/zvision/scripting/controls/safe_control.h
index 6e1095e304..3e8c17635c 100644
--- a/engines/zvision/scripting/controls/safe_control.h
+++ b/engines/zvision/scripting/controls/safe_control.h
@@ -34,6 +34,7 @@ namespace Video {
namespace ZVision {
+// Only used in Zork Nemesis, handles the safe in the Asylum (ac4g)
class SafeControl : public Control {
public:
SafeControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
@@ -51,19 +52,12 @@ private:
int32 _outerRadiusSqr;
int16 _zeroPointer;
int16 _startPointer;
- int16 _curFrame;
int16 _targetFrame;
- int32 _frameTime;
-
- int16 _lastRenderedFrame;
public:
bool onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
bool onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
bool process(uint32 deltaTimeInMillis);
-
-private:
- void renderFrame(uint frameNumber);
};
} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/save_control.cpp b/engines/zvision/scripting/controls/save_control.cpp
index b35611feca..2ac77c4776 100644
--- a/engines/zvision/scripting/controls/save_control.cpp
+++ b/engines/zvision/scripting/controls/save_control.cpp
@@ -29,7 +29,8 @@
#include "zvision/scripting/script_manager.h"
#include "zvision/text/string_manager.h"
-#include "zvision/core/save_manager.h"
+#include "zvision/file/save_manager.h"
+#include "zvision/graphics/render_manager.h"
#include "common/str.h"
#include "common/stream.h"
@@ -97,18 +98,16 @@ bool SaveControl::process(uint32 deltaTimeInMillis) {
if (inp->getText().size() > 0) {
bool toSave = true;
if (iter->exist)
- if (!_engine->askQuestion(_engine->getStringManager()->getTextLine(StringManager::ZVISION_STR_SAVEEXIST)))
+ if (!_engine->getRenderManager()->askQuestion(_engine->getStringManager()->getTextLine(StringManager::ZVISION_STR_SAVEEXIST)))
toSave = false;
if (toSave) {
- // FIXME: At this point, the screen shows the save control, so the save game thumbnails will always
- // show the save control
- _engine->getSaveManager()->saveGameBuffered(iter->saveId, inp->getText());
- _engine->delayedMessage(_engine->getStringManager()->getTextLine(StringManager::ZVISION_STR_SAVED), 2000);
+ _engine->getSaveManager()->saveGame(iter->saveId, inp->getText(), true);
+ _engine->getRenderManager()->delayedMessage(_engine->getStringManager()->getTextLine(StringManager::ZVISION_STR_SAVED), 2000);
_engine->getScriptManager()->changeLocation(_engine->getScriptManager()->getLastMenuLocation());
}
} else {
- _engine->timedMessage(_engine->getStringManager()->getTextLine(StringManager::ZVISION_STR_SAVEEMPTY), 2000);
+ _engine->getRenderManager()->timedMessage(_engine->getStringManager()->getTextLine(StringManager::ZVISION_STR_SAVEEMPTY), 2000);
}
} else {
_engine->getSaveManager()->loadGame(iter->saveId);
diff --git a/engines/zvision/scripting/controls/titler_control.cpp b/engines/zvision/scripting/controls/titler_control.cpp
index 10ba0af655..683d6660af 100644
--- a/engines/zvision/scripting/controls/titler_control.cpp
+++ b/engines/zvision/scripting/controls/titler_control.cpp
@@ -67,20 +67,22 @@ TitlerControl::TitlerControl(ZVision *engine, uint32 key, Common::SeekableReadSt
if (!_rectangle.isEmpty()) {
_surface = new Graphics::Surface;
- _surface->create(_rectangle.width(), _rectangle.height(), _engine->_pixelFormat);
+ _surface->create(_rectangle.width(), _rectangle.height(), _engine->_resourcePixelFormat);
_surface->fillRect(Common::Rect(_surface->w, _surface->h), 0);
}
}
TitlerControl::~TitlerControl() {
- if (_surface)
+ if (_surface) {
+ _surface->free();
delete _surface;
+ }
}
void TitlerControl::setString(int strLine) {
if (strLine != _curString && strLine >= 0 && strLine < (int)_strings.size()) {
_surface->fillRect(Common::Rect(_surface->w, _surface->h), 0);
- _engine->getTextRenderer()->drawTxtInOneLine(_strings[strLine], *_surface);
+ _engine->getTextRenderer()->drawTextWithWordWrapping(_strings[strLine], *_surface);
_engine->getRenderManager()->blitSurfaceToBkg(*_surface, _rectangle.left, _rectangle.top);
_curString = strLine;
}
diff --git a/engines/zvision/scripting/controls/titler_control.h b/engines/zvision/scripting/controls/titler_control.h
index 075e47c9e9..dd96e4a846 100644
--- a/engines/zvision/scripting/controls/titler_control.h
+++ b/engines/zvision/scripting/controls/titler_control.h
@@ -32,6 +32,7 @@
namespace ZVision {
+// Only used in Zork Nemesis, handles the death screen with the Restore/Exit buttons
class TitlerControl : public Control {
public:
TitlerControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
diff --git a/engines/zvision/scripting/sidefx/animation_node.cpp b/engines/zvision/scripting/effects/animation_effect.cpp
index 3a21227d1a..511a0db353 100644
--- a/engines/zvision/scripting/sidefx/animation_node.cpp
+++ b/engines/zvision/scripting/effects/animation_effect.cpp
@@ -22,7 +22,7 @@
#include "common/scummsys.h"
-#include "zvision/scripting/sidefx/animation_node.h"
+#include "zvision/scripting/effects/animation_effect.h"
#include "zvision/zvision.h"
#include "zvision/graphics/render_manager.h"
@@ -33,20 +33,27 @@
namespace ZVision {
-AnimationNode::AnimationNode(ZVision *engine, uint32 controlKey, const Common::String &fileName, int32 mask, int32 frate, bool DisposeAfterUse)
- : SideFX(engine, controlKey, SIDEFX_ANIM),
- _DisposeAfterUse(DisposeAfterUse),
+AnimationEffect::AnimationEffect(ZVision *engine, uint32 controlKey, const Common::String &fileName, int32 mask, int32 frate, bool disposeAfterUse)
+ : ScriptingEffect(engine, controlKey, SCRIPTING_EFFECT_ANIM),
+ _disposeAfterUse(disposeAfterUse),
_mask(mask),
_animation(NULL) {
_animation = engine->loadAnimation(fileName);
- _frmDelay = 1000.0 / _animation->getDuration().framerate();
- if (frate > 0)
- _frmDelay = 1000.0 / frate;
+ if (frate > 0) {
+ _frmDelayOverride = (int32)(1000.0 / frate);
+
+ // WORKAROUND: We do not allow the engine to delay more than 66 msec
+ // per frame (15fps max)
+ if (_frmDelayOverride > 66)
+ _frmDelayOverride = 66;
+ } else {
+ _frmDelayOverride = 0;
+ }
}
-AnimationNode::~AnimationNode() {
+AnimationEffect::~AnimationEffect() {
if (_animation)
delete _animation;
@@ -56,60 +63,83 @@ AnimationNode::~AnimationNode() {
if (it != _playList.end()) {
_engine->getScriptManager()->setStateValue((*it).slot, 2);
- if ((*it)._scaled)
+ if ((*it)._scaled) {
+ (*it)._scaled->free();
delete(*it)._scaled;
+ }
}
_playList.clear();
}
-bool AnimationNode::process(uint32 deltaTimeInMillis) {
+bool AnimationEffect::process(uint32 deltaTimeInMillis) {
+ ScriptManager *scriptManager = _engine->getScriptManager();
+ RenderManager *renderManager = _engine->getRenderManager();
+ RenderTable::RenderState renderState = renderManager->getRenderTable()->getRenderState();
+ bool isPanorama = (renderState == RenderTable::PANORAMA);
+ int16 velocity = _engine->getMouseVelocity() + _engine->getKeyboardVelocity();
+
+ // Do not update animation nodes in panoramic mode while turning, if the user
+ // has set this option
+ if (scriptManager->getStateValue(StateKey_NoTurnAnim) == 1 && isPanorama && velocity)
+ return false;
+
PlayNodes::iterator it = _playList.begin();
if (it != _playList.end()) {
playnode *nod = &(*it);
- nod->_delay -= deltaTimeInMillis;
- if (nod->_delay <= 0) {
- nod->_delay += _frmDelay;
-
- const Graphics::Surface *frame = NULL;
-
- if (nod->_curFrame == -1) { // Start of new playlist node
- nod->_curFrame = nod->start;
-
- _animation->seekToFrame(nod->_curFrame);
- frame = _animation->decodeNextFrame();
-
- nod->_delay = _frmDelay;
- if (nod->slot)
- _engine->getScriptManager()->setStateValue(nod->slot, 1);
- } else {
- nod->_curFrame++;
-
- if (nod->_curFrame > nod->stop) {
- nod->loop--;
-
- if (nod->loop == 0) {
- if (nod->slot >= 0)
- _engine->getScriptManager()->setStateValue(nod->slot, 2);
- if (nod->_scaled)
- delete nod->_scaled;
- _playList.erase(it);
- return _DisposeAfterUse;
- }
-
- nod->_curFrame = nod->start;
- _animation->seekToFrame(nod->_curFrame);
+ if (nod->_curFrame == -1) {
+ // The node is just beginning playback
+ nod->_curFrame = nod->start;
+
+ _animation->start();
+ _animation->seekToFrame(nod->start);
+ _animation->setEndFrame(nod->stop);
+
+ nod->_delay = deltaTimeInMillis; // Force the frame to draw
+ if (nod->slot)
+ scriptManager->setStateValue(nod->slot, 1);
+ } else if (_animation->endOfVideo()) {
+ // The node has reached the end; check if we need to loop
+ nod->loop--;
+
+ if (nod->loop == 0) {
+ if (nod->slot >= 0)
+ scriptManager->setStateValue(nod->slot, 2);
+ if (nod->_scaled) {
+ nod->_scaled->free();
+ delete nod->_scaled;
}
+ _playList.erase(it);
+ return _disposeAfterUse;
+ }
- frame = _animation->decodeNextFrame();
+ nod->_curFrame = nod->start;
+ _animation->seekToFrame(nod->start);
+ }
+
+ // Check if we need to draw a frame
+ bool needsUpdate = false;
+ if (_frmDelayOverride == 0) {
+ // If not overridden, use the VideoDecoder's check
+ needsUpdate = _animation->needsUpdate();
+ } else {
+ // Otherwise, implement our own timing
+ nod->_delay -= deltaTimeInMillis;
+
+ if (nod->_delay <= 0) {
+ nod->_delay += _frmDelayOverride;
+ needsUpdate = true;
}
+ }
- if (frame) {
+ if (needsUpdate) {
+ const Graphics::Surface *frame = _animation->decodeNextFrame();
+ if (frame) {
uint32 dstw;
uint32 dsth;
- if (_engine->getRenderManager()->getRenderTable()->getRenderState() == RenderTable::PANORAMA) {
+ if (isPanorama) {
dstw = nod->pos.height();
dsth = nod->pos.width();
} else {
@@ -126,6 +156,7 @@ bool AnimationNode::process(uint32 deltaTimeInMillis) {
if (frame->w > dstw || frame->h > dsth || (frame->w == dstw / 2 && frame->h == dsth / 2)) {
if (nod->_scaled)
if (nod->_scaled->w != dstw || nod->_scaled->h != dsth) {
+ nod->_scaled->free();
delete nod->_scaled;
nod->_scaled = NULL;
}
@@ -135,22 +166,17 @@ bool AnimationNode::process(uint32 deltaTimeInMillis) {
nod->_scaled->create(dstw, dsth, frame->format);
}
- _engine->getRenderManager()->scaleBuffer(frame->getPixels(), nod->_scaled->getPixels(), frame->w, frame->h, frame->format.bytesPerPixel, dstw, dsth);
+ renderManager->scaleBuffer(frame->getPixels(), nod->_scaled->getPixels(), frame->w, frame->h, frame->format.bytesPerPixel, dstw, dsth);
frame = nod->_scaled;
}
- if (_engine->getRenderManager()->getRenderTable()->getRenderState() == RenderTable::PANORAMA) {
+ if (isPanorama) {
Graphics::Surface *transposed = RenderManager::tranposeSurface(frame);
- if (_mask > 0)
- _engine->getRenderManager()->blitSurfaceToBkg(*transposed, nod->pos.left, nod->pos.top, _mask);
- else
- _engine->getRenderManager()->blitSurfaceToBkg(*transposed, nod->pos.left, nod->pos.top);
+ renderManager->blitSurfaceToBkg(*transposed, nod->pos.left, nod->pos.top, _mask);
+ transposed->free();
delete transposed;
} else {
- if (_mask > 0)
- _engine->getRenderManager()->blitSurfaceToBkg(*frame, nod->pos.left, nod->pos.top, _mask);
- else
- _engine->getRenderManager()->blitSurfaceToBkg(*frame, nod->pos.left, nod->pos.top);
+ renderManager->blitSurfaceToBkg(*frame, nod->pos.left, nod->pos.top, _mask);
}
}
}
@@ -159,16 +185,12 @@ bool AnimationNode::process(uint32 deltaTimeInMillis) {
return false;
}
-void AnimationNode::addPlayNode(int32 slot, int x, int y, int x2, int y2, int startFrame, int endFrame, int loops) {
+void AnimationEffect::addPlayNode(int32 slot, int x, int y, int x2, int y2, int startFrame, int endFrame, int loops) {
playnode nod;
nod.loop = loops;
nod.pos = Common::Rect(x, y, x2 + 1, y2 + 1);
nod.start = startFrame;
- nod.stop = endFrame;
-
- if (nod.stop >= (int)_animation->getFrameCount())
- nod.stop = _animation->getFrameCount() - 1;
-
+ nod.stop = CLIP<int>(endFrame, 0, _animation->getFrameCount() - 1);
nod.slot = slot;
nod._curFrame = -1;
nod._delay = 0;
@@ -176,12 +198,14 @@ void AnimationNode::addPlayNode(int32 slot, int x, int y, int x2, int y2, int st
_playList.push_back(nod);
}
-bool AnimationNode::stop() {
+bool AnimationEffect::stop() {
PlayNodes::iterator it = _playList.begin();
if (it != _playList.end()) {
_engine->getScriptManager()->setStateValue((*it).slot, 2);
- if ((*it)._scaled)
+ if ((*it)._scaled) {
+ (*it)._scaled->free();
delete(*it)._scaled;
+ }
}
_playList.clear();
@@ -190,21 +214,4 @@ bool AnimationNode::stop() {
return false;
}
-void AnimationNode::setNewFrameDelay(int32 newDelay) {
- if (newDelay > 0) {
- PlayNodes::iterator it = _playList.begin();
- if (it != _playList.end()) {
- playnode *nod = &(*it);
- float percent = (float)nod->_delay / (float)_frmDelay;
- nod->_delay = percent * newDelay; // Scale to new max
- }
-
- _frmDelay = newDelay;
- }
-}
-
-int32 AnimationNode::getFrameDelay() {
- return _frmDelay;
-}
-
} // End of namespace ZVision
diff --git a/engines/zvision/scripting/sidefx/animation_node.h b/engines/zvision/scripting/effects/animation_effect.h
index 3adfd91f32..fd6e24ab8b 100644
--- a/engines/zvision/scripting/sidefx/animation_node.h
+++ b/engines/zvision/scripting/effects/animation_effect.h
@@ -23,7 +23,7 @@
#ifndef ZVISION_ANIMATION_NODE_H
#define ZVISION_ANIMATION_NODE_H
-#include "zvision/scripting/sidefx.h"
+#include "zvision/scripting/scripting_effect.h"
#include "common/rect.h"
#include "common/list.h"
@@ -39,10 +39,10 @@ namespace ZVision {
class ZVision;
-class AnimationNode : public SideFX {
+class AnimationEffect : public ScriptingEffect {
public:
- AnimationNode(ZVision *engine, uint32 controlKey, const Common::String &fileName, int32 mask, int32 frate, bool DisposeAfterUse = true);
- ~AnimationNode();
+ AnimationEffect(ZVision *engine, uint32 controlKey, const Common::String &fileName, int32 mask, int32 frate, bool disposeAfterUse = true);
+ ~AnimationEffect();
struct playnode {
Common::Rect pos;
@@ -61,10 +61,10 @@ private:
PlayNodes _playList;
int32 _mask;
- bool _DisposeAfterUse;
+ bool _disposeAfterUse;
Video::VideoDecoder *_animation;
- int32 _frmDelay;
+ int32 _frmDelayOverride;
public:
bool process(uint32 deltaTimeInMillis);
@@ -72,9 +72,6 @@ public:
void addPlayNode(int32 slot, int x, int y, int x2, int y2, int startFrame, int endFrame, int loops = 1);
bool stop();
-
- void setNewFrameDelay(int32 newDelay);
- int32 getFrameDelay();
};
} // End of namespace ZVision
diff --git a/engines/zvision/scripting/sidefx/distort_node.cpp b/engines/zvision/scripting/effects/distort_effect.cpp
index 0d5c8b1ed5..113b5d048d 100644
--- a/engines/zvision/scripting/sidefx/distort_node.cpp
+++ b/engines/zvision/scripting/effects/distort_effect.cpp
@@ -22,7 +22,7 @@
#include "common/scummsys.h"
-#include "zvision/scripting/sidefx/distort_node.h"
+#include "zvision/scripting/effects/distort_effect.h"
#include "zvision/zvision.h"
#include "zvision/scripting/script_manager.h"
@@ -34,7 +34,7 @@
namespace ZVision {
DistortNode::DistortNode(ZVision *engine, uint32 key, int16 speed, float startAngle, float endAngle, float startLineScale, float endLineScale)
- : SideFX(engine, key, SIDEFX_DISTORT) {
+ : ScriptingEffect(engine, key, SCRIPTING_EFFECT_DISTORT) {
_angle = _engine->getRenderManager()->getRenderTable()->getAngle();
_linScale = _engine->getRenderManager()->getRenderTable()->getLinscale();
@@ -52,7 +52,7 @@ DistortNode::DistortNode(ZVision *engine, uint32 key, int16 speed, float startAn
_diffLinScale = endLineScale - startLineScale;
_frmSpeed = (float)speed / 15.0;
- _frames = ceil((5.0 - _frmSpeed * 2.0) / _frmSpeed);
+ _frames = (int)ceil((5.0 - _frmSpeed * 2.0) / _frmSpeed);
if (_frames <= 0)
_frames = 1;
@@ -65,7 +65,6 @@ DistortNode::~DistortNode() {
}
bool DistortNode::process(uint32 deltaTimeInMillis) {
-
float updTime = deltaTimeInMillis / (1000.0 / 60.0);
if (_incr)
diff --git a/engines/zvision/scripting/sidefx/distort_node.h b/engines/zvision/scripting/effects/distort_effect.h
index 787a69bdde..c64f10e6ff 100644
--- a/engines/zvision/scripting/sidefx/distort_node.h
+++ b/engines/zvision/scripting/effects/distort_effect.h
@@ -23,13 +23,13 @@
#ifndef ZVISION_DISTORT_NODE_H
#define ZVISION_DISTORT_NODE_H
-#include "zvision/scripting/sidefx.h"
+#include "zvision/scripting/scripting_effect.h"
namespace ZVision {
class ZVision;
-class DistortNode : public SideFX {
+class DistortNode : public ScriptingEffect {
public:
DistortNode(ZVision *engine, uint32 key, int16 speed, float startAngle, float endAngle, float startLineScale, float endLineScale);
~DistortNode();
diff --git a/engines/zvision/scripting/sidefx/music_node.cpp b/engines/zvision/scripting/effects/music_effect.cpp
index 56598189f6..e3fdc96dba 100644
--- a/engines/zvision/scripting/sidefx/music_node.cpp
+++ b/engines/zvision/scripting/effects/music_effect.cpp
@@ -22,7 +22,7 @@
#include "common/scummsys.h"
-#include "zvision/scripting/sidefx/music_node.h"
+#include "zvision/scripting/effects/music_effect.h"
#include "zvision/zvision.h"
#include "zvision/scripting/script_manager.h"
@@ -36,16 +36,33 @@
namespace ZVision {
-MusicNode::MusicNode(ZVision *engine, uint32 key, Common::String &filename, bool loop, int8 volume)
- : MusicNodeBASE(engine, key, SIDEFX_AUDIO) {
+static const uint8 dbMapLinear[256] =
+{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4,
+4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7,
+8, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12, 12, 13, 13, 14,
+14, 15, 15, 16, 16, 17, 18, 18, 19, 20, 21, 21, 22, 23, 24, 25,
+26, 27, 28, 29, 30, 31, 32, 33, 34, 36, 37, 38, 40, 41, 43, 45,
+46, 48, 50, 52, 53, 55, 57, 60, 62, 64, 67, 69, 72, 74, 77, 80,
+83, 86, 89, 92, 96, 99, 103, 107, 111, 115, 119, 123, 128, 133, 137, 143,
+148, 153, 159, 165, 171, 177, 184, 191, 198, 205, 212, 220, 228, 237, 245, 255};
+
+MusicNode::MusicNode(ZVision *engine, uint32 key, Common::String &filename, bool loop, uint8 volume)
+ : MusicNodeBASE(engine, key, SCRIPTING_EFFECT_AUDIO) {
_loop = loop;
_volume = volume;
+ _deltaVolume = 0;
+ _balance = 0;
_crossfade = false;
_crossfadeTarget = 0;
_crossfadeTime = 0;
- _attenuate = 0;
- _pantrack = false;
- _pantrackPosition = 0;
_sub = NULL;
_stereo = false;
_loaded = false;
@@ -66,9 +83,9 @@ MusicNode::MusicNode(ZVision *engine, uint32 key, Common::String &filename, bool
if (_loop) {
Audio::LoopingAudioStream *loopingAudioStream = new Audio::LoopingAudioStream(audioStream, 0, DisposeAfterUse::YES);
- _engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_handle, loopingAudioStream, -1, _volume);
+ _engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_handle, loopingAudioStream, -1, dbMapLinear[_volume]);
} else {
- _engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_handle, audioStream, -1, _volume);
+ _engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_handle, audioStream, -1, dbMapLinear[_volume]);
}
if (_key != StateKey_NotSet)
@@ -88,26 +105,23 @@ MusicNode::MusicNode(ZVision *engine, uint32 key, Common::String &filename, bool
}
MusicNode::~MusicNode() {
- if (!_loaded)
+ if (_loaded)
_engine->_mixer->stopHandle(_handle);
if (_key != StateKey_NotSet)
_engine->getScriptManager()->setStateValue(_key, 2);
if (_sub)
delete _sub;
- debug(1, "MusicNode: %d destroyed\n", _key);
+ debug(1, "MusicNode: %d destroyed", _key);
}
-void MusicNode::setPanTrack(int16 pos) {
- if (!_stereo) {
- _pantrack = true;
- _pantrackPosition = pos;
- setVolume(_volume);
- }
+void MusicNode::setDeltaVolume(uint8 volume) {
+ _deltaVolume = volume;
+ setVolume(_volume);
}
-void MusicNode::unsetPanTrack() {
- _pantrack = false;
- setVolume(_volume);
+void MusicNode::setBalance(int8 balance) {
+ _balance = balance;
+ _engine->_mixer->setChannelBalance(_handle, _balance);
}
void MusicNode::setFade(int32 time, uint8 target) {
@@ -126,7 +140,7 @@ bool MusicNode::process(uint32 deltaTimeInMillis) {
if (_crossfadeTime > 0) {
if ((int32)deltaTimeInMillis > _crossfadeTime)
deltaTimeInMillis = _crossfadeTime;
- _newvol += floor(((float)(_crossfadeTarget - _newvol) / (float)_crossfadeTime)) * (float)deltaTimeInMillis;
+ _newvol += (int)(floor(((float)(_crossfadeTarget - _newvol) / (float)_crossfadeTime)) * (float)deltaTimeInMillis);
_crossfadeTime -= deltaTimeInMillis;
} else {
_crossfade = false;
@@ -134,10 +148,10 @@ bool MusicNode::process(uint32 deltaTimeInMillis) {
}
}
- if (_pantrack || _volume != _newvol)
+ if (_volume != _newvol)
setVolume(_newvol);
- if (_sub)
+ if (_sub && _engine->getScriptManager()->getStateValue(StateKey_Subtitles) == 1)
_sub->process(_engine->_mixer->getSoundElapsedTime(_handle) / 100);
}
return false;
@@ -146,59 +160,89 @@ bool MusicNode::process(uint32 deltaTimeInMillis) {
void MusicNode::setVolume(uint8 newVolume) {
if (!_loaded)
return;
- if (_pantrack) {
- int curX = _engine->getScriptManager()->getStateValue(StateKey_ViewPos);
- curX -= _pantrackPosition;
- int32 _width = _engine->getRenderManager()->getBkgSize().x;
- if (curX < (-_width) / 2)
- curX += _width;
- else if (curX >= _width / 2)
- curX -= _width;
-
- float norm = (float)curX / ((float)_width / 2.0);
- float lvl = fabs(norm);
- if (lvl > 0.5)
- lvl = (lvl - 0.5) * 1.7;
- else
- lvl = 1.0;
- float bal = sin(-norm * 3.1415926) * 127.0;
+ _volume = newVolume;
- if (_engine->_mixer->isSoundHandleActive(_handle)) {
- _engine->_mixer->setChannelBalance(_handle, bal);
- _engine->_mixer->setChannelVolume(_handle, newVolume * lvl);
- }
- } else {
- if (_engine->_mixer->isSoundHandleActive(_handle)) {
- _engine->_mixer->setChannelBalance(_handle, 0);
- _engine->_mixer->setChannelVolume(_handle, newVolume);
- }
- }
+ if (_deltaVolume >= _volume)
+ _engine->_mixer->setChannelVolume(_handle, 0);
+ else
+ _engine->_mixer->setChannelVolume(_handle, dbMapLinear[_volume - _deltaVolume]);
+}
- _volume = newVolume;
+uint8 MusicNode::getVolume() {
+ return _volume;
}
PanTrackNode::PanTrackNode(ZVision *engine, uint32 key, uint32 slot, int16 pos)
- : SideFX(engine, key, SIDEFX_PANTRACK) {
+ : ScriptingEffect(engine, key, SCRIPTING_EFFECT_PANTRACK) {
_slot = slot;
+ _position = pos;
- SideFX *fx = _engine->getScriptManager()->getSideFX(slot);
- if (fx && fx->getType() == SIDEFX_AUDIO) {
- MusicNodeBASE *mus = (MusicNodeBASE *)fx;
- mus->setPanTrack(pos);
- }
+ // Try to set pan value for music node immediately
+ process(0);
}
PanTrackNode::~PanTrackNode() {
- SideFX *fx = _engine->getScriptManager()->getSideFX(_slot);
- if (fx && fx->getType() == SIDEFX_AUDIO) {
+}
+
+bool PanTrackNode::process(uint32 deltaTimeInMillis) {
+ ScriptManager * scriptManager = _engine->getScriptManager();
+ ScriptingEffect *fx = scriptManager->getSideFX(_slot);
+ if (fx && fx->getType() == SCRIPTING_EFFECT_AUDIO) {
MusicNodeBASE *mus = (MusicNodeBASE *)fx;
- mus->unsetPanTrack();
+
+ int curPos = scriptManager->getStateValue(StateKey_ViewPos);
+ int16 _width = _engine->getRenderManager()->getBkgSize().x;
+ int16 _halfWidth = _width / 2;
+ int16 _quarterWidth = _width / 4;
+
+ int tmp = 0;
+ if (curPos <= _position)
+ tmp = _position - curPos;
+ else
+ tmp = _position - curPos + _width;
+
+ int balance = 0;
+
+ if (tmp > _halfWidth)
+ tmp -= _width;
+
+ if (tmp > _quarterWidth) {
+ balance = 1;
+ tmp = _halfWidth - tmp;
+ } else if (tmp < -_quarterWidth) {
+ balance = -1;
+ tmp = -_halfWidth - tmp;
+ }
+
+ // Originally it's value -90...90 but we use -127...127 and therefore 360 replaced by 508
+ mus->setBalance( (508 * tmp) / _width );
+
+ tmp = (360 * tmp) / _width;
+
+ int deltaVol = balance;
+
+ // This value sets how fast volume goes off than sound source back of you
+ // By this value we can hack some "bugs" have place in originall game engine like beat sound in ZGI-dc10
+ int volumeCorrection = 2;
+
+ if (_engine->getGameId() == GID_GRANDINQUISITOR) {
+ if (scriptManager->getCurrentLocation() == "dc10")
+ volumeCorrection = 5;
+ }
+
+ if (deltaVol != 0)
+ deltaVol = (mus->getVolume() * volumeCorrection) * (90 - tmp * balance) / 90;
+ if (deltaVol > 255)
+ deltaVol = 255;
+
+ mus->setDeltaVolume(deltaVol);
}
+ return false;
}
MusicMidiNode::MusicMidiNode(ZVision *engine, uint32 key, int8 program, int8 note, int8 volume)
- : MusicNodeBASE(engine, key, SIDEFX_AUDIO) {
+ : MusicNodeBASE(engine, key, SCRIPTING_EFFECT_AUDIO) {
_volume = volume;
_prog = program;
_noteNumber = note;
@@ -225,10 +269,10 @@ MusicMidiNode::~MusicMidiNode() {
_engine->getScriptManager()->setStateValue(_key, 2);
}
-void MusicMidiNode::setPanTrack(int16 pos) {
+void MusicMidiNode::setDeltaVolume(uint8 volume) {
}
-void MusicMidiNode::unsetPanTrack() {
+void MusicMidiNode::setBalance(int8 balance) {
}
void MusicMidiNode::setFade(int32 time, uint8 target) {
@@ -245,4 +289,8 @@ void MusicMidiNode::setVolume(uint8 newVolume) {
_volume = newVolume;
}
+uint8 MusicMidiNode::getVolume() {
+ return _volume;
+}
+
} // End of namespace ZVision
diff --git a/engines/zvision/scripting/sidefx/music_node.h b/engines/zvision/scripting/effects/music_effect.h
index 09bdc3707e..7657be8e09 100644
--- a/engines/zvision/scripting/sidefx/music_node.h
+++ b/engines/zvision/scripting/effects/music_effect.h
@@ -24,8 +24,8 @@
#define ZVISION_MUSIC_NODE_H
#include "audio/mixer.h"
-#include "zvision/scripting/sidefx.h"
-#include "zvision/graphics/subtitles.h"
+#include "zvision/scripting/scripting_effect.h"
+#include "zvision/text/subtitles.h"
namespace Common {
class String;
@@ -33,9 +33,9 @@ class String;
namespace ZVision {
-class MusicNodeBASE : public SideFX {
+class MusicNodeBASE : public ScriptingEffect {
public:
- MusicNodeBASE(ZVision *engine, uint32 key, SideFXType type) : SideFX(engine, key, type) {}
+ MusicNodeBASE(ZVision *engine, uint32 key, ScriptingEffectType type) : ScriptingEffect(engine, key, type) {}
~MusicNodeBASE() {}
/**
@@ -48,16 +48,16 @@ public:
virtual bool process(uint32 deltaTimeInMillis) = 0;
virtual void setVolume(uint8 volume) = 0;
-
- virtual void setPanTrack(int16 pos) = 0;
- virtual void unsetPanTrack() = 0;
+ virtual uint8 getVolume() = 0;
+ virtual void setDeltaVolume(uint8 volume) = 0;
+ virtual void setBalance(int8 balance) = 0;
virtual void setFade(int32 time, uint8 target) = 0;
};
class MusicNode : public MusicNodeBASE {
public:
- MusicNode(ZVision *engine, uint32 key, Common::String &file, bool loop, int8 volume);
+ MusicNode(ZVision *engine, uint32 key, Common::String &file, bool loop, uint8 volume);
~MusicNode();
/**
@@ -70,17 +70,16 @@ public:
bool process(uint32 deltaTimeInMillis);
void setVolume(uint8 volume);
-
- void setPanTrack(int16 pos);
- void unsetPanTrack();
+ uint8 getVolume();
+ void setDeltaVolume(uint8 volume);
+ void setBalance(int8 balance);
void setFade(int32 time, uint8 target);
private:
- bool _pantrack;
- int32 _pantrackPosition;
- int32 _attenuate;
uint8 _volume;
+ uint8 _deltaVolume;
+ int8 _balance;
bool _loop;
bool _crossfade;
uint8 _crossfadeTarget;
@@ -91,6 +90,7 @@ private:
bool _loaded;
};
+// Only used by Zork: Nemesis, for the flute and piano puzzles (tj4e and ve6f, as well as vr)
class MusicMidiNode : public MusicNodeBASE {
public:
MusicMidiNode(ZVision *engine, uint32 key, int8 program, int8 note, int8 volume);
@@ -106,9 +106,9 @@ public:
bool process(uint32 deltaTimeInMillis);
void setVolume(uint8 volume);
-
- void setPanTrack(int16 pos);
- void unsetPanTrack();
+ uint8 getVolume();
+ void setDeltaVolume(uint8 volume);
+ void setBalance(int8 balance);
void setFade(int32 time, uint8 target);
@@ -120,13 +120,16 @@ private:
int8 _prog;
};
-class PanTrackNode : public SideFX {
+class PanTrackNode : public ScriptingEffect {
public:
PanTrackNode(ZVision *engine, uint32 key, uint32 slot, int16 pos);
~PanTrackNode();
+ bool process(uint32 deltaTimeInMillis);
+
private:
uint32 _slot;
+ int16 _position;
};
} // End of namespace ZVision
diff --git a/engines/zvision/scripting/sidefx/region_node.cpp b/engines/zvision/scripting/effects/region_effect.cpp
index de613d8af2..78061cf4de 100644
--- a/engines/zvision/scripting/sidefx/region_node.cpp
+++ b/engines/zvision/scripting/effects/region_effect.cpp
@@ -22,7 +22,7 @@
#include "common/scummsys.h"
-#include "zvision/scripting/sidefx/region_node.h"
+#include "zvision/scripting/effects/region_effect.h"
#include "zvision/zvision.h"
#include "zvision/scripting/script_manager.h"
@@ -30,8 +30,8 @@
namespace ZVision {
-RegionNode::RegionNode(ZVision *engine, uint32 key, Effect *effect, uint32 delay)
- : SideFX(engine, key, SIDEFX_REGION) {
+RegionNode::RegionNode(ZVision *engine, uint32 key, GraphicsEffect *effect, uint32 delay)
+ : ScriptingEffect(engine, key, SCRIPTING_EFFECT_REGION) {
_effect = effect;
_delay = delay;
_timeLeft = 0;
diff --git a/engines/zvision/scripting/sidefx/region_node.h b/engines/zvision/scripting/effects/region_effect.h
index ec716b6e3e..4fc16224ff 100644
--- a/engines/zvision/scripting/sidefx/region_node.h
+++ b/engines/zvision/scripting/effects/region_effect.h
@@ -25,16 +25,16 @@
#include "graphics/surface.h"
-#include "zvision/scripting/sidefx.h"
-#include "zvision/graphics/effect.h"
+#include "zvision/scripting/scripting_effect.h"
+#include "zvision/graphics/graphics_effect.h"
namespace ZVision {
class ZVision;
-class RegionNode : public SideFX {
+class RegionNode : public ScriptingEffect {
public:
- RegionNode(ZVision *engine, uint32 key, Effect *effect, uint32 delay);
+ RegionNode(ZVision *engine, uint32 key, GraphicsEffect *effect, uint32 delay);
~RegionNode();
/**
@@ -49,7 +49,7 @@ public:
private:
int32 _timeLeft;
uint32 _delay;
- Effect *_effect;
+ GraphicsEffect *_effect;
};
} // End of namespace ZVision
diff --git a/engines/zvision/scripting/sidefx/syncsound_node.cpp b/engines/zvision/scripting/effects/syncsound_effect.cpp
index c1f139694b..70ba97deb8 100644
--- a/engines/zvision/scripting/sidefx/syncsound_node.cpp
+++ b/engines/zvision/scripting/effects/syncsound_effect.cpp
@@ -22,7 +22,7 @@
#include "common/scummsys.h"
-#include "zvision/scripting/sidefx/syncsound_node.h"
+#include "zvision/scripting/effects/syncsound_effect.h"
#include "zvision/zvision.h"
#include "zvision/scripting/script_manager.h"
@@ -36,7 +36,7 @@
namespace ZVision {
SyncSoundNode::SyncSoundNode(ZVision *engine, uint32 key, Common::String &filename, int32 syncto)
- : SideFX(engine, key, SIDEFX_AUDIO) {
+ : ScriptingEffect(engine, key, SCRIPTING_EFFECT_AUDIO) {
_syncto = syncto;
_sub = NULL;
@@ -76,7 +76,7 @@ bool SyncSoundNode::process(uint32 deltaTimeInMillis) {
if (_engine->getScriptManager()->getSideFX(_syncto) == NULL)
return stop();
- if (_sub)
+ if (_sub && _engine->getScriptManager()->getStateValue(StateKey_Subtitles) == 1)
_sub->process(_engine->_mixer->getSoundElapsedTime(_handle) / 100);
}
return false;
diff --git a/engines/zvision/scripting/sidefx/syncsound_node.h b/engines/zvision/scripting/effects/syncsound_effect.h
index 7cd02a8aef..0eabff77a3 100644
--- a/engines/zvision/scripting/sidefx/syncsound_node.h
+++ b/engines/zvision/scripting/effects/syncsound_effect.h
@@ -24,15 +24,15 @@
#define ZVISION_SYNCSOUND_NODE_H
#include "audio/mixer.h"
-#include "zvision/scripting/sidefx.h"
-#include "zvision/graphics/subtitles.h"
+#include "zvision/scripting/scripting_effect.h"
+#include "zvision/text/subtitles.h"
namespace Common {
class String;
}
namespace ZVision {
-class SyncSoundNode : public SideFX {
+class SyncSoundNode : public ScriptingEffect {
public:
SyncSoundNode(ZVision *engine, uint32 key, Common::String &file, int32 syncto);
~SyncSoundNode();
diff --git a/engines/zvision/scripting/sidefx/timer_node.cpp b/engines/zvision/scripting/effects/timer_effect.cpp
index 170f6e7472..778f9dec6c 100644
--- a/engines/zvision/scripting/sidefx/timer_node.cpp
+++ b/engines/zvision/scripting/effects/timer_effect.cpp
@@ -22,7 +22,7 @@
#include "common/scummsys.h"
-#include "zvision/scripting/sidefx/timer_node.h"
+#include "zvision/scripting/effects/timer_effect.h"
#include "zvision/zvision.h"
#include "zvision/scripting/script_manager.h"
@@ -32,7 +32,7 @@
namespace ZVision {
TimerNode::TimerNode(ZVision *engine, uint32 key, uint timeInSeconds)
- : SideFX(engine, key, SIDEFX_TIMER) {
+ : ScriptingEffect(engine, key, SCRIPTING_EFFECT_TIMER) {
_timeLeft = 0;
if (_engine->getGameId() == GID_NEMESIS)
diff --git a/engines/zvision/scripting/sidefx/timer_node.h b/engines/zvision/scripting/effects/timer_effect.h
index 7a26aff251..5e45d54d7d 100644
--- a/engines/zvision/scripting/sidefx/timer_node.h
+++ b/engines/zvision/scripting/effects/timer_effect.h
@@ -23,13 +23,13 @@
#ifndef ZVISION_TIMER_NODE_H
#define ZVISION_TIMER_NODE_H
-#include "zvision/scripting/sidefx.h"
+#include "zvision/scripting/scripting_effect.h"
namespace ZVision {
class ZVision;
-class TimerNode : public SideFX {
+class TimerNode : public ScriptingEffect {
public:
TimerNode(ZVision *engine, uint32 key, uint timeInSeconds);
~TimerNode();
diff --git a/engines/zvision/scripting/sidefx/ttytext_node.cpp b/engines/zvision/scripting/effects/ttytext_effect.cpp
index 9a7fa01649..8d340dae39 100644
--- a/engines/zvision/scripting/sidefx/ttytext_node.cpp
+++ b/engines/zvision/scripting/effects/ttytext_effect.cpp
@@ -22,7 +22,7 @@
#include "common/scummsys.h"
-#include "zvision/scripting/sidefx/ttytext_node.h"
+#include "zvision/scripting/effects/ttytext_effect.h"
#include "zvision/zvision.h"
#include "zvision/scripting/script_manager.h"
@@ -35,7 +35,7 @@
namespace ZVision {
ttyTextNode::ttyTextNode(ZVision *engine, uint32 key, const Common::String &file, const Common::Rect &r, int32 delay) :
- SideFX(engine, key, SIDEFX_TTYTXT),
+ ScriptingEffect(engine, key, SCRIPTING_EFFECT_TTYTXT),
_fnt(engine) {
_delay = delay;
_r = r;
@@ -56,10 +56,10 @@ ttyTextNode::ttyTextNode(ZVision *engine, uint32 key, const Common::String &file
delete infile;
}
- _img.create(_r.width(), _r.height(), _engine->_pixelFormat);
- _style.sharp = true;
- _style.readAllStyle(_txtbuf);
- _style.setFont(_fnt);
+ _img.create(_r.width(), _r.height(), _engine->_resourcePixelFormat);
+ _state._sharp = true;
+ _state.readAllStyles(_txtbuf);
+ _state.updateFontWithTextState(_fnt);
_engine->getScriptManager()->setStateValue(_key, 1);
}
@@ -74,29 +74,27 @@ bool ttyTextNode::process(uint32 deltaTimeInMillis) {
if (_nexttime < 0) {
if (_txtpos < _txtbuf.size()) {
if (_txtbuf[_txtpos] == '<') {
- int32 strt = _txtpos;
- int32 endt = 0;
+ int32 start = _txtpos;
+ int32 end = 0;
int16 ret = 0;
while (_txtbuf[_txtpos] != '>' && _txtpos < _txtbuf.size())
_txtpos++;
- endt = _txtpos;
- if (strt != -1)
- if ((endt - strt - 1) > 0)
- ret = _style.parseStyle(_txtbuf.c_str() + strt + 1, endt - strt - 1);
-
- if (ret & (TXT_RET_FNTCHG | TXT_RET_FNTSTL | TXT_RET_NEWLN)) {
- if (ret & TXT_RET_FNTCHG)
- _style.setFont(_fnt);
- if (ret & TXT_RET_FNTSTL)
- _style.setFontStyle(_fnt);
-
- if (ret & TXT_RET_NEWLN)
- newline();
+ end = _txtpos;
+ if (start != -1) {
+ if ((end - start - 1) > 0) {
+ ret = _state.parseStyle(_txtbuf.c_str() + start + 1, end - start - 1);
+ }
+ }
+
+ if (ret & (TEXT_CHANGE_FONT_TYPE | TEXT_CHANGE_FONT_STYLE)) {
+ _state.updateFontWithTextState(_fnt);
+ } else if (ret & TEXT_CHANGE_NEWLINE) {
+ newline();
}
- if (ret & TXT_RET_HASSTBOX) {
+ if (ret & TEXT_CHANGE_HAS_STATE_BOX) {
Common::String buf;
- buf = Common::String::format("%d", _engine->getScriptManager()->getStateValue(_style.statebox));
+ buf = Common::String::format("%d", _engine->getScriptManager()->getStateValue(_state._statebox));
for (uint8 j = 0; j < buf.size(); j++)
outchar(buf[j]);
@@ -158,7 +156,7 @@ void ttyTextNode::newline() {
}
void ttyTextNode::outchar(uint16 chr) {
- uint32 clr = _engine->_pixelFormat.RGBToColor(_style.red, _style.green, _style.blue);
+ uint32 clr = _engine->_resourcePixelFormat.RGBToColor(_state._red, _state._green, _state._blue);
if (_dx + _fnt.getCharWidth(chr) > _r.width())
newline();
diff --git a/engines/zvision/scripting/sidefx/ttytext_node.h b/engines/zvision/scripting/effects/ttytext_effect.h
index b6cbed3e34..18cbbbaee3 100644
--- a/engines/zvision/scripting/sidefx/ttytext_node.h
+++ b/engines/zvision/scripting/effects/ttytext_effect.h
@@ -26,16 +26,16 @@
#include "common/rect.h"
#include "graphics/surface.h"
-#include "zvision/scripting/sidefx.h"
+#include "zvision/scripting/scripting_effect.h"
#include "zvision/text/text.h"
-#include "zvision/graphics/truetype_font.h"
+#include "zvision/text/truetype_font.h"
namespace Common {
class String;
}
namespace ZVision {
-class ttyTextNode : public SideFX {
+class ttyTextNode : public ScriptingEffect {
public:
ttyTextNode(ZVision *engine, uint32 key, const Common::String &file, const Common::Rect &r, int32 delay);
~ttyTextNode();
@@ -51,7 +51,7 @@ public:
private:
Common::Rect _r;
- cTxtStyle _style;
+ TextStyleState _state;
StyledTTFont _fnt;
Common::String _txtbuf;
uint32 _txtpos;
diff --git a/engines/zvision/core/menu.cpp b/engines/zvision/scripting/menu.cpp
index 31e0d71370..064bd1b57d 100644
--- a/engines/zvision/core/menu.cpp
+++ b/engines/zvision/scripting/menu.cpp
@@ -20,26 +20,22 @@
*
*/
-#include "common/scummsys.h"
-
-#include "zvision/core/menu.h"
-
#include "zvision/graphics/render_manager.h"
+#include "zvision/scripting/menu.h"
namespace ZVision {
enum {
- SLOT_START_SLOT = 151,
- SLOT_SPELL_1 = 191,
- SLOT_USER_CHOSE_THIS_SPELL = 205,
- SLOT_REVERSED_SPELLBOOK = 206
+ kMainMenuSave = 0,
+ kMainMenuLoad = 1,
+ kMainMenuPrefs = 2,
+ kMainMenuExit = 3
};
enum {
- menu_MAIN_SAVE = 0,
- menu_MAIN_REST = 1,
- menu_MAIN_PREF = 2,
- menu_MAIN_EXIT = 3
+ kMenuItem = 0,
+ kMenuMagic = 1,
+ kMenuMain = 2
};
MenuHandler::MenuHandler(ZVision *engine) {
@@ -50,13 +46,13 @@ MenuHandler::MenuHandler(ZVision *engine) {
MenuZGI::MenuZGI(ZVision *engine) :
MenuHandler(engine) {
menuMouseFocus = -1;
- inmenu = false;
+ inMenu = false;
scrolled[0] = false;
scrolled[1] = false;
scrolled[2] = false;
- scrollPos[0] = 0.0;
- scrollPos[1] = 0.0;
- scrollPos[2] = 0.0;
+ scrollPos[0] = 0;
+ scrollPos[1] = 0;
+ scrollPos[2] = 0;
mouseOnItem = -1;
redraw = false;
clean = false;
@@ -64,15 +60,15 @@ MenuZGI::MenuZGI(ZVision *engine) :
char buf[24];
for (int i = 1; i < 4; i++) {
sprintf(buf, "gmzau%2.2x1.tga", i);
- _engine->getRenderManager()->readImageToSurface(buf, menuback[i - 1][0], false);
+ _engine->getRenderManager()->readImageToSurface(buf, menuBack[i - 1][0], false);
sprintf(buf, "gmzau%2.2x1.tga", i + 0x10);
- _engine->getRenderManager()->readImageToSurface(buf, menuback[i - 1][1], false);
+ _engine->getRenderManager()->readImageToSurface(buf, menuBack[i - 1][1], false);
}
for (int i = 0; i < 4; i++) {
sprintf(buf, "gmzmu%2.2x1.tga", i);
- _engine->getRenderManager()->readImageToSurface(buf, menubar[i][0], false);
+ _engine->getRenderManager()->readImageToSurface(buf, menuBar[i][0], false);
sprintf(buf, "gmznu%2.2x1.tga", i);
- _engine->getRenderManager()->readImageToSurface(buf, menubar[i][1], false);
+ _engine->getRenderManager()->readImageToSurface(buf, menuBar[i][1], false);
}
for (int i = 0; i < 50; i++) {
@@ -90,12 +86,12 @@ MenuZGI::MenuZGI(ZVision *engine) :
MenuZGI::~MenuZGI() {
for (int i = 0; i < 3; i++) {
- menuback[i][0].free();
- menuback[i][1].free();
+ menuBack[i][0].free();
+ menuBack[i][1].free();
}
for (int i = 0; i < 4; i++) {
- menubar[i][0].free();
- menubar[i][1].free();
+ menuBar[i][0].free();
+ menuBar[i][1].free();
}
for (int i = 0; i < 50; i++) {
if (items[i][0]) {
@@ -122,8 +118,8 @@ MenuZGI::~MenuZGI() {
void MenuZGI::onMouseUp(const Common::Point &Pos) {
if (Pos.y < 40) {
switch (menuMouseFocus) {
- case menu_ITEM:
- if (menuBarFlag & menuBar_Items) {
+ case kMenuItem:
+ if (menuBarFlag & kMenubarItems) {
int itemCount = _engine->getScriptManager()->getStateValue(StateKey_Inv_TotalSlots);
if (itemCount == 0)
itemCount = 20;
@@ -131,13 +127,13 @@ void MenuZGI::onMouseUp(const Common::Point &Pos) {
for (int i = 0; i < itemCount; i++) {
int itemspace = (600 - 28) / itemCount;
- if (Common::Rect(scrollPos[menu_ITEM] + itemspace * i, 0,
- scrollPos[menu_ITEM] + itemspace * i + 28, 32).contains(Pos)) {
+ if (Common::Rect(scrollPos[kMenuItem] + itemspace * i, 0,
+ scrollPos[kMenuItem] + itemspace * i + 28, 32).contains(Pos)) {
int32 mouseItem = _engine->getScriptManager()->getStateValue(StateKey_InventoryItem);
if (mouseItem >= 0 && mouseItem < 0xE0) {
_engine->getScriptManager()->inventoryDrop(mouseItem);
- _engine->getScriptManager()->inventoryAdd(_engine->getScriptManager()->getStateValue(SLOT_START_SLOT + i));
- _engine->getScriptManager()->setStateValue(SLOT_START_SLOT + i, mouseItem);
+ _engine->getScriptManager()->inventoryAdd(_engine->getScriptManager()->getStateValue(StateKey_Inv_StartSlot + i));
+ _engine->getScriptManager()->setStateValue(StateKey_Inv_StartSlot + i, mouseItem);
redraw = true;
}
@@ -146,62 +142,62 @@ void MenuZGI::onMouseUp(const Common::Point &Pos) {
}
break;
- case menu_MAGIC:
- if (menuBarFlag & menuBar_Magic) {
+ case kMenuMagic:
+ if (menuBarFlag & kMenubarMagic) {
for (int i = 0; i < 12; i++) {
- uint itemnum = _engine->getScriptManager()->getStateValue(SLOT_SPELL_1 + i);
+ uint itemnum = _engine->getScriptManager()->getStateValue(StateKey_Spell_1 + i);
if (itemnum != 0) {
- if (_engine->getScriptManager()->getStateValue(SLOT_REVERSED_SPELLBOOK) == 1)
+ if (_engine->getScriptManager()->getStateValue(StateKey_Reversed_Spellbooc) == 1)
itemnum = 0xEE + i;
else
itemnum = 0xE0 + i;
}
if (itemnum)
if (_engine->getScriptManager()->getStateValue(StateKey_InventoryItem) == 0 || _engine->getScriptManager()->getStateValue(StateKey_InventoryItem) >= 0xE0)
- if (Common::Rect(668 + 47 * i - scrollPos[menu_MAGIC], 0,
- 668 + 47 * i - scrollPos[menu_MAGIC] + 28, 32).contains(Pos))
- _engine->getScriptManager()->setStateValue(SLOT_USER_CHOSE_THIS_SPELL, itemnum);
+ if (Common::Rect(668 + 47 * i - scrollPos[kMenuMagic], 0,
+ 668 + 47 * i - scrollPos[kMenuMagic] + 28, 32).contains(Pos))
+ _engine->getScriptManager()->setStateValue(StateKey_Active_Spell, itemnum);
}
}
break;
- case menu_MAIN:
+ case kMenuMain:
// Exit
- if (menuBarFlag & menuBar_Exit)
+ if (menuBarFlag & kMenubarExit)
if (Common::Rect(320 + 135,
- scrollPos[menu_MAIN],
+ scrollPos[kMenuMain],
320 + 135 + 135,
- scrollPos[menu_MAIN] + 32).contains(Pos)) {
+ scrollPos[kMenuMain] + 32).contains(Pos)) {
_engine->ifQuit();
}
// Settings
- if (menuBarFlag & menuBar_Settings)
+ if (menuBarFlag & kMenubarSettings)
if (Common::Rect(320 ,
- scrollPos[menu_MAIN],
+ scrollPos[kMenuMain],
320 + 135,
- scrollPos[menu_MAIN] + 32).contains(Pos)) {
+ scrollPos[kMenuMain] + 32).contains(Pos)) {
_engine->getScriptManager()->changeLocation('g', 'j', 'p', 'e', 0);
}
// Load
- if (menuBarFlag & menuBar_Restore)
+ if (menuBarFlag & kMenubarRestore)
if (Common::Rect(320 - 135,
- scrollPos[menu_MAIN],
+ scrollPos[kMenuMain],
320,
- scrollPos[menu_MAIN] + 32).contains(Pos)) {
+ scrollPos[kMenuMain] + 32).contains(Pos)) {
_engine->getScriptManager()->changeLocation('g', 'j', 'r', 'e', 0);
}
// Save
- if (menuBarFlag & menuBar_Save)
+ if (menuBarFlag & kMenubarSave)
if (Common::Rect(320 - 135 * 2,
- scrollPos[menu_MAIN],
+ scrollPos[kMenuMain],
320 - 135,
- scrollPos[menu_MAIN] + 32).contains(Pos)) {
+ scrollPos[kMenuMain] + 32).contains(Pos)) {
_engine->getScriptManager()->changeLocation('g', 'j', 's', 'e', 0);
}
break;
@@ -212,12 +208,12 @@ void MenuZGI::onMouseUp(const Common::Point &Pos) {
void MenuZGI::onMouseMove(const Common::Point &Pos) {
if (Pos.y < 40) {
- if (!inmenu)
+ if (!inMenu)
redraw = true;
- inmenu = true;
+ inMenu = true;
switch (menuMouseFocus) {
- case menu_ITEM:
- if (menuBarFlag & menuBar_Items) {
+ case kMenuItem:
+ if (menuBarFlag & kMenubarItems) {
int itemCount = _engine->getScriptManager()->getStateValue(StateKey_Inv_TotalSlots);
if (itemCount == 0)
itemCount = 20;
@@ -231,78 +227,78 @@ void MenuZGI::onMouseMove(const Common::Point &Pos) {
for (int i = 0; i < itemCount; i++) {
int itemspace = (600 - 28) / itemCount;
- if (Common::Rect(scrollPos[menu_ITEM] + itemspace * i, 0,
- scrollPos[menu_ITEM] + itemspace * i + 28, 32).contains(Pos)) {
+ if (Common::Rect(scrollPos[kMenuItem] + itemspace * i, 0,
+ scrollPos[kMenuItem] + itemspace * i + 28, 32).contains(Pos)) {
mouseOnItem = i;
break;
}
}
if (lastItem != mouseOnItem)
- if (_engine->getScriptManager()->getStateValue(SLOT_START_SLOT + mouseOnItem) ||
- _engine->getScriptManager()->getStateValue(SLOT_START_SLOT + lastItem))
+ if (_engine->getScriptManager()->getStateValue(StateKey_Inv_StartSlot + mouseOnItem) ||
+ _engine->getScriptManager()->getStateValue(StateKey_Inv_StartSlot + lastItem))
redraw = true;
}
break;
- case menu_MAGIC:
- if (menuBarFlag & menuBar_Magic) {
+ case kMenuMagic:
+ if (menuBarFlag & kMenubarMagic) {
int lastItem = mouseOnItem;
mouseOnItem = -1;
for (int i = 0; i < 12; i++) {
- if (Common::Rect(668 + 47 * i - scrollPos[menu_MAGIC], 0,
- 668 + 47 * i - scrollPos[menu_MAGIC] + 28, 32).contains(Pos)) {
+ if (Common::Rect(668 + 47 * i - scrollPos[kMenuMagic], 0,
+ 668 + 47 * i - scrollPos[kMenuMagic] + 28, 32).contains(Pos)) {
mouseOnItem = i;
break;
}
}
if (lastItem != mouseOnItem)
- if (_engine->getScriptManager()->getStateValue(SLOT_SPELL_1 + mouseOnItem) ||
- _engine->getScriptManager()->getStateValue(SLOT_SPELL_1 + lastItem))
+ if (_engine->getScriptManager()->getStateValue(StateKey_Spell_1 + mouseOnItem) ||
+ _engine->getScriptManager()->getStateValue(StateKey_Spell_1 + lastItem))
redraw = true;
}
break;
- case menu_MAIN: {
+ case kMenuMain: {
int lastItem = mouseOnItem;
mouseOnItem = -1;
// Exit
- if (menuBarFlag & menuBar_Exit)
+ if (menuBarFlag & kMenubarExit)
if (Common::Rect(320 + 135,
- scrollPos[menu_MAIN],
+ scrollPos[kMenuMain],
320 + 135 + 135,
- scrollPos[menu_MAIN] + 32).contains(Pos)) {
- mouseOnItem = menu_MAIN_EXIT;
+ scrollPos[kMenuMain] + 32).contains(Pos)) {
+ mouseOnItem = kMainMenuExit;
}
// Settings
- if (menuBarFlag & menuBar_Settings)
+ if (menuBarFlag & kMenubarSettings)
if (Common::Rect(320 ,
- scrollPos[menu_MAIN],
+ scrollPos[kMenuMain],
320 + 135,
- scrollPos[menu_MAIN] + 32).contains(Pos)) {
- mouseOnItem = menu_MAIN_PREF;
+ scrollPos[kMenuMain] + 32).contains(Pos)) {
+ mouseOnItem = kMainMenuPrefs;
}
// Load
- if (menuBarFlag & menuBar_Restore)
+ if (menuBarFlag & kMenubarRestore)
if (Common::Rect(320 - 135,
- scrollPos[menu_MAIN],
+ scrollPos[kMenuMain],
320,
- scrollPos[menu_MAIN] + 32).contains(Pos)) {
- mouseOnItem = menu_MAIN_REST;
+ scrollPos[kMenuMain] + 32).contains(Pos)) {
+ mouseOnItem = kMainMenuLoad;
}
// Save
- if (menuBarFlag & menuBar_Save)
+ if (menuBarFlag & kMenubarSave)
if (Common::Rect(320 - 135 * 2,
- scrollPos[menu_MAIN],
+ scrollPos[kMenuMain],
320 - 135,
- scrollPos[menu_MAIN] + 32).contains(Pos)) {
- mouseOnItem = menu_MAIN_SAVE;
+ scrollPos[kMenuMain] + 32).contains(Pos)) {
+ mouseOnItem = kMainMenuSave;
}
if (lastItem != mouseOnItem)
@@ -313,25 +309,25 @@ void MenuZGI::onMouseMove(const Common::Point &Pos) {
default:
int cur_menu = menuMouseFocus;
if (Common::Rect(64, 0, 64 + 512, 8).contains(Pos)) { // Main
- menuMouseFocus = menu_MAIN;
- scrolled[menu_MAIN] = false;
- scrollPos[menu_MAIN] = menuback[menu_MAIN][1].h - menuback[menu_MAIN][0].h;
+ menuMouseFocus = kMenuMain;
+ scrolled[kMenuMain] = false;
+ scrollPos[kMenuMain] = menuBack[kMenuMain][1].h - menuBack[kMenuMain][0].h;
_engine->getScriptManager()->setStateValue(StateKey_MenuState, 2);
}
- if (menuBarFlag & menuBar_Magic)
+ if (menuBarFlag & kMenubarMagic)
if (Common::Rect(640 - 28, 0, 640, 32).contains(Pos)) { // Magic
- menuMouseFocus = menu_MAGIC;
- scrolled[menu_MAGIC] = false;
- scrollPos[menu_MAGIC] = 28;
+ menuMouseFocus = kMenuMagic;
+ scrolled[kMenuMagic] = false;
+ scrollPos[kMenuMagic] = 28;
_engine->getScriptManager()->setStateValue(StateKey_MenuState, 3);
}
- if (menuBarFlag & menuBar_Items)
+ if (menuBarFlag & kMenubarItems)
if (Common::Rect(0, 0, 28, 32).contains(Pos)) { // Items
- menuMouseFocus = menu_ITEM;
- scrolled[menu_ITEM] = false;
- scrollPos[menu_ITEM] = 28 - 600;
+ menuMouseFocus = kMenuItem;
+ scrolled[kMenuItem] = false;
+ scrollPos[kMenuItem] = 28 - 600;
_engine->getScriptManager()->setStateValue(StateKey_MenuState, 1);
}
@@ -341,9 +337,9 @@ void MenuZGI::onMouseMove(const Common::Point &Pos) {
break;
}
} else {
- if (inmenu)
+ if (inMenu)
clean = true;
- inmenu = false;
+ inMenu = false;
if (_engine->getScriptManager()->getStateValue(StateKey_MenuState) != 0)
_engine->getScriptManager()->setStateValue(StateKey_MenuState, 0);
menuMouseFocus = -1;
@@ -356,24 +352,24 @@ void MenuZGI::process(uint32 deltatime) {
clean = false;
}
switch (menuMouseFocus) {
- case menu_ITEM:
- if (menuBarFlag & menuBar_Items)
- if (!scrolled[menu_ITEM]) {
+ case kMenuItem:
+ if (menuBarFlag & kMenubarItems)
+ if (!scrolled[kMenuItem]) {
redraw = true;
float scrl = 600.0 * (deltatime / 1000.0);
if (scrl == 0)
scrl = 1.0;
- scrollPos [menu_ITEM] += scrl;
+ scrollPos[kMenuItem] += (int)scrl;
- if (scrollPos[menu_ITEM] >= 0) {
- scrolled[menu_ITEM] = true;
- scrollPos [menu_ITEM] = 0;
+ if (scrollPos[kMenuItem] >= 0) {
+ scrolled[kMenuItem] = true;
+ scrollPos[kMenuItem] = 0;
}
}
if (redraw) {
- _engine->getRenderManager()->blitSurfaceToMenu(menuback[menu_ITEM][0], scrollPos[menu_ITEM], 0);
+ _engine->getRenderManager()->blitSurfaceToMenu(menuBack[kMenuItem][0], scrollPos[kMenuItem], 0);
int itemCount = _engine->getScriptManager()->getStateValue(StateKey_Inv_TotalSlots);
if (itemCount == 0)
@@ -389,7 +385,7 @@ void MenuZGI::process(uint32 deltatime) {
if (mouseOnItem == i)
inrect = true;
- uint curItemId = _engine->getScriptManager()->getStateValue(SLOT_START_SLOT + i);
+ uint curItemId = _engine->getScriptManager()->getStateValue(StateKey_Inv_StartSlot + i);
if (curItemId != 0) {
if (itemId[i] != curItemId) {
@@ -402,9 +398,9 @@ void MenuZGI::process(uint32 deltatime) {
}
if (inrect)
- _engine->getRenderManager()->blitSurfaceToMenu(*items[i][1], scrollPos[menu_ITEM] + itemspace * i, 0, 0);
+ _engine->getRenderManager()->blitSurfaceToMenu(*items[i][1], scrollPos[kMenuItem] + itemspace * i, 0, 0);
else
- _engine->getRenderManager()->blitSurfaceToMenu(*items[i][0], scrollPos[menu_ITEM] + itemspace * i, 0, 0);
+ _engine->getRenderManager()->blitSurfaceToMenu(*items[i][0], scrollPos[kMenuItem] + itemspace * i, 0, 0);
} else {
if (items[i][0]) {
@@ -425,24 +421,24 @@ void MenuZGI::process(uint32 deltatime) {
}
break;
- case menu_MAGIC:
- if (menuBarFlag & menuBar_Magic)
- if (!scrolled[menu_MAGIC]) {
+ case kMenuMagic:
+ if (menuBarFlag & kMenubarMagic)
+ if (!scrolled[kMenuMagic]) {
redraw = true;
float scrl = 600.0 * (deltatime / 1000.0);
if (scrl == 0)
scrl = 1.0;
- scrollPos [menu_MAGIC] += scrl;
+ scrollPos[kMenuMagic] += (int)scrl;
- if (scrollPos[menu_MAGIC] >= 600) {
- scrolled[menu_MAGIC] = true;
- scrollPos [menu_MAGIC] = 600;
+ if (scrollPos[kMenuMagic] >= 600) {
+ scrolled[kMenuMagic] = true;
+ scrollPos[kMenuMagic] = 600;
}
}
if (redraw) {
- _engine->getRenderManager()->blitSurfaceToMenu(menuback[menu_MAGIC][0], 640 - scrollPos[menu_MAGIC], 0);
+ _engine->getRenderManager()->blitSurfaceToMenu(menuBack[kMenuMagic][0], 640 - scrollPos[kMenuMagic], 0);
for (int i = 0; i < 12; i++) {
bool inrect = false;
@@ -450,9 +446,9 @@ void MenuZGI::process(uint32 deltatime) {
if (mouseOnItem == i)
inrect = true;
- uint curItemId = _engine->getScriptManager()->getStateValue(SLOT_SPELL_1 + i);
+ uint curItemId = _engine->getScriptManager()->getStateValue(StateKey_Spell_1 + i);
if (curItemId) {
- if (_engine->getScriptManager()->getStateValue(SLOT_REVERSED_SPELLBOOK) == 1)
+ if (_engine->getScriptManager()->getStateValue(StateKey_Reversed_Spellbooc) == 1)
curItemId = 0xEE + i;
else
curItemId = 0xE0 + i;
@@ -469,9 +465,9 @@ void MenuZGI::process(uint32 deltatime) {
}
if (inrect)
- _engine->getRenderManager()->blitSurfaceToMenu(*magic[i][1], 668 + 47 * i - scrollPos[menu_MAGIC], 0, 0);
+ _engine->getRenderManager()->blitSurfaceToMenu(*magic[i][1], 668 + 47 * i - scrollPos[kMenuMagic], 0, 0);
else
- _engine->getRenderManager()->blitSurfaceToMenu(*magic[i][0], 668 + 47 * i - scrollPos[menu_MAGIC], 0, 0);
+ _engine->getRenderManager()->blitSurfaceToMenu(*magic[i][0], 668 + 47 * i - scrollPos[kMenuMagic], 0, 0);
} else {
if (magic[i][0]) {
@@ -491,61 +487,61 @@ void MenuZGI::process(uint32 deltatime) {
}
break;
- case menu_MAIN:
- if (!scrolled[menu_MAIN]) {
+ case kMenuMain:
+ if (!scrolled[kMenuMain]) {
redraw = true;
float scrl = 32.0 * 2.0 * (deltatime / 1000.0);
if (scrl == 0)
scrl = 1.0;
- scrollPos [menu_MAIN] += scrl;
+ scrollPos[kMenuMain] += (int)scrl;
- if (scrollPos[menu_MAIN] >= 0) {
- scrolled[menu_MAIN] = true;
- scrollPos [menu_MAIN] = 0;
+ if (scrollPos[kMenuMain] >= 0) {
+ scrolled[kMenuMain] = true;
+ scrollPos[kMenuMain] = 0;
}
}
if (redraw) {
- _engine->getRenderManager()->blitSurfaceToMenu(menuback[menu_MAIN][0], 30, scrollPos[menu_MAIN]);
+ _engine->getRenderManager()->blitSurfaceToMenu(menuBack[kMenuMain][0], 30, scrollPos[kMenuMain]);
- if (menuBarFlag & menuBar_Exit) {
- if (mouseOnItem == menu_MAIN_EXIT)
- _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_EXIT][1], 320 + 135, scrollPos[menu_MAIN]);
+ if (menuBarFlag & kMenubarExit) {
+ if (mouseOnItem == kMainMenuExit)
+ _engine->getRenderManager()->blitSurfaceToMenu(menuBar[kMainMenuExit][1], 320 + 135, scrollPos[kMenuMain]);
else
- _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_EXIT][0], 320 + 135, scrollPos[menu_MAIN]);
+ _engine->getRenderManager()->blitSurfaceToMenu(menuBar[kMainMenuExit][0], 320 + 135, scrollPos[kMenuMain]);
}
- if (menuBarFlag & menuBar_Settings) {
- if (mouseOnItem == menu_MAIN_PREF)
- _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_PREF][1], 320, scrollPos[menu_MAIN]);
+ if (menuBarFlag & kMenubarSettings) {
+ if (mouseOnItem == kMainMenuPrefs)
+ _engine->getRenderManager()->blitSurfaceToMenu(menuBar[kMainMenuPrefs][1], 320, scrollPos[kMenuMain]);
else
- _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_PREF][0], 320, scrollPos[menu_MAIN]);
+ _engine->getRenderManager()->blitSurfaceToMenu(menuBar[kMainMenuPrefs][0], 320, scrollPos[kMenuMain]);
}
- if (menuBarFlag & menuBar_Restore) {
- if (mouseOnItem == menu_MAIN_REST)
- _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_REST][1], 320 - 135, scrollPos[menu_MAIN]);
+ if (menuBarFlag & kMenubarRestore) {
+ if (mouseOnItem == kMainMenuLoad)
+ _engine->getRenderManager()->blitSurfaceToMenu(menuBar[kMainMenuLoad][1], 320 - 135, scrollPos[kMenuMain]);
else
- _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_REST][0], 320 - 135, scrollPos[menu_MAIN]);
+ _engine->getRenderManager()->blitSurfaceToMenu(menuBar[kMainMenuLoad][0], 320 - 135, scrollPos[kMenuMain]);
}
- if (menuBarFlag & menuBar_Save) {
- if (mouseOnItem == menu_MAIN_SAVE)
- _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_SAVE][1], 320 - 135 * 2, scrollPos[menu_MAIN]);
+ if (menuBarFlag & kMenubarSave) {
+ if (mouseOnItem == kMainMenuSave)
+ _engine->getRenderManager()->blitSurfaceToMenu(menuBar[kMainMenuSave][1], 320 - 135 * 2, scrollPos[kMenuMain]);
else
- _engine->getRenderManager()->blitSurfaceToMenu(menubar[menu_MAIN_SAVE][0], 320 - 135 * 2, scrollPos[menu_MAIN]);
+ _engine->getRenderManager()->blitSurfaceToMenu(menuBar[kMainMenuSave][0], 320 - 135 * 2, scrollPos[kMenuMain]);
}
redraw = false;
}
break;
default:
if (redraw) {
- if (inmenu) {
- _engine->getRenderManager()->blitSurfaceToMenu(menuback[menu_MAIN][1], 30, 0);
+ if (inMenu) {
+ _engine->getRenderManager()->blitSurfaceToMenu(menuBack[kMenuMain][1], 30, 0);
- if (menuBarFlag & menuBar_Items)
- _engine->getRenderManager()->blitSurfaceToMenu(menuback[menu_ITEM][1], 0, 0);
+ if (menuBarFlag & kMenubarItems)
+ _engine->getRenderManager()->blitSurfaceToMenu(menuBack[kMenuItem][1], 0, 0);
- if (menuBarFlag & menuBar_Magic)
- _engine->getRenderManager()->blitSurfaceToMenu(menuback[menu_MAGIC][1], 640 - 28, 0);
+ if (menuBarFlag & kMenubarMagic)
+ _engine->getRenderManager()->blitSurfaceToMenu(menuBack[kMenuMagic][1], 640 - 28, 0);
}
redraw = false;
}
@@ -555,9 +551,9 @@ void MenuZGI::process(uint32 deltatime) {
MenuNemesis::MenuNemesis(ZVision *engine) :
MenuHandler(engine) {
- inmenu = false;
+ inMenu = false;
scrolled = false;
- scrollPos = 0.0;
+ scrollPos = 0;
mouseOnItem = -1;
redraw = false;
delay = 0;
@@ -569,7 +565,7 @@ MenuNemesis::MenuNemesis(ZVision *engine) :
_engine->getRenderManager()->readImageToSurface(buf, but[i][j], false);
}
- _engine->getRenderManager()->readImageToSurface("bar.tga", menubar, false);
+ _engine->getRenderManager()->readImageToSurface("bar.tga", menuBar, false);
frm = 0;
}
@@ -579,7 +575,7 @@ MenuNemesis::~MenuNemesis() {
for (int j = 0; j < 6; j++)
but[i][j].free();
- menubar.free();
+ menuBar.free();
}
static const int16 buts[4][2] = { {120 , 64}, {144, 184}, {128, 328}, {120, 456} };
@@ -587,7 +583,7 @@ static const int16 buts[4][2] = { {120 , 64}, {144, 184}, {128, 328}, {120, 456}
void MenuNemesis::onMouseUp(const Common::Point &Pos) {
if (Pos.y < 40) {
// Exit
- if (menuBarFlag & menuBar_Exit)
+ if (menuBarFlag & kMenubarExit)
if (Common::Rect(buts[3][1],
scrollPos,
buts[3][0] + buts[3][1],
@@ -598,7 +594,7 @@ void MenuNemesis::onMouseUp(const Common::Point &Pos) {
}
// Settings
- if (menuBarFlag & menuBar_Settings)
+ if (menuBarFlag & kMenubarSettings)
if (Common::Rect(buts[2][1],
scrollPos,
buts[2][0] + buts[2][1],
@@ -609,7 +605,7 @@ void MenuNemesis::onMouseUp(const Common::Point &Pos) {
}
// Load
- if (menuBarFlag & menuBar_Restore)
+ if (menuBarFlag & kMenubarRestore)
if (Common::Rect(buts[1][1],
scrollPos,
buts[1][0] + buts[1][1],
@@ -620,7 +616,7 @@ void MenuNemesis::onMouseUp(const Common::Point &Pos) {
}
// Save
- if (menuBarFlag & menuBar_Save)
+ if (menuBarFlag & kMenubarSave)
if (Common::Rect(buts[0][1],
scrollPos,
buts[0][0] + buts[0][1],
@@ -635,7 +631,7 @@ void MenuNemesis::onMouseUp(const Common::Point &Pos) {
void MenuNemesis::onMouseMove(const Common::Point &Pos) {
if (Pos.y < 40) {
- inmenu = true;
+ inMenu = true;
if (_engine->getScriptManager()->getStateValue(StateKey_MenuState) != 2)
_engine->getScriptManager()->setStateValue(StateKey_MenuState, 2);
@@ -644,39 +640,39 @@ void MenuNemesis::onMouseMove(const Common::Point &Pos) {
mouseOnItem = -1;
// Exit
- if (menuBarFlag & menuBar_Exit)
+ if (menuBarFlag & kMenubarExit)
if (Common::Rect(buts[3][1],
scrollPos,
buts[3][0] + buts[3][1],
scrollPos + 32).contains(Pos)) {
- mouseOnItem = menu_MAIN_EXIT;
+ mouseOnItem = kMainMenuExit;
}
// Settings
- if (menuBarFlag & menuBar_Settings)
+ if (menuBarFlag & kMenubarSettings)
if (Common::Rect(buts[2][1],
scrollPos,
buts[2][0] + buts[2][1],
scrollPos + 32).contains(Pos)) {
- mouseOnItem = menu_MAIN_PREF;
+ mouseOnItem = kMainMenuPrefs;
}
// Load
- if (menuBarFlag & menuBar_Restore)
+ if (menuBarFlag & kMenubarRestore)
if (Common::Rect(buts[1][1],
scrollPos,
buts[1][0] + buts[1][1],
scrollPos + 32).contains(Pos)) {
- mouseOnItem = menu_MAIN_REST;
+ mouseOnItem = kMainMenuLoad;
}
// Save
- if (menuBarFlag & menuBar_Save)
+ if (menuBarFlag & kMenubarSave)
if (Common::Rect(buts[0][1],
scrollPos,
buts[0][0] + buts[0][1],
scrollPos + 32).contains(Pos)) {
- mouseOnItem = menu_MAIN_SAVE;
+ mouseOnItem = kMainMenuSave;
}
if (lastItem != mouseOnItem) {
@@ -685,7 +681,7 @@ void MenuNemesis::onMouseMove(const Common::Point &Pos) {
delay = 200;
}
} else {
- inmenu = false;
+ inMenu = false;
if (_engine->getScriptManager()->getStateValue(StateKey_MenuState) != 0)
_engine->getScriptManager()->setStateValue(StateKey_MenuState, 0);
mouseOnItem = -1;
@@ -693,14 +689,14 @@ void MenuNemesis::onMouseMove(const Common::Point &Pos) {
}
void MenuNemesis::process(uint32 deltatime) {
- if (inmenu) {
+ if (inMenu) {
if (!scrolled) {
float scrl = 32.0 * 2.0 * (deltatime / 1000.0);
if (scrl == 0)
scrl = 1.0;
- scrollPos += scrl;
+ scrollPos += (int)scrl;
redraw = true;
}
@@ -719,22 +715,22 @@ void MenuNemesis::process(uint32 deltatime) {
}
if (redraw) {
- _engine->getRenderManager()->blitSurfaceToMenu(menubar, 64, scrollPos);
+ _engine->getRenderManager()->blitSurfaceToMenu(menuBar, 64, scrollPos);
- if (menuBarFlag & menuBar_Exit)
- if (mouseOnItem == menu_MAIN_EXIT)
+ if (menuBarFlag & kMenubarExit)
+ if (mouseOnItem == kMainMenuExit)
_engine->getRenderManager()->blitSurfaceToMenu(but[3][frm], buts[3][1], scrollPos);
- if (menuBarFlag & menuBar_Settings)
- if (mouseOnItem == menu_MAIN_PREF)
+ if (menuBarFlag & kMenubarSettings)
+ if (mouseOnItem == kMainMenuPrefs)
_engine->getRenderManager()->blitSurfaceToMenu(but[2][frm], buts[2][1], scrollPos);
- if (menuBarFlag & menuBar_Restore)
- if (mouseOnItem == menu_MAIN_REST)
+ if (menuBarFlag & kMenubarRestore)
+ if (mouseOnItem == kMainMenuLoad)
_engine->getRenderManager()->blitSurfaceToMenu(but[1][frm], buts[1][1], scrollPos);
- if (menuBarFlag & menuBar_Save)
- if (mouseOnItem == menu_MAIN_SAVE)
+ if (menuBarFlag & kMenubarSave)
+ if (mouseOnItem == kMainMenuSave)
_engine->getRenderManager()->blitSurfaceToMenu(but[0][frm], buts[0][1], scrollPos);
redraw = false;
@@ -747,16 +743,16 @@ void MenuNemesis::process(uint32 deltatime) {
if (scrl == 0)
scrl = 1.0;
- Common::Rect cl(64, 32 + scrollPos - scrl, 64 + 512, 32 + scrollPos + 1);
+ Common::Rect cl(64, (int16)(32 + scrollPos - scrl), 64 + 512, 32 + scrollPos + 1);
_engine->getRenderManager()->clearMenuSurface(cl);
- scrollPos -= scrl;
+ scrollPos -= (int)scrl;
redraw = true;
} else
scrollPos = -32;
if (redraw) {
- _engine->getRenderManager()->blitSurfaceToMenu(menubar, 64, scrollPos);
+ _engine->getRenderManager()->blitSurfaceToMenu(menuBar, 64, scrollPos);
redraw = false;
}
}
diff --git a/engines/zvision/core/menu.h b/engines/zvision/scripting/menu.h
index ebe0bb50ac..f6b21b9c97 100644
--- a/engines/zvision/core/menu.h
+++ b/engines/zvision/scripting/menu.h
@@ -32,12 +32,12 @@
namespace ZVision {
enum menuBar {
- menuBar_Exit = 0x1,
- menuBar_Settings = 0x2,
- menuBar_Restore = 0x4,
- menuBar_Save = 0x8,
- menuBar_Items = 0x100,
- menuBar_Magic = 0x200
+ kMenubarExit = 0x1,
+ kMenubarSettings = 0x2,
+ kMenubarRestore = 0x4,
+ kMenubarSave = 0x8,
+ kMenubarItems = 0x100,
+ kMenubarMagic = 0x200
};
class MenuHandler {
@@ -68,8 +68,8 @@ public:
void onMouseUp(const Common::Point &Pos);
void process(uint32 deltaTimeInMillis);
private:
- Graphics::Surface menuback[3][2];
- Graphics::Surface menubar[4][2];
+ Graphics::Surface menuBack[3][2];
+ Graphics::Surface menuBar[4][2];
Graphics::Surface *items[50][2];
uint itemId[50];
@@ -77,19 +77,13 @@ private:
uint magicId[12];
int menuMouseFocus;
- bool inmenu;
+ bool inMenu;
int mouseOnItem;
- bool scrolled[3];
+ bool scrolled[3];
int16 scrollPos[3];
- enum {
- menu_ITEM = 0,
- menu_MAGIC = 1,
- menu_MAIN = 2
- };
-
bool clean;
bool redraw;
@@ -104,13 +98,13 @@ public:
void process(uint32 deltaTimeInMillis);
private:
Graphics::Surface but[4][6];
- Graphics::Surface menubar;
+ Graphics::Surface menuBar;
- bool inmenu;
+ bool inMenu;
int mouseOnItem;
- bool scrolled;
+ bool scrolled;
int16 scrollPos;
bool redraw;
@@ -120,6 +114,6 @@ private:
};
-}
+} // End of namespace ZVision
#endif
diff --git a/engines/zvision/scripting/scr_file_handling.cpp b/engines/zvision/scripting/scr_file_handling.cpp
index c117da5ec2..edc1b8622c 100644
--- a/engines/zvision/scripting/scr_file_handling.cpp
+++ b/engines/zvision/scripting/scr_file_handling.cpp
@@ -47,15 +47,13 @@ namespace ZVision {
void ScriptManager::parseScrFile(const Common::String &fileName, ScriptScope &scope) {
Common::File file;
if (!_engine->getSearchManager()->openFile(file, fileName)) {
- warning("Script file not found: %s", fileName.c_str());
- return;
+ error("Script file not found: %s", fileName.c_str());
}
while (!file.eos()) {
Common::String line = file.readLine();
if (file.err()) {
- warning("Error parsing scr file: %s", fileName.c_str());
- return;
+ error("Error parsing scr file: %s", fileName.c_str());
}
trimCommentsAndWhiteSpace(&line);
@@ -85,9 +83,18 @@ void ScriptManager::parsePuzzle(Puzzle *puzzle, Common::SeekableReadStream &stre
while (!stream.eos() && !line.contains('}')) {
if (line.matchString("criteria {", true)) {
- parseCriteria(stream, puzzle->criteriaList);
+ parseCriteria(stream, puzzle->criteriaList, puzzle->key);
} else if (line.matchString("results {", true)) {
parseResults(stream, puzzle->resultActions);
+
+ // WORKAROUND for a script bug in Zork Nemesis, room ve5e (tuning
+ // fork box closeup). If the player leaves the screen while the
+ // box is open, puzzle 19398 shows the animation where the box
+ // closes, but the box state (state variable 19397) is not updated.
+ // We insert the missing assignment for the box state here.
+ // Fixes bug #6803.
+ if (_engine->getGameId() == GID_NEMESIS && puzzle->key == 19398)
+ puzzle->resultActions.push_back(new ActionAssign(_engine, 11, "19397, 0"));
} else if (line.matchString("flags {", true)) {
setStateFlag(puzzle->key, parseFlags(stream));
}
@@ -99,11 +106,18 @@ void ScriptManager::parsePuzzle(Puzzle *puzzle, Common::SeekableReadStream &stre
puzzle->addedBySetState = false;
}
-bool ScriptManager::parseCriteria(Common::SeekableReadStream &stream, Common::List<Common::List<Puzzle::CriteriaEntry> > &criteriaList) const {
+bool ScriptManager::parseCriteria(Common::SeekableReadStream &stream, Common::List<Common::List<Puzzle::CriteriaEntry> > &criteriaList, uint32 key) const {
// Loop until we find the closing brace
Common::String line = stream.readLine();
trimCommentsAndWhiteSpace(&line);
+ // Skip any commented out criteria. If all the criteria are commented out,
+ // we might end up with an invalid criteria list (bug #6776).
+ while (line.empty()) {
+ line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ }
+
// Criteria can be empty
if (line.contains('}')) {
return false;
@@ -112,6 +126,21 @@ bool ScriptManager::parseCriteria(Common::SeekableReadStream &stream, Common::Li
// Create a new List to hold the CriteriaEntries
criteriaList.push_back(Common::List<Puzzle::CriteriaEntry>());
+ // WORKAROUND for a script bug in Zork: Nemesis, room td9e (fist puzzle)
+ // Since we patch the script that triggers when manipulating the left fist
+ // (below), we add an additional check for the left fist sound, so that it
+ // doesn't get killed immediately when the left fist animation starts.
+ // Together with the workaround below, it fixes bug #6783.
+ if (_engine->getGameId() == GID_NEMESIS && key == 3594) {
+ Puzzle::CriteriaEntry entry;
+ entry.key = 567;
+ entry.criteriaOperator = Puzzle::NOT_EQUAL_TO;
+ entry.argumentIsAKey = false;
+ entry.argument = 1;
+
+ criteriaList.back().push_back(entry);
+ }
+
while (!stream.eos() && !line.contains('}')) {
Puzzle::CriteriaEntry entry;
@@ -123,6 +152,13 @@ bool ScriptManager::parseCriteria(Common::SeekableReadStream &stream, Common::Li
token = tokenizer.nextToken();
sscanf(token.c_str(), "[%u]", &(entry.key));
+ // WORKAROUND for a script bug in Zork: Nemesis, room td9e (fist puzzle)
+ // Check for the state of animation 567 (left fist) when manipulating
+ // the fingers of the left fist (puzzle slots 3582, 3583).
+ // Together with the workaround above, it fixes bug #6783.
+ if (_engine->getGameId() == GID_NEMESIS && (key == 3582 || key == 3583) && entry.key == 568)
+ entry.key = 567;
+
// Parse the operator out of the second token
token = tokenizer.nextToken();
if (token.c_str()[0] == '=')
@@ -134,9 +170,17 @@ bool ScriptManager::parseCriteria(Common::SeekableReadStream &stream, Common::Li
else if (token.c_str()[0] == '<')
entry.criteriaOperator = Puzzle::LESS_THAN;
+ // There are supposed to be three tokens, but there is no
+ // guarantee that there will be a space between the second and
+ // the third one (bug #6774)
+ if (token.size() == 1) {
+ token = tokenizer.nextToken();
+ } else {
+ token.deleteChar(0);
+ }
+
// First determine if the last token is an id or a value
// Then parse it into 'argument'
- token = tokenizer.nextToken();
if (token.contains('[')) {
sscanf(token.c_str(), "[%u]", &(entry.argument));
entry.argumentIsAKey = true;
@@ -216,6 +260,7 @@ void ScriptManager::parseResults(Common::SeekableReadStream &stream, Common::Lis
} else if (act.matchString("animpreload", true)) {
actionList.push_back(new ActionPreloadAnimation(_engine, slot, args));
} else if (act.matchString("animunload", true)) {
+ // Only used by ZGI (locations cd6e, cd6k, dg2f, dg4e, dv1j)
actionList.push_back(new ActionUnloadAnimation(_engine, slot, args));
} else if (act.matchString("attenuate", true)) {
actionList.push_back(new ActionAttenuate(_engine, slot, args));
@@ -234,12 +279,13 @@ void ScriptManager::parseResults(Common::SeekableReadStream &stream, Common::Lis
} else if (act.matchString("disable_control", true)) {
actionList.push_back(new ActionDisableControl(_engine, slot, args));
} else if (act.matchString("disable_venus", true)) {
- actionList.push_back(new ActionDisableVenus(_engine, slot, args));
+ // Not used. Purposely left empty
} else if (act.matchString("display_message", true)) {
actionList.push_back(new ActionDisplayMessage(_engine, slot, args));
} else if (act.matchString("dissolve", true)) {
actionList.push_back(new ActionDissolve(_engine));
} else if (act.matchString("distort", true)) {
+ // Only used by Zork: Nemesis for the "treatment" puzzle in the Sanitarium (aj30)
actionList.push_back(new ActionDistort(_engine, slot, args));
} else if (act.matchString("enable_control", true)) {
actionList.push_back(new ActionEnableControl(_engine, slot, args));
@@ -248,6 +294,7 @@ void ScriptManager::parseResults(Common::SeekableReadStream &stream, Common::Lis
} else if (act.matchString("inventory", true)) {
actionList.push_back(new ActionInventory(_engine, slot, args));
} else if (act.matchString("kill", true)) {
+ // Only used by ZGI
actionList.push_back(new ActionKill(_engine, slot, args));
} else if (act.matchString("menu_bar_enable", true)) {
actionList.push_back(new ActionMenuBarEnable(_engine, slot, args));
@@ -264,8 +311,11 @@ void ScriptManager::parseResults(Common::SeekableReadStream &stream, Common::Lis
} else if (act.matchString("random", true)) {
actionList.push_back(new ActionRandom(_engine, slot, args));
} else if (act.matchString("region", true)) {
+ // Only used by Zork: Nemesis
actionList.push_back(new ActionRegion(_engine, slot, args));
} else if (act.matchString("restore_game", true)) {
+ // Only used by ZGI to load the restart game slot, r.svr.
+ // Used by the credits screen.
actionList.push_back(new ActionRestoreGame(_engine, slot, args));
} else if (act.matchString("rotate_to", true)) {
actionList.push_back(new ActionRotateTo(_engine, slot, args));
@@ -276,7 +326,7 @@ void ScriptManager::parseResults(Common::SeekableReadStream &stream, Common::Lis
} else if (act.matchString("set_screen", true)) {
actionList.push_back(new ActionSetScreen(_engine, slot, args));
} else if (act.matchString("set_venus", true)) {
- actionList.push_back(new ActionSetVenus(_engine, slot, args));
+ // Not used. Purposely left empty
} else if (act.matchString("stop", true)) {
actionList.push_back(new ActionStop(_engine, slot, args));
} else if (act.matchString("streamvideo", true)) {
@@ -337,6 +387,16 @@ Control *ScriptManager::parseControl(Common::String &line, Common::SeekableReadS
Common::String controlType(controlTypeBuffer);
if (controlType.equalsIgnoreCase("push_toggle")) {
+ // WORKAROUND for a script bug in ZGI: There is an invalid hotspot
+ // at scene em1h (bottom of tower), which points to a missing
+ // script em1n. This is a hotspot at the right of the screen.
+ // In the original, this hotspot doesn't lead anywhere anyway,
+ // so instead of moving to a missing scene, we just remove the
+ // hotspot altogether. The alternative would be to just process
+ // and ignore invalid scenes, but I don't think it's worth the
+ // effort. Fixes bug #6780.
+ if (_engine->getGameId() == GID_GRANDINQUISITOR && key == 5653)
+ return NULL;
return new PushToggleControl(_engine, key, stream);
} else if (controlType.equalsIgnoreCase("flat")) {
Control::parseFlatControl(_engine);
@@ -345,25 +405,32 @@ Control *ScriptManager::parseControl(Common::String &line, Common::SeekableReadS
Control::parsePanoramaControl(_engine, stream);
return NULL;
} else if (controlType.equalsIgnoreCase("tilt")) {
+ // Only used in Zork Nemesis, handles tilt controls (ZGI doesn't have a tilt view)
Control::parseTiltControl(_engine, stream);
return NULL;
- } else if (controlType.equalsIgnoreCase("lever")) {
- return new LeverControl(_engine, key, stream);
} else if (controlType.equalsIgnoreCase("slot")) {
return new SlotControl(_engine, key, stream);
} else if (controlType.equalsIgnoreCase("input")) {
return new InputControl(_engine, key, stream);
} else if (controlType.equalsIgnoreCase("save")) {
return new SaveControl(_engine, key, stream);
+ } else if (controlType.equalsIgnoreCase("lever")) {
+ // Only used in Zork Nemesis, handles draggable levers (te2e, tm7e, tp2e, tt2e, tz2e)
+ return new LeverControl(_engine, key, stream);
} else if (controlType.equalsIgnoreCase("safe")) {
+ // Only used in Zork Nemesis, handles the safe in the Asylum (ac4g)
return new SafeControl(_engine, key, stream);
} else if (controlType.equalsIgnoreCase("hotmovie")) {
+ // Only used in Zork Nemesis, handles movies where the player needs to click on something (mj7g, vw3g)
return new HotMovControl(_engine, key, stream);
} else if (controlType.equalsIgnoreCase("fist")) {
+ // Only used in Zork Nemesis, handles the door lock puzzle with the skeletal fingers (td9e)
return new FistControl(_engine, key, stream);
} else if (controlType.equalsIgnoreCase("paint")) {
+ // Only used in Zork Nemesis, handles the painting puzzle screen in Lucien's room in Irondune (ch4g)
return new PaintControl(_engine, key, stream);
} else if (controlType.equalsIgnoreCase("titler")) {
+ // Only used in Zork Nemesis, handles the death screen with the Restore/Exit buttons (cjde)
return new TitlerControl(_engine, key, stream);
}
return NULL;
diff --git a/engines/zvision/scripting/script_manager.cpp b/engines/zvision/scripting/script_manager.cpp
index 4c1e69072d..70eaab2a0a 100644
--- a/engines/zvision/scripting/script_manager.cpp
+++ b/engines/zvision/scripting/script_manager.cpp
@@ -27,9 +27,10 @@
#include "zvision/zvision.h"
#include "zvision/graphics/render_manager.h"
#include "zvision/graphics/cursors/cursor_manager.h"
-#include "zvision/core/save_manager.h"
+#include "zvision/file/save_manager.h"
#include "zvision/scripting/actions.h"
-#include "zvision/scripting/sidefx/timer_node.h"
+#include "zvision/scripting/menu.h"
+#include "zvision/scripting/effects/timer_effect.h"
#include "common/algorithm.h"
#include "common/hashmap.h"
@@ -71,21 +72,23 @@ void ScriptManager::initialize() {
}
void ScriptManager::update(uint deltaTimeMillis) {
- if (_currentLocation.node != _nextLocation.node ||
- _currentLocation.room != _nextLocation.room ||
- _currentLocation.view != _nextLocation.view ||
- _currentLocation.world != _nextLocation.world)
- ChangeLocationReal();
+ if (_currentLocation != _nextLocation) {
+ ChangeLocationReal(false);
+ }
updateNodes(deltaTimeMillis);
- if (! execScope(nodeview))
+ if (!execScope(nodeview)) {
return;
- if (! execScope(room))
+ }
+ if (!execScope(room)) {
return;
- if (! execScope(world))
+ }
+ if (!execScope(world)) {
return;
- if (! execScope(universe))
+ }
+ if (!execScope(universe)) {
return;
+ }
updateControls(deltaTimeMillis);
}
@@ -96,17 +99,22 @@ bool ScriptManager::execScope(ScriptScope &scope) {
scope.scopeQueue = tmp;
scope.scopeQueue->clear();
- for (PuzzleList::iterator PuzzleIter = scope.puzzles.begin(); PuzzleIter != scope.puzzles.end(); ++PuzzleIter)
+ for (PuzzleList::iterator PuzzleIter = scope.puzzles.begin(); PuzzleIter != scope.puzzles.end(); ++PuzzleIter) {
(*PuzzleIter)->addedBySetState = false;
+ }
if (scope.procCount < 2 || getStateValue(StateKey_ExecScopeStyle)) {
- for (PuzzleList::iterator PuzzleIter = scope.puzzles.begin(); PuzzleIter != scope.puzzles.end(); ++PuzzleIter)
- if (!checkPuzzleCriteria(*PuzzleIter, scope.procCount))
+ for (PuzzleList::iterator PuzzleIter = scope.puzzles.begin(); PuzzleIter != scope.puzzles.end(); ++PuzzleIter) {
+ if (!checkPuzzleCriteria(*PuzzleIter, scope.procCount)) {
return false;
+ }
+ }
} else {
- for (PuzzleList::iterator PuzzleIter = scope.execQueue->begin(); PuzzleIter != scope.execQueue->end(); ++PuzzleIter)
- if (!checkPuzzleCriteria(*PuzzleIter, scope.procCount))
+ for (PuzzleList::iterator PuzzleIter = scope.execQueue->begin(); PuzzleIter != scope.execQueue->end(); ++PuzzleIter) {
+ if (!checkPuzzleCriteria(*PuzzleIter, scope.procCount)) {
return false;
+ }
+ }
}
if (scope.procCount < 2) {
@@ -118,9 +126,11 @@ bool ScriptManager::execScope(ScriptScope &scope) {
void ScriptManager::referenceTableAddPuzzle(uint32 key, PuzzleRef ref) {
if (_referenceTable.contains(key)) {
Common::Array<PuzzleRef> *arr = &_referenceTable[key];
- for (uint32 i = 0; i < arr->size(); i++)
- if ((*arr)[i].puz == ref.puz)
+ for (uint32 i = 0; i < arr->size(); i++) {
+ if ((*arr)[i].puz == ref.puz) {
return;
+ }
+ }
}
_referenceTable[key].push_back(ref);
@@ -138,9 +148,11 @@ void ScriptManager::addPuzzlesToReferenceTable(ScriptScope &scope) {
referenceTableAddPuzzle(puzzlePtr->key, ref);
// Iterate through each CriteriaEntry and add a reference from the criteria key to the Puzzle
- for (Common::List<Common::List<Puzzle::CriteriaEntry> >::iterator criteriaIter = (*PuzzleIter)->criteriaList.begin(); criteriaIter != (*PuzzleIter)->criteriaList.end(); ++criteriaIter)
- for (Common::List<Puzzle::CriteriaEntry>::iterator entryIter = criteriaIter->begin(); entryIter != criteriaIter->end(); ++entryIter)
+ for (Common::List<Common::List<Puzzle::CriteriaEntry> >::iterator criteriaIter = (*PuzzleIter)->criteriaList.begin(); criteriaIter != (*PuzzleIter)->criteriaList.end(); ++criteriaIter) {
+ for (Common::List<Puzzle::CriteriaEntry>::iterator entryIter = criteriaIter->begin(); entryIter != criteriaIter->end(); ++entryIter) {
referenceTableAddPuzzle(entryIter->key, ref);
+ }
+ }
}
}
@@ -158,8 +170,9 @@ void ScriptManager::updateNodes(uint deltaTimeMillis) {
}
void ScriptManager::updateControls(uint deltaTimeMillis) {
- if (!_activeControls)
+ if (!_activeControls) {
return;
+ }
// Process only one event
if (!_controlEvents.empty()) {
@@ -186,21 +199,24 @@ void ScriptManager::updateControls(uint deltaTimeMillis) {
_controlEvents.pop_front();
}
- for (ControlList::iterator iter = _activeControls->begin(); iter != _activeControls->end(); iter++)
- if ((*iter)->process(deltaTimeMillis))
+ for (ControlList::iterator iter = _activeControls->begin(); iter != _activeControls->end(); iter++) {
+ if ((*iter)->process(deltaTimeMillis)) {
break;
+ }
+ }
}
bool ScriptManager::checkPuzzleCriteria(Puzzle *puzzle, uint counter) {
// Check if the puzzle is already finished
// Also check that the puzzle isn't disabled
- if (getStateValue(puzzle->key) == 1 || (getStateFlag(puzzle->key) & Puzzle::DISABLED) == Puzzle::DISABLED) {
+ if (getStateValue(puzzle->key) == 1 || (getStateFlag(puzzle->key) & Puzzle::DISABLED)) {
return true;
}
// Check each Criteria
- if (counter == 0 && (getStateFlag(puzzle->key) & Puzzle::DO_ME_NOW) == 0)
+ if (counter == 0 && (getStateFlag(puzzle->key) & Puzzle::DO_ME_NOW) == 0) {
return true;
+ }
bool criteriaMet = false;
for (Common::List<Common::List<Puzzle::CriteriaEntry> >::iterator criteriaIter = puzzle->criteriaList.begin(); criteriaIter != puzzle->criteriaList.end(); ++criteriaIter) {
@@ -209,10 +225,11 @@ bool ScriptManager::checkPuzzleCriteria(Puzzle *puzzle, uint counter) {
for (Common::List<Puzzle::CriteriaEntry>::iterator entryIter = criteriaIter->begin(); entryIter != criteriaIter->end(); ++entryIter) {
// Get the value to compare against
int argumentValue;
- if (entryIter->argumentIsAKey)
+ if (entryIter->argumentIsAKey) {
argumentValue = getStateValue(entryIter->argument);
- else
+ } else {
argumentValue = entryIter->argument;
+ }
// Do the comparison
switch (entryIter->criteriaOperator) {
@@ -250,8 +267,9 @@ bool ScriptManager::checkPuzzleCriteria(Puzzle *puzzle, uint counter) {
setStateValue(puzzle->key, 1);
for (Common::List<ResultAction *>::iterator resultIter = puzzle->resultActions.begin(); resultIter != puzzle->resultActions.end(); ++resultIter) {
- if (!(*resultIter)->execute())
+ if (!(*resultIter)->execute()) {
return false;
+ }
}
}
@@ -274,13 +292,15 @@ void ScriptManager::cleanScriptScope(ScriptScope &scope) {
scope.privQueueTwo.clear();
scope.scopeQueue = &scope.privQueueOne;
scope.execQueue = &scope.privQueueTwo;
- for (PuzzleList::iterator iter = scope.puzzles.begin(); iter != scope.puzzles.end(); ++iter)
+ for (PuzzleList::iterator iter = scope.puzzles.begin(); iter != scope.puzzles.end(); ++iter) {
delete(*iter);
+ }
scope.puzzles.clear();
- for (ControlList::iterator iter = scope.controls.begin(); iter != scope.controls.end(); ++iter)
+ for (ControlList::iterator iter = scope.controls.begin(); iter != scope.controls.end(); ++iter) {
delete(*iter);
+ }
scope.controls.clear();
@@ -288,44 +308,49 @@ void ScriptManager::cleanScriptScope(ScriptScope &scope) {
}
int ScriptManager::getStateValue(uint32 key) {
- if (_globalState.contains(key))
+ if (_globalState.contains(key)) {
return _globalState[key];
- else
+ } else {
return 0;
+ }
}
void ScriptManager::queuePuzzles(uint32 key) {
if (_referenceTable.contains(key)) {
Common::Array<PuzzleRef> *arr = &_referenceTable[key];
- for (int32 i = arr->size() - 1; i >= 0; i--)
+ for (int32 i = arr->size() - 1; i >= 0; i--) {
if (!(*arr)[i].puz->addedBySetState) {
(*arr)[i].scope->scopeQueue->push_back((*arr)[i].puz);
(*arr)[i].puz->addedBySetState = true;
}
+ }
}
}
void ScriptManager::setStateValue(uint32 key, int value) {
- if (value == 0)
+ if (value == 0) {
_globalState.erase(key);
- else
+ } else {
_globalState[key] = value;
+ }
queuePuzzles(key);
}
void ScriptManager::setStateValueSilent(uint32 key, int value) {
- if (value == 0)
+ if (value == 0) {
_globalState.erase(key);
- else
+ } else {
_globalState[key] = value;
+ }
}
uint ScriptManager::getStateFlag(uint32 key) {
- if (_globalStateFlags.contains(key))
+ if (_globalStateFlags.contains(key)) {
return _globalStateFlags[key];
- else
+ } else {
return 0;
+ }
}
void ScriptManager::setStateFlag(uint32 key, uint value) {
@@ -335,10 +360,11 @@ void ScriptManager::setStateFlag(uint32 key, uint value) {
}
void ScriptManager::setStateFlagSilent(uint32 key, uint value) {
- if (value == 0)
+ if (value == 0) {
_globalStateFlags.erase(key);
- else
+ } else {
_globalStateFlags[key] = value;
+ }
}
void ScriptManager::unsetStateFlag(uint32 key, uint value) {
@@ -347,23 +373,29 @@ void ScriptManager::unsetStateFlag(uint32 key, uint value) {
if (_globalStateFlags.contains(key)) {
_globalStateFlags[key] &= ~value;
- if (_globalStateFlags[key] == 0)
+ if (_globalStateFlags[key] == 0) {
_globalStateFlags.erase(key);
+ }
}
}
Control *ScriptManager::getControl(uint32 key) {
- for (ControlList::iterator iter = _activeControls->begin(); iter != _activeControls->end(); ++iter)
- if ((*iter)->getKey() == key)
+ for (ControlList::iterator iter = _activeControls->begin(); iter != _activeControls->end(); ++iter) {
+ if ((*iter)->getKey() == key) {
return *iter;
+ }
+ }
+
return nullptr;
}
void ScriptManager::focusControl(uint32 key) {
- if (!_activeControls)
+ if (!_activeControls) {
return;
- if (_currentlyFocusedControl == key)
+ }
+ if (_currentlyFocusedControl == key) {
return;
+ }
for (ControlList::iterator iter = _activeControls->begin(); iter != _activeControls->end(); ++iter) {
uint32 controlKey = (*iter)->getKey();
@@ -381,11 +413,11 @@ void ScriptManager::setFocusControlKey(uint32 key) {
_currentlyFocusedControl = key;
}
-void ScriptManager::addSideFX(SideFX *fx) {
+void ScriptManager::addSideFX(ScriptingEffect *fx) {
_activeSideFx.push_back(fx);
}
-SideFX *ScriptManager::getSideFX(uint32 key) {
+ScriptingEffect *ScriptManager::getSideFX(uint32 key) {
for (SideFXList::iterator iter = _activeSideFx.begin(); iter != _activeSideFx.end(); ++iter) {
if ((*iter)->getKey() == key) {
return (*iter);
@@ -429,7 +461,7 @@ void ScriptManager::killSideFx(uint32 key) {
}
}
-void ScriptManager::killSideFxType(SideFX::SideFXType type) {
+void ScriptManager::killSideFxType(ScriptingEffect::ScriptingEffectType type) {
for (SideFXList::iterator iter = _activeSideFx.begin(); iter != _activeSideFx.end();) {
if ((*iter)->getType() & type) {
(*iter)->kill();
@@ -442,50 +474,60 @@ void ScriptManager::killSideFxType(SideFX::SideFXType type) {
}
void ScriptManager::onMouseDown(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
- if (!_activeControls)
+ if (!_activeControls) {
return;
+ }
for (ControlList::iterator iter = _activeControls->reverse_begin(); iter != _activeControls->end(); iter--) {
- if ((*iter)->onMouseDown(screenSpacePos, backgroundImageSpacePos))
+ if ((*iter)->onMouseDown(screenSpacePos, backgroundImageSpacePos)) {
return;
+ }
}
}
void ScriptManager::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
- if (!_activeControls)
+ if (!_activeControls) {
return;
+ }
for (ControlList::iterator iter = _activeControls->reverse_begin(); iter != _activeControls->end(); iter--) {
- if ((*iter)->onMouseUp(screenSpacePos, backgroundImageSpacePos))
+ if ((*iter)->onMouseUp(screenSpacePos, backgroundImageSpacePos)) {
return;
+ }
}
}
bool ScriptManager::onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
- if (!_activeControls)
+ if (!_activeControls) {
return false;
+ }
for (ControlList::iterator iter = _activeControls->reverse_begin(); iter != _activeControls->end(); iter--) {
- if ((*iter)->onMouseMove(screenSpacePos, backgroundImageSpacePos))
+ if ((*iter)->onMouseMove(screenSpacePos, backgroundImageSpacePos)) {
return true;
+ }
}
return false;
}
void ScriptManager::onKeyDown(Common::KeyState keyState) {
- if (!_activeControls)
+ if (!_activeControls) {
return;
+ }
for (ControlList::iterator iter = _activeControls->begin(); iter != _activeControls->end(); ++iter) {
- if ((*iter)->onKeyDown(keyState))
+ if ((*iter)->onKeyDown(keyState)) {
return;
+ }
}
}
void ScriptManager::onKeyUp(Common::KeyState keyState) {
- if (!_activeControls)
+ if (!_activeControls) {
return;
+ }
for (ControlList::iterator iter = _activeControls->begin(); iter != _activeControls->end(); ++iter) {
- if ((*iter)->onKeyUp(keyState))
+ if ((*iter)->onKeyUp(keyState)) {
return;
+ }
}
}
@@ -499,8 +541,8 @@ void ScriptManager::changeLocation(char _world, char _room, char _node, char _vi
_nextLocation.node = _node;
_nextLocation.view = _view;
_nextLocation.offset = offset;
- // If next location 0000 - it's indicate to go to previous location.
- if (_nextLocation.world == '0' && _nextLocation.room == '0' && _nextLocation.node == '0' && _nextLocation.view == '0') {
+ // If next location is 0000, return to the previous location.
+ if (_nextLocation == "0000") {
if (getStateValue(StateKey_World) != 'g' || getStateValue(StateKey_Room) != 'j') {
_nextLocation.world = getStateValue(StateKey_LastWorld);
_nextLocation.room = getStateValue(StateKey_LastRoom);
@@ -517,36 +559,42 @@ void ScriptManager::changeLocation(char _world, char _room, char _node, char _vi
}
}
-void ScriptManager::ChangeLocationReal() {
+void ScriptManager::ChangeLocationReal(bool isLoading) {
assert(_nextLocation.world != 0);
debug(1, "Changing location to: %c %c %c %c %u", _nextLocation.world, _nextLocation.room, _nextLocation.node, _nextLocation.view, _nextLocation.offset);
- if (_nextLocation.world == 'g' && _nextLocation.room == 'j' && !ConfMan.getBool("originalsaveload")) {
- if ((_nextLocation.node == 's' || _nextLocation.node == 'r') && _nextLocation.view == 'e') {
+ const bool enteringMenu = (_nextLocation.world == 'g' && _nextLocation.room == 'j');
+ const bool leavingMenu = (_currentLocation.world == 'g' && _currentLocation.room == 'j');
+ const bool isSaveScreen = (enteringMenu && _nextLocation.node == 's' && _nextLocation.view == 'e');
+ const bool isRestoreScreen = (enteringMenu && _nextLocation.node == 'r' && _nextLocation.view == 'e');
+
+ if (enteringMenu && !ConfMan.getBool("originalsaveload")) {
+ if (isSaveScreen || isRestoreScreen) {
// Hook up the ScummVM save/restore dialog
- bool isSave = (_nextLocation.node == 's');
- bool gameSavedOrLoaded = _engine->getSaveManager()->scummVMSaveLoadDialog(isSave);
- if (!gameSavedOrLoaded || isSave) {
+ bool gameSavedOrLoaded = _engine->getSaveManager()->scummVMSaveLoadDialog(isSaveScreen);
+ if (!gameSavedOrLoaded || isSaveScreen) {
// Reload the current room
_nextLocation.world = _currentLocation.world;
_nextLocation.room = _currentLocation.room;
_nextLocation.node = _currentLocation.node;
_nextLocation.view = _currentLocation.view;
_nextLocation.offset = _currentLocation.offset;
- _currentLocation.world = '0';
+
+ return;
+ } else {
+ _currentLocation.world = 'g';
_currentLocation.room = '0';
_currentLocation.node = '0';
_currentLocation.view = '0';
_currentLocation.offset = 0;
- } else
- return;
+ }
}
}
_engine->setRenderDelay(2);
- if (getStateValue(StateKey_World) != 'g' || getStateValue(StateKey_Room) != 'j') {
- if (_nextLocation.world != 'g' || _nextLocation.room != 'j') {
+ if (!leavingMenu) {
+ if (!isLoading && !enteringMenu) {
setStateValue(StateKey_LastWorld, getStateValue(StateKey_World));
setStateValue(StateKey_LastRoom, getStateValue(StateKey_Room));
setStateValue(StateKey_LastNode, getStateValue(StateKey_Node));
@@ -561,16 +609,13 @@ void ScriptManager::ChangeLocationReal() {
}
}
- if (_nextLocation.world == 'g' && _nextLocation.room == 'j') {
- if (_nextLocation.node == 's' && _nextLocation.view == 'e' &&
- _currentLocation.world != 'g' && _currentLocation.room != 'j')
+ if (enteringMenu) {
+ if (isSaveScreen && !leavingMenu) {
_engine->getSaveManager()->prepareSaveBuffer();
+ }
} else {
- if (_currentLocation.world == 'g' && _currentLocation.room == 'j')
+ if (leavingMenu) {
_engine->getSaveManager()->flushSaveBuffer();
- else {
- // Auto save
- //_engine->getSaveManager()->autoSave();
}
}
@@ -583,7 +628,7 @@ void ScriptManager::ChangeLocationReal() {
_referenceTable.clear();
addPuzzlesToReferenceTable(universe);
- _engine->menuBarEnable(0xFFFF);
+ _engine->getMenuHandler()->setEnable(0xFFFF);
if (_nextLocation.world != _currentLocation.world) {
cleanScriptScope(nodeview);
@@ -634,7 +679,7 @@ void ScriptManager::ChangeLocationReal() {
// Change the background position
_engine->getRenderManager()->setBackgroundPosition(_nextLocation.offset);
- if (_currentLocation.world == 0 && _currentLocation.room == 0 && _currentLocation.node == 0 && _currentLocation.view == 0) {
+ if (_currentLocation == "0000") {
_currentLocation = _nextLocation;
execScope(world);
execScope(room);
@@ -652,7 +697,7 @@ void ScriptManager::ChangeLocationReal() {
execScope(nodeview);
}
- _engine->checkBorders();
+ _engine->getRenderManager()->checkBorders();
}
void ScriptManager::serialize(Common::WriteStream *stream) {
@@ -667,26 +712,30 @@ void ScriptManager::serialize(Common::WriteStream *stream) {
stream->writeByte(getStateValue(StateKey_View));
stream->writeUint32LE(getStateValue(StateKey_ViewPos));
- for (SideFXList::iterator iter = _activeSideFx.begin(); iter != _activeSideFx.end(); ++iter)
+ for (SideFXList::iterator iter = _activeSideFx.begin(); iter != _activeSideFx.end(); ++iter) {
(*iter)->serialize(stream);
+ }
stream->writeUint32BE(MKTAG('F', 'L', 'A', 'G'));
int32 slots = 20000;
- if (_engine->getGameId() == GID_NEMESIS)
+ if (_engine->getGameId() == GID_NEMESIS) {
slots = 30000;
+ }
stream->writeUint32LE(slots * 2);
- for (int32 i = 0; i < slots; i++)
+ for (int32 i = 0; i < slots; i++) {
stream->writeUint16LE(getStateFlag(i));
+ }
stream->writeUint32BE(MKTAG('P', 'U', 'Z', 'Z'));
stream->writeUint32LE(slots * 2);
- for (int32 i = 0; i < slots; i++)
+ for (int32 i = 0; i < slots; i++) {
stream->writeSint16LE(getStateValue(i));
+ }
}
void ScriptManager::deserialize(Common::SeekableReadStream *stream) {
@@ -703,8 +752,9 @@ void ScriptManager::deserialize(Common::SeekableReadStream *stream) {
_currentLocation.room = 0;
_currentLocation.view = 0;
- for (SideFXList::iterator iter = _activeSideFx.begin(); iter != _activeSideFx.end(); iter++)
+ for (SideFXList::iterator iter = _activeSideFx.begin(); iter != _activeSideFx.end(); iter++) {
delete(*iter);
+ }
_activeSideFx.clear();
@@ -737,20 +787,23 @@ void ScriptManager::deserialize(Common::SeekableReadStream *stream) {
case MKTAG('T', 'I', 'M', 'R'): {
uint32 key = stream->readUint32LE();
uint32 time = stream->readUint32LE();
- if (_engine->getGameId() == GID_GRANDINQUISITOR)
+ if (_engine->getGameId() == GID_GRANDINQUISITOR) {
time /= 100;
- else if (_engine->getGameId() == GID_NEMESIS)
+ } else if (_engine->getGameId() == GID_NEMESIS) {
time /= 1000;
+ }
addSideFX(new TimerNode(_engine, key, time));
}
break;
case MKTAG('F', 'L', 'A', 'G'):
- for (uint32 i = 0; i < tagSize / 2; i++)
+ for (uint32 i = 0; i < tagSize / 2; i++) {
setStateFlagSilent(i, stream->readUint16LE());
+ }
break;
case MKTAG('P', 'U', 'Z', 'Z'):
- for (uint32 i = 0; i < tagSize / 2; i++)
+ for (uint32 i = 0; i < tagSize / 2; i++) {
setStateValueSilent(i, stream->readUint16LE());
+ }
break;
default:
stream->seek(tagSize, SEEK_CUR);
@@ -759,7 +812,7 @@ void ScriptManager::deserialize(Common::SeekableReadStream *stream) {
_nextLocation = nextLocation;
- ChangeLocationReal();
+ ChangeLocationReal(true);
_engine->setRenderDelay(10);
setStateValue(StateKey_RestoreFlag, 1);
@@ -804,10 +857,11 @@ void ScriptManager::flushEvent(Common::EventType type) {
EventList::iterator it = _controlEvents.begin();
while (it != _controlEvents.end()) {
- if ((*it).type == type)
+ if ((*it).type == type) {
it = _controlEvents.erase(it);
- else
+ } else {
it++;
+ }
}
}
@@ -836,12 +890,15 @@ ValueSlot::ValueSlot(ScriptManager *scriptManager, const char *slotValue):
}
int16 ValueSlot::getValue() {
if (slot) {
- if (value >= 0)
+ if (value >= 0) {
return _scriptManager->getStateValue(value);
- else
+ }
+ else {
return 0;
- } else
+ }
+ } else {
return value;
+ }
}
} // End of namespace ZVision
diff --git a/engines/zvision/scripting/script_manager.h b/engines/zvision/scripting/script_manager.h
index 1e308faf0d..7c276bf917 100644
--- a/engines/zvision/scripting/script_manager.h
+++ b/engines/zvision/scripting/script_manager.h
@@ -25,7 +25,7 @@
#include "zvision/scripting/puzzle.h"
#include "zvision/scripting/control.h"
-#include "zvision/scripting/sidefx.h"
+#include "zvision/scripting/scripting_effect.h"
#include "common/hashmap.h"
#include "common/queue.h"
@@ -87,6 +87,7 @@ enum StateKey {
StateKey_JapanFonts = 75,
StateKey_ExecScopeStyle = 76,
StateKey_Brightness = 77,
+ StateKey_MPEGMovies = 78,
StateKey_EF9_R = 91,
StateKey_EF9_G = 92,
StateKey_EF9_B = 93,
@@ -94,7 +95,12 @@ enum StateKey {
StateKey_Inv_Cnt_Slot = 100,
StateKey_Inv_1_Slot = 101,
StateKey_Inv_49_Slot = 149,
- StateKey_Inv_TotalSlots = 150
+ // ZGI only
+ StateKey_Inv_TotalSlots = 150,
+ StateKey_Inv_StartSlot = 151,
+ StateKey_Spell_1 = 191,
+ StateKey_Active_Spell = 205,
+ StateKey_Reversed_Spellbooc = 206
};
struct Location {
@@ -107,11 +113,33 @@ struct Location {
uint32 offset;
};
+inline bool operator==(const Location& lhs, const Location& rhs) {
+ return (
+ lhs.world == rhs.world &&
+ lhs.room == rhs.room &&
+ lhs.node == rhs.node &&
+ lhs.view == rhs.view
+ );
+}
+
+inline bool operator==(const Location& lhs, const char* rhs) {
+ Common::String lhsStr = Common::String::format("%c%c%c%c", lhs.world, lhs.room, lhs.node, lhs.view);
+ return lhsStr == rhs;
+}
+
+inline bool operator!=(const Location& lhs, const Location& rhs) {
+ return !(lhs == rhs);
+}
+
+inline bool operator!=(const Location& lhs, const char* rhs) {
+ return !(lhs == rhs);
+}
+
typedef Common::List<Puzzle *> PuzzleList;
typedef Common::Queue<Puzzle *> PuzzleQueue;
typedef Common::List<Control *> ControlList;
typedef Common::HashMap<uint32, int32> StateMap;
-typedef Common::List<SideFX *> SideFXList;
+typedef Common::List<ScriptingEffect *> SideFXList;
typedef Common::List<Common::Event> EventList;
class ScriptManager {
@@ -191,12 +219,12 @@ public:
// Only change focus control without call focus/unfocus.
void setFocusControlKey(uint32 key);
- void addSideFX(SideFX *fx);
- SideFX *getSideFX(uint32 key);
+ void addSideFX(ScriptingEffect *fx);
+ ScriptingEffect *getSideFX(uint32 key);
void deleteSideFx(uint32 key);
void stopSideFx(uint32 key);
void killSideFx(uint32 key);
- void killSideFxType(SideFX::SideFXType type);
+ void killSideFxType(ScriptingEffect::ScriptingEffectType type);
void addEvent(Common::Event);
void flushEvent(Common::EventType type);
@@ -267,7 +295,7 @@ private:
bool execScope(ScriptScope &scope);
/** Perform change location */
- void ChangeLocationReal();
+ void ChangeLocationReal(bool isLoading);
int8 inventoryGetCount();
void inventorySetCount(int8 cnt);
@@ -282,7 +310,7 @@ public:
void inventoryDrop(int16 item);
void inventoryCycle();
- // TODO: Make this private. It was only made public so Console::cmdParseAllScrFiles() could use it
+private:
/**
* Parses a script file into triggers and events
*
@@ -291,7 +319,6 @@ public:
*/
void parseScrFile(const Common::String &fileName, ScriptScope &scope);
-private:
/**
* Parses the stream into a Puzzle object
* Helper method for parseScrFile.
@@ -307,9 +334,10 @@ private:
*
* @param criteria Pointer to the Criteria object to fill
* @param stream Scr file stream
+ * @param key Puzzle key (for workarounds)
* @return Whether any criteria were read
*/
- bool parseCriteria(Common::SeekableReadStream &stream, Common::List<Common::List<Puzzle::CriteriaEntry> > &criteriaList) const;
+ bool parseCriteria(Common::SeekableReadStream &stream, Common::List<Common::List<Puzzle::CriteriaEntry> > &criteriaList, uint32 key) const;
/**
* Parses the stream into a ResultAction objects
diff --git a/engines/zvision/scripting/sidefx.h b/engines/zvision/scripting/scripting_effect.h
index 5bb14f0cdd..2a2153204f 100644
--- a/engines/zvision/scripting/sidefx.h
+++ b/engines/zvision/scripting/scripting_effect.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SIDEFX_H_INCLUDED
-#define SIDEFX_H_INCLUDED
+#ifndef SCRIPTING_EFFECT_H_INCLUDED
+#define SCRIPTING_EFFECT_H_INCLUDED
namespace Common {
class SeekableReadStream;
@@ -33,29 +33,39 @@ namespace ZVision {
class ZVision;
-class SideFX {
+/**
+ * The base class that represents effects created from Actions.
+ * This class is virtual.
+ *
+ * Detailed Description:
+ * A scene has Controls. By interacting with the controls, the user
+ * causes Actions to execute. Certain Actions create 'effects', for
+ * example, a sound or an animation. This is the base class for
+ * those effects.
+ */
+class ScriptingEffect {
public:
- enum SideFXType {
- SIDEFX_ANIM = 1,
- SIDEFX_AUDIO = 2,
- SIDEFX_DISTORT = 4,
- SIDEFX_PANTRACK = 8,
- SIDEFX_REGION = 16,
- SIDEFX_TIMER = 32,
- SIDEFX_TTYTXT = 64,
- SIDEFX_UNK = 128,
- SIDEFX_ALL = 255
+ enum ScriptingEffectType {
+ SCRIPTING_EFFECT_ANIM = 1,
+ SCRIPTING_EFFECT_AUDIO = 2,
+ SCRIPTING_EFFECT_DISTORT = 4,
+ SCRIPTING_EFFECT_PANTRACK = 8,
+ SCRIPTING_EFFECT_REGION = 16,
+ SCRIPTING_EFFECT_TIMER = 32,
+ SCRIPTING_EFFECT_TTYTXT = 64,
+ SCRIPTING_EFFECT_UNKNOWN = 128,
+ SCRIPTING_EFFECT_ALL = 255
};
- SideFX() : _engine(0), _key(0), _type(SIDEFX_UNK) {}
- SideFX(ZVision *engine, uint32 key, SideFXType type) : _engine(engine), _key(key), _type(type) {}
- virtual ~SideFX() {}
+ ScriptingEffect() : _engine(0), _key(0), _type(SCRIPTING_EFFECT_UNKNOWN) {}
+ ScriptingEffect(ZVision *engine, uint32 key, ScriptingEffectType type) : _engine(engine), _key(key), _type(type) {}
+ virtual ~ScriptingEffect() {}
uint32 getKey() {
return _key;
}
- SideFXType getType() {
+ ScriptingEffectType getType() {
return _type;
}
@@ -103,7 +113,7 @@ public:
protected:
ZVision *_engine;
uint32 _key;
- SideFXType _type;
+ ScriptingEffectType _type;
// Static member functions
public:
@@ -111,4 +121,4 @@ public:
};
} // End of namespace ZVision
-#endif // SIDEFX_H_INCLUDED
+#endif // SCRIPTING_EFFECT_H_INCLUDED
diff --git a/engines/zvision/sound/zork_raw.cpp b/engines/zvision/sound/zork_raw.cpp
index 8688039325..124235e0e0 100644
--- a/engines/zvision/sound/zork_raw.cpp
+++ b/engines/zvision/sound/zork_raw.cpp
@@ -33,7 +33,6 @@
#include "zvision/sound/zork_raw.h"
#include "zvision/zvision.h"
-#include "zvision/detection.h"
namespace ZVision {
@@ -73,10 +72,7 @@ RawChunkStream::RawChunk RawChunkStream::readNextChunk(Common::SeekableReadStrea
tmp.size = 0;
tmp.data = NULL;
- if (!stream)
- return tmp;
-
- if (stream && (stream->size() == 0 || stream->eos()))
+ if (!stream || stream->size() == 0 || stream->eos())
return tmp;
tmp.size = (stream->size() - stream->pos()) * 2;
@@ -139,7 +135,8 @@ int RawChunkStream::readBuffer(int16 *buffer, Common::SeekableReadStream *stream
return bytesRead;
}
-const SoundParams RawZorkStream::_zNemSoundParamLookupTable[32] = {{'0', 0x1F40, false, false, false},
+const SoundParams RawZorkStream::_zNemSoundParamLookupTable[32] = {
+ {'0', 0x1F40, false, false, false},
{'1', 0x1F40, true, false, false},
{'2', 0x1F40, false, false, true},
{'3', 0x1F40, true, false, true},
@@ -173,7 +170,8 @@ const SoundParams RawZorkStream::_zNemSoundParamLookupTable[32] = {{'0', 0x1F40,
{'x', 0xAC44, true, true, true}
};
-const SoundParams RawZorkStream::_zgiSoundParamLookupTable[24] = {{'4', 0x2B11, false, false, false},
+const SoundParams RawZorkStream::_zgiSoundParamLookupTable[24] = {
+ {'4', 0x2B11, false, false, false},
{'5', 0x2B11, true, false, false},
{'6', 0x2B11, false, false, true},
{'7', 0x2B11, true, false, true},
@@ -216,7 +214,6 @@ RawZorkStream::RawZorkStream(uint32 rate, bool stereo, DisposeAfterUse::Flag dis
}
int RawZorkStream::readBuffer(int16 *buffer, const int numSamples) {
-
int32 bytesRead = _streamReader.readBuffer(buffer, _stream.get(), numSamples);
if (_stream->eos())
@@ -244,19 +241,29 @@ Audio::RewindableAudioStream *makeRawZorkStream(Common::SeekableReadStream *stre
return new RawZorkStream(rate, stereo, disposeAfterUse, stream);
}
-Audio::RewindableAudioStream *makeRawZorkStream(const byte *buffer, uint32 size,
- int rate,
- bool stereo,
- DisposeAfterUse::Flag disposeAfterUse) {
- return makeRawZorkStream(new Common::MemoryReadStream(buffer, size, disposeAfterUse), rate, stereo, DisposeAfterUse::YES);
-}
-
Audio::RewindableAudioStream *makeRawZorkStream(const Common::String &filePath, ZVision *engine) {
Common::File *file = new Common::File();
- assert(engine->getSearchManager()->openFile(*file, filePath));
+ Common::String actualName = filePath;
+ bool found = engine->getSearchManager()->openFile(*file, actualName);
+ bool isRaw = actualName.hasSuffix(".raw");
+
+ if ((!found && isRaw) || (found && isRaw && file->size() < 10)) {
+ if (found)
+ file->close();
+
+ // Check for an audio patch (.src)
+ actualName.setChar('s', actualName.size() - 3);
+ actualName.setChar('r', actualName.size() - 2);
+ actualName.setChar('c', actualName.size() - 1);
+
+ if (!engine->getSearchManager()->openFile(*file, actualName))
+ return NULL;
+ } else if (!found && !isRaw) {
+ return NULL;
+ }
// Get the file name
- Common::StringTokenizer tokenizer(filePath, "/\\");
+ Common::StringTokenizer tokenizer(actualName, "/\\");
Common::String fileName;
while (!tokenizer.empty()) {
fileName = tokenizer.nextToken();
diff --git a/engines/zvision/sound/zork_raw.h b/engines/zvision/sound/zork_raw.h
index 0b408d818c..892bad4d5f 100644
--- a/engines/zvision/sound/zork_raw.h
+++ b/engines/zvision/sound/zork_raw.h
@@ -123,20 +123,6 @@ public:
};
/**
- * Creates an audio stream, which plays from the given buffer.
- *
- * @param buffer Buffer to play from.
- * @param size Size of the buffer in bytes.
- * @param rate Rate of the sound data.
- * @param dispose AfterUse Whether to free the buffer after use (with free!).
- * @return The new SeekableAudioStream (or 0 on failure).
- */
-Audio::RewindableAudioStream *makeRawZorkStream(const byte *buffer, uint32 size,
- int rate,
- bool stereo,
- DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES);
-
-/**
* Creates an audio stream, which plays from the given stream.
*
* @param stream Stream object to play from.
diff --git a/engines/zvision/text/string_manager.cpp b/engines/zvision/text/string_manager.cpp
index ec10b6220c..c62e18f4b0 100644
--- a/engines/zvision/text/string_manager.cpp
+++ b/engines/zvision/text/string_manager.cpp
@@ -43,21 +43,17 @@ StringManager::~StringManager() {
}
void StringManager::initialize(ZVisionGameId gameId) {
- if (gameId == GID_NEMESIS) {
- // TODO: Check this hardcoded filename against all versions of Nemesis
+ if (gameId == GID_NEMESIS)
loadStrFile("nemesis.str");
- } else if (gameId == GID_GRANDINQUISITOR) {
- // TODO: Check this hardcoded filename against all versions of Grand Inquisitor
+ else if (gameId == GID_GRANDINQUISITOR)
loadStrFile("inquis.str");
- }
}
void StringManager::loadStrFile(const Common::String &fileName) {
Common::File file;
- if (!_engine->getSearchManager()->openFile(file, fileName)) {
- warning("%s does not exist. String parsing failed", fileName.c_str());
- return;
- }
+ if (!_engine->getSearchManager()->openFile(file, fileName))
+ error("%s does not exist. String parsing failed", fileName.c_str());
+
uint lineNumber = 0;
while (!file.eos()) {
_lines[lineNumber] = readWideLine(file);
diff --git a/engines/zvision/text/string_manager.h b/engines/zvision/text/string_manager.h
index b77ad65040..2c31cf7afe 100644
--- a/engines/zvision/text/string_manager.h
+++ b/engines/zvision/text/string_manager.h
@@ -23,8 +23,7 @@
#ifndef ZVISION_STRING_MANAGER_H
#define ZVISION_STRING_MANAGER_H
-#include "zvision/detection.h"
-#include "zvision/graphics/truetype_font.h"
+#include "zvision/text/truetype_font.h"
namespace Graphics {
class FontManager;
diff --git a/engines/zvision/graphics/subtitles.cpp b/engines/zvision/text/subtitles.cpp
index d2c56f0991..ffc9e2b808 100644
--- a/engines/zvision/graphics/subtitles.cpp
+++ b/engines/zvision/text/subtitles.cpp
@@ -21,13 +21,13 @@
*/
#include "zvision/graphics/render_manager.h"
-#include "zvision/graphics/subtitles.h"
+#include "zvision/text/subtitles.h"
#include "zvision/file/search_manager.h"
#include "zvision/text/text.h"
namespace ZVision {
-Subtitle::Subtitle(ZVision *engine, const Common::String &subname) :
+Subtitle::Subtitle(ZVision *engine, const Common::String &subname, bool upscaleToHires) :
_engine(engine),
_areaId(-1),
_subId(-1) {
@@ -44,6 +44,8 @@ Subtitle::Subtitle(ZVision *engine, const Common::String &subname) :
int32 x1, y1, x2, y2;
sscanf(str.c_str(), "%*[^:]:%d %d %d %d", &x1, &y1, &x2, &y2);
Common::Rect rct = Common::Rect(x1, y1, x2, y2);
+ if (upscaleToHires)
+ _engine->getRenderManager()->upscaleRect(rct);
_areaId = _engine->getRenderManager()->createSubArea(rct);
} else if (str.matchString("*TextFile*", true)) {
char filename[64];
@@ -67,6 +69,11 @@ Subtitle::Subtitle(ZVision *engine, const Common::String &subname) :
int32 sb;
if (sscanf(str.c_str(), "%*[^:]:(%d,%d)=%d", &st, &en, &sb) == 3) {
if (sb <= (int32)_subs.size()) {
+ if (upscaleToHires) {
+ // Convert from 15FPS (AVI) to 29.97FPS (VOB)
+ st = st * 2997 / 1500;
+ en = en * 2997 / 1500;
+ }
_subs[sb].start = st;
_subs[sb].stop = en;
}
diff --git a/engines/zvision/graphics/subtitles.h b/engines/zvision/text/subtitles.h
index c3da6583a4..329339be55 100644
--- a/engines/zvision/graphics/subtitles.h
+++ b/engines/zvision/text/subtitles.h
@@ -31,7 +31,7 @@ class ZVision;
class Subtitle {
public:
- Subtitle(ZVision *engine, const Common::String &subname);
+ Subtitle(ZVision *engine, const Common::String &subname, bool upscaleToHires = false);
~Subtitle();
void process(int32 time);
diff --git a/engines/zvision/text/text.cpp b/engines/zvision/text/text.cpp
index 406c36e5b0..868ee4f1ae 100644
--- a/engines/zvision/text/text.cpp
+++ b/engines/zvision/text/text.cpp
@@ -33,33 +33,37 @@
#include "zvision/text/text.h"
#include "zvision/graphics/render_manager.h"
-#include "zvision/graphics/truetype_font.h"
+#include "zvision/text/truetype_font.h"
#include "zvision/scripting/script_manager.h"
namespace ZVision {
-cTxtStyle::cTxtStyle() {
- fontname = "Arial";
- blue = 255;
- green = 255;
- red = 255;
- bold = false;
- escapement = 0;
- italic = false;
- justify = TXT_JUSTIFY_LEFT;
- newline = false;
- size = 12;
- skipcolor = false;
- strikeout = false;
- underline = false;
- statebox = 0;
- sharp = false;
+TextStyleState::TextStyleState() {
+ _fontname = "Arial";
+ _blue = 255;
+ _green = 255;
+ _red = 255;
+ _bold = false;
+#if 0
+ _newline = false;
+ _escapement = 0;
+#endif
+ _italic = false;
+ _justification = TEXT_JUSTIFY_LEFT;
+ _size = 12;
+#if 0
+ _skipcolor = false;
+#endif
+ _strikeout = false;
+ _underline = false;
+ _statebox = 0;
+ _sharp = false;
}
-txtReturn cTxtStyle::parseStyle(const Common::String &strin, int16 ln) {
- Common::String buf = Common::String(strin.c_str(), ln);
+TextChange TextStyleState::parseStyle(const Common::String &str, int16 len) {
+ Common::String buf = Common::String(str.c_str(), len);
- int8 retval = TXT_RET_NOTHING;
+ uint retval = TEXT_CHANGE_NONE;
Common::StringTokenizer tokenizer(buf, " ");
Common::String token;
@@ -80,73 +84,77 @@ txtReturn cTxtStyle::parseStyle(const Common::String &strin, int16 ln) {
if (_tmp.lastChar() == '"')
_tmp.deleteLastChar();
- fontname = _tmp;
+ _fontname = _tmp;
} else {
if (!tokenizer.empty())
- fontname = token;
+ _fontname = token;
}
- retval |= TXT_RET_FNTCHG;
+ retval |= TEXT_CHANGE_FONT_TYPE;
} else if (token.matchString("blue", true)) {
if (!tokenizer.empty()) {
token = tokenizer.nextToken();
int32 tmp = atoi(token.c_str());
- if (blue != tmp) {
- blue = tmp;
- retval |= TXT_RET_FNTSTL;
+ if (_blue != tmp) {
+ _blue = tmp;
+ retval |= TEXT_CHANGE_FONT_STYLE;
}
}
} else if (token.matchString("red", true)) {
if (!tokenizer.empty()) {
token = tokenizer.nextToken();
int32 tmp = atoi(token.c_str());
- if (red != tmp) {
- red = tmp;
- retval |= TXT_RET_FNTSTL;
+ if (_red != tmp) {
+ _red = tmp;
+ retval |= TEXT_CHANGE_FONT_STYLE;
}
}
} else if (token.matchString("green", true)) {
if (!tokenizer.empty()) {
token = tokenizer.nextToken();
int32 tmp = atoi(token.c_str());
- if (green != tmp) {
- green = tmp;
- retval |= TXT_RET_FNTSTL;
+ if (_green != tmp) {
+ _green = tmp;
+ retval |= TEXT_CHANGE_FONT_STYLE;
}
}
} else if (token.matchString("newline", true)) {
+#if 0
if ((retval & TXT_RET_NEWLN) == 0)
- newline = 0;
+ _newline = 0;
- newline++;
- retval |= TXT_RET_NEWLN;
+ _newline++;
+#endif
+ retval |= TEXT_CHANGE_NEWLINE;
} else if (token.matchString("point", true)) {
if (!tokenizer.empty()) {
token = tokenizer.nextToken();
int32 tmp = atoi(token.c_str());
- if (size != tmp) {
- size = tmp;
- retval |= TXT_RET_FNTCHG;
+ if (_size != tmp) {
+ _size = tmp;
+ retval |= TEXT_CHANGE_FONT_TYPE;
}
}
} else if (token.matchString("escapement", true)) {
if (!tokenizer.empty()) {
token = tokenizer.nextToken();
+#if 0
int32 tmp = atoi(token.c_str());
- escapement = tmp;
+ _escapement = tmp;
+#endif
}
} else if (token.matchString("italic", true)) {
if (!tokenizer.empty()) {
token = tokenizer.nextToken();
if (token.matchString("on", true)) {
- if (italic != true) {
- italic = true;
- retval |= TXT_RET_FNTSTL;
+ if (_italic != true) {
+ _italic = true;
+ retval |= TEXT_CHANGE_FONT_STYLE;
}
} else if (token.matchString("off", true)) {
- if (italic != false) {
- italic = false;
- retval |= TXT_RET_FNTSTL;
+ if (_italic != false) {
+ _italic = false;
+ retval |= TEXT_CHANGE_FONT_STYLE;
}
}
}
@@ -154,14 +162,14 @@ txtReturn cTxtStyle::parseStyle(const Common::String &strin, int16 ln) {
if (!tokenizer.empty()) {
token = tokenizer.nextToken();
if (token.matchString("on", true)) {
- if (underline != true) {
- underline = true;
- retval |= TXT_RET_FNTSTL;
+ if (_underline != true) {
+ _underline = true;
+ retval |= TEXT_CHANGE_FONT_STYLE;
}
} else if (token.matchString("off", true)) {
- if (underline != false) {
- underline = false;
- retval |= TXT_RET_FNTSTL;
+ if (_underline != false) {
+ _underline = false;
+ retval |= TEXT_CHANGE_FONT_STYLE;
}
}
}
@@ -169,14 +177,14 @@ txtReturn cTxtStyle::parseStyle(const Common::String &strin, int16 ln) {
if (!tokenizer.empty()) {
token = tokenizer.nextToken();
if (token.matchString("on", true)) {
- if (strikeout != true) {
- strikeout = true;
- retval |= TXT_RET_FNTSTL;
+ if (_strikeout != true) {
+ _strikeout = true;
+ retval |= TEXT_CHANGE_FONT_STYLE;
}
} else if (token.matchString("off", true)) {
- if (strikeout != false) {
- strikeout = false;
- retval |= TXT_RET_FNTSTL;
+ if (_strikeout != false) {
+ _strikeout = false;
+ retval |= TEXT_CHANGE_FONT_STYLE;
}
}
}
@@ -184,50 +192,52 @@ txtReturn cTxtStyle::parseStyle(const Common::String &strin, int16 ln) {
if (!tokenizer.empty()) {
token = tokenizer.nextToken();
if (token.matchString("on", true)) {
- if (bold != true) {
- bold = true;
- retval |= TXT_RET_FNTSTL;
+ if (_bold != true) {
+ _bold = true;
+ retval |= TEXT_CHANGE_FONT_STYLE;
}
} else if (token.matchString("off", true)) {
- if (bold != false) {
- bold = false;
- retval |= TXT_RET_FNTSTL;
+ if (_bold != false) {
+ _bold = false;
+ retval |= TEXT_CHANGE_FONT_STYLE;
}
}
}
} else if (token.matchString("skipcolor", true)) {
if (!tokenizer.empty()) {
token = tokenizer.nextToken();
+#if 0
if (token.matchString("on", true)) {
- skipcolor = true;
+ _skipcolor = true;
} else if (token.matchString("off", true)) {
- skipcolor = false;
+ _skipcolor = false;
}
+#endif
}
} else if (token.matchString("image", true)) {
// Not used
} else if (token.matchString("statebox", true)) {
if (!tokenizer.empty()) {
token = tokenizer.nextToken();
- statebox = atoi(token.c_str());
- retval |= TXT_RET_HASSTBOX;
+ _statebox = atoi(token.c_str());
+ retval |= TEXT_CHANGE_HAS_STATE_BOX;
}
} else if (token.matchString("justify", true)) {
if (!tokenizer.empty()) {
token = tokenizer.nextToken();
if (token.matchString("center", true))
- justify = TXT_JUSTIFY_CENTER;
+ _justification = TEXT_JUSTIFY_CENTER;
else if (token.matchString("left", true))
- justify = TXT_JUSTIFY_LEFT;
+ _justification = TEXT_JUSTIFY_LEFT;
else if (token.matchString("right", true))
- justify = TXT_JUSTIFY_RIGHT;
+ _justification = TEXT_JUSTIFY_RIGHT;
}
}
}
- return (txtReturn)retval;
+ return (TextChange)retval;
}
-void cTxtStyle::readAllStyle(const Common::String &txt) {
+void TextStyleState::readAllStyles(const Common::String &txt) {
int16 startTextPosition = -1;
int16 endTextPosition = -1;
@@ -236,251 +246,273 @@ void cTxtStyle::readAllStyle(const Common::String &txt) {
startTextPosition = i;
else if (txt[i] == '>') {
endTextPosition = i;
- if (startTextPosition != -1)
- if ((endTextPosition - startTextPosition - 1) > 0)
+ if (startTextPosition != -1) {
+ if ((endTextPosition - startTextPosition - 1) > 0) {
parseStyle(Common::String(txt.c_str() + startTextPosition + 1), endTextPosition - startTextPosition - 1);
+ }
+ }
}
}
}
-void cTxtStyle::setFontStyle(StyledTTFont &font) {
+void TextStyleState::updateFontWithTextState(StyledTTFont &font) {
uint tempStyle = 0;
- if (bold)
- tempStyle |= StyledTTFont::STTF_BOLD;
-
- if (italic)
- tempStyle |= StyledTTFont::STTF_ITALIC;
-
- if (underline)
- tempStyle |= StyledTTFont::STTF_UNDERLINE;
-
- if (strikeout)
- tempStyle |= StyledTTFont::STTF_STRIKEOUT;
-
- if (sharp)
- tempStyle |= StyledTTFont::STTF_SHARP;
+ if (_bold) {
+ tempStyle |= StyledTTFont::TTF_STYLE_BOLD;
+ }
+ if (_italic) {
+ tempStyle |= StyledTTFont::TTF_STYLE_ITALIC;
+ }
+ if (_underline) {
+ tempStyle |= StyledTTFont::TTF_STYLE_UNDERLINE;
+ }
+ if (_strikeout) {
+ tempStyle |= StyledTTFont::TTF_STYLE_STRIKETHROUGH;
+ }
+ if (_sharp) {
+ tempStyle |= StyledTTFont::TTF_STYLE_SHARP;
+ }
- font.setStyle(tempStyle);
+ font.loadFont(_fontname, _size, tempStyle);
}
-void cTxtStyle::setFont(StyledTTFont &font) {
- uint tempStyle = 0;
-
- if (bold)
- tempStyle |= StyledTTFont::STTF_BOLD;
+void TextRenderer::drawTextWithJustification(const Common::String &text, StyledTTFont &font, uint32 color, Graphics::Surface &dest, int lineY, TextJustification justify) {
+ if (justify == TEXT_JUSTIFY_LEFT)
+ font.drawString(&dest, text, 0, lineY, dest.w, color, Graphics::kTextAlignLeft);
+ else if (justify == TEXT_JUSTIFY_CENTER)
+ font.drawString(&dest, text, 0, lineY, dest.w, color, Graphics::kTextAlignCenter);
+ else if (justify == TEXT_JUSTIFY_RIGHT)
+ font.drawString(&dest, text, 0, lineY, dest.w, color, Graphics::kTextAlignRight);
+}
- if (italic)
- tempStyle |= StyledTTFont::STTF_ITALIC;
+int32 TextRenderer::drawText(const Common::String &text, TextStyleState &state, Graphics::Surface &dest) {
+ StyledTTFont font(_engine);
+ state.updateFontWithTextState(font);
- if (underline)
- tempStyle |= StyledTTFont::STTF_UNDERLINE;
+ uint32 color = _engine->_resourcePixelFormat.RGBToColor(state._red, state._green, state._blue);
+ drawTextWithJustification(text, font, color, dest, 0, state._justification);
- if (strikeout)
- tempStyle |= StyledTTFont::STTF_STRIKEOUT;
+ return font.getStringWidth(text);
+}
- if (sharp)
- tempStyle |= StyledTTFont::STTF_SHARP;
+struct TextSurface {
+ TextSurface(Graphics::Surface *surface, Common::Point surfaceOffset, uint lineNumber)
+ : _surface(surface),
+ _surfaceOffset(surfaceOffset),
+ _lineNumber(lineNumber) {
+ }
- font.loadFont(fontname, size, tempStyle);
-}
+ Graphics::Surface *_surface;
+ Common::Point _surfaceOffset;
+ uint _lineNumber;
+};
-Graphics::Surface *TextRenderer::render(StyledTTFont &fnt, const Common::String &txt, cTxtStyle &style) {
- style.setFontStyle(fnt);
- uint32 clr = _engine->_pixelFormat.RGBToColor(style.red, style.green, style.blue);
- return fnt.renderSolidText(txt, clr);
-}
+void TextRenderer::drawTextWithWordWrapping(const Common::String &text, Graphics::Surface &dest) {
+ Common::Array<TextSurface> textSurfaces;
+ Common::Array<uint> lineWidths;
+ Common::Array<TextJustification> lineJustifications;
-void TextRenderer::drawTxtWithJustify(const Common::String &txt, StyledTTFont &fnt, uint32 color, Graphics::Surface &dst, int lineY, txtJustify justify) {
- if (justify == TXT_JUSTIFY_LEFT)
- fnt.drawString(&dst, txt, 0, lineY, dst.w, color, Graphics::kTextAlignLeft);
- else if (justify == TXT_JUSTIFY_CENTER)
- fnt.drawString(&dst, txt, 0, lineY, dst.w, color, Graphics::kTextAlignCenter);
- else if (justify == TXT_JUSTIFY_RIGHT)
- fnt.drawString(&dst, txt, 0, lineY, dst.w, color, Graphics::kTextAlignRight);
-}
+ // Create the initial text state
+ TextStyleState currentState;
-int32 TextRenderer::drawTxt(const Common::String &txt, cTxtStyle &fontStyle, Graphics::Surface &dst) {
+ // Create an empty font and bind it to the state
StyledTTFont font(_engine);
- fontStyle.setFont(font);
+ currentState.updateFontWithTextState(font);
- dst.fillRect(Common::Rect(dst.w, dst.h), 0);
+ Common::String currentSentence; // Not a true 'grammatical' sentence. Rather, it's just a collection of words
+ Common::String currentWord;
+ int sentenceWidth = 0;
+ int wordWidth = 0;
+ int lineWidth = 0;
+ int lineHeight = font.getFontHeight();
- uint32 clr = _engine->_pixelFormat.RGBToColor(fontStyle.red, fontStyle.green, fontStyle.blue);
+ uint currentLineNumber = 0u;
- int16 w;
+ uint numSpaces = 0u;
+ int spaceWidth = 0;
- w = font.getStringWidth(txt);
+ // The pixel offset to the currentSentence
+ Common::Point sentencePixelOffset;
- drawTxtWithJustify(txt, font, clr, dst, 0, fontStyle.justify);
+ uint i = 0u;
+ uint stringlen = text.size();
- return w;
-}
+ while (i < stringlen) {
+ if (text[i] == '<') {
+ // Flush the currentWord to the currentSentence
+ currentSentence += currentWord;
+ sentenceWidth += wordWidth;
+
+ // Reset the word variables
+ currentWord.clear();
+ wordWidth = 0;
+
+ // Parse the style tag
+ uint startTextPosition = i;
+ while (i < stringlen && text[i] != '>') {
+ ++i;
+ }
+ uint endTextPosition = i;
-void TextRenderer::drawTxtInOneLine(const Common::String &text, Graphics::Surface &dst) {
- const int16 TXT_CFG_TEXTURES_LINES = 256; // For now I don't want remake it
- const int TXT_CFG_TEXTURES_PER_LINE = 6;
- cTxtStyle style, style2;
- int16 startTextPosition = -1;
- int16 endTextPosition = -1;
- int16 i = 0;
- int16 dx = 0, dy = 0;
- int16 textPixelWidth;
- int16 textPosition = 0;
- Common::String buf;
- Common::String buf2;
-
- Graphics::Surface *TxtSurfaces[TXT_CFG_TEXTURES_LINES][TXT_CFG_TEXTURES_PER_LINE];
- int16 currentline = 0, currentlineitm = 0;
-
- int TxtJustify[TXT_CFG_TEXTURES_LINES];
- int TxtPoint[TXT_CFG_TEXTURES_LINES];
-
- for (int16 k = 0; k < TXT_CFG_TEXTURES_LINES; k++) {
- TxtPoint[k] = 0;
- for (int j = 0; j < TXT_CFG_TEXTURES_PER_LINE; j++)
- TxtSurfaces[k][j] = NULL;
- }
+ uint32 textColor = currentState.getTextColor(_engine);
- int16 stringlen = text.size();
+ uint stateChanges = 0u;
+ if ((endTextPosition - startTextPosition - 1) > 0) {
+ stateChanges = currentState.parseStyle(Common::String(text.c_str() + startTextPosition + 1), endTextPosition - startTextPosition - 1);
+ }
- StyledTTFont font(_engine);
+ if (stateChanges & (TEXT_CHANGE_FONT_TYPE | TEXT_CHANGE_FONT_STYLE)) {
+ // Use the last state to render out the current sentence
+ // Styles apply to the text 'after' them
+ if (!currentSentence.empty()) {
+ textSurfaces.push_back(TextSurface(font.renderSolidText(currentSentence, textColor), sentencePixelOffset, currentLineNumber));
- style.setFont(font);
+ lineWidth += sentenceWidth;
+ sentencePixelOffset.x += sentenceWidth;
- int16 prevbufspace = 0, prevtxtspace = 0;
+ // Reset the sentence variables
+ currentSentence.clear();
+ sentenceWidth = 0;
+ }
- while (i < stringlen) {
- TxtJustify[currentline] = style.justify;
- if (text[i] == '<') {
- int16 ret = 0;
+ // Update the current state with the style information
+ currentState.updateFontWithTextState(font);
- startTextPosition = i;
- while (i < stringlen && text[i] != '>')
- i++;
- endTextPosition = i;
- if (startTextPosition != -1)
- if ((endTextPosition - startTextPosition - 1) > 0) {
- style2 = style;
- ret = style.parseStyle(Common::String(text.c_str() + startTextPosition + 1), endTextPosition - startTextPosition - 1);
+ lineHeight = MAX(lineHeight, font.getFontHeight());
+ spaceWidth = font.getCharWidth(' ');
+ }
+ if (stateChanges & TEXT_CHANGE_NEWLINE) {
+ // If the current sentence has content, render it out
+ if (!currentSentence.empty()) {
+ textSurfaces.push_back(TextSurface(font.renderSolidText(currentSentence, textColor), sentencePixelOffset, currentLineNumber));
}
+
+ // Set line width
+ lineWidths.push_back(lineWidth + sentenceWidth - (numSpaces * spaceWidth));
+
+ currentSentence.clear();
+ sentenceWidth = 0;
+
+ // Update the offsets
+ sentencePixelOffset.x = 0u;
+ sentencePixelOffset.y += lineHeight;
+
+ // Reset the line variables
+ lineHeight = font.getFontHeight();
+ lineWidth = 0;
+ ++currentLineNumber;
+ lineJustifications.push_back(currentState._justification);
+ }
+ if (stateChanges & TEXT_CHANGE_HAS_STATE_BOX) {
+ Common::String temp = Common::String::format("%d", _engine->getScriptManager()->getStateValue(currentState._statebox));
+ wordWidth += font.getStringWidth(temp);
- if (ret & (TXT_RET_FNTCHG | TXT_RET_FNTSTL | TXT_RET_NEWLN)) {
- if (buf.size() > 0) {
- textPixelWidth = font.getStringWidth(buf);
-
- TxtSurfaces[currentline][currentlineitm] = render(font, buf, style2);
- TxtPoint[currentline] = MAX(font.getFontHeight(), TxtPoint[currentline]);
+ // If the word causes the line to overflow, render the sentence and start a new line
+ if (lineWidth + sentenceWidth + wordWidth > dest.w) {
+ textSurfaces.push_back(TextSurface(font.renderSolidText(currentSentence, textColor), sentencePixelOffset, currentLineNumber));
- currentlineitm++;
+ // Set line width
+ lineWidths.push_back(lineWidth + sentenceWidth - (numSpaces * spaceWidth));
- buf.clear();
- prevbufspace = 0;
- textPosition = 0;
- dx += textPixelWidth;
+ currentSentence.clear();
+ sentenceWidth = 0;
- }
- if (ret & TXT_RET_FNTCHG) {
- style.setFont(font);
- }
- if (ret & TXT_RET_FNTSTL)
- style.setFontStyle(font);
+ // Update the offsets
+ sentencePixelOffset.x = 0u;
+ sentencePixelOffset.y += lineHeight;
- if (ret & TXT_RET_NEWLN) {
- currentline++;
- currentlineitm = 0;
- dx = 0;
+ // Reset the line variables
+ lineHeight = font.getFontHeight();
+ lineWidth = 0;
+ ++currentLineNumber;
+ lineJustifications.push_back(currentState._justification);
}
}
-
- if (ret & TXT_RET_HASSTBOX) {
- Common::String buf3;
- buf3 = Common::String::format("%d", _engine->getScriptManager()->getStateValue(style.statebox));
- buf += buf3;
- textPosition += buf3.size();
- }
-
} else {
-
- buf += text[i];
- textPosition++;
+ currentWord += text[i];
+ wordWidth += font.getCharWidth(text[i]);
if (text[i] == ' ') {
- prevbufspace = textPosition - 1;
- prevtxtspace = i;
- }
+ // When we hit the first space, flush the current word to the sentence
+ if (!currentWord.empty()) {
+ currentSentence += currentWord;
+ sentenceWidth += wordWidth;
- if (font.isLoaded()) {
- textPixelWidth = font.getStringWidth(buf);
- if (textPixelWidth + dx > dst.w) {
- if (prevbufspace == 0) {
- prevtxtspace = i;
- prevbufspace = textPosition - 1;
- }
- buf2 = Common::String(buf.c_str(), prevbufspace + 1);
+ currentWord.clear();
+ wordWidth = 0;
+ }
- if (buf2.size() > 0) {
- TxtSurfaces[currentline][currentlineitm] = render(font, buf2, style);
- TxtPoint[currentline] = MAX(font.getFontHeight(), TxtPoint[currentline]);
+ // We track the number of spaces so we can disregard their width in lineWidth calculations
+ ++numSpaces;
+ } else {
+ // If the word causes the line to overflow, render the sentence and start a new line
+ if (lineWidth + sentenceWidth + wordWidth > dest.w) {
+ // Only render out content
+ if (!currentSentence.empty()) {
+ textSurfaces.push_back(TextSurface(font.renderSolidText(currentSentence, currentState.getTextColor(_engine)), sentencePixelOffset, currentLineNumber));
}
- buf.clear();
- i = prevtxtspace;
- prevbufspace = 0;
- textPosition = 0;
- currentline++;
- currentlineitm = 0;
- dx = 0;
+ // Set line width
+ lineWidths.push_back(lineWidth + sentenceWidth - (numSpaces * spaceWidth));
+
+ currentSentence.clear();
+ sentenceWidth = 0;
+
+ // Update the offsets
+ sentencePixelOffset.x = 0u;
+ sentencePixelOffset.y += lineHeight;
+
+ // Reset the line variables
+ lineHeight = font.getFontHeight();
+ lineWidth = 0;
+ ++currentLineNumber;
+ lineJustifications.push_back(currentState._justification);
}
+
+ numSpaces = 0u;
}
}
+
i++;
}
- if (buf.size() > 0) {
- TxtSurfaces[currentline][currentlineitm] = render(font, buf, style);
- TxtPoint[currentline] = MAX(font.getFontHeight(), TxtPoint[currentline]);
+ // Render out any remaining words/sentences
+ if (!currentWord.empty() || !currentSentence.empty()) {
+ currentSentence += currentWord;
+ sentenceWidth += wordWidth;
+
+ textSurfaces.push_back(TextSurface(font.renderSolidText(currentSentence, currentState.getTextColor(_engine)), sentencePixelOffset, currentLineNumber));
}
- dy = 0;
- for (i = 0; i <= currentline; i++) {
- int16 j = 0;
- int16 width = 0;
- while (TxtSurfaces[i][j] != NULL) {
- width += TxtSurfaces[i][j]->w;
- j++;
- }
- dx = 0;
- for (int32 jj = 0; jj < j; jj++) {
- if (TxtJustify[i] == TXT_JUSTIFY_LEFT)
- _engine->getRenderManager()->blitSurfaceToSurface(*TxtSurfaces[i][jj], dst, dx, dy + TxtPoint[i] - TxtSurfaces[i][jj]->h, 0);
-
- else if (TxtJustify[i] == TXT_JUSTIFY_CENTER)
- _engine->getRenderManager()->blitSurfaceToSurface(*TxtSurfaces[i][jj], dst, ((dst.w - width) / 2) + dx, dy + TxtPoint[i] - TxtSurfaces[i][jj]->h, 0);
+ lineWidths.push_back(lineWidth + sentenceWidth);
+ lineJustifications.push_back(currentState._justification);
- else if (TxtJustify[i] == TXT_JUSTIFY_RIGHT)
- _engine->getRenderManager()->blitSurfaceToSurface(*TxtSurfaces[i][jj], dst, dst.w - width + dx, dy + TxtPoint[i] - TxtSurfaces[i][jj]->h, 0);
+ for (Common::Array<TextSurface>::iterator iter = textSurfaces.begin(); iter != textSurfaces.end(); ++iter) {
+ Common::Rect empty;
- dx += TxtSurfaces[i][jj]->w;
+ if (lineJustifications[iter->_lineNumber] == TEXT_JUSTIFY_LEFT) {
+ _engine->getRenderManager()->blitSurfaceToSurface(*iter->_surface, empty, dest, iter->_surfaceOffset.x, iter->_surfaceOffset.y, 0);
+ } else if (lineJustifications[iter->_lineNumber] == TEXT_JUSTIFY_CENTER) {
+ _engine->getRenderManager()->blitSurfaceToSurface(*iter->_surface, empty, dest, ((dest.w - lineWidths[iter->_lineNumber]) / 2) + iter->_surfaceOffset.x, iter->_surfaceOffset.y, 0);
+ } else if (lineJustifications[iter->_lineNumber] == TEXT_JUSTIFY_RIGHT) {
+ _engine->getRenderManager()->blitSurfaceToSurface(*iter->_surface, empty, dest, dest.w - lineWidths[iter->_lineNumber] + iter->_surfaceOffset.x, iter->_surfaceOffset.y, 0);
}
- dy += TxtPoint[i];
+ // Release memory
+ iter->_surface->free();
+ delete iter->_surface;
}
-
- for (i = 0; i < TXT_CFG_TEXTURES_LINES; i++)
- for (int32 j = 0; j < TXT_CFG_TEXTURES_PER_LINE; j++)
- if (TxtSurfaces[i][j] != NULL) {
- TxtSurfaces[i][j]->free();
- delete TxtSurfaces[i][j];
- }
}
Common::String readWideLine(Common::SeekableReadStream &stream) {
Common::String asciiString;
- while (!stream.eos()) {
+ while (true) {
uint32 value = stream.readUint16LE();
+ if (stream.eos())
+ break;
// Check for CRLF
if (value == 0x0A0D) {
// Read in the extra NULL char
@@ -495,10 +527,12 @@ Common::String readWideLine(Common::SeekableReadStream &stream) {
} else if (value >= 0x80 && value < 0x800) {
asciiString += (char)(0xC0 | ((value >> 6) & 0x1F));
asciiString += (char)(0x80 | (value & 0x3F));
- } else if (value >= 0x800 && value < 0x10000) {
+ } else if (value >= 0x800 && value < 0x10000 && value != 0xCCCC) {
asciiString += (char)(0xE0 | ((value >> 12) & 0xF));
asciiString += (char)(0x80 | ((value >> 6) & 0x3F));
asciiString += (char)(0x80 | (value & 0x3F));
+ } else if (value == 0xCCCC) {
+ // Ignore, this character is used as newline sometimes
} else if (value >= 0x10000 && value < 0x200000) {
asciiString += (char)(0xF0);
asciiString += (char)(0x80 | ((value >> 12) & 0x3F));
diff --git a/engines/zvision/text/text.h b/engines/zvision/text/text.h
index ecec3ccde6..5dd872a440 100644
--- a/engines/zvision/text/text.h
+++ b/engines/zvision/text/text.h
@@ -24,63 +24,60 @@
#ifndef ZVISION_TEXT_H
#define ZVISION_TEXT_H
-#include "zvision/detection.h"
-#include "zvision/graphics/truetype_font.h"
+#include "zvision/text/truetype_font.h"
#include "zvision/zvision.h"
namespace ZVision {
class ZVision;
-enum txtJustify {
- TXT_JUSTIFY_CENTER = 0,
- TXT_JUSTIFY_LEFT = 1,
- TXT_JUSTIFY_RIGHT = 2
+enum TextJustification {
+ TEXT_JUSTIFY_CENTER = 0,
+ TEXT_JUSTIFY_LEFT = 1,
+ TEXT_JUSTIFY_RIGHT = 2
};
-enum txtReturn {
- TXT_RET_NOTHING = 0x0,
- TXT_RET_FNTCHG = 0x1,
- TXT_RET_FNTSTL = 0x2,
- TXT_RET_NEWLN = 0x4,
- TXT_RET_HASSTBOX = 0x8
+enum TextChange {
+ TEXT_CHANGE_NONE = 0x0,
+ TEXT_CHANGE_FONT_TYPE = 0x1,
+ TEXT_CHANGE_FONT_STYLE = 0x2,
+ TEXT_CHANGE_NEWLINE = 0x4,
+ TEXT_CHANGE_HAS_STATE_BOX = 0x8
};
-class cTxtStyle {
+class TextStyleState {
public:
- cTxtStyle();
- txtReturn parseStyle(const Common::String &strin, int16 len);
- void readAllStyle(const Common::String &txt);
- void setFontStyle(StyledTTFont &font);
- void setFont(StyledTTFont &font);
+ TextStyleState();
+ TextChange parseStyle(const Common::String &str, int16 len);
+ void readAllStyles(const Common::String &txt);
+ void updateFontWithTextState(StyledTTFont &font);
+
+ uint32 getTextColor(ZVision *engine) {
+ return engine->_resourcePixelFormat.RGBToColor(_red, _green, _blue);
+ }
public:
- Common::String fontname;
- txtJustify justify; // 0 - center, 1-left, 2-right
- int16 size;
- uint8 red; // 0-255
- uint8 green; // 0-255
- uint8 blue; // 0-255
- int8 newline;
- int8 escapement;
- bool italic;
- bool bold;
- bool underline;
- bool strikeout;
- bool skipcolor;
- int32 statebox;
- bool sharp;
- // char image ??
+ Common::String _fontname;
+ TextJustification _justification;
+ int16 _size;
+ uint8 _red; // 0-255
+ uint8 _green; // 0-255
+ uint8 _blue; // 0-255
+ bool _italic;
+ bool _bold;
+ bool _underline;
+ bool _strikeout;
+ int32 _statebox;
+ bool _sharp;
};
class TextRenderer {
public:
TextRenderer(ZVision *engine): _engine(engine) {};
- void drawTxtWithJustify(const Common::String &txt, StyledTTFont &fnt, uint32 color, Graphics::Surface &dst, int lineY, txtJustify justify);
- int32 drawTxt(const Common::String &txt, cTxtStyle &fontStyle, Graphics::Surface &dst);
- Graphics::Surface *render(StyledTTFont &fnt, const Common::String &txt, cTxtStyle &style);
- void drawTxtInOneLine(const Common::String &txt, Graphics::Surface &dst);
+ void drawTextWithJustification(const Common::String &text, StyledTTFont &font, uint32 color, Graphics::Surface &dest, int lineY, TextJustification jusification);
+ int32 drawText(const Common::String &text, TextStyleState &state, Graphics::Surface &dest);
+ void drawTextWithWordWrapping(const Common::String &text, Graphics::Surface &dest);
private:
ZVision *_engine;
diff --git a/engines/zvision/text/truetype_font.cpp b/engines/zvision/text/truetype_font.cpp
new file mode 100644
index 0000000000..acb053ea8d
--- /dev/null
+++ b/engines/zvision/text/truetype_font.cpp
@@ -0,0 +1,265 @@
+/* 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/scummsys.h"
+#include "common/config-manager.h"
+#include "common/debug.h"
+#include "common/file.h"
+#include "common/system.h"
+#include "common/unzip.h"
+#include "common/ustr.h"
+#include "graphics/font.h"
+#include "graphics/fonts/ttf.h"
+#include "graphics/surface.h"
+
+#include "zvision/zvision.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/text/truetype_font.h"
+
+namespace ZVision {
+
+const FontStyle systemFonts[] = {
+ { "*times new roman*", "times", "FreeSerif", "Italic", "LiberationSerif" },
+ { "*times*", "times", "FreeSerif", "Italic", "LiberationSerif" },
+ { "*century schoolbook*", "censcbk", "FreeSerif", "Italic", "LiberationSerif" },
+ { "*garamond*", "gara", "FreeSerif", "Italic", "LiberationSerif" },
+ { "*courier new*", "cour", "FreeMono", "Oblique", "LiberationMono" },
+ { "*courier*", "cour", "FreeMono", "Oblique", "LiberationMono" },
+ { "*ZorkDeath*", "cour", "FreeMono", "Oblique", "LiberationMono" },
+ { "*arial*", "arial", "FreeSans", "Oblique", "LiberationSans" },
+ { "*ZorkNormal*", "arial", "FreeSans", "Oblique", "LiberationSans" }
+};
+
+const FontStyle getSystemFont(int fontIndex) {
+ return systemFonts[fontIndex];
+}
+
+StyledTTFont::StyledTTFont(ZVision *engine) {
+ _engine = engine;
+ _style = 0;
+ _font = nullptr;
+ _lineHeight = 0;
+}
+
+StyledTTFont::~StyledTTFont() {
+ delete _font;
+}
+
+bool StyledTTFont::loadFont(const Common::String &fontName, int32 point, uint style) {
+ // Don't re-load the font if we've already loaded it
+ // We have to check for empty so we can default to Arial
+ if (!fontName.empty() && _fontName.equalsIgnoreCase(fontName) && _lineHeight == point && _style == style) {
+ return true;
+ }
+
+ _style = style;
+
+ Common::String newFontName;
+ Common::String freeFontName;
+ Common::String liberationFontName;
+
+ for (int i = 0; i < FONT_COUNT; i++) {
+ FontStyle curFont = getSystemFont(i);
+ if (fontName.matchString(curFont.zorkFont, true)) {
+ newFontName = curFont.fontBase;
+ freeFontName = curFont.freeFontBase;
+ liberationFontName = curFont.liberationFontBase;
+
+ if ((_style & TTF_STYLE_BOLD) && (_style & TTF_STYLE_ITALIC)) {
+ newFontName += "bi";
+ freeFontName += "Bold";
+ freeFontName += curFont.freeFontItalicName;
+ liberationFontName += "-BoldItalic";
+ } else if (_style & TTF_STYLE_BOLD) {
+ newFontName += "bd";
+ freeFontName += "Bold";
+ liberationFontName += "-Bold";
+ } else if (_style & TTF_STYLE_ITALIC) {
+ newFontName += "i";
+ freeFontName += curFont.freeFontItalicName;
+ liberationFontName += "-Italic";
+ } else {
+ liberationFontName += "-Regular";
+ }
+
+ newFontName += ".ttf";
+ freeFontName += ".ttf";
+ liberationFontName += ".ttf";
+ break;
+ }
+ }
+
+ if (newFontName.empty()) {
+ debug("Could not identify font: %s. Reverting to Arial", fontName.c_str());
+ newFontName = "arial.ttf";
+ freeFontName = "FreeSans.ttf";
+ liberationFontName = "LiberationSans-Regular.ttf";
+ }
+
+ bool sharp = (_style & TTF_STYLE_SHARP) == TTF_STYLE_SHARP;
+
+ Common::File file;
+ if (!file.open(newFontName) && !_engine->getSearchManager()->openFile(file, newFontName) &&
+ !file.open(liberationFontName) && !_engine->getSearchManager()->openFile(file, liberationFontName) &&
+ !file.open(freeFontName) && !_engine->getSearchManager()->openFile(file, freeFontName))
+ error("Unable to open font file %s (Liberation Font alternative: %s, FreeFont alternative: %s)", newFontName.c_str(), liberationFontName.c_str(), freeFontName.c_str());
+
+ Graphics::Font *newFont = Graphics::loadTTFFont(file, point, 60, (sharp ? Graphics::kTTFRenderModeMonochrome : Graphics::kTTFRenderModeNormal)); // 66 dpi for 640 x 480 on 14" display
+ if (newFont == nullptr) {
+ return false;
+ }
+
+ delete _font;
+ _font = newFont;
+
+ _fontName = fontName;
+ _lineHeight = point;
+
+ return true;
+}
+
+int StyledTTFont::getFontHeight() {
+ if (_font)
+ return _font->getFontHeight();
+
+ return 0;
+}
+
+int StyledTTFont::getMaxCharWidth() {
+ if (_font)
+ return _font->getMaxCharWidth();
+
+ return 0;
+}
+
+int StyledTTFont::getCharWidth(byte chr) {
+ if (_font)
+ return _font->getCharWidth(chr);
+
+ return 0;
+}
+
+int StyledTTFont::getKerningOffset(byte left, byte right) {
+ if (_font)
+ return _font->getKerningOffset(left, right);
+
+ return 0;
+}
+
+Common::U32String StyledTTFont::convertUtf8ToUtf32(const Common::String &str) {
+ // The String class, and therefore the Font class as well, assume one
+ // character is one byte, but in this case it's actually an UTF-8
+ // string with up to 4 bytes per character. To work around this,
+ // convert it to an U32String before drawing it, because our Font class
+ // can handle that.
+ Common::U32String u32str;
+ uint i = 0;
+ while (i < str.size()) {
+ uint32 chr = 0;
+ if ((str[i] & 0xF8) == 0xF0) {
+ chr |= (str[i++] & 0x07) << 18;
+ chr |= (str[i++] & 0x3F) << 12;
+ chr |= (str[i++] & 0x3F) << 6;
+ chr |= (str[i++] & 0x3F);
+ } else if ((str[i] & 0xF0) == 0xE0) {
+ chr |= (str[i++] & 0x0F) << 12;
+ chr |= (str[i++] & 0x3F) << 6;
+ chr |= (str[i++] & 0x3F);
+ } else if ((str[i] & 0xE0) == 0xC0) {
+ chr |= (str[i++] & 0x1F) << 6;
+ chr |= (str[i++] & 0x3F);
+ } else {
+ chr = (str[i++] & 0x7F);
+ }
+ u32str += chr;
+ }
+ return u32str;
+}
+
+void StyledTTFont::drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) {
+ if (_font) {
+ _font->drawChar(dst, chr, x, y, color);
+ if (_style & TTF_STYLE_UNDERLINE) {
+ int16 pos = (int16)floor(_font->getFontHeight() * 0.87);
+ int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
+ dst->fillRect(Common::Rect(x, y + pos, x + _font->getCharWidth(chr), y + pos + thk), color);
+ }
+ if (_style & TTF_STYLE_STRIKETHROUGH) {
+ int16 pos = (int16)floor(_font->getFontHeight() * 0.60);
+ int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
+ dst->fillRect(Common::Rect(x, y + pos, x + _font->getCharWidth(chr), y + pos + thk), color);
+ }
+ }
+}
+
+void StyledTTFont::drawString(Graphics::Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, Graphics::TextAlign align) {
+ if (_font) {
+ Common::U32String u32str = convertUtf8ToUtf32(str);
+ _font->drawString(dst, u32str, x, y, w, color, align);
+ if (_style & TTF_STYLE_UNDERLINE) {
+ int16 pos = (int16)floor(_font->getFontHeight() * 0.87);
+ int16 wd = MIN(_font->getStringWidth(u32str), w);
+ int16 stX = x;
+ if (align == Graphics::kTextAlignCenter)
+ stX += (w - wd) / 2;
+ else if (align == Graphics::kTextAlignRight)
+ stX += (w - wd);
+
+ int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
+
+ dst->fillRect(Common::Rect(stX, y + pos, stX + wd, y + pos + thk), color);
+ }
+ if (_style & TTF_STYLE_STRIKETHROUGH) {
+ int16 pos = (int16)floor(_font->getFontHeight() * 0.60);
+ int16 wd = MIN(_font->getStringWidth(u32str), w);
+ int16 stX = x;
+ if (align == Graphics::kTextAlignCenter)
+ stX += (w - wd) / 2;
+ else if (align == Graphics::kTextAlignRight)
+ stX += (w - wd);
+
+ int thk = MAX((int)(_font->getFontHeight() * 0.05), 1);
+
+ dst->fillRect(Common::Rect(stX, y + pos, stX + wd, y + pos + thk), color);
+ }
+ }
+}
+
+int StyledTTFont::getStringWidth(const Common::String &str) {
+ if (_font)
+ return _font->getStringWidth(str);
+ return 0;
+}
+
+Graphics::Surface *StyledTTFont::renderSolidText(const Common::String &str, uint32 color) {
+ Graphics::Surface *tmp = new Graphics::Surface;
+ if (_font) {
+ int16 w = _font->getStringWidth(str);
+ if (w && w < 1024) {
+ tmp->create(w, _font->getFontHeight(), _engine->_resourcePixelFormat);
+ drawString(tmp, str, 0, 0, w, color);
+ }
+ }
+ return tmp;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/graphics/truetype_font.h b/engines/zvision/text/truetype_font.h
index b5fac4af8a..6abe05cda6 100644
--- a/engines/zvision/graphics/truetype_font.h
+++ b/engines/zvision/text/truetype_font.h
@@ -34,6 +34,16 @@ struct Surface;
namespace ZVision {
+struct FontStyle {
+ const char *zorkFont;
+ const char *fontBase;
+ const char *freeFontBase;
+ const char *freeFontItalicName;
+ const char *liberationFontBase;
+};
+
+#define FONT_COUNT 9
+
class ZVision;
// Styled TTF
@@ -43,11 +53,11 @@ public:
~StyledTTFont();
enum {
- STTF_BOLD = 1,
- STTF_ITALIC = 2,
- STTF_UNDERLINE = 4,
- STTF_STRIKEOUT = 8,
- STTF_SHARP = 16
+ TTF_STYLE_BOLD = 0x01,
+ TTF_STYLE_ITALIC = 0x02,
+ TTF_STYLE_UNDERLINE = 0x04,
+ TTF_STYLE_STRIKETHROUGH = 0x08,
+ TTF_STYLE_SHARP = 0x10
};
private:
@@ -55,18 +65,18 @@ private:
Graphics::Font *_font;
int _lineHeight;
uint _style;
- Common::String _fntName;
+ Common::String _fontName;
public:
- bool loadFont(const Common::String &fontName, int32 point);
bool loadFont(const Common::String &fontName, int32 point, uint style);
- void setStyle(uint newStyle);
int getFontHeight();
int getMaxCharWidth();
int getCharWidth(byte chr);
int getKerningOffset(byte left, byte right);
+ Common::U32String convertUtf8ToUtf32(const Common::String &str);
+
void drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color);
void drawString(Graphics::Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, Graphics::TextAlign align = Graphics::kTextAlignLeft);
diff --git a/engines/zvision/video/rlf_decoder.cpp b/engines/zvision/video/rlf_decoder.cpp
index bdb5dc18bc..3bbf22edff 100644
--- a/engines/zvision/video/rlf_decoder.cpp
+++ b/engines/zvision/video/rlf_decoder.cpp
@@ -30,8 +30,6 @@
#include "common/debug.h"
#include "common/endian.h"
-#include "graphics/colormasks.h"
-
namespace ZVision {
RLFDecoder::~RLFDecoder() {
@@ -41,9 +39,13 @@ RLFDecoder::~RLFDecoder() {
bool RLFDecoder::loadStream(Common::SeekableReadStream *stream) {
close();
- addTrack(new RLFVideoTrack(stream));
-
- return true;
+ // Check if the stream is valid
+ if (stream && !stream->err() && stream->readUint32BE() == MKTAG('F', 'E', 'L', 'R')) {
+ addTrack(new RLFVideoTrack(stream));
+ return true;
+ } else {
+ return false;
+ }
}
RLFDecoder::RLFVideoTrack::RLFVideoTrack(Common::SeekableReadStream *stream)
@@ -54,7 +56,7 @@ RLFDecoder::RLFVideoTrack::RLFVideoTrack(Common::SeekableReadStream *stream)
_height(0),
_frameTime(0),
_frames(0),
- _curFrame(0),
+ _displayedFrame(-1),
_frameBufferByteSize(0) {
if (!readHeader()) {
@@ -62,7 +64,7 @@ RLFDecoder::RLFVideoTrack::RLFVideoTrack(Common::SeekableReadStream *stream)
return;
}
- _currentFrameBuffer.create(_width, _height, Graphics::createPixelFormat<565>());
+ _currentFrameBuffer.create(_width, _height, getPixelFormat());
_frameBufferByteSize = _width * _height * sizeof(uint16);
_frames = new Frame[_frameCount];
@@ -83,10 +85,6 @@ RLFDecoder::RLFVideoTrack::~RLFVideoTrack() {
}
bool RLFDecoder::RLFVideoTrack::readHeader() {
- if (_readStream->readUint32BE() != MKTAG('F', 'E', 'L', 'R')) {
- return false;
- }
-
// Read the header
_readStream->readUint32LE(); // Size1
_readStream->readUint32LE(); // Unknown1
@@ -161,22 +159,17 @@ RLFDecoder::RLFVideoTrack::Frame RLFDecoder::RLFVideoTrack::readNextFrame() {
bool RLFDecoder::RLFVideoTrack::seek(const Audio::Timestamp &time) {
uint frame = getFrameAtTime(time);
- assert(frame < (int)_frameCount);
+ assert(frame < _frameCount);
- if ((uint)_curFrame == frame)
+ if ((uint)_displayedFrame == frame)
return true;
- if (frame < 0) {
- _curFrame = 0;
- return false;
- }
-
- int closestFrame = _curFrame;
- int distance = (int)frame - _curFrame;
+ int closestFrame = _displayedFrame;
+ int distance = (int)frame - closestFrame;
if (distance < 0) {
for (uint i = 0; i < _completeFrames.size(); ++i) {
- if ((int)_completeFrames[i] > frame)
+ if (_completeFrames[i] > frame)
break;
closestFrame = _completeFrames[i];
}
@@ -196,19 +189,18 @@ bool RLFDecoder::RLFVideoTrack::seek(const Audio::Timestamp &time) {
applyFrameToCurrent(i);
}
- _curFrame = frame;
+ _displayedFrame = frame - 1;
return true;
}
const Graphics::Surface *RLFDecoder::RLFVideoTrack::decodeNextFrame() {
- // When an animation ends, rewind
- if (_curFrame == (int)_frameCount)
- seek(Audio::Timestamp(0, getFrameRate().toInt()));
-
- applyFrameToCurrent(_curFrame);
+ if (_displayedFrame >= (int)_frameCount)
+ return NULL;
+
+ _displayedFrame++;
+ applyFrameToCurrent(_displayedFrame);
- _curFrame++;
return &_currentFrameBuffer;
}
@@ -242,10 +234,7 @@ void RLFDecoder::RLFVideoTrack::decodeMaskedRunLengthEncoding(int8 *source, int8
return;
}
- byte r, g, b;
- Graphics::colorToRGB<Graphics::ColorMasks<555> >(READ_LE_UINT16(source + sourceOffset), r, g, b);
- uint16 destColor = Graphics::RGBToColor<Graphics::ColorMasks<565> >(r, g, b);
- WRITE_UINT16(dest + destOffset, destColor);
+ WRITE_UINT16(dest + destOffset, READ_LE_UINT16(source + sourceOffset));
sourceOffset += 2;
destOffset += 2;
@@ -289,10 +278,7 @@ void RLFDecoder::RLFVideoTrack::decodeSimpleRunLengthEncoding(int8 *source, int8
return;
}
- byte r, g, b;
- Graphics::colorToRGB<Graphics::ColorMasks<555> >(READ_LE_UINT16(source + sourceOffset), r, g, b);
- uint16 destColor = Graphics::RGBToColor<Graphics::ColorMasks<565> >(r, g, b);
- WRITE_UINT16(dest + destOffset, destColor);
+ WRITE_UINT16(dest + destOffset, READ_LE_UINT16(source + sourceOffset));
sourceOffset += 2;
destOffset += 2;
@@ -306,9 +292,7 @@ void RLFDecoder::RLFVideoTrack::decodeSimpleRunLengthEncoding(int8 *source, int8
return;
}
- byte r, g, b;
- Graphics::colorToRGB<Graphics::ColorMasks<555> >(READ_LE_UINT16(source + sourceOffset), r, g, b);
- uint16 sampleColor = Graphics::RGBToColor<Graphics::ColorMasks<565> >(r, g, b);
+ uint16 sampleColor = READ_LE_UINT16(source + sourceOffset);
sourceOffset += 2;
numberOfCopy = numberOfSamples + 2;
diff --git a/engines/zvision/video/rlf_decoder.h b/engines/zvision/video/rlf_decoder.h
index f0f31c2128..8b8cbaecd5 100644
--- a/engines/zvision/video/rlf_decoder.h
+++ b/engines/zvision/video/rlf_decoder.h
@@ -45,15 +45,15 @@ private:
uint16 getWidth() const { return _width; }
uint16 getHeight() const { return _height; }
- Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0); /*RGB 565*/ }
- int getCurFrame() const { return _curFrame; }
+ Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0); /* RGB 555 */ }
+ int getCurFrame() const { return _displayedFrame; }
int getFrameCount() const { return _frameCount; }
const Graphics::Surface *decodeNextFrame();
bool isSeekable() const { return true; }
bool seek(const Audio::Timestamp &time);
protected:
- Common::Rational getFrameRate() const { return Common::Rational(60, _frameTime); }
+ Common::Rational getFrameRate() const { return Common::Rational(1000, _frameTime); }
private:
enum EncodingType {
@@ -121,7 +121,7 @@ private:
Frame *_frames;
Common::Array<uint> _completeFrames;
- int _curFrame;
+ int _displayedFrame;
Graphics::Surface _currentFrameBuffer;
uint32 _frameBufferByteSize;
diff --git a/engines/zvision/video/video.cpp b/engines/zvision/video/video.cpp
index 189fb22194..1cfd0f4197 100644
--- a/engines/zvision/video/video.cpp
+++ b/engines/zvision/video/video.cpp
@@ -23,13 +23,17 @@
#include "common/scummsys.h"
#include "common/system.h"
#include "video/video_decoder.h"
+#ifdef USE_MPEG2
+#include "video/mpegps_decoder.h"
+#endif
#include "engines/util.h"
#include "graphics/surface.h"
#include "zvision/zvision.h"
#include "zvision/core/clock.h"
#include "zvision/graphics/render_manager.h"
-#include "zvision/graphics/subtitles.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/text/subtitles.h"
#include "zvision/video/rlf_decoder.h"
#include "zvision/video/zork_avi_decoder.h"
@@ -44,12 +48,21 @@ Video::VideoDecoder *ZVision::loadAnimation(const Common::String &fileName) {
animation = new RLFDecoder();
else if (tmpFileName.hasSuffix(".avi"))
animation = new ZorkAVIDecoder();
+#ifdef USE_MPEG2
+ else if (tmpFileName.hasSuffix(".vob"))
+ animation = new Video::MPEGPSDecoder();
+#endif
else
error("Unknown suffix for animation %s", fileName.c_str());
Common::File *_file = getSearchManager()->openFile(tmpFileName);
- animation->loadStream(_file);
-
+ if (!_file)
+ error("Error opening %s", tmpFileName.c_str());
+
+ bool loaded = animation->loadStream(_file);
+ if (!loaded)
+ error("Error loading animation %s", tmpFileName.c_str());
+
return animation;
}
@@ -70,6 +83,7 @@ void ZVision::playVideo(Video::VideoDecoder &vid, const Common::Rect &destRect,
uint16 y = _workingWindow.top + dst.top;
uint16 finalWidth = dst.width() < _workingWindow.width() ? dst.width() : _workingWindow.width();
uint16 finalHeight = dst.height() < _workingWindow.height() ? dst.height() : _workingWindow.height();
+ bool showSubs = (_scriptManager->getStateValue(StateKey_Subtitles) == 1);
_clock.stop();
vid.start();
@@ -101,7 +115,7 @@ void ZVision::playVideo(Video::VideoDecoder &vid, const Common::Rect &destRect,
if (vid.needsUpdate()) {
const Graphics::Surface *frame = vid.decodeNextFrame();
- if (sub)
+ if (sub && showSubs)
sub->process(vid.getCurFrame());
if (frame) {
@@ -109,7 +123,8 @@ void ZVision::playVideo(Video::VideoDecoder &vid, const Common::Rect &destRect,
_renderManager->scaleBuffer(frame->getPixels(), scaled->getPixels(), frame->w, frame->h, frame->format.bytesPerPixel, scaled->w, scaled->h);
frame = scaled;
}
- _system->copyRectToScreen((const byte *)frame->getPixels(), frame->pitch, x, y, finalWidth, finalHeight);
+ Common::Rect rect = Common::Rect(x, y, x + finalWidth, y + finalHeight);
+ _renderManager->copyToScreen(*frame, rect, 0, 0);
_renderManager->processSubs(0);
}
}
diff --git a/engines/zvision/video/zork_avi_decoder.cpp b/engines/zvision/video/zork_avi_decoder.cpp
index 67fab0a114..cf8505ec82 100644
--- a/engines/zvision/video/zork_avi_decoder.cpp
+++ b/engines/zvision/video/zork_avi_decoder.cpp
@@ -39,17 +39,34 @@ Video::AVIDecoder::AVIAudioTrack *ZorkAVIDecoder::createAudioTrack(Video::AVIDec
}
void ZorkAVIDecoder::ZorkAVIAudioTrack::queueSound(Common::SeekableReadStream *stream) {
+ bool updateCurChunk = true;
if (_audStream) {
if (_wvInfo.tag == kWaveFormatZorkPCM) {
assert(_wvInfo.size == 8);
RawChunkStream::RawChunk chunk = decoder->readNextChunk(stream);
delete stream;
- if (chunk.data)
- _audStream->queueBuffer((byte *)chunk.data, chunk.size, DisposeAfterUse::YES, Audio::FLAG_16BITS | Audio::FLAG_LITTLE_ENDIAN | Audio::FLAG_STEREO);
+ if (chunk.data) {
+ byte flags = Audio::FLAG_16BITS | Audio::FLAG_STEREO;
+#ifdef SCUMM_LITTLE_ENDIAN
+ // RawChunkStream produces native endianness int16
+ flags |= Audio::FLAG_LITTLE_ENDIAN;
+#endif
+ _audStream->queueBuffer((byte *)chunk.data, chunk.size, DisposeAfterUse::YES, flags);
+ }
} else {
+ updateCurChunk = false;
AVIAudioTrack::queueSound(stream);
}
+ } else {
+ delete stream;
+ }
+
+ // The superclass always updates _curChunk, whether or not audio has
+ // been queued, so we should do that too. Unless the superclass already
+ // has done it for us.
+ if (updateCurChunk) {
+ _curChunk++;
}
}
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
index 4e5307c182..779fdc4464 100644
--- a/engines/zvision/zvision.cpp
+++ b/engines/zvision/zvision.cpp
@@ -27,13 +27,12 @@
#include "zvision/scripting/script_manager.h"
#include "zvision/graphics/render_manager.h"
#include "zvision/graphics/cursors/cursor_manager.h"
-#include "zvision/core/save_manager.h"
+#include "zvision/file/save_manager.h"
#include "zvision/text/string_manager.h"
-#include "zvision/detection.h"
-#include "zvision/core/menu.h"
+#include "zvision/scripting/menu.h"
#include "zvision/file/search_manager.h"
#include "zvision/text/text.h"
-#include "zvision/graphics/truetype_font.h"
+#include "zvision/text/truetype_font.h"
#include "zvision/sound/midi.h"
#include "zvision/file/zfs_archive.h"
@@ -46,42 +45,42 @@
#include "common/system.h"
#include "common/file.h"
+#include "gui/message.h"
#include "engines/util.h"
-
#include "audio/mixer.h"
namespace ZVision {
-#define ZVISION_SETTINGS_KEYS_COUNT 17
+#define ZVISION_SETTINGS_KEYS_COUNT 12
struct zvisionIniSettings {
const char *name;
int16 slot;
- int16 deflt;
+ int16 defaultValue; // -1: use the bool value
+ bool defaultBoolValue;
+ bool allowEditing;
} settingsKeys[ZVISION_SETTINGS_KEYS_COUNT] = {
- {"ZVision_KeyboardTurnSpeed", StateKey_KbdRotateSpeed, 5},
- {"ZVision_PanaRotateSpeed", StateKey_RotateSpeed, 540},
- {"ZVision_QSoundEnabled", StateKey_Qsound, 1},
- {"ZVision_VenusEnabled", StateKey_VenusEnable, 1},
- {"ZVision_HighQuality", StateKey_HighQuality, 1},
- {"ZVision_Platform", StateKey_Platform, 0},
- {"ZVision_InstallLevel", StateKey_InstallLevel, 0},
- {"ZVision_CountryCode", StateKey_CountryCode, 0},
- {"ZVision_CPU", StateKey_CPU, 1},
- {"ZVision_MovieCursor", StateKey_MovieCursor, 1},
- {"ZVision_NoAnimWhileTurning", StateKey_NoTurnAnim, 0},
- {"ZVision_Win958", StateKey_WIN958, 0},
- {"ZVision_ShowErrorDialogs", StateKey_ShowErrorDlg, 0},
- {"ZVision_ShowSubtitles", StateKey_Subtitles, 1},
- {"ZVision_DebugCheats", StateKey_DebugCheats, 0},
- {"ZVision_JapaneseFonts", StateKey_JapanFonts, 0},
- {"ZVision_Brightness", StateKey_Brightness, 0}
+ // Hardcoded settings
+ {"countrycode", StateKey_CountryCode, 0, false, false}, // always 0 = US, subtitles are shown for codes 0 - 4, unused
+ {"lineskipvideo", StateKey_VideoLineSkip, 0, false, false}, // video line skip, 0 = default, 1 = always, 2 = pixel double when possible, unused
+ {"installlevel", StateKey_InstallLevel, 0, false, false}, // 0 = full, checked by universe.scr
+ {"highquality", StateKey_HighQuality, -1, true, false}, // high panorama quality, unused
+ {"qsoundenabled", StateKey_Qsound, -1, true, false}, // 1 = enable QSound - TODO: not supported yet
+ {"debugcheats", StateKey_DebugCheats, -1, true, false}, // always start with the GOxxxx cheat enabled
+ // Editable settings
+ {"keyboardturnspeed", StateKey_KbdRotateSpeed, 5, false, true},
+ {"panarotatespeed", StateKey_RotateSpeed, 540, false, true}, // checked by universe.scr
+ {"noanimwhileturning", StateKey_NoTurnAnim, -1, false, true}, // toggle playing animations during pana rotation
+ {"venusenabled", StateKey_VenusEnable, -1, true, true},
+ {"subtitles", StateKey_Subtitles, -1, true, true},
+ {"mpegmovies", StateKey_MPEGMovies, -1, true, true} // Zork: Grand Inquisitor DVD hi-res MPEG movies (0 = normal, 1 = hires, 2 = disable option)
};
ZVision::ZVision(OSystem *syst, const ZVisionGameDescription *gameDesc)
: Engine(syst),
_gameDescription(gameDesc),
- _pixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0), /*RGB 565*/
+ _resourcePixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0), /* RGB 555 */
+ _screenPixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0), /* RGB 565 */
_desiredFrameTime(33), /* ~30 fps */
_clock(_system),
_scriptManager(nullptr),
@@ -95,25 +94,18 @@ ZVision::ZVision(OSystem *syst, const ZVisionGameDescription *gameDesc)
_menu(nullptr),
_searchManager(nullptr),
_textRenderer(nullptr),
- _halveDelay(false),
+ _doubleFPS(false),
_audioId(0),
- _rendDelay(2),
- _kbdVelocity(0),
+ _frameRenderDelay(2),
+ _keyboardVelocity(0),
_mouseVelocity(0),
- _videoIsPlaying(false) {
+ _videoIsPlaying(false),
+ _renderedFrameCount(0),
+ _fps(0) {
debug(1, "ZVision::ZVision");
- uint16 workingWindowWidth = (gameDesc->gameId == GID_NEMESIS) ? ZNM_WORKING_WINDOW_WIDTH : ZGI_WORKING_WINDOW_WIDTH;
- uint16 workingWindowHeight = (gameDesc->gameId == GID_NEMESIS) ? ZNM_WORKING_WINDOW_HEIGHT : ZGI_WORKING_WINDOW_HEIGHT;
- _workingWindow = Common::Rect(
- (WINDOW_WIDTH - workingWindowWidth) / 2,
- (WINDOW_HEIGHT - workingWindowHeight) / 2,
- ((WINDOW_WIDTH - workingWindowWidth) / 2) + workingWindowWidth,
- ((WINDOW_HEIGHT - workingWindowHeight) / 2) + workingWindowHeight
- );
-
- memset(_cheatBuff, 0, sizeof(_cheatBuff));
+ memset(_cheatBuffer, 0, sizeof(_cheatBuffer));
}
ZVision::~ZVision() {
@@ -124,24 +116,45 @@ ZVision::~ZVision() {
delete _cursorManager;
delete _stringManager;
delete _saveManager;
- delete _renderManager;
delete _scriptManager;
+ delete _renderManager; // should be deleted after the script manager
delete _rnd;
delete _midiManager;
+ getTimerManager()->removeTimerProc(&fpsTimerCallback);
+
// Remove all of our debug levels
DebugMan.clearAllDebugChannels();
}
void ZVision::registerDefaultSettings() {
- for (int i = 0; i < ZVISION_SETTINGS_KEYS_COUNT; i++)
- ConfMan.registerDefault(settingsKeys[i].name, settingsKeys[i].deflt);
+ for (int i = 0; i < ZVISION_SETTINGS_KEYS_COUNT; i++) {
+ if (settingsKeys[i].allowEditing) {
+ if (settingsKeys[i].defaultValue >= 0)
+ ConfMan.registerDefault(settingsKeys[i].name, settingsKeys[i].defaultValue);
+ else
+ ConfMan.registerDefault(settingsKeys[i].name, settingsKeys[i].defaultBoolValue);
+ }
+ }
+
+ ConfMan.registerDefault("originalsaveload", false);
ConfMan.registerDefault("doublefps", false);
}
void ZVision::loadSettings() {
- for (int i = 0; i < ZVISION_SETTINGS_KEYS_COUNT; i++)
- _scriptManager->setStateValue(settingsKeys[i].slot, ConfMan.getInt(settingsKeys[i].name));
+ int16 value = 0;
+ bool boolValue = false;
+
+ for (int i = 0; i < ZVISION_SETTINGS_KEYS_COUNT; i++) {
+ if (settingsKeys[i].defaultValue >= 0) {
+ value = (settingsKeys[i].allowEditing) ? ConfMan.getInt(settingsKeys[i].name) : settingsKeys[i].defaultValue;
+ } else {
+ boolValue = (settingsKeys[i].allowEditing) ? ConfMan.getBool(settingsKeys[i].name) : settingsKeys[i].defaultBoolValue;
+ value = (boolValue) ? 1 : 0;
+ }
+
+ _scriptManager->setStateValue(settingsKeys[i].slot, value);
+ }
if (getGameId() == GID_NEMESIS)
_scriptManager->setStateValue(StateKey_ExecScopeStyle, 1);
@@ -150,8 +163,15 @@ void ZVision::loadSettings() {
}
void ZVision::saveSettings() {
- for (int i = 0; i < ZVISION_SETTINGS_KEYS_COUNT; i++)
- ConfMan.setInt(settingsKeys[i].name, _scriptManager->getStateValue(settingsKeys[i].slot));
+ for (int i = 0; i < ZVISION_SETTINGS_KEYS_COUNT; i++) {
+ if (settingsKeys[i].allowEditing) {
+ if (settingsKeys[i].defaultValue >= 0)
+ ConfMan.setInt(settingsKeys[i].name, _scriptManager->getStateValue(settingsKeys[i].slot));
+ else
+ ConfMan.setBool(settingsKeys[i].name, (_scriptManager->getStateValue(settingsKeys[i].slot) == 1));
+ }
+ }
+
ConfMan.flushToDisk();
}
@@ -163,40 +183,32 @@ void ZVision::initialize() {
_searchManager->addDir("FONTS");
_searchManager->addDir("addon");
- if (_gameDescription->gameId == GID_GRANDINQUISITOR) {
- _searchManager->loadZix("INQUIS.ZIX");
- _searchManager->addPatch("C000H01Q.RAW", "C000H01Q.SRC");
- _searchManager->addPatch("CM00H01Q.RAW", "CM00H01Q.SRC");
- _searchManager->addPatch("DM00H01Q.RAW", "DM00H01Q.SRC");
- _searchManager->addPatch("E000H01Q.RAW", "E000H01Q.SRC");
- _searchManager->addPatch("EM00H50Q.RAW", "EM00H50Q.SRC");
- _searchManager->addPatch("GJNPH65P.RAW", "GJNPH65P.SRC");
- _searchManager->addPatch("GJNPH72P.RAW", "GJNPH72P.SRC");
- _searchManager->addPatch("H000H01Q.RAW", "H000H01Q.SRC");
- _searchManager->addPatch("M000H01Q.RAW", "M000H01Q.SRC");
- _searchManager->addPatch("P000H01Q.RAW", "P000H01Q.SRC");
- _searchManager->addPatch("Q000H01Q.RAW", "Q000H01Q.SRC");
- _searchManager->addPatch("SW00H01Q.RAW", "SW00H01Q.SRC");
- _searchManager->addPatch("T000H01Q.RAW", "T000H01Q.SRC");
- _searchManager->addPatch("U000H01Q.RAW", "U000H01Q.SRC");
- } else if (_gameDescription->gameId == GID_NEMESIS)
- _searchManager->loadZix("NEMESIS.ZIX");
-
- initGraphics(WINDOW_WIDTH, WINDOW_HEIGHT, true, &_pixelFormat);
+ if (getGameId() == GID_GRANDINQUISITOR) {
+ if (!_searchManager->loadZix("INQUIS.ZIX"))
+ error("Unable to load file INQUIS.ZIX");
+ } else if (getGameId() == GID_NEMESIS) {
+ if (!_searchManager->loadZix("NEMESIS.ZIX")) {
+ // The game might not be installed, try MEDIUM.ZIX instead
+ if (!_searchManager->loadZix("ZNEMSCR/MEDIUM.ZIX"))
+ error("Unable to load the file ZNEMSCR/MEDIUM.ZIX");
+ }
+ }
+
+ initScreen();
// Register random source
_rnd = new Common::RandomSource("zvision");
// Create managers
_scriptManager = new ScriptManager(this);
- _renderManager = new RenderManager(this, WINDOW_WIDTH, WINDOW_HEIGHT, _workingWindow, _pixelFormat);
+ _renderManager = new RenderManager(this, WINDOW_WIDTH, WINDOW_HEIGHT, _workingWindow, _resourcePixelFormat, _doubleFPS);
_saveManager = new SaveManager(this);
_stringManager = new StringManager(this);
- _cursorManager = new CursorManager(this, &_pixelFormat);
+ _cursorManager = new CursorManager(this, _resourcePixelFormat);
_textRenderer = new TextRenderer(this);
_midiManager = new MidiManager();
- if (_gameDescription->gameId == GID_GRANDINQUISITOR)
+ if (getGameId() == GID_GRANDINQUISITOR)
_menu = new MenuZGI(this);
else
_menu = new MenuNemesis(this);
@@ -204,17 +216,27 @@ void ZVision::initialize() {
// Initialize the managers
_cursorManager->initialize();
_scriptManager->initialize();
- _stringManager->initialize(_gameDescription->gameId);
+ _stringManager->initialize(getGameId());
registerDefaultSettings();
loadSettings();
+#ifndef USE_MPEG2
+ // libmpeg2 not loaded, disable the MPEG2 movies option
+ _scriptManager->setStateValue(StateKey_MPEGMovies, 2);
+#endif
+
// Create debugger console. It requires GFX to be initialized
_console = new Console(this);
- _halveDelay = ConfMan.getBool("doublefps");
+ _doubleFPS = ConfMan.getBool("doublefps");
+
+ // Initialize FPS timer callback
+ getTimerManager()->installTimerProc(&fpsTimerCallback, 1000000, this, "zvisionFPS");
}
+extern const FontStyle getSystemFont(int fontIndex);
+
Common::Error ZVision::run() {
initialize();
@@ -222,6 +244,68 @@ Common::Error ZVision::run() {
if (ConfMan.hasKey("save_slot"))
_saveManager->loadGame(ConfMan.getInt("save_slot"));
+ bool foundAllFonts = true;
+
+ // Before starting, make absolutely sure that the user has copied the needed fonts
+ for (int i = 0; i < FONT_COUNT; i++) {
+ FontStyle curFont = getSystemFont(i);
+ Common::String freeFontBoldItalic = Common::String("Bold") + curFont.freeFontItalicName;
+
+ const char *fontSuffixes[4] = { "", "bd", "i", "bi" };
+ const char *freeFontSuffixes[4] = { "", "Bold", curFont.freeFontItalicName, freeFontBoldItalic.c_str() };
+ const char *liberationFontSuffixes[4] = { "-Regular", "-Bold", "-Italic", "-BoldItalic" };
+
+ for (int j = 0; j < 4; j++) {
+ Common::String fontName = curFont.fontBase;
+ if (fontName == "censcbk" && j > 0)
+ fontName = "schlbk";
+ fontName += fontSuffixes[j];
+ fontName += ".ttf";
+
+ if (fontName == "schlbkbd.ttf")
+ fontName = "schlbkb.ttf";
+ if (fontName == "garabi.ttf")
+ continue;
+ if (fontName == "garai.ttf")
+ fontName = "garait.ttf";
+
+ Common::String freeFontName = curFont.freeFontBase;
+ freeFontName += freeFontSuffixes[j];
+ freeFontName += ".ttf";
+
+ Common::String liberationFontName = curFont.liberationFontBase;
+ liberationFontName += liberationFontSuffixes[j];
+ liberationFontName += ".ttf";
+
+ if (!Common::File::exists(fontName) && !_searchManager->hasFile(fontName) &&
+ !Common::File::exists(liberationFontName) && !_searchManager->hasFile(liberationFontName) &&
+ !Common::File::exists(freeFontName) && !_searchManager->hasFile(freeFontName)) {
+ foundAllFonts = false;
+ break;
+ }
+ }
+
+ if (!foundAllFonts)
+ break;
+ }
+
+ if (!foundAllFonts) {
+ GUI::MessageDialog dialog(
+ "Before playing this game, you'll need to copy the required "
+ "fonts into ScummVM's extras directory, or into the game directory. "
+ "On Windows, you'll need the following font files from the Windows "
+ "font directory: Times New Roman, Century Schoolbook, Garamond, "
+ "Courier New and Arial. Alternatively, you can download the "
+ "Liberation Fonts or the GNU FreeFont package. You'll need all the "
+ "fonts from the font package you choose, i.e., LiberationMono, "
+ "LiberationSans and LiberationSerif, or FreeMono, FreeSans and "
+ "FreeSerif respectively."
+ );
+ dialog.runModal();
+ quitGame();
+ return Common::kUnknownError;
+ }
+
// Main loop
while (!shouldQuit()) {
_clock.update();
@@ -231,106 +315,42 @@ Common::Error ZVision::run() {
_cursorManager->setItemID(_scriptManager->getStateValue(StateKey_InventoryItem));
processEvents();
- updateRotation();
+ _renderManager->updateRotation();
- // Call _renderManager->update() first so the background renders
- // before anything that puzzles/controls will render
_scriptManager->update(deltaTime);
_menu->process(deltaTime);
// Render the backBuffer to the screen
- _renderManager->prepareBkg();
+ _renderManager->prepareBackground();
_renderManager->renderMenuToScreen();
_renderManager->processSubs(deltaTime);
- _renderManager->renderBackbufferToScreen();
+ _renderManager->renderSceneToScreen();
// Update the screen
- if (_rendDelay <= 0)
+ if (canRender()) {
_system->updateScreen();
- else
- _rendDelay--;
+ _renderedFrameCount++;
+ } else {
+ _frameRenderDelay--;
+ }
// Calculate the frame delay based off a desired frame time
int delay = _desiredFrameTime - int32(_system->getMillis() - currentTime);
// Ensure non-negative
delay = delay < 0 ? 0 : delay;
- if (_halveDelay)
- delay >>= 1;
- _system->delayMillis(delay);
- }
- return Common::kNoError;
-}
-
-bool ZVision::askQuestion(const Common::String &str) {
- uint16 msgid = _renderManager->createSubArea();
- _renderManager->updateSubArea(msgid, str);
- _renderManager->processSubs(0);
- _renderManager->renderBackbufferToScreen();
- _clock.stop();
-
- int result = 0;
-
- while (result == 0) {
- Common::Event evnt;
- while (_eventMan->pollEvent(evnt)) {
- if (evnt.type == Common::EVENT_KEYDOWN) {
- switch (evnt.kbd.keycode) {
- case Common::KEYCODE_y:
- result = 2;
- break;
- case Common::KEYCODE_n:
- result = 1;
- break;
- default:
- break;
- }
- }
+ if (_doubleFPS) {
+ delay >>= 1;
}
- _system->updateScreen();
- if (_halveDelay)
- _system->delayMillis(33);
- else
- _system->delayMillis(66);
- }
- _renderManager->deleteSubArea(msgid);
- _clock.start();
- return result == 2;
-}
-void ZVision::delayedMessage(const Common::String &str, uint16 milsecs) {
- uint16 msgid = _renderManager->createSubArea();
- _renderManager->updateSubArea(msgid, str);
- _renderManager->processSubs(0);
- _renderManager->renderBackbufferToScreen();
- _clock.stop();
-
- uint32 stopTime = _system->getMillis() + milsecs;
- while (_system->getMillis() < stopTime) {
- Common::Event evnt;
- while (_eventMan->pollEvent(evnt)) {
- if (evnt.type == Common::EVENT_KEYDOWN &&
- (evnt.kbd.keycode == Common::KEYCODE_SPACE ||
- evnt.kbd.keycode == Common::KEYCODE_RETURN ||
- evnt.kbd.keycode == Common::KEYCODE_ESCAPE))
- break;
+ if (canSaveGameStateCurrently() && shouldPerformAutoSave(_saveManager->getLastSaveTime())) {
+ _saveManager->autoSave();
}
- _system->updateScreen();
- if (_halveDelay)
- _system->delayMillis(33);
- else
- _system->delayMillis(66);
+
+ _system->delayMillis(delay);
}
- _renderManager->deleteSubArea(msgid);
- _clock.start();
-}
-void ZVision::timedMessage(const Common::String &str, uint16 milsecs) {
- uint16 msgid = _renderManager->createSubArea();
- _renderManager->updateSubArea(msgid, str);
- _renderManager->processSubs(0);
- _renderManager->renderBackbufferToScreen();
- _renderManager->deleteSubArea(msgid, milsecs);
+ return Common::kNoError;
}
void ZVision::pauseEngineIntern(bool pause) {
@@ -347,200 +367,50 @@ Common::String ZVision::generateSaveFileName(uint slot) {
return Common::String::format("%s.%03u", _targetName.c_str(), slot);
}
-Common::String ZVision::generateAutoSaveFileName() {
- return Common::String::format("%s.auto", _targetName.c_str());
-}
-
void ZVision::setRenderDelay(uint delay) {
- _rendDelay = delay;
+ _frameRenderDelay = delay;
}
bool ZVision::canRender() {
- return _rendDelay <= 0;
+ return _frameRenderDelay <= 0;
}
-void ZVision::updateRotation() {
- int16 _velocity = _mouseVelocity + _kbdVelocity;
-
- if (_halveDelay)
- _velocity /= 2;
-
- if (_velocity) {
- RenderTable::RenderState renderState = _renderManager->getRenderTable()->getRenderState();
- if (renderState == RenderTable::PANORAMA) {
- int16 startPosition = _scriptManager->getStateValue(StateKey_ViewPos);
-
- int16 newPosition = startPosition + (_renderManager->getRenderTable()->getPanoramaReverse() ? -_velocity : _velocity);
-
- int16 zeroPoint = _renderManager->getRenderTable()->getPanoramaZeroPoint();
- if (startPosition >= zeroPoint && newPosition < zeroPoint)
- _scriptManager->setStateValue(StateKey_Rounds, _scriptManager->getStateValue(StateKey_Rounds) - 1);
- if (startPosition <= zeroPoint && newPosition > zeroPoint)
- _scriptManager->setStateValue(StateKey_Rounds, _scriptManager->getStateValue(StateKey_Rounds) + 1);
-
- int16 screenWidth = _renderManager->getBkgSize().x;
- if (screenWidth)
- newPosition %= screenWidth;
-
- if (newPosition < 0)
- newPosition += screenWidth;
-
- _renderManager->setBackgroundPosition(newPosition);
- } else if (renderState == RenderTable::TILT) {
- int16 startPosition = _scriptManager->getStateValue(StateKey_ViewPos);
-
- int16 newPosition = startPosition + _velocity;
-
- int16 screenHeight = _renderManager->getBkgSize().y;
- int16 tiltGap = _renderManager->getRenderTable()->getTiltGap();
-
- if (newPosition >= (screenHeight - tiltGap))
- newPosition = screenHeight - tiltGap;
- if (newPosition <= tiltGap)
- newPosition = tiltGap;
-
- _renderManager->setBackgroundPosition(newPosition);
- }
- }
+GUI::Debugger *ZVision::getDebugger() {
+ return _console;
}
-void ZVision::checkBorders() {
- RenderTable::RenderState renderState = _renderManager->getRenderTable()->getRenderState();
- if (renderState == RenderTable::PANORAMA) {
- int16 startPosition = _scriptManager->getStateValue(StateKey_ViewPos);
-
- int16 newPosition = startPosition;
-
- int16 screenWidth = _renderManager->getBkgSize().x;
-
- if (screenWidth)
- newPosition %= screenWidth;
-
- if (newPosition < 0)
- newPosition += screenWidth;
+void ZVision::syncSoundSettings() {
+ Engine::syncSoundSettings();
- if (startPosition != newPosition)
- _renderManager->setBackgroundPosition(newPosition);
- } else if (renderState == RenderTable::TILT) {
- int16 startPosition = _scriptManager->getStateValue(StateKey_ViewPos);
-
- int16 newPosition = startPosition;
-
- int16 screenHeight = _renderManager->getBkgSize().y;
- int16 tiltGap = _renderManager->getRenderTable()->getTiltGap();
-
- if (newPosition >= (screenHeight - tiltGap))
- newPosition = screenHeight - tiltGap;
- if (newPosition <= tiltGap)
- newPosition = tiltGap;
-
- if (startPosition != newPosition)
- _renderManager->setBackgroundPosition(newPosition);
- }
+ _scriptManager->setStateValue(StateKey_Subtitles, ConfMan.getBool("subtitles") ? 1 : 0);
}
-void ZVision::rotateTo(int16 _toPos, int16 _time) {
- if (_renderManager->getRenderTable()->getRenderState() != RenderTable::PANORAMA)
- return;
-
- if (_time == 0)
- _time = 1;
-
- int32 maxX = _renderManager->getBkgSize().x;
- int32 curX = _renderManager->getCurrentBackgroundOffset();
- int32 dx = 0;
-
- if (curX == _toPos)
- return;
-
- if (curX > _toPos) {
- if (curX - _toPos > maxX / 2)
- dx = (_toPos + (maxX - curX)) / _time;
- else
- dx = -(curX - _toPos) / _time;
- } else {
- if (_toPos - curX > maxX / 2)
- dx = -((maxX - _toPos) + curX) / _time;
- else
- dx = (_toPos - curX) / _time;
- }
-
- _clock.stop();
-
- for (int16 i = 0; i <= _time; i++) {
- if (i == _time)
- curX = _toPos;
- else
- curX += dx;
-
- if (curX < 0)
- curX = maxX - curX;
- else if (curX >= maxX)
- curX %= maxX;
-
- _renderManager->setBackgroundPosition(curX);
-
- _renderManager->prepareBkg();
- _renderManager->renderBackbufferToScreen();
-
- _system->updateScreen();
-
- _system->delayMillis(500 / _time);
- }
-
- _clock.start();
-}
-
-void ZVision::menuBarEnable(uint16 menus) {
- if (_menu)
- _menu->setEnable(menus);
-}
-
-uint16 ZVision::getMenuBarEnable() {
- if (_menu)
- return _menu->getEnable();
- return 0;
-}
-
-bool ZVision::ifQuit() {
- if (askQuestion(_stringManager->getTextLine(StringManager::ZVISION_STR_EXITPROMT))) {
- quitGame();
- return true;
- }
- return false;
+void ZVision::fpsTimerCallback(void *refCon) {
+ ((ZVision *)refCon)->fpsTimer();
}
-void ZVision::pushKeyToCheatBuf(uint8 key) {
- for (int i = 0; i < KEYBUF_SIZE - 1; i++)
- _cheatBuff[i] = _cheatBuff[i + 1];
-
- _cheatBuff[KEYBUF_SIZE - 1] = key;
+void ZVision::fpsTimer() {
+ _fps = _renderedFrameCount;
+ _renderedFrameCount = 0;
}
-bool ZVision::checkCode(const char *code) {
- int codeLen = strlen(code);
-
- if (codeLen > KEYBUF_SIZE)
- return false;
-
- for (int i = 0; i < codeLen; i++)
- if (code[i] != _cheatBuff[KEYBUF_SIZE - codeLen + i] && code[i] != '?')
- return false;
+void ZVision::initScreen() {
+ uint16 workingWindowWidth = (getGameId() == GID_NEMESIS) ? ZNM_WORKING_WINDOW_WIDTH : ZGI_WORKING_WINDOW_WIDTH;
+ uint16 workingWindowHeight = (getGameId() == GID_NEMESIS) ? ZNM_WORKING_WINDOW_HEIGHT : ZGI_WORKING_WINDOW_HEIGHT;
+ _workingWindow = Common::Rect(
+ (WINDOW_WIDTH - workingWindowWidth) / 2,
+ (WINDOW_HEIGHT - workingWindowHeight) / 2,
+ ((WINDOW_WIDTH - workingWindowWidth) / 2) + workingWindowWidth,
+ ((WINDOW_HEIGHT - workingWindowHeight) / 2) + workingWindowHeight
+ );
- return true;
+ initGraphics(WINDOW_WIDTH, WINDOW_HEIGHT, true, &_screenPixelFormat);
}
-uint8 ZVision::getBufferedKey(uint8 pos) {
- if (pos >= KEYBUF_SIZE)
- return 0;
- else
- return _cheatBuff[KEYBUF_SIZE - pos - 1];
-}
+void ZVision::initHiresScreen() {
+ _renderManager->upscaleRect(_workingWindow);
-void ZVision::showDebugMsg(const Common::String &msg, int16 delay) {
- uint16 msgid = _renderManager->createSubArea();
- _renderManager->updateSubArea(msgid, msg);
- _renderManager->deleteSubArea(msgid, delay);
+ initGraphics(HIRES_WINDOW_WIDTH, HIRES_WINDOW_HEIGHT, true, &_screenPixelFormat);
}
} // End of namespace ZVision
diff --git a/engines/zvision/zvision.h b/engines/zvision/zvision.h
index 78c1c824a1..4c948faaa4 100644
--- a/engines/zvision/zvision.h
+++ b/engines/zvision/zvision.h
@@ -24,7 +24,6 @@
#ifndef ZVISION_ZVISION_H
#define ZVISION_ZVISION_H
-#include "zvision/detection.h"
#include "zvision/core/clock.h"
#include "zvision/file/search_manager.h"
@@ -41,6 +40,16 @@ namespace Video {
class VideoDecoder;
}
+/**
+ * This is the namespace of the ZVision engine.
+ *
+ * Status of this engine: complete
+ *
+ * Games using this engine:
+ * - Zork Nemesis: The Forbidden Lands
+ * - Zork: Grand Inquisitor
+ *
+ */
namespace ZVision {
struct ZVisionGameDescription;
@@ -56,6 +65,33 @@ class TextRenderer;
class Subtitle;
class MidiManager;
+enum {
+ WINDOW_WIDTH = 640,
+ WINDOW_HEIGHT = 480,
+
+ HIRES_WINDOW_WIDTH = 800,
+ HIRES_WINDOW_HEIGHT = 600,
+
+ // Zork Nemesis working window sizes
+ ZNM_WORKING_WINDOW_WIDTH = 512,
+ ZNM_WORKING_WINDOW_HEIGHT = 320,
+
+ // ZGI working window sizes
+ ZGI_WORKING_WINDOW_WIDTH = 640,
+ ZGI_WORKING_WINDOW_HEIGHT = 344,
+
+ ROTATION_SCREEN_EDGE_OFFSET = 60,
+ MAX_ROTATION_SPEED = 400, // Pixels per second
+
+ KEYBUF_SIZE = 20
+};
+
+enum ZVisionGameId {
+ GID_NONE = 0,
+ GID_NEMESIS = 1,
+ GID_GRANDINQUISITOR = 2
+};
+
class ZVision : public Engine {
public:
ZVision(OSystem *syst, const ZVisionGameDescription *gameDesc);
@@ -68,27 +104,10 @@ public:
* edges of this Rectangle
*/
Common::Rect _workingWindow;
- const Graphics::PixelFormat _pixelFormat;
+ const Graphics::PixelFormat _resourcePixelFormat;
+ const Graphics::PixelFormat _screenPixelFormat;
private:
- enum {
- WINDOW_WIDTH = 640,
- WINDOW_HEIGHT = 480,
-
- // Zork nemesis working window sizes
- ZNM_WORKING_WINDOW_WIDTH = 512,
- ZNM_WORKING_WINDOW_HEIGHT = 320,
-
- // ZGI working window sizes
- ZGI_WORKING_WINDOW_WIDTH = 640,
- ZGI_WORKING_WINDOW_HEIGHT = 344,
-
- ROTATION_SCREEN_EDGE_OFFSET = 60,
- MAX_ROTATION_SPEED = 400, // Pixels per second
-
- KEYBUF_SIZE = 20
- };
-
Console *_console;
const ZVisionGameDescription *_gameDescription;
@@ -101,12 +120,12 @@ private:
ScriptManager *_scriptManager;
RenderManager *_renderManager;
CursorManager *_cursorManager;
- SaveManager *_saveManager;
StringManager *_stringManager;
- MenuHandler *_menu;
SearchManager *_searchManager;
TextRenderer *_textRenderer;
MidiManager *_midiManager;
+ SaveManager *_saveManager;
+ MenuHandler *_menu;
// Clock
Clock _clock;
@@ -117,19 +136,24 @@ private:
// To prevent allocation every time we process events
Common::Event _event;
- int _rendDelay;
+ int _frameRenderDelay;
+ int _renderedFrameCount;
+ int _fps;
int16 _mouseVelocity;
- int16 _kbdVelocity;
- bool _halveDelay;
+ int16 _keyboardVelocity;
+ bool _doubleFPS;
bool _videoIsPlaying;
- uint8 _cheatBuff[KEYBUF_SIZE];
+ uint8 _cheatBuffer[KEYBUF_SIZE];
+
public:
- uint32 getFeatures() const;
- Common::Language getLanguage() const;
Common::Error run();
void pauseEngineIntern(bool pause);
+ ZVisionGameId getGameId() const;
+ Common::Language getLanguage() const;
+ uint32 getFeatures() const;
+
ScriptManager *getScriptManager() const {
return _scriptManager;
}
@@ -154,15 +178,33 @@ public:
MidiManager *getMidiManager() const {
return _midiManager;
}
+ MenuHandler *getMenuHandler() const {
+ return _menu;
+ }
+
Common::RandomSource *getRandomSource() const {
return _rnd;
}
- ZVisionGameId getGameId() const {
- return _gameDescription->gameId;
+ int16 getKeyboardVelocity() const {
+ return _keyboardVelocity;
+ }
+ int16 getMouseVelocity() const {
+ return _mouseVelocity;
}
uint8 getZvisionKey(Common::KeyCode scummKeyCode);
+ void startClock() {
+ _clock.start();
+ }
+
+ void stopClock() {
+ _clock.stop();
+ }
+
+ void initScreen();
+ void initHiresScreen();
+
/**
* Play a video until it is finished. This is a blocking call. It will call
* _clock.stop() when the video starts and _clock.start() when the video finishes.
@@ -175,35 +217,31 @@ public:
void playVideo(Video::VideoDecoder &videoDecoder, const Common::Rect &destRect = Common::Rect(0, 0, 0, 0), bool skippable = true, Subtitle *sub = NULL);
Video::VideoDecoder *loadAnimation(const Common::String &fileName);
- void rotateTo(int16 to, int16 time);
-
Common::String generateSaveFileName(uint slot);
- Common::String generateAutoSaveFileName();
-
- bool askQuestion(const Common::String &str);
- void delayedMessage(const Common::String &str, uint16 milsecs);
- void timedMessage(const Common::String &str, uint16 milsecs);
void setRenderDelay(uint);
bool canRender();
+ static void fpsTimerCallback(void *refCon);
+ void fpsTimer();
+ int getFPS() const {
+ return _fps;
+ }
+
+ GUI::Debugger *getDebugger();
+ void syncSoundSettings();
void loadSettings();
void saveSettings();
- void menuBarEnable(uint16 menus);
- uint16 getMenuBarEnable();
-
bool ifQuit();
- void checkBorders();
- void showDebugMsg(const Common::String &msg, int16 delay = 3000);
-
// Engine features
bool hasFeature(EngineFeature f) const;
bool canLoadGameStateCurrently();
bool canSaveGameStateCurrently();
Common::Error loadGameState(int slot);
Common::Error saveGameState(int slot, const Common::String &desc);
+
private:
void initialize();
void initFonts();
@@ -214,7 +252,6 @@ private:
void processEvents();
void onMouseMove(const Common::Point &pos);
- void updateRotation();
void registerDefaultSettings();
void shortKeys(Common::Event);
diff --git a/graphics/fonts/ttf.cpp b/graphics/fonts/ttf.cpp
index ba57613601..dc7335f1c2 100644
--- a/graphics/fonts/ttf.cpp
+++ b/graphics/fonts/ttf.cpp
@@ -474,11 +474,11 @@ bool TTFFont::cacheGlyph(Glyph &glyph, uint32 chr) const {
switch (bitmap.pixel_mode) {
case FT_PIXEL_MODE_MONO:
- for (int y = 0; y < bitmap.rows; ++y) {
+ for (int y = 0; y < (int)bitmap.rows; ++y) {
const uint8 *curSrc = src;
uint8 mask = 0;
- for (int x = 0; x < bitmap.width; ++x) {
+ for (int x = 0; x < (int)bitmap.width; ++x) {
if ((x % 8) == 0)
mask = *curSrc++;
@@ -494,7 +494,7 @@ bool TTFFont::cacheGlyph(Glyph &glyph, uint32 chr) const {
break;
case FT_PIXEL_MODE_GRAY:
- for (int y = 0; y < bitmap.rows; ++y) {
+ for (int y = 0; y < (int)bitmap.rows; ++y) {
memcpy(dst, src, bitmap.width);
dst += glyph.image.pitch;
src += srcPitch;
diff --git a/gui/Tooltip.cpp b/gui/Tooltip.cpp
index e5f06bcafe..ba313ee34f 100644
--- a/gui/Tooltip.cpp
+++ b/gui/Tooltip.cpp
@@ -40,6 +40,8 @@ Tooltip::Tooltip() :
void Tooltip::setup(Dialog *parent, Widget *widget, int x, int y) {
assert(widget->hasTooltip());
+ _parent = parent;
+
_maxWidth = g_gui.xmlEval()->getVar("Globals.Tooltip.MaxWidth", 100);
_xdelta = g_gui.xmlEval()->getVar("Globals.Tooltip.XDelta", 0);
_ydelta = g_gui.xmlEval()->getVar("Globals.Tooltip.YDelta", 0);
diff --git a/gui/Tooltip.h b/gui/Tooltip.h
index f83fc40966..58b6d8a429 100644
--- a/gui/Tooltip.h
+++ b/gui/Tooltip.h
@@ -32,6 +32,9 @@ namespace GUI {
class Widget;
class Tooltip : public Dialog {
+private:
+ Dialog *_parent;
+
public:
Tooltip();
@@ -39,12 +42,30 @@ public:
void drawDialog();
protected:
- virtual void handleMouseDown(int x, int y, int button, int clickCount) { close(); }
- virtual void handleMouseUp(int x, int y, int button, int clickCount) { close(); }
- virtual void handleMouseWheel(int x, int y, int direction) { close(); }
- virtual void handleKeyDown(Common::KeyState state) { close(); }
- virtual void handleKeyUp(Common::KeyState state) { close(); }
- virtual void handleMouseMoved(int x, int y, int button) { close(); }
+ virtual void handleMouseDown(int x, int y, int button, int clickCount) {
+ close();
+ _parent->handleMouseDown(x + (getAbsX() - _parent->getAbsX()), y + (getAbsY() - _parent->getAbsY()), button, clickCount);
+ }
+ virtual void handleMouseUp(int x, int y, int button, int clickCount) {
+ close();
+ _parent->handleMouseUp(x + (getAbsX() - _parent->getAbsX()), y + (getAbsY() - _parent->getAbsY()), button, clickCount);
+ }
+ virtual void handleMouseWheel(int x, int y, int direction) {
+ close();
+ _parent->handleMouseWheel(x + (getAbsX() - _parent->getAbsX()), y + (getAbsX() - _parent->getAbsX()), direction);
+ }
+ virtual void handleKeyDown(Common::KeyState state) {
+ close();
+ _parent->handleKeyDown(state);
+ }
+ virtual void handleKeyUp(Common::KeyState state) {
+ close();
+ _parent->handleKeyUp(state);
+ }
+ virtual void handleMouseMoved(int x, int y, int button) {
+ close();
+ _parent->handleMouseMoved(x + (getAbsX() - _parent->getAbsX()), y + (getAbsY() - _parent->getAbsY()), button);
+ }
int _maxWidth;
int _xdelta, _ydelta;
diff --git a/gui/about.cpp b/gui/about.cpp
index b25efc1cd0..daec2b7e48 100644
--- a/gui/about.cpp
+++ b/gui/about.cpp
@@ -57,7 +57,7 @@ enum {
static const char *copyright_text[] = {
"",
-"C0""Copyright (C) 2001-2014 The ScummVM Team",
+"C0""Copyright (C) 2001-2015 The ScummVM Team",
"C0""http://www.scummvm.org",
"",
"C0""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 binary.",
diff --git a/gui/credits.h b/gui/credits.h
index 5b33797a63..7ae12bf599 100644
--- a/gui/credits.h
+++ b/gui/credits.h
@@ -322,8 +322,10 @@ static const char *credits[] = {
"C0""Einar Johan T. S\370m\345en",
"C0""Tobia Tesan",
"",
-"C1""ZVision",
+"C1""Z-Vision",
"C0""Adrian Astley",
+"C0""Filippos Karapetis",
+"C0""Anton Yarcev",
"",
"",
"C1""Backend Teams",
@@ -580,7 +582,6 @@ static const char *credits[] = {
"C1""German",
"C0""Simon Sawatzki",
"C0""Lothar Serra Mari",
-"C2""(retired)",
"",
"C1""Hungarian",
"C0""Alex Bevilacqua",
@@ -630,6 +631,18 @@ static const char *credits[] = {
"C0""Alejandro G\363mez de la Mu\361oza",
"C2""Soltys Spanish translation",
"",
+"C1""CGE2",
+"A0""Arnaud Boutonne",
+"C0""Arnaud Boutonn\351",
+"C2""Sfinx English translation",
+"C0""Thierry Crozat",
+"C2""Sfinx English translation",
+"A0""Peter Bozso",
+"C0""Peter Bozs\363",
+"C2""Sfinx English translation editor",
+"C0""Ryan Clark",
+"C2""Sfinx English translation editor",
+"",
"C1""Drascula",
"C0""Thierry Crozat",
"C2""Improve French translation",
@@ -680,6 +693,8 @@ static const char *credits[] = {
"C2""Several Pegasus Prime patches",
"C0""Andreas Karlsson",
"C2""Initial port for SymbianOS",
+"C0""Stefan Kristiansson",
+"C2""Initial work on SDL2 support",
"C0""Claudio Matsuoka",
"C2""Daily Linux builds",
"C0""Thomas Mayer",
@@ -830,7 +845,7 @@ static const char *credits[] = {
"C0""James Woodcock",
"C2""Soundtrack enhancements",
"C0""Anton Yartsev",
-"C2""For the original re-implementation of the ZVision engine",
+"C2""For the original re-implementation of the Z-Vision engine",
"C0""Tony Warriner and everyone at Revolution Software Ltd. for sharing with us the source of some of their brilliant games, allowing us to release Beneath a Steel Sky as freeware... and generally being supportive above and beyond the call of duty.",
"C0""",
"C0""John Passfield and Steve Stamatiadis for sharing the source of their classic title, Flight of the Amazon Queen and also being incredibly supportive.",
diff --git a/gui/debugger.cpp b/gui/debugger.cpp
index 216bd626fe..466681e89d 100644
--- a/gui/debugger.cpp
+++ b/gui/debugger.cpp
@@ -522,11 +522,25 @@ struct ArchiveMemberLess {
bool Debugger::cmdMd5(int argc, const char **argv) {
if (argc < 2) {
- debugPrintf("md5 <filename | pattern>\n");
+ debugPrintf("md5 [-n length] <filename | pattern>\n");
} else {
+ uint32 length = 0;
+ uint paramOffset = 0;
+
+ // If the user supplied an -n parameter, set the bytes to read
+ if (!strcmp(argv[1], "-n")) {
+ // Make sure that we have at least two more parameters
+ if (argc < 4) {
+ debugPrintf("md5 [-n length] <filename | pattern>\n");
+ return true;
+ }
+ length = atoi(argv[2]);
+ paramOffset = 2;
+ }
+
// Assume that spaces are part of a single filename.
- Common::String filename = argv[1];
- for (int i = 2; i < argc; i++) {
+ Common::String filename = argv[1 + paramOffset];
+ for (int i = 2 + paramOffset; i < argc; i++) {
filename = filename + " " + argv[i];
}
Common::ArchiveMemberList list;
@@ -536,9 +550,9 @@ bool Debugger::cmdMd5(int argc, const char **argv) {
} else {
sort(list.begin(), list.end(), ArchiveMemberLess());
for (Common::ArchiveMemberList::iterator iter = list.begin(); iter != list.end(); ++iter) {
- Common::ReadStream *stream = (*iter)->createReadStream();
- Common::String md5 = Common::computeStreamMD5AsString(*stream, 0);
- debugPrintf("%s %s\n", md5.c_str(), (*iter)->getDisplayName().c_str());
+ Common::SeekableReadStream *stream = (*iter)->createReadStream();
+ Common::String md5 = Common::computeStreamMD5AsString(*stream, length);
+ debugPrintf("%s %s %d\n", md5.c_str(), (*iter)->getDisplayName().c_str(), stream->size());
delete stream;
}
}
@@ -548,11 +562,25 @@ bool Debugger::cmdMd5(int argc, const char **argv) {
bool Debugger::cmdMd5Mac(int argc, const char **argv) {
if (argc < 2) {
- debugPrintf("md5mac <base filename>\n");
+ debugPrintf("md5mac [-n length] <base filename>\n");
} else {
+ uint32 length = 0;
+ uint paramOffset = 0;
+
+ // If the user supplied an -n parameter, set the bytes to read
+ if (!strcmp(argv[1], "-n")) {
+ // Make sure that we have at least two more parameters
+ if (argc < 4) {
+ debugPrintf("md5mac [-n length] <base filename>\n");
+ return true;
+ }
+ length = atoi(argv[2]);
+ paramOffset = 2;
+ }
+
// Assume that spaces are part of a single filename.
- Common::String filename = argv[1];
- for (int i = 2; i < argc; i++) {
+ Common::String filename = argv[1 + paramOffset];
+ for (int i = 2 + paramOffset; i < argc; i++) {
filename = filename + " " + argv[i];
}
Common::MacResManager macResMan;
@@ -568,13 +596,13 @@ bool Debugger::cmdMd5Mac(int argc, const char **argv) {
} else {
// The resource fork is probably the most relevant one.
if (macResMan.hasResFork()) {
- Common::String md5 = macResMan.computeResForkMD5AsString(0);
- debugPrintf("%s %s (resource)\n", md5.c_str(), macResMan.getBaseFileName().c_str());
+ Common::String md5 = macResMan.computeResForkMD5AsString(length);
+ debugPrintf("%s %s (resource) %d\n", md5.c_str(), macResMan.getBaseFileName().c_str(), macResMan.getResForkDataSize());
}
if (macResMan.hasDataFork()) {
- Common::ReadStream *stream = macResMan.getDataFork();
- Common::String md5 = Common::computeStreamMD5AsString(*stream, 0);
- debugPrintf("%s %s (data)\n", md5.c_str(), macResMan.getBaseFileName().c_str());
+ Common::SeekableReadStream *stream = macResMan.getDataFork();
+ Common::String md5 = Common::computeStreamMD5AsString(*stream, length);
+ debugPrintf("%s %s (data) %d\n", md5.c_str(), macResMan.getBaseFileName().c_str(), stream->size());
}
}
macResMan.close();
diff --git a/gui/dialog.cpp b/gui/dialog.cpp
index fa4e508494..315c24e9bf 100644
--- a/gui/dialog.cpp
+++ b/gui/dialog.cpp
@@ -219,7 +219,7 @@ void Dialog::handleMouseWheel(int x, int y, int direction) {
if (!w)
w = _focusedWidget;
if (w)
- w->handleMouseWheel(x, y, direction);
+ w->handleMouseWheel(x - (w->getAbsX() - _x), y - (w->getAbsY() - _y), direction);
}
void Dialog::handleKeyDown(Common::KeyState state) {
diff --git a/gui/launcher.cpp b/gui/launcher.cpp
index 4496c11a3d..5abf0aba26 100644
--- a/gui/launcher.cpp
+++ b/gui/launcher.cpp
@@ -1156,9 +1156,9 @@ void LauncherDialog::updateButtons() {
_loadButton->setEnabled(en);
_loadButton->draw();
}
- switchButtonsText(_addButton, "~A~dd Game...", "Mass Add...");
+ switchButtonsText(_addButton, "~A~dd Game...", _s("Mass Add..."));
#ifdef ENABLE_EVENTRECORDER
- switchButtonsText(_loadButton, "~L~oad...", "Record...");
+ switchButtonsText(_loadButton, "~L~oad...", _s("Record..."));
#endif
}
diff --git a/gui/options.cpp b/gui/options.cpp
index 726b89d437..ba247e5f15 100644
--- a/gui/options.cpp
+++ b/gui/options.cpp
@@ -445,11 +445,9 @@ void OptionsDialog::close() {
if (_oplPopUp) {
if (_enableAudioSettings) {
- const OPL::Config::EmulatorDescription *ed = OPL::Config::getAvailable();
- while (ed->name && ed->id != (int)_oplPopUp->getSelectedTag())
- ++ed;
+ const OPL::Config::EmulatorDescription *ed = OPL::Config::findDriver(_oplPopUp->getSelectedTag());
- if (ed->name)
+ if (ed)
ConfMan.set("opl_driver", ed->name, _domain);
else
ConfMan.removeKey("opl_driver", _domain);
diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp
index 339ec95c50..a333c5fe57 100644
--- a/gui/saveload-dialog.cpp
+++ b/gui/saveload-dialog.cpp
@@ -654,16 +654,25 @@ void SaveLoadChooserGrid::open() {
// In case there was a gap found use the slot.
if (lastSlot + 1 < curSlot) {
- _nextFreeSaveSlot = lastSlot + 1;
- break;
+ // Check that the save slot can be used for user saves.
+ SaveStateDescriptor desc = _metaEngine->querySaveMetaInfos(_target.c_str(), lastSlot + 1);
+ if (!desc.getWriteProtectedFlag()) {
+ _nextFreeSaveSlot = lastSlot + 1;
+ break;
+ }
}
lastSlot = curSlot;
}
// Use the next available slot otherwise.
- if (_nextFreeSaveSlot == -1 && lastSlot + 1 < _metaEngine->getMaximumSaveSlot()) {
- _nextFreeSaveSlot = lastSlot + 1;
+ const int maxSlot = _metaEngine->getMaximumSaveSlot();
+ for (int i = lastSlot; _nextFreeSaveSlot == -1 && i < maxSlot; ++i) {
+ // Check that the save slot can be used for user saves.
+ SaveStateDescriptor desc = _metaEngine->querySaveMetaInfos(_target.c_str(), i + 1);
+ if (!desc.getWriteProtectedFlag()) {
+ _nextFreeSaveSlot = i + 1;
+ }
}
}
diff --git a/gui/themes/translations.dat b/gui/themes/translations.dat
index bfa33d4feb..b93ee09287 100644
--- a/gui/themes/translations.dat
+++ b/gui/themes/translations.dat
Binary files differ
diff --git a/icons/scummvm.info b/icons/scummvm.info
index e30a7129ef..f603627122 100644
--- a/icons/scummvm.info
+++ b/icons/scummvm.info
Binary files differ
diff --git a/icons/scummvm_drawer.info b/icons/scummvm_drawer.info
index 26f6a8633d..03b62536a2 100644
--- a/icons/scummvm_drawer.info
+++ b/icons/scummvm_drawer.info
Binary files differ
diff --git a/image/codecs/cinepak.cpp b/image/codecs/cinepak.cpp
index 8464aa3889..4e858921ee 100644
--- a/image/codecs/cinepak.cpp
+++ b/image/codecs/cinepak.cpp
@@ -21,6 +21,7 @@
*/
#include "image/codecs/cinepak.h"
+#include "image/codecs/cinepak_tables.h"
#include "common/debug.h"
#include "common/stream.h"
@@ -34,23 +35,328 @@
namespace Image {
-#define PUT_PIXEL(offset, lum, u, v) \
- if (_pixelFormat.bytesPerPixel != 1) { \
- byte r = _clipTable[lum + (v << 1)]; \
- byte g = _clipTable[lum - (u >> 1) - v]; \
- byte b = _clipTable[lum + (u << 1)]; \
- \
- if (_pixelFormat.bytesPerPixel == 2) \
- *((uint16 *)_curFrame.surface->getPixels() + offset) = _pixelFormat.RGBToColor(r, g, b); \
- else \
- *((uint32 *)_curFrame.surface->getPixels() + offset) = _pixelFormat.RGBToColor(r, g, b); \
- } else \
- *((byte *)_curFrame.surface->getPixels() + offset) = lum
-
-CinepakDecoder::CinepakDecoder(int bitsPerPixel) : Codec() {
- _curFrame.surface = NULL;
- _curFrame.strips = NULL;
+namespace {
+
+inline void convertYUVToRGB(const byte *clipTable, byte y, int8 u, int8 v, byte &r, byte &g, byte &b) {
+ r = clipTable[y + (v << 1)];
+ g = clipTable[y - (u >> 1) - v];
+ b = clipTable[y + (u << 1)];
+}
+
+inline uint32 convertYUVToColor(const byte *clipTable, const Graphics::PixelFormat &format, byte y, byte u, byte v) {
+ byte r, g, b;
+ convertYUVToRGB(clipTable, y, u, v, r, g, b);
+ return format.RGBToColor(r, g, b);
+}
+
+inline uint16 createDitherTableIndex(const byte *clipTable, byte y, int8 u, int8 v) {
+ byte r, g, b;
+ convertYUVToRGB(clipTable, y, u, v, r, g, b);
+ return ((r & 0xF8) << 6) |
+ ((g & 0xF8) << 1) |
+ ((b & 0xF0) >> 4);
+}
+
+/**
+ * Put a raw pixel to the destination surface
+ */
+template<typename PixelInt>
+inline void putPixelRaw(PixelInt *dst, const byte *clipTable, const Graphics::PixelFormat &format, byte y, byte u, byte v) {
+ *dst = convertYUVToColor(clipTable, format, y, u, v);
+}
+
+/**
+ * Specialized putPixelRaw for palettized 8bpp output
+ */
+template<>
+inline void putPixelRaw(byte *dst, const byte *clipTable, const Graphics::PixelFormat &format, byte y, byte u, byte v) {
+ *dst = y;
+}
+
+/**
+ * The default codebook converter: raw output.
+ */
+struct CodebookConverterRaw {
+ template<typename PixelInt>
+ static inline void decodeBlock1(byte codebookIndex, const CinepakStrip &strip, PixelInt *(&rows)[4], const byte *clipTable, const byte *colorMap, const Graphics::PixelFormat &format) {
+ const CinepakCodebook &codebook = strip.v1_codebook[codebookIndex];
+ putPixelRaw(rows[0] + 0, clipTable, format, codebook.y[0], codebook.u, codebook.v);
+ putPixelRaw(rows[0] + 1, clipTable, format, codebook.y[0], codebook.u, codebook.v);
+ putPixelRaw(rows[1] + 0, clipTable, format, codebook.y[0], codebook.u, codebook.v);
+ putPixelRaw(rows[1] + 1, clipTable, format, codebook.y[0], codebook.u, codebook.v);
+
+ putPixelRaw(rows[0] + 2, clipTable, format, codebook.y[1], codebook.u, codebook.v);
+ putPixelRaw(rows[0] + 3, clipTable, format, codebook.y[1], codebook.u, codebook.v);
+ putPixelRaw(rows[1] + 2, clipTable, format, codebook.y[1], codebook.u, codebook.v);
+ putPixelRaw(rows[1] + 3, clipTable, format, codebook.y[1], codebook.u, codebook.v);
+
+ putPixelRaw(rows[2] + 0, clipTable, format, codebook.y[2], codebook.u, codebook.v);
+ putPixelRaw(rows[2] + 1, clipTable, format, codebook.y[2], codebook.u, codebook.v);
+ putPixelRaw(rows[3] + 0, clipTable, format, codebook.y[2], codebook.u, codebook.v);
+ putPixelRaw(rows[3] + 1, clipTable, format, codebook.y[2], codebook.u, codebook.v);
+
+ putPixelRaw(rows[2] + 2, clipTable, format, codebook.y[3], codebook.u, codebook.v);
+ putPixelRaw(rows[2] + 3, clipTable, format, codebook.y[3], codebook.u, codebook.v);
+ putPixelRaw(rows[3] + 2, clipTable, format, codebook.y[3], codebook.u, codebook.v);
+ putPixelRaw(rows[3] + 3, clipTable, format, codebook.y[3], codebook.u, codebook.v);
+ }
+
+ template<typename PixelInt>
+ static inline void decodeBlock4(const byte (&codebookIndex)[4], const CinepakStrip &strip, PixelInt *(&rows)[4], const byte *clipTable, const byte *colorMap, const Graphics::PixelFormat &format) {
+ const CinepakCodebook &codebook1 = strip.v4_codebook[codebookIndex[0]];
+ putPixelRaw(rows[0] + 0, clipTable, format, codebook1.y[0], codebook1.u, codebook1.v);
+ putPixelRaw(rows[0] + 1, clipTable, format, codebook1.y[1], codebook1.u, codebook1.v);
+ putPixelRaw(rows[1] + 0, clipTable, format, codebook1.y[2], codebook1.u, codebook1.v);
+ putPixelRaw(rows[1] + 1, clipTable, format, codebook1.y[3], codebook1.u, codebook1.v);
+
+ const CinepakCodebook &codebook2 = strip.v4_codebook[codebookIndex[1]];
+ putPixelRaw(rows[0] + 2, clipTable, format, codebook2.y[0], codebook2.u, codebook2.v);
+ putPixelRaw(rows[0] + 3, clipTable, format, codebook2.y[1], codebook2.u, codebook2.v);
+ putPixelRaw(rows[1] + 2, clipTable, format, codebook2.y[2], codebook2.u, codebook2.v);
+ putPixelRaw(rows[1] + 3, clipTable, format, codebook2.y[3], codebook2.u, codebook2.v);
+
+ const CinepakCodebook &codebook3 = strip.v4_codebook[codebookIndex[2]];
+ putPixelRaw(rows[2] + 0, clipTable, format, codebook3.y[0], codebook3.u, codebook3.v);
+ putPixelRaw(rows[2] + 1, clipTable, format, codebook3.y[1], codebook3.u, codebook3.v);
+ putPixelRaw(rows[3] + 0, clipTable, format, codebook3.y[2], codebook3.u, codebook3.v);
+ putPixelRaw(rows[3] + 1, clipTable, format, codebook3.y[3], codebook3.u, codebook3.v);
+
+ const CinepakCodebook &codebook4 = strip.v4_codebook[codebookIndex[3]];
+ putPixelRaw(rows[2] + 2, clipTable, format, codebook4.y[0], codebook4.u, codebook4.v);
+ putPixelRaw(rows[2] + 3, clipTable, format, codebook4.y[1], codebook4.u, codebook4.v);
+ putPixelRaw(rows[3] + 2, clipTable, format, codebook4.y[2], codebook4.u, codebook4.v);
+ putPixelRaw(rows[3] + 3, clipTable, format, codebook4.y[3], codebook4.u, codebook4.v);
+ }
+};
+
+/**
+ * Codebook converter that dithers in VFW-style
+ */
+struct CodebookConverterDitherVFW {
+ static inline void decodeBlock1(byte codebookIndex, const CinepakStrip &strip, byte *(&rows)[4], const byte *clipTable, const byte *colorMap, const Graphics::PixelFormat &format) {
+ const CinepakCodebook &codebook = strip.v1_codebook[codebookIndex];
+ byte blockBuffer[16];
+ ditherCodebookSmooth(codebook, blockBuffer, colorMap);
+ rows[0][0] = blockBuffer[0];
+ rows[0][1] = blockBuffer[1];
+ rows[0][2] = blockBuffer[2];
+ rows[0][3] = blockBuffer[3];
+ rows[1][0] = blockBuffer[4];
+ rows[1][1] = blockBuffer[5];
+ rows[1][2] = blockBuffer[6];
+ rows[1][3] = blockBuffer[7];
+ rows[2][0] = blockBuffer[8];
+ rows[2][1] = blockBuffer[9];
+ rows[2][2] = blockBuffer[10];
+ rows[2][3] = blockBuffer[11];
+ rows[3][0] = blockBuffer[12];
+ rows[3][1] = blockBuffer[13];
+ rows[3][2] = blockBuffer[14];
+ rows[3][3] = blockBuffer[15];
+ }
+
+ static inline void decodeBlock4(const byte (&codebookIndex)[4], const CinepakStrip &strip, byte *(&rows)[4], const byte *clipTable, const byte *colorMap, const Graphics::PixelFormat &format) {
+ byte blockBuffer[16];
+ ditherCodebookDetail(strip.v4_codebook[codebookIndex[0]], blockBuffer, colorMap);
+ rows[0][0] = blockBuffer[0];
+ rows[0][1] = blockBuffer[1];
+ rows[1][0] = blockBuffer[4];
+ rows[1][1] = blockBuffer[5];
+
+ ditherCodebookDetail(strip.v4_codebook[codebookIndex[1]], blockBuffer, colorMap);
+ rows[0][2] = blockBuffer[2];
+ rows[0][3] = blockBuffer[3];
+ rows[1][2] = blockBuffer[6];
+ rows[1][3] = blockBuffer[7];
+
+ ditherCodebookDetail(strip.v4_codebook[codebookIndex[2]], blockBuffer, colorMap);
+ rows[2][0] = blockBuffer[8];
+ rows[2][1] = blockBuffer[9];
+ rows[3][0] = blockBuffer[12];
+ rows[3][1] = blockBuffer[13];
+
+ ditherCodebookDetail(strip.v4_codebook[codebookIndex[3]], blockBuffer, colorMap);
+ rows[2][2] = blockBuffer[10];
+ rows[2][3] = blockBuffer[11];
+ rows[3][2] = blockBuffer[14];
+ rows[3][3] = blockBuffer[15];
+ }
+
+private:
+ static inline void ditherCodebookDetail(const CinepakCodebook &codebook, byte *dst, const byte *colorMap) {
+ int uLookup = (byte)codebook.u * 2;
+ int vLookup = (byte)codebook.v * 2;
+ uint32 uv1 = s_uLookup[uLookup] | s_vLookup[vLookup];
+ uint32 uv2 = s_uLookup[uLookup + 1] | s_vLookup[vLookup + 1];
+
+ int yLookup1 = codebook.y[0] * 2;
+ int yLookup2 = codebook.y[1] * 2;
+ int yLookup3 = codebook.y[2] * 2;
+ int yLookup4 = codebook.y[3] * 2;
+
+ uint32 pixelGroup1 = uv2 | s_yLookup[yLookup1 + 1];
+ uint32 pixelGroup2 = uv2 | s_yLookup[yLookup2 + 1];
+ uint32 pixelGroup3 = uv1 | s_yLookup[yLookup3];
+ uint32 pixelGroup4 = uv1 | s_yLookup[yLookup4];
+ uint32 pixelGroup5 = uv1 | s_yLookup[yLookup1];
+ uint32 pixelGroup6 = uv1 | s_yLookup[yLookup2];
+ uint32 pixelGroup7 = uv2 | s_yLookup[yLookup3 + 1];
+ uint32 pixelGroup8 = uv2 | s_yLookup[yLookup4 + 1];
+
+ dst[0] = getRGBLookupEntry(colorMap, pixelGroup1 & 0xFFFF);
+ dst[1] = getRGBLookupEntry(colorMap, pixelGroup2 >> 16);
+ dst[2] = getRGBLookupEntry(colorMap, pixelGroup5 & 0xFFFF);
+ dst[3] = getRGBLookupEntry(colorMap, pixelGroup6 >> 16);
+ dst[4] = getRGBLookupEntry(colorMap, pixelGroup3 & 0xFFFF);
+ dst[5] = getRGBLookupEntry(colorMap, pixelGroup4 >> 16);
+ dst[6] = getRGBLookupEntry(colorMap, pixelGroup7 & 0xFFFF);
+ dst[7] = getRGBLookupEntry(colorMap, pixelGroup8 >> 16);
+ dst[8] = getRGBLookupEntry(colorMap, pixelGroup1 >> 16);
+ dst[9] = getRGBLookupEntry(colorMap, pixelGroup6 & 0xFFFF);
+ dst[10] = getRGBLookupEntry(colorMap, pixelGroup5 >> 16);
+ dst[11] = getRGBLookupEntry(colorMap, pixelGroup2 & 0xFFFF);
+ dst[12] = getRGBLookupEntry(colorMap, pixelGroup3 >> 16);
+ dst[13] = getRGBLookupEntry(colorMap, pixelGroup8 & 0xFFFF);
+ dst[14] = getRGBLookupEntry(colorMap, pixelGroup7 >> 16);
+ dst[15] = getRGBLookupEntry(colorMap, pixelGroup4 & 0xFFFF);
+ }
+
+ static inline void ditherCodebookSmooth(const CinepakCodebook &codebook, byte *dst, const byte *colorMap) {
+ int uLookup = (byte)codebook.u * 2;
+ int vLookup = (byte)codebook.v * 2;
+ uint32 uv1 = s_uLookup[uLookup] | s_vLookup[vLookup];
+ uint32 uv2 = s_uLookup[uLookup + 1] | s_vLookup[vLookup + 1];
+
+ int yLookup1 = codebook.y[0] * 2;
+ int yLookup2 = codebook.y[1] * 2;
+ int yLookup3 = codebook.y[2] * 2;
+ int yLookup4 = codebook.y[3] * 2;
+
+ uint32 pixelGroup1 = uv2 | s_yLookup[yLookup1 + 1];
+ uint32 pixelGroup2 = uv1 | s_yLookup[yLookup2];
+ uint32 pixelGroup3 = uv1 | s_yLookup[yLookup1];
+ uint32 pixelGroup4 = uv2 | s_yLookup[yLookup2 + 1];
+ uint32 pixelGroup5 = uv2 | s_yLookup[yLookup3 + 1];
+ uint32 pixelGroup6 = uv1 | s_yLookup[yLookup3];
+ uint32 pixelGroup7 = uv1 | s_yLookup[yLookup4];
+ uint32 pixelGroup8 = uv2 | s_yLookup[yLookup4 + 1];
+
+ dst[0] = getRGBLookupEntry(colorMap, pixelGroup1 & 0xFFFF);
+ dst[1] = getRGBLookupEntry(colorMap, pixelGroup1 >> 16);
+ dst[2] = getRGBLookupEntry(colorMap, pixelGroup2 & 0xFFFF);
+ dst[3] = getRGBLookupEntry(colorMap, pixelGroup2 >> 16);
+ dst[4] = getRGBLookupEntry(colorMap, pixelGroup3 & 0xFFFF);
+ dst[5] = getRGBLookupEntry(colorMap, pixelGroup3 >> 16);
+ dst[6] = getRGBLookupEntry(colorMap, pixelGroup4 & 0xFFFF);
+ dst[7] = getRGBLookupEntry(colorMap, pixelGroup4 >> 16);
+ dst[8] = getRGBLookupEntry(colorMap, pixelGroup5 >> 16);
+ dst[9] = getRGBLookupEntry(colorMap, pixelGroup6 & 0xFFFF);
+ dst[10] = getRGBLookupEntry(colorMap, pixelGroup7 >> 16);
+ dst[11] = getRGBLookupEntry(colorMap, pixelGroup8 & 0xFFFF);
+ dst[12] = getRGBLookupEntry(colorMap, pixelGroup6 >> 16);
+ dst[13] = getRGBLookupEntry(colorMap, pixelGroup5 & 0xFFFF);
+ dst[14] = getRGBLookupEntry(colorMap, pixelGroup8 >> 16);
+ dst[15] = getRGBLookupEntry(colorMap, pixelGroup7 & 0xFFFF);
+ }
+
+ static inline byte getRGBLookupEntry(const byte *colorMap, uint16 index) {
+ return colorMap[s_defaultPaletteLookup[CLIP<int>(index, 0, 1024)]];
+ }
+};
+
+/**
+ * Codebook converter that dithers in QT-style
+ */
+struct CodebookConverterDitherQT {
+ static inline void decodeBlock1(byte codebookIndex, const CinepakStrip &strip, byte *(&rows)[4], const byte *clipTable, const byte *colorMap, const Graphics::PixelFormat &format) {
+ const byte *colorPtr = strip.v1_dither + (codebookIndex << 2);
+ WRITE_UINT32(rows[0], READ_UINT32(colorPtr));
+ WRITE_UINT32(rows[1], READ_UINT32(colorPtr + 1024));
+ WRITE_UINT32(rows[2], READ_UINT32(colorPtr + 2048));
+ WRITE_UINT32(rows[3], READ_UINT32(colorPtr + 3072));
+ }
+
+ static inline void decodeBlock4(const byte (&codebookIndex)[4], const CinepakStrip &strip, byte *(&rows)[4], const byte *clipTable, const byte *colorMap, const Graphics::PixelFormat &format) {
+ const byte *colorPtr = strip.v4_dither + (codebookIndex[0] << 2);
+ WRITE_UINT16(rows[0] + 0, READ_UINT16(colorPtr + 0));
+ WRITE_UINT16(rows[1] + 0, READ_UINT16(colorPtr + 2));
+
+ colorPtr = strip.v4_dither + (codebookIndex[1] << 2);
+ WRITE_UINT16(rows[0] + 2, READ_UINT16(colorPtr + 1024));
+ WRITE_UINT16(rows[1] + 2, READ_UINT16(colorPtr + 1026));
+
+ colorPtr = strip.v4_dither + (codebookIndex[2] << 2);
+ WRITE_UINT16(rows[2] + 0, READ_UINT16(colorPtr + 2048));
+ WRITE_UINT16(rows[3] + 0, READ_UINT16(colorPtr + 2050));
+
+ colorPtr = strip.v4_dither + (codebookIndex[3] << 2);
+ WRITE_UINT16(rows[2] + 2, READ_UINT16(colorPtr + 3072));
+ WRITE_UINT16(rows[3] + 2, READ_UINT16(colorPtr + 3074));
+ }
+};
+
+template<typename PixelInt, typename CodebookConverter>
+void decodeVectorsTmpl(CinepakFrame &frame, const byte *clipTable, const byte *colorMap, Common::SeekableReadStream &stream, uint16 strip, byte chunkID, uint32 chunkSize) {
+ uint32 flag = 0, mask = 0;
+ PixelInt *iy[4];
+ int32 startPos = stream.pos();
+
+ for (uint16 y = frame.strips[strip].rect.top; y < frame.strips[strip].rect.bottom; y += 4) {
+ iy[0] = (PixelInt *)frame.surface->getBasePtr(frame.strips[strip].rect.left, + y);
+ iy[1] = iy[0] + frame.width;
+ iy[2] = iy[1] + frame.width;
+ iy[3] = iy[2] + frame.width;
+
+ for (uint16 x = frame.strips[strip].rect.left; x < frame.strips[strip].rect.right; x += 4) {
+ if ((chunkID & 0x01) && !(mask >>= 1)) {
+ if ((stream.pos() - startPos + 4) > (int32)chunkSize)
+ return;
+
+ flag = stream.readUint32BE();
+ mask = 0x80000000;
+ }
+
+ if (!(chunkID & 0x01) || (flag & mask)) {
+ if (!(chunkID & 0x02) && !(mask >>= 1)) {
+ if ((stream.pos() - startPos + 4) > (int32)chunkSize)
+ return;
+
+ flag = stream.readUint32BE();
+ mask = 0x80000000;
+ }
+
+ if ((chunkID & 0x02) || (~flag & mask)) {
+ if ((stream.pos() - startPos + 1) > (int32)chunkSize)
+ return;
+
+ // Get the codebook
+ byte codebook = stream.readByte();
+ CodebookConverter::decodeBlock1(codebook, frame.strips[strip], iy, clipTable, colorMap, frame.surface->format);
+ } else if (flag & mask) {
+ if ((stream.pos() - startPos + 4) > (int32)chunkSize)
+ return;
+
+ byte codebook[4];
+ stream.read(codebook, 4);
+ CodebookConverter::decodeBlock4(codebook, frame.strips[strip], iy, clipTable, colorMap, frame.surface->format);
+ }
+ }
+
+ for (byte i = 0; i < 4; i++)
+ iy[i] += 4;
+ }
+ }
+}
+
+} // End of anonymous namespace
+
+CinepakDecoder::CinepakDecoder(int bitsPerPixel) : Codec(), _bitsPerPixel(bitsPerPixel) {
+ _curFrame.surface = 0;
+ _curFrame.strips = 0;
_y = 0;
+ _colorMap = 0;
+ _ditherPalette = 0;
+ _ditherType = kDitherTypeUnknown;
if (bitsPerPixel == 8) {
_pixelFormat = Graphics::PixelFormat::createFormatCLUT8();
@@ -86,6 +392,9 @@ CinepakDecoder::~CinepakDecoder() {
delete[] _curFrame.strips;
delete[] _clipTableBuf;
+
+ delete[] _colorMap;
+ delete[] _ditherPalette;
}
const Graphics::Surface *CinepakDecoder::decodeFrame(Common::SeekableReadStream &stream) {
@@ -96,7 +405,7 @@ const Graphics::Surface *CinepakDecoder::decodeFrame(Common::SeekableReadStream
_curFrame.height = stream.readUint16BE();
_curFrame.stripCount = stream.readUint16BE();
- if (_curFrame.strips == NULL)
+ if (!_curFrame.strips)
_curFrame.strips = new CinepakStrip[_curFrame.stripCount];
debug(4, "Cinepak Frame: Width = %d, Height = %d, Strip Count = %d", _curFrame.width, _curFrame.height, _curFrame.stripCount);
@@ -120,10 +429,15 @@ const Graphics::Surface *CinepakDecoder::decodeFrame(Common::SeekableReadStream
for (uint16 i = 0; i < _curFrame.stripCount; i++) {
if (i > 0 && !(_curFrame.flags & 1)) { // Use codebooks from last strip
+
for (uint16 j = 0; j < 256; j++) {
_curFrame.strips[i].v1_codebook[j] = _curFrame.strips[i - 1].v1_codebook[j];
_curFrame.strips[i].v4_codebook[j] = _curFrame.strips[i - 1].v4_codebook[j];
}
+
+ // Copy the QuickTime dither tables
+ memcpy(_curFrame.strips[i].v1_dither, _curFrame.strips[i - 1].v1_dither, 256 * 4 * 4 * 4);
+ memcpy(_curFrame.strips[i].v4_dither, _curFrame.strips[i - 1].v4_dither, 256 * 4 * 4 * 4);
}
_curFrame.strips[i].id = stream.readUint16BE();
@@ -166,7 +480,10 @@ const Graphics::Surface *CinepakDecoder::decodeFrame(Common::SeekableReadStream
case 0x30:
case 0x31:
case 0x32:
- decodeVectors(stream, i, chunkID, chunkSize);
+ if (_ditherPalette)
+ ditherVectors(stream, i, chunkID, chunkSize);
+ else
+ decodeVectors(stream, i, chunkID, chunkSize);
break;
default:
warning("Unknown Cinepak chunk ID %02x", chunkID);
@@ -203,8 +520,7 @@ void CinepakDecoder::loadCodebook(Common::SeekableReadStream &stream, uint16 str
if ((stream.pos() - startPos + n) > (int32)chunkSize)
break;
- for (byte j = 0; j < 4; j++)
- codebook[i].y[j] = stream.readByte();
+ stream.read(codebook[i].y, 4);
if (n == 6) {
codebook[i].u = stream.readSByte();
@@ -216,99 +532,150 @@ void CinepakDecoder::loadCodebook(Common::SeekableReadStream &stream, uint16 str
codebook[i].u = 0;
codebook[i].v = 0;
}
+
+ // Dither the codebook if we're dithering for QuickTime
+ if (_ditherType == kDitherTypeQT)
+ ditherCodebookQT(strip, codebookType, i);
}
}
}
+void CinepakDecoder::ditherCodebookQT(uint16 strip, byte codebookType, uint16 codebookIndex) {
+ if (codebookType == 1) {
+ const CinepakCodebook &codebook = _curFrame.strips[strip].v1_codebook[codebookIndex];
+ byte *output = _curFrame.strips[strip].v1_dither + (codebookIndex << 2);
+
+ byte *ditherEntry = _colorMap + createDitherTableIndex(_clipTable, codebook.y[0], codebook.u, codebook.v);
+ output[0x000] = ditherEntry[0x0000];
+ output[0x001] = ditherEntry[0x4000];
+ output[0x400] = ditherEntry[0xC000];
+ output[0x401] = ditherEntry[0x0000];
+
+ ditherEntry = _colorMap + createDitherTableIndex(_clipTable, codebook.y[1], codebook.u, codebook.v);
+ output[0x002] = ditherEntry[0x8000];
+ output[0x003] = ditherEntry[0xC000];
+ output[0x402] = ditherEntry[0x4000];
+ output[0x403] = ditherEntry[0x8000];
+
+ ditherEntry = _colorMap + createDitherTableIndex(_clipTable, codebook.y[2], codebook.u, codebook.v);
+ output[0x800] = ditherEntry[0x4000];
+ output[0x801] = ditherEntry[0x8000];
+ output[0xC00] = ditherEntry[0x8000];
+ output[0xC01] = ditherEntry[0xC000];
+
+ ditherEntry = _colorMap + createDitherTableIndex(_clipTable, codebook.y[3], codebook.u, codebook.v);
+ output[0x802] = ditherEntry[0xC000];
+ output[0x803] = ditherEntry[0x0000];
+ output[0xC02] = ditherEntry[0x0000];
+ output[0xC03] = ditherEntry[0x4000];
+ } else {
+ const CinepakCodebook &codebook = _curFrame.strips[strip].v4_codebook[codebookIndex];
+ byte *output = _curFrame.strips[strip].v4_dither + (codebookIndex << 2);
+
+ byte *ditherEntry = _colorMap + createDitherTableIndex(_clipTable, codebook.y[0], codebook.u, codebook.v);
+ output[0x000] = ditherEntry[0x0000];
+ output[0x400] = ditherEntry[0x8000];
+ output[0x800] = ditherEntry[0x4000];
+ output[0xC00] = ditherEntry[0xC000];
+
+ ditherEntry = _colorMap + createDitherTableIndex(_clipTable, codebook.y[1], codebook.u, codebook.v);
+ output[0x001] = ditherEntry[0x4000];
+ output[0x401] = ditherEntry[0xC000];
+ output[0x801] = ditherEntry[0x8000];
+ output[0xC01] = ditherEntry[0x0000];
+
+ ditherEntry = _colorMap + createDitherTableIndex(_clipTable, codebook.y[2], codebook.u, codebook.v);
+ output[0x002] = ditherEntry[0xC000];
+ output[0x402] = ditherEntry[0x4000];
+ output[0x802] = ditherEntry[0x8000];
+ output[0xC02] = ditherEntry[0x0000];
+
+ ditherEntry = _colorMap + createDitherTableIndex(_clipTable, codebook.y[3], codebook.u, codebook.v);
+ output[0x003] = ditherEntry[0x0000];
+ output[0x403] = ditherEntry[0x8000];
+ output[0x803] = ditherEntry[0xC000];
+ output[0xC03] = ditherEntry[0x4000];
+ }
+}
+
void CinepakDecoder::decodeVectors(Common::SeekableReadStream &stream, uint16 strip, byte chunkID, uint32 chunkSize) {
- uint32 flag = 0, mask = 0;
- uint32 iy[4];
- int32 startPos = stream.pos();
+ if (_curFrame.surface->format.bytesPerPixel == 1) {
+ decodeVectorsTmpl<byte, CodebookConverterRaw>(_curFrame, _clipTable, _colorMap, stream, strip, chunkID, chunkSize);
+ } else if (_curFrame.surface->format.bytesPerPixel == 2) {
+ decodeVectorsTmpl<uint16, CodebookConverterRaw>(_curFrame, _clipTable, _colorMap, stream, strip, chunkID, chunkSize);
+ } else if (_curFrame.surface->format.bytesPerPixel == 4) {
+ decodeVectorsTmpl<uint32, CodebookConverterRaw>(_curFrame, _clipTable, _colorMap, stream, strip, chunkID, chunkSize);
+ }
+}
- for (uint16 y = _curFrame.strips[strip].rect.top; y < _curFrame.strips[strip].rect.bottom; y += 4) {
- iy[0] = _curFrame.strips[strip].rect.left + y * _curFrame.width;
- iy[1] = iy[0] + _curFrame.width;
- iy[2] = iy[1] + _curFrame.width;
- iy[3] = iy[2] + _curFrame.width;
+bool CinepakDecoder::canDither(DitherType type) const {
+ return (type == kDitherTypeVFW || type == kDitherTypeQT) && _bitsPerPixel == 24;
+}
- for (uint16 x = _curFrame.strips[strip].rect.left; x < _curFrame.strips[strip].rect.right; x += 4) {
- if ((chunkID & 0x01) && !(mask >>= 1)) {
- if ((stream.pos() - startPos + 4) > (int32)chunkSize)
- return;
+void CinepakDecoder::setDither(DitherType type, const byte *palette) {
+ assert(canDither(type));
- flag = stream.readUint32BE();
- mask = 0x80000000;
- }
+ delete[] _colorMap;
+ delete[] _ditherPalette;
- if (!(chunkID & 0x01) || (flag & mask)) {
- if (!(chunkID & 0x02) && !(mask >>= 1)) {
- if ((stream.pos() - startPos + 4) > (int32)chunkSize)
- return;
+ _ditherPalette = new byte[256 * 3];
+ memcpy(_ditherPalette, palette, 256 * 3);
- flag = stream.readUint32BE();
- mask = 0x80000000;
- }
+ _dirtyPalette = true;
+ _pixelFormat = Graphics::PixelFormat::createFormatCLUT8();
+ _ditherType = type;
- if ((chunkID & 0x02) || (~flag & mask)) {
- if ((stream.pos() - startPos + 1) > (int32)chunkSize)
- return;
+ if (type == kDitherTypeVFW) {
+ _colorMap = new byte[221];
- // Get the codebook
- CinepakCodebook codebook = _curFrame.strips[strip].v1_codebook[stream.readByte()];
-
- PUT_PIXEL(iy[0] + 0, codebook.y[0], codebook.u, codebook.v);
- PUT_PIXEL(iy[0] + 1, codebook.y[0], codebook.u, codebook.v);
- PUT_PIXEL(iy[1] + 0, codebook.y[0], codebook.u, codebook.v);
- PUT_PIXEL(iy[1] + 1, codebook.y[0], codebook.u, codebook.v);
-
- PUT_PIXEL(iy[0] + 2, codebook.y[1], codebook.u, codebook.v);
- PUT_PIXEL(iy[0] + 3, codebook.y[1], codebook.u, codebook.v);
- PUT_PIXEL(iy[1] + 2, codebook.y[1], codebook.u, codebook.v);
- PUT_PIXEL(iy[1] + 3, codebook.y[1], codebook.u, codebook.v);
-
- PUT_PIXEL(iy[2] + 0, codebook.y[2], codebook.u, codebook.v);
- PUT_PIXEL(iy[2] + 1, codebook.y[2], codebook.u, codebook.v);
- PUT_PIXEL(iy[3] + 0, codebook.y[2], codebook.u, codebook.v);
- PUT_PIXEL(iy[3] + 1, codebook.y[2], codebook.u, codebook.v);
-
- PUT_PIXEL(iy[2] + 2, codebook.y[3], codebook.u, codebook.v);
- PUT_PIXEL(iy[2] + 3, codebook.y[3], codebook.u, codebook.v);
- PUT_PIXEL(iy[3] + 2, codebook.y[3], codebook.u, codebook.v);
- PUT_PIXEL(iy[3] + 3, codebook.y[3], codebook.u, codebook.v);
- } else if (flag & mask) {
- if ((stream.pos() - startPos + 4) > (int32)chunkSize)
- return;
+ for (int i = 0; i < 221; i++)
+ _colorMap[i] = findNearestRGB(i);
+ } else {
+ // Generate QuickTime dither table
+ // 4 blocks of 0x4000 bytes (RGB554 lookup)
+ _colorMap = createQuickTimeDitherTable(palette, 256);
+ }
+}
+
+byte CinepakDecoder::findNearestRGB(int index) const {
+ int r = s_defaultPalette[index * 3];
+ int g = s_defaultPalette[index * 3 + 1];
+ int b = s_defaultPalette[index * 3 + 2];
+
+ byte result = 0;
+ int diff = 0x7FFFFFFF;
+
+ for (int i = 0; i < 256; i++) {
+ int bDiff = b - (int)_ditherPalette[i * 3 + 2];
+ int curDiffB = diff - (bDiff * bDiff);
+
+ if (curDiffB > 0) {
+ int gDiff = g - (int)_ditherPalette[i * 3 + 1];
+ int curDiffG = curDiffB - (gDiff * gDiff);
+
+ if (curDiffG > 0) {
+ int rDiff = r - (int)_ditherPalette[i * 3];
+ int curDiffR = curDiffG - (rDiff * rDiff);
- CinepakCodebook codebook = _curFrame.strips[strip].v4_codebook[stream.readByte()];
- PUT_PIXEL(iy[0] + 0, codebook.y[0], codebook.u, codebook.v);
- PUT_PIXEL(iy[0] + 1, codebook.y[1], codebook.u, codebook.v);
- PUT_PIXEL(iy[1] + 0, codebook.y[2], codebook.u, codebook.v);
- PUT_PIXEL(iy[1] + 1, codebook.y[3], codebook.u, codebook.v);
-
- codebook = _curFrame.strips[strip].v4_codebook[stream.readByte()];
- PUT_PIXEL(iy[0] + 2, codebook.y[0], codebook.u, codebook.v);
- PUT_PIXEL(iy[0] + 3, codebook.y[1], codebook.u, codebook.v);
- PUT_PIXEL(iy[1] + 2, codebook.y[2], codebook.u, codebook.v);
- PUT_PIXEL(iy[1] + 3, codebook.y[3], codebook.u, codebook.v);
-
- codebook = _curFrame.strips[strip].v4_codebook[stream.readByte()];
- PUT_PIXEL(iy[2] + 0, codebook.y[0], codebook.u, codebook.v);
- PUT_PIXEL(iy[2] + 1, codebook.y[1], codebook.u, codebook.v);
- PUT_PIXEL(iy[3] + 0, codebook.y[2], codebook.u, codebook.v);
- PUT_PIXEL(iy[3] + 1, codebook.y[3], codebook.u, codebook.v);
-
- codebook = _curFrame.strips[strip].v4_codebook[stream.readByte()];
- PUT_PIXEL(iy[2] + 2, codebook.y[0], codebook.u, codebook.v);
- PUT_PIXEL(iy[2] + 3, codebook.y[1], codebook.u, codebook.v);
- PUT_PIXEL(iy[3] + 2, codebook.y[2], codebook.u, codebook.v);
- PUT_PIXEL(iy[3] + 3, codebook.y[3], codebook.u, codebook.v);
+ if (curDiffR > 0) {
+ diff -= curDiffR;
+ result = i;
+
+ if (diff == 0)
+ break;
}
}
-
- for (byte i = 0; i < 4; i++)
- iy[i] += 4;
}
}
+
+ return result;
+}
+
+void CinepakDecoder::ditherVectors(Common::SeekableReadStream &stream, uint16 strip, byte chunkID, uint32 chunkSize) {
+ if (_ditherType == kDitherTypeVFW)
+ decodeVectorsTmpl<byte, CodebookConverterDitherVFW>(_curFrame, _clipTable, _colorMap, stream, strip, chunkID, chunkSize);
+ else
+ decodeVectorsTmpl<byte, CodebookConverterDitherQT>(_curFrame, _clipTable, _colorMap, stream, strip, chunkID, chunkSize);
}
} // End of namespace Image
diff --git a/image/codecs/cinepak.h b/image/codecs/cinepak.h
index e9cd437730..4efb1191cc 100644
--- a/image/codecs/cinepak.h
+++ b/image/codecs/cinepak.h
@@ -46,6 +46,7 @@ struct CinepakStrip {
uint16 length;
Common::Rect rect;
CinepakCodebook v1_codebook[256], v4_codebook[256];
+ byte v1_dither[256 * 4 * 4 * 4], v4_dither[256 * 4 * 4 * 4];
};
struct CinepakFrame {
@@ -63,6 +64,9 @@ struct CinepakFrame {
* Cinepak decoder.
*
* Used by BMP/AVI and PICT/QuickTime.
+ *
+ * Used in engines:
+ * - sherlock
*/
class CinepakDecoder : public Codec {
public:
@@ -72,14 +76,30 @@ public:
const Graphics::Surface *decodeFrame(Common::SeekableReadStream &stream);
Graphics::PixelFormat getPixelFormat() const { return _pixelFormat; }
+ bool containsPalette() const { return _ditherPalette != 0; }
+ const byte *getPalette() { _dirtyPalette = false; return _ditherPalette; }
+ bool hasDirtyPalette() const { return _dirtyPalette; }
+ bool canDither(DitherType type) const;
+ void setDither(DitherType type, const byte *palette);
+
private:
CinepakFrame _curFrame;
int32 _y;
+ int _bitsPerPixel;
Graphics::PixelFormat _pixelFormat;
byte *_clipTable, *_clipTableBuf;
+ byte *_ditherPalette;
+ bool _dirtyPalette;
+ byte *_colorMap;
+ DitherType _ditherType;
+
void loadCodebook(Common::SeekableReadStream &stream, uint16 strip, byte codebookType, byte chunkID, uint32 chunkSize);
void decodeVectors(Common::SeekableReadStream &stream, uint16 strip, byte chunkID, uint32 chunkSize);
+
+ byte findNearestRGB(int index) const;
+ void ditherVectors(Common::SeekableReadStream &stream, uint16 strip, byte chunkID, uint32 chunkSize);
+ void ditherCodebookQT(uint16 strip, byte codebookType, uint16 codebookIndex);
};
} // End of namespace Image
diff --git a/image/codecs/cinepak_tables.h b/image/codecs/cinepak_tables.h
new file mode 100644
index 0000000000..03131cec22
--- /dev/null
+++ b/image/codecs/cinepak_tables.h
@@ -0,0 +1,780 @@
+/* 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 IMAGE_CODECS_CINEPAK_TABLES_H
+#define IMAGE_CODECS_CINEPAK_TABLES_H
+
+#include "common/scummsys.h"
+
+namespace Image {
+
+static const byte s_defaultPaletteLookup[1024] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
+ 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
+ 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
+ 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
+ 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
+ 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02,
+ 0x04, 0x04, 0x04, 0x05, 0x06, 0x07, 0x07, 0x07,
+ 0x04, 0x04, 0x04, 0x05, 0x06, 0x07, 0x07, 0x07,
+ 0x04, 0x04, 0x04, 0x05, 0x06, 0x07, 0x07, 0x07,
+ 0x04, 0x04, 0x04, 0x05, 0x06, 0x07, 0x07, 0x07,
+ 0x08, 0x08, 0x08, 0x09, 0x0A, 0x07, 0x07, 0x07,
+ 0x0B, 0x0B, 0x0B, 0x0C, 0x0D, 0x0D, 0x0D, 0x07,
+ 0x0E, 0x0E, 0x0E, 0x0F, 0x0D, 0x0D, 0x0D, 0x0D,
+ 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x0D, 0x0D,
+ 0x12, 0x12, 0x12, 0x13, 0x14, 0x15, 0x16, 0x16,
+ 0x12, 0x12, 0x12, 0x13, 0x14, 0x15, 0x16, 0x16,
+ 0x12, 0x12, 0x12, 0x13, 0x14, 0x15, 0x16, 0x16,
+ 0x12, 0x12, 0x12, 0x13, 0x14, 0x15, 0x16, 0x16,
+ 0x17, 0x17, 0x17, 0x18, 0x19, 0x1A, 0x16, 0x16,
+ 0x1B, 0x1B, 0x1B, 0x1C, 0x1D, 0x1E, 0x1E, 0x1E,
+ 0x1F, 0x1F, 0x1F, 0x20, 0x21, 0x1E, 0x1E, 0x1E,
+ 0x22, 0x22, 0x22, 0x23, 0x24, 0x24, 0x24, 0x1E,
+ 0x25, 0x25, 0x25, 0x26, 0x27, 0x28, 0x29, 0x29,
+ 0x25, 0x25, 0x25, 0x26, 0x27, 0x28, 0x29, 0x29,
+ 0x25, 0x25, 0x25, 0x26, 0x27, 0x28, 0x29, 0x29,
+ 0x25, 0x25, 0x25, 0x26, 0x27, 0x28, 0x29, 0x29,
+ 0x2A, 0x2A, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2E,
+ 0x2F, 0x2F, 0x2F, 0x30, 0x31, 0x32, 0x2E, 0x2E,
+ 0x33, 0x33, 0x33, 0x34, 0x35, 0x36, 0x36, 0x36,
+ 0x33, 0x33, 0x33, 0x34, 0x35, 0x36, 0x36, 0x36,
+ 0x37, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3B, 0x3B,
+ 0x37, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3B, 0x3B,
+ 0x37, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3B, 0x3B,
+ 0x3C, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x40, 0x40,
+ 0x41, 0x41, 0x42, 0x43, 0x44, 0x45, 0x45, 0x45,
+ 0x46, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4A, 0x4A,
+ 0x4B, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x4F, 0x4F,
+ 0x4B, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x4F, 0x4F,
+ 0x50, 0x50, 0x51, 0x52, 0x53, 0x54, 0x54, 0x54,
+ 0x50, 0x50, 0x51, 0x52, 0x53, 0x54, 0x54, 0x54,
+ 0x50, 0x50, 0x51, 0x52, 0x53, 0x54, 0x54, 0x54,
+ 0x55, 0x55, 0x56, 0x57, 0x58, 0x59, 0x59, 0x59,
+ 0x5A, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5E, 0x5E,
+ 0x5F, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x63, 0x63,
+ 0x64, 0x64, 0x65, 0x66, 0x67, 0x68, 0x68, 0x68,
+ 0x64, 0x64, 0x65, 0x66, 0x67, 0x68, 0x68, 0x68,
+ 0x69, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6D, 0x6D,
+ 0x69, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6D, 0x6D,
+ 0x69, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6D, 0x6D,
+ 0x6E, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x72, 0x72,
+ 0x73, 0x73, 0x74, 0x75, 0x76, 0x77, 0x77, 0x77,
+ 0x78, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7C, 0x7C,
+ 0x7D, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x81, 0x81,
+ 0x7D, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x81, 0x81,
+ 0x82, 0x82, 0x83, 0x84, 0x85, 0x86, 0x86, 0x86,
+ 0x82, 0x82, 0x83, 0x84, 0x85, 0x86, 0x86, 0x86,
+ 0x87, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8B, 0x8B,
+ 0x8C, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x90, 0x90,
+ 0x91, 0x91, 0x92, 0x93, 0x94, 0x95, 0x95, 0x95,
+ 0x96, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9A, 0x9A,
+ 0x96, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9A, 0x9A,
+ 0x96, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9A, 0x9A,
+ 0x9B, 0x9B, 0x9B, 0x9C, 0x9D, 0x9D, 0x9D, 0x9D,
+ 0x9E, 0x9B, 0x9B, 0x9C, 0x9D, 0x9D, 0x9D, 0x9D,
+ 0x9E, 0x9E, 0x9F, 0xA0, 0xA1, 0xA1, 0xA1, 0xA1,
+ 0xA2, 0xA2, 0xA3, 0xA4, 0xA5, 0xA5, 0xA5, 0xA5,
+ 0xA6, 0xA6, 0xA7, 0xA8, 0xA9, 0xA9, 0xA9, 0xA9,
+ 0xAA, 0xAA, 0xAB, 0xAC, 0xAD, 0xAD, 0xAD, 0xAD,
+ 0xAA, 0xAA, 0xAB, 0xAC, 0xAD, 0xAD, 0xAD, 0xAD,
+ 0xAA, 0xAA, 0xAB, 0xAC, 0xAD, 0xAD, 0xAD, 0xAD,
+ 0xAE, 0xAE, 0xAE, 0xAF, 0xB0, 0xB0, 0xB0, 0xB0,
+ 0xAE, 0xAE, 0xAE, 0xAF, 0xB0, 0xB0, 0xB0, 0xB0,
+ 0xB4, 0xB1, 0xB1, 0xB2, 0xB3, 0xB3, 0xB3, 0xB3,
+ 0xB4, 0xB4, 0xB5, 0xB6, 0xB7, 0xB7, 0xB7, 0xB7,
+ 0xB8, 0xB8, 0xB9, 0xBA, 0xBB, 0xBB, 0xBB, 0xBB,
+ 0xBC, 0xBC, 0xBD, 0xBE, 0xBF, 0xBF, 0xBF, 0xBF,
+ 0xBC, 0xBC, 0xBD, 0xBE, 0xBF, 0xBF, 0xBF, 0xBF,
+ 0xBC, 0xBC, 0xBD, 0xBE, 0xBF, 0xBF, 0xBF, 0xBF,
+ 0xC2, 0xC0, 0xC0, 0xC0, 0xC1, 0xC1, 0xC1, 0xC1,
+ 0xC2, 0xC2, 0xC0, 0xC0, 0xC1, 0xC1, 0xC1, 0xC1,
+ 0xC2, 0xC2, 0xC2, 0xC3, 0xC4, 0xC4, 0xC4, 0xC4,
+ 0xC8, 0xC5, 0xC5, 0xC6, 0xC7, 0xC7, 0xC7, 0xC7,
+ 0xC8, 0xC8, 0xC9, 0xCA, 0xCB, 0xCB, 0xCB, 0xCB,
+ 0xCC, 0xCC, 0xCD, 0xCE, 0xCF, 0xCF, 0xCF, 0xCF,
+ 0xCC, 0xCC, 0xCD, 0xCE, 0xCF, 0xCF, 0xCF, 0xCF,
+ 0xCC, 0xCC, 0xCD, 0xCE, 0xCF, 0xCF, 0xCF, 0xCF,
+ 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0,
+ 0xD2, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0,
+ 0xD2, 0xD2, 0xD1, 0xD1, 0xD1, 0xD1, 0xD1, 0xD1,
+ 0xD2, 0xD2, 0xD2, 0xD3, 0xD3, 0xD3, 0xD3, 0xD3,
+ 0xD4, 0xD4, 0xD4, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5,
+ 0xD4, 0xD4, 0xD4, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5,
+ 0xD4, 0xD4, 0xD4, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5,
+ 0xD4, 0xD4, 0xD4, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5,
+ 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6,
+ 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6,
+ 0xD8, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6,
+ 0xD8, 0xD8, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7,
+ 0xD8, 0xD8, 0xD8, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9,
+ 0xD8, 0xD8, 0xD8, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9,
+ 0xD8, 0xD8, 0xD8, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9,
+ 0xD8, 0xD8, 0xD8, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9,
+ 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA,
+ 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA,
+ 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA,
+ 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA,
+ 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB,
+ 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB,
+ 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB,
+ 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB,
+ 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC,
+ 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC,
+ 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC,
+ 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC,
+ 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC,
+ 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC,
+ 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC,
+ 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC
+};
+
+static const byte s_defaultPalette[221 * 3] = {
+ 0x02, 0x02, 0x02,
+ 0x19, 0x19, 0x19,
+ 0x47, 0x02, 0x19,
+ 0x19, 0x0D, 0x47,
+ 0x00, 0x51, 0x00,
+ 0x2E, 0x3A, 0x00,
+ 0x5C, 0x23, 0x00,
+ 0x8F, 0x0A, 0x00,
+ 0x00, 0x45, 0x2E,
+ 0x2E, 0x2E, 0x2E,
+ 0x5C, 0x17, 0x2E,
+ 0x00, 0x3A, 0x5C,
+ 0x2E, 0x23, 0x5C,
+ 0x5C, 0x0C, 0x5C,
+ 0x00, 0x2C, 0x95,
+ 0x2E, 0x15, 0x95,
+ 0x00, 0x1A, 0xDC,
+ 0x2E, 0x03, 0xDC,
+ 0x15, 0x66, 0x15,
+ 0x43, 0x4F, 0x15,
+ 0x71, 0x38, 0x15,
+ 0xA4, 0x1E, 0x15,
+ 0xDB, 0x02, 0x15,
+ 0x15, 0x5A, 0x43,
+ 0x43, 0x43, 0x43,
+ 0x71, 0x2C, 0x43,
+ 0xA4, 0x13, 0x43,
+ 0x15, 0x4F, 0x71,
+ 0x43, 0x38, 0x71,
+ 0x71, 0x21, 0x71,
+ 0xA4, 0x07, 0x71,
+ 0x15, 0x40, 0xAA,
+ 0x43, 0x29, 0xAA,
+ 0x71, 0x12, 0xAA,
+ 0x15, 0x2F, 0xF1,
+ 0x43, 0x18, 0xF1,
+ 0x71, 0x01, 0xF1,
+ 0x29, 0x79, 0x29,
+ 0x57, 0x62, 0x29,
+ 0x85, 0x4B, 0x29,
+ 0xB7, 0x32, 0x29,
+ 0xEF, 0x16, 0x29,
+ 0x29, 0x6E, 0x57,
+ 0x57, 0x57, 0x57,
+ 0x85, 0x40, 0x57,
+ 0xB7, 0x27, 0x57,
+ 0xEF, 0x0B, 0x57,
+ 0x29, 0x62, 0x85,
+ 0x57, 0x4B, 0x85,
+ 0x85, 0x34, 0x85,
+ 0xB7, 0x1B, 0x85,
+ 0x29, 0x54, 0xBE,
+ 0x57, 0x3D, 0xBE,
+ 0x85, 0x26, 0xBE,
+ 0xB7, 0x0D, 0xBE,
+ 0x03, 0xB5, 0x09,
+ 0x3C, 0x99, 0x09,
+ 0x6A, 0x82, 0x09,
+ 0x98, 0x6B, 0x09,
+ 0xCA, 0x51, 0x09,
+ 0x03, 0xA9, 0x3C,
+ 0x3C, 0x8C, 0x3C,
+ 0x6A, 0x75, 0x3C,
+ 0x98, 0x5E, 0x3C,
+ 0xCA, 0x45, 0x3C,
+ 0x03, 0x9D, 0x6A,
+ 0x3C, 0x81, 0x6A,
+ 0x6A, 0x6A, 0x6A,
+ 0x98, 0x53, 0x6A,
+ 0xCA, 0x39, 0x6A,
+ 0x03, 0x92, 0x98,
+ 0x3C, 0x75, 0x98,
+ 0x6A, 0x5E, 0x98,
+ 0x98, 0x47, 0x98,
+ 0xCA, 0x2E, 0x98,
+ 0x03, 0x83, 0xD1,
+ 0x3C, 0x67, 0xD1,
+ 0x6A, 0x50, 0xD1,
+ 0x98, 0x39, 0xD1,
+ 0xCA, 0x20, 0xD1,
+ 0x14, 0xC7, 0x1B,
+ 0x4D, 0xAB, 0x1B,
+ 0x7B, 0x94, 0x1B,
+ 0xA9, 0x7D, 0x1B,
+ 0xDC, 0x63, 0x1B,
+ 0x14, 0xBA, 0x4D,
+ 0x4D, 0x9E, 0x4D,
+ 0x7B, 0x87, 0x4D,
+ 0xA9, 0x70, 0x4D,
+ 0xDC, 0x57, 0x4D,
+ 0x14, 0xAF, 0x7B,
+ 0x4D, 0x92, 0x7B,
+ 0x7B, 0x7B, 0x7B,
+ 0xA9, 0x64, 0x7B,
+ 0xDC, 0x4B, 0x7B,
+ 0x14, 0xA3, 0xA9,
+ 0x4D, 0x87, 0xA9,
+ 0x7B, 0x70, 0xA9,
+ 0xA9, 0x59, 0xA9,
+ 0xDC, 0x40, 0xA9,
+ 0x14, 0x95, 0xE2,
+ 0x4D, 0x79, 0xE2,
+ 0x7B, 0x62, 0xE2,
+ 0xA9, 0x4B, 0xE2,
+ 0xDC, 0x31, 0xE2,
+ 0x25, 0xD8, 0x2C,
+ 0x5E, 0xBB, 0x2C,
+ 0x8C, 0xA4, 0x2C,
+ 0xBA, 0x8D, 0x2C,
+ 0xED, 0x74, 0x2C,
+ 0x25, 0xCB, 0x5E,
+ 0x5E, 0xAF, 0x5E,
+ 0x8C, 0x98, 0x5E,
+ 0xBA, 0x81, 0x5E,
+ 0xED, 0x67, 0x5E,
+ 0x25, 0xC0, 0x8C,
+ 0x5E, 0xA3, 0x8C,
+ 0x8C, 0x8C, 0x8C,
+ 0xBA, 0x75, 0x8C,
+ 0xED, 0x5C, 0x8C,
+ 0x25, 0xB4, 0xBA,
+ 0x5E, 0x98, 0xBA,
+ 0x8C, 0x81, 0xBA,
+ 0xBA, 0x6A, 0xBA,
+ 0xED, 0x50, 0xBA,
+ 0x25, 0xA6, 0xF3,
+ 0x5E, 0x8A, 0xF3,
+ 0x8C, 0x73, 0xF3,
+ 0xBA, 0x5C, 0xF3,
+ 0xED, 0x42, 0xF3,
+ 0x35, 0xF6, 0x04,
+ 0x6E, 0xD9, 0x04,
+ 0x9C, 0xC2, 0x04,
+ 0xCA, 0xAB, 0x04,
+ 0xFD, 0x92, 0x04,
+ 0x35, 0xE8, 0x3C,
+ 0x6E, 0xCB, 0x3C,
+ 0x9C, 0xB4, 0x3C,
+ 0xCA, 0x9D, 0x3C,
+ 0xFD, 0x84, 0x3C,
+ 0x35, 0xDB, 0x6E,
+ 0x6E, 0xBF, 0x6E,
+ 0x9C, 0xA8, 0x6E,
+ 0xCA, 0x91, 0x6E,
+ 0xFD, 0x78, 0x6E,
+ 0x35, 0xD0, 0x9C,
+ 0x6E, 0xB3, 0x9C,
+ 0x9C, 0x9C, 0x9C,
+ 0xCA, 0x85, 0x9C,
+ 0xFD, 0x6C, 0x9C,
+ 0x35, 0xC4, 0xCA,
+ 0x6E, 0xA8, 0xCA,
+ 0x9C, 0x91, 0xCA,
+ 0xCA, 0x7A, 0xCA,
+ 0xFD, 0x61, 0xCA,
+ 0x7E, 0xE9, 0x13,
+ 0xAC, 0xD2, 0x13,
+ 0xDA, 0xBB, 0x13,
+ 0x45, 0xF7, 0x4B,
+ 0x7E, 0xDB, 0x4B,
+ 0xAC, 0xC4, 0x4B,
+ 0xDA, 0xAD, 0x4B,
+ 0x45, 0xEB, 0x7E,
+ 0x7E, 0xCE, 0x7E,
+ 0xAC, 0xB7, 0x7E,
+ 0xDA, 0xA0, 0x7E,
+ 0x45, 0xDF, 0xAC,
+ 0x7E, 0xC3, 0xAC,
+ 0xAC, 0xAC, 0xAC,
+ 0xDA, 0x95, 0xAC,
+ 0x45, 0xD4, 0xDA,
+ 0x7E, 0xB7, 0xDA,
+ 0xAC, 0xA0, 0xDA,
+ 0xDA, 0x89, 0xDA,
+ 0x8C, 0xF7, 0x22,
+ 0xBA, 0xE0, 0x22,
+ 0xE8, 0xC9, 0x22,
+ 0x8C, 0xE9, 0x59,
+ 0xBA, 0xD2, 0x59,
+ 0xE8, 0xBB, 0x59,
+ 0x53, 0xF9, 0x8C,
+ 0x8C, 0xDD, 0x8C,
+ 0xBA, 0xC6, 0x8C,
+ 0xE8, 0xAF, 0x8C,
+ 0x53, 0xEE, 0xBA,
+ 0x8C, 0xD1, 0xBA,
+ 0xBA, 0xBA, 0xBA,
+ 0xE8, 0xA3, 0xBA,
+ 0x53, 0xE2, 0xE8,
+ 0x8C, 0xC6, 0xE8,
+ 0xBA, 0xAF, 0xE8,
+ 0xE8, 0x98, 0xE8,
+ 0xC8, 0xEE, 0x30,
+ 0xF6, 0xD7, 0x30,
+ 0x9A, 0xF7, 0x67,
+ 0xC8, 0xE0, 0x67,
+ 0xF6, 0xC9, 0x67,
+ 0x9A, 0xEA, 0x9A,
+ 0xC8, 0xD3, 0x9A,
+ 0xF6, 0xBC, 0x9A,
+ 0x61, 0xFB, 0xC8,
+ 0x9A, 0xDF, 0xC8,
+ 0xC8, 0xC8, 0xC8,
+ 0xF6, 0xB1, 0xC8,
+ 0x61, 0xF0, 0xF6,
+ 0x9A, 0xD3, 0xF6,
+ 0xC8, 0xBC, 0xF6,
+ 0xF6, 0xA5, 0xF6,
+ 0xD5, 0xFB, 0x3D,
+ 0xD5, 0xED, 0x74,
+ 0xA7, 0xF7, 0xA7,
+ 0xD5, 0xE0, 0xA7,
+ 0xA7, 0xEC, 0xD5,
+ 0xD5, 0xD5, 0xD5,
+ 0xE1, 0xFA, 0x81,
+ 0xE1, 0xED, 0xB3,
+ 0xB3, 0xF8, 0xE1,
+ 0xE1, 0xE1, 0xE1,
+ 0xED, 0xF9, 0xBF,
+ 0xED, 0xED, 0xED,
+ 0xF8, 0xF8, 0xF8
+};
+
+static const uint32 s_yLookup[512] = {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000040, 0x00000000, 0x00000040, 0x00000000,
+ 0x00000040, 0x00000000, 0x00000040, 0x00000000,
+ 0x00000040, 0x00000000, 0x00000040, 0x00000040,
+ 0x00000040, 0x00000040, 0x00000040, 0x00000040,
+ 0x00000040, 0x00000040, 0x00400040, 0x00000040,
+ 0x00400040, 0x00000040, 0x00400040, 0x00000040,
+ 0x00400040, 0x00000040, 0x00400040, 0x00000040,
+ 0x00400040, 0x00400040, 0x00400040, 0x00400040,
+ 0x00400040, 0x00400040, 0x00400040, 0x00400040,
+ 0x00400040, 0x00400040, 0x00400040, 0x00400040,
+ 0x00400040, 0x00400040, 0x00400040, 0x00400040,
+ 0x00400040, 0x00400040, 0x00400080, 0x00400040,
+ 0x00400080, 0x00400040, 0x00400080, 0x00400040,
+ 0x00400080, 0x00400040, 0x00400080, 0x00400080,
+ 0x00400080, 0x00400080, 0x00400080, 0x00400080,
+ 0x00400080, 0x00400080, 0x00400080, 0x00400080,
+ 0x00800080, 0x00400080, 0x00800080, 0x00400080,
+ 0x00800080, 0x00400080, 0x00800080, 0x00400080,
+ 0x00800080, 0x00800080, 0x00800080, 0x00800080,
+ 0x00800080, 0x00800080, 0x00800080, 0x00800080,
+ 0x00800080, 0x00800080, 0x00800080, 0x00800080,
+ 0x00800080, 0x00800080, 0x00800080, 0x00800080,
+ 0x00800080, 0x00800080, 0x008000C0, 0x00800080,
+ 0x008000C0, 0x00800080, 0x008000C0, 0x00800080,
+ 0x008000C0, 0x00800080, 0x008000C0, 0x008000C0,
+ 0x008000C0, 0x008000C0, 0x008000C0, 0x008000C0,
+ 0x008000C0, 0x008000C0, 0x00C000C0, 0x008000C0,
+ 0x00C000C0, 0x008000C0, 0x00C000C0, 0x008000C0,
+ 0x00C000C0, 0x008000C0, 0x00C000C0, 0x00C000C0,
+ 0x00C000C0, 0x00C000C0, 0x00C000C0, 0x00C000C0,
+ 0x00C000C0, 0x00C000C0, 0x00C000C0, 0x00C000C0,
+ 0x00C000C0, 0x00C000C0, 0x00C000C0, 0x00C000C0,
+ 0x00C000C0, 0x00C000C0, 0x00C00100, 0x00C000C0,
+ 0x00C00100, 0x00C000C0, 0x00C00100, 0x00C000C0,
+ 0x00C00100, 0x00C000C0, 0x00C00100, 0x00C00100,
+ 0x00C00100, 0x00C00100, 0x00C00100, 0x00C00100,
+ 0x00C00100, 0x00C00100, 0x01000100, 0x00C00100,
+ 0x01000100, 0x00C00100, 0x01000100, 0x00C00100,
+ 0x01000100, 0x00C00100, 0x01000100, 0x01000100,
+ 0x01000100, 0x01000100, 0x01000100, 0x01000100,
+ 0x01000100, 0x01000100, 0x01000100, 0x01000100,
+ 0x01000100, 0x01000100, 0x01000100, 0x01000100,
+ 0x01000100, 0x01000100, 0x01000140, 0x01000100,
+ 0x01000140, 0x01000100, 0x01000140, 0x01000100,
+ 0x01000140, 0x01000140, 0x01000140, 0x01000140,
+ 0x01000140, 0x01000140, 0x01000140, 0x01000140,
+ 0x01400140, 0x01000140, 0x01400140, 0x01000140,
+ 0x01400140, 0x01000140, 0x01400140, 0x01000140,
+ 0x01400140, 0x01400140, 0x01400140, 0x01400140,
+ 0x01400140, 0x01400140, 0x01400140, 0x01400140,
+ 0x01400140, 0x01400140, 0x01400140, 0x01400140,
+ 0x01400140, 0x01400140, 0x01400180, 0x01400140,
+ 0x01400180, 0x01400140, 0x01400180, 0x01400140,
+ 0x01400180, 0x01400140, 0x01400180, 0x01400180,
+ 0x01400180, 0x01400180, 0x01400180, 0x01400180,
+ 0x01800180, 0x01400180, 0x01800180, 0x01400180,
+ 0x01800180, 0x01400180, 0x01800180, 0x01400180,
+ 0x01800180, 0x01800180, 0x01800180, 0x01800180,
+ 0x01800180, 0x01800180, 0x01800180, 0x01800180,
+ 0x01800180, 0x01800180, 0x01800180, 0x01800180,
+ 0x01800180, 0x01800180, 0x018001C0, 0x01800180,
+ 0x018001C0, 0x01800180, 0x018001C0, 0x01800180,
+ 0x018001C0, 0x018001C0, 0x018001C0, 0x018001C0,
+ 0x018001C0, 0x018001C0, 0x018001C0, 0x018001C0,
+ 0x01C001C0, 0x018001C0, 0x01C001C0, 0x018001C0,
+ 0x01C001C0, 0x018001C0, 0x01C001C0, 0x01C001C0,
+ 0x01C001C0, 0x01C001C0, 0x01C001C0, 0x01C001C0,
+ 0x01C001C0, 0x01C001C0, 0x01C001C0, 0x01C001C0,
+ 0x01C001C0, 0x01C001C0, 0x01C00200, 0x01C001C0,
+ 0x01C00200, 0x01C001C0, 0x01C00200, 0x01C001C0,
+ 0x01C00200, 0x01C001C0, 0x01C00200, 0x01C00200,
+ 0x01C00200, 0x01C00200, 0x01C00200, 0x01C00200,
+ 0x02000200, 0x01C00200, 0x02000200, 0x01C00200,
+ 0x02000200, 0x01C00200, 0x02000200, 0x02000200,
+ 0x02000200, 0x02000200, 0x02000200, 0x02000200,
+ 0x02000200, 0x02000200, 0x02000200, 0x02000200,
+ 0x02000200, 0x02000200, 0x02000240, 0x02000200,
+ 0x02000240, 0x02000200, 0x02000240, 0x02000200,
+ 0x02000240, 0x02000240, 0x02000240, 0x02000240,
+ 0x02000240, 0x02000240, 0x02400240, 0x02000240,
+ 0x02400240, 0x02000240, 0x02400240, 0x02000240,
+ 0x02400240, 0x02000240, 0x02400240, 0x02400240,
+ 0x02400240, 0x02400240, 0x02400240, 0x02400240,
+ 0x02400240, 0x02400240, 0x02400240, 0x02400240,
+ 0x02400280, 0x02400240, 0x02400280, 0x02400240,
+ 0x02400280, 0x02400240, 0x02400280, 0x02400280,
+ 0x02400280, 0x02400280, 0x02400280, 0x02400280,
+ 0x02800280, 0x02400280, 0x02800280, 0x02400280,
+ 0x02800280, 0x02400280, 0x02800280, 0x02800280,
+ 0x02800280, 0x02800280, 0x02800280, 0x02800280,
+ 0x02800280, 0x02800280, 0x02800280, 0x02800280,
+ 0x02800280, 0x02800280, 0x028002C0, 0x02800280,
+ 0x028002C0, 0x02800280, 0x028002C0, 0x02800280,
+ 0x028002C0, 0x028002C0, 0x028002C0, 0x028002C0,
+ 0x02C002C0, 0x028002C0, 0x02C002C0, 0x028002C0,
+ 0x02C002C0, 0x028002C0, 0x02C002C0, 0x02C002C0,
+ 0x02C002C0, 0x02C002C0, 0x02C002C0, 0x02C002C0,
+ 0x02C002C0, 0x02C002C0, 0x02C002C0, 0x02C002C0,
+ 0x02C00300, 0x02C002C0, 0x02C00300, 0x02C002C0,
+ 0x02C00300, 0x02C002C0, 0x02C00300, 0x02C00300,
+ 0x02C00300, 0x02C00300, 0x02C00300, 0x02C00300,
+ 0x03000300, 0x02C00300, 0x03000300, 0x02C00300,
+ 0x03000300, 0x03000300, 0x03000300, 0x03000300,
+ 0x03000300, 0x03000300, 0x03000300, 0x03000300,
+ 0x03000300, 0x03000300, 0x03000340, 0x03000300,
+ 0x03000340, 0x03000300, 0x03000340, 0x03000300,
+ 0x03000340, 0x03000340, 0x03000340, 0x03000340,
+ 0x03400340, 0x03000340, 0x03400340, 0x03000340,
+ 0x03400340, 0x03000340, 0x03400340, 0x03400340,
+ 0x03400340, 0x03400340, 0x03400340, 0x03400340,
+ 0x03400340, 0x03400340, 0x03400340, 0x03400340,
+ 0x03400380, 0x03400340, 0x03400380, 0x03400340,
+ 0x03400380, 0x03400380, 0x03400380, 0x03400380,
+ 0x03800380, 0x03400380, 0x03800380, 0x03400380,
+ 0x03800380, 0x03400380, 0x03800380, 0x03800380,
+ 0x03800380, 0x03800380, 0x03800380, 0x03800380,
+ 0x03800380, 0x03800380, 0x038003C0, 0x03800380,
+ 0x038003C0, 0x03800380, 0x038003C0, 0x03800380,
+ 0x038003C0, 0x038003C0, 0x038003C0, 0x038003C0,
+ 0x03C003C0, 0x038003C0, 0x03C003C0, 0x038003C0,
+ 0x03C003C0, 0x03C003C0, 0x03C003C0, 0x03C003C0,
+ 0x03C003C0, 0x03C003C0, 0x03C003C0, 0x03C003C0,
+ 0x03C003C0, 0x03C003C0, 0x03C003C0, 0x03C003C0,
+ 0x03C003C0, 0x03C003C0, 0x03C003C0, 0x03C003C0,
+ 0x03C003C0, 0x03C003C0, 0x03C003C0, 0x03C003C0
+};
+
+static const uint32 s_uLookup[512] = {
+ 0x00200020, 0x00200020, 0x00200020, 0x00200020,
+ 0x00200020, 0x00200020, 0x00200020, 0x00200020,
+ 0x00200020, 0x00200020, 0x00280020, 0x00200020,
+ 0x00280020, 0x00200020, 0x00280020, 0x00200020,
+ 0x00280020, 0x00200020, 0x00280020, 0x00280020,
+ 0x00280020, 0x00280020, 0x00280020, 0x00280020,
+ 0x00280020, 0x00280020, 0x00280020, 0x00280020,
+ 0x00280020, 0x00280028, 0x00280020, 0x00280028,
+ 0x00280020, 0x00280028, 0x00280020, 0x00280028,
+ 0x00280028, 0x00280028, 0x00280028, 0x00280028,
+ 0x00280028, 0x00280028, 0x00280028, 0x00280028,
+ 0x00280028, 0x00280028, 0x00280028, 0x00280028,
+ 0x00280028, 0x00280028, 0x00280028, 0x00280028,
+ 0x00280028, 0x00280028, 0x00280028, 0x00280028,
+ 0x00280028, 0x00280028, 0x00300028, 0x00280028,
+ 0x00300028, 0x00280028, 0x00300028, 0x00280028,
+ 0x00300028, 0x00280028, 0x00300028, 0x00280028,
+ 0x00300028, 0x00300028, 0x00300028, 0x00300028,
+ 0x00300028, 0x00300028, 0x00300028, 0x00300028,
+ 0x00300028, 0x00300028, 0x00300028, 0x00300028,
+ 0x00300028, 0x00300030, 0x00300028, 0x00300030,
+ 0x00300028, 0x00300030, 0x00300028, 0x00300030,
+ 0x00300028, 0x00300030, 0x00300028, 0x00300030,
+ 0x00300030, 0x00300030, 0x00300030, 0x00300030,
+ 0x00300030, 0x00300030, 0x00300030, 0x00300030,
+ 0x00300030, 0x00300030, 0x00300030, 0x00300030,
+ 0x00300030, 0x00300030, 0x00300030, 0x00300030,
+ 0x00300030, 0x00300030, 0x00300030, 0x00300030,
+ 0x00300030, 0x00300030, 0x00300030, 0x00300030,
+ 0x00300030, 0x00300030, 0x00380030, 0x00300030,
+ 0x00380030, 0x00300030, 0x00380030, 0x00300030,
+ 0x00380030, 0x00300030, 0x00380030, 0x00300030,
+ 0x00380030, 0x00300030, 0x00380030, 0x00300030,
+ 0x00380030, 0x00380030, 0x00380030, 0x00380030,
+ 0x00380030, 0x00380030, 0x00380030, 0x00380030,
+ 0x00380030, 0x00380030, 0x00380030, 0x00380030,
+ 0x00380030, 0x00380030, 0x00380030, 0x00380038,
+ 0x00380030, 0x00380038, 0x00380030, 0x00380038,
+ 0x00380030, 0x00380038, 0x00380030, 0x00380038,
+ 0x00380030, 0x00380038, 0x00380030, 0x00380038,
+ 0x00380038, 0x00380038, 0x00380038, 0x00380038,
+ 0x00380038, 0x00380038, 0x00380038, 0x00380038,
+ 0x00380038, 0x00380038, 0x00380038, 0x00380038,
+ 0x00380038, 0x00380038, 0x00380038, 0x00380038,
+ 0x00380038, 0x00380038, 0x00380038, 0x00380038,
+ 0x00380038, 0x00380038, 0x00380038, 0x00380038,
+ 0x00380038, 0x00380038, 0x00380038, 0x00380038,
+ 0x00380038, 0x00380038, 0x00380038, 0x00380038,
+ 0x00380038, 0x00380038, 0x00380038, 0x00380038,
+ 0x00380038, 0x00380038, 0x00380038, 0x00380038,
+ 0x00380038, 0x00380038, 0x00380038, 0x00380038,
+ 0x00380038, 0x00380038, 0x00380038, 0x00380038,
+ 0x00380038, 0x00380038, 0x00380038, 0x00380038,
+ 0x00380038, 0x00380038, 0x00380038, 0x00380038,
+ 0x00380038, 0x00380038, 0x00380038, 0x00380038,
+ 0x00380038, 0x00380038, 0x00380038, 0x00380038,
+ 0x00380038, 0x00380038, 0x00380038, 0x00380038,
+ 0x00380038, 0x00380038, 0x00380038, 0x00380038,
+ 0x00380038, 0x00380038, 0x00380038, 0x00380038,
+ 0x00380038, 0x00380038, 0x00380038, 0x00380038,
+ 0x00380038, 0x00380038, 0x00380038, 0x00380038,
+ 0x00380038, 0x00380038, 0x00380038, 0x00380038,
+ 0x00380038, 0x00380038, 0x00380038, 0x00380038,
+ 0x00380038, 0x00380038, 0x00380038, 0x00380038,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00080000, 0x00000000,
+ 0x00080000, 0x00000000, 0x00080000, 0x00000000,
+ 0x00080000, 0x00000000, 0x00080000, 0x00000000,
+ 0x00080000, 0x00000000, 0x00080000, 0x00000000,
+ 0x00080000, 0x00080000, 0x00080000, 0x00080000,
+ 0x00080000, 0x00080000, 0x00080000, 0x00080000,
+ 0x00080000, 0x00080000, 0x00080000, 0x00080000,
+ 0x00080000, 0x00080008, 0x00080000, 0x00080008,
+ 0x00080000, 0x00080008, 0x00080000, 0x00080008,
+ 0x00080000, 0x00080008, 0x00080000, 0x00080008,
+ 0x00080008, 0x00080008, 0x00080008, 0x00080008,
+ 0x00080008, 0x00080008, 0x00080008, 0x00080008,
+ 0x00080008, 0x00080008, 0x00080008, 0x00080008,
+ 0x00080008, 0x00080008, 0x00080008, 0x00080008,
+ 0x00080008, 0x00080008, 0x00080008, 0x00080008,
+ 0x00080008, 0x00080008, 0x00100008, 0x00080008,
+ 0x00100008, 0x00080008, 0x00100008, 0x00080008,
+ 0x00100008, 0x00080008, 0x00100008, 0x00080008,
+ 0x00100008, 0x00080008, 0x00100008, 0x00100008,
+ 0x00100008, 0x00100008, 0x00100008, 0x00100008,
+ 0x00100008, 0x00100008, 0x00100008, 0x00100008,
+ 0x00100008, 0x00100008, 0x00100008, 0x00100010,
+ 0x00100008, 0x00100010, 0x00100008, 0x00100010,
+ 0x00100008, 0x00100010, 0x00100008, 0x00100010,
+ 0x00100010, 0x00100010, 0x00100010, 0x00100010,
+ 0x00100010, 0x00100010, 0x00100010, 0x00100010,
+ 0x00100010, 0x00100010, 0x00100010, 0x00100010,
+ 0x00100010, 0x00100010, 0x00100010, 0x00100010,
+ 0x00100010, 0x00100010, 0x00100010, 0x00100010,
+ 0x00100010, 0x00100010, 0x00180010, 0x00100010,
+ 0x00180010, 0x00100010, 0x00180010, 0x00100010,
+ 0x00180010, 0x00100010, 0x00180010, 0x00100010,
+ 0x00180010, 0x00180010, 0x00180010, 0x00180010,
+ 0x00180010, 0x00180010, 0x00180010, 0x00180010,
+ 0x00180010, 0x00180010, 0x00180010, 0x00180018,
+ 0x00180010, 0x00180018, 0x00180010, 0x00180018,
+ 0x00180010, 0x00180018, 0x00180010, 0x00180018,
+ 0x00180018, 0x00180018, 0x00180018, 0x00180018,
+ 0x00180018, 0x00180018, 0x00180018, 0x00180018,
+ 0x00180018, 0x00180018, 0x00180018, 0x00180018,
+ 0x00180018, 0x00180018, 0x00180018, 0x00180018,
+ 0x00180018, 0x00180018, 0x00180018, 0x00180018,
+ 0x00200018, 0x00180018, 0x00200018, 0x00180018,
+ 0x00200018, 0x00180018, 0x00200018, 0x00180018,
+ 0x00200018, 0x00200018, 0x00200018, 0x00200018,
+ 0x00200018, 0x00200018, 0x00200018, 0x00200018,
+ 0x00200018, 0x00200018, 0x00200018, 0x00200020,
+ 0x00200018, 0x00200020, 0x00200018, 0x00200020,
+ 0x00200018, 0x00200020, 0x00200020, 0x00200020,
+ 0x00200020, 0x00200020, 0x00200020, 0x00200020,
+ 0x00200020, 0x00200020, 0x00200020, 0x00200020
+};
+
+static const uint32 s_vLookup[512] = {
+ 0x00030003, 0x00030003, 0x00030003, 0x00030003,
+ 0x00030003, 0x00030003, 0x00030003, 0x00030003,
+ 0x00030003, 0x00030003, 0x00030003, 0x00030004,
+ 0x00030003, 0x00030004, 0x00030003, 0x00030004,
+ 0x00030003, 0x00030004, 0x00030004, 0x00030004,
+ 0x00030004, 0x00030004, 0x00030004, 0x00030004,
+ 0x00030004, 0x00030004, 0x00030004, 0x00030004,
+ 0x00030004, 0x00040004, 0x00030004, 0x00040004,
+ 0x00030004, 0x00040004, 0x00030004, 0x00040004,
+ 0x00040004, 0x00040004, 0x00040004, 0x00040004,
+ 0x00040004, 0x00040004, 0x00040004, 0x00040004,
+ 0x00040004, 0x00040004, 0x00040004, 0x00040004,
+ 0x00040004, 0x00040004, 0x00040004, 0x00040004,
+ 0x00040004, 0x00040004, 0x00040004, 0x00040004,
+ 0x00040004, 0x00040005, 0x00040004, 0x00040005,
+ 0x00040004, 0x00040005, 0x00040004, 0x00040005,
+ 0x00040004, 0x00040005, 0x00040005, 0x00040005,
+ 0x00040005, 0x00040005, 0x00040005, 0x00040005,
+ 0x00040005, 0x00040005, 0x00040005, 0x00040005,
+ 0x00040005, 0x00050005, 0x00040005, 0x00050005,
+ 0x00040005, 0x00050005, 0x00040005, 0x00050005,
+ 0x00040005, 0x00050005, 0x00050005, 0x00050005,
+ 0x00050005, 0x00050005, 0x00050005, 0x00050005,
+ 0x00050005, 0x00050005, 0x00050005, 0x00050005,
+ 0x00050005, 0x00050005, 0x00050005, 0x00050005,
+ 0x00050005, 0x00050005, 0x00050005, 0x00050005,
+ 0x00050005, 0x00050005, 0x00050005, 0x00050005,
+ 0x00050005, 0x00050006, 0x00050005, 0x00050006,
+ 0x00050005, 0x00050006, 0x00050005, 0x00050006,
+ 0x00050005, 0x00050006, 0x00050006, 0x00050006,
+ 0x00050006, 0x00050006, 0x00050006, 0x00050006,
+ 0x00050006, 0x00050006, 0x00050006, 0x00050006,
+ 0x00050006, 0x00050006, 0x00050006, 0x00060006,
+ 0x00050006, 0x00060006, 0x00050006, 0x00060006,
+ 0x00050006, 0x00060006, 0x00050006, 0x00060006,
+ 0x00050006, 0x00060006, 0x00060006, 0x00060006,
+ 0x00060006, 0x00060006, 0x00060006, 0x00060006,
+ 0x00060006, 0x00060006, 0x00060006, 0x00060006,
+ 0x00060006, 0x00060006, 0x00060006, 0x00060006,
+ 0x00060006, 0x00060006, 0x00060006, 0x00060006,
+ 0x00060006, 0x00060006, 0x00060006, 0x00060006,
+ 0x00060006, 0x00060007, 0x00060006, 0x00060007,
+ 0x00060006, 0x00060007, 0x00060006, 0x00060007,
+ 0x00060006, 0x00060007, 0x00060006, 0x00060007,
+ 0x00060007, 0x00060007, 0x00060007, 0x00060007,
+ 0x00060007, 0x00060007, 0x00060007, 0x00060007,
+ 0x00060007, 0x00060007, 0x00060007, 0x00060007,
+ 0x00060007, 0x00070007, 0x00060007, 0x00070007,
+ 0x00060007, 0x00070007, 0x00060007, 0x00070007,
+ 0x00060007, 0x00070007, 0x00060007, 0x00070007,
+ 0x00060007, 0x00070007, 0x00070007, 0x00070007,
+ 0x00070007, 0x00070007, 0x00070007, 0x00070007,
+ 0x00070007, 0x00070007, 0x00070007, 0x00070007,
+ 0x00070007, 0x00070007, 0x00070007, 0x00070007,
+ 0x00070007, 0x00070007, 0x00070007, 0x00070007,
+ 0x00070007, 0x00070007, 0x00070007, 0x00070007,
+ 0x00070007, 0x00070007, 0x00070007, 0x00070007,
+ 0x00070007, 0x00070007, 0x00070007, 0x00070007,
+ 0x00070007, 0x00070007, 0x00070007, 0x00070007,
+ 0x00070007, 0x00070007, 0x00070007, 0x00070007,
+ 0x00070007, 0x00070007, 0x00070007, 0x00070007,
+ 0x00070007, 0x00070007, 0x00070007, 0x00070007,
+ 0x00070007, 0x00070007, 0x00070007, 0x00070007,
+ 0x00070007, 0x00070007, 0x00070007, 0x00070007,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000001, 0x00000000, 0x00000001,
+ 0x00000000, 0x00000001, 0x00000000, 0x00000001,
+ 0x00000000, 0x00000001, 0x00000000, 0x00000001,
+ 0x00000000, 0x00000001, 0x00000001, 0x00000001,
+ 0x00000001, 0x00000001, 0x00000001, 0x00000001,
+ 0x00000001, 0x00000001, 0x00000001, 0x00000001,
+ 0x00000001, 0x00000001, 0x00000001, 0x00000001,
+ 0x00000001, 0x00010001, 0x00000001, 0x00010001,
+ 0x00000001, 0x00010001, 0x00000001, 0x00010001,
+ 0x00000001, 0x00010001, 0x00000001, 0x00010001,
+ 0x00000001, 0x00010001, 0x00010001, 0x00010001,
+ 0x00010001, 0x00010001, 0x00010001, 0x00010001,
+ 0x00010001, 0x00010001, 0x00010001, 0x00010001,
+ 0x00010001, 0x00010001, 0x00010001, 0x00010001,
+ 0x00010001, 0x00010001, 0x00010001, 0x00010001,
+ 0x00010001, 0x00010001, 0x00010001, 0x00010001,
+ 0x00010001, 0x00010001, 0x00010001, 0x00010001,
+ 0x00010001, 0x00010002, 0x00010001, 0x00010002,
+ 0x00010001, 0x00010002, 0x00010001, 0x00010002,
+ 0x00010001, 0x00010002, 0x00010001, 0x00010002,
+ 0x00010002, 0x00010002, 0x00010002, 0x00010002,
+ 0x00010002, 0x00010002, 0x00010002, 0x00010002,
+ 0x00010002, 0x00010002, 0x00010002, 0x00010002,
+ 0x00010002, 0x00020002, 0x00010002, 0x00020002,
+ 0x00010002, 0x00020002, 0x00010002, 0x00020002,
+ 0x00010002, 0x00020002, 0x00020002, 0x00020002,
+ 0x00020002, 0x00020002, 0x00020002, 0x00020002,
+ 0x00020002, 0x00020002, 0x00020002, 0x00020002,
+ 0x00020002, 0x00020002, 0x00020002, 0x00020002,
+ 0x00020002, 0x00020002, 0x00020002, 0x00020002,
+ 0x00020002, 0x00020002, 0x00020002, 0x00020002,
+ 0x00020002, 0x00020003, 0x00020002, 0x00020003,
+ 0x00020002, 0x00020003, 0x00020002, 0x00020003,
+ 0x00020003, 0x00020003, 0x00020003, 0x00020003,
+ 0x00020003, 0x00020003, 0x00020003, 0x00020003,
+ 0x00020003, 0x00020003, 0x00020003, 0x00030003,
+ 0x00020003, 0x00030003, 0x00020003, 0x00030003,
+ 0x00020003, 0x00030003, 0x00030003, 0x00030003,
+ 0x00030003, 0x00030003, 0x00030003, 0x00030003,
+ 0x00030003, 0x00030003, 0x00030003, 0x00030003
+};
+
+} // End of namespace Image
+
+#endif
diff --git a/image/codecs/codec.cpp b/image/codecs/codec.cpp
index 6b0c7ebcfb..398e9c562c 100644
--- a/image/codecs/codec.cpp
+++ b/image/codecs/codec.cpp
@@ -20,6 +20,7 @@
*
*/
+#include "common/list.h"
#include "common/scummsys.h"
#include "image/codecs/codec.h"
@@ -44,6 +45,153 @@
namespace Image {
+namespace {
+
+/**
+ * Add a color to the QuickTime dither table check queue if it hasn't already been found.
+ */
+inline void addColorToQueue(uint16 color, uint16 index, byte *checkBuffer, Common::List<uint16> &checkQueue) {
+ if ((READ_UINT16(checkBuffer + color * 2) & 0xFF) == 0) {
+ // Previously unfound color
+ WRITE_UINT16(checkBuffer + color * 2, index);
+ checkQueue.push_back(color);
+ }
+}
+
+inline byte adjustColorRange(byte currentColor, byte correctColor, byte palColor) {
+ return CLIP<int>(currentColor - palColor + correctColor, 0, 255);
+}
+
+inline uint16 makeQuickTimeDitherColor(byte r, byte g, byte b) {
+ // RGB554
+ return ((r & 0xF8) << 6) | ((g & 0xF8) << 1) | (b >> 4);
+}
+
+} // End of anonymous namespace
+
+byte *Codec::createQuickTimeDitherTable(const byte *palette, uint colorCount) {
+ byte *buf = new byte[0x10000];
+ memset(buf, 0, 0x10000);
+
+ Common::List<uint16> checkQueue;
+
+ bool foundBlack = false;
+ bool foundWhite = false;
+
+ const byte *palPtr = palette;
+
+ // See what colors we have, and add them to the queue to check
+ for (uint i = 0; i < colorCount; i++) {
+ byte r = *palPtr++;
+ byte g = *palPtr++;
+ byte b = *palPtr++;
+ uint16 n = (i << 8) | 1;
+ uint16 col = makeQuickTimeDitherColor(r, g, b);
+
+ if (col == 0) {
+ // Special case for close-to-black
+ // The original did more here, but it effectively discarded the value
+ // due to a poor if-check (whole 16-bit value instead of lower 8-bits).
+ WRITE_UINT16(buf, n);
+ foundBlack = true;
+ } else if (col == 0x3FFF) {
+ // Special case for close-to-white
+ // The original did more here, but it effectively discarded the value
+ // due to a poor if-check (whole 16-bit value instead of lower 8-bits).
+ WRITE_UINT16(buf + 0x7FFE, n);
+ foundWhite = true;
+ } else {
+ // Previously unfound color
+ addColorToQueue(col, n, buf, checkQueue);
+ }
+ }
+
+ // More special handling for white
+ if (foundWhite)
+ checkQueue.push_front(0x3FFF);
+
+ // More special handling for black
+ if (foundBlack)
+ checkQueue.push_front(0);
+
+ // Go through the list of colors we have and match up similar colors
+ // to fill in the table as best as we can.
+ while (!checkQueue.empty()) {
+ uint16 col = checkQueue.front();
+ checkQueue.pop_front();
+ uint16 index = READ_UINT16(buf + col * 2);
+
+ uint32 x = col << 4;
+ if ((x & 0xFF) < 0xF0)
+ addColorToQueue((x + 0x10) >> 4, index, buf, checkQueue);
+ if ((x & 0xFF) >= 0x10)
+ addColorToQueue((x - 0x10) >> 4, index, buf, checkQueue);
+
+ uint32 y = col << 7;
+ if ((y & 0xFF00) < 0xF800)
+ addColorToQueue((y + 0x800) >> 7, index, buf, checkQueue);
+ if ((y & 0xFF00) >= 0x800)
+ addColorToQueue((y - 0x800) >> 7, index, buf, checkQueue);
+
+ uint32 z = col << 2;
+ if ((z & 0xFF00) < 0xF800)
+ addColorToQueue((z + 0x800) >> 2, index, buf, checkQueue);
+ if ((z & 0xFF00) >= 0x800)
+ addColorToQueue((z - 0x800) >> 2, index, buf, checkQueue);
+ }
+
+ // Contract the table back to just palette entries
+ for (int i = 0; i < 0x4000; i++)
+ buf[i] = READ_UINT16(buf + i * 2) >> 8;
+
+ // Now go through and distribute the error to three more pixels
+ byte *bufPtr = buf;
+ for (uint realR = 0; realR < 0x100; realR += 8) {
+ for (uint realG = 0; realG < 0x100; realG += 8) {
+ for (uint realB = 0; realB < 0x100; realB += 16) {
+ byte palIndex = *bufPtr;
+ byte r = realR;
+ byte g = realG;
+ byte b = realB;
+
+ byte palR = palette[palIndex * 3] & 0xF8;
+ byte palG = palette[palIndex * 3 + 1] & 0xF8;
+ byte palB = palette[palIndex * 3 + 2] & 0xF0;
+
+ r = adjustColorRange(r, realR, palR);
+ g = adjustColorRange(g, realG, palG);
+ b = adjustColorRange(b, realB, palB);
+ palIndex = buf[makeQuickTimeDitherColor(r, g, b)];
+ bufPtr[0x4000] = palIndex;
+
+ palR = palette[palIndex * 3] & 0xF8;
+ palG = palette[palIndex * 3 + 1] & 0xF8;
+ palB = palette[palIndex * 3 + 2] & 0xF0;
+
+ r = adjustColorRange(r, realR, palR);
+ g = adjustColorRange(g, realG, palG);
+ b = adjustColorRange(b, realB, palB);
+ palIndex = buf[makeQuickTimeDitherColor(r, g, b)];
+ bufPtr[0x8000] = palIndex;
+
+ palR = palette[palIndex * 3] & 0xF8;
+ palG = palette[palIndex * 3 + 1] & 0xF8;
+ palB = palette[palIndex * 3 + 2] & 0xF0;
+
+ r = adjustColorRange(r, realR, palR);
+ g = adjustColorRange(g, realG, palG);
+ b = adjustColorRange(b, realB, palB);
+ palIndex = buf[makeQuickTimeDitherColor(r, g, b)];
+ bufPtr[0xC000] = palIndex;
+
+ bufPtr++;
+ }
+ }
+ }
+
+ return buf;
+}
+
Codec *createBitmapCodec(uint32 tag, int width, int height, int bitsPerPixel) {
switch (tag) {
case SWAP_CONSTANT_32(0):
diff --git a/image/codecs/codec.h b/image/codecs/codec.h
index d87758e65e..5c072132d3 100644
--- a/image/codecs/codec.h
+++ b/image/codecs/codec.h
@@ -59,6 +59,20 @@ public:
virtual ~Codec() {}
/**
+ * A type of dithering.
+ */
+ enum DitherType {
+ /** Unknown */
+ kDitherTypeUnknown,
+
+ /** Video for Windows dithering */
+ kDitherTypeVFW,
+
+ /** QuickTime dithering */
+ kDitherTypeQT
+ };
+
+ /**
* Decode the frame for the given data and return a pointer to a surface
* containing the decoded frame.
*
@@ -86,6 +100,21 @@ public:
* Does the codec have a dirty palette?
*/
virtual bool hasDirtyPalette() const { return false; }
+
+ /**
+ * Can the codec dither down to 8bpp?
+ */
+ virtual bool canDither(DitherType type) const { return false; }
+
+ /**
+ * Activate dithering mode with a palette
+ */
+ virtual void setDither(DitherType type, const byte *palette) {}
+
+ /**
+ * Create a dither table, as used by QuickTime codecs.
+ */
+ static byte *createQuickTimeDitherTable(const byte *palette, uint colorCount);
};
/**
diff --git a/image/codecs/qtrle.cpp b/image/codecs/qtrle.cpp
index 94744efa5a..8a83cfa2bd 100644
--- a/image/codecs/qtrle.cpp
+++ b/image/codecs/qtrle.cpp
@@ -37,27 +37,45 @@ namespace Image {
QTRLEDecoder::QTRLEDecoder(uint16 width, uint16 height, byte bitsPerPixel) : Codec() {
_bitsPerPixel = bitsPerPixel;
+ _ditherPalette = 0;
+ _width = width;
+ _height = height;
+ _surface = 0;
+ _dirtyPalette = false;
+ _colorMap = 0;
// We need to ensure the width is a multiple of 4
+ _paddedWidth = width;
uint16 wMod = width % 4;
if (wMod != 0)
- width += 4 - wMod;
+ _paddedWidth += 4 - wMod;
+}
- _surface = new Graphics::Surface();
- _surface->create(width, height, getPixelFormat());
+QTRLEDecoder::~QTRLEDecoder() {
+ if (_surface) {
+ _surface->free();
+ delete _surface;
+ }
+
+ delete[] _colorMap;
+ delete[] _ditherPalette;
}
#define CHECK_STREAM_PTR(n) \
- if ((stream.pos() + n) > stream.size()) { \
- warning("QTRLE Problem: stream out of bounds (%d > %d)", stream.pos() + n, stream.size()); \
- return; \
- }
+ do { \
+ if ((stream.pos() + n) > stream.size()) { \
+ warning("QTRLE Problem: stream out of bounds (%d > %d)", stream.pos() + n, stream.size()); \
+ return; \
+ } \
+ } while (0)
#define CHECK_PIXEL_PTR(n) \
- if ((int32)pixelPtr + n > _surface->w * _surface->h) { \
- warning("QTRLE Problem: pixel ptr = %d, pixel limit = %d", pixelPtr + n, _surface->w * _surface->h); \
- return; \
- } \
+ do { \
+ if ((int32)pixelPtr + n > (int)_paddedWidth * _surface->h) { \
+ warning("QTRLE Problem: pixel ptr = %d, pixel limit = %d", pixelPtr + n, _paddedWidth * _surface->h); \
+ return; \
+ } \
+ } while (0)
void QTRLEDecoder::decode1(Common::SeekableReadStream &stream, uint32 rowPtr, uint32 linesToChange) {
uint32 pixelPtr = 0;
@@ -73,7 +91,7 @@ void QTRLEDecoder::decode1(Common::SeekableReadStream &stream, uint32 rowPtr, ui
if (skip & 0x80) {
linesToChange--;
- rowPtr += _surface->w;
+ rowPtr += _paddedWidth;
pixelPtr = rowPtr + 2 * (skip & 0x7f);
} else
pixelPtr += 2 * skip;
@@ -159,7 +177,7 @@ void QTRLEDecoder::decode2_4(Common::SeekableReadStream &stream, uint32 rowPtr,
}
}
- rowPtr += _surface->w;
+ rowPtr += _paddedWidth;
}
}
@@ -204,7 +222,7 @@ void QTRLEDecoder::decode8(Common::SeekableReadStream &stream, uint32 rowPtr, ui
}
}
- rowPtr += _surface->w;
+ rowPtr += _paddedWidth;
}
}
@@ -242,7 +260,7 @@ void QTRLEDecoder::decode16(Common::SeekableReadStream &stream, uint32 rowPtr, u
}
}
- rowPtr += _surface->w;
+ rowPtr += _paddedWidth;
}
}
@@ -288,7 +306,72 @@ void QTRLEDecoder::decode24(Common::SeekableReadStream &stream, uint32 rowPtr, u
}
}
- rowPtr += _surface->w;
+ rowPtr += _paddedWidth;
+ }
+}
+
+namespace {
+
+inline uint16 readDitherColor24(Common::ReadStream &stream) {
+ uint16 color = (stream.readByte() & 0xF8) << 6;
+ color |= (stream.readByte() & 0xF8) << 1;
+ color |= stream.readByte() >> 4;
+ return color;
+}
+
+} // End of anonymous namespace
+
+void QTRLEDecoder::dither24(Common::SeekableReadStream &stream, uint32 rowPtr, uint32 linesToChange) {
+ uint32 pixelPtr = 0;
+ byte *output = (byte *)_surface->getPixels();
+
+ static const uint16 colorTableOffsets[] = { 0x0000, 0xC000, 0x4000, 0x8000 };
+
+ // clone2727 thinks this should be startLine & 3, but the original definitely
+ // isn't doing this. Unless startLine & 3 is always 0? Kinda defeats the
+ // purpose of the compression then.
+ byte curColorTableOffset = 0;
+
+ while (linesToChange--) {
+ CHECK_STREAM_PTR(2);
+
+ byte rowOffset = stream.readByte() - 1;
+ pixelPtr = rowPtr + rowOffset;
+ uint16 colorTableOffset = colorTableOffsets[curColorTableOffset] + (rowOffset << 14);
+
+ for (int8 rleCode = stream.readSByte(); rleCode != -1; rleCode = stream.readSByte()) {
+ if (rleCode == 0) {
+ // there's another skip code in the stream
+ CHECK_STREAM_PTR(1);
+ pixelPtr += stream.readByte() - 1;
+ } else if (rleCode < 0) {
+ // decode the run length code
+ rleCode = -rleCode;
+
+ CHECK_STREAM_PTR(3);
+ CHECK_PIXEL_PTR(rleCode);
+
+ uint16 color = readDitherColor24(stream);
+
+ while (rleCode--) {
+ output[pixelPtr++] = _colorMap[colorTableOffset + color];
+ colorTableOffset += 0x4000;
+ }
+ } else {
+ CHECK_STREAM_PTR(rleCode * 3);
+ CHECK_PIXEL_PTR(rleCode);
+
+ // copy pixels directly to output
+ while (rleCode--) {
+ uint16 color = readDitherColor24(stream);
+ output[pixelPtr++] = _colorMap[colorTableOffset + color];
+ colorTableOffset += 0x4000;
+ }
+ }
+ }
+
+ rowPtr += _paddedWidth;
+ curColorTableOffset = (curColorTableOffset + 1) & 3;
}
}
@@ -336,13 +419,16 @@ void QTRLEDecoder::decode32(Common::SeekableReadStream &stream, uint32 rowPtr, u
}
}
- rowPtr += _surface->w;
+ rowPtr += _paddedWidth;
}
}
const Graphics::Surface *QTRLEDecoder::decodeFrame(Common::SeekableReadStream &stream) {
+ if (!_surface)
+ createSurface();
+
uint16 startLine = 0;
- uint16 height = _surface->h;
+ uint16 height = _height;
// check if this frame is even supposed to change
if (stream.size() < 8)
@@ -365,7 +451,7 @@ const Graphics::Surface *QTRLEDecoder::decodeFrame(Common::SeekableReadStream &s
stream.readUint16BE(); // Unknown
}
- uint32 rowPtr = _surface->w * startLine;
+ uint32 rowPtr = _paddedWidth * startLine;
switch (_bitsPerPixel) {
case 1:
@@ -388,7 +474,10 @@ const Graphics::Surface *QTRLEDecoder::decodeFrame(Common::SeekableReadStream &s
decode16(stream, rowPtr, height);
break;
case 24:
- decode24(stream, rowPtr, height);
+ if (_ditherPalette)
+ dither24(stream, rowPtr, height);
+ else
+ decode24(stream, rowPtr, height);
break;
case 32:
decode32(stream, rowPtr, height);
@@ -400,12 +489,10 @@ const Graphics::Surface *QTRLEDecoder::decodeFrame(Common::SeekableReadStream &s
return _surface;
}
-QTRLEDecoder::~QTRLEDecoder() {
- _surface->free();
- delete _surface;
-}
-
Graphics::PixelFormat QTRLEDecoder::getPixelFormat() const {
+ if (_ditherPalette)
+ return Graphics::PixelFormat::createFormatCLUT8();
+
switch (_bitsPerPixel) {
case 1:
case 33:
@@ -428,4 +515,31 @@ Graphics::PixelFormat QTRLEDecoder::getPixelFormat() const {
return Graphics::PixelFormat();
}
+bool QTRLEDecoder::canDither(DitherType type) const {
+ // Only 24-bit dithering is implemented at the moment
+ return type == kDitherTypeQT && _bitsPerPixel == 24;
+}
+
+void QTRLEDecoder::setDither(DitherType type, const byte *palette) {
+ assert(canDither(type));
+
+ _ditherPalette = new byte[256 * 3];
+ memcpy(_ditherPalette, palette, 256 * 3);
+ _dirtyPalette = true;
+
+ delete[] _colorMap;
+ _colorMap = createQuickTimeDitherTable(palette, 256);
+}
+
+void QTRLEDecoder::createSurface() {
+ if (_surface) {
+ _surface->free();
+ delete _surface;
+ }
+
+ _surface = new Graphics::Surface();
+ _surface->create(_paddedWidth, _height, getPixelFormat());
+ _surface->w = _width;
+}
+
} // End of namespace Image
diff --git a/image/codecs/qtrle.h b/image/codecs/qtrle.h
index b44a46c3e2..e345fbeedf 100644
--- a/image/codecs/qtrle.h
+++ b/image/codecs/qtrle.h
@@ -41,16 +41,29 @@ public:
const Graphics::Surface *decodeFrame(Common::SeekableReadStream &stream);
Graphics::PixelFormat getPixelFormat() const;
+ bool containsPalette() const { return _ditherPalette != 0; }
+ const byte *getPalette() { _dirtyPalette = false; return _ditherPalette; }
+ bool hasDirtyPalette() const { return _dirtyPalette; }
+ bool canDither(DitherType type) const;
+ void setDither(DitherType type, const byte *palette);
+
private:
byte _bitsPerPixel;
-
Graphics::Surface *_surface;
+ uint16 _width, _height;
+ uint32 _paddedWidth;
+ byte *_ditherPalette;
+ bool _dirtyPalette;
+ byte *_colorMap;
+
+ void createSurface();
void decode1(Common::SeekableReadStream &stream, uint32 rowPtr, uint32 linesToChange);
void decode2_4(Common::SeekableReadStream &stream, uint32 rowPtr, uint32 linesToChange, byte bpp);
void decode8(Common::SeekableReadStream &stream, uint32 rowPtr, uint32 linesToChange);
void decode16(Common::SeekableReadStream &stream, uint32 rowPtr, uint32 linesToChange);
void decode24(Common::SeekableReadStream &stream, uint32 rowPtr, uint32 linesToChange);
+ void dither24(Common::SeekableReadStream &stream, uint32 rowPtr, uint32 linesToChange);
void decode32(Common::SeekableReadStream &stream, uint32 rowPtr, uint32 linesToChange);
};
diff --git a/image/codecs/rpza.cpp b/image/codecs/rpza.cpp
index 5aeee7c90b..8d648e1cc1 100644
--- a/image/codecs/rpza.cpp
+++ b/image/codecs/rpza.cpp
@@ -32,43 +32,185 @@
namespace Image {
RPZADecoder::RPZADecoder(uint16 width, uint16 height) : Codec() {
- // We need to increase the surface size to a multiple of 4
- uint16 wMod = width % 4;
- if (wMod != 0)
- width += 4 - wMod;
-
- _surface = new Graphics::Surface();
- _surface->create(width, height, getPixelFormat());
+ _format = Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0);
+ _ditherPalette = 0;
+ _dirtyPalette = false;
+ _colorMap = 0;
+ _width = width;
+ _height = height;
+ _blockWidth = (width + 3) / 4;
+ _blockHeight = (height + 3) / 4;
+ _surface = 0;
}
RPZADecoder::~RPZADecoder() {
- _surface->free();
- delete _surface;
+ if (_surface) {
+ _surface->free();
+ delete _surface;
+ }
+
+ delete[] _ditherPalette;
}
#define ADVANCE_BLOCK() \
- pixelPtr += 4; \
- if (pixelPtr >= _surface->w) { \
- pixelPtr = 0; \
- rowPtr += _surface->w * 4; \
+ blockPtr += 4; \
+ if (blockPtr >= endPtr) { \
+ blockPtr += pitch * 3; \
+ endPtr = blockPtr + pitch; \
} \
totalBlocks--; \
if (totalBlocks < 0) \
error("rpza block counter just went negative (this should not happen)") \
-#define PUT_PIXEL(color) \
- if ((int32)blockPtr < _surface->w * _surface->h) \
- WRITE_UINT16((uint16 *)_surface->getPixels() + blockPtr, color); \
- blockPtr++
+struct BlockDecoderRaw {
+ static inline void drawFillBlock(uint16 *blockPtr, uint16 pitch, uint16 color, const byte *colorMap) {
+ blockPtr[0] = color;
+ blockPtr[1] = color;
+ blockPtr[2] = color;
+ blockPtr[3] = color;
+ blockPtr += pitch;
+ blockPtr[0] = color;
+ blockPtr[1] = color;
+ blockPtr[2] = color;
+ blockPtr[3] = color;
+ blockPtr += pitch;
+ blockPtr[0] = color;
+ blockPtr[1] = color;
+ blockPtr[2] = color;
+ blockPtr[3] = color;
+ blockPtr += pitch;
+ blockPtr[0] = color;
+ blockPtr[1] = color;
+ blockPtr[2] = color;
+ blockPtr[3] = color;
+ }
-const Graphics::Surface *RPZADecoder::decodeFrame(Common::SeekableReadStream &stream) {
+ static inline void drawRawBlock(uint16 *blockPtr, uint16 pitch, const uint16 (&colors)[16], const byte *colorMap) {
+ blockPtr[0] = colors[0];
+ blockPtr[1] = colors[1];
+ blockPtr[2] = colors[2];
+ blockPtr[3] = colors[3];
+ blockPtr += pitch;
+ blockPtr[0] = colors[4];
+ blockPtr[1] = colors[5];
+ blockPtr[2] = colors[6];
+ blockPtr[3] = colors[7];
+ blockPtr += pitch;
+ blockPtr[0] = colors[8];
+ blockPtr[1] = colors[9];
+ blockPtr[2] = colors[10];
+ blockPtr[3] = colors[11];
+ blockPtr += pitch;
+ blockPtr[0] = colors[12];
+ blockPtr[1] = colors[13];
+ blockPtr[2] = colors[14];
+ blockPtr[3] = colors[15];
+ }
+
+ static inline void drawBlendBlock(uint16 *blockPtr, uint16 pitch, const uint16 (&colors)[4], const byte (&indexes)[4], const byte *colorMap) {
+ blockPtr[0] = colors[(indexes[0] >> 6) & 0x03];
+ blockPtr[1] = colors[(indexes[0] >> 4) & 0x03];
+ blockPtr[2] = colors[(indexes[0] >> 2) & 0x03];
+ blockPtr[3] = colors[(indexes[0] >> 0) & 0x03];
+ blockPtr += pitch;
+ blockPtr[0] = colors[(indexes[1] >> 6) & 0x03];
+ blockPtr[1] = colors[(indexes[1] >> 4) & 0x03];
+ blockPtr[2] = colors[(indexes[1] >> 2) & 0x03];
+ blockPtr[3] = colors[(indexes[1] >> 0) & 0x03];
+ blockPtr += pitch;
+ blockPtr[0] = colors[(indexes[2] >> 6) & 0x03];
+ blockPtr[1] = colors[(indexes[2] >> 4) & 0x03];
+ blockPtr[2] = colors[(indexes[2] >> 2) & 0x03];
+ blockPtr[3] = colors[(indexes[2] >> 0) & 0x03];
+ blockPtr += pitch;
+ blockPtr[0] = colors[(indexes[3] >> 6) & 0x03];
+ blockPtr[1] = colors[(indexes[3] >> 4) & 0x03];
+ blockPtr[2] = colors[(indexes[3] >> 2) & 0x03];
+ blockPtr[3] = colors[(indexes[3] >> 0) & 0x03];
+ }
+};
+
+struct BlockDecoderDither {
+ static inline void drawFillBlock(byte *blockPtr, uint16 pitch, uint16 color, const byte *colorMap) {
+ const byte *mapOffset = colorMap + (color >> 1);
+ byte pixel1 = mapOffset[0x0000];
+ byte pixel2 = mapOffset[0x4000];
+ byte pixel3 = mapOffset[0x8000];
+ byte pixel4 = mapOffset[0xC000];
+
+ blockPtr[0] = pixel1;
+ blockPtr[1] = pixel2;
+ blockPtr[2] = pixel3;
+ blockPtr[3] = pixel4;
+ blockPtr += pitch;
+ blockPtr[0] = pixel4;
+ blockPtr[1] = pixel1;
+ blockPtr[2] = pixel2;
+ blockPtr[3] = pixel3;
+ blockPtr += pitch;
+ blockPtr[0] = pixel2;
+ blockPtr[1] = pixel3;
+ blockPtr[2] = pixel4;
+ blockPtr[3] = pixel1;
+ blockPtr += pitch;
+ blockPtr[0] = pixel3;
+ blockPtr[1] = pixel4;
+ blockPtr[2] = pixel1;
+ blockPtr[3] = pixel2;
+ }
+
+ static inline void drawRawBlock(byte *blockPtr, uint16 pitch, const uint16 (&colors)[16], const byte *colorMap) {
+ blockPtr[0] = colorMap[(colors[0] >> 1) + 0x0000];
+ blockPtr[1] = colorMap[(colors[1] >> 1) + 0x4000];
+ blockPtr[2] = colorMap[(colors[2] >> 1) + 0x8000];
+ blockPtr[3] = colorMap[(colors[3] >> 1) + 0xC000];
+ blockPtr += pitch;
+ blockPtr[0] = colorMap[(colors[4] >> 1) + 0xC000];
+ blockPtr[1] = colorMap[(colors[5] >> 1) + 0x0000];
+ blockPtr[2] = colorMap[(colors[6] >> 1) + 0x4000];
+ blockPtr[3] = colorMap[(colors[7] >> 1) + 0x8000];
+ blockPtr += pitch;
+ blockPtr[0] = colorMap[(colors[8] >> 1) + 0x4000];
+ blockPtr[1] = colorMap[(colors[9] >> 1) + 0x8000];
+ blockPtr[2] = colorMap[(colors[10] >> 1) + 0xC000];
+ blockPtr[3] = colorMap[(colors[11] >> 1) + 0x0000];
+ blockPtr += pitch;
+ blockPtr[0] = colorMap[(colors[12] >> 1) + 0x8000];
+ blockPtr[1] = colorMap[(colors[13] >> 1) + 0xC000];
+ blockPtr[2] = colorMap[(colors[14] >> 1) + 0x0000];
+ blockPtr[3] = colorMap[(colors[15] >> 1) + 0x4000];
+ }
+
+ static inline void drawBlendBlock(byte *blockPtr, uint16 pitch, const uint16 (&colors)[4], const byte (&indexes)[4], const byte *colorMap) {
+ blockPtr[0] = colorMap[(colors[(indexes[0] >> 6) & 0x03] >> 1) + 0x0000];
+ blockPtr[1] = colorMap[(colors[(indexes[0] >> 4) & 0x03] >> 1) + 0x4000];
+ blockPtr[2] = colorMap[(colors[(indexes[0] >> 2) & 0x03] >> 1) + 0x8000];
+ blockPtr[3] = colorMap[(colors[(indexes[0] >> 0) & 0x03] >> 1) + 0xC000];
+ blockPtr += pitch;
+ blockPtr[0] = colorMap[(colors[(indexes[1] >> 6) & 0x03] >> 1) + 0xC000];
+ blockPtr[1] = colorMap[(colors[(indexes[1] >> 4) & 0x03] >> 1) + 0x0000];
+ blockPtr[2] = colorMap[(colors[(indexes[1] >> 2) & 0x03] >> 1) + 0x4000];
+ blockPtr[3] = colorMap[(colors[(indexes[1] >> 0) & 0x03] >> 1) + 0x8000];
+ blockPtr += pitch;
+ blockPtr[0] = colorMap[(colors[(indexes[2] >> 6) & 0x03] >> 1) + 0x4000];
+ blockPtr[1] = colorMap[(colors[(indexes[2] >> 4) & 0x03] >> 1) + 0x8000];
+ blockPtr[2] = colorMap[(colors[(indexes[2] >> 2) & 0x03] >> 1) + 0xC000];
+ blockPtr[3] = colorMap[(colors[(indexes[2] >> 0) & 0x03] >> 1) + 0x0000];
+ blockPtr += pitch;
+ blockPtr[0] = colorMap[(colors[(indexes[3] >> 6) & 0x03] >> 1) + 0x8000];
+ blockPtr[1] = colorMap[(colors[(indexes[3] >> 4) & 0x03] >> 1) + 0xC000];
+ blockPtr[2] = colorMap[(colors[(indexes[3] >> 2) & 0x03] >> 1) + 0x0000];
+ blockPtr[3] = colorMap[(colors[(indexes[3] >> 0) & 0x03] >> 1) + 0x4000];
+ }
+};
+
+template<typename PixelInt, typename BlockDecoder>
+static inline void decodeFrameTmpl(Common::SeekableReadStream &stream, PixelInt *ptr, uint16 pitch, uint16 blockWidth, uint16 blockHeight, const byte *colorMap) {
uint16 colorA = 0, colorB = 0;
uint16 color4[4];
- uint32 rowPtr = 0;
- uint32 pixelPtr = 0;
- uint32 blockPtr = 0;
- uint32 rowInc = _surface->w - 4;
+ PixelInt *blockPtr = ptr;
+ PixelInt *endPtr = ptr + pitch;
uint16 ta;
uint16 tb;
@@ -88,7 +230,7 @@ const Graphics::Surface *RPZADecoder::decodeFrame(Common::SeekableReadStream &st
}
// Number of 4x4 blocks in frame
- int32 totalBlocks = ((_surface->w + 3) / 4) * ((_surface->h + 3) / 4);
+ int32 totalBlocks = blockWidth * blockHeight;
// Process chunk data
while ((uint32)stream.pos() < chunkSize) {
@@ -117,14 +259,9 @@ const Graphics::Surface *RPZADecoder::decodeFrame(Common::SeekableReadStream &st
break;
case 0xa0: // Fill blocks with one color
colorA = stream.readUint16BE();
+
while (numBlocks--) {
- blockPtr = rowPtr + pixelPtr;
- for (byte pixel_y = 0; pixel_y < 4; pixel_y++) {
- for (byte pixel_x = 0; pixel_x < 4; pixel_x++) {
- PUT_PIXEL(colorA);
- }
- blockPtr += rowInc;
- }
+ BlockDecoder::drawFillBlock(blockPtr, pitch, colorA, colorMap);
ADVANCE_BLOCK();
}
break;
@@ -136,10 +273,10 @@ const Graphics::Surface *RPZADecoder::decodeFrame(Common::SeekableReadStream &st
colorB = stream.readUint16BE();
// Sort out the colors
- color4[0] = colorB;
+ color4[0] = colorB & 0x7FFF;
color4[1] = 0;
color4[2] = 0;
- color4[3] = colorA;
+ color4[3] = colorA & 0x7FFF;
// Red components
ta = (colorA >> 10) & 0x1F;
@@ -160,42 +297,69 @@ const Graphics::Surface *RPZADecoder::decodeFrame(Common::SeekableReadStream &st
color4[2] |= ((21 * ta + 11 * tb) >> 5);
while (numBlocks--) {
- blockPtr = rowPtr + pixelPtr;
- for (byte pixel_y = 0; pixel_y < 4; pixel_y++) {
- byte index = stream.readByte();
- for (byte pixel_x = 0; pixel_x < 4; pixel_x++) {
- byte idx = (index >> (2 * (3 - pixel_x))) & 0x03;
- PUT_PIXEL(color4[idx]);
- }
- blockPtr += rowInc;
- }
+ byte indexes[4];
+ stream.read(indexes, 4);
+
+ BlockDecoder::drawBlendBlock(blockPtr, pitch, color4, indexes, colorMap);
ADVANCE_BLOCK();
}
break;
// Fill block with 16 colors
- case 0x00:
- blockPtr = rowPtr + pixelPtr;
- for (byte pixel_y = 0; pixel_y < 4; pixel_y++) {
- for (byte pixel_x = 0; pixel_x < 4; pixel_x++) {
- // We already have color of upper left pixel
- if (pixel_y != 0 || pixel_x != 0)
- colorA = stream.readUint16BE();
-
- PUT_PIXEL(colorA);
- }
- blockPtr += rowInc;
- }
+ case 0x00: {
+ uint16 colors[16];
+ colors[0] = colorA;
+
+ for (int i = 0; i < 15; i++)
+ colors[i + 1] = stream.readUint16BE();
+
+ BlockDecoder::drawRawBlock(blockPtr, pitch, colors, colorMap);
ADVANCE_BLOCK();
break;
+ }
// Unknown opcode
default:
error("Unknown opcode %02x in rpza chunk", opcode);
}
}
+}
+
+const Graphics::Surface *RPZADecoder::decodeFrame(Common::SeekableReadStream &stream) {
+ if (!_surface) {
+ _surface = new Graphics::Surface();
+
+ // Allocate enough space in the surface for the blocks
+ _surface->create(_blockWidth * 4, _blockHeight * 4, getPixelFormat());
+
+ // Adjust width/height to be the right ones
+ _surface->w = _width;
+ _surface->h = _height;
+ }
+
+ if (_colorMap)
+ decodeFrameTmpl<byte, BlockDecoderDither>(stream, (byte *)_surface->getPixels(), _surface->pitch, _blockWidth, _blockHeight, _colorMap);
+ else
+ decodeFrameTmpl<uint16, BlockDecoderRaw>(stream, (uint16 *)_surface->getPixels(), _surface->pitch / 2, _blockWidth, _blockHeight, _colorMap);
return _surface;
}
+bool RPZADecoder::canDither(DitherType type) const {
+ return type == kDitherTypeQT;
+}
+
+void RPZADecoder::setDither(DitherType type, const byte *palette) {
+ assert(canDither(type));
+
+ _ditherPalette = new byte[256 * 3];
+ memcpy(_ditherPalette, palette, 256 * 3);
+
+ _dirtyPalette = true;
+ _format = Graphics::PixelFormat::createFormatCLUT8();
+
+ delete[] _colorMap;
+ _colorMap = createQuickTimeDitherTable(palette, 256);
+}
+
} // End of namespace Image
diff --git a/image/codecs/rpza.h b/image/codecs/rpza.h
index d1dbbdb676..d62b385330 100644
--- a/image/codecs/rpza.h
+++ b/image/codecs/rpza.h
@@ -39,10 +39,22 @@ public:
~RPZADecoder();
const Graphics::Surface *decodeFrame(Common::SeekableReadStream &stream);
- Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0); }
+ Graphics::PixelFormat getPixelFormat() const { return _format; }
+
+ bool containsPalette() const { return _ditherPalette != 0; }
+ const byte *getPalette() { _dirtyPalette = false; return _ditherPalette; }
+ bool hasDirtyPalette() const { return _dirtyPalette; }
+ bool canDither(DitherType type) const;
+ void setDither(DitherType type, const byte *palette);
private:
+ Graphics::PixelFormat _format;
Graphics::Surface *_surface;
+ byte *_ditherPalette;
+ bool _dirtyPalette;
+ byte *_colorMap;
+ uint16 _width, _height;
+ uint16 _blockWidth, _blockHeight;
};
} // End of namespace Image
diff --git a/po/POTFILES b/po/POTFILES
index a33c8e3a83..6a865060fc 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -10,6 +10,7 @@ gui/KeysDialog.cpp
gui/launcher.cpp
gui/massadd.cpp
gui/options.cpp
+gui/recorderdialog.cpp
gui/saveload-dialog.cpp
gui/themebrowser.cpp
gui/ThemeEngine.cpp
diff --git a/po/be_BY.po b/po/be_BY.po
index 868ade94fb..37090afb42 100644
--- a/po/be_BY.po
+++ b/po/be_BY.po
@@ -1,5 +1,5 @@
# Belarusian translation for ScummVM.
-# Copyright (C) 2010-2014 ScummVM Team
+# Copyright (C) 2010-2015 The ScummVM Team
# This file is distributed under the same license as the ScummVM package.
# Ivan Lukyanov <greencis@mail.ru>, 2013-2014.
#
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.7.0git\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2014-10-04 00:58+0100\n"
+"POT-Creation-Date: 2015-06-30 20:57+0100\n"
"PO-Revision-Date: 2014-07-02 17:22+0300\n"
"Last-Translator: Ivan Lukyanov <greencis@mail.ru>\n"
"Language-Team: Ivan Lukyanov <greencis@mail.ru>\n"
@@ -55,10 +55,11 @@ msgstr "ÃÒÕàå"
#: gui/browser.cpp:75 gui/chooser.cpp:46 gui/KeysDialog.cpp:43
#: gui/launcher.cpp:351 gui/massadd.cpp:95 gui/options.cpp:1239
+#: gui/recorderdialog.cpp:70 gui/recorderdialog.cpp:156
#: gui/saveload-dialog.cpp:216 gui/saveload-dialog.cpp:276
-#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:922
+#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:931
#: gui/themebrowser.cpp:55 gui/fluidsynth-dialog.cpp:152
-#: engines/engine.cpp:452 backends/platform/wii/options.cpp:48
+#: engines/engine.cpp:483 backends/platform/wii/options.cpp:48
#: backends/events/default/default-events.cpp:196
#: backends/events/default/default-events.cpp:218
#: engines/drascula/saveload.cpp:49 engines/parallaction/saveload.cpp:274
@@ -71,9 +72,9 @@ msgid "Choose"
msgstr "°ÑàÐæì"
#: gui/gui-manager.cpp:117 backends/keymapper/remap-dialog.cpp:53
-#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
-#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
-#: engines/scumm/help.cpp:209
+#: engines/scumm/help.cpp:126 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:192
+#: engines/scumm/help.cpp:210
msgid "Close"
msgstr "·ÐÚàëæì"
@@ -89,7 +90,7 @@ msgstr "¿ÐÚÐ×Ðæì ÚÛÐÒöïâãàã"
msgid "Remap keys"
msgstr "¿ÕàÐßàë×ÝÐçëæì ÚÛÐÒöèë"
-#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:86
+#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:87
msgid "Toggle fullscreen"
msgstr "¿ÕàÐÚÛîçíÝÝÕ ÝÐ þÒÕáì íÚàÐÝ"
@@ -103,13 +104,13 @@ msgstr "¿àë×ÝÐçëæì"
#: gui/KeysDialog.cpp:42 gui/launcher.cpp:352 gui/launcher.cpp:1048
#: gui/launcher.cpp:1052 gui/massadd.cpp:92 gui/options.cpp:1240
-#: gui/saveload-dialog.cpp:923 gui/fluidsynth-dialog.cpp:153
-#: engines/engine.cpp:371 engines/engine.cpp:382
+#: gui/saveload-dialog.cpp:932 gui/fluidsynth-dialog.cpp:153
+#: engines/engine.cpp:402 engines/engine.cpp:413
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
#: engines/agos/animation.cpp:558 engines/drascula/saveload.cpp:49
-#: engines/groovie/script.cpp:399 engines/parallaction/saveload.cpp:274
-#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1825
+#: engines/groovie/script.cpp:408 engines/parallaction/saveload.cpp:274
+#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1834
#: engines/scumm/players/player_v3m.cpp:130
#: engines/scumm/players/player_v5m.cpp:108 engines/sky/compact.cpp:131
#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:524
@@ -479,7 +480,7 @@ msgstr ""
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -489,7 +490,7 @@ msgstr "ÂÐÚ"
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -525,6 +526,14 @@ msgstr "³íâÐï ÓãÛìÝï ÝÕ ßÐÔâàëÜÛöÒÐÕ ×ÐÓàã×Úã ×ÐåÐÒÐÝÝïþ ßàÐ× ÓÐÛÞþÝÐÕ ÜÕÝî."
msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr "ScummVM ÝÕ ×ÜÞÓ ×ÝÐÙáæö àãåÐÒöçÞÚ ÔÛï ×ÐßãáÚã ÐÑàÐÝÐÙ ÓãÛìÝö!"
+#: gui/launcher.cpp:1159
+msgid "Mass Add..."
+msgstr "ÈÜÐâ ÓãÛìÝïþ..."
+
+#: gui/launcher.cpp:1161
+msgid "Record..."
+msgstr ""
+
#: gui/massadd.cpp:79 gui/massadd.cpp:82
msgid "... progress ..."
msgstr "... èãÚÐî ..."
@@ -623,7 +632,7 @@ msgid "Special dithering modes supported by some games"
msgstr "ÁßÕæëïÛìÝëï àíÖëÜë àíÝÔíàëÝÓã, ßÐÔâàëÜÞþÒÐÝëï ÝÕÚÐâÞàëÜö ÓãÛìÝïÜö"
#: gui/options.cpp:760
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2249
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2298
msgid "Fullscreen mode"
msgstr "¿ÞþÝÐíÚàÐÝÝë àíÖëÜ"
@@ -943,6 +952,43 @@ msgstr ""
"ÂíÜÐ, ÐÑàÐÝÐï ÒÐÜö, ÝÕ ßÐÔâàëÜÛöÒÐÕ ÑïÓãçãî ÜÞÒã. ºÐÛö Òë ÖÐÔÐÕæÕ "
"ÒëÚÐàëáâÞþÒÐæì Óíâãî âíÜã, ÒÐÜ ÝÕÐÑåÞÔÝÐ áßÐçÐâÚã ßÕàÐÚÛîçëææÐ ÝÐ öÝèãî ÜÞÒã."
+#: gui/recorderdialog.cpp:64
+msgid "Recorder or Playback Gameplay"
+msgstr ""
+
+#: gui/recorderdialog.cpp:69 gui/recorderdialog.cpp:156
+#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
+msgid "Delete"
+msgstr "²ëÔÐÛöæì"
+
+#: gui/recorderdialog.cpp:71
+msgid "Record"
+msgstr ""
+
+#: gui/recorderdialog.cpp:72
+#, fuzzy
+msgid "Playback"
+msgstr "³ãÛïæì"
+
+#: gui/recorderdialog.cpp:74
+msgid "Edit"
+msgstr ""
+
+#: gui/recorderdialog.cpp:86 gui/recorderdialog.cpp:243
+#: gui/recorderdialog.cpp:253
+msgid "Author: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:87 gui/recorderdialog.cpp:244
+#: gui/recorderdialog.cpp:254
+msgid "Notes: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:155
+#, fuzzy
+msgid "Do you really want to delete this record?"
+msgstr "²ë áÐßàÐþÔë ÖÐÔÐÕæÕ ÒëÔÐÛöæì ÓíâÐ ×ÐåÐÒÐÝÝÕ?"
+
#: gui/saveload-dialog.cpp:167
msgid "List view"
msgstr "²ëÓÛïÔ áßöáã"
@@ -963,23 +1009,19 @@ msgstr "ÇÐá ÝÕ ×ÐßöáÐÝë"
msgid "No playtime saved"
msgstr "ÇÐá ÓãÛìÝö ÝÕ ×ÐßöáÐÝë"
-#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
-msgid "Delete"
-msgstr "²ëÔÐÛöæì"
-
#: gui/saveload-dialog.cpp:275
msgid "Do you really want to delete this saved game?"
msgstr "²ë áÐßàÐþÔë ÖÐÔÐÕæÕ ÒëÔÐÛöæì ÓíâÐ ×ÐåÐÒÐÝÝÕ?"
-#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:875
+#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:884
msgid "Date: "
msgstr "´ÐâÐ: "
-#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:881
+#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:890
msgid "Time: "
msgstr "ÇÐá: "
-#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:889
+#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:898
msgid "Playtime: "
msgstr "ÇÐá ÓãÛìÝö: "
@@ -995,19 +1037,19 @@ msgstr "½ÐáâãßÝë"
msgid "Prev"
msgstr "¿ÐßïàíÔÝö"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "New Save"
msgstr "½ÞÒÐÕ ×ÐåÐÒÐÝÝÕ"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "Create a new save game"
msgstr "ÁâÒÐàëæì ÝÞÒë ×Ðßöá ÓãÛìÝö"
-#: gui/saveload-dialog.cpp:868
+#: gui/saveload-dialog.cpp:877
msgid "Name: "
msgstr "½Ð×ÒÐ: "
-#: gui/saveload-dialog.cpp:940
+#: gui/saveload-dialog.cpp:949
#, c-format
msgid "Enter a description for slot %d:"
msgstr "ÃÒïÔ×öæÕ ÐßöáÐÝÝÕ áÛÞâÐ %d:"
@@ -1158,7 +1200,7 @@ msgstr "¿àÐßãáæöæì àÐÔÞÚ"
msgid "Error running game:"
msgstr "¿ÐÜëÛÚÐ ×ÐßãáÚã ÓãÛìÝö:"
-#: base/main.cpp:536
+#: base/main.cpp:554
msgid "Could not find any engine capable of running the selected game"
msgstr "½Õ ÜÐÓã ×ÝÐÙáæö àãåÐÒöçÞÚ ÔÛï ×ÐßãáÚã ÐÑàÐÝÐÙ ÓãÛìÝö"
@@ -1276,7 +1318,7 @@ msgstr "³~Ð~ÛÞþÝÐÕ ÜÕÝî"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:803
#: engines/cruise/menu.cpp:212 engines/drascula/saveload.cpp:336
#: engines/dreamweb/saveload.cpp:261 engines/neverhood/menumodule.cpp:873
-#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:758
+#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:759
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save game:"
msgstr "·ÐåÐÒÐæì ÓãÛìÝî:"
@@ -1289,7 +1331,7 @@ msgstr "·ÐåÐÒÐæì ÓãÛìÝî:"
#: engines/agi/saveload.cpp:803 engines/cruise/menu.cpp:212
#: engines/drascula/saveload.cpp:336 engines/dreamweb/saveload.cpp:261
#: engines/neverhood/menumodule.cpp:873 engines/pegasus/pegasus.cpp:377
-#: engines/sci/engine/kfile.cpp:758 engines/scumm/dialogs.cpp:188
+#: engines/sci/engine/kfile.cpp:759 engines/scumm/dialogs.cpp:188
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save"
msgstr "·ÐåÐÒÐæì"
@@ -1328,23 +1370,23 @@ msgstr "~°~ÔÜÕÝÐ"
msgid "~K~eys"
msgstr "~º~ÛÐÒöèë"
-#: engines/engine.cpp:245
+#: engines/engine.cpp:276
msgid "Could not initialize color format."
msgstr "½Õ ÜÐÓã öÝöæëïÛö×ÐÒÐæì äÐàÜÐâ ÚÞÛÕàã."
-#: engines/engine.cpp:253
+#: engines/engine.cpp:284
msgid "Could not switch to video mode: '"
msgstr "½Õ ÐâàëÜÐÛÐáï ßÕàÐÚÛîçëæì ÒöÔíÐàíÖëÜ: '"
-#: engines/engine.cpp:262
+#: engines/engine.cpp:293
msgid "Could not apply aspect ratio setting."
msgstr "½Õ ÐâàëÜÐÛÐáï ÒëÚÐàëáâÐæì ÚÐàíÚæëî áãÐÔÝÞáöÝ ÑÐÚÞþ."
-#: engines/engine.cpp:267
+#: engines/engine.cpp:298
msgid "Could not apply fullscreen setting."
msgstr "½Õ ÜÐÓã þÖëæì ßÞþÝÐíÚàÐÝÝë àíÖëÜ."
-#: engines/engine.cpp:367
+#: engines/engine.cpp:398
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1358,7 +1400,7 @@ msgstr ""
"ÝÐ ÖÞàáâÚö ÔëáÚ. ¿ÐÔàÐÑï×ÝÐáæö ÜÞÖÝÐ ×ÝÐÙáæö þ\n"
"äÐÙÛÕ README."
-#: engines/engine.cpp:378
+#: engines/engine.cpp:409
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1373,7 +1415,7 @@ msgstr ""
"×'ïÒöææÐ Üã×ëÚÐ. ¿ÐÔàÐÑï×ÝÐáæö ÜÞÖÝÐ ×ÝÐÙáæö þ\n"
"äÐÙÛÕ README."
-#: engines/engine.cpp:436
+#: engines/engine.cpp:467
#, c-format
msgid ""
"Gamestate load failed (%s)! Please consult the README for basic information, "
@@ -1383,7 +1425,7 @@ msgstr ""
"README ×Ð ÑÐ×ÐÒÐÙ öÝäÐàÜÐæëïÙ, Ð âÐÚáÐÜÐ öÝáâàãÚæëïÜö ßàÐ âÞÕ, ïÚ ÐâàëÜÐæì "
"ÔÐÛÕÙèãî ÔÐßÐÜÞÓã."
-#: engines/engine.cpp:449
+#: engines/engine.cpp:480
msgid ""
"WARNING: The game you are about to start is not yet fully supported by "
"ScummVM. As such, it is likely to be unstable, and any saves you make might "
@@ -1393,7 +1435,7 @@ msgstr ""
"ScummVM æÐÛÚÐÜ. ÏÝÐ, åãâçíÙ ×Ð þáñ, ÝÕ ÑãÔ×Õ ßàÐæÐÒÐæì áâÐÑöÛìÝÐ, ö "
"×ÐåÐÒÐÝÝö ÓãÛìÝïþ ÜÞÓãæì ÝÕ ßàÐæÐÒÐæì ã ÑãÔãçëå ÒÕàáöïå ScummVM."
-#: engines/engine.cpp:452
+#: engines/engine.cpp:483
msgid "Start anyway"
msgstr "Ãáñ ÐÔÝÞ ×Ðßãáæöæì"
@@ -1603,11 +1645,11 @@ msgstr "ÀíÖëÜ âÐçßÐÔÐ þÚÛîçÐÝë."
msgid "Touchpad mode disabled."
msgstr "ÀíÖëÜ âÐçßÐÔÐ ÒëÚÛîçÐÝë."
-#: backends/platform/maemo/maemo.cpp:209
+#: backends/platform/maemo/maemo.cpp:208
msgid "Click Mode"
msgstr "ÀíÖëÜ ßáâàëçÚö"
-#: backends/platform/maemo/maemo.cpp:215
+#: backends/platform/maemo/maemo.cpp:214
#: backends/platform/symbian/src/SymbianActions.cpp:42
#: backends/platform/wince/CEActionsPocket.cpp:60
#: backends/platform/wince/CEActionsSmartphone.cpp:43
@@ -1615,11 +1657,11 @@ msgstr "ÀíÖëÜ ßáâàëçÚö"
msgid "Left Click"
msgstr "»ÕÒÐï ßáâàëçÚÐ"
-#: backends/platform/maemo/maemo.cpp:218
+#: backends/platform/maemo/maemo.cpp:217
msgid "Middle Click"
msgstr "ÁïàíÔÝïï ßáâàëçÚÐ"
-#: backends/platform/maemo/maemo.cpp:221
+#: backends/platform/maemo/maemo.cpp:220
#: backends/platform/symbian/src/SymbianActions.cpp:43
#: backends/platform/wince/CEActionsSmartphone.cpp:44
#: backends/platform/tizen/form.cpp:267
@@ -1656,19 +1698,19 @@ msgctxt "lowres"
msgid "Normal (no scaling)"
msgstr "±Õ× ßÐÒÕÛöçíÝÝï"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2148
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2197
msgid "Enabled aspect ratio correction"
msgstr "ºÐàíÚæëï áãÐÔÝÞáöÝ ÑÐÚÞþ ãÚÛîçÐÝÐ"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2154
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2203
msgid "Disabled aspect ratio correction"
msgstr "ºÐàíÚæëï áãÐÔÝÞáöÝ ÑÐÚÞþ ÒëÚÛîçÐÝÐ"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2209
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2258
msgid "Active graphics filter:"
msgstr "°ÚâëþÝë ÓàÐäöçÝë äöÛìâà:"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2251
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2300
msgid "Windowed mode"
msgstr "°ÚÞÝÝë àíÖëÜ"
@@ -1727,8 +1769,8 @@ msgstr "ÅãâÚö àíÖëÜ"
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
#: backends/events/default/default-events.cpp:218
-#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:82
-#: engines/scumm/help.cpp:84
+#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:83
+#: engines/scumm/help.cpp:85
msgid "Quit"
msgstr "²ëåÐÔ"
@@ -1748,7 +1790,7 @@ msgstr "²öàâãÐÛìÝÐï ÚÛÐÒöïâãàÐ"
msgid "Key mapper"
msgstr "¿àë×ÝÐçíÝÝÕ ÚÛÐÒöè"
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
msgid "Do you want to quit ?"
msgstr "²ë áÐßàÐþÔë ÖÐÔÐÕæÕ ÒëÙáæö?"
@@ -2083,35 +2125,56 @@ msgstr "¿áâàëçÚö þÚÛîçÐÝë"
msgid "Clicking Disabled"
msgstr "¿áâàëçÚö ÒëÚÛîçÐÝë"
-#: engines/agi/detection.cpp:142 engines/drascula/detection.cpp:302
+#: engines/agi/detection.cpp:147 engines/drascula/detection.cpp:302
#: engines/dreamweb/detection.cpp:47 engines/neverhood/detection.cpp:160
#: engines/sci/detection.cpp:394 engines/toltecs/detection.cpp:200
-#: engines/zvision/detection.cpp:103
+#: engines/zvision/detection.cpp:246
msgid "Use original save/load screens"
msgstr "²ëÚÐàëáâÞþÒÐæì ÐàëÓöÝÐÛìÝëï íÚàÐÝë ×Ðßöáã/çëâÐÝÝö ÓãÛìÝö"
-#: engines/agi/detection.cpp:143 engines/drascula/detection.cpp:303
+#: engines/agi/detection.cpp:148 engines/drascula/detection.cpp:303
#: engines/dreamweb/detection.cpp:48 engines/neverhood/detection.cpp:161
#: engines/sci/detection.cpp:395 engines/toltecs/detection.cpp:201
-#: engines/zvision/detection.cpp:104
+#: engines/zvision/detection.cpp:247
msgid "Use the original save/load screens, instead of the ScummVM ones"
msgstr ""
"²ëÚÐàëáâÞþÒÐæì ÐàëÓöÝÐÛìÝëï íÚàÐÝë ×Ðßöáã ö ×ÐåÐÒÐÝÝï ÓãÛìÝö ×ÐÜÕáâ "
"×àÞÑÛÕÝëå ã ScummVM"
+#: engines/agi/detection.cpp:157
+#, fuzzy
+msgid "Use an alternative palette"
+msgstr "²ëÚÐàëáâÞþÒÐæì ÐÛìâíàÝÐâëþÝë þáâãß (âÞÛìÚö ÔÛï CD ÒÕàáöö ÓãÛìÝö)"
+
+#: engines/agi/detection.cpp:158
+msgid ""
+"Use an alternative palette, common for all Amiga games. This was the old "
+"behavior"
+msgstr ""
+
+#: engines/agi/detection.cpp:167
+#, fuzzy
+msgid "Mouse support"
+msgstr "¿ÐÔâàëÜÚÐ ßàÞßãáÚÐþ"
+
+#: engines/agi/detection.cpp:168
+msgid ""
+"Enables mouse support. Allows to use mouse for movement and in game menus."
+msgstr ""
+
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore game:"
msgstr "Ã×ÝÐÒöæì ÓãÛìÝî:"
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore"
msgstr "Ã×ÝÐÒöæì"
-#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2368
+#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2377
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -2122,7 +2185,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2361
+#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2370
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -2133,7 +2196,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2379
+#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2388
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -2149,12 +2212,12 @@ msgstr ""
msgid "Cutscene file '%s' not found!"
msgstr "ÄÐÙÛ ×ÐáâÐþÚö '%s' ÝÕ ×ÝÞÙÔ×ÕÝë!"
-#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:81
+#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:101
#, fuzzy
msgid "Color Blind Mode"
msgstr "ÀíÖëÜ ßáâàëçÚö"
-#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:82
+#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:102
msgid "Enable Color Blind Mode by default"
msgstr ""
@@ -2205,7 +2268,7 @@ msgstr "ÅãâÚö àíÖëÜ ÒöÔíÐ"
msgid "Play movies at an increased speed"
msgstr "¿àÐÙÓàÐÒÐÕ ÒöÔíÐ ÝÐ ßÐÒïÛöçÐÝÐÙ åãâÚÐáæö"
-#: engines/groovie/script.cpp:399
+#: engines/groovie/script.cpp:408
msgid "Failed to save game"
msgstr "½Õ ÐâàëÜÐÛÐáï ×ÐåÐÒÐæì ÓãÛìÝî"
@@ -2503,12 +2566,12 @@ msgid "Use an alternative game intro (CD version only)"
msgstr "²ëÚÐàëáâÞþÒÐæì ÐÛìâíàÝÐâëþÝë þáâãß (âÞÛìÚö ÔÛï CD ÒÕàáöö ÓãÛìÝö)"
#: engines/sci/detection.cpp:374
-msgid "EGA undithering"
-msgstr "EGA ÑÕ× àÐáâàã"
+msgid "Skip EGA dithering pass (full color backgrounds)"
+msgstr ""
#: engines/sci/detection.cpp:375
-msgid "Enable undithering in EGA games"
-msgstr "ÃÚÛîçÐÕ àíÖëÜ ÑÕ× àÐáâàÐÒÐÝÝï þ EGA ÓãÛìÝïå"
+msgid "Skip dithering pass in EGA games, graphics are shown with full colors"
+msgstr ""
#: engines/sci/detection.cpp:384
msgid "Prefer digital sound effects"
@@ -2584,12 +2647,14 @@ msgstr "³ãÛìÝï áßëÝÕÝÐ. ½ÐæöáÝöæÕ ßàÐÑÕÛ, ÚÐÑ ßàÐæïÓÝãæì."
#. "Moechten Sie wirklich neu starten? (J/N)J"
#. Will react to J as 'Yes'
#: engines/scumm/dialogs.cpp:183
-msgid "Are you sure you want to restart? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to restart? (Y/N)Y"
msgstr "²ë þßíþÝÕÝë, èâÞ ÖÐÔÐÕæÕ ßÐçÐæì ö×ÝÞþ? (Y/N)"
#. I18N: you may specify 'Yes' symbol at the end of the line. See previous comment
#: engines/scumm/dialogs.cpp:185
-msgid "Are you sure you want to quit? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to quit? (Y/N)Y"
msgstr "²ë þßíþÝÕÝë, èâÞ ÖÐÔÐÕæÕ ÒëÙáæö? (Y/N)"
#: engines/scumm/dialogs.cpp:190
@@ -2677,516 +2742,541 @@ msgstr "¿àÐÚâëÚÐÝâ"
msgid "Expert"
msgstr "ÍÚáßÕàâ"
-#: engines/scumm/help.cpp:73
+#: engines/scumm/help.cpp:74
msgid "Common keyboard commands:"
msgstr "°ÓãÛìÝëï ÚÛÐÒöïâãàÝëï ÚÐÜÐÝÔë:"
-#: engines/scumm/help.cpp:74
+#: engines/scumm/help.cpp:75
msgid "Save / Load dialog"
msgstr "´ëïÛÞÓ ×Ðßöáã / çëâÐÝÝï"
-#: engines/scumm/help.cpp:76
+#: engines/scumm/help.cpp:77
msgid "Skip line of text"
msgstr "¿àÐßãáæöæì àÐÔÞÚ"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Esc"
msgstr "Esc"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Skip cutscene"
msgstr "¿àÐßãáæöæì ×ÐáâÐþÚã"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Space"
msgstr "¿àÐÑÕÛ"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Pause game"
msgstr "¿Ðþ×Ð ÓãÛìÝö"
-#: engines/scumm/help.cpp:79 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:95 engines/scumm/help.cpp:96
-#: engines/scumm/help.cpp:97 engines/scumm/help.cpp:98
-#: engines/scumm/help.cpp:99 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:96 engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98 engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Ctrl"
msgstr "Ctrl"
-#: engines/scumm/help.cpp:79
+#: engines/scumm/help.cpp:80
msgid "Load game state 1-10"
msgstr "·ÐÓàã×öæì ÓãÛìÝî 1-10"
-#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:81 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Alt"
msgstr "Alt"
-#: engines/scumm/help.cpp:80
+#: engines/scumm/help.cpp:81
msgid "Save game state 1-10"
msgstr "·ÐåÐÒÐæì ÓãÛìÝî 1-10"
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:90
msgid "Enter"
msgstr "ÃÒÞÔ"
-#: engines/scumm/help.cpp:87
+#: engines/scumm/help.cpp:88
msgid "Music volume up / down"
msgstr "³ãçÝÐáæì Üã×ëÚö ßÐÒïÛöçëæì / ßÐÜÕÝèëæì"
-#: engines/scumm/help.cpp:88
+#: engines/scumm/help.cpp:89
msgid "Text speed slower / faster"
msgstr "ÅãâÚÐáæì âíÚáâã åãâçíÙ / ßÐÒÞÛìÝÕÙ"
-#: engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:90
msgid "Simulate left mouse button"
msgstr "ÍÜãÛïæëï ÛÕÒÐÙ ÚÛÐÒöèë Üëèë"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Tab"
msgstr "Tab"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Simulate right mouse button"
msgstr "ÍÜãÛïæëï ßàÐÒÐÙ ÚÛÐÒöèë Üëèë"
-#: engines/scumm/help.cpp:93
+#: engines/scumm/help.cpp:94
msgid "Special keyboard commands:"
msgstr "ÁßÕæëïÛìÝëï ÚÛÐÒöïâãàÝëï ÚÐÜÐÝÔë:"
-#: engines/scumm/help.cpp:94
+#: engines/scumm/help.cpp:95
msgid "Show / Hide console"
msgstr "¿ÐÚÐ×Ðæì / ¿àëÑàÐæì ÚÐÝáÞÛì"
-#: engines/scumm/help.cpp:95
+#: engines/scumm/help.cpp:96
msgid "Start the debugger"
msgstr "·ÐßãáÚ ÐÔÛÐÔçëÚÐ"
-#: engines/scumm/help.cpp:96
+#: engines/scumm/help.cpp:97
msgid "Show memory consumption"
msgstr "¿ÐÚÐ×Ðæì áßÐÖëÒÐÝÝÕ ßÐÜïæö"
-#: engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98
msgid "Run in fast mode (*)"
msgstr "·Ðßãáæöæì åãâÚö àíÖëÜ (*)"
-#: engines/scumm/help.cpp:98
+#: engines/scumm/help.cpp:99
msgid "Run in really fast mode (*)"
msgstr "·Ðßãáæöæì ÒÕÛìÜö åãâÚö àíÖëÜ (*)"
-#: engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100
msgid "Toggle mouse capture"
msgstr "¿ÕàÐÚÛîçíÝÝÕ ßÕàÐåÞßã Üëèë"
-#: engines/scumm/help.cpp:100
+#: engines/scumm/help.cpp:101
msgid "Switch between graphics filters"
msgstr "¿ÕàÐÚÛîçíÝÝÕ ßÐÜöÖ ÓàÐäöçÝëÜö äöÛìâàÐÜö"
-#: engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102
msgid "Increase / Decrease scale factor"
msgstr "¿ÐÒïÛöçëæì/ßÐÜÕÝèëæì ÜÐèâÐÑ"
-#: engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:103
msgid "Toggle aspect-ratio correction"
msgstr "¿ÕàÐÚÛîçíÝÝÕ ÚÐàíÚæëö áãÐÔÝÞáöÝ ÑÐÚÞþ"
-#: engines/scumm/help.cpp:107
+#: engines/scumm/help.cpp:108
msgid "* Note that using ctrl-f and"
msgstr "* ²ëÚÐàëáâÐÝÝÕ Ctrl-F ö"
-#: engines/scumm/help.cpp:108
+#: engines/scumm/help.cpp:109
msgid " ctrl-g are not recommended"
msgstr " Ctrl-G ÝÕ àíÚÐÜÕÝÔãÕææÐ,"
-#: engines/scumm/help.cpp:109
+#: engines/scumm/help.cpp:110
msgid " since they may cause crashes"
msgstr " ÑÞ ïÝë ÜÞÓãæì ßàëÒÕáæö ÔÐ"
-#: engines/scumm/help.cpp:110
+#: engines/scumm/help.cpp:111
msgid " or incorrect game behavior."
msgstr " ÝïáÛãèÝÐÙ àÐÑÞâë ÓãÛìÝö."
-#: engines/scumm/help.cpp:114
+#: engines/scumm/help.cpp:115
msgid "Spinning drafts on the keyboard:"
msgstr "·ÜïÝïÝëï çÐàÝÐÒöÚö ÝÐ ÚÛÐÒöïâãàë:"
-#: engines/scumm/help.cpp:116
+#: engines/scumm/help.cpp:117
msgid "Main game controls:"
msgstr "°áÝÞþÝÐÕ ÚöàÐÒÐÝÝÕ ÓãÛìÝñÙ:"
-#: engines/scumm/help.cpp:121 engines/scumm/help.cpp:136
-#: engines/scumm/help.cpp:161
+#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
+#: engines/scumm/help.cpp:162
msgid "Push"
msgstr "¿åÐæì"
-#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
-#: engines/scumm/help.cpp:162
+#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
+#: engines/scumm/help.cpp:163
msgid "Pull"
msgstr "ÆïÓÝãæì"
-#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
-#: engines/scumm/help.cpp:163 engines/scumm/help.cpp:197
-#: engines/scumm/help.cpp:207
+#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
+#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:198
+#: engines/scumm/help.cpp:208
msgid "Give"
msgstr "´Ðæì"
-#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
-#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:190
-#: engines/scumm/help.cpp:208
+#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
+#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
+#: engines/scumm/help.cpp:209
msgid "Open"
msgstr "°ÔçëÝöæì"
-#: engines/scumm/help.cpp:126
+#: engines/scumm/help.cpp:127
msgid "Go to"
msgstr "¦áæö"
-#: engines/scumm/help.cpp:127
+#: engines/scumm/help.cpp:128
msgid "Get"
msgstr "Ã×ïæì"
-#: engines/scumm/help.cpp:128 engines/scumm/help.cpp:152
-#: engines/scumm/help.cpp:170 engines/scumm/help.cpp:198
-#: engines/scumm/help.cpp:213 engines/scumm/help.cpp:224
-#: engines/scumm/help.cpp:250
+#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:153
+#: engines/scumm/help.cpp:171 engines/scumm/help.cpp:199
+#: engines/scumm/help.cpp:214 engines/scumm/help.cpp:225
+#: engines/scumm/help.cpp:251
msgid "Use"
msgstr "²ëÚÐàëáâÐæì"
-#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:142
msgid "Read"
msgstr "ÇëâÐæì"
-#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:147
+#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:148
msgid "New kid"
msgstr "½ÞÒë ßÕàá"
-#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:153
-#: engines/scumm/help.cpp:171
+#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
+#: engines/scumm/help.cpp:172
msgid "Turn on"
msgstr "ÃÚÛîçëæì"
-#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
-#: engines/scumm/help.cpp:172
+#: engines/scumm/help.cpp:133 engines/scumm/help.cpp:155
+#: engines/scumm/help.cpp:173
msgid "Turn off"
msgstr "²ëÚÛîçëæì"
-#: engines/scumm/help.cpp:142 engines/scumm/help.cpp:167
-#: engines/scumm/help.cpp:194
+#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
+#: engines/scumm/help.cpp:195
msgid "Walk to"
msgstr "¦áæö ÔÐ"
-#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
-#: engines/scumm/help.cpp:195 engines/scumm/help.cpp:210
-#: engines/scumm/help.cpp:227
+#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:228
msgid "Pick up"
msgstr "¿ÐÔÝïæì"
-#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:145 engines/scumm/help.cpp:170
msgid "What is"
msgstr "ÈâÞ âÐÚÞÕ"
-#: engines/scumm/help.cpp:146
+#: engines/scumm/help.cpp:147
msgid "Unlock"
msgstr "°ÔçëÝöæì"
-#: engines/scumm/help.cpp:149
+#: engines/scumm/help.cpp:150
msgid "Put on"
msgstr "¿ÐÚÛÐáæö"
-#: engines/scumm/help.cpp:150
+#: engines/scumm/help.cpp:151
msgid "Take off"
msgstr "¿ÐÔÝïæì"
-#: engines/scumm/help.cpp:156
+#: engines/scumm/help.cpp:157
msgid "Fix"
msgstr "²ëßàÐÒöæì"
-#: engines/scumm/help.cpp:158
+#: engines/scumm/help.cpp:159
msgid "Switch"
msgstr "¿ÕàÐÚÛîçëæì"
-#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:228
+#: engines/scumm/help.cpp:167 engines/scumm/help.cpp:229
msgid "Look"
msgstr "³ÛïÔ×Õæì"
-#: engines/scumm/help.cpp:173 engines/scumm/help.cpp:223
+#: engines/scumm/help.cpp:174 engines/scumm/help.cpp:224
msgid "Talk"
msgstr "³ÐÒÐàëæì"
-#: engines/scumm/help.cpp:174
+#: engines/scumm/help.cpp:175
msgid "Travel"
msgstr "¿ÐÔÐàÞÖÝöçÐæì"
-#: engines/scumm/help.cpp:175
+#: engines/scumm/help.cpp:176
msgid "To Henry / To Indy"
msgstr "³ÕÝàë/¦ÝÔë"
#. I18N: These are different musical notes
-#: engines/scumm/help.cpp:179
+#: engines/scumm/help.cpp:180
msgid "play C minor on distaff"
msgstr "öÓàÐæì ÔÞ ÜöÝÞà ÝÐ ÚÐÛÐþàÞæÕ"
-#: engines/scumm/help.cpp:180
+#: engines/scumm/help.cpp:181
msgid "play D on distaff"
msgstr "öÓàÐæì àí ÝÐ ÚÐÛÐþàÞæÕ"
-#: engines/scumm/help.cpp:181
+#: engines/scumm/help.cpp:182
msgid "play E on distaff"
msgstr "öÓàÐæì Üö ÝÐ ÚÐÛÐþàÞæÕ"
-#: engines/scumm/help.cpp:182
+#: engines/scumm/help.cpp:183
msgid "play F on distaff"
msgstr "öÓàÐæì äÐ ÝÐ ÚÐÛÐþàÞæÕ"
-#: engines/scumm/help.cpp:183
+#: engines/scumm/help.cpp:184
msgid "play G on distaff"
msgstr "öÓàÐæì áÞÛì ÝÐ ÚÐÛÐþàÞæÕ"
-#: engines/scumm/help.cpp:184
+#: engines/scumm/help.cpp:185
msgid "play A on distaff"
msgstr "öÓàÐæì Ûï ÝÐ ÚÐÛÐþàÞæÕ"
-#: engines/scumm/help.cpp:185
+#: engines/scumm/help.cpp:186
msgid "play B on distaff"
msgstr "öÓàÐæì áö ÝÐ ÚÐÛÐþàÞæÕ"
-#: engines/scumm/help.cpp:186
+#: engines/scumm/help.cpp:187
msgid "play C major on distaff"
msgstr "öÓàÐæì ÔÞ ÜÐÖÞà ÝÐ ÚÐÛÐþàÞæÕ"
-#: engines/scumm/help.cpp:192 engines/scumm/help.cpp:214
+#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
msgid "puSh"
msgstr "ßåÐæì"
-#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
+#: engines/scumm/help.cpp:194 engines/scumm/help.cpp:216
msgid "pull (Yank)"
msgstr "æïÓÝãæì (çÐßÛïæì)"
-#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:212
-#: engines/scumm/help.cpp:248
+#: engines/scumm/help.cpp:197 engines/scumm/help.cpp:213
+#: engines/scumm/help.cpp:249
msgid "Talk to"
msgstr "³ÐÒÐàëæì ×"
-#: engines/scumm/help.cpp:199 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:200 engines/scumm/help.cpp:212
msgid "Look at"
msgstr "³ÛïÔ×Õæì ÝÐ"
-#: engines/scumm/help.cpp:200
+#: engines/scumm/help.cpp:201
msgid "turn oN"
msgstr "ãÚÛîçëæì"
-#: engines/scumm/help.cpp:201
+#: engines/scumm/help.cpp:202
msgid "turn oFf"
msgstr "ÒëÚÛîçëæì"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "KeyUp"
msgstr "ÃÒÕàå"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "Highlight prev dialogue"
msgstr "¿ÐÔáÒïâÛöæì ßÐßïàíÔÝö ÔëïÛÞÓ"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "KeyDown"
msgstr "ÃÝö×"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "Highlight next dialogue"
msgstr "¿ÐÔáÒïâÛöæì ÝÐáâãßÝë ÔëïÛÞÓ"
-#: engines/scumm/help.cpp:222
+#: engines/scumm/help.cpp:223
msgid "Walk"
msgstr "¦áæö"
-#: engines/scumm/help.cpp:225 engines/scumm/help.cpp:234
-#: engines/scumm/help.cpp:241 engines/scumm/help.cpp:249
+#: engines/scumm/help.cpp:226 engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:242 engines/scumm/help.cpp:250
msgid "Inventory"
msgstr "¦ÝÒÕÝâÐà"
-#: engines/scumm/help.cpp:226
+#: engines/scumm/help.cpp:227
msgid "Object"
msgstr "°Ñ'ÕÚâ"
-#: engines/scumm/help.cpp:229
+#: engines/scumm/help.cpp:230
msgid "Black and White / Color"
msgstr "ÇÞàÝÐ-ÑÕÛë / ºÐÛïàÞÒë"
-#: engines/scumm/help.cpp:232
+#: engines/scumm/help.cpp:233
msgid "Eyes"
msgstr "²Þçë"
-#: engines/scumm/help.cpp:233
+#: engines/scumm/help.cpp:234
msgid "Tongue"
msgstr "Ï×ëÚ"
-#: engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:236
msgid "Punch"
msgstr "ÃÔÐà"
-#: engines/scumm/help.cpp:236
+#: engines/scumm/help.cpp:237
msgid "Kick"
msgstr "½ÐÓÞÙ"
-#: engines/scumm/help.cpp:239 engines/scumm/help.cpp:247
+#: engines/scumm/help.cpp:240 engines/scumm/help.cpp:248
msgid "Examine"
msgstr "¿àÐÒÕàëæì"
-#: engines/scumm/help.cpp:240
+#: engines/scumm/help.cpp:241
msgid "Regular cursor"
msgstr "·ÒëçÐÙÝë ÚãàáÞà"
#. I18N: Comm is a communication device
-#: engines/scumm/help.cpp:243
+#: engines/scumm/help.cpp:244
msgid "Comm"
msgstr "ºÐÜ"
-#: engines/scumm/help.cpp:246
+#: engines/scumm/help.cpp:247
msgid "Save / Load / Options"
msgstr "·ÐÓàã×öæì / ·ÐåÐÒÐæì / ½ÐÛÐÔë"
-#: engines/scumm/help.cpp:255
+#: engines/scumm/help.cpp:256
msgid "Other game controls:"
msgstr "°áâÐâÝïÕ ÚöàÐÒÐÝÝÕ ÓãÛìÝñÙ:"
-#: engines/scumm/help.cpp:257 engines/scumm/help.cpp:267
+#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:268
msgid "Inventory:"
msgstr "¦ÝÒÕÝâÐà:"
-#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:274
+#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
msgid "Scroll list up"
msgstr "¿àÐÚàãæöæì áßöá ãÒÕàå"
-#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
+#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:276
msgid "Scroll list down"
msgstr "¿àÐÚàãæöæì áßöá ãÝö×"
-#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:268
+#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:269
msgid "Upper left item"
msgstr "²ÕàåÝö ÛÕÒë ßàÐÔÜÕâ"
-#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:270
+#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
msgid "Lower left item"
msgstr "½öÖÝö ÛÕÒë ßàÐÔÜÕâ"
-#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
+#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:272
msgid "Upper right item"
msgstr "²ÕàåÝö ßàÐÒë ßàÐÔÜÕâ"
-#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:273
+#: engines/scumm/help.cpp:264 engines/scumm/help.cpp:274
msgid "Lower right item"
msgstr "½öÖÝö ßàÐÒë ßàÐÔÜÕâ"
-#: engines/scumm/help.cpp:269
+#: engines/scumm/help.cpp:270
msgid "Middle left item"
msgstr "ÁïàíÔÝö ÛÕÒë ßàÐÔÜÕâ"
-#: engines/scumm/help.cpp:272
+#: engines/scumm/help.cpp:273
msgid "Middle right item"
msgstr "ÁïàíÔÝö ßàÐÒë ßàÐÔÜÕâ"
-#: engines/scumm/help.cpp:279 engines/scumm/help.cpp:284
+#: engines/scumm/help.cpp:280 engines/scumm/help.cpp:285
msgid "Switching characters:"
msgstr "·ÜÕÝÐ ÓÕàÞï:"
-#: engines/scumm/help.cpp:281
+#: engines/scumm/help.cpp:282
msgid "Second kid"
msgstr "´àãÓö ÓÕàÞÙ"
-#: engines/scumm/help.cpp:282
+#: engines/scumm/help.cpp:283
msgid "Third kid"
msgstr "Âàíæö ÓÕàÞÙ"
-#: engines/scumm/help.cpp:294
+#: engines/scumm/help.cpp:292
+#, fuzzy
+msgid "Toggle Inventory/IQ Points display"
+msgstr "ÃÚÛîçëæì ßÐÚÐ× ÔÐÔ×ÕÝëå ã æíÝâàë íÚàÐÝÐ"
+
+#: engines/scumm/help.cpp:293
+msgid "Toggle Keyboard/Mouse Fighting (*)"
+msgstr ""
+
+#: engines/scumm/help.cpp:295
+msgid "* Keyboard Fighting is always on,"
+msgstr ""
+
+#: engines/scumm/help.cpp:296
+msgid " so despite the in-game message this"
+msgstr ""
+
+#: engines/scumm/help.cpp:297
+msgid " actually toggles Mouse Fighting Off/On"
+msgstr ""
+
+#: engines/scumm/help.cpp:304
msgid "Fighting controls (numpad):"
msgstr "ºöàÐÒÐÝÝÕ ÑÞÕÜ (ÛöçÑÐÒëï ÚÛÐÒöèë)"
-#: engines/scumm/help.cpp:295 engines/scumm/help.cpp:296
-#: engines/scumm/help.cpp:297
+#: engines/scumm/help.cpp:305 engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:307
msgid "Step back"
msgstr "ºàÞÚ ÝÐ×ÐÔ"
-#: engines/scumm/help.cpp:298
+#: engines/scumm/help.cpp:308
msgid "Block high"
msgstr "°ÑÐàÞÝÐ ×ÒÕàåã"
-#: engines/scumm/help.cpp:299
+#: engines/scumm/help.cpp:309
msgid "Block middle"
msgstr "°ÑÐàÞÝÐ ßÐáïàíÔ×öÝÕ"
-#: engines/scumm/help.cpp:300
+#: engines/scumm/help.cpp:310
msgid "Block low"
msgstr "°ÑÐàÞÝÐ ×Ýö×ã"
-#: engines/scumm/help.cpp:301
+#: engines/scumm/help.cpp:311
msgid "Punch high"
msgstr "ÃÔÐà ×ÒÕàåã"
-#: engines/scumm/help.cpp:302
+#: engines/scumm/help.cpp:312
msgid "Punch middle"
msgstr "ÃÔÐà ßÐáïàíÔ×öÝÕ"
-#: engines/scumm/help.cpp:303
+#: engines/scumm/help.cpp:313
msgid "Punch low"
msgstr "ÃÔÐà ×Ýö×ã"
-#: engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:315
+msgid "Sucker punch"
+msgstr ""
+
+#: engines/scumm/help.cpp:318
msgid "These are for Indy on left."
msgstr "³íâÐ ÚÐÛö ¦ÝÔë ×ÛÕÒÐ."
-#: engines/scumm/help.cpp:307
+#: engines/scumm/help.cpp:319
msgid "When Indy is on the right,"
msgstr "ºÐÛö ¦ÝÔë áßàÐÒÐ,"
-#: engines/scumm/help.cpp:308
+#: engines/scumm/help.cpp:320
msgid "7, 4, and 1 are switched with"
msgstr "7, 4 ö 1 ×ÜïÝïîææÐ ×"
-#: engines/scumm/help.cpp:309
+#: engines/scumm/help.cpp:321
msgid "9, 6, and 3, respectively."
msgstr "9, 6 ö 3 ÐÔßÐÒÕÔÝÐ."
-#: engines/scumm/help.cpp:316
+#: engines/scumm/help.cpp:328
msgid "Biplane controls (numpad):"
msgstr "ºöàÐÒÐÝÝÕ áÐÜÐÛñâÐÜ (ÛöçÑÐÒëï ÚÛÐÒöèë)"
-#: engines/scumm/help.cpp:317
+#: engines/scumm/help.cpp:329
msgid "Fly to upper left"
msgstr "»ïæÕæì ÝÐÛÕÒÐ-þÒÕàå"
-#: engines/scumm/help.cpp:318
+#: engines/scumm/help.cpp:330
msgid "Fly to left"
msgstr "»ïæÕæì ÝÐÛÕÒÐ"
-#: engines/scumm/help.cpp:319
+#: engines/scumm/help.cpp:331
msgid "Fly to lower left"
msgstr "»ïæÕæì ÝÐÛÕÒÐ-þÝö×"
-#: engines/scumm/help.cpp:320
+#: engines/scumm/help.cpp:332
msgid "Fly upwards"
msgstr "»ïæÕæì ãÒÕàå"
-#: engines/scumm/help.cpp:321
+#: engines/scumm/help.cpp:333
msgid "Fly straight"
msgstr "»ïæÕæì ßàÐÜÐ"
-#: engines/scumm/help.cpp:322
+#: engines/scumm/help.cpp:334
msgid "Fly down"
msgstr "»ïæÕæì ãÝö×"
-#: engines/scumm/help.cpp:323
+#: engines/scumm/help.cpp:335
msgid "Fly to upper right"
msgstr "»ïæÕæì ÝÐßàÐÒÐ-þÒÕàå"
-#: engines/scumm/help.cpp:324
+#: engines/scumm/help.cpp:336
msgid "Fly to right"
msgstr "»ïæÕæì ÝÐßàÐÒÐ"
-#: engines/scumm/help.cpp:325
+#: engines/scumm/help.cpp:337
msgid "Fly to lower right"
msgstr "»ïæÕæì ÝÐßàÐÒÐ-þÝö×"
-#: engines/scumm/scumm.cpp:1823
+#: engines/scumm/scumm.cpp:1832
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
@@ -3195,11 +3285,12 @@ msgstr ""
"ÀíÖëÜ \"àÞÔÝÐÓÐ\" MIDI ßÐâàÐÑãÕ ÐÑÝÐþÛÕÝÝÕ Roland Upgrade ÐÔ\n"
"LucasArts, ÐÛÕ ÝÕ åÐßÐÕ %s. ¿ÕàÐÚÛîçÐîáï ÝÐ AdLib."
-#: engines/scumm/scumm.cpp:2594
+#: engines/scumm/scumm.cpp:2644
+#, fuzzy
msgid ""
-"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
-"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
-"directory inside the Tentacle game directory."
+"Usually, Maniac Mansion would start now. But for that to work, the game "
+"files for Maniac Mansion have to be in the 'Maniac' directory inside the "
+"Tentacle game directory, and the game has to be added to ScummVM."
msgstr ""
"·ÐàÐ× ßÐÒöÝÝÐ ×ÐßãáæöææÐ ÓãÛìÝï Maniac Mansion. °ÛÕ ScummVM ßÐÚãÛì ÓíâÐÓÐ ÝÕ "
"þÜÕÕ. ºÐÑ ×ÓãÛïæì, ÝÐæöáÝöæÕ '½ÞÒÐï ÓãÛìÝï' ã áâÐàâÐÒëÜ ÜÕÝî ScummVM, Ð "
@@ -3338,6 +3429,48 @@ msgstr ""
msgid "Show the current number of frames per second in the upper left corner"
msgstr ""
+#: engines/zvision/detection.cpp:256
+msgid "Double FPS"
+msgstr ""
+
+#: engines/zvision/detection.cpp:257
+msgid "Increase game FPS from 30 to 60"
+msgstr ""
+
+#: engines/zvision/detection.cpp:266
+#, fuzzy
+msgid "Enable Venus"
+msgstr "ÃÚÛîçëæì àíÖëÜ ÓÕÛöï"
+
+#: engines/zvision/detection.cpp:267
+msgid "Enable the Venus help system"
+msgstr ""
+
+#: engines/zvision/detection.cpp:276
+msgid "Disable animation while turning"
+msgstr ""
+
+#: engines/zvision/detection.cpp:277
+msgid "Disable animation while turning in panoramic mode"
+msgstr ""
+
+#: engines/zvision/detection.cpp:286
+msgid "Use the hires MPEG movies"
+msgstr ""
+
+#: engines/zvision/detection.cpp:287
+#, fuzzy
+msgid ""
+"Use the hires MPEG movies of the DVD version, instead of the lowres AVI ones"
+msgstr ""
+"²ëÚÐàëáâÞþÒÐæì ÐÛìâíàÝÐâëþÝë ÝÐÑÞà áàíÑÝëå ÚãàáÞàÐþ ×ÐÜÕáâ ×ÒëçÐÙÝëå ×ÐÛÐâëå"
+
+#~ msgid "EGA undithering"
+#~ msgstr "EGA ÑÕ× àÐáâàã"
+
+#~ msgid "Enable undithering in EGA games"
+#~ msgstr "ÃÚÛîçÐÕ àíÖëÜ ÑÕ× àÐáâàÐÒÐÝÝï þ EGA ÓãÛìÝïå"
+
#~ msgid "MPEG-2 cutscenes found but ScummVM has been built without MPEG-2"
#~ msgstr ""
#~ "·ÝÞÙÔ×ÕÝë ×ÐáâÐþÚö þ äÐàÜÐæÕ MPEG-2, ÐÛÕ ScummVM Ñëþ áÐÑàÐÝë ÑÕ× "
@@ -3347,9 +3480,6 @@ msgstr ""
#~ msgid "Mass Add..."
#~ msgstr "ÈÜÐâ ÓãÛìÝïþ..."
-#~ msgid "Mass Add..."
-#~ msgstr "ÈÜÐâ ÓãÛìÝïþ..."
-
#~ msgid ""
#~ "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
#~ msgstr ""
diff --git a/po/ca_ES.po b/po/ca_ES.po
index 86f8bbed86..bfbc9b8c37 100644
--- a/po/ca_ES.po
+++ b/po/ca_ES.po
@@ -1,5 +1,5 @@
# Catalan translation for ScummVM.
-# Copyright (C) 2007-2014 ScummVM Team
+# Copyright (C) 2007-2015 The ScummVM Team
# This file is distributed under the same license as the ScummVM package.
# Jordi Vilalta Prat <jvprat@jvprat.com>, 2007-2011.
#
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.6.0git\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2014-10-04 00:58+0100\n"
+"POT-Creation-Date: 2015-06-30 20:57+0100\n"
"PO-Revision-Date: 2013-05-05 14:16+0100\n"
"Last-Translator: Jordi Vilalta Prat <jvprat@jvprat.com>\n"
"Language-Team: Catalan <scummvm-devel@lists.sf.net>\n"
@@ -52,10 +52,11 @@ msgstr "Amunt"
#: gui/browser.cpp:75 gui/chooser.cpp:46 gui/KeysDialog.cpp:43
#: gui/launcher.cpp:351 gui/massadd.cpp:95 gui/options.cpp:1239
+#: gui/recorderdialog.cpp:70 gui/recorderdialog.cpp:156
#: gui/saveload-dialog.cpp:216 gui/saveload-dialog.cpp:276
-#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:922
+#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:931
#: gui/themebrowser.cpp:55 gui/fluidsynth-dialog.cpp:152
-#: engines/engine.cpp:452 backends/platform/wii/options.cpp:48
+#: engines/engine.cpp:483 backends/platform/wii/options.cpp:48
#: backends/events/default/default-events.cpp:196
#: backends/events/default/default-events.cpp:218
#: engines/drascula/saveload.cpp:49 engines/parallaction/saveload.cpp:274
@@ -68,9 +69,9 @@ msgid "Choose"
msgstr "Escull"
#: gui/gui-manager.cpp:117 backends/keymapper/remap-dialog.cpp:53
-#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
-#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
-#: engines/scumm/help.cpp:209
+#: engines/scumm/help.cpp:126 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:192
+#: engines/scumm/help.cpp:210
msgid "Close"
msgstr "Tanca"
@@ -86,7 +87,7 @@ msgstr "Mostra el teclat"
msgid "Remap keys"
msgstr "Assigna les tecles"
-#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:86
+#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:87
msgid "Toggle fullscreen"
msgstr "Commuta la pantalla completa"
@@ -100,13 +101,13 @@ msgstr "Assigna"
#: gui/KeysDialog.cpp:42 gui/launcher.cpp:352 gui/launcher.cpp:1048
#: gui/launcher.cpp:1052 gui/massadd.cpp:92 gui/options.cpp:1240
-#: gui/saveload-dialog.cpp:923 gui/fluidsynth-dialog.cpp:153
-#: engines/engine.cpp:371 engines/engine.cpp:382
+#: gui/saveload-dialog.cpp:932 gui/fluidsynth-dialog.cpp:153
+#: engines/engine.cpp:402 engines/engine.cpp:413
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
#: engines/agos/animation.cpp:558 engines/drascula/saveload.cpp:49
-#: engines/groovie/script.cpp:399 engines/parallaction/saveload.cpp:274
-#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1825
+#: engines/groovie/script.cpp:408 engines/parallaction/saveload.cpp:274
+#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1834
#: engines/scumm/players/player_v3m.cpp:130
#: engines/scumm/players/player_v5m.cpp:108 engines/sky/compact.cpp:131
#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:524
@@ -479,7 +480,7 @@ msgstr ""
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -489,7 +490,7 @@ msgstr "Sí"
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -527,6 +528,14 @@ msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr ""
"ScummVM no ha pogut trobar cap motor capaç d'executar el joc seleccionat!"
+#: gui/launcher.cpp:1159
+msgid "Mass Add..."
+msgstr "Addició Massiva..."
+
+#: gui/launcher.cpp:1161
+msgid "Record..."
+msgstr ""
+
#: gui/massadd.cpp:79 gui/massadd.cpp:82
msgid "... progress ..."
msgstr "... progrés ..."
@@ -626,7 +635,7 @@ msgid "Special dithering modes supported by some games"
msgstr "Modes de tramat especials suportats per alguns jocs"
#: gui/options.cpp:760
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2249
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2298
msgid "Fullscreen mode"
msgstr "Mode pantalla completa"
@@ -946,6 +955,43 @@ msgstr ""
"El tema que heu seleccionat no suporta l'idioma actual. Si voleu utilitzar "
"aquest tema primer haureu de canviar a un altre idioma."
+#: gui/recorderdialog.cpp:64
+msgid "Recorder or Playback Gameplay"
+msgstr ""
+
+#: gui/recorderdialog.cpp:69 gui/recorderdialog.cpp:156
+#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
+msgid "Delete"
+msgstr "Suprimeix"
+
+#: gui/recorderdialog.cpp:71
+msgid "Record"
+msgstr ""
+
+#: gui/recorderdialog.cpp:72
+#, fuzzy
+msgid "Playback"
+msgstr "Jugar"
+
+#: gui/recorderdialog.cpp:74
+msgid "Edit"
+msgstr ""
+
+#: gui/recorderdialog.cpp:86 gui/recorderdialog.cpp:243
+#: gui/recorderdialog.cpp:253
+msgid "Author: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:87 gui/recorderdialog.cpp:244
+#: gui/recorderdialog.cpp:254
+msgid "Notes: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:155
+#, fuzzy
+msgid "Do you really want to delete this record?"
+msgstr "Realment voleu suprimir aquesta partida?"
+
#: gui/saveload-dialog.cpp:167
msgid "List view"
msgstr "Vista de llistat"
@@ -966,23 +1012,19 @@ msgstr "No hi ha hora desada"
msgid "No playtime saved"
msgstr "No hi ha temps de joc desat"
-#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
-msgid "Delete"
-msgstr "Suprimeix"
-
#: gui/saveload-dialog.cpp:275
msgid "Do you really want to delete this saved game?"
msgstr "Realment voleu suprimir aquesta partida?"
-#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:875
+#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:884
msgid "Date: "
msgstr "Data: "
-#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:881
+#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:890
msgid "Time: "
msgstr "Hora: "
-#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:889
+#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:898
msgid "Playtime: "
msgstr "Temps de joc: "
@@ -998,19 +1040,19 @@ msgstr "Següent"
msgid "Prev"
msgstr "Anterior"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "New Save"
msgstr "Nova partida desada"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "Create a new save game"
msgstr "Crea una nova partida desada"
-#: gui/saveload-dialog.cpp:868
+#: gui/saveload-dialog.cpp:877
msgid "Name: "
msgstr "Nom: "
-#: gui/saveload-dialog.cpp:940
+#: gui/saveload-dialog.cpp:949
#, c-format
msgid "Enter a description for slot %d:"
msgstr "Entreu la descripció per l'espai %d:"
@@ -1166,7 +1208,7 @@ msgstr "Salta la línia"
msgid "Error running game:"
msgstr "Error al executar el joc:"
-#: base/main.cpp:536
+#: base/main.cpp:554
msgid "Could not find any engine capable of running the selected game"
msgstr "No s'ha pogut trobar cap motor capaç d'executar el joc seleccionat"
@@ -1284,7 +1326,7 @@ msgstr "~R~etorna al Llançador"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:803
#: engines/cruise/menu.cpp:212 engines/drascula/saveload.cpp:336
#: engines/dreamweb/saveload.cpp:261 engines/neverhood/menumodule.cpp:873
-#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:758
+#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:759
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save game:"
msgstr "Desa la partida:"
@@ -1297,7 +1339,7 @@ msgstr "Desa la partida:"
#: engines/agi/saveload.cpp:803 engines/cruise/menu.cpp:212
#: engines/drascula/saveload.cpp:336 engines/dreamweb/saveload.cpp:261
#: engines/neverhood/menumodule.cpp:873 engines/pegasus/pegasus.cpp:377
-#: engines/sci/engine/kfile.cpp:758 engines/scumm/dialogs.cpp:188
+#: engines/sci/engine/kfile.cpp:759 engines/scumm/dialogs.cpp:188
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save"
msgstr "Desa"
@@ -1334,23 +1376,23 @@ msgstr "~C~ancel·la"
msgid "~K~eys"
msgstr "~T~ecles"
-#: engines/engine.cpp:245
+#: engines/engine.cpp:276
msgid "Could not initialize color format."
msgstr "No s'ha pogut iniciar el format de color."
-#: engines/engine.cpp:253
+#: engines/engine.cpp:284
msgid "Could not switch to video mode: '"
msgstr "No s'ha pogut canviar al mode de vídeo: '"
-#: engines/engine.cpp:262
+#: engines/engine.cpp:293
msgid "Could not apply aspect ratio setting."
msgstr "No s'ha pogut aplicar la configuració de la relació d'aspecte."
-#: engines/engine.cpp:267
+#: engines/engine.cpp:298
msgid "Could not apply fullscreen setting."
msgstr "No s'ha pogut aplicar l'ajust de pantalla completa."
-#: engines/engine.cpp:367
+#: engines/engine.cpp:398
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1364,7 +1406,7 @@ msgstr ""
"els fitxers de dades al disc dur.\n"
"Consulteu el fitxer README per a més detalls."
-#: engines/engine.cpp:378
+#: engines/engine.cpp:409
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1378,7 +1420,7 @@ msgstr ""
"tal de poder sentir la música del joc.\n"
"Consulteu el fitxer README per a més detalls."
-#: engines/engine.cpp:436
+#: engines/engine.cpp:467
#, c-format
msgid ""
"Gamestate load failed (%s)! Please consult the README for basic information, "
@@ -1387,7 +1429,7 @@ msgstr ""
"No s'ha pogut carregar la partida (%s)! Consulteu el fitxer README per a la "
"informació bàsica i les instruccions sobre com obtenir més assistència."
-#: engines/engine.cpp:449
+#: engines/engine.cpp:480
msgid ""
"WARNING: The game you are about to start is not yet fully supported by "
"ScummVM. As such, it is likely to be unstable, and any saves you make might "
@@ -1397,7 +1439,7 @@ msgstr ""
"pel ScummVM. Com a tal, probablement serà inestable, i pot ser que les "
"partides que deseu no funcionin en versions futures de ScummVM."
-#: engines/engine.cpp:452
+#: engines/engine.cpp:483
msgid "Start anyway"
msgstr "Inicia de totes maneres"
@@ -1607,11 +1649,11 @@ msgstr "Mode Touchpad activat."
msgid "Touchpad mode disabled."
msgstr "Mode Touchpad desactivat."
-#: backends/platform/maemo/maemo.cpp:209
+#: backends/platform/maemo/maemo.cpp:208
msgid "Click Mode"
msgstr "Mode clic"
-#: backends/platform/maemo/maemo.cpp:215
+#: backends/platform/maemo/maemo.cpp:214
#: backends/platform/symbian/src/SymbianActions.cpp:42
#: backends/platform/wince/CEActionsPocket.cpp:60
#: backends/platform/wince/CEActionsSmartphone.cpp:43
@@ -1619,11 +1661,11 @@ msgstr "Mode clic"
msgid "Left Click"
msgstr "Clic esquerre"
-#: backends/platform/maemo/maemo.cpp:218
+#: backends/platform/maemo/maemo.cpp:217
msgid "Middle Click"
msgstr "Clic central"
-#: backends/platform/maemo/maemo.cpp:221
+#: backends/platform/maemo/maemo.cpp:220
#: backends/platform/symbian/src/SymbianActions.cpp:43
#: backends/platform/wince/CEActionsSmartphone.cpp:44
#: backends/platform/tizen/form.cpp:267
@@ -1660,19 +1702,19 @@ msgctxt "lowres"
msgid "Normal (no scaling)"
msgstr "Normal (no escalat)"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2148
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2197
msgid "Enabled aspect ratio correction"
msgstr "S'ha activat la correcció de la relació d'aspecte"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2154
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2203
msgid "Disabled aspect ratio correction"
msgstr "S'ha desactivat la correcció de la relació d'aspecte"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2209
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2258
msgid "Active graphics filter:"
msgstr "Filtre de gràfics actiu:"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2251
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2300
msgid "Windowed mode"
msgstr "Mode de finestra"
@@ -1732,8 +1774,8 @@ msgstr "Mode ràpid"
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
#: backends/events/default/default-events.cpp:218
-#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:82
-#: engines/scumm/help.cpp:84
+#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:83
+#: engines/scumm/help.cpp:85
msgid "Quit"
msgstr "Surt"
@@ -1753,7 +1795,7 @@ msgstr "Teclat virtual"
msgid "Key mapper"
msgstr "Assignador de tecles"
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
msgid "Do you want to quit ?"
msgstr "Vols sortir?"
@@ -2088,34 +2130,55 @@ msgstr "Clicat activat"
msgid "Clicking Disabled"
msgstr "Clicat desactivat"
-#: engines/agi/detection.cpp:142 engines/drascula/detection.cpp:302
+#: engines/agi/detection.cpp:147 engines/drascula/detection.cpp:302
#: engines/dreamweb/detection.cpp:47 engines/neverhood/detection.cpp:160
#: engines/sci/detection.cpp:394 engines/toltecs/detection.cpp:200
-#: engines/zvision/detection.cpp:103
+#: engines/zvision/detection.cpp:246
msgid "Use original save/load screens"
msgstr "Utilitza les pantalles originals de desat/càrrega"
-#: engines/agi/detection.cpp:143 engines/drascula/detection.cpp:303
+#: engines/agi/detection.cpp:148 engines/drascula/detection.cpp:303
#: engines/dreamweb/detection.cpp:48 engines/neverhood/detection.cpp:161
#: engines/sci/detection.cpp:395 engines/toltecs/detection.cpp:201
-#: engines/zvision/detection.cpp:104
+#: engines/zvision/detection.cpp:247
msgid "Use the original save/load screens, instead of the ScummVM ones"
msgstr ""
"Utilitza les pantalles originals de desat/càrrega, en lloc de les de ScummVM"
+#: engines/agi/detection.cpp:157
+#, fuzzy
+msgid "Use an alternative palette"
+msgstr "Utilitza una introducció del joc alternativa (només per la versió CD)"
+
+#: engines/agi/detection.cpp:158
+msgid ""
+"Use an alternative palette, common for all Amiga games. This was the old "
+"behavior"
+msgstr ""
+
+#: engines/agi/detection.cpp:167
+#, fuzzy
+msgid "Mouse support"
+msgstr "Suport per saltar text i escenes"
+
+#: engines/agi/detection.cpp:168
+msgid ""
+"Enables mouse support. Allows to use mouse for movement and in game menus."
+msgstr ""
+
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore game:"
msgstr "Recupera la partida:"
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore"
msgstr "Restaura"
-#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2368
+#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2377
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -2126,7 +2189,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2361
+#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2370
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -2137,7 +2200,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2379
+#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2388
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -2153,12 +2216,12 @@ msgstr ""
msgid "Cutscene file '%s' not found!"
msgstr "No s'ha trobat el fitxer d'escena '%s'!"
-#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:81
+#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:101
#, fuzzy
msgid "Color Blind Mode"
msgstr "Mode clic"
-#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:82
+#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:102
msgid "Enable Color Blind Mode by default"
msgstr ""
@@ -2210,7 +2273,7 @@ msgstr "Velocitat ràpida de les pel·lícules"
msgid "Play movies at an increased speed"
msgstr "Reprodueix les pel·lícules a major velocitat"
-#: engines/groovie/script.cpp:399
+#: engines/groovie/script.cpp:408
msgid "Failed to save game"
msgstr "No s'ha pogut desar l'estat del joc"
@@ -2508,12 +2571,12 @@ msgid "Use an alternative game intro (CD version only)"
msgstr "Utilitza una introducció del joc alternativa (només per la versió CD)"
#: engines/sci/detection.cpp:374
-msgid "EGA undithering"
-msgstr "Elimina el tramat d'EGA"
+msgid "Skip EGA dithering pass (full color backgrounds)"
+msgstr ""
#: engines/sci/detection.cpp:375
-msgid "Enable undithering in EGA games"
-msgstr "Activa l'eliminació del tramat en els jocs EGA"
+msgid "Skip dithering pass in EGA games, graphics are shown with full colors"
+msgstr ""
#: engines/sci/detection.cpp:384
msgid "Prefer digital sound effects"
@@ -2589,12 +2652,14 @@ msgstr "Joc pausat. Premeu ESPAI per continuar."
#. "Moechten Sie wirklich neu starten? (J/N)J"
#. Will react to J as 'Yes'
#: engines/scumm/dialogs.cpp:183
-msgid "Are you sure you want to restart? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to restart? (Y/N)Y"
msgstr "Esteu segur de voler reiniciar? (S/N)S"
#. I18N: you may specify 'Yes' symbol at the end of the line. See previous comment
#: engines/scumm/dialogs.cpp:185
-msgid "Are you sure you want to quit? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to quit? (Y/N)Y"
msgstr "Esteu segur de voler sortir? (S/N)S"
#: engines/scumm/dialogs.cpp:190
@@ -2682,516 +2747,541 @@ msgstr "Pràctica"
msgid "Expert"
msgstr "Expert"
-#: engines/scumm/help.cpp:73
+#: engines/scumm/help.cpp:74
msgid "Common keyboard commands:"
msgstr "Comandes comuns de teclat:"
-#: engines/scumm/help.cpp:74
+#: engines/scumm/help.cpp:75
msgid "Save / Load dialog"
msgstr "Diàleg de desat / càrrega"
-#: engines/scumm/help.cpp:76
+#: engines/scumm/help.cpp:77
msgid "Skip line of text"
msgstr "Salta la línia de text"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Esc"
msgstr "Esc"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Skip cutscene"
msgstr "Salta la seqüència de video"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Space"
msgstr "Espai"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Pause game"
msgstr "Pausa la partida"
-#: engines/scumm/help.cpp:79 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:95 engines/scumm/help.cpp:96
-#: engines/scumm/help.cpp:97 engines/scumm/help.cpp:98
-#: engines/scumm/help.cpp:99 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:96 engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98 engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Ctrl"
msgstr "Ctrl"
-#: engines/scumm/help.cpp:79
+#: engines/scumm/help.cpp:80
msgid "Load game state 1-10"
msgstr "Carrega partida 1-10"
-#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:81 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Alt"
msgstr "Alt"
-#: engines/scumm/help.cpp:80
+#: engines/scumm/help.cpp:81
msgid "Save game state 1-10"
msgstr "Desa partida 1-10"
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:90
msgid "Enter"
msgstr "Intro"
-#: engines/scumm/help.cpp:87
+#: engines/scumm/help.cpp:88
msgid "Music volume up / down"
msgstr "Puja / Baixa el volum de la música"
-#: engines/scumm/help.cpp:88
+#: engines/scumm/help.cpp:89
msgid "Text speed slower / faster"
msgstr "Velocitat de text més lenta / més ràpida"
-#: engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:90
msgid "Simulate left mouse button"
msgstr "Simula el botó esquerre del ratolí"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Tab"
msgstr "Tab"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Simulate right mouse button"
msgstr "Simula el botó dret del ratolí"
-#: engines/scumm/help.cpp:93
+#: engines/scumm/help.cpp:94
msgid "Special keyboard commands:"
msgstr "Comandes especials de teclat:"
-#: engines/scumm/help.cpp:94
+#: engines/scumm/help.cpp:95
msgid "Show / Hide console"
msgstr "Mostra / Oculta la consola"
-#: engines/scumm/help.cpp:95
+#: engines/scumm/help.cpp:96
msgid "Start the debugger"
msgstr "Inicia el depurador"
-#: engines/scumm/help.cpp:96
+#: engines/scumm/help.cpp:97
msgid "Show memory consumption"
msgstr "Mostra el consum de memòria"
-#: engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98
msgid "Run in fast mode (*)"
msgstr "Executa en mode ràpid (*)"
-#: engines/scumm/help.cpp:98
+#: engines/scumm/help.cpp:99
msgid "Run in really fast mode (*)"
msgstr "Executa en mode realment ràpid (*)"
-#: engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100
msgid "Toggle mouse capture"
msgstr "Commuta la captura del ratolí"
-#: engines/scumm/help.cpp:100
+#: engines/scumm/help.cpp:101
msgid "Switch between graphics filters"
msgstr "Commuta entre els filtres gràfics"
-#: engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102
msgid "Increase / Decrease scale factor"
msgstr "Augmenta / Disminueix el factor d'escala"
-#: engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:103
msgid "Toggle aspect-ratio correction"
msgstr "Commuta la correcció de la relació d'aspecte"
-#: engines/scumm/help.cpp:107
+#: engines/scumm/help.cpp:108
msgid "* Note that using ctrl-f and"
msgstr "* Tingueu en compte que no es"
-#: engines/scumm/help.cpp:108
+#: engines/scumm/help.cpp:109
msgid " ctrl-g are not recommended"
msgstr " recomana utilitzar ctrl-f i ctrl-g"
-#: engines/scumm/help.cpp:109
+#: engines/scumm/help.cpp:110
msgid " since they may cause crashes"
msgstr " ja que poden provocar errors o"
-#: engines/scumm/help.cpp:110
+#: engines/scumm/help.cpp:111
msgid " or incorrect game behavior."
msgstr " comportament del joc incorrecte."
-#: engines/scumm/help.cpp:114
+#: engines/scumm/help.cpp:115
msgid "Spinning drafts on the keyboard:"
msgstr "Filant des del teclat:"
-#: engines/scumm/help.cpp:116
+#: engines/scumm/help.cpp:117
msgid "Main game controls:"
msgstr "Controls principals del joc:"
-#: engines/scumm/help.cpp:121 engines/scumm/help.cpp:136
-#: engines/scumm/help.cpp:161
+#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
+#: engines/scumm/help.cpp:162
msgid "Push"
msgstr "Empeny"
-#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
-#: engines/scumm/help.cpp:162
+#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
+#: engines/scumm/help.cpp:163
msgid "Pull"
msgstr "Estira"
-#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
-#: engines/scumm/help.cpp:163 engines/scumm/help.cpp:197
-#: engines/scumm/help.cpp:207
+#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
+#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:198
+#: engines/scumm/help.cpp:208
msgid "Give"
msgstr "Dóna"
-#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
-#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:190
-#: engines/scumm/help.cpp:208
+#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
+#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
+#: engines/scumm/help.cpp:209
msgid "Open"
msgstr "Obre"
-#: engines/scumm/help.cpp:126
+#: engines/scumm/help.cpp:127
msgid "Go to"
msgstr "Vés a"
-#: engines/scumm/help.cpp:127
+#: engines/scumm/help.cpp:128
msgid "Get"
msgstr "Obté"
-#: engines/scumm/help.cpp:128 engines/scumm/help.cpp:152
-#: engines/scumm/help.cpp:170 engines/scumm/help.cpp:198
-#: engines/scumm/help.cpp:213 engines/scumm/help.cpp:224
-#: engines/scumm/help.cpp:250
+#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:153
+#: engines/scumm/help.cpp:171 engines/scumm/help.cpp:199
+#: engines/scumm/help.cpp:214 engines/scumm/help.cpp:225
+#: engines/scumm/help.cpp:251
msgid "Use"
msgstr "Utilitza"
-#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:142
msgid "Read"
msgstr "Llegeix"
-#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:147
+#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:148
msgid "New kid"
msgstr "Nou noi"
-#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:153
-#: engines/scumm/help.cpp:171
+#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
+#: engines/scumm/help.cpp:172
msgid "Turn on"
msgstr "Engega"
-#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
-#: engines/scumm/help.cpp:172
+#: engines/scumm/help.cpp:133 engines/scumm/help.cpp:155
+#: engines/scumm/help.cpp:173
msgid "Turn off"
msgstr "Apaga"
-#: engines/scumm/help.cpp:142 engines/scumm/help.cpp:167
-#: engines/scumm/help.cpp:194
+#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
+#: engines/scumm/help.cpp:195
msgid "Walk to"
msgstr "Vés a"
-#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
-#: engines/scumm/help.cpp:195 engines/scumm/help.cpp:210
-#: engines/scumm/help.cpp:227
+#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:228
msgid "Pick up"
msgstr "Agafa"
-#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:145 engines/scumm/help.cpp:170
msgid "What is"
msgstr "Què és"
-#: engines/scumm/help.cpp:146
+#: engines/scumm/help.cpp:147
msgid "Unlock"
msgstr "Desbloqueja"
-#: engines/scumm/help.cpp:149
+#: engines/scumm/help.cpp:150
msgid "Put on"
msgstr "Posa a"
-#: engines/scumm/help.cpp:150
+#: engines/scumm/help.cpp:151
msgid "Take off"
msgstr "Aixecar el vol"
-#: engines/scumm/help.cpp:156
+#: engines/scumm/help.cpp:157
msgid "Fix"
msgstr "Arregla"
-#: engines/scumm/help.cpp:158
+#: engines/scumm/help.cpp:159
msgid "Switch"
msgstr "Commuta"
-#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:228
+#: engines/scumm/help.cpp:167 engines/scumm/help.cpp:229
msgid "Look"
msgstr "Mira"
-#: engines/scumm/help.cpp:173 engines/scumm/help.cpp:223
+#: engines/scumm/help.cpp:174 engines/scumm/help.cpp:224
msgid "Talk"
msgstr "Parla"
-#: engines/scumm/help.cpp:174
+#: engines/scumm/help.cpp:175
msgid "Travel"
msgstr "Viatja"
-#: engines/scumm/help.cpp:175
+#: engines/scumm/help.cpp:176
msgid "To Henry / To Indy"
msgstr "A en Henry / A l'Indy"
#. I18N: These are different musical notes
-#: engines/scumm/help.cpp:179
+#: engines/scumm/help.cpp:180
msgid "play C minor on distaff"
msgstr "toca un Do menor amb la filosa"
-#: engines/scumm/help.cpp:180
+#: engines/scumm/help.cpp:181
msgid "play D on distaff"
msgstr "toca un Re amb la filosa"
-#: engines/scumm/help.cpp:181
+#: engines/scumm/help.cpp:182
msgid "play E on distaff"
msgstr "toca un Mi amb la filosa"
-#: engines/scumm/help.cpp:182
+#: engines/scumm/help.cpp:183
msgid "play F on distaff"
msgstr "toca un Fa amb la filosa"
-#: engines/scumm/help.cpp:183
+#: engines/scumm/help.cpp:184
msgid "play G on distaff"
msgstr "toca un Sol amb la filosa"
-#: engines/scumm/help.cpp:184
+#: engines/scumm/help.cpp:185
msgid "play A on distaff"
msgstr "toca un La amb la filosa"
-#: engines/scumm/help.cpp:185
+#: engines/scumm/help.cpp:186
msgid "play B on distaff"
msgstr "toca un Si amb la filosa"
-#: engines/scumm/help.cpp:186
+#: engines/scumm/help.cpp:187
msgid "play C major on distaff"
msgstr "toca un Do major amb la filosa"
-#: engines/scumm/help.cpp:192 engines/scumm/help.cpp:214
+#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
msgid "puSh"
msgstr "empentar"
-#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
+#: engines/scumm/help.cpp:194 engines/scumm/help.cpp:216
msgid "pull (Yank)"
msgstr "estirar"
-#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:212
-#: engines/scumm/help.cpp:248
+#: engines/scumm/help.cpp:197 engines/scumm/help.cpp:213
+#: engines/scumm/help.cpp:249
msgid "Talk to"
msgstr "Parla amb"
-#: engines/scumm/help.cpp:199 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:200 engines/scumm/help.cpp:212
msgid "Look at"
msgstr "Mira"
-#: engines/scumm/help.cpp:200
+#: engines/scumm/help.cpp:201
msgid "turn oN"
msgstr "engega"
-#: engines/scumm/help.cpp:201
+#: engines/scumm/help.cpp:202
msgid "turn oFf"
msgstr "apaga"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "KeyUp"
msgstr "Tecla amunt"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "Highlight prev dialogue"
msgstr "Remarcar el diàleg anterior"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "KeyDown"
msgstr "Tecla avall"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "Highlight next dialogue"
msgstr "Remarcar el diàleg següent"
-#: engines/scumm/help.cpp:222
+#: engines/scumm/help.cpp:223
msgid "Walk"
msgstr "Camina"
-#: engines/scumm/help.cpp:225 engines/scumm/help.cpp:234
-#: engines/scumm/help.cpp:241 engines/scumm/help.cpp:249
+#: engines/scumm/help.cpp:226 engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:242 engines/scumm/help.cpp:250
msgid "Inventory"
msgstr "Inventari"
-#: engines/scumm/help.cpp:226
+#: engines/scumm/help.cpp:227
msgid "Object"
msgstr "Objecte"
-#: engines/scumm/help.cpp:229
+#: engines/scumm/help.cpp:230
msgid "Black and White / Color"
msgstr "Blanc i negre / Color"
-#: engines/scumm/help.cpp:232
+#: engines/scumm/help.cpp:233
msgid "Eyes"
msgstr "Ulls"
-#: engines/scumm/help.cpp:233
+#: engines/scumm/help.cpp:234
msgid "Tongue"
msgstr "Llengua"
-#: engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:236
msgid "Punch"
msgstr "Cop de puny"
-#: engines/scumm/help.cpp:236
+#: engines/scumm/help.cpp:237
msgid "Kick"
msgstr "Puntada"
-#: engines/scumm/help.cpp:239 engines/scumm/help.cpp:247
+#: engines/scumm/help.cpp:240 engines/scumm/help.cpp:248
msgid "Examine"
msgstr "Examina"
-#: engines/scumm/help.cpp:240
+#: engines/scumm/help.cpp:241
msgid "Regular cursor"
msgstr "Cursor normal"
#. I18N: Comm is a communication device
-#: engines/scumm/help.cpp:243
+#: engines/scumm/help.cpp:244
msgid "Comm"
msgstr "Comunicador"
-#: engines/scumm/help.cpp:246
+#: engines/scumm/help.cpp:247
msgid "Save / Load / Options"
msgstr "Desa / Carrega / Opcions"
-#: engines/scumm/help.cpp:255
+#: engines/scumm/help.cpp:256
msgid "Other game controls:"
msgstr "Altres controls del joc"
-#: engines/scumm/help.cpp:257 engines/scumm/help.cpp:267
+#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:268
msgid "Inventory:"
msgstr "Inventari:"
-#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:274
+#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
msgid "Scroll list up"
msgstr "Desplaça la llista amunt"
-#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
+#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:276
msgid "Scroll list down"
msgstr "Desplaça la llista avall"
-#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:268
+#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:269
msgid "Upper left item"
msgstr "Element superior esquerre"
-#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:270
+#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
msgid "Lower left item"
msgstr "Element inferior esquerre"
-#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
+#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:272
msgid "Upper right item"
msgstr "Element superior dret"
-#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:273
+#: engines/scumm/help.cpp:264 engines/scumm/help.cpp:274
msgid "Lower right item"
msgstr "Element inferior dret"
-#: engines/scumm/help.cpp:269
+#: engines/scumm/help.cpp:270
msgid "Middle left item"
msgstr "Element mig esquerre"
-#: engines/scumm/help.cpp:272
+#: engines/scumm/help.cpp:273
msgid "Middle right item"
msgstr "Element mig dret"
-#: engines/scumm/help.cpp:279 engines/scumm/help.cpp:284
+#: engines/scumm/help.cpp:280 engines/scumm/help.cpp:285
msgid "Switching characters:"
msgstr "Canvia els personatges:"
-#: engines/scumm/help.cpp:281
+#: engines/scumm/help.cpp:282
msgid "Second kid"
msgstr "Segon noi"
-#: engines/scumm/help.cpp:282
+#: engines/scumm/help.cpp:283
msgid "Third kid"
msgstr "Tercer noi"
-#: engines/scumm/help.cpp:294
+#: engines/scumm/help.cpp:292
+#, fuzzy
+msgid "Toggle Inventory/IQ Points display"
+msgstr "Conmuta la visualització de dades central"
+
+#: engines/scumm/help.cpp:293
+msgid "Toggle Keyboard/Mouse Fighting (*)"
+msgstr ""
+
+#: engines/scumm/help.cpp:295
+msgid "* Keyboard Fighting is always on,"
+msgstr ""
+
+#: engines/scumm/help.cpp:296
+msgid " so despite the in-game message this"
+msgstr ""
+
+#: engines/scumm/help.cpp:297
+msgid " actually toggles Mouse Fighting Off/On"
+msgstr ""
+
+#: engines/scumm/help.cpp:304
msgid "Fighting controls (numpad):"
msgstr "Controls de lluita (teclat numèric):"
-#: engines/scumm/help.cpp:295 engines/scumm/help.cpp:296
-#: engines/scumm/help.cpp:297
+#: engines/scumm/help.cpp:305 engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:307
msgid "Step back"
msgstr "Pas enrere"
-#: engines/scumm/help.cpp:298
+#: engines/scumm/help.cpp:308
msgid "Block high"
msgstr "Bloqueig alt"
-#: engines/scumm/help.cpp:299
+#: engines/scumm/help.cpp:309
msgid "Block middle"
msgstr "Bloqueig mig"
-#: engines/scumm/help.cpp:300
+#: engines/scumm/help.cpp:310
msgid "Block low"
msgstr "Bloqueig baix"
-#: engines/scumm/help.cpp:301
+#: engines/scumm/help.cpp:311
msgid "Punch high"
msgstr "Puntada alta"
-#: engines/scumm/help.cpp:302
+#: engines/scumm/help.cpp:312
msgid "Punch middle"
msgstr "Puntada mitja"
-#: engines/scumm/help.cpp:303
+#: engines/scumm/help.cpp:313
msgid "Punch low"
msgstr "Puntada baixa"
-#: engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:315
+msgid "Sucker punch"
+msgstr ""
+
+#: engines/scumm/help.cpp:318
msgid "These are for Indy on left."
msgstr "Aquests són per l'Indy a l'esquerra."
-#: engines/scumm/help.cpp:307
+#: engines/scumm/help.cpp:319
msgid "When Indy is on the right,"
msgstr "Quan l'Indy és a la dreta,"
-#: engines/scumm/help.cpp:308
+#: engines/scumm/help.cpp:320
msgid "7, 4, and 1 are switched with"
msgstr "el 7, el 4 i l'1 s'intercanvien amb"
-#: engines/scumm/help.cpp:309
+#: engines/scumm/help.cpp:321
msgid "9, 6, and 3, respectively."
msgstr "el 9, el 6 i el 3, respectivament."
-#: engines/scumm/help.cpp:316
+#: engines/scumm/help.cpp:328
msgid "Biplane controls (numpad):"
msgstr "Controls del biplà (teclat numèric):"
-#: engines/scumm/help.cpp:317
+#: engines/scumm/help.cpp:329
msgid "Fly to upper left"
msgstr "Vola amunt i a l'esquerra"
-#: engines/scumm/help.cpp:318
+#: engines/scumm/help.cpp:330
msgid "Fly to left"
msgstr "Vola a l'esquerra"
-#: engines/scumm/help.cpp:319
+#: engines/scumm/help.cpp:331
msgid "Fly to lower left"
msgstr "Vola avall i a l'esquerra"
-#: engines/scumm/help.cpp:320
+#: engines/scumm/help.cpp:332
msgid "Fly upwards"
msgstr "Vola amunt"
-#: engines/scumm/help.cpp:321
+#: engines/scumm/help.cpp:333
msgid "Fly straight"
msgstr "Vola recte"
-#: engines/scumm/help.cpp:322
+#: engines/scumm/help.cpp:334
msgid "Fly down"
msgstr "Vola avall"
-#: engines/scumm/help.cpp:323
+#: engines/scumm/help.cpp:335
msgid "Fly to upper right"
msgstr "Vola amunt i a la dreta"
-#: engines/scumm/help.cpp:324
+#: engines/scumm/help.cpp:336
msgid "Fly to right"
msgstr "Vola a la dreta"
-#: engines/scumm/help.cpp:325
+#: engines/scumm/help.cpp:337
msgid "Fly to lower right"
msgstr "Vola avall i a la dreta"
-#: engines/scumm/scumm.cpp:1823
+#: engines/scumm/scumm.cpp:1832
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
@@ -3200,11 +3290,12 @@ msgstr ""
"El suport de MIDI natiu requereix l'actualització Roland de LucasArts,\n"
"però no s'ha trobat %s. S'utilitzarà AdLib."
-#: engines/scumm/scumm.cpp:2594
+#: engines/scumm/scumm.cpp:2644
+#, fuzzy
msgid ""
-"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
-"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
-"directory inside the Tentacle game directory."
+"Usually, Maniac Mansion would start now. But for that to work, the game "
+"files for Maniac Mansion have to be in the 'Maniac' directory inside the "
+"Tentacle game directory, and the game has to be added to ScummVM."
msgstr ""
"Normalment, en aquest punt s'engegaria el Maniac Mansion. Però ScummVM no ho "
"fa encara. Per jugar-hi, aneu a 'Afegir joc' al menú principal de ScummVM i "
@@ -3346,6 +3437,49 @@ msgstr ""
msgid "Show the current number of frames per second in the upper left corner"
msgstr ""
+#: engines/zvision/detection.cpp:256
+msgid "Double FPS"
+msgstr ""
+
+#: engines/zvision/detection.cpp:257
+msgid "Increase game FPS from 30 to 60"
+msgstr ""
+
+#: engines/zvision/detection.cpp:266
+#, fuzzy
+msgid "Enable Venus"
+msgstr "Activa el mode heli"
+
+#: engines/zvision/detection.cpp:267
+msgid "Enable the Venus help system"
+msgstr ""
+
+#: engines/zvision/detection.cpp:276
+msgid "Disable animation while turning"
+msgstr ""
+
+#: engines/zvision/detection.cpp:277
+msgid "Disable animation while turning in panoramic mode"
+msgstr ""
+
+#: engines/zvision/detection.cpp:286
+msgid "Use the hires MPEG movies"
+msgstr ""
+
+#: engines/zvision/detection.cpp:287
+#, fuzzy
+msgid ""
+"Use the hires MPEG movies of the DVD version, instead of the lowres AVI ones"
+msgstr ""
+"Utilitza el conjunt alternatiu de cursors platejats, en lloc dels normals "
+"daurats"
+
+#~ msgid "EGA undithering"
+#~ msgstr "Elimina el tramat d'EGA"
+
+#~ msgid "Enable undithering in EGA games"
+#~ msgstr "Activa l'eliminació del tramat en els jocs EGA"
+
#, fuzzy
#~ msgid "MPEG-2 cutscenes found but ScummVM has been built without MPEG-2"
#~ msgstr ""
@@ -3356,9 +3490,6 @@ msgstr ""
#~ msgid "Mass Add..."
#~ msgstr "Afegeix Jocs"
-#~ msgid "Mass Add..."
-#~ msgstr "Addició Massiva..."
-
#~ msgid ""
#~ "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
#~ msgstr ""
diff --git a/po/cs_CZ.po b/po/cs_CZ.po
index 0b5a3c88bf..9bfec00254 100644
--- a/po/cs_CZ.po
+++ b/po/cs_CZ.po
@@ -1,5 +1,5 @@
# Czech translation for ScummVM.
-# Copyright (C) 2001-2014 ScummVM Team
+# Copyright (C) 2001-2015 The ScummVM Team
# This file is distributed under the same license as the ScummVM package.
# Zbynìk Schwarz <zbynek.schwarz@gmail.com>, 2011-2013.
#
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.7.0git\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2014-10-04 00:58+0100\n"
+"POT-Creation-Date: 2015-06-30 20:57+0100\n"
"PO-Revision-Date: 2014-02-27 21:43+0100\n"
"Last-Translator: Zbynìk Schwarz <zbynek.schwarz@gmail.com>\n"
"Language-Team: \n"
@@ -56,10 +56,11 @@ msgstr "Jít nahoru"
#: gui/browser.cpp:75 gui/chooser.cpp:46 gui/KeysDialog.cpp:43
#: gui/launcher.cpp:351 gui/massadd.cpp:95 gui/options.cpp:1239
+#: gui/recorderdialog.cpp:70 gui/recorderdialog.cpp:156
#: gui/saveload-dialog.cpp:216 gui/saveload-dialog.cpp:276
-#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:922
+#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:931
#: gui/themebrowser.cpp:55 gui/fluidsynth-dialog.cpp:152
-#: engines/engine.cpp:452 backends/platform/wii/options.cpp:48
+#: engines/engine.cpp:483 backends/platform/wii/options.cpp:48
#: backends/events/default/default-events.cpp:196
#: backends/events/default/default-events.cpp:218
#: engines/drascula/saveload.cpp:49 engines/parallaction/saveload.cpp:274
@@ -72,9 +73,9 @@ msgid "Choose"
msgstr "Zvolit"
#: gui/gui-manager.cpp:117 backends/keymapper/remap-dialog.cpp:53
-#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
-#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
-#: engines/scumm/help.cpp:209
+#: engines/scumm/help.cpp:126 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:192
+#: engines/scumm/help.cpp:210
msgid "Close"
msgstr "Zavøít"
@@ -90,7 +91,7 @@ msgstr "Zobrazit klávesnici"
msgid "Remap keys"
msgstr "Pøemapovat klávesy"
-#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:86
+#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:87
msgid "Toggle fullscreen"
msgstr "Pøepnout celou obrazovku"
@@ -104,13 +105,13 @@ msgstr "Mapovat"
#: gui/KeysDialog.cpp:42 gui/launcher.cpp:352 gui/launcher.cpp:1048
#: gui/launcher.cpp:1052 gui/massadd.cpp:92 gui/options.cpp:1240
-#: gui/saveload-dialog.cpp:923 gui/fluidsynth-dialog.cpp:153
-#: engines/engine.cpp:371 engines/engine.cpp:382
+#: gui/saveload-dialog.cpp:932 gui/fluidsynth-dialog.cpp:153
+#: engines/engine.cpp:402 engines/engine.cpp:413
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
#: engines/agos/animation.cpp:558 engines/drascula/saveload.cpp:49
-#: engines/groovie/script.cpp:399 engines/parallaction/saveload.cpp:274
-#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1825
+#: engines/groovie/script.cpp:408 engines/parallaction/saveload.cpp:274
+#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1834
#: engines/scumm/players/player_v3m.cpp:130
#: engines/scumm/players/player_v5m.cpp:108 engines/sky/compact.cpp:131
#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:524
@@ -478,7 +479,7 @@ msgstr ""
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -488,7 +489,7 @@ msgstr "Ano"
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -524,6 +525,14 @@ msgstr "Tato hra nepodporuje spou¹tìní her ze spou¹tìèe"
msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr "ScummVM nemohl najít ¾ádné jádro schopné vybranou hru spustit!"
+#: gui/launcher.cpp:1159
+msgid "Mass Add..."
+msgstr "Hromadné Pøidání..."
+
+#: gui/launcher.cpp:1161
+msgid "Record..."
+msgstr ""
+
#: gui/massadd.cpp:79 gui/massadd.cpp:82
msgid "... progress ..."
msgstr "... prùbìh ..."
@@ -622,7 +631,7 @@ msgid "Special dithering modes supported by some games"
msgstr "Speciální re¾imy chvìní podporované nìkterými hrami"
#: gui/options.cpp:760
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2249
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2298
msgid "Fullscreen mode"
msgstr "Re¾im celé obrazovky"
@@ -938,6 +947,43 @@ msgstr ""
"Vzhled, který jste zvolili, nepodporuje Vá¹ souèasný jazyk. Pokud chcete "
"tento vzhled pou¾ít, musíte nejdøíve pøepnout na jiný jazyk."
+#: gui/recorderdialog.cpp:64
+msgid "Recorder or Playback Gameplay"
+msgstr ""
+
+#: gui/recorderdialog.cpp:69 gui/recorderdialog.cpp:156
+#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
+msgid "Delete"
+msgstr "Smazat"
+
+#: gui/recorderdialog.cpp:71
+msgid "Record"
+msgstr ""
+
+#: gui/recorderdialog.cpp:72
+#, fuzzy
+msgid "Playback"
+msgstr "Hrát"
+
+#: gui/recorderdialog.cpp:74
+msgid "Edit"
+msgstr ""
+
+#: gui/recorderdialog.cpp:86 gui/recorderdialog.cpp:243
+#: gui/recorderdialog.cpp:253
+msgid "Author: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:87 gui/recorderdialog.cpp:244
+#: gui/recorderdialog.cpp:254
+msgid "Notes: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:155
+#, fuzzy
+msgid "Do you really want to delete this record?"
+msgstr "Opravdu chcete tuto ulo¾enou hru vymazat"
+
#: gui/saveload-dialog.cpp:167
msgid "List view"
msgstr "Seznam"
@@ -958,23 +1004,19 @@ msgstr "®ádný ulo¾ený èas"
msgid "No playtime saved"
msgstr "®ádná ulo¾ená doba hraní"
-#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
-msgid "Delete"
-msgstr "Smazat"
-
#: gui/saveload-dialog.cpp:275
msgid "Do you really want to delete this saved game?"
msgstr "Opravdu chcete tuto ulo¾enou hru vymazat"
-#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:875
+#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:884
msgid "Date: "
msgstr "Datum:"
-#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:881
+#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:890
msgid "Time: "
msgstr "Èas:"
-#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:889
+#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:898
msgid "Playtime: "
msgstr "Doba hraní:"
@@ -990,19 +1032,19 @@ msgstr "Dal¹í"
msgid "Prev"
msgstr "Pøedchozí"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "New Save"
msgstr "Nová ulo¾ená pozice"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "Create a new save game"
msgstr "Vytvoøit novou ulo¾enou hru."
-#: gui/saveload-dialog.cpp:868
+#: gui/saveload-dialog.cpp:877
msgid "Name: "
msgstr "Název:"
-#: gui/saveload-dialog.cpp:940
+#: gui/saveload-dialog.cpp:949
#, c-format
msgid "Enter a description for slot %d:"
msgstr "Zadejte popis pro pozici %d:"
@@ -1155,7 +1197,7 @@ msgstr "Pøeskoèit øádek"
msgid "Error running game:"
msgstr "Chyba pøi spu¹tìní hry:"
-#: base/main.cpp:536
+#: base/main.cpp:554
msgid "Could not find any engine capable of running the selected game"
msgstr "Nelze nalézt ¾ádné jádro schopné vybranou hru spustit"
@@ -1272,7 +1314,7 @@ msgstr "~N~ávrat do Spou¹tìèe"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:803
#: engines/cruise/menu.cpp:212 engines/drascula/saveload.cpp:336
#: engines/dreamweb/saveload.cpp:261 engines/neverhood/menumodule.cpp:873
-#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:758
+#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:759
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save game:"
msgstr "Ulo¾it hru:"
@@ -1285,7 +1327,7 @@ msgstr "Ulo¾it hru:"
#: engines/agi/saveload.cpp:803 engines/cruise/menu.cpp:212
#: engines/drascula/saveload.cpp:336 engines/dreamweb/saveload.cpp:261
#: engines/neverhood/menumodule.cpp:873 engines/pegasus/pegasus.cpp:377
-#: engines/sci/engine/kfile.cpp:758 engines/scumm/dialogs.cpp:188
+#: engines/sci/engine/kfile.cpp:759 engines/scumm/dialogs.cpp:188
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save"
msgstr "Ulo¾it"
@@ -1323,23 +1365,23 @@ msgstr "~Z~ru¹it"
msgid "~K~eys"
msgstr "~K~lávesy"
-#: engines/engine.cpp:245
+#: engines/engine.cpp:276
msgid "Could not initialize color format."
msgstr "Nelze zavést barevný formát."
-#: engines/engine.cpp:253
+#: engines/engine.cpp:284
msgid "Could not switch to video mode: '"
msgstr "Nelze pøepnout na re¾im obrazu: '"
-#: engines/engine.cpp:262
+#: engines/engine.cpp:293
msgid "Could not apply aspect ratio setting."
msgstr "Nelze pou¾ít nastavení pomìru stran."
-#: engines/engine.cpp:267
+#: engines/engine.cpp:298
msgid "Could not apply fullscreen setting."
msgstr "Nelze pou¾ít nastavení celé obrazovky."
-#: engines/engine.cpp:367
+#: engines/engine.cpp:398
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1353,7 +1395,7 @@ msgstr ""
"datové soubory na Vá¹ pevný disk.\n"
"Pro podrobnosti si pøeètìte README."
-#: engines/engine.cpp:378
+#: engines/engine.cpp:409
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1367,7 +1409,7 @@ msgstr ""
"abyste mohli poslouchat hudbu ve høe.\n"
"Pro podrobnosti si pøeètìte README."
-#: engines/engine.cpp:436
+#: engines/engine.cpp:467
#, c-format
msgid ""
"Gamestate load failed (%s)! Please consult the README for basic information, "
@@ -1376,7 +1418,7 @@ msgstr ""
"Naètení stavu hry selhalo (%s)! Prosím pøeètìte si dokumentaci pro základní "
"informace a pokyny k získání dal¹í podpory."
-#: engines/engine.cpp:449
+#: engines/engine.cpp:480
msgid ""
"WARNING: The game you are about to start is not yet fully supported by "
"ScummVM. As such, it is likely to be unstable, and any saves you make might "
@@ -1386,7 +1428,7 @@ msgstr ""
"ScummVM. Proto je mo¾né, ¾e bude nestabilní a jakékoli ulo¾ené hry nemusí "
"fungovat v budoucích verzích ScummVM."
-#: engines/engine.cpp:452
+#: engines/engine.cpp:483
msgid "Start anyway"
msgstr "Pøesto spustit"
@@ -1596,11 +1638,11 @@ msgstr "Touchpad re¾im zapnut"
msgid "Touchpad mode disabled."
msgstr "Touchpad re¾im vypnut"
-#: backends/platform/maemo/maemo.cpp:209
+#: backends/platform/maemo/maemo.cpp:208
msgid "Click Mode"
msgstr "Re¾im kliknutí"
-#: backends/platform/maemo/maemo.cpp:215
+#: backends/platform/maemo/maemo.cpp:214
#: backends/platform/symbian/src/SymbianActions.cpp:42
#: backends/platform/wince/CEActionsPocket.cpp:60
#: backends/platform/wince/CEActionsSmartphone.cpp:43
@@ -1608,11 +1650,11 @@ msgstr "Re¾im kliknutí"
msgid "Left Click"
msgstr "Levé Kliknutí"
-#: backends/platform/maemo/maemo.cpp:218
+#: backends/platform/maemo/maemo.cpp:217
msgid "Middle Click"
msgstr "Kliknutí prostøedním tlaèítkem"
-#: backends/platform/maemo/maemo.cpp:221
+#: backends/platform/maemo/maemo.cpp:220
#: backends/platform/symbian/src/SymbianActions.cpp:43
#: backends/platform/wince/CEActionsSmartphone.cpp:44
#: backends/platform/tizen/form.cpp:267
@@ -1649,19 +1691,19 @@ msgctxt "lowres"
msgid "Normal (no scaling)"
msgstr "Normální (bez zmìny velikosti)"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2148
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2197
msgid "Enabled aspect ratio correction"
msgstr "Povolena korekce pomìru stran"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2154
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2203
msgid "Disabled aspect ratio correction"
msgstr "Zakázána korekce pomìru stran"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2209
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2258
msgid "Active graphics filter:"
msgstr "Aktivní grafický filtr:"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2251
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2300
msgid "Windowed mode"
msgstr "Re¾im do okna"
@@ -1720,8 +1762,8 @@ msgstr "Rychlý re¾im"
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
#: backends/events/default/default-events.cpp:218
-#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:82
-#: engines/scumm/help.cpp:84
+#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:83
+#: engines/scumm/help.cpp:85
msgid "Quit"
msgstr "Ukonèit"
@@ -1741,7 +1783,7 @@ msgstr "Virtuální klávesnice"
msgid "Key mapper"
msgstr "Mapovaè kláves"
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
msgid "Do you want to quit ?"
msgstr "Chcete ukonèit ?"
@@ -2078,33 +2120,54 @@ msgstr "Kliknutí Povoleno"
msgid "Clicking Disabled"
msgstr "Kliknutí Zakázáno"
-#: engines/agi/detection.cpp:142 engines/drascula/detection.cpp:302
+#: engines/agi/detection.cpp:147 engines/drascula/detection.cpp:302
#: engines/dreamweb/detection.cpp:47 engines/neverhood/detection.cpp:160
#: engines/sci/detection.cpp:394 engines/toltecs/detection.cpp:200
-#: engines/zvision/detection.cpp:103
+#: engines/zvision/detection.cpp:246
msgid "Use original save/load screens"
msgstr "Pou¾ít pùvodní obrazovky naètení/ulo¾ení"
-#: engines/agi/detection.cpp:143 engines/drascula/detection.cpp:303
+#: engines/agi/detection.cpp:148 engines/drascula/detection.cpp:303
#: engines/dreamweb/detection.cpp:48 engines/neverhood/detection.cpp:161
#: engines/sci/detection.cpp:395 engines/toltecs/detection.cpp:201
-#: engines/zvision/detection.cpp:104
+#: engines/zvision/detection.cpp:247
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"
+#: engines/agi/detection.cpp:157
+#, fuzzy
+msgid "Use an alternative palette"
+msgstr "Pou¾ít jinou verzi úvodu (Pouze verze CD)"
+
+#: engines/agi/detection.cpp:158
+msgid ""
+"Use an alternative palette, common for all Amiga games. This was the old "
+"behavior"
+msgstr ""
+
+#: engines/agi/detection.cpp:167
+#, fuzzy
+msgid "Mouse support"
+msgstr "Podpora pøeskoèení"
+
+#: engines/agi/detection.cpp:168
+msgid ""
+"Enables mouse support. Allows to use mouse for movement and in game menus."
+msgstr ""
+
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore game:"
msgstr "Obnovit hru"
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore"
msgstr "Obnovit"
-#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2368
+#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2377
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -2115,7 +2178,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2361
+#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2370
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -2126,7 +2189,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2379
+#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2388
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -2142,12 +2205,12 @@ msgstr ""
msgid "Cutscene file '%s' not found!"
msgstr "Soubor videa '%s' nenalezen'"
-#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:81
+#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:101
#, fuzzy
msgid "Color Blind Mode"
msgstr "Re¾im kliknutí"
-#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:82
+#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:102
msgid "Enable Color Blind Mode by default"
msgstr ""
@@ -2199,7 +2262,7 @@ msgstr "Zvý¹ená rychlost videa"
msgid "Play movies at an increased speed"
msgstr "Pøehrát videa se zvý¹enou rychlostí"
-#: engines/groovie/script.cpp:399
+#: engines/groovie/script.cpp:408
msgid "Failed to save game"
msgstr "Nelze ulo¾it hru."
@@ -2496,12 +2559,12 @@ msgid "Use an alternative game intro (CD version only)"
msgstr "Pou¾ít jinou verzi úvodu (Pouze verze CD)"
#: engines/sci/detection.cpp:374
-msgid "EGA undithering"
-msgstr "Nerozkládání EGA"
+msgid "Skip EGA dithering pass (full color backgrounds)"
+msgstr ""
#: engines/sci/detection.cpp:375
-msgid "Enable undithering in EGA games"
-msgstr "Povolit nerozkládání v EGA hrách"
+msgid "Skip dithering pass in EGA games, graphics are shown with full colors"
+msgstr ""
#: engines/sci/detection.cpp:384
msgid "Prefer digital sound effects"
@@ -2572,12 +2635,14 @@ msgstr "Hra Pozastavena. Stisknìte MEZERNÍK pro pokraèování."
#. "Moechten Sie wirklich neu starten? (J/N)J"
#. Will react to J as 'Yes'
#: engines/scumm/dialogs.cpp:183
-msgid "Are you sure you want to restart? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to restart? (Y/N)Y"
msgstr "Jste si jisti, ¾e chcete restartovat? (A/N)A"
#. I18N: you may specify 'Yes' symbol at the end of the line. See previous comment
#: engines/scumm/dialogs.cpp:185
-msgid "Are you sure you want to quit? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to quit? (Y/N)Y"
msgstr "Jste si jisti, ¾e chcete odejít? (A/N)A"
#: engines/scumm/dialogs.cpp:190
@@ -2665,516 +2730,541 @@ msgstr "Cvièení"
msgid "Expert"
msgstr "Pokroèilý"
-#: engines/scumm/help.cpp:73
+#: engines/scumm/help.cpp:74
msgid "Common keyboard commands:"
msgstr "Bì¾né klávesové pøíkazy"
-#: engines/scumm/help.cpp:74
+#: engines/scumm/help.cpp:75
msgid "Save / Load dialog"
msgstr "Dialog Nahrát / Ulo¾it"
-#: engines/scumm/help.cpp:76
+#: engines/scumm/help.cpp:77
msgid "Skip line of text"
msgstr "Pøeskoèit øádek textu"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Esc"
msgstr "Mezerník"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Skip cutscene"
msgstr "Pøeskoèit video"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Space"
msgstr "Mezerník"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Pause game"
msgstr "Pozastavit hru"
-#: engines/scumm/help.cpp:79 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:95 engines/scumm/help.cpp:96
-#: engines/scumm/help.cpp:97 engines/scumm/help.cpp:98
-#: engines/scumm/help.cpp:99 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:96 engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98 engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Ctrl"
msgstr "Ctrl"
-#: engines/scumm/help.cpp:79
+#: engines/scumm/help.cpp:80
msgid "Load game state 1-10"
msgstr "Nahrát stav hry 1-10"
-#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:81 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Alt"
msgstr "Alt"
-#: engines/scumm/help.cpp:80
+#: engines/scumm/help.cpp:81
msgid "Save game state 1-10"
msgstr "Ulo¾it stav hry 1-10"
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:90
msgid "Enter"
msgstr "Enter"
-#: engines/scumm/help.cpp:87
+#: engines/scumm/help.cpp:88
msgid "Music volume up / down"
msgstr "Hlasitost hudby nahoru / dolù"
-#: engines/scumm/help.cpp:88
+#: engines/scumm/help.cpp:89
msgid "Text speed slower / faster"
msgstr "Zvý¹it / Sní¾it rychlost textu"
-#: engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:90
msgid "Simulate left mouse button"
msgstr "Napodobit levé tlaèítko my¹i"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Tab"
msgstr "Tab"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Simulate right mouse button"
msgstr "Napodobit pravé tlaèítko my¹i"
-#: engines/scumm/help.cpp:93
+#: engines/scumm/help.cpp:94
msgid "Special keyboard commands:"
msgstr "Speciální klávesové pøíkazy"
-#: engines/scumm/help.cpp:94
+#: engines/scumm/help.cpp:95
msgid "Show / Hide console"
msgstr "Ukázat / Skrýt konzoli"
-#: engines/scumm/help.cpp:95
+#: engines/scumm/help.cpp:96
msgid "Start the debugger"
msgstr "Spustit ladící program"
-#: engines/scumm/help.cpp:96
+#: engines/scumm/help.cpp:97
msgid "Show memory consumption"
msgstr "Zobrazit spotøebu pamìti"
-#: engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98
msgid "Run in fast mode (*)"
msgstr "Spustit v rychlém re¾imu (*)"
-#: engines/scumm/help.cpp:98
+#: engines/scumm/help.cpp:99
msgid "Run in really fast mode (*)"
msgstr "Spustit ve velmi rychlém re¾imu (*)"
-#: engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100
msgid "Toggle mouse capture"
msgstr "Povolit zachycování my¹i"
-#: engines/scumm/help.cpp:100
+#: engines/scumm/help.cpp:101
msgid "Switch between graphics filters"
msgstr "Pøepínat mezi grafickými filtry"
-#: engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102
msgid "Increase / Decrease scale factor"
msgstr "Zvìt¹it / Zmen¹it faktor zmìny velikosti"
-#: engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:103
msgid "Toggle aspect-ratio correction"
msgstr "Povolit korekci pomìru stran"
-#: engines/scumm/help.cpp:107
+#: engines/scumm/help.cpp:108
msgid "* Note that using ctrl-f and"
msgstr "Upozoròujeme, ¾e pou¾ívání ctrl-f a"
-#: engines/scumm/help.cpp:108
+#: engines/scumm/help.cpp:109
msgid " ctrl-g are not recommended"
msgstr " ctrl-g není doporuèeno"
-#: engines/scumm/help.cpp:109
+#: engines/scumm/help.cpp:110
msgid " since they may cause crashes"
msgstr "jeliko¾ mù¾ou zpùsobit pád"
-#: engines/scumm/help.cpp:110
+#: engines/scumm/help.cpp:111
msgid " or incorrect game behavior."
msgstr " nebo nesprávné chování hry."
-#: engines/scumm/help.cpp:114
+#: engines/scumm/help.cpp:115
msgid "Spinning drafts on the keyboard:"
msgstr "Pletení náèrtkù na klávesnici:"
-#: engines/scumm/help.cpp:116
+#: engines/scumm/help.cpp:117
msgid "Main game controls:"
msgstr "Hlavní ovládací prvky:"
-#: engines/scumm/help.cpp:121 engines/scumm/help.cpp:136
-#: engines/scumm/help.cpp:161
+#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
+#: engines/scumm/help.cpp:162
msgid "Push"
msgstr "Tlaèit"
-#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
-#: engines/scumm/help.cpp:162
+#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
+#: engines/scumm/help.cpp:163
msgid "Pull"
msgstr "Táhnout"
-#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
-#: engines/scumm/help.cpp:163 engines/scumm/help.cpp:197
-#: engines/scumm/help.cpp:207
+#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
+#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:198
+#: engines/scumm/help.cpp:208
msgid "Give"
msgstr "Dát"
-#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
-#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:190
-#: engines/scumm/help.cpp:208
+#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
+#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
+#: engines/scumm/help.cpp:209
msgid "Open"
msgstr "Otevøít"
-#: engines/scumm/help.cpp:126
+#: engines/scumm/help.cpp:127
msgid "Go to"
msgstr "Jít do"
-#: engines/scumm/help.cpp:127
+#: engines/scumm/help.cpp:128
msgid "Get"
msgstr "Vzít"
-#: engines/scumm/help.cpp:128 engines/scumm/help.cpp:152
-#: engines/scumm/help.cpp:170 engines/scumm/help.cpp:198
-#: engines/scumm/help.cpp:213 engines/scumm/help.cpp:224
-#: engines/scumm/help.cpp:250
+#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:153
+#: engines/scumm/help.cpp:171 engines/scumm/help.cpp:199
+#: engines/scumm/help.cpp:214 engines/scumm/help.cpp:225
+#: engines/scumm/help.cpp:251
msgid "Use"
msgstr "Pou¾ít"
-#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:142
msgid "Read"
msgstr "Pøeèíst"
-#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:147
+#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:148
msgid "New kid"
msgstr "Nové dítì"
-#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:153
-#: engines/scumm/help.cpp:171
+#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
+#: engines/scumm/help.cpp:172
msgid "Turn on"
msgstr "Zapnout"
-#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
-#: engines/scumm/help.cpp:172
+#: engines/scumm/help.cpp:133 engines/scumm/help.cpp:155
+#: engines/scumm/help.cpp:173
msgid "Turn off"
msgstr "Vypnout"
-#: engines/scumm/help.cpp:142 engines/scumm/help.cpp:167
-#: engines/scumm/help.cpp:194
+#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
+#: engines/scumm/help.cpp:195
msgid "Walk to"
msgstr "Pøejít na"
-#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
-#: engines/scumm/help.cpp:195 engines/scumm/help.cpp:210
-#: engines/scumm/help.cpp:227
+#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:228
msgid "Pick up"
msgstr "Sebrat"
-#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:145 engines/scumm/help.cpp:170
msgid "What is"
msgstr "Co je"
-#: engines/scumm/help.cpp:146
+#: engines/scumm/help.cpp:147
msgid "Unlock"
msgstr "Odemknout"
-#: engines/scumm/help.cpp:149
+#: engines/scumm/help.cpp:150
msgid "Put on"
msgstr "Obléct"
-#: engines/scumm/help.cpp:150
+#: engines/scumm/help.cpp:151
msgid "Take off"
msgstr "Svléct"
-#: engines/scumm/help.cpp:156
+#: engines/scumm/help.cpp:157
msgid "Fix"
msgstr "Spravit"
-#: engines/scumm/help.cpp:158
+#: engines/scumm/help.cpp:159
msgid "Switch"
msgstr "Pøepnout"
-#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:228
+#: engines/scumm/help.cpp:167 engines/scumm/help.cpp:229
msgid "Look"
msgstr "Dívat se"
-#: engines/scumm/help.cpp:173 engines/scumm/help.cpp:223
+#: engines/scumm/help.cpp:174 engines/scumm/help.cpp:224
msgid "Talk"
msgstr "Mluvit"
-#: engines/scumm/help.cpp:174
+#: engines/scumm/help.cpp:175
msgid "Travel"
msgstr "Cestovat"
-#: engines/scumm/help.cpp:175
+#: engines/scumm/help.cpp:176
msgid "To Henry / To Indy"
msgstr "Henrymu / Indymu"
#. I18N: These are different musical notes
-#: engines/scumm/help.cpp:179
+#: engines/scumm/help.cpp:180
msgid "play C minor on distaff"
msgstr "zahrát c moll na pøeslici"
-#: engines/scumm/help.cpp:180
+#: engines/scumm/help.cpp:181
msgid "play D on distaff"
msgstr "zahrát D na pøeslici"
-#: engines/scumm/help.cpp:181
+#: engines/scumm/help.cpp:182
msgid "play E on distaff"
msgstr "zahrát E na pøeslici"
-#: engines/scumm/help.cpp:182
+#: engines/scumm/help.cpp:183
msgid "play F on distaff"
msgstr "zahrát F na pøeslici"
-#: engines/scumm/help.cpp:183
+#: engines/scumm/help.cpp:184
msgid "play G on distaff"
msgstr "zahrát G na pøeslici"
-#: engines/scumm/help.cpp:184
+#: engines/scumm/help.cpp:185
msgid "play A on distaff"
msgstr "zahrát A na pøeslici"
-#: engines/scumm/help.cpp:185
+#: engines/scumm/help.cpp:186
msgid "play B on distaff"
msgstr "zahrát B na pøeslici"
-#: engines/scumm/help.cpp:186
+#: engines/scumm/help.cpp:187
msgid "play C major on distaff"
msgstr "zahrát C dur na pøeslici"
-#: engines/scumm/help.cpp:192 engines/scumm/help.cpp:214
+#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
msgid "puSh"
msgstr "tlaèIt"
-#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
+#: engines/scumm/help.cpp:194 engines/scumm/help.cpp:216
msgid "pull (Yank)"
msgstr "táhnout (©kubnout)"
-#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:212
-#: engines/scumm/help.cpp:248
+#: engines/scumm/help.cpp:197 engines/scumm/help.cpp:213
+#: engines/scumm/help.cpp:249
msgid "Talk to"
msgstr "Mluvit s"
-#: engines/scumm/help.cpp:199 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:200 engines/scumm/help.cpp:212
msgid "Look at"
msgstr "Dívat se na"
-#: engines/scumm/help.cpp:200
+#: engines/scumm/help.cpp:201
msgid "turn oN"
msgstr "zapnouT"
-#: engines/scumm/help.cpp:201
+#: engines/scumm/help.cpp:202
msgid "turn oFf"
msgstr "vypnoUt"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "KeyUp"
msgstr "KlávesaNahoru"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "Highlight prev dialogue"
msgstr "Zvýraznit pøedchozí dialog"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "KeyDown"
msgstr "KlávesaDolù"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "Highlight next dialogue"
msgstr "Zvýraznit následující dialog"
-#: engines/scumm/help.cpp:222
+#: engines/scumm/help.cpp:223
msgid "Walk"
msgstr "Jít"
-#: engines/scumm/help.cpp:225 engines/scumm/help.cpp:234
-#: engines/scumm/help.cpp:241 engines/scumm/help.cpp:249
+#: engines/scumm/help.cpp:226 engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:242 engines/scumm/help.cpp:250
msgid "Inventory"
msgstr "Inventáø"
-#: engines/scumm/help.cpp:226
+#: engines/scumm/help.cpp:227
msgid "Object"
msgstr "Objekt"
-#: engines/scumm/help.cpp:229
+#: engines/scumm/help.cpp:230
msgid "Black and White / Color"
msgstr "Èernobílé / Barva"
-#: engines/scumm/help.cpp:232
+#: engines/scumm/help.cpp:233
msgid "Eyes"
msgstr "Oèi"
-#: engines/scumm/help.cpp:233
+#: engines/scumm/help.cpp:234
msgid "Tongue"
msgstr "Jazyk"
-#: engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:236
msgid "Punch"
msgstr "Udeøit"
-#: engines/scumm/help.cpp:236
+#: engines/scumm/help.cpp:237
msgid "Kick"
msgstr "Kopnout"
-#: engines/scumm/help.cpp:239 engines/scumm/help.cpp:247
+#: engines/scumm/help.cpp:240 engines/scumm/help.cpp:248
msgid "Examine"
msgstr "Prohlédnout"
-#: engines/scumm/help.cpp:240
+#: engines/scumm/help.cpp:241
msgid "Regular cursor"
msgstr "Obyèejný kurzor"
#. I18N: Comm is a communication device
-#: engines/scumm/help.cpp:243
+#: engines/scumm/help.cpp:244
msgid "Comm"
msgstr "Komunikace"
-#: engines/scumm/help.cpp:246
+#: engines/scumm/help.cpp:247
msgid "Save / Load / Options"
msgstr "Ulo¾it / Nahrát / Volby"
-#: engines/scumm/help.cpp:255
+#: engines/scumm/help.cpp:256
msgid "Other game controls:"
msgstr "Dal¹í ovládací prvky hry"
-#: engines/scumm/help.cpp:257 engines/scumm/help.cpp:267
+#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:268
msgid "Inventory:"
msgstr "Inventáø:"
-#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:274
+#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
msgid "Scroll list up"
msgstr "Posunout seznam nahoru"
-#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
+#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:276
msgid "Scroll list down"
msgstr "Posunout seznam dolu"
-#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:268
+#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:269
msgid "Upper left item"
msgstr "Polo¾ka vlevo nahoøe"
-#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:270
+#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
msgid "Lower left item"
msgstr "Polo¾ka vlevo dole"
-#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
+#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:272
msgid "Upper right item"
msgstr "Polo¾ka vpravo nahoøe"
-#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:273
+#: engines/scumm/help.cpp:264 engines/scumm/help.cpp:274
msgid "Lower right item"
msgstr "Polo¾ka vpravo dole"
-#: engines/scumm/help.cpp:269
+#: engines/scumm/help.cpp:270
msgid "Middle left item"
msgstr "Polo¾ka vlevo uprostøed"
-#: engines/scumm/help.cpp:272
+#: engines/scumm/help.cpp:273
msgid "Middle right item"
msgstr "Polo¾ka vpravo uprostøed"
-#: engines/scumm/help.cpp:279 engines/scumm/help.cpp:284
+#: engines/scumm/help.cpp:280 engines/scumm/help.cpp:285
msgid "Switching characters:"
msgstr "Mìnìní postav:"
-#: engines/scumm/help.cpp:281
+#: engines/scumm/help.cpp:282
msgid "Second kid"
msgstr "Druhé dítì"
-#: engines/scumm/help.cpp:282
+#: engines/scumm/help.cpp:283
msgid "Third kid"
msgstr "Tøetí dítì"
-#: engines/scumm/help.cpp:294
+#: engines/scumm/help.cpp:292
+#, fuzzy
+msgid "Toggle Inventory/IQ Points display"
+msgstr "Pøepnout centrální datovou obrazovku"
+
+#: engines/scumm/help.cpp:293
+msgid "Toggle Keyboard/Mouse Fighting (*)"
+msgstr ""
+
+#: engines/scumm/help.cpp:295
+msgid "* Keyboard Fighting is always on,"
+msgstr ""
+
+#: engines/scumm/help.cpp:296
+msgid " so despite the in-game message this"
+msgstr ""
+
+#: engines/scumm/help.cpp:297
+msgid " actually toggles Mouse Fighting Off/On"
+msgstr ""
+
+#: engines/scumm/help.cpp:304
msgid "Fighting controls (numpad):"
msgstr "Ovládání boje (num. kláv.)"
-#: engines/scumm/help.cpp:295 engines/scumm/help.cpp:296
-#: engines/scumm/help.cpp:297
+#: engines/scumm/help.cpp:305 engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:307
msgid "Step back"
msgstr "Ustoupit"
-#: engines/scumm/help.cpp:298
+#: engines/scumm/help.cpp:308
msgid "Block high"
msgstr "Bránit nahoøe"
-#: engines/scumm/help.cpp:299
+#: engines/scumm/help.cpp:309
msgid "Block middle"
msgstr "Bránit uprostøed"
-#: engines/scumm/help.cpp:300
+#: engines/scumm/help.cpp:310
msgid "Block low"
msgstr "Bránit dole"
-#: engines/scumm/help.cpp:301
+#: engines/scumm/help.cpp:311
msgid "Punch high"
msgstr "Udeøit nahoru"
-#: engines/scumm/help.cpp:302
+#: engines/scumm/help.cpp:312
msgid "Punch middle"
msgstr "Udeøit doprostøed"
-#: engines/scumm/help.cpp:303
+#: engines/scumm/help.cpp:313
msgid "Punch low"
msgstr "Udeøit dolù"
-#: engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:315
+msgid "Sucker punch"
+msgstr ""
+
+#: engines/scumm/help.cpp:318
msgid "These are for Indy on left."
msgstr "Tyto jsou pro Indyho nalevo."
-#: engines/scumm/help.cpp:307
+#: engines/scumm/help.cpp:319
msgid "When Indy is on the right,"
msgstr "Kdy¾ je Indy napravo,"
-#: engines/scumm/help.cpp:308
+#: engines/scumm/help.cpp:320
msgid "7, 4, and 1 are switched with"
msgstr "71 4 a 1 jsou zamìnìny s"
-#: engines/scumm/help.cpp:309
+#: engines/scumm/help.cpp:321
msgid "9, 6, and 3, respectively."
msgstr "9, 6 a 3, v tomto poøadí."
-#: engines/scumm/help.cpp:316
+#: engines/scumm/help.cpp:328
msgid "Biplane controls (numpad):"
msgstr "Kontrola dvojplo¹níku (numerická klávesnice)"
-#: engines/scumm/help.cpp:317
+#: engines/scumm/help.cpp:329
msgid "Fly to upper left"
msgstr "Letìt doprava nahoru"
-#: engines/scumm/help.cpp:318
+#: engines/scumm/help.cpp:330
msgid "Fly to left"
msgstr "Letìt doleva"
-#: engines/scumm/help.cpp:319
+#: engines/scumm/help.cpp:331
msgid "Fly to lower left"
msgstr "Letìt doleva dolù"
-#: engines/scumm/help.cpp:320
+#: engines/scumm/help.cpp:332
msgid "Fly upwards"
msgstr "Letìt nahoru"
-#: engines/scumm/help.cpp:321
+#: engines/scumm/help.cpp:333
msgid "Fly straight"
msgstr "Letìt rovnì"
-#: engines/scumm/help.cpp:322
+#: engines/scumm/help.cpp:334
msgid "Fly down"
msgstr "Letìt dolù"
-#: engines/scumm/help.cpp:323
+#: engines/scumm/help.cpp:335
msgid "Fly to upper right"
msgstr "Letìt doprava nahoru"
-#: engines/scumm/help.cpp:324
+#: engines/scumm/help.cpp:336
msgid "Fly to right"
msgstr "Letìt doprava"
-#: engines/scumm/help.cpp:325
+#: engines/scumm/help.cpp:337
msgid "Fly to lower right"
msgstr "Letìt doprava dolù"
-#: engines/scumm/scumm.cpp:1823
+#: engines/scumm/scumm.cpp:1832
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
@@ -3183,11 +3273,12 @@ msgstr ""
"Pøirozená podpora MIDI vy¾aduje Aktualizaci Roland od LucasArts,\n"
"ale %s chybí. Místo toho je pou¾it AdLib."
-#: engines/scumm/scumm.cpp:2594
+#: engines/scumm/scumm.cpp:2644
+#, fuzzy
msgid ""
-"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
-"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
-"directory inside the Tentacle game directory."
+"Usually, Maniac Mansion would start now. But for that to work, the game "
+"files for Maniac Mansion have to be in the 'Maniac' directory inside the "
+"Tentacle game directory, and the game has to be added to ScummVM."
msgstr ""
"Normálnì by teï Maniac Mansion byl spu¹tìn. Ale ScummVM toto zatím nedìlá. "
"Abyste toto mohli hrát, pøejdìte do 'Pøidat Hru' v poèáteèním menu ScummVM a "
@@ -3321,6 +3412,47 @@ msgstr ""
msgid "Show the current number of frames per second in the upper left corner"
msgstr ""
+#: engines/zvision/detection.cpp:256
+msgid "Double FPS"
+msgstr ""
+
+#: engines/zvision/detection.cpp:257
+msgid "Increase game FPS from 30 to 60"
+msgstr ""
+
+#: engines/zvision/detection.cpp:266
+#, fuzzy
+msgid "Enable Venus"
+msgstr "Zapnout héliový re¾im"
+
+#: engines/zvision/detection.cpp:267
+msgid "Enable the Venus help system"
+msgstr ""
+
+#: engines/zvision/detection.cpp:276
+msgid "Disable animation while turning"
+msgstr ""
+
+#: engines/zvision/detection.cpp:277
+msgid "Disable animation while turning in panoramic mode"
+msgstr ""
+
+#: engines/zvision/detection.cpp:286
+msgid "Use the hires MPEG movies"
+msgstr ""
+
+#: engines/zvision/detection.cpp:287
+#, fuzzy
+msgid ""
+"Use the hires MPEG movies of the DVD version, instead of the lowres AVI ones"
+msgstr "Pou¾ít alternativní sadu støíbrných kurzorù místo standardních zlatých"
+
+#~ msgid "EGA undithering"
+#~ msgstr "Nerozkládání EGA"
+
+#~ msgid "Enable undithering in EGA games"
+#~ msgstr "Povolit nerozkládání v EGA hrách"
+
#~ msgid "MPEG-2 cutscenes found but ScummVM has been built without MPEG-2"
#~ msgstr "Videa MPEG-2 nalezena, ale ScummVM byl sestaven bez MPEG-2"
@@ -3328,9 +3460,6 @@ msgstr ""
#~ msgid "Mass Add..."
#~ msgstr "Hromadné Pøidání..."
-#~ msgid "Mass Add..."
-#~ msgstr "Hromadné Pøidání..."
-
#~ msgid ""
#~ "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
#~ msgstr ""
diff --git a/po/da_DA.po b/po/da_DA.po
index 480e2005d0..82760de5d8 100644
--- a/po/da_DA.po
+++ b/po/da_DA.po
@@ -1,5 +1,5 @@
# Dansk translation for ScummVM
-# Copyright (C) 2010-2014 ScummVM Team
+# Copyright (C) 2010-2015 The ScummVM Team
# This file is distributed under the same license as the ScummVM package.
# Steffen Nyeland <steffen@nyeland.dk>, 2010.
#
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.3.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2014-10-04 00:58+0100\n"
+"POT-Creation-Date: 2015-06-30 20:57+0100\n"
"PO-Revision-Date: 2014-07-09 17:34+0100\n"
"Last-Translator: Steffen Nyeland <steffen@nyeland.dk>\n"
"Language-Team: Steffen Nyeland <steffen@nyeland.dk>\n"
@@ -54,10 +54,11 @@ msgstr "Gå op"
#: gui/browser.cpp:75 gui/chooser.cpp:46 gui/KeysDialog.cpp:43
#: gui/launcher.cpp:351 gui/massadd.cpp:95 gui/options.cpp:1239
+#: gui/recorderdialog.cpp:70 gui/recorderdialog.cpp:156
#: gui/saveload-dialog.cpp:216 gui/saveload-dialog.cpp:276
-#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:922
+#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:931
#: gui/themebrowser.cpp:55 gui/fluidsynth-dialog.cpp:152
-#: engines/engine.cpp:452 backends/platform/wii/options.cpp:48
+#: engines/engine.cpp:483 backends/platform/wii/options.cpp:48
#: backends/events/default/default-events.cpp:196
#: backends/events/default/default-events.cpp:218
#: engines/drascula/saveload.cpp:49 engines/parallaction/saveload.cpp:274
@@ -70,9 +71,9 @@ msgid "Choose"
msgstr "Vælg"
#: gui/gui-manager.cpp:117 backends/keymapper/remap-dialog.cpp:53
-#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
-#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
-#: engines/scumm/help.cpp:209
+#: engines/scumm/help.cpp:126 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:192
+#: engines/scumm/help.cpp:210
msgid "Close"
msgstr "Luk"
@@ -88,7 +89,7 @@ msgstr "Vis tastatur"
msgid "Remap keys"
msgstr "Kortlæg taster"
-#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:86
+#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:87
msgid "Toggle fullscreen"
msgstr "Skift fuldskærm"
@@ -102,13 +103,13 @@ msgstr "Kortlæg"
#: gui/KeysDialog.cpp:42 gui/launcher.cpp:352 gui/launcher.cpp:1048
#: gui/launcher.cpp:1052 gui/massadd.cpp:92 gui/options.cpp:1240
-#: gui/saveload-dialog.cpp:923 gui/fluidsynth-dialog.cpp:153
-#: engines/engine.cpp:371 engines/engine.cpp:382
+#: gui/saveload-dialog.cpp:932 gui/fluidsynth-dialog.cpp:153
+#: engines/engine.cpp:402 engines/engine.cpp:413
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
#: engines/agos/animation.cpp:558 engines/drascula/saveload.cpp:49
-#: engines/groovie/script.cpp:399 engines/parallaction/saveload.cpp:274
-#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1825
+#: engines/groovie/script.cpp:408 engines/parallaction/saveload.cpp:274
+#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1834
#: engines/scumm/players/player_v3m.cpp:130
#: engines/scumm/players/player_v5m.cpp:108 engines/sky/compact.cpp:131
#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:524
@@ -478,7 +479,7 @@ msgstr ""
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -488,7 +489,7 @@ msgstr "Ja"
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -525,6 +526,14 @@ msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr ""
"ScummVM kunne ikke finde en motor, istand til at afvikle det valgte spil!"
+#: gui/launcher.cpp:1159
+msgid "Mass Add..."
+msgstr "Tilføj flere..."
+
+#: gui/launcher.cpp:1161
+msgid "Record..."
+msgstr ""
+
#: gui/massadd.cpp:79 gui/massadd.cpp:82
msgid "... progress ..."
msgstr "... fremskridt ..."
@@ -623,7 +632,7 @@ msgid "Special dithering modes supported by some games"
msgstr "Speciel farvereduceringstilstand understøttet a nogle spil"
#: gui/options.cpp:760
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2249
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2298
msgid "Fullscreen mode"
msgstr "Fuldskærms tilstand"
@@ -937,6 +946,43 @@ msgstr ""
"Temaet du valgte understøtter ikke dit aktuelle sprog. Hvis du ønsker at "
"bruge dette tema, skal du skifte til et andet sprog først."
+#: gui/recorderdialog.cpp:64
+msgid "Recorder or Playback Gameplay"
+msgstr ""
+
+#: gui/recorderdialog.cpp:69 gui/recorderdialog.cpp:156
+#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
+msgid "Delete"
+msgstr "Slet"
+
+#: gui/recorderdialog.cpp:71
+msgid "Record"
+msgstr ""
+
+#: gui/recorderdialog.cpp:72
+#, fuzzy
+msgid "Playback"
+msgstr "Spil"
+
+#: gui/recorderdialog.cpp:74
+msgid "Edit"
+msgstr ""
+
+#: gui/recorderdialog.cpp:86 gui/recorderdialog.cpp:243
+#: gui/recorderdialog.cpp:253
+msgid "Author: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:87 gui/recorderdialog.cpp:244
+#: gui/recorderdialog.cpp:254
+msgid "Notes: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:155
+#, fuzzy
+msgid "Do you really want to delete this record?"
+msgstr "Vil du virkelig slette denne gemmer?"
+
#: gui/saveload-dialog.cpp:167
msgid "List view"
msgstr "Liste visning"
@@ -957,23 +1003,19 @@ msgstr "Intet tidspunkt gemt"
msgid "No playtime saved"
msgstr "Ingen spilletid gemt"
-#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
-msgid "Delete"
-msgstr "Slet"
-
#: gui/saveload-dialog.cpp:275
msgid "Do you really want to delete this saved game?"
msgstr "Vil du virkelig slette denne gemmer?"
-#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:875
+#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:884
msgid "Date: "
msgstr "Dato:"
-#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:881
+#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:890
msgid "Time: "
msgstr "Tid:"
-#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:889
+#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:898
msgid "Playtime: "
msgstr "Spilletid:"
@@ -989,19 +1031,19 @@ msgstr "Næste"
msgid "Prev"
msgstr "Forrige"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "New Save"
msgstr "Ny Gemmer"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "Create a new save game"
msgstr "Opret en ny gemmer"
-#: gui/saveload-dialog.cpp:868
+#: gui/saveload-dialog.cpp:877
msgid "Name: "
msgstr "Navn:"
-#: gui/saveload-dialog.cpp:940
+#: gui/saveload-dialog.cpp:949
#, c-format
msgid "Enter a description for slot %d:"
msgstr "Indtast en beskrivelse af plads %d:"
@@ -1154,7 +1196,7 @@ msgstr "Spring linje over"
msgid "Error running game:"
msgstr "Fejl ved kørsel af spil:"
-#: base/main.cpp:536
+#: base/main.cpp:554
msgid "Could not find any engine capable of running the selected game"
msgstr "Kunne ikke finde nogen motor istand til at afvikle det valgte spil"
@@ -1272,7 +1314,7 @@ msgstr "~R~etur til oversigt"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:803
#: engines/cruise/menu.cpp:212 engines/drascula/saveload.cpp:336
#: engines/dreamweb/saveload.cpp:261 engines/neverhood/menumodule.cpp:873
-#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:758
+#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:759
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save game:"
msgstr "Gemmer:"
@@ -1285,7 +1327,7 @@ msgstr "Gemmer:"
#: engines/agi/saveload.cpp:803 engines/cruise/menu.cpp:212
#: engines/drascula/saveload.cpp:336 engines/dreamweb/saveload.cpp:261
#: engines/neverhood/menumodule.cpp:873 engines/pegasus/pegasus.cpp:377
-#: engines/sci/engine/kfile.cpp:758 engines/scumm/dialogs.cpp:188
+#: engines/sci/engine/kfile.cpp:759 engines/scumm/dialogs.cpp:188
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save"
msgstr "Gem"
@@ -1323,23 +1365,23 @@ msgstr "~F~ortryd"
msgid "~K~eys"
msgstr "~T~aster"
-#: engines/engine.cpp:245
+#: engines/engine.cpp:276
msgid "Could not initialize color format."
msgstr "Kunne ikke initialisere farveformat."
-#: engines/engine.cpp:253
+#: engines/engine.cpp:284
msgid "Could not switch to video mode: '"
msgstr "Kunne ikke skifte til videotilstand: '"
-#: engines/engine.cpp:262
+#: engines/engine.cpp:293
msgid "Could not apply aspect ratio setting."
msgstr "Kunne ikke anvende billedformat korrektion indstilling."
-#: engines/engine.cpp:267
+#: engines/engine.cpp:298
msgid "Could not apply fullscreen setting."
msgstr "Kunne ikke anvende fuldskærm indstilling."
-#: engines/engine.cpp:367
+#: engines/engine.cpp:398
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1353,7 +1395,7 @@ msgstr ""
"datafiler til din harddisk i stedet.\n"
"Se README fil for detaljer."
-#: engines/engine.cpp:378
+#: engines/engine.cpp:409
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1367,7 +1409,7 @@ msgstr ""
"for at lytte til spillets musik.\n"
"Se README fil for detaljer."
-#: engines/engine.cpp:436
+#: engines/engine.cpp:467
#, c-format
msgid ""
"Gamestate load failed (%s)! Please consult the README for basic information, "
@@ -1377,7 +1419,7 @@ msgstr ""
"grundlæggende oplysninger, og for at få instruktioner om, hvordan man får "
"yderligere hjælp."
-#: engines/engine.cpp:449
+#: engines/engine.cpp:480
msgid ""
"WARNING: The game you are about to start is not yet fully supported by "
"ScummVM. As such, it is likely to be unstable, and any saves you make might "
@@ -1387,7 +1429,7 @@ msgstr ""
"ScummVM. Således, er det sandsynligt, at det er ustabilt, og alle gemmer du "
"foretager fungerer muligvis ikke i fremtidige versioner af ScummVM."
-#: engines/engine.cpp:452
+#: engines/engine.cpp:483
msgid "Start anyway"
msgstr "Start alligevel"
@@ -1596,11 +1638,11 @@ msgstr "Pegeplade tilstand aktiveret."
msgid "Touchpad mode disabled."
msgstr "Pegeplade tilstand deaktiveret."
-#: backends/platform/maemo/maemo.cpp:209
+#: backends/platform/maemo/maemo.cpp:208
msgid "Click Mode"
msgstr "Klik tilstand"
-#: backends/platform/maemo/maemo.cpp:215
+#: backends/platform/maemo/maemo.cpp:214
#: backends/platform/symbian/src/SymbianActions.cpp:42
#: backends/platform/wince/CEActionsPocket.cpp:60
#: backends/platform/wince/CEActionsSmartphone.cpp:43
@@ -1608,11 +1650,11 @@ msgstr "Klik tilstand"
msgid "Left Click"
msgstr "Venstre klik"
-#: backends/platform/maemo/maemo.cpp:218
+#: backends/platform/maemo/maemo.cpp:217
msgid "Middle Click"
msgstr "Miderste klik"
-#: backends/platform/maemo/maemo.cpp:221
+#: backends/platform/maemo/maemo.cpp:220
#: backends/platform/symbian/src/SymbianActions.cpp:43
#: backends/platform/wince/CEActionsSmartphone.cpp:44
#: backends/platform/tizen/form.cpp:267
@@ -1649,19 +1691,19 @@ msgctxt "lowres"
msgid "Normal (no scaling)"
msgstr "Normal (ingen skalering)"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2148
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2197
msgid "Enabled aspect ratio correction"
msgstr "Aktivér billedformat korrektion"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2154
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2203
msgid "Disabled aspect ratio correction"
msgstr "Deaktivér billedformat korrektion"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2209
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2258
msgid "Active graphics filter:"
msgstr "Aktive grafik filtre:"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2251
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2300
msgid "Windowed mode"
msgstr "Vindue tilstand"
@@ -1720,8 +1762,8 @@ msgstr "Hurtig tilstand"
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
#: backends/events/default/default-events.cpp:218
-#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:82
-#: engines/scumm/help.cpp:84
+#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:83
+#: engines/scumm/help.cpp:85
msgid "Quit"
msgstr "Afslut"
@@ -1741,7 +1783,7 @@ msgstr "Virtuelt tastatur"
msgid "Key mapper"
msgstr "Tastetildeling"
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
msgid "Do you want to quit ?"
msgstr "Vil du afslutte?"
@@ -2077,33 +2119,54 @@ msgstr "Klik aktiveret"
msgid "Clicking Disabled"
msgstr "Klik deaktiveret"
-#: engines/agi/detection.cpp:142 engines/drascula/detection.cpp:302
+#: engines/agi/detection.cpp:147 engines/drascula/detection.cpp:302
#: engines/dreamweb/detection.cpp:47 engines/neverhood/detection.cpp:160
#: engines/sci/detection.cpp:394 engines/toltecs/detection.cpp:200
-#: engines/zvision/detection.cpp:103
+#: engines/zvision/detection.cpp:246
msgid "Use original save/load screens"
msgstr "Brug original gem/indlæs skærme"
-#: engines/agi/detection.cpp:143 engines/drascula/detection.cpp:303
+#: engines/agi/detection.cpp:148 engines/drascula/detection.cpp:303
#: engines/dreamweb/detection.cpp:48 engines/neverhood/detection.cpp:161
#: engines/sci/detection.cpp:395 engines/toltecs/detection.cpp:201
-#: engines/zvision/detection.cpp:104
+#: engines/zvision/detection.cpp:247
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"
+#: engines/agi/detection.cpp:157
+#, fuzzy
+msgid "Use an alternative palette"
+msgstr "Brug en alternativ spil intro (kun CD version)"
+
+#: engines/agi/detection.cpp:158
+msgid ""
+"Use an alternative palette, common for all Amiga games. This was the old "
+"behavior"
+msgstr ""
+
+#: engines/agi/detection.cpp:167
+#, fuzzy
+msgid "Mouse support"
+msgstr "Spring over støtte"
+
+#: engines/agi/detection.cpp:168
+msgid ""
+"Enables mouse support. Allows to use mouse for movement and in game menus."
+msgstr ""
+
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore game:"
msgstr "Gendan spil:"
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore"
msgstr "Gendan"
-#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2368
+#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2377
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -2114,7 +2177,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2361
+#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2370
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -2125,7 +2188,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2379
+#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2388
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -2141,12 +2204,12 @@ msgstr ""
msgid "Cutscene file '%s' not found!"
msgstr "Filmsekvens fil '%s' ikke fundet!"
-#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:81
+#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:101
#, fuzzy
msgid "Color Blind Mode"
msgstr "Klik tilstand"
-#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:82
+#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:102
msgid "Enable Color Blind Mode by default"
msgstr ""
@@ -2198,7 +2261,7 @@ msgstr "Hurtig film hastighed"
msgid "Play movies at an increased speed"
msgstr "Afspil film med forhøjet hastighed"
-#: engines/groovie/script.cpp:399
+#: engines/groovie/script.cpp:408
msgid "Failed to save game"
msgstr "Mislykkedes at gemme spil"
@@ -2497,12 +2560,12 @@ msgid "Use an alternative game intro (CD version only)"
msgstr "Brug en alternativ spil intro (kun CD version)"
#: engines/sci/detection.cpp:374
-msgid "EGA undithering"
-msgstr "EGA farveforøgelse"
+msgid "Skip EGA dithering pass (full color backgrounds)"
+msgstr ""
#: engines/sci/detection.cpp:375
-msgid "Enable undithering in EGA games"
-msgstr "Aktiver farveforøgelse i EGA spil"
+msgid "Skip dithering pass in EGA games, graphics are shown with full colors"
+msgstr ""
#: engines/sci/detection.cpp:384
msgid "Prefer digital sound effects"
@@ -2574,12 +2637,14 @@ msgstr "Spil sat på pause. Tryk MELLEMRUM for at fortsætte."
#. "Moechten Sie wirklich neu starten? (J/N)J"
#. Will react to J as 'Yes'
#: engines/scumm/dialogs.cpp:183
-msgid "Are you sure you want to restart? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to restart? (Y/N)Y"
msgstr "Er du sikker på at du vil genstarte? (J/N) "
#. I18N: you may specify 'Yes' symbol at the end of the line. See previous comment
#: engines/scumm/dialogs.cpp:185
-msgid "Are you sure you want to quit? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to quit? (Y/N)Y"
msgstr "Er du sikker på at du vil afslutte? (J/N) "
#: engines/scumm/dialogs.cpp:190
@@ -2667,516 +2732,541 @@ msgstr "Træning"
msgid "Expert"
msgstr "Ekspert"
-#: engines/scumm/help.cpp:73
+#: engines/scumm/help.cpp:74
msgid "Common keyboard commands:"
msgstr "Almindelige tastatur kommandoer:"
-#: engines/scumm/help.cpp:74
+#: engines/scumm/help.cpp:75
msgid "Save / Load dialog"
msgstr "Gem / Indlæs dialog"
-#: engines/scumm/help.cpp:76
+#: engines/scumm/help.cpp:77
msgid "Skip line of text"
msgstr "Spring tekstlinje over"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Esc"
msgstr "Esc"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Skip cutscene"
msgstr "Spring mellemscene over"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Space"
msgstr "Mellemrum"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Pause game"
msgstr "Pause spil"
-#: engines/scumm/help.cpp:79 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:95 engines/scumm/help.cpp:96
-#: engines/scumm/help.cpp:97 engines/scumm/help.cpp:98
-#: engines/scumm/help.cpp:99 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:96 engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98 engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Ctrl"
msgstr "Ctrl"
-#: engines/scumm/help.cpp:79
+#: engines/scumm/help.cpp:80
msgid "Load game state 1-10"
msgstr "Indlæs spil tilstand 1-10"
-#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:81 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Alt"
msgstr "Alt"
-#: engines/scumm/help.cpp:80
+#: engines/scumm/help.cpp:81
msgid "Save game state 1-10"
msgstr "Gem spil tilstand 1-10"
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:90
msgid "Enter"
msgstr "Enter"
-#: engines/scumm/help.cpp:87
+#: engines/scumm/help.cpp:88
msgid "Music volume up / down"
msgstr "Musik lydstyrke op / ned"
-#: engines/scumm/help.cpp:88
+#: engines/scumm/help.cpp:89
msgid "Text speed slower / faster"
msgstr "Tekst hastighed langsommere / hurtigere"
-#: engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:90
msgid "Simulate left mouse button"
msgstr "Simulere venstre museknap"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Tab"
msgstr "Tab"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Simulate right mouse button"
msgstr "Simulere højre museknap"
-#: engines/scumm/help.cpp:93
+#: engines/scumm/help.cpp:94
msgid "Special keyboard commands:"
msgstr "Specielle tastatur kommandoer:"
-#: engines/scumm/help.cpp:94
+#: engines/scumm/help.cpp:95
msgid "Show / Hide console"
msgstr "Vis / Skjul konsol"
-#: engines/scumm/help.cpp:95
+#: engines/scumm/help.cpp:96
msgid "Start the debugger"
msgstr "Start fejlfinder"
-#: engines/scumm/help.cpp:96
+#: engines/scumm/help.cpp:97
msgid "Show memory consumption"
msgstr "Vis hukommelsesforbrug"
-#: engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98
msgid "Run in fast mode (*)"
msgstr "Kør i hurtig tilstand (*)"
-#: engines/scumm/help.cpp:98
+#: engines/scumm/help.cpp:99
msgid "Run in really fast mode (*)"
msgstr "Kør i meget hurtig tilstand (*)"
-#: engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100
msgid "Toggle mouse capture"
msgstr "Skift muse fanger"
-#: engines/scumm/help.cpp:100
+#: engines/scumm/help.cpp:101
msgid "Switch between graphics filters"
msgstr "Skift mellem grafik filtre"
-#: engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102
msgid "Increase / Decrease scale factor"
msgstr "Hæv / Sænk skaleringsfaktor"
-#: engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:103
msgid "Toggle aspect-ratio correction"
msgstr "Skift billedformat korrektion"
-#: engines/scumm/help.cpp:107
+#: engines/scumm/help.cpp:108
msgid "* Note that using ctrl-f and"
msgstr "* Bemærk at brug af ctrl-f og"
-#: engines/scumm/help.cpp:108
+#: engines/scumm/help.cpp:109
msgid " ctrl-g are not recommended"
msgstr " ctrl-g ikke kan ikke anbefales"
-#: engines/scumm/help.cpp:109
+#: engines/scumm/help.cpp:110
msgid " since they may cause crashes"
msgstr " siden de kan skabe nedbrud"
-#: engines/scumm/help.cpp:110
+#: engines/scumm/help.cpp:111
msgid " or incorrect game behavior."
msgstr " eller ukorrekt opførsel af spil."
-#: engines/scumm/help.cpp:114
+#: engines/scumm/help.cpp:115
msgid "Spinning drafts on the keyboard:"
msgstr "Spind ordspil på tastaturet:"
-#: engines/scumm/help.cpp:116
+#: engines/scumm/help.cpp:117
msgid "Main game controls:"
msgstr "Vigtigste spilstyring:"
-#: engines/scumm/help.cpp:121 engines/scumm/help.cpp:136
-#: engines/scumm/help.cpp:161
+#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
+#: engines/scumm/help.cpp:162
msgid "Push"
msgstr "Skub"
-#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
-#: engines/scumm/help.cpp:162
+#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
+#: engines/scumm/help.cpp:163
msgid "Pull"
msgstr "Træk"
-#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
-#: engines/scumm/help.cpp:163 engines/scumm/help.cpp:197
-#: engines/scumm/help.cpp:207
+#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
+#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:198
+#: engines/scumm/help.cpp:208
msgid "Give"
msgstr "Giv"
-#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
-#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:190
-#: engines/scumm/help.cpp:208
+#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
+#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
+#: engines/scumm/help.cpp:209
msgid "Open"
msgstr "Åbn"
-#: engines/scumm/help.cpp:126
+#: engines/scumm/help.cpp:127
msgid "Go to"
msgstr "Gå til"
-#: engines/scumm/help.cpp:127
+#: engines/scumm/help.cpp:128
msgid "Get"
msgstr "Tag"
-#: engines/scumm/help.cpp:128 engines/scumm/help.cpp:152
-#: engines/scumm/help.cpp:170 engines/scumm/help.cpp:198
-#: engines/scumm/help.cpp:213 engines/scumm/help.cpp:224
-#: engines/scumm/help.cpp:250
+#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:153
+#: engines/scumm/help.cpp:171 engines/scumm/help.cpp:199
+#: engines/scumm/help.cpp:214 engines/scumm/help.cpp:225
+#: engines/scumm/help.cpp:251
msgid "Use"
msgstr "Brug"
-#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:142
msgid "Read"
msgstr "Læs"
-#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:147
+#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:148
msgid "New kid"
msgstr "Nyt barn"
-#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:153
-#: engines/scumm/help.cpp:171
+#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
+#: engines/scumm/help.cpp:172
msgid "Turn on"
msgstr "Tænd"
-#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
-#: engines/scumm/help.cpp:172
+#: engines/scumm/help.cpp:133 engines/scumm/help.cpp:155
+#: engines/scumm/help.cpp:173
msgid "Turn off"
msgstr "Sluk"
-#: engines/scumm/help.cpp:142 engines/scumm/help.cpp:167
-#: engines/scumm/help.cpp:194
+#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
+#: engines/scumm/help.cpp:195
msgid "Walk to"
msgstr "Gå til"
-#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
-#: engines/scumm/help.cpp:195 engines/scumm/help.cpp:210
-#: engines/scumm/help.cpp:227
+#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:228
msgid "Pick up"
msgstr "Tag op"
-#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:145 engines/scumm/help.cpp:170
msgid "What is"
msgstr "Hvad er"
-#: engines/scumm/help.cpp:146
+#: engines/scumm/help.cpp:147
msgid "Unlock"
msgstr "Lås op"
-#: engines/scumm/help.cpp:149
+#: engines/scumm/help.cpp:150
msgid "Put on"
msgstr "Tag på"
-#: engines/scumm/help.cpp:150
+#: engines/scumm/help.cpp:151
msgid "Take off"
msgstr "Tag af"
-#: engines/scumm/help.cpp:156
+#: engines/scumm/help.cpp:157
msgid "Fix"
msgstr "Lav"
-#: engines/scumm/help.cpp:158
+#: engines/scumm/help.cpp:159
msgid "Switch"
msgstr "Skift"
-#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:228
+#: engines/scumm/help.cpp:167 engines/scumm/help.cpp:229
msgid "Look"
msgstr "Se"
-#: engines/scumm/help.cpp:173 engines/scumm/help.cpp:223
+#: engines/scumm/help.cpp:174 engines/scumm/help.cpp:224
msgid "Talk"
msgstr "Tal"
-#: engines/scumm/help.cpp:174
+#: engines/scumm/help.cpp:175
msgid "Travel"
msgstr "Rejs"
-#: engines/scumm/help.cpp:175
+#: engines/scumm/help.cpp:176
msgid "To Henry / To Indy"
msgstr "Til Henry / Til Indy"
#. I18N: These are different musical notes
-#: engines/scumm/help.cpp:179
+#: engines/scumm/help.cpp:180
msgid "play C minor on distaff"
msgstr "spil C-mol på rok"
-#: engines/scumm/help.cpp:180
+#: engines/scumm/help.cpp:181
msgid "play D on distaff"
msgstr "spil D på rok"
-#: engines/scumm/help.cpp:181
+#: engines/scumm/help.cpp:182
msgid "play E on distaff"
msgstr "spil E på rok"
-#: engines/scumm/help.cpp:182
+#: engines/scumm/help.cpp:183
msgid "play F on distaff"
msgstr "spil F på rok"
-#: engines/scumm/help.cpp:183
+#: engines/scumm/help.cpp:184
msgid "play G on distaff"
msgstr "spil G på rok"
-#: engines/scumm/help.cpp:184
+#: engines/scumm/help.cpp:185
msgid "play A on distaff"
msgstr "spil A på rok"
-#: engines/scumm/help.cpp:185
+#: engines/scumm/help.cpp:186
msgid "play B on distaff"
msgstr "spil H på rok"
-#: engines/scumm/help.cpp:186
+#: engines/scumm/help.cpp:187
msgid "play C major on distaff"
msgstr "spil C-dur på rok"
-#: engines/scumm/help.cpp:192 engines/scumm/help.cpp:214
+#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
msgid "puSh"
msgstr "Skub"
-#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
+#: engines/scumm/help.cpp:194 engines/scumm/help.cpp:216
msgid "pull (Yank)"
msgstr "træk (Y)"
-#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:212
-#: engines/scumm/help.cpp:248
+#: engines/scumm/help.cpp:197 engines/scumm/help.cpp:213
+#: engines/scumm/help.cpp:249
msgid "Talk to"
msgstr "Tal til"
-#: engines/scumm/help.cpp:199 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:200 engines/scumm/help.cpp:212
msgid "Look at"
msgstr "Lur på"
-#: engines/scumm/help.cpp:200
+#: engines/scumm/help.cpp:201
msgid "turn oN"
msgstr "tæNd"
-#: engines/scumm/help.cpp:201
+#: engines/scumm/help.cpp:202
msgid "turn oFf"
msgstr "sluk (F)"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "KeyUp"
msgstr "TastOp"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "Highlight prev dialogue"
msgstr "Fremhæv forrige dialog"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "KeyDown"
msgstr "TastNed"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "Highlight next dialogue"
msgstr "Fremhæv næste dialog"
-#: engines/scumm/help.cpp:222
+#: engines/scumm/help.cpp:223
msgid "Walk"
msgstr "Gå"
-#: engines/scumm/help.cpp:225 engines/scumm/help.cpp:234
-#: engines/scumm/help.cpp:241 engines/scumm/help.cpp:249
+#: engines/scumm/help.cpp:226 engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:242 engines/scumm/help.cpp:250
msgid "Inventory"
msgstr "Oversigt"
-#: engines/scumm/help.cpp:226
+#: engines/scumm/help.cpp:227
msgid "Object"
msgstr "Objekt"
-#: engines/scumm/help.cpp:229
+#: engines/scumm/help.cpp:230
msgid "Black and White / Color"
msgstr "Sort og hvid / Farve"
-#: engines/scumm/help.cpp:232
+#: engines/scumm/help.cpp:233
msgid "Eyes"
msgstr "Øjne"
-#: engines/scumm/help.cpp:233
+#: engines/scumm/help.cpp:234
msgid "Tongue"
msgstr "Tunge"
-#: engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:236
msgid "Punch"
msgstr "Slag"
-#: engines/scumm/help.cpp:236
+#: engines/scumm/help.cpp:237
msgid "Kick"
msgstr "Spark"
-#: engines/scumm/help.cpp:239 engines/scumm/help.cpp:247
+#: engines/scumm/help.cpp:240 engines/scumm/help.cpp:248
msgid "Examine"
msgstr "Undersøg"
-#: engines/scumm/help.cpp:240
+#: engines/scumm/help.cpp:241
msgid "Regular cursor"
msgstr "Normal markør"
#. I18N: Comm is a communication device
-#: engines/scumm/help.cpp:243
+#: engines/scumm/help.cpp:244
msgid "Comm"
msgstr "Komm"
-#: engines/scumm/help.cpp:246
+#: engines/scumm/help.cpp:247
msgid "Save / Load / Options"
msgstr "Gem / Indlæs / Indstillinger"
-#: engines/scumm/help.cpp:255
+#: engines/scumm/help.cpp:256
msgid "Other game controls:"
msgstr "Andre spil kontroller"
-#: engines/scumm/help.cpp:257 engines/scumm/help.cpp:267
+#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:268
msgid "Inventory:"
msgstr "Oversigt:"
-#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:274
+#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
msgid "Scroll list up"
msgstr "Rul liste op"
-#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
+#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:276
msgid "Scroll list down"
msgstr "Rul liste ned"
-#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:268
+#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:269
msgid "Upper left item"
msgstr "Øverste venstre punkt"
-#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:270
+#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
msgid "Lower left item"
msgstr "Nederste højre punkt"
-#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
+#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:272
msgid "Upper right item"
msgstr "Øverste højre punkt"
-#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:273
+#: engines/scumm/help.cpp:264 engines/scumm/help.cpp:274
msgid "Lower right item"
msgstr "Nederste venstre punkt"
-#: engines/scumm/help.cpp:269
+#: engines/scumm/help.cpp:270
msgid "Middle left item"
msgstr "Midterste højre punkt"
-#: engines/scumm/help.cpp:272
+#: engines/scumm/help.cpp:273
msgid "Middle right item"
msgstr "Midterste højre punkt"
-#: engines/scumm/help.cpp:279 engines/scumm/help.cpp:284
+#: engines/scumm/help.cpp:280 engines/scumm/help.cpp:285
msgid "Switching characters:"
msgstr "Skift personer:"
-#: engines/scumm/help.cpp:281
+#: engines/scumm/help.cpp:282
msgid "Second kid"
msgstr "Andet barn"
-#: engines/scumm/help.cpp:282
+#: engines/scumm/help.cpp:283
msgid "Third kid"
msgstr "Tredie barn"
-#: engines/scumm/help.cpp:294
+#: engines/scumm/help.cpp:292
+#, fuzzy
+msgid "Toggle Inventory/IQ Points display"
+msgstr "Skift Center Data Display"
+
+#: engines/scumm/help.cpp:293
+msgid "Toggle Keyboard/Mouse Fighting (*)"
+msgstr ""
+
+#: engines/scumm/help.cpp:295
+msgid "* Keyboard Fighting is always on,"
+msgstr ""
+
+#: engines/scumm/help.cpp:296
+msgid " so despite the in-game message this"
+msgstr ""
+
+#: engines/scumm/help.cpp:297
+msgid " actually toggles Mouse Fighting Off/On"
+msgstr ""
+
+#: engines/scumm/help.cpp:304
msgid "Fighting controls (numpad):"
msgstr "Kamp kontroller (numtast):"
-#: engines/scumm/help.cpp:295 engines/scumm/help.cpp:296
-#: engines/scumm/help.cpp:297
+#: engines/scumm/help.cpp:305 engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:307
msgid "Step back"
msgstr "Skridt tilbage"
-#: engines/scumm/help.cpp:298
+#: engines/scumm/help.cpp:308
msgid "Block high"
msgstr "Blokér højt"
-#: engines/scumm/help.cpp:299
+#: engines/scumm/help.cpp:309
msgid "Block middle"
msgstr "Blokér midtfor"
-#: engines/scumm/help.cpp:300
+#: engines/scumm/help.cpp:310
msgid "Block low"
msgstr "Blokér lavt"
-#: engines/scumm/help.cpp:301
+#: engines/scumm/help.cpp:311
msgid "Punch high"
msgstr "Slå højt"
-#: engines/scumm/help.cpp:302
+#: engines/scumm/help.cpp:312
msgid "Punch middle"
msgstr "Slå midtfor"
-#: engines/scumm/help.cpp:303
+#: engines/scumm/help.cpp:313
msgid "Punch low"
msgstr "Slå lavt"
-#: engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:315
+msgid "Sucker punch"
+msgstr ""
+
+#: engines/scumm/help.cpp:318
msgid "These are for Indy on left."
msgstr "Disse er for Indy til venstre"
-#: engines/scumm/help.cpp:307
+#: engines/scumm/help.cpp:319
msgid "When Indy is on the right,"
msgstr "Når Indy er til højre,"
-#: engines/scumm/help.cpp:308
+#: engines/scumm/help.cpp:320
msgid "7, 4, and 1 are switched with"
msgstr "7, 4 og 1 bliver bytte med"
-#: engines/scumm/help.cpp:309
+#: engines/scumm/help.cpp:321
msgid "9, 6, and 3, respectively."
msgstr "repektivt 9, 6 og 3."
-#: engines/scumm/help.cpp:316
+#: engines/scumm/help.cpp:328
msgid "Biplane controls (numpad):"
msgstr "Biplan kontroller (numtast):"
-#: engines/scumm/help.cpp:317
+#: engines/scumm/help.cpp:329
msgid "Fly to upper left"
msgstr "Flyv øverst til venste"
-#: engines/scumm/help.cpp:318
+#: engines/scumm/help.cpp:330
msgid "Fly to left"
msgstr "Flyv til venstre"
-#: engines/scumm/help.cpp:319
+#: engines/scumm/help.cpp:331
msgid "Fly to lower left"
msgstr "Flyv nederst til venstre"
-#: engines/scumm/help.cpp:320
+#: engines/scumm/help.cpp:332
msgid "Fly upwards"
msgstr "Flyv opad"
-#: engines/scumm/help.cpp:321
+#: engines/scumm/help.cpp:333
msgid "Fly straight"
msgstr "Flyv ligeud"
-#: engines/scumm/help.cpp:322
+#: engines/scumm/help.cpp:334
msgid "Fly down"
msgstr "Flyv nedad"
-#: engines/scumm/help.cpp:323
+#: engines/scumm/help.cpp:335
msgid "Fly to upper right"
msgstr "Flyv øverst til højre"
-#: engines/scumm/help.cpp:324
+#: engines/scumm/help.cpp:336
msgid "Fly to right"
msgstr "Flyv til højre"
-#: engines/scumm/help.cpp:325
+#: engines/scumm/help.cpp:337
msgid "Fly to lower right"
msgstr "Flyv nederst til højre"
-#: engines/scumm/scumm.cpp:1823
+#: engines/scumm/scumm.cpp:1832
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
@@ -3185,11 +3275,12 @@ msgstr ""
"Indbygget MIDI understøttelse kræver Roland opgradering fra LucasArts,\n"
"men %s mangler. Bruger AdLib i stedet."
-#: engines/scumm/scumm.cpp:2594
+#: engines/scumm/scumm.cpp:2644
+#, fuzzy
msgid ""
-"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
-"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
-"directory inside the Tentacle game directory."
+"Usually, Maniac Mansion would start now. But for that to work, the game "
+"files for Maniac Mansion have to be in the 'Maniac' directory inside the "
+"Tentacle game directory, and the game has to be added to ScummVM."
msgstr ""
"Normalt ville Maniac Mansion begynde nu. Men ScummVM kan ikke gøre det "
"endnu. For at spille det, gå til 'Tilføj spil' i ScummVM start-menuen og "
@@ -3326,6 +3417,48 @@ msgstr ""
msgid "Show the current number of frames per second in the upper left corner"
msgstr ""
+#: engines/zvision/detection.cpp:256
+msgid "Double FPS"
+msgstr ""
+
+#: engines/zvision/detection.cpp:257
+msgid "Increase game FPS from 30 to 60"
+msgstr ""
+
+#: engines/zvision/detection.cpp:266
+#, fuzzy
+msgid "Enable Venus"
+msgstr "Aktivér helium tilstand"
+
+#: engines/zvision/detection.cpp:267
+msgid "Enable the Venus help system"
+msgstr ""
+
+#: engines/zvision/detection.cpp:276
+msgid "Disable animation while turning"
+msgstr ""
+
+#: engines/zvision/detection.cpp:277
+msgid "Disable animation while turning in panoramic mode"
+msgstr ""
+
+#: engines/zvision/detection.cpp:286
+msgid "Use the hires MPEG movies"
+msgstr ""
+
+#: engines/zvision/detection.cpp:287
+#, fuzzy
+msgid ""
+"Use the hires MPEG movies of the DVD version, instead of the lowres AVI ones"
+msgstr ""
+"Brug det alternative sæt af sølv markører, i stedet for de normale gyldne"
+
+#~ msgid "EGA undithering"
+#~ msgstr "EGA farveforøgelse"
+
+#~ msgid "Enable undithering in EGA games"
+#~ msgstr "Aktiver farveforøgelse i EGA spil"
+
#~ msgid "MPEG-2 cutscenes found but ScummVM has been built without MPEG-2"
#~ msgstr "MPEG-2 filmsekvenser fundet, men ScummVM er bygget uden MPEG-2"
@@ -3333,9 +3466,6 @@ msgstr ""
#~ msgid "Mass Add..."
#~ msgstr "Tilføj flere..."
-#~ msgid "Mass Add..."
-#~ msgstr "Tilføj flere..."
-
#~ msgid ""
#~ "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
#~ msgstr "Sluk for Generel MIDI kortlægning for spil med Roland MT-32 lydspor"
diff --git a/po/de_DE.po b/po/de_DE.po
index c127f109bf..0e7e5d901c 100644
--- a/po/de_DE.po
+++ b/po/de_DE.po
@@ -1,21 +1,23 @@
# German translation for ScummVM.
-# Copyright (C) 2010-2014 ScummVM Team
+# Copyright (C) 2010-2015 The ScummVM Team
# This file is distributed under the same license as the ScummVM package.
-# Simon Sawatzki <SimSaw@gmx.de>, Lothar Serra Mari, 2014.
+# Simon Sawatzki <SimSaw@gmx.de>, Lothar Serra Mari <scummvm@rootfather.de>, 2015.
#
msgid ""
msgstr ""
-"Project-Id-Version: ScummVM 1.5.0git\n"
+"Project-Id-Version: ScummVM 1.8.0git\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2014-10-04 00:58+0100\n"
-"PO-Revision-Date: 2014-06-14 19:34+0100\n"
-"Last-Translator: Simon Sawatzki <SimSaw@gmx.de>\n"
-"Language-Team: Simon Sawatzki <SimSaw@gmx.de>, Lothar Serra Mari (retired)\n"
+"POT-Creation-Date: 2015-06-30 20:57+0100\n"
+"PO-Revision-Date: 2015-07-04 12:06+0200\n"
+"Last-Translator: Lothar Serra Mari <scummvm@rootfather.de>\n"
+"Language-Team: Simon Sawatzki <SimSaw@gmx.de>, Lothar Serra Mari "
+"<scummvm@rootfather.de>\n"
"Language: Deutsch\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=iso-8859-1\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Poedit 1.8.2\n"
#: gui/about.cpp:94
#, c-format
@@ -36,7 +38,8 @@ msgstr "Versteckte Dateien anzeigen"
#: gui/browser.cpp:68
msgid "Show files marked with the hidden attribute"
-msgstr "Dateien mit Versteckt-Attribut anzeigen"
+msgstr ""
+"Dateien anzeigen, die mit dem \"Versteckt-Attribut\" gekennzeichnet sind"
#: gui/browser.cpp:72
msgid "Go up"
@@ -53,10 +56,11 @@ msgstr "Pfad hoch"
#: gui/browser.cpp:75 gui/chooser.cpp:46 gui/KeysDialog.cpp:43
#: gui/launcher.cpp:351 gui/massadd.cpp:95 gui/options.cpp:1239
+#: gui/recorderdialog.cpp:70 gui/recorderdialog.cpp:156
#: gui/saveload-dialog.cpp:216 gui/saveload-dialog.cpp:276
-#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:922
+#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:931
#: gui/themebrowser.cpp:55 gui/fluidsynth-dialog.cpp:152
-#: engines/engine.cpp:452 backends/platform/wii/options.cpp:48
+#: engines/engine.cpp:483 backends/platform/wii/options.cpp:48
#: backends/events/default/default-events.cpp:196
#: backends/events/default/default-events.cpp:218
#: engines/drascula/saveload.cpp:49 engines/parallaction/saveload.cpp:274
@@ -69,9 +73,9 @@ msgid "Choose"
msgstr "Auswählen"
#: gui/gui-manager.cpp:117 backends/keymapper/remap-dialog.cpp:53
-#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
-#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
-#: engines/scumm/help.cpp:209
+#: engines/scumm/help.cpp:126 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:192
+#: engines/scumm/help.cpp:210
msgid "Close"
msgstr "Schließen"
@@ -87,9 +91,9 @@ msgstr "Tastatur anzeigen"
msgid "Remap keys"
msgstr "Tasten neu zuweisen"
-#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:86
+#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:87
msgid "Toggle fullscreen"
-msgstr "Vollbild EIN/AUS"
+msgstr "Vollbild umschalten"
#: gui/KeysDialog.h:36 gui/KeysDialog.cpp:145
msgid "Choose an action to map"
@@ -101,13 +105,13 @@ msgstr "Zuweisen"
#: gui/KeysDialog.cpp:42 gui/launcher.cpp:352 gui/launcher.cpp:1048
#: gui/launcher.cpp:1052 gui/massadd.cpp:92 gui/options.cpp:1240
-#: gui/saveload-dialog.cpp:923 gui/fluidsynth-dialog.cpp:153
-#: engines/engine.cpp:371 engines/engine.cpp:382
+#: gui/saveload-dialog.cpp:932 gui/fluidsynth-dialog.cpp:153
+#: engines/engine.cpp:402 engines/engine.cpp:413
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
#: engines/agos/animation.cpp:558 engines/drascula/saveload.cpp:49
-#: engines/groovie/script.cpp:399 engines/parallaction/saveload.cpp:274
-#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1825
+#: engines/groovie/script.cpp:408 engines/parallaction/saveload.cpp:274
+#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1834
#: engines/scumm/players/player_v3m.cpp:130
#: engines/scumm/players/player_v5m.cpp:108 engines/sky/compact.cpp:131
#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:524
@@ -220,12 +224,12 @@ msgstr "GFX"
#: gui/launcher.cpp:248
msgid "Override global graphic settings"
-msgstr "Globale Grafikeinstellungen übergehen"
+msgstr "Globale Grafik-Einstellungen übergehen"
#: gui/launcher.cpp:250
msgctxt "lowres"
msgid "Override global graphic settings"
-msgstr "Globale Grafikeinstellungen übergehen"
+msgstr "Globale Grafik-Einstellungen übergehen"
#: gui/launcher.cpp:257 gui/options.cpp:1096
msgid "Audio"
@@ -233,12 +237,12 @@ msgstr "Audio"
#: gui/launcher.cpp:260
msgid "Override global audio settings"
-msgstr "Globale Audioeinstellungen übergehen"
+msgstr "Globale Audio-Einstellungen übergehen"
#: gui/launcher.cpp:262
msgctxt "lowres"
msgid "Override global audio settings"
-msgstr "Globale Audioeinstellungen übergehen"
+msgstr "Globale Audio-Einstellungen übergehen"
#: gui/launcher.cpp:271 gui/options.cpp:1101
msgid "Volume"
@@ -256,7 +260,7 @@ msgstr "Globale Lautstärke-Einstellungen übergehen"
#: gui/launcher.cpp:278
msgctxt "lowres"
msgid "Override global volume settings"
-msgstr "Globale Lautstärkeeinstellungen übergehen"
+msgstr "Globale Lautstärke-Einstellungen übergehen"
#: gui/launcher.cpp:286 gui/options.cpp:1111
msgid "MIDI"
@@ -304,7 +308,7 @@ msgstr "Spielpfad:"
#: gui/launcher.cpp:330 gui/options.cpp:1150
msgid "Extra Path:"
-msgstr "Extrapfad:"
+msgstr "Extras:"
#: gui/launcher.cpp:330 gui/launcher.cpp:332 gui/launcher.cpp:333
msgid "Specifies path to additional data used by the game"
@@ -313,7 +317,7 @@ msgstr "Legt das Verzeichnis für zusätzliche Spieldateien fest."
#: gui/launcher.cpp:332 gui/options.cpp:1152
msgctxt "lowres"
msgid "Extra Path:"
-msgstr "Extrapfad:"
+msgstr "Extras:"
#: gui/launcher.cpp:339 gui/options.cpp:1134
msgid "Save Path:"
@@ -322,12 +326,12 @@ msgstr "Spielstände:"
#: gui/launcher.cpp:339 gui/launcher.cpp:341 gui/launcher.cpp:342
#: gui/options.cpp:1134 gui/options.cpp:1136 gui/options.cpp:1137
msgid "Specifies where your saved games are put"
-msgstr "Legt fest, wo die Spielstände abgelegt werden."
+msgstr "Legt fest, wo die Spielstände gespeichert werden."
#: gui/launcher.cpp:341 gui/options.cpp:1136
msgctxt "lowres"
msgid "Save Path:"
-msgstr "Speichern:"
+msgstr "Spielstände:"
#: gui/launcher.cpp:360 gui/launcher.cpp:459 gui/launcher.cpp:517
#: gui/launcher.cpp:571 gui/options.cpp:1145 gui/options.cpp:1153
@@ -387,7 +391,7 @@ msgstr "~O~ptionen"
#: gui/launcher.cpp:628
msgid "Change global ScummVM options"
-msgstr "Globale ScummVM-Einstellungen bearbeiten"
+msgstr "Globale ScummVM-Einstellungen ändern"
#: gui/launcher.cpp:630
msgid "~S~tart"
@@ -479,7 +483,7 @@ msgstr ""
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -489,7 +493,7 @@ msgstr "Ja"
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -526,9 +530,17 @@ msgstr ""
msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr "ScummVM konnte keine Engine finden, um das Spiel zu starten!"
+#: gui/launcher.cpp:1159
+msgid "Mass Add..."
+msgstr "Durchsuchen"
+
+#: gui/launcher.cpp:1161
+msgid "Record..."
+msgstr "Aufzeichnen"
+
#: gui/massadd.cpp:79 gui/massadd.cpp:82
msgid "... progress ..."
-msgstr "... läuft..."
+msgstr "... läuft ..."
#: gui/massadd.cpp:259
msgid "Scan complete!"
@@ -593,11 +605,11 @@ msgstr "48 kHz"
#: gui/options.cpp:651 gui/options.cpp:859
msgctxt "soundfont"
msgid "None"
-msgstr "-"
+msgstr "Kein SoundFont"
#: gui/options.cpp:389
msgid "Failed to apply some of the graphic options changes:"
-msgstr "Fehler bei einigen Änderungen in Grafikoptionen:"
+msgstr "Folgende Grafikoptionen konnten nicht geändert werden:"
#: gui/options.cpp:401
msgid "the video mode could not be changed."
@@ -626,7 +638,7 @@ msgstr ""
"Spezielle Farbmischungsmethoden werden von manchen Spielen unterstützt."
#: gui/options.cpp:760
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2249
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2298
msgid "Fullscreen mode"
msgstr "Vollbildmodus"
@@ -640,7 +652,7 @@ msgstr "Seitenverhältnis für Spiele mit der Auflösung 320x200 korrigieren"
#: gui/options.cpp:771
msgid "Preferred Device:"
-msgstr "Standard-Gerät:"
+msgstr "Bevorzugtes Gerät:"
#: gui/options.cpp:771
msgid "Music Device:"
@@ -718,11 +730,11 @@ msgstr "SoundFont:"
#: gui/options.cpp:864
msgid "Mixed AdLib/MIDI mode"
-msgstr "AdLib-/MIDI-Modus"
+msgstr "Gemischter AdLib/MIDI-Modus"
#: gui/options.cpp:864
msgid "Use both MIDI and AdLib sound generation"
-msgstr "Benutzt MIDI und AdLib zur Sounderzeugung."
+msgstr "Kombiniert MIDI-Musik mit AdLib-Soundeffekten"
#: gui/options.cpp:867
msgid "MIDI gain:"
@@ -744,24 +756,24 @@ msgstr ""
#: gui/options.cpp:886
msgid "True Roland MT-32 (disable GM emulation)"
-msgstr "Echte Roland-MT-32-Emulation (GM-Emulation deaktiviert)"
+msgstr "Echte Roland MT-32 (GM-Emulation deaktiviert)"
#: gui/options.cpp:886 gui/options.cpp:888
msgid ""
"Check if you want to use your real hardware Roland-compatible sound device "
"connected to your computer"
msgstr ""
-"Wählen Sie dies aus, wenn Sie Ihre echte Hardware, die mit einer Roland-"
-"kompatiblen Soundkarte verbunden ist, verwenden möchten."
+"Wählen Sie dies aus, wenn Sie ein echtes Roland-kompatibles Soundgerät "
+"verwenden"
#: gui/options.cpp:888
msgctxt "lowres"
msgid "True Roland MT-32 (no GM emulation)"
-msgstr "Echte Roland-MT-32-Emulation (kein GM)"
+msgstr "Echte Roland MT-32 (keine GM-Emulation)"
#: gui/options.cpp:891
msgid "Roland GS Device (enable MT-32 mappings)"
-msgstr "Roland-GS-Modus (MT-32-Zuweisungen aktivieren)"
+msgstr "Roland-GS-Gerät (MT-32-Zuweisungen aktivieren)"
#: gui/options.cpp:891
msgid ""
@@ -798,7 +810,7 @@ msgstr "Untertitel-Tempo:"
#: gui/options.cpp:937
msgctxt "lowres"
msgid "Text and Speech:"
-msgstr "Sprache + Text:"
+msgstr "Text u. Sprache:"
#: gui/options.cpp:941
msgid "Spch"
@@ -833,7 +845,7 @@ msgstr "Musiklautstärke:"
#: gui/options.cpp:970
msgid "Mute All"
-msgstr "Alles aus"
+msgstr "Alles stumm"
#: gui/options.cpp:973
msgid "SFX volume:"
@@ -859,12 +871,12 @@ msgstr "Sprachlautst.:"
#: gui/options.cpp:1142
msgid "Theme Path:"
-msgstr "Themenpfad:"
+msgstr "Themen:"
#: gui/options.cpp:1144
msgctxt "lowres"
msgid "Theme Path:"
-msgstr "Themenpfad:"
+msgstr "Themen:"
#: gui/options.cpp:1150 gui/options.cpp:1152 gui/options.cpp:1153
msgid "Specifies path to additional data used by all games or ScummVM"
@@ -874,12 +886,12 @@ msgstr ""
#: gui/options.cpp:1159
msgid "Plugins Path:"
-msgstr "Plugin-Pfad:"
+msgstr "Plugins:"
#: gui/options.cpp:1161
msgctxt "lowres"
msgid "Plugins Path:"
-msgstr "Plugin-Pfad:"
+msgstr "Plugins:"
#: gui/options.cpp:1170 gui/fluidsynth-dialog.cpp:138
msgid "Misc"
@@ -905,7 +917,7 @@ msgstr "Autom. Speichern:"
#: gui/options.cpp:1192
msgctxt "lowres"
msgid "Autosave:"
-msgstr "Speich.(auto)"
+msgstr "Autospeichern:"
#: gui/options.cpp:1200
msgid "Keys"
@@ -951,6 +963,41 @@ msgstr ""
"dieses Thema benutzen wollen, müssen Sie erst zu einer anderen Sprache "
"wechseln."
+#: gui/recorderdialog.cpp:64
+msgid "Recorder or Playback Gameplay"
+msgstr "Spiel aufzeichnen oder wiedergeben"
+
+#: gui/recorderdialog.cpp:69 gui/recorderdialog.cpp:156
+#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
+msgid "Delete"
+msgstr "Löschen"
+
+#: gui/recorderdialog.cpp:71
+msgid "Record"
+msgstr "Aufnahme"
+
+#: gui/recorderdialog.cpp:72
+msgid "Playback"
+msgstr "Wiedergabe"
+
+#: gui/recorderdialog.cpp:74
+msgid "Edit"
+msgstr "Bearbeiten"
+
+#: gui/recorderdialog.cpp:86 gui/recorderdialog.cpp:243
+#: gui/recorderdialog.cpp:253
+msgid "Author: "
+msgstr "Autor:"
+
+#: gui/recorderdialog.cpp:87 gui/recorderdialog.cpp:244
+#: gui/recorderdialog.cpp:254
+msgid "Notes: "
+msgstr "Notizen:"
+
+#: gui/recorderdialog.cpp:155
+msgid "Do you really want to delete this record?"
+msgstr "Möchten Sie diese Aufnahme wirklich löschen?"
+
#: gui/saveload-dialog.cpp:167
msgid "List view"
msgstr "Listenansicht"
@@ -971,23 +1018,19 @@ msgstr "Keine Zeit gespeichert"
msgid "No playtime saved"
msgstr "Keine Spielzeit gespeichert"
-#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
-msgid "Delete"
-msgstr "Löschen"
-
#: gui/saveload-dialog.cpp:275
msgid "Do you really want to delete this saved game?"
msgstr "Diesen Spielstand wirklich löschen?"
-#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:875
+#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:884
msgid "Date: "
msgstr "Datum: "
-#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:881
+#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:890
msgid "Time: "
msgstr "Zeit: "
-#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:889
+#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:898
msgid "Playtime: "
msgstr "Spieldauer: "
@@ -1003,19 +1046,19 @@ msgstr "Vor"
msgid "Prev"
msgstr "Zurück"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "New Save"
msgstr "Neuer Spielstand"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "Create a new save game"
msgstr "Erstellt einen neuen Spielstand."
-#: gui/saveload-dialog.cpp:868
+#: gui/saveload-dialog.cpp:877
msgid "Name: "
msgstr "Name: "
-#: gui/saveload-dialog.cpp:940
+#: gui/saveload-dialog.cpp:949
#, c-format
msgid "Enter a description for slot %d:"
msgstr "Geben Sie eine Beschreibung für Speicherplatz %d ein:"
@@ -1168,7 +1211,7 @@ msgstr "Zeile überspringen"
msgid "Error running game:"
msgstr "Fehler beim Ausführen des Spiels:"
-#: base/main.cpp:536
+#: base/main.cpp:554
msgid "Could not find any engine capable of running the selected game"
msgstr "Konnte keine Spiel-Engine finden, die dieses Spiel starten kann."
@@ -1178,7 +1221,7 @@ msgstr "Kein Fehler"
#: common/error.cpp:40
msgid "Game data not found"
-msgstr "Spieldaten nicht gefunden"
+msgstr "Spieldateien nicht gefunden"
#: common/error.cpp:42
msgid "Game id not supported"
@@ -1289,7 +1332,7 @@ msgstr "Zur Spiele~l~iste"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:803
#: engines/cruise/menu.cpp:212 engines/drascula/saveload.cpp:336
#: engines/dreamweb/saveload.cpp:261 engines/neverhood/menumodule.cpp:873
-#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:758
+#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:759
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save game:"
msgstr "Speichern:"
@@ -1302,7 +1345,7 @@ msgstr "Speichern:"
#: engines/agi/saveload.cpp:803 engines/cruise/menu.cpp:212
#: engines/drascula/saveload.cpp:336 engines/dreamweb/saveload.cpp:261
#: engines/neverhood/menumodule.cpp:873 engines/pegasus/pegasus.cpp:377
-#: engines/sci/engine/kfile.cpp:758 engines/scumm/dialogs.cpp:188
+#: engines/sci/engine/kfile.cpp:759 engines/scumm/dialogs.cpp:188
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save"
msgstr "Speichern"
@@ -1339,23 +1382,23 @@ msgstr "~A~bbrechen"
msgid "~K~eys"
msgstr "~T~asten"
-#: engines/engine.cpp:245
+#: engines/engine.cpp:276
msgid "Could not initialize color format."
msgstr "Konnte Farbenformat nicht initialisieren."
-#: engines/engine.cpp:253
+#: engines/engine.cpp:284
msgid "Could not switch to video mode: '"
-msgstr "Konnte nicht zu Grafikmodus wechseln: '"
+msgstr "Konnte nicht zu Grafikmodus wechseln: \""
-#: engines/engine.cpp:262
+#: engines/engine.cpp:293
msgid "Could not apply aspect ratio setting."
msgstr "Konnte Einstellung für Seitenverhältniskorrektur nicht anwenden."
-#: engines/engine.cpp:267
+#: engines/engine.cpp:298
msgid "Could not apply fullscreen setting."
msgstr "Konnte Einstellung für Vollbildmodus nicht anwenden."
-#: engines/engine.cpp:367
+#: engines/engine.cpp:398
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1371,7 +1414,7 @@ msgstr ""
"Lesen Sie die Liesmich-Datei für\n"
"weitere Informationen."
-#: engines/engine.cpp:378
+#: engines/engine.cpp:409
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1386,7 +1429,7 @@ msgstr ""
"Spiel hören zu können. Lesen Sie die\n"
"Liesmich-Datei für weitere Informationen."
-#: engines/engine.cpp:436
+#: engines/engine.cpp:467
#, c-format
msgid ""
"Gamestate load failed (%s)! Please consult the README for basic information, "
@@ -1395,7 +1438,7 @@ msgstr ""
"Laden des Spielstands %s fehlgeschlagen! Bitte lesen Sie die Liesmich-Datei "
"für grundlegende Informationen und Anweisungen zu weiterer Hilfe."
-#: engines/engine.cpp:449
+#: engines/engine.cpp:480
msgid ""
"WARNING: The game you are about to start is not yet fully supported by "
"ScummVM. As such, it is likely to be unstable, and any saves you make might "
@@ -1406,7 +1449,7 @@ msgstr ""
"und jegliche Spielstände, die Sie erstellen, könnten in zukünftigen "
"Versionen von ScummVM nicht mehr funktionieren."
-#: engines/engine.cpp:452
+#: engines/engine.cpp:483
msgid "Start anyway"
msgstr "Trotzdem starten"
@@ -1558,7 +1601,7 @@ msgstr "Zu Y-Position gehen"
#: backends/platform/ds/arm9/source/dsoptions.cpp:87
msgid "Use laptop trackpad-style cursor control"
-msgstr "Den Trackpad-Style für Maussteuerung benutzen"
+msgstr "Den Trackpad-Modus für Maussteuerung benutzen"
#: backends/platform/ds/arm9/source/dsoptions.cpp:88
msgid "Tap for left click, double tap right click"
@@ -1570,7 +1613,7 @@ msgstr "Empfindlichkeit"
#: backends/platform/ds/arm9/source/dsoptions.cpp:99
msgid "Initial top screen scale:"
-msgstr "Vergößerung des oberen Bildschirms:"
+msgstr "Vergrößerung des oberen Bildschirms:"
#: backends/platform/ds/arm9/source/dsoptions.cpp:105
msgid "Main screen scaling:"
@@ -1616,11 +1659,11 @@ msgstr "Touchpad-Modus aktiviert."
msgid "Touchpad mode disabled."
msgstr "Touchpad-Modus ausgeschaltet."
-#: backends/platform/maemo/maemo.cpp:209
+#: backends/platform/maemo/maemo.cpp:208
msgid "Click Mode"
msgstr "Klickmodus"
-#: backends/platform/maemo/maemo.cpp:215
+#: backends/platform/maemo/maemo.cpp:214
#: backends/platform/symbian/src/SymbianActions.cpp:42
#: backends/platform/wince/CEActionsPocket.cpp:60
#: backends/platform/wince/CEActionsSmartphone.cpp:43
@@ -1628,11 +1671,11 @@ msgstr "Klickmodus"
msgid "Left Click"
msgstr "Linksklick"
-#: backends/platform/maemo/maemo.cpp:218
+#: backends/platform/maemo/maemo.cpp:217
msgid "Middle Click"
msgstr "Mittelklick"
-#: backends/platform/maemo/maemo.cpp:221
+#: backends/platform/maemo/maemo.cpp:220
#: backends/platform/symbian/src/SymbianActions.cpp:43
#: backends/platform/wince/CEActionsSmartphone.cpp:44
#: backends/platform/tizen/form.cpp:267
@@ -1658,7 +1701,7 @@ msgstr "Fenster"
#: backends/platform/sdl/macosx/appmenu_osx.mm:114
msgid "Minimize"
-msgstr "Im Dock ablegen"
+msgstr "Minimieren"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:46
msgid "Normal (no scaling)"
@@ -1669,19 +1712,19 @@ msgctxt "lowres"
msgid "Normal (no scaling)"
msgstr "Normal ohn.Skalieren"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2148
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2197
msgid "Enabled aspect ratio correction"
msgstr "Seitenverhältniskorrektur an"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2154
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2203
msgid "Disabled aspect ratio correction"
msgstr "Seitenverhältniskorrektur aus"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2209
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2258
msgid "Active graphics filter:"
msgstr "Aktiver Grafikfilter:"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2251
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2300
msgid "Windowed mode"
msgstr "Fenstermodus"
@@ -1740,8 +1783,8 @@ msgstr "Schneller Modus"
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
#: backends/events/default/default-events.cpp:218
-#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:82
-#: engines/scumm/help.cpp:84
+#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:83
+#: engines/scumm/help.cpp:85
msgid "Quit"
msgstr "Beenden"
@@ -1761,7 +1804,7 @@ msgstr "Virtuelle Tastatur"
msgid "Key mapper"
msgstr "Tasten zuordnen"
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
msgid "Do you want to quit ?"
msgstr "Möchten Sie beenden?"
@@ -2098,34 +2141,57 @@ msgstr "Klicken aktiviert"
msgid "Clicking Disabled"
msgstr "Klicken deaktiviert"
-#: engines/agi/detection.cpp:142 engines/drascula/detection.cpp:302
+#: engines/agi/detection.cpp:147 engines/drascula/detection.cpp:302
#: engines/dreamweb/detection.cpp:47 engines/neverhood/detection.cpp:160
#: engines/sci/detection.cpp:394 engines/toltecs/detection.cpp:200
-#: engines/zvision/detection.cpp:103
+#: engines/zvision/detection.cpp:246
msgid "Use original save/load screens"
msgstr "Originale Spielstand-Menüs"
-#: engines/agi/detection.cpp:143 engines/drascula/detection.cpp:303
+#: engines/agi/detection.cpp:148 engines/drascula/detection.cpp:303
#: engines/dreamweb/detection.cpp:48 engines/neverhood/detection.cpp:161
#: engines/sci/detection.cpp:395 engines/toltecs/detection.cpp:201
-#: engines/zvision/detection.cpp:104
+#: engines/zvision/detection.cpp:247
msgid "Use the original save/load screens, instead of the ScummVM ones"
msgstr ""
"Verwendet die originalen Menüs zum Speichern und Laden statt der von ScummVM."
+#: engines/agi/detection.cpp:157
+msgid "Use an alternative palette"
+msgstr "Alternative Farbpalette verwenden"
+
+#: engines/agi/detection.cpp:158
+msgid ""
+"Use an alternative palette, common for all Amiga games. This was the old "
+"behavior"
+msgstr ""
+"Verwende eine alternative Farbpalette für alle Amiga-Spiele. Dies war das "
+"alte Verhalten."
+
+#: engines/agi/detection.cpp:167
+msgid "Mouse support"
+msgstr "Maus-Unterstützung"
+
+#: engines/agi/detection.cpp:168
+msgid ""
+"Enables mouse support. Allows to use mouse for movement and in game menus."
+msgstr ""
+"Aktiviere Maus-Unterstützung. Erlaubt die Verwendung der Maus zur Bewegung "
+"und in Menüs innerhalb des Spiels."
+
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore game:"
msgstr "Spiel laden:"
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore"
msgstr "Laden"
-#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2368
+#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2377
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -2136,7 +2202,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2361
+#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2370
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -2147,7 +2213,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2379
+#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2388
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -2163,14 +2229,13 @@ msgstr ""
msgid "Cutscene file '%s' not found!"
msgstr "Zwischensequenz \"%s\" nicht gefunden!"
-#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:81
-#, fuzzy
+#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:101
msgid "Color Blind Mode"
-msgstr "Klickmodus"
+msgstr "Modus für Farbenblinde"
-#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:82
+#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:102
msgid "Enable Color Blind Mode by default"
-msgstr ""
+msgstr "Modus für Farbenblinde standardmäßig einschalten"
#: engines/drascula/saveload.cpp:47
msgid ""
@@ -2220,17 +2285,17 @@ msgstr "Schnelles Film-Tempo"
msgid "Play movies at an increased speed"
msgstr "Spielt Filme mit erhöhter Geschwindigkeit ab."
-#: engines/groovie/script.cpp:399
+#: engines/groovie/script.cpp:408
msgid "Failed to save game"
msgstr "Konnte Spielstand nicht speichern."
#: engines/hopkins/detection.cpp:76 engines/hopkins/detection.cpp:86
msgid "Gore Mode"
-msgstr ""
+msgstr "Blutmodus"
#: engines/hopkins/detection.cpp:77 engines/hopkins/detection.cpp:87
msgid "Enable Gore Mode when available"
-msgstr ""
+msgstr "Blutmodus aktivieren, wenn verfügbar"
#. I18N: Studio audience adds an applause and cheering sounds whenever
#. Malcolm makes a joke.
@@ -2245,7 +2310,7 @@ msgstr "Aktiviert Studio-Publikum."
#. I18N: This option allows the user to skip text and cutscenes.
#: engines/kyra/detection.cpp:73
msgid "Skip support"
-msgstr "Überspring-Unterstützung"
+msgstr "Erlaube Überspringen"
#: engines/kyra/detection.cpp:74
msgid "Allow text and cutscenes to be skipped"
@@ -2364,6 +2429,13 @@ msgid ""
"Do you wish to use this save game file with ScummVM?\n"
"\n"
msgstr ""
+"Die folgende originale Spielstand-Datei wurde in Ihrem Spieleverzeichnis "
+"gefunden:\n"
+"\n"
+"%s %s\n"
+"\n"
+"Möchten Sie diese Spielstand-Datei in ScummVM verwenden?\n"
+"\n"
#: engines/kyra/saveload_eob.cpp:590
#, c-format
@@ -2371,6 +2443,9 @@ msgid ""
"A save game file was found in the specified slot %d. Overwrite?\n"
"\n"
msgstr ""
+"Eine Spielstand-Datei wurde im gewählten Speicherplatz %d gefunden. "
+"Überschreiben?\n"
+"\n"
#: engines/kyra/saveload_eob.cpp:623
#, c-format
@@ -2382,6 +2457,12 @@ msgid ""
"'import_savefile'.\n"
"\n"
msgstr ""
+"%d originale Spielstand-Dateien wurden erfolgreich nach ScummVM\n"
+"importiert. Wenn Sie weitere Spielstand-Dateien später manuell importieren "
+"wollen,\n"
+"müssen Sie die ScummVM-Entwicklerkonsole öffnen und den Befehl "
+"\"import_savefile\" verwenden.\n"
+"\n"
#. I18N: Option for fast scene switching
#: engines/mohawk/dialogs.cpp:92 engines/mohawk/dialogs.cpp:167
@@ -2523,12 +2604,14 @@ msgid "Use an alternative game intro (CD version only)"
msgstr "Verwendet einen alternativen Vorspann (nur bei CD-Version)."
#: engines/sci/detection.cpp:374
-msgid "EGA undithering"
-msgstr "Antifehlerdiffusion für EGA"
+msgid "Skip EGA dithering pass (full color backgrounds)"
+msgstr "Überspringe EGA-Fehlerdiffusion (Vollfarbige Hintergründe)"
#: engines/sci/detection.cpp:375
-msgid "Enable undithering in EGA games"
-msgstr "Aktiviert die Aufhebung der Fehlerdiffusion in EGA-Spielen."
+msgid "Skip dithering pass in EGA games, graphics are shown with full colors"
+msgstr ""
+"Überspringe Fehlerdiffusion in EGA-Spielen, Grafik wird mit allen Farben "
+"gezeigt"
#: engines/sci/detection.cpp:384
msgid "Prefer digital sound effects"
@@ -2603,12 +2686,12 @@ msgstr "Spielpause. Zum Weiterspielen Leertaste drücken."
#. "Moechten Sie wirklich neu starten? (J/N)J"
#. Will react to J as 'Yes'
#: engines/scumm/dialogs.cpp:183
-msgid "Are you sure you want to restart? (Y/N)"
+msgid "Are you sure you want to restart? (Y/N)Y"
msgstr "Möchten Sie wirklich neu starten? (J/N)J"
#. I18N: you may specify 'Yes' symbol at the end of the line. See previous comment
#: engines/scumm/dialogs.cpp:185
-msgid "Are you sure you want to quit? (Y/N)"
+msgid "Are you sure you want to quit? (Y/N)Y"
msgstr "Möchten Sie wirklich beenden? (J/N)J"
#: engines/scumm/dialogs.cpp:190
@@ -2665,7 +2748,7 @@ msgstr "~W~eiter"
#: engines/scumm/dialogs.cpp:600
msgid "Speech Only"
-msgstr "Nur Sprachausgabe"
+msgstr "Nur Sprache"
#: engines/scumm/dialogs.cpp:601
msgid "Speech and Subtitles"
@@ -2686,7 +2769,7 @@ msgstr "Wähle einen Schwierigkeitsgrad."
#: engines/scumm/dialogs.cpp:658
msgid "Refer to your Loom(TM) manual for help."
-msgstr "Für Hilfe schaue ins Loom-Handbuch."
+msgstr "Für Hilfe schauen Sie ins Loom-Handbuch."
#: engines/scumm/dialogs.cpp:662
msgid "Practice"
@@ -2696,516 +2779,540 @@ msgstr "Anfänger"
msgid "Expert"
msgstr "Experte"
-#: engines/scumm/help.cpp:73
+#: engines/scumm/help.cpp:74
msgid "Common keyboard commands:"
msgstr "Allgemeine Tastenbefehle:"
-#: engines/scumm/help.cpp:74
+#: engines/scumm/help.cpp:75
msgid "Save / Load dialog"
msgstr "Menü zum Speichern/Laden"
-#: engines/scumm/help.cpp:76
+#: engines/scumm/help.cpp:77
msgid "Skip line of text"
msgstr "Textzeile überspringen"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Esc"
msgstr "Esc"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Skip cutscene"
msgstr "Zwischensequenz überspringen"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Space"
msgstr "Leertaste"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Pause game"
msgstr "Spielpause"
-#: engines/scumm/help.cpp:79 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:95 engines/scumm/help.cpp:96
-#: engines/scumm/help.cpp:97 engines/scumm/help.cpp:98
-#: engines/scumm/help.cpp:99 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:96 engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98 engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Ctrl"
msgstr "Strg"
-#: engines/scumm/help.cpp:79
+#: engines/scumm/help.cpp:80
msgid "Load game state 1-10"
msgstr "Spielstand 1-10 laden"
-#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:81 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Alt"
msgstr "Alt"
-#: engines/scumm/help.cpp:80
+#: engines/scumm/help.cpp:81
msgid "Save game state 1-10"
msgstr "Spielstand 1-10 speichern"
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:90
msgid "Enter"
msgstr "Enter"
-#: engines/scumm/help.cpp:87
+#: engines/scumm/help.cpp:88
msgid "Music volume up / down"
msgstr "Musiklautstärke höher/niedriger"
-#: engines/scumm/help.cpp:88
+#: engines/scumm/help.cpp:89
msgid "Text speed slower / faster"
msgstr "Texttempo langsamer/schneller"
-#: engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:90
msgid "Simulate left mouse button"
msgstr "Linke Maustaste simulieren"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Tab"
msgstr "Tabulator"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Simulate right mouse button"
msgstr "Rechte Maustaste simulieren"
-#: engines/scumm/help.cpp:93
+#: engines/scumm/help.cpp:94
msgid "Special keyboard commands:"
msgstr "Spezielle Tastenbefehle:"
-#: engines/scumm/help.cpp:94
+#: engines/scumm/help.cpp:95
msgid "Show / Hide console"
msgstr "Konsole zeigen/verbergen"
-#: engines/scumm/help.cpp:95
+#: engines/scumm/help.cpp:96
msgid "Start the debugger"
msgstr "Debugger starten"
-#: engines/scumm/help.cpp:96
+#: engines/scumm/help.cpp:97
msgid "Show memory consumption"
msgstr "Speicherverbrauch anzeigen"
-#: engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98
msgid "Run in fast mode (*)"
msgstr "Schneller Modus (*)"
-#: engines/scumm/help.cpp:98
+#: engines/scumm/help.cpp:99
msgid "Run in really fast mode (*)"
msgstr "Sehr schneller Modus (*)"
-#: engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100
msgid "Toggle mouse capture"
msgstr "Mauseingrenzung in Fenster EIN/AUS"
-#: engines/scumm/help.cpp:100
+#: engines/scumm/help.cpp:101
msgid "Switch between graphics filters"
msgstr "Zwischen Grafikfiltern wechseln"
-#: engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102
msgid "Increase / Decrease scale factor"
msgstr "Größenverhätlnis höher/niedriger"
-#: engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:103
msgid "Toggle aspect-ratio correction"
msgstr "Seitenverhältnis anpassen: EIN/AUS"
-#: engines/scumm/help.cpp:107
+#: engines/scumm/help.cpp:108
msgid "* Note that using ctrl-f and"
msgstr "* Es wird davon abgeraten,"
-#: engines/scumm/help.cpp:108
+#: engines/scumm/help.cpp:109
msgid " ctrl-g are not recommended"
-msgstr " Strg+f und Strg+g zu verwenden,"
+msgstr " Strg+F und Strg+G zu verwenden,"
-#: engines/scumm/help.cpp:109
+#: engines/scumm/help.cpp:110
msgid " since they may cause crashes"
msgstr " da dies Abstürze oder fehlerhaftes"
-#: engines/scumm/help.cpp:110
+#: engines/scumm/help.cpp:111
msgid " or incorrect game behavior."
msgstr " Spielverhalten verursachen kann."
-#: engines/scumm/help.cpp:114
+#: engines/scumm/help.cpp:115
msgid "Spinning drafts on the keyboard:"
msgstr "Sprüche mit Tastatur spinnen:"
-#: engines/scumm/help.cpp:116
+#: engines/scumm/help.cpp:117
msgid "Main game controls:"
msgstr "Hauptspielsteuerung:"
-#: engines/scumm/help.cpp:121 engines/scumm/help.cpp:136
-#: engines/scumm/help.cpp:161
+#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
+#: engines/scumm/help.cpp:162
msgid "Push"
msgstr "Drücke"
-#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
-#: engines/scumm/help.cpp:162
+#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
+#: engines/scumm/help.cpp:163
msgid "Pull"
msgstr "Ziehe"
-#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
-#: engines/scumm/help.cpp:163 engines/scumm/help.cpp:197
-#: engines/scumm/help.cpp:207
+#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
+#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:198
+#: engines/scumm/help.cpp:208
msgid "Give"
msgstr "Gib"
-#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
-#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:190
-#: engines/scumm/help.cpp:208
+#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
+#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
+#: engines/scumm/help.cpp:209
msgid "Open"
msgstr "Öffne"
-#: engines/scumm/help.cpp:126
+#: engines/scumm/help.cpp:127
msgid "Go to"
msgstr "Gehe zu"
-#: engines/scumm/help.cpp:127
+#: engines/scumm/help.cpp:128
msgid "Get"
msgstr "Nimm"
-#: engines/scumm/help.cpp:128 engines/scumm/help.cpp:152
-#: engines/scumm/help.cpp:170 engines/scumm/help.cpp:198
-#: engines/scumm/help.cpp:213 engines/scumm/help.cpp:224
-#: engines/scumm/help.cpp:250
+#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:153
+#: engines/scumm/help.cpp:171 engines/scumm/help.cpp:199
+#: engines/scumm/help.cpp:214 engines/scumm/help.cpp:225
+#: engines/scumm/help.cpp:251
msgid "Use"
msgstr "Benutze"
-#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:142
msgid "Read"
msgstr "Lies"
-#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:147
+#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:148
msgid "New kid"
msgstr "Person"
-#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:153
-#: engines/scumm/help.cpp:171
+#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
+#: engines/scumm/help.cpp:172
msgid "Turn on"
msgstr "Schalt ein"
-#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
-#: engines/scumm/help.cpp:172
+#: engines/scumm/help.cpp:133 engines/scumm/help.cpp:155
+#: engines/scumm/help.cpp:173
msgid "Turn off"
msgstr "Schalt aus"
-#: engines/scumm/help.cpp:142 engines/scumm/help.cpp:167
-#: engines/scumm/help.cpp:194
+#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
+#: engines/scumm/help.cpp:195
msgid "Walk to"
msgstr "Gehe zu"
-#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
-#: engines/scumm/help.cpp:195 engines/scumm/help.cpp:210
-#: engines/scumm/help.cpp:227
+#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:228
msgid "Pick up"
msgstr "Nimm"
-#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:145 engines/scumm/help.cpp:170
msgid "What is"
msgstr "Was ist"
-#: engines/scumm/help.cpp:146
+#: engines/scumm/help.cpp:147
msgid "Unlock"
msgstr "Schließ auf"
-#: engines/scumm/help.cpp:149
+#: engines/scumm/help.cpp:150
msgid "Put on"
msgstr "Zieh an"
-#: engines/scumm/help.cpp:150
+#: engines/scumm/help.cpp:151
msgid "Take off"
msgstr "Nimm ab"
-#: engines/scumm/help.cpp:156
+#: engines/scumm/help.cpp:157
msgid "Fix"
msgstr "Reparier"
-#: engines/scumm/help.cpp:158
+#: engines/scumm/help.cpp:159
msgid "Switch"
msgstr "Wechsle"
-#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:228
+#: engines/scumm/help.cpp:167 engines/scumm/help.cpp:229
msgid "Look"
msgstr "Schau"
-#: engines/scumm/help.cpp:173 engines/scumm/help.cpp:223
+#: engines/scumm/help.cpp:174 engines/scumm/help.cpp:224
msgid "Talk"
msgstr "Rede"
-#: engines/scumm/help.cpp:174
+#: engines/scumm/help.cpp:175
msgid "Travel"
msgstr "Reise"
-#: engines/scumm/help.cpp:175
+#: engines/scumm/help.cpp:176
msgid "To Henry / To Indy"
msgstr "Zu Henry/Zu Indy"
#. I18N: These are different musical notes
-#: engines/scumm/help.cpp:179
+#: engines/scumm/help.cpp:180
msgid "play C minor on distaff"
msgstr "spiele tiefes C auf Stab"
-#: engines/scumm/help.cpp:180
+#: engines/scumm/help.cpp:181
msgid "play D on distaff"
msgstr "spiele D auf Stab"
-#: engines/scumm/help.cpp:181
+#: engines/scumm/help.cpp:182
msgid "play E on distaff"
msgstr "spiele E auf Stab"
-#: engines/scumm/help.cpp:182
+#: engines/scumm/help.cpp:183
msgid "play F on distaff"
msgstr "spiele F auf Stab"
-#: engines/scumm/help.cpp:183
+#: engines/scumm/help.cpp:184
msgid "play G on distaff"
msgstr "spiele G auf Stab"
-#: engines/scumm/help.cpp:184
+#: engines/scumm/help.cpp:185
msgid "play A on distaff"
msgstr "spiele A auf Stab"
-#: engines/scumm/help.cpp:185
+#: engines/scumm/help.cpp:186
msgid "play B on distaff"
msgstr "spiele B auf Stab"
-#: engines/scumm/help.cpp:186
+#: engines/scumm/help.cpp:187
msgid "play C major on distaff"
msgstr "spiele hohes C auf Stab"
-#: engines/scumm/help.cpp:192 engines/scumm/help.cpp:214
+#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
msgid "puSh"
msgstr "Drücke"
-#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
+#: engines/scumm/help.cpp:194 engines/scumm/help.cpp:216
msgid "pull (Yank)"
msgstr "Ziehe"
-#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:212
-#: engines/scumm/help.cpp:248
+#: engines/scumm/help.cpp:197 engines/scumm/help.cpp:213
+#: engines/scumm/help.cpp:249
msgid "Talk to"
msgstr "Rede mit"
-#: engines/scumm/help.cpp:199 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:200 engines/scumm/help.cpp:212
msgid "Look at"
msgstr "Schau an"
-#: engines/scumm/help.cpp:200
+#: engines/scumm/help.cpp:201
msgid "turn oN"
msgstr "Mach an"
-#: engines/scumm/help.cpp:201
+#: engines/scumm/help.cpp:202
msgid "turn oFf"
msgstr "Mach aus"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "KeyUp"
msgstr "Hoch-Taste"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "Highlight prev dialogue"
msgstr "Vorige Dialogwahl markieren"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "KeyDown"
msgstr "Runter-Taste"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "Highlight next dialogue"
msgstr "Nächste Dialogwahl markieren"
-#: engines/scumm/help.cpp:222
+#: engines/scumm/help.cpp:223
msgid "Walk"
msgstr "Gehe"
-#: engines/scumm/help.cpp:225 engines/scumm/help.cpp:234
-#: engines/scumm/help.cpp:241 engines/scumm/help.cpp:249
+#: engines/scumm/help.cpp:226 engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:242 engines/scumm/help.cpp:250
msgid "Inventory"
msgstr "Inventar"
-#: engines/scumm/help.cpp:226
+#: engines/scumm/help.cpp:227
msgid "Object"
msgstr "Objekt"
-#: engines/scumm/help.cpp:229
+#: engines/scumm/help.cpp:230
msgid "Black and White / Color"
msgstr "Graustufen-Modus/Farbe"
-#: engines/scumm/help.cpp:232
+#: engines/scumm/help.cpp:233
msgid "Eyes"
msgstr "Augen"
-#: engines/scumm/help.cpp:233
+#: engines/scumm/help.cpp:234
msgid "Tongue"
msgstr "Zunge"
-#: engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:236
msgid "Punch"
msgstr "Schlage"
-#: engines/scumm/help.cpp:236
+#: engines/scumm/help.cpp:237
msgid "Kick"
msgstr "Tritt"
-#: engines/scumm/help.cpp:239 engines/scumm/help.cpp:247
+#: engines/scumm/help.cpp:240 engines/scumm/help.cpp:248
msgid "Examine"
msgstr "Betrachte"
-#: engines/scumm/help.cpp:240
+#: engines/scumm/help.cpp:241
msgid "Regular cursor"
msgstr "Normaler Mauszeiger"
#. I18N: Comm is a communication device
-#: engines/scumm/help.cpp:243
+#: engines/scumm/help.cpp:244
msgid "Comm"
msgstr "Kommunikation"
-#: engines/scumm/help.cpp:246
+#: engines/scumm/help.cpp:247
msgid "Save / Load / Options"
msgstr "Speichern / Laden / Optionen"
-#: engines/scumm/help.cpp:255
+#: engines/scumm/help.cpp:256
msgid "Other game controls:"
msgstr "Weitere Steuerung:"
-#: engines/scumm/help.cpp:257 engines/scumm/help.cpp:267
+#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:268
msgid "Inventory:"
msgstr "Inventar:"
-#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:274
+#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
msgid "Scroll list up"
msgstr "Liste hochblättern"
-#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
+#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:276
msgid "Scroll list down"
msgstr "Liste runterblättern"
-#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:268
+#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:269
msgid "Upper left item"
msgstr "Oberer linker Gegenstand"
-#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:270
+#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
msgid "Lower left item"
msgstr "Unterer linker Gegenstand"
-#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
+#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:272
msgid "Upper right item"
msgstr "Oberer rechter Gegenstand"
-#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:273
+#: engines/scumm/help.cpp:264 engines/scumm/help.cpp:274
msgid "Lower right item"
msgstr "Unterer rechter Gegenstand"
-#: engines/scumm/help.cpp:269
+#: engines/scumm/help.cpp:270
msgid "Middle left item"
msgstr "Mittlerer linker Gegenstand"
-#: engines/scumm/help.cpp:272
+#: engines/scumm/help.cpp:273
msgid "Middle right item"
msgstr "Mittlerer rechter Gegenstand"
-#: engines/scumm/help.cpp:279 engines/scumm/help.cpp:284
+#: engines/scumm/help.cpp:280 engines/scumm/help.cpp:285
msgid "Switching characters:"
msgstr "Figuren wechseln:"
-#: engines/scumm/help.cpp:281
+#: engines/scumm/help.cpp:282
msgid "Second kid"
msgstr "Zweites Kind"
-#: engines/scumm/help.cpp:282
+#: engines/scumm/help.cpp:283
msgid "Third kid"
msgstr "Drittes Kind"
-#: engines/scumm/help.cpp:294
+#: engines/scumm/help.cpp:292
+msgid "Toggle Inventory/IQ Points display"
+msgstr "Inventar-/IQ-Punkt-Anzeige umschalten"
+
+#: engines/scumm/help.cpp:293
+msgid "Toggle Keyboard/Mouse Fighting (*)"
+msgstr "Schalte zwischen Tastatur-/Maus-Kämpfen um (*)"
+
+#: engines/scumm/help.cpp:295
+msgid "* Keyboard Fighting is always on,"
+msgstr "* Tastatur-Steuerung der Kämpfe ist immer an,"
+
+#: engines/scumm/help.cpp:296
+msgid " so despite the in-game message this"
+msgstr " demnach wird trotz der Meldung im Spiel"
+
+#: engines/scumm/help.cpp:297
+msgid " actually toggles Mouse Fighting Off/On"
+msgstr " die Maus-Steuerung der Kämpfe ein-/ausgeschaltet"
+
+#: engines/scumm/help.cpp:304
msgid "Fighting controls (numpad):"
msgstr "Kampfsteuerung (Ziffernblock):"
-#: engines/scumm/help.cpp:295 engines/scumm/help.cpp:296
-#: engines/scumm/help.cpp:297
+#: engines/scumm/help.cpp:305 engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:307
msgid "Step back"
msgstr "Schritt zurück"
-#: engines/scumm/help.cpp:298
+#: engines/scumm/help.cpp:308
msgid "Block high"
msgstr "Deckung oben"
-#: engines/scumm/help.cpp:299
+#: engines/scumm/help.cpp:309
msgid "Block middle"
msgstr "Deckung Mitte"
-#: engines/scumm/help.cpp:300
+#: engines/scumm/help.cpp:310
msgid "Block low"
msgstr "Deckung unten"
-#: engines/scumm/help.cpp:301
+#: engines/scumm/help.cpp:311
msgid "Punch high"
msgstr "Schlag oben"
-#: engines/scumm/help.cpp:302
+#: engines/scumm/help.cpp:312
msgid "Punch middle"
msgstr "Schlag Mitte"
-#: engines/scumm/help.cpp:303
+#: engines/scumm/help.cpp:313
msgid "Punch low"
msgstr "Schlag unten"
-#: engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:315
+msgid "Sucker punch"
+msgstr "Unerwarteter Schlag"
+
+#: engines/scumm/help.cpp:318
msgid "These are for Indy on left."
msgstr "Dies gilt für Indy links."
-#: engines/scumm/help.cpp:307
+#: engines/scumm/help.cpp:319
msgid "When Indy is on the right,"
msgstr "Wenn Indy rechts steht,"
-#: engines/scumm/help.cpp:308
+#: engines/scumm/help.cpp:320
msgid "7, 4, and 1 are switched with"
msgstr "werden 7, 4 und 1 je mit"
-#: engines/scumm/help.cpp:309
+#: engines/scumm/help.cpp:321
msgid "9, 6, and 3, respectively."
msgstr "9, 6 und 3 vertauscht."
-#: engines/scumm/help.cpp:316
+#: engines/scumm/help.cpp:328
msgid "Biplane controls (numpad):"
msgstr "Doppeldecker (Ziffernblock):"
-#: engines/scumm/help.cpp:317
+#: engines/scumm/help.cpp:329
msgid "Fly to upper left"
msgstr "Nach oben links fliegen"
-#: engines/scumm/help.cpp:318
+#: engines/scumm/help.cpp:330
msgid "Fly to left"
msgstr "Nach links fliegen"
-#: engines/scumm/help.cpp:319
+#: engines/scumm/help.cpp:331
msgid "Fly to lower left"
msgstr "Nach unten links fliegen"
-#: engines/scumm/help.cpp:320
+#: engines/scumm/help.cpp:332
msgid "Fly upwards"
msgstr "Nach oben fliegen"
-#: engines/scumm/help.cpp:321
+#: engines/scumm/help.cpp:333
msgid "Fly straight"
msgstr "Geradeaus fliegen"
-#: engines/scumm/help.cpp:322
+#: engines/scumm/help.cpp:334
msgid "Fly down"
msgstr "Nach unten fliegen"
-#: engines/scumm/help.cpp:323
+#: engines/scumm/help.cpp:335
msgid "Fly to upper right"
msgstr "Nach oben rechts fliegen"
-#: engines/scumm/help.cpp:324
+#: engines/scumm/help.cpp:336
msgid "Fly to right"
msgstr "Nach rechts fliegen"
-#: engines/scumm/help.cpp:325
+#: engines/scumm/help.cpp:337
msgid "Fly to lower right"
msgstr "Nach unten rechts fliegen"
-#: engines/scumm/scumm.cpp:1823
+#: engines/scumm/scumm.cpp:1832
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
@@ -3215,11 +3322,11 @@ msgstr ""
"Roland-Upgrade von LucasArts, aber %s\n"
"fehlt. Stattdessen wird AdLib verwendet."
-#: engines/scumm/scumm.cpp:2594
+#: engines/scumm/scumm.cpp:2644
msgid ""
-"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
-"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
-"directory inside the Tentacle game directory."
+"Usually, Maniac Mansion would start now. But for that to work, the game "
+"files for Maniac Mansion have to be in the 'Maniac' directory inside the "
+"Tentacle game directory, and the game has to be added to ScummVM."
msgstr ""
"Normalerweise würde jetzt Maniac Mansion starten. ScummVM kann das jedoch "
"noch nicht. Um dieses Spiel zu spielen, klicken Sie auf \"Spiel hinzufügen\" "
@@ -3231,12 +3338,16 @@ msgid ""
"Could not find the 'Loom' Macintosh executable to read the\n"
"instruments from. Music will be disabled."
msgstr ""
+"Macintosh-Programmdatei für Instrumente in \"Loom\" nicht\n"
+"gefunden. Musik wird abgeschaltet."
#: engines/scumm/players/player_v5m.cpp:107
msgid ""
"Could not find the 'Monkey Island' Macintosh executable to read the\n"
"instruments from. Music will be disabled."
msgstr ""
+"Macintosh-Programmdatei für Instrumente in \"Monkey Island\" nicht\n"
+"gefunden. Musik wird abgeschaltet."
#: engines/sky/compact.cpp:130
msgid ""
@@ -3286,7 +3397,7 @@ msgstr ""
#: engines/sword1/animation.cpp:568 engines/sword2/animation.cpp:470
#, c-format
msgid "Cutscene '%s' not found"
-msgstr "Zwischensequenz \"%s\" gefunden"
+msgstr "Zwischensequenz \"%s\" nicht gefunden"
#: engines/sword1/control.cpp:863
msgid ""
@@ -3346,24 +3457,66 @@ msgstr "Zeigt Objektbeschriftungen bei Mausberührung an."
msgid ""
"You're missing the 'teenagent.dat' file. Get it from the ScummVM website"
msgstr ""
-"Ihnen fehlt die Datei teenagent.dat. Laden Sie sich diese von der ScummVM-"
-"Website unter http://www.scummvm.org herunter."
+"Ihnen fehlt die Datei \"teenagent.dat\". Laden Sie sich diese von der "
+"ScummVM-Website unter http://www.scummvm.org herunter."
#: engines/teenagent/resources.cpp:116
msgid ""
"The teenagent.dat file is compressed and zlib hasn't been included in this "
"executable. Please decompress it"
msgstr ""
-"Die Datei teenagent.dat ist gepackt und zlib zum Entpacken wurde in dieser "
-"ausführbaren Datei nicht miteingebunden. Bitte entpacken Sie die Datei."
+"Die Datei \"teenagent.dat\" ist gepackt und zlib zum Entpacken wurde in "
+"dieser ausführbaren Datei nicht miteingebunden. Bitte entpacken Sie die "
+"Datei."
#: engines/wintermute/detection.cpp:58
msgid "Show FPS-counter"
-msgstr ""
+msgstr "Zähler für Bilder pro Sekunde anzeigen"
#: engines/wintermute/detection.cpp:59
msgid "Show the current number of frames per second in the upper left corner"
msgstr ""
+"Zeige die aktuelle Anzahl von Bildern pro Sekunde in der oberen linken Ecke"
+
+#: engines/zvision/detection.cpp:256
+msgid "Double FPS"
+msgstr "FPS verdoppeln"
+
+#: engines/zvision/detection.cpp:257
+msgid "Increase game FPS from 30 to 60"
+msgstr "Bilder pro Sekunde im Spiel von 30 auf 60 erhöhen"
+
+#: engines/zvision/detection.cpp:266
+msgid "Enable Venus"
+msgstr "Venus aktivieren"
+
+#: engines/zvision/detection.cpp:267
+msgid "Enable the Venus help system"
+msgstr "Aktiviere das Venus-Hilfesystem"
+
+#: engines/zvision/detection.cpp:276
+msgid "Disable animation while turning"
+msgstr "Animation während Drehen ausschalten"
+
+#: engines/zvision/detection.cpp:277
+msgid "Disable animation while turning in panoramic mode"
+msgstr "Animation während Drehen im Panorama-Modus ausschalten"
+
+#: engines/zvision/detection.cpp:286
+msgid "Use the hires MPEG movies"
+msgstr "Nutze hochauflösende MPEG-Filme"
+
+#: engines/zvision/detection.cpp:287
+msgid ""
+"Use the hires MPEG movies of the DVD version, instead of the lowres AVI ones"
+msgstr ""
+"Verwende hochauflösende MPEG-Filme der DVD-Version anstelle der AVI-Filme"
+
+#~ msgid "EGA undithering"
+#~ msgstr "Antifehlerdiffusion für EGA"
+
+#~ msgid "Enable undithering in EGA games"
+#~ msgstr "Aktiviert die Aufhebung der Fehlerdiffusion in EGA-Spielen."
#~ msgid "MPEG-2 cutscenes found but ScummVM has been built without MPEG-2"
#~ msgstr ""
@@ -3374,9 +3527,6 @@ msgstr ""
#~ msgid "Mass Add..."
#~ msgstr "Durchsuchen"
-#~ msgid "Mass Add..."
-#~ msgstr "Durchsuchen"
-
#~ msgid ""
#~ "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
#~ msgstr ""
diff --git a/po/es_ES.po b/po/es_ES.po
index 479747bb20..32f3aba74e 100644
--- a/po/es_ES.po
+++ b/po/es_ES.po
@@ -1,5 +1,5 @@
# Spanish translation for ScummVM.
-# Copyright (C) 2010-2014 ScummVM Team
+# Copyright (C) 2010-2015 The ScummVM Team
# This file is distributed under the same license as the ScummVM package.
# Tomás Maidagan, 2011.
#
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.4.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2014-10-04 00:58+0100\n"
+"POT-Creation-Date: 2015-06-30 20:57+0100\n"
"PO-Revision-Date: 2014-07-06 20:39+0100\n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -53,10 +53,11 @@ msgstr "Arriba"
#: gui/browser.cpp:75 gui/chooser.cpp:46 gui/KeysDialog.cpp:43
#: gui/launcher.cpp:351 gui/massadd.cpp:95 gui/options.cpp:1239
+#: gui/recorderdialog.cpp:70 gui/recorderdialog.cpp:156
#: gui/saveload-dialog.cpp:216 gui/saveload-dialog.cpp:276
-#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:922
+#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:931
#: gui/themebrowser.cpp:55 gui/fluidsynth-dialog.cpp:152
-#: engines/engine.cpp:452 backends/platform/wii/options.cpp:48
+#: engines/engine.cpp:483 backends/platform/wii/options.cpp:48
#: backends/events/default/default-events.cpp:196
#: backends/events/default/default-events.cpp:218
#: engines/drascula/saveload.cpp:49 engines/parallaction/saveload.cpp:274
@@ -69,9 +70,9 @@ msgid "Choose"
msgstr "Aceptar"
#: gui/gui-manager.cpp:117 backends/keymapper/remap-dialog.cpp:53
-#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
-#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
-#: engines/scumm/help.cpp:209
+#: engines/scumm/help.cpp:126 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:192
+#: engines/scumm/help.cpp:210
msgid "Close"
msgstr "Cerrar"
@@ -87,7 +88,7 @@ msgstr "Mostrar el teclado"
msgid "Remap keys"
msgstr "Asignar teclas"
-#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:86
+#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:87
msgid "Toggle fullscreen"
msgstr "Activar/Desactivar pantalla completa"
@@ -101,13 +102,13 @@ msgstr "Asignar"
#: gui/KeysDialog.cpp:42 gui/launcher.cpp:352 gui/launcher.cpp:1048
#: gui/launcher.cpp:1052 gui/massadd.cpp:92 gui/options.cpp:1240
-#: gui/saveload-dialog.cpp:923 gui/fluidsynth-dialog.cpp:153
-#: engines/engine.cpp:371 engines/engine.cpp:382
+#: gui/saveload-dialog.cpp:932 gui/fluidsynth-dialog.cpp:153
+#: engines/engine.cpp:402 engines/engine.cpp:413
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
#: engines/agos/animation.cpp:558 engines/drascula/saveload.cpp:49
-#: engines/groovie/script.cpp:399 engines/parallaction/saveload.cpp:274
-#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1825
+#: engines/groovie/script.cpp:408 engines/parallaction/saveload.cpp:274
+#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1834
#: engines/scumm/players/player_v3m.cpp:130
#: engines/scumm/players/player_v5m.cpp:108 engines/sky/compact.cpp:131
#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:524
@@ -477,7 +478,7 @@ msgstr ""
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -487,7 +488,7 @@ msgstr "Sí"
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -524,6 +525,14 @@ msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr ""
"¡ScummVM no ha podido encontrar ningún motor capaz de ejecutar el juego!"
+#: gui/launcher.cpp:1159
+msgid "Mass Add..."
+msgstr "Añadir varios..."
+
+#: gui/launcher.cpp:1161
+msgid "Record..."
+msgstr ""
+
#: gui/massadd.cpp:79 gui/massadd.cpp:82
msgid "... progress ..."
msgstr "... progreso..."
@@ -622,7 +631,7 @@ msgid "Special dithering modes supported by some games"
msgstr "Modos especiales de expansión compatibles con algunos juegos"
#: gui/options.cpp:760
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2249
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2298
msgid "Fullscreen mode"
msgstr "Pantalla completa"
@@ -944,6 +953,43 @@ msgstr ""
"El tema seleccionado no es compatible con el idioma actual. Si quieres usar "
"este tema debes cambiar a otro idioma primero."
+#: gui/recorderdialog.cpp:64
+msgid "Recorder or Playback Gameplay"
+msgstr ""
+
+#: gui/recorderdialog.cpp:69 gui/recorderdialog.cpp:156
+#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
+msgid "Delete"
+msgstr "Borrar"
+
+#: gui/recorderdialog.cpp:71
+msgid "Record"
+msgstr ""
+
+#: gui/recorderdialog.cpp:72
+#, fuzzy
+msgid "Playback"
+msgstr "Jugar"
+
+#: gui/recorderdialog.cpp:74
+msgid "Edit"
+msgstr ""
+
+#: gui/recorderdialog.cpp:86 gui/recorderdialog.cpp:243
+#: gui/recorderdialog.cpp:253
+msgid "Author: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:87 gui/recorderdialog.cpp:244
+#: gui/recorderdialog.cpp:254
+msgid "Notes: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:155
+#, fuzzy
+msgid "Do you really want to delete this record?"
+msgstr "¿Seguro que quieres borrar esta partida?"
+
#: gui/saveload-dialog.cpp:167
msgid "List view"
msgstr "Modo lista"
@@ -964,23 +1010,19 @@ msgstr "No hay hora guardada"
msgid "No playtime saved"
msgstr "No hay tiempo guardado"
-#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
-msgid "Delete"
-msgstr "Borrar"
-
#: gui/saveload-dialog.cpp:275
msgid "Do you really want to delete this saved game?"
msgstr "¿Seguro que quieres borrar esta partida?"
-#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:875
+#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:884
msgid "Date: "
msgstr "Fecha: "
-#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:881
+#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:890
msgid "Time: "
msgstr "Hora: "
-#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:889
+#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:898
msgid "Playtime: "
msgstr "Tiempo: "
@@ -996,19 +1038,19 @@ msgstr "Siguiente"
msgid "Prev"
msgstr "Anterior"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "New Save"
msgstr "Guardar"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "Create a new save game"
msgstr "Guarda una nueva partida"
-#: gui/saveload-dialog.cpp:868
+#: gui/saveload-dialog.cpp:877
msgid "Name: "
msgstr "Nombre:"
-#: gui/saveload-dialog.cpp:940
+#: gui/saveload-dialog.cpp:949
#, c-format
msgid "Enter a description for slot %d:"
msgstr "Introduce una descripción para la ranura %d:"
@@ -1161,7 +1203,7 @@ msgstr "Saltar frase"
msgid "Error running game:"
msgstr "Error al ejecutar el juego:"
-#: base/main.cpp:536
+#: base/main.cpp:554
msgid "Could not find any engine capable of running the selected game"
msgstr "No se ha podido encontrar ningún motor capaz de ejecutar el juego"
@@ -1278,7 +1320,7 @@ msgstr "~V~olver al lanzador"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:803
#: engines/cruise/menu.cpp:212 engines/drascula/saveload.cpp:336
#: engines/dreamweb/saveload.cpp:261 engines/neverhood/menumodule.cpp:873
-#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:758
+#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:759
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save game:"
msgstr "Guardar partida"
@@ -1291,7 +1333,7 @@ msgstr "Guardar partida"
#: engines/agi/saveload.cpp:803 engines/cruise/menu.cpp:212
#: engines/drascula/saveload.cpp:336 engines/dreamweb/saveload.cpp:261
#: engines/neverhood/menumodule.cpp:873 engines/pegasus/pegasus.cpp:377
-#: engines/sci/engine/kfile.cpp:758 engines/scumm/dialogs.cpp:188
+#: engines/sci/engine/kfile.cpp:759 engines/scumm/dialogs.cpp:188
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save"
msgstr "Guardar"
@@ -1330,23 +1372,23 @@ msgstr "~C~ancelar"
msgid "~K~eys"
msgstr "~T~eclas"
-#: engines/engine.cpp:245
+#: engines/engine.cpp:276
msgid "Could not initialize color format."
msgstr "No se ha podido iniciar el formato de color."
-#: engines/engine.cpp:253
+#: engines/engine.cpp:284
msgid "Could not switch to video mode: '"
msgstr "No se ha podido cambiar al modo de video: '"
-#: engines/engine.cpp:262
+#: engines/engine.cpp:293
msgid "Could not apply aspect ratio setting."
msgstr "No se ha podido aplicar el ajuste de corrección de aspecto"
-#: engines/engine.cpp:267
+#: engines/engine.cpp:298
msgid "Could not apply fullscreen setting."
msgstr "No se ha podido aplicar el ajuste de pantalla completa."
-#: engines/engine.cpp:367
+#: engines/engine.cpp:398
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1360,7 +1402,7 @@ msgstr ""
"copiar los archivos del juego al disco duro.\n"
"Consulta el archivo README para más detalles."
-#: engines/engine.cpp:378
+#: engines/engine.cpp:409
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1374,7 +1416,7 @@ msgstr ""
"poder escuchar la música del juego.\n"
"Consulta el archivo README para más detalles."
-#: engines/engine.cpp:436
+#: engines/engine.cpp:467
#, c-format
msgid ""
"Gamestate load failed (%s)! Please consult the README for basic information, "
@@ -1384,7 +1426,7 @@ msgstr ""
"README para encontrar información básica e instrucciones sobre cómo obtener "
"más ayuda."
-#: engines/engine.cpp:449
+#: engines/engine.cpp:480
msgid ""
"WARNING: The game you are about to start is not yet fully supported by "
"ScummVM. As such, it is likely to be unstable, and any saves you make might "
@@ -1394,7 +1436,7 @@ msgstr ""
"ScummVM. Por lo tanto, puede que sea inestable, y que las partidas que "
"guardes no funcionen en versiones futuras de ScummVM."
-#: engines/engine.cpp:452
+#: engines/engine.cpp:483
msgid "Start anyway"
msgstr "Jugar aun así"
@@ -1604,11 +1646,11 @@ msgstr "Modo Touchpad activado."
msgid "Touchpad mode disabled."
msgstr "Modo Touchpad desactivado."
-#: backends/platform/maemo/maemo.cpp:209
+#: backends/platform/maemo/maemo.cpp:208
msgid "Click Mode"
msgstr "Modo clic"
-#: backends/platform/maemo/maemo.cpp:215
+#: backends/platform/maemo/maemo.cpp:214
#: backends/platform/symbian/src/SymbianActions.cpp:42
#: backends/platform/wince/CEActionsPocket.cpp:60
#: backends/platform/wince/CEActionsSmartphone.cpp:43
@@ -1616,11 +1658,11 @@ msgstr "Modo clic"
msgid "Left Click"
msgstr "Clic izquierdo"
-#: backends/platform/maemo/maemo.cpp:218
+#: backends/platform/maemo/maemo.cpp:217
msgid "Middle Click"
msgstr "Clic central"
-#: backends/platform/maemo/maemo.cpp:221
+#: backends/platform/maemo/maemo.cpp:220
#: backends/platform/symbian/src/SymbianActions.cpp:43
#: backends/platform/wince/CEActionsSmartphone.cpp:44
#: backends/platform/tizen/form.cpp:267
@@ -1657,19 +1699,19 @@ msgctxt "lowres"
msgid "Normal (no scaling)"
msgstr "Normal"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2148
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2197
msgid "Enabled aspect ratio correction"
msgstr "Activar la corrección de aspecto"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2154
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2203
msgid "Disabled aspect ratio correction"
msgstr "Desactivar la corrección de aspecto"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2209
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2258
msgid "Active graphics filter:"
msgstr "Filtro de gráficos activo:"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2251
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2300
msgid "Windowed mode"
msgstr "Modo ventana"
@@ -1728,8 +1770,8 @@ msgstr "Modo rápido"
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
#: backends/events/default/default-events.cpp:218
-#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:82
-#: engines/scumm/help.cpp:84
+#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:83
+#: engines/scumm/help.cpp:85
msgid "Quit"
msgstr "Salir"
@@ -1749,7 +1791,7 @@ msgstr "Teclado virtual"
msgid "Key mapper"
msgstr "Asignación de teclas"
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
msgid "Do you want to quit ?"
msgstr "¿Quieres salir?"
@@ -2085,34 +2127,56 @@ msgstr "Clic activado"
msgid "Clicking Disabled"
msgstr "Clic desactivado"
-#: engines/agi/detection.cpp:142 engines/drascula/detection.cpp:302
+#: engines/agi/detection.cpp:147 engines/drascula/detection.cpp:302
#: engines/dreamweb/detection.cpp:47 engines/neverhood/detection.cpp:160
#: engines/sci/detection.cpp:394 engines/toltecs/detection.cpp:200
-#: engines/zvision/detection.cpp:103
+#: engines/zvision/detection.cpp:246
msgid "Use original save/load screens"
msgstr "Usar pantallas de guardar/cargar originales"
-#: engines/agi/detection.cpp:143 engines/drascula/detection.cpp:303
+#: engines/agi/detection.cpp:148 engines/drascula/detection.cpp:303
#: engines/dreamweb/detection.cpp:48 engines/neverhood/detection.cpp:161
#: engines/sci/detection.cpp:395 engines/toltecs/detection.cpp:201
-#: engines/zvision/detection.cpp:104
+#: engines/zvision/detection.cpp:247
msgid "Use the original save/load screens, instead of the ScummVM ones"
msgstr ""
"Utilizar las pantallas de guardar/cargar originales, en vez de las de ScummVM"
+#: engines/agi/detection.cpp:157
+#, fuzzy
+msgid "Use an alternative palette"
+msgstr ""
+"Usa una introducción alternativa para el juego (solo para la versión CD)"
+
+#: engines/agi/detection.cpp:158
+msgid ""
+"Use an alternative palette, common for all Amiga games. This was the old "
+"behavior"
+msgstr ""
+
+#: engines/agi/detection.cpp:167
+#, fuzzy
+msgid "Mouse support"
+msgstr "Permitir omisiones"
+
+#: engines/agi/detection.cpp:168
+msgid ""
+"Enables mouse support. Allows to use mouse for movement and in game menus."
+msgstr ""
+
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore game:"
msgstr "Cargar partida:"
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore"
msgstr "Cargar"
-#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2368
+#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2377
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -2123,7 +2187,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2361
+#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2370
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -2134,7 +2198,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2379
+#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2388
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -2150,12 +2214,12 @@ msgstr ""
msgid "Cutscene file '%s' not found!"
msgstr "No se ha encontrado el vídeo '%s'"
-#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:81
+#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:101
#, fuzzy
msgid "Color Blind Mode"
msgstr "Modo clic"
-#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:82
+#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:102
msgid "Enable Color Blind Mode by default"
msgstr ""
@@ -2207,7 +2271,7 @@ msgstr "Velocidad rápida de vídeos"
msgid "Play movies at an increased speed"
msgstr "Reproducir vídeos a mayor velocidad"
-#: engines/groovie/script.cpp:399
+#: engines/groovie/script.cpp:408
msgid "Failed to save game"
msgstr "Fallo al guardar la partida"
@@ -2507,12 +2571,12 @@ msgstr ""
"Usa una introducción alternativa para el juego (solo para la versión CD)"
#: engines/sci/detection.cpp:374
-msgid "EGA undithering"
-msgstr "Difuminado EGA"
+msgid "Skip EGA dithering pass (full color backgrounds)"
+msgstr ""
#: engines/sci/detection.cpp:375
-msgid "Enable undithering in EGA games"
-msgstr "Activar difuminado en los juegos EGA"
+msgid "Skip dithering pass in EGA games, graphics are shown with full colors"
+msgstr ""
#: engines/sci/detection.cpp:384
msgid "Prefer digital sound effects"
@@ -2585,12 +2649,14 @@ msgstr "Juego pausado. Pulsa Espacio para continuar."
#. "Moechten Sie wirklich neu starten? (J/N)J"
#. Will react to J as 'Yes'
#: engines/scumm/dialogs.cpp:183
-msgid "Are you sure you want to restart? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to restart? (Y/N)Y"
msgstr "¿Seguro que quieres reiniciar? (S/N)S"
#. I18N: you may specify 'Yes' symbol at the end of the line. See previous comment
#: engines/scumm/dialogs.cpp:185
-msgid "Are you sure you want to quit? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to quit? (Y/N)Y"
msgstr "¿Seguro que quieres salir? (S/N)S"
#: engines/scumm/dialogs.cpp:190
@@ -2678,516 +2744,541 @@ msgstr "Práctica"
msgid "Expert"
msgstr "Experto"
-#: engines/scumm/help.cpp:73
+#: engines/scumm/help.cpp:74
msgid "Common keyboard commands:"
msgstr "Comandos básicos de teclado:"
-#: engines/scumm/help.cpp:74
+#: engines/scumm/help.cpp:75
msgid "Save / Load dialog"
msgstr "Pantalla de guardar / cargar"
-#: engines/scumm/help.cpp:76
+#: engines/scumm/help.cpp:77
msgid "Skip line of text"
msgstr "Saltar frase"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Esc"
msgstr "Esc"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Skip cutscene"
msgstr "Saltar escena"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Space"
msgstr "Espacio"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Pause game"
msgstr "Pausar el juego"
-#: engines/scumm/help.cpp:79 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:95 engines/scumm/help.cpp:96
-#: engines/scumm/help.cpp:97 engines/scumm/help.cpp:98
-#: engines/scumm/help.cpp:99 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:96 engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98 engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Ctrl"
msgstr "Ctrl"
-#: engines/scumm/help.cpp:79
+#: engines/scumm/help.cpp:80
msgid "Load game state 1-10"
msgstr "Cargar partida 1-10"
-#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:81 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Alt"
msgstr "Alt"
-#: engines/scumm/help.cpp:80
+#: engines/scumm/help.cpp:81
msgid "Save game state 1-10"
msgstr "Guardar partida 1-10"
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:90
msgid "Enter"
msgstr "Enter"
-#: engines/scumm/help.cpp:87
+#: engines/scumm/help.cpp:88
msgid "Music volume up / down"
msgstr "Subir / Bajar el volumen de la música"
-#: engines/scumm/help.cpp:88
+#: engines/scumm/help.cpp:89
msgid "Text speed slower / faster"
msgstr "Aumentar / Disminuir la vel. de texto"
-#: engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:90
msgid "Simulate left mouse button"
msgstr "Simular botón izquierdo del ratón"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Tab"
msgstr "Tab"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Simulate right mouse button"
msgstr "Simular botón derecho del ratón"
-#: engines/scumm/help.cpp:93
+#: engines/scumm/help.cpp:94
msgid "Special keyboard commands:"
msgstr "Comandos especiales de teclado:"
-#: engines/scumm/help.cpp:94
+#: engines/scumm/help.cpp:95
msgid "Show / Hide console"
msgstr "Mostrar / Ocultar consola"
-#: engines/scumm/help.cpp:95
+#: engines/scumm/help.cpp:96
msgid "Start the debugger"
msgstr "Iniciar debugger"
-#: engines/scumm/help.cpp:96
+#: engines/scumm/help.cpp:97
msgid "Show memory consumption"
msgstr "Mostrar consumo de memoria"
-#: engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98
msgid "Run in fast mode (*)"
msgstr "Ejecutar en modo rápido (*)"
-#: engines/scumm/help.cpp:98
+#: engines/scumm/help.cpp:99
msgid "Run in really fast mode (*)"
msgstr "Ejecutar en modo muy rápido (*)"
-#: engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100
msgid "Toggle mouse capture"
msgstr "Activar/Desactivar captura de ratón"
-#: engines/scumm/help.cpp:100
+#: engines/scumm/help.cpp:101
msgid "Switch between graphics filters"
msgstr "Alternar entre filtros gráficos"
-#: engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102
msgid "Increase / Decrease scale factor"
msgstr "Aumentar / Disminuir factor de escalado"
-#: engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:103
msgid "Toggle aspect-ratio correction"
msgstr "Activar/Desactivar corrección de aspecto"
-#: engines/scumm/help.cpp:107
+#: engines/scumm/help.cpp:108
msgid "* Note that using ctrl-f and"
msgstr "* No se recomienda utilizar"
-#: engines/scumm/help.cpp:108
+#: engines/scumm/help.cpp:109
msgid " ctrl-g are not recommended"
msgstr " ctrl-f y ctrl-g, ya que pueden"
-#: engines/scumm/help.cpp:109
+#: engines/scumm/help.cpp:110
msgid " since they may cause crashes"
msgstr " provocar cuelgues o un"
-#: engines/scumm/help.cpp:110
+#: engines/scumm/help.cpp:111
msgid " or incorrect game behavior."
msgstr " funcionamiento incorrecto del juego."
-#: engines/scumm/help.cpp:114
+#: engines/scumm/help.cpp:115
msgid "Spinning drafts on the keyboard:"
msgstr "Tejer hechizos con el teclado:"
-#: engines/scumm/help.cpp:116
+#: engines/scumm/help.cpp:117
msgid "Main game controls:"
msgstr "Controles básicos:"
-#: engines/scumm/help.cpp:121 engines/scumm/help.cpp:136
-#: engines/scumm/help.cpp:161
+#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
+#: engines/scumm/help.cpp:162
msgid "Push"
msgstr "Empujar"
-#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
-#: engines/scumm/help.cpp:162
+#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
+#: engines/scumm/help.cpp:163
msgid "Pull"
msgstr "Tirar"
-#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
-#: engines/scumm/help.cpp:163 engines/scumm/help.cpp:197
-#: engines/scumm/help.cpp:207
+#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
+#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:198
+#: engines/scumm/help.cpp:208
msgid "Give"
msgstr "Dar"
-#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
-#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:190
-#: engines/scumm/help.cpp:208
+#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
+#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
+#: engines/scumm/help.cpp:209
msgid "Open"
msgstr "Abrir"
-#: engines/scumm/help.cpp:126
+#: engines/scumm/help.cpp:127
msgid "Go to"
msgstr "Ir a"
-#: engines/scumm/help.cpp:127
+#: engines/scumm/help.cpp:128
msgid "Get"
msgstr "Coger"
-#: engines/scumm/help.cpp:128 engines/scumm/help.cpp:152
-#: engines/scumm/help.cpp:170 engines/scumm/help.cpp:198
-#: engines/scumm/help.cpp:213 engines/scumm/help.cpp:224
-#: engines/scumm/help.cpp:250
+#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:153
+#: engines/scumm/help.cpp:171 engines/scumm/help.cpp:199
+#: engines/scumm/help.cpp:214 engines/scumm/help.cpp:225
+#: engines/scumm/help.cpp:251
msgid "Use"
msgstr "Usar"
-#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:142
msgid "Read"
msgstr "Leer"
-#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:147
+#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:148
msgid "New kid"
msgstr "Cambiar personaje"
-#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:153
-#: engines/scumm/help.cpp:171
+#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
+#: engines/scumm/help.cpp:172
msgid "Turn on"
msgstr "Encender"
-#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
-#: engines/scumm/help.cpp:172
+#: engines/scumm/help.cpp:133 engines/scumm/help.cpp:155
+#: engines/scumm/help.cpp:173
msgid "Turn off"
msgstr "Apagar"
-#: engines/scumm/help.cpp:142 engines/scumm/help.cpp:167
-#: engines/scumm/help.cpp:194
+#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
+#: engines/scumm/help.cpp:195
msgid "Walk to"
msgstr "Ir a"
-#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
-#: engines/scumm/help.cpp:195 engines/scumm/help.cpp:210
-#: engines/scumm/help.cpp:227
+#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:228
msgid "Pick up"
msgstr "Recoger"
-#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:145 engines/scumm/help.cpp:170
msgid "What is"
msgstr "Qué es"
-#: engines/scumm/help.cpp:146
+#: engines/scumm/help.cpp:147
msgid "Unlock"
msgstr "Abrir con llave"
-#: engines/scumm/help.cpp:149
+#: engines/scumm/help.cpp:150
msgid "Put on"
msgstr "Ponerse"
-#: engines/scumm/help.cpp:150
+#: engines/scumm/help.cpp:151
msgid "Take off"
msgstr "Quitarse"
-#: engines/scumm/help.cpp:156
+#: engines/scumm/help.cpp:157
msgid "Fix"
msgstr "Arreglar"
-#: engines/scumm/help.cpp:158
+#: engines/scumm/help.cpp:159
msgid "Switch"
msgstr "Cambiar"
-#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:228
+#: engines/scumm/help.cpp:167 engines/scumm/help.cpp:229
msgid "Look"
msgstr "Mirar"
-#: engines/scumm/help.cpp:173 engines/scumm/help.cpp:223
+#: engines/scumm/help.cpp:174 engines/scumm/help.cpp:224
msgid "Talk"
msgstr "Hablar"
-#: engines/scumm/help.cpp:174
+#: engines/scumm/help.cpp:175
msgid "Travel"
msgstr "Viajar"
-#: engines/scumm/help.cpp:175
+#: engines/scumm/help.cpp:176
msgid "To Henry / To Indy"
msgstr "Henry / Indy"
#. I18N: These are different musical notes
-#: engines/scumm/help.cpp:179
+#: engines/scumm/help.cpp:180
msgid "play C minor on distaff"
msgstr "Tocar do menor con el bastón"
-#: engines/scumm/help.cpp:180
+#: engines/scumm/help.cpp:181
msgid "play D on distaff"
msgstr "Tocar re con el bastón"
-#: engines/scumm/help.cpp:181
+#: engines/scumm/help.cpp:182
msgid "play E on distaff"
msgstr "Tocar mi con el bastón"
-#: engines/scumm/help.cpp:182
+#: engines/scumm/help.cpp:183
msgid "play F on distaff"
msgstr "Tocar fa con el bastón"
-#: engines/scumm/help.cpp:183
+#: engines/scumm/help.cpp:184
msgid "play G on distaff"
msgstr "Tocar sol con el bastón"
-#: engines/scumm/help.cpp:184
+#: engines/scumm/help.cpp:185
msgid "play A on distaff"
msgstr "Tocar la con el bastón"
-#: engines/scumm/help.cpp:185
+#: engines/scumm/help.cpp:186
msgid "play B on distaff"
msgstr "Tocar si con el bastón"
-#: engines/scumm/help.cpp:186
+#: engines/scumm/help.cpp:187
msgid "play C major on distaff"
msgstr "Tocar do mayor con el bastón"
-#: engines/scumm/help.cpp:192 engines/scumm/help.cpp:214
+#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
msgid "puSh"
msgstr "Empujar"
-#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
+#: engines/scumm/help.cpp:194 engines/scumm/help.cpp:216
msgid "pull (Yank)"
msgstr "Tirar"
-#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:212
-#: engines/scumm/help.cpp:248
+#: engines/scumm/help.cpp:197 engines/scumm/help.cpp:213
+#: engines/scumm/help.cpp:249
msgid "Talk to"
msgstr "Hablar con"
-#: engines/scumm/help.cpp:199 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:200 engines/scumm/help.cpp:212
msgid "Look at"
msgstr "Mirar"
-#: engines/scumm/help.cpp:200
+#: engines/scumm/help.cpp:201
msgid "turn oN"
msgstr "Encender"
-#: engines/scumm/help.cpp:201
+#: engines/scumm/help.cpp:202
msgid "turn oFf"
msgstr "Apagar"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "KeyUp"
msgstr "Arriba"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "Highlight prev dialogue"
msgstr "Seleccionar diálogo anterior"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "KeyDown"
msgstr "Abajo"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "Highlight next dialogue"
msgstr "Seleccionar diálogo siguiente"
-#: engines/scumm/help.cpp:222
+#: engines/scumm/help.cpp:223
msgid "Walk"
msgstr "Caminar"
-#: engines/scumm/help.cpp:225 engines/scumm/help.cpp:234
-#: engines/scumm/help.cpp:241 engines/scumm/help.cpp:249
+#: engines/scumm/help.cpp:226 engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:242 engines/scumm/help.cpp:250
msgid "Inventory"
msgstr "Inventario"
-#: engines/scumm/help.cpp:226
+#: engines/scumm/help.cpp:227
msgid "Object"
msgstr "Objeto"
-#: engines/scumm/help.cpp:229
+#: engines/scumm/help.cpp:230
msgid "Black and White / Color"
msgstr "Blanco y negro / Color"
-#: engines/scumm/help.cpp:232
+#: engines/scumm/help.cpp:233
msgid "Eyes"
msgstr "Ojos"
-#: engines/scumm/help.cpp:233
+#: engines/scumm/help.cpp:234
msgid "Tongue"
msgstr "Lengua"
-#: engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:236
msgid "Punch"
msgstr "Puñetazo"
-#: engines/scumm/help.cpp:236
+#: engines/scumm/help.cpp:237
msgid "Kick"
msgstr "Patada"
-#: engines/scumm/help.cpp:239 engines/scumm/help.cpp:247
+#: engines/scumm/help.cpp:240 engines/scumm/help.cpp:248
msgid "Examine"
msgstr "Examinar"
-#: engines/scumm/help.cpp:240
+#: engines/scumm/help.cpp:241
msgid "Regular cursor"
msgstr "Cursor normal"
#. I18N: Comm is a communication device
-#: engines/scumm/help.cpp:243
+#: engines/scumm/help.cpp:244
msgid "Comm"
msgstr "Comm"
-#: engines/scumm/help.cpp:246
+#: engines/scumm/help.cpp:247
msgid "Save / Load / Options"
msgstr "Guardar / Cargar / Opciones"
-#: engines/scumm/help.cpp:255
+#: engines/scumm/help.cpp:256
msgid "Other game controls:"
msgstr "Otros controles:"
-#: engines/scumm/help.cpp:257 engines/scumm/help.cpp:267
+#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:268
msgid "Inventory:"
msgstr "Inventario:"
-#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:274
+#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
msgid "Scroll list up"
msgstr "Subir"
-#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
+#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:276
msgid "Scroll list down"
msgstr "Bajar"
-#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:268
+#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:269
msgid "Upper left item"
msgstr "Objeto superior izquierdo"
-#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:270
+#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
msgid "Lower left item"
msgstr "Objeto inferior izquierdo"
-#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
+#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:272
msgid "Upper right item"
msgstr "Objeto superior derecho"
-#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:273
+#: engines/scumm/help.cpp:264 engines/scumm/help.cpp:274
msgid "Lower right item"
msgstr "Objeto inferior derecho"
-#: engines/scumm/help.cpp:269
+#: engines/scumm/help.cpp:270
msgid "Middle left item"
msgstr "Objeto izquierdo del medio"
-#: engines/scumm/help.cpp:272
+#: engines/scumm/help.cpp:273
msgid "Middle right item"
msgstr "Objeto derecho del medio"
-#: engines/scumm/help.cpp:279 engines/scumm/help.cpp:284
+#: engines/scumm/help.cpp:280 engines/scumm/help.cpp:285
msgid "Switching characters:"
msgstr "Cambiar personaje:"
-#: engines/scumm/help.cpp:281
+#: engines/scumm/help.cpp:282
msgid "Second kid"
msgstr "Segundo chaval"
-#: engines/scumm/help.cpp:282
+#: engines/scumm/help.cpp:283
msgid "Third kid"
msgstr "Tercer chaval"
-#: engines/scumm/help.cpp:294
+#: engines/scumm/help.cpp:292
+#, fuzzy
+msgid "Toggle Inventory/IQ Points display"
+msgstr "Activar/Desactivar pantalla de datos"
+
+#: engines/scumm/help.cpp:293
+msgid "Toggle Keyboard/Mouse Fighting (*)"
+msgstr ""
+
+#: engines/scumm/help.cpp:295
+msgid "* Keyboard Fighting is always on,"
+msgstr ""
+
+#: engines/scumm/help.cpp:296
+msgid " so despite the in-game message this"
+msgstr ""
+
+#: engines/scumm/help.cpp:297
+msgid " actually toggles Mouse Fighting Off/On"
+msgstr ""
+
+#: engines/scumm/help.cpp:304
msgid "Fighting controls (numpad):"
msgstr "Controles de lucha (tecl. num.):"
-#: engines/scumm/help.cpp:295 engines/scumm/help.cpp:296
-#: engines/scumm/help.cpp:297
+#: engines/scumm/help.cpp:305 engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:307
msgid "Step back"
msgstr "Retroceder"
-#: engines/scumm/help.cpp:298
+#: engines/scumm/help.cpp:308
msgid "Block high"
msgstr "Bloqueo alto"
-#: engines/scumm/help.cpp:299
+#: engines/scumm/help.cpp:309
msgid "Block middle"
msgstr "Bloqueo medio"
-#: engines/scumm/help.cpp:300
+#: engines/scumm/help.cpp:310
msgid "Block low"
msgstr "Bloqueo bajo"
-#: engines/scumm/help.cpp:301
+#: engines/scumm/help.cpp:311
msgid "Punch high"
msgstr "Puñetazo alto"
-#: engines/scumm/help.cpp:302
+#: engines/scumm/help.cpp:312
msgid "Punch middle"
msgstr "Puñetazo medio"
-#: engines/scumm/help.cpp:303
+#: engines/scumm/help.cpp:313
msgid "Punch low"
msgstr "Puñetazo bajo"
-#: engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:315
+msgid "Sucker punch"
+msgstr ""
+
+#: engines/scumm/help.cpp:318
msgid "These are for Indy on left."
msgstr "Válidos cuando Indy está a la izquierda."
-#: engines/scumm/help.cpp:307
+#: engines/scumm/help.cpp:319
msgid "When Indy is on the right,"
msgstr "Cuando Indy está a la derecha,"
-#: engines/scumm/help.cpp:308
+#: engines/scumm/help.cpp:320
msgid "7, 4, and 1 are switched with"
msgstr "7, 4 y 1 se cambian por"
-#: engines/scumm/help.cpp:309
+#: engines/scumm/help.cpp:321
msgid "9, 6, and 3, respectively."
msgstr "9, 6 y 3, respectivamente."
-#: engines/scumm/help.cpp:316
+#: engines/scumm/help.cpp:328
msgid "Biplane controls (numpad):"
msgstr "Controles del biplano (tecl. num.)"
-#: engines/scumm/help.cpp:317
+#: engines/scumm/help.cpp:329
msgid "Fly to upper left"
msgstr "Volar arriba y a la izquierda"
-#: engines/scumm/help.cpp:318
+#: engines/scumm/help.cpp:330
msgid "Fly to left"
msgstr "Volar a la izquierda"
-#: engines/scumm/help.cpp:319
+#: engines/scumm/help.cpp:331
msgid "Fly to lower left"
msgstr "Volar abajo y a la izquierda"
-#: engines/scumm/help.cpp:320
+#: engines/scumm/help.cpp:332
msgid "Fly upwards"
msgstr "Volar arriba"
-#: engines/scumm/help.cpp:321
+#: engines/scumm/help.cpp:333
msgid "Fly straight"
msgstr "Volar recto"
-#: engines/scumm/help.cpp:322
+#: engines/scumm/help.cpp:334
msgid "Fly down"
msgstr "Volar abajo"
-#: engines/scumm/help.cpp:323
+#: engines/scumm/help.cpp:335
msgid "Fly to upper right"
msgstr "Volar arriba y a la derecha"
-#: engines/scumm/help.cpp:324
+#: engines/scumm/help.cpp:336
msgid "Fly to right"
msgstr "Volar a la derecha"
-#: engines/scumm/help.cpp:325
+#: engines/scumm/help.cpp:337
msgid "Fly to lower right"
msgstr "Volar abajo y a la derecha"
-#: engines/scumm/scumm.cpp:1823
+#: engines/scumm/scumm.cpp:1832
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
@@ -3196,11 +3287,12 @@ msgstr ""
"El soporte MIDI nativo requiere la actualización Roland de LucasArts,\n"
"pero %s no está disponible. Se usará AdLib."
-#: engines/scumm/scumm.cpp:2594
+#: engines/scumm/scumm.cpp:2644
+#, fuzzy
msgid ""
-"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
-"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
-"directory inside the Tentacle game directory."
+"Usually, Maniac Mansion would start now. But for that to work, the game "
+"files for Maniac Mansion have to be in the 'Maniac' directory inside the "
+"Tentacle game directory, and the game has to be added to ScummVM."
msgstr ""
"Maniac Mansion debería arrancar en este momento, pero ScummVM aún no lo "
"permite. Para jugar, ve a 'Añadir juego' en el menú de inicio de ScummVM y "
@@ -3343,6 +3435,48 @@ msgstr ""
msgid "Show the current number of frames per second in the upper left corner"
msgstr ""
+#: engines/zvision/detection.cpp:256
+msgid "Double FPS"
+msgstr ""
+
+#: engines/zvision/detection.cpp:257
+msgid "Increase game FPS from 30 to 60"
+msgstr ""
+
+#: engines/zvision/detection.cpp:266
+#, fuzzy
+msgid "Enable Venus"
+msgstr "Activar el modo helio"
+
+#: engines/zvision/detection.cpp:267
+msgid "Enable the Venus help system"
+msgstr ""
+
+#: engines/zvision/detection.cpp:276
+msgid "Disable animation while turning"
+msgstr ""
+
+#: engines/zvision/detection.cpp:277
+msgid "Disable animation while turning in panoramic mode"
+msgstr ""
+
+#: engines/zvision/detection.cpp:286
+msgid "Use the hires MPEG movies"
+msgstr ""
+
+#: engines/zvision/detection.cpp:287
+#, fuzzy
+msgid ""
+"Use the hires MPEG movies of the DVD version, instead of the lowres AVI ones"
+msgstr ""
+"Usar los cursores plateados alternativos, en vez de los dorados normales"
+
+#~ msgid "EGA undithering"
+#~ msgstr "Difuminado EGA"
+
+#~ msgid "Enable undithering in EGA games"
+#~ msgstr "Activar difuminado en los juegos EGA"
+
#~ msgid "MPEG-2 cutscenes found but ScummVM has been built without MPEG-2"
#~ msgstr ""
#~ "Se han encontrado vídeos MPEG-2, pero se ha compilado ScummVM sin MPEG-2"
@@ -3351,9 +3485,6 @@ msgstr ""
#~ msgid "Mass Add..."
#~ msgstr "Añad. varios"
-#~ msgid "Mass Add..."
-#~ msgstr "Añadir varios..."
-
#~ msgid ""
#~ "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
#~ msgstr ""
diff --git a/po/eu.po b/po/eu.po
index 7babff50b6..9381f0576c 100644
--- a/po/eu.po
+++ b/po/eu.po
@@ -1,5 +1,5 @@
# Basque translation for ScummVM.
-# Copyright (C) 2012-2014 ScummVM Team
+# Copyright (C) 2012-2015 The ScummVM Team
# This file is distributed under the same license as the ScummVM package.
# Mikel Iturbe Urretxa <mikel@hamahiru.org>, 2012.
#
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.5.0git\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2014-10-04 00:58+0100\n"
+"POT-Creation-Date: 2015-06-30 20:57+0100\n"
"PO-Revision-Date: 2011-12-15 14:53+0100\n"
"Last-Translator: Mikel Iturbe Urretxa <mikel@hamahiru.org>\n"
"Language-Team: Librezale <librezale@librezale.org>\n"
@@ -53,10 +53,11 @@ msgstr "Joan gora"
#: gui/browser.cpp:75 gui/chooser.cpp:46 gui/KeysDialog.cpp:43
#: gui/launcher.cpp:351 gui/massadd.cpp:95 gui/options.cpp:1239
+#: gui/recorderdialog.cpp:70 gui/recorderdialog.cpp:156
#: gui/saveload-dialog.cpp:216 gui/saveload-dialog.cpp:276
-#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:922
+#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:931
#: gui/themebrowser.cpp:55 gui/fluidsynth-dialog.cpp:152
-#: engines/engine.cpp:452 backends/platform/wii/options.cpp:48
+#: engines/engine.cpp:483 backends/platform/wii/options.cpp:48
#: backends/events/default/default-events.cpp:196
#: backends/events/default/default-events.cpp:218
#: engines/drascula/saveload.cpp:49 engines/parallaction/saveload.cpp:274
@@ -69,9 +70,9 @@ msgid "Choose"
msgstr "Aukeratu"
#: gui/gui-manager.cpp:117 backends/keymapper/remap-dialog.cpp:53
-#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
-#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
-#: engines/scumm/help.cpp:209
+#: engines/scumm/help.cpp:126 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:192
+#: engines/scumm/help.cpp:210
msgid "Close"
msgstr "Itxi"
@@ -87,7 +88,7 @@ msgstr "Teklatua erakutsi"
msgid "Remap keys"
msgstr "Teklak esleitu"
-#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:86
+#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:87
msgid "Toggle fullscreen"
msgstr "Txandakatu pantaila osoa"
@@ -101,13 +102,13 @@ msgstr "Esleitu"
#: gui/KeysDialog.cpp:42 gui/launcher.cpp:352 gui/launcher.cpp:1048
#: gui/launcher.cpp:1052 gui/massadd.cpp:92 gui/options.cpp:1240
-#: gui/saveload-dialog.cpp:923 gui/fluidsynth-dialog.cpp:153
-#: engines/engine.cpp:371 engines/engine.cpp:382
+#: gui/saveload-dialog.cpp:932 gui/fluidsynth-dialog.cpp:153
+#: engines/engine.cpp:402 engines/engine.cpp:413
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
#: engines/agos/animation.cpp:558 engines/drascula/saveload.cpp:49
-#: engines/groovie/script.cpp:399 engines/parallaction/saveload.cpp:274
-#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1825
+#: engines/groovie/script.cpp:408 engines/parallaction/saveload.cpp:274
+#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1834
#: engines/scumm/players/player_v3m.cpp:130
#: engines/scumm/players/player_v5m.cpp:108 engines/sky/compact.cpp:131
#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:524
@@ -477,7 +478,7 @@ msgstr ""
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -487,7 +488,7 @@ msgstr "Bai"
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -526,6 +527,14 @@ msgstr ""
"ScummVM-k ezin izan du aukeraturiko jokoa exekutatzeko gai den motorerik "
"aurkitu!"
+#: gui/launcher.cpp:1159
+msgid "Mass Add..."
+msgstr "Hainbat gehitu..."
+
+#: gui/launcher.cpp:1161
+msgid "Record..."
+msgstr ""
+
#: gui/massadd.cpp:79 gui/massadd.cpp:82
msgid "... progress ..."
msgstr "... aurrerapena ..."
@@ -626,7 +635,7 @@ msgid "Special dithering modes supported by some games"
msgstr "Joko batzuk onarturiko lausotze-modu bereziak"
#: gui/options.cpp:760
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2249
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2298
msgid "Fullscreen mode"
msgstr "Pantaila osoa"
@@ -944,6 +953,43 @@ msgstr ""
"Aukeraturiko gaia ez da zure hizkuntzarekin bateragarria. Gai hau erabili "
"nahi baduzu, aurretik beste hizkuntza batera pasa behar duzu."
+#: gui/recorderdialog.cpp:64
+msgid "Recorder or Playback Gameplay"
+msgstr ""
+
+#: gui/recorderdialog.cpp:69 gui/recorderdialog.cpp:156
+#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
+msgid "Delete"
+msgstr "Ezabatu"
+
+#: gui/recorderdialog.cpp:71
+msgid "Record"
+msgstr ""
+
+#: gui/recorderdialog.cpp:72
+#, fuzzy
+msgid "Playback"
+msgstr "Jolastu"
+
+#: gui/recorderdialog.cpp:74
+msgid "Edit"
+msgstr ""
+
+#: gui/recorderdialog.cpp:86 gui/recorderdialog.cpp:243
+#: gui/recorderdialog.cpp:253
+msgid "Author: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:87 gui/recorderdialog.cpp:244
+#: gui/recorderdialog.cpp:254
+msgid "Notes: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:155
+#, fuzzy
+msgid "Do you really want to delete this record?"
+msgstr "Ezabatu partida gorde hau?"
+
#: gui/saveload-dialog.cpp:167
msgid "List view"
msgstr ""
@@ -964,23 +1010,19 @@ msgstr "Ez dago ordurik gordeta"
msgid "No playtime saved"
msgstr "Ez dago denborarik gordeta"
-#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
-msgid "Delete"
-msgstr "Ezabatu"
-
#: gui/saveload-dialog.cpp:275
msgid "Do you really want to delete this saved game?"
msgstr "Ezabatu partida gorde hau?"
-#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:875
+#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:884
msgid "Date: "
msgstr "Data:"
-#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:881
+#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:890
msgid "Time: "
msgstr "Ordua"
-#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:889
+#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:898
msgid "Playtime: "
msgstr "Denbora:"
@@ -996,22 +1038,22 @@ msgstr ""
msgid "Prev"
msgstr ""
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
#, fuzzy
msgid "New Save"
msgstr "Gorde"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
#, fuzzy
msgid "Create a new save game"
msgstr "Ezin izan da jokoa gorde"
-#: gui/saveload-dialog.cpp:868
+#: gui/saveload-dialog.cpp:877
#, fuzzy
msgid "Name: "
msgstr "Izena:"
-#: gui/saveload-dialog.cpp:940
+#: gui/saveload-dialog.cpp:949
#, c-format
msgid "Enter a description for slot %d:"
msgstr ""
@@ -1169,7 +1211,7 @@ msgstr "Lerroa saltatu"
msgid "Error running game:"
msgstr "Jokoa exekutatzean errorea:"
-#: base/main.cpp:536
+#: base/main.cpp:554
msgid "Could not find any engine capable of running the selected game"
msgstr "Ezin izan da aukeraturiko jokoa exekutatzeko gai den motorerik aurkitu"
@@ -1286,7 +1328,7 @@ msgstr "It~z~uli abiarazlera"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:803
#: engines/cruise/menu.cpp:212 engines/drascula/saveload.cpp:336
#: engines/dreamweb/saveload.cpp:261 engines/neverhood/menumodule.cpp:873
-#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:758
+#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:759
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save game:"
msgstr "Gorde jokoa:"
@@ -1299,7 +1341,7 @@ msgstr "Gorde jokoa:"
#: engines/agi/saveload.cpp:803 engines/cruise/menu.cpp:212
#: engines/drascula/saveload.cpp:336 engines/dreamweb/saveload.cpp:261
#: engines/neverhood/menumodule.cpp:873 engines/pegasus/pegasus.cpp:377
-#: engines/sci/engine/kfile.cpp:758 engines/scumm/dialogs.cpp:188
+#: engines/sci/engine/kfile.cpp:759 engines/scumm/dialogs.cpp:188
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save"
msgstr "Gorde"
@@ -1336,23 +1378,23 @@ msgstr "~U~tzi"
msgid "~K~eys"
msgstr "~T~eklak"
-#: engines/engine.cpp:245
+#: engines/engine.cpp:276
msgid "Could not initialize color format."
msgstr "Kolore formatua ezin izan da hasieratu."
-#: engines/engine.cpp:253
+#: engines/engine.cpp:284
msgid "Could not switch to video mode: '"
msgstr "Ezin izan da aldatu bideo modura : '"
-#: engines/engine.cpp:262
+#: engines/engine.cpp:293
msgid "Could not apply aspect ratio setting."
msgstr "Ezin izan da formatu-ratio ezarpena aplikatu."
-#: engines/engine.cpp:267
+#: engines/engine.cpp:298
msgid "Could not apply fullscreen setting."
msgstr "Ezin izan da pantaila-osoa ezarpena aplikatu."
-#: engines/engine.cpp:367
+#: engines/engine.cpp:398
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1366,7 +1408,7 @@ msgstr ""
"fitxategiak disko gogorrera kopiatzea.\n"
"Jo README fitxategira xehetasunetarako."
-#: engines/engine.cpp:378
+#: engines/engine.cpp:409
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1380,7 +1422,7 @@ msgstr ""
"izateko. Jo README fitxategira\n"
"xehetasunetarako."
-#: engines/engine.cpp:436
+#: engines/engine.cpp:467
#, c-format
msgid ""
"Gamestate load failed (%s)! Please consult the README for basic information, "
@@ -1389,7 +1431,7 @@ msgstr ""
"Jokoaren egoera kargatzeak huts egin du (%s)! Jo ezazu README-ra oinarrizko "
"informaziorako eta laguntza gehiago nola jaso jakiteko."
-#: engines/engine.cpp:449
+#: engines/engine.cpp:480
msgid ""
"WARNING: The game you are about to start is not yet fully supported by "
"ScummVM. As such, it is likely to be unstable, and any saves you make might "
@@ -1399,7 +1441,7 @@ msgstr ""
"Hori dela eta, ezegonkorra izan daiteke eta gerta daiteke gordeta izan "
"ditzakezun partidan ez ibiltzea ScummVM-ren etorkizuneko bertsioetan."
-#: engines/engine.cpp:452
+#: engines/engine.cpp:483
msgid "Start anyway"
msgstr "Jolastu berdin-berdin"
@@ -1609,11 +1651,11 @@ msgstr "Touchpad modua gaituta."
msgid "Touchpad mode disabled."
msgstr "Touchpad modua desgaituta."
-#: backends/platform/maemo/maemo.cpp:209
+#: backends/platform/maemo/maemo.cpp:208
msgid "Click Mode"
msgstr "Klikatzeko modua"
-#: backends/platform/maemo/maemo.cpp:215
+#: backends/platform/maemo/maemo.cpp:214
#: backends/platform/symbian/src/SymbianActions.cpp:42
#: backends/platform/wince/CEActionsPocket.cpp:60
#: backends/platform/wince/CEActionsSmartphone.cpp:43
@@ -1621,11 +1663,11 @@ msgstr "Klikatzeko modua"
msgid "Left Click"
msgstr "Ezker-klika"
-#: backends/platform/maemo/maemo.cpp:218
+#: backends/platform/maemo/maemo.cpp:217
msgid "Middle Click"
msgstr "Erdiko klika"
-#: backends/platform/maemo/maemo.cpp:221
+#: backends/platform/maemo/maemo.cpp:220
#: backends/platform/symbian/src/SymbianActions.cpp:43
#: backends/platform/wince/CEActionsSmartphone.cpp:44
#: backends/platform/tizen/form.cpp:267
@@ -1662,19 +1704,19 @@ msgctxt "lowres"
msgid "Normal (no scaling)"
msgstr "Normala"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2148
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2197
msgid "Enabled aspect ratio correction"
msgstr "Formatu-ratio zuzenketa gaituta"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2154
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2203
msgid "Disabled aspect ratio correction"
msgstr "Formatu-ratio zuzenketa desgaituta"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2209
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2258
msgid "Active graphics filter:"
msgstr "Filtro grafiko aktiboa:"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2251
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2300
msgid "Windowed mode"
msgstr "Leiho modua"
@@ -1734,8 +1776,8 @@ msgstr "Modu bizkorra"
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
#: backends/events/default/default-events.cpp:218
-#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:82
-#: engines/scumm/help.cpp:84
+#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:83
+#: engines/scumm/help.cpp:85
msgid "Quit"
msgstr "Irten"
@@ -1755,7 +1797,7 @@ msgstr "Teklatu birtuala"
msgid "Key mapper"
msgstr "Teklen esleipena"
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
msgid "Do you want to quit ?"
msgstr "Irten nahi al duzu?"
@@ -2092,33 +2134,52 @@ msgstr "Klikatzea gaituta"
msgid "Clicking Disabled"
msgstr "Klikatzea desgaituta"
-#: engines/agi/detection.cpp:142 engines/drascula/detection.cpp:302
+#: engines/agi/detection.cpp:147 engines/drascula/detection.cpp:302
#: engines/dreamweb/detection.cpp:47 engines/neverhood/detection.cpp:160
#: engines/sci/detection.cpp:394 engines/toltecs/detection.cpp:200
-#: engines/zvision/detection.cpp:103
+#: engines/zvision/detection.cpp:246
msgid "Use original save/load screens"
msgstr ""
-#: engines/agi/detection.cpp:143 engines/drascula/detection.cpp:303
+#: engines/agi/detection.cpp:148 engines/drascula/detection.cpp:303
#: engines/dreamweb/detection.cpp:48 engines/neverhood/detection.cpp:161
#: engines/sci/detection.cpp:395 engines/toltecs/detection.cpp:201
-#: engines/zvision/detection.cpp:104
+#: engines/zvision/detection.cpp:247
msgid "Use the original save/load screens, instead of the ScummVM ones"
msgstr ""
+#: engines/agi/detection.cpp:157
+msgid "Use an alternative palette"
+msgstr ""
+
+#: engines/agi/detection.cpp:158
+msgid ""
+"Use an alternative palette, common for all Amiga games. This was the old "
+"behavior"
+msgstr ""
+
+#: engines/agi/detection.cpp:167
+msgid "Mouse support"
+msgstr ""
+
+#: engines/agi/detection.cpp:168
+msgid ""
+"Enables mouse support. Allows to use mouse for movement and in game menus."
+msgstr ""
+
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore game:"
msgstr "Jokoa kargatu:"
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore"
msgstr "Kargatu"
-#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2368
+#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2377
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -2129,7 +2190,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2361
+#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2370
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -2140,7 +2201,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2379
+#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2388
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -2156,12 +2217,12 @@ msgstr ""
msgid "Cutscene file '%s' not found!"
msgstr "'%s' bideo fitxategia ez da aurkitu!"
-#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:81
+#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:101
#, fuzzy
msgid "Color Blind Mode"
msgstr "Klikatzeko modua"
-#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:82
+#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:102
msgid "Enable Color Blind Mode by default"
msgstr ""
@@ -2216,7 +2277,7 @@ msgstr "Modu bizkorra"
msgid "Play movies at an increased speed"
msgstr ""
-#: engines/groovie/script.cpp:399
+#: engines/groovie/script.cpp:408
msgid "Failed to save game"
msgstr "Ezin izan da jokoa gorde"
@@ -2518,13 +2579,12 @@ msgid "Use an alternative game intro (CD version only)"
msgstr ""
#: engines/sci/detection.cpp:374
-msgid "EGA undithering"
-msgstr "EGA lausotzea"
+msgid "Skip EGA dithering pass (full color backgrounds)"
+msgstr ""
#: engines/sci/detection.cpp:375
-#, fuzzy
-msgid "Enable undithering in EGA games"
-msgstr "EGA lausotzea gaitu joko bateragarrietan"
+msgid "Skip dithering pass in EGA games, graphics are shown with full colors"
+msgstr ""
#: engines/sci/detection.cpp:384
#, fuzzy
@@ -2595,12 +2655,14 @@ msgstr "Joko pausatua. Sakatu ZURIUNEA jarraitzeko."
#. "Moechten Sie wirklich neu starten? (J/N)J"
#. Will react to J as 'Yes'
#: engines/scumm/dialogs.cpp:183
-msgid "Are you sure you want to restart? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to restart? (Y/N)Y"
msgstr "Ziur zaude berrabiarazi nahi duzula (B/E)B"
#. I18N: you may specify 'Yes' symbol at the end of the line. See previous comment
#: engines/scumm/dialogs.cpp:185
-msgid "Are you sure you want to quit? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to quit? (Y/N)Y"
msgstr "Ziur zaude irten nahi duzula? (B/E)B"
#: engines/scumm/dialogs.cpp:190
@@ -2688,516 +2750,540 @@ msgstr "Entrenamendua"
msgid "Expert"
msgstr "Aditua"
-#: engines/scumm/help.cpp:73
+#: engines/scumm/help.cpp:74
msgid "Common keyboard commands:"
msgstr "Teklatuko komando oinarrizkoak:"
-#: engines/scumm/help.cpp:74
+#: engines/scumm/help.cpp:75
msgid "Save / Load dialog"
msgstr "Gorde / Kargatu pantaila"
-#: engines/scumm/help.cpp:76
+#: engines/scumm/help.cpp:77
msgid "Skip line of text"
msgstr "Esaldia saltatu"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Esc"
msgstr "Ihes"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Skip cutscene"
msgstr "Eszena saltatu"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Space"
msgstr "Zuriunea"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Pause game"
msgstr "Jokoa pausatu"
-#: engines/scumm/help.cpp:79 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:95 engines/scumm/help.cpp:96
-#: engines/scumm/help.cpp:97 engines/scumm/help.cpp:98
-#: engines/scumm/help.cpp:99 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:96 engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98 engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Ctrl"
msgstr "Ktrl"
-#: engines/scumm/help.cpp:79
+#: engines/scumm/help.cpp:80
msgid "Load game state 1-10"
msgstr "1-10 jokoa kargatu"
-#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:81 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Alt"
msgstr "Alt"
-#: engines/scumm/help.cpp:80
+#: engines/scumm/help.cpp:81
msgid "Save game state 1-10"
msgstr "1-10 partida gorde"
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:90
msgid "Enter"
msgstr "Sartu"
-#: engines/scumm/help.cpp:87
+#: engines/scumm/help.cpp:88
msgid "Music volume up / down"
msgstr "Musikaren bolumena gora / behera"
-#: engines/scumm/help.cpp:88
+#: engines/scumm/help.cpp:89
msgid "Text speed slower / faster"
msgstr "Testu-abiadura astiroago / bizkorrago"
-#: engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:90
msgid "Simulate left mouse button"
msgstr "Saguaren ezker botoia simulatu"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Tab"
msgstr "Tab"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Simulate right mouse button"
msgstr "Saguaren eskuin botoia simulatu"
-#: engines/scumm/help.cpp:93
+#: engines/scumm/help.cpp:94
msgid "Special keyboard commands:"
msgstr "Teklatuko komando bereziak:"
-#: engines/scumm/help.cpp:94
+#: engines/scumm/help.cpp:95
msgid "Show / Hide console"
msgstr "Kontsola erakutsi / ezkutatu"
-#: engines/scumm/help.cpp:95
+#: engines/scumm/help.cpp:96
msgid "Start the debugger"
msgstr "Araztailea abiarazi"
-#: engines/scumm/help.cpp:96
+#: engines/scumm/help.cpp:97
msgid "Show memory consumption"
msgstr "Memoria kontsumoa erakutsi"
-#: engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98
msgid "Run in fast mode (*)"
msgstr "Modu azkarrean exekutatu (*)"
-#: engines/scumm/help.cpp:98
+#: engines/scumm/help.cpp:99
msgid "Run in really fast mode (*)"
msgstr "Era oso azkarrean exekutatu (*)"
-#: engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100
msgid "Toggle mouse capture"
msgstr "Saguaren kaptura"
-#: engines/scumm/help.cpp:100
+#: engines/scumm/help.cpp:101
msgid "Switch between graphics filters"
msgstr "Filtro grafikoen artean txandakatu"
-#: engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102
msgid "Increase / Decrease scale factor"
msgstr "Eskala faktorea handitu / txikitu"
-#: engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:103
msgid "Toggle aspect-ratio correction"
msgstr "Txandakatu fFormatu-ratioaren zuzenketa"
-#: engines/scumm/help.cpp:107
+#: engines/scumm/help.cpp:108
msgid "* Note that using ctrl-f and"
msgstr "* Ktrl-F eta Ktrl-G"
-#: engines/scumm/help.cpp:108
+#: engines/scumm/help.cpp:109
msgid " ctrl-g are not recommended"
msgstr "erabiltzea ez da gomendagarria"
-#: engines/scumm/help.cpp:109
+#: engines/scumm/help.cpp:110
msgid " since they may cause crashes"
msgstr "kraskadurak eta jokoaren jokabide"
-#: engines/scumm/help.cpp:110
+#: engines/scumm/help.cpp:111
msgid " or incorrect game behavior."
msgstr "desegokia sor dezaketelako."
-#: engines/scumm/help.cpp:114
+#: engines/scumm/help.cpp:115
msgid "Spinning drafts on the keyboard:"
msgstr "Sorginkeriak teklatuarekin egin:"
-#: engines/scumm/help.cpp:116
+#: engines/scumm/help.cpp:117
msgid "Main game controls:"
msgstr "Joko kontrol nagusiak:"
-#: engines/scumm/help.cpp:121 engines/scumm/help.cpp:136
-#: engines/scumm/help.cpp:161
+#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
+#: engines/scumm/help.cpp:162
msgid "Push"
msgstr "Bultzatu"
-#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
-#: engines/scumm/help.cpp:162
+#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
+#: engines/scumm/help.cpp:163
msgid "Pull"
msgstr "Tiratu"
-#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
-#: engines/scumm/help.cpp:163 engines/scumm/help.cpp:197
-#: engines/scumm/help.cpp:207
+#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
+#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:198
+#: engines/scumm/help.cpp:208
msgid "Give"
msgstr "Eman"
-#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
-#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:190
-#: engines/scumm/help.cpp:208
+#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
+#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
+#: engines/scumm/help.cpp:209
msgid "Open"
msgstr "Ireki"
-#: engines/scumm/help.cpp:126
+#: engines/scumm/help.cpp:127
msgid "Go to"
msgstr "Joan"
-#: engines/scumm/help.cpp:127
+#: engines/scumm/help.cpp:128
msgid "Get"
msgstr "Jaso"
-#: engines/scumm/help.cpp:128 engines/scumm/help.cpp:152
-#: engines/scumm/help.cpp:170 engines/scumm/help.cpp:198
-#: engines/scumm/help.cpp:213 engines/scumm/help.cpp:224
-#: engines/scumm/help.cpp:250
+#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:153
+#: engines/scumm/help.cpp:171 engines/scumm/help.cpp:199
+#: engines/scumm/help.cpp:214 engines/scumm/help.cpp:225
+#: engines/scumm/help.cpp:251
msgid "Use"
msgstr "Erabili"
-#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:142
msgid "Read"
msgstr "Irakurri"
-#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:147
+#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:148
msgid "New kid"
msgstr "Pertsonaia aldatu"
-#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:153
-#: engines/scumm/help.cpp:171
+#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
+#: engines/scumm/help.cpp:172
msgid "Turn on"
msgstr "Piztu"
-#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
-#: engines/scumm/help.cpp:172
+#: engines/scumm/help.cpp:133 engines/scumm/help.cpp:155
+#: engines/scumm/help.cpp:173
msgid "Turn off"
msgstr "Itzali"
-#: engines/scumm/help.cpp:142 engines/scumm/help.cpp:167
-#: engines/scumm/help.cpp:194
+#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
+#: engines/scumm/help.cpp:195
msgid "Walk to"
msgstr "Joan"
-#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
-#: engines/scumm/help.cpp:195 engines/scumm/help.cpp:210
-#: engines/scumm/help.cpp:227
+#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:228
msgid "Pick up"
msgstr "Jaso"
-#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:145 engines/scumm/help.cpp:170
msgid "What is"
msgstr "Zer da"
-#: engines/scumm/help.cpp:146
+#: engines/scumm/help.cpp:147
msgid "Unlock"
msgstr "Ireki"
-#: engines/scumm/help.cpp:149
+#: engines/scumm/help.cpp:150
msgid "Put on"
msgstr "Ipini"
-#: engines/scumm/help.cpp:150
+#: engines/scumm/help.cpp:151
msgid "Take off"
msgstr "Kendu"
-#: engines/scumm/help.cpp:156
+#: engines/scumm/help.cpp:157
msgid "Fix"
msgstr "Konpondu"
-#: engines/scumm/help.cpp:158
+#: engines/scumm/help.cpp:159
msgid "Switch"
msgstr "Aldatu"
-#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:228
+#: engines/scumm/help.cpp:167 engines/scumm/help.cpp:229
msgid "Look"
msgstr "Begiratu"
-#: engines/scumm/help.cpp:173 engines/scumm/help.cpp:223
+#: engines/scumm/help.cpp:174 engines/scumm/help.cpp:224
msgid "Talk"
msgstr "Hitz egin"
-#: engines/scumm/help.cpp:174
+#: engines/scumm/help.cpp:175
msgid "Travel"
msgstr "Bidaiatu"
-#: engines/scumm/help.cpp:175
+#: engines/scumm/help.cpp:176
msgid "To Henry / To Indy"
msgstr "Henry / Indy"
#. I18N: These are different musical notes
-#: engines/scumm/help.cpp:179
+#: engines/scumm/help.cpp:180
msgid "play C minor on distaff"
msgstr "Jo C minor bastoiarekin"
-#: engines/scumm/help.cpp:180
+#: engines/scumm/help.cpp:181
msgid "play D on distaff"
msgstr "Jo D bastoiarekin"
-#: engines/scumm/help.cpp:181
+#: engines/scumm/help.cpp:182
msgid "play E on distaff"
msgstr "Jo E bastoiarekin"
-#: engines/scumm/help.cpp:182
+#: engines/scumm/help.cpp:183
msgid "play F on distaff"
msgstr "Jo F bastoiarekin"
-#: engines/scumm/help.cpp:183
+#: engines/scumm/help.cpp:184
msgid "play G on distaff"
msgstr "Jo G bastoiarekin"
-#: engines/scumm/help.cpp:184
+#: engines/scumm/help.cpp:185
msgid "play A on distaff"
msgstr "Jo A bastoiarekin"
-#: engines/scumm/help.cpp:185
+#: engines/scumm/help.cpp:186
msgid "play B on distaff"
msgstr "Jo B bastoiarekin"
-#: engines/scumm/help.cpp:186
+#: engines/scumm/help.cpp:187
msgid "play C major on distaff"
msgstr "Jo C maior bastoiarekin"
-#: engines/scumm/help.cpp:192 engines/scumm/help.cpp:214
+#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
msgid "puSh"
msgstr "Bultzatu"
-#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
+#: engines/scumm/help.cpp:194 engines/scumm/help.cpp:216
msgid "pull (Yank)"
msgstr "Tiratu"
-#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:212
-#: engines/scumm/help.cpp:248
+#: engines/scumm/help.cpp:197 engines/scumm/help.cpp:213
+#: engines/scumm/help.cpp:249
msgid "Talk to"
msgstr "Hitz egin"
-#: engines/scumm/help.cpp:199 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:200 engines/scumm/help.cpp:212
msgid "Look at"
msgstr "Begiratu"
-#: engines/scumm/help.cpp:200
+#: engines/scumm/help.cpp:201
msgid "turn oN"
msgstr "Piztu"
-#: engines/scumm/help.cpp:201
+#: engines/scumm/help.cpp:202
msgid "turn oFf"
msgstr "Itzali"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "KeyUp"
msgstr "Gora"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "Highlight prev dialogue"
msgstr "Aurreko elkarrizketa aukeratu"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "KeyDown"
msgstr "Behera"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "Highlight next dialogue"
msgstr "Hurrengo elkarrizketa aukeratu"
-#: engines/scumm/help.cpp:222
+#: engines/scumm/help.cpp:223
msgid "Walk"
msgstr "Ibili"
-#: engines/scumm/help.cpp:225 engines/scumm/help.cpp:234
-#: engines/scumm/help.cpp:241 engines/scumm/help.cpp:249
+#: engines/scumm/help.cpp:226 engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:242 engines/scumm/help.cpp:250
msgid "Inventory"
msgstr "Inbentarioa"
-#: engines/scumm/help.cpp:226
+#: engines/scumm/help.cpp:227
msgid "Object"
msgstr "Objektua"
-#: engines/scumm/help.cpp:229
+#: engines/scumm/help.cpp:230
msgid "Black and White / Color"
msgstr "Zuri Beltza / Koloretan"
-#: engines/scumm/help.cpp:232
+#: engines/scumm/help.cpp:233
msgid "Eyes"
msgstr "Begiak"
-#: engines/scumm/help.cpp:233
+#: engines/scumm/help.cpp:234
msgid "Tongue"
msgstr "Mihia"
-#: engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:236
msgid "Punch"
msgstr "Ukabilkada"
-#: engines/scumm/help.cpp:236
+#: engines/scumm/help.cpp:237
msgid "Kick"
msgstr "Ostikada"
-#: engines/scumm/help.cpp:239 engines/scumm/help.cpp:247
+#: engines/scumm/help.cpp:240 engines/scumm/help.cpp:248
msgid "Examine"
msgstr "Aztertu"
-#: engines/scumm/help.cpp:240
+#: engines/scumm/help.cpp:241
msgid "Regular cursor"
msgstr "Kurtsore normala"
#. I18N: Comm is a communication device
-#: engines/scumm/help.cpp:243
+#: engines/scumm/help.cpp:244
msgid "Comm"
msgstr "Comm"
-#: engines/scumm/help.cpp:246
+#: engines/scumm/help.cpp:247
msgid "Save / Load / Options"
msgstr "Gorde / Kargatu / Aukerak"
-#: engines/scumm/help.cpp:255
+#: engines/scumm/help.cpp:256
msgid "Other game controls:"
msgstr "Beste kontrol batzuk:"
-#: engines/scumm/help.cpp:257 engines/scumm/help.cpp:267
+#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:268
msgid "Inventory:"
msgstr "Inbentarioa:"
-#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:274
+#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
msgid "Scroll list up"
msgstr "Gora"
-#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
+#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:276
msgid "Scroll list down"
msgstr "Behera"
-#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:268
+#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:269
msgid "Upper left item"
msgstr "Goiko ezkerreko objektua"
-#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:270
+#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
msgid "Lower left item"
msgstr "Beheko ezkerreko objektua"
-#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
+#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:272
msgid "Upper right item"
msgstr "Goiko eskuineko objektua"
-#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:273
+#: engines/scumm/help.cpp:264 engines/scumm/help.cpp:274
msgid "Lower right item"
msgstr "Beheko eskuineko objektua"
-#: engines/scumm/help.cpp:269
+#: engines/scumm/help.cpp:270
msgid "Middle left item"
msgstr "Erdiko ezkereko objektua"
-#: engines/scumm/help.cpp:272
+#: engines/scumm/help.cpp:273
msgid "Middle right item"
msgstr "Erdiko eskuineko objektua"
-#: engines/scumm/help.cpp:279 engines/scumm/help.cpp:284
+#: engines/scumm/help.cpp:280 engines/scumm/help.cpp:285
msgid "Switching characters:"
msgstr "Pertsonaia aldatu:"
-#: engines/scumm/help.cpp:281
+#: engines/scumm/help.cpp:282
msgid "Second kid"
msgstr "Bigarren gaztea"
-#: engines/scumm/help.cpp:282
+#: engines/scumm/help.cpp:283
msgid "Third kid"
msgstr "Hirugarren gaztea"
-#: engines/scumm/help.cpp:294
+#: engines/scumm/help.cpp:292
+msgid "Toggle Inventory/IQ Points display"
+msgstr ""
+
+#: engines/scumm/help.cpp:293
+msgid "Toggle Keyboard/Mouse Fighting (*)"
+msgstr ""
+
+#: engines/scumm/help.cpp:295
+msgid "* Keyboard Fighting is always on,"
+msgstr ""
+
+#: engines/scumm/help.cpp:296
+msgid " so despite the in-game message this"
+msgstr ""
+
+#: engines/scumm/help.cpp:297
+msgid " actually toggles Mouse Fighting Off/On"
+msgstr ""
+
+#: engines/scumm/help.cpp:304
msgid "Fighting controls (numpad):"
msgstr "Borroka-kontrolak (tekl. num.)"
-#: engines/scumm/help.cpp:295 engines/scumm/help.cpp:296
-#: engines/scumm/help.cpp:297
+#: engines/scumm/help.cpp:305 engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:307
msgid "Step back"
msgstr "Atzera egin"
-#: engines/scumm/help.cpp:298
+#: engines/scumm/help.cpp:308
msgid "Block high"
msgstr "Blokeo garaia"
-#: engines/scumm/help.cpp:299
+#: engines/scumm/help.cpp:309
msgid "Block middle"
msgstr "Erdiko blokeoa"
-#: engines/scumm/help.cpp:300
+#: engines/scumm/help.cpp:310
msgid "Block low"
msgstr "Blokeo baxua"
-#: engines/scumm/help.cpp:301
+#: engines/scumm/help.cpp:311
msgid "Punch high"
msgstr "Ukabilkada altua"
-#: engines/scumm/help.cpp:302
+#: engines/scumm/help.cpp:312
msgid "Punch middle"
msgstr "Ukabilkada erdira"
-#: engines/scumm/help.cpp:303
+#: engines/scumm/help.cpp:313
msgid "Punch low"
msgstr "Ukabilkada baxua"
-#: engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:315
+msgid "Sucker punch"
+msgstr ""
+
+#: engines/scumm/help.cpp:318
msgid "These are for Indy on left."
msgstr "Indy ezkerrean dagoenerako dira,"
-#: engines/scumm/help.cpp:307
+#: engines/scumm/help.cpp:319
msgid "When Indy is on the right,"
msgstr "Indy eskuinean dagoenean,"
-#: engines/scumm/help.cpp:308
+#: engines/scumm/help.cpp:320
msgid "7, 4, and 1 are switched with"
msgstr "7, 4 eta 1 aldatuak dira"
-#: engines/scumm/help.cpp:309
+#: engines/scumm/help.cpp:321
msgid "9, 6, and 3, respectively."
msgstr "9, 6 eta 3rekin, hurrenez hurren."
-#: engines/scumm/help.cpp:316
+#: engines/scumm/help.cpp:328
msgid "Biplane controls (numpad):"
msgstr "Biplanoaren kontrolak (tekl. num.)"
-#: engines/scumm/help.cpp:317
+#: engines/scumm/help.cpp:329
msgid "Fly to upper left"
msgstr "Gora eta ezkerrera hegan egin"
-#: engines/scumm/help.cpp:318
+#: engines/scumm/help.cpp:330
msgid "Fly to left"
msgstr "Ezkerrera hegan egin"
-#: engines/scumm/help.cpp:319
+#: engines/scumm/help.cpp:331
msgid "Fly to lower left"
msgstr "Behera eta ezkerrera hegan egin"
-#: engines/scumm/help.cpp:320
+#: engines/scumm/help.cpp:332
msgid "Fly upwards"
msgstr "Gorantz hegan egin"
-#: engines/scumm/help.cpp:321
+#: engines/scumm/help.cpp:333
msgid "Fly straight"
msgstr "Zuzen hegan egin"
-#: engines/scumm/help.cpp:322
+#: engines/scumm/help.cpp:334
msgid "Fly down"
msgstr "Behera hegan egin"
-#: engines/scumm/help.cpp:323
+#: engines/scumm/help.cpp:335
msgid "Fly to upper right"
msgstr "Gora eta eskuinera hegan egin"
-#: engines/scumm/help.cpp:324
+#: engines/scumm/help.cpp:336
msgid "Fly to right"
msgstr "Eskuinera hegan egin"
-#: engines/scumm/help.cpp:325
+#: engines/scumm/help.cpp:337
msgid "Fly to lower right"
msgstr "Behera eta eskuinera hegan egin"
-#: engines/scumm/scumm.cpp:1823
+#: engines/scumm/scumm.cpp:1832
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
@@ -3206,11 +3292,12 @@ msgstr ""
"MIDI euskarri natiboak LucasArts-en Roland eguneraketa behar du,\n"
"baina %s ez dago eskuragarri. AdLib erabiliko da."
-#: engines/scumm/scumm.cpp:2594
+#: engines/scumm/scumm.cpp:2644
+#, fuzzy
msgid ""
-"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
-"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
-"directory inside the Tentacle game directory."
+"Usually, Maniac Mansion would start now. But for that to work, the game "
+"files for Maniac Mansion have to be in the 'Maniac' directory inside the "
+"Tentacle game directory, and the game has to be added to ScummVM."
msgstr ""
"Maniac Mansion orain hasi beharko litzateke, baina ScummVM-k ez du "
"baimentzen oraindik. Jolasteko , joan 'Jokoa gehitu' hasierako menura eta "
@@ -3347,6 +3434,47 @@ msgstr ""
msgid "Show the current number of frames per second in the upper left corner"
msgstr ""
+#: engines/zvision/detection.cpp:256
+msgid "Double FPS"
+msgstr ""
+
+#: engines/zvision/detection.cpp:257
+msgid "Increase game FPS from 30 to 60"
+msgstr ""
+
+#: engines/zvision/detection.cpp:266
+#, fuzzy
+msgid "Enable Venus"
+msgstr "Roland GS modua gaitu"
+
+#: engines/zvision/detection.cpp:267
+msgid "Enable the Venus help system"
+msgstr ""
+
+#: engines/zvision/detection.cpp:276
+msgid "Disable animation while turning"
+msgstr ""
+
+#: engines/zvision/detection.cpp:277
+msgid "Disable animation while turning in panoramic mode"
+msgstr ""
+
+#: engines/zvision/detection.cpp:286
+msgid "Use the hires MPEG movies"
+msgstr ""
+
+#: engines/zvision/detection.cpp:287
+msgid ""
+"Use the hires MPEG movies of the DVD version, instead of the lowres AVI ones"
+msgstr ""
+
+#~ msgid "EGA undithering"
+#~ msgstr "EGA lausotzea"
+
+#, fuzzy
+#~ msgid "Enable undithering in EGA games"
+#~ msgstr "EGA lausotzea gaitu joko bateragarrietan"
+
#, fuzzy
#~ msgid "MPEG-2 cutscenes found but ScummVM has been built without MPEG-2"
#~ msgstr ""
@@ -3357,9 +3485,6 @@ msgstr ""
#~ msgid "Mass Add..."
#~ msgstr "Hainbat gehitu..."
-#~ msgid "Mass Add..."
-#~ msgstr "Hainbat gehitu..."
-
#~ msgid ""
#~ "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
#~ msgstr ""
diff --git a/po/fi_FI.po b/po/fi_FI.po
index 1958be3139..04aea37268 100644
--- a/po/fi_FI.po
+++ b/po/fi_FI.po
@@ -1,5 +1,5 @@
# Finnish translation for ScummVM.
-# Copyright (c) 2012-2014 ScummVM Team
+# Copyright (c) 2012-2015 The ScummVM Team
# This file is distributed under the same license as the ScummVM package.
# Toni Saarela <saarela@gmail.com>, 2012.
#
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.6.0git\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2014-10-04 00:58+0100\n"
+"POT-Creation-Date: 2015-06-30 20:57+0100\n"
"PO-Revision-Date: 2012-12-01 19:37+0200\n"
"Last-Translator: Toni Saarela <saarela@gmail.com>\n"
"Language-Team: Finnish\n"
@@ -54,10 +54,11 @@ msgstr "Siirry ylös"
#: gui/browser.cpp:75 gui/chooser.cpp:46 gui/KeysDialog.cpp:43
#: gui/launcher.cpp:351 gui/massadd.cpp:95 gui/options.cpp:1239
+#: gui/recorderdialog.cpp:70 gui/recorderdialog.cpp:156
#: gui/saveload-dialog.cpp:216 gui/saveload-dialog.cpp:276
-#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:922
+#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:931
#: gui/themebrowser.cpp:55 gui/fluidsynth-dialog.cpp:152
-#: engines/engine.cpp:452 backends/platform/wii/options.cpp:48
+#: engines/engine.cpp:483 backends/platform/wii/options.cpp:48
#: backends/events/default/default-events.cpp:196
#: backends/events/default/default-events.cpp:218
#: engines/drascula/saveload.cpp:49 engines/parallaction/saveload.cpp:274
@@ -70,9 +71,9 @@ msgid "Choose"
msgstr "Valitse"
#: gui/gui-manager.cpp:117 backends/keymapper/remap-dialog.cpp:53
-#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
-#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
-#: engines/scumm/help.cpp:209
+#: engines/scumm/help.cpp:126 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:192
+#: engines/scumm/help.cpp:210
msgid "Close"
msgstr "Sulje"
@@ -88,7 +89,7 @@ msgstr "Näytä näppäimistö"
msgid "Remap keys"
msgstr "Määritä näppäimet uudelleen"
-#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:86
+#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:87
msgid "Toggle fullscreen"
msgstr "Kokoruututilan vaihto"
@@ -102,13 +103,13 @@ msgstr "Näppäinkartta"
#: gui/KeysDialog.cpp:42 gui/launcher.cpp:352 gui/launcher.cpp:1048
#: gui/launcher.cpp:1052 gui/massadd.cpp:92 gui/options.cpp:1240
-#: gui/saveload-dialog.cpp:923 gui/fluidsynth-dialog.cpp:153
-#: engines/engine.cpp:371 engines/engine.cpp:382
+#: gui/saveload-dialog.cpp:932 gui/fluidsynth-dialog.cpp:153
+#: engines/engine.cpp:402 engines/engine.cpp:413
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
#: engines/agos/animation.cpp:558 engines/drascula/saveload.cpp:49
-#: engines/groovie/script.cpp:399 engines/parallaction/saveload.cpp:274
-#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1825
+#: engines/groovie/script.cpp:408 engines/parallaction/saveload.cpp:274
+#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1834
#: engines/scumm/players/player_v3m.cpp:130
#: engines/scumm/players/player_v5m.cpp:108 engines/sky/compact.cpp:131
#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:524
@@ -478,7 +479,7 @@ msgstr ""
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -488,7 +489,7 @@ msgstr "Kyllä"
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -525,6 +526,14 @@ msgstr "Tämä peli ei tue pelitallennuksien lataamista pelin ulkopuolelta."
msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr "ScummVM ei löytänyt pelimoottoria joka tukee valittua peliä!"
+#: gui/launcher.cpp:1159
+msgid "Mass Add..."
+msgstr "Lisää monta..."
+
+#: gui/launcher.cpp:1161
+msgid "Record..."
+msgstr ""
+
#: gui/massadd.cpp:79 gui/massadd.cpp:82
msgid "... progress ..."
msgstr "... skannaa ..."
@@ -627,7 +636,7 @@ msgid "Special dithering modes supported by some games"
msgstr "Erityiset dithering asetukset joita jotkut pelit tukevat"
#: gui/options.cpp:760
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2249
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2298
msgid "Fullscreen mode"
msgstr "Kokoruututila"
@@ -945,6 +954,43 @@ msgstr ""
"Valitsemasi teema ei tue nykyistä valitsemaasi kieltä. Vaihda kieli ensin, "
"ja yritä sitten uudelleen."
+#: gui/recorderdialog.cpp:64
+msgid "Recorder or Playback Gameplay"
+msgstr ""
+
+#: gui/recorderdialog.cpp:69 gui/recorderdialog.cpp:156
+#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
+msgid "Delete"
+msgstr "Poista"
+
+#: gui/recorderdialog.cpp:71
+msgid "Record"
+msgstr ""
+
+#: gui/recorderdialog.cpp:72
+#, fuzzy
+msgid "Playback"
+msgstr "Pelaa"
+
+#: gui/recorderdialog.cpp:74
+msgid "Edit"
+msgstr ""
+
+#: gui/recorderdialog.cpp:86 gui/recorderdialog.cpp:243
+#: gui/recorderdialog.cpp:253
+msgid "Author: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:87 gui/recorderdialog.cpp:244
+#: gui/recorderdialog.cpp:254
+msgid "Notes: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:155
+#, fuzzy
+msgid "Do you really want to delete this record?"
+msgstr "Haluatko varmasti poistaa tämän pelitallennuksen?"
+
#: gui/saveload-dialog.cpp:167
msgid "List view"
msgstr "Listanäkymä"
@@ -965,23 +1011,19 @@ msgstr "Aikaa ei ole tallennettu"
msgid "No playtime saved"
msgstr "Peliaikaa ei ole tallennettu"
-#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
-msgid "Delete"
-msgstr "Poista"
-
#: gui/saveload-dialog.cpp:275
msgid "Do you really want to delete this saved game?"
msgstr "Haluatko varmasti poistaa tämän pelitallennuksen?"
-#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:875
+#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:884
msgid "Date: "
msgstr "Päiväys: "
-#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:881
+#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:890
msgid "Time: "
msgstr "Aika: "
-#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:889
+#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:898
msgid "Playtime: "
msgstr "Peliaika: "
@@ -997,19 +1039,19 @@ msgstr "Seuraava"
msgid "Prev"
msgstr "Edellinen"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "New Save"
msgstr "Uusi pelitallennus"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "Create a new save game"
msgstr "Luo uusi pelitallennus"
-#: gui/saveload-dialog.cpp:868
+#: gui/saveload-dialog.cpp:877
msgid "Name: "
msgstr "Nimi: "
-#: gui/saveload-dialog.cpp:940
+#: gui/saveload-dialog.cpp:949
#, c-format
msgid "Enter a description for slot %d:"
msgstr "Anna kuvaus tallennukselle numero %d:"
@@ -1167,7 +1209,7 @@ msgstr "Ohita rivi"
msgid "Error running game:"
msgstr "Virhe ajettaessa peliä:"
-#: base/main.cpp:536
+#: base/main.cpp:554
msgid "Could not find any engine capable of running the selected game"
msgstr "Pelimoottoria joka tukisi valittua peliä ei löytynyt"
@@ -1286,7 +1328,7 @@ msgstr "Palaa p~e~livalitsimeen"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:803
#: engines/cruise/menu.cpp:212 engines/drascula/saveload.cpp:336
#: engines/dreamweb/saveload.cpp:261 engines/neverhood/menumodule.cpp:873
-#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:758
+#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:759
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save game:"
msgstr "Tallenna peli:"
@@ -1299,7 +1341,7 @@ msgstr "Tallenna peli:"
#: engines/agi/saveload.cpp:803 engines/cruise/menu.cpp:212
#: engines/drascula/saveload.cpp:336 engines/dreamweb/saveload.cpp:261
#: engines/neverhood/menumodule.cpp:873 engines/pegasus/pegasus.cpp:377
-#: engines/sci/engine/kfile.cpp:758 engines/scumm/dialogs.cpp:188
+#: engines/sci/engine/kfile.cpp:759 engines/scumm/dialogs.cpp:188
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save"
msgstr "Tallenna"
@@ -1336,23 +1378,23 @@ msgstr "~P~eruuta"
msgid "~K~eys"
msgstr "~N~äppäimet"
-#: engines/engine.cpp:245
+#: engines/engine.cpp:276
msgid "Could not initialize color format."
msgstr "Väriformaattia ei voitu alustaa"
-#: engines/engine.cpp:253
+#: engines/engine.cpp:284
msgid "Could not switch to video mode: '"
msgstr "Videotilan vaihto ei onnistunut:'"
-#: engines/engine.cpp:262
+#: engines/engine.cpp:293
msgid "Could not apply aspect ratio setting."
msgstr "Kuvasuhdeasetusta ei voitu asettaa."
-#: engines/engine.cpp:267
+#: engines/engine.cpp:298
msgid "Could not apply fullscreen setting."
msgstr "Kokoruututila-asetusta ei voi asettaa."
-#: engines/engine.cpp:367
+#: engines/engine.cpp:398
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1365,7 +1407,7 @@ msgstr ""
"pelin tiedostot kovalevyllesi. Avaa LUEMINUT\n"
"tiedosto ohjeita varten."
-#: engines/engine.cpp:378
+#: engines/engine.cpp:409
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1378,7 +1420,7 @@ msgstr ""
"ohjelmistoa käyttäen, jotta musiikit\n"
"kuuluvat. Lue ohjeet LUEMINUT tiedostosta."
-#: engines/engine.cpp:436
+#: engines/engine.cpp:467
#, c-format
msgid ""
"Gamestate load failed (%s)! Please consult the README for basic information, "
@@ -1387,7 +1429,7 @@ msgstr ""
"Pelitilan lataus epäonnistui (%s)! Avaa LUEMINUT tiedosto saadaksesi "
"lisätietoa."
-#: engines/engine.cpp:449
+#: engines/engine.cpp:480
msgid ""
"WARNING: The game you are about to start is not yet fully supported by "
"ScummVM. As such, it is likely to be unstable, and any saves you make might "
@@ -1397,7 +1439,7 @@ msgstr ""
"epävakaa, eivätkä pelitallennukset välttämättä toimi tulevissa ScummVM:n "
"versioissa."
-#: engines/engine.cpp:452
+#: engines/engine.cpp:483
msgid "Start anyway"
msgstr "Pelaa silti"
@@ -1609,11 +1651,11 @@ msgstr "Touchad tila päällä"
msgid "Touchpad mode disabled."
msgstr "Touchpad tila pois päältä"
-#: backends/platform/maemo/maemo.cpp:209
+#: backends/platform/maemo/maemo.cpp:208
msgid "Click Mode"
msgstr "Klikkaus moodi"
-#: backends/platform/maemo/maemo.cpp:215
+#: backends/platform/maemo/maemo.cpp:214
#: backends/platform/symbian/src/SymbianActions.cpp:42
#: backends/platform/wince/CEActionsPocket.cpp:60
#: backends/platform/wince/CEActionsSmartphone.cpp:43
@@ -1621,11 +1663,11 @@ msgstr "Klikkaus moodi"
msgid "Left Click"
msgstr "Vasen klikkaus"
-#: backends/platform/maemo/maemo.cpp:218
+#: backends/platform/maemo/maemo.cpp:217
msgid "Middle Click"
msgstr "Keskiklikkaus"
-#: backends/platform/maemo/maemo.cpp:221
+#: backends/platform/maemo/maemo.cpp:220
#: backends/platform/symbian/src/SymbianActions.cpp:43
#: backends/platform/wince/CEActionsSmartphone.cpp:44
#: backends/platform/tizen/form.cpp:267
@@ -1662,19 +1704,19 @@ msgctxt "lowres"
msgid "Normal (no scaling)"
msgstr "Normaali (ei skaalausta)"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2148
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2197
msgid "Enabled aspect ratio correction"
msgstr "Kuvasuhteen korjaus päällä"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2154
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2203
msgid "Disabled aspect ratio correction"
msgstr "Kuvasuhteen korjaus pois päältä"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2209
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2258
msgid "Active graphics filter:"
msgstr "Valittu grafiikkafiltteri:"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2251
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2300
msgid "Windowed mode"
msgstr "Ikkunoitu tila"
@@ -1734,8 +1776,8 @@ msgstr "Nopea moodi"
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
#: backends/events/default/default-events.cpp:218
-#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:82
-#: engines/scumm/help.cpp:84
+#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:83
+#: engines/scumm/help.cpp:85
msgid "Quit"
msgstr "Lopeta"
@@ -1755,7 +1797,7 @@ msgstr "Virtuaalinen näppäimistö"
msgid "Key mapper"
msgstr "Näppäinmäärittelijä"
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
msgid "Do you want to quit ?"
msgstr "Haluatko lopettaa?"
@@ -2093,33 +2135,54 @@ msgstr "Klikkaus päällä"
msgid "Clicking Disabled"
msgstr "Klikkaus pois päältä"
-#: engines/agi/detection.cpp:142 engines/drascula/detection.cpp:302
+#: engines/agi/detection.cpp:147 engines/drascula/detection.cpp:302
#: engines/dreamweb/detection.cpp:47 engines/neverhood/detection.cpp:160
#: engines/sci/detection.cpp:394 engines/toltecs/detection.cpp:200
-#: engines/zvision/detection.cpp:103
+#: engines/zvision/detection.cpp:246
msgid "Use original save/load screens"
msgstr "Käytä alkuperäisiä tallenna/lataa valikkoja"
-#: engines/agi/detection.cpp:143 engines/drascula/detection.cpp:303
+#: engines/agi/detection.cpp:148 engines/drascula/detection.cpp:303
#: engines/dreamweb/detection.cpp:48 engines/neverhood/detection.cpp:161
#: engines/sci/detection.cpp:395 engines/toltecs/detection.cpp:201
-#: engines/zvision/detection.cpp:104
+#: engines/zvision/detection.cpp:247
msgid "Use the original save/load screens, instead of the ScummVM ones"
msgstr "Käytä alkuperäisiä tallenna/lataa valikkoja, ScummVM valikoiden sijaan"
+#: engines/agi/detection.cpp:157
+#, fuzzy
+msgid "Use an alternative palette"
+msgstr "Käytä vaihtoehtoista pelin introa (vain CD versiossa)"
+
+#: engines/agi/detection.cpp:158
+msgid ""
+"Use an alternative palette, common for all Amiga games. This was the old "
+"behavior"
+msgstr ""
+
+#: engines/agi/detection.cpp:167
+#, fuzzy
+msgid "Mouse support"
+msgstr "Ohita tuki"
+
+#: engines/agi/detection.cpp:168
+msgid ""
+"Enables mouse support. Allows to use mouse for movement and in game menus."
+msgstr ""
+
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore game:"
msgstr "Lataa pelitallenne:"
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore"
msgstr "Lataa tallenne"
-#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2368
+#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2377
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -2130,7 +2193,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2361
+#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2370
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -2141,7 +2204,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2379
+#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2388
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -2157,12 +2220,12 @@ msgstr ""
msgid "Cutscene file '%s' not found!"
msgstr "Videotiedostoa '%s' ei löytynyt!"
-#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:81
+#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:101
#, fuzzy
msgid "Color Blind Mode"
msgstr "Klikkaus moodi"
-#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:82
+#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:102
msgid "Enable Color Blind Mode by default"
msgstr ""
@@ -2214,7 +2277,7 @@ msgstr "Nopea moodi"
msgid "Play movies at an increased speed"
msgstr ""
-#: engines/groovie/script.cpp:399
+#: engines/groovie/script.cpp:408
msgid "Failed to save game"
msgstr "Pelin tallentaminen epäonnistui."
@@ -2509,12 +2572,12 @@ msgid "Use an alternative game intro (CD version only)"
msgstr "Käytä vaihtoehtoista pelin introa (vain CD versiossa)"
#: engines/sci/detection.cpp:374
-msgid "EGA undithering"
-msgstr "EGA unditteröinti"
+msgid "Skip EGA dithering pass (full color backgrounds)"
+msgstr ""
#: engines/sci/detection.cpp:375
-msgid "Enable undithering in EGA games"
-msgstr "Käytä unditteröintiä EGA peleissä"
+msgid "Skip dithering pass in EGA games, graphics are shown with full colors"
+msgstr ""
#: engines/sci/detection.cpp:384
msgid "Prefer digital sound effects"
@@ -2586,12 +2649,14 @@ msgstr "Pause. Paina välilyöntiä jatkaaksesi."
#. "Moechten Sie wirklich neu starten? (J/N)J"
#. Will react to J as 'Yes'
#: engines/scumm/dialogs.cpp:183
-msgid "Are you sure you want to restart? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to restart? (Y/N)Y"
msgstr "Haluatko varmasti aloittaa pelin alusta? (K/E)K"
#. I18N: you may specify 'Yes' symbol at the end of the line. See previous comment
#: engines/scumm/dialogs.cpp:185
-msgid "Are you sure you want to quit? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to quit? (Y/N)Y"
msgstr "Haluatko varmati lopettaa?"
#: engines/scumm/dialogs.cpp:190
@@ -2679,516 +2744,540 @@ msgstr "Harjoitus"
msgid "Expert"
msgstr "Ekspertti"
-#: engines/scumm/help.cpp:73
+#: engines/scumm/help.cpp:74
msgid "Common keyboard commands:"
msgstr "Yleisiä näppäimistökomentoja:"
-#: engines/scumm/help.cpp:74
+#: engines/scumm/help.cpp:75
msgid "Save / Load dialog"
msgstr "Tallenna / Lataa peli"
-#: engines/scumm/help.cpp:76
+#: engines/scumm/help.cpp:77
msgid "Skip line of text"
msgstr "Ohita rivi tekstiä"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Esc"
msgstr "Esc"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Skip cutscene"
msgstr "Ohita video"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Space"
msgstr "Välilyönti"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Pause game"
msgstr "Pause"
-#: engines/scumm/help.cpp:79 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:95 engines/scumm/help.cpp:96
-#: engines/scumm/help.cpp:97 engines/scumm/help.cpp:98
-#: engines/scumm/help.cpp:99 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:96 engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98 engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Ctrl"
msgstr "Ctrl"
-#: engines/scumm/help.cpp:79
+#: engines/scumm/help.cpp:80
msgid "Load game state 1-10"
msgstr "Lataa pelitila 1-10"
-#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:81 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Alt"
msgstr "Alt"
-#: engines/scumm/help.cpp:80
+#: engines/scumm/help.cpp:81
msgid "Save game state 1-10"
msgstr "Tallenna pelitila 1-10"
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:90
msgid "Enter"
msgstr "Enter"
-#: engines/scumm/help.cpp:87
+#: engines/scumm/help.cpp:88
msgid "Music volume up / down"
msgstr "Musiikin äänenvoimakkuus ylös / alas"
-#: engines/scumm/help.cpp:88
+#: engines/scumm/help.cpp:89
msgid "Text speed slower / faster"
msgstr "Hidasta/nopeuta tekstiä"
-#: engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:90
msgid "Simulate left mouse button"
msgstr "Simuloi hiiren vasenta näppäintä"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Tab"
msgstr "Sarkain"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Simulate right mouse button"
msgstr "Simuloi oikeaa hiiren nappia"
-#: engines/scumm/help.cpp:93
+#: engines/scumm/help.cpp:94
msgid "Special keyboard commands:"
msgstr "Erityiskomennot:"
-#: engines/scumm/help.cpp:94
+#: engines/scumm/help.cpp:95
msgid "Show / Hide console"
msgstr "Näytä / piilota konsoli"
-#: engines/scumm/help.cpp:95
+#: engines/scumm/help.cpp:96
msgid "Start the debugger"
msgstr "Käynnistä debuggeri"
-#: engines/scumm/help.cpp:96
+#: engines/scumm/help.cpp:97
msgid "Show memory consumption"
msgstr "Näytä muistinkulutus"
-#: engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98
msgid "Run in fast mode (*)"
msgstr "Aja nopeassa tilassa (*)"
-#: engines/scumm/help.cpp:98
+#: engines/scumm/help.cpp:99
msgid "Run in really fast mode (*)"
msgstr "Aja erittäin nopeassa tilassa (*)"
-#: engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100
msgid "Toggle mouse capture"
msgstr "Kytke hiiren kaappaus päälle tai pois"
-#: engines/scumm/help.cpp:100
+#: engines/scumm/help.cpp:101
msgid "Switch between graphics filters"
msgstr "Vaihda grafiikkafiltteriä"
-#: engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102
msgid "Increase / Decrease scale factor"
msgstr "Kasvata / vähennä skaalakerrointa"
-#: engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:103
msgid "Toggle aspect-ratio correction"
msgstr "Kytke kuvasuhdekorjaus päälle tai pois"
-#: engines/scumm/help.cpp:107
+#: engines/scumm/help.cpp:108
msgid "* Note that using ctrl-f and"
msgstr "* Huomaa että ctrl-f ja"
-#: engines/scumm/help.cpp:108
+#: engines/scumm/help.cpp:109
msgid " ctrl-g are not recommended"
msgstr " ctrl-g ovat epävakaita eikä"
-#: engines/scumm/help.cpp:109
+#: engines/scumm/help.cpp:110
msgid " since they may cause crashes"
msgstr " niiden käyttöä suositella"
-#: engines/scumm/help.cpp:110
+#: engines/scumm/help.cpp:111
msgid " or incorrect game behavior."
msgstr " mahdollisten virheiden vuoksi."
-#: engines/scumm/help.cpp:114
+#: engines/scumm/help.cpp:115
msgid "Spinning drafts on the keyboard:"
msgstr ""
-#: engines/scumm/help.cpp:116
+#: engines/scumm/help.cpp:117
msgid "Main game controls:"
msgstr "Pelin tärkeimmät kontrollit:"
-#: engines/scumm/help.cpp:121 engines/scumm/help.cpp:136
-#: engines/scumm/help.cpp:161
+#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
+#: engines/scumm/help.cpp:162
msgid "Push"
msgstr "Paina"
-#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
-#: engines/scumm/help.cpp:162
+#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
+#: engines/scumm/help.cpp:163
msgid "Pull"
msgstr "Vedä"
-#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
-#: engines/scumm/help.cpp:163 engines/scumm/help.cpp:197
-#: engines/scumm/help.cpp:207
+#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
+#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:198
+#: engines/scumm/help.cpp:208
msgid "Give"
msgstr "Anna"
-#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
-#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:190
-#: engines/scumm/help.cpp:208
+#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
+#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
+#: engines/scumm/help.cpp:209
msgid "Open"
msgstr "Avaa"
-#: engines/scumm/help.cpp:126
+#: engines/scumm/help.cpp:127
msgid "Go to"
msgstr "Mene"
-#: engines/scumm/help.cpp:127
+#: engines/scumm/help.cpp:128
msgid "Get"
msgstr "Ota"
-#: engines/scumm/help.cpp:128 engines/scumm/help.cpp:152
-#: engines/scumm/help.cpp:170 engines/scumm/help.cpp:198
-#: engines/scumm/help.cpp:213 engines/scumm/help.cpp:224
-#: engines/scumm/help.cpp:250
+#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:153
+#: engines/scumm/help.cpp:171 engines/scumm/help.cpp:199
+#: engines/scumm/help.cpp:214 engines/scumm/help.cpp:225
+#: engines/scumm/help.cpp:251
msgid "Use"
msgstr "Käytä"
-#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:142
msgid "Read"
msgstr "Lue"
-#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:147
+#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:148
msgid "New kid"
msgstr "Uusi lapsi"
-#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:153
-#: engines/scumm/help.cpp:171
+#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
+#: engines/scumm/help.cpp:172
msgid "Turn on"
msgstr "Käynnistä"
-#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
-#: engines/scumm/help.cpp:172
+#: engines/scumm/help.cpp:133 engines/scumm/help.cpp:155
+#: engines/scumm/help.cpp:173
msgid "Turn off"
msgstr "Sammuta"
-#: engines/scumm/help.cpp:142 engines/scumm/help.cpp:167
-#: engines/scumm/help.cpp:194
+#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
+#: engines/scumm/help.cpp:195
msgid "Walk to"
msgstr "Kävele"
-#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
-#: engines/scumm/help.cpp:195 engines/scumm/help.cpp:210
-#: engines/scumm/help.cpp:227
+#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:228
msgid "Pick up"
msgstr "Ota"
-#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:145 engines/scumm/help.cpp:170
msgid "What is"
msgstr "Mitä on"
-#: engines/scumm/help.cpp:146
+#: engines/scumm/help.cpp:147
msgid "Unlock"
msgstr "Avaa lukko"
-#: engines/scumm/help.cpp:149
+#: engines/scumm/help.cpp:150
msgid "Put on"
msgstr "Pue ylle"
-#: engines/scumm/help.cpp:150
+#: engines/scumm/help.cpp:151
msgid "Take off"
msgstr "Lähde matkaan"
-#: engines/scumm/help.cpp:156
+#: engines/scumm/help.cpp:157
msgid "Fix"
msgstr "Korjaa"
-#: engines/scumm/help.cpp:158
+#: engines/scumm/help.cpp:159
msgid "Switch"
msgstr "Vaihda"
-#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:228
+#: engines/scumm/help.cpp:167 engines/scumm/help.cpp:229
msgid "Look"
msgstr "Katso"
-#: engines/scumm/help.cpp:173 engines/scumm/help.cpp:223
+#: engines/scumm/help.cpp:174 engines/scumm/help.cpp:224
msgid "Talk"
msgstr "Puhu"
-#: engines/scumm/help.cpp:174
+#: engines/scumm/help.cpp:175
msgid "Travel"
msgstr "Matkusta"
-#: engines/scumm/help.cpp:175
+#: engines/scumm/help.cpp:176
msgid "To Henry / To Indy"
msgstr "Henry / Indy"
#. I18N: These are different musical notes
-#: engines/scumm/help.cpp:179
+#: engines/scumm/help.cpp:180
msgid "play C minor on distaff"
msgstr "soita C molli"
-#: engines/scumm/help.cpp:180
+#: engines/scumm/help.cpp:181
msgid "play D on distaff"
msgstr "soita D"
-#: engines/scumm/help.cpp:181
+#: engines/scumm/help.cpp:182
msgid "play E on distaff"
msgstr "soita E"
-#: engines/scumm/help.cpp:182
+#: engines/scumm/help.cpp:183
msgid "play F on distaff"
msgstr "soita F"
-#: engines/scumm/help.cpp:183
+#: engines/scumm/help.cpp:184
msgid "play G on distaff"
msgstr "soita G"
-#: engines/scumm/help.cpp:184
+#: engines/scumm/help.cpp:185
msgid "play A on distaff"
msgstr "soita A"
-#: engines/scumm/help.cpp:185
+#: engines/scumm/help.cpp:186
msgid "play B on distaff"
msgstr "soita B"
-#: engines/scumm/help.cpp:186
+#: engines/scumm/help.cpp:187
msgid "play C major on distaff"
msgstr "soita C duuri"
-#: engines/scumm/help.cpp:192 engines/scumm/help.cpp:214
+#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
msgid "puSh"
msgstr "Paina"
-#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
+#: engines/scumm/help.cpp:194 engines/scumm/help.cpp:216
msgid "pull (Yank)"
msgstr "Vedä"
-#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:212
-#: engines/scumm/help.cpp:248
+#: engines/scumm/help.cpp:197 engines/scumm/help.cpp:213
+#: engines/scumm/help.cpp:249
msgid "Talk to"
msgstr "Puhu"
-#: engines/scumm/help.cpp:199 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:200 engines/scumm/help.cpp:212
msgid "Look at"
msgstr "Katso"
-#: engines/scumm/help.cpp:200
+#: engines/scumm/help.cpp:201
msgid "turn oN"
msgstr "Kytke päälle"
-#: engines/scumm/help.cpp:201
+#: engines/scumm/help.cpp:202
msgid "turn oFf"
msgstr "Kytke pois päältä"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "KeyUp"
msgstr "KeyUp"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "Highlight prev dialogue"
msgstr "Korosta edellistä dialogia"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "KeyDown"
msgstr "KeyDown"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "Highlight next dialogue"
msgstr "Korosta seuraavaa dialogia"
-#: engines/scumm/help.cpp:222
+#: engines/scumm/help.cpp:223
msgid "Walk"
msgstr "Kävele"
-#: engines/scumm/help.cpp:225 engines/scumm/help.cpp:234
-#: engines/scumm/help.cpp:241 engines/scumm/help.cpp:249
+#: engines/scumm/help.cpp:226 engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:242 engines/scumm/help.cpp:250
msgid "Inventory"
msgstr "Tavarat"
-#: engines/scumm/help.cpp:226
+#: engines/scumm/help.cpp:227
msgid "Object"
msgstr "Esine"
-#: engines/scumm/help.cpp:229
+#: engines/scumm/help.cpp:230
msgid "Black and White / Color"
msgstr "Mustavalko / Väri"
-#: engines/scumm/help.cpp:232
+#: engines/scumm/help.cpp:233
msgid "Eyes"
msgstr "Silmät"
-#: engines/scumm/help.cpp:233
+#: engines/scumm/help.cpp:234
msgid "Tongue"
msgstr "Kieli"
-#: engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:236
msgid "Punch"
msgstr "Lyö"
-#: engines/scumm/help.cpp:236
+#: engines/scumm/help.cpp:237
msgid "Kick"
msgstr "Potkaise"
-#: engines/scumm/help.cpp:239 engines/scumm/help.cpp:247
+#: engines/scumm/help.cpp:240 engines/scumm/help.cpp:248
msgid "Examine"
msgstr "Tutki"
-#: engines/scumm/help.cpp:240
+#: engines/scumm/help.cpp:241
msgid "Regular cursor"
msgstr "Tavallinen kursori"
#. I18N: Comm is a communication device
-#: engines/scumm/help.cpp:243
+#: engines/scumm/help.cpp:244
msgid "Comm"
msgstr "Kommunikointilaite"
-#: engines/scumm/help.cpp:246
+#: engines/scumm/help.cpp:247
msgid "Save / Load / Options"
msgstr "Tallenna / Lataa / Asetukset"
-#: engines/scumm/help.cpp:255
+#: engines/scumm/help.cpp:256
msgid "Other game controls:"
msgstr "Muut pelin ohjaimet:"
-#: engines/scumm/help.cpp:257 engines/scumm/help.cpp:267
+#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:268
msgid "Inventory:"
msgstr "Tavarat:"
-#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:274
+#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
msgid "Scroll list up"
msgstr "Vieritä listaa ylös"
-#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
+#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:276
msgid "Scroll list down"
msgstr "Vieritä listaa alas"
-#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:268
+#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:269
msgid "Upper left item"
msgstr ""
-#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:270
+#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
msgid "Lower left item"
msgstr ""
-#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
+#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:272
msgid "Upper right item"
msgstr ""
-#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:273
+#: engines/scumm/help.cpp:264 engines/scumm/help.cpp:274
msgid "Lower right item"
msgstr ""
-#: engines/scumm/help.cpp:269
+#: engines/scumm/help.cpp:270
msgid "Middle left item"
msgstr ""
-#: engines/scumm/help.cpp:272
+#: engines/scumm/help.cpp:273
msgid "Middle right item"
msgstr ""
-#: engines/scumm/help.cpp:279 engines/scumm/help.cpp:284
+#: engines/scumm/help.cpp:280 engines/scumm/help.cpp:285
msgid "Switching characters:"
msgstr "Vaihda hahmoa:"
-#: engines/scumm/help.cpp:281
+#: engines/scumm/help.cpp:282
msgid "Second kid"
msgstr "Toinen lapsi"
-#: engines/scumm/help.cpp:282
+#: engines/scumm/help.cpp:283
msgid "Third kid"
msgstr "Kolmas lapsi"
-#: engines/scumm/help.cpp:294
+#: engines/scumm/help.cpp:292
+msgid "Toggle Inventory/IQ Points display"
+msgstr ""
+
+#: engines/scumm/help.cpp:293
+msgid "Toggle Keyboard/Mouse Fighting (*)"
+msgstr ""
+
+#: engines/scumm/help.cpp:295
+msgid "* Keyboard Fighting is always on,"
+msgstr ""
+
+#: engines/scumm/help.cpp:296
+msgid " so despite the in-game message this"
+msgstr ""
+
+#: engines/scumm/help.cpp:297
+msgid " actually toggles Mouse Fighting Off/On"
+msgstr ""
+
+#: engines/scumm/help.cpp:304
msgid "Fighting controls (numpad):"
msgstr "Tappeluohjaimet (numpad)"
-#: engines/scumm/help.cpp:295 engines/scumm/help.cpp:296
-#: engines/scumm/help.cpp:297
+#: engines/scumm/help.cpp:305 engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:307
msgid "Step back"
msgstr "Astu taakse"
-#: engines/scumm/help.cpp:298
+#: engines/scumm/help.cpp:308
msgid "Block high"
msgstr "Torju korkea"
-#: engines/scumm/help.cpp:299
+#: engines/scumm/help.cpp:309
msgid "Block middle"
msgstr "Torju keskeltä"
-#: engines/scumm/help.cpp:300
+#: engines/scumm/help.cpp:310
msgid "Block low"
msgstr "Torju alhaalta"
-#: engines/scumm/help.cpp:301
+#: engines/scumm/help.cpp:311
msgid "Punch high"
msgstr "Lyö ylös"
-#: engines/scumm/help.cpp:302
+#: engines/scumm/help.cpp:312
msgid "Punch middle"
msgstr "Lyö keskelle"
-#: engines/scumm/help.cpp:303
+#: engines/scumm/help.cpp:313
msgid "Punch low"
msgstr "Lyö alas"
-#: engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:315
+msgid "Sucker punch"
+msgstr ""
+
+#: engines/scumm/help.cpp:318
msgid "These are for Indy on left."
msgstr "Nämä ovat Indylle vasemmalla."
-#: engines/scumm/help.cpp:307
+#: engines/scumm/help.cpp:319
msgid "When Indy is on the right,"
msgstr "Kun Indy on oikealla, "
-#: engines/scumm/help.cpp:308
+#: engines/scumm/help.cpp:320
msgid "7, 4, and 1 are switched with"
msgstr "7, 4 ja 1 vaihdetaan näppäinten"
-#: engines/scumm/help.cpp:309
+#: engines/scumm/help.cpp:321
msgid "9, 6, and 3, respectively."
msgstr "9, 6 ja 3 kanssa."
-#: engines/scumm/help.cpp:316
+#: engines/scumm/help.cpp:328
msgid "Biplane controls (numpad):"
msgstr "Koneen ohjaimet (numpad):"
-#: engines/scumm/help.cpp:317
+#: engines/scumm/help.cpp:329
msgid "Fly to upper left"
msgstr "Lennä ylös vasemmalle"
-#: engines/scumm/help.cpp:318
+#: engines/scumm/help.cpp:330
msgid "Fly to left"
msgstr "Lennä vasemmalle"
-#: engines/scumm/help.cpp:319
+#: engines/scumm/help.cpp:331
msgid "Fly to lower left"
msgstr "Lennä alas vasemmalle"
-#: engines/scumm/help.cpp:320
+#: engines/scumm/help.cpp:332
msgid "Fly upwards"
msgstr "Lennä ylöspäin"
-#: engines/scumm/help.cpp:321
+#: engines/scumm/help.cpp:333
msgid "Fly straight"
msgstr "Lennä suoraan"
-#: engines/scumm/help.cpp:322
+#: engines/scumm/help.cpp:334
msgid "Fly down"
msgstr "Lennä alas"
-#: engines/scumm/help.cpp:323
+#: engines/scumm/help.cpp:335
msgid "Fly to upper right"
msgstr "Lennä ylös oikealle"
-#: engines/scumm/help.cpp:324
+#: engines/scumm/help.cpp:336
msgid "Fly to right"
msgstr "Lennä oikealle"
-#: engines/scumm/help.cpp:325
+#: engines/scumm/help.cpp:337
msgid "Fly to lower right"
msgstr "Lennä alas oikealle"
-#: engines/scumm/scumm.cpp:1823
+#: engines/scumm/scumm.cpp:1832
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
@@ -3197,11 +3286,12 @@ msgstr ""
"Suora MIDI tuki vaatii Roland päivityksen LucasArtsilta, mutta\n"
"%s puuttuu. Käytetään AdLibia sen sijaan."
-#: engines/scumm/scumm.cpp:2594
+#: engines/scumm/scumm.cpp:2644
+#, fuzzy
msgid ""
-"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
-"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
-"directory inside the Tentacle game directory."
+"Usually, Maniac Mansion would start now. But for that to work, the game "
+"files for Maniac Mansion have to be in the 'Maniac' directory inside the "
+"Tentacle game directory, and the game has to be added to ScummVM."
msgstr ""
"Maniac Mansionin pitäisi nyt käynnistyä, mutta ScummVM ei tue sitä vielä. "
"Pelataksesi Maniac Mansionia, mene ScummVM:n päävalikkoon ja paina 'Lisää "
@@ -3338,6 +3428,47 @@ msgstr ""
msgid "Show the current number of frames per second in the upper left corner"
msgstr ""
+#: engines/zvision/detection.cpp:256
+msgid "Double FPS"
+msgstr ""
+
+#: engines/zvision/detection.cpp:257
+msgid "Increase game FPS from 30 to 60"
+msgstr ""
+
+#: engines/zvision/detection.cpp:266
+#, fuzzy
+msgid "Enable Venus"
+msgstr "Käytä helium moodia"
+
+#: engines/zvision/detection.cpp:267
+msgid "Enable the Venus help system"
+msgstr ""
+
+#: engines/zvision/detection.cpp:276
+msgid "Disable animation while turning"
+msgstr ""
+
+#: engines/zvision/detection.cpp:277
+msgid "Disable animation while turning in panoramic mode"
+msgstr ""
+
+#: engines/zvision/detection.cpp:286
+msgid "Use the hires MPEG movies"
+msgstr ""
+
+#: engines/zvision/detection.cpp:287
+#, fuzzy
+msgid ""
+"Use the hires MPEG movies of the DVD version, instead of the lowres AVI ones"
+msgstr "Käytä vaihtoehtoisia hopeisia kursoreita normaalien kultaisten sijaan"
+
+#~ msgid "EGA undithering"
+#~ msgstr "EGA unditteröinti"
+
+#~ msgid "Enable undithering in EGA games"
+#~ msgstr "Käytä unditteröintiä EGA peleissä"
+
#, fuzzy
#~ msgid "MPEG-2 cutscenes found but ScummVM has been built without MPEG-2"
#~ msgstr "PSX videoita löydetty, mutta ScummVM on käännetty ilman RGB tukea"
@@ -3346,9 +3477,6 @@ msgstr ""
#~ msgid "Mass Add..."
#~ msgstr "Lisää monta..."
-#~ msgid "Mass Add..."
-#~ msgstr "Lisää monta..."
-
#~ msgid ""
#~ "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
#~ msgstr "Poistaa General MIDIn peleistä joissa on Roland MT-32 ääniraita"
diff --git a/po/fr_FR.po b/po/fr_FR.po
index 6e47183fe3..2627e1e54f 100644
--- a/po/fr_FR.po
+++ b/po/fr_FR.po
@@ -1,5 +1,5 @@
# French translation for ScummVM.
-# Copyright (C) 2010-2014 ScummVM Team
+# Copyright (C) 2010-2015 The ScummVM Team
# This file is distributed under the same license as the ScummVM package.
# Thierry Crozat <criezy@scummvm.org>, 2011.
#
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.3.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2014-10-04 00:58+0100\n"
+"POT-Creation-Date: 2015-06-30 20:57+0100\n"
"PO-Revision-Date: 2014-07-05 13:49-0000\n"
"Last-Translator: Thierry Crozat <criezy@scummvm.org>\n"
"Language-Team: French <scummvm-devel@lists.sf.net>\n"
@@ -54,10 +54,11 @@ msgstr "Remonter"
#: gui/browser.cpp:75 gui/chooser.cpp:46 gui/KeysDialog.cpp:43
#: gui/launcher.cpp:351 gui/massadd.cpp:95 gui/options.cpp:1239
+#: gui/recorderdialog.cpp:70 gui/recorderdialog.cpp:156
#: gui/saveload-dialog.cpp:216 gui/saveload-dialog.cpp:276
-#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:922
+#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:931
#: gui/themebrowser.cpp:55 gui/fluidsynth-dialog.cpp:152
-#: engines/engine.cpp:452 backends/platform/wii/options.cpp:48
+#: engines/engine.cpp:483 backends/platform/wii/options.cpp:48
#: backends/events/default/default-events.cpp:196
#: backends/events/default/default-events.cpp:218
#: engines/drascula/saveload.cpp:49 engines/parallaction/saveload.cpp:274
@@ -70,9 +71,9 @@ msgid "Choose"
msgstr "Choisir"
#: gui/gui-manager.cpp:117 backends/keymapper/remap-dialog.cpp:53
-#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
-#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
-#: engines/scumm/help.cpp:209
+#: engines/scumm/help.cpp:126 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:192
+#: engines/scumm/help.cpp:210
msgid "Close"
msgstr "Fermer"
@@ -88,7 +89,7 @@ msgstr "Afficher le clavier"
msgid "Remap keys"
msgstr "Changer l'affectation des touches"
-#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:86
+#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:87
msgid "Toggle fullscreen"
msgstr "Basculer en plein écran"
@@ -102,13 +103,13 @@ msgstr "Affecter"
#: gui/KeysDialog.cpp:42 gui/launcher.cpp:352 gui/launcher.cpp:1048
#: gui/launcher.cpp:1052 gui/massadd.cpp:92 gui/options.cpp:1240
-#: gui/saveload-dialog.cpp:923 gui/fluidsynth-dialog.cpp:153
-#: engines/engine.cpp:371 engines/engine.cpp:382
+#: gui/saveload-dialog.cpp:932 gui/fluidsynth-dialog.cpp:153
+#: engines/engine.cpp:402 engines/engine.cpp:413
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
#: engines/agos/animation.cpp:558 engines/drascula/saveload.cpp:49
-#: engines/groovie/script.cpp:399 engines/parallaction/saveload.cpp:274
-#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1825
+#: engines/groovie/script.cpp:408 engines/parallaction/saveload.cpp:274
+#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1834
#: engines/scumm/players/player_v3m.cpp:130
#: engines/scumm/players/player_v5m.cpp:108 engines/sky/compact.cpp:131
#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:524
@@ -479,7 +480,7 @@ msgstr ""
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -489,7 +490,7 @@ msgstr "Oui"
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -526,6 +527,14 @@ msgstr ""
msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr "ScummVM n'a pas pu trouvé de moteur pour lancer le jeu sélectionné."
+#: gui/launcher.cpp:1159
+msgid "Mass Add..."
+msgstr "Ajout Massif..."
+
+#: gui/launcher.cpp:1161
+msgid "Record..."
+msgstr ""
+
#: gui/massadd.cpp:79 gui/massadd.cpp:82
msgid "... progress ..."
msgstr "... en cours ..."
@@ -625,7 +634,7 @@ msgid "Special dithering modes supported by some games"
msgstr "Mode spécial de tramage supporté par certains jeux"
#: gui/options.cpp:760
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2249
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2298
msgid "Fullscreen mode"
msgstr "Plein écran"
@@ -950,6 +959,43 @@ msgstr ""
"Le thème que vous avez sélectioné ne support pas la langue française. Si "
"vous voulez l'utiliser vous devez d'abord changer de langue."
+#: gui/recorderdialog.cpp:64
+msgid "Recorder or Playback Gameplay"
+msgstr ""
+
+#: gui/recorderdialog.cpp:69 gui/recorderdialog.cpp:156
+#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
+msgid "Delete"
+msgstr "Supprimer"
+
+#: gui/recorderdialog.cpp:71
+msgid "Record"
+msgstr ""
+
+#: gui/recorderdialog.cpp:72
+#, fuzzy
+msgid "Playback"
+msgstr "Jouer"
+
+#: gui/recorderdialog.cpp:74
+msgid "Edit"
+msgstr ""
+
+#: gui/recorderdialog.cpp:86 gui/recorderdialog.cpp:243
+#: gui/recorderdialog.cpp:253
+msgid "Author: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:87 gui/recorderdialog.cpp:244
+#: gui/recorderdialog.cpp:254
+msgid "Notes: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:155
+#, fuzzy
+msgid "Do you really want to delete this record?"
+msgstr "Voulez-vous vraiment supprimer cette sauvegarde ?"
+
#: gui/saveload-dialog.cpp:167
msgid "List view"
msgstr "Vue en liste"
@@ -970,23 +1016,19 @@ msgstr "Heure inconnue"
msgid "No playtime saved"
msgstr "Durée de jeu inconnue"
-#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
-msgid "Delete"
-msgstr "Supprimer"
-
#: gui/saveload-dialog.cpp:275
msgid "Do you really want to delete this saved game?"
msgstr "Voulez-vous vraiment supprimer cette sauvegarde ?"
-#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:875
+#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:884
msgid "Date: "
msgstr "Date: "
-#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:881
+#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:890
msgid "Time: "
msgstr "Heure: "
-#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:889
+#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:898
msgid "Playtime: "
msgstr "Durée de jeu: "
@@ -1002,19 +1044,19 @@ msgstr "Suivant"
msgid "Prev"
msgstr "Précédent"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "New Save"
msgstr "Nouvelle Sauvegarde"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "Create a new save game"
msgstr "Crée une nouvelle sauvegarde."
-#: gui/saveload-dialog.cpp:868
+#: gui/saveload-dialog.cpp:877
msgid "Name: "
msgstr "Nom: "
-#: gui/saveload-dialog.cpp:940
+#: gui/saveload-dialog.cpp:949
#, c-format
msgid "Enter a description for slot %d:"
msgstr "Entrez une description pour l'emplacement %d:"
@@ -1166,7 +1208,7 @@ msgstr "Passer la phrase"
msgid "Error running game:"
msgstr "Erreur lors de l'éxécution du jeu:"
-#: base/main.cpp:536
+#: base/main.cpp:554
msgid "Could not find any engine capable of running the selected game"
msgstr "Impossible de trouver un moteur pour exécuter le jeu sélectionné"
@@ -1285,7 +1327,7 @@ msgstr "Retour au ~L~anceur"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:803
#: engines/cruise/menu.cpp:212 engines/drascula/saveload.cpp:336
#: engines/dreamweb/saveload.cpp:261 engines/neverhood/menumodule.cpp:873
-#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:758
+#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:759
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save game:"
msgstr "Sauvegarde:"
@@ -1298,7 +1340,7 @@ msgstr "Sauvegarde:"
#: engines/agi/saveload.cpp:803 engines/cruise/menu.cpp:212
#: engines/drascula/saveload.cpp:336 engines/dreamweb/saveload.cpp:261
#: engines/neverhood/menumodule.cpp:873 engines/pegasus/pegasus.cpp:377
-#: engines/sci/engine/kfile.cpp:758 engines/scumm/dialogs.cpp:188
+#: engines/sci/engine/kfile.cpp:759 engines/scumm/dialogs.cpp:188
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save"
msgstr "Sauver"
@@ -1336,23 +1378,23 @@ msgstr "~A~nnuler"
msgid "~K~eys"
msgstr "~T~ouches"
-#: engines/engine.cpp:245
+#: engines/engine.cpp:276
msgid "Could not initialize color format."
msgstr "Impossible d'initialiser le format des couleurs."
-#: engines/engine.cpp:253
+#: engines/engine.cpp:284
msgid "Could not switch to video mode: '"
msgstr "Impossible de changer le mode vidéo à: '"
-#: engines/engine.cpp:262
+#: engines/engine.cpp:293
msgid "Could not apply aspect ratio setting."
msgstr "Impossible d'appliquer la correction du rapport d'aspect."
-#: engines/engine.cpp:267
+#: engines/engine.cpp:298
msgid "Could not apply fullscreen setting."
msgstr "Impossible d'appliquer l'option plein écran."
-#: engines/engine.cpp:367
+#: engines/engine.cpp:398
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1366,7 +1408,7 @@ msgstr ""
"données du jeu sur votre disque dur.\n"
"Lisez le fichier README pour plus de détails."
-#: engines/engine.cpp:378
+#: engines/engine.cpp:409
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1380,7 +1422,7 @@ msgstr ""
"logiciel approprié.\n"
"Lisez le fichier README pour plus de détails."
-#: engines/engine.cpp:436
+#: engines/engine.cpp:467
#, c-format
msgid ""
"Gamestate load failed (%s)! Please consult the README for basic information, "
@@ -1389,7 +1431,7 @@ msgstr ""
"Echec du chargement (%s)! . Lisez le fichier README pour les informations de "
"base et les instructions pour obtenir de l'aide supplémentaire."
-#: engines/engine.cpp:449
+#: engines/engine.cpp:480
msgid ""
"WARNING: The game you are about to start is not yet fully supported by "
"ScummVM. As such, it is likely to be unstable, and any saves you make might "
@@ -1399,7 +1441,7 @@ msgstr ""
"complètement supporté par ScummVM. Il est donc instable et les sauvegardes "
"peuvent ne pas marcher avec une future version de ScummVM."
-#: engines/engine.cpp:452
+#: engines/engine.cpp:483
msgid "Start anyway"
msgstr "Jouer quand même"
@@ -1609,11 +1651,11 @@ msgstr "Mode touchpad activé"
msgid "Touchpad mode disabled."
msgstr "Mode touchpad désactivé"
-#: backends/platform/maemo/maemo.cpp:209
+#: backends/platform/maemo/maemo.cpp:208
msgid "Click Mode"
msgstr "Mode Clic"
-#: backends/platform/maemo/maemo.cpp:215
+#: backends/platform/maemo/maemo.cpp:214
#: backends/platform/symbian/src/SymbianActions.cpp:42
#: backends/platform/wince/CEActionsPocket.cpp:60
#: backends/platform/wince/CEActionsSmartphone.cpp:43
@@ -1621,11 +1663,11 @@ msgstr "Mode Clic"
msgid "Left Click"
msgstr "Clic Gauche"
-#: backends/platform/maemo/maemo.cpp:218
+#: backends/platform/maemo/maemo.cpp:217
msgid "Middle Click"
msgstr "Clic Milieu"
-#: backends/platform/maemo/maemo.cpp:221
+#: backends/platform/maemo/maemo.cpp:220
#: backends/platform/symbian/src/SymbianActions.cpp:43
#: backends/platform/wince/CEActionsSmartphone.cpp:44
#: backends/platform/tizen/form.cpp:267
@@ -1662,19 +1704,19 @@ msgctxt "lowres"
msgid "Normal (no scaling)"
msgstr "Normal"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2148
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2197
msgid "Enabled aspect ratio correction"
msgstr "Activer la correction du rapport d'aspect"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2154
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2203
msgid "Disabled aspect ratio correction"
msgstr "Désactiver la correction du rapport d'aspect"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2209
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2258
msgid "Active graphics filter:"
msgstr "Mode graphique actif:"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2251
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2300
msgid "Windowed mode"
msgstr "Mode Fenêtre"
@@ -1733,8 +1775,8 @@ msgstr "Mode rapide"
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
#: backends/events/default/default-events.cpp:218
-#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:82
-#: engines/scumm/help.cpp:84
+#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:83
+#: engines/scumm/help.cpp:85
msgid "Quit"
msgstr "Quitter"
@@ -1754,7 +1796,7 @@ msgstr "Clavier virtuel"
msgid "Key mapper"
msgstr "Affectation des touches"
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
msgid "Do you want to quit ?"
msgstr "Voulez-vous quitter ?"
@@ -2091,35 +2133,56 @@ msgstr "Clic Activé"
msgid "Clicking Disabled"
msgstr "Clic Désactivé"
-#: engines/agi/detection.cpp:142 engines/drascula/detection.cpp:302
+#: engines/agi/detection.cpp:147 engines/drascula/detection.cpp:302
#: engines/dreamweb/detection.cpp:47 engines/neverhood/detection.cpp:160
#: engines/sci/detection.cpp:394 engines/toltecs/detection.cpp:200
-#: engines/zvision/detection.cpp:103
+#: engines/zvision/detection.cpp:246
msgid "Use original save/load screens"
msgstr "Dialogues sauvegarde/chargement d'origine"
-#: engines/agi/detection.cpp:143 engines/drascula/detection.cpp:303
+#: engines/agi/detection.cpp:148 engines/drascula/detection.cpp:303
#: engines/dreamweb/detection.cpp:48 engines/neverhood/detection.cpp:161
#: engines/sci/detection.cpp:395 engines/toltecs/detection.cpp:201
-#: engines/zvision/detection.cpp:104
+#: engines/zvision/detection.cpp:247
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 "
"ScummVM"
+#: engines/agi/detection.cpp:157
+#, fuzzy
+msgid "Use an alternative palette"
+msgstr "Utiliser une intro alternative (version CD uniquement)"
+
+#: engines/agi/detection.cpp:158
+msgid ""
+"Use an alternative palette, common for all Amiga games. This was the old "
+"behavior"
+msgstr ""
+
+#: engines/agi/detection.cpp:167
+#, fuzzy
+msgid "Mouse support"
+msgstr "Support des interruptions"
+
+#: engines/agi/detection.cpp:168
+msgid ""
+"Enables mouse support. Allows to use mouse for movement and in game menus."
+msgstr ""
+
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore game:"
msgstr "Charger le jeu:"
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore"
msgstr "Charger"
-#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2368
+#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2377
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -2130,7 +2193,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2361
+#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2370
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -2141,7 +2204,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2379
+#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2388
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -2157,12 +2220,12 @@ msgstr ""
msgid "Cutscene file '%s' not found!"
msgstr "Fichier de séquence '%s' non trouvé!"
-#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:81
+#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:101
#, fuzzy
msgid "Color Blind Mode"
msgstr "Mode Clic"
-#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:82
+#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:102
msgid "Enable Color Blind Mode by default"
msgstr ""
@@ -2214,7 +2277,7 @@ msgstr "Vidéo rapide"
msgid "Play movies at an increased speed"
msgstr "Joue les vidéos plus rapidement"
-#: engines/groovie/script.cpp:399
+#: engines/groovie/script.cpp:408
msgid "Failed to save game"
msgstr "Échec de la sauvegarde."
@@ -2513,12 +2576,12 @@ msgid "Use an alternative game intro (CD version only)"
msgstr "Utiliser une intro alternative (version CD uniquement)"
#: engines/sci/detection.cpp:374
-msgid "EGA undithering"
-msgstr "Détramage EGA"
+msgid "Skip EGA dithering pass (full color backgrounds)"
+msgstr ""
#: engines/sci/detection.cpp:375
-msgid "Enable undithering in EGA games"
-msgstr "Activer le détramage dans les jeux EGA"
+msgid "Skip dithering pass in EGA games, graphics are shown with full colors"
+msgstr ""
#: engines/sci/detection.cpp:384
msgid "Prefer digital sound effects"
@@ -2593,12 +2656,14 @@ msgstr "Jeu en pause. Appuyer sur Espace pour Reprendre."
#. "Moechten Sie wirklich neu starten? (J/N)J"
#. Will react to J as 'Yes'
#: engines/scumm/dialogs.cpp:183
-msgid "Are you sure you want to restart? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to restart? (Y/N)Y"
msgstr "Voulez-vous vraiment recommencer ? (O/N)O"
#. I18N: you may specify 'Yes' symbol at the end of the line. See previous comment
#: engines/scumm/dialogs.cpp:185
-msgid "Are you sure you want to quit? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to quit? (Y/N)Y"
msgstr "Voulez-vous vraiment quitter ? (O/N)O"
#: engines/scumm/dialogs.cpp:190
@@ -2686,516 +2751,541 @@ msgstr "Essai"
msgid "Expert"
msgstr "Expert"
-#: engines/scumm/help.cpp:73
+#: engines/scumm/help.cpp:74
msgid "Common keyboard commands:"
msgstr "Commandes clavier communes:"
-#: engines/scumm/help.cpp:74
+#: engines/scumm/help.cpp:75
msgid "Save / Load dialog"
msgstr "Dialogue de Sauvegarde/Chargement"
-#: engines/scumm/help.cpp:76
+#: engines/scumm/help.cpp:77
msgid "Skip line of text"
msgstr "Passer la phrase"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Esc"
msgstr "Esc"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Skip cutscene"
msgstr "Passer la séquence"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Space"
msgstr "Espace"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Pause game"
msgstr "Mettre en pause:"
-#: engines/scumm/help.cpp:79 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:95 engines/scumm/help.cpp:96
-#: engines/scumm/help.cpp:97 engines/scumm/help.cpp:98
-#: engines/scumm/help.cpp:99 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:96 engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98 engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Ctrl"
msgstr "Ctrl"
-#: engines/scumm/help.cpp:79
+#: engines/scumm/help.cpp:80
msgid "Load game state 1-10"
msgstr "Charger sauvegarde 1-10:"
-#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:81 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Alt"
msgstr "Alt"
-#: engines/scumm/help.cpp:80
+#: engines/scumm/help.cpp:81
msgid "Save game state 1-10"
msgstr "Écrire sauvegarde 1-10:"
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:90
msgid "Enter"
msgstr "Entrer"
-#: engines/scumm/help.cpp:87
+#: engines/scumm/help.cpp:88
msgid "Music volume up / down"
msgstr "Augmenter / Diminuer volume musique"
-#: engines/scumm/help.cpp:88
+#: engines/scumm/help.cpp:89
msgid "Text speed slower / faster"
msgstr "Diminuer/Augmenter vitesse du texte"
-#: engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:90
msgid "Simulate left mouse button"
msgstr "Simuler bouton gauche de la souris"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Tab"
msgstr "Tab"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Simulate right mouse button"
msgstr "Simuler bouton droit de la souris"
-#: engines/scumm/help.cpp:93
+#: engines/scumm/help.cpp:94
msgid "Special keyboard commands:"
msgstr "Commandes clavier spéciales:"
-#: engines/scumm/help.cpp:94
+#: engines/scumm/help.cpp:95
msgid "Show / Hide console"
msgstr "Afficher/Cacher la console"
-#: engines/scumm/help.cpp:95
+#: engines/scumm/help.cpp:96
msgid "Start the debugger"
msgstr "Ouvrir le débugger"
-#: engines/scumm/help.cpp:96
+#: engines/scumm/help.cpp:97
msgid "Show memory consumption"
msgstr "Afficher la consomation de mémoire"
-#: engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98
msgid "Run in fast mode (*)"
msgstr "Jouer en mode rapide (*)"
-#: engines/scumm/help.cpp:98
+#: engines/scumm/help.cpp:99
msgid "Run in really fast mode (*)"
msgstr "Jouer en mode très rapide (*)"
-#: engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100
msgid "Toggle mouse capture"
msgstr "Capturer/Libérer la souris"
-#: engines/scumm/help.cpp:100
+#: engines/scumm/help.cpp:101
msgid "Switch between graphics filters"
msgstr "Changer de filtre graphique"
-#: engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102
msgid "Increase / Decrease scale factor"
msgstr "Augmenter/Diminuer le facteur d'échelle"
-#: engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:103
msgid "Toggle aspect-ratio correction"
msgstr "Changer correction du rapport d'aspect"
-#: engines/scumm/help.cpp:107
+#: engines/scumm/help.cpp:108
msgid "* Note that using ctrl-f and"
msgstr "* Note que l'utilisation de crtl-f et"
-#: engines/scumm/help.cpp:108
+#: engines/scumm/help.cpp:109
msgid " ctrl-g are not recommended"
msgstr " crtl-g n'est pas recommandé car"
-#: engines/scumm/help.cpp:109
+#: engines/scumm/help.cpp:110
msgid " since they may cause crashes"
msgstr " elle peut causer des plantages ou"
-#: engines/scumm/help.cpp:110
+#: engines/scumm/help.cpp:111
msgid " or incorrect game behavior."
msgstr " ou comportement incorrect du jeu."
-#: engines/scumm/help.cpp:114
+#: engines/scumm/help.cpp:115
msgid "Spinning drafts on the keyboard:"
msgstr "Filage au clavier:"
-#: engines/scumm/help.cpp:116
+#: engines/scumm/help.cpp:117
msgid "Main game controls:"
msgstr "Controles principaux du jeu:"
-#: engines/scumm/help.cpp:121 engines/scumm/help.cpp:136
-#: engines/scumm/help.cpp:161
+#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
+#: engines/scumm/help.cpp:162
msgid "Push"
msgstr "Pousser"
-#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
-#: engines/scumm/help.cpp:162
+#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
+#: engines/scumm/help.cpp:163
msgid "Pull"
msgstr "Tirer"
-#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
-#: engines/scumm/help.cpp:163 engines/scumm/help.cpp:197
-#: engines/scumm/help.cpp:207
+#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
+#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:198
+#: engines/scumm/help.cpp:208
msgid "Give"
msgstr "Donner"
-#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
-#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:190
-#: engines/scumm/help.cpp:208
+#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
+#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
+#: engines/scumm/help.cpp:209
msgid "Open"
msgstr "Ouvrir"
-#: engines/scumm/help.cpp:126
+#: engines/scumm/help.cpp:127
msgid "Go to"
msgstr "Aller"
-#: engines/scumm/help.cpp:127
+#: engines/scumm/help.cpp:128
msgid "Get"
msgstr "Prendre"
-#: engines/scumm/help.cpp:128 engines/scumm/help.cpp:152
-#: engines/scumm/help.cpp:170 engines/scumm/help.cpp:198
-#: engines/scumm/help.cpp:213 engines/scumm/help.cpp:224
-#: engines/scumm/help.cpp:250
+#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:153
+#: engines/scumm/help.cpp:171 engines/scumm/help.cpp:199
+#: engines/scumm/help.cpp:214 engines/scumm/help.cpp:225
+#: engines/scumm/help.cpp:251
msgid "Use"
msgstr "Utiliser"
-#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:142
msgid "Read"
msgstr "Lire"
-#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:147
+#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:148
msgid "New kid"
msgstr "Changer"
-#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:153
-#: engines/scumm/help.cpp:171
+#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
+#: engines/scumm/help.cpp:172
msgid "Turn on"
msgstr "Allumer"
-#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
-#: engines/scumm/help.cpp:172
+#: engines/scumm/help.cpp:133 engines/scumm/help.cpp:155
+#: engines/scumm/help.cpp:173
msgid "Turn off"
msgstr "Éteindre"
-#: engines/scumm/help.cpp:142 engines/scumm/help.cpp:167
-#: engines/scumm/help.cpp:194
+#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
+#: engines/scumm/help.cpp:195
msgid "Walk to"
msgstr "Aller"
-#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
-#: engines/scumm/help.cpp:195 engines/scumm/help.cpp:210
-#: engines/scumm/help.cpp:227
+#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:228
msgid "Pick up"
msgstr "Prendre"
-#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:145 engines/scumm/help.cpp:170
msgid "What is"
msgstr "Qu'est-ce"
-#: engines/scumm/help.cpp:146
+#: engines/scumm/help.cpp:147
msgid "Unlock"
msgstr "Déverrouiller"
-#: engines/scumm/help.cpp:149
+#: engines/scumm/help.cpp:150
msgid "Put on"
msgstr "Mettre"
-#: engines/scumm/help.cpp:150
+#: engines/scumm/help.cpp:151
msgid "Take off"
msgstr "Enlever"
-#: engines/scumm/help.cpp:156
+#: engines/scumm/help.cpp:157
msgid "Fix"
msgstr "Réparer"
-#: engines/scumm/help.cpp:158
+#: engines/scumm/help.cpp:159
msgid "Switch"
msgstr "Commuter"
-#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:228
+#: engines/scumm/help.cpp:167 engines/scumm/help.cpp:229
msgid "Look"
msgstr "Regarder"
-#: engines/scumm/help.cpp:173 engines/scumm/help.cpp:223
+#: engines/scumm/help.cpp:174 engines/scumm/help.cpp:224
msgid "Talk"
msgstr "Parler"
-#: engines/scumm/help.cpp:174
+#: engines/scumm/help.cpp:175
msgid "Travel"
msgstr "Voyager"
-#: engines/scumm/help.cpp:175
+#: engines/scumm/help.cpp:176
msgid "To Henry / To Indy"
msgstr "Henry / Indy"
#. I18N: These are different musical notes
-#: engines/scumm/help.cpp:179
+#: engines/scumm/help.cpp:180
msgid "play C minor on distaff"
msgstr "jouer Do mineur sur la quenouille"
-#: engines/scumm/help.cpp:180
+#: engines/scumm/help.cpp:181
msgid "play D on distaff"
msgstr "jouer Ré sur la quenouille"
-#: engines/scumm/help.cpp:181
+#: engines/scumm/help.cpp:182
msgid "play E on distaff"
msgstr "jouer Mi sur la quenouille"
-#: engines/scumm/help.cpp:182
+#: engines/scumm/help.cpp:183
msgid "play F on distaff"
msgstr "jouer Fa sur la quenouille"
-#: engines/scumm/help.cpp:183
+#: engines/scumm/help.cpp:184
msgid "play G on distaff"
msgstr "jouer Sol sur la quenouille"
-#: engines/scumm/help.cpp:184
+#: engines/scumm/help.cpp:185
msgid "play A on distaff"
msgstr "jouer La sur la quenouille"
-#: engines/scumm/help.cpp:185
+#: engines/scumm/help.cpp:186
msgid "play B on distaff"
msgstr "jouer Si sur la quenouille"
-#: engines/scumm/help.cpp:186
+#: engines/scumm/help.cpp:187
msgid "play C major on distaff"
msgstr "jouer Do Majeur sur la quenouille"
-#: engines/scumm/help.cpp:192 engines/scumm/help.cpp:214
+#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
msgid "puSh"
msgstr "Pousser"
-#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
+#: engines/scumm/help.cpp:194 engines/scumm/help.cpp:216
msgid "pull (Yank)"
msgstr "Tirer"
-#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:212
-#: engines/scumm/help.cpp:248
+#: engines/scumm/help.cpp:197 engines/scumm/help.cpp:213
+#: engines/scumm/help.cpp:249
msgid "Talk to"
msgstr "Parler à"
-#: engines/scumm/help.cpp:199 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:200 engines/scumm/help.cpp:212
msgid "Look at"
msgstr "Regarder"
-#: engines/scumm/help.cpp:200
+#: engines/scumm/help.cpp:201
msgid "turn oN"
msgstr "Allumer"
-#: engines/scumm/help.cpp:201
+#: engines/scumm/help.cpp:202
msgid "turn oFf"
msgstr "Éteindre"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "KeyUp"
msgstr "Touche Haut"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "Highlight prev dialogue"
msgstr "Sélectionner le dialogue précédent"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "KeyDown"
msgstr "Touche Bas"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "Highlight next dialogue"
msgstr "Sélectionner le dialogue suivant"
-#: engines/scumm/help.cpp:222
+#: engines/scumm/help.cpp:223
msgid "Walk"
msgstr "Marcher"
-#: engines/scumm/help.cpp:225 engines/scumm/help.cpp:234
-#: engines/scumm/help.cpp:241 engines/scumm/help.cpp:249
+#: engines/scumm/help.cpp:226 engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:242 engines/scumm/help.cpp:250
msgid "Inventory"
msgstr "Inventaire"
-#: engines/scumm/help.cpp:226
+#: engines/scumm/help.cpp:227
msgid "Object"
msgstr "Objet"
-#: engines/scumm/help.cpp:229
+#: engines/scumm/help.cpp:230
msgid "Black and White / Color"
msgstr "Noir et Blanc / Couleur"
-#: engines/scumm/help.cpp:232
+#: engines/scumm/help.cpp:233
msgid "Eyes"
msgstr "Yeux"
-#: engines/scumm/help.cpp:233
+#: engines/scumm/help.cpp:234
msgid "Tongue"
msgstr "Langue"
-#: engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:236
msgid "Punch"
msgstr "Frapper"
-#: engines/scumm/help.cpp:236
+#: engines/scumm/help.cpp:237
msgid "Kick"
msgstr "Coup de pied"
-#: engines/scumm/help.cpp:239 engines/scumm/help.cpp:247
+#: engines/scumm/help.cpp:240 engines/scumm/help.cpp:248
msgid "Examine"
msgstr "Examiner"
-#: engines/scumm/help.cpp:240
+#: engines/scumm/help.cpp:241
msgid "Regular cursor"
msgstr "Curseur normal"
#. I18N: Comm is a communication device
-#: engines/scumm/help.cpp:243
+#: engines/scumm/help.cpp:244
msgid "Comm"
msgstr "Comm"
-#: engines/scumm/help.cpp:246
+#: engines/scumm/help.cpp:247
msgid "Save / Load / Options"
msgstr "Sauvegarder / Charger / Options"
-#: engines/scumm/help.cpp:255
+#: engines/scumm/help.cpp:256
msgid "Other game controls:"
msgstr "Autres controles du jeu:"
-#: engines/scumm/help.cpp:257 engines/scumm/help.cpp:267
+#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:268
msgid "Inventory:"
msgstr "Inventaires:"
-#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:274
+#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
msgid "Scroll list up"
msgstr "Faire défiler vers le haut"
-#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
+#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:276
msgid "Scroll list down"
msgstr "Faire défiler vers le bas"
-#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:268
+#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:269
msgid "Upper left item"
msgstr "Élément en haut à gauche"
-#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:270
+#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
msgid "Lower left item"
msgstr "Élément en bas à gauche"
-#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
+#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:272
msgid "Upper right item"
msgstr "Élément en haut à droite"
-#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:273
+#: engines/scumm/help.cpp:264 engines/scumm/help.cpp:274
msgid "Lower right item"
msgstr "Élément en bas à droite"
-#: engines/scumm/help.cpp:269
+#: engines/scumm/help.cpp:270
msgid "Middle left item"
msgstr "Élément au milieu à gauche"
-#: engines/scumm/help.cpp:272
+#: engines/scumm/help.cpp:273
msgid "Middle right item"
msgstr "Élément au milieu à droite"
-#: engines/scumm/help.cpp:279 engines/scumm/help.cpp:284
+#: engines/scumm/help.cpp:280 engines/scumm/help.cpp:285
msgid "Switching characters:"
msgstr "Changer de personnage"
-#: engines/scumm/help.cpp:281
+#: engines/scumm/help.cpp:282
msgid "Second kid"
msgstr "Second enfant"
-#: engines/scumm/help.cpp:282
+#: engines/scumm/help.cpp:283
msgid "Third kid"
msgstr "Troisième enfant"
-#: engines/scumm/help.cpp:294
+#: engines/scumm/help.cpp:292
+#, fuzzy
+msgid "Toggle Inventory/IQ Points display"
+msgstr "Basculer l'Affichage Central"
+
+#: engines/scumm/help.cpp:293
+msgid "Toggle Keyboard/Mouse Fighting (*)"
+msgstr ""
+
+#: engines/scumm/help.cpp:295
+msgid "* Keyboard Fighting is always on,"
+msgstr ""
+
+#: engines/scumm/help.cpp:296
+msgid " so despite the in-game message this"
+msgstr ""
+
+#: engines/scumm/help.cpp:297
+msgid " actually toggles Mouse Fighting Off/On"
+msgstr ""
+
+#: engines/scumm/help.cpp:304
msgid "Fighting controls (numpad):"
msgstr "Controles de combat (pavet numérique):"
-#: engines/scumm/help.cpp:295 engines/scumm/help.cpp:296
-#: engines/scumm/help.cpp:297
+#: engines/scumm/help.cpp:305 engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:307
msgid "Step back"
msgstr "Pas en arrière"
-#: engines/scumm/help.cpp:298
+#: engines/scumm/help.cpp:308
msgid "Block high"
msgstr "Bloquer haut"
-#: engines/scumm/help.cpp:299
+#: engines/scumm/help.cpp:309
msgid "Block middle"
msgstr "Bloquer milieu"
-#: engines/scumm/help.cpp:300
+#: engines/scumm/help.cpp:310
msgid "Block low"
msgstr "Bloquer bas"
-#: engines/scumm/help.cpp:301
+#: engines/scumm/help.cpp:311
msgid "Punch high"
msgstr "Fraper haut"
-#: engines/scumm/help.cpp:302
+#: engines/scumm/help.cpp:312
msgid "Punch middle"
msgstr "Frapper milieu"
-#: engines/scumm/help.cpp:303
+#: engines/scumm/help.cpp:313
msgid "Punch low"
msgstr "Frapper bas"
-#: engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:315
+msgid "Sucker punch"
+msgstr ""
+
+#: engines/scumm/help.cpp:318
msgid "These are for Indy on left."
msgstr "Correct quand Indy est à gauche."
-#: engines/scumm/help.cpp:307
+#: engines/scumm/help.cpp:319
msgid "When Indy is on the right,"
msgstr "Quand Indy est à droite, 7, 4 et 1"
-#: engines/scumm/help.cpp:308
+#: engines/scumm/help.cpp:320
msgid "7, 4, and 1 are switched with"
msgstr "sont interverties avec 9, 6 et 3"
-#: engines/scumm/help.cpp:309
+#: engines/scumm/help.cpp:321
msgid "9, 6, and 3, respectively."
msgstr "respectivement."
-#: engines/scumm/help.cpp:316
+#: engines/scumm/help.cpp:328
msgid "Biplane controls (numpad):"
msgstr "Controles du biplane (paver numérique):"
-#: engines/scumm/help.cpp:317
+#: engines/scumm/help.cpp:329
msgid "Fly to upper left"
msgstr "Voler vers le haut à gauche"
-#: engines/scumm/help.cpp:318
+#: engines/scumm/help.cpp:330
msgid "Fly to left"
msgstr "Voler vers la gauche"
-#: engines/scumm/help.cpp:319
+#: engines/scumm/help.cpp:331
msgid "Fly to lower left"
msgstr "Voler vers le bas à gauche"
-#: engines/scumm/help.cpp:320
+#: engines/scumm/help.cpp:332
msgid "Fly upwards"
msgstr "Voler vers le haut"
-#: engines/scumm/help.cpp:321
+#: engines/scumm/help.cpp:333
msgid "Fly straight"
msgstr "Voler tout droit"
-#: engines/scumm/help.cpp:322
+#: engines/scumm/help.cpp:334
msgid "Fly down"
msgstr "Voler vers le bas"
-#: engines/scumm/help.cpp:323
+#: engines/scumm/help.cpp:335
msgid "Fly to upper right"
msgstr "Voler vers le haut à droite"
-#: engines/scumm/help.cpp:324
+#: engines/scumm/help.cpp:336
msgid "Fly to right"
msgstr "Voler vers la droite"
-#: engines/scumm/help.cpp:325
+#: engines/scumm/help.cpp:337
msgid "Fly to lower right"
msgstr "Voler vers la bas à droite"
-#: engines/scumm/scumm.cpp:1823
+#: engines/scumm/scumm.cpp:1832
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
@@ -3204,11 +3294,12 @@ msgstr ""
"Support MIDI natif requière la mise à jour Roland de LucasArt,\n"
"mais %s manque. Utilise AdLib à la place."
-#: engines/scumm/scumm.cpp:2594
+#: engines/scumm/scumm.cpp:2644
+#, fuzzy
msgid ""
-"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
-"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
-"directory inside the Tentacle game directory."
+"Usually, Maniac Mansion would start now. But for that to work, the game "
+"files for Maniac Mansion have to be in the 'Maniac' directory inside the "
+"Tentacle game directory, and the game has to be added to ScummVM."
msgstr ""
"Normalement, Maniac Mansion devrait démarrer maintenant. Cependant ScummVM "
"ne supporte pas encore cette fonctionalité. Pour jouer à Maniac Mansion, "
@@ -3352,6 +3443,47 @@ msgstr ""
msgid "Show the current number of frames per second in the upper left corner"
msgstr ""
+#: engines/zvision/detection.cpp:256
+msgid "Double FPS"
+msgstr ""
+
+#: engines/zvision/detection.cpp:257
+msgid "Increase game FPS from 30 to 60"
+msgstr ""
+
+#: engines/zvision/detection.cpp:266
+#, fuzzy
+msgid "Enable Venus"
+msgstr "Activer le mode helium"
+
+#: engines/zvision/detection.cpp:267
+msgid "Enable the Venus help system"
+msgstr ""
+
+#: engines/zvision/detection.cpp:276
+msgid "Disable animation while turning"
+msgstr ""
+
+#: engines/zvision/detection.cpp:277
+msgid "Disable animation while turning in panoramic mode"
+msgstr ""
+
+#: engines/zvision/detection.cpp:286
+msgid "Use the hires MPEG movies"
+msgstr ""
+
+#: engines/zvision/detection.cpp:287
+#, fuzzy
+msgid ""
+"Use the hires MPEG movies of the DVD version, instead of the lowres AVI ones"
+msgstr "Utiliser les curseurs argentés au lieu des curseurs normaux dorés"
+
+#~ msgid "EGA undithering"
+#~ msgstr "Détramage EGA"
+
+#~ msgid "Enable undithering in EGA games"
+#~ msgstr "Activer le détramage dans les jeux EGA"
+
#~ msgid "MPEG-2 cutscenes found but ScummVM has been built without MPEG-2"
#~ msgstr ""
#~ "Scènes cinématiques MPEG-2 détectées mais ScummVM a été compilé sans le "
@@ -3361,9 +3493,6 @@ msgstr ""
#~ msgid "Mass Add..."
#~ msgstr "Ajout Massif..."
-#~ msgid "Mass Add..."
-#~ msgstr "Ajout Massif..."
-
#~ msgid ""
#~ "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
#~ msgstr "Désactiver la conversion des pistes MT-32 en General MIDI"
diff --git a/po/gl_ES.po b/po/gl_ES.po
index cc8569d2f1..a6a5365e42 100644
--- a/po/gl_ES.po
+++ b/po/gl_ES.po
@@ -1,5 +1,5 @@
# Galician translation for ScummVM.
-# Copyright (C) 2010-2014 ScummVM Team
+# Copyright (C) 2010-2015 The ScummVM Team
# This file is distributed under the same license as the ScummVM package.
# Santiago G. Sanz <s.sanz@uvigo.es>, 2013.
#
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.6.0git\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2014-10-04 00:58+0100\n"
+"POT-Creation-Date: 2015-06-30 20:57+0100\n"
"PO-Revision-Date: 2014-07-02 09:51+0100\n"
"Last-Translator: Santiago G. Sanz <s.sanz@uvigo.es>\n"
"Language-Team: Santiago G. Sanz <s.sanz@uvigo.es>\n"
@@ -53,10 +53,11 @@ msgstr "Arriba"
#: gui/browser.cpp:75 gui/chooser.cpp:46 gui/KeysDialog.cpp:43
#: gui/launcher.cpp:351 gui/massadd.cpp:95 gui/options.cpp:1239
+#: gui/recorderdialog.cpp:70 gui/recorderdialog.cpp:156
#: gui/saveload-dialog.cpp:216 gui/saveload-dialog.cpp:276
-#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:922
+#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:931
#: gui/themebrowser.cpp:55 gui/fluidsynth-dialog.cpp:152
-#: engines/engine.cpp:452 backends/platform/wii/options.cpp:48
+#: engines/engine.cpp:483 backends/platform/wii/options.cpp:48
#: backends/events/default/default-events.cpp:196
#: backends/events/default/default-events.cpp:218
#: engines/drascula/saveload.cpp:49 engines/parallaction/saveload.cpp:274
@@ -69,9 +70,9 @@ msgid "Choose"
msgstr "Elixir"
#: gui/gui-manager.cpp:117 backends/keymapper/remap-dialog.cpp:53
-#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
-#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
-#: engines/scumm/help.cpp:209
+#: engines/scumm/help.cpp:126 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:192
+#: engines/scumm/help.cpp:210
msgid "Close"
msgstr "Pechar"
@@ -87,7 +88,7 @@ msgstr "Mostrar teclado"
msgid "Remap keys"
msgstr "Asignar teclas"
-#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:86
+#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:87
msgid "Toggle fullscreen"
msgstr "Activar/desactivar pantalla completa"
@@ -101,13 +102,13 @@ msgstr "Asignar"
#: gui/KeysDialog.cpp:42 gui/launcher.cpp:352 gui/launcher.cpp:1048
#: gui/launcher.cpp:1052 gui/massadd.cpp:92 gui/options.cpp:1240
-#: gui/saveload-dialog.cpp:923 gui/fluidsynth-dialog.cpp:153
-#: engines/engine.cpp:371 engines/engine.cpp:382
+#: gui/saveload-dialog.cpp:932 gui/fluidsynth-dialog.cpp:153
+#: engines/engine.cpp:402 engines/engine.cpp:413
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
#: engines/agos/animation.cpp:558 engines/drascula/saveload.cpp:49
-#: engines/groovie/script.cpp:399 engines/parallaction/saveload.cpp:274
-#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1825
+#: engines/groovie/script.cpp:408 engines/parallaction/saveload.cpp:274
+#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1834
#: engines/scumm/players/player_v3m.cpp:130
#: engines/scumm/players/player_v5m.cpp:108 engines/sky/compact.cpp:131
#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:524
@@ -475,7 +476,7 @@ msgstr ""
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -485,7 +486,7 @@ msgstr "Si"
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -521,6 +522,14 @@ msgstr "O xogo non permite cargar partidas dende o iniciador."
msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr "ScummVM non foi quen de atopar un motor para executar o xogo!"
+#: gui/launcher.cpp:1159
+msgid "Mass Add..."
+msgstr "Engadir en masa..."
+
+#: gui/launcher.cpp:1161
+msgid "Record..."
+msgstr ""
+
#: gui/massadd.cpp:79 gui/massadd.cpp:82
msgid "... progress ..."
msgstr "...progreso..."
@@ -619,7 +628,7 @@ msgid "Special dithering modes supported by some games"
msgstr "Modos de interpolación de cores compatibles con algúns xogos"
#: gui/options.cpp:760
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2249
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2298
msgid "Fullscreen mode"
msgstr "Pantalla completa"
@@ -937,6 +946,43 @@ msgstr ""
"O tema seleccionado non é compatible co idioma actual. Para empregar o tema, "
"deberás cambiar antes o idioma da interfaz."
+#: gui/recorderdialog.cpp:64
+msgid "Recorder or Playback Gameplay"
+msgstr ""
+
+#: gui/recorderdialog.cpp:69 gui/recorderdialog.cpp:156
+#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
+msgid "Delete"
+msgstr "Eliminar"
+
+#: gui/recorderdialog.cpp:71
+msgid "Record"
+msgstr ""
+
+#: gui/recorderdialog.cpp:72
+#, fuzzy
+msgid "Playback"
+msgstr "Xogar"
+
+#: gui/recorderdialog.cpp:74
+msgid "Edit"
+msgstr ""
+
+#: gui/recorderdialog.cpp:86 gui/recorderdialog.cpp:243
+#: gui/recorderdialog.cpp:253
+msgid "Author: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:87 gui/recorderdialog.cpp:244
+#: gui/recorderdialog.cpp:254
+msgid "Notes: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:155
+#, fuzzy
+msgid "Do you really want to delete this record?"
+msgstr "Seguro que queres eliminar esta partida?"
+
#: gui/saveload-dialog.cpp:167
msgid "List view"
msgstr "Lista"
@@ -957,23 +1003,19 @@ msgstr "Non hai hora gardada"
msgid "No playtime saved"
msgstr "Non hai tempo de xogo gardado"
-#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
-msgid "Delete"
-msgstr "Eliminar"
-
#: gui/saveload-dialog.cpp:275
msgid "Do you really want to delete this saved game?"
msgstr "Seguro que queres eliminar esta partida?"
-#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:875
+#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:884
msgid "Date: "
msgstr "Data:"
-#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:881
+#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:890
msgid "Time: "
msgstr "Hora:"
-#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:889
+#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:898
msgid "Playtime: "
msgstr "Tempo de xogo:"
@@ -989,19 +1031,19 @@ msgstr "Seg."
msgid "Prev"
msgstr "Ant."
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "New Save"
msgstr "Novo ficheiro"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "Create a new save game"
msgstr "Crea un novo ficheiro de gardado"
-#: gui/saveload-dialog.cpp:868
+#: gui/saveload-dialog.cpp:877
msgid "Name: "
msgstr "Nome:"
-#: gui/saveload-dialog.cpp:940
+#: gui/saveload-dialog.cpp:949
#, c-format
msgid "Enter a description for slot %d:"
msgstr "Introduce unha descrición para o espazo %d:"
@@ -1155,7 +1197,7 @@ msgstr "Omitir liña"
msgid "Error running game:"
msgstr "Erro de execución do xogo:"
-#: base/main.cpp:536
+#: base/main.cpp:554
msgid "Could not find any engine capable of running the selected game"
msgstr "Non se puido atopar un motor para executar o xogo seleccionado"
@@ -1272,7 +1314,7 @@ msgstr "~V~olver ao Iniciador"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:803
#: engines/cruise/menu.cpp:212 engines/drascula/saveload.cpp:336
#: engines/dreamweb/saveload.cpp:261 engines/neverhood/menumodule.cpp:873
-#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:758
+#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:759
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save game:"
msgstr "Gardar partida:"
@@ -1285,7 +1327,7 @@ msgstr "Gardar partida:"
#: engines/agi/saveload.cpp:803 engines/cruise/menu.cpp:212
#: engines/drascula/saveload.cpp:336 engines/dreamweb/saveload.cpp:261
#: engines/neverhood/menumodule.cpp:873 engines/pegasus/pegasus.cpp:377
-#: engines/sci/engine/kfile.cpp:758 engines/scumm/dialogs.cpp:188
+#: engines/sci/engine/kfile.cpp:759 engines/scumm/dialogs.cpp:188
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save"
msgstr "Gardar"
@@ -1323,23 +1365,23 @@ msgstr "~C~ancelar"
msgid "~K~eys"
msgstr "~T~eclas"
-#: engines/engine.cpp:245
+#: engines/engine.cpp:276
msgid "Could not initialize color format."
msgstr "Non se puido iniciar o formato de cor."
-#: engines/engine.cpp:253
+#: engines/engine.cpp:284
msgid "Could not switch to video mode: '"
msgstr "Non se puido cambiar ao modo de vídeo: '"
-#: engines/engine.cpp:262
+#: engines/engine.cpp:293
msgid "Could not apply aspect ratio setting."
msgstr "Non se puido aplicar a configuración de proporción."
-#: engines/engine.cpp:267
+#: engines/engine.cpp:298
msgid "Could not apply fullscreen setting."
msgstr "Non se puido aplicar a configuración de pantalla completa."
-#: engines/engine.cpp:367
+#: engines/engine.cpp:398
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1353,7 +1395,7 @@ msgstr ""
"os ficheiros de datos ao disco duro. Consulta\n"
"o ficheiro README para obter máis información."
-#: engines/engine.cpp:378
+#: engines/engine.cpp:409
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1367,7 +1409,7 @@ msgstr ""
"do xogo. Consulta o ficheiro README\n"
"para obter máis información."
-#: engines/engine.cpp:436
+#: engines/engine.cpp:467
#, c-format
msgid ""
"Gamestate load failed (%s)! Please consult the README for basic information, "
@@ -1376,7 +1418,7 @@ msgstr ""
"Erro ao cargar (%s)! Consulta o ficheiro README para obter información "
"básica e máis instrucións para acadar asistencia adicional."
-#: engines/engine.cpp:449
+#: engines/engine.cpp:480
msgid ""
"WARNING: The game you are about to start is not yet fully supported by "
"ScummVM. As such, it is likely to be unstable, and any saves you make might "
@@ -1386,7 +1428,7 @@ msgstr ""
"Por iso, talvez sexa inestable e os ficheiros de gardado talvez non "
"funcionen en futuras versións de ScummVM."
-#: engines/engine.cpp:452
+#: engines/engine.cpp:483
msgid "Start anyway"
msgstr "Iniciar de todos os xeitos"
@@ -1596,11 +1638,11 @@ msgstr "Modo panel táctil activado."
msgid "Touchpad mode disabled."
msgstr "Modo panel táctil desactivado."
-#: backends/platform/maemo/maemo.cpp:209
+#: backends/platform/maemo/maemo.cpp:208
msgid "Click Mode"
msgstr "Modo rato"
-#: backends/platform/maemo/maemo.cpp:215
+#: backends/platform/maemo/maemo.cpp:214
#: backends/platform/symbian/src/SymbianActions.cpp:42
#: backends/platform/wince/CEActionsPocket.cpp:60
#: backends/platform/wince/CEActionsSmartphone.cpp:43
@@ -1608,11 +1650,11 @@ msgstr "Modo rato"
msgid "Left Click"
msgstr "Botón primario"
-#: backends/platform/maemo/maemo.cpp:218
+#: backends/platform/maemo/maemo.cpp:217
msgid "Middle Click"
msgstr "Botón central"
-#: backends/platform/maemo/maemo.cpp:221
+#: backends/platform/maemo/maemo.cpp:220
#: backends/platform/symbian/src/SymbianActions.cpp:43
#: backends/platform/wince/CEActionsSmartphone.cpp:44
#: backends/platform/tizen/form.cpp:267
@@ -1649,19 +1691,19 @@ msgctxt "lowres"
msgid "Normal (no scaling)"
msgstr "Normal (sen escala)"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2148
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2197
msgid "Enabled aspect ratio correction"
msgstr "Corrección de proporción activada"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2154
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2203
msgid "Disabled aspect ratio correction"
msgstr "Corrección de proporción desactivada"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2209
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2258
msgid "Active graphics filter:"
msgstr "Filtro de gráficos activo:"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2251
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2300
msgid "Windowed mode"
msgstr "Modo en ventá"
@@ -1720,8 +1762,8 @@ msgstr "Modo rápido"
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
#: backends/events/default/default-events.cpp:218
-#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:82
-#: engines/scumm/help.cpp:84
+#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:83
+#: engines/scumm/help.cpp:85
msgid "Quit"
msgstr "Saír"
@@ -1741,7 +1783,7 @@ msgstr "Teclado virtual"
msgid "Key mapper"
msgstr "Asignador de teclas"
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
msgid "Do you want to quit ?"
msgstr "Queres saír?"
@@ -2076,34 +2118,55 @@ msgstr "Premer activado"
msgid "Clicking Disabled"
msgstr "Premer desactivado"
-#: engines/agi/detection.cpp:142 engines/drascula/detection.cpp:302
+#: engines/agi/detection.cpp:147 engines/drascula/detection.cpp:302
#: engines/dreamweb/detection.cpp:47 engines/neverhood/detection.cpp:160
#: engines/sci/detection.cpp:394 engines/toltecs/detection.cpp:200
-#: engines/zvision/detection.cpp:103
+#: engines/zvision/detection.cpp:246
msgid "Use original save/load screens"
msgstr "Empregar pantallas orixinais de gardado e carga"
-#: engines/agi/detection.cpp:143 engines/drascula/detection.cpp:303
+#: engines/agi/detection.cpp:148 engines/drascula/detection.cpp:303
#: engines/dreamweb/detection.cpp:48 engines/neverhood/detection.cpp:161
#: engines/sci/detection.cpp:395 engines/toltecs/detection.cpp:201
-#: engines/zvision/detection.cpp:104
+#: engines/zvision/detection.cpp:247
msgid "Use the original save/load screens, instead of the ScummVM ones"
msgstr ""
"Empregar as pantallas orixinais de gardado e carga, no canto das de ScummVM"
+#: engines/agi/detection.cpp:157
+#, fuzzy
+msgid "Use an alternative palette"
+msgstr "Empregar unha introdución alternativa para o xogo (só versión en CD)"
+
+#: engines/agi/detection.cpp:158
+msgid ""
+"Use an alternative palette, common for all Amiga games. This was the old "
+"behavior"
+msgstr ""
+
+#: engines/agi/detection.cpp:167
+#, fuzzy
+msgid "Mouse support"
+msgstr "Omisións"
+
+#: engines/agi/detection.cpp:168
+msgid ""
+"Enables mouse support. Allows to use mouse for movement and in game menus."
+msgstr ""
+
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore game:"
msgstr "Restaurar xogo:"
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore"
msgstr "Restaurar"
-#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2368
+#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2377
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -2114,7 +2177,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2361
+#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2370
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -2125,7 +2188,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2379
+#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2388
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -2141,12 +2204,12 @@ msgstr ""
msgid "Cutscene file '%s' not found!"
msgstr "Non se atopou o ficheiro de secuencia %s!"
-#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:81
+#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:101
#, fuzzy
msgid "Color Blind Mode"
msgstr "Modo rato"
-#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:82
+#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:102
msgid "Enable Color Blind Mode by default"
msgstr ""
@@ -2198,7 +2261,7 @@ msgstr "Velocidade de vídeo rápida"
msgid "Play movies at an increased speed"
msgstr "Reproducir vídeos a máis velocidade"
-#: engines/groovie/script.cpp:399
+#: engines/groovie/script.cpp:408
msgid "Failed to save game"
msgstr "Erro ao gardar a partida"
@@ -2496,12 +2559,12 @@ msgid "Use an alternative game intro (CD version only)"
msgstr "Empregar unha introdución alternativa para o xogo (só versión en CD)"
#: engines/sci/detection.cpp:374
-msgid "EGA undithering"
-msgstr "Non interpolación EGA"
+msgid "Skip EGA dithering pass (full color backgrounds)"
+msgstr ""
#: engines/sci/detection.cpp:375
-msgid "Enable undithering in EGA games"
-msgstr "Activar a non interpolación nos xogos en EGA"
+msgid "Skip dithering pass in EGA games, graphics are shown with full colors"
+msgstr ""
#: engines/sci/detection.cpp:384
msgid "Prefer digital sound effects"
@@ -2576,12 +2639,14 @@ msgstr "Xogo en pausa. Pulsa a barra espazadora para continuar."
#. "Moechten Sie wirklich neu starten? (J/N)J"
#. Will react to J as 'Yes'
#: engines/scumm/dialogs.cpp:183
-msgid "Are you sure you want to restart? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to restart? (Y/N)Y"
msgstr "Seguro que queres reiniciar? (S/N)S"
#. I18N: you may specify 'Yes' symbol at the end of the line. See previous comment
#: engines/scumm/dialogs.cpp:185
-msgid "Are you sure you want to quit? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to quit? (Y/N)Y"
msgstr "Seguro que queres saír? (S/N)S"
#: engines/scumm/dialogs.cpp:190
@@ -2669,516 +2734,541 @@ msgstr "Práctica"
msgid "Expert"
msgstr "Experto"
-#: engines/scumm/help.cpp:73
+#: engines/scumm/help.cpp:74
msgid "Common keyboard commands:"
msgstr "Comandos de teclado comúns:"
-#: engines/scumm/help.cpp:74
+#: engines/scumm/help.cpp:75
msgid "Save / Load dialog"
msgstr "Gardar/cargar diálogo"
-#: engines/scumm/help.cpp:76
+#: engines/scumm/help.cpp:77
msgid "Skip line of text"
msgstr "Omitir liña de texto"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Esc"
msgstr "ESC"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Skip cutscene"
msgstr "Omitir secuencia"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Space"
msgstr "Barra espazadora"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Pause game"
msgstr "Pausar xogo"
-#: engines/scumm/help.cpp:79 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:95 engines/scumm/help.cpp:96
-#: engines/scumm/help.cpp:97 engines/scumm/help.cpp:98
-#: engines/scumm/help.cpp:99 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:96 engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98 engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Ctrl"
msgstr "CTRL"
-#: engines/scumm/help.cpp:79
+#: engines/scumm/help.cpp:80
msgid "Load game state 1-10"
msgstr "Cargar partida 1-10"
-#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:81 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Alt"
msgstr "ALT"
-#: engines/scumm/help.cpp:80
+#: engines/scumm/help.cpp:81
msgid "Save game state 1-10"
msgstr "Gardar partida 1-10"
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:90
msgid "Enter"
msgstr "INTRO"
-#: engines/scumm/help.cpp:87
+#: engines/scumm/help.cpp:88
msgid "Music volume up / down"
msgstr "Subir/baixar volume de música"
-#: engines/scumm/help.cpp:88
+#: engines/scumm/help.cpp:89
msgid "Text speed slower / faster"
msgstr "Acelerar/frear texto"
-#: engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:90
msgid "Simulate left mouse button"
msgstr "Simular botón primario do rato"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Tab"
msgstr "TAB"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Simulate right mouse button"
msgstr "Simular botón secundario do rato"
-#: engines/scumm/help.cpp:93
+#: engines/scumm/help.cpp:94
msgid "Special keyboard commands:"
msgstr "Comandos de teclado especiais:"
-#: engines/scumm/help.cpp:94
+#: engines/scumm/help.cpp:95
msgid "Show / Hide console"
msgstr "Mostrar/ocultar consola"
-#: engines/scumm/help.cpp:95
+#: engines/scumm/help.cpp:96
msgid "Start the debugger"
msgstr "Iniciar o depurador"
-#: engines/scumm/help.cpp:96
+#: engines/scumm/help.cpp:97
msgid "Show memory consumption"
msgstr "Mostrar consumo de memoria"
-#: engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98
msgid "Run in fast mode (*)"
msgstr "Executar en modo rápido (*)"
-#: engines/scumm/help.cpp:98
+#: engines/scumm/help.cpp:99
msgid "Run in really fast mode (*)"
msgstr "Executar en modo moi rápido (*)"
-#: engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100
msgid "Toggle mouse capture"
msgstr "Activar/desactivar captura de rato"
-#: engines/scumm/help.cpp:100
+#: engines/scumm/help.cpp:101
msgid "Switch between graphics filters"
msgstr "Cambiar filtro de gráficos"
-#: engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102
msgid "Increase / Decrease scale factor"
msgstr "Aumentar/reducir factor de escala"
-#: engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:103
msgid "Toggle aspect-ratio correction"
msgstr "Activar/desactivar corrección de proporción"
-#: engines/scumm/help.cpp:107
+#: engines/scumm/help.cpp:108
msgid "* Note that using ctrl-f and"
msgstr "* Nota: non recomendamos"
-#: engines/scumm/help.cpp:108
+#: engines/scumm/help.cpp:109
msgid " ctrl-g are not recommended"
msgstr " empregar CTRL-F nin CTRL-G,"
-#: engines/scumm/help.cpp:109
+#: engines/scumm/help.cpp:110
msgid " since they may cause crashes"
msgstr " xa que poden provocar bloqueos"
-#: engines/scumm/help.cpp:110
+#: engines/scumm/help.cpp:111
msgid " or incorrect game behavior."
msgstr " ou outros erros no xogo."
-#: engines/scumm/help.cpp:114
+#: engines/scumm/help.cpp:115
msgid "Spinning drafts on the keyboard:"
msgstr "Tecer feitizos co teclado:"
-#: engines/scumm/help.cpp:116
+#: engines/scumm/help.cpp:117
msgid "Main game controls:"
msgstr "Controis principais de xogo:"
-#: engines/scumm/help.cpp:121 engines/scumm/help.cpp:136
-#: engines/scumm/help.cpp:161
+#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
+#: engines/scumm/help.cpp:162
msgid "Push"
msgstr "Empuxar"
-#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
-#: engines/scumm/help.cpp:162
+#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
+#: engines/scumm/help.cpp:163
msgid "Pull"
msgstr "Tirar de"
-#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
-#: engines/scumm/help.cpp:163 engines/scumm/help.cpp:197
-#: engines/scumm/help.cpp:207
+#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
+#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:198
+#: engines/scumm/help.cpp:208
msgid "Give"
msgstr "Dar"
-#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
-#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:190
-#: engines/scumm/help.cpp:208
+#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
+#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
+#: engines/scumm/help.cpp:209
msgid "Open"
msgstr "Abrir"
-#: engines/scumm/help.cpp:126
+#: engines/scumm/help.cpp:127
msgid "Go to"
msgstr "Ir a"
-#: engines/scumm/help.cpp:127
+#: engines/scumm/help.cpp:128
msgid "Get"
msgstr "Coller"
-#: engines/scumm/help.cpp:128 engines/scumm/help.cpp:152
-#: engines/scumm/help.cpp:170 engines/scumm/help.cpp:198
-#: engines/scumm/help.cpp:213 engines/scumm/help.cpp:224
-#: engines/scumm/help.cpp:250
+#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:153
+#: engines/scumm/help.cpp:171 engines/scumm/help.cpp:199
+#: engines/scumm/help.cpp:214 engines/scumm/help.cpp:225
+#: engines/scumm/help.cpp:251
msgid "Use"
msgstr "Usar"
-#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:142
msgid "Read"
msgstr "Ler"
-#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:147
+#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:148
msgid "New kid"
msgstr "Rapaz"
-#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:153
-#: engines/scumm/help.cpp:171
+#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
+#: engines/scumm/help.cpp:172
msgid "Turn on"
msgstr "Acender"
-#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
-#: engines/scumm/help.cpp:172
+#: engines/scumm/help.cpp:133 engines/scumm/help.cpp:155
+#: engines/scumm/help.cpp:173
msgid "Turn off"
msgstr "Apagar"
-#: engines/scumm/help.cpp:142 engines/scumm/help.cpp:167
-#: engines/scumm/help.cpp:194
+#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
+#: engines/scumm/help.cpp:195
msgid "Walk to"
msgstr "Ir a"
-#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
-#: engines/scumm/help.cpp:195 engines/scumm/help.cpp:210
-#: engines/scumm/help.cpp:227
+#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:228
msgid "Pick up"
msgstr "Coller"
-#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:145 engines/scumm/help.cpp:170
msgid "What is"
msgstr "Que é"
-#: engines/scumm/help.cpp:146
+#: engines/scumm/help.cpp:147
msgid "Unlock"
msgstr "Despechar"
-#: engines/scumm/help.cpp:149
+#: engines/scumm/help.cpp:150
msgid "Put on"
msgstr "Poñer"
-#: engines/scumm/help.cpp:150
+#: engines/scumm/help.cpp:151
msgid "Take off"
msgstr "Quitar"
-#: engines/scumm/help.cpp:156
+#: engines/scumm/help.cpp:157
msgid "Fix"
msgstr "Reparar"
-#: engines/scumm/help.cpp:158
+#: engines/scumm/help.cpp:159
msgid "Switch"
msgstr "Cambiar"
-#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:228
+#: engines/scumm/help.cpp:167 engines/scumm/help.cpp:229
msgid "Look"
msgstr "Mirar"
-#: engines/scumm/help.cpp:173 engines/scumm/help.cpp:223
+#: engines/scumm/help.cpp:174 engines/scumm/help.cpp:224
msgid "Talk"
msgstr "Falar"
-#: engines/scumm/help.cpp:174
+#: engines/scumm/help.cpp:175
msgid "Travel"
msgstr "Viaxar"
-#: engines/scumm/help.cpp:175
+#: engines/scumm/help.cpp:176
msgid "To Henry / To Indy"
msgstr "A Henry / A Indy"
#. I18N: These are different musical notes
-#: engines/scumm/help.cpp:179
+#: engines/scumm/help.cpp:180
msgid "play C minor on distaff"
msgstr "tocar do menor no bastón"
-#: engines/scumm/help.cpp:180
+#: engines/scumm/help.cpp:181
msgid "play D on distaff"
msgstr "tocar re no bastón"
-#: engines/scumm/help.cpp:181
+#: engines/scumm/help.cpp:182
msgid "play E on distaff"
msgstr "tocar mi no bastón"
-#: engines/scumm/help.cpp:182
+#: engines/scumm/help.cpp:183
msgid "play F on distaff"
msgstr "tocar fa no bastón"
-#: engines/scumm/help.cpp:183
+#: engines/scumm/help.cpp:184
msgid "play G on distaff"
msgstr "tocar sol no bastón"
-#: engines/scumm/help.cpp:184
+#: engines/scumm/help.cpp:185
msgid "play A on distaff"
msgstr "tocar la no bastón"
-#: engines/scumm/help.cpp:185
+#: engines/scumm/help.cpp:186
msgid "play B on distaff"
msgstr "tocar si no bastón"
-#: engines/scumm/help.cpp:186
+#: engines/scumm/help.cpp:187
msgid "play C major on distaff"
msgstr "tocar do maior no bastón"
-#: engines/scumm/help.cpp:192 engines/scumm/help.cpp:214
+#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
msgid "puSh"
msgstr "Empurrar"
-#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
+#: engines/scumm/help.cpp:194 engines/scumm/help.cpp:216
msgid "pull (Yank)"
msgstr "Tirar de"
-#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:212
-#: engines/scumm/help.cpp:248
+#: engines/scumm/help.cpp:197 engines/scumm/help.cpp:213
+#: engines/scumm/help.cpp:249
msgid "Talk to"
msgstr "Falar con"
-#: engines/scumm/help.cpp:199 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:200 engines/scumm/help.cpp:212
msgid "Look at"
msgstr "Mirar"
-#: engines/scumm/help.cpp:200
+#: engines/scumm/help.cpp:201
msgid "turn oN"
msgstr "Acender"
-#: engines/scumm/help.cpp:201
+#: engines/scumm/help.cpp:202
msgid "turn oFf"
msgstr "Apagar"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "KeyUp"
msgstr "Arriba"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "Highlight prev dialogue"
msgstr "Destacar diálogo anterior"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "KeyDown"
msgstr "Abaixo"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "Highlight next dialogue"
msgstr "Destacar diálogo seguinte"
-#: engines/scumm/help.cpp:222
+#: engines/scumm/help.cpp:223
msgid "Walk"
msgstr "Ir a"
-#: engines/scumm/help.cpp:225 engines/scumm/help.cpp:234
-#: engines/scumm/help.cpp:241 engines/scumm/help.cpp:249
+#: engines/scumm/help.cpp:226 engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:242 engines/scumm/help.cpp:250
msgid "Inventory"
msgstr "Inventario"
-#: engines/scumm/help.cpp:226
+#: engines/scumm/help.cpp:227
msgid "Object"
msgstr "Obxecto"
-#: engines/scumm/help.cpp:229
+#: engines/scumm/help.cpp:230
msgid "Black and White / Color"
msgstr "Branco e negro/cor"
-#: engines/scumm/help.cpp:232
+#: engines/scumm/help.cpp:233
msgid "Eyes"
msgstr "Ollos"
-#: engines/scumm/help.cpp:233
+#: engines/scumm/help.cpp:234
msgid "Tongue"
msgstr "Lingua"
-#: engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:236
msgid "Punch"
msgstr "Bater a"
-#: engines/scumm/help.cpp:236
+#: engines/scumm/help.cpp:237
msgid "Kick"
msgstr "Patear a"
-#: engines/scumm/help.cpp:239 engines/scumm/help.cpp:247
+#: engines/scumm/help.cpp:240 engines/scumm/help.cpp:248
msgid "Examine"
msgstr "Examinar"
-#: engines/scumm/help.cpp:240
+#: engines/scumm/help.cpp:241
msgid "Regular cursor"
msgstr "Cursor normal"
#. I18N: Comm is a communication device
-#: engines/scumm/help.cpp:243
+#: engines/scumm/help.cpp:244
msgid "Comm"
msgstr "Comunicador"
-#: engines/scumm/help.cpp:246
+#: engines/scumm/help.cpp:247
msgid "Save / Load / Options"
msgstr "Gardar/cargar/opcións"
-#: engines/scumm/help.cpp:255
+#: engines/scumm/help.cpp:256
msgid "Other game controls:"
msgstr "Outros controis de xogo:"
-#: engines/scumm/help.cpp:257 engines/scumm/help.cpp:267
+#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:268
msgid "Inventory:"
msgstr "Inventario:"
-#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:274
+#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
msgid "Scroll list up"
msgstr "Subir lista"
-#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
+#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:276
msgid "Scroll list down"
msgstr "Baixar lista"
-#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:268
+#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:269
msgid "Upper left item"
msgstr "Obxecto esquerdo arriba"
-#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:270
+#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
msgid "Lower left item"
msgstr "Obxecto esquerdo abaixo"
-#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
+#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:272
msgid "Upper right item"
msgstr "Obxecto dereito arriba"
-#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:273
+#: engines/scumm/help.cpp:264 engines/scumm/help.cpp:274
msgid "Lower right item"
msgstr "Obxecto dereito abaixo"
-#: engines/scumm/help.cpp:269
+#: engines/scumm/help.cpp:270
msgid "Middle left item"
msgstr "Obxecto esquerdo medio"
-#: engines/scumm/help.cpp:272
+#: engines/scumm/help.cpp:273
msgid "Middle right item"
msgstr "Obxecto dereito medio"
-#: engines/scumm/help.cpp:279 engines/scumm/help.cpp:284
+#: engines/scumm/help.cpp:280 engines/scumm/help.cpp:285
msgid "Switching characters:"
msgstr "Cambiar caracteres:"
-#: engines/scumm/help.cpp:281
+#: engines/scumm/help.cpp:282
msgid "Second kid"
msgstr "Rapaz 2"
-#: engines/scumm/help.cpp:282
+#: engines/scumm/help.cpp:283
msgid "Third kid"
msgstr "Rapaz 3"
-#: engines/scumm/help.cpp:294
+#: engines/scumm/help.cpp:292
+#, fuzzy
+msgid "Toggle Inventory/IQ Points display"
+msgstr "Activar/Desactivar pantalla de datos"
+
+#: engines/scumm/help.cpp:293
+msgid "Toggle Keyboard/Mouse Fighting (*)"
+msgstr ""
+
+#: engines/scumm/help.cpp:295
+msgid "* Keyboard Fighting is always on,"
+msgstr ""
+
+#: engines/scumm/help.cpp:296
+msgid " so despite the in-game message this"
+msgstr ""
+
+#: engines/scumm/help.cpp:297
+msgid " actually toggles Mouse Fighting Off/On"
+msgstr ""
+
+#: engines/scumm/help.cpp:304
msgid "Fighting controls (numpad):"
msgstr "Controis de combate (teclado numérico):"
-#: engines/scumm/help.cpp:295 engines/scumm/help.cpp:296
-#: engines/scumm/help.cpp:297
+#: engines/scumm/help.cpp:305 engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:307
msgid "Step back"
msgstr "Paso atrás"
-#: engines/scumm/help.cpp:298
+#: engines/scumm/help.cpp:308
msgid "Block high"
msgstr "Bloqueo alto"
-#: engines/scumm/help.cpp:299
+#: engines/scumm/help.cpp:309
msgid "Block middle"
msgstr "Bloqueo medio"
-#: engines/scumm/help.cpp:300
+#: engines/scumm/help.cpp:310
msgid "Block low"
msgstr "Bloqueo baixo"
-#: engines/scumm/help.cpp:301
+#: engines/scumm/help.cpp:311
msgid "Punch high"
msgstr "Puñazo alto"
-#: engines/scumm/help.cpp:302
+#: engines/scumm/help.cpp:312
msgid "Punch middle"
msgstr "Puñazo medio"
-#: engines/scumm/help.cpp:303
+#: engines/scumm/help.cpp:313
msgid "Punch low"
msgstr "Puñazo baixo"
-#: engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:315
+msgid "Sucker punch"
+msgstr ""
+
+#: engines/scumm/help.cpp:318
msgid "These are for Indy on left."
msgstr "Son para Indy na esquerda."
-#: engines/scumm/help.cpp:307
+#: engines/scumm/help.cpp:319
msgid "When Indy is on the right,"
msgstr "Se está na dereita,"
-#: engines/scumm/help.cpp:308
+#: engines/scumm/help.cpp:320
msgid "7, 4, and 1 are switched with"
msgstr "7, 4 e 1 cámbianse por"
-#: engines/scumm/help.cpp:309
+#: engines/scumm/help.cpp:321
msgid "9, 6, and 3, respectively."
msgstr "9, 6 e 3 respectivamente."
-#: engines/scumm/help.cpp:316
+#: engines/scumm/help.cpp:328
msgid "Biplane controls (numpad):"
msgstr "Controis de biplano (teclado numérico):"
-#: engines/scumm/help.cpp:317
+#: engines/scumm/help.cpp:329
msgid "Fly to upper left"
msgstr "Voar á esquerda arriba"
-#: engines/scumm/help.cpp:318
+#: engines/scumm/help.cpp:330
msgid "Fly to left"
msgstr "Voar á esquerda"
-#: engines/scumm/help.cpp:319
+#: engines/scumm/help.cpp:331
msgid "Fly to lower left"
msgstr "Voar á esquerda abaixo"
-#: engines/scumm/help.cpp:320
+#: engines/scumm/help.cpp:332
msgid "Fly upwards"
msgstr "Voar arriba"
-#: engines/scumm/help.cpp:321
+#: engines/scumm/help.cpp:333
msgid "Fly straight"
msgstr "Voar recto"
-#: engines/scumm/help.cpp:322
+#: engines/scumm/help.cpp:334
msgid "Fly down"
msgstr "Voar abaixo"
-#: engines/scumm/help.cpp:323
+#: engines/scumm/help.cpp:335
msgid "Fly to upper right"
msgstr "Voar á dereita arriba"
-#: engines/scumm/help.cpp:324
+#: engines/scumm/help.cpp:336
msgid "Fly to right"
msgstr "Voar á dereita"
-#: engines/scumm/help.cpp:325
+#: engines/scumm/help.cpp:337
msgid "Fly to lower right"
msgstr "Voar á dereita abaixo"
-#: engines/scumm/scumm.cpp:1823
+#: engines/scumm/scumm.cpp:1832
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
@@ -3187,11 +3277,12 @@ msgstr ""
"A compatibilidade nativa con MIDI precisa a actualización de Roland\n"
"de LucasArts, mais falla %s. Empregarase AdLib."
-#: engines/scumm/scumm.cpp:2594
+#: engines/scumm/scumm.cpp:2644
+#, fuzzy
msgid ""
-"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
-"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
-"directory inside the Tentacle game directory."
+"Usually, Maniac Mansion would start now. But for that to work, the game "
+"files for Maniac Mansion have to be in the 'Maniac' directory inside the "
+"Tentacle game directory, and the game has to be added to ScummVM."
msgstr ""
"Maniac Mansion tería que empezar agora. Porén, ScummVM aínda non é quen de "
"facelo. Para xogar, vai a Engadir xogo no menú de inicio de ScummVM e "
@@ -3332,6 +3423,49 @@ msgstr ""
msgid "Show the current number of frames per second in the upper left corner"
msgstr ""
+#: engines/zvision/detection.cpp:256
+msgid "Double FPS"
+msgstr ""
+
+#: engines/zvision/detection.cpp:257
+msgid "Increase game FPS from 30 to 60"
+msgstr ""
+
+#: engines/zvision/detection.cpp:266
+#, fuzzy
+msgid "Enable Venus"
+msgstr "Activar o modo helio"
+
+#: engines/zvision/detection.cpp:267
+msgid "Enable the Venus help system"
+msgstr ""
+
+#: engines/zvision/detection.cpp:276
+msgid "Disable animation while turning"
+msgstr ""
+
+#: engines/zvision/detection.cpp:277
+msgid "Disable animation while turning in panoramic mode"
+msgstr ""
+
+#: engines/zvision/detection.cpp:286
+msgid "Use the hires MPEG movies"
+msgstr ""
+
+#: engines/zvision/detection.cpp:287
+#, fuzzy
+msgid ""
+"Use the hires MPEG movies of the DVD version, instead of the lowres AVI ones"
+msgstr ""
+"Empregar o xogo de cursores prateados alternativo, no canto dos dourados "
+"normais"
+
+#~ msgid "EGA undithering"
+#~ msgstr "Non interpolación EGA"
+
+#~ msgid "Enable undithering in EGA games"
+#~ msgstr "Activar a non interpolación nos xogos en EGA"
+
#~ msgid "MPEG-2 cutscenes found but ScummVM has been built without MPEG-2"
#~ msgstr "Atopáronse secuencias MPEG-2, mais ScummVM foi compilado sen MPEG-2"
@@ -3339,9 +3473,6 @@ msgstr ""
#~ msgid "Mass Add..."
#~ msgstr "Engadir en masa..."
-#~ msgid "Mass Add..."
-#~ msgstr "Engadir en masa..."
-
#~ msgid ""
#~ "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
#~ msgstr "Desactiva o General MIDI para os xogos con música en Roland MT-32"
diff --git a/po/hu_HU.po b/po/hu_HU.po
index ef3507be98..2121b0a100 100644
--- a/po/hu_HU.po
+++ b/po/hu_HU.po
@@ -1,5 +1,5 @@
# Hungarian translation for ScummVM.
-# Copyright (C) 2010-2014 ScummVM Team
+# Copyright (C) 2010-2015 The ScummVM Team
# This file is distributed under the same license as the ScummVM package.
# George Kormendi <grubycza@hotmail.com>, 2010.
#
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.3.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2014-10-04 00:58+0100\n"
+"POT-Creation-Date: 2015-06-30 20:57+0100\n"
"PO-Revision-Date: 2014-02-18 06:30+0100\n"
"Last-Translator: George Kormendi <grubycza@hotmail.com>\n"
"Language-Team: Hungarian\n"
@@ -55,10 +55,11 @@ msgstr "Feljebb"
#: gui/browser.cpp:75 gui/chooser.cpp:46 gui/KeysDialog.cpp:43
#: gui/launcher.cpp:351 gui/massadd.cpp:95 gui/options.cpp:1239
+#: gui/recorderdialog.cpp:70 gui/recorderdialog.cpp:156
#: gui/saveload-dialog.cpp:216 gui/saveload-dialog.cpp:276
-#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:922
+#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:931
#: gui/themebrowser.cpp:55 gui/fluidsynth-dialog.cpp:152
-#: engines/engine.cpp:452 backends/platform/wii/options.cpp:48
+#: engines/engine.cpp:483 backends/platform/wii/options.cpp:48
#: backends/events/default/default-events.cpp:196
#: backends/events/default/default-events.cpp:218
#: engines/drascula/saveload.cpp:49 engines/parallaction/saveload.cpp:274
@@ -71,9 +72,9 @@ msgid "Choose"
msgstr "Választ"
#: gui/gui-manager.cpp:117 backends/keymapper/remap-dialog.cpp:53
-#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
-#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
-#: engines/scumm/help.cpp:209
+#: engines/scumm/help.cpp:126 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:192
+#: engines/scumm/help.cpp:210
msgid "Close"
msgstr "Bezár"
@@ -89,7 +90,7 @@ msgstr "Billentyûzet beállítások"
msgid "Remap keys"
msgstr "Billentyûk átállítása"
-#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:86
+#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:87
msgid "Toggle fullscreen"
msgstr "Teljesképernyõ kapcsoló"
@@ -103,13 +104,13 @@ msgstr "Kiosztás"
#: gui/KeysDialog.cpp:42 gui/launcher.cpp:352 gui/launcher.cpp:1048
#: gui/launcher.cpp:1052 gui/massadd.cpp:92 gui/options.cpp:1240
-#: gui/saveload-dialog.cpp:923 gui/fluidsynth-dialog.cpp:153
-#: engines/engine.cpp:371 engines/engine.cpp:382
+#: gui/saveload-dialog.cpp:932 gui/fluidsynth-dialog.cpp:153
+#: engines/engine.cpp:402 engines/engine.cpp:413
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
#: engines/agos/animation.cpp:558 engines/drascula/saveload.cpp:49
-#: engines/groovie/script.cpp:399 engines/parallaction/saveload.cpp:274
-#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1825
+#: engines/groovie/script.cpp:408 engines/parallaction/saveload.cpp:274
+#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1834
#: engines/scumm/players/player_v3m.cpp:130
#: engines/scumm/players/player_v5m.cpp:108 engines/sky/compact.cpp:131
#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:524
@@ -477,7 +478,7 @@ msgstr ""
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -487,7 +488,7 @@ msgstr "Igen"
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -524,6 +525,14 @@ msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr ""
"ScummVM nem talált olyan játékmotort ami a választott játékot támogatja!"
+#: gui/launcher.cpp:1159
+msgid "Mass Add..."
+msgstr "Masszív mód..."
+
+#: gui/launcher.cpp:1161
+msgid "Record..."
+msgstr ""
+
#: gui/massadd.cpp:79 gui/massadd.cpp:82
msgid "... progress ..."
msgstr "... folyamatban ..."
@@ -622,7 +631,7 @@ msgid "Special dithering modes supported by some games"
msgstr "Néhány játék támogatja a speciális árnyalási módokat"
#: gui/options.cpp:760
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2249
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2298
msgid "Fullscreen mode"
msgstr "Teljesképernyõs mód:"
@@ -936,6 +945,43 @@ msgstr ""
"A kiválasztott téma nem támogatja a nyelvedet. Ha használni akarod ezt a "
"témát, elõszõr válts át egy másik nyelvre."
+#: gui/recorderdialog.cpp:64
+msgid "Recorder or Playback Gameplay"
+msgstr ""
+
+#: gui/recorderdialog.cpp:69 gui/recorderdialog.cpp:156
+#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
+msgid "Delete"
+msgstr "Töröl"
+
+#: gui/recorderdialog.cpp:71
+msgid "Record"
+msgstr ""
+
+#: gui/recorderdialog.cpp:72
+#, fuzzy
+msgid "Playback"
+msgstr "Játék"
+
+#: gui/recorderdialog.cpp:74
+msgid "Edit"
+msgstr ""
+
+#: gui/recorderdialog.cpp:86 gui/recorderdialog.cpp:243
+#: gui/recorderdialog.cpp:253
+msgid "Author: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:87 gui/recorderdialog.cpp:244
+#: gui/recorderdialog.cpp:254
+msgid "Notes: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:155
+#, fuzzy
+msgid "Do you really want to delete this record?"
+msgstr "Biztos hogy törölni akarod ezt a játékállást?"
+
#: gui/saveload-dialog.cpp:167
msgid "List view"
msgstr "Lista nézet"
@@ -956,23 +1002,19 @@ msgstr "Idõ nincs mentve"
msgid "No playtime saved"
msgstr "Játékidõ nincs mentve"
-#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
-msgid "Delete"
-msgstr "Töröl"
-
#: gui/saveload-dialog.cpp:275
msgid "Do you really want to delete this saved game?"
msgstr "Biztos hogy törölni akarod ezt a játékállást?"
-#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:875
+#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:884
msgid "Date: "
msgstr "Dátum:"
-#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:881
+#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:890
msgid "Time: "
msgstr "Idõ:"
-#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:889
+#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:898
msgid "Playtime: "
msgstr "Játékidõ:"
@@ -988,19 +1030,19 @@ msgstr "Következõ"
msgid "Prev"
msgstr "Elõzõ"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "New Save"
msgstr "Új Mentés"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "Create a new save game"
msgstr "Új játékmentés készítése"
-#: gui/saveload-dialog.cpp:868
+#: gui/saveload-dialog.cpp:877
msgid "Name: "
msgstr "Név:"
-#: gui/saveload-dialog.cpp:940
+#: gui/saveload-dialog.cpp:949
#, c-format
msgid "Enter a description for slot %d:"
msgstr "Adj meg egy leírást a %d slothoz:"
@@ -1152,7 +1194,7 @@ msgstr "Sor átlépése"
msgid "Error running game:"
msgstr "Hiba a játék futtatásakor:"
-#: base/main.cpp:536
+#: base/main.cpp:554
msgid "Could not find any engine capable of running the selected game"
msgstr "Nem található olyan játékmotor ami a választott játékot támogatja"
@@ -1269,7 +1311,7 @@ msgstr "Visszatérés az indítóba"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:803
#: engines/cruise/menu.cpp:212 engines/drascula/saveload.cpp:336
#: engines/dreamweb/saveload.cpp:261 engines/neverhood/menumodule.cpp:873
-#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:758
+#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:759
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save game:"
msgstr "Játék mentése:"
@@ -1282,7 +1324,7 @@ msgstr "Játék mentése:"
#: engines/agi/saveload.cpp:803 engines/cruise/menu.cpp:212
#: engines/drascula/saveload.cpp:336 engines/dreamweb/saveload.cpp:261
#: engines/neverhood/menumodule.cpp:873 engines/pegasus/pegasus.cpp:377
-#: engines/sci/engine/kfile.cpp:758 engines/scumm/dialogs.cpp:188
+#: engines/sci/engine/kfile.cpp:759 engines/scumm/dialogs.cpp:188
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save"
msgstr "Mentés"
@@ -1319,23 +1361,23 @@ msgstr "Mégse"
msgid "~K~eys"
msgstr "Billentyük"
-#: engines/engine.cpp:245
+#: engines/engine.cpp:276
msgid "Could not initialize color format."
msgstr "Szín formátum nincs alkalmazva"
-#: engines/engine.cpp:253
+#: engines/engine.cpp:284
msgid "Could not switch to video mode: '"
msgstr "Videómód nincs átállítva: ' "
-#: engines/engine.cpp:262
+#: engines/engine.cpp:293
msgid "Could not apply aspect ratio setting."
msgstr "Méretarány korrekció nem változott."
-#: engines/engine.cpp:267
+#: engines/engine.cpp:298
msgid "Could not apply fullscreen setting."
msgstr "Teljesképernyõs beállítás nincs alkalmazva"
-#: engines/engine.cpp:367
+#: engines/engine.cpp:398
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1349,7 +1391,7 @@ msgstr ""
"adatfájljait a merevlemezedre.\n"
"Nézd meg a README fájlt a részletekért."
-#: engines/engine.cpp:378
+#: engines/engine.cpp:409
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1363,7 +1405,7 @@ msgstr ""
"hogy a játék zenéje hallható legyen.\n"
"Nézd meg a README fájlt a részletekért."
-#: engines/engine.cpp:436
+#: engines/engine.cpp:467
#, c-format
msgid ""
"Gamestate load failed (%s)! Please consult the README for basic information, "
@@ -1372,7 +1414,7 @@ msgstr ""
"(%s) játékállás betöltése nem sikerült!. Olvassd el a README-t az alap "
"információkról, és hogy hogyan segíthetsz a késõbbiekben."
-#: engines/engine.cpp:449
+#: engines/engine.cpp:480
msgid ""
"WARNING: The game you are about to start is not yet fully supported by "
"ScummVM. As such, it is likely to be unstable, and any saves you make might "
@@ -1382,7 +1424,7 @@ msgstr ""
"ScummVM. Számíts rá hogy nem stabilan fut, és a mentések nem mûködnek a "
"jövõbeni ScummVM verziókkal."
-#: engines/engine.cpp:452
+#: engines/engine.cpp:483
msgid "Start anyway"
msgstr "Indítás így is"
@@ -1590,11 +1632,11 @@ msgstr "Touchpad mód engedélyezve."
msgid "Touchpad mode disabled."
msgstr "Touchpad mód letiltva."
-#: backends/platform/maemo/maemo.cpp:209
+#: backends/platform/maemo/maemo.cpp:208
msgid "Click Mode"
msgstr "Kattintás Mód"
-#: backends/platform/maemo/maemo.cpp:215
+#: backends/platform/maemo/maemo.cpp:214
#: backends/platform/symbian/src/SymbianActions.cpp:42
#: backends/platform/wince/CEActionsPocket.cpp:60
#: backends/platform/wince/CEActionsSmartphone.cpp:43
@@ -1602,11 +1644,11 @@ msgstr "Kattintás Mód"
msgid "Left Click"
msgstr "Bal katt"
-#: backends/platform/maemo/maemo.cpp:218
+#: backends/platform/maemo/maemo.cpp:217
msgid "Middle Click"
msgstr "Középsõ katt"
-#: backends/platform/maemo/maemo.cpp:221
+#: backends/platform/maemo/maemo.cpp:220
#: backends/platform/symbian/src/SymbianActions.cpp:43
#: backends/platform/wince/CEActionsSmartphone.cpp:44
#: backends/platform/tizen/form.cpp:267
@@ -1643,19 +1685,19 @@ msgctxt "lowres"
msgid "Normal (no scaling)"
msgstr "Normál (nincs átméretezés)"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2148
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2197
msgid "Enabled aspect ratio correction"
msgstr "Méretarány korrekció engedélyezve"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2154
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2203
msgid "Disabled aspect ratio correction"
msgstr "Méretarány korrekció letiltva"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2209
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2258
msgid "Active graphics filter:"
msgstr "Aktív grafikus szûrõk:"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2251
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2300
msgid "Windowed mode"
msgstr "Ablakos mód"
@@ -1714,8 +1756,8 @@ msgstr "Gyors mód"
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
#: backends/events/default/default-events.cpp:218
-#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:82
-#: engines/scumm/help.cpp:84
+#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:83
+#: engines/scumm/help.cpp:85
msgid "Quit"
msgstr "Kilépés"
@@ -1735,7 +1777,7 @@ msgstr "Virtuális billentyûzet"
msgid "Key mapper"
msgstr "Billentyû kiosztás"
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
msgid "Do you want to quit ?"
msgstr "Ki akarsz lépni ?"
@@ -2068,33 +2110,54 @@ msgstr "Kattintás engedve"
msgid "Clicking Disabled"
msgstr "Kattintás tiltva"
-#: engines/agi/detection.cpp:142 engines/drascula/detection.cpp:302
+#: engines/agi/detection.cpp:147 engines/drascula/detection.cpp:302
#: engines/dreamweb/detection.cpp:47 engines/neverhood/detection.cpp:160
#: engines/sci/detection.cpp:394 engines/toltecs/detection.cpp:200
-#: engines/zvision/detection.cpp:103
+#: engines/zvision/detection.cpp:246
msgid "Use original save/load screens"
msgstr "Eredeti ment/tölt képernyõk használata"
-#: engines/agi/detection.cpp:143 engines/drascula/detection.cpp:303
+#: engines/agi/detection.cpp:148 engines/drascula/detection.cpp:303
#: engines/dreamweb/detection.cpp:48 engines/neverhood/detection.cpp:161
#: engines/sci/detection.cpp:395 engines/toltecs/detection.cpp:201
-#: engines/zvision/detection.cpp:104
+#: engines/zvision/detection.cpp:247
msgid "Use the original save/load screens, instead of the ScummVM ones"
msgstr "Az eredeti mentés/betöltés képernyõ használata a ScummVM képek helyett"
+#: engines/agi/detection.cpp:157
+#, fuzzy
+msgid "Use an alternative palette"
+msgstr "Alternatív játékintro használata (csak CD verziónál)"
+
+#: engines/agi/detection.cpp:158
+msgid ""
+"Use an alternative palette, common for all Amiga games. This was the old "
+"behavior"
+msgstr ""
+
+#: engines/agi/detection.cpp:167
+#, fuzzy
+msgid "Mouse support"
+msgstr "Átugrás támogatás"
+
+#: engines/agi/detection.cpp:168
+msgid ""
+"Enables mouse support. Allows to use mouse for movement and in game menus."
+msgstr ""
+
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore game:"
msgstr "Játékmenet visszaállítása:"
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore"
msgstr "Visszaállítás"
-#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2368
+#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2377
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -2105,7 +2168,7 @@ msgstr ""
"\n"
"%s fájlból nem sikerült"
-#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2361
+#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2370
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -2116,7 +2179,7 @@ msgstr ""
"\n"
"%s fájlba nem sikerült"
-#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2379
+#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2388
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -2132,12 +2195,12 @@ msgstr ""
msgid "Cutscene file '%s' not found!"
msgstr "'%s' átvezetõ fájl nem található"
-#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:81
+#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:101
#, fuzzy
msgid "Color Blind Mode"
msgstr "Kattintás Mód"
-#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:82
+#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:102
msgid "Enable Color Blind Mode by default"
msgstr ""
@@ -2188,7 +2251,7 @@ msgstr "Gyors filmsebesség"
msgid "Play movies at an increased speed"
msgstr "Filmek lejátszása nagyobb sebességgel"
-#: engines/groovie/script.cpp:399
+#: engines/groovie/script.cpp:408
msgid "Failed to save game"
msgstr "Játék mentés nem sikerült"
@@ -2486,12 +2549,12 @@ msgid "Use an alternative game intro (CD version only)"
msgstr "Alternatív játékintro használata (csak CD verziónál)"
#: engines/sci/detection.cpp:374
-msgid "EGA undithering"
-msgstr "EGA szinjavítás"
+msgid "Skip EGA dithering pass (full color backgrounds)"
+msgstr ""
#: engines/sci/detection.cpp:375
-msgid "Enable undithering in EGA games"
-msgstr "Undithering engedélyezése EGA játékokban"
+msgid "Skip dithering pass in EGA games, graphics are shown with full colors"
+msgstr ""
#: engines/sci/detection.cpp:384
msgid "Prefer digital sound effects"
@@ -2562,12 +2625,14 @@ msgstr "Játék szünetel. SPACE a folytatáshoz."
#. "Moechten Sie wirklich neu starten? (J/N)J"
#. Will react to J as 'Yes'
#: engines/scumm/dialogs.cpp:183
-msgid "Are you sure you want to restart? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to restart? (Y/N)Y"
msgstr "Biztos hogy újra akarod indítani? (Y/N)"
#. I18N: you may specify 'Yes' symbol at the end of the line. See previous comment
#: engines/scumm/dialogs.cpp:185
-msgid "Are you sure you want to quit? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to quit? (Y/N)Y"
msgstr "Biztos hogy ki akarsz lépni? (Y/N)"
#: engines/scumm/dialogs.cpp:190
@@ -2655,516 +2720,541 @@ msgstr "Gyakorlás"
msgid "Expert"
msgstr "Szakértõ"
-#: engines/scumm/help.cpp:73
+#: engines/scumm/help.cpp:74
msgid "Common keyboard commands:"
msgstr "Általános billentyûparancsok:"
-#: engines/scumm/help.cpp:74
+#: engines/scumm/help.cpp:75
msgid "Save / Load dialog"
msgstr "Ment / Tölt dialógus"
-#: engines/scumm/help.cpp:76
+#: engines/scumm/help.cpp:77
msgid "Skip line of text"
msgstr "Szövegsor átugrása"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Esc"
msgstr "Esc"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Skip cutscene"
msgstr "Bevezetõ átugrása"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Space"
msgstr "Szóköz"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Pause game"
msgstr "Szünet a játékban"
-#: engines/scumm/help.cpp:79 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:95 engines/scumm/help.cpp:96
-#: engines/scumm/help.cpp:97 engines/scumm/help.cpp:98
-#: engines/scumm/help.cpp:99 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:96 engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98 engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Ctrl"
msgstr "Ctrl"
-#: engines/scumm/help.cpp:79
+#: engines/scumm/help.cpp:80
msgid "Load game state 1-10"
msgstr "1-10 Játékállás betöltése"
-#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:81 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Alt"
msgstr "Alt"
-#: engines/scumm/help.cpp:80
+#: engines/scumm/help.cpp:81
msgid "Save game state 1-10"
msgstr "1-10 Játékállás mentése"
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:90
msgid "Enter"
msgstr "Enter"
-#: engines/scumm/help.cpp:87
+#: engines/scumm/help.cpp:88
msgid "Music volume up / down"
msgstr "Zene hangerõ fel / le"
-#: engines/scumm/help.cpp:88
+#: engines/scumm/help.cpp:89
msgid "Text speed slower / faster"
msgstr "Szövegsebesség gyors / lassú"
-#: engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:90
msgid "Simulate left mouse button"
msgstr "Bal egérgomb szimuláció"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Tab"
msgstr "Tab"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Simulate right mouse button"
msgstr "Jobb egérgomb szimuláció"
-#: engines/scumm/help.cpp:93
+#: engines/scumm/help.cpp:94
msgid "Special keyboard commands:"
msgstr "Speciális billentyûparancsok:"
-#: engines/scumm/help.cpp:94
+#: engines/scumm/help.cpp:95
msgid "Show / Hide console"
msgstr "Konzol be / ki kapcsolás"
-#: engines/scumm/help.cpp:95
+#: engines/scumm/help.cpp:96
msgid "Start the debugger"
msgstr "Hibakeresõ indítása"
-#: engines/scumm/help.cpp:96
+#: engines/scumm/help.cpp:97
msgid "Show memory consumption"
msgstr "Memóriakihasználtság látszik"
-#: engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98
msgid "Run in fast mode (*)"
msgstr "Futtatás gyors módban (*)"
-#: engines/scumm/help.cpp:98
+#: engines/scumm/help.cpp:99
msgid "Run in really fast mode (*)"
msgstr "Futtatás túlgyors módban (*)"
-#: engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100
msgid "Toggle mouse capture"
msgstr "Egér rögzítés kapcsoló"
-#: engines/scumm/help.cpp:100
+#: engines/scumm/help.cpp:101
msgid "Switch between graphics filters"
msgstr "Kapcsolás grafikus szûrõk között"
-#: engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102
msgid "Increase / Decrease scale factor"
msgstr "Lépték növelés / csökkentés"
-#: engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:103
msgid "Toggle aspect-ratio correction"
msgstr "Méretarány korrekció kapcsoló"
-#: engines/scumm/help.cpp:107
+#: engines/scumm/help.cpp:108
msgid "* Note that using ctrl-f and"
msgstr "* Megjegyzés, ctrl-f és"
-#: engines/scumm/help.cpp:108
+#: engines/scumm/help.cpp:109
msgid " ctrl-g are not recommended"
msgstr " ctrl-g használata nem javasolt"
-#: engines/scumm/help.cpp:109
+#: engines/scumm/help.cpp:110
msgid " since they may cause crashes"
msgstr " mert rendszerösszeomlást vagy"
-#: engines/scumm/help.cpp:110
+#: engines/scumm/help.cpp:111
msgid " or incorrect game behavior."
msgstr " vagy hibás játékmûködést okoz."
-#: engines/scumm/help.cpp:114
+#: engines/scumm/help.cpp:115
msgid "Spinning drafts on the keyboard:"
msgstr "Forgó draftok a billentyûzeten:"
-#: engines/scumm/help.cpp:116
+#: engines/scumm/help.cpp:117
msgid "Main game controls:"
msgstr "Fõ játékvezérlõk:"
-#: engines/scumm/help.cpp:121 engines/scumm/help.cpp:136
-#: engines/scumm/help.cpp:161
+#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
+#: engines/scumm/help.cpp:162
msgid "Push"
msgstr "Tol"
-#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
-#: engines/scumm/help.cpp:162
+#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
+#: engines/scumm/help.cpp:163
msgid "Pull"
msgstr "Húz"
-#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
-#: engines/scumm/help.cpp:163 engines/scumm/help.cpp:197
-#: engines/scumm/help.cpp:207
+#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
+#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:198
+#: engines/scumm/help.cpp:208
msgid "Give"
msgstr "Ad"
-#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
-#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:190
-#: engines/scumm/help.cpp:208
+#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
+#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
+#: engines/scumm/help.cpp:209
msgid "Open"
msgstr "Nyit"
-#: engines/scumm/help.cpp:126
+#: engines/scumm/help.cpp:127
msgid "Go to"
msgstr "Menj"
-#: engines/scumm/help.cpp:127
+#: engines/scumm/help.cpp:128
msgid "Get"
msgstr "Vesz"
-#: engines/scumm/help.cpp:128 engines/scumm/help.cpp:152
-#: engines/scumm/help.cpp:170 engines/scumm/help.cpp:198
-#: engines/scumm/help.cpp:213 engines/scumm/help.cpp:224
-#: engines/scumm/help.cpp:250
+#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:153
+#: engines/scumm/help.cpp:171 engines/scumm/help.cpp:199
+#: engines/scumm/help.cpp:214 engines/scumm/help.cpp:225
+#: engines/scumm/help.cpp:251
msgid "Use"
msgstr "Használ"
-#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:142
msgid "Read"
msgstr "Olvas"
-#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:147
+#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:148
msgid "New kid"
msgstr "Új gyerek"
-#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:153
-#: engines/scumm/help.cpp:171
+#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
+#: engines/scumm/help.cpp:172
msgid "Turn on"
msgstr "Bekapcsol"
-#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
-#: engines/scumm/help.cpp:172
+#: engines/scumm/help.cpp:133 engines/scumm/help.cpp:155
+#: engines/scumm/help.cpp:173
msgid "Turn off"
msgstr "Kikapcsol"
-#: engines/scumm/help.cpp:142 engines/scumm/help.cpp:167
-#: engines/scumm/help.cpp:194
+#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
+#: engines/scumm/help.cpp:195
msgid "Walk to"
msgstr "Odamegy"
-#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
-#: engines/scumm/help.cpp:195 engines/scumm/help.cpp:210
-#: engines/scumm/help.cpp:227
+#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:228
msgid "Pick up"
msgstr "Felvesz"
-#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:145 engines/scumm/help.cpp:170
msgid "What is"
msgstr "Mi ez"
-#: engines/scumm/help.cpp:146
+#: engines/scumm/help.cpp:147
msgid "Unlock"
msgstr "Felold"
-#: engines/scumm/help.cpp:149
+#: engines/scumm/help.cpp:150
msgid "Put on"
msgstr "Felvesz"
-#: engines/scumm/help.cpp:150
+#: engines/scumm/help.cpp:151
msgid "Take off"
msgstr "Letesz"
-#: engines/scumm/help.cpp:156
+#: engines/scumm/help.cpp:157
msgid "Fix"
msgstr "Javít"
-#: engines/scumm/help.cpp:158
+#: engines/scumm/help.cpp:159
msgid "Switch"
msgstr "Kapcsol"
-#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:228
+#: engines/scumm/help.cpp:167 engines/scumm/help.cpp:229
msgid "Look"
msgstr "Megnéz"
-#: engines/scumm/help.cpp:173 engines/scumm/help.cpp:223
+#: engines/scumm/help.cpp:174 engines/scumm/help.cpp:224
msgid "Talk"
msgstr "Beszél"
-#: engines/scumm/help.cpp:174
+#: engines/scumm/help.cpp:175
msgid "Travel"
msgstr "Utazás"
-#: engines/scumm/help.cpp:175
+#: engines/scumm/help.cpp:176
msgid "To Henry / To Indy"
msgstr "Henrytõl / Indytõl"
#. I18N: These are different musical notes
-#: engines/scumm/help.cpp:179
+#: engines/scumm/help.cpp:180
msgid "play C minor on distaff"
msgstr "C moll játék a bottal"
-#: engines/scumm/help.cpp:180
+#: engines/scumm/help.cpp:181
msgid "play D on distaff"
msgstr "Játék D-ben a bottal"
-#: engines/scumm/help.cpp:181
+#: engines/scumm/help.cpp:182
msgid "play E on distaff"
msgstr "Játék E-ben a bottal"
-#: engines/scumm/help.cpp:182
+#: engines/scumm/help.cpp:183
msgid "play F on distaff"
msgstr "Játék F-ben a bottal"
-#: engines/scumm/help.cpp:183
+#: engines/scumm/help.cpp:184
msgid "play G on distaff"
msgstr "Játék G-ben a bottal"
-#: engines/scumm/help.cpp:184
+#: engines/scumm/help.cpp:185
msgid "play A on distaff"
msgstr "Játék A-ban a bottal"
-#: engines/scumm/help.cpp:185
+#: engines/scumm/help.cpp:186
msgid "play B on distaff"
msgstr "Játék B-ben a bottal"
-#: engines/scumm/help.cpp:186
+#: engines/scumm/help.cpp:187
msgid "play C major on distaff"
msgstr "C dúr játék a bottal"
-#: engines/scumm/help.cpp:192 engines/scumm/help.cpp:214
+#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
msgid "puSh"
msgstr "Megtol"
-#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
+#: engines/scumm/help.cpp:194 engines/scumm/help.cpp:216
msgid "pull (Yank)"
msgstr "húz (Ránt)"
-#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:212
-#: engines/scumm/help.cpp:248
+#: engines/scumm/help.cpp:197 engines/scumm/help.cpp:213
+#: engines/scumm/help.cpp:249
msgid "Talk to"
msgstr "Beszél"
-#: engines/scumm/help.cpp:199 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:200 engines/scumm/help.cpp:212
msgid "Look at"
msgstr "Megnézi"
-#: engines/scumm/help.cpp:200
+#: engines/scumm/help.cpp:201
msgid "turn oN"
msgstr "Bekapcsol"
-#: engines/scumm/help.cpp:201
+#: engines/scumm/help.cpp:202
msgid "turn oFf"
msgstr "Kikapcsol"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "KeyUp"
msgstr "FelGomb"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "Highlight prev dialogue"
msgstr "Elõzõ dialógus kiemelése"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "KeyDown"
msgstr "LeGomb"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "Highlight next dialogue"
msgstr "Következõ dialógus kiemelése"
-#: engines/scumm/help.cpp:222
+#: engines/scumm/help.cpp:223
msgid "Walk"
msgstr "Megy"
-#: engines/scumm/help.cpp:225 engines/scumm/help.cpp:234
-#: engines/scumm/help.cpp:241 engines/scumm/help.cpp:249
+#: engines/scumm/help.cpp:226 engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:242 engines/scumm/help.cpp:250
msgid "Inventory"
msgstr "Tárgylista"
-#: engines/scumm/help.cpp:226
+#: engines/scumm/help.cpp:227
msgid "Object"
msgstr "Tárgy"
-#: engines/scumm/help.cpp:229
+#: engines/scumm/help.cpp:230
msgid "Black and White / Color"
msgstr "Fekete fehér / Színes"
-#: engines/scumm/help.cpp:232
+#: engines/scumm/help.cpp:233
msgid "Eyes"
msgstr "Szemek"
-#: engines/scumm/help.cpp:233
+#: engines/scumm/help.cpp:234
msgid "Tongue"
msgstr "Nyelv"
-#: engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:236
msgid "Punch"
msgstr "Megüt"
-#: engines/scumm/help.cpp:236
+#: engines/scumm/help.cpp:237
msgid "Kick"
msgstr "Megüt"
-#: engines/scumm/help.cpp:239 engines/scumm/help.cpp:247
+#: engines/scumm/help.cpp:240 engines/scumm/help.cpp:248
msgid "Examine"
msgstr "Vizsgál"
-#: engines/scumm/help.cpp:240
+#: engines/scumm/help.cpp:241
msgid "Regular cursor"
msgstr "Szabvány kurzor"
#. I18N: Comm is a communication device
-#: engines/scumm/help.cpp:243
+#: engines/scumm/help.cpp:244
msgid "Comm"
msgstr "Comm"
-#: engines/scumm/help.cpp:246
+#: engines/scumm/help.cpp:247
msgid "Save / Load / Options"
msgstr "Ment / Tölt / Opciók"
-#: engines/scumm/help.cpp:255
+#: engines/scumm/help.cpp:256
msgid "Other game controls:"
msgstr "Egyébb játékvezérlõk:"
-#: engines/scumm/help.cpp:257 engines/scumm/help.cpp:267
+#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:268
msgid "Inventory:"
msgstr "Tárgylista:"
-#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:274
+#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
msgid "Scroll list up"
msgstr "Listagörgetés fel"
-#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
+#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:276
msgid "Scroll list down"
msgstr "Listagörgetés le"
-#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:268
+#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:269
msgid "Upper left item"
msgstr "Bal felsõ tárgy"
-#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:270
+#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
msgid "Lower left item"
msgstr "Bal alsó tárgy"
-#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
+#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:272
msgid "Upper right item"
msgstr "Jobb felsõ tárgy"
-#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:273
+#: engines/scumm/help.cpp:264 engines/scumm/help.cpp:274
msgid "Lower right item"
msgstr "Jobb alsó tárgy"
-#: engines/scumm/help.cpp:269
+#: engines/scumm/help.cpp:270
msgid "Middle left item"
msgstr "Bal középsõ tárgy"
-#: engines/scumm/help.cpp:272
+#: engines/scumm/help.cpp:273
msgid "Middle right item"
msgstr "Jobb középsõ tárgy"
-#: engines/scumm/help.cpp:279 engines/scumm/help.cpp:284
+#: engines/scumm/help.cpp:280 engines/scumm/help.cpp:285
msgid "Switching characters:"
msgstr "Karakterek cseréje:"
-#: engines/scumm/help.cpp:281
+#: engines/scumm/help.cpp:282
msgid "Second kid"
msgstr "Második gyerek"
-#: engines/scumm/help.cpp:282
+#: engines/scumm/help.cpp:283
msgid "Third kid"
msgstr "Harmadik gyerek"
-#: engines/scumm/help.cpp:294
+#: engines/scumm/help.cpp:292
+#, fuzzy
+msgid "Toggle Inventory/IQ Points display"
+msgstr "Adatképernyõ kapcsoló"
+
+#: engines/scumm/help.cpp:293
+msgid "Toggle Keyboard/Mouse Fighting (*)"
+msgstr ""
+
+#: engines/scumm/help.cpp:295
+msgid "* Keyboard Fighting is always on,"
+msgstr ""
+
+#: engines/scumm/help.cpp:296
+msgid " so despite the in-game message this"
+msgstr ""
+
+#: engines/scumm/help.cpp:297
+msgid " actually toggles Mouse Fighting Off/On"
+msgstr ""
+
+#: engines/scumm/help.cpp:304
msgid "Fighting controls (numpad):"
msgstr "Verekedés irányítók (numpad):"
-#: engines/scumm/help.cpp:295 engines/scumm/help.cpp:296
-#: engines/scumm/help.cpp:297
+#: engines/scumm/help.cpp:305 engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:307
msgid "Step back"
msgstr "Hátralép"
-#: engines/scumm/help.cpp:298
+#: engines/scumm/help.cpp:308
msgid "Block high"
msgstr "Felsõ védés"
-#: engines/scumm/help.cpp:299
+#: engines/scumm/help.cpp:309
msgid "Block middle"
msgstr "Védés középen"
-#: engines/scumm/help.cpp:300
+#: engines/scumm/help.cpp:310
msgid "Block low"
msgstr "Alsó védés"
-#: engines/scumm/help.cpp:301
+#: engines/scumm/help.cpp:311
msgid "Punch high"
msgstr "Felsõ ütés"
-#: engines/scumm/help.cpp:302
+#: engines/scumm/help.cpp:312
msgid "Punch middle"
msgstr "Ütés középen"
-#: engines/scumm/help.cpp:303
+#: engines/scumm/help.cpp:313
msgid "Punch low"
msgstr "Alsó ütés"
-#: engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:315
+msgid "Sucker punch"
+msgstr ""
+
+#: engines/scumm/help.cpp:318
msgid "These are for Indy on left."
msgstr "Indytõl balra levõ."
-#: engines/scumm/help.cpp:307
+#: engines/scumm/help.cpp:319
msgid "When Indy is on the right,"
msgstr "Indytõl jobbra levõ,"
-#: engines/scumm/help.cpp:308
+#: engines/scumm/help.cpp:320
msgid "7, 4, and 1 are switched with"
msgstr "7, 4, és 1 átkapcsolva"
-#: engines/scumm/help.cpp:309
+#: engines/scumm/help.cpp:321
msgid "9, 6, and 3, respectively."
msgstr "9, 6, és 3-ra, egyenként."
-#: engines/scumm/help.cpp:316
+#: engines/scumm/help.cpp:328
msgid "Biplane controls (numpad):"
msgstr "Repülõ vezérlõk (numpad):"
-#: engines/scumm/help.cpp:317
+#: engines/scumm/help.cpp:329
msgid "Fly to upper left"
msgstr "Balra fel repülés"
-#: engines/scumm/help.cpp:318
+#: engines/scumm/help.cpp:330
msgid "Fly to left"
msgstr "Balra repülés"
-#: engines/scumm/help.cpp:319
+#: engines/scumm/help.cpp:331
msgid "Fly to lower left"
msgstr "Balra le repülés"
-#: engines/scumm/help.cpp:320
+#: engines/scumm/help.cpp:332
msgid "Fly upwards"
msgstr "Repülés fel"
-#: engines/scumm/help.cpp:321
+#: engines/scumm/help.cpp:333
msgid "Fly straight"
msgstr "Repülés elõre"
-#: engines/scumm/help.cpp:322
+#: engines/scumm/help.cpp:334
msgid "Fly down"
msgstr "Repülés le"
-#: engines/scumm/help.cpp:323
+#: engines/scumm/help.cpp:335
msgid "Fly to upper right"
msgstr "Jobbra fel repülés"
-#: engines/scumm/help.cpp:324
+#: engines/scumm/help.cpp:336
msgid "Fly to right"
msgstr "Jobbra repülés"
-#: engines/scumm/help.cpp:325
+#: engines/scumm/help.cpp:337
msgid "Fly to lower right"
msgstr "Jobbra le repülés"
-#: engines/scumm/scumm.cpp:1823
+#: engines/scumm/scumm.cpp:1832
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
@@ -3173,11 +3263,12 @@ msgstr ""
"Native MIDI támogatáshoz kell a Roland Upgrade a LucasArts-tól,\n"
"a %s hiányzik. AdLib-ot használok helyette."
-#: engines/scumm/scumm.cpp:2594
+#: engines/scumm/scumm.cpp:2644
+#, fuzzy
msgid ""
-"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
-"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
-"directory inside the Tentacle game directory."
+"Usually, Maniac Mansion would start now. But for that to work, the game "
+"files for Maniac Mansion have to be in the 'Maniac' directory inside the "
+"Tentacle game directory, and the game has to be added to ScummVM."
msgstr ""
"Általában a Maniac Mansion indulna itt. De a ScummVM most nem indítja el. Ha "
"játszani akarsz vele menj a ScummVM fõmenüben a 'Játék hozzáadás' ra és "
@@ -3315,6 +3406,47 @@ msgstr ""
msgid "Show the current number of frames per second in the upper left corner"
msgstr ""
+#: engines/zvision/detection.cpp:256
+msgid "Double FPS"
+msgstr ""
+
+#: engines/zvision/detection.cpp:257
+msgid "Increase game FPS from 30 to 60"
+msgstr ""
+
+#: engines/zvision/detection.cpp:266
+#, fuzzy
+msgid "Enable Venus"
+msgstr "Helium mód engedélyezve"
+
+#: engines/zvision/detection.cpp:267
+msgid "Enable the Venus help system"
+msgstr ""
+
+#: engines/zvision/detection.cpp:276
+msgid "Disable animation while turning"
+msgstr ""
+
+#: engines/zvision/detection.cpp:277
+msgid "Disable animation while turning in panoramic mode"
+msgstr ""
+
+#: engines/zvision/detection.cpp:286
+msgid "Use the hires MPEG movies"
+msgstr ""
+
+#: engines/zvision/detection.cpp:287
+#, fuzzy
+msgid ""
+"Use the hires MPEG movies of the DVD version, instead of the lowres AVI ones"
+msgstr "Alternatív ezüst kurzorszett használata, a normál arany helyett"
+
+#~ msgid "EGA undithering"
+#~ msgstr "EGA szinjavítás"
+
+#~ msgid "Enable undithering in EGA games"
+#~ msgstr "Undithering engedélyezése EGA játékokban"
+
#~ msgid "MPEG-2 cutscenes found but ScummVM has been built without MPEG-2"
#~ msgstr ""
#~ "MPEG-2 átvezetõfilmet találtam, de a ScummVM MPEG-2 nélkül van lefordítva"
@@ -3323,9 +3455,6 @@ msgstr ""
#~ msgid "Mass Add..."
#~ msgstr "Masszív mód..."
-#~ msgid "Mass Add..."
-#~ msgstr "Masszív mód..."
-
#~ msgid ""
#~ "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
#~ msgstr "General MIDI leképezés Roland MT-32 zenés játékokhoz kikapcsolva"
diff --git a/po/it_IT.po b/po/it_IT.po
index a0192b29bb..5dfa8039b4 100644
--- a/po/it_IT.po
+++ b/po/it_IT.po
@@ -1,5 +1,5 @@
# Italian translation for ScummVM.
-# Copyright (C) 2010-2014 ScummVM Team
+# Copyright (C) 2010-2015 The ScummVM Team
# This file is distributed under the same license as the ScummVM package.
# Matteo 'Maff' Angelino <matteo.maff at gmail dot com>, 2010.
#
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.3.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2014-10-04 00:58+0100\n"
+"POT-Creation-Date: 2015-06-30 20:57+0100\n"
"PO-Revision-Date: 2014-07-03 17:59-0600\n"
"Last-Translator: Matteo 'Maff' Angelino <matteo.maff at gmail dot com>\n"
"Language-Team: Italian\n"
@@ -52,10 +52,11 @@ msgstr "Su"
#: gui/browser.cpp:75 gui/chooser.cpp:46 gui/KeysDialog.cpp:43
#: gui/launcher.cpp:351 gui/massadd.cpp:95 gui/options.cpp:1239
+#: gui/recorderdialog.cpp:70 gui/recorderdialog.cpp:156
#: gui/saveload-dialog.cpp:216 gui/saveload-dialog.cpp:276
-#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:922
+#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:931
#: gui/themebrowser.cpp:55 gui/fluidsynth-dialog.cpp:152
-#: engines/engine.cpp:452 backends/platform/wii/options.cpp:48
+#: engines/engine.cpp:483 backends/platform/wii/options.cpp:48
#: backends/events/default/default-events.cpp:196
#: backends/events/default/default-events.cpp:218
#: engines/drascula/saveload.cpp:49 engines/parallaction/saveload.cpp:274
@@ -68,9 +69,9 @@ msgid "Choose"
msgstr "Scegli"
#: gui/gui-manager.cpp:117 backends/keymapper/remap-dialog.cpp:53
-#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
-#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
-#: engines/scumm/help.cpp:209
+#: engines/scumm/help.cpp:126 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:192
+#: engines/scumm/help.cpp:210
msgid "Close"
msgstr "Chiudi"
@@ -86,7 +87,7 @@ msgstr "Mostra tastiera"
msgid "Remap keys"
msgstr "Riprogramma tasti"
-#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:86
+#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:87
msgid "Toggle fullscreen"
msgstr "Attiva / disattiva schermo intero"
@@ -100,13 +101,13 @@ msgstr "Mappa"
#: gui/KeysDialog.cpp:42 gui/launcher.cpp:352 gui/launcher.cpp:1048
#: gui/launcher.cpp:1052 gui/massadd.cpp:92 gui/options.cpp:1240
-#: gui/saveload-dialog.cpp:923 gui/fluidsynth-dialog.cpp:153
-#: engines/engine.cpp:371 engines/engine.cpp:382
+#: gui/saveload-dialog.cpp:932 gui/fluidsynth-dialog.cpp:153
+#: engines/engine.cpp:402 engines/engine.cpp:413
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
#: engines/agos/animation.cpp:558 engines/drascula/saveload.cpp:49
-#: engines/groovie/script.cpp:399 engines/parallaction/saveload.cpp:274
-#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1825
+#: engines/groovie/script.cpp:408 engines/parallaction/saveload.cpp:274
+#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1834
#: engines/scumm/players/player_v3m.cpp:130
#: engines/scumm/players/player_v5m.cpp:108 engines/sky/compact.cpp:131
#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:524
@@ -475,7 +476,7 @@ msgstr ""
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -485,7 +486,7 @@ msgstr "Sì"
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -525,6 +526,14 @@ msgstr ""
"ScummVM non ha potuto trovare un motore in grado di eseguire il gioco "
"selezionato!"
+#: gui/launcher.cpp:1159
+msgid "Mass Add..."
+msgstr "Agg. in massa..."
+
+#: gui/launcher.cpp:1161
+msgid "Record..."
+msgstr ""
+
#: gui/massadd.cpp:79 gui/massadd.cpp:82
msgid "... progress ..."
msgstr "... progresso ..."
@@ -623,7 +632,7 @@ msgid "Special dithering modes supported by some games"
msgstr "Modalità di resa grafica speciali supportate da alcuni giochi"
#: gui/options.cpp:760
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2249
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2298
msgid "Fullscreen mode"
msgstr "Modalità a schermo intero"
@@ -941,6 +950,43 @@ msgstr ""
"Il tema che hai selezionato non supporta la lingua attuale. Se vuoi "
"utilizzare questo tema devi prima cambiare la lingua."
+#: gui/recorderdialog.cpp:64
+msgid "Recorder or Playback Gameplay"
+msgstr ""
+
+#: gui/recorderdialog.cpp:69 gui/recorderdialog.cpp:156
+#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
+msgid "Delete"
+msgstr "Elimina"
+
+#: gui/recorderdialog.cpp:71
+msgid "Record"
+msgstr ""
+
+#: gui/recorderdialog.cpp:72
+#, fuzzy
+msgid "Playback"
+msgstr "Gioca"
+
+#: gui/recorderdialog.cpp:74
+msgid "Edit"
+msgstr ""
+
+#: gui/recorderdialog.cpp:86 gui/recorderdialog.cpp:243
+#: gui/recorderdialog.cpp:253
+msgid "Author: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:87 gui/recorderdialog.cpp:244
+#: gui/recorderdialog.cpp:254
+msgid "Notes: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:155
+#, fuzzy
+msgid "Do you really want to delete this record?"
+msgstr "Sei sicuro di voler eliminare questo salvataggio?"
+
#: gui/saveload-dialog.cpp:167
msgid "List view"
msgstr "Elenco"
@@ -961,23 +1007,19 @@ msgstr "Nessun orario salvato"
msgid "No playtime saved"
msgstr "Nessun tempo salvato"
-#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
-msgid "Delete"
-msgstr "Elimina"
-
#: gui/saveload-dialog.cpp:275
msgid "Do you really want to delete this saved game?"
msgstr "Sei sicuro di voler eliminare questo salvataggio?"
-#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:875
+#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:884
msgid "Date: "
msgstr "Data: "
-#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:881
+#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:890
msgid "Time: "
msgstr "Ora: "
-#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:889
+#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:898
msgid "Playtime: "
msgstr "Tempo di gioco: "
@@ -993,19 +1035,19 @@ msgstr "Succ."
msgid "Prev"
msgstr "Prec."
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "New Save"
msgstr "Nuovo salvataggio"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "Create a new save game"
msgstr "Crea un nuovo salvataggio"
-#: gui/saveload-dialog.cpp:868
+#: gui/saveload-dialog.cpp:877
msgid "Name: "
msgstr "Nome: "
-#: gui/saveload-dialog.cpp:940
+#: gui/saveload-dialog.cpp:949
#, c-format
msgid "Enter a description for slot %d:"
msgstr "Inserisci una descrizione per la posizione %d:"
@@ -1159,7 +1201,7 @@ msgstr "Salta battuta"
msgid "Error running game:"
msgstr "Errore nell'esecuzione del gioco:"
-#: base/main.cpp:536
+#: base/main.cpp:554
msgid "Could not find any engine capable of running the selected game"
msgstr ""
"Impossibile trovare un motore in grado di eseguire il gioco selezionato"
@@ -1277,7 +1319,7 @@ msgstr "~V~ai a elenco giochi"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:803
#: engines/cruise/menu.cpp:212 engines/drascula/saveload.cpp:336
#: engines/dreamweb/saveload.cpp:261 engines/neverhood/menumodule.cpp:873
-#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:758
+#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:759
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save game:"
msgstr "Salva gioco:"
@@ -1290,7 +1332,7 @@ msgstr "Salva gioco:"
#: engines/agi/saveload.cpp:803 engines/cruise/menu.cpp:212
#: engines/drascula/saveload.cpp:336 engines/dreamweb/saveload.cpp:261
#: engines/neverhood/menumodule.cpp:873 engines/pegasus/pegasus.cpp:377
-#: engines/sci/engine/kfile.cpp:758 engines/scumm/dialogs.cpp:188
+#: engines/sci/engine/kfile.cpp:759 engines/scumm/dialogs.cpp:188
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save"
msgstr "Salva"
@@ -1329,23 +1371,23 @@ msgstr "~A~nnulla"
msgid "~K~eys"
msgstr "~T~asti"
-#: engines/engine.cpp:245
+#: engines/engine.cpp:276
msgid "Could not initialize color format."
msgstr "Impossibile inizializzare il formato colore."
-#: engines/engine.cpp:253
+#: engines/engine.cpp:284
msgid "Could not switch to video mode: '"
msgstr "Impossibile cambiare la modalità video: '"
-#: engines/engine.cpp:262
+#: engines/engine.cpp:293
msgid "Could not apply aspect ratio setting."
msgstr "Impossibile applicare l'impostazione proporzioni"
-#: engines/engine.cpp:267
+#: engines/engine.cpp:298
msgid "Could not apply fullscreen setting."
msgstr "Impossibile applicare l'impostazione schermo intero."
-#: engines/engine.cpp:367
+#: engines/engine.cpp:398
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1359,7 +1401,7 @@ msgstr ""
"sull'hard disk.\n"
"Vedi il file README per i dettagli."
-#: engines/engine.cpp:378
+#: engines/engine.cpp:409
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1373,7 +1415,7 @@ msgstr ""
"la musica del gioco.\n"
"Vedi il file README per i dettagli."
-#: engines/engine.cpp:436
+#: engines/engine.cpp:467
#, c-format
msgid ""
"Gamestate load failed (%s)! Please consult the README for basic information, "
@@ -1383,7 +1425,7 @@ msgstr ""
"per le informazioni di base e per le istruzioni su come ottenere ulteriore "
"assistenza."
-#: engines/engine.cpp:449
+#: engines/engine.cpp:480
msgid ""
"WARNING: The game you are about to start is not yet fully supported by "
"ScummVM. As such, it is likely to be unstable, and any saves you make might "
@@ -1393,7 +1435,7 @@ msgstr ""
"ScummVM. È quindi possibile che sia instabile, e i salvataggi potrebbero non "
"funzionare con future versioni di ScummVM."
-#: engines/engine.cpp:452
+#: engines/engine.cpp:483
msgid "Start anyway"
msgstr "Avvia comunque"
@@ -1603,11 +1645,11 @@ msgstr "Modalità touchpad attivata."
msgid "Touchpad mode disabled."
msgstr "Modalità touchpad disattivata."
-#: backends/platform/maemo/maemo.cpp:209
+#: backends/platform/maemo/maemo.cpp:208
msgid "Click Mode"
msgstr "Modalità clic"
-#: backends/platform/maemo/maemo.cpp:215
+#: backends/platform/maemo/maemo.cpp:214
#: backends/platform/symbian/src/SymbianActions.cpp:42
#: backends/platform/wince/CEActionsPocket.cpp:60
#: backends/platform/wince/CEActionsSmartphone.cpp:43
@@ -1615,11 +1657,11 @@ msgstr "Modalità clic"
msgid "Left Click"
msgstr "Clic sinistro"
-#: backends/platform/maemo/maemo.cpp:218
+#: backends/platform/maemo/maemo.cpp:217
msgid "Middle Click"
msgstr "Clic centrale"
-#: backends/platform/maemo/maemo.cpp:221
+#: backends/platform/maemo/maemo.cpp:220
#: backends/platform/symbian/src/SymbianActions.cpp:43
#: backends/platform/wince/CEActionsSmartphone.cpp:44
#: backends/platform/tizen/form.cpp:267
@@ -1656,19 +1698,19 @@ msgctxt "lowres"
msgid "Normal (no scaling)"
msgstr "Normale (no ridim.)"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2148
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2197
msgid "Enabled aspect ratio correction"
msgstr "Correzione proporzioni attivata"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2154
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2203
msgid "Disabled aspect ratio correction"
msgstr "Correzione proporzioni disattivata"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2209
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2258
msgid "Active graphics filter:"
msgstr "Filtro grafico attivo:"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2251
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2300
msgid "Windowed mode"
msgstr "Modalità finestra"
@@ -1727,8 +1769,8 @@ msgstr "Modalità veloce"
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
#: backends/events/default/default-events.cpp:218
-#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:82
-#: engines/scumm/help.cpp:84
+#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:83
+#: engines/scumm/help.cpp:85
msgid "Quit"
msgstr "Esci"
@@ -1748,7 +1790,7 @@ msgstr "Tastiera virtuale"
msgid "Key mapper"
msgstr "Programmatore tasti"
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
msgid "Do you want to quit ?"
msgstr "Sei sicuro di voler uscire?"
@@ -2083,35 +2125,56 @@ msgstr "Clic attivato"
msgid "Clicking Disabled"
msgstr "Clic disattivato"
-#: engines/agi/detection.cpp:142 engines/drascula/detection.cpp:302
+#: engines/agi/detection.cpp:147 engines/drascula/detection.cpp:302
#: engines/dreamweb/detection.cpp:47 engines/neverhood/detection.cpp:160
#: engines/sci/detection.cpp:394 engines/toltecs/detection.cpp:200
-#: engines/zvision/detection.cpp:103
+#: engines/zvision/detection.cpp:246
msgid "Use original save/load screens"
msgstr "Usa schermate di salvataggio originali"
-#: engines/agi/detection.cpp:143 engines/drascula/detection.cpp:303
+#: engines/agi/detection.cpp:148 engines/drascula/detection.cpp:303
#: engines/dreamweb/detection.cpp:48 engines/neverhood/detection.cpp:161
#: engines/sci/detection.cpp:395 engines/toltecs/detection.cpp:201
-#: engines/zvision/detection.cpp:104
+#: engines/zvision/detection.cpp:247
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 "
"di ScummVM"
+#: engines/agi/detection.cpp:157
+#, fuzzy
+msgid "Use an alternative palette"
+msgstr "Usa un'intro del gioco alternativa (solo versione CD)"
+
+#: engines/agi/detection.cpp:158
+msgid ""
+"Use an alternative palette, common for all Amiga games. This was the old "
+"behavior"
+msgstr ""
+
+#: engines/agi/detection.cpp:167
+#, fuzzy
+msgid "Mouse support"
+msgstr "Interruzione del parlato"
+
+#: engines/agi/detection.cpp:168
+msgid ""
+"Enables mouse support. Allows to use mouse for movement and in game menus."
+msgstr ""
+
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore game:"
msgstr "Ripristina gioco:"
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore"
msgstr "Ripristina"
-#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2368
+#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2377
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -2122,7 +2185,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2361
+#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2370
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -2133,7 +2196,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2379
+#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2388
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -2149,12 +2212,12 @@ msgstr ""
msgid "Cutscene file '%s' not found!"
msgstr "File della scena di intermezzo '%s' non trovato!"
-#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:81
+#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:101
#, fuzzy
msgid "Color Blind Mode"
msgstr "Modalità clic"
-#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:82
+#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:102
msgid "Enable Color Blind Mode by default"
msgstr ""
@@ -2206,7 +2269,7 @@ msgstr "Alta velocità filmati"
msgid "Play movies at an increased speed"
msgstr "Aumenta la velocità di riproduzione dei filmati"
-#: engines/groovie/script.cpp:399
+#: engines/groovie/script.cpp:408
msgid "Failed to save game"
msgstr "Impossibile salvare il gioco"
@@ -2504,12 +2567,12 @@ msgid "Use an alternative game intro (CD version only)"
msgstr "Usa un'intro del gioco alternativa (solo versione CD)"
#: engines/sci/detection.cpp:374
-msgid "EGA undithering"
-msgstr "Undithering EGA"
+msgid "Skip EGA dithering pass (full color backgrounds)"
+msgstr ""
#: engines/sci/detection.cpp:375
-msgid "Enable undithering in EGA games"
-msgstr "Attiva undithering nei giochi EGA"
+msgid "Skip dithering pass in EGA games, graphics are shown with full colors"
+msgstr ""
#: engines/sci/detection.cpp:384
msgid "Prefer digital sound effects"
@@ -2583,12 +2646,14 @@ msgstr "Gioco in pausa. Premere SPAZIO per continuare."
#. "Moechten Sie wirklich neu starten? (J/N)J"
#. Will react to J as 'Yes'
#: engines/scumm/dialogs.cpp:183
-msgid "Are you sure you want to restart? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to restart? (Y/N)Y"
msgstr "Sei sicuro di voler riavviare? (S/N)S"
#. I18N: you may specify 'Yes' symbol at the end of the line. See previous comment
#: engines/scumm/dialogs.cpp:185
-msgid "Are you sure you want to quit? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to quit? (Y/N)Y"
msgstr "Sei sicuro di voler uscire? (S/N)S"
#: engines/scumm/dialogs.cpp:190
@@ -2676,516 +2741,541 @@ msgstr "Base"
msgid "Expert"
msgstr "Expert"
-#: engines/scumm/help.cpp:73
+#: engines/scumm/help.cpp:74
msgid "Common keyboard commands:"
msgstr "Comandi da tastiera comuni:"
-#: engines/scumm/help.cpp:74
+#: engines/scumm/help.cpp:75
msgid "Save / Load dialog"
msgstr "Finestra di salvataggio / caricamento"
-#: engines/scumm/help.cpp:76
+#: engines/scumm/help.cpp:77
msgid "Skip line of text"
msgstr "Salta battuta"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Esc"
msgstr "Esc"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Skip cutscene"
msgstr "Salta scena di intermezzo"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Space"
msgstr "Spazio"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Pause game"
msgstr "Metti in pausa"
-#: engines/scumm/help.cpp:79 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:95 engines/scumm/help.cpp:96
-#: engines/scumm/help.cpp:97 engines/scumm/help.cpp:98
-#: engines/scumm/help.cpp:99 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:96 engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98 engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Ctrl"
msgstr "Ctrl"
-#: engines/scumm/help.cpp:79
+#: engines/scumm/help.cpp:80
msgid "Load game state 1-10"
msgstr "Carica salvataggio 1-10"
-#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:81 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Alt"
msgstr "Alt"
-#: engines/scumm/help.cpp:80
+#: engines/scumm/help.cpp:81
msgid "Save game state 1-10"
msgstr "Salva nella posizione 1-10"
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:90
msgid "Enter"
msgstr "Invio"
-#: engines/scumm/help.cpp:87
+#: engines/scumm/help.cpp:88
msgid "Music volume up / down"
msgstr "Volume musica su / giù"
-#: engines/scumm/help.cpp:88
+#: engines/scumm/help.cpp:89
msgid "Text speed slower / faster"
msgstr "Testo più veloce / meno veloce"
-#: engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:90
msgid "Simulate left mouse button"
msgstr "Simula clic sinistro del mouse"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Tab"
msgstr "Tab"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Simulate right mouse button"
msgstr "Simula clic destro del mouse"
-#: engines/scumm/help.cpp:93
+#: engines/scumm/help.cpp:94
msgid "Special keyboard commands:"
msgstr "Comandi da tastiera speciali:"
-#: engines/scumm/help.cpp:94
+#: engines/scumm/help.cpp:95
msgid "Show / Hide console"
msgstr "Mostra/nascondi console"
-#: engines/scumm/help.cpp:95
+#: engines/scumm/help.cpp:96
msgid "Start the debugger"
msgstr "Avvia il debugger"
-#: engines/scumm/help.cpp:96
+#: engines/scumm/help.cpp:97
msgid "Show memory consumption"
msgstr "Mostra consumo memoria"
-#: engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98
msgid "Run in fast mode (*)"
msgstr "Esegui in modalità veloce (*)"
-#: engines/scumm/help.cpp:98
+#: engines/scumm/help.cpp:99
msgid "Run in really fast mode (*)"
msgstr "Esegui in modalità molto veloce (*)"
-#: engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100
msgid "Toggle mouse capture"
msgstr "Attiva / disattiva ancoraggio del mouse"
-#: engines/scumm/help.cpp:100
+#: engines/scumm/help.cpp:101
msgid "Switch between graphics filters"
msgstr "Cambia filtro grafico"
-#: engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102
msgid "Increase / Decrease scale factor"
msgstr "Aumenta / diminuisci dimensioni"
-#: engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:103
msgid "Toggle aspect-ratio correction"
msgstr "Cambia correzione proporzioni"
-#: engines/scumm/help.cpp:107
+#: engines/scumm/help.cpp:108
msgid "* Note that using ctrl-f and"
msgstr "* Nota che l'utilizzo di ctrl-f e"
-#: engines/scumm/help.cpp:108
+#: engines/scumm/help.cpp:109
msgid " ctrl-g are not recommended"
msgstr " ctrl-g non è consigliato perché"
-#: engines/scumm/help.cpp:109
+#: engines/scumm/help.cpp:110
msgid " since they may cause crashes"
msgstr " potrebbe causare blocchi o un"
-#: engines/scumm/help.cpp:110
+#: engines/scumm/help.cpp:111
msgid " or incorrect game behavior."
msgstr " o comportamento errato del gioco."
-#: engines/scumm/help.cpp:114
+#: engines/scumm/help.cpp:115
msgid "Spinning drafts on the keyboard:"
msgstr "Tessere melodie da tastiera:"
-#: engines/scumm/help.cpp:116
+#: engines/scumm/help.cpp:117
msgid "Main game controls:"
msgstr "Controlli principali di gioco:"
-#: engines/scumm/help.cpp:121 engines/scumm/help.cpp:136
-#: engines/scumm/help.cpp:161
+#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
+#: engines/scumm/help.cpp:162
msgid "Push"
msgstr "Premi"
-#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
-#: engines/scumm/help.cpp:162
+#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
+#: engines/scumm/help.cpp:163
msgid "Pull"
msgstr "Tira"
-#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
-#: engines/scumm/help.cpp:163 engines/scumm/help.cpp:197
-#: engines/scumm/help.cpp:207
+#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
+#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:198
+#: engines/scumm/help.cpp:208
msgid "Give"
msgstr "Dai"
-#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
-#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:190
-#: engines/scumm/help.cpp:208
+#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
+#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
+#: engines/scumm/help.cpp:209
msgid "Open"
msgstr "Apri"
-#: engines/scumm/help.cpp:126
+#: engines/scumm/help.cpp:127
msgid "Go to"
msgstr "Vai verso"
-#: engines/scumm/help.cpp:127
+#: engines/scumm/help.cpp:128
msgid "Get"
msgstr "Prendi"
-#: engines/scumm/help.cpp:128 engines/scumm/help.cpp:152
-#: engines/scumm/help.cpp:170 engines/scumm/help.cpp:198
-#: engines/scumm/help.cpp:213 engines/scumm/help.cpp:224
-#: engines/scumm/help.cpp:250
+#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:153
+#: engines/scumm/help.cpp:171 engines/scumm/help.cpp:199
+#: engines/scumm/help.cpp:214 engines/scumm/help.cpp:225
+#: engines/scumm/help.cpp:251
msgid "Use"
msgstr "Usa"
-#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:142
msgid "Read"
msgstr "Leggi"
-#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:147
+#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:148
msgid "New kid"
msgstr "Cambia personaggio"
-#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:153
-#: engines/scumm/help.cpp:171
+#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
+#: engines/scumm/help.cpp:172
msgid "Turn on"
msgstr "Accendi"
-#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
-#: engines/scumm/help.cpp:172
+#: engines/scumm/help.cpp:133 engines/scumm/help.cpp:155
+#: engines/scumm/help.cpp:173
msgid "Turn off"
msgstr "Spegni"
-#: engines/scumm/help.cpp:142 engines/scumm/help.cpp:167
-#: engines/scumm/help.cpp:194
+#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
+#: engines/scumm/help.cpp:195
msgid "Walk to"
msgstr "Cammina verso"
-#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
-#: engines/scumm/help.cpp:195 engines/scumm/help.cpp:210
-#: engines/scumm/help.cpp:227
+#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:228
msgid "Pick up"
msgstr "Raccogli"
-#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:145 engines/scumm/help.cpp:170
msgid "What is"
msgstr "Che cos'è"
-#: engines/scumm/help.cpp:146
+#: engines/scumm/help.cpp:147
msgid "Unlock"
msgstr "Apri"
-#: engines/scumm/help.cpp:149
+#: engines/scumm/help.cpp:150
msgid "Put on"
msgstr "Indossa"
-#: engines/scumm/help.cpp:150
+#: engines/scumm/help.cpp:151
msgid "Take off"
msgstr "Togli"
-#: engines/scumm/help.cpp:156
+#: engines/scumm/help.cpp:157
msgid "Fix"
msgstr "Ripara"
-#: engines/scumm/help.cpp:158
+#: engines/scumm/help.cpp:159
msgid "Switch"
msgstr "Sposta"
-#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:228
+#: engines/scumm/help.cpp:167 engines/scumm/help.cpp:229
msgid "Look"
msgstr "Guarda"
-#: engines/scumm/help.cpp:173 engines/scumm/help.cpp:223
+#: engines/scumm/help.cpp:174 engines/scumm/help.cpp:224
msgid "Talk"
msgstr "Parla"
-#: engines/scumm/help.cpp:174
+#: engines/scumm/help.cpp:175
msgid "Travel"
msgstr "Viaggio"
-#: engines/scumm/help.cpp:175
+#: engines/scumm/help.cpp:176
msgid "To Henry / To Indy"
msgstr "A Henry / a Indy"
#. I18N: These are different musical notes
-#: engines/scumm/help.cpp:179
+#: engines/scumm/help.cpp:180
msgid "play C minor on distaff"
msgstr "suona Do (C) minore sul bastone"
-#: engines/scumm/help.cpp:180
+#: engines/scumm/help.cpp:181
msgid "play D on distaff"
msgstr "suona Re (D) sul bastone"
-#: engines/scumm/help.cpp:181
+#: engines/scumm/help.cpp:182
msgid "play E on distaff"
msgstr "suona Mi (E) sul bastone"
-#: engines/scumm/help.cpp:182
+#: engines/scumm/help.cpp:183
msgid "play F on distaff"
msgstr "suona Fa (F) sul bastone"
-#: engines/scumm/help.cpp:183
+#: engines/scumm/help.cpp:184
msgid "play G on distaff"
msgstr "suona Sol (G) sul bastone"
-#: engines/scumm/help.cpp:184
+#: engines/scumm/help.cpp:185
msgid "play A on distaff"
msgstr "suona La (A) sul bastone"
-#: engines/scumm/help.cpp:185
+#: engines/scumm/help.cpp:186
msgid "play B on distaff"
msgstr "suona Si (B) sul bastone"
-#: engines/scumm/help.cpp:186
+#: engines/scumm/help.cpp:187
msgid "play C major on distaff"
msgstr "suona Do (C) maggiore sul bastone"
-#: engines/scumm/help.cpp:192 engines/scumm/help.cpp:214
+#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
msgid "puSh"
msgstr "Premi"
-#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
+#: engines/scumm/help.cpp:194 engines/scumm/help.cpp:216
msgid "pull (Yank)"
msgstr "Tira"
-#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:212
-#: engines/scumm/help.cpp:248
+#: engines/scumm/help.cpp:197 engines/scumm/help.cpp:213
+#: engines/scumm/help.cpp:249
msgid "Talk to"
msgstr "Parla con"
-#: engines/scumm/help.cpp:199 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:200 engines/scumm/help.cpp:212
msgid "Look at"
msgstr "Esamina"
-#: engines/scumm/help.cpp:200
+#: engines/scumm/help.cpp:201
msgid "turn oN"
msgstr "Accendi"
-#: engines/scumm/help.cpp:201
+#: engines/scumm/help.cpp:202
msgid "turn oFf"
msgstr "Spegni"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "KeyUp"
msgstr "Tasto su"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "Highlight prev dialogue"
msgstr "Evidenzia dialogo precedente"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "KeyDown"
msgstr "Tasto giù"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "Highlight next dialogue"
msgstr "Evidenzia dialogo successivo"
-#: engines/scumm/help.cpp:222
+#: engines/scumm/help.cpp:223
msgid "Walk"
msgstr "Cammina"
-#: engines/scumm/help.cpp:225 engines/scumm/help.cpp:234
-#: engines/scumm/help.cpp:241 engines/scumm/help.cpp:249
+#: engines/scumm/help.cpp:226 engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:242 engines/scumm/help.cpp:250
msgid "Inventory"
msgstr "Inventario"
-#: engines/scumm/help.cpp:226
+#: engines/scumm/help.cpp:227
msgid "Object"
msgstr "Oggetto"
-#: engines/scumm/help.cpp:229
+#: engines/scumm/help.cpp:230
msgid "Black and White / Color"
msgstr "Bianco e nero / colori"
-#: engines/scumm/help.cpp:232
+#: engines/scumm/help.cpp:233
msgid "Eyes"
msgstr "Occhi"
-#: engines/scumm/help.cpp:233
+#: engines/scumm/help.cpp:234
msgid "Tongue"
msgstr "Lingua"
-#: engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:236
msgid "Punch"
msgstr "Pugno"
-#: engines/scumm/help.cpp:236
+#: engines/scumm/help.cpp:237
msgid "Kick"
msgstr "Calcio"
-#: engines/scumm/help.cpp:239 engines/scumm/help.cpp:247
+#: engines/scumm/help.cpp:240 engines/scumm/help.cpp:248
msgid "Examine"
msgstr "Esamina"
-#: engines/scumm/help.cpp:240
+#: engines/scumm/help.cpp:241
msgid "Regular cursor"
msgstr "Cursore normale"
#. I18N: Comm is a communication device
-#: engines/scumm/help.cpp:243
+#: engines/scumm/help.cpp:244
msgid "Comm"
msgstr "Comm"
-#: engines/scumm/help.cpp:246
+#: engines/scumm/help.cpp:247
msgid "Save / Load / Options"
msgstr "Salva / Carica / Opzioni"
-#: engines/scumm/help.cpp:255
+#: engines/scumm/help.cpp:256
msgid "Other game controls:"
msgstr "Altre opzioni di gioco:"
-#: engines/scumm/help.cpp:257 engines/scumm/help.cpp:267
+#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:268
msgid "Inventory:"
msgstr "Inventario:"
-#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:274
+#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
msgid "Scroll list up"
msgstr "Scorri lista verso l'alto"
-#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
+#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:276
msgid "Scroll list down"
msgstr "Scorri lista verso il basso"
-#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:268
+#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:269
msgid "Upper left item"
msgstr "Oggetto in alto a sinistra"
-#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:270
+#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
msgid "Lower left item"
msgstr "Oggetto in basso a sinistra"
-#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
+#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:272
msgid "Upper right item"
msgstr "Oggetto in alto a destra"
-#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:273
+#: engines/scumm/help.cpp:264 engines/scumm/help.cpp:274
msgid "Lower right item"
msgstr "Oggetto in basso a destra"
-#: engines/scumm/help.cpp:269
+#: engines/scumm/help.cpp:270
msgid "Middle left item"
msgstr "Oggetto al centro a sinistra"
-#: engines/scumm/help.cpp:272
+#: engines/scumm/help.cpp:273
msgid "Middle right item"
msgstr "Oggetto al centro a destra"
-#: engines/scumm/help.cpp:279 engines/scumm/help.cpp:284
+#: engines/scumm/help.cpp:280 engines/scumm/help.cpp:285
msgid "Switching characters:"
msgstr "Cambio personaggio:"
-#: engines/scumm/help.cpp:281
+#: engines/scumm/help.cpp:282
msgid "Second kid"
msgstr "Secondo ragazzo"
-#: engines/scumm/help.cpp:282
+#: engines/scumm/help.cpp:283
msgid "Third kid"
msgstr "Terzo ragazzo"
-#: engines/scumm/help.cpp:294
+#: engines/scumm/help.cpp:292
+#, fuzzy
+msgid "Toggle Inventory/IQ Points display"
+msgstr "Mostra/nascondi schermo centrale dati"
+
+#: engines/scumm/help.cpp:293
+msgid "Toggle Keyboard/Mouse Fighting (*)"
+msgstr ""
+
+#: engines/scumm/help.cpp:295
+msgid "* Keyboard Fighting is always on,"
+msgstr ""
+
+#: engines/scumm/help.cpp:296
+msgid " so despite the in-game message this"
+msgstr ""
+
+#: engines/scumm/help.cpp:297
+msgid " actually toggles Mouse Fighting Off/On"
+msgstr ""
+
+#: engines/scumm/help.cpp:304
msgid "Fighting controls (numpad):"
msgstr "Controlli di combattimento (tastierino numerico):"
-#: engines/scumm/help.cpp:295 engines/scumm/help.cpp:296
-#: engines/scumm/help.cpp:297
+#: engines/scumm/help.cpp:305 engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:307
msgid "Step back"
msgstr "Passo indietro"
-#: engines/scumm/help.cpp:298
+#: engines/scumm/help.cpp:308
msgid "Block high"
msgstr "Para in alto"
-#: engines/scumm/help.cpp:299
+#: engines/scumm/help.cpp:309
msgid "Block middle"
msgstr "Para al centro"
-#: engines/scumm/help.cpp:300
+#: engines/scumm/help.cpp:310
msgid "Block low"
msgstr "Para in basso"
-#: engines/scumm/help.cpp:301
+#: engines/scumm/help.cpp:311
msgid "Punch high"
msgstr "Colpisci in alto"
-#: engines/scumm/help.cpp:302
+#: engines/scumm/help.cpp:312
msgid "Punch middle"
msgstr "Colpisci al centro"
-#: engines/scumm/help.cpp:303
+#: engines/scumm/help.cpp:313
msgid "Punch low"
msgstr "Colpisci in basso"
-#: engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:315
+msgid "Sucker punch"
+msgstr ""
+
+#: engines/scumm/help.cpp:318
msgid "These are for Indy on left."
msgstr "Questi sono i controlli quando"
-#: engines/scumm/help.cpp:307
+#: engines/scumm/help.cpp:319
msgid "When Indy is on the right,"
msgstr "Indy è sulla sinistra. Quando è"
-#: engines/scumm/help.cpp:308
+#: engines/scumm/help.cpp:320
msgid "7, 4, and 1 are switched with"
msgstr "sulla destra, 7, 4 e 1 sostituiscono"
-#: engines/scumm/help.cpp:309
+#: engines/scumm/help.cpp:321
msgid "9, 6, and 3, respectively."
msgstr "rispettivamente 9, 6 e 3."
-#: engines/scumm/help.cpp:316
+#: engines/scumm/help.cpp:328
msgid "Biplane controls (numpad):"
msgstr "Controlli biplano (tastierino numerico):"
-#: engines/scumm/help.cpp:317
+#: engines/scumm/help.cpp:329
msgid "Fly to upper left"
msgstr "Vola in alto a sinistra"
-#: engines/scumm/help.cpp:318
+#: engines/scumm/help.cpp:330
msgid "Fly to left"
msgstr "Vola a sinistra"
-#: engines/scumm/help.cpp:319
+#: engines/scumm/help.cpp:331
msgid "Fly to lower left"
msgstr "Vola in basso a sinistra"
-#: engines/scumm/help.cpp:320
+#: engines/scumm/help.cpp:332
msgid "Fly upwards"
msgstr "Vola in alto"
-#: engines/scumm/help.cpp:321
+#: engines/scumm/help.cpp:333
msgid "Fly straight"
msgstr "Vola diritto"
-#: engines/scumm/help.cpp:322
+#: engines/scumm/help.cpp:334
msgid "Fly down"
msgstr "Vola in basso"
-#: engines/scumm/help.cpp:323
+#: engines/scumm/help.cpp:335
msgid "Fly to upper right"
msgstr "Vola in alto a destra"
-#: engines/scumm/help.cpp:324
+#: engines/scumm/help.cpp:336
msgid "Fly to right"
msgstr "Vola a destra"
-#: engines/scumm/help.cpp:325
+#: engines/scumm/help.cpp:337
msgid "Fly to lower right"
msgstr "Vola in basso a destra"
-#: engines/scumm/scumm.cpp:1823
+#: engines/scumm/scumm.cpp:1832
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
@@ -3194,11 +3284,12 @@ msgstr ""
"Il supporto nativo MIDI richiede il Roland Upgrade della LucasArts,\n"
"ma %s non è presente. Verrà usato AdLib."
-#: engines/scumm/scumm.cpp:2594
+#: engines/scumm/scumm.cpp:2644
+#, fuzzy
msgid ""
-"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
-"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
-"directory inside the Tentacle game directory."
+"Usually, Maniac Mansion would start now. But for that to work, the game "
+"files for Maniac Mansion have to be in the 'Maniac' directory inside the "
+"Tentacle game directory, and the game has to be added to ScummVM."
msgstr ""
"Originariamente, a questo punto dovrebbe partire Maniac Mansion. Ma ScummVM "
"non lo può ancora fare. Per giocarci, vai a \"Aggiungi gioco\" nel menu "
@@ -3340,6 +3431,48 @@ msgstr ""
msgid "Show the current number of frames per second in the upper left corner"
msgstr ""
+#: engines/zvision/detection.cpp:256
+msgid "Double FPS"
+msgstr ""
+
+#: engines/zvision/detection.cpp:257
+msgid "Increase game FPS from 30 to 60"
+msgstr ""
+
+#: engines/zvision/detection.cpp:266
+#, fuzzy
+msgid "Enable Venus"
+msgstr "Attiva la modalità elio"
+
+#: engines/zvision/detection.cpp:267
+msgid "Enable the Venus help system"
+msgstr ""
+
+#: engines/zvision/detection.cpp:276
+msgid "Disable animation while turning"
+msgstr ""
+
+#: engines/zvision/detection.cpp:277
+msgid "Disable animation while turning in panoramic mode"
+msgstr ""
+
+#: engines/zvision/detection.cpp:286
+msgid "Use the hires MPEG movies"
+msgstr ""
+
+#: engines/zvision/detection.cpp:287
+#, fuzzy
+msgid ""
+"Use the hires MPEG movies of the DVD version, instead of the lowres AVI ones"
+msgstr ""
+"Usa il set alternativo di cursori d'argento al posto di quelli normali d'oro"
+
+#~ msgid "EGA undithering"
+#~ msgstr "Undithering EGA"
+
+#~ msgid "Enable undithering in EGA games"
+#~ msgstr "Attiva undithering nei giochi EGA"
+
#~ msgid "MPEG-2 cutscenes found but ScummVM has been built without MPEG-2"
#~ msgstr ""
#~ "Sono state trovare scene di intermezzo MPEG-2 ma ScummVM è stato "
@@ -3349,9 +3482,6 @@ msgstr ""
#~ msgid "Mass Add..."
#~ msgstr "Agg. massa..."
-#~ msgid "Mass Add..."
-#~ msgstr "Agg. in massa..."
-
#~ msgid ""
#~ "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
#~ msgstr ""
diff --git a/po/nb_NO.po b/po/nb_NO.po
index cf211a46a4..1c73957a54 100644
--- a/po/nb_NO.po
+++ b/po/nb_NO.po
@@ -1,5 +1,5 @@
# Norwegian (Bokmaal) translation for ScummVM.
-# Copyright (C) 2010-2014 ScummVM Team
+# Copyright (C) 2010-2015 The ScummVM Team
# This file is distributed under the same license as the ScummVM package.
# Einar Johan T. Sømåen <einarjohants@gmail.com>, 2010.
#
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.3.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2014-10-04 00:58+0100\n"
+"POT-Creation-Date: 2015-06-30 20:57+0100\n"
"PO-Revision-Date: 2014-07-11 00:02+0100\n"
"Last-Translator: Einar Johan Trøan Sømåen <einarjohants@gmail.com>\n"
"Language-Team: somaen <einarjohants@gmail.com>\n"
@@ -55,10 +55,11 @@ msgstr "Oppover"
#: gui/browser.cpp:75 gui/chooser.cpp:46 gui/KeysDialog.cpp:43
#: gui/launcher.cpp:351 gui/massadd.cpp:95 gui/options.cpp:1239
+#: gui/recorderdialog.cpp:70 gui/recorderdialog.cpp:156
#: gui/saveload-dialog.cpp:216 gui/saveload-dialog.cpp:276
-#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:922
+#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:931
#: gui/themebrowser.cpp:55 gui/fluidsynth-dialog.cpp:152
-#: engines/engine.cpp:452 backends/platform/wii/options.cpp:48
+#: engines/engine.cpp:483 backends/platform/wii/options.cpp:48
#: backends/events/default/default-events.cpp:196
#: backends/events/default/default-events.cpp:218
#: engines/drascula/saveload.cpp:49 engines/parallaction/saveload.cpp:274
@@ -71,9 +72,9 @@ msgid "Choose"
msgstr "Velg"
#: gui/gui-manager.cpp:117 backends/keymapper/remap-dialog.cpp:53
-#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
-#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
-#: engines/scumm/help.cpp:209
+#: engines/scumm/help.cpp:126 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:192
+#: engines/scumm/help.cpp:210
msgid "Close"
msgstr "Lukk"
@@ -89,7 +90,7 @@ msgstr "Vis tastatur"
msgid "Remap keys"
msgstr "Omkoble taster"
-#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:86
+#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:87
msgid "Toggle fullscreen"
msgstr "Veksle fullskjerm"
@@ -103,13 +104,13 @@ msgstr "Koble"
#: gui/KeysDialog.cpp:42 gui/launcher.cpp:352 gui/launcher.cpp:1048
#: gui/launcher.cpp:1052 gui/massadd.cpp:92 gui/options.cpp:1240
-#: gui/saveload-dialog.cpp:923 gui/fluidsynth-dialog.cpp:153
-#: engines/engine.cpp:371 engines/engine.cpp:382
+#: gui/saveload-dialog.cpp:932 gui/fluidsynth-dialog.cpp:153
+#: engines/engine.cpp:402 engines/engine.cpp:413
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
#: engines/agos/animation.cpp:558 engines/drascula/saveload.cpp:49
-#: engines/groovie/script.cpp:399 engines/parallaction/saveload.cpp:274
-#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1825
+#: engines/groovie/script.cpp:408 engines/parallaction/saveload.cpp:274
+#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1834
#: engines/scumm/players/player_v3m.cpp:130
#: engines/scumm/players/player_v5m.cpp:108 engines/sky/compact.cpp:131
#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:524
@@ -479,7 +480,7 @@ msgstr ""
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -489,7 +490,7 @@ msgstr "Ja"
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -526,6 +527,14 @@ msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr ""
"ScummVM kunne ikke finne noen motor som kunne kjøre det valgte spillet!"
+#: gui/launcher.cpp:1159
+msgid "Mass Add..."
+msgstr "Legg til flere..."
+
+#: gui/launcher.cpp:1161
+msgid "Record..."
+msgstr ""
+
#: gui/massadd.cpp:79 gui/massadd.cpp:82
msgid "... progress ..."
msgstr "... fremdrift ..."
@@ -626,7 +635,7 @@ msgid "Special dithering modes supported by some games"
msgstr "Spesiel dithering-modus støttet av enkelte spill"
#: gui/options.cpp:760
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2249
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2298
msgid "Fullscreen mode"
msgstr "Fullskjermsmodus"
@@ -938,6 +947,43 @@ msgstr ""
"Temaet du valgte støtter ikke det aktive språket. Hvis du vil bruke dette "
"temaet, må du bytte til et annet språk først."
+#: gui/recorderdialog.cpp:64
+msgid "Recorder or Playback Gameplay"
+msgstr ""
+
+#: gui/recorderdialog.cpp:69 gui/recorderdialog.cpp:156
+#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
+msgid "Delete"
+msgstr "Slett"
+
+#: gui/recorderdialog.cpp:71
+msgid "Record"
+msgstr ""
+
+#: gui/recorderdialog.cpp:72
+#, fuzzy
+msgid "Playback"
+msgstr "Spill"
+
+#: gui/recorderdialog.cpp:74
+msgid "Edit"
+msgstr ""
+
+#: gui/recorderdialog.cpp:86 gui/recorderdialog.cpp:243
+#: gui/recorderdialog.cpp:253
+msgid "Author: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:87 gui/recorderdialog.cpp:244
+#: gui/recorderdialog.cpp:254
+msgid "Notes: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:155
+#, fuzzy
+msgid "Do you really want to delete this record?"
+msgstr "Vil du virkelig slette dette lagrede spillet?"
+
#: gui/saveload-dialog.cpp:167
msgid "List view"
msgstr "Listevisning"
@@ -958,23 +1004,19 @@ msgstr "Ingen tid lagret"
msgid "No playtime saved"
msgstr "Ingen spilltid lagret"
-#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
-msgid "Delete"
-msgstr "Slett"
-
#: gui/saveload-dialog.cpp:275
msgid "Do you really want to delete this saved game?"
msgstr "Vil du virkelig slette dette lagrede spillet?"
-#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:875
+#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:884
msgid "Date: "
msgstr "Dato: "
-#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:881
+#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:890
msgid "Time: "
msgstr "Tid: "
-#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:889
+#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:898
msgid "Playtime: "
msgstr "Spilltid: "
@@ -990,19 +1032,19 @@ msgstr "Neste"
msgid "Prev"
msgstr "Forrige"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "New Save"
msgstr "Nytt lagret spill"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "Create a new save game"
msgstr "Opprett ett nytt lagret spill."
-#: gui/saveload-dialog.cpp:868
+#: gui/saveload-dialog.cpp:877
msgid "Name: "
msgstr "Navn:"
-#: gui/saveload-dialog.cpp:940
+#: gui/saveload-dialog.cpp:949
#, c-format
msgid "Enter a description for slot %d:"
msgstr "Gi en beskrivelse for posisjon %d:"
@@ -1154,7 +1196,7 @@ msgstr "Hopp over linje"
msgid "Error running game:"
msgstr "Problem ved kjøring av spill:"
-#: base/main.cpp:536
+#: base/main.cpp:554
msgid "Could not find any engine capable of running the selected game"
msgstr "Kunne ikke finne noen motor som kunne kjøre det valgte spillet"
@@ -1272,7 +1314,7 @@ msgstr "~T~ilbake til oppstarter"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:803
#: engines/cruise/menu.cpp:212 engines/drascula/saveload.cpp:336
#: engines/dreamweb/saveload.cpp:261 engines/neverhood/menumodule.cpp:873
-#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:758
+#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:759
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save game:"
msgstr "Lagret spill:"
@@ -1285,7 +1327,7 @@ msgstr "Lagret spill:"
#: engines/agi/saveload.cpp:803 engines/cruise/menu.cpp:212
#: engines/drascula/saveload.cpp:336 engines/dreamweb/saveload.cpp:261
#: engines/neverhood/menumodule.cpp:873 engines/pegasus/pegasus.cpp:377
-#: engines/sci/engine/kfile.cpp:758 engines/scumm/dialogs.cpp:188
+#: engines/sci/engine/kfile.cpp:759 engines/scumm/dialogs.cpp:188
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save"
msgstr "Lagre"
@@ -1323,23 +1365,23 @@ msgstr "~A~vbryt"
msgid "~K~eys"
msgstr "~T~aster"
-#: engines/engine.cpp:245
+#: engines/engine.cpp:276
msgid "Could not initialize color format."
msgstr "Kunne ikke initalisere fargeformat."
-#: engines/engine.cpp:253
+#: engines/engine.cpp:284
msgid "Could not switch to video mode: '"
msgstr "Kunne ikke veksle til videomodus: '"
-#: engines/engine.cpp:262
+#: engines/engine.cpp:293
msgid "Could not apply aspect ratio setting."
msgstr "Kunne ikke aktivere aspektrate-innstilling."
-#: engines/engine.cpp:267
+#: engines/engine.cpp:298
msgid "Could not apply fullscreen setting."
msgstr "Kunne ikke aktivere fullskjermsinnstilling."
-#: engines/engine.cpp:367
+#: engines/engine.cpp:398
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1353,7 +1395,7 @@ msgstr ""
"datafilene til harddisken din istedet.\n"
"Se README-filen for detaljer."
-#: engines/engine.cpp:378
+#: engines/engine.cpp:409
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1367,7 +1409,7 @@ msgstr ""
"kunne høre på spillets musikk.\n"
"Se README-filen for detaljer."
-#: engines/engine.cpp:436
+#: engines/engine.cpp:467
#, c-format
msgid ""
"Gamestate load failed (%s)! Please consult the README for basic information, "
@@ -1376,7 +1418,7 @@ msgstr ""
"Klarte ikke laste spill (%s)! Vennligst se i README-fila for grunnleggende "
"informasjon og instruksjoner om hvordan du kan få mer hjelp."
-#: engines/engine.cpp:449
+#: engines/engine.cpp:480
msgid ""
"WARNING: The game you are about to start is not yet fully supported by "
"ScummVM. As such, it is likely to be unstable, and any saves you make might "
@@ -1386,7 +1428,7 @@ msgstr ""
"Derfor er det sannsynlig at det vil være ustabilt, og det er ikke sikkert at "
"lagrede spill vil fortsette å fungere i fremtidige versjoner av ScummVM."
-#: engines/engine.cpp:452
+#: engines/engine.cpp:483
msgid "Start anyway"
msgstr "Start allikevel"
@@ -1596,11 +1638,11 @@ msgstr "Touchpad-modus aktivert."
msgid "Touchpad mode disabled."
msgstr "Touchpad-modus deaktivert."
-#: backends/platform/maemo/maemo.cpp:209
+#: backends/platform/maemo/maemo.cpp:208
msgid "Click Mode"
msgstr "Klikkmodus"
-#: backends/platform/maemo/maemo.cpp:215
+#: backends/platform/maemo/maemo.cpp:214
#: backends/platform/symbian/src/SymbianActions.cpp:42
#: backends/platform/wince/CEActionsPocket.cpp:60
#: backends/platform/wince/CEActionsSmartphone.cpp:43
@@ -1608,11 +1650,11 @@ msgstr "Klikkmodus"
msgid "Left Click"
msgstr "Venstreklikk"
-#: backends/platform/maemo/maemo.cpp:218
+#: backends/platform/maemo/maemo.cpp:217
msgid "Middle Click"
msgstr "Midtklikk"
-#: backends/platform/maemo/maemo.cpp:221
+#: backends/platform/maemo/maemo.cpp:220
#: backends/platform/symbian/src/SymbianActions.cpp:43
#: backends/platform/wince/CEActionsSmartphone.cpp:44
#: backends/platform/tizen/form.cpp:267
@@ -1649,19 +1691,19 @@ msgctxt "lowres"
msgid "Normal (no scaling)"
msgstr "Normal (ingen skalering)"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2148
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2197
msgid "Enabled aspect ratio correction"
msgstr "Aspekt-rate korrigering aktivert"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2154
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2203
msgid "Disabled aspect ratio correction"
msgstr "Aspekt-rate korrigering deaktivert"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2209
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2258
msgid "Active graphics filter:"
msgstr "Aktivt grafikkfilter:"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2251
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2300
msgid "Windowed mode"
msgstr "Vindusmodus"
@@ -1720,8 +1762,8 @@ msgstr "Rask modus"
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
#: backends/events/default/default-events.cpp:218
-#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:82
-#: engines/scumm/help.cpp:84
+#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:83
+#: engines/scumm/help.cpp:85
msgid "Quit"
msgstr "Avslutt"
@@ -1741,7 +1783,7 @@ msgstr "Virtuelt tastatur"
msgid "Key mapper"
msgstr "Tastkobler"
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
msgid "Do you want to quit ?"
msgstr "Vil du avslutte?"
@@ -2077,33 +2119,54 @@ msgstr "Klikking aktivert"
msgid "Clicking Disabled"
msgstr "Klikking deaktivert"
-#: engines/agi/detection.cpp:142 engines/drascula/detection.cpp:302
+#: engines/agi/detection.cpp:147 engines/drascula/detection.cpp:302
#: engines/dreamweb/detection.cpp:47 engines/neverhood/detection.cpp:160
#: engines/sci/detection.cpp:394 engines/toltecs/detection.cpp:200
-#: engines/zvision/detection.cpp:103
+#: engines/zvision/detection.cpp:246
msgid "Use original save/load screens"
msgstr "Bruk originale lagre/laste-skjermer"
-#: engines/agi/detection.cpp:143 engines/drascula/detection.cpp:303
+#: engines/agi/detection.cpp:148 engines/drascula/detection.cpp:303
#: engines/dreamweb/detection.cpp:48 engines/neverhood/detection.cpp:161
#: engines/sci/detection.cpp:395 engines/toltecs/detection.cpp:201
-#: engines/zvision/detection.cpp:104
+#: engines/zvision/detection.cpp:247
msgid "Use the original save/load screens, instead of the ScummVM ones"
msgstr "Bruk de originale lagre/laste-skjermene, istedenfor ScummVM-variantene"
+#: engines/agi/detection.cpp:157
+#, fuzzy
+msgid "Use an alternative palette"
+msgstr "Bruk en alternativ intro (Kun for CD-versjon)"
+
+#: engines/agi/detection.cpp:158
+msgid ""
+"Use an alternative palette, common for all Amiga games. This was the old "
+"behavior"
+msgstr ""
+
+#: engines/agi/detection.cpp:167
+#, fuzzy
+msgid "Mouse support"
+msgstr "Hopp over"
+
+#: engines/agi/detection.cpp:168
+msgid ""
+"Enables mouse support. Allows to use mouse for movement and in game menus."
+msgstr ""
+
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore game:"
msgstr "Gjennopprett spill:"
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore"
msgstr "Gjenopprett"
-#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2368
+#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2377
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -2114,7 +2177,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2361
+#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2370
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -2125,7 +2188,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2379
+#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2388
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -2141,12 +2204,12 @@ msgstr ""
msgid "Cutscene file '%s' not found!"
msgstr "Fant ikke cutscenefil '%s'!"
-#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:81
+#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:101
#, fuzzy
msgid "Color Blind Mode"
msgstr "Klikkmodus"
-#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:82
+#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:102
msgid "Enable Color Blind Mode by default"
msgstr ""
@@ -2198,7 +2261,7 @@ msgstr "Rask filmhastighet"
msgid "Play movies at an increased speed"
msgstr "Spill filmer med økt hastighet"
-#: engines/groovie/script.cpp:399
+#: engines/groovie/script.cpp:408
msgid "Failed to save game"
msgstr "Klarte ikke å lagre spill."
@@ -2497,12 +2560,12 @@ msgid "Use an alternative game intro (CD version only)"
msgstr "Bruk en alternativ intro (Kun for CD-versjon)"
#: engines/sci/detection.cpp:374
-msgid "EGA undithering"
-msgstr "EGA av-dithering"
+msgid "Skip EGA dithering pass (full color backgrounds)"
+msgstr ""
#: engines/sci/detection.cpp:375
-msgid "Enable undithering in EGA games"
-msgstr "Aktiver av-dithering i EGA-spill"
+msgid "Skip dithering pass in EGA games, graphics are shown with full colors"
+msgstr ""
#: engines/sci/detection.cpp:384
msgid "Prefer digital sound effects"
@@ -2574,12 +2637,14 @@ msgstr "Spill pauset. Trykk på MELLOMROMstasten for å fortsette."
#. "Moechten Sie wirklich neu starten? (J/N)J"
#. Will react to J as 'Yes'
#: engines/scumm/dialogs.cpp:183
-msgid "Are you sure you want to restart? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to restart? (Y/N)Y"
msgstr "Er du sikker på at du vil avslutte? (Y/N)"
#. I18N: you may specify 'Yes' symbol at the end of the line. See previous comment
#: engines/scumm/dialogs.cpp:185
-msgid "Are you sure you want to quit? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to quit? (Y/N)Y"
msgstr "Er du sikker på at du vil avslutte? (Y/N)"
#: engines/scumm/dialogs.cpp:190
@@ -2667,516 +2732,540 @@ msgstr "Trening"
msgid "Expert"
msgstr "Ekspert"
-#: engines/scumm/help.cpp:73
+#: engines/scumm/help.cpp:74
msgid "Common keyboard commands:"
msgstr "Vanlige tastaturkommandoer:"
-#: engines/scumm/help.cpp:74
+#: engines/scumm/help.cpp:75
msgid "Save / Load dialog"
msgstr "Lagre- / åpne-dialog"
-#: engines/scumm/help.cpp:76
+#: engines/scumm/help.cpp:77
msgid "Skip line of text"
msgstr "Hopp over tekstlinje"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Esc"
msgstr "Esc"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Skip cutscene"
msgstr "Hopp over cutscene"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Space"
msgstr "Space"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Pause game"
msgstr "Pause spill"
-#: engines/scumm/help.cpp:79 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:95 engines/scumm/help.cpp:96
-#: engines/scumm/help.cpp:97 engines/scumm/help.cpp:98
-#: engines/scumm/help.cpp:99 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:96 engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98 engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Ctrl"
msgstr "Ctrl"
-#: engines/scumm/help.cpp:79
+#: engines/scumm/help.cpp:80
msgid "Load game state 1-10"
msgstr "Åpne spilltilstand 1-10"
-#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:81 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Alt"
msgstr "Alt"
-#: engines/scumm/help.cpp:80
+#: engines/scumm/help.cpp:81
msgid "Save game state 1-10"
msgstr "Lagre spilltilstand 1-10"
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:90
msgid "Enter"
msgstr "Enter"
-#: engines/scumm/help.cpp:87
+#: engines/scumm/help.cpp:88
msgid "Music volume up / down"
msgstr "Musikkvolum opp/ned"
-#: engines/scumm/help.cpp:88
+#: engines/scumm/help.cpp:89
msgid "Text speed slower / faster"
msgstr "Tekstfart saktere/raskere"
-#: engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:90
msgid "Simulate left mouse button"
msgstr "Simuler venstre mustast"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Tab"
msgstr "Tab"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Simulate right mouse button"
msgstr "Simuler høyre mustast"
-#: engines/scumm/help.cpp:93
+#: engines/scumm/help.cpp:94
msgid "Special keyboard commands:"
msgstr "Spesielle tastaturkommandoer:"
-#: engines/scumm/help.cpp:94
+#: engines/scumm/help.cpp:95
msgid "Show / Hide console"
msgstr "Vis / Skjul konsollen"
-#: engines/scumm/help.cpp:95
+#: engines/scumm/help.cpp:96
msgid "Start the debugger"
msgstr "Start debuggeren"
-#: engines/scumm/help.cpp:96
+#: engines/scumm/help.cpp:97
msgid "Show memory consumption"
msgstr "Vis minneforbruk"
-#: engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98
msgid "Run in fast mode (*)"
msgstr "Kjør i rask modus (*)"
-#: engines/scumm/help.cpp:98
+#: engines/scumm/help.cpp:99
msgid "Run in really fast mode (*)"
msgstr "Kjør i virkelig rask modus (*)"
-#: engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100
msgid "Toggle mouse capture"
msgstr "Veksle muslåsing"
-#: engines/scumm/help.cpp:100
+#: engines/scumm/help.cpp:101
msgid "Switch between graphics filters"
msgstr "Bytt grafikkfiltre"
-#: engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102
msgid "Increase / Decrease scale factor"
msgstr "Øk / Minsk skaleringsfaktor"
-#: engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:103
msgid "Toggle aspect-ratio correction"
msgstr "Veksle aspekt-rate korrigering"
-#: engines/scumm/help.cpp:107
+#: engines/scumm/help.cpp:108
msgid "* Note that using ctrl-f and"
msgstr "* Merk at å bruke ctrl-f og"
-#: engines/scumm/help.cpp:108
+#: engines/scumm/help.cpp:109
msgid " ctrl-g are not recommended"
msgstr " ctrl-g anbefales ikke, siden"
-#: engines/scumm/help.cpp:109
+#: engines/scumm/help.cpp:110
msgid " since they may cause crashes"
msgstr " de kan forårsake kræsj, eller"
-#: engines/scumm/help.cpp:110
+#: engines/scumm/help.cpp:111
msgid " or incorrect game behavior."
msgstr " eller feilaktig spilloppførsel."
-#: engines/scumm/help.cpp:114
+#: engines/scumm/help.cpp:115
msgid "Spinning drafts on the keyboard:"
msgstr "Spinne drafts på tastaturet:"
-#: engines/scumm/help.cpp:116
+#: engines/scumm/help.cpp:117
msgid "Main game controls:"
msgstr "Hovedkontroller for spill:"
-#: engines/scumm/help.cpp:121 engines/scumm/help.cpp:136
-#: engines/scumm/help.cpp:161
+#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
+#: engines/scumm/help.cpp:162
msgid "Push"
msgstr "Dytt"
-#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
-#: engines/scumm/help.cpp:162
+#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
+#: engines/scumm/help.cpp:163
msgid "Pull"
msgstr "Dra"
-#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
-#: engines/scumm/help.cpp:163 engines/scumm/help.cpp:197
-#: engines/scumm/help.cpp:207
+#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
+#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:198
+#: engines/scumm/help.cpp:208
msgid "Give"
msgstr "Gi"
-#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
-#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:190
-#: engines/scumm/help.cpp:208
+#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
+#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
+#: engines/scumm/help.cpp:209
msgid "Open"
msgstr "Åpne"
-#: engines/scumm/help.cpp:126
+#: engines/scumm/help.cpp:127
msgid "Go to"
msgstr "Gå til"
-#: engines/scumm/help.cpp:127
+#: engines/scumm/help.cpp:128
msgid "Get"
msgstr "Få"
-#: engines/scumm/help.cpp:128 engines/scumm/help.cpp:152
-#: engines/scumm/help.cpp:170 engines/scumm/help.cpp:198
-#: engines/scumm/help.cpp:213 engines/scumm/help.cpp:224
-#: engines/scumm/help.cpp:250
+#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:153
+#: engines/scumm/help.cpp:171 engines/scumm/help.cpp:199
+#: engines/scumm/help.cpp:214 engines/scumm/help.cpp:225
+#: engines/scumm/help.cpp:251
msgid "Use"
msgstr "Bruk"
-#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:142
msgid "Read"
msgstr "Les"
-#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:147
+#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:148
msgid "New kid"
msgstr "Bytt unge"
-#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:153
-#: engines/scumm/help.cpp:171
+#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
+#: engines/scumm/help.cpp:172
msgid "Turn on"
msgstr "Slå på"
-#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
-#: engines/scumm/help.cpp:172
+#: engines/scumm/help.cpp:133 engines/scumm/help.cpp:155
+#: engines/scumm/help.cpp:173
msgid "Turn off"
msgstr "Slå av"
-#: engines/scumm/help.cpp:142 engines/scumm/help.cpp:167
-#: engines/scumm/help.cpp:194
+#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
+#: engines/scumm/help.cpp:195
msgid "Walk to"
msgstr "Gå til"
-#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
-#: engines/scumm/help.cpp:195 engines/scumm/help.cpp:210
-#: engines/scumm/help.cpp:227
+#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:228
msgid "Pick up"
msgstr "Plukk opp"
-#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:145 engines/scumm/help.cpp:170
msgid "What is"
msgstr "Hva er"
-#: engines/scumm/help.cpp:146
+#: engines/scumm/help.cpp:147
msgid "Unlock"
msgstr "Lås opp"
-#: engines/scumm/help.cpp:149
+#: engines/scumm/help.cpp:150
msgid "Put on"
msgstr "Ta på tøy"
-#: engines/scumm/help.cpp:150
+#: engines/scumm/help.cpp:151
msgid "Take off"
msgstr "Ta av tøy"
-#: engines/scumm/help.cpp:156
+#: engines/scumm/help.cpp:157
msgid "Fix"
msgstr "Fiks"
-#: engines/scumm/help.cpp:158
+#: engines/scumm/help.cpp:159
msgid "Switch"
msgstr "Bytt"
-#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:228
+#: engines/scumm/help.cpp:167 engines/scumm/help.cpp:229
msgid "Look"
msgstr "Kikk"
-#: engines/scumm/help.cpp:173 engines/scumm/help.cpp:223
+#: engines/scumm/help.cpp:174 engines/scumm/help.cpp:224
msgid "Talk"
msgstr "Snakk"
-#: engines/scumm/help.cpp:174
+#: engines/scumm/help.cpp:175
msgid "Travel"
msgstr "Reis"
-#: engines/scumm/help.cpp:175
+#: engines/scumm/help.cpp:176
msgid "To Henry / To Indy"
msgstr "Til Henry / Til Indy"
#. I18N: These are different musical notes
-#: engines/scumm/help.cpp:179
+#: engines/scumm/help.cpp:180
msgid "play C minor on distaff"
msgstr "Spill C moll på distaffen"
-#: engines/scumm/help.cpp:180
+#: engines/scumm/help.cpp:181
msgid "play D on distaff"
msgstr "spill D på distaffen"
-#: engines/scumm/help.cpp:181
+#: engines/scumm/help.cpp:182
msgid "play E on distaff"
msgstr "spill E på distaffen"
-#: engines/scumm/help.cpp:182
+#: engines/scumm/help.cpp:183
msgid "play F on distaff"
msgstr "spill F på distaffen"
-#: engines/scumm/help.cpp:183
+#: engines/scumm/help.cpp:184
msgid "play G on distaff"
msgstr "spill G på distaffen"
-#: engines/scumm/help.cpp:184
+#: engines/scumm/help.cpp:185
msgid "play A on distaff"
msgstr "spill A på distaffen"
-#: engines/scumm/help.cpp:185
+#: engines/scumm/help.cpp:186
msgid "play B on distaff"
msgstr "spill H på distaffen"
-#: engines/scumm/help.cpp:186
+#: engines/scumm/help.cpp:187
msgid "play C major on distaff"
msgstr "spill C dur på distaffen"
-#: engines/scumm/help.cpp:192 engines/scumm/help.cpp:214
+#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
msgid "puSh"
msgstr "Dytt"
-#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
+#: engines/scumm/help.cpp:194 engines/scumm/help.cpp:216
msgid "pull (Yank)"
msgstr "Dra"
-#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:212
-#: engines/scumm/help.cpp:248
+#: engines/scumm/help.cpp:197 engines/scumm/help.cpp:213
+#: engines/scumm/help.cpp:249
msgid "Talk to"
msgstr "Snakk til"
-#: engines/scumm/help.cpp:199 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:200 engines/scumm/help.cpp:212
msgid "Look at"
msgstr "Se på"
-#: engines/scumm/help.cpp:200
+#: engines/scumm/help.cpp:201
msgid "turn oN"
msgstr "Slå på"
-#: engines/scumm/help.cpp:201
+#: engines/scumm/help.cpp:202
msgid "turn oFf"
msgstr "Slå av"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "KeyUp"
msgstr "Ned-tast"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "Highlight prev dialogue"
msgstr "Merk forrige dialog"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "KeyDown"
msgstr "Opp-tast"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "Highlight next dialogue"
msgstr "Merk neste dialog"
-#: engines/scumm/help.cpp:222
+#: engines/scumm/help.cpp:223
msgid "Walk"
msgstr "Gå"
-#: engines/scumm/help.cpp:225 engines/scumm/help.cpp:234
-#: engines/scumm/help.cpp:241 engines/scumm/help.cpp:249
+#: engines/scumm/help.cpp:226 engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:242 engines/scumm/help.cpp:250
msgid "Inventory"
msgstr "Inventar"
-#: engines/scumm/help.cpp:226
+#: engines/scumm/help.cpp:227
msgid "Object"
msgstr "Gjenstand"
-#: engines/scumm/help.cpp:229
+#: engines/scumm/help.cpp:230
msgid "Black and White / Color"
msgstr "Svart/Hvitt / Farger"
-#: engines/scumm/help.cpp:232
+#: engines/scumm/help.cpp:233
msgid "Eyes"
msgstr "Øyne"
-#: engines/scumm/help.cpp:233
+#: engines/scumm/help.cpp:234
msgid "Tongue"
msgstr "Tunge"
-#: engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:236
msgid "Punch"
msgstr "Slå"
-#: engines/scumm/help.cpp:236
+#: engines/scumm/help.cpp:237
msgid "Kick"
msgstr "Spark"
-#: engines/scumm/help.cpp:239 engines/scumm/help.cpp:247
+#: engines/scumm/help.cpp:240 engines/scumm/help.cpp:248
msgid "Examine"
msgstr "Undersøk"
-#: engines/scumm/help.cpp:240
+#: engines/scumm/help.cpp:241
msgid "Regular cursor"
msgstr "Vanlig muspeker"
#. I18N: Comm is a communication device
-#: engines/scumm/help.cpp:243
+#: engines/scumm/help.cpp:244
msgid "Comm"
msgstr "Comm"
-#: engines/scumm/help.cpp:246
+#: engines/scumm/help.cpp:247
msgid "Save / Load / Options"
msgstr "Lagre / Åpne / Valg"
-#: engines/scumm/help.cpp:255
+#: engines/scumm/help.cpp:256
msgid "Other game controls:"
msgstr "Andre spillkontroller"
-#: engines/scumm/help.cpp:257 engines/scumm/help.cpp:267
+#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:268
msgid "Inventory:"
msgstr "Inventar:"
-#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:274
+#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
msgid "Scroll list up"
msgstr "Bla liste opp"
-#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
+#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:276
msgid "Scroll list down"
msgstr "Bla liste ned"
-#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:268
+#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:269
msgid "Upper left item"
msgstr "Øvre venstre gjenstand"
-#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:270
+#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
msgid "Lower left item"
msgstr "Nedre venstre gjenstand"
-#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
+#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:272
msgid "Upper right item"
msgstr "Øvre høyre gjenstand"
-#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:273
+#: engines/scumm/help.cpp:264 engines/scumm/help.cpp:274
msgid "Lower right item"
msgstr "Nedre høyre gjenstand"
-#: engines/scumm/help.cpp:269
+#: engines/scumm/help.cpp:270
msgid "Middle left item"
msgstr "Midtre venstre gjenstand"
-#: engines/scumm/help.cpp:272
+#: engines/scumm/help.cpp:273
msgid "Middle right item"
msgstr "Midtre høyre gjenstand"
-#: engines/scumm/help.cpp:279 engines/scumm/help.cpp:284
+#: engines/scumm/help.cpp:280 engines/scumm/help.cpp:285
msgid "Switching characters:"
msgstr "Bytte av karakterer:"
-#: engines/scumm/help.cpp:281
+#: engines/scumm/help.cpp:282
msgid "Second kid"
msgstr "Andre unge"
-#: engines/scumm/help.cpp:282
+#: engines/scumm/help.cpp:283
msgid "Third kid"
msgstr "Tredje unge"
-#: engines/scumm/help.cpp:294
+#: engines/scumm/help.cpp:292
+msgid "Toggle Inventory/IQ Points display"
+msgstr ""
+
+#: engines/scumm/help.cpp:293
+msgid "Toggle Keyboard/Mouse Fighting (*)"
+msgstr ""
+
+#: engines/scumm/help.cpp:295
+msgid "* Keyboard Fighting is always on,"
+msgstr ""
+
+#: engines/scumm/help.cpp:296
+msgid " so despite the in-game message this"
+msgstr ""
+
+#: engines/scumm/help.cpp:297
+msgid " actually toggles Mouse Fighting Off/On"
+msgstr ""
+
+#: engines/scumm/help.cpp:304
msgid "Fighting controls (numpad):"
msgstr "Kampkontroller (talltastatur)"
-#: engines/scumm/help.cpp:295 engines/scumm/help.cpp:296
-#: engines/scumm/help.cpp:297
+#: engines/scumm/help.cpp:305 engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:307
msgid "Step back"
msgstr "Bakoversteg"
-#: engines/scumm/help.cpp:298
+#: engines/scumm/help.cpp:308
msgid "Block high"
msgstr "Høy blokk"
-#: engines/scumm/help.cpp:299
+#: engines/scumm/help.cpp:309
msgid "Block middle"
msgstr "Mid-blokk"
-#: engines/scumm/help.cpp:300
+#: engines/scumm/help.cpp:310
msgid "Block low"
msgstr "Lav blokk"
-#: engines/scumm/help.cpp:301
+#: engines/scumm/help.cpp:311
msgid "Punch high"
msgstr "Slå høyt"
-#: engines/scumm/help.cpp:302
+#: engines/scumm/help.cpp:312
msgid "Punch middle"
msgstr "Slå midje"
-#: engines/scumm/help.cpp:303
+#: engines/scumm/help.cpp:313
msgid "Punch low"
msgstr "Slå lavt"
-#: engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:315
+msgid "Sucker punch"
+msgstr ""
+
+#: engines/scumm/help.cpp:318
msgid "These are for Indy on left."
msgstr "Gjelder når Indy er til venstre."
-#: engines/scumm/help.cpp:307
+#: engines/scumm/help.cpp:319
msgid "When Indy is on the right,"
msgstr "Når Indy er til høyre,"
-#: engines/scumm/help.cpp:308
+#: engines/scumm/help.cpp:320
msgid "7, 4, and 1 are switched with"
msgstr "Byttes 7, 4, og 1 med"
-#: engines/scumm/help.cpp:309
+#: engines/scumm/help.cpp:321
msgid "9, 6, and 3, respectively."
msgstr "henholdsvis 9, 6, og 3."
-#: engines/scumm/help.cpp:316
+#: engines/scumm/help.cpp:328
msgid "Biplane controls (numpad):"
msgstr "Flykontroller (talltastatur)"
-#: engines/scumm/help.cpp:317
+#: engines/scumm/help.cpp:329
msgid "Fly to upper left"
msgstr "Fly til øvre venstre"
-#: engines/scumm/help.cpp:318
+#: engines/scumm/help.cpp:330
msgid "Fly to left"
msgstr "Fly til venstre"
-#: engines/scumm/help.cpp:319
+#: engines/scumm/help.cpp:331
msgid "Fly to lower left"
msgstr "Fly til nedre venstre"
-#: engines/scumm/help.cpp:320
+#: engines/scumm/help.cpp:332
msgid "Fly upwards"
msgstr "Fly oppover"
-#: engines/scumm/help.cpp:321
+#: engines/scumm/help.cpp:333
msgid "Fly straight"
msgstr "Fly rett"
-#: engines/scumm/help.cpp:322
+#: engines/scumm/help.cpp:334
msgid "Fly down"
msgstr "Fly ned"
-#: engines/scumm/help.cpp:323
+#: engines/scumm/help.cpp:335
msgid "Fly to upper right"
msgstr "Fly til øvre høyre"
-#: engines/scumm/help.cpp:324
+#: engines/scumm/help.cpp:336
msgid "Fly to right"
msgstr "Fly til høyre"
-#: engines/scumm/help.cpp:325
+#: engines/scumm/help.cpp:337
msgid "Fly to lower right"
msgstr "Fly til nedre høyre"
-#: engines/scumm/scumm.cpp:1823
+#: engines/scumm/scumm.cpp:1832
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
@@ -3185,11 +3274,12 @@ msgstr ""
"Ekte MIDI-støtte krever «Roland Upgrade» fra LucasArts,\n"
"men %s mangler. Bruker AdLib istedet."
-#: engines/scumm/scumm.cpp:2594
+#: engines/scumm/scumm.cpp:2644
+#, fuzzy
msgid ""
-"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
-"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
-"directory inside the Tentacle game directory."
+"Usually, Maniac Mansion would start now. But for that to work, the game "
+"files for Maniac Mansion have to be in the 'Maniac' directory inside the "
+"Tentacle game directory, and the game has to be added to ScummVM."
msgstr ""
"Vanligvis, ville Maniac Mansion ha startet nå. Men ScummVM støtter ikke det "
"ennå. Så, for å spille Maniac Mansion, gå til 'Legg til spill' i ScummVM-"
@@ -3323,6 +3413,48 @@ msgstr ""
msgid "Show the current number of frames per second in the upper left corner"
msgstr ""
+#: engines/zvision/detection.cpp:256
+msgid "Double FPS"
+msgstr ""
+
+#: engines/zvision/detection.cpp:257
+msgid "Increase game FPS from 30 to 60"
+msgstr ""
+
+#: engines/zvision/detection.cpp:266
+#, fuzzy
+msgid "Enable Venus"
+msgstr "Aktiver helium-modus"
+
+#: engines/zvision/detection.cpp:267
+msgid "Enable the Venus help system"
+msgstr ""
+
+#: engines/zvision/detection.cpp:276
+msgid "Disable animation while turning"
+msgstr ""
+
+#: engines/zvision/detection.cpp:277
+msgid "Disable animation while turning in panoramic mode"
+msgstr ""
+
+#: engines/zvision/detection.cpp:286
+msgid "Use the hires MPEG movies"
+msgstr ""
+
+#: engines/zvision/detection.cpp:287
+#, fuzzy
+msgid ""
+"Use the hires MPEG movies of the DVD version, instead of the lowres AVI ones"
+msgstr ""
+"Bruk det alternative settet med sølvmuspekere, istedenfor de normale gylne."
+
+#~ msgid "EGA undithering"
+#~ msgstr "EGA av-dithering"
+
+#~ msgid "Enable undithering in EGA games"
+#~ msgstr "Aktiver av-dithering i EGA-spill"
+
#~ msgid "MPEG-2 cutscenes found but ScummVM has been built without MPEG-2"
#~ msgstr "MPEG2-cutscener funnet men ScummVM er bygd uten MPEG2-støtte"
@@ -3330,9 +3462,6 @@ msgstr ""
#~ msgid "Mass Add..."
#~ msgstr "Legg til flere..."
-#~ msgid "Mass Add..."
-#~ msgstr "Legg til flere..."
-
#~ msgid ""
#~ "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
#~ msgstr "Slå av General MIDI-kobling for spill som har Roland MT-32-lydspor"
diff --git a/po/nl_NL.po b/po/nl_NL.po
index 3a9e6d8172..970ff6ce8b 100644
--- a/po/nl_NL.po
+++ b/po/nl_NL.po
@@ -1,5 +1,5 @@
# LANGUAGE translation for ScummVM.
-# Copyright (C) YEAR ScummVM Team
+# Copyright (C) 2014-2015 The ScummVM Team
# This file is distributed under the same license as the ScummVM package.
# FIRST AUTHOR scummvm@bencastricum.nl, 2014.
#
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.8.0git\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2014-11-25 20:41+0100\n"
+"POT-Creation-Date: 2015-06-30 20:57+0100\n"
"PO-Revision-Date: 2014-11-25 20:46+0100\n"
"Last-Translator: Ben Castricum <scummvm@bencastricum.nl>\n"
"Language-Team: Ben Castricum <scummvm@bencastricum.nl>\n"
@@ -55,10 +55,11 @@ msgstr "Ga omhoog"
#: gui/browser.cpp:75 gui/chooser.cpp:46 gui/KeysDialog.cpp:43
#: gui/launcher.cpp:351 gui/massadd.cpp:95 gui/options.cpp:1239
+#: gui/recorderdialog.cpp:70 gui/recorderdialog.cpp:156
#: gui/saveload-dialog.cpp:216 gui/saveload-dialog.cpp:276
-#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:922
+#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:931
#: gui/themebrowser.cpp:55 gui/fluidsynth-dialog.cpp:152
-#: engines/engine.cpp:452 backends/platform/wii/options.cpp:48
+#: engines/engine.cpp:483 backends/platform/wii/options.cpp:48
#: backends/events/default/default-events.cpp:196
#: backends/events/default/default-events.cpp:218
#: engines/drascula/saveload.cpp:49 engines/parallaction/saveload.cpp:274
@@ -71,9 +72,9 @@ msgid "Choose"
msgstr "Selecteer"
#: gui/gui-manager.cpp:117 backends/keymapper/remap-dialog.cpp:53
-#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
-#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
-#: engines/scumm/help.cpp:209
+#: engines/scumm/help.cpp:126 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:192
+#: engines/scumm/help.cpp:210
msgid "Close"
msgstr "Sluiten"
@@ -89,7 +90,7 @@ msgstr "Toon toetsenbord"
msgid "Remap keys"
msgstr "Toetsen opnieuw koppelen"
-#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:86
+#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:87
msgid "Toggle fullscreen"
msgstr "Volledig scherm in-/uitschakelen"
@@ -103,13 +104,13 @@ msgstr "Koppel"
#: gui/KeysDialog.cpp:42 gui/launcher.cpp:352 gui/launcher.cpp:1048
#: gui/launcher.cpp:1052 gui/massadd.cpp:92 gui/options.cpp:1240
-#: gui/saveload-dialog.cpp:923 gui/fluidsynth-dialog.cpp:153
-#: engines/engine.cpp:371 engines/engine.cpp:382
+#: gui/saveload-dialog.cpp:932 gui/fluidsynth-dialog.cpp:153
+#: engines/engine.cpp:402 engines/engine.cpp:413
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
#: engines/agos/animation.cpp:558 engines/drascula/saveload.cpp:49
#: engines/groovie/script.cpp:408 engines/parallaction/saveload.cpp:274
-#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1825
+#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1834
#: engines/scumm/players/player_v3m.cpp:130
#: engines/scumm/players/player_v5m.cpp:108 engines/sky/compact.cpp:131
#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:524
@@ -481,7 +482,7 @@ msgstr ""
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -491,7 +492,7 @@ msgstr "Ja"
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -529,6 +530,14 @@ msgstr ""
"ScummVM heeft geen engine gevonden die in staat was het geselecteerde spel "
"te spelen!"
+#: gui/launcher.cpp:1159
+msgid "Mass Add..."
+msgstr ""
+
+#: gui/launcher.cpp:1161
+msgid "Record..."
+msgstr ""
+
#: gui/massadd.cpp:79 gui/massadd.cpp:82
msgid "... progress ..."
msgstr "... voortgang ..."
@@ -631,7 +640,7 @@ msgid "Special dithering modes supported by some games"
msgstr "Speciale ditheringmodi die door sommige games ondersteund worden."
#: gui/options.cpp:760
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2249
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2298
msgid "Fullscreen mode"
msgstr "Volledig-scherm modus"
@@ -950,6 +959,43 @@ msgstr ""
"De thema die u heeft geselecteerd ondersteund uw gekozen taal niet. Als u "
"dit thema wilt gebruiken dient u eerst een andere taal te selecteren."
+#: gui/recorderdialog.cpp:64
+msgid "Recorder or Playback Gameplay"
+msgstr ""
+
+#: gui/recorderdialog.cpp:69 gui/recorderdialog.cpp:156
+#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
+msgid "Delete"
+msgstr "Verwijderen"
+
+#: gui/recorderdialog.cpp:71
+msgid "Record"
+msgstr ""
+
+#: gui/recorderdialog.cpp:72
+#, fuzzy
+msgid "Playback"
+msgstr "Spelen"
+
+#: gui/recorderdialog.cpp:74
+msgid "Edit"
+msgstr ""
+
+#: gui/recorderdialog.cpp:86 gui/recorderdialog.cpp:243
+#: gui/recorderdialog.cpp:253
+msgid "Author: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:87 gui/recorderdialog.cpp:244
+#: gui/recorderdialog.cpp:254
+msgid "Notes: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:155
+#, fuzzy
+msgid "Do you really want to delete this record?"
+msgstr "Wilt u dit opgeslagen spel echt verwijderen?"
+
#: gui/saveload-dialog.cpp:167
msgid "List view"
msgstr "Lijstopmaak"
@@ -970,23 +1016,19 @@ msgstr "Geen tijd opgeslagen"
msgid "No playtime saved"
msgstr "Geen speeltijd opgeslagen"
-#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
-msgid "Delete"
-msgstr "Verwijderen"
-
#: gui/saveload-dialog.cpp:275
msgid "Do you really want to delete this saved game?"
msgstr "Wilt u dit opgeslagen spel echt verwijderen?"
-#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:875
+#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:884
msgid "Date: "
msgstr "Datum: "
-#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:881
+#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:890
msgid "Time: "
msgstr "Tijd: "
-#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:889
+#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:898
msgid "Playtime: "
msgstr "Speeltijd: "
@@ -1002,19 +1044,19 @@ msgstr "Volgende"
msgid "Prev"
msgstr "Vorig"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "New Save"
msgstr "Nieuw spel opslaan"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "Create a new save game"
msgstr "Nieuw spel opslaan"
-#: gui/saveload-dialog.cpp:868
+#: gui/saveload-dialog.cpp:877
msgid "Name: "
msgstr "Naam: "
-#: gui/saveload-dialog.cpp:940
+#: gui/saveload-dialog.cpp:949
#, c-format
msgid "Enter a description for slot %d:"
msgstr "Geef een omschrijving voor slot %d:"
@@ -1167,7 +1209,7 @@ msgstr "Regel overslaan"
msgid "Error running game:"
msgstr "Fout tijdens het starten van spel:"
-#: base/main.cpp:536
+#: base/main.cpp:554
msgid "Could not find any engine capable of running the selected game"
msgstr ""
"Kon geen engine vinden die in staat was het geselecteerde spel te spelen"
@@ -1338,24 +1380,24 @@ msgstr "~A~nnuleer"
msgid "~K~eys"
msgstr "~T~oetsen"
-#: engines/engine.cpp:245
+#: engines/engine.cpp:276
msgid "Could not initialize color format."
msgstr "Kon kleurformaat niet initialiseren."
# can this be changed into "Could not switch to video mode '%s'"?
-#: engines/engine.cpp:253
+#: engines/engine.cpp:284
msgid "Could not switch to video mode: '"
msgstr "Kon niet schakelen naar videomodus: '"
-#: engines/engine.cpp:262
+#: engines/engine.cpp:293
msgid "Could not apply aspect ratio setting."
msgstr "Pixelverhoudinginstelling kon niet toegepast worden."
-#: engines/engine.cpp:267
+#: engines/engine.cpp:298
msgid "Could not apply fullscreen setting."
msgstr "Kon volledig-scherminstelling niet toepassen."
-#: engines/engine.cpp:367
+#: engines/engine.cpp:398
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1369,7 +1411,7 @@ msgstr ""
"bestanden naar uw harddisk te kopieren.\n"
"Voor details kijk in de README."
-#: engines/engine.cpp:378
+#: engines/engine.cpp:409
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1382,7 +1424,7 @@ msgstr ""
"CD rip programma om te kunnen luisteren naar\n"
"het spelmuziek. Voor details kijk in de README."
-#: engines/engine.cpp:436
+#: engines/engine.cpp:467
#, c-format
msgid ""
"Gamestate load failed (%s)! Please consult the README for basic information, "
@@ -1392,7 +1434,7 @@ msgstr ""
"voor basisinformatie, en voor instructies voor het verkrijgen van verdere "
"assistentie."
-#: engines/engine.cpp:449
+#: engines/engine.cpp:480
msgid ""
"WARNING: The game you are about to start is not yet fully supported by "
"ScummVM. As such, it is likely to be unstable, and any saves you make might "
@@ -1403,7 +1445,7 @@ msgstr ""
"instabiel is, en opgeslagen spellen zullen mogelijk niet werken in "
"toekomstige versies van ScummVM."
-#: engines/engine.cpp:452
+#: engines/engine.cpp:483
msgid "Start anyway"
msgstr "Evengoed starten"
@@ -1613,11 +1655,11 @@ msgstr "Touchpadmodus ingeschakeld."
msgid "Touchpad mode disabled."
msgstr "Touchpadmodus uitgeschakeld."
-#: backends/platform/maemo/maemo.cpp:209
+#: backends/platform/maemo/maemo.cpp:208
msgid "Click Mode"
msgstr "Klik Modus"
-#: backends/platform/maemo/maemo.cpp:215
+#: backends/platform/maemo/maemo.cpp:214
#: backends/platform/symbian/src/SymbianActions.cpp:42
#: backends/platform/wince/CEActionsPocket.cpp:60
#: backends/platform/wince/CEActionsSmartphone.cpp:43
@@ -1625,11 +1667,11 @@ msgstr "Klik Modus"
msgid "Left Click"
msgstr "Linker Klik"
-#: backends/platform/maemo/maemo.cpp:218
+#: backends/platform/maemo/maemo.cpp:217
msgid "Middle Click"
msgstr "Middelste Klik"
-#: backends/platform/maemo/maemo.cpp:221
+#: backends/platform/maemo/maemo.cpp:220
#: backends/platform/symbian/src/SymbianActions.cpp:43
#: backends/platform/wince/CEActionsSmartphone.cpp:44
#: backends/platform/tizen/form.cpp:267
@@ -1666,19 +1708,19 @@ msgctxt "lowres"
msgid "Normal (no scaling)"
msgstr "Normaal (niet schalen)"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2148
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2197
msgid "Enabled aspect ratio correction"
msgstr "Pixelverhoudingcorrectie ingeschakeld"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2154
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2203
msgid "Disabled aspect ratio correction"
msgstr "Pixelverhoudingcorrectie uitgeschakeld"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2209
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2258
msgid "Active graphics filter:"
msgstr "Actieve grafische filter:"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2251
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2300
msgid "Windowed mode"
msgstr "Venstermodus"
@@ -1737,8 +1779,8 @@ msgstr "Snelle modus"
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
#: backends/events/default/default-events.cpp:218
-#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:82
-#: engines/scumm/help.cpp:84
+#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:83
+#: engines/scumm/help.cpp:85
msgid "Quit"
msgstr "Stoppen"
@@ -1758,7 +1800,7 @@ msgstr "Virtueel toetsenbord"
msgid "Key mapper"
msgstr "Toets koppeltool"
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
msgid "Do you want to quit ?"
msgstr "Wilt u stoppen?"
@@ -2095,21 +2137,43 @@ msgstr "Klikken Aangezet"
msgid "Clicking Disabled"
msgstr "Klikken Uitgeschakeld"
-#: engines/agi/detection.cpp:142 engines/drascula/detection.cpp:302
+#: engines/agi/detection.cpp:147 engines/drascula/detection.cpp:302
#: engines/dreamweb/detection.cpp:47 engines/neverhood/detection.cpp:160
#: engines/sci/detection.cpp:394 engines/toltecs/detection.cpp:200
-#: engines/zvision/detection.cpp:103
+#: engines/zvision/detection.cpp:246
msgid "Use original save/load screens"
msgstr "Gebruik originele opslaan/laad schermen"
-#: engines/agi/detection.cpp:143 engines/drascula/detection.cpp:303
+#: engines/agi/detection.cpp:148 engines/drascula/detection.cpp:303
#: engines/dreamweb/detection.cpp:48 engines/neverhood/detection.cpp:161
#: engines/sci/detection.cpp:395 engines/toltecs/detection.cpp:201
-#: engines/zvision/detection.cpp:104
+#: engines/zvision/detection.cpp:247
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"
+#: engines/agi/detection.cpp:157
+#, fuzzy
+msgid "Use an alternative palette"
+msgstr ""
+"Gebruik een alternatieve versie van de intro (alleen voor de CD versie)"
+
+#: engines/agi/detection.cpp:158
+msgid ""
+"Use an alternative palette, common for all Amiga games. This was the old "
+"behavior"
+msgstr ""
+
+#: engines/agi/detection.cpp:167
+#, fuzzy
+msgid "Mouse support"
+msgstr "Support overslaan"
+
+#: engines/agi/detection.cpp:168
+msgid ""
+"Enables mouse support. Allows to use mouse for movement and in game menus."
+msgstr ""
+
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
@@ -2122,7 +2186,7 @@ msgstr "Laad opgeslagen spel:"
msgid "Restore"
msgstr "Laad"
-#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2368
+#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2377
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -2133,7 +2197,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2361
+#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2370
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -2144,7 +2208,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2379
+#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2388
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -2160,11 +2224,11 @@ msgstr ""
msgid "Cutscene file '%s' not found!"
msgstr "Cutscene bestand '%s' niet gevonden!"
-#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:91
+#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:101
msgid "Color Blind Mode"
msgstr "Kleurenblind Modus"
-#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:92
+#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:102
msgid "Enable Color Blind Mode by default"
msgstr "Schakel Kleurenblind modus standaard in"
@@ -2530,12 +2594,12 @@ msgstr ""
"Gebruik een alternatieve versie van de intro (alleen voor de CD versie)"
#: engines/sci/detection.cpp:374
-msgid "EGA undithering"
-msgstr "EGA undithering"
+msgid "Skip EGA dithering pass (full color backgrounds)"
+msgstr ""
#: engines/sci/detection.cpp:375
-msgid "Enable undithering in EGA games"
-msgstr "Undithering inschakelen in EGA spellen"
+msgid "Skip dithering pass in EGA games, graphics are shown with full colors"
+msgstr ""
#: engines/sci/detection.cpp:384
msgid "Prefer digital sound effects"
@@ -2703,516 +2767,541 @@ msgstr "Oefenen"
msgid "Expert"
msgstr "Expert"
-#: engines/scumm/help.cpp:73
+#: engines/scumm/help.cpp:74
msgid "Common keyboard commands:"
msgstr "Gebruikelijke toetsenbord commandos:"
-#: engines/scumm/help.cpp:74
+#: engines/scumm/help.cpp:75
msgid "Save / Load dialog"
msgstr "Opslaan / Laden dialoog"
-#: engines/scumm/help.cpp:76
+#: engines/scumm/help.cpp:77
msgid "Skip line of text"
msgstr "Regel text overslaan"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Esc"
msgstr "Esc"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Skip cutscene"
msgstr "Cutscene overslaan"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Space"
msgstr "Spatie"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Pause game"
msgstr "Spel pauzeren"
-#: engines/scumm/help.cpp:79 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:95 engines/scumm/help.cpp:96
-#: engines/scumm/help.cpp:97 engines/scumm/help.cpp:98
-#: engines/scumm/help.cpp:99 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:96 engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98 engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Ctrl"
msgstr "Ctrl"
-#: engines/scumm/help.cpp:79
+#: engines/scumm/help.cpp:80
msgid "Load game state 1-10"
msgstr "Laad opgeslagen spel 1-10"
-#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:81 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Alt"
msgstr "Alt"
-#: engines/scumm/help.cpp:80
+#: engines/scumm/help.cpp:81
msgid "Save game state 1-10"
msgstr "Spel opslaan 1-10"
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:90
msgid "Enter"
msgstr "Enter"
-#: engines/scumm/help.cpp:87
+#: engines/scumm/help.cpp:88
msgid "Music volume up / down"
msgstr "Muziek volume omhoog / omlaag"
-#: engines/scumm/help.cpp:88
+#: engines/scumm/help.cpp:89
msgid "Text speed slower / faster"
msgstr "Tekst langzamer / sneller"
-#: engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:90
msgid "Simulate left mouse button"
msgstr "Simuleer linkermuisknop"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Tab"
msgstr "Tab"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Simulate right mouse button"
msgstr "Simuleer rechtermuisknop"
-#: engines/scumm/help.cpp:93
+#: engines/scumm/help.cpp:94
msgid "Special keyboard commands:"
msgstr "Speciale toetsenbord commando's:"
-#: engines/scumm/help.cpp:94
+#: engines/scumm/help.cpp:95
msgid "Show / Hide console"
msgstr "Toon / Verberg console"
-#: engines/scumm/help.cpp:95
+#: engines/scumm/help.cpp:96
msgid "Start the debugger"
msgstr "Start de debugger"
-#: engines/scumm/help.cpp:96
+#: engines/scumm/help.cpp:97
msgid "Show memory consumption"
msgstr "Toon geheugen gebruik"
-#: engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98
msgid "Run in fast mode (*)"
msgstr "Draai in snelle modus (*)"
-#: engines/scumm/help.cpp:98
+#: engines/scumm/help.cpp:99
msgid "Run in really fast mode (*)"
msgstr "Draai in zeer snelle modus (*)"
-#: engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100
msgid "Toggle mouse capture"
msgstr "Mousecapture In-/Uitschakelen"
-#: engines/scumm/help.cpp:100
+#: engines/scumm/help.cpp:101
msgid "Switch between graphics filters"
msgstr "Schakel tussen grafische filters"
-#: engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102
msgid "Increase / Decrease scale factor"
msgstr "Verhoog / Verlaag schalingsfactor"
-#: engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:103
msgid "Toggle aspect-ratio correction"
msgstr "Schakel pixelverhoudingcorrectie aan/uit"
-#: engines/scumm/help.cpp:107
+#: engines/scumm/help.cpp:108
msgid "* Note that using ctrl-f and"
msgstr "* Het gebruik van Ctrl-F en"
-#: engines/scumm/help.cpp:108
+#: engines/scumm/help.cpp:109
msgid " ctrl-g are not recommended"
msgstr " Ctrl-G wordt niet aanbevolen"
-#: engines/scumm/help.cpp:109
+#: engines/scumm/help.cpp:110
msgid " since they may cause crashes"
msgstr " omdat dit crashes of andere"
-#: engines/scumm/help.cpp:110
+#: engines/scumm/help.cpp:111
msgid " or incorrect game behavior."
msgstr " effecten in het spel kan veroorzaken."
-#: engines/scumm/help.cpp:114
+#: engines/scumm/help.cpp:115
msgid "Spinning drafts on the keyboard:"
msgstr "Garen spinnen op het toetsenbord:"
-#: engines/scumm/help.cpp:116
+#: engines/scumm/help.cpp:117
msgid "Main game controls:"
msgstr "Hoofd spel besturing:"
-#: engines/scumm/help.cpp:121 engines/scumm/help.cpp:136
-#: engines/scumm/help.cpp:161
+#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
+#: engines/scumm/help.cpp:162
msgid "Push"
msgstr "Duw"
-#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
-#: engines/scumm/help.cpp:162
+#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
+#: engines/scumm/help.cpp:163
msgid "Pull"
msgstr "Trek"
-#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
-#: engines/scumm/help.cpp:163 engines/scumm/help.cpp:197
-#: engines/scumm/help.cpp:207
+#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
+#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:198
+#: engines/scumm/help.cpp:208
msgid "Give"
msgstr "Geef"
-#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
-#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:190
-#: engines/scumm/help.cpp:208
+#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
+#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
+#: engines/scumm/help.cpp:209
msgid "Open"
msgstr "Open"
-#: engines/scumm/help.cpp:126
+#: engines/scumm/help.cpp:127
msgid "Go to"
msgstr "Ga naar"
-#: engines/scumm/help.cpp:127
+#: engines/scumm/help.cpp:128
msgid "Get"
msgstr "Pak"
-#: engines/scumm/help.cpp:128 engines/scumm/help.cpp:152
-#: engines/scumm/help.cpp:170 engines/scumm/help.cpp:198
-#: engines/scumm/help.cpp:213 engines/scumm/help.cpp:224
-#: engines/scumm/help.cpp:250
+#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:153
+#: engines/scumm/help.cpp:171 engines/scumm/help.cpp:199
+#: engines/scumm/help.cpp:214 engines/scumm/help.cpp:225
+#: engines/scumm/help.cpp:251
msgid "Use"
msgstr "Gebruik"
-#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:142
msgid "Read"
msgstr "Lees"
-#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:147
+#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:148
msgid "New kid"
msgstr "Nieuw kind"
-#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:153
-#: engines/scumm/help.cpp:171
+#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
+#: engines/scumm/help.cpp:172
msgid "Turn on"
msgstr "Zet aan"
-#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
-#: engines/scumm/help.cpp:172
+#: engines/scumm/help.cpp:133 engines/scumm/help.cpp:155
+#: engines/scumm/help.cpp:173
msgid "Turn off"
msgstr "Zet uit"
-#: engines/scumm/help.cpp:142 engines/scumm/help.cpp:167
-#: engines/scumm/help.cpp:194
+#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
+#: engines/scumm/help.cpp:195
msgid "Walk to"
msgstr "Loop naar"
-#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
-#: engines/scumm/help.cpp:195 engines/scumm/help.cpp:210
-#: engines/scumm/help.cpp:227
+#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:228
msgid "Pick up"
msgstr "Pak op"
-#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:145 engines/scumm/help.cpp:170
msgid "What is"
msgstr "Wat is"
-#: engines/scumm/help.cpp:146
+#: engines/scumm/help.cpp:147
msgid "Unlock"
msgstr "Maak open"
-#: engines/scumm/help.cpp:149
+#: engines/scumm/help.cpp:150
msgid "Put on"
msgstr "Zet op"
-#: engines/scumm/help.cpp:150
+#: engines/scumm/help.cpp:151
msgid "Take off"
msgstr "Doe af"
-#: engines/scumm/help.cpp:156
+#: engines/scumm/help.cpp:157
msgid "Fix"
msgstr "Repareer"
-#: engines/scumm/help.cpp:158
+#: engines/scumm/help.cpp:159
msgid "Switch"
msgstr "Schakel"
-#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:228
+#: engines/scumm/help.cpp:167 engines/scumm/help.cpp:229
msgid "Look"
msgstr "Kijk"
-#: engines/scumm/help.cpp:173 engines/scumm/help.cpp:223
+#: engines/scumm/help.cpp:174 engines/scumm/help.cpp:224
msgid "Talk"
msgstr "Praat"
-#: engines/scumm/help.cpp:174
+#: engines/scumm/help.cpp:175
msgid "Travel"
msgstr "Reis"
-#: engines/scumm/help.cpp:175
+#: engines/scumm/help.cpp:176
msgid "To Henry / To Indy"
msgstr "Naar Henry / Naar Indy"
#. I18N: These are different musical notes
-#: engines/scumm/help.cpp:179
+#: engines/scumm/help.cpp:180
msgid "play C minor on distaff"
msgstr "speel C mineur op spinrok"
-#: engines/scumm/help.cpp:180
+#: engines/scumm/help.cpp:181
msgid "play D on distaff"
msgstr "speel D op spinrok"
-#: engines/scumm/help.cpp:181
+#: engines/scumm/help.cpp:182
msgid "play E on distaff"
msgstr "speel E op spinrok"
-#: engines/scumm/help.cpp:182
+#: engines/scumm/help.cpp:183
msgid "play F on distaff"
msgstr "speel F op spinrok"
-#: engines/scumm/help.cpp:183
+#: engines/scumm/help.cpp:184
msgid "play G on distaff"
msgstr "speel G op spinrok"
-#: engines/scumm/help.cpp:184
+#: engines/scumm/help.cpp:185
msgid "play A on distaff"
msgstr "speel A op spinrok"
-#: engines/scumm/help.cpp:185
+#: engines/scumm/help.cpp:186
msgid "play B on distaff"
msgstr "speel B op spinrok"
-#: engines/scumm/help.cpp:186
+#: engines/scumm/help.cpp:187
msgid "play C major on distaff"
msgstr "speel C majeur op spinrok"
-#: engines/scumm/help.cpp:192 engines/scumm/help.cpp:214
+#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
msgid "puSh"
msgstr "Duw"
-#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
+#: engines/scumm/help.cpp:194 engines/scumm/help.cpp:216
msgid "pull (Yank)"
msgstr "Trek"
-#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:212
-#: engines/scumm/help.cpp:248
+#: engines/scumm/help.cpp:197 engines/scumm/help.cpp:213
+#: engines/scumm/help.cpp:249
msgid "Talk to"
msgstr "Praat met"
-#: engines/scumm/help.cpp:199 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:200 engines/scumm/help.cpp:212
msgid "Look at"
msgstr "Kijk naar"
-#: engines/scumm/help.cpp:200
+#: engines/scumm/help.cpp:201
msgid "turn oN"
msgstr "zet aaN"
-#: engines/scumm/help.cpp:201
+#: engines/scumm/help.cpp:202
msgid "turn oFf"
msgstr "zet uit"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "KeyUp"
msgstr "ToetsOmhoog"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "Highlight prev dialogue"
msgstr "Vorig dialoog oplichten"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "KeyDown"
msgstr "ToetsOmlaag"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "Highlight next dialogue"
msgstr "Volgend dialoog oplichten"
-#: engines/scumm/help.cpp:222
+#: engines/scumm/help.cpp:223
msgid "Walk"
msgstr "Loop"
-#: engines/scumm/help.cpp:225 engines/scumm/help.cpp:234
-#: engines/scumm/help.cpp:241 engines/scumm/help.cpp:249
+#: engines/scumm/help.cpp:226 engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:242 engines/scumm/help.cpp:250
msgid "Inventory"
msgstr "Inventaris"
-#: engines/scumm/help.cpp:226
+#: engines/scumm/help.cpp:227
msgid "Object"
msgstr "Object"
-#: engines/scumm/help.cpp:229
+#: engines/scumm/help.cpp:230
msgid "Black and White / Color"
msgstr "Zwart-Wit / Kleur"
-#: engines/scumm/help.cpp:232
+#: engines/scumm/help.cpp:233
msgid "Eyes"
msgstr "Ogen"
-#: engines/scumm/help.cpp:233
+#: engines/scumm/help.cpp:234
msgid "Tongue"
msgstr "Tong"
-#: engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:236
msgid "Punch"
msgstr "Stoot"
-#: engines/scumm/help.cpp:236
+#: engines/scumm/help.cpp:237
msgid "Kick"
msgstr "Schop"
-#: engines/scumm/help.cpp:239 engines/scumm/help.cpp:247
+#: engines/scumm/help.cpp:240 engines/scumm/help.cpp:248
msgid "Examine"
msgstr "Onderzoek"
-#: engines/scumm/help.cpp:240
+#: engines/scumm/help.cpp:241
msgid "Regular cursor"
msgstr "Normale cursor"
#. I18N: Comm is a communication device
-#: engines/scumm/help.cpp:243
+#: engines/scumm/help.cpp:244
msgid "Comm"
msgstr "Comm"
-#: engines/scumm/help.cpp:246
+#: engines/scumm/help.cpp:247
msgid "Save / Load / Options"
msgstr "Opslaan / Laden / Opties"
-#: engines/scumm/help.cpp:255
+#: engines/scumm/help.cpp:256
msgid "Other game controls:"
msgstr "Andere spel besturing:"
-#: engines/scumm/help.cpp:257 engines/scumm/help.cpp:267
+#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:268
msgid "Inventory:"
msgstr "Inventaris:"
-#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:274
+#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
msgid "Scroll list up"
msgstr "Scroll lijst omhoog"
-#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
+#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:276
msgid "Scroll list down"
msgstr "Scroll lijst naar beneden"
-#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:268
+#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:269
msgid "Upper left item"
msgstr "Linker bovenste voorwerp"
-#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:270
+#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
msgid "Lower left item"
msgstr "Linker beneden voorwerp"
-#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
+#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:272
msgid "Upper right item"
msgstr "Rechter bovenste voorwerp"
-#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:273
+#: engines/scumm/help.cpp:264 engines/scumm/help.cpp:274
msgid "Lower right item"
msgstr "Rechter beneden voorwerp"
-#: engines/scumm/help.cpp:269
+#: engines/scumm/help.cpp:270
msgid "Middle left item"
msgstr "Linker middelste voorwerp"
-#: engines/scumm/help.cpp:272
+#: engines/scumm/help.cpp:273
msgid "Middle right item"
msgstr "Rechter middelste voorwerp"
-#: engines/scumm/help.cpp:279 engines/scumm/help.cpp:284
+#: engines/scumm/help.cpp:280 engines/scumm/help.cpp:285
msgid "Switching characters:"
msgstr "Verwissel karakters:"
-#: engines/scumm/help.cpp:281
+#: engines/scumm/help.cpp:282
msgid "Second kid"
msgstr "Tweede kind"
-#: engines/scumm/help.cpp:282
+#: engines/scumm/help.cpp:283
msgid "Third kid"
msgstr "Derde kind"
-#: engines/scumm/help.cpp:294
+#: engines/scumm/help.cpp:292
+#, fuzzy
+msgid "Toggle Inventory/IQ Points display"
+msgstr "Aan-/Uitzetten centreren van Datascherm"
+
+#: engines/scumm/help.cpp:293
+msgid "Toggle Keyboard/Mouse Fighting (*)"
+msgstr ""
+
+#: engines/scumm/help.cpp:295
+msgid "* Keyboard Fighting is always on,"
+msgstr ""
+
+#: engines/scumm/help.cpp:296
+msgid " so despite the in-game message this"
+msgstr ""
+
+#: engines/scumm/help.cpp:297
+msgid " actually toggles Mouse Fighting Off/On"
+msgstr ""
+
+#: engines/scumm/help.cpp:304
msgid "Fighting controls (numpad):"
msgstr "Gevechtbesturing (numeriek toetsenblok):"
-#: engines/scumm/help.cpp:295 engines/scumm/help.cpp:296
-#: engines/scumm/help.cpp:297
+#: engines/scumm/help.cpp:305 engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:307
msgid "Step back"
msgstr "Stap terug"
-#: engines/scumm/help.cpp:298
+#: engines/scumm/help.cpp:308
msgid "Block high"
msgstr "Blokker hoog"
-#: engines/scumm/help.cpp:299
+#: engines/scumm/help.cpp:309
msgid "Block middle"
msgstr "Blokkeer midden"
-#: engines/scumm/help.cpp:300
+#: engines/scumm/help.cpp:310
msgid "Block low"
msgstr "Blokkeer laag"
-#: engines/scumm/help.cpp:301
+#: engines/scumm/help.cpp:311
msgid "Punch high"
msgstr "Stoot hoog"
-#: engines/scumm/help.cpp:302
+#: engines/scumm/help.cpp:312
msgid "Punch middle"
msgstr "Stoot in het midden"
-#: engines/scumm/help.cpp:303
+#: engines/scumm/help.cpp:313
msgid "Punch low"
msgstr "Stoot laag"
-#: engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:315
+msgid "Sucker punch"
+msgstr ""
+
+#: engines/scumm/help.cpp:318
msgid "These are for Indy on left."
msgstr "Deze zijn voor Indy op links."
-#: engines/scumm/help.cpp:307
+#: engines/scumm/help.cpp:319
msgid "When Indy is on the right,"
msgstr "Wanneer Indy rechts staat,"
-#: engines/scumm/help.cpp:308
+#: engines/scumm/help.cpp:320
msgid "7, 4, and 1 are switched with"
msgstr "7, 4 en 1 zijn verwisseld met"
-#: engines/scumm/help.cpp:309
+#: engines/scumm/help.cpp:321
msgid "9, 6, and 3, respectively."
msgstr "9, 6 en 3 respectievelijk."
-#: engines/scumm/help.cpp:316
+#: engines/scumm/help.cpp:328
msgid "Biplane controls (numpad):"
msgstr "Tweedekkerbesturing (numeriek toetsenbord):"
-#: engines/scumm/help.cpp:317
+#: engines/scumm/help.cpp:329
msgid "Fly to upper left"
msgstr "Vlieg naar links omhoog"
-#: engines/scumm/help.cpp:318
+#: engines/scumm/help.cpp:330
msgid "Fly to left"
msgstr "Vlieg naar links"
-#: engines/scumm/help.cpp:319
+#: engines/scumm/help.cpp:331
msgid "Fly to lower left"
msgstr "Vlieg naar links omlaag"
-#: engines/scumm/help.cpp:320
+#: engines/scumm/help.cpp:332
msgid "Fly upwards"
msgstr "Vlieg omhoog"
-#: engines/scumm/help.cpp:321
+#: engines/scumm/help.cpp:333
msgid "Fly straight"
msgstr "Vlieg recht"
-#: engines/scumm/help.cpp:322
+#: engines/scumm/help.cpp:334
msgid "Fly down"
msgstr "Vlieg omlaag"
-#: engines/scumm/help.cpp:323
+#: engines/scumm/help.cpp:335
msgid "Fly to upper right"
msgstr "Vlieg naar rechts omhoog"
-#: engines/scumm/help.cpp:324
+#: engines/scumm/help.cpp:336
msgid "Fly to right"
msgstr "Vlieg naar rechts"
-#: engines/scumm/help.cpp:325
+#: engines/scumm/help.cpp:337
msgid "Fly to lower right"
msgstr "Vlieg naar rechts omlaag"
-#: engines/scumm/scumm.cpp:1823
+#: engines/scumm/scumm.cpp:1832
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
@@ -3221,11 +3310,12 @@ msgstr ""
"Voor MIDI support is de Roland Upgrade van Lucasarts vereist,\n"
"maar %s ontbreekt. Er wordt nu AdLib gebruikt."
-#: engines/scumm/scumm.cpp:2594
+#: engines/scumm/scumm.cpp:2644
+#, fuzzy
msgid ""
-"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
-"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
-"directory inside the Tentacle game directory."
+"Usually, Maniac Mansion would start now. But for that to work, the game "
+"files for Maniac Mansion have to be in the 'Maniac' directory inside the "
+"Tentacle game directory, and the game has to be added to ScummVM."
msgstr ""
"Normaal gesproken zou Maniac Mansion nu starten. Maar ScummVM doet dat nog "
"niet. Om het te spelen, ga naar \"Spel Toevoegen\" in het ScummVM start menu "
@@ -3367,3 +3457,46 @@ msgstr "Toon FPS-teller"
#: engines/wintermute/detection.cpp:59
msgid "Show the current number of frames per second in the upper left corner"
msgstr "Toon de huidige Frames Per Second teller in de linkerbovenhoek"
+
+#: engines/zvision/detection.cpp:256
+msgid "Double FPS"
+msgstr ""
+
+#: engines/zvision/detection.cpp:257
+msgid "Increase game FPS from 30 to 60"
+msgstr ""
+
+#: engines/zvision/detection.cpp:266
+#, fuzzy
+msgid "Enable Venus"
+msgstr "Helium-modus aangezet"
+
+#: engines/zvision/detection.cpp:267
+msgid "Enable the Venus help system"
+msgstr ""
+
+#: engines/zvision/detection.cpp:276
+msgid "Disable animation while turning"
+msgstr ""
+
+#: engines/zvision/detection.cpp:277
+msgid "Disable animation while turning in panoramic mode"
+msgstr ""
+
+#: engines/zvision/detection.cpp:286
+msgid "Use the hires MPEG movies"
+msgstr ""
+
+#: engines/zvision/detection.cpp:287
+#, fuzzy
+msgid ""
+"Use the hires MPEG movies of the DVD version, instead of the lowres AVI ones"
+msgstr ""
+"Gebruik de alternative set van zilveren cursors, in plaats van de normale "
+"gouden"
+
+#~ msgid "EGA undithering"
+#~ msgstr "EGA undithering"
+
+#~ msgid "Enable undithering in EGA games"
+#~ msgstr "Undithering inschakelen in EGA spellen"
diff --git a/po/nn_NO.po b/po/nn_NO.po
index de5698e61d..2741620b8e 100644
--- a/po/nn_NO.po
+++ b/po/nn_NO.po
@@ -1,5 +1,5 @@
# Norwegian (Nynorsk) translation for ScummVM.
-# Copyright (C) 2010-2014 ScummVM Team
+# Copyright (C) 2010-2015 The ScummVM Team
# This file is distributed under the same license as the ScummVM package.
# Einar Johan T. Sømåen <einarjohants@gmail.com>, 2010.
#
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.3.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2014-10-04 00:58+0100\n"
+"POT-Creation-Date: 2015-06-30 20:57+0100\n"
"PO-Revision-Date: 2014-07-11 00:04+0100\n"
"Last-Translator: Einar Johan Trøan Sømåen <einarjohants@gmail.com>\n"
"Language-Team: somaen <einarjohants@gmail.com>\n"
@@ -55,10 +55,11 @@ msgstr "Oppover"
#: gui/browser.cpp:75 gui/chooser.cpp:46 gui/KeysDialog.cpp:43
#: gui/launcher.cpp:351 gui/massadd.cpp:95 gui/options.cpp:1239
+#: gui/recorderdialog.cpp:70 gui/recorderdialog.cpp:156
#: gui/saveload-dialog.cpp:216 gui/saveload-dialog.cpp:276
-#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:922
+#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:931
#: gui/themebrowser.cpp:55 gui/fluidsynth-dialog.cpp:152
-#: engines/engine.cpp:452 backends/platform/wii/options.cpp:48
+#: engines/engine.cpp:483 backends/platform/wii/options.cpp:48
#: backends/events/default/default-events.cpp:196
#: backends/events/default/default-events.cpp:218
#: engines/drascula/saveload.cpp:49 engines/parallaction/saveload.cpp:274
@@ -71,9 +72,9 @@ msgid "Choose"
msgstr "Vel"
#: gui/gui-manager.cpp:117 backends/keymapper/remap-dialog.cpp:53
-#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
-#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
-#: engines/scumm/help.cpp:209
+#: engines/scumm/help.cpp:126 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:192
+#: engines/scumm/help.cpp:210
msgid "Close"
msgstr "Steng"
@@ -89,7 +90,7 @@ msgstr "Syn Tastatur"
msgid "Remap keys"
msgstr "Omkople tastar"
-#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:86
+#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:87
msgid "Toggle fullscreen"
msgstr "Veksle fullskjerm"
@@ -103,13 +104,13 @@ msgstr "Kople"
#: gui/KeysDialog.cpp:42 gui/launcher.cpp:352 gui/launcher.cpp:1048
#: gui/launcher.cpp:1052 gui/massadd.cpp:92 gui/options.cpp:1240
-#: gui/saveload-dialog.cpp:923 gui/fluidsynth-dialog.cpp:153
-#: engines/engine.cpp:371 engines/engine.cpp:382
+#: gui/saveload-dialog.cpp:932 gui/fluidsynth-dialog.cpp:153
+#: engines/engine.cpp:402 engines/engine.cpp:413
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
#: engines/agos/animation.cpp:558 engines/drascula/saveload.cpp:49
-#: engines/groovie/script.cpp:399 engines/parallaction/saveload.cpp:274
-#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1825
+#: engines/groovie/script.cpp:408 engines/parallaction/saveload.cpp:274
+#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1834
#: engines/scumm/players/player_v3m.cpp:130
#: engines/scumm/players/player_v5m.cpp:108 engines/sky/compact.cpp:131
#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:524
@@ -478,7 +479,7 @@ msgstr ""
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -488,7 +489,7 @@ msgstr "Ja"
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -526,6 +527,14 @@ msgstr ""
"ScummVM kunne ikkje finne nokon motor som var i stand til å køyre det velde "
"spelet!"
+#: gui/launcher.cpp:1159
+msgid "Mass Add..."
+msgstr "Legg til fleire..."
+
+#: gui/launcher.cpp:1161
+msgid "Record..."
+msgstr ""
+
#: gui/massadd.cpp:79 gui/massadd.cpp:82
msgid "... progress ..."
msgstr "... fremdrift ..."
@@ -624,7 +633,7 @@ msgid "Special dithering modes supported by some games"
msgstr "Spesielle dithering-modus som støttast av nokre spel"
#: gui/options.cpp:760
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2249
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2298
msgid "Fullscreen mode"
msgstr "Fullskjermsmodus"
@@ -937,6 +946,43 @@ msgstr ""
"Temaet du har valt støttar ikkje det aktive språket. Om du vil nytte dette "
"temaet må du bytte til eit anna språk først."
+#: gui/recorderdialog.cpp:64
+msgid "Recorder or Playback Gameplay"
+msgstr ""
+
+#: gui/recorderdialog.cpp:69 gui/recorderdialog.cpp:156
+#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
+msgid "Delete"
+msgstr "Slett"
+
+#: gui/recorderdialog.cpp:71
+msgid "Record"
+msgstr ""
+
+#: gui/recorderdialog.cpp:72
+#, fuzzy
+msgid "Playback"
+msgstr "Spel"
+
+#: gui/recorderdialog.cpp:74
+msgid "Edit"
+msgstr ""
+
+#: gui/recorderdialog.cpp:86 gui/recorderdialog.cpp:243
+#: gui/recorderdialog.cpp:253
+msgid "Author: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:87 gui/recorderdialog.cpp:244
+#: gui/recorderdialog.cpp:254
+msgid "Notes: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:155
+#, fuzzy
+msgid "Do you really want to delete this record?"
+msgstr "Vil du verkeleg slette det lagra spelet?"
+
#: gui/saveload-dialog.cpp:167
msgid "List view"
msgstr "Listevisning"
@@ -957,23 +1003,19 @@ msgstr "Inga tid lagra"
msgid "No playtime saved"
msgstr "Inga speletid lagra"
-#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
-msgid "Delete"
-msgstr "Slett"
-
#: gui/saveload-dialog.cpp:275
msgid "Do you really want to delete this saved game?"
msgstr "Vil du verkeleg slette det lagra spelet?"
-#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:875
+#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:884
msgid "Date: "
msgstr "Dato: "
-#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:881
+#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:890
msgid "Time: "
msgstr "Tid: "
-#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:889
+#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:898
msgid "Playtime: "
msgstr "Speletid: "
@@ -989,19 +1031,19 @@ msgstr "Neste"
msgid "Prev"
msgstr "Forrige"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "New Save"
msgstr "Ny Lagring"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "Create a new save game"
msgstr "Lag eit nytt lagra spel"
-#: gui/saveload-dialog.cpp:868
+#: gui/saveload-dialog.cpp:877
msgid "Name: "
msgstr "Namn:"
-#: gui/saveload-dialog.cpp:940
+#: gui/saveload-dialog.cpp:949
#, c-format
msgid "Enter a description for slot %d:"
msgstr ""
@@ -1153,7 +1195,7 @@ msgstr "Hopp over linje"
msgid "Error running game:"
msgstr "Feil under køyring av spel:"
-#: base/main.cpp:536
+#: base/main.cpp:554
msgid "Could not find any engine capable of running the selected game"
msgstr "Kunne ikkje finne nokon motor som kunne køyre det velde spelet."
@@ -1271,7 +1313,7 @@ msgstr "Tilbake til Oppsta~r~tar"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:803
#: engines/cruise/menu.cpp:212 engines/drascula/saveload.cpp:336
#: engines/dreamweb/saveload.cpp:261 engines/neverhood/menumodule.cpp:873
-#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:758
+#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:759
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save game:"
msgstr "Lagra spel:"
@@ -1284,7 +1326,7 @@ msgstr "Lagra spel:"
#: engines/agi/saveload.cpp:803 engines/cruise/menu.cpp:212
#: engines/drascula/saveload.cpp:336 engines/dreamweb/saveload.cpp:261
#: engines/neverhood/menumodule.cpp:873 engines/pegasus/pegasus.cpp:377
-#: engines/sci/engine/kfile.cpp:758 engines/scumm/dialogs.cpp:188
+#: engines/sci/engine/kfile.cpp:759 engines/scumm/dialogs.cpp:188
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save"
msgstr "Lagre"
@@ -1317,24 +1359,24 @@ msgstr "~A~vbryt"
msgid "~K~eys"
msgstr "~T~astar"
-#: engines/engine.cpp:245
+#: engines/engine.cpp:276
msgid "Could not initialize color format."
msgstr ""
-#: engines/engine.cpp:253
+#: engines/engine.cpp:284
msgid "Could not switch to video mode: '"
msgstr "Kunne ikkje veksle til videomodus: '"
-#: engines/engine.cpp:262
+#: engines/engine.cpp:293
#, fuzzy
msgid "Could not apply aspect ratio setting."
msgstr "Veksle aspekt-korrigering"
-#: engines/engine.cpp:267
+#: engines/engine.cpp:298
msgid "Could not apply fullscreen setting."
msgstr ""
-#: engines/engine.cpp:367
+#: engines/engine.cpp:398
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1343,7 +1385,7 @@ msgid ""
"See the README file for details."
msgstr ""
-#: engines/engine.cpp:378
+#: engines/engine.cpp:409
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1352,14 +1394,14 @@ msgid ""
"See the README file for details."
msgstr ""
-#: engines/engine.cpp:436
+#: engines/engine.cpp:467
#, c-format
msgid ""
"Gamestate load failed (%s)! Please consult the README for basic information, "
"and for instructions on how to obtain further assistance."
msgstr ""
-#: engines/engine.cpp:449
+#: engines/engine.cpp:480
msgid ""
"WARNING: The game you are about to start is not yet fully supported by "
"ScummVM. As such, it is likely to be unstable, and any saves you make might "
@@ -1369,7 +1411,7 @@ msgstr ""
"ennå. Derfor er det sannsynleg at det er ustabilt, og det er mogleg at lagra "
"spel ikkje vil fungere med fremtidige versjonar av ScummVM."
-#: engines/engine.cpp:452
+#: engines/engine.cpp:483
msgid "Start anyway"
msgstr "Start allikevel"
@@ -1575,11 +1617,11 @@ msgstr "~O~vergangar aktivert"
msgid "Touchpad mode disabled."
msgstr "Deaktivert GFX"
-#: backends/platform/maemo/maemo.cpp:209
+#: backends/platform/maemo/maemo.cpp:208
msgid "Click Mode"
msgstr "Klikkmodus"
-#: backends/platform/maemo/maemo.cpp:215
+#: backends/platform/maemo/maemo.cpp:214
#: backends/platform/symbian/src/SymbianActions.cpp:42
#: backends/platform/wince/CEActionsPocket.cpp:60
#: backends/platform/wince/CEActionsSmartphone.cpp:43
@@ -1587,11 +1629,11 @@ msgstr "Klikkmodus"
msgid "Left Click"
msgstr "Venstreklikk"
-#: backends/platform/maemo/maemo.cpp:218
+#: backends/platform/maemo/maemo.cpp:217
msgid "Middle Click"
msgstr "Midtklikk"
-#: backends/platform/maemo/maemo.cpp:221
+#: backends/platform/maemo/maemo.cpp:220
#: backends/platform/symbian/src/SymbianActions.cpp:43
#: backends/platform/wince/CEActionsSmartphone.cpp:44
#: backends/platform/tizen/form.cpp:267
@@ -1628,21 +1670,21 @@ msgctxt "lowres"
msgid "Normal (no scaling)"
msgstr "Normal (ikkje skaler)"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2148
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2197
#, fuzzy
msgid "Enabled aspect ratio correction"
msgstr "Aspekt-korrigering"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2154
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2203
#, fuzzy
msgid "Disabled aspect ratio correction"
msgstr "Aspekt-korrigering"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2209
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2258
msgid "Active graphics filter:"
msgstr "Aktivt grafikkfilter:"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2251
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2300
msgid "Windowed mode"
msgstr "Vindusmodus"
@@ -1702,8 +1744,8 @@ msgstr "Rask modus"
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
#: backends/events/default/default-events.cpp:218
-#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:82
-#: engines/scumm/help.cpp:84
+#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:83
+#: engines/scumm/help.cpp:85
msgid "Quit"
msgstr "Avslutt"
@@ -1723,7 +1765,7 @@ msgstr "Virtuelt tastatur"
msgid "Key mapper"
msgstr "Tastkopler"
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
msgid "Do you want to quit ?"
msgstr "Vil du avslutte?"
@@ -2071,33 +2113,54 @@ msgstr "~O~vergangar aktivert"
msgid "Clicking Disabled"
msgstr "Klikking Deaktivert"
-#: engines/agi/detection.cpp:142 engines/drascula/detection.cpp:302
+#: engines/agi/detection.cpp:147 engines/drascula/detection.cpp:302
#: engines/dreamweb/detection.cpp:47 engines/neverhood/detection.cpp:160
#: engines/sci/detection.cpp:394 engines/toltecs/detection.cpp:200
-#: engines/zvision/detection.cpp:103
+#: engines/zvision/detection.cpp:246
msgid "Use original save/load screens"
msgstr "Nytt opprinnelege skjermar for lagring/lasting"
-#: engines/agi/detection.cpp:143 engines/drascula/detection.cpp:303
+#: engines/agi/detection.cpp:148 engines/drascula/detection.cpp:303
#: engines/dreamweb/detection.cpp:48 engines/neverhood/detection.cpp:161
#: engines/sci/detection.cpp:395 engines/toltecs/detection.cpp:201
-#: engines/zvision/detection.cpp:104
+#: engines/zvision/detection.cpp:247
msgid "Use the original save/load screens, instead of the ScummVM ones"
msgstr ""
+#: engines/agi/detection.cpp:157
+#, fuzzy
+msgid "Use an alternative palette"
+msgstr "Nytt diskettversjonens åpning (Kun CD-versjon)"
+
+#: engines/agi/detection.cpp:158
+msgid ""
+"Use an alternative palette, common for all Amiga games. This was the old "
+"behavior"
+msgstr ""
+
+#: engines/agi/detection.cpp:167
+#, fuzzy
+msgid "Mouse support"
+msgstr "Hopp over"
+
+#: engines/agi/detection.cpp:168
+msgid ""
+"Enables mouse support. Allows to use mouse for movement and in game menus."
+msgstr ""
+
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore game:"
msgstr "Gjenopprett spel:"
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore"
msgstr "Gjenopprett"
-#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2368
+#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2377
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -2105,7 +2168,7 @@ msgid ""
"%s"
msgstr ""
-#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2361
+#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2370
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -2113,7 +2176,7 @@ msgid ""
"%s"
msgstr ""
-#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2379
+#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2388
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -2126,12 +2189,12 @@ msgstr ""
msgid "Cutscene file '%s' not found!"
msgstr ""
-#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:81
+#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:101
#, fuzzy
msgid "Color Blind Mode"
msgstr "Klikkmodus"
-#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:82
+#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:102
msgid "Enable Color Blind Mode by default"
msgstr ""
@@ -2178,7 +2241,7 @@ msgstr "Rask modus"
msgid "Play movies at an increased speed"
msgstr "Spel filmar med auka hastighet"
-#: engines/groovie/script.cpp:399
+#: engines/groovie/script.cpp:408
#, fuzzy
msgid "Failed to save game"
msgstr "Lagra spel:"
@@ -2478,11 +2541,11 @@ msgid "Use an alternative game intro (CD version only)"
msgstr "Nytt diskettversjonens åpning (Kun CD-versjon)"
#: engines/sci/detection.cpp:374
-msgid "EGA undithering"
+msgid "Skip EGA dithering pass (full color backgrounds)"
msgstr ""
#: engines/sci/detection.cpp:375
-msgid "Enable undithering in EGA games"
+msgid "Skip dithering pass in EGA games, graphics are shown with full colors"
msgstr ""
#: engines/sci/detection.cpp:384
@@ -2552,12 +2615,14 @@ msgstr "Spelet er pausa. Trykk MELLOMROM for å fortsette."
#. "Moechten Sie wirklich neu starten? (J/N)J"
#. Will react to J as 'Yes'
#: engines/scumm/dialogs.cpp:183
-msgid "Are you sure you want to restart? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to restart? (Y/N)Y"
msgstr "Er du sikker på at du vil starte på nytt (Y/N)?"
#. I18N: you may specify 'Yes' symbol at the end of the line. See previous comment
#: engines/scumm/dialogs.cpp:185
-msgid "Are you sure you want to quit? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to quit? (Y/N)Y"
msgstr "Er du sikker på at du vil avslutte (Y/N)?"
#: engines/scumm/dialogs.cpp:190
@@ -2648,528 +2713,553 @@ msgstr ""
msgid "Expert"
msgstr "Ekspert"
-#: engines/scumm/help.cpp:73
+#: engines/scumm/help.cpp:74
msgid "Common keyboard commands:"
msgstr "Vanlege tastaturkommandoar:"
-#: engines/scumm/help.cpp:74
+#: engines/scumm/help.cpp:75
msgid "Save / Load dialog"
msgstr "Åpne- / Lagre-dialog"
-#: engines/scumm/help.cpp:76
+#: engines/scumm/help.cpp:77
msgid "Skip line of text"
msgstr "Hopp over tekstlinje"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Esc"
msgstr "Esc"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Skip cutscene"
msgstr "Hopp over cutscene"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Space"
msgstr "Opprom"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Pause game"
msgstr "Pause spel"
-#: engines/scumm/help.cpp:79 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:95 engines/scumm/help.cpp:96
-#: engines/scumm/help.cpp:97 engines/scumm/help.cpp:98
-#: engines/scumm/help.cpp:99 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:96 engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98 engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Ctrl"
msgstr "Ctrl"
-#: engines/scumm/help.cpp:79
+#: engines/scumm/help.cpp:80
msgid "Load game state 1-10"
msgstr "Åpne speltilstand 1-10"
-#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:81 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Alt"
msgstr "Alt"
-#: engines/scumm/help.cpp:80
+#: engines/scumm/help.cpp:81
msgid "Save game state 1-10"
msgstr "Lagre speltilstand 1-10"
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:90
msgid "Enter"
msgstr "Enter"
-#: engines/scumm/help.cpp:87
+#: engines/scumm/help.cpp:88
msgid "Music volume up / down"
msgstr "Musikkvolum opp / ned"
-#: engines/scumm/help.cpp:88
+#: engines/scumm/help.cpp:89
msgid "Text speed slower / faster"
msgstr "Tekstfart saktare / fortare"
-#: engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:90
msgid "Simulate left mouse button"
msgstr "Simuler venstre musknapp"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Tab"
msgstr "Tab"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Simulate right mouse button"
msgstr "Simuler høgre musknapp"
-#: engines/scumm/help.cpp:93
+#: engines/scumm/help.cpp:94
msgid "Special keyboard commands:"
msgstr "Spesielle tastaturkommandoar:"
-#: engines/scumm/help.cpp:94
+#: engines/scumm/help.cpp:95
msgid "Show / Hide console"
msgstr "Vis / Skjul konsoll"
-#: engines/scumm/help.cpp:95
+#: engines/scumm/help.cpp:96
msgid "Start the debugger"
msgstr "Start debuggaren"
-#: engines/scumm/help.cpp:96
+#: engines/scumm/help.cpp:97
msgid "Show memory consumption"
msgstr "Vis minneforbruk"
-#: engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98
msgid "Run in fast mode (*)"
msgstr "Køyr i rask modus (*)"
-#: engines/scumm/help.cpp:98
+#: engines/scumm/help.cpp:99
msgid "Run in really fast mode (*)"
msgstr "Køyr i verkeleg rask modus (*)"
-#: engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100
msgid "Toggle mouse capture"
msgstr "Veksle muslåsing"
-#: engines/scumm/help.cpp:100
+#: engines/scumm/help.cpp:101
msgid "Switch between graphics filters"
msgstr "Veksle grafikkfiltre"
-#: engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102
msgid "Increase / Decrease scale factor"
msgstr "Øk/Minsk skaleringsfaktor"
-#: engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:103
msgid "Toggle aspect-ratio correction"
msgstr "Veksle aspekt-korrigering"
-#: engines/scumm/help.cpp:107
+#: engines/scumm/help.cpp:108
msgid "* Note that using ctrl-f and"
msgstr "* Merk at å bruke ctrl-f og"
-#: engines/scumm/help.cpp:108
+#: engines/scumm/help.cpp:109
msgid " ctrl-g are not recommended"
msgstr " ctrl-g er ikkje anbefalt då"
-#: engines/scumm/help.cpp:109
+#: engines/scumm/help.cpp:110
msgid " since they may cause crashes"
msgstr " dei kan forårsake kræsj og"
-#: engines/scumm/help.cpp:110
+#: engines/scumm/help.cpp:111
#, fuzzy
msgid " or incorrect game behavior."
msgstr "Spel"
-#: engines/scumm/help.cpp:114
+#: engines/scumm/help.cpp:115
msgid "Spinning drafts on the keyboard:"
msgstr "Spinne drafts på tastaturet:"
-#: engines/scumm/help.cpp:116
+#: engines/scumm/help.cpp:117
msgid "Main game controls:"
msgstr "Hovedkontrollar for spel:"
-#: engines/scumm/help.cpp:121 engines/scumm/help.cpp:136
-#: engines/scumm/help.cpp:161
+#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
+#: engines/scumm/help.cpp:162
msgid "Push"
msgstr "Dytt"
-#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
-#: engines/scumm/help.cpp:162
+#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
+#: engines/scumm/help.cpp:163
msgid "Pull"
msgstr "Dra"
-#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
-#: engines/scumm/help.cpp:163 engines/scumm/help.cpp:197
-#: engines/scumm/help.cpp:207
+#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
+#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:198
+#: engines/scumm/help.cpp:208
msgid "Give"
msgstr "Gi"
-#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
-#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:190
-#: engines/scumm/help.cpp:208
+#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
+#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
+#: engines/scumm/help.cpp:209
msgid "Open"
msgstr "Åpne"
-#: engines/scumm/help.cpp:126
+#: engines/scumm/help.cpp:127
msgid "Go to"
msgstr "Gå til"
-#: engines/scumm/help.cpp:127
+#: engines/scumm/help.cpp:128
msgid "Get"
msgstr "Få"
-#: engines/scumm/help.cpp:128 engines/scumm/help.cpp:152
-#: engines/scumm/help.cpp:170 engines/scumm/help.cpp:198
-#: engines/scumm/help.cpp:213 engines/scumm/help.cpp:224
-#: engines/scumm/help.cpp:250
+#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:153
+#: engines/scumm/help.cpp:171 engines/scumm/help.cpp:199
+#: engines/scumm/help.cpp:214 engines/scumm/help.cpp:225
+#: engines/scumm/help.cpp:251
msgid "Use"
msgstr "Nytt"
-#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:142
msgid "Read"
msgstr "Les"
-#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:147
+#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:148
msgid "New kid"
msgstr "Bytt unge"
-#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:153
-#: engines/scumm/help.cpp:171
+#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
+#: engines/scumm/help.cpp:172
msgid "Turn on"
msgstr "Slå på"
-#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
-#: engines/scumm/help.cpp:172
+#: engines/scumm/help.cpp:133 engines/scumm/help.cpp:155
+#: engines/scumm/help.cpp:173
msgid "Turn off"
msgstr "Slå av"
-#: engines/scumm/help.cpp:142 engines/scumm/help.cpp:167
-#: engines/scumm/help.cpp:194
+#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
+#: engines/scumm/help.cpp:195
msgid "Walk to"
msgstr "Gå til"
-#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
-#: engines/scumm/help.cpp:195 engines/scumm/help.cpp:210
-#: engines/scumm/help.cpp:227
+#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:228
msgid "Pick up"
msgstr "Plukk opp"
-#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:145 engines/scumm/help.cpp:170
msgid "What is"
msgstr "Kva er"
-#: engines/scumm/help.cpp:146
+#: engines/scumm/help.cpp:147
msgid "Unlock"
msgstr "Lås opp"
-#: engines/scumm/help.cpp:149
+#: engines/scumm/help.cpp:150
msgid "Put on"
msgstr "Ta på (klede)"
-#: engines/scumm/help.cpp:150
+#: engines/scumm/help.cpp:151
msgid "Take off"
msgstr "Ta av (klede)"
-#: engines/scumm/help.cpp:156
+#: engines/scumm/help.cpp:157
msgid "Fix"
msgstr "Fiks"
-#: engines/scumm/help.cpp:158
+#: engines/scumm/help.cpp:159
msgid "Switch"
msgstr "Bytt"
-#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:228
+#: engines/scumm/help.cpp:167 engines/scumm/help.cpp:229
msgid "Look"
msgstr "Kikk"
-#: engines/scumm/help.cpp:173 engines/scumm/help.cpp:223
+#: engines/scumm/help.cpp:174 engines/scumm/help.cpp:224
msgid "Talk"
msgstr "Snakk"
-#: engines/scumm/help.cpp:174
+#: engines/scumm/help.cpp:175
msgid "Travel"
msgstr "Reis"
-#: engines/scumm/help.cpp:175
+#: engines/scumm/help.cpp:176
msgid "To Henry / To Indy"
msgstr "Til Henry / Til Indy"
#. I18N: These are different musical notes
-#: engines/scumm/help.cpp:179
+#: engines/scumm/help.cpp:180
msgid "play C minor on distaff"
msgstr "spel C moll på distaffen "
-#: engines/scumm/help.cpp:180
+#: engines/scumm/help.cpp:181
msgid "play D on distaff"
msgstr "spel D på distaffen"
-#: engines/scumm/help.cpp:181
+#: engines/scumm/help.cpp:182
msgid "play E on distaff"
msgstr "spel E på distaffen"
-#: engines/scumm/help.cpp:182
+#: engines/scumm/help.cpp:183
msgid "play F on distaff"
msgstr "spel F på distaffen"
-#: engines/scumm/help.cpp:183
+#: engines/scumm/help.cpp:184
msgid "play G on distaff"
msgstr "spel G på distaffen"
-#: engines/scumm/help.cpp:184
+#: engines/scumm/help.cpp:185
msgid "play A on distaff"
msgstr "spel A på distaffen"
-#: engines/scumm/help.cpp:185
+#: engines/scumm/help.cpp:186
msgid "play B on distaff"
msgstr "spel H på distaffen"
-#: engines/scumm/help.cpp:186
+#: engines/scumm/help.cpp:187
msgid "play C major on distaff"
msgstr "spel C dur på distaffen"
-#: engines/scumm/help.cpp:192 engines/scumm/help.cpp:214
+#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
msgid "puSh"
msgstr "Dytt"
-#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
+#: engines/scumm/help.cpp:194 engines/scumm/help.cpp:216
msgid "pull (Yank)"
msgstr "Dra"
-#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:212
-#: engines/scumm/help.cpp:248
+#: engines/scumm/help.cpp:197 engines/scumm/help.cpp:213
+#: engines/scumm/help.cpp:249
msgid "Talk to"
msgstr "Snakk til"
-#: engines/scumm/help.cpp:199 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:200 engines/scumm/help.cpp:212
msgid "Look at"
msgstr "Se på"
-#: engines/scumm/help.cpp:200
+#: engines/scumm/help.cpp:201
msgid "turn oN"
msgstr "Slå på"
-#: engines/scumm/help.cpp:201
+#: engines/scumm/help.cpp:202
msgid "turn oFf"
msgstr "Slå av"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "KeyUp"
msgstr "Opp-tast"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "Highlight prev dialogue"
msgstr "Merk forrige dialog"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "KeyDown"
msgstr "Ned-tast"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "Highlight next dialogue"
msgstr "Merk neste dialog"
-#: engines/scumm/help.cpp:222
+#: engines/scumm/help.cpp:223
msgid "Walk"
msgstr "Gå"
-#: engines/scumm/help.cpp:225 engines/scumm/help.cpp:234
-#: engines/scumm/help.cpp:241 engines/scumm/help.cpp:249
+#: engines/scumm/help.cpp:226 engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:242 engines/scumm/help.cpp:250
msgid "Inventory"
msgstr "Inventar"
-#: engines/scumm/help.cpp:226
+#: engines/scumm/help.cpp:227
msgid "Object"
msgstr "Objekt"
-#: engines/scumm/help.cpp:229
+#: engines/scumm/help.cpp:230
msgid "Black and White / Color"
msgstr "Svart-Kvitt / Fargar"
-#: engines/scumm/help.cpp:232
+#: engines/scumm/help.cpp:233
msgid "Eyes"
msgstr "Auger"
-#: engines/scumm/help.cpp:233
+#: engines/scumm/help.cpp:234
msgid "Tongue"
msgstr "Tunge"
-#: engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:236
msgid "Punch"
msgstr "Slå"
-#: engines/scumm/help.cpp:236
+#: engines/scumm/help.cpp:237
msgid "Kick"
msgstr "Spark"
-#: engines/scumm/help.cpp:239 engines/scumm/help.cpp:247
+#: engines/scumm/help.cpp:240 engines/scumm/help.cpp:248
msgid "Examine"
msgstr "Undersøk"
-#: engines/scumm/help.cpp:240
+#: engines/scumm/help.cpp:241
msgid "Regular cursor"
msgstr "Vanleg peikar"
#. I18N: Comm is a communication device
-#: engines/scumm/help.cpp:243
+#: engines/scumm/help.cpp:244
msgid "Comm"
msgstr "Comm"
-#: engines/scumm/help.cpp:246
+#: engines/scumm/help.cpp:247
msgid "Save / Load / Options"
msgstr "Åpne / Lagre / Val"
-#: engines/scumm/help.cpp:255
+#: engines/scumm/help.cpp:256
msgid "Other game controls:"
msgstr "Andre spelkontrollar:"
-#: engines/scumm/help.cpp:257 engines/scumm/help.cpp:267
+#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:268
msgid "Inventory:"
msgstr "Inventar:"
-#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:274
+#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
msgid "Scroll list up"
msgstr "Bla liste opp"
-#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
+#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:276
msgid "Scroll list down"
msgstr "Bla liste ned"
-#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:268
+#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:269
msgid "Upper left item"
msgstr "Øvre venstre gjenstand"
-#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:270
+#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
msgid "Lower left item"
msgstr "Nedre venstre gjenstand"
-#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
+#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:272
msgid "Upper right item"
msgstr "Øvre høgre gjenstand"
-#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:273
+#: engines/scumm/help.cpp:264 engines/scumm/help.cpp:274
msgid "Lower right item"
msgstr "Nedre høgre gjenstand"
-#: engines/scumm/help.cpp:269
+#: engines/scumm/help.cpp:270
msgid "Middle left item"
msgstr "Midtre venstre gjenstand"
-#: engines/scumm/help.cpp:272
+#: engines/scumm/help.cpp:273
msgid "Middle right item"
msgstr "Midtre høgre gjenstand"
-#: engines/scumm/help.cpp:279 engines/scumm/help.cpp:284
+#: engines/scumm/help.cpp:280 engines/scumm/help.cpp:285
msgid "Switching characters:"
msgstr "Veksle karakterar:"
-#: engines/scumm/help.cpp:281
+#: engines/scumm/help.cpp:282
msgid "Second kid"
msgstr "Andre unge"
-#: engines/scumm/help.cpp:282
+#: engines/scumm/help.cpp:283
msgid "Third kid"
msgstr "Tredje unge"
-#: engines/scumm/help.cpp:294
+#: engines/scumm/help.cpp:292
+msgid "Toggle Inventory/IQ Points display"
+msgstr ""
+
+#: engines/scumm/help.cpp:293
+msgid "Toggle Keyboard/Mouse Fighting (*)"
+msgstr ""
+
+#: engines/scumm/help.cpp:295
+msgid "* Keyboard Fighting is always on,"
+msgstr ""
+
+#: engines/scumm/help.cpp:296
+msgid " so despite the in-game message this"
+msgstr ""
+
+#: engines/scumm/help.cpp:297
+msgid " actually toggles Mouse Fighting Off/On"
+msgstr ""
+
+#: engines/scumm/help.cpp:304
msgid "Fighting controls (numpad):"
msgstr "Kampkontrollar (taltastatur)"
-#: engines/scumm/help.cpp:295 engines/scumm/help.cpp:296
-#: engines/scumm/help.cpp:297
+#: engines/scumm/help.cpp:305 engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:307
msgid "Step back"
msgstr "Bakoversteg"
-#: engines/scumm/help.cpp:298
+#: engines/scumm/help.cpp:308
msgid "Block high"
msgstr "Høg blokk"
-#: engines/scumm/help.cpp:299
+#: engines/scumm/help.cpp:309
msgid "Block middle"
msgstr "Midt blokk"
-#: engines/scumm/help.cpp:300
+#: engines/scumm/help.cpp:310
msgid "Block low"
msgstr "Lav blokk"
-#: engines/scumm/help.cpp:301
+#: engines/scumm/help.cpp:311
msgid "Punch high"
msgstr "Høgt slag"
-#: engines/scumm/help.cpp:302
+#: engines/scumm/help.cpp:312
msgid "Punch middle"
msgstr "Midtslag"
-#: engines/scumm/help.cpp:303
+#: engines/scumm/help.cpp:313
msgid "Punch low"
msgstr "Lavt slag"
-#: engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:315
+msgid "Sucker punch"
+msgstr ""
+
+#: engines/scumm/help.cpp:318
msgid "These are for Indy on left."
msgstr "Gjeld Indy på Venstre side."
-#: engines/scumm/help.cpp:307
+#: engines/scumm/help.cpp:319
msgid "When Indy is on the right,"
msgstr "Med Indy på høgre side,"
-#: engines/scumm/help.cpp:308
+#: engines/scumm/help.cpp:320
msgid "7, 4, and 1 are switched with"
msgstr "byttast 7, 4, og 1 med"
-#: engines/scumm/help.cpp:309
+#: engines/scumm/help.cpp:321
msgid "9, 6, and 3, respectively."
msgstr "9, 6, og 3, henhaldsvis."
-#: engines/scumm/help.cpp:316
+#: engines/scumm/help.cpp:328
msgid "Biplane controls (numpad):"
msgstr "Flykontrollar (taltastatur)"
-#: engines/scumm/help.cpp:317
+#: engines/scumm/help.cpp:329
msgid "Fly to upper left"
msgstr "Fly til øvre venstre"
-#: engines/scumm/help.cpp:318
+#: engines/scumm/help.cpp:330
msgid "Fly to left"
msgstr "Fly til venstre"
-#: engines/scumm/help.cpp:319
+#: engines/scumm/help.cpp:331
msgid "Fly to lower left"
msgstr "Fly til nedre venstre"
-#: engines/scumm/help.cpp:320
+#: engines/scumm/help.cpp:332
msgid "Fly upwards"
msgstr "Fly oppover"
-#: engines/scumm/help.cpp:321
+#: engines/scumm/help.cpp:333
msgid "Fly straight"
msgstr "Fly rett"
-#: engines/scumm/help.cpp:322
+#: engines/scumm/help.cpp:334
msgid "Fly down"
msgstr "Fly ned"
-#: engines/scumm/help.cpp:323
+#: engines/scumm/help.cpp:335
msgid "Fly to upper right"
msgstr "Fly til øvre høgre"
-#: engines/scumm/help.cpp:324
+#: engines/scumm/help.cpp:336
msgid "Fly to right"
msgstr "Fly til høgre"
-#: engines/scumm/help.cpp:325
+#: engines/scumm/help.cpp:337
msgid "Fly to lower right"
msgstr "Fly til nedre høgre"
-#: engines/scumm/scumm.cpp:1823
+#: engines/scumm/scumm.cpp:1832
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
"but %s is missing. Using AdLib instead."
msgstr ""
-#: engines/scumm/scumm.cpp:2594
+#: engines/scumm/scumm.cpp:2644
+#, fuzzy
msgid ""
-"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
-"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
-"directory inside the Tentacle game directory."
+"Usually, Maniac Mansion would start now. But for that to work, the game "
+"files for Maniac Mansion have to be in the 'Maniac' directory inside the "
+"Tentacle game directory, and the game has to be added to ScummVM."
msgstr ""
"Opprinneleg, skulle Maniac Mansion ha starta no. Men ScummVM støttar ikkje "
"det enno. For å spele Maniac Mansion, gå til 'Legg til spel' i ScummVM-"
@@ -3291,10 +3381,42 @@ msgstr ""
msgid "Show the current number of frames per second in the upper left corner"
msgstr ""
-#~ msgctxt "lowres"
-#~ msgid "Mass Add..."
-#~ msgstr "Legg til fleire..."
+#: engines/zvision/detection.cpp:256
+msgid "Double FPS"
+msgstr ""
+#: engines/zvision/detection.cpp:257
+msgid "Increase game FPS from 30 to 60"
+msgstr ""
+
+#: engines/zvision/detection.cpp:266
+#, fuzzy
+msgid "Enable Venus"
+msgstr "Grafikkmodus:"
+
+#: engines/zvision/detection.cpp:267
+msgid "Enable the Venus help system"
+msgstr ""
+
+#: engines/zvision/detection.cpp:276
+msgid "Disable animation while turning"
+msgstr ""
+
+#: engines/zvision/detection.cpp:277
+msgid "Disable animation while turning in panoramic mode"
+msgstr ""
+
+#: engines/zvision/detection.cpp:286
+msgid "Use the hires MPEG movies"
+msgstr ""
+
+#: engines/zvision/detection.cpp:287
+#, fuzzy
+msgid ""
+"Use the hires MPEG movies of the DVD version, instead of the lowres AVI ones"
+msgstr "Nytt det alternative settet med sølvpeikarar, istaden for dei gylne"
+
+#~ msgctxt "lowres"
#~ msgid "Mass Add..."
#~ msgstr "Legg til fleire..."
diff --git a/po/pl_PL.po b/po/pl_PL.po
index 83df595da5..c131023dfc 100644
--- a/po/pl_PL.po
+++ b/po/pl_PL.po
@@ -1,5 +1,5 @@
# Polish translation for ScummVM.
-# Copyright (C) 2010-2014 ScummVM Team
+# Copyright (C) 2010-2015 The ScummVM Team
# This file is distributed under the same license as the ScummVM package.
# Grajpopolsku.pl <grajpopolsku@gmail.com>, 2011-2013.
#
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.3.0\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2014-10-04 00:58+0100\n"
+"POT-Creation-Date: 2015-06-30 20:57+0100\n"
"PO-Revision-Date: 2014-07-02 12:28+0100\n"
"Last-Translator: Micha³ Zi±bkowski <mziab@o2.pl>\n"
"Language-Team: Grajpopolsku.pl <grajpopolsku@gmail.com>\n"
@@ -56,10 +56,11 @@ msgstr "W górê"
#: gui/browser.cpp:75 gui/chooser.cpp:46 gui/KeysDialog.cpp:43
#: gui/launcher.cpp:351 gui/massadd.cpp:95 gui/options.cpp:1239
+#: gui/recorderdialog.cpp:70 gui/recorderdialog.cpp:156
#: gui/saveload-dialog.cpp:216 gui/saveload-dialog.cpp:276
-#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:922
+#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:931
#: gui/themebrowser.cpp:55 gui/fluidsynth-dialog.cpp:152
-#: engines/engine.cpp:452 backends/platform/wii/options.cpp:48
+#: engines/engine.cpp:483 backends/platform/wii/options.cpp:48
#: backends/events/default/default-events.cpp:196
#: backends/events/default/default-events.cpp:218
#: engines/drascula/saveload.cpp:49 engines/parallaction/saveload.cpp:274
@@ -72,9 +73,9 @@ msgid "Choose"
msgstr "Wybierz"
#: gui/gui-manager.cpp:117 backends/keymapper/remap-dialog.cpp:53
-#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
-#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
-#: engines/scumm/help.cpp:209
+#: engines/scumm/help.cpp:126 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:192
+#: engines/scumm/help.cpp:210
msgid "Close"
msgstr "Zamknij"
@@ -90,7 +91,7 @@ msgstr "Wy¶wietl klawiaturê"
msgid "Remap keys"
msgstr "Dostosuj klawisze"
-#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:86
+#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:87
msgid "Toggle fullscreen"
msgstr "W³±cz/wy³±cz pe³ny ekran"
@@ -104,13 +105,13 @@ msgstr "Przypisz"
#: gui/KeysDialog.cpp:42 gui/launcher.cpp:352 gui/launcher.cpp:1048
#: gui/launcher.cpp:1052 gui/massadd.cpp:92 gui/options.cpp:1240
-#: gui/saveload-dialog.cpp:923 gui/fluidsynth-dialog.cpp:153
-#: engines/engine.cpp:371 engines/engine.cpp:382
+#: gui/saveload-dialog.cpp:932 gui/fluidsynth-dialog.cpp:153
+#: engines/engine.cpp:402 engines/engine.cpp:413
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
#: engines/agos/animation.cpp:558 engines/drascula/saveload.cpp:49
-#: engines/groovie/script.cpp:399 engines/parallaction/saveload.cpp:274
-#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1825
+#: engines/groovie/script.cpp:408 engines/parallaction/saveload.cpp:274
+#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1834
#: engines/scumm/players/player_v3m.cpp:130
#: engines/scumm/players/player_v5m.cpp:108 engines/sky/compact.cpp:131
#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:524
@@ -477,7 +478,7 @@ msgstr ""
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -487,7 +488,7 @@ msgstr "Tak"
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -523,6 +524,14 @@ msgstr "Ta gra nie wspiera wczytywania z launchera."
msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr "ScummVM nie znalaz³ silnika zdolnego uruchomiæ wybran± grê!"
+#: gui/launcher.cpp:1159
+msgid "Mass Add..."
+msgstr "Masowe dodawanie..."
+
+#: gui/launcher.cpp:1161
+msgid "Record..."
+msgstr ""
+
#: gui/massadd.cpp:79 gui/massadd.cpp:82
msgid "... progress ..."
msgstr "... postêp ..."
@@ -621,7 +630,7 @@ msgid "Special dithering modes supported by some games"
msgstr "Specjalne tryby ditheringu wspierane przez niektóre gry"
#: gui/options.cpp:760
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2249
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2298
msgid "Fullscreen mode"
msgstr "Pe³ny ekran"
@@ -938,6 +947,43 @@ msgstr ""
"Wybrany styl nie obs³uguje obecnego jêzyka. Je¶li chcesz go u¿ywaæ, zmieñ "
"najpierw swój jêzyk."
+#: gui/recorderdialog.cpp:64
+msgid "Recorder or Playback Gameplay"
+msgstr ""
+
+#: gui/recorderdialog.cpp:69 gui/recorderdialog.cpp:156
+#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
+msgid "Delete"
+msgstr "Skasuj"
+
+#: gui/recorderdialog.cpp:71
+msgid "Record"
+msgstr ""
+
+#: gui/recorderdialog.cpp:72
+#, fuzzy
+msgid "Playback"
+msgstr "Uruchom"
+
+#: gui/recorderdialog.cpp:74
+msgid "Edit"
+msgstr ""
+
+#: gui/recorderdialog.cpp:86 gui/recorderdialog.cpp:243
+#: gui/recorderdialog.cpp:253
+msgid "Author: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:87 gui/recorderdialog.cpp:244
+#: gui/recorderdialog.cpp:254
+msgid "Notes: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:155
+#, fuzzy
+msgid "Do you really want to delete this record?"
+msgstr "Na pewno chcesz skasowaæ ten zapis?"
+
#: gui/saveload-dialog.cpp:167
msgid "List view"
msgstr "Widok listy"
@@ -958,23 +1004,19 @@ msgstr "Brak godziny"
msgid "No playtime saved"
msgstr "Brak czasu gry"
-#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
-msgid "Delete"
-msgstr "Skasuj"
-
#: gui/saveload-dialog.cpp:275
msgid "Do you really want to delete this saved game?"
msgstr "Na pewno chcesz skasowaæ ten zapis?"
-#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:875
+#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:884
msgid "Date: "
msgstr "Data: "
-#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:881
+#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:890
msgid "Time: "
msgstr "Czas: "
-#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:889
+#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:898
msgid "Playtime: "
msgstr "Czas gry: "
@@ -990,19 +1032,19 @@ msgstr "Nastêpny"
msgid "Prev"
msgstr "Poprzedni"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "New Save"
msgstr "Nowy zapis"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "Create a new save game"
msgstr "Stwórz nowy zapis"
-#: gui/saveload-dialog.cpp:868
+#: gui/saveload-dialog.cpp:877
msgid "Name: "
msgstr "Nazwa: "
-#: gui/saveload-dialog.cpp:940
+#: gui/saveload-dialog.cpp:949
#, c-format
msgid "Enter a description for slot %d:"
msgstr "Podaj opis dla slotu %d:"
@@ -1154,7 +1196,7 @@ msgstr "Pomiñ liniê"
msgid "Error running game:"
msgstr "B³±d podczas uruchamiania gry:"
-#: base/main.cpp:536
+#: base/main.cpp:554
msgid "Could not find any engine capable of running the selected game"
msgstr "Nie uda³o siê znale¼æ silnika zdolnego do uruchomienia zaznaczonej gry"
@@ -1271,7 +1313,7 @@ msgstr "~P~owrót do launchera"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:803
#: engines/cruise/menu.cpp:212 engines/drascula/saveload.cpp:336
#: engines/dreamweb/saveload.cpp:261 engines/neverhood/menumodule.cpp:873
-#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:758
+#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:759
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save game:"
msgstr "Zapis:"
@@ -1284,7 +1326,7 @@ msgstr "Zapis:"
#: engines/agi/saveload.cpp:803 engines/cruise/menu.cpp:212
#: engines/drascula/saveload.cpp:336 engines/dreamweb/saveload.cpp:261
#: engines/neverhood/menumodule.cpp:873 engines/pegasus/pegasus.cpp:377
-#: engines/sci/engine/kfile.cpp:758 engines/scumm/dialogs.cpp:188
+#: engines/sci/engine/kfile.cpp:759 engines/scumm/dialogs.cpp:188
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save"
msgstr "Zapisz"
@@ -1322,23 +1364,23 @@ msgstr "~A~nuluj"
msgid "~K~eys"
msgstr "~K~lawisze"
-#: engines/engine.cpp:245
+#: engines/engine.cpp:276
msgid "Could not initialize color format."
msgstr "Nie uda³o siê zainicjalizowaæ formatu kolorów."
-#: engines/engine.cpp:253
+#: engines/engine.cpp:284
msgid "Could not switch to video mode: '"
msgstr "Nie uda³o siê prze³±czyæ w tryb wideo: '"
-#: engines/engine.cpp:262
+#: engines/engine.cpp:293
msgid "Could not apply aspect ratio setting."
msgstr "Nie uda³o siê zastosowaæ ustawienia formatu obrazu."
-#: engines/engine.cpp:267
+#: engines/engine.cpp:298
msgid "Could not apply fullscreen setting."
msgstr "Nie uda³o siê zastosowaæ ustawienia pe³nego ekranu."
-#: engines/engine.cpp:367
+#: engines/engine.cpp:398
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1350,7 +1392,7 @@ msgstr ""
"znane problemów. St±d zalecane jest skopiowanie plików gry na twardy dysk.\n"
"Dalsze informacje s± dostêpne w pliku README."
-#: engines/engine.cpp:378
+#: engines/engine.cpp:409
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1362,7 +1404,7 @@ msgstr ""
"skopiowaæ na dysk za pomoc± odpowiedniego rippera CD audio.\n"
"Dalsze informacje s± dostêpne w pliku README."
-#: engines/engine.cpp:436
+#: engines/engine.cpp:467
#, c-format
msgid ""
"Gamestate load failed (%s)! Please consult the README for basic information, "
@@ -1371,7 +1413,7 @@ msgstr ""
"Odczyt stanu gry nie powiód³ siê (%s)! Aby uzyskaæ podstawowe informacje "
"oraz dowiedzieæ jak szukaæ dalszej pomocy, sprawd¼ plik README."
-#: engines/engine.cpp:449
+#: engines/engine.cpp:480
msgid ""
"WARNING: The game you are about to start is not yet fully supported by "
"ScummVM. As such, it is likely to be unstable, and any saves you make might "
@@ -1381,7 +1423,7 @@ msgstr ""
"ScummVM. W zwi±zku z tym mo¿e byæ ona niestabilna, a wszelkie zapisy, "
"których dokonasz, mog± byæ nieobs³ugiwane w przysz³ych wersjach ScummVM."
-#: engines/engine.cpp:452
+#: engines/engine.cpp:483
msgid "Start anyway"
msgstr "W³±cz mimo tego"
@@ -1591,11 +1633,11 @@ msgstr "Tryb touchpada w³±czony."
msgid "Touchpad mode disabled."
msgstr "Tryb touchpada wy³±czony."
-#: backends/platform/maemo/maemo.cpp:209
+#: backends/platform/maemo/maemo.cpp:208
msgid "Click Mode"
msgstr "Tryb klikania"
-#: backends/platform/maemo/maemo.cpp:215
+#: backends/platform/maemo/maemo.cpp:214
#: backends/platform/symbian/src/SymbianActions.cpp:42
#: backends/platform/wince/CEActionsPocket.cpp:60
#: backends/platform/wince/CEActionsSmartphone.cpp:43
@@ -1603,11 +1645,11 @@ msgstr "Tryb klikania"
msgid "Left Click"
msgstr "Klikniêcie LPM"
-#: backends/platform/maemo/maemo.cpp:218
+#: backends/platform/maemo/maemo.cpp:217
msgid "Middle Click"
msgstr "¦rodkowy przycisk"
-#: backends/platform/maemo/maemo.cpp:221
+#: backends/platform/maemo/maemo.cpp:220
#: backends/platform/symbian/src/SymbianActions.cpp:43
#: backends/platform/wince/CEActionsSmartphone.cpp:44
#: backends/platform/tizen/form.cpp:267
@@ -1644,19 +1686,19 @@ msgctxt "lowres"
msgid "Normal (no scaling)"
msgstr "Zwyk³y (bez skalowania)"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2148
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2197
msgid "Enabled aspect ratio correction"
msgstr "W³±czono korekcjê formatu obrazu"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2154
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2203
msgid "Disabled aspect ratio correction"
msgstr "Wy³±czono korekcjê formatu obrazu"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2209
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2258
msgid "Active graphics filter:"
msgstr "Aktywny filtr graficzny:"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2251
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2300
msgid "Windowed mode"
msgstr "Okno"
@@ -1715,8 +1757,8 @@ msgstr "Tryb szybki"
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
#: backends/events/default/default-events.cpp:218
-#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:82
-#: engines/scumm/help.cpp:84
+#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:83
+#: engines/scumm/help.cpp:85
msgid "Quit"
msgstr "Zakoñcz"
@@ -1736,7 +1778,7 @@ msgstr "Wirtualna klawiatura"
msgid "Key mapper"
msgstr "Mapper klawiszy"
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
msgid "Do you want to quit ?"
msgstr "Chcesz wyj¶æ?"
@@ -2069,33 +2111,54 @@ msgstr "Klikanie w³±czone"
msgid "Clicking Disabled"
msgstr "Klikanie wy³±czone"
-#: engines/agi/detection.cpp:142 engines/drascula/detection.cpp:302
+#: engines/agi/detection.cpp:147 engines/drascula/detection.cpp:302
#: engines/dreamweb/detection.cpp:47 engines/neverhood/detection.cpp:160
#: engines/sci/detection.cpp:394 engines/toltecs/detection.cpp:200
-#: engines/zvision/detection.cpp:103
+#: engines/zvision/detection.cpp:246
msgid "Use original save/load screens"
msgstr "U¿yj oryginalnych ekranów odczytu/zapisu"
-#: engines/agi/detection.cpp:143 engines/drascula/detection.cpp:303
+#: engines/agi/detection.cpp:148 engines/drascula/detection.cpp:303
#: engines/dreamweb/detection.cpp:48 engines/neverhood/detection.cpp:161
#: engines/sci/detection.cpp:395 engines/toltecs/detection.cpp:201
-#: engines/zvision/detection.cpp:104
+#: engines/zvision/detection.cpp:247
msgid "Use the original save/load screens, instead of the ScummVM ones"
msgstr "U¿yj oryginalnych ekranów odczytu/zapisu zamiast tych ze ScummVM"
+#: engines/agi/detection.cpp:157
+#, fuzzy
+msgid "Use an alternative palette"
+msgstr "U¿yj alternatywnego intra (tylko dla wersji CD)"
+
+#: engines/agi/detection.cpp:158
+msgid ""
+"Use an alternative palette, common for all Amiga games. This was the old "
+"behavior"
+msgstr ""
+
+#: engines/agi/detection.cpp:167
+#, fuzzy
+msgid "Mouse support"
+msgstr "Obs³uga pomijania"
+
+#: engines/agi/detection.cpp:168
+msgid ""
+"Enables mouse support. Allows to use mouse for movement and in game menus."
+msgstr ""
+
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore game:"
msgstr "Wznów grê:"
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore"
msgstr "Wznów"
-#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2368
+#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2377
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -2106,7 +2169,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2361
+#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2370
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -2117,7 +2180,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2379
+#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2388
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -2133,12 +2196,12 @@ msgstr ""
msgid "Cutscene file '%s' not found!"
msgstr "Nie znaleziono pliku przerywnika '%s'!"
-#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:81
+#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:101
#, fuzzy
msgid "Color Blind Mode"
msgstr "Tryb klikania"
-#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:82
+#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:102
msgid "Enable Color Blind Mode by default"
msgstr ""
@@ -2189,7 +2252,7 @@ msgstr "Przy¶pieszone filmy"
msgid "Play movies at an increased speed"
msgstr "Odtwarzaj filmy ze zwiêkszon± prêdko¶ci±"
-#: engines/groovie/script.cpp:399
+#: engines/groovie/script.cpp:408
msgid "Failed to save game"
msgstr "Nie uda³o siê zapisaæ stanu gry"
@@ -2485,12 +2548,12 @@ msgid "Use an alternative game intro (CD version only)"
msgstr "U¿yj alternatywnego intra (tylko dla wersji CD)"
#: engines/sci/detection.cpp:374
-msgid "EGA undithering"
-msgstr "Anty-dithering EGA"
+msgid "Skip EGA dithering pass (full color backgrounds)"
+msgstr ""
#: engines/sci/detection.cpp:375
-msgid "Enable undithering in EGA games"
-msgstr "W³±cz anty-dithering we wspieranych grach EGA"
+msgid "Skip dithering pass in EGA games, graphics are shown with full colors"
+msgstr ""
#: engines/sci/detection.cpp:384
msgid "Prefer digital sound effects"
@@ -2563,12 +2626,14 @@ msgstr "Gra wstrzymana. Naci¶nij spacjê, aby wznowiæ."
#. "Moechten Sie wirklich neu starten? (J/N)J"
#. Will react to J as 'Yes'
#: engines/scumm/dialogs.cpp:183
-msgid "Are you sure you want to restart? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to restart? (Y/N)Y"
msgstr "Na pewno chcesz zrestartowaæ grê? (T/N)T"
#. I18N: you may specify 'Yes' symbol at the end of the line. See previous comment
#: engines/scumm/dialogs.cpp:185
-msgid "Are you sure you want to quit? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to quit? (Y/N)Y"
msgstr "Na pewno chcesz wyj¶æ? (T/N)T"
#: engines/scumm/dialogs.cpp:190
@@ -2656,516 +2721,541 @@ msgstr "Trening"
msgid "Expert"
msgstr "Ekspert"
-#: engines/scumm/help.cpp:73
+#: engines/scumm/help.cpp:74
msgid "Common keyboard commands:"
msgstr "Skróty klawiaturowe:"
-#: engines/scumm/help.cpp:74
+#: engines/scumm/help.cpp:75
msgid "Save / Load dialog"
msgstr "Okno Zapisz / Wczytaj"
-#: engines/scumm/help.cpp:76
+#: engines/scumm/help.cpp:77
msgid "Skip line of text"
msgstr "Pomiñ linijkê tekstu"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Esc"
msgstr "Esc"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Skip cutscene"
msgstr "Pomiñ scenkê"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Space"
msgstr "Spacja"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Pause game"
msgstr "Wstrzymaj grê"
-#: engines/scumm/help.cpp:79 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:95 engines/scumm/help.cpp:96
-#: engines/scumm/help.cpp:97 engines/scumm/help.cpp:98
-#: engines/scumm/help.cpp:99 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:96 engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98 engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Ctrl"
msgstr "Ctrl"
-#: engines/scumm/help.cpp:79
+#: engines/scumm/help.cpp:80
msgid "Load game state 1-10"
msgstr "Wczytaj stan gry 1-10"
-#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:81 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Alt"
msgstr "Alt"
-#: engines/scumm/help.cpp:80
+#: engines/scumm/help.cpp:81
msgid "Save game state 1-10"
msgstr "Zapisz stan gry 1-10"
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:90
msgid "Enter"
msgstr "Enter"
-#: engines/scumm/help.cpp:87
+#: engines/scumm/help.cpp:88
msgid "Music volume up / down"
msgstr "Zwiêksz/zmniejsz g³o¶no¶æ muzyki"
-#: engines/scumm/help.cpp:88
+#: engines/scumm/help.cpp:89
msgid "Text speed slower / faster"
msgstr "Zwiêksz/zmniejsz prêdko¶æ tekstu"
-#: engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:90
msgid "Simulate left mouse button"
msgstr "Symuluje lewy przycisk myszy"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Tab"
msgstr "Tab"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Simulate right mouse button"
msgstr "Symuluje prawy przycisk myszy"
-#: engines/scumm/help.cpp:93
+#: engines/scumm/help.cpp:94
msgid "Special keyboard commands:"
msgstr "Specjalne skróty klawiaturowe:"
-#: engines/scumm/help.cpp:94
+#: engines/scumm/help.cpp:95
msgid "Show / Hide console"
msgstr "Schowaj / poka¿ konsolê"
-#: engines/scumm/help.cpp:95
+#: engines/scumm/help.cpp:96
msgid "Start the debugger"
msgstr "W³±cz debugger"
-#: engines/scumm/help.cpp:96
+#: engines/scumm/help.cpp:97
msgid "Show memory consumption"
msgstr "Poka¿ zu¿ycie pamiêci"
-#: engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98
msgid "Run in fast mode (*)"
msgstr "W³±cz w trybie szybkim (*)"
-#: engines/scumm/help.cpp:98
+#: engines/scumm/help.cpp:99
msgid "Run in really fast mode (*)"
msgstr "W³±cz w trybie bardzo szybkim (*)"
-#: engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100
msgid "Toggle mouse capture"
msgstr "W³±cz/wy³±cz przechwytywanie myszy"
-#: engines/scumm/help.cpp:100
+#: engines/scumm/help.cpp:101
msgid "Switch between graphics filters"
msgstr "Prze³±czaj pomiêdzy filtrami grafiki"
-#: engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102
msgid "Increase / Decrease scale factor"
msgstr "Zwiêksz / zmniejsz wspó³czynnik skalowania"
-#: engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:103
msgid "Toggle aspect-ratio correction"
msgstr "W³±cz/wy³±cz korekcjê formatu obrazu"
-#: engines/scumm/help.cpp:107
+#: engines/scumm/help.cpp:108
msgid "* Note that using ctrl-f and"
msgstr "* Miej na uwadze, ¿e u¿ywanie ctrl-f"
-#: engines/scumm/help.cpp:108
+#: engines/scumm/help.cpp:109
msgid " ctrl-g are not recommended"
msgstr " i ctrl-g nie jest wskazane"
-#: engines/scumm/help.cpp:109
+#: engines/scumm/help.cpp:110
msgid " since they may cause crashes"
msgstr " poniewa¿ mog± one spowodowaæ zawieszenie siê,"
-#: engines/scumm/help.cpp:110
+#: engines/scumm/help.cpp:111
msgid " or incorrect game behavior."
msgstr " b±d¼ nieodpowiednie zachowanie gry."
-#: engines/scumm/help.cpp:114
+#: engines/scumm/help.cpp:115
msgid "Spinning drafts on the keyboard:"
msgstr "Tkanie splotów na klawiaturze:"
-#: engines/scumm/help.cpp:116
+#: engines/scumm/help.cpp:117
msgid "Main game controls:"
msgstr "G³ówne sterowanie gry:"
-#: engines/scumm/help.cpp:121 engines/scumm/help.cpp:136
-#: engines/scumm/help.cpp:161
+#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
+#: engines/scumm/help.cpp:162
msgid "Push"
msgstr "Pchnij"
-#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
-#: engines/scumm/help.cpp:162
+#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
+#: engines/scumm/help.cpp:163
msgid "Pull"
msgstr "Poci±gnij"
-#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
-#: engines/scumm/help.cpp:163 engines/scumm/help.cpp:197
-#: engines/scumm/help.cpp:207
+#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
+#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:198
+#: engines/scumm/help.cpp:208
msgid "Give"
msgstr "Daj"
-#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
-#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:190
-#: engines/scumm/help.cpp:208
+#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
+#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
+#: engines/scumm/help.cpp:209
msgid "Open"
msgstr "Otwórz"
-#: engines/scumm/help.cpp:126
+#: engines/scumm/help.cpp:127
msgid "Go to"
msgstr "Id¼ do"
-#: engines/scumm/help.cpp:127
+#: engines/scumm/help.cpp:128
msgid "Get"
msgstr "We¼"
-#: engines/scumm/help.cpp:128 engines/scumm/help.cpp:152
-#: engines/scumm/help.cpp:170 engines/scumm/help.cpp:198
-#: engines/scumm/help.cpp:213 engines/scumm/help.cpp:224
-#: engines/scumm/help.cpp:250
+#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:153
+#: engines/scumm/help.cpp:171 engines/scumm/help.cpp:199
+#: engines/scumm/help.cpp:214 engines/scumm/help.cpp:225
+#: engines/scumm/help.cpp:251
msgid "Use"
msgstr "U¿yj"
-#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:142
msgid "Read"
msgstr "Czytaj"
-#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:147
+#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:148
msgid "New kid"
msgstr "Nowy dzieciak"
-#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:153
-#: engines/scumm/help.cpp:171
+#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
+#: engines/scumm/help.cpp:172
msgid "Turn on"
msgstr "W³±cz"
-#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
-#: engines/scumm/help.cpp:172
+#: engines/scumm/help.cpp:133 engines/scumm/help.cpp:155
+#: engines/scumm/help.cpp:173
msgid "Turn off"
msgstr "Wy³±cz"
-#: engines/scumm/help.cpp:142 engines/scumm/help.cpp:167
-#: engines/scumm/help.cpp:194
+#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
+#: engines/scumm/help.cpp:195
msgid "Walk to"
msgstr "Podejd¼ do"
-#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
-#: engines/scumm/help.cpp:195 engines/scumm/help.cpp:210
-#: engines/scumm/help.cpp:227
+#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:228
msgid "Pick up"
msgstr "Podnie¶"
-#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:145 engines/scumm/help.cpp:170
msgid "What is"
msgstr "Czym jest"
-#: engines/scumm/help.cpp:146
+#: engines/scumm/help.cpp:147
msgid "Unlock"
msgstr "Otwórz"
-#: engines/scumm/help.cpp:149
+#: engines/scumm/help.cpp:150
msgid "Put on"
msgstr "Za³ó¿"
-#: engines/scumm/help.cpp:150
+#: engines/scumm/help.cpp:151
msgid "Take off"
msgstr "Zdejmij"
-#: engines/scumm/help.cpp:156
+#: engines/scumm/help.cpp:157
msgid "Fix"
msgstr "Napraw"
-#: engines/scumm/help.cpp:158
+#: engines/scumm/help.cpp:159
msgid "Switch"
msgstr "Prze³±cz"
-#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:228
+#: engines/scumm/help.cpp:167 engines/scumm/help.cpp:229
msgid "Look"
msgstr "Spójrz"
-#: engines/scumm/help.cpp:173 engines/scumm/help.cpp:223
+#: engines/scumm/help.cpp:174 engines/scumm/help.cpp:224
msgid "Talk"
msgstr "Rozmawiaj"
-#: engines/scumm/help.cpp:174
+#: engines/scumm/help.cpp:175
msgid "Travel"
msgstr "Podró¿uj"
-#: engines/scumm/help.cpp:175
+#: engines/scumm/help.cpp:176
msgid "To Henry / To Indy"
msgstr "Do Henry'ego / Do Indy'ego"
#. I18N: These are different musical notes
-#: engines/scumm/help.cpp:179
+#: engines/scumm/help.cpp:180
msgid "play C minor on distaff"
msgstr "zagraj c-moll na k±dzieli"
-#: engines/scumm/help.cpp:180
+#: engines/scumm/help.cpp:181
msgid "play D on distaff"
msgstr "zagraj D na k±dzieli"
-#: engines/scumm/help.cpp:181
+#: engines/scumm/help.cpp:182
msgid "play E on distaff"
msgstr "zagraj E na k±dzieli"
-#: engines/scumm/help.cpp:182
+#: engines/scumm/help.cpp:183
msgid "play F on distaff"
msgstr "zagraj F na k±dzieli"
-#: engines/scumm/help.cpp:183
+#: engines/scumm/help.cpp:184
msgid "play G on distaff"
msgstr "zagraj G na k±dzieli"
-#: engines/scumm/help.cpp:184
+#: engines/scumm/help.cpp:185
msgid "play A on distaff"
msgstr "zagraj A na k±dzieli"
-#: engines/scumm/help.cpp:185
+#: engines/scumm/help.cpp:186
msgid "play B on distaff"
msgstr "zagraj B na k±dzieli"
-#: engines/scumm/help.cpp:186
+#: engines/scumm/help.cpp:187
msgid "play C major on distaff"
msgstr "zagraj C-dur na k±dzieli"
-#: engines/scumm/help.cpp:192 engines/scumm/help.cpp:214
+#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
msgid "puSh"
msgstr "pchnij"
-#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
+#: engines/scumm/help.cpp:194 engines/scumm/help.cpp:216
msgid "pull (Yank)"
msgstr "poci±gnij"
-#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:212
-#: engines/scumm/help.cpp:248
+#: engines/scumm/help.cpp:197 engines/scumm/help.cpp:213
+#: engines/scumm/help.cpp:249
msgid "Talk to"
msgstr "Rozmawiaj z"
-#: engines/scumm/help.cpp:199 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:200 engines/scumm/help.cpp:212
msgid "Look at"
msgstr "Spójrz na"
-#: engines/scumm/help.cpp:200
+#: engines/scumm/help.cpp:201
msgid "turn oN"
msgstr "w³±cz"
-#: engines/scumm/help.cpp:201
+#: engines/scumm/help.cpp:202
msgid "turn oFf"
msgstr "wy³±cz"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "KeyUp"
msgstr "Strza³ka do góry"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "Highlight prev dialogue"
msgstr "Pod¶wietl poprzedni dialog"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "KeyDown"
msgstr "Strza³ka w dó³"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "Highlight next dialogue"
msgstr "Pod¶wietl nastêpny dialog"
-#: engines/scumm/help.cpp:222
+#: engines/scumm/help.cpp:223
msgid "Walk"
msgstr "Id¼"
-#: engines/scumm/help.cpp:225 engines/scumm/help.cpp:234
-#: engines/scumm/help.cpp:241 engines/scumm/help.cpp:249
+#: engines/scumm/help.cpp:226 engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:242 engines/scumm/help.cpp:250
msgid "Inventory"
msgstr "Ekwipunek"
-#: engines/scumm/help.cpp:226
+#: engines/scumm/help.cpp:227
msgid "Object"
msgstr "Przedmiot"
-#: engines/scumm/help.cpp:229
+#: engines/scumm/help.cpp:230
msgid "Black and White / Color"
msgstr "Czarno-bia³y / Kolorowy"
-#: engines/scumm/help.cpp:232
+#: engines/scumm/help.cpp:233
msgid "Eyes"
msgstr "Oczy"
-#: engines/scumm/help.cpp:233
+#: engines/scumm/help.cpp:234
msgid "Tongue"
msgstr "Jêzyk"
-#: engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:236
msgid "Punch"
msgstr "Piê¶æ"
-#: engines/scumm/help.cpp:236
+#: engines/scumm/help.cpp:237
msgid "Kick"
msgstr "Kopniêcie"
-#: engines/scumm/help.cpp:239 engines/scumm/help.cpp:247
+#: engines/scumm/help.cpp:240 engines/scumm/help.cpp:248
msgid "Examine"
msgstr "Zbadaj"
-#: engines/scumm/help.cpp:240
+#: engines/scumm/help.cpp:241
msgid "Regular cursor"
msgstr "Zwyk³y kursor"
#. I18N: Comm is a communication device
-#: engines/scumm/help.cpp:243
+#: engines/scumm/help.cpp:244
msgid "Comm"
msgstr "Kom."
-#: engines/scumm/help.cpp:246
+#: engines/scumm/help.cpp:247
msgid "Save / Load / Options"
msgstr "Zapis / Odczyt / Opcje"
-#: engines/scumm/help.cpp:255
+#: engines/scumm/help.cpp:256
msgid "Other game controls:"
msgstr "Reszta sterowania gry:"
-#: engines/scumm/help.cpp:257 engines/scumm/help.cpp:267
+#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:268
msgid "Inventory:"
msgstr "Ekwipunek:"
-#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:274
+#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
msgid "Scroll list up"
msgstr "Przewiñ listê do góry"
-#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
+#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:276
msgid "Scroll list down"
msgstr "Przewiñ listê w dó³"
-#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:268
+#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:269
msgid "Upper left item"
msgstr "Przedmiot u góry, z lewej"
-#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:270
+#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
msgid "Lower left item"
msgstr "Przedmiot na dole, z lewej"
-#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
+#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:272
msgid "Upper right item"
msgstr "Przedmiot u góry, z prawej"
-#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:273
+#: engines/scumm/help.cpp:264 engines/scumm/help.cpp:274
msgid "Lower right item"
msgstr "Przedmiot na dole, z prawej"
-#: engines/scumm/help.cpp:269
+#: engines/scumm/help.cpp:270
msgid "Middle left item"
msgstr "Przedmiot na ¶rodku, z lewej"
-#: engines/scumm/help.cpp:272
+#: engines/scumm/help.cpp:273
msgid "Middle right item"
msgstr "Przedmiot na ¶rodku, z prawej"
-#: engines/scumm/help.cpp:279 engines/scumm/help.cpp:284
+#: engines/scumm/help.cpp:280 engines/scumm/help.cpp:285
msgid "Switching characters:"
msgstr "Zmiana postaci:"
-#: engines/scumm/help.cpp:281
+#: engines/scumm/help.cpp:282
msgid "Second kid"
msgstr "Drugi dzieciak"
-#: engines/scumm/help.cpp:282
+#: engines/scumm/help.cpp:283
msgid "Third kid"
msgstr "Trzeci dzieciak"
-#: engines/scumm/help.cpp:294
+#: engines/scumm/help.cpp:292
+#, fuzzy
+msgid "Toggle Inventory/IQ Points display"
+msgstr "W³±cz/wy³±cz widok danych"
+
+#: engines/scumm/help.cpp:293
+msgid "Toggle Keyboard/Mouse Fighting (*)"
+msgstr ""
+
+#: engines/scumm/help.cpp:295
+msgid "* Keyboard Fighting is always on,"
+msgstr ""
+
+#: engines/scumm/help.cpp:296
+msgid " so despite the in-game message this"
+msgstr ""
+
+#: engines/scumm/help.cpp:297
+msgid " actually toggles Mouse Fighting Off/On"
+msgstr ""
+
+#: engines/scumm/help.cpp:304
msgid "Fighting controls (numpad):"
msgstr "Sterowanie podczas walki (klaw. num.):"
-#: engines/scumm/help.cpp:295 engines/scumm/help.cpp:296
-#: engines/scumm/help.cpp:297
+#: engines/scumm/help.cpp:305 engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:307
msgid "Step back"
msgstr "Odsuñ siê"
-#: engines/scumm/help.cpp:298
+#: engines/scumm/help.cpp:308
msgid "Block high"
msgstr "Wysoki blok"
-#: engines/scumm/help.cpp:299
+#: engines/scumm/help.cpp:309
msgid "Block middle"
msgstr "¦rodkowy blok"
-#: engines/scumm/help.cpp:300
+#: engines/scumm/help.cpp:310
msgid "Block low"
msgstr "Dolny blok"
-#: engines/scumm/help.cpp:301
+#: engines/scumm/help.cpp:311
msgid "Punch high"
msgstr "Wysokie uderzenie"
-#: engines/scumm/help.cpp:302
+#: engines/scumm/help.cpp:312
msgid "Punch middle"
msgstr "¦rodkowe uderzenie"
-#: engines/scumm/help.cpp:303
+#: engines/scumm/help.cpp:313
msgid "Punch low"
msgstr "Niskie uderzenie"
-#: engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:315
+msgid "Sucker punch"
+msgstr ""
+
+#: engines/scumm/help.cpp:318
msgid "These are for Indy on left."
msgstr "Te s± dla Indy'ego po lewej."
-#: engines/scumm/help.cpp:307
+#: engines/scumm/help.cpp:319
msgid "When Indy is on the right,"
msgstr "Kiedy Indy jest po prawej,"
-#: engines/scumm/help.cpp:308
+#: engines/scumm/help.cpp:320
msgid "7, 4, and 1 are switched with"
msgstr "7, 4 i 1 zostaj± zamienione"
-#: engines/scumm/help.cpp:309
+#: engines/scumm/help.cpp:321
msgid "9, 6, and 3, respectively."
msgstr "na 9, 6 i 3."
-#: engines/scumm/help.cpp:316
+#: engines/scumm/help.cpp:328
msgid "Biplane controls (numpad):"
msgstr "Sterowanie dwup³atowcem (klaw. num.):"
-#: engines/scumm/help.cpp:317
+#: engines/scumm/help.cpp:329
msgid "Fly to upper left"
msgstr "Leæ do góry, w lewo"
-#: engines/scumm/help.cpp:318
+#: engines/scumm/help.cpp:330
msgid "Fly to left"
msgstr "Leæ w lewo"
-#: engines/scumm/help.cpp:319
+#: engines/scumm/help.cpp:331
msgid "Fly to lower left"
msgstr "Leæ na dó³, w lewo"
-#: engines/scumm/help.cpp:320
+#: engines/scumm/help.cpp:332
msgid "Fly upwards"
msgstr "Leæ do góry"
-#: engines/scumm/help.cpp:321
+#: engines/scumm/help.cpp:333
msgid "Fly straight"
msgstr "Leæ prosto"
-#: engines/scumm/help.cpp:322
+#: engines/scumm/help.cpp:334
msgid "Fly down"
msgstr "Leæ w dó³"
-#: engines/scumm/help.cpp:323
+#: engines/scumm/help.cpp:335
msgid "Fly to upper right"
msgstr "Leæ do góry, w prawo"
-#: engines/scumm/help.cpp:324
+#: engines/scumm/help.cpp:336
msgid "Fly to right"
msgstr "Leæ w prawo"
-#: engines/scumm/help.cpp:325
+#: engines/scumm/help.cpp:337
msgid "Fly to lower right"
msgstr "Leæ w dó³, w prawo"
-#: engines/scumm/scumm.cpp:1823
+#: engines/scumm/scumm.cpp:1832
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
@@ -3174,11 +3264,12 @@ msgstr ""
"Natywne wsparcie MIDI wymaga aktualizacji Rolanda od LucasArts,\n"
"ale brakuje %s. Prze³±czam na tryb AdLib."
-#: engines/scumm/scumm.cpp:2594
+#: engines/scumm/scumm.cpp:2644
+#, fuzzy
msgid ""
-"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
-"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
-"directory inside the Tentacle game directory."
+"Usually, Maniac Mansion would start now. But for that to work, the game "
+"files for Maniac Mansion have to be in the 'Maniac' directory inside the "
+"Tentacle game directory, and the game has to be added to ScummVM."
msgstr ""
"Zwykle w tym momencie uruchomi³oby siê Maniac Mansion, ale ScummVM jeszcze "
"tego nie obs³uguje. Aby zagraæ, u¿yj \"Dodaj grê...\" z menu startowego "
@@ -3320,6 +3411,48 @@ msgstr ""
msgid "Show the current number of frames per second in the upper left corner"
msgstr ""
+#: engines/zvision/detection.cpp:256
+msgid "Double FPS"
+msgstr ""
+
+#: engines/zvision/detection.cpp:257
+msgid "Increase game FPS from 30 to 60"
+msgstr ""
+
+#: engines/zvision/detection.cpp:266
+#, fuzzy
+msgid "Enable Venus"
+msgstr "W³±cz tryb helowy"
+
+#: engines/zvision/detection.cpp:267
+msgid "Enable the Venus help system"
+msgstr ""
+
+#: engines/zvision/detection.cpp:276
+msgid "Disable animation while turning"
+msgstr ""
+
+#: engines/zvision/detection.cpp:277
+msgid "Disable animation while turning in panoramic mode"
+msgstr ""
+
+#: engines/zvision/detection.cpp:286
+msgid "Use the hires MPEG movies"
+msgstr ""
+
+#: engines/zvision/detection.cpp:287
+#, fuzzy
+msgid ""
+"Use the hires MPEG movies of the DVD version, instead of the lowres AVI ones"
+msgstr ""
+"U¿yj alternatywnego zestawu srebrnych kursorów zamiast zwyk³ych z³otych"
+
+#~ msgid "EGA undithering"
+#~ msgstr "Anty-dithering EGA"
+
+#~ msgid "Enable undithering in EGA games"
+#~ msgstr "W³±cz anty-dithering we wspieranych grach EGA"
+
#~ msgid "MPEG-2 cutscenes found but ScummVM has been built without MPEG-2"
#~ msgstr ""
#~ "Znaleziono przerywniki w formacie MPEG-2, ale ScummVM jest skompilowany "
@@ -3329,9 +3462,6 @@ msgstr ""
#~ msgid "Mass Add..."
#~ msgstr "Masowe dodawanie..."
-#~ msgid "Mass Add..."
-#~ msgstr "Masowe dodawanie..."
-
#~ msgid ""
#~ "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
#~ msgstr ""
diff --git a/po/pt_BR.po b/po/pt_BR.po
index 71161bde14..8280b28154 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -1,5 +1,5 @@
# Portuguese (Brazilian) translation for ScummVM.
-# Copyright (C) 2010-2014 ScummVM Team
+# Copyright (C) 2010-2015 The ScummVM Team
# This file is distributed under the same license as the ScummVM package.
# Saulo Benigno <saulobenigno@gmail.com>, 2010.
#
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.3.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2014-10-04 00:58+0100\n"
+"POT-Creation-Date: 2015-06-30 20:57+0100\n"
"PO-Revision-Date: 2011-10-21 21:30-0300\n"
"Last-Translator: Saulo Benigno <saulobenigno@gmail.com>\n"
"Language-Team: ScummBR (www.scummbr.com) <scummbr@yahoo.com.br>\n"
@@ -57,10 +57,11 @@ msgstr "Acima"
#: gui/browser.cpp:75 gui/chooser.cpp:46 gui/KeysDialog.cpp:43
#: gui/launcher.cpp:351 gui/massadd.cpp:95 gui/options.cpp:1239
+#: gui/recorderdialog.cpp:70 gui/recorderdialog.cpp:156
#: gui/saveload-dialog.cpp:216 gui/saveload-dialog.cpp:276
-#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:922
+#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:931
#: gui/themebrowser.cpp:55 gui/fluidsynth-dialog.cpp:152
-#: engines/engine.cpp:452 backends/platform/wii/options.cpp:48
+#: engines/engine.cpp:483 backends/platform/wii/options.cpp:48
#: backends/events/default/default-events.cpp:196
#: backends/events/default/default-events.cpp:218
#: engines/drascula/saveload.cpp:49 engines/parallaction/saveload.cpp:274
@@ -73,9 +74,9 @@ msgid "Choose"
msgstr "Escolher"
#: gui/gui-manager.cpp:117 backends/keymapper/remap-dialog.cpp:53
-#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
-#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
-#: engines/scumm/help.cpp:209
+#: engines/scumm/help.cpp:126 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:192
+#: engines/scumm/help.cpp:210
msgid "Close"
msgstr "Fechar"
@@ -91,7 +92,7 @@ msgstr "Mostrar teclado"
msgid "Remap keys"
msgstr "Remapear teclas"
-#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:86
+#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:87
#, fuzzy
msgid "Toggle fullscreen"
msgstr "Habilita Tela Cheia"
@@ -106,13 +107,13 @@ msgstr "Mapear"
#: gui/KeysDialog.cpp:42 gui/launcher.cpp:352 gui/launcher.cpp:1048
#: gui/launcher.cpp:1052 gui/massadd.cpp:92 gui/options.cpp:1240
-#: gui/saveload-dialog.cpp:923 gui/fluidsynth-dialog.cpp:153
-#: engines/engine.cpp:371 engines/engine.cpp:382
+#: gui/saveload-dialog.cpp:932 gui/fluidsynth-dialog.cpp:153
+#: engines/engine.cpp:402 engines/engine.cpp:413
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
#: engines/agos/animation.cpp:558 engines/drascula/saveload.cpp:49
-#: engines/groovie/script.cpp:399 engines/parallaction/saveload.cpp:274
-#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1825
+#: engines/groovie/script.cpp:408 engines/parallaction/saveload.cpp:274
+#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1834
#: engines/scumm/players/player_v3m.cpp:130
#: engines/scumm/players/player_v5m.cpp:108 engines/sky/compact.cpp:131
#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:524
@@ -482,7 +483,7 @@ msgstr ""
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -492,7 +493,7 @@ msgstr "Sim"
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -531,6 +532,14 @@ msgstr ""
"ScummVM não conseguiu encontrar qualquer programa capaz de rodar o jogo "
"selecionado!"
+#: gui/launcher.cpp:1159
+msgid "Mass Add..."
+msgstr "Multi-Adição..."
+
+#: gui/launcher.cpp:1161
+msgid "Record..."
+msgstr ""
+
#: gui/massadd.cpp:79 gui/massadd.cpp:82
msgid "... progress ..."
msgstr "... progresso ..."
@@ -633,7 +642,7 @@ msgid "Special dithering modes supported by some games"
msgstr "Modos especiais de dithering suportados por alguns jogos"
#: gui/options.cpp:760
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2249
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2298
msgid "Fullscreen mode"
msgstr "Modo Tela Cheia"
@@ -950,6 +959,43 @@ msgstr ""
"O tema que você selecionou não suporta seu idioma atual. Se você quiser usar "
"este tema você precisa mudar para outro idioma."
+#: gui/recorderdialog.cpp:64
+msgid "Recorder or Playback Gameplay"
+msgstr ""
+
+#: gui/recorderdialog.cpp:69 gui/recorderdialog.cpp:156
+#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
+msgid "Delete"
+msgstr "Excluir"
+
+#: gui/recorderdialog.cpp:71
+msgid "Record"
+msgstr ""
+
+#: gui/recorderdialog.cpp:72
+#, fuzzy
+msgid "Playback"
+msgstr "Jogar"
+
+#: gui/recorderdialog.cpp:74
+msgid "Edit"
+msgstr ""
+
+#: gui/recorderdialog.cpp:86 gui/recorderdialog.cpp:243
+#: gui/recorderdialog.cpp:253
+msgid "Author: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:87 gui/recorderdialog.cpp:244
+#: gui/recorderdialog.cpp:254
+msgid "Notes: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:155
+#, fuzzy
+msgid "Do you really want to delete this record?"
+msgstr "Você realmente quer excluir este jogo salvo?"
+
#: gui/saveload-dialog.cpp:167
msgid "List view"
msgstr ""
@@ -970,23 +1016,19 @@ msgstr "Sem hora salva"
msgid "No playtime saved"
msgstr "Sem tempo de jogo salvo"
-#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
-msgid "Delete"
-msgstr "Excluir"
-
#: gui/saveload-dialog.cpp:275
msgid "Do you really want to delete this saved game?"
msgstr "Você realmente quer excluir este jogo salvo?"
-#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:875
+#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:884
msgid "Date: "
msgstr "Data:"
-#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:881
+#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:890
msgid "Time: "
msgstr "Hora:"
-#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:889
+#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:898
msgid "Playtime: "
msgstr "Tempo de jogo:"
@@ -1002,22 +1044,22 @@ msgstr ""
msgid "Prev"
msgstr ""
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
#, fuzzy
msgid "New Save"
msgstr "Salvar"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
#, fuzzy
msgid "Create a new save game"
msgstr "Falha ao salvar o jogo"
-#: gui/saveload-dialog.cpp:868
+#: gui/saveload-dialog.cpp:877
#, fuzzy
msgid "Name: "
msgstr "Nome:"
-#: gui/saveload-dialog.cpp:940
+#: gui/saveload-dialog.cpp:949
#, c-format
msgid "Enter a description for slot %d:"
msgstr ""
@@ -1176,7 +1218,7 @@ msgstr "Pula linha"
msgid "Error running game:"
msgstr "Erro ao executar o jogo:"
-#: base/main.cpp:536
+#: base/main.cpp:554
msgid "Could not find any engine capable of running the selected game"
msgstr ""
"Não foi possível encontrar qualquer programa capaz de rodar o jogo "
@@ -1296,7 +1338,7 @@ msgstr "~V~oltar ao menu"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:803
#: engines/cruise/menu.cpp:212 engines/drascula/saveload.cpp:336
#: engines/dreamweb/saveload.cpp:261 engines/neverhood/menumodule.cpp:873
-#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:758
+#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:759
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save game:"
msgstr "Salvar jogo:"
@@ -1309,7 +1351,7 @@ msgstr "Salvar jogo:"
#: engines/agi/saveload.cpp:803 engines/cruise/menu.cpp:212
#: engines/drascula/saveload.cpp:336 engines/dreamweb/saveload.cpp:261
#: engines/neverhood/menumodule.cpp:873 engines/pegasus/pegasus.cpp:377
-#: engines/sci/engine/kfile.cpp:758 engines/scumm/dialogs.cpp:188
+#: engines/sci/engine/kfile.cpp:759 engines/scumm/dialogs.cpp:188
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save"
msgstr "Salvar"
@@ -1348,23 +1390,23 @@ msgstr "~C~ancelar"
msgid "~K~eys"
msgstr "~T~eclas"
-#: engines/engine.cpp:245
+#: engines/engine.cpp:276
msgid "Could not initialize color format."
msgstr "Não foi possível inicializar o formato de cor."
-#: engines/engine.cpp:253
+#: engines/engine.cpp:284
msgid "Could not switch to video mode: '"
msgstr "Não foi possível alternar o modo de vídeo atual:"
-#: engines/engine.cpp:262
+#: engines/engine.cpp:293
msgid "Could not apply aspect ratio setting."
msgstr "Não foi possível aplicar a correção de proporção"
-#: engines/engine.cpp:267
+#: engines/engine.cpp:298
msgid "Could not apply fullscreen setting."
msgstr "Não foi possível aplicar a configuração de tela cheia."
-#: engines/engine.cpp:367
+#: engines/engine.cpp:398
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1378,7 +1420,7 @@ msgstr ""
"os arquivos de dados para o disco rígido.\n"
"Consulte o arquivo README para mais detalhes."
-#: engines/engine.cpp:378
+#: engines/engine.cpp:409
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1392,7 +1434,7 @@ msgstr ""
"para ouvir a música do jogo.\n"
"Consulte o arquivo README para mais detalhes."
-#: engines/engine.cpp:436
+#: engines/engine.cpp:467
#, fuzzy, c-format
msgid ""
"Gamestate load failed (%s)! Please consult the README for basic information, "
@@ -1402,7 +1444,7 @@ msgstr ""
"Por favor, consulte o README para obter informações básicas, e para obter "
"instruções sobre como obter assistência adicional."
-#: engines/engine.cpp:449
+#: engines/engine.cpp:480
msgid ""
"WARNING: The game you are about to start is not yet fully supported by "
"ScummVM. As such, it is likely to be unstable, and any saves you make might "
@@ -1412,7 +1454,7 @@ msgstr ""
"suportado pelo ScummVM. Como tal, é provável que seja instável, e qualquer "
"jogo salvo que você fizer pode não funcionar em futuras versões do ScummVM."
-#: engines/engine.cpp:452
+#: engines/engine.cpp:483
msgid "Start anyway"
msgstr "Iniciar de qualquer maneira"
@@ -1623,11 +1665,11 @@ msgstr "Modo Touchpad ligado."
msgid "Touchpad mode disabled."
msgstr "Modo Touchpad desligado."
-#: backends/platform/maemo/maemo.cpp:209
+#: backends/platform/maemo/maemo.cpp:208
msgid "Click Mode"
msgstr ""
-#: backends/platform/maemo/maemo.cpp:215
+#: backends/platform/maemo/maemo.cpp:214
#: backends/platform/symbian/src/SymbianActions.cpp:42
#: backends/platform/wince/CEActionsPocket.cpp:60
#: backends/platform/wince/CEActionsSmartphone.cpp:43
@@ -1635,12 +1677,12 @@ msgstr ""
msgid "Left Click"
msgstr "Clique com o botão esquerdo"
-#: backends/platform/maemo/maemo.cpp:218
+#: backends/platform/maemo/maemo.cpp:217
#, fuzzy
msgid "Middle Click"
msgstr "Item do meio na esquerda"
-#: backends/platform/maemo/maemo.cpp:221
+#: backends/platform/maemo/maemo.cpp:220
#: backends/platform/symbian/src/SymbianActions.cpp:43
#: backends/platform/wince/CEActionsSmartphone.cpp:44
#: backends/platform/tizen/form.cpp:267
@@ -1677,19 +1719,19 @@ msgctxt "lowres"
msgid "Normal (no scaling)"
msgstr "Normal (sem escala)"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2148
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2197
msgid "Enabled aspect ratio correction"
msgstr "Correção de proporção habilitada"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2154
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2203
msgid "Disabled aspect ratio correction"
msgstr "Correção de proporção desabilitada"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2209
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2258
msgid "Active graphics filter:"
msgstr "Ativa os filtros gráficos"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2251
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2300
msgid "Windowed mode"
msgstr "Modo janela"
@@ -1749,8 +1791,8 @@ msgstr "Modo rápido"
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
#: backends/events/default/default-events.cpp:218
-#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:82
-#: engines/scumm/help.cpp:84
+#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:83
+#: engines/scumm/help.cpp:85
msgid "Quit"
msgstr "Sair"
@@ -1770,7 +1812,7 @@ msgstr "Teclado virtual"
msgid "Key mapper"
msgstr "Mapeador de Teclas"
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
msgid "Do you want to quit ?"
msgstr "Você deseja sair ?"
@@ -2107,33 +2149,52 @@ msgstr "Clicando Habilitado"
msgid "Clicking Disabled"
msgstr "Clicando Desabilitado"
-#: engines/agi/detection.cpp:142 engines/drascula/detection.cpp:302
+#: engines/agi/detection.cpp:147 engines/drascula/detection.cpp:302
#: engines/dreamweb/detection.cpp:47 engines/neverhood/detection.cpp:160
#: engines/sci/detection.cpp:394 engines/toltecs/detection.cpp:200
-#: engines/zvision/detection.cpp:103
+#: engines/zvision/detection.cpp:246
msgid "Use original save/load screens"
msgstr ""
-#: engines/agi/detection.cpp:143 engines/drascula/detection.cpp:303
+#: engines/agi/detection.cpp:148 engines/drascula/detection.cpp:303
#: engines/dreamweb/detection.cpp:48 engines/neverhood/detection.cpp:161
#: engines/sci/detection.cpp:395 engines/toltecs/detection.cpp:201
-#: engines/zvision/detection.cpp:104
+#: engines/zvision/detection.cpp:247
msgid "Use the original save/load screens, instead of the ScummVM ones"
msgstr ""
+#: engines/agi/detection.cpp:157
+msgid "Use an alternative palette"
+msgstr ""
+
+#: engines/agi/detection.cpp:158
+msgid ""
+"Use an alternative palette, common for all Amiga games. This was the old "
+"behavior"
+msgstr ""
+
+#: engines/agi/detection.cpp:167
+msgid "Mouse support"
+msgstr ""
+
+#: engines/agi/detection.cpp:168
+msgid ""
+"Enables mouse support. Allows to use mouse for movement and in game menus."
+msgstr ""
+
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore game:"
msgstr "Restaurar jogo:"
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore"
msgstr "Restaurar"
-#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2368
+#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2377
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -2144,7 +2205,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2361
+#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2370
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -2155,7 +2216,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2379
+#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2388
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -2171,11 +2232,11 @@ msgstr ""
msgid "Cutscene file '%s' not found!"
msgstr "Arquivo de vídeo '%s' não encontrado!"
-#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:81
+#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:101
msgid "Color Blind Mode"
msgstr ""
-#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:82
+#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:102
msgid "Enable Color Blind Mode by default"
msgstr ""
@@ -2236,7 +2297,7 @@ msgstr "Modo rápido"
msgid "Play movies at an increased speed"
msgstr ""
-#: engines/groovie/script.cpp:399
+#: engines/groovie/script.cpp:408
msgid "Failed to save game"
msgstr "Falha ao salvar o jogo"
@@ -2544,13 +2605,12 @@ msgid "Use an alternative game intro (CD version only)"
msgstr ""
#: engines/sci/detection.cpp:374
-msgid "EGA undithering"
-msgstr "EGA sem dithering"
+msgid "Skip EGA dithering pass (full color backgrounds)"
+msgstr ""
#: engines/sci/detection.cpp:375
-#, fuzzy
-msgid "Enable undithering in EGA games"
-msgstr "Habilita EGA sem dithering em jogos com suporte"
+msgid "Skip dithering pass in EGA games, graphics are shown with full colors"
+msgstr ""
#: engines/sci/detection.cpp:384
#, fuzzy
@@ -2621,12 +2681,14 @@ msgstr "Jogo pausado. Pressione ESPAÇO para continuar."
#. "Moechten Sie wirklich neu starten? (J/N)J"
#. Will react to J as 'Yes'
#: engines/scumm/dialogs.cpp:183
-msgid "Are you sure you want to restart? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to restart? (Y/N)Y"
msgstr "Tem certeza de que deseja reiniciar? (S/N)S"
#. I18N: you may specify 'Yes' symbol at the end of the line. See previous comment
#: engines/scumm/dialogs.cpp:185
-msgid "Are you sure you want to quit? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to quit? (Y/N)Y"
msgstr "Tem certeza de que deseja sair? (S/N)S"
#: engines/scumm/dialogs.cpp:190
@@ -2714,516 +2776,540 @@ msgstr ""
msgid "Expert"
msgstr ""
-#: engines/scumm/help.cpp:73
+#: engines/scumm/help.cpp:74
msgid "Common keyboard commands:"
msgstr "Comandos de teclado comuns:"
-#: engines/scumm/help.cpp:74
+#: engines/scumm/help.cpp:75
msgid "Save / Load dialog"
msgstr "Menu Salvar / Carregar"
-#: engines/scumm/help.cpp:76
+#: engines/scumm/help.cpp:77
msgid "Skip line of text"
msgstr "Pula linha de texto"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Esc"
msgstr "Esc"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Skip cutscene"
msgstr "Pula cena"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Space"
msgstr "Espaço"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Pause game"
msgstr "Pausar jogo:"
-#: engines/scumm/help.cpp:79 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:95 engines/scumm/help.cpp:96
-#: engines/scumm/help.cpp:97 engines/scumm/help.cpp:98
-#: engines/scumm/help.cpp:99 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:96 engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98 engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Ctrl"
msgstr "Ctrl"
-#: engines/scumm/help.cpp:79
+#: engines/scumm/help.cpp:80
msgid "Load game state 1-10"
msgstr "Carregar estado do jogo 1-10"
-#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:81 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Alt"
msgstr "Alt"
-#: engines/scumm/help.cpp:80
+#: engines/scumm/help.cpp:81
msgid "Save game state 1-10"
msgstr "Salvar estado do jogo 1-10"
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:90
msgid "Enter"
msgstr "Enter"
-#: engines/scumm/help.cpp:87
+#: engines/scumm/help.cpp:88
msgid "Music volume up / down"
msgstr "Volume da música"
-#: engines/scumm/help.cpp:88
+#: engines/scumm/help.cpp:89
msgid "Text speed slower / faster"
msgstr "Velocidade do texto devagar / rápido"
-#: engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:90
msgid "Simulate left mouse button"
msgstr "Simula botão esquerdo do mouse"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Tab"
msgstr "Tab"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Simulate right mouse button"
msgstr "Simula botão direito do mouse"
-#: engines/scumm/help.cpp:93
+#: engines/scumm/help.cpp:94
msgid "Special keyboard commands:"
msgstr "Comandos de teclado especiais:"
-#: engines/scumm/help.cpp:94
+#: engines/scumm/help.cpp:95
msgid "Show / Hide console"
msgstr "Mostrar / Ocultar console"
-#: engines/scumm/help.cpp:95
+#: engines/scumm/help.cpp:96
msgid "Start the debugger"
msgstr "Inicia o depurador"
-#: engines/scumm/help.cpp:96
+#: engines/scumm/help.cpp:97
msgid "Show memory consumption"
msgstr "Exibe o consumo de memória"
-#: engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98
msgid "Run in fast mode (*)"
msgstr "Joga em modo rápido (*)"
-#: engines/scumm/help.cpp:98
+#: engines/scumm/help.cpp:99
msgid "Run in really fast mode (*)"
msgstr "Joga em modo super rápido (*)"
-#: engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100
msgid "Toggle mouse capture"
msgstr "Habilita captura do mouse"
-#: engines/scumm/help.cpp:100
+#: engines/scumm/help.cpp:101
msgid "Switch between graphics filters"
msgstr "Alterna entre os filtros gráficos"
-#: engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102
msgid "Increase / Decrease scale factor"
msgstr "Aumenta / Diminui o fator de escala"
-#: engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:103
msgid "Toggle aspect-ratio correction"
msgstr "Habilita correção de proporção"
-#: engines/scumm/help.cpp:107
+#: engines/scumm/help.cpp:108
msgid "* Note that using ctrl-f and"
msgstr "* A utilização de ctrl-f ou"
-#: engines/scumm/help.cpp:108
+#: engines/scumm/help.cpp:109
msgid " ctrl-g are not recommended"
msgstr " ctrl-g não é recomendada"
-#: engines/scumm/help.cpp:109
+#: engines/scumm/help.cpp:110
msgid " since they may cause crashes"
msgstr " visto que poderá causar travas"
-#: engines/scumm/help.cpp:110
+#: engines/scumm/help.cpp:111
msgid " or incorrect game behavior."
msgstr " ou procedimentos estranhos nos jogos."
-#: engines/scumm/help.cpp:114
+#: engines/scumm/help.cpp:115
msgid "Spinning drafts on the keyboard:"
msgstr "Tecer feitiços no teclado:"
-#: engines/scumm/help.cpp:116
+#: engines/scumm/help.cpp:117
msgid "Main game controls:"
msgstr "Controles principais do jogo:"
-#: engines/scumm/help.cpp:121 engines/scumm/help.cpp:136
-#: engines/scumm/help.cpp:161
+#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
+#: engines/scumm/help.cpp:162
msgid "Push"
msgstr "Empurar"
-#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
-#: engines/scumm/help.cpp:162
+#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
+#: engines/scumm/help.cpp:163
msgid "Pull"
msgstr "Puxar"
-#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
-#: engines/scumm/help.cpp:163 engines/scumm/help.cpp:197
-#: engines/scumm/help.cpp:207
+#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
+#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:198
+#: engines/scumm/help.cpp:208
msgid "Give"
msgstr "Dar"
-#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
-#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:190
-#: engines/scumm/help.cpp:208
+#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
+#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
+#: engines/scumm/help.cpp:209
msgid "Open"
msgstr "Abrir"
-#: engines/scumm/help.cpp:126
+#: engines/scumm/help.cpp:127
msgid "Go to"
msgstr "Ir para"
-#: engines/scumm/help.cpp:127
+#: engines/scumm/help.cpp:128
msgid "Get"
msgstr "Pegar"
-#: engines/scumm/help.cpp:128 engines/scumm/help.cpp:152
-#: engines/scumm/help.cpp:170 engines/scumm/help.cpp:198
-#: engines/scumm/help.cpp:213 engines/scumm/help.cpp:224
-#: engines/scumm/help.cpp:250
+#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:153
+#: engines/scumm/help.cpp:171 engines/scumm/help.cpp:199
+#: engines/scumm/help.cpp:214 engines/scumm/help.cpp:225
+#: engines/scumm/help.cpp:251
msgid "Use"
msgstr "Usar"
-#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:142
msgid "Read"
msgstr "Ler"
-#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:147
+#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:148
msgid "New kid"
msgstr "Nova criança"
-#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:153
-#: engines/scumm/help.cpp:171
+#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
+#: engines/scumm/help.cpp:172
msgid "Turn on"
msgstr "Ligar"
-#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
-#: engines/scumm/help.cpp:172
+#: engines/scumm/help.cpp:133 engines/scumm/help.cpp:155
+#: engines/scumm/help.cpp:173
msgid "Turn off"
msgstr "Desligar"
-#: engines/scumm/help.cpp:142 engines/scumm/help.cpp:167
-#: engines/scumm/help.cpp:194
+#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
+#: engines/scumm/help.cpp:195
msgid "Walk to"
msgstr "Andar até"
-#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
-#: engines/scumm/help.cpp:195 engines/scumm/help.cpp:210
-#: engines/scumm/help.cpp:227
+#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:228
msgid "Pick up"
msgstr "Pegar"
-#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:145 engines/scumm/help.cpp:170
msgid "What is"
msgstr "O que é"
-#: engines/scumm/help.cpp:146
+#: engines/scumm/help.cpp:147
msgid "Unlock"
msgstr "Destravar"
-#: engines/scumm/help.cpp:149
+#: engines/scumm/help.cpp:150
msgid "Put on"
msgstr "Vestir"
-#: engines/scumm/help.cpp:150
+#: engines/scumm/help.cpp:151
msgid "Take off"
msgstr "Decolar"
-#: engines/scumm/help.cpp:156
+#: engines/scumm/help.cpp:157
msgid "Fix"
msgstr "Consertar"
-#: engines/scumm/help.cpp:158
+#: engines/scumm/help.cpp:159
msgid "Switch"
msgstr "Trocar"
-#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:228
+#: engines/scumm/help.cpp:167 engines/scumm/help.cpp:229
msgid "Look"
msgstr "Olhar"
-#: engines/scumm/help.cpp:173 engines/scumm/help.cpp:223
+#: engines/scumm/help.cpp:174 engines/scumm/help.cpp:224
msgid "Talk"
msgstr "Falar"
-#: engines/scumm/help.cpp:174
+#: engines/scumm/help.cpp:175
msgid "Travel"
msgstr "Viajar"
-#: engines/scumm/help.cpp:175
+#: engines/scumm/help.cpp:176
msgid "To Henry / To Indy"
msgstr "Para Henry / Para Indy"
#. I18N: These are different musical notes
-#: engines/scumm/help.cpp:179
+#: engines/scumm/help.cpp:180
msgid "play C minor on distaff"
msgstr "toca dó menor no fio"
-#: engines/scumm/help.cpp:180
+#: engines/scumm/help.cpp:181
msgid "play D on distaff"
msgstr "toca D no fio"
-#: engines/scumm/help.cpp:181
+#: engines/scumm/help.cpp:182
msgid "play E on distaff"
msgstr "toca E no fio"
-#: engines/scumm/help.cpp:182
+#: engines/scumm/help.cpp:183
msgid "play F on distaff"
msgstr "toca F no fio"
-#: engines/scumm/help.cpp:183
+#: engines/scumm/help.cpp:184
msgid "play G on distaff"
msgstr "toca G no fio"
-#: engines/scumm/help.cpp:184
+#: engines/scumm/help.cpp:185
msgid "play A on distaff"
msgstr "toca A no fio"
-#: engines/scumm/help.cpp:185
+#: engines/scumm/help.cpp:186
msgid "play B on distaff"
msgstr "toca B no fio"
-#: engines/scumm/help.cpp:186
+#: engines/scumm/help.cpp:187
msgid "play C major on distaff"
msgstr "toca dó maior no fio"
-#: engines/scumm/help.cpp:192 engines/scumm/help.cpp:214
+#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
msgid "puSh"
msgstr "Empurrar"
-#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
+#: engines/scumm/help.cpp:194 engines/scumm/help.cpp:216
msgid "pull (Yank)"
msgstr "Puxar"
-#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:212
-#: engines/scumm/help.cpp:248
+#: engines/scumm/help.cpp:197 engines/scumm/help.cpp:213
+#: engines/scumm/help.cpp:249
msgid "Talk to"
msgstr "Falar"
-#: engines/scumm/help.cpp:199 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:200 engines/scumm/help.cpp:212
msgid "Look at"
msgstr "Olhar para"
-#: engines/scumm/help.cpp:200
+#: engines/scumm/help.cpp:201
msgid "turn oN"
msgstr "Ligar"
-#: engines/scumm/help.cpp:201
+#: engines/scumm/help.cpp:202
msgid "turn oFf"
msgstr "Desligar"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "KeyUp"
msgstr "TeclaCima"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "Highlight prev dialogue"
msgstr "Destacar diálogo anterior"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "KeyDown"
msgstr "TeclaBaixo"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "Highlight next dialogue"
msgstr "Destacar próximo diálogo"
-#: engines/scumm/help.cpp:222
+#: engines/scumm/help.cpp:223
msgid "Walk"
msgstr "Andar"
-#: engines/scumm/help.cpp:225 engines/scumm/help.cpp:234
-#: engines/scumm/help.cpp:241 engines/scumm/help.cpp:249
+#: engines/scumm/help.cpp:226 engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:242 engines/scumm/help.cpp:250
msgid "Inventory"
msgstr "Inventário"
-#: engines/scumm/help.cpp:226
+#: engines/scumm/help.cpp:227
msgid "Object"
msgstr "Objeto"
-#: engines/scumm/help.cpp:229
+#: engines/scumm/help.cpp:230
msgid "Black and White / Color"
msgstr "Preto e Branco / Cor"
-#: engines/scumm/help.cpp:232
+#: engines/scumm/help.cpp:233
msgid "Eyes"
msgstr "Olhos"
-#: engines/scumm/help.cpp:233
+#: engines/scumm/help.cpp:234
msgid "Tongue"
msgstr "Língua"
-#: engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:236
msgid "Punch"
msgstr "Soco"
-#: engines/scumm/help.cpp:236
+#: engines/scumm/help.cpp:237
msgid "Kick"
msgstr "Chute"
-#: engines/scumm/help.cpp:239 engines/scumm/help.cpp:247
+#: engines/scumm/help.cpp:240 engines/scumm/help.cpp:248
msgid "Examine"
msgstr "Examinar"
-#: engines/scumm/help.cpp:240
+#: engines/scumm/help.cpp:241
msgid "Regular cursor"
msgstr "Cursor normal"
#. I18N: Comm is a communication device
-#: engines/scumm/help.cpp:243
+#: engines/scumm/help.cpp:244
msgid "Comm"
msgstr "Comunicador"
-#: engines/scumm/help.cpp:246
+#: engines/scumm/help.cpp:247
msgid "Save / Load / Options"
msgstr "Salvar / Carregar / Opções"
-#: engines/scumm/help.cpp:255
+#: engines/scumm/help.cpp:256
msgid "Other game controls:"
msgstr "Outros controles do jogo:"
-#: engines/scumm/help.cpp:257 engines/scumm/help.cpp:267
+#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:268
msgid "Inventory:"
msgstr "Inventário:"
-#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:274
+#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
msgid "Scroll list up"
msgstr "Subir na lista"
-#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
+#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:276
msgid "Scroll list down"
msgstr "Descer na lista"
-#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:268
+#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:269
msgid "Upper left item"
msgstr "Item da esquerda superior"
-#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:270
+#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
msgid "Lower left item"
msgstr "Item da esquerda inferior"
-#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
+#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:272
msgid "Upper right item"
msgstr "Item da direita superior"
-#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:273
+#: engines/scumm/help.cpp:264 engines/scumm/help.cpp:274
msgid "Lower right item"
msgstr "Item da direita inferior"
-#: engines/scumm/help.cpp:269
+#: engines/scumm/help.cpp:270
msgid "Middle left item"
msgstr "Item do meio na esquerda"
-#: engines/scumm/help.cpp:272
+#: engines/scumm/help.cpp:273
msgid "Middle right item"
msgstr "Item do meio na direita"
-#: engines/scumm/help.cpp:279 engines/scumm/help.cpp:284
+#: engines/scumm/help.cpp:280 engines/scumm/help.cpp:285
msgid "Switching characters:"
msgstr "Trocando personagens:"
-#: engines/scumm/help.cpp:281
+#: engines/scumm/help.cpp:282
msgid "Second kid"
msgstr "Segunda criança"
-#: engines/scumm/help.cpp:282
+#: engines/scumm/help.cpp:283
msgid "Third kid"
msgstr "Terceira criança"
-#: engines/scumm/help.cpp:294
+#: engines/scumm/help.cpp:292
+msgid "Toggle Inventory/IQ Points display"
+msgstr ""
+
+#: engines/scumm/help.cpp:293
+msgid "Toggle Keyboard/Mouse Fighting (*)"
+msgstr ""
+
+#: engines/scumm/help.cpp:295
+msgid "* Keyboard Fighting is always on,"
+msgstr ""
+
+#: engines/scumm/help.cpp:296
+msgid " so despite the in-game message this"
+msgstr ""
+
+#: engines/scumm/help.cpp:297
+msgid " actually toggles Mouse Fighting Off/On"
+msgstr ""
+
+#: engines/scumm/help.cpp:304
msgid "Fighting controls (numpad):"
msgstr "Controle de luta (teclado numérico):"
-#: engines/scumm/help.cpp:295 engines/scumm/help.cpp:296
-#: engines/scumm/help.cpp:297
+#: engines/scumm/help.cpp:305 engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:307
msgid "Step back"
msgstr "Passo para trás"
-#: engines/scumm/help.cpp:298
+#: engines/scumm/help.cpp:308
msgid "Block high"
msgstr "Defender em cima"
-#: engines/scumm/help.cpp:299
+#: engines/scumm/help.cpp:309
msgid "Block middle"
msgstr "Defender no meio"
-#: engines/scumm/help.cpp:300
+#: engines/scumm/help.cpp:310
msgid "Block low"
msgstr "Defender embaixo"
-#: engines/scumm/help.cpp:301
+#: engines/scumm/help.cpp:311
msgid "Punch high"
msgstr "Soco em cima"
-#: engines/scumm/help.cpp:302
+#: engines/scumm/help.cpp:312
msgid "Punch middle"
msgstr "Soco no meio"
-#: engines/scumm/help.cpp:303
+#: engines/scumm/help.cpp:313
msgid "Punch low"
msgstr "Soco embaixo"
-#: engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:315
+msgid "Sucker punch"
+msgstr ""
+
+#: engines/scumm/help.cpp:318
msgid "These are for Indy on left."
msgstr "Estes são para o Indy na esquerda."
-#: engines/scumm/help.cpp:307
+#: engines/scumm/help.cpp:319
msgid "When Indy is on the right,"
msgstr "Quando Indy estiver na direita,"
-#: engines/scumm/help.cpp:308
+#: engines/scumm/help.cpp:320
msgid "7, 4, and 1 are switched with"
msgstr "7, 4 e 1 são trocados por"
-#: engines/scumm/help.cpp:309
+#: engines/scumm/help.cpp:321
msgid "9, 6, and 3, respectively."
msgstr "9, 6 e 3, respectivamente."
-#: engines/scumm/help.cpp:316
+#: engines/scumm/help.cpp:328
msgid "Biplane controls (numpad):"
msgstr "Controles do avião (teclado numérico)"
-#: engines/scumm/help.cpp:317
+#: engines/scumm/help.cpp:329
msgid "Fly to upper left"
msgstr "Voar para esquerda superior"
-#: engines/scumm/help.cpp:318
+#: engines/scumm/help.cpp:330
msgid "Fly to left"
msgstr "Voar para esquerda"
-#: engines/scumm/help.cpp:319
+#: engines/scumm/help.cpp:331
msgid "Fly to lower left"
msgstr "Voar para esquerda inferior"
-#: engines/scumm/help.cpp:320
+#: engines/scumm/help.cpp:332
msgid "Fly upwards"
msgstr "Voar para cima"
-#: engines/scumm/help.cpp:321
+#: engines/scumm/help.cpp:333
msgid "Fly straight"
msgstr "Voar reto"
-#: engines/scumm/help.cpp:322
+#: engines/scumm/help.cpp:334
msgid "Fly down"
msgstr "Voar para baixo"
-#: engines/scumm/help.cpp:323
+#: engines/scumm/help.cpp:335
msgid "Fly to upper right"
msgstr "Voar para direita superior"
-#: engines/scumm/help.cpp:324
+#: engines/scumm/help.cpp:336
msgid "Fly to right"
msgstr "Voar para direita"
-#: engines/scumm/help.cpp:325
+#: engines/scumm/help.cpp:337
msgid "Fly to lower right"
msgstr "Voar para direita inferior"
-#: engines/scumm/scumm.cpp:1823
+#: engines/scumm/scumm.cpp:1832
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
@@ -3233,11 +3319,12 @@ msgstr ""
"LucasArts,\n"
"mas %s está faltando. Utilizando AdLib ao invés."
-#: engines/scumm/scumm.cpp:2594
+#: engines/scumm/scumm.cpp:2644
+#, fuzzy
msgid ""
-"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
-"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
-"directory inside the Tentacle game directory."
+"Usually, Maniac Mansion would start now. But for that to work, the game "
+"files for Maniac Mansion have to be in the 'Maniac' directory inside the "
+"Tentacle game directory, and the game has to be added to ScummVM."
msgstr ""
"\"Na versão original, o jogo Maniac Mansion rodaria agora mesmo. Porem a "
"atual versão do ScummVM não suporta essa ação. Para jogar Maniac Mansion, "
@@ -3378,6 +3465,47 @@ msgstr ""
msgid "Show the current number of frames per second in the upper left corner"
msgstr ""
+#: engines/zvision/detection.cpp:256
+msgid "Double FPS"
+msgstr ""
+
+#: engines/zvision/detection.cpp:257
+msgid "Increase game FPS from 30 to 60"
+msgstr ""
+
+#: engines/zvision/detection.cpp:266
+#, fuzzy
+msgid "Enable Venus"
+msgstr "Ligar modo Roland GS"
+
+#: engines/zvision/detection.cpp:267
+msgid "Enable the Venus help system"
+msgstr ""
+
+#: engines/zvision/detection.cpp:276
+msgid "Disable animation while turning"
+msgstr ""
+
+#: engines/zvision/detection.cpp:277
+msgid "Disable animation while turning in panoramic mode"
+msgstr ""
+
+#: engines/zvision/detection.cpp:286
+msgid "Use the hires MPEG movies"
+msgstr ""
+
+#: engines/zvision/detection.cpp:287
+msgid ""
+"Use the hires MPEG movies of the DVD version, instead of the lowres AVI ones"
+msgstr ""
+
+#~ msgid "EGA undithering"
+#~ msgstr "EGA sem dithering"
+
+#, fuzzy
+#~ msgid "Enable undithering in EGA games"
+#~ msgstr "Habilita EGA sem dithering em jogos com suporte"
+
#, fuzzy
#~ msgid "MPEG-2 cutscenes found but ScummVM has been built without MPEG-2"
#~ msgstr ""
@@ -3388,9 +3516,6 @@ msgstr ""
#~ msgid "Mass Add..."
#~ msgstr "Multi-Adição..."
-#~ msgid "Mass Add..."
-#~ msgstr "Multi-Adição..."
-
#~ msgid ""
#~ "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
#~ msgstr ""
diff --git a/po/ru_RU.po b/po/ru_RU.po
index 89ee15e7ce..066333bbb5 100644
--- a/po/ru_RU.po
+++ b/po/ru_RU.po
@@ -1,5 +1,5 @@
# Russian translation for ScummVM.
-# Copyright (C) 2010-2014 ScummVM Team
+# Copyright (C) 2010-2015 The ScummVM Team
# This file is distributed under the same license as the ScummVM package.
# Eugene Sandulenko <sev@scummvm.org>, 2010-2014
#
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.3.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2014-10-04 00:58+0100\n"
+"POT-Creation-Date: 2015-06-30 20:57+0100\n"
"PO-Revision-Date: 2014-07-02 17:20+0300\n"
"Last-Translator: Eugene Sandulenko <sev@scummvm.org>\n"
"Language-Team: Russian\n"
@@ -55,10 +55,11 @@ msgstr "²ÒÕàå"
#: gui/browser.cpp:75 gui/chooser.cpp:46 gui/KeysDialog.cpp:43
#: gui/launcher.cpp:351 gui/massadd.cpp:95 gui/options.cpp:1239
+#: gui/recorderdialog.cpp:70 gui/recorderdialog.cpp:156
#: gui/saveload-dialog.cpp:216 gui/saveload-dialog.cpp:276
-#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:922
+#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:931
#: gui/themebrowser.cpp:55 gui/fluidsynth-dialog.cpp:152
-#: engines/engine.cpp:452 backends/platform/wii/options.cpp:48
+#: engines/engine.cpp:483 backends/platform/wii/options.cpp:48
#: backends/events/default/default-events.cpp:196
#: backends/events/default/default-events.cpp:218
#: engines/drascula/saveload.cpp:49 engines/parallaction/saveload.cpp:274
@@ -71,9 +72,9 @@ msgid "Choose"
msgstr "²ëÑàÐâì"
#: gui/gui-manager.cpp:117 backends/keymapper/remap-dialog.cpp:53
-#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
-#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
-#: engines/scumm/help.cpp:209
+#: engines/scumm/help.cpp:126 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:192
+#: engines/scumm/help.cpp:210
msgid "Close"
msgstr "·ÐÚàëâì"
@@ -89,7 +90,7 @@ msgstr "¿ÞÚÐ×Ðâì ÚÛÐÒØÐâãàã"
msgid "Remap keys"
msgstr "¿ÕàÕÝÐ×ÝÐçØâì ÚÛÐÒØèØ"
-#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:86
+#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:87
msgid "Toggle fullscreen"
msgstr "¿ÕàÕÚÛîçÕÝØÕ ÝÐ ÒÕáì íÚàÐÝ"
@@ -103,13 +104,13 @@ msgstr "½Ð×ÝÐçØâì"
#: gui/KeysDialog.cpp:42 gui/launcher.cpp:352 gui/launcher.cpp:1048
#: gui/launcher.cpp:1052 gui/massadd.cpp:92 gui/options.cpp:1240
-#: gui/saveload-dialog.cpp:923 gui/fluidsynth-dialog.cpp:153
-#: engines/engine.cpp:371 engines/engine.cpp:382
+#: gui/saveload-dialog.cpp:932 gui/fluidsynth-dialog.cpp:153
+#: engines/engine.cpp:402 engines/engine.cpp:413
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
#: engines/agos/animation.cpp:558 engines/drascula/saveload.cpp:49
-#: engines/groovie/script.cpp:399 engines/parallaction/saveload.cpp:274
-#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1825
+#: engines/groovie/script.cpp:408 engines/parallaction/saveload.cpp:274
+#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1834
#: engines/scumm/players/player_v3m.cpp:130
#: engines/scumm/players/player_v5m.cpp:108 engines/sky/compact.cpp:131
#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:524
@@ -478,7 +479,7 @@ msgstr ""
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -488,7 +489,7 @@ msgstr "´Ð"
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -524,6 +525,14 @@ msgstr "ÍâÐ ØÓàÐ ÝÕ ßÞÔÔÕàÖØÒÐÕâ ×ÐÓàã×Úã áÞåàÐÝÕÝØÙ çÕàÕ× ÓÛÐÒÝÞÕ ÜÕÝî."
msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr "ScummVM ÝÕ áÜÞÓ ÝÐÙâØ ÔÒØÖÞÚ ÔÛï ×ÐßãáÚÐ ÒëÑàÐÝÝÞÙ ØÓàë!"
+#: gui/launcher.cpp:1159
+msgid "Mass Add..."
+msgstr "¼ÝÞÓÞ ØÓà..."
+
+#: gui/launcher.cpp:1161
+msgid "Record..."
+msgstr ""
+
#: gui/massadd.cpp:79 gui/massadd.cpp:82
msgid "... progress ..."
msgstr "... Øéã ..."
@@ -622,7 +631,7 @@ msgid "Special dithering modes supported by some games"
msgstr "ÁßÕæØÐÛìÝëÕ àÕÖØÜë àÕÝÔÕàØÝÓÐ, ßÞÔÔÕàÖØÒÐÕÜëÕ ÝÕÚÞâÞàëÜØ ØÓàÐÜØ"
#: gui/options.cpp:760
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2249
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2298
msgid "Fullscreen mode"
msgstr "¿ÞÛÝÞíÚàÐÝÝëÙ àÕÖØÜ"
@@ -943,6 +952,43 @@ msgstr ""
"ÂÕÜÐ, ÒëÑàÐÝÝÐï ÒÐÜØ, ÝÕ ßÞÔÔÕàÖØÒÐÕâ âÕÚãéØÙ ï×ëÚ. µáÛØ Òë åÞâØâÕ "
"ØáßÞÛì×ÞÒÐâì íâã âÕÜã, ÒÐÜ ÝÕÞÑåÞÔØÜÞ áÝÐçÐÛÐ ßÕàÕÚÛîçØâìáï ÝÐ ÔàãÓÞÙ ï×ëÚ."
+#: gui/recorderdialog.cpp:64
+msgid "Recorder or Playback Gameplay"
+msgstr ""
+
+#: gui/recorderdialog.cpp:69 gui/recorderdialog.cpp:156
+#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
+msgid "Delete"
+msgstr "ÃÔÐÛØâì"
+
+#: gui/recorderdialog.cpp:71
+msgid "Record"
+msgstr ""
+
+#: gui/recorderdialog.cpp:72
+#, fuzzy
+msgid "Playback"
+msgstr "¸ÓàÐâì"
+
+#: gui/recorderdialog.cpp:74
+msgid "Edit"
+msgstr ""
+
+#: gui/recorderdialog.cpp:86 gui/recorderdialog.cpp:243
+#: gui/recorderdialog.cpp:253
+msgid "Author: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:87 gui/recorderdialog.cpp:244
+#: gui/recorderdialog.cpp:254
+msgid "Notes: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:155
+#, fuzzy
+msgid "Do you really want to delete this record?"
+msgstr "²ë ÔÕÙáâÒØâÕÛìÝÞ åÞâØâÕ ãÔÐÛØâì íâÞ áÞåàÐÝÕÝØÕ?"
+
#: gui/saveload-dialog.cpp:167
msgid "List view"
msgstr "²ØÔ áßØáÚÐ"
@@ -963,23 +1009,19 @@ msgstr "²àÕÜï ÝÕ ×ÐßØáÐÝÞ"
msgid "No playtime saved"
msgstr "²àÕÜï ØÓàë ÝÕ ×ÐßØáÐÝÞ"
-#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
-msgid "Delete"
-msgstr "ÃÔÐÛØâì"
-
#: gui/saveload-dialog.cpp:275
msgid "Do you really want to delete this saved game?"
msgstr "²ë ÔÕÙáâÒØâÕÛìÝÞ åÞâØâÕ ãÔÐÛØâì íâÞ áÞåàÐÝÕÝØÕ?"
-#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:875
+#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:884
msgid "Date: "
msgstr "´ÐâÐ: "
-#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:881
+#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:890
msgid "Time: "
msgstr "²àÕÜï: "
-#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:889
+#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:898
msgid "Playtime: "
msgstr "²àÕÜï ØÓàë: "
@@ -995,19 +1037,19 @@ msgstr "ÁÛÕÔãîéØÙ"
msgid "Prev"
msgstr "¿àÕÔëÔãéØÙ"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "New Save"
msgstr "½ÞÒÞÕ áÞåàÐÝÕÝØÕ"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "Create a new save game"
msgstr "ÁÞ×ÔÐâì ÝÞÒãî ×ÐßØáì ØÓàë"
-#: gui/saveload-dialog.cpp:868
+#: gui/saveload-dialog.cpp:877
msgid "Name: "
msgstr "½Ð×ÒÐÝØÕ: "
-#: gui/saveload-dialog.cpp:940
+#: gui/saveload-dialog.cpp:949
#, c-format
msgid "Enter a description for slot %d:"
msgstr "²ÒÕÔØâÕ ÞßØáÐÝØÕ áÛÞâÐ %d:"
@@ -1160,7 +1202,7 @@ msgstr "¿àÞßãáâØâì áâàÞÚã"
msgid "Error running game:"
msgstr "¾èØÑÚÐ ×ÐßãáÚÐ ØÓàë:"
-#: base/main.cpp:536
+#: base/main.cpp:554
msgid "Could not find any engine capable of running the selected game"
msgstr "½Õ ÜÞÓã ÝÐÙâØ ÔÒØÖÞÚ ÔÛï ×ÐßãáÚÐ ÒëÑàÐÝÝÞÙ ØÓàë"
@@ -1278,7 +1320,7 @@ msgstr "~²~ ÓÛÐÒÝÞÕ ÜÕÝî"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:803
#: engines/cruise/menu.cpp:212 engines/drascula/saveload.cpp:336
#: engines/dreamweb/saveload.cpp:261 engines/neverhood/menumodule.cpp:873
-#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:758
+#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:759
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save game:"
msgstr "ÁÞåàÐÝØâì ØÓàã:"
@@ -1291,7 +1333,7 @@ msgstr "ÁÞåàÐÝØâì ØÓàã:"
#: engines/agi/saveload.cpp:803 engines/cruise/menu.cpp:212
#: engines/drascula/saveload.cpp:336 engines/dreamweb/saveload.cpp:261
#: engines/neverhood/menumodule.cpp:873 engines/pegasus/pegasus.cpp:377
-#: engines/sci/engine/kfile.cpp:758 engines/scumm/dialogs.cpp:188
+#: engines/sci/engine/kfile.cpp:759 engines/scumm/dialogs.cpp:188
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save"
msgstr "ÁÞåàÐÝØâì"
@@ -1330,23 +1372,23 @@ msgstr "¾~â~ÜÕÝÐ"
msgid "~K~eys"
msgstr "~º~ÛÐÒØèØ"
-#: engines/engine.cpp:245
+#: engines/engine.cpp:276
msgid "Could not initialize color format."
msgstr "½Õ ÜÞÓã ØÝØæØÐÛØ×ØàÞÒÐâì äÞàÜÐâ æÒÕâÐ."
-#: engines/engine.cpp:253
+#: engines/engine.cpp:284
msgid "Could not switch to video mode: '"
msgstr "½Õ ãÔÐÛÞáì ßÕàÕÚÛîçØâì ÒØÔÕÞàÕÖØÜ: '"
-#: engines/engine.cpp:262
+#: engines/engine.cpp:293
msgid "Could not apply aspect ratio setting."
msgstr "½Õ ãÔÐÛÞáì ØáßÞÛì×ÞÒÐâì ÚÞààÕÚæØî áÞÞâÝÞèÕÝØï áâÞàÞÝ."
-#: engines/engine.cpp:267
+#: engines/engine.cpp:298
msgid "Could not apply fullscreen setting."
msgstr "½Õ ÜÞÓã ßàØÜÕÝØâì ßÞÛÝÞíÚàÐÝÝëÙ àÕÖØÜ."
-#: engines/engine.cpp:367
+#: engines/engine.cpp:398
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1360,7 +1402,7 @@ msgstr ""
"ÝÐ ÖñáâÚØÙ ÔØáÚ. ¿ÞÔàÞÑÝÞáâØ ÜÞÖÝÞ ÝÐÙâØ Ò\n"
"äÐÙÛÕ README."
-#: engines/engine.cpp:378
+#: engines/engine.cpp:409
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1375,7 +1417,7 @@ msgstr ""
"ßÞïÒØâáï Üã×ëÚÐ. ¿ÞÔàÞÑÝÞáâØ ÜÞÖÝÞ ÝÐÙâØ Ò\n"
"äÐÙÛÕ README."
-#: engines/engine.cpp:436
+#: engines/engine.cpp:467
#, c-format
msgid ""
"Gamestate load failed (%s)! Please consult the README for basic information, "
@@ -1385,7 +1427,7 @@ msgstr ""
"README ×Ð ÑÐ×ÞÒÞÙ ØÝäÞàÜÐæØÕÙ, Ð âÐÚÖÕ ØÝáâàãÚæØïÜØ Þ âÞÜ, ÚÐÚ ßÞÛãçØâì "
"ÔÐÛìÝÕÙèãî ßÞÜÞéì."
-#: engines/engine.cpp:449
+#: engines/engine.cpp:480
msgid ""
"WARNING: The game you are about to start is not yet fully supported by "
"ScummVM. As such, it is likely to be unstable, and any saves you make might "
@@ -1395,7 +1437,7 @@ msgstr ""
"ßÞÔÔÕàÖØÒÐÕâáï ScummVM ßÞÛÝÞáâìî. ¾ÝÐ, áÚÞàÕÕ ÒáÕÓÞ, ÝÕ ÑãÔÕâ àÐÑÞâÐâì "
"áâÐÑØÛìÝÞ, Ø áÞåàÐÝÕÝØï ØÓà ÜÞÓãâ ÝÕ àÐÑÞâÐâì Ò ÑãÔãéØå ÒÕàáØïå ScummVM."
-#: engines/engine.cpp:452
+#: engines/engine.cpp:483
msgid "Start anyway"
msgstr "²áñ àÐÒÝÞ ×ÐßãáâØâì"
@@ -1605,11 +1647,11 @@ msgstr "ÀÕÖØÜ âÐçßÐÔÐ ÒÚÛîçñÝ."
msgid "Touchpad mode disabled."
msgstr "ÀÕÖØÜ âÐçßÐÔÐ ÒëÚÛîçÕÝ."
-#: backends/platform/maemo/maemo.cpp:209
+#: backends/platform/maemo/maemo.cpp:208
msgid "Click Mode"
msgstr "ÀÕÖØÜ éÕÛçÚÐ"
-#: backends/platform/maemo/maemo.cpp:215
+#: backends/platform/maemo/maemo.cpp:214
#: backends/platform/symbian/src/SymbianActions.cpp:42
#: backends/platform/wince/CEActionsPocket.cpp:60
#: backends/platform/wince/CEActionsSmartphone.cpp:43
@@ -1617,11 +1659,11 @@ msgstr "ÀÕÖØÜ éÕÛçÚÐ"
msgid "Left Click"
msgstr "»ÕÒëÙ éÕÛçÞÚ"
-#: backends/platform/maemo/maemo.cpp:218
+#: backends/platform/maemo/maemo.cpp:217
msgid "Middle Click"
msgstr "ÁàÕÔÝØÙ éÕÛçÞÚ"
-#: backends/platform/maemo/maemo.cpp:221
+#: backends/platform/maemo/maemo.cpp:220
#: backends/platform/symbian/src/SymbianActions.cpp:43
#: backends/platform/wince/CEActionsSmartphone.cpp:44
#: backends/platform/tizen/form.cpp:267
@@ -1658,19 +1700,19 @@ msgctxt "lowres"
msgid "Normal (no scaling)"
msgstr "±Õ× ãÒÕÛØçÕÝØï"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2148
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2197
msgid "Enabled aspect ratio correction"
msgstr "ºÞààÕÚæØï áÞÞâÝÞèÕÝØï áâÞàÞÝ ÒÚÛîçÕÝÐ"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2154
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2203
msgid "Disabled aspect ratio correction"
msgstr "ºÞààÕÚæØï áÞÞâÝÞèÕÝØï áâÞàÞÝ ÒëÚÛîçÕÝÐ"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2209
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2258
msgid "Active graphics filter:"
msgstr "°ÚâØÒÝëÙ ÓàÐäØçÕáÚØÙ äØÛìâà:"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2251
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2300
msgid "Windowed mode"
msgstr "¾ÚÞÝÝëÙ àÕÖØÜ"
@@ -1729,8 +1771,8 @@ msgstr "±ëáâàëÙ àÕÖØÜ"
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
#: backends/events/default/default-events.cpp:218
-#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:82
-#: engines/scumm/help.cpp:84
+#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:83
+#: engines/scumm/help.cpp:85
msgid "Quit"
msgstr "²ëåÞÔ"
@@ -1750,7 +1792,7 @@ msgstr "²ØàâãÐÛìÝÐï ÚÛÐÒØÐâãàÐ"
msgid "Key mapper"
msgstr "½Ð×ÝÐçÕÝØÕ ÚÛÐÒØè"
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
msgid "Do you want to quit ?"
msgstr "²ë ÔÕÙáâÒØâÕÛìÝÞ åÞâØâÕ ÒëÙâØ?"
@@ -2083,35 +2125,56 @@ msgstr "ÉÕÛçÚØ ÒÚÛîçÕÝë"
msgid "Clicking Disabled"
msgstr "ÉÕÛçÚØ ÒëÚÛîçÕÝë"
-#: engines/agi/detection.cpp:142 engines/drascula/detection.cpp:302
+#: engines/agi/detection.cpp:147 engines/drascula/detection.cpp:302
#: engines/dreamweb/detection.cpp:47 engines/neverhood/detection.cpp:160
#: engines/sci/detection.cpp:394 engines/toltecs/detection.cpp:200
-#: engines/zvision/detection.cpp:103
+#: engines/zvision/detection.cpp:246
msgid "Use original save/load screens"
msgstr "¸áßÞÛì×ÞÒÐâì ÞàØÓØÝÐÛìÝëÕ íÚàÐÝë ×ÐßØáØ/çâÕÝØï ØÓàë"
-#: engines/agi/detection.cpp:143 engines/drascula/detection.cpp:303
+#: engines/agi/detection.cpp:148 engines/drascula/detection.cpp:303
#: engines/dreamweb/detection.cpp:48 engines/neverhood/detection.cpp:161
#: engines/sci/detection.cpp:395 engines/toltecs/detection.cpp:201
-#: engines/zvision/detection.cpp:104
+#: engines/zvision/detection.cpp:247
msgid "Use the original save/load screens, instead of the ScummVM ones"
msgstr ""
"¸áßÞÛì×ÞÒÐâì ÞàØÓØÝÐÛìÝëÕ íÚàÐÝë ×ÐßØáØ Ø áÞåàÐÝÕÝØï ØÓàë ÒÜÕáâÞ áÔÕÛÐÝÝëå Ò "
"ScummVM"
+#: engines/agi/detection.cpp:157
+#, fuzzy
+msgid "Use an alternative palette"
+msgstr "¸áßÞÛì×ÞÒÐâì ÐÛìâÕàÝÐâØÒÝÞÕ ÒáâãßÛÕÝØÕ (âÞÛìÚÞ ÔÛï CD ÒÕàáØØ ØÓàë)"
+
+#: engines/agi/detection.cpp:158
+msgid ""
+"Use an alternative palette, common for all Amiga games. This was the old "
+"behavior"
+msgstr ""
+
+#: engines/agi/detection.cpp:167
+#, fuzzy
+msgid "Mouse support"
+msgstr "¿ÞÔÔÕàÖÚÐ ßàÞßãáÚÞÒ"
+
+#: engines/agi/detection.cpp:168
+msgid ""
+"Enables mouse support. Allows to use mouse for movement and in game menus."
+msgstr ""
+
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore game:"
msgstr "²ÞááâÐÝÞÒØâì ØÓàã:"
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore"
msgstr "²ÞááâÐÝÞÒØâì"
-#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2368
+#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2377
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -2122,7 +2185,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2361
+#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2370
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -2133,7 +2196,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2379
+#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2388
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -2149,12 +2212,12 @@ msgstr ""
msgid "Cutscene file '%s' not found!"
msgstr "ÄÐÙÛ ×ÐáâÐÒÚØ '%s' ÝÕ ÝÐÙÔÕÝ!"
-#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:81
+#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:101
#, fuzzy
msgid "Color Blind Mode"
msgstr "ÀÕÖØÜ éÕÛçÚÐ"
-#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:82
+#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:102
msgid "Enable Color Blind Mode by default"
msgstr ""
@@ -2206,7 +2269,7 @@ msgstr "ÀÕÖØÜ ãáÚÞàÕÝÝÞÓÞ ÒØÔÕÞ"
msgid "Play movies at an increased speed"
msgstr "²ÞáßàÞØ×ÒÞÔØâ ÒØÔÕÞàÞÛØÚØ á ãÒÕÛØçÕÝÝÞÙ áÚÞàÞáâìî"
-#: engines/groovie/script.cpp:399
+#: engines/groovie/script.cpp:408
msgid "Failed to save game"
msgstr "½Õ ãÔÐÛÞáì áÞåàÐÝØâì ØÓàã"
@@ -2504,12 +2567,12 @@ msgid "Use an alternative game intro (CD version only)"
msgstr "¸áßÞÛì×ÞÒÐâì ÐÛìâÕàÝÐâØÒÝÞÕ ÒáâãßÛÕÝØÕ (âÞÛìÚÞ ÔÛï CD ÒÕàáØØ ØÓàë)"
#: engines/sci/detection.cpp:374
-msgid "EGA undithering"
-msgstr "EGA ÑÕ× àÐáâàÐ"
+msgid "Skip EGA dithering pass (full color backgrounds)"
+msgstr ""
#: engines/sci/detection.cpp:375
-msgid "Enable undithering in EGA games"
-msgstr "²ÚÛîçÐÕâ àÕÖØÜ ÑÕ× àÐáâàØàÞÒÐÝØï Ò EGA ØÓàÐå"
+msgid "Skip dithering pass in EGA games, graphics are shown with full colors"
+msgstr ""
#: engines/sci/detection.cpp:384
msgid "Prefer digital sound effects"
@@ -2586,12 +2649,14 @@ msgstr "¸ÓàÐ ÞáâÐÝÞÒÛÕÝÐ. ½ÐÖÜØâÕ ßàÞÑÕÛ, çâÞÑë ßàÞÔÞÛÖØâì."
#. "Moechten Sie wirklich neu starten? (J/N)J"
#. Will react to J as 'Yes'
#: engines/scumm/dialogs.cpp:183
-msgid "Are you sure you want to restart? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to restart? (Y/N)Y"
msgstr "²ë ãÒÕàÕÝë, çâÞ åÞâØâÕ ÝÐçÐâì áÝÞÒÐ? (Y/N)"
#. I18N: you may specify 'Yes' symbol at the end of the line. See previous comment
#: engines/scumm/dialogs.cpp:185
-msgid "Are you sure you want to quit? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to quit? (Y/N)Y"
msgstr "²ë ãÒÕàÕÝë, çâÞ åÞâØâÕ ÒëÙâØ? (Y/N)"
#: engines/scumm/dialogs.cpp:190
@@ -2679,516 +2744,541 @@ msgstr "¿àÐÚâØÚÐÝâ"
msgid "Expert"
msgstr "ÍÚáßÕàâ"
-#: engines/scumm/help.cpp:73
+#: engines/scumm/help.cpp:74
msgid "Common keyboard commands:"
msgstr "¾ÑéØÕ ÚÛÐÒØÐâãàÝëÕ ÚÞÜÐÝÔë:"
-#: engines/scumm/help.cpp:74
+#: engines/scumm/help.cpp:75
msgid "Save / Load dialog"
msgstr "´ØÐÛÞÓ ×ÐßØáØ / çâÕÝØï"
-#: engines/scumm/help.cpp:76
+#: engines/scumm/help.cpp:77
msgid "Skip line of text"
msgstr "¿àÞßãáâØâì áâàÞÚã"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Esc"
msgstr "Esc"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Skip cutscene"
msgstr "¿àÞßãáâØâì ×ÐáâÐÒÚã"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Space"
msgstr "¿àÞÑÕÛ"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Pause game"
msgstr "¿Ðã×Ð ØÓàë"
-#: engines/scumm/help.cpp:79 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:95 engines/scumm/help.cpp:96
-#: engines/scumm/help.cpp:97 engines/scumm/help.cpp:98
-#: engines/scumm/help.cpp:99 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:96 engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98 engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Ctrl"
msgstr "Ctrl"
-#: engines/scumm/help.cpp:79
+#: engines/scumm/help.cpp:80
msgid "Load game state 1-10"
msgstr "·ÐÓàã×Øâì ØÓàã 1-10"
-#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:81 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Alt"
msgstr "Alt"
-#: engines/scumm/help.cpp:80
+#: engines/scumm/help.cpp:81
msgid "Save game state 1-10"
msgstr "ÁÞåàÐÝØâì ØÓàã 1-10"
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:90
msgid "Enter"
msgstr "²ÒÞÔ"
-#: engines/scumm/help.cpp:87
+#: engines/scumm/help.cpp:88
msgid "Music volume up / down"
msgstr "³àÞÜÚÞáâì Üã×ëÚØ ãÒÕÛØçØâì / ãÜÕÝìèØâì"
-#: engines/scumm/help.cpp:88
+#: engines/scumm/help.cpp:89
msgid "Text speed slower / faster"
msgstr "ÁÚÞàÞáâì âÕÚáâÐ ÑëáâàÕÕ / ÜÕÔÛÕÝÝÕÕ"
-#: engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:90
msgid "Simulate left mouse button"
msgstr "ÍÜãÛïæØï ÝÐÖÐâØï ÛÕÒÞÙ ÚÛÐÒØèØ ÜëèØ"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Tab"
msgstr "Tab"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Simulate right mouse button"
msgstr "ÍÜãÛïæØï ßàÐÒÞÙ ÚÛÐÒØèØ ÜëèØ"
-#: engines/scumm/help.cpp:93
+#: engines/scumm/help.cpp:94
msgid "Special keyboard commands:"
msgstr "ÁßÕæØÐÛìÝëÕ ÚÛÐÒØÐâãàÝëÕ ÚÞÜÐÝÔë:"
-#: engines/scumm/help.cpp:94
+#: engines/scumm/help.cpp:95
msgid "Show / Hide console"
msgstr "¿ÞÚÐ×Ðâì / ÃÑàÐâì ÚÞÝáÞÛì"
-#: engines/scumm/help.cpp:95
+#: engines/scumm/help.cpp:96
msgid "Start the debugger"
msgstr "·ÐßãáÚ ÞâÛÐÔçØÚÐ"
-#: engines/scumm/help.cpp:96
+#: engines/scumm/help.cpp:97
msgid "Show memory consumption"
msgstr "¿ÞÚÐ×Ðâì ßÞâàÕÑÛÕÝØÕ ßÐÜïâØ"
-#: engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98
msgid "Run in fast mode (*)"
msgstr "·ÐßãáâØâì ÑëáâàëÙ àÕÖØÜ (*)"
-#: engines/scumm/help.cpp:98
+#: engines/scumm/help.cpp:99
msgid "Run in really fast mode (*)"
msgstr "·ÐßãáâØâì ÞçÕÝì ÑëáâàëÙ àÕÖØÜ (*)"
-#: engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100
msgid "Toggle mouse capture"
msgstr "¿ÕàÕÚÛîçÕÝØÕ ßÕàÕåÒÐâÐ ÜëèØ"
-#: engines/scumm/help.cpp:100
+#: engines/scumm/help.cpp:101
msgid "Switch between graphics filters"
msgstr "¿ÕàÕÚÛîçÕÝØÕ ÜÕÖÔã ÓàÐäØçÕáÚØÜØ äØÛìâàÐÜØ"
-#: engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102
msgid "Increase / Decrease scale factor"
msgstr "ÃÒÕÛØçØâì/ãÜÕÝìèØâì ÜÐáèâÐÑ"
-#: engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:103
msgid "Toggle aspect-ratio correction"
msgstr "¿ÕàÕÚÛîçÕÝØÕ ÚÞààÕÚæØØ áÞÞâÝÞèÕÝØï áâÞàÞÝ"
-#: engines/scumm/help.cpp:107
+#: engines/scumm/help.cpp:108
msgid "* Note that using ctrl-f and"
msgstr "* ¸áßÞÛì×ÞÒÐÝØÕ ctrl-f Ø"
-#: engines/scumm/help.cpp:108
+#: engines/scumm/help.cpp:109
msgid " ctrl-g are not recommended"
msgstr " ctrl-g ÝÕ àÕÚÞÜÕÝÔãÕâáï,"
-#: engines/scumm/help.cpp:109
+#: engines/scumm/help.cpp:110
msgid " since they may cause crashes"
msgstr " âÐÚ ÚÐÚ ÞÝØ ÜÞÓãâ ßàØÒÕáâØ Ú"
-#: engines/scumm/help.cpp:110
+#: engines/scumm/help.cpp:111
msgid " or incorrect game behavior."
msgstr " ÝÕÒÕàÝÞÙ àÐÑÞâÕ ØÓàë."
-#: engines/scumm/help.cpp:114
+#: engines/scumm/help.cpp:115
msgid "Spinning drafts on the keyboard:"
msgstr "¸×ÜÕÝïÕÜëÕ çÕàÝÞÒØÚØ ÝÐ ÚÛÐÒØÐâãàÕ:"
-#: engines/scumm/help.cpp:116
+#: engines/scumm/help.cpp:117
msgid "Main game controls:"
msgstr "¾áÝÞÒÝÞÕ ãßàÐÒÛÕÝØÕ ØÓàÞÙ:"
-#: engines/scumm/help.cpp:121 engines/scumm/help.cpp:136
-#: engines/scumm/help.cpp:161
+#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
+#: engines/scumm/help.cpp:162
msgid "Push"
msgstr "ÂÞÛÚÐâì"
-#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
-#: engines/scumm/help.cpp:162
+#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
+#: engines/scumm/help.cpp:163
msgid "Pull"
msgstr "ÂïÝãâì"
-#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
-#: engines/scumm/help.cpp:163 engines/scumm/help.cpp:197
-#: engines/scumm/help.cpp:207
+#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
+#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:198
+#: engines/scumm/help.cpp:208
msgid "Give"
msgstr "´Ðâì"
-#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
-#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:190
-#: engines/scumm/help.cpp:208
+#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
+#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
+#: engines/scumm/help.cpp:209
msgid "Open"
msgstr "¾âÚàëâì"
-#: engines/scumm/help.cpp:126
+#: engines/scumm/help.cpp:127
msgid "Go to"
msgstr "¸ÔâØ"
-#: engines/scumm/help.cpp:127
+#: engines/scumm/help.cpp:128
msgid "Get"
msgstr "²×ïâì"
-#: engines/scumm/help.cpp:128 engines/scumm/help.cpp:152
-#: engines/scumm/help.cpp:170 engines/scumm/help.cpp:198
-#: engines/scumm/help.cpp:213 engines/scumm/help.cpp:224
-#: engines/scumm/help.cpp:250
+#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:153
+#: engines/scumm/help.cpp:171 engines/scumm/help.cpp:199
+#: engines/scumm/help.cpp:214 engines/scumm/help.cpp:225
+#: engines/scumm/help.cpp:251
msgid "Use"
msgstr "¸áßÞÛì×ÞÒÐâì"
-#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:142
msgid "Read"
msgstr "ÇØâÐâì"
-#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:147
+#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:148
msgid "New kid"
msgstr "½ÞÒëÙ ßÕàá"
-#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:153
-#: engines/scumm/help.cpp:171
+#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
+#: engines/scumm/help.cpp:172
msgid "Turn on"
msgstr "²ÚÛîçØâì"
-#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
-#: engines/scumm/help.cpp:172
+#: engines/scumm/help.cpp:133 engines/scumm/help.cpp:155
+#: engines/scumm/help.cpp:173
msgid "Turn off"
msgstr "²ëÚÛîçØâì"
-#: engines/scumm/help.cpp:142 engines/scumm/help.cpp:167
-#: engines/scumm/help.cpp:194
+#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
+#: engines/scumm/help.cpp:195
msgid "Walk to"
msgstr "¸ÔâØ Ú"
-#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
-#: engines/scumm/help.cpp:195 engines/scumm/help.cpp:210
-#: engines/scumm/help.cpp:227
+#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:228
msgid "Pick up"
msgstr "¿ÞÔÝïâì"
-#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:145 engines/scumm/help.cpp:170
msgid "What is"
msgstr "ÇâÞ âÐÚÞÕ"
-#: engines/scumm/help.cpp:146
+#: engines/scumm/help.cpp:147
msgid "Unlock"
msgstr "¾âÚàëâì"
-#: engines/scumm/help.cpp:149
+#: engines/scumm/help.cpp:150
msgid "Put on"
msgstr "¿ÞÛÞÖØâì"
-#: engines/scumm/help.cpp:150
+#: engines/scumm/help.cpp:151
msgid "Take off"
msgstr "¿ÞÔÝïâì"
-#: engines/scumm/help.cpp:156
+#: engines/scumm/help.cpp:157
msgid "Fix"
msgstr "¸áßàÐÒØâì"
-#: engines/scumm/help.cpp:158
+#: engines/scumm/help.cpp:159
msgid "Switch"
msgstr "¿ÕàÕÚÛîçØâì"
-#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:228
+#: engines/scumm/help.cpp:167 engines/scumm/help.cpp:229
msgid "Look"
msgstr "ÁÜÞâàÕâì"
-#: engines/scumm/help.cpp:173 engines/scumm/help.cpp:223
+#: engines/scumm/help.cpp:174 engines/scumm/help.cpp:224
msgid "Talk"
msgstr "³ÞÒÞàØâì"
-#: engines/scumm/help.cpp:174
+#: engines/scumm/help.cpp:175
msgid "Travel"
msgstr "¿ãâÕèÕáâÒÞÒÐâì"
-#: engines/scumm/help.cpp:175
+#: engines/scumm/help.cpp:176
msgid "To Henry / To Indy"
msgstr "³ÕÝàØ/¸ÝÔØ"
#. I18N: These are different musical notes
-#: engines/scumm/help.cpp:179
+#: engines/scumm/help.cpp:180
msgid "play C minor on distaff"
msgstr "ØÓàÐâì ÔÞ ÜØÝÞà ÝÐ ßàïÛÚÕ"
-#: engines/scumm/help.cpp:180
+#: engines/scumm/help.cpp:181
msgid "play D on distaff"
msgstr "ØÓàÐâì àÕ ÝÐ ßàïÛÚÕ"
-#: engines/scumm/help.cpp:181
+#: engines/scumm/help.cpp:182
msgid "play E on distaff"
msgstr "ØÓàÐâì ÜØ ÝÐ ßàïÛÚÕ"
-#: engines/scumm/help.cpp:182
+#: engines/scumm/help.cpp:183
msgid "play F on distaff"
msgstr "ØÓàÐâì äÐ ÝÐ ßàïÛÚÕ"
-#: engines/scumm/help.cpp:183
+#: engines/scumm/help.cpp:184
msgid "play G on distaff"
msgstr "ØÓàÐâì áÞÛì ÝÐ ßàïÛÚÕ"
-#: engines/scumm/help.cpp:184
+#: engines/scumm/help.cpp:185
msgid "play A on distaff"
msgstr "ØÓàÐâì Ûï ÝÐ ßàïÛÚÕ"
-#: engines/scumm/help.cpp:185
+#: engines/scumm/help.cpp:186
msgid "play B on distaff"
msgstr "ØÓàÐâì áØ ÝÐ ßàïÛÚÕ"
-#: engines/scumm/help.cpp:186
+#: engines/scumm/help.cpp:187
msgid "play C major on distaff"
msgstr "ØÓàÐâì ÔÞ ÜÐÖÞà ÝÐ ßàïÛÚÕ"
-#: engines/scumm/help.cpp:192 engines/scumm/help.cpp:214
+#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
msgid "puSh"
msgstr "âÞÛÚÐâì"
-#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
+#: engines/scumm/help.cpp:194 engines/scumm/help.cpp:216
msgid "pull (Yank)"
msgstr "âïÝãâì (æÕßÛïâì)"
-#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:212
-#: engines/scumm/help.cpp:248
+#: engines/scumm/help.cpp:197 engines/scumm/help.cpp:213
+#: engines/scumm/help.cpp:249
msgid "Talk to"
msgstr "³ÞÒÞàØâì á"
-#: engines/scumm/help.cpp:199 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:200 engines/scumm/help.cpp:212
msgid "Look at"
msgstr "ÁÜÞâàÕâì ÝÐ"
-#: engines/scumm/help.cpp:200
+#: engines/scumm/help.cpp:201
msgid "turn oN"
msgstr "ÒÚÛîçØâì"
-#: engines/scumm/help.cpp:201
+#: engines/scumm/help.cpp:202
msgid "turn oFf"
msgstr "ÒëÚÛîçØâì"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "KeyUp"
msgstr "²ÒÕàå"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "Highlight prev dialogue"
msgstr "¿ÞÔáÒÕâØâì ßàÕÔëÔãéØÙ ÔØÐÛÞÓ"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "KeyDown"
msgstr "²ÝØ×"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "Highlight next dialogue"
msgstr "¿ÞÔáÒÕâØâì áÛÕÔãîéØÙ ÔØÐÛÞÓ"
-#: engines/scumm/help.cpp:222
+#: engines/scumm/help.cpp:223
msgid "Walk"
msgstr "¸ÔâØ"
-#: engines/scumm/help.cpp:225 engines/scumm/help.cpp:234
-#: engines/scumm/help.cpp:241 engines/scumm/help.cpp:249
+#: engines/scumm/help.cpp:226 engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:242 engines/scumm/help.cpp:250
msgid "Inventory"
msgstr "¸ÝÒÕÝâÐàì"
-#: engines/scumm/help.cpp:226
+#: engines/scumm/help.cpp:227
msgid "Object"
msgstr "¾ÑêÕÚâ"
-#: engines/scumm/help.cpp:229
+#: engines/scumm/help.cpp:230
msgid "Black and White / Color"
msgstr "ÇÕàÝÞ-ÑÕÛëÙ / ÆÒÕâÝÞÙ"
-#: engines/scumm/help.cpp:232
+#: engines/scumm/help.cpp:233
msgid "Eyes"
msgstr "³ÛÐ×Ð"
-#: engines/scumm/help.cpp:233
+#: engines/scumm/help.cpp:234
msgid "Tongue"
msgstr "Ï×ëÚ"
-#: engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:236
msgid "Punch"
msgstr "ÃÔÐà"
-#: engines/scumm/help.cpp:236
+#: engines/scumm/help.cpp:237
msgid "Kick"
msgstr "½ÞÓÞÙ"
-#: engines/scumm/help.cpp:239 engines/scumm/help.cpp:247
+#: engines/scumm/help.cpp:240 engines/scumm/help.cpp:248
msgid "Examine"
msgstr "¿àÞÒÕàØâì"
-#: engines/scumm/help.cpp:240
+#: engines/scumm/help.cpp:241
msgid "Regular cursor"
msgstr "¾ÑëçÝëÙ ÚãàáÞà"
#. I18N: Comm is a communication device
-#: engines/scumm/help.cpp:243
+#: engines/scumm/help.cpp:244
msgid "Comm"
msgstr "ºÞÜÜ"
-#: engines/scumm/help.cpp:246
+#: engines/scumm/help.cpp:247
msgid "Save / Load / Options"
msgstr "·ÐÓàã×Øâì / ÁÞåàÐÝØâì / ½ÐáâàÞÙÚØ"
-#: engines/scumm/help.cpp:255
+#: engines/scumm/help.cpp:256
msgid "Other game controls:"
msgstr "¾áâÐÛìÝÞÕ ãßàÐÒÛÕÝØÕ ØÓàÞÙ:"
-#: engines/scumm/help.cpp:257 engines/scumm/help.cpp:267
+#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:268
msgid "Inventory:"
msgstr "¸ÝÒÕÝâÐàì:"
-#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:274
+#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
msgid "Scroll list up"
msgstr "¿àÞÚàãâØâì áßØáÞÚ ÒÒÕàå"
-#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
+#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:276
msgid "Scroll list down"
msgstr "¿àÞÚàãâØâì áßØáÞÚ ÒÝØ×"
-#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:268
+#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:269
msgid "Upper left item"
msgstr "²ÕàåÝØÙ ÛÕÒëÙ ßàÕÔÜÕâ"
-#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:270
+#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
msgid "Lower left item"
msgstr "½ØÖÝØÙ ÛÕÒëÙ ßàÕÔÜÕâ"
-#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
+#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:272
msgid "Upper right item"
msgstr "²ÕàåÝØÙ ßàÐÒëÙ ßàÕÔÜÕâ"
-#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:273
+#: engines/scumm/help.cpp:264 engines/scumm/help.cpp:274
msgid "Lower right item"
msgstr "½ØÖÝØÙ ßàÐÒëÙ ßàÕÔÜÕâ"
-#: engines/scumm/help.cpp:269
+#: engines/scumm/help.cpp:270
msgid "Middle left item"
msgstr "ÁàÕÔÝØÙ ÛÕÒëÙ ßàÕÔÜÕâ"
-#: engines/scumm/help.cpp:272
+#: engines/scumm/help.cpp:273
msgid "Middle right item"
msgstr "ÁàÕÔÝØÙ ßàÐÒëÙ ßàÕÔÜÕâ"
-#: engines/scumm/help.cpp:279 engines/scumm/help.cpp:284
+#: engines/scumm/help.cpp:280 engines/scumm/help.cpp:285
msgid "Switching characters:"
msgstr "ÁÜÕÝÐ ÓÕàÞï:"
-#: engines/scumm/help.cpp:281
+#: engines/scumm/help.cpp:282
msgid "Second kid"
msgstr "²âÞàÞÙ ÓÕàÞÙ"
-#: engines/scumm/help.cpp:282
+#: engines/scumm/help.cpp:283
msgid "Third kid"
msgstr "ÂàÕâØÙ ÓÕàÞÙ"
-#: engines/scumm/help.cpp:294
+#: engines/scumm/help.cpp:292
+#, fuzzy
+msgid "Toggle Inventory/IQ Points display"
+msgstr "²ÚÛîçØâì ßÞÚÐ× ÔÐÝÝëå Ò æÕÝâàÕ íÚàÐÝÐ"
+
+#: engines/scumm/help.cpp:293
+msgid "Toggle Keyboard/Mouse Fighting (*)"
+msgstr ""
+
+#: engines/scumm/help.cpp:295
+msgid "* Keyboard Fighting is always on,"
+msgstr ""
+
+#: engines/scumm/help.cpp:296
+msgid " so despite the in-game message this"
+msgstr ""
+
+#: engines/scumm/help.cpp:297
+msgid " actually toggles Mouse Fighting Off/On"
+msgstr ""
+
+#: engines/scumm/help.cpp:304
msgid "Fighting controls (numpad):"
msgstr "ÃßàÐÒÛÕÝØÕ ÑÞÕÜ (æØäàÞÒëÕ ÚÛÐÒØèØ)"
-#: engines/scumm/help.cpp:295 engines/scumm/help.cpp:296
-#: engines/scumm/help.cpp:297
+#: engines/scumm/help.cpp:305 engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:307
msgid "Step back"
msgstr "ÈÐÓ ÝÐ×ÐÔ"
-#: engines/scumm/help.cpp:298
+#: engines/scumm/help.cpp:308
msgid "Block high"
msgstr "·ÐéØâÐ áÒÕàåã"
-#: engines/scumm/help.cpp:299
+#: engines/scumm/help.cpp:309
msgid "Block middle"
msgstr "·ÐéØâÐ ßÞáÕàÕÔØÝÕ"
-#: engines/scumm/help.cpp:300
+#: engines/scumm/help.cpp:310
msgid "Block low"
msgstr "·ÐéØâÐ áÝØ×ã"
-#: engines/scumm/help.cpp:301
+#: engines/scumm/help.cpp:311
msgid "Punch high"
msgstr "ÃÔÐà áÒÕàåã"
-#: engines/scumm/help.cpp:302
+#: engines/scumm/help.cpp:312
msgid "Punch middle"
msgstr "ÃÔÐà ßÞáÕàÕÔØÝÕ"
-#: engines/scumm/help.cpp:303
+#: engines/scumm/help.cpp:313
msgid "Punch low"
msgstr "ÃÔÐà áÝØ×ã"
-#: engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:315
+msgid "Sucker punch"
+msgstr ""
+
+#: engines/scumm/help.cpp:318
msgid "These are for Indy on left."
msgstr "ÍâÞ ÚÞÓÔÐ ¸ÝÔØ áÛÕÒÐ."
-#: engines/scumm/help.cpp:307
+#: engines/scumm/help.cpp:319
msgid "When Indy is on the right,"
msgstr "ºÞÓÔÐ ¸ÝÔØ áßàÐÒÐ,"
-#: engines/scumm/help.cpp:308
+#: engines/scumm/help.cpp:320
msgid "7, 4, and 1 are switched with"
msgstr "7, 4 Ø 1 ÜÕÝïîâáï á"
-#: engines/scumm/help.cpp:309
+#: engines/scumm/help.cpp:321
msgid "9, 6, and 3, respectively."
msgstr "9, 6 Ø 3 áÞÞâÒÕâáâÒÕÝÝÞ."
-#: engines/scumm/help.cpp:316
+#: engines/scumm/help.cpp:328
msgid "Biplane controls (numpad):"
msgstr "ÃßàÐÒÛÕÝØÕ áÐÜÞÛñâÞÜ (æØäàÞÒëÕ ÚÛÐÒØèØ)"
-#: engines/scumm/help.cpp:317
+#: engines/scumm/help.cpp:329
msgid "Fly to upper left"
msgstr "»ÕâÕâì ÒÛÕÒÞ-ÒÒÕàå"
-#: engines/scumm/help.cpp:318
+#: engines/scumm/help.cpp:330
msgid "Fly to left"
msgstr "»ÕâÕâì ÒÛÕÒÞ"
-#: engines/scumm/help.cpp:319
+#: engines/scumm/help.cpp:331
msgid "Fly to lower left"
msgstr "»ÕâÕâì ÒÛÕÒÞ-ÒÝØ×"
-#: engines/scumm/help.cpp:320
+#: engines/scumm/help.cpp:332
msgid "Fly upwards"
msgstr "»ÕâÕâì ÒÒÕàå"
-#: engines/scumm/help.cpp:321
+#: engines/scumm/help.cpp:333
msgid "Fly straight"
msgstr "»ÕâÕâì ßàïÜÞ"
-#: engines/scumm/help.cpp:322
+#: engines/scumm/help.cpp:334
msgid "Fly down"
msgstr "»ÕâÕâì ÒÝØ×"
-#: engines/scumm/help.cpp:323
+#: engines/scumm/help.cpp:335
msgid "Fly to upper right"
msgstr "»ÕâÕâì ÒßàÐÒÞ-ÒÒÕàå"
-#: engines/scumm/help.cpp:324
+#: engines/scumm/help.cpp:336
msgid "Fly to right"
msgstr "»ÕâÕâì ÒßàÐÒÞ"
-#: engines/scumm/help.cpp:325
+#: engines/scumm/help.cpp:337
msgid "Fly to lower right"
msgstr "»ÕâÕâì ÒßàÐÒÞ-ÒÝØ×"
-#: engines/scumm/scumm.cpp:1823
+#: engines/scumm/scumm.cpp:1832
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
@@ -3197,11 +3287,12 @@ msgstr ""
"ÀÕÖØÜ \"àÞÔÝÞÓÞ\" MIDI âàÕÑãÕâ ÞÑÝÞÒÛÕÝØÕ Roland Upgrade Þâ\n"
"LucasArts, ÝÞ ÝÕ åÒÐâÐÕâ %s. ¿ÕàÕÚÛîçÐîáì ÝÐ AdLib."
-#: engines/scumm/scumm.cpp:2594
+#: engines/scumm/scumm.cpp:2644
+#, fuzzy
msgid ""
-"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
-"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
-"directory inside the Tentacle game directory."
+"Usually, Maniac Mansion would start now. But for that to work, the game "
+"files for Maniac Mansion have to be in the 'Maniac' directory inside the "
+"Tentacle game directory, and the game has to be added to ScummVM."
msgstr ""
"ÁÕÙçÐá ÔÞÛÖÝÐ ×ÐßãáâØâìáï ØÓàÐ Maniac Mansion. ½Þ ScummVM ßÞÚÐ íâÞÓÞ ÝÕ "
"ãÜÕÕâ. ÇâÞÑë áëÓàÐâì, ÝÐÖÜØâÕ '½ÞÒÐï ØÓàÐ' Ò áâÐàâÞÒÞÜ ÜÕÝî ScummVM, Ð ×ÐâÕÜ "
@@ -3339,6 +3430,48 @@ msgstr ""
msgid "Show the current number of frames per second in the upper left corner"
msgstr ""
+#: engines/zvision/detection.cpp:256
+msgid "Double FPS"
+msgstr ""
+
+#: engines/zvision/detection.cpp:257
+msgid "Increase game FPS from 30 to 60"
+msgstr ""
+
+#: engines/zvision/detection.cpp:266
+#, fuzzy
+msgid "Enable Venus"
+msgstr "²ÚÛîçØâì àÕÖØÜ ÓÕÛØï"
+
+#: engines/zvision/detection.cpp:267
+msgid "Enable the Venus help system"
+msgstr ""
+
+#: engines/zvision/detection.cpp:276
+msgid "Disable animation while turning"
+msgstr ""
+
+#: engines/zvision/detection.cpp:277
+msgid "Disable animation while turning in panoramic mode"
+msgstr ""
+
+#: engines/zvision/detection.cpp:286
+msgid "Use the hires MPEG movies"
+msgstr ""
+
+#: engines/zvision/detection.cpp:287
+#, fuzzy
+msgid ""
+"Use the hires MPEG movies of the DVD version, instead of the lowres AVI ones"
+msgstr ""
+"¸áßÞÛì×ÞÒÐâì ÐÛìâÕàÝÐâØÒÝëÙ ÝÐÑÞà áÕàÕÑàïÝëå ÚãàáÞàÞÒ ÒÜÕáâÞ ÞÑëçÝëå ×ÞÛÞâëå"
+
+#~ msgid "EGA undithering"
+#~ msgstr "EGA ÑÕ× àÐáâàÐ"
+
+#~ msgid "Enable undithering in EGA games"
+#~ msgstr "²ÚÛîçÐÕâ àÕÖØÜ ÑÕ× àÐáâàØàÞÒÐÝØï Ò EGA ØÓàÐå"
+
#~ msgid "MPEG-2 cutscenes found but ScummVM has been built without MPEG-2"
#~ msgstr ""
#~ "½ÐÙÔÕÝë ×ÐáâÐÒÚØ Ò äÞàÜÐâÕ MPEG-2, ÝÞ ScummVM ÑëÛ áÞÑàÐÝ ÑÕ× ßÞÔÔÕàÖÚØ "
@@ -3348,9 +3481,6 @@ msgstr ""
#~ msgid "Mass Add..."
#~ msgstr "¼ÝÞÓÞ ØÓà..."
-#~ msgid "Mass Add..."
-#~ msgstr "¼ÝÞÓÞ ØÓà..."
-
#~ msgid ""
#~ "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
#~ msgstr ""
diff --git a/po/scummvm.pot b/po/scummvm.pot
index 72600ff994..49689e914b 100644
--- a/po/scummvm.pot
+++ b/po/scummvm.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.8.0git\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2014-10-04 00:58+0100\n"
+"POT-Creation-Date: 2015-06-30 20:57+0100\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"
@@ -53,10 +53,11 @@ msgstr ""
#: gui/browser.cpp:75 gui/chooser.cpp:46 gui/KeysDialog.cpp:43
#: gui/launcher.cpp:351 gui/massadd.cpp:95 gui/options.cpp:1239
+#: gui/recorderdialog.cpp:70 gui/recorderdialog.cpp:156
#: gui/saveload-dialog.cpp:216 gui/saveload-dialog.cpp:276
-#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:922
+#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:931
#: gui/themebrowser.cpp:55 gui/fluidsynth-dialog.cpp:152
-#: engines/engine.cpp:452 backends/platform/wii/options.cpp:48
+#: engines/engine.cpp:483 backends/platform/wii/options.cpp:48
#: backends/events/default/default-events.cpp:196
#: backends/events/default/default-events.cpp:218
#: engines/drascula/saveload.cpp:49 engines/parallaction/saveload.cpp:274
@@ -69,9 +70,9 @@ msgid "Choose"
msgstr ""
#: gui/gui-manager.cpp:117 backends/keymapper/remap-dialog.cpp:53
-#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
-#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
-#: engines/scumm/help.cpp:209
+#: engines/scumm/help.cpp:126 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:192
+#: engines/scumm/help.cpp:210
msgid "Close"
msgstr ""
@@ -87,7 +88,7 @@ msgstr ""
msgid "Remap keys"
msgstr ""
-#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:86
+#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:87
msgid "Toggle fullscreen"
msgstr ""
@@ -101,13 +102,13 @@ msgstr ""
#: gui/KeysDialog.cpp:42 gui/launcher.cpp:352 gui/launcher.cpp:1048
#: gui/launcher.cpp:1052 gui/massadd.cpp:92 gui/options.cpp:1240
-#: gui/saveload-dialog.cpp:923 gui/fluidsynth-dialog.cpp:153
-#: engines/engine.cpp:371 engines/engine.cpp:382
+#: gui/saveload-dialog.cpp:932 gui/fluidsynth-dialog.cpp:153
+#: engines/engine.cpp:402 engines/engine.cpp:413
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
#: engines/agos/animation.cpp:558 engines/drascula/saveload.cpp:49
-#: engines/groovie/script.cpp:399 engines/parallaction/saveload.cpp:274
-#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1825
+#: engines/groovie/script.cpp:408 engines/parallaction/saveload.cpp:274
+#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1834
#: engines/scumm/players/player_v3m.cpp:130
#: engines/scumm/players/player_v5m.cpp:108 engines/sky/compact.cpp:131
#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:524
@@ -471,7 +472,7 @@ msgstr ""
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -481,7 +482,7 @@ msgstr ""
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -517,6 +518,14 @@ msgstr ""
msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr ""
+#: gui/launcher.cpp:1159
+msgid "Mass Add..."
+msgstr ""
+
+#: gui/launcher.cpp:1161
+msgid "Record..."
+msgstr ""
+
#: gui/massadd.cpp:79 gui/massadd.cpp:82
msgid "... progress ..."
msgstr ""
@@ -615,7 +624,7 @@ msgid "Special dithering modes supported by some games"
msgstr ""
#: gui/options.cpp:760
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2249
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2298
msgid "Fullscreen mode"
msgstr ""
@@ -921,6 +930,41 @@ msgid ""
"to use this theme you need to switch to another language first."
msgstr ""
+#: gui/recorderdialog.cpp:64
+msgid "Recorder or Playback Gameplay"
+msgstr ""
+
+#: gui/recorderdialog.cpp:69 gui/recorderdialog.cpp:156
+#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
+msgid "Delete"
+msgstr ""
+
+#: gui/recorderdialog.cpp:71
+msgid "Record"
+msgstr ""
+
+#: gui/recorderdialog.cpp:72
+msgid "Playback"
+msgstr ""
+
+#: gui/recorderdialog.cpp:74
+msgid "Edit"
+msgstr ""
+
+#: gui/recorderdialog.cpp:86 gui/recorderdialog.cpp:243
+#: gui/recorderdialog.cpp:253
+msgid "Author: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:87 gui/recorderdialog.cpp:244
+#: gui/recorderdialog.cpp:254
+msgid "Notes: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:155
+msgid "Do you really want to delete this record?"
+msgstr ""
+
#: gui/saveload-dialog.cpp:167
msgid "List view"
msgstr ""
@@ -941,23 +985,19 @@ msgstr ""
msgid "No playtime saved"
msgstr ""
-#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
-msgid "Delete"
-msgstr ""
-
#: gui/saveload-dialog.cpp:275
msgid "Do you really want to delete this saved game?"
msgstr ""
-#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:875
+#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:884
msgid "Date: "
msgstr ""
-#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:881
+#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:890
msgid "Time: "
msgstr ""
-#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:889
+#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:898
msgid "Playtime: "
msgstr ""
@@ -973,19 +1013,19 @@ msgstr ""
msgid "Prev"
msgstr ""
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "New Save"
msgstr ""
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "Create a new save game"
msgstr ""
-#: gui/saveload-dialog.cpp:868
+#: gui/saveload-dialog.cpp:877
msgid "Name: "
msgstr ""
-#: gui/saveload-dialog.cpp:940
+#: gui/saveload-dialog.cpp:949
#, c-format
msgid "Enter a description for slot %d:"
msgstr ""
@@ -1136,7 +1176,7 @@ msgstr ""
msgid "Error running game:"
msgstr ""
-#: base/main.cpp:536
+#: base/main.cpp:554
msgid "Could not find any engine capable of running the selected game"
msgstr ""
@@ -1253,7 +1293,7 @@ msgstr ""
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:803
#: engines/cruise/menu.cpp:212 engines/drascula/saveload.cpp:336
#: engines/dreamweb/saveload.cpp:261 engines/neverhood/menumodule.cpp:873
-#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:758
+#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:759
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save game:"
msgstr ""
@@ -1266,7 +1306,7 @@ msgstr ""
#: engines/agi/saveload.cpp:803 engines/cruise/menu.cpp:212
#: engines/drascula/saveload.cpp:336 engines/dreamweb/saveload.cpp:261
#: engines/neverhood/menumodule.cpp:873 engines/pegasus/pegasus.cpp:377
-#: engines/sci/engine/kfile.cpp:758 engines/scumm/dialogs.cpp:188
+#: engines/sci/engine/kfile.cpp:759 engines/scumm/dialogs.cpp:188
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save"
msgstr ""
@@ -1299,23 +1339,23 @@ msgstr ""
msgid "~K~eys"
msgstr ""
-#: engines/engine.cpp:245
+#: engines/engine.cpp:276
msgid "Could not initialize color format."
msgstr ""
-#: engines/engine.cpp:253
+#: engines/engine.cpp:284
msgid "Could not switch to video mode: '"
msgstr ""
-#: engines/engine.cpp:262
+#: engines/engine.cpp:293
msgid "Could not apply aspect ratio setting."
msgstr ""
-#: engines/engine.cpp:267
+#: engines/engine.cpp:298
msgid "Could not apply fullscreen setting."
msgstr ""
-#: engines/engine.cpp:367
+#: engines/engine.cpp:398
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1324,7 +1364,7 @@ msgid ""
"See the README file for details."
msgstr ""
-#: engines/engine.cpp:378
+#: engines/engine.cpp:409
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1333,21 +1373,21 @@ msgid ""
"See the README file for details."
msgstr ""
-#: engines/engine.cpp:436
+#: engines/engine.cpp:467
#, c-format
msgid ""
"Gamestate load failed (%s)! Please consult the README for basic information, "
"and for instructions on how to obtain further assistance."
msgstr ""
-#: engines/engine.cpp:449
+#: engines/engine.cpp:480
msgid ""
"WARNING: The game you are about to start is not yet fully supported by "
"ScummVM. As such, it is likely to be unstable, and any saves you make might "
"not work in future versions of ScummVM."
msgstr ""
-#: engines/engine.cpp:452
+#: engines/engine.cpp:483
msgid "Start anyway"
msgstr ""
@@ -1549,11 +1589,11 @@ msgstr ""
msgid "Touchpad mode disabled."
msgstr ""
-#: backends/platform/maemo/maemo.cpp:209
+#: backends/platform/maemo/maemo.cpp:208
msgid "Click Mode"
msgstr ""
-#: backends/platform/maemo/maemo.cpp:215
+#: backends/platform/maemo/maemo.cpp:214
#: backends/platform/symbian/src/SymbianActions.cpp:42
#: backends/platform/wince/CEActionsPocket.cpp:60
#: backends/platform/wince/CEActionsSmartphone.cpp:43
@@ -1561,11 +1601,11 @@ msgstr ""
msgid "Left Click"
msgstr ""
-#: backends/platform/maemo/maemo.cpp:218
+#: backends/platform/maemo/maemo.cpp:217
msgid "Middle Click"
msgstr ""
-#: backends/platform/maemo/maemo.cpp:221
+#: backends/platform/maemo/maemo.cpp:220
#: backends/platform/symbian/src/SymbianActions.cpp:43
#: backends/platform/wince/CEActionsSmartphone.cpp:44
#: backends/platform/tizen/form.cpp:267
@@ -1602,19 +1642,19 @@ msgctxt "lowres"
msgid "Normal (no scaling)"
msgstr ""
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2148
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2197
msgid "Enabled aspect ratio correction"
msgstr ""
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2154
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2203
msgid "Disabled aspect ratio correction"
msgstr ""
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2209
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2258
msgid "Active graphics filter:"
msgstr ""
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2251
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2300
msgid "Windowed mode"
msgstr ""
@@ -1673,8 +1713,8 @@ msgstr ""
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
#: backends/events/default/default-events.cpp:218
-#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:82
-#: engines/scumm/help.cpp:84
+#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:83
+#: engines/scumm/help.cpp:85
msgid "Quit"
msgstr ""
@@ -1694,7 +1734,7 @@ msgstr ""
msgid "Key mapper"
msgstr ""
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
msgid "Do you want to quit ?"
msgstr ""
@@ -2025,33 +2065,52 @@ msgstr ""
msgid "Clicking Disabled"
msgstr ""
-#: engines/agi/detection.cpp:142 engines/drascula/detection.cpp:302
+#: engines/agi/detection.cpp:147 engines/drascula/detection.cpp:302
#: engines/dreamweb/detection.cpp:47 engines/neverhood/detection.cpp:160
#: engines/sci/detection.cpp:394 engines/toltecs/detection.cpp:200
-#: engines/zvision/detection.cpp:103
+#: engines/zvision/detection.cpp:246
msgid "Use original save/load screens"
msgstr ""
-#: engines/agi/detection.cpp:143 engines/drascula/detection.cpp:303
+#: engines/agi/detection.cpp:148 engines/drascula/detection.cpp:303
#: engines/dreamweb/detection.cpp:48 engines/neverhood/detection.cpp:161
#: engines/sci/detection.cpp:395 engines/toltecs/detection.cpp:201
-#: engines/zvision/detection.cpp:104
+#: engines/zvision/detection.cpp:247
msgid "Use the original save/load screens, instead of the ScummVM ones"
msgstr ""
+#: engines/agi/detection.cpp:157
+msgid "Use an alternative palette"
+msgstr ""
+
+#: engines/agi/detection.cpp:158
+msgid ""
+"Use an alternative palette, common for all Amiga games. This was the old "
+"behavior"
+msgstr ""
+
+#: engines/agi/detection.cpp:167
+msgid "Mouse support"
+msgstr ""
+
+#: engines/agi/detection.cpp:168
+msgid ""
+"Enables mouse support. Allows to use mouse for movement and in game menus."
+msgstr ""
+
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore game:"
msgstr ""
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore"
msgstr ""
-#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2368
+#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2377
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -2059,7 +2118,7 @@ msgid ""
"%s"
msgstr ""
-#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2361
+#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2370
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -2067,7 +2126,7 @@ msgid ""
"%s"
msgstr ""
-#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2379
+#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2388
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -2080,11 +2139,11 @@ msgstr ""
msgid "Cutscene file '%s' not found!"
msgstr ""
-#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:81
+#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:101
msgid "Color Blind Mode"
msgstr ""
-#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:82
+#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:102
msgid "Enable Color Blind Mode by default"
msgstr ""
@@ -2129,7 +2188,7 @@ msgstr ""
msgid "Play movies at an increased speed"
msgstr ""
-#: engines/groovie/script.cpp:399
+#: engines/groovie/script.cpp:408
msgid "Failed to save game"
msgstr ""
@@ -2409,11 +2468,11 @@ msgid "Use an alternative game intro (CD version only)"
msgstr ""
#: engines/sci/detection.cpp:374
-msgid "EGA undithering"
+msgid "Skip EGA dithering pass (full color backgrounds)"
msgstr ""
#: engines/sci/detection.cpp:375
-msgid "Enable undithering in EGA games"
+msgid "Skip dithering pass in EGA games, graphics are shown with full colors"
msgstr ""
#: engines/sci/detection.cpp:384
@@ -2483,12 +2542,12 @@ msgstr ""
#. "Moechten Sie wirklich neu starten? (J/N)J"
#. Will react to J as 'Yes'
#: engines/scumm/dialogs.cpp:183
-msgid "Are you sure you want to restart? (Y/N)"
+msgid "Are you sure you want to restart? (Y/N)Y"
msgstr ""
#. I18N: you may specify 'Yes' symbol at the end of the line. See previous comment
#: engines/scumm/dialogs.cpp:185
-msgid "Are you sure you want to quit? (Y/N)"
+msgid "Are you sure you want to quit? (Y/N)Y"
msgstr ""
#: engines/scumm/dialogs.cpp:190
@@ -2576,527 +2635,551 @@ msgstr ""
msgid "Expert"
msgstr ""
-#: engines/scumm/help.cpp:73
+#: engines/scumm/help.cpp:74
msgid "Common keyboard commands:"
msgstr ""
-#: engines/scumm/help.cpp:74
+#: engines/scumm/help.cpp:75
msgid "Save / Load dialog"
msgstr ""
-#: engines/scumm/help.cpp:76
+#: engines/scumm/help.cpp:77
msgid "Skip line of text"
msgstr ""
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Esc"
msgstr ""
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Skip cutscene"
msgstr ""
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Space"
msgstr ""
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Pause game"
msgstr ""
-#: engines/scumm/help.cpp:79 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:95 engines/scumm/help.cpp:96
-#: engines/scumm/help.cpp:97 engines/scumm/help.cpp:98
-#: engines/scumm/help.cpp:99 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:96 engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98 engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Ctrl"
msgstr ""
-#: engines/scumm/help.cpp:79
+#: engines/scumm/help.cpp:80
msgid "Load game state 1-10"
msgstr ""
-#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:81 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Alt"
msgstr ""
-#: engines/scumm/help.cpp:80
+#: engines/scumm/help.cpp:81
msgid "Save game state 1-10"
msgstr ""
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:90
msgid "Enter"
msgstr ""
-#: engines/scumm/help.cpp:87
+#: engines/scumm/help.cpp:88
msgid "Music volume up / down"
msgstr ""
-#: engines/scumm/help.cpp:88
+#: engines/scumm/help.cpp:89
msgid "Text speed slower / faster"
msgstr ""
-#: engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:90
msgid "Simulate left mouse button"
msgstr ""
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Tab"
msgstr ""
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Simulate right mouse button"
msgstr ""
-#: engines/scumm/help.cpp:93
+#: engines/scumm/help.cpp:94
msgid "Special keyboard commands:"
msgstr ""
-#: engines/scumm/help.cpp:94
+#: engines/scumm/help.cpp:95
msgid "Show / Hide console"
msgstr ""
-#: engines/scumm/help.cpp:95
+#: engines/scumm/help.cpp:96
msgid "Start the debugger"
msgstr ""
-#: engines/scumm/help.cpp:96
+#: engines/scumm/help.cpp:97
msgid "Show memory consumption"
msgstr ""
-#: engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98
msgid "Run in fast mode (*)"
msgstr ""
-#: engines/scumm/help.cpp:98
+#: engines/scumm/help.cpp:99
msgid "Run in really fast mode (*)"
msgstr ""
-#: engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100
msgid "Toggle mouse capture"
msgstr ""
-#: engines/scumm/help.cpp:100
+#: engines/scumm/help.cpp:101
msgid "Switch between graphics filters"
msgstr ""
-#: engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102
msgid "Increase / Decrease scale factor"
msgstr ""
-#: engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:103
msgid "Toggle aspect-ratio correction"
msgstr ""
-#: engines/scumm/help.cpp:107
+#: engines/scumm/help.cpp:108
msgid "* Note that using ctrl-f and"
msgstr ""
-#: engines/scumm/help.cpp:108
+#: engines/scumm/help.cpp:109
msgid " ctrl-g are not recommended"
msgstr ""
-#: engines/scumm/help.cpp:109
+#: engines/scumm/help.cpp:110
msgid " since they may cause crashes"
msgstr ""
-#: engines/scumm/help.cpp:110
+#: engines/scumm/help.cpp:111
msgid " or incorrect game behavior."
msgstr ""
-#: engines/scumm/help.cpp:114
+#: engines/scumm/help.cpp:115
msgid "Spinning drafts on the keyboard:"
msgstr ""
-#: engines/scumm/help.cpp:116
+#: engines/scumm/help.cpp:117
msgid "Main game controls:"
msgstr ""
-#: engines/scumm/help.cpp:121 engines/scumm/help.cpp:136
-#: engines/scumm/help.cpp:161
-msgid "Push"
-msgstr ""
-
#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
#: engines/scumm/help.cpp:162
-msgid "Pull"
+msgid "Push"
msgstr ""
#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
-#: engines/scumm/help.cpp:163 engines/scumm/help.cpp:197
-#: engines/scumm/help.cpp:207
-msgid "Give"
+#: engines/scumm/help.cpp:163
+msgid "Pull"
msgstr ""
#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
-#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:190
+#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:198
#: engines/scumm/help.cpp:208
+msgid "Give"
+msgstr ""
+
+#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
+#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
+#: engines/scumm/help.cpp:209
msgid "Open"
msgstr ""
-#: engines/scumm/help.cpp:126
+#: engines/scumm/help.cpp:127
msgid "Go to"
msgstr ""
-#: engines/scumm/help.cpp:127
+#: engines/scumm/help.cpp:128
msgid "Get"
msgstr ""
-#: engines/scumm/help.cpp:128 engines/scumm/help.cpp:152
-#: engines/scumm/help.cpp:170 engines/scumm/help.cpp:198
-#: engines/scumm/help.cpp:213 engines/scumm/help.cpp:224
-#: engines/scumm/help.cpp:250
+#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:153
+#: engines/scumm/help.cpp:171 engines/scumm/help.cpp:199
+#: engines/scumm/help.cpp:214 engines/scumm/help.cpp:225
+#: engines/scumm/help.cpp:251
msgid "Use"
msgstr ""
-#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:142
msgid "Read"
msgstr ""
-#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:147
+#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:148
msgid "New kid"
msgstr ""
-#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:153
-#: engines/scumm/help.cpp:171
+#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
+#: engines/scumm/help.cpp:172
msgid "Turn on"
msgstr ""
-#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
-#: engines/scumm/help.cpp:172
+#: engines/scumm/help.cpp:133 engines/scumm/help.cpp:155
+#: engines/scumm/help.cpp:173
msgid "Turn off"
msgstr ""
-#: engines/scumm/help.cpp:142 engines/scumm/help.cpp:167
-#: engines/scumm/help.cpp:194
+#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
+#: engines/scumm/help.cpp:195
msgid "Walk to"
msgstr ""
-#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
-#: engines/scumm/help.cpp:195 engines/scumm/help.cpp:210
-#: engines/scumm/help.cpp:227
+#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:228
msgid "Pick up"
msgstr ""
-#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:145 engines/scumm/help.cpp:170
msgid "What is"
msgstr ""
-#: engines/scumm/help.cpp:146
+#: engines/scumm/help.cpp:147
msgid "Unlock"
msgstr ""
-#: engines/scumm/help.cpp:149
+#: engines/scumm/help.cpp:150
msgid "Put on"
msgstr ""
-#: engines/scumm/help.cpp:150
+#: engines/scumm/help.cpp:151
msgid "Take off"
msgstr ""
-#: engines/scumm/help.cpp:156
+#: engines/scumm/help.cpp:157
msgid "Fix"
msgstr ""
-#: engines/scumm/help.cpp:158
+#: engines/scumm/help.cpp:159
msgid "Switch"
msgstr ""
-#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:228
+#: engines/scumm/help.cpp:167 engines/scumm/help.cpp:229
msgid "Look"
msgstr ""
-#: engines/scumm/help.cpp:173 engines/scumm/help.cpp:223
+#: engines/scumm/help.cpp:174 engines/scumm/help.cpp:224
msgid "Talk"
msgstr ""
-#: engines/scumm/help.cpp:174
+#: engines/scumm/help.cpp:175
msgid "Travel"
msgstr ""
-#: engines/scumm/help.cpp:175
+#: engines/scumm/help.cpp:176
msgid "To Henry / To Indy"
msgstr ""
#. I18N: These are different musical notes
-#: engines/scumm/help.cpp:179
+#: engines/scumm/help.cpp:180
msgid "play C minor on distaff"
msgstr ""
-#: engines/scumm/help.cpp:180
+#: engines/scumm/help.cpp:181
msgid "play D on distaff"
msgstr ""
-#: engines/scumm/help.cpp:181
+#: engines/scumm/help.cpp:182
msgid "play E on distaff"
msgstr ""
-#: engines/scumm/help.cpp:182
+#: engines/scumm/help.cpp:183
msgid "play F on distaff"
msgstr ""
-#: engines/scumm/help.cpp:183
+#: engines/scumm/help.cpp:184
msgid "play G on distaff"
msgstr ""
-#: engines/scumm/help.cpp:184
+#: engines/scumm/help.cpp:185
msgid "play A on distaff"
msgstr ""
-#: engines/scumm/help.cpp:185
+#: engines/scumm/help.cpp:186
msgid "play B on distaff"
msgstr ""
-#: engines/scumm/help.cpp:186
+#: engines/scumm/help.cpp:187
msgid "play C major on distaff"
msgstr ""
-#: engines/scumm/help.cpp:192 engines/scumm/help.cpp:214
+#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
msgid "puSh"
msgstr ""
-#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
+#: engines/scumm/help.cpp:194 engines/scumm/help.cpp:216
msgid "pull (Yank)"
msgstr ""
-#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:212
-#: engines/scumm/help.cpp:248
+#: engines/scumm/help.cpp:197 engines/scumm/help.cpp:213
+#: engines/scumm/help.cpp:249
msgid "Talk to"
msgstr ""
-#: engines/scumm/help.cpp:199 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:200 engines/scumm/help.cpp:212
msgid "Look at"
msgstr ""
-#: engines/scumm/help.cpp:200
+#: engines/scumm/help.cpp:201
msgid "turn oN"
msgstr ""
-#: engines/scumm/help.cpp:201
+#: engines/scumm/help.cpp:202
msgid "turn oFf"
msgstr ""
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "KeyUp"
msgstr ""
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "Highlight prev dialogue"
msgstr ""
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "KeyDown"
msgstr ""
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "Highlight next dialogue"
msgstr ""
-#: engines/scumm/help.cpp:222
+#: engines/scumm/help.cpp:223
msgid "Walk"
msgstr ""
-#: engines/scumm/help.cpp:225 engines/scumm/help.cpp:234
-#: engines/scumm/help.cpp:241 engines/scumm/help.cpp:249
+#: engines/scumm/help.cpp:226 engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:242 engines/scumm/help.cpp:250
msgid "Inventory"
msgstr ""
-#: engines/scumm/help.cpp:226
+#: engines/scumm/help.cpp:227
msgid "Object"
msgstr ""
-#: engines/scumm/help.cpp:229
+#: engines/scumm/help.cpp:230
msgid "Black and White / Color"
msgstr ""
-#: engines/scumm/help.cpp:232
+#: engines/scumm/help.cpp:233
msgid "Eyes"
msgstr ""
-#: engines/scumm/help.cpp:233
+#: engines/scumm/help.cpp:234
msgid "Tongue"
msgstr ""
-#: engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:236
msgid "Punch"
msgstr ""
-#: engines/scumm/help.cpp:236
+#: engines/scumm/help.cpp:237
msgid "Kick"
msgstr ""
-#: engines/scumm/help.cpp:239 engines/scumm/help.cpp:247
+#: engines/scumm/help.cpp:240 engines/scumm/help.cpp:248
msgid "Examine"
msgstr ""
-#: engines/scumm/help.cpp:240
+#: engines/scumm/help.cpp:241
msgid "Regular cursor"
msgstr ""
#. I18N: Comm is a communication device
-#: engines/scumm/help.cpp:243
+#: engines/scumm/help.cpp:244
msgid "Comm"
msgstr ""
-#: engines/scumm/help.cpp:246
+#: engines/scumm/help.cpp:247
msgid "Save / Load / Options"
msgstr ""
-#: engines/scumm/help.cpp:255
+#: engines/scumm/help.cpp:256
msgid "Other game controls:"
msgstr ""
-#: engines/scumm/help.cpp:257 engines/scumm/help.cpp:267
+#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:268
msgid "Inventory:"
msgstr ""
-#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:274
+#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
msgid "Scroll list up"
msgstr ""
-#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
+#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:276
msgid "Scroll list down"
msgstr ""
-#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:268
+#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:269
msgid "Upper left item"
msgstr ""
-#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:270
+#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
msgid "Lower left item"
msgstr ""
-#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
+#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:272
msgid "Upper right item"
msgstr ""
-#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:273
+#: engines/scumm/help.cpp:264 engines/scumm/help.cpp:274
msgid "Lower right item"
msgstr ""
-#: engines/scumm/help.cpp:269
+#: engines/scumm/help.cpp:270
msgid "Middle left item"
msgstr ""
-#: engines/scumm/help.cpp:272
+#: engines/scumm/help.cpp:273
msgid "Middle right item"
msgstr ""
-#: engines/scumm/help.cpp:279 engines/scumm/help.cpp:284
+#: engines/scumm/help.cpp:280 engines/scumm/help.cpp:285
msgid "Switching characters:"
msgstr ""
-#: engines/scumm/help.cpp:281
+#: engines/scumm/help.cpp:282
msgid "Second kid"
msgstr ""
-#: engines/scumm/help.cpp:282
+#: engines/scumm/help.cpp:283
msgid "Third kid"
msgstr ""
-#: engines/scumm/help.cpp:294
-msgid "Fighting controls (numpad):"
+#: engines/scumm/help.cpp:292
+msgid "Toggle Inventory/IQ Points display"
+msgstr ""
+
+#: engines/scumm/help.cpp:293
+msgid "Toggle Keyboard/Mouse Fighting (*)"
+msgstr ""
+
+#: engines/scumm/help.cpp:295
+msgid "* Keyboard Fighting is always on,"
+msgstr ""
+
+#: engines/scumm/help.cpp:296
+msgid " so despite the in-game message this"
msgstr ""
-#: engines/scumm/help.cpp:295 engines/scumm/help.cpp:296
#: engines/scumm/help.cpp:297
+msgid " actually toggles Mouse Fighting Off/On"
+msgstr ""
+
+#: engines/scumm/help.cpp:304
+msgid "Fighting controls (numpad):"
+msgstr ""
+
+#: engines/scumm/help.cpp:305 engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:307
msgid "Step back"
msgstr ""
-#: engines/scumm/help.cpp:298
+#: engines/scumm/help.cpp:308
msgid "Block high"
msgstr ""
-#: engines/scumm/help.cpp:299
+#: engines/scumm/help.cpp:309
msgid "Block middle"
msgstr ""
-#: engines/scumm/help.cpp:300
+#: engines/scumm/help.cpp:310
msgid "Block low"
msgstr ""
-#: engines/scumm/help.cpp:301
+#: engines/scumm/help.cpp:311
msgid "Punch high"
msgstr ""
-#: engines/scumm/help.cpp:302
+#: engines/scumm/help.cpp:312
msgid "Punch middle"
msgstr ""
-#: engines/scumm/help.cpp:303
+#: engines/scumm/help.cpp:313
msgid "Punch low"
msgstr ""
-#: engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:315
+msgid "Sucker punch"
+msgstr ""
+
+#: engines/scumm/help.cpp:318
msgid "These are for Indy on left."
msgstr ""
-#: engines/scumm/help.cpp:307
+#: engines/scumm/help.cpp:319
msgid "When Indy is on the right,"
msgstr ""
-#: engines/scumm/help.cpp:308
+#: engines/scumm/help.cpp:320
msgid "7, 4, and 1 are switched with"
msgstr ""
-#: engines/scumm/help.cpp:309
+#: engines/scumm/help.cpp:321
msgid "9, 6, and 3, respectively."
msgstr ""
-#: engines/scumm/help.cpp:316
+#: engines/scumm/help.cpp:328
msgid "Biplane controls (numpad):"
msgstr ""
-#: engines/scumm/help.cpp:317
+#: engines/scumm/help.cpp:329
msgid "Fly to upper left"
msgstr ""
-#: engines/scumm/help.cpp:318
+#: engines/scumm/help.cpp:330
msgid "Fly to left"
msgstr ""
-#: engines/scumm/help.cpp:319
+#: engines/scumm/help.cpp:331
msgid "Fly to lower left"
msgstr ""
-#: engines/scumm/help.cpp:320
+#: engines/scumm/help.cpp:332
msgid "Fly upwards"
msgstr ""
-#: engines/scumm/help.cpp:321
+#: engines/scumm/help.cpp:333
msgid "Fly straight"
msgstr ""
-#: engines/scumm/help.cpp:322
+#: engines/scumm/help.cpp:334
msgid "Fly down"
msgstr ""
-#: engines/scumm/help.cpp:323
+#: engines/scumm/help.cpp:335
msgid "Fly to upper right"
msgstr ""
-#: engines/scumm/help.cpp:324
+#: engines/scumm/help.cpp:336
msgid "Fly to right"
msgstr ""
-#: engines/scumm/help.cpp:325
+#: engines/scumm/help.cpp:337
msgid "Fly to lower right"
msgstr ""
-#: engines/scumm/scumm.cpp:1823
+#: engines/scumm/scumm.cpp:1832
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
"but %s is missing. Using AdLib instead."
msgstr ""
-#: engines/scumm/scumm.cpp:2594
+#: engines/scumm/scumm.cpp:2644
msgid ""
-"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
-"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
-"directory inside the Tentacle game directory."
+"Usually, Maniac Mansion would start now. But for that to work, the game "
+"files for Maniac Mansion have to be in the 'Maniac' directory inside the "
+"Tentacle game directory, and the game has to be added to ScummVM."
msgstr ""
#: engines/scumm/players/player_v3m.cpp:129
@@ -3211,3 +3294,36 @@ msgstr ""
#: engines/wintermute/detection.cpp:59
msgid "Show the current number of frames per second in the upper left corner"
msgstr ""
+
+#: engines/zvision/detection.cpp:256
+msgid "Double FPS"
+msgstr ""
+
+#: engines/zvision/detection.cpp:257
+msgid "Increase game FPS from 30 to 60"
+msgstr ""
+
+#: engines/zvision/detection.cpp:266
+msgid "Enable Venus"
+msgstr ""
+
+#: engines/zvision/detection.cpp:267
+msgid "Enable the Venus help system"
+msgstr ""
+
+#: engines/zvision/detection.cpp:276
+msgid "Disable animation while turning"
+msgstr ""
+
+#: engines/zvision/detection.cpp:277
+msgid "Disable animation while turning in panoramic mode"
+msgstr ""
+
+#: engines/zvision/detection.cpp:286
+msgid "Use the hires MPEG movies"
+msgstr ""
+
+#: engines/zvision/detection.cpp:287
+msgid ""
+"Use the hires MPEG movies of the DVD version, instead of the lowres AVI ones"
+msgstr ""
diff --git a/po/se_SE.po b/po/se_SE.po
index d08f6962c9..d49cf3606a 100644
--- a/po/se_SE.po
+++ b/po/se_SE.po
@@ -1,5 +1,5 @@
# Swedish translation for ScummVM.
-# Copyright (C) 2011-2014 ScummVM Team
+# Copyright (C) 2011-2015 The ScummVM Team
# This file is distributed under the same license as the ScummVM package.
# Hampus Flink <hampus.flink@gmail.com>, 2011.
#
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.5.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2014-10-04 00:58+0100\n"
+"POT-Creation-Date: 2015-06-30 20:57+0100\n"
"PO-Revision-Date: 2014-07-02 16:30+0100\n"
"Last-Translator: Hampus Flink <hampus.flink@gmail.com>\n"
"Language-Team: \n"
@@ -55,10 +55,11 @@ msgstr "Uppåt"
#: gui/browser.cpp:75 gui/chooser.cpp:46 gui/KeysDialog.cpp:43
#: gui/launcher.cpp:351 gui/massadd.cpp:95 gui/options.cpp:1239
+#: gui/recorderdialog.cpp:70 gui/recorderdialog.cpp:156
#: gui/saveload-dialog.cpp:216 gui/saveload-dialog.cpp:276
-#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:922
+#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:931
#: gui/themebrowser.cpp:55 gui/fluidsynth-dialog.cpp:152
-#: engines/engine.cpp:452 backends/platform/wii/options.cpp:48
+#: engines/engine.cpp:483 backends/platform/wii/options.cpp:48
#: backends/events/default/default-events.cpp:196
#: backends/events/default/default-events.cpp:218
#: engines/drascula/saveload.cpp:49 engines/parallaction/saveload.cpp:274
@@ -71,9 +72,9 @@ msgid "Choose"
msgstr "Välj"
#: gui/gui-manager.cpp:117 backends/keymapper/remap-dialog.cpp:53
-#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
-#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
-#: engines/scumm/help.cpp:209
+#: engines/scumm/help.cpp:126 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:192
+#: engines/scumm/help.cpp:210
msgid "Close"
msgstr "Stäng"
@@ -89,7 +90,7 @@ msgstr "Visa tangentbord"
msgid "Remap keys"
msgstr "Ställ in tangenter"
-#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:86
+#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:87
msgid "Toggle fullscreen"
msgstr "Fullskärmsläge"
@@ -103,13 +104,13 @@ msgstr "Ställ in"
#: gui/KeysDialog.cpp:42 gui/launcher.cpp:352 gui/launcher.cpp:1048
#: gui/launcher.cpp:1052 gui/massadd.cpp:92 gui/options.cpp:1240
-#: gui/saveload-dialog.cpp:923 gui/fluidsynth-dialog.cpp:153
-#: engines/engine.cpp:371 engines/engine.cpp:382
+#: gui/saveload-dialog.cpp:932 gui/fluidsynth-dialog.cpp:153
+#: engines/engine.cpp:402 engines/engine.cpp:413
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
#: engines/agos/animation.cpp:558 engines/drascula/saveload.cpp:49
-#: engines/groovie/script.cpp:399 engines/parallaction/saveload.cpp:274
-#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1825
+#: engines/groovie/script.cpp:408 engines/parallaction/saveload.cpp:274
+#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1834
#: engines/scumm/players/player_v3m.cpp:130
#: engines/scumm/players/player_v5m.cpp:108 engines/sky/compact.cpp:131
#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:524
@@ -479,7 +480,7 @@ msgstr ""
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -489,7 +490,7 @@ msgstr "Ja"
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -526,6 +527,14 @@ msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr ""
"ScummVM kunde inte hitta en motor kapabel till att köra det valda spelet!"
+#: gui/launcher.cpp:1159
+msgid "Mass Add..."
+msgstr "Masstillägg..."
+
+#: gui/launcher.cpp:1161
+msgid "Record..."
+msgstr ""
+
#: gui/massadd.cpp:79 gui/massadd.cpp:82
msgid "... progress ..."
msgstr "... progression ..."
@@ -624,7 +633,7 @@ msgid "Special dithering modes supported by some games"
msgstr "Speciella gitterlägen stödda av vissa spel"
#: gui/options.cpp:760
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2249
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2298
msgid "Fullscreen mode"
msgstr "Fullskärmsläge"
@@ -941,6 +950,43 @@ msgstr ""
"Temat du valde stöder inte ditt språk. Om du vill använda det här temat "
"måste först byta till ett annat språk."
+#: gui/recorderdialog.cpp:64
+msgid "Recorder or Playback Gameplay"
+msgstr ""
+
+#: gui/recorderdialog.cpp:69 gui/recorderdialog.cpp:156
+#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
+msgid "Delete"
+msgstr "Radera"
+
+#: gui/recorderdialog.cpp:71
+msgid "Record"
+msgstr ""
+
+#: gui/recorderdialog.cpp:72
+#, fuzzy
+msgid "Playback"
+msgstr "Spela"
+
+#: gui/recorderdialog.cpp:74
+msgid "Edit"
+msgstr ""
+
+#: gui/recorderdialog.cpp:86 gui/recorderdialog.cpp:243
+#: gui/recorderdialog.cpp:253
+msgid "Author: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:87 gui/recorderdialog.cpp:244
+#: gui/recorderdialog.cpp:254
+msgid "Notes: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:155
+#, fuzzy
+msgid "Do you really want to delete this record?"
+msgstr "Vill du verkligen radera den här spardatan?"
+
#: gui/saveload-dialog.cpp:167
msgid "List view"
msgstr "Visa som lista"
@@ -961,23 +1007,19 @@ msgstr "Ingen tid sparad"
msgid "No playtime saved"
msgstr "Ingen speltid sparad"
-#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
-msgid "Delete"
-msgstr "Radera"
-
#: gui/saveload-dialog.cpp:275
msgid "Do you really want to delete this saved game?"
msgstr "Vill du verkligen radera den här spardatan?"
-#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:875
+#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:884
msgid "Date: "
msgstr "Datum:"
-#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:881
+#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:890
msgid "Time: "
msgstr "Tid:"
-#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:889
+#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:898
msgid "Playtime: "
msgstr "Speltid:"
@@ -993,19 +1035,19 @@ msgstr "Nästa"
msgid "Prev"
msgstr "Bakåt"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "New Save"
msgstr "Ny sparning"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "Create a new save game"
msgstr "Skapa ett nytt sparat spel"
-#: gui/saveload-dialog.cpp:868
+#: gui/saveload-dialog.cpp:877
msgid "Name: "
msgstr "Namn:"
-#: gui/saveload-dialog.cpp:940
+#: gui/saveload-dialog.cpp:949
#, c-format
msgid "Enter a description for slot %d:"
msgstr "Ange en beskrivning för position %d:"
@@ -1159,7 +1201,7 @@ msgstr "Skippa rad"
msgid "Error running game:"
msgstr "Fel under körning av spel:"
-#: base/main.cpp:536
+#: base/main.cpp:554
msgid "Could not find any engine capable of running the selected game"
msgstr "Kunde inte hitta en motor kapabel till att köra det valda spelet"
@@ -1277,7 +1319,7 @@ msgstr "Åte~r~vänd till launcher"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:803
#: engines/cruise/menu.cpp:212 engines/drascula/saveload.cpp:336
#: engines/dreamweb/saveload.cpp:261 engines/neverhood/menumodule.cpp:873
-#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:758
+#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:759
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save game:"
msgstr "Spara spelet:"
@@ -1290,7 +1332,7 @@ msgstr "Spara spelet:"
#: engines/agi/saveload.cpp:803 engines/cruise/menu.cpp:212
#: engines/drascula/saveload.cpp:336 engines/dreamweb/saveload.cpp:261
#: engines/neverhood/menumodule.cpp:873 engines/pegasus/pegasus.cpp:377
-#: engines/sci/engine/kfile.cpp:758 engines/scumm/dialogs.cpp:188
+#: engines/sci/engine/kfile.cpp:759 engines/scumm/dialogs.cpp:188
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save"
msgstr "Spara"
@@ -1328,23 +1370,23 @@ msgstr "A~v~bryt"
msgid "~K~eys"
msgstr "~T~angenter"
-#: engines/engine.cpp:245
+#: engines/engine.cpp:276
msgid "Could not initialize color format."
msgstr "Kunde inte initialisera färgformat."
-#: engines/engine.cpp:253
+#: engines/engine.cpp:284
msgid "Could not switch to video mode: '"
msgstr "Kunde inte byta till videoläget: '"
-#: engines/engine.cpp:262
+#: engines/engine.cpp:293
msgid "Could not apply aspect ratio setting."
msgstr "Kunde inte ändra inställningen för bildförhållanden."
-#: engines/engine.cpp:267
+#: engines/engine.cpp:298
msgid "Could not apply fullscreen setting."
msgstr "Kunde inte applicera fullskärmsinställning."
-#: engines/engine.cpp:367
+#: engines/engine.cpp:398
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1358,7 +1400,7 @@ msgstr ""
"datafilerna till din hårddisk istället.\n"
"Se README-filen för detaljer."
-#: engines/engine.cpp:378
+#: engines/engine.cpp:409
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1372,7 +1414,7 @@ msgstr ""
"för att kunna lyssna på spelets musik.\n"
"Se README-filen för detaljer."
-#: engines/engine.cpp:436
+#: engines/engine.cpp:467
#, c-format
msgid ""
"Gamestate load failed (%s)! Please consult the README for basic information, "
@@ -1381,7 +1423,7 @@ msgstr ""
"Kunde inte ladda spardata (%s)! Hänvisa till README-filen för grundläggande "
"information och instruktioner för ytterligare assistans."
-#: engines/engine.cpp:449
+#: engines/engine.cpp:480
msgid ""
"WARNING: The game you are about to start is not yet fully supported by "
"ScummVM. As such, it is likely to be unstable, and any saves you make might "
@@ -1391,7 +1433,7 @@ msgstr ""
"ScummVM. Därför är det troligtvis instabilt och om du skapar spardata kan de "
"möjligtvis vara inkompatibla med framtida versioner av ScummVM."
-#: engines/engine.cpp:452
+#: engines/engine.cpp:483
msgid "Start anyway"
msgstr "Starta ändå"
@@ -1601,11 +1643,11 @@ msgstr "Touchpad-läge aktiverat."
msgid "Touchpad mode disabled."
msgstr "Touchpad-läge inaktiverat."
-#: backends/platform/maemo/maemo.cpp:209
+#: backends/platform/maemo/maemo.cpp:208
msgid "Click Mode"
msgstr "Klickläge"
-#: backends/platform/maemo/maemo.cpp:215
+#: backends/platform/maemo/maemo.cpp:214
#: backends/platform/symbian/src/SymbianActions.cpp:42
#: backends/platform/wince/CEActionsPocket.cpp:60
#: backends/platform/wince/CEActionsSmartphone.cpp:43
@@ -1613,11 +1655,11 @@ msgstr "Klickläge"
msgid "Left Click"
msgstr "Vänsterklick"
-#: backends/platform/maemo/maemo.cpp:218
+#: backends/platform/maemo/maemo.cpp:217
msgid "Middle Click"
msgstr "Mittenklick"
-#: backends/platform/maemo/maemo.cpp:221
+#: backends/platform/maemo/maemo.cpp:220
#: backends/platform/symbian/src/SymbianActions.cpp:43
#: backends/platform/wince/CEActionsSmartphone.cpp:44
#: backends/platform/tizen/form.cpp:267
@@ -1654,19 +1696,19 @@ msgctxt "lowres"
msgid "Normal (no scaling)"
msgstr "Normalt (ingen skalning)"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2148
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2197
msgid "Enabled aspect ratio correction"
msgstr "Korrektion av bildförhållande på"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2154
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2203
msgid "Disabled aspect ratio correction"
msgstr "Korrektion av bildförhållande av"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2209
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2258
msgid "Active graphics filter:"
msgstr "Aktivt grafikfilter:"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2251
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2300
msgid "Windowed mode"
msgstr "Fönsterläge"
@@ -1725,8 +1767,8 @@ msgstr "Snabbläge"
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
#: backends/events/default/default-events.cpp:218
-#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:82
-#: engines/scumm/help.cpp:84
+#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:83
+#: engines/scumm/help.cpp:85
msgid "Quit"
msgstr "Avsluta"
@@ -1746,7 +1788,7 @@ msgstr "Virtuellt tangentbord"
msgid "Key mapper"
msgstr "Tangentinst."
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
msgid "Do you want to quit ?"
msgstr "Vill du avsluta?"
@@ -2082,33 +2124,54 @@ msgstr "Klickning aktiverad"
msgid "Clicking Disabled"
msgstr "Klickning deaktiverad"
-#: engines/agi/detection.cpp:142 engines/drascula/detection.cpp:302
+#: engines/agi/detection.cpp:147 engines/drascula/detection.cpp:302
#: engines/dreamweb/detection.cpp:47 engines/neverhood/detection.cpp:160
#: engines/sci/detection.cpp:394 engines/toltecs/detection.cpp:200
-#: engines/zvision/detection.cpp:103
+#: engines/zvision/detection.cpp:246
msgid "Use original save/load screens"
msgstr "Använd originalskärmar för spara/ladda"
-#: engines/agi/detection.cpp:143 engines/drascula/detection.cpp:303
+#: engines/agi/detection.cpp:148 engines/drascula/detection.cpp:303
#: engines/dreamweb/detection.cpp:48 engines/neverhood/detection.cpp:161
#: engines/sci/detection.cpp:395 engines/toltecs/detection.cpp:201
-#: engines/zvision/detection.cpp:104
+#: engines/zvision/detection.cpp:247
msgid "Use the original save/load screens, instead of the ScummVM ones"
msgstr "Använder originalskärmarna för spara/ladda istället för ScummVM:s"
+#: engines/agi/detection.cpp:157
+#, fuzzy
+msgid "Use an alternative palette"
+msgstr "Använd alternativt spelintro (endast CD-version)"
+
+#: engines/agi/detection.cpp:158
+msgid ""
+"Use an alternative palette, common for all Amiga games. This was the old "
+"behavior"
+msgstr ""
+
+#: engines/agi/detection.cpp:167
+#, fuzzy
+msgid "Mouse support"
+msgstr "Skipp-stöd"
+
+#: engines/agi/detection.cpp:168
+msgid ""
+"Enables mouse support. Allows to use mouse for movement and in game menus."
+msgstr ""
+
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore game:"
msgstr "Återställ spel:"
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore"
msgstr "Återställ"
-#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2368
+#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2377
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -2119,7 +2182,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2361
+#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2370
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -2130,7 +2193,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2379
+#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2388
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -2146,12 +2209,12 @@ msgstr ""
msgid "Cutscene file '%s' not found!"
msgstr "Filmscensfilen '%s' hittades ej!"
-#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:81
+#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:101
#, fuzzy
msgid "Color Blind Mode"
msgstr "Klickläge"
-#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:82
+#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:102
msgid "Enable Color Blind Mode by default"
msgstr ""
@@ -2203,7 +2266,7 @@ msgstr "Snabb filmhastighet"
msgid "Play movies at an increased speed"
msgstr "Spela filmer i högre hastighet"
-#: engines/groovie/script.cpp:399
+#: engines/groovie/script.cpp:408
msgid "Failed to save game"
msgstr "Kunde inte spara spelet."
@@ -2501,12 +2564,12 @@ msgid "Use an alternative game intro (CD version only)"
msgstr "Använd alternativt spelintro (endast CD-version)"
#: engines/sci/detection.cpp:374
-msgid "EGA undithering"
-msgstr "EGA anti-gitter"
+msgid "Skip EGA dithering pass (full color backgrounds)"
+msgstr ""
#: engines/sci/detection.cpp:375
-msgid "Enable undithering in EGA games"
-msgstr "Aktivera anti-gitter i EGA-spel"
+msgid "Skip dithering pass in EGA games, graphics are shown with full colors"
+msgstr ""
#: engines/sci/detection.cpp:384
msgid "Prefer digital sound effects"
@@ -2579,12 +2642,14 @@ msgstr "Spelet pausat. Tryck MELLANSLAG för att fortsätta."
#. "Moechten Sie wirklich neu starten? (J/N)J"
#. Will react to J as 'Yes'
#: engines/scumm/dialogs.cpp:183
-msgid "Are you sure you want to restart? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to restart? (Y/N)Y"
msgstr "Är du säker på att du vill starta om? (J/N)J"
#. I18N: you may specify 'Yes' symbol at the end of the line. See previous comment
#: engines/scumm/dialogs.cpp:185
-msgid "Are you sure you want to quit? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to quit? (Y/N)Y"
msgstr "Är du säker på att du vill avsluta? (J/N)J"
#: engines/scumm/dialogs.cpp:190
@@ -2672,516 +2737,541 @@ msgstr "Övning"
msgid "Expert"
msgstr "Expert"
-#: engines/scumm/help.cpp:73
+#: engines/scumm/help.cpp:74
msgid "Common keyboard commands:"
msgstr "Vanliga kortkommandon:"
-#: engines/scumm/help.cpp:74
+#: engines/scumm/help.cpp:75
msgid "Save / Load dialog"
msgstr "Spara / Ladda-fönster"
-#: engines/scumm/help.cpp:76
+#: engines/scumm/help.cpp:77
msgid "Skip line of text"
msgstr "Skippa textrad"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Esc"
msgstr "Esc"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Skip cutscene"
msgstr "Skippa scen"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Space"
msgstr "Mellanslag"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Pause game"
msgstr "Pausa spelet"
-#: engines/scumm/help.cpp:79 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:95 engines/scumm/help.cpp:96
-#: engines/scumm/help.cpp:97 engines/scumm/help.cpp:98
-#: engines/scumm/help.cpp:99 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:96 engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98 engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Ctrl"
msgstr "Ctrl"
-#: engines/scumm/help.cpp:79
+#: engines/scumm/help.cpp:80
msgid "Load game state 1-10"
msgstr "Ladda spardata 1-10"
-#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:81 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Alt"
msgstr "Alt"
-#: engines/scumm/help.cpp:80
+#: engines/scumm/help.cpp:81
msgid "Save game state 1-10"
msgstr "Spara speldata 1-10"
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:90
msgid "Enter"
msgstr "Enter"
-#: engines/scumm/help.cpp:87
+#: engines/scumm/help.cpp:88
msgid "Music volume up / down"
msgstr "Musikvolym höj / sänk"
-#: engines/scumm/help.cpp:88
+#: engines/scumm/help.cpp:89
msgid "Text speed slower / faster"
msgstr "Texthastighet sänk / öka"
-#: engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:90
msgid "Simulate left mouse button"
msgstr "Simulera vänster musknapp"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Tab"
msgstr "Tab"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Simulate right mouse button"
msgstr "Simulera höger musknapp"
-#: engines/scumm/help.cpp:93
+#: engines/scumm/help.cpp:94
msgid "Special keyboard commands:"
msgstr "Specialkortkommandon:"
-#: engines/scumm/help.cpp:94
+#: engines/scumm/help.cpp:95
msgid "Show / Hide console"
msgstr "Visa / göm konsol"
-#: engines/scumm/help.cpp:95
+#: engines/scumm/help.cpp:96
msgid "Start the debugger"
msgstr "Öppna debug-konsolen"
-#: engines/scumm/help.cpp:96
+#: engines/scumm/help.cpp:97
msgid "Show memory consumption"
msgstr "Visa minnesförbrukning"
-#: engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98
msgid "Run in fast mode (*)"
msgstr "Kör i snabbläge (*)"
-#: engines/scumm/help.cpp:98
+#: engines/scumm/help.cpp:99
msgid "Run in really fast mode (*)"
msgstr "Kör i extra snabbt läge (*)"
-#: engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100
msgid "Toggle mouse capture"
msgstr "Musrestriktion av/på"
-#: engines/scumm/help.cpp:100
+#: engines/scumm/help.cpp:101
msgid "Switch between graphics filters"
msgstr "Växla grafikfilter"
-#: engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102
msgid "Increase / Decrease scale factor"
msgstr "Öka / sänk skalningsfaktor"
-#: engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:103
msgid "Toggle aspect-ratio correction"
msgstr "Korrektion av bildförhållande på/av"
-#: engines/scumm/help.cpp:107
+#: engines/scumm/help.cpp:108
msgid "* Note that using ctrl-f and"
msgstr "* Observera att användning av ctrl-f"
-#: engines/scumm/help.cpp:108
+#: engines/scumm/help.cpp:109
msgid " ctrl-g are not recommended"
msgstr "och ctrl-g inte rekommenderas"
-#: engines/scumm/help.cpp:109
+#: engines/scumm/help.cpp:110
msgid " since they may cause crashes"
msgstr "då detta kan orsaka krascher"
-#: engines/scumm/help.cpp:110
+#: engines/scumm/help.cpp:111
msgid " or incorrect game behavior."
msgstr " eller felaktigt spelbeteende."
-#: engines/scumm/help.cpp:114
+#: engines/scumm/help.cpp:115
msgid "Spinning drafts on the keyboard:"
msgstr "Väva melodier med tangentbordet:"
-#: engines/scumm/help.cpp:116
+#: engines/scumm/help.cpp:117
msgid "Main game controls:"
msgstr "Huvudkontroller:"
-#: engines/scumm/help.cpp:121 engines/scumm/help.cpp:136
-#: engines/scumm/help.cpp:161
+#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
+#: engines/scumm/help.cpp:162
msgid "Push"
msgstr "Tryck"
-#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
-#: engines/scumm/help.cpp:162
+#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
+#: engines/scumm/help.cpp:163
msgid "Pull"
msgstr "Dra"
-#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
-#: engines/scumm/help.cpp:163 engines/scumm/help.cpp:197
-#: engines/scumm/help.cpp:207
+#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
+#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:198
+#: engines/scumm/help.cpp:208
msgid "Give"
msgstr "Ge"
-#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
-#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:190
-#: engines/scumm/help.cpp:208
+#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
+#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
+#: engines/scumm/help.cpp:209
msgid "Open"
msgstr "Öppna"
-#: engines/scumm/help.cpp:126
+#: engines/scumm/help.cpp:127
msgid "Go to"
msgstr "Gå till"
-#: engines/scumm/help.cpp:127
+#: engines/scumm/help.cpp:128
msgid "Get"
msgstr "Ta emot"
-#: engines/scumm/help.cpp:128 engines/scumm/help.cpp:152
-#: engines/scumm/help.cpp:170 engines/scumm/help.cpp:198
-#: engines/scumm/help.cpp:213 engines/scumm/help.cpp:224
-#: engines/scumm/help.cpp:250
+#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:153
+#: engines/scumm/help.cpp:171 engines/scumm/help.cpp:199
+#: engines/scumm/help.cpp:214 engines/scumm/help.cpp:225
+#: engines/scumm/help.cpp:251
msgid "Use"
msgstr "Använd"
-#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:142
msgid "Read"
msgstr "Läs"
-#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:147
+#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:148
msgid "New kid"
msgstr "Ny unge"
-#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:153
-#: engines/scumm/help.cpp:171
+#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
+#: engines/scumm/help.cpp:172
msgid "Turn on"
msgstr "Sätt på"
-#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
-#: engines/scumm/help.cpp:172
+#: engines/scumm/help.cpp:133 engines/scumm/help.cpp:155
+#: engines/scumm/help.cpp:173
msgid "Turn off"
msgstr "Stäng av"
-#: engines/scumm/help.cpp:142 engines/scumm/help.cpp:167
-#: engines/scumm/help.cpp:194
+#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
+#: engines/scumm/help.cpp:195
msgid "Walk to"
msgstr "Gå till"
-#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
-#: engines/scumm/help.cpp:195 engines/scumm/help.cpp:210
-#: engines/scumm/help.cpp:227
+#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:228
msgid "Pick up"
msgstr "Ta"
-#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:145 engines/scumm/help.cpp:170
msgid "What is"
msgstr "Vad är"
-#: engines/scumm/help.cpp:146
+#: engines/scumm/help.cpp:147
msgid "Unlock"
msgstr "Lås upp"
-#: engines/scumm/help.cpp:149
+#: engines/scumm/help.cpp:150
msgid "Put on"
msgstr "Ta på"
-#: engines/scumm/help.cpp:150
+#: engines/scumm/help.cpp:151
msgid "Take off"
msgstr "Ta av"
-#: engines/scumm/help.cpp:156
+#: engines/scumm/help.cpp:157
msgid "Fix"
msgstr "Laga"
-#: engines/scumm/help.cpp:158
+#: engines/scumm/help.cpp:159
msgid "Switch"
msgstr "Byt"
-#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:228
+#: engines/scumm/help.cpp:167 engines/scumm/help.cpp:229
msgid "Look"
msgstr "Titta"
-#: engines/scumm/help.cpp:173 engines/scumm/help.cpp:223
+#: engines/scumm/help.cpp:174 engines/scumm/help.cpp:224
msgid "Talk"
msgstr "Tala"
-#: engines/scumm/help.cpp:174
+#: engines/scumm/help.cpp:175
msgid "Travel"
msgstr "Res"
-#: engines/scumm/help.cpp:175
+#: engines/scumm/help.cpp:176
msgid "To Henry / To Indy"
msgstr "Till Henry / Till Indy"
#. I18N: These are different musical notes
-#: engines/scumm/help.cpp:179
+#: engines/scumm/help.cpp:180
msgid "play C minor on distaff"
msgstr "spela C-moll på staven"
-#: engines/scumm/help.cpp:180
+#: engines/scumm/help.cpp:181
msgid "play D on distaff"
msgstr "spela D på staven"
-#: engines/scumm/help.cpp:181
+#: engines/scumm/help.cpp:182
msgid "play E on distaff"
msgstr "spela E på staven"
-#: engines/scumm/help.cpp:182
+#: engines/scumm/help.cpp:183
msgid "play F on distaff"
msgstr "spela F på staven"
-#: engines/scumm/help.cpp:183
+#: engines/scumm/help.cpp:184
msgid "play G on distaff"
msgstr "spela G på staven"
-#: engines/scumm/help.cpp:184
+#: engines/scumm/help.cpp:185
msgid "play A on distaff"
msgstr "spela A på staven"
-#: engines/scumm/help.cpp:185
+#: engines/scumm/help.cpp:186
msgid "play B on distaff"
msgstr "spela H på staven"
-#: engines/scumm/help.cpp:186
+#: engines/scumm/help.cpp:187
msgid "play C major on distaff"
msgstr "spela C-dur på staven"
-#: engines/scumm/help.cpp:192 engines/scumm/help.cpp:214
+#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
msgid "puSh"
msgstr "Tryck"
-#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
+#: engines/scumm/help.cpp:194 engines/scumm/help.cpp:216
msgid "pull (Yank)"
msgstr "Dra"
-#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:212
-#: engines/scumm/help.cpp:248
+#: engines/scumm/help.cpp:197 engines/scumm/help.cpp:213
+#: engines/scumm/help.cpp:249
msgid "Talk to"
msgstr "Tala med"
-#: engines/scumm/help.cpp:199 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:200 engines/scumm/help.cpp:212
msgid "Look at"
msgstr "Titta på"
-#: engines/scumm/help.cpp:200
+#: engines/scumm/help.cpp:201
msgid "turn oN"
msgstr "Sätt på"
-#: engines/scumm/help.cpp:201
+#: engines/scumm/help.cpp:202
msgid "turn oFf"
msgstr "Stäng av"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "KeyUp"
msgstr "Piltangent upp"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "Highlight prev dialogue"
msgstr "Markera föreg. dialog"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "KeyDown"
msgstr "Piltangent ned"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "Highlight next dialogue"
msgstr "Markera nästa dialog"
-#: engines/scumm/help.cpp:222
+#: engines/scumm/help.cpp:223
msgid "Walk"
msgstr "Gå"
-#: engines/scumm/help.cpp:225 engines/scumm/help.cpp:234
-#: engines/scumm/help.cpp:241 engines/scumm/help.cpp:249
+#: engines/scumm/help.cpp:226 engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:242 engines/scumm/help.cpp:250
msgid "Inventory"
msgstr "Inventarie"
-#: engines/scumm/help.cpp:226
+#: engines/scumm/help.cpp:227
msgid "Object"
msgstr "Objekt"
-#: engines/scumm/help.cpp:229
+#: engines/scumm/help.cpp:230
msgid "Black and White / Color"
msgstr "Svartvitt / Färg"
-#: engines/scumm/help.cpp:232
+#: engines/scumm/help.cpp:233
msgid "Eyes"
msgstr "Ögon"
-#: engines/scumm/help.cpp:233
+#: engines/scumm/help.cpp:234
msgid "Tongue"
msgstr "Tunga"
-#: engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:236
msgid "Punch"
msgstr "Slå"
-#: engines/scumm/help.cpp:236
+#: engines/scumm/help.cpp:237
msgid "Kick"
msgstr "Sparka"
-#: engines/scumm/help.cpp:239 engines/scumm/help.cpp:247
+#: engines/scumm/help.cpp:240 engines/scumm/help.cpp:248
msgid "Examine"
msgstr "Undersök"
-#: engines/scumm/help.cpp:240
+#: engines/scumm/help.cpp:241
msgid "Regular cursor"
msgstr "Vanlig pekare"
#. I18N: Comm is a communication device
-#: engines/scumm/help.cpp:243
+#: engines/scumm/help.cpp:244
msgid "Comm"
msgstr "Comm"
-#: engines/scumm/help.cpp:246
+#: engines/scumm/help.cpp:247
msgid "Save / Load / Options"
msgstr "Spara / Ladda / Inst."
-#: engines/scumm/help.cpp:255
+#: engines/scumm/help.cpp:256
msgid "Other game controls:"
msgstr "Övriga spelkontroller:"
-#: engines/scumm/help.cpp:257 engines/scumm/help.cpp:267
+#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:268
msgid "Inventory:"
msgstr "Inventarie:"
-#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:274
+#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
msgid "Scroll list up"
msgstr "Bläddra listan uppåt"
-#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
+#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:276
msgid "Scroll list down"
msgstr "Bläddra listan nedåt"
-#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:268
+#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:269
msgid "Upper left item"
msgstr "Övre vänstra föremålet"
-#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:270
+#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
msgid "Lower left item"
msgstr "Nedre vänstra föremålet"
-#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
+#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:272
msgid "Upper right item"
msgstr "Övre högra föremålet"
-#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:273
+#: engines/scumm/help.cpp:264 engines/scumm/help.cpp:274
msgid "Lower right item"
msgstr "Nedre högra föremålet"
-#: engines/scumm/help.cpp:269
+#: engines/scumm/help.cpp:270
msgid "Middle left item"
msgstr "Mellersta vänstra föremålet"
-#: engines/scumm/help.cpp:272
+#: engines/scumm/help.cpp:273
msgid "Middle right item"
msgstr "Mellersta högra föremålet"
-#: engines/scumm/help.cpp:279 engines/scumm/help.cpp:284
+#: engines/scumm/help.cpp:280 engines/scumm/help.cpp:285
msgid "Switching characters:"
msgstr "Byta karaktärer:"
-#: engines/scumm/help.cpp:281
+#: engines/scumm/help.cpp:282
msgid "Second kid"
msgstr "Andra ungen"
-#: engines/scumm/help.cpp:282
+#: engines/scumm/help.cpp:283
msgid "Third kid"
msgstr "Tredje ungen"
-#: engines/scumm/help.cpp:294
+#: engines/scumm/help.cpp:292
+#, fuzzy
+msgid "Toggle Inventory/IQ Points display"
+msgstr "Aktivera centrerad dataskärm"
+
+#: engines/scumm/help.cpp:293
+msgid "Toggle Keyboard/Mouse Fighting (*)"
+msgstr ""
+
+#: engines/scumm/help.cpp:295
+msgid "* Keyboard Fighting is always on,"
+msgstr ""
+
+#: engines/scumm/help.cpp:296
+msgid " so despite the in-game message this"
+msgstr ""
+
+#: engines/scumm/help.cpp:297
+msgid " actually toggles Mouse Fighting Off/On"
+msgstr ""
+
+#: engines/scumm/help.cpp:304
msgid "Fighting controls (numpad):"
msgstr "Slagsmålskontroller (nr. tangenter)"
-#: engines/scumm/help.cpp:295 engines/scumm/help.cpp:296
-#: engines/scumm/help.cpp:297
+#: engines/scumm/help.cpp:305 engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:307
msgid "Step back"
msgstr "Steg bakåt"
-#: engines/scumm/help.cpp:298
+#: engines/scumm/help.cpp:308
msgid "Block high"
msgstr "Blockera högt"
-#: engines/scumm/help.cpp:299
+#: engines/scumm/help.cpp:309
msgid "Block middle"
msgstr "Blockera midjehöjd"
-#: engines/scumm/help.cpp:300
+#: engines/scumm/help.cpp:310
msgid "Block low"
msgstr "Blockera lågt"
-#: engines/scumm/help.cpp:301
+#: engines/scumm/help.cpp:311
msgid "Punch high"
msgstr "Slå högt"
-#: engines/scumm/help.cpp:302
+#: engines/scumm/help.cpp:312
msgid "Punch middle"
msgstr "Slå midjehöjd"
-#: engines/scumm/help.cpp:303
+#: engines/scumm/help.cpp:313
msgid "Punch low"
msgstr "Slå lågt"
-#: engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:315
+msgid "Sucker punch"
+msgstr ""
+
+#: engines/scumm/help.cpp:318
msgid "These are for Indy on left."
msgstr "Gäller när Indy står till vänster."
-#: engines/scumm/help.cpp:307
+#: engines/scumm/help.cpp:319
msgid "When Indy is on the right,"
msgstr "När Indy står till höger byter"
-#: engines/scumm/help.cpp:308
+#: engines/scumm/help.cpp:320
msgid "7, 4, and 1 are switched with"
msgstr "7, 4 och 1 plats med"
-#: engines/scumm/help.cpp:309
+#: engines/scumm/help.cpp:321
msgid "9, 6, and 3, respectively."
msgstr "9, 6 och 3."
-#: engines/scumm/help.cpp:316
+#: engines/scumm/help.cpp:328
msgid "Biplane controls (numpad):"
msgstr "Biplanskontroller (nr. tangenter)"
-#: engines/scumm/help.cpp:317
+#: engines/scumm/help.cpp:329
msgid "Fly to upper left"
msgstr "Flyg åt övre vänster"
-#: engines/scumm/help.cpp:318
+#: engines/scumm/help.cpp:330
msgid "Fly to left"
msgstr "Flyg åt vänster"
-#: engines/scumm/help.cpp:319
+#: engines/scumm/help.cpp:331
msgid "Fly to lower left"
msgstr "Flyg åt nedre vänster"
-#: engines/scumm/help.cpp:320
+#: engines/scumm/help.cpp:332
msgid "Fly upwards"
msgstr "Flyg uppåt"
-#: engines/scumm/help.cpp:321
+#: engines/scumm/help.cpp:333
msgid "Fly straight"
msgstr "Flyg rakt fram"
-#: engines/scumm/help.cpp:322
+#: engines/scumm/help.cpp:334
msgid "Fly down"
msgstr "Flyg nedåt"
-#: engines/scumm/help.cpp:323
+#: engines/scumm/help.cpp:335
msgid "Fly to upper right"
msgstr "Flyg åt övre höger"
-#: engines/scumm/help.cpp:324
+#: engines/scumm/help.cpp:336
msgid "Fly to right"
msgstr "Flyg åt höger"
-#: engines/scumm/help.cpp:325
+#: engines/scumm/help.cpp:337
msgid "Fly to lower right"
msgstr "Flyg åt nedre höger"
-#: engines/scumm/scumm.cpp:1823
+#: engines/scumm/scumm.cpp:1832
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
@@ -3190,11 +3280,12 @@ msgstr ""
"Stöd för Native MIDI kräver Roland-uppdateringen från LucasArts,\n"
"men %s saknas. Använder AdLib istället."
-#: engines/scumm/scumm.cpp:2594
+#: engines/scumm/scumm.cpp:2644
+#, fuzzy
msgid ""
-"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
-"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
-"directory inside the Tentacle game directory."
+"Usually, Maniac Mansion would start now. But for that to work, the game "
+"files for Maniac Mansion have to be in the 'Maniac' directory inside the "
+"Tentacle game directory, and the game has to be added to ScummVM."
msgstr ""
"Vanligtvis hade Maniac Mansion startat nu, men ScummVM kan inte göra detta "
"än. För att spela spelet, gå till \"Lägg till spel\" i ScummVM:s huvudmeny "
@@ -3328,6 +3419,48 @@ msgstr ""
msgid "Show the current number of frames per second in the upper left corner"
msgstr ""
+#: engines/zvision/detection.cpp:256
+msgid "Double FPS"
+msgstr ""
+
+#: engines/zvision/detection.cpp:257
+msgid "Increase game FPS from 30 to 60"
+msgstr ""
+
+#: engines/zvision/detection.cpp:266
+#, fuzzy
+msgid "Enable Venus"
+msgstr "Aktivera heliumläge"
+
+#: engines/zvision/detection.cpp:267
+msgid "Enable the Venus help system"
+msgstr ""
+
+#: engines/zvision/detection.cpp:276
+msgid "Disable animation while turning"
+msgstr ""
+
+#: engines/zvision/detection.cpp:277
+msgid "Disable animation while turning in panoramic mode"
+msgstr ""
+
+#: engines/zvision/detection.cpp:286
+msgid "Use the hires MPEG movies"
+msgstr ""
+
+#: engines/zvision/detection.cpp:287
+#, fuzzy
+msgid ""
+"Use the hires MPEG movies of the DVD version, instead of the lowres AVI ones"
+msgstr ""
+"Använd de alternativa silverpekarna istället för de normala guldpekarna"
+
+#~ msgid "EGA undithering"
+#~ msgstr "EGA anti-gitter"
+
+#~ msgid "Enable undithering in EGA games"
+#~ msgstr "Aktivera anti-gitter i EGA-spel"
+
#~ msgid "MPEG-2 cutscenes found but ScummVM has been built without MPEG-2"
#~ msgstr "MPEG-2-filmscener hittades men ScummVM har byggts utan MPEG-2"
@@ -3335,9 +3468,6 @@ msgstr ""
#~ msgid "Mass Add..."
#~ msgstr "Masstillägg..."
-#~ msgid "Mass Add..."
-#~ msgstr "Masstillägg..."
-
#~ msgid ""
#~ "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
#~ msgstr ""
diff --git a/po/uk_UA.po b/po/uk_UA.po
index 5a7554189e..7245d1bcf7 100644
--- a/po/uk_UA.po
+++ b/po/uk_UA.po
@@ -1,5 +1,5 @@
# Ukrainian translation for ScummVM.
-# Copyright (C) 2010-2014 ScummVM Team
+# Copyright (C) 2010-2015 The ScummVM Team
# This file is distributed under the same license as the ScummVM package.
# Lubomyr Lisen, 2010.
# Eugene Sandulenko <sev@scummvm.org>, 2010-2014
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.3.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2014-10-04 00:58+0100\n"
+"POT-Creation-Date: 2015-06-30 20:57+0100\n"
"PO-Revision-Date: 2014-07-01 02:34+0300\n"
"Last-Translator: Eugene Sandulenko <sev@scummvm.org>\n"
"Language-Team: Ukrainian\n"
@@ -55,10 +55,11 @@ msgstr "²ÓÞàã"
#: gui/browser.cpp:75 gui/chooser.cpp:46 gui/KeysDialog.cpp:43
#: gui/launcher.cpp:351 gui/massadd.cpp:95 gui/options.cpp:1239
+#: gui/recorderdialog.cpp:70 gui/recorderdialog.cpp:156
#: gui/saveload-dialog.cpp:216 gui/saveload-dialog.cpp:276
-#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:922
+#: gui/saveload-dialog.cpp:547 gui/saveload-dialog.cpp:931
#: gui/themebrowser.cpp:55 gui/fluidsynth-dialog.cpp:152
-#: engines/engine.cpp:452 backends/platform/wii/options.cpp:48
+#: engines/engine.cpp:483 backends/platform/wii/options.cpp:48
#: backends/events/default/default-events.cpp:196
#: backends/events/default/default-events.cpp:218
#: engines/drascula/saveload.cpp:49 engines/parallaction/saveload.cpp:274
@@ -71,9 +72,9 @@ msgid "Choose"
msgstr "²ØÑàÐâØ"
#: gui/gui-manager.cpp:117 backends/keymapper/remap-dialog.cpp:53
-#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
-#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
-#: engines/scumm/help.cpp:209
+#: engines/scumm/help.cpp:126 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:192
+#: engines/scumm/help.cpp:210
msgid "Close"
msgstr "·ÐÚàØâØ"
@@ -89,7 +90,7 @@ msgstr "¿ÞÚÐ×ÐâØ ÚÛÐÒöÐâãàã"
msgid "Remap keys"
msgstr "¿ÕàÕßàØ×ÝÐçØâØ ÚÛÐÒöèö"
-#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:86
+#: gui/gui-manager.cpp:131 base/main.cpp:326 engines/scumm/help.cpp:87
msgid "Toggle fullscreen"
msgstr "¿ÕàÕÜÚÝãâØ ßÞÒÝÞÕÚàÐÝÝØÙ àÕÖØÜ"
@@ -103,13 +104,13 @@ msgstr "¿àØ×ÝÐçØâØ"
#: gui/KeysDialog.cpp:42 gui/launcher.cpp:352 gui/launcher.cpp:1048
#: gui/launcher.cpp:1052 gui/massadd.cpp:92 gui/options.cpp:1240
-#: gui/saveload-dialog.cpp:923 gui/fluidsynth-dialog.cpp:153
-#: engines/engine.cpp:371 engines/engine.cpp:382
+#: gui/saveload-dialog.cpp:932 gui/fluidsynth-dialog.cpp:153
+#: engines/engine.cpp:402 engines/engine.cpp:413
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
#: engines/agos/animation.cpp:558 engines/drascula/saveload.cpp:49
-#: engines/groovie/script.cpp:399 engines/parallaction/saveload.cpp:274
-#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1825
+#: engines/groovie/script.cpp:408 engines/parallaction/saveload.cpp:274
+#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1834
#: engines/scumm/players/player_v3m.cpp:130
#: engines/scumm/players/player_v5m.cpp:108 engines/sky/compact.cpp:131
#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:524
@@ -479,7 +480,7 @@ msgstr ""
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -489,7 +490,7 @@ msgstr "ÂÐÚ"
#: gui/launcher.cpp:793 gui/launcher.cpp:941 gui/launcher.cpp:1000
#: gui/fluidsynth-dialog.cpp:217
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
#: backends/platform/wince/CELauncherDialog.cpp:83
@@ -526,6 +527,14 @@ msgstr "Æï ÓàÐ ÝÕ ßöÔâàØÜãô ×ÐÒÐÝâÐÖÕÝÝï ×ÑÕàÕÖÕÝì çÕàÕ× ÓÞÛÞÒÝÕ ÜÕÝî."
msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr "ScummVM ÝÕ ×ÜöÓ ×ÝÐÙâØ ÔÒØÖÞÚ ÔÛï ×ÐßãáÚã ÒØÑàÐÝÞ÷ ÓàØ!"
+#: gui/launcher.cpp:1159
+msgid "Mass Add..."
+msgstr "´ÞÔ. ÑÐÓÐâÞ..."
+
+#: gui/launcher.cpp:1161
+msgid "Record..."
+msgstr ""
+
#: gui/massadd.cpp:79 gui/massadd.cpp:82
msgid "... progress ..."
msgstr "... ßÞèãÚ ..."
@@ -624,7 +633,7 @@ msgid "Special dithering modes supported by some games"
msgstr "ÁßÕæöÐÛìÝö àÕÖØÜØ àÐáâàãÒÐÝÝï, ïÚö ßöÔâàØÜãîâì ÔÕïÚö öÓàØ"
#: gui/options.cpp:760
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2249
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2298
msgid "Fullscreen mode"
msgstr "¿ÞÒÝÞÕÚàÐÝÝØÙ àÕÖØÜ"
@@ -943,6 +952,43 @@ msgstr ""
"²ØÑàÐÝÐ âÕÜÐ ÝÕ ßöÔâàØÜãô ßÞâÞçÝã ÜÞÒã. ÏÚéÞ ÒØ åÞçÕâÕ ÒØÚÞàØáâÞÒãÒÐâØ æî "
"âÕÜã, ßÞâàöÑÝÞ Ò ßÕàèã çÕàÓã ×ÜöÝØâØ ÜÞÒã."
+#: gui/recorderdialog.cpp:64
+msgid "Recorder or Playback Gameplay"
+msgstr ""
+
+#: gui/recorderdialog.cpp:69 gui/recorderdialog.cpp:156
+#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
+msgid "Delete"
+msgstr "²ØÔÐÛØâØ"
+
+#: gui/recorderdialog.cpp:71
+msgid "Record"
+msgstr ""
+
+#: gui/recorderdialog.cpp:72
+#, fuzzy
+msgid "Playback"
+msgstr "³àÐâØ"
+
+#: gui/recorderdialog.cpp:74
+msgid "Edit"
+msgstr ""
+
+#: gui/recorderdialog.cpp:86 gui/recorderdialog.cpp:243
+#: gui/recorderdialog.cpp:253
+msgid "Author: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:87 gui/recorderdialog.cpp:244
+#: gui/recorderdialog.cpp:254
+msgid "Notes: "
+msgstr ""
+
+#: gui/recorderdialog.cpp:155
+#, fuzzy
+msgid "Do you really want to delete this record?"
+msgstr "²Ø ÔöÙáÝÞ åÞçÕâÕ ÒØÔÐÛØâØ æÕ ×ÑÕàÕÖÕÝÝï?"
+
#: gui/saveload-dialog.cpp:167
msgid "List view"
msgstr "²ØÓÛïÔ áßØáÚã"
@@ -963,23 +1009,19 @@ msgstr "ÇÐá ÝÕ ×ÐßØáÐÝÞ"
msgid "No playtime saved"
msgstr "ÇÐá ÓàØ ÝÕ ×ÐßØáÐÝÞ"
-#: gui/saveload-dialog.cpp:220 gui/saveload-dialog.cpp:276
-msgid "Delete"
-msgstr "²ØÔÐÛØâØ"
-
#: gui/saveload-dialog.cpp:275
msgid "Do you really want to delete this saved game?"
msgstr "²Ø ÔöÙáÝÞ åÞçÕâÕ ÒØÔÐÛØâØ æÕ ×ÑÕàÕÖÕÝÝï?"
-#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:875
+#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:884
msgid "Date: "
msgstr "´ÐâÐ: "
-#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:881
+#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:890
msgid "Time: "
msgstr "ÇÐá: "
-#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:889
+#: gui/saveload-dialog.cpp:395 gui/saveload-dialog.cpp:898
msgid "Playtime: "
msgstr "ÇÐá ÓàØ: "
@@ -995,19 +1037,19 @@ msgstr "½ÐáãâßÝØÙ"
msgid "Prev"
msgstr "¿ÞßÕàÕÔÝöÙ"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "New Save"
msgstr "½ÞÒÕ ×ÑÕàÕÖÕÝÝï"
-#: gui/saveload-dialog.cpp:739
+#: gui/saveload-dialog.cpp:748
msgid "Create a new save game"
msgstr "ÁâÒÞàØâØ ÝÞÒØÙ ×ÐßØá ÓàØ"
-#: gui/saveload-dialog.cpp:868
+#: gui/saveload-dialog.cpp:877
msgid "Name: "
msgstr "½Ð×ÒÐ: "
-#: gui/saveload-dialog.cpp:940
+#: gui/saveload-dialog.cpp:949
#, c-format
msgid "Enter a description for slot %d:"
msgstr "²ÒÕÔöâì ÞßØá ÔÛï áÛÞâã %d:"
@@ -1160,7 +1202,7 @@ msgstr "¿àÞßãáâØâØ àïÔÞÚ"
msgid "Error running game:"
msgstr "¿ÞÜØÛÚÐ ×ÐßãáÚã ÓàØ:"
-#: base/main.cpp:536
+#: base/main.cpp:554
msgid "Could not find any engine capable of running the selected game"
msgstr "½Õ ÜÞÖã ×ÝÐÙâØ ÔÒØÖÞÚ ÔÛï ×ÐßãáÚã ÒØÑàÐÝÞ÷ ÓàØ"
@@ -1277,7 +1319,7 @@ msgstr "~¿~ÞÒÕà.Ò ÓÞÛÞÒÝÕ ÜÕÝî"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:803
#: engines/cruise/menu.cpp:212 engines/drascula/saveload.cpp:336
#: engines/dreamweb/saveload.cpp:261 engines/neverhood/menumodule.cpp:873
-#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:758
+#: engines/pegasus/pegasus.cpp:377 engines/sci/engine/kfile.cpp:759
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save game:"
msgstr "·ÑÕàÕÓâØ Óàã: "
@@ -1290,7 +1332,7 @@ msgstr "·ÑÕàÕÓâØ Óàã: "
#: engines/agi/saveload.cpp:803 engines/cruise/menu.cpp:212
#: engines/drascula/saveload.cpp:336 engines/dreamweb/saveload.cpp:261
#: engines/neverhood/menumodule.cpp:873 engines/pegasus/pegasus.cpp:377
-#: engines/sci/engine/kfile.cpp:758 engines/scumm/dialogs.cpp:188
+#: engines/sci/engine/kfile.cpp:759 engines/scumm/dialogs.cpp:188
#: engines/toltecs/menu.cpp:281 engines/tsage/scenes.cpp:598
msgid "Save"
msgstr "·ÐßØáÐâØ"
@@ -1328,23 +1370,23 @@ msgstr "²ö~Ô~ÜöÝÐ"
msgid "~K~eys"
msgstr "~º~ÛÐÒöèö"
-#: engines/engine.cpp:245
+#: engines/engine.cpp:276
msgid "Could not initialize color format."
msgstr "½Õ ÜÞÖã ÝÐÛÐèâãÒÐâØ äÞàÜÐâ ÚÞÛìÞàã."
-#: engines/engine.cpp:253
+#: engines/engine.cpp:284
msgid "Could not switch to video mode: '"
msgstr "½Õ ÒÔÐÛÞáï ßÕàÕÚÛîçØâØ ÒöÔÕÞàÕÖØÜ: '"
-#: engines/engine.cpp:262
+#: engines/engine.cpp:293
msgid "Could not apply aspect ratio setting."
msgstr "½Õ ÒÔÐÛÞáï ×ÐáâÞáãÒÐâØ ÚÞàÕÚæöî áßöÒÒöÔÝÞèÕÝÝï áâÞàöÝ."
-#: engines/engine.cpp:267
+#: engines/engine.cpp:298
msgid "Could not apply fullscreen setting."
msgstr "½Õ ÒÔÐÛÞáï ×ÐáâÞáãÒÐâØ ßÞÒÝÞÕÚàÐÝÝØÙ àÕÖØÜ."
-#: engines/engine.cpp:367
+#: engines/engine.cpp:398
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1358,7 +1400,7 @@ msgstr ""
"ÓàØ ÝÐ ÖÞàáâÚØÙ ÔØáÚ.\n"
"´ØÒöâìáï äÐÙÛ README ÔÛï ßÞÔÐÛìèØå öÝáâàãÚæöÙ."
-#: engines/engine.cpp:378
+#: engines/engine.cpp:409
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1372,7 +1414,7 @@ msgstr ""
"âÞÓÞ, éÞÑ ÜÞÖÝÐ ÑãÛÞ áÛãåÐâØ Üã×ØÚã ã Óàö.\n"
"´ØÒöâìáï äÐÙÛ README ÔÛï ßÞÔÐÛìèØå öÝáâàãÚæöÙ."
-#: engines/engine.cpp:436
+#: engines/engine.cpp:467
#, c-format
msgid ""
"Gamestate load failed (%s)! Please consult the README for basic information, "
@@ -1381,7 +1423,7 @@ msgstr ""
"·ÐÒÐÝâÐÖÕÝÝï áâÐÝã ÓàØ ÝÕ ÒÔÐÛÞáï (%s)! . ±ãÔì-ÛÐáÚÐ, ÔØÒöâìáï äÐÙÛ README "
"ÔÛï ÞáÝÞÒÝÞ÷ öÝÞàÜÐæö÷, Ð âÐÚÞÖ öÝáâàãÚæöÙ, ïÚ ÞâàØÜÐâØ ßÞÔÐÛìèã ÔÞßÞÜÞÓã."
-#: engines/engine.cpp:449
+#: engines/engine.cpp:480
msgid ""
"WARNING: The game you are about to start is not yet fully supported by "
"ScummVM. As such, it is likely to be unstable, and any saves you make might "
@@ -1391,7 +1433,7 @@ msgstr ""
"ScummVM. ÁÚÞàèÕ ×Ð ÒáÕ ÒÞÝÐ ÝÕ ÑãÔÕ ßàÐæîÒÐâØ áâÐÑöÛìÝÞ, ö ×ÑÕàÕÖÕÝÝï öÓÞà, "
"ïÚö ÒØ ×àÞÑØâÕ, ÜÞÖãâì ÝÕ ßàÐæîÒÐâØ ã ßÞÔÐÛìèØå ÒÕàáöïå ScummVM."
-#: engines/engine.cpp:452
+#: engines/engine.cpp:483
msgid "Start anyway"
msgstr "²áÕ ÞÔÝÞ ×ÐßãáâØâØ"
@@ -1601,11 +1643,11 @@ msgstr "ÀÕÖØÜ âÐçßÐÔã ãÒöÜÚÝÕÝÞ."
msgid "Touchpad mode disabled."
msgstr "ÀÕÖØÜ âÐçßÐÔã ÒØÜÚÝÕÝÞ."
-#: backends/platform/maemo/maemo.cpp:209
+#: backends/platform/maemo/maemo.cpp:208
msgid "Click Mode"
msgstr "ÀÕÖØÜ ÚÛöÚöÒ"
-#: backends/platform/maemo/maemo.cpp:215
+#: backends/platform/maemo/maemo.cpp:214
#: backends/platform/symbian/src/SymbianActions.cpp:42
#: backends/platform/wince/CEActionsPocket.cpp:60
#: backends/platform/wince/CEActionsSmartphone.cpp:43
@@ -1613,11 +1655,11 @@ msgstr "ÀÕÖØÜ ÚÛöÚöÒ"
msgid "Left Click"
msgstr "»öÒØÙ ÚÛöÚ"
-#: backends/platform/maemo/maemo.cpp:218
+#: backends/platform/maemo/maemo.cpp:217
msgid "Middle Click"
msgstr "ÁÕàÕÔÝöÙ ÚÛöÚ"
-#: backends/platform/maemo/maemo.cpp:221
+#: backends/platform/maemo/maemo.cpp:220
#: backends/platform/symbian/src/SymbianActions.cpp:43
#: backends/platform/wince/CEActionsSmartphone.cpp:44
#: backends/platform/tizen/form.cpp:267
@@ -1654,19 +1696,19 @@ msgctxt "lowres"
msgid "Normal (no scaling)"
msgstr "±Õ× ×ÑöÛìèÕÝÝï"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2148
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2197
msgid "Enabled aspect ratio correction"
msgstr "ºÞàÕÚæöî áßöÒÒöÔÝÞèÕÝÝï áâÞàöÝ ãÒöÜÚÝÕÝÞ"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2154
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2203
msgid "Disabled aspect ratio correction"
msgstr "ºÞàÕÚæöî áßöÒÒöÔÝÞèÕÝÝï áâÞàöÝ ÒØÜÚÝÕÝÞ"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2209
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2258
msgid "Active graphics filter:"
msgstr "¿ÞâÞçÝØÙ ÓàÐäöçÝØÙ äöÛìâà:"
-#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2251
+#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2300
msgid "Windowed mode"
msgstr "²öÚÞÝÝØÙ àÕÖØÜ"
@@ -1725,8 +1767,8 @@ msgstr "ÈÒØÔÚØÙ àÕÖØÜ"
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
#: backends/events/default/default-events.cpp:218
-#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:82
-#: engines/scumm/help.cpp:84
+#: engines/scumm/dialogs.cpp:192 engines/scumm/help.cpp:83
+#: engines/scumm/help.cpp:85
msgid "Quit"
msgstr "²ØåöÔ"
@@ -1746,7 +1788,7 @@ msgstr "²öàâãÐÛìÝÐ ÚÛÐÒöÐâãàÐ"
msgid "Key mapper"
msgstr "¿àØ×ÝÐçÕÝÝï ÚÛÐÒöè"
-#: backends/events/symbiansdl/symbiansdl-events.cpp:184
+#: backends/events/symbiansdl/symbiansdl-events.cpp:186
msgid "Do you want to quit ?"
msgstr "²Ø ÔöÙáÝÞ åÞçÕâÕ ÒØÙâØ?"
@@ -2081,34 +2123,55 @@ msgstr "ºÛöÚØ ãÒöÜÚÝÕÝÞ"
msgid "Clicking Disabled"
msgstr "ºÛöÚØ ÒØÜÚÝÕÝÞ"
-#: engines/agi/detection.cpp:142 engines/drascula/detection.cpp:302
+#: engines/agi/detection.cpp:147 engines/drascula/detection.cpp:302
#: engines/dreamweb/detection.cpp:47 engines/neverhood/detection.cpp:160
#: engines/sci/detection.cpp:394 engines/toltecs/detection.cpp:200
-#: engines/zvision/detection.cpp:103
+#: engines/zvision/detection.cpp:246
msgid "Use original save/load screens"
msgstr "²ØÚÞàØáâÞÒãÒÐâØ ÞàØÓ. ×ÑÕàÕÖÕÝÝï/×ÐÒÐÝâÐÖÕÝÝï ÕÚàÐÝØ"
-#: engines/agi/detection.cpp:143 engines/drascula/detection.cpp:303
+#: engines/agi/detection.cpp:148 engines/drascula/detection.cpp:303
#: engines/dreamweb/detection.cpp:48 engines/neverhood/detection.cpp:161
#: engines/sci/detection.cpp:395 engines/toltecs/detection.cpp:201
-#: engines/zvision/detection.cpp:104
+#: engines/zvision/detection.cpp:247
msgid "Use the original save/load screens, instead of the ScummVM ones"
msgstr ""
"²ØÚÞàØáâÞÒãÒÐâØ ÞàØÓöÝÐÛìÝö ×ÑÕàÕÖÕÝÝï/×ÐÒÐÝâÐÖÕÝÝï ÕÚàÐÝØ, ×ÐÜöáâì ScummVM"
+#: engines/agi/detection.cpp:157
+#, fuzzy
+msgid "Use an alternative palette"
+msgstr "²ØÚÞàØáâÞÒãÒÐâØ ÐÛìâÕàÝÐâØÒÝØÙ Òáâãß ÓàØ (âöÛìÚØ CD ÒÕàáöï)"
+
+#: engines/agi/detection.cpp:158
+msgid ""
+"Use an alternative palette, common for all Amiga games. This was the old "
+"behavior"
+msgstr ""
+
+#: engines/agi/detection.cpp:167
+#, fuzzy
+msgid "Mouse support"
+msgstr "¿öÔâàØÜãÒÐâØ ¿àÞßãáâØâØ"
+
+#: engines/agi/detection.cpp:168
+msgid ""
+"Enables mouse support. Allows to use mouse for movement and in game menus."
+msgstr ""
+
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore game:"
msgstr "²öÔÝÞÒØâØ Óàã:"
#: engines/agi/saveload.cpp:816 engines/drascula/saveload.cpp:349
#: engines/dreamweb/saveload.cpp:169 engines/neverhood/menumodule.cpp:886
-#: engines/sci/engine/kfile.cpp:857 engines/toltecs/menu.cpp:256
+#: engines/sci/engine/kfile.cpp:858 engines/toltecs/menu.cpp:256
msgid "Restore"
msgstr "²öÔÝÞÒØâØ"
-#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2368
+#: engines/agos/saveload.cpp:160 engines/scumm/scumm.cpp:2377
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -2119,7 +2182,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2361
+#: engines/agos/saveload.cpp:195 engines/scumm/scumm.cpp:2370
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -2130,7 +2193,7 @@ msgstr ""
"\n"
"%s"
-#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2379
+#: engines/agos/saveload.cpp:203 engines/scumm/scumm.cpp:2388
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -2146,12 +2209,12 @@ msgstr ""
msgid "Cutscene file '%s' not found!"
msgstr "ÄÐÙÛ àÞÛØÚã '%s' ÝÕ ×ÝÐÙÔÕÝÞ!"
-#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:81
+#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:101
#, fuzzy
msgid "Color Blind Mode"
msgstr "ÀÕÖØÜ ÚÛöÚöÒ"
-#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:82
+#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:102
msgid "Enable Color Blind Mode by default"
msgstr ""
@@ -2202,7 +2265,7 @@ msgstr "ÀÕÖØÜ èÒØÔÚÞÓÞ ÒöÔÕÞ"
msgid "Play movies at an increased speed"
msgstr "¿àÞÓàÐÒÐâØ ÒöÔÕÞ × ßöÔÒØéÕÝÝÞî èÒØÔÚöáâî"
-#: engines/groovie/script.cpp:399
+#: engines/groovie/script.cpp:408
msgid "Failed to save game"
msgstr "½Õ ÒÔÐÛÞáï ×ÐßØáÐâØ Óàã"
@@ -2499,12 +2562,12 @@ msgid "Use an alternative game intro (CD version only)"
msgstr "²ØÚÞàØáâÞÒãÒÐâØ ÐÛìâÕàÝÐâØÒÝØÙ Òáâãß ÓàØ (âöÛìÚØ CD ÒÕàáöï)"
#: engines/sci/detection.cpp:374
-msgid "EGA undithering"
-msgstr "EGA ÑÕ× àÐáâàãÒÐÝÝï"
+msgid "Skip EGA dithering pass (full color backgrounds)"
+msgstr ""
#: engines/sci/detection.cpp:375
-msgid "Enable undithering in EGA games"
-msgstr "ÃÒöÜÚÝãâØ ÐÝâØ-×ÓÛÐÔÖãÒÐÝÝï Ò EGA öÓàÐå"
+msgid "Skip dithering pass in EGA games, graphics are shown with full colors"
+msgstr ""
#: engines/sci/detection.cpp:384
msgid "Prefer digital sound effects"
@@ -2577,12 +2640,14 @@ msgstr "¦Óàã ßàØ×ãßØÝÕÝÞ. ½ÐâØáÝöâì ßàÞÑöÛ ÔÛï ßàÞÔÞÒÖÕÝÝï."
#. "Moechten Sie wirklich neu starten? (J/N)J"
#. Will react to J as 'Yes'
#: engines/scumm/dialogs.cpp:183
-msgid "Are you sure you want to restart? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to restart? (Y/N)Y"
msgstr "²Ø ãßÕÒÝÕÝö, éÞ åÞçÕâÕ àÞ×ßÞçÐâØ áßÞçÐâÚã? (Y/N)"
#. I18N: you may specify 'Yes' symbol at the end of the line. See previous comment
#: engines/scumm/dialogs.cpp:185
-msgid "Are you sure you want to quit? (Y/N)"
+#, fuzzy
+msgid "Are you sure you want to quit? (Y/N)Y"
msgstr "²Ø ãßÕÒÝÕÝö, éÞ åÞçÕâÕ ÒØÙâØ? (Y/N)"
#: engines/scumm/dialogs.cpp:190
@@ -2670,516 +2735,541 @@ msgstr "¿àÐÚâØÚÐ"
msgid "Expert"
msgstr "µÚáßÕàâ"
-#: engines/scumm/help.cpp:73
+#: engines/scumm/help.cpp:74
msgid "Common keyboard commands:"
msgstr "¾áÝÞÒÝö ÚÞÜÐÝÔØ ÚÛÐÒöÐâãàØ:"
-#: engines/scumm/help.cpp:74
+#: engines/scumm/help.cpp:75
msgid "Save / Load dialog"
msgstr "´öÐÛÞÓ ×ÑÕàÕÖÕÝÝï / ×ÐÒÐÝâÐÖÕÝÝï"
-#: engines/scumm/help.cpp:76
+#: engines/scumm/help.cpp:77
msgid "Skip line of text"
msgstr "¿àÞßãáâØâØ àïÔÞÚ âÕÚáâã"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Esc"
msgstr "Esc"
-#: engines/scumm/help.cpp:77
+#: engines/scumm/help.cpp:78
msgid "Skip cutscene"
msgstr "¿àÞßãáâØâØ àÞÛØÚ"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Space"
msgstr "Space"
-#: engines/scumm/help.cpp:78
+#: engines/scumm/help.cpp:79
msgid "Pause game"
msgstr "¿Ðã×Ð"
-#: engines/scumm/help.cpp:79 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:95 engines/scumm/help.cpp:96
-#: engines/scumm/help.cpp:97 engines/scumm/help.cpp:98
-#: engines/scumm/help.cpp:99 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:96 engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98 engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Ctrl"
msgstr "Ctrl"
-#: engines/scumm/help.cpp:79
+#: engines/scumm/help.cpp:80
msgid "Load game state 1-10"
msgstr "·ÐÒÐÝâÐÖØâØ áâÐÝ ÓàØ 1-10"
-#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:84
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:100
-#: engines/scumm/help.cpp:101 engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:81 engines/scumm/help.cpp:85
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103
msgid "Alt"
msgstr "Alt"
-#: engines/scumm/help.cpp:80
+#: engines/scumm/help.cpp:81
msgid "Save game state 1-10"
msgstr "·ÑÕàÕÓâØ áâÐÝ ÓàØ 1-10"
-#: engines/scumm/help.cpp:86 engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:90
msgid "Enter"
msgstr "Enter"
-#: engines/scumm/help.cpp:87
+#: engines/scumm/help.cpp:88
msgid "Music volume up / down"
msgstr "³ãçÝöáâì Üã×ØÚØ ÒØéÕ / ÝØÖçÕ"
-#: engines/scumm/help.cpp:88
+#: engines/scumm/help.cpp:89
msgid "Text speed slower / faster"
msgstr "ÈÒØÔÚöáâì âÕÚáâã ßÞÒöÛìÝöèÕ / èÒØÔèÕ"
-#: engines/scumm/help.cpp:89
+#: engines/scumm/help.cpp:90
msgid "Simulate left mouse button"
msgstr "ÁØÜãÛîÒÐâØ ÛöÒØÙ ÚÛöÚ"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Tab"
msgstr "Tab"
-#: engines/scumm/help.cpp:90
+#: engines/scumm/help.cpp:91
msgid "Simulate right mouse button"
msgstr "ÁØÜãÛîÒÐâØ ßàÐÒØÙ ÚÛöÚ"
-#: engines/scumm/help.cpp:93
+#: engines/scumm/help.cpp:94
msgid "Special keyboard commands:"
msgstr "ÁßÕæöÐÛìÝö ÚÞÜÐÝÔØ ÚÛÐÒöÐâãàØ:"
-#: engines/scumm/help.cpp:94
+#: engines/scumm/help.cpp:95
msgid "Show / Hide console"
msgstr "¿ÞÚÐ×ÐâØ / cåÞÒÐâØ ÚÞÝáÞÛì"
-#: engines/scumm/help.cpp:95
+#: engines/scumm/help.cpp:96
msgid "Start the debugger"
msgstr "·ÐßãáÚ ÒöÔÛÐÔçØÚÐ"
-#: engines/scumm/help.cpp:96
+#: engines/scumm/help.cpp:97
msgid "Show memory consumption"
msgstr "¿ÞÚÐ×ÐâØ áßÞÖØÒÐÝÝï ßÐÜ'ïâö"
-#: engines/scumm/help.cpp:97
+#: engines/scumm/help.cpp:98
msgid "Run in fast mode (*)"
msgstr "²ØÚÞÝÐâØ Ò èÒØÔÚÞÜã àÕÖØÜö (*)"
-#: engines/scumm/help.cpp:98
+#: engines/scumm/help.cpp:99
msgid "Run in really fast mode (*)"
msgstr "²ØÚÞÝÐâØ Ò ÔãÖÕ èÒØÔÚÞÜã àÕÖØÜö (*)"
-#: engines/scumm/help.cpp:99
+#: engines/scumm/help.cpp:100
msgid "Toggle mouse capture"
msgstr "ÃÒöÜÚÝãâØ ×ÐåÞßÛÕÝÝï ÜØèö"
-#: engines/scumm/help.cpp:100
+#: engines/scumm/help.cpp:101
msgid "Switch between graphics filters"
msgstr "¿ÕàÕÚÛîçÕÝÝï ÜöÖ ÓàÐäöçÝØÜØ äöÛìâàÐÜØ"
-#: engines/scumm/help.cpp:101
+#: engines/scumm/help.cpp:102
msgid "Increase / Decrease scale factor"
msgstr "·ÑöÛìèÕÝÝï / ·ÜÕÝèÕÝÝï ÜÐáèâÐÑã"
-#: engines/scumm/help.cpp:102
+#: engines/scumm/help.cpp:103
msgid "Toggle aspect-ratio correction"
msgstr "ºÞàÕÚæöï áßöÒÒöÔÝÞèÕÝÝï áâÞàöÝ"
-#: engines/scumm/help.cpp:107
+#: engines/scumm/help.cpp:108
msgid "* Note that using ctrl-f and"
msgstr "* ·ÐãÒÐÖØÜÞ, éÞ ÒØÚÞàØáâÐÝÝï ctrl-f ö"
-#: engines/scumm/help.cpp:108
+#: engines/scumm/help.cpp:109
msgid " ctrl-g are not recommended"
msgstr " ctrl-g ÝÕ àÕÚÞÜÕÝÔãôâìáï"
-#: engines/scumm/help.cpp:109
+#: engines/scumm/help.cpp:110
msgid " since they may cause crashes"
msgstr " ÞáÚöÛìÚØ ÒÞÝØ ÜÞÖãâì ÒØÚÛØÚÐâØ ×ÑÞ÷"
-#: engines/scumm/help.cpp:110
+#: engines/scumm/help.cpp:111
msgid " or incorrect game behavior."
msgstr " ÐÑÞ ÝÕßàÐÒØÛìÝã ßÞÒÕÔöÝÚã ÓàØ."
-#: engines/scumm/help.cpp:114
+#: engines/scumm/help.cpp:115
msgid "Spinning drafts on the keyboard:"
msgstr "·ÜöÝÝö çÞàÝÞÒØÚØ ÝÐ ÚÛÐÒöÐâãàö:"
-#: engines/scumm/help.cpp:116
+#: engines/scumm/help.cpp:117
msgid "Main game controls:"
msgstr "¾áÝÞÒÝö Þßæö÷ ÚÕàãÒÐÝÝï:"
-#: engines/scumm/help.cpp:121 engines/scumm/help.cpp:136
-#: engines/scumm/help.cpp:161
+#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
+#: engines/scumm/help.cpp:162
msgid "Push"
msgstr "½ÐâØáÚ"
-#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137
-#: engines/scumm/help.cpp:162
+#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
+#: engines/scumm/help.cpp:163
msgid "Pull"
msgstr "ÂïÓâØ"
-#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138
-#: engines/scumm/help.cpp:163 engines/scumm/help.cpp:197
-#: engines/scumm/help.cpp:207
+#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
+#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:198
+#: engines/scumm/help.cpp:208
msgid "Give"
msgstr "´ÐâØ"
-#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139
-#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:190
-#: engines/scumm/help.cpp:208
+#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140
+#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191
+#: engines/scumm/help.cpp:209
msgid "Open"
msgstr "²öÔÚàØâØ"
-#: engines/scumm/help.cpp:126
+#: engines/scumm/help.cpp:127
msgid "Go to"
msgstr "¹âØ ÔÞ"
-#: engines/scumm/help.cpp:127
+#: engines/scumm/help.cpp:128
msgid "Get"
msgstr "¾âàØÜÐâØ"
-#: engines/scumm/help.cpp:128 engines/scumm/help.cpp:152
-#: engines/scumm/help.cpp:170 engines/scumm/help.cpp:198
-#: engines/scumm/help.cpp:213 engines/scumm/help.cpp:224
-#: engines/scumm/help.cpp:250
+#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:153
+#: engines/scumm/help.cpp:171 engines/scumm/help.cpp:199
+#: engines/scumm/help.cpp:214 engines/scumm/help.cpp:225
+#: engines/scumm/help.cpp:251
msgid "Use"
msgstr "²ØÚÞàØáâÐâØ"
-#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:141
+#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:142
msgid "Read"
msgstr "ÇØâÐâØ"
-#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:147
+#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:148
msgid "New kid"
msgstr "½ÞÒÐ ÔØâØÝÐ"
-#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:153
-#: engines/scumm/help.cpp:171
+#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
+#: engines/scumm/help.cpp:172
msgid "Turn on"
msgstr "ÃÒöÜÚÝãâØ"
-#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154
-#: engines/scumm/help.cpp:172
+#: engines/scumm/help.cpp:133 engines/scumm/help.cpp:155
+#: engines/scumm/help.cpp:173
msgid "Turn off"
msgstr "²ØÜÚÝãâØ"
-#: engines/scumm/help.cpp:142 engines/scumm/help.cpp:167
-#: engines/scumm/help.cpp:194
+#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
+#: engines/scumm/help.cpp:195
msgid "Walk to"
msgstr "¦âØ ÔÞ"
-#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168
-#: engines/scumm/help.cpp:195 engines/scumm/help.cpp:210
-#: engines/scumm/help.cpp:227
+#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:228
msgid "Pick up"
msgstr "¿öÔöÑàÐâØ"
-#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169
+#: engines/scumm/help.cpp:145 engines/scumm/help.cpp:170
msgid "What is"
msgstr "ÉÞ ô"
-#: engines/scumm/help.cpp:146
+#: engines/scumm/help.cpp:147
msgid "Unlock"
msgstr "ÀÞ×ÑÛÞÚãÒÐâØ"
-#: engines/scumm/help.cpp:149
+#: engines/scumm/help.cpp:150
msgid "Put on"
msgstr "¿ÞáâÐÒØâØ ÝÐ"
-#: engines/scumm/help.cpp:150
+#: engines/scumm/help.cpp:151
msgid "Take off"
msgstr "·ÝïâØ"
-#: engines/scumm/help.cpp:156
+#: engines/scumm/help.cpp:157
msgid "Fix"
msgstr "½ÐÛÐÓÞÔØâØ"
-#: engines/scumm/help.cpp:158
+#: engines/scumm/help.cpp:159
msgid "Switch"
msgstr "¿ÕàÕÜÚÝãâØ"
-#: engines/scumm/help.cpp:166 engines/scumm/help.cpp:228
+#: engines/scumm/help.cpp:167 engines/scumm/help.cpp:229
msgid "Look"
msgstr "³ÛïÝãâØ"
-#: engines/scumm/help.cpp:173 engines/scumm/help.cpp:223
+#: engines/scumm/help.cpp:174 engines/scumm/help.cpp:224
msgid "Talk"
msgstr "³ÞÒÞàØâØ"
-#: engines/scumm/help.cpp:174
+#: engines/scumm/help.cpp:175
msgid "Travel"
msgstr "¿ÞÔÞàÞÖ"
-#: engines/scumm/help.cpp:175
+#: engines/scumm/help.cpp:176
msgid "To Henry / To Indy"
msgstr "à ³ÕÝàö / à ¦ÝÔö"
#. I18N: These are different musical notes
-#: engines/scumm/help.cpp:179
+#: engines/scumm/help.cpp:180
msgid "play C minor on distaff"
msgstr "ÓàÐâØ ÔÞ ÜöÝÞà ÝÐ ßàïÔæö"
-#: engines/scumm/help.cpp:180
+#: engines/scumm/help.cpp:181
msgid "play D on distaff"
msgstr "ÓàÐâØ àÕ ÝÐ ßàïÔæö"
-#: engines/scumm/help.cpp:181
+#: engines/scumm/help.cpp:182
msgid "play E on distaff"
msgstr "ÓàÐâØ Üö ÝÐ ßàïÔæö"
-#: engines/scumm/help.cpp:182
+#: engines/scumm/help.cpp:183
msgid "play F on distaff"
msgstr "ÓàÐâØ äÐ ÝÐ ßàïÔæö"
-#: engines/scumm/help.cpp:183
+#: engines/scumm/help.cpp:184
msgid "play G on distaff"
msgstr "ÓàÐâØ áÞÛì ÝÐ ßàïÔæö"
-#: engines/scumm/help.cpp:184
+#: engines/scumm/help.cpp:185
msgid "play A on distaff"
msgstr "ÓàÐâØ Ûï ÝÐ ßàïÔæö"
-#: engines/scumm/help.cpp:185
+#: engines/scumm/help.cpp:186
msgid "play B on distaff"
msgstr "ÓàÐâØ áö ÝÐ ßàïÔæö"
-#: engines/scumm/help.cpp:186
+#: engines/scumm/help.cpp:187
msgid "play C major on distaff"
msgstr "ÓàÐâØ ÔÞ ÜÐÖÞà ÝÐ ßàïÔæö"
-#: engines/scumm/help.cpp:192 engines/scumm/help.cpp:214
+#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
msgid "puSh"
msgstr "¿ÞèâÞÒå"
-#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
+#: engines/scumm/help.cpp:194 engines/scumm/help.cpp:216
msgid "pull (Yank)"
msgstr "âïÓÝãâØ (ÁÜØÚÝãâØ)"
-#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:212
-#: engines/scumm/help.cpp:248
+#: engines/scumm/help.cpp:197 engines/scumm/help.cpp:213
+#: engines/scumm/help.cpp:249
msgid "Talk to"
msgstr "³ÞÒÞàØâØ ÔÞ"
-#: engines/scumm/help.cpp:199 engines/scumm/help.cpp:211
+#: engines/scumm/help.cpp:200 engines/scumm/help.cpp:212
msgid "Look at"
msgstr "³ÛïÝãâØ ÝÐ"
-#: engines/scumm/help.cpp:200
+#: engines/scumm/help.cpp:201
msgid "turn oN"
msgstr "ÃÒöÜÚÝãâØ"
-#: engines/scumm/help.cpp:201
+#: engines/scumm/help.cpp:202
msgid "turn oFf"
msgstr "²ØÜÚÝãâØ"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "KeyUp"
msgstr "½ÐâØáÝãâØ"
-#: engines/scumm/help.cpp:217
+#: engines/scumm/help.cpp:218
msgid "Highlight prev dialogue"
msgstr "²ØÔöÛØâØ ßÞßÕàÕÔÝöÙ ÔöÐÛÞÓ"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "KeyDown"
msgstr "²öÔßãáâØâØ"
-#: engines/scumm/help.cpp:218
+#: engines/scumm/help.cpp:219
msgid "Highlight next dialogue"
msgstr "²ØÔöÛØâØ ÝÐáâãßÝØÙ ÔöÐÛÞÓ"
-#: engines/scumm/help.cpp:222
+#: engines/scumm/help.cpp:223
msgid "Walk"
msgstr "¦âØ"
-#: engines/scumm/help.cpp:225 engines/scumm/help.cpp:234
-#: engines/scumm/help.cpp:241 engines/scumm/help.cpp:249
+#: engines/scumm/help.cpp:226 engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:242 engines/scumm/help.cpp:250
msgid "Inventory"
msgstr "¦ÝÒÕÝâÐà"
-#: engines/scumm/help.cpp:226
+#: engines/scumm/help.cpp:227
msgid "Object"
msgstr "¾Ñ'ôÚâ"
-#: engines/scumm/help.cpp:229
+#: engines/scumm/help.cpp:230
msgid "Black and White / Color"
msgstr "ÇÞàÝÞÑöÛØÙ / ºÞÛìÞàÞÒØÙ"
-#: engines/scumm/help.cpp:232
+#: engines/scumm/help.cpp:233
msgid "Eyes"
msgstr "¾çö"
-#: engines/scumm/help.cpp:233
+#: engines/scumm/help.cpp:234
msgid "Tongue"
msgstr "Ï×ØÚ"
-#: engines/scumm/help.cpp:235
+#: engines/scumm/help.cpp:236
msgid "Punch"
msgstr "²ÔÐàØâØ ÚãÛÐÚÞÜ"
-#: engines/scumm/help.cpp:236
+#: engines/scumm/help.cpp:237
msgid "Kick"
msgstr "²ÔÐàØâØ ÝÞÓÞî"
-#: engines/scumm/help.cpp:239 engines/scumm/help.cpp:247
+#: engines/scumm/help.cpp:240 engines/scumm/help.cpp:248
msgid "Examine"
msgstr "ÀÞ×ÓÛïÝãâØ"
-#: engines/scumm/help.cpp:240
+#: engines/scumm/help.cpp:241
msgid "Regular cursor"
msgstr "·ÒØçÐÙÝØÙ ÚãàáÞà"
#. I18N: Comm is a communication device
-#: engines/scumm/help.cpp:243
+#: engines/scumm/help.cpp:244
msgid "Comm"
msgstr "ºÞÜÜ"
-#: engines/scumm/help.cpp:246
+#: engines/scumm/help.cpp:247
msgid "Save / Load / Options"
msgstr "·ÑÕàÕÖÕÝÝï / ·ÐÒÐÝâÐÖÕÝÝï / ½ÐÛÐèâãÒÐÝÝï"
-#: engines/scumm/help.cpp:255
+#: engines/scumm/help.cpp:256
msgid "Other game controls:"
msgstr "¦ÝèÕ ÚÕàãÒÐÝÝï ÓàÞî:"
-#: engines/scumm/help.cpp:257 engines/scumm/help.cpp:267
+#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:268
msgid "Inventory:"
msgstr "¦ÝÒÕÝâÐà:"
-#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:274
+#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
msgid "Scroll list up"
msgstr "¿àÞÚàãçÕÝÝï áßØáÚã ÔÞÓÞàØ"
-#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275
+#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:276
msgid "Scroll list down"
msgstr "¿àÞÚàãçÕÝÝï áßØáÚã ÔÞÝØ×ã"
-#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:268
+#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:269
msgid "Upper left item"
msgstr "²ÕàåÝï ×ÛöÒÐ àöç"
-#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:270
+#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
msgid "Lower left item"
msgstr "½ØÖÝï ×ÛöÒÐ àöç"
-#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271
+#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:272
msgid "Upper right item"
msgstr "²ÕàåÝï áßàÐÒÐ àöç"
-#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:273
+#: engines/scumm/help.cpp:264 engines/scumm/help.cpp:274
msgid "Lower right item"
msgstr "½ØÖÝï áßàÐÒÐ àöç"
-#: engines/scumm/help.cpp:269
+#: engines/scumm/help.cpp:270
msgid "Middle left item"
msgstr "ÁÕàÕÔÝï ×ÛöÒÐ àöç"
-#: engines/scumm/help.cpp:272
+#: engines/scumm/help.cpp:273
msgid "Middle right item"
msgstr "ÁÕàÕÔÝï áßàÐÒÐ àöç"
-#: engines/scumm/help.cpp:279 engines/scumm/help.cpp:284
+#: engines/scumm/help.cpp:280 engines/scumm/help.cpp:285
msgid "Switching characters:"
msgstr "¿ÕàÕÚÛîçÕÝÝï ÓÕàÞ÷Ò:"
-#: engines/scumm/help.cpp:281
+#: engines/scumm/help.cpp:282
msgid "Second kid"
msgstr "´àãÓÐ ÔØâØÝÐ"
-#: engines/scumm/help.cpp:282
+#: engines/scumm/help.cpp:283
msgid "Third kid"
msgstr "ÂàÕâï ÔØâØÝÐ"
-#: engines/scumm/help.cpp:294
+#: engines/scumm/help.cpp:292
+#, fuzzy
+msgid "Toggle Inventory/IQ Points display"
+msgstr "¿ÕàÕÜÚÝãâØ ßÞÚÐ×ãÒÐÝÝï Ò æÕÝâàö ÕÚàÐÝã"
+
+#: engines/scumm/help.cpp:293
+msgid "Toggle Keyboard/Mouse Fighting (*)"
+msgstr ""
+
+#: engines/scumm/help.cpp:295
+msgid "* Keyboard Fighting is always on,"
+msgstr ""
+
+#: engines/scumm/help.cpp:296
+msgid " so despite the in-game message this"
+msgstr ""
+
+#: engines/scumm/help.cpp:297
+msgid " actually toggles Mouse Fighting Off/On"
+msgstr ""
+
+#: engines/scumm/help.cpp:304
msgid "Fighting controls (numpad):"
msgstr "ºÕàãÒÐÝÝï ÑöÙÚÞî (numpad):"
-#: engines/scumm/help.cpp:295 engines/scumm/help.cpp:296
-#: engines/scumm/help.cpp:297
+#: engines/scumm/help.cpp:305 engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:307
msgid "Step back"
msgstr "ºàÞÚ ÝÐ×ÐÔ"
-#: engines/scumm/help.cpp:298
+#: engines/scumm/help.cpp:308
msgid "Block high"
msgstr "±ÛÞÚãÒÐâØ ×ÒÕàåã"
-#: engines/scumm/help.cpp:299
+#: engines/scumm/help.cpp:309
msgid "Block middle"
msgstr "±ÛÞÚãÒÐâØ ßÞáÕàÕÔØÝö"
-#: engines/scumm/help.cpp:300
+#: engines/scumm/help.cpp:310
msgid "Block low"
msgstr "±ÛÞÚãÒÐâØ ×ÝØ×ã"
-#: engines/scumm/help.cpp:301
+#: engines/scumm/help.cpp:311
msgid "Punch high"
msgstr "±ØâØ ×ÒÕàåã"
-#: engines/scumm/help.cpp:302
+#: engines/scumm/help.cpp:312
msgid "Punch middle"
msgstr "±ØâØ ßÞáÕàÕÔØÝö"
-#: engines/scumm/help.cpp:303
+#: engines/scumm/help.cpp:313
msgid "Punch low"
msgstr "±ØâØ ×ÝØ×ã"
-#: engines/scumm/help.cpp:306
+#: engines/scumm/help.cpp:315
+msgid "Sucker punch"
+msgstr ""
+
+#: engines/scumm/help.cpp:318
msgid "These are for Indy on left."
msgstr "à ÒØßÐÔÚã ÔÛï ¦ÝÔö ×ÛöÒÐ."
-#: engines/scumm/help.cpp:307
+#: engines/scumm/help.cpp:319
msgid "When Indy is on the right,"
msgstr "ºÞÛØ ¦ÝÔö ô áßàÐÒÐ,"
-#: engines/scumm/help.cpp:308
+#: engines/scumm/help.cpp:320
msgid "7, 4, and 1 are switched with"
msgstr "7, 4, ö 1 ßÕàÕÜØÚÐîâìáï ÝÐ"
-#: engines/scumm/help.cpp:309
+#: engines/scumm/help.cpp:321
msgid "9, 6, and 3, respectively."
msgstr "9, 6 ö 3 ÒöÔßÞÒöÔÝÞ."
-#: engines/scumm/help.cpp:316
+#: engines/scumm/help.cpp:328
msgid "Biplane controls (numpad):"
msgstr "ºÕàãÒÐÝÝï ÑößÛÐÝÞÜ (numpad):"
-#: engines/scumm/help.cpp:317
+#: engines/scumm/help.cpp:329
msgid "Fly to upper left"
msgstr "»ÕâöâØ ÔÞÓÞàØ ÝÐÛöÒÞ"
-#: engines/scumm/help.cpp:318
+#: engines/scumm/help.cpp:330
msgid "Fly to left"
msgstr "»ÕâöâØ ÝÐÛöÒÞ"
-#: engines/scumm/help.cpp:319
+#: engines/scumm/help.cpp:331
msgid "Fly to lower left"
msgstr "»ÕâöâØ ÝØÖçÕ ÝÐÛöÒÞ"
-#: engines/scumm/help.cpp:320
+#: engines/scumm/help.cpp:332
msgid "Fly upwards"
msgstr "»ÕâöâØ ÔÞÓÞàØ"
-#: engines/scumm/help.cpp:321
+#: engines/scumm/help.cpp:333
msgid "Fly straight"
msgstr "»ÕâöâØ ßàïÜÞ"
-#: engines/scumm/help.cpp:322
+#: engines/scumm/help.cpp:334
msgid "Fly down"
msgstr "»ÕâöâØ ÔÞÝØ×ã"
-#: engines/scumm/help.cpp:323
+#: engines/scumm/help.cpp:335
msgid "Fly to upper right"
msgstr "»ÕâöâØ ÔÞÓÞàØ ÝÐßàÐÒÞ"
-#: engines/scumm/help.cpp:324
+#: engines/scumm/help.cpp:336
msgid "Fly to right"
msgstr "»ÕâöâØ ÝÐßàÐÒÞ"
-#: engines/scumm/help.cpp:325
+#: engines/scumm/help.cpp:337
msgid "Fly to lower right"
msgstr "»ÕâöâØ ÔÞÝØ×ã ÝÐßàÐÒÞ"
-#: engines/scumm/scumm.cpp:1823
+#: engines/scumm/scumm.cpp:1832
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
@@ -3188,11 +3278,12 @@ msgstr ""
"ÀÕÖØÜ \"àöÔÝÞÓÞ\" MIDI ßÞâàÕÑãô ßÞÝÞÒÛÕÝÝï Roland Upgrade ÒöÔ\n"
"LucasArts, ßàÞâÕ %s ÒöÔáãâÝöÙ. ¿ÕàÕÜØÚÐîáì ÝÐ AdLib."
-#: engines/scumm/scumm.cpp:2594
+#: engines/scumm/scumm.cpp:2644
+#, fuzzy
msgid ""
-"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
-"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
-"directory inside the Tentacle game directory."
+"Usually, Maniac Mansion would start now. But for that to work, the game "
+"files for Maniac Mansion have to be in the 'Maniac' directory inside the "
+"Tentacle game directory, and the game has to be added to ScummVM."
msgstr ""
"·Ð×ÒØçÐÙ, ×ÐàÐ× ÑØ ×ÐßãáâØÒáï Maniac Mansion. ¿àÞâÕ ScummVM éÕ æìÞÓÞ ÝÕ "
"ÒÜöô. ÉÞÑ ÓàÐâØ ã ÝìÞÓÞ, ÞÑÕàöâì '´ÞÔÐâØ Óàã' ã ßÞçÐâÚÞÒÞÜã ÜÕÝî ScummVM, ö "
@@ -3328,6 +3419,49 @@ msgstr ""
msgid "Show the current number of frames per second in the upper left corner"
msgstr ""
+#: engines/zvision/detection.cpp:256
+msgid "Double FPS"
+msgstr ""
+
+#: engines/zvision/detection.cpp:257
+msgid "Increase game FPS from 30 to 60"
+msgstr ""
+
+#: engines/zvision/detection.cpp:266
+#, fuzzy
+msgid "Enable Venus"
+msgstr "ÃÒöÜÚÝãâØ àÕÖØÜ ³ÕÛöãÜ"
+
+#: engines/zvision/detection.cpp:267
+msgid "Enable the Venus help system"
+msgstr ""
+
+#: engines/zvision/detection.cpp:276
+msgid "Disable animation while turning"
+msgstr ""
+
+#: engines/zvision/detection.cpp:277
+msgid "Disable animation while turning in panoramic mode"
+msgstr ""
+
+#: engines/zvision/detection.cpp:286
+msgid "Use the hires MPEG movies"
+msgstr ""
+
+#: engines/zvision/detection.cpp:287
+#, fuzzy
+msgid ""
+"Use the hires MPEG movies of the DVD version, instead of the lowres AVI ones"
+msgstr ""
+"²ØÚÞàØáâÞÒãÒÐâØ ÐÛìâÕàÝÐâØÒÝØÙ ÝÐÑöà áàöÑÝØå ÚãàáÞàöÒ, ×ÐÜöáâì ×ÒØçÐÙÝØå "
+"×ÞÛÞâØå"
+
+#~ msgid "EGA undithering"
+#~ msgstr "EGA ÑÕ× àÐáâàãÒÐÝÝï"
+
+#~ msgid "Enable undithering in EGA games"
+#~ msgstr "ÃÒöÜÚÝãâØ ÐÝâØ-×ÓÛÐÔÖãÒÐÝÝï Ò EGA öÓàÐå"
+
#~ msgid "MPEG-2 cutscenes found but ScummVM has been built without MPEG-2"
#~ msgstr ""
#~ "·ÝÐÙÔÕÝö àÞÛØÚØ MPEG-2, ÐÛÕ ScummVM ÑãÒ ×öÑàÐÝØÙ ÑÕ× ßöÔâàØÜÚØ MPEG-2"
@@ -3336,9 +3470,6 @@ msgstr ""
#~ msgid "Mass Add..."
#~ msgstr "´ÞÔ. ÑÐÓÐâÞ..."
-#~ msgid "Mass Add..."
-#~ msgstr "´ÞÔ. ÑÐÓÐâÞ..."
-
#~ msgid ""
#~ "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
#~ msgstr ""
diff --git a/ports.mk b/ports.mk
index fdab7e23af..398a0c4b5a 100644
--- a/ports.mk
+++ b/ports.mk
@@ -324,10 +324,12 @@ endif
@cd $(srcdir)/dists/msvc10 && ../../devtools/create_project/create_project ../.. --msvc --msvc-version 10 >/dev/null && git add -f engines/plugins_table.h *.sln *.vcxproj *.vcxproj.filters *.props
@echo Creating MSVC11 project files...
@cd $(srcdir)/dists/msvc11 && ../../devtools/create_project/create_project ../.. --msvc --msvc-version 11 >/dev/null && git add -f engines/plugins_table.h *.sln *.vcxproj *.vcxproj.filters *.props
+ @echo Creating MSVC12 project files...
+ @cd $(srcdir)/dists/msvc12 && ../../devtools/create_project/create_project ../.. --msvc --msvc-version 12 >/dev/null && git add -f engines/plugins_table.h *.sln *.vcxproj *.vcxproj.filters *.props
@echo
@echo All is done.
@echo Now run
- @echo "\tgit commit 'DISTS: Generated Code::Blocks and MSVC project files'"
+ @echo "\tgit commit -m 'DISTS: Generated Code::Blocks and MSVC project files'"
# Mark special targets as phony
.PHONY: deb bundle osxsnap win32dist install uninstall
diff --git a/test/audio/timestamp.h b/test/audio/timestamp.h
index ca56e34a4d..ec42a55ec4 100644
--- a/test/audio/timestamp.h
+++ b/test/audio/timestamp.h
@@ -2,6 +2,8 @@
#include "audio/timestamp.h"
+#include <limits.h>
+
class TimestampTestSuite : public CxxTest::TestSuite
{
public:
@@ -238,4 +240,15 @@ class TimestampTestSuite : public CxxTest::TestSuite
TS_ASSERT_EQUALS(c.numberOfFrames(), 11025);
TS_ASSERT_EQUALS(c.totalNumberOfFrames(), 33075);
}
+
+ void test_no_overflow() {
+ // The constructor should not overflow and give incoherent values
+ const Audio::Timestamp a = Audio::Timestamp(0, UINT_MAX, 1000);
+
+ int secs = UINT_MAX / 1000;
+ int frames = UINT_MAX % 1000;
+
+ TS_ASSERT_EQUALS(a.secs(), secs);
+ TS_ASSERT_EQUALS(a.numberOfFrames(), frames);
+ }
};
diff --git a/test/common/endian.h b/test/common/endian.h
index cba7618c43..065b6997fc 100644
--- a/test/common/endian.h
+++ b/test/common/endian.h
@@ -10,6 +10,18 @@ class EndianTestSuite : public CxxTest::TestSuite
TS_ASSERT_EQUALS(MKTAG('A','B','C','D'), tag);
}
+ void test_READ_BE_UINT64() {
+ const byte data[8] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF};
+ uint64 value = READ_BE_UINT64(data);
+ TS_ASSERT_EQUALS(value, 0x123456789ABCDEFFULL);
+ }
+
+ void test_READ_LE_UINT64() {
+ const byte data[8] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF};
+ uint64 value = READ_LE_UINT64(data);
+ TS_ASSERT_EQUALS(value, 0xFFDEBC9A78563412ULL);
+ }
+
void test_READ_BE_UINT32() {
const char data[4] = { 0x12, 0x34, 0x56, 0x78 };
uint32 value = READ_BE_UINT32(data);
diff --git a/test/common/memoryreadstream.h b/test/common/memoryreadstream.h
index adef861a5e..3e1472f408 100644
--- a/test/common/memoryreadstream.h
+++ b/test/common/memoryreadstream.h
@@ -60,28 +60,32 @@ class MemoryReadStreamTestSuite : public CxxTest::TestSuite {
}
void test_seek_read_le() {
- byte contents[] = { 1, 2, 3, 4, 5, 6, 7 };
+ byte contents[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
Common::MemoryReadStream ms(contents, sizeof(contents));
TS_ASSERT_EQUALS(ms.readUint16LE(), 0x0201UL);
TS_ASSERT_EQUALS(ms.pos(), 2);
TS_ASSERT_EQUALS(ms.readUint32LE(), 0x06050403UL);
TS_ASSERT_EQUALS(ms.pos(), 6);
- TS_ASSERT_EQUALS(ms.readByte(), 0x07);
- TS_ASSERT_EQUALS(ms.pos(), 7);
+ TS_ASSERT_EQUALS(ms.readUint64LE(), 0x0E0D0C0B0A090807ULL);
+ TS_ASSERT_EQUALS(ms.pos(), 14);
+ TS_ASSERT_EQUALS(ms.readByte(), 0x0F);
+ TS_ASSERT_EQUALS(ms.pos(), 15);
TS_ASSERT(!ms.eos());
}
void test_seek_read_be() {
- byte contents[] = { 1, 2, 3, 4, 5, 6, 7 };
+ byte contents[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
Common::MemoryReadStream ms(contents, sizeof(contents));
TS_ASSERT_EQUALS(ms.readUint16BE(), 0x0102UL);
TS_ASSERT_EQUALS(ms.pos(), 2);
TS_ASSERT_EQUALS(ms.readUint32BE(), 0x03040506UL);
TS_ASSERT_EQUALS(ms.pos(), 6);
- TS_ASSERT_EQUALS(ms.readByte(), 0x07);
- TS_ASSERT_EQUALS(ms.pos(), 7);
+ TS_ASSERT_EQUALS(ms.readUint64BE(), 0x0708090A0B0C0D0EULL);
+ TS_ASSERT_EQUALS(ms.pos(), 14);
+ TS_ASSERT_EQUALS(ms.readByte(), 0x0F);
+ TS_ASSERT_EQUALS(ms.pos(), 15);
TS_ASSERT(!ms.eos());
}
diff --git a/test/common/memoryreadstreamendian.h b/test/common/memoryreadstreamendian.h
index 35e804c70b..c25ec29e1a 100644
--- a/test/common/memoryreadstreamendian.h
+++ b/test/common/memoryreadstreamendian.h
@@ -60,54 +60,62 @@ class MemoryReadStreamEndianTestSuite : public CxxTest::TestSuite {
}
void test_seek_read_le() {
- byte contents[] = { 1, 2, 3, 4, 5, 6, 7 };
+ byte contents[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
Common::MemoryReadStreamEndian ms(contents, sizeof(contents), false);
TS_ASSERT_EQUALS(ms.readUint16LE(), 0x0201UL);
TS_ASSERT_EQUALS(ms.pos(), 2);
TS_ASSERT_EQUALS(ms.readUint32LE(), 0x06050403UL);
TS_ASSERT_EQUALS(ms.pos(), 6);
- TS_ASSERT_EQUALS(ms.readByte(), 0x07);
- TS_ASSERT_EQUALS(ms.pos(), 7);
+ TS_ASSERT_EQUALS(ms.readUint64LE(), 0x0E0D0C0B0A090807ULL);
+ TS_ASSERT_EQUALS(ms.pos(), 14);
+ TS_ASSERT_EQUALS(ms.readByte(), 0x0F);
+ TS_ASSERT_EQUALS(ms.pos(), 15);
TS_ASSERT(!ms.eos());
}
void test_seek_read_be() {
- byte contents[] = { 1, 2, 3, 4, 5, 6, 7 };
+ byte contents[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
Common::MemoryReadStreamEndian ms(contents, sizeof(contents), false);
TS_ASSERT_EQUALS(ms.readUint16BE(), 0x0102UL);
TS_ASSERT_EQUALS(ms.pos(), 2);
TS_ASSERT_EQUALS(ms.readUint32BE(), 0x03040506UL);
TS_ASSERT_EQUALS(ms.pos(), 6);
- TS_ASSERT_EQUALS(ms.readByte(), 0x07);
- TS_ASSERT_EQUALS(ms.pos(), 7);
+ TS_ASSERT_EQUALS(ms.readUint64BE(), 0x0708090A0B0C0D0EULL);
+ TS_ASSERT_EQUALS(ms.pos(), 14);
+ TS_ASSERT_EQUALS(ms.readByte(), 0x0F);
+ TS_ASSERT_EQUALS(ms.pos(), 15);
TS_ASSERT(!ms.eos());
}
void test_seek_read_le2() {
- byte contents[] = { 1, 2, 3, 4, 5, 6, 7 };
+ byte contents[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
Common::MemoryReadStreamEndian ms(contents, sizeof(contents), false);
TS_ASSERT_EQUALS(ms.readUint16(), 0x0201UL);
TS_ASSERT_EQUALS(ms.pos(), 2);
TS_ASSERT_EQUALS(ms.readUint32(), 0x06050403UL);
TS_ASSERT_EQUALS(ms.pos(), 6);
- TS_ASSERT_EQUALS(ms.readByte(), 0x07);
- TS_ASSERT_EQUALS(ms.pos(), 7);
+ TS_ASSERT_EQUALS(ms.readUint64(), 0x0E0D0C0B0A090807ULL);
+ TS_ASSERT_EQUALS(ms.pos(), 14);
+ TS_ASSERT_EQUALS(ms.readByte(), 0x0F);
+ TS_ASSERT_EQUALS(ms.pos(), 15);
TS_ASSERT(!ms.eos());
}
void test_seek_read_be2() {
- byte contents[] = { 1, 2, 3, 4, 5, 6, 7 };
+ byte contents[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
Common::MemoryReadStreamEndian ms(contents, sizeof(contents), true);
TS_ASSERT_EQUALS(ms.readUint16(), 0x0102UL);
TS_ASSERT_EQUALS(ms.pos(), 2);
TS_ASSERT_EQUALS(ms.readUint32(), 0x03040506UL);
TS_ASSERT_EQUALS(ms.pos(), 6);
- TS_ASSERT_EQUALS(ms.readByte(), 0x07);
- TS_ASSERT_EQUALS(ms.pos(), 7);
+ TS_ASSERT_EQUALS(ms.readUint64(), 0x0708090A0B0C0D0EULL);
+ TS_ASSERT_EQUALS(ms.pos(), 14);
+ TS_ASSERT_EQUALS(ms.readByte(), 0x0F);
+ TS_ASSERT_EQUALS(ms.pos(), 15);
TS_ASSERT(!ms.eos());
}
};
diff --git a/test/cxxtest/cxxtestgen.py b/test/cxxtest/cxxtestgen.py
index 4145c3ca3e..46267ac3e3 100755
--- a/test/cxxtest/cxxtestgen.py
+++ b/test/cxxtest/cxxtestgen.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
'''Usage: %s [OPTIONS] <input file(s)>
Generate test source file for CxxTest.
diff --git a/video/avi_decoder.cpp b/video/avi_decoder.cpp
index 7119c72f07..700975d9a2 100644
--- a/video/avi_decoder.cpp
+++ b/video/avi_decoder.cpp
@@ -815,6 +815,30 @@ void AVIDecoder::AVIVideoTrack::forceTrackEnd() {
_curFrame = _frameCount - 1;
}
+const byte *AVIDecoder::AVIVideoTrack::getPalette() const {
+ if (_videoCodec && _videoCodec->containsPalette())
+ return _videoCodec->getPalette();
+
+ _dirtyPalette = false;
+ return _palette;
+}
+
+bool AVIDecoder::AVIVideoTrack::hasDirtyPalette() const {
+ if (_videoCodec && _videoCodec->containsPalette())
+ return _videoCodec->hasDirtyPalette();
+
+ return _dirtyPalette;
+}
+
+bool AVIDecoder::AVIVideoTrack::canDither() const {
+ return _videoCodec && _videoCodec->canDither(Image::Codec::kDitherTypeVFW);
+}
+
+void AVIDecoder::AVIVideoTrack::setDither(const byte *palette) {
+ assert(_videoCodec);
+ _videoCodec->setDither(Image::Codec::kDitherTypeVFW, palette);
+}
+
AVIDecoder::AVIAudioTrack::AVIAudioTrack(const AVIStreamHeader &streamHeader, const PCMWaveFormat &waveFormat, Audio::Mixer::SoundType soundType)
: _audsHeader(streamHeader), _wvInfo(waveFormat), _soundType(soundType), _curChunk(0) {
_audStream = createAudioStream();
diff --git a/video/avi_decoder.h b/video/avi_decoder.h
index 8941ff4e75..6c1ce1a4b9 100644
--- a/video/avi_decoder.h
+++ b/video/avi_decoder.h
@@ -179,11 +179,14 @@ protected:
int getCurFrame() const { return _curFrame; }
int getFrameCount() const { return _frameCount; }
const Graphics::Surface *decodeNextFrame() { return _lastFrame; }
- const byte *getPalette() const { _dirtyPalette = false; return _palette; }
- bool hasDirtyPalette() const { return _dirtyPalette; }
+
+ const byte *getPalette() const;
+ bool hasDirtyPalette() const;
void setCurFrame(int frame) { _curFrame = frame; }
void loadPaletteFromChunk(Common::SeekableReadStream *chunk);
void useInitialPalette();
+ bool canDither() const;
+ void setDither(const byte *palette);
bool isTruemotion1() const;
void forceDimensions(uint16 width, uint16 height);
diff --git a/video/module.mk b/video/module.mk
index 5754350e42..be014598f2 100644
--- a/video/module.mk
+++ b/video/module.mk
@@ -5,6 +5,7 @@ MODULE_OBJS := \
coktel_decoder.o \
dxa_decoder.o \
flic_decoder.o \
+ mpegps_decoder.o \
psx_decoder.o \
qt_decoder.o \
smk_decoder.o \
diff --git a/video/mpegps_decoder.cpp b/video/mpegps_decoder.cpp
new file mode 100644
index 0000000000..d8f7f5a68c
--- /dev/null
+++ b/video/mpegps_decoder.cpp
@@ -0,0 +1,732 @@
+/* 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 "common/debug.h"
+#include "common/endian.h"
+#include "common/stream.h"
+#include "common/system.h"
+#include "common/textconsole.h"
+
+#include "video/mpegps_decoder.h"
+#include "image/codecs/mpeg.h"
+
+// The demuxing code is based on libav's demuxing code
+
+namespace Video {
+
+enum {
+ kStartCodePack = 0x1BA,
+ kStartCodeSystemHeader = 0x1BB,
+ kStartCodeProgramStreamMap = 0x1BC,
+ kStartCodePrivateStream1 = 0x1BD,
+ kStartCodePaddingStream = 0x1BE,
+ kStartCodePrivateStream2 = 0x1BF
+};
+
+MPEGPSDecoder::MPEGPSDecoder() {
+ _stream = 0;
+ memset(_psmESType, 0, 256);
+}
+
+MPEGPSDecoder::~MPEGPSDecoder() {
+ close();
+}
+
+bool MPEGPSDecoder::loadStream(Common::SeekableReadStream *stream) {
+ close();
+
+ _stream = stream;
+
+ if (!addFirstVideoTrack()) {
+ close();
+ return false;
+ }
+
+ _stream->seek(0);
+ return true;
+}
+
+void MPEGPSDecoder::close() {
+ VideoDecoder::close();
+
+ delete _stream;
+ _stream = 0;
+
+ _streamMap.clear();
+
+ memset(_psmESType, 0, 256);
+}
+
+void MPEGPSDecoder::readNextPacket() {
+ if (_stream->eos())
+ return;
+
+ for (;;) {
+ int32 startCode;
+ uint32 pts, dts;
+ int size = readNextPacketHeader(startCode, pts, dts);
+
+ if (size < 0) {
+ // End of stream
+ for (TrackListIterator it = getTrackListBegin(); it != getTrackListEnd(); it++)
+ if ((*it)->getTrackType() == Track::kTrackTypeVideo)
+ ((MPEGVideoTrack *)*it)->setEndOfTrack();
+ return;
+ }
+
+ MPEGStream *stream = 0;
+ Common::SeekableReadStream *packet = _stream->readStream(size);
+
+ if (_streamMap.contains(startCode)) {
+ // We already found the stream
+ stream = _streamMap[startCode];
+ } else {
+ // We haven't seen this before
+
+ if (startCode == kStartCodePrivateStream1) {
+ PrivateStreamType streamType = detectPrivateStreamType(packet);
+ packet->seek(0);
+
+ // TODO: Handling of these types (as needed)
+
+ const char *typeName;
+
+ switch (streamType) {
+ case kPrivateStreamAC3:
+ typeName = "AC-3";
+ break;
+ case kPrivateStreamDTS:
+ typeName = "DTS";
+ break;
+ case kPrivateStreamDVDPCM:
+ typeName = "DVD PCM";
+ break;
+ case kPrivateStreamPS2Audio:
+ typeName = "PS2 Audio";
+ break;
+ default:
+ typeName = "Unknown";
+ break;
+ }
+
+ warning("Unhandled DVD private stream: %s", typeName);
+
+ // Make it 0 so we don't get the warning twice
+ _streamMap[startCode] = 0;
+ } else if (startCode >= 0x1E0 && startCode <= 0x1EF) {
+ // Video stream
+ // TODO: Multiple video streams
+ warning("Found extra video stream 0x%04X", startCode);
+ _streamMap[startCode] = 0;
+ } else if (startCode >= 0x1C0 && startCode <= 0x1DF) {
+#ifdef USE_MAD
+ // MPEG Audio stream
+ MPEGAudioTrack *audioTrack = new MPEGAudioTrack(packet);
+ stream = audioTrack;
+ _streamMap[startCode] = audioTrack;
+ addTrack(audioTrack);
+#else
+ warning("Found audio stream 0x%04X, but no MAD support compiled in", startCode);
+ _streamMap[startCode] = 0;
+#endif
+ } else {
+ // Probably not relevant
+ debug(0, "Found unhandled MPEG-PS stream type 0x%04x", startCode);
+ _streamMap[startCode] = 0;
+ }
+ }
+
+ if (stream) {
+ bool done = stream->sendPacket(packet, pts, dts);
+
+ if (done && stream->getStreamType() == MPEGStream::kStreamTypeVideo)
+ return;
+ } else {
+ delete packet;
+ }
+ }
+}
+
+#define MAX_SYNC_SIZE 100000
+
+int MPEGPSDecoder::findNextStartCode(uint32 &size) {
+ size = MAX_SYNC_SIZE;
+ int32 state = 0xFF;
+
+ while (size > 0) {
+ byte v = _stream->readByte();
+
+ if (_stream->eos())
+ return -1;
+
+ size--;
+
+ if (state == 0x1)
+ return ((state << 8) | v) & 0xFFFFFF;
+
+ state = ((state << 8) | v) & 0xFFFFFF;
+ }
+
+ return -1;
+}
+
+int MPEGPSDecoder::readNextPacketHeader(int32 &startCode, uint32 &pts, uint32 &dts) {
+ for (;;) {
+ uint32 size;
+ startCode = findNextStartCode(size);
+
+ if (_stream->eos())
+ return -1;
+
+ if (startCode < 0)
+ continue;
+
+ uint32 lastSync = _stream->pos();
+
+ if (startCode == kStartCodePack || startCode == kStartCodeSystemHeader)
+ continue;
+
+ int length = _stream->readUint16BE();
+
+ if (startCode == kStartCodePaddingStream || startCode == kStartCodePrivateStream2) {
+ _stream->skip(length);
+ continue;
+ }
+
+ if (startCode == kStartCodeProgramStreamMap) {
+ parseProgramStreamMap(length);
+ continue;
+ }
+
+ // Find matching stream
+ if (!((startCode >= 0x1C0 && startCode <= 0x1DF) ||
+ (startCode >= 0x1E0 && startCode <= 0x1EF) ||
+ startCode == kStartCodePrivateStream1 || startCode == 0x1FD))
+ continue;
+
+ // Stuffing
+ byte c;
+ for (;;) {
+ if (length < 1) {
+ _stream->seek(lastSync);
+ continue;
+ }
+
+ c = _stream->readByte();
+ length--;
+
+ // XXX: for mpeg1, should test only bit 7
+ if (c != 0xFF)
+ break;
+ }
+
+ if ((c & 0xC0) == 0x40) {
+ // Buffer scale and size
+ _stream->readByte();
+ c = _stream->readByte();
+ length -= 2;
+ }
+
+ pts = 0xFFFFFFFF;
+ dts = 0xFFFFFFFF;
+
+ if ((c & 0xE0) == 0x20) {
+ dts = pts = readPTS(c);
+ length -= 4;
+
+ if (c & 0x10) {
+ dts = readPTS(-1);
+ length -= 5;
+ }
+ } else if ((c & 0xC0) == 0x80) {
+ // MPEG-2 PES
+ byte flags = _stream->readByte();
+ int headerLength = _stream->readByte();
+ length -= 2;
+
+ if (headerLength > length) {
+ _stream->seek(lastSync);
+ continue;
+ }
+
+ length -= headerLength;
+
+ if (flags & 0x80) {
+ dts = pts = readPTS(-1);
+ headerLength -= 5;
+
+ if (flags & 0x40) {
+ dts = readPTS(-1);
+ headerLength -= 5;
+ }
+ }
+
+ if (flags & 0x3F && headerLength == 0) {
+ flags &= 0xC0;
+ warning("Further flags set but no bytes left");
+ }
+
+ if (flags & 0x01) { // PES extension
+ byte pesExt =_stream->readByte();
+ headerLength--;
+
+ // Skip PES private data, program packet sequence
+ int skip = (pesExt >> 4) & 0xB;
+ skip += skip & 0x9;
+
+ if (pesExt & 0x40 || skip > headerLength) {
+ warning("pesExt %x is invalid", pesExt);
+ pesExt = skip = 0;
+ } else {
+ _stream->skip(skip);
+ headerLength -= skip;
+ }
+
+ if (pesExt & 0x01) { // PES extension 2
+ byte ext2Length = _stream->readByte();
+ headerLength--;
+
+ if ((ext2Length & 0x7F) != 0) {
+ byte idExt = _stream->readByte();
+
+ if ((idExt & 0x80) == 0)
+ startCode = (startCode & 0xFF) << 8;
+
+ headerLength--;
+ }
+ }
+ }
+
+ if (headerLength < 0) {
+ _stream->seek(lastSync);
+ continue;
+ }
+
+ _stream->skip(headerLength);
+ } else if (c != 0xF) {
+ continue;
+ }
+
+ if (length < 0) {
+ _stream->seek(lastSync);
+ continue;
+ }
+
+ return length;
+ }
+}
+
+uint32 MPEGPSDecoder::readPTS(int c) {
+ byte buf[5];
+
+ buf[0] = (c < 0) ? _stream->readByte() : c;
+ _stream->read(buf + 1, 4);
+
+ return ((buf[0] & 0x0E) << 29) | ((READ_BE_UINT16(buf + 1) >> 1) << 15) | (READ_BE_UINT16(buf + 3) >> 1);
+}
+
+void MPEGPSDecoder::parseProgramStreamMap(int length) {
+ _stream->readByte();
+ _stream->readByte();
+
+ // skip program stream info
+ _stream->skip(_stream->readUint16BE());
+
+ int esMapLength = _stream->readUint16BE();
+
+ while (esMapLength >= 4) {
+ byte type = _stream->readByte();
+ byte esID = _stream->readByte();
+ uint16 esInfoLength = _stream->readUint16BE();
+
+ // Remember mapping from stream id to stream type
+ _psmESType[esID] = type;
+
+ // Skip program stream info
+ _stream->skip(esInfoLength);
+
+ esMapLength -= 4 + esInfoLength;
+ }
+
+ _stream->readUint32BE(); // CRC32
+}
+
+bool MPEGPSDecoder::addFirstVideoTrack() {
+ for (;;) {
+ int32 startCode;
+ uint32 pts, dts;
+ int size = readNextPacketHeader(startCode, pts, dts);
+
+ // End of stream? We failed
+ if (size < 0)
+ return false;
+
+ if (startCode >= 0x1E0 && startCode <= 0x1EF) {
+ // Video stream
+ // Can be MPEG-1/2 or MPEG-4/h.264. We'll assume the former and
+ // I hope we never need the latter.
+ Common::SeekableReadStream *firstPacket = _stream->readStream(size);
+ MPEGVideoTrack *track = new MPEGVideoTrack(firstPacket, getDefaultHighColorFormat());
+ addTrack(track);
+ _streamMap[startCode] = track;
+ delete firstPacket;
+ break;
+ }
+
+ _stream->skip(size);
+ }
+
+ return true;
+}
+
+MPEGPSDecoder::PrivateStreamType MPEGPSDecoder::detectPrivateStreamType(Common::SeekableReadStream *packet) {
+ uint32 dvdCode = packet->readUint32LE();
+ if (packet->eos())
+ return kPrivateStreamUnknown;
+
+ uint32 ps2Header = packet->readUint32BE();
+ if (!packet->eos() && ps2Header == MKTAG('S', 'S', 'h', 'd'))
+ return kPrivateStreamPS2Audio;
+
+ switch (dvdCode & 0xE0) {
+ case 0x80:
+ if ((dvdCode & 0xF8) == 0x88)
+ return kPrivateStreamDTS;
+
+ return kPrivateStreamAC3;
+ case 0xA0:
+ return kPrivateStreamDVDPCM;
+ }
+
+ return kPrivateStreamUnknown;
+}
+
+MPEGPSDecoder::MPEGVideoTrack::MPEGVideoTrack(Common::SeekableReadStream *firstPacket, const Graphics::PixelFormat &format) {
+ _surface = 0;
+ _endOfTrack = false;
+ _curFrame = -1;
+ _nextFrameStartTime = Audio::Timestamp(0, 27000000); // 27 MHz timer
+
+ findDimensions(firstPacket, format);
+
+#ifdef USE_MPEG2
+ _mpegDecoder = new Image::MPEGDecoder();
+#endif
+}
+
+MPEGPSDecoder::MPEGVideoTrack::~MPEGVideoTrack() {
+#ifdef USE_MPEG2
+ delete _mpegDecoder;
+#endif
+
+ if (_surface) {
+ _surface->free();
+ delete _surface;
+ }
+}
+
+uint16 MPEGPSDecoder::MPEGVideoTrack::getWidth() const {
+ return _surface ? _surface->w : 0;
+}
+
+uint16 MPEGPSDecoder::MPEGVideoTrack::getHeight() const {
+ return _surface ? _surface->h : 0;
+}
+
+Graphics::PixelFormat MPEGPSDecoder::MPEGVideoTrack::getPixelFormat() const {
+ if (!_surface)
+ return Graphics::PixelFormat();
+
+ return _surface->format;
+}
+
+const Graphics::Surface *MPEGPSDecoder::MPEGVideoTrack::decodeNextFrame() {
+ return _surface;
+}
+
+bool MPEGPSDecoder::MPEGVideoTrack::sendPacket(Common::SeekableReadStream *packet, uint32 pts, uint32 dts) {
+#ifdef USE_MPEG2
+ uint32 framePeriod;
+ bool foundFrame = _mpegDecoder->decodePacket(*packet, framePeriod, _surface);
+
+ if (foundFrame) {
+ _curFrame++;
+ _nextFrameStartTime = _nextFrameStartTime.addFrames(framePeriod);
+ }
+#endif
+
+ delete packet;
+
+#ifdef USE_MPEG2
+ return foundFrame;
+#else
+ return true;
+#endif
+}
+
+void MPEGPSDecoder::MPEGVideoTrack::findDimensions(Common::SeekableReadStream *firstPacket, const Graphics::PixelFormat &format) {
+ // First, check for the picture start code
+ if (firstPacket->readUint32BE() != 0x1B3)
+ error("Failed to detect MPEG sequence start");
+
+ // This is part of the bitstream, but there's really no purpose
+ // to use Common::BitStream just for this: 12 bits width, 12 bits
+ // height
+ uint16 width = firstPacket->readByte() << 4;
+ uint16 height = firstPacket->readByte();
+ width |= (height & 0xF0) >> 4;
+ height = ((height & 0x0F) << 8) | firstPacket->readByte();
+
+ debug(0, "MPEG dimensions: %dx%d", width, height);
+
+ _surface = new Graphics::Surface();
+ _surface->create(width, height, format);
+
+ firstPacket->seek(0);
+}
+
+#ifdef USE_MAD
+
+// The audio code here is almost entirely based on what we do in mp3.cpp
+
+MPEGPSDecoder::MPEGAudioTrack::MPEGAudioTrack(Common::SeekableReadStream *firstPacket) {
+ // The MAD_BUFFER_GUARD must always contain zeros (the reason
+ // for this is that the Layer III Huffman decoder of libMAD
+ // may read a few bytes beyond the end of the input buffer).
+ memset(_buf + BUFFER_SIZE, 0, MAD_BUFFER_GUARD);
+
+ _state = MP3_STATE_INIT;
+ _audStream = 0;
+
+ // Find out our audio parameters
+ initStream(firstPacket);
+
+ while (_state != MP3_STATE_EOS)
+ readHeader(firstPacket);
+
+ _audStream = Audio::makeQueuingAudioStream(_frame.header.samplerate, MAD_NCHANNELS(&_frame.header) == 2);
+
+ deinitStream();
+
+ firstPacket->seek(0);
+ _state = MP3_STATE_INIT;
+}
+
+MPEGPSDecoder::MPEGAudioTrack::~MPEGAudioTrack() {
+ deinitStream();
+ delete _audStream;
+}
+
+static inline int scaleSample(mad_fixed_t sample) {
+ // round
+ sample += (1L << (MAD_F_FRACBITS - 16));
+
+ // clip
+ if (sample > MAD_F_ONE - 1)
+ sample = MAD_F_ONE - 1;
+ else if (sample < -MAD_F_ONE)
+ sample = -MAD_F_ONE;
+
+ // quantize and scale to not saturate when mixing a lot of channels
+ return sample >> (MAD_F_FRACBITS + 1 - 16);
+}
+
+bool MPEGPSDecoder::MPEGAudioTrack::sendPacket(Common::SeekableReadStream *packet, uint32 pts, uint32 dts) {
+ while (_state != MP3_STATE_EOS)
+ decodeMP3Data(packet);
+
+ _state = MP3_STATE_READY;
+ delete packet;
+ return true;
+}
+
+Audio::AudioStream *MPEGPSDecoder::MPEGAudioTrack::getAudioStream() const {
+ return _audStream;
+}
+
+void MPEGPSDecoder::MPEGAudioTrack::initStream(Common::SeekableReadStream *packet) {
+ if (_state != MP3_STATE_INIT)
+ deinitStream();
+
+ // Init MAD
+ mad_stream_init(&_stream);
+ mad_frame_init(&_frame);
+ mad_synth_init(&_synth);
+
+ // Reset the stream data
+ packet->seek(0, SEEK_SET);
+
+ // Update state
+ _state = MP3_STATE_READY;
+
+ // Read the first few sample bytes
+ readMP3Data(packet);
+}
+
+void MPEGPSDecoder::MPEGAudioTrack::deinitStream() {
+ if (_state == MP3_STATE_INIT)
+ return;
+
+ // Deinit MAD
+ mad_synth_finish(&_synth);
+ mad_frame_finish(&_frame);
+ mad_stream_finish(&_stream);
+
+ _state = MP3_STATE_EOS;
+}
+
+void MPEGPSDecoder::MPEGAudioTrack::readMP3Data(Common::SeekableReadStream *packet) {
+ uint32 remaining = 0;
+
+ // Give up immediately if we already used up all data in the stream
+ if (packet->eos()) {
+ _state = MP3_STATE_EOS;
+ return;
+ }
+
+ if (_stream.next_frame) {
+ // If there is still data in the MAD stream, we need to preserve it.
+ // Note that we use memmove, as we are reusing the same buffer,
+ // and hence the data regions we copy from and to may overlap.
+ remaining = _stream.bufend - _stream.next_frame;
+ assert(remaining < BUFFER_SIZE); // Paranoia check
+ memmove(_buf, _stream.next_frame, remaining);
+ }
+
+ memset(_buf + remaining, 0, BUFFER_SIZE - remaining);
+
+ // Try to read the next block
+ uint32 size = packet->read(_buf + remaining, BUFFER_SIZE - remaining);
+ if (size == 0) {
+ _state = MP3_STATE_EOS;
+ return;
+ }
+
+ // Feed the data we just read into the stream decoder
+ _stream.error = MAD_ERROR_NONE;
+ mad_stream_buffer(&_stream, _buf, size + remaining);
+}
+
+void MPEGPSDecoder::MPEGAudioTrack::readHeader(Common::SeekableReadStream *packet) {
+ if (_state != MP3_STATE_READY)
+ return;
+
+ // If necessary, load more data into the stream decoder
+ if (_stream.error == MAD_ERROR_BUFLEN)
+ readMP3Data(packet);
+
+ while (_state != MP3_STATE_EOS) {
+ _stream.error = MAD_ERROR_NONE;
+
+ // Decode the next header. Note: mad_frame_decode would do this for us, too.
+ // However, for seeking we don't want to decode the full frame (else it would
+ // be far too slow). Hence we perform this explicitly in a separate step.
+ if (mad_header_decode(&_frame.header, &_stream) == -1) {
+ if (_stream.error == MAD_ERROR_BUFLEN) {
+ readMP3Data(packet); // Read more data
+ continue;
+ } else if (MAD_RECOVERABLE(_stream.error)) {
+ debug(6, "MPEGAudioTrack::readHeader(): Recoverable error in mad_header_decode (%s)", mad_stream_errorstr(&_stream));
+ continue;
+ } else {
+ warning("MPEGAudioTrack::readHeader(): Unrecoverable error in mad_header_decode (%s)", mad_stream_errorstr(&_stream));
+ break;
+ }
+ }
+
+ break;
+ }
+
+ if (_stream.error != MAD_ERROR_NONE)
+ _state = MP3_STATE_EOS;
+}
+
+void MPEGPSDecoder::MPEGAudioTrack::decodeMP3Data(Common::SeekableReadStream *packet) {
+ if (_state == MP3_STATE_INIT)
+ initStream(packet);
+
+ if (_state == MP3_STATE_EOS)
+ return;
+
+ do {
+ // If necessary, load more data into the stream decoder
+ if (_stream.error == MAD_ERROR_BUFLEN)
+ readMP3Data(packet);
+
+ while (_state == MP3_STATE_READY) {
+ _stream.error = MAD_ERROR_NONE;
+
+ // Decode the next frame
+ if (mad_frame_decode(&_frame, &_stream) == -1) {
+ if (_stream.error == MAD_ERROR_BUFLEN) {
+ break; // Read more data
+ } else if (MAD_RECOVERABLE(_stream.error)) {
+ // Note: we will occasionally see MAD_ERROR_BADDATAPTR errors here.
+ // These are normal and expected (caused by our frame skipping (i.e. "seeking")
+ // code above).
+ debug(6, "MPEGAudioTrack::decodeMP3Data(): Recoverable error in mad_frame_decode (%s)", mad_stream_errorstr(&_stream));
+ continue;
+ } else {
+ warning("MPEGAudioTrack::decodeMP3Data(): Unrecoverable error in mad_frame_decode (%s)", mad_stream_errorstr(&_stream));
+ break;
+ }
+ }
+
+ // Synthesize PCM data
+ mad_synth_frame(&_synth, &_frame);
+
+ // Output it to our queue
+ if (_synth.pcm.length != 0) {
+ byte *buffer = (byte *)malloc(_synth.pcm.length * 2 * MAD_NCHANNELS(&_frame.header));
+ int16 *ptr = (int16 *)buffer;
+
+ for (int i = 0; i < _synth.pcm.length; i++) {
+ *ptr++ = (int16)scaleSample(_synth.pcm.samples[0][i]);
+
+ if (MAD_NCHANNELS(&_frame.header) == 2)
+ *ptr++ = (int16)scaleSample(_synth.pcm.samples[1][i]);
+ }
+
+ int flags = Audio::FLAG_16BITS;
+
+ if (_audStream->isStereo())
+ flags |= Audio::FLAG_STEREO;
+
+#ifdef SCUMM_LITTLE_ENDIAN
+ flags |= Audio::FLAG_LITTLE_ENDIAN;
+#endif
+
+ _audStream->queueBuffer(buffer, _synth.pcm.length * 2 * MAD_NCHANNELS(&_frame.header), DisposeAfterUse::YES, flags);
+ }
+ break;
+ }
+ } while (_state != MP3_STATE_EOS && _stream.error == MAD_ERROR_BUFLEN);
+
+ if (_stream.error != MAD_ERROR_NONE)
+ _state = MP3_STATE_EOS;
+}
+
+#endif
+
+} // End of namespace Video
diff --git a/video/mpegps_decoder.h b/video/mpegps_decoder.h
new file mode 100644
index 0000000000..0184d6f9ba
--- /dev/null
+++ b/video/mpegps_decoder.h
@@ -0,0 +1,189 @@
+/* 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 VIDEO_MPEGPS_DECODER_H
+#define VIDEO_MPEGPS_DECODER_H
+
+#include "common/hashmap.h"
+#include "graphics/surface.h"
+#include "video/video_decoder.h"
+
+#ifdef USE_MAD
+#include <mad.h>
+#endif
+
+namespace Audio {
+class QueuingAudioStream;
+}
+
+namespace Common {
+class SeekableReadStream;
+}
+
+namespace Graphics {
+struct PixelFormat;
+}
+
+namespace Image {
+class MPEGDecoder;
+}
+
+namespace Video {
+
+/**
+ * Decoder for MPEG Program Stream videos.
+ * Video decoder used in engines:
+ * - zvision
+ */
+class MPEGPSDecoder : public VideoDecoder {
+public:
+ MPEGPSDecoder();
+ virtual ~MPEGPSDecoder();
+
+ bool loadStream(Common::SeekableReadStream *stream);
+ void close();
+
+protected:
+ void readNextPacket();
+ bool useAudioSync() const { return false; }
+
+private:
+ // Base class for handling MPEG streams
+ class MPEGStream {
+ public:
+ virtual ~MPEGStream() {}
+
+ enum StreamType {
+ kStreamTypeVideo,
+ kStreamTypeAudio
+ };
+
+ virtual bool sendPacket(Common::SeekableReadStream *firstPacket, uint32 pts, uint32 dts) = 0;
+ virtual StreamType getStreamType() const = 0;
+ };
+
+ // An MPEG 1/2 video track
+ class MPEGVideoTrack : public VideoTrack, public MPEGStream {
+ public:
+ MPEGVideoTrack(Common::SeekableReadStream *firstPacket, const Graphics::PixelFormat &format);
+ ~MPEGVideoTrack();
+
+ bool endOfTrack() const { return _endOfTrack; }
+ uint16 getWidth() const;
+ uint16 getHeight() const;
+ Graphics::PixelFormat getPixelFormat() const;
+ int getCurFrame() const { return _curFrame; }
+ uint32 getNextFrameStartTime() const { return _nextFrameStartTime.msecs(); }
+ const Graphics::Surface *decodeNextFrame();
+
+ bool sendPacket(Common::SeekableReadStream *packet, uint32 pts, uint32 dts);
+ StreamType getStreamType() const { return kStreamTypeVideo; }
+
+ void setEndOfTrack() { _endOfTrack = true; }
+
+ private:
+ bool _endOfTrack;
+ int _curFrame;
+ Audio::Timestamp _nextFrameStartTime;
+ Graphics::Surface *_surface;
+
+ void findDimensions(Common::SeekableReadStream *firstPacket, const Graphics::PixelFormat &format);
+
+#ifdef USE_MPEG2
+ Image::MPEGDecoder *_mpegDecoder;
+#endif
+ };
+
+#ifdef USE_MAD
+ // An MPEG audio track
+ // TODO: Merge this with the normal MP3Stream somehow
+ class MPEGAudioTrack : public AudioTrack, public MPEGStream {
+ public:
+ MPEGAudioTrack(Common::SeekableReadStream *firstPacket);
+ ~MPEGAudioTrack();
+
+ bool sendPacket(Common::SeekableReadStream *packet, uint32 pts, uint32 dts);
+ StreamType getStreamType() const { return kStreamTypeAudio; }
+
+ protected:
+ Audio::AudioStream *getAudioStream() const;
+
+ private:
+ Audio::QueuingAudioStream *_audStream;
+
+ enum State {
+ MP3_STATE_INIT, // Need to init the decoder
+ MP3_STATE_READY, // ready for processing data
+ MP3_STATE_EOS // end of data reached (may need to loop)
+ };
+
+ State _state;
+
+ mad_stream _stream;
+ mad_frame _frame;
+ mad_synth _synth;
+
+ enum {
+ BUFFER_SIZE = 5 * 8192
+ };
+
+ // This buffer contains a slab of input data
+ byte _buf[BUFFER_SIZE + MAD_BUFFER_GUARD];
+
+ void initStream(Common::SeekableReadStream *packet);
+ void deinitStream();
+ void readMP3Data(Common::SeekableReadStream *packet);
+ void readHeader(Common::SeekableReadStream *packet);
+ void decodeMP3Data(Common::SeekableReadStream *packet);
+ };
+#endif
+
+ // The different types of private streams we can detect at the moment
+ enum PrivateStreamType {
+ kPrivateStreamUnknown,
+ kPrivateStreamAC3,
+ kPrivateStreamDTS,
+ kPrivateStreamDVDPCM,
+ kPrivateStreamPS2Audio
+ };
+
+ PrivateStreamType detectPrivateStreamType(Common::SeekableReadStream *packet);
+
+ bool addFirstVideoTrack();
+
+ int readNextPacketHeader(int32 &startCode, uint32 &pts, uint32 &dts);
+ int findNextStartCode(uint32 &size);
+ uint32 readPTS(int c);
+
+ void parseProgramStreamMap(int length);
+ byte _psmESType[256];
+
+ // A map from stream types to stream handlers
+ typedef Common::HashMap<int, MPEGStream *> StreamMap;
+ StreamMap _streamMap;
+
+ Common::SeekableReadStream *_stream;
+};
+
+} // End of namespace Video
+
+#endif
diff --git a/video/qt_decoder.cpp b/video/qt_decoder.cpp
index 0a29692948..324bf65294 100644
--- a/video/qt_decoder.cpp
+++ b/video/qt_decoder.cpp
@@ -286,13 +286,15 @@ QuickTimeDecoder::VideoTrackHandler::VideoTrackHandler(QuickTimeDecoder *decoder
_curEdit = 0;
enterNewEditList(false);
- _holdNextFrameStartTime = false;
_curFrame = -1;
_durationOverride = -1;
_scaledSurface = 0;
_curPalette = 0;
_dirtyPalette = false;
_reversed = false;
+ _forcedDitherPalette = 0;
+ _ditherTable = 0;
+ _ditherFrame = 0;
}
QuickTimeDecoder::VideoTrackHandler::~VideoTrackHandler() {
@@ -300,6 +302,14 @@ QuickTimeDecoder::VideoTrackHandler::~VideoTrackHandler() {
_scaledSurface->free();
delete _scaledSurface;
}
+
+ delete[] _forcedDitherPalette;
+ delete[] _ditherTable;
+
+ if (_ditherFrame) {
+ _ditherFrame->free();
+ delete _ditherFrame;
+ }
}
bool QuickTimeDecoder::VideoTrackHandler::endOfTrack() const {
@@ -347,15 +357,12 @@ bool QuickTimeDecoder::VideoTrackHandler::seek(const Audio::Timestamp &requested
}
}
- // All that's left is to figure out what our starting time is going to be
- // Compare the starting point for the frame to where we need to be
- _holdNextFrameStartTime = getRateAdjustedFrameTime() != (uint32)time.totalNumberOfFrames();
-
- // If we went past the time, go back a frame. _curFrame before this point is at the frame
- // that should be displayed. This adjustment ensures it is on the frame before the one that
- // should be displayed.
- if (_holdNextFrameStartTime)
+ // Check if we went past, then adjust the frame times
+ if (getRateAdjustedFrameTime() != (uint32)time.totalNumberOfFrames()) {
_curFrame--;
+ _durationOverride = getRateAdjustedFrameTime() - time.totalNumberOfFrames();
+ _nextFrameStartTime = time.totalNumberOfFrames();
+ }
if (_reversed) {
// Call setReverse again to update
@@ -386,6 +393,9 @@ uint16 QuickTimeDecoder::VideoTrackHandler::getHeight() const {
}
Graphics::PixelFormat QuickTimeDecoder::VideoTrackHandler::getPixelFormat() const {
+ if (_forcedDitherPalette)
+ return Graphics::PixelFormat::createFormatCLUT8();
+
return ((VideoSampleDesc *)_parent->sampleDescs[0])->_videoCodec->getPixelFormat();
}
@@ -397,8 +407,22 @@ uint32 QuickTimeDecoder::VideoTrackHandler::getNextFrameStartTime() const {
if (endOfTrack())
return 0;
- // Convert to milliseconds so the tracks can be compared
- return getRateAdjustedFrameTime() * 1000 / _parent->timeScale;
+ Audio::Timestamp frameTime(0, getRateAdjustedFrameTime(), _parent->timeScale);
+
+ // Check if the frame goes beyond the end of the edit. In that case, the next frame
+ // should really be when we cross the edit boundary.
+ if (_reversed) {
+ Audio::Timestamp editStartTime(0, _parent->editList[_curEdit].timeOffset, _decoder->_timeScale);
+ if (frameTime < editStartTime)
+ return editStartTime.msecs();
+ } else {
+ Audio::Timestamp nextEditStartTime(0, _parent->editList[_curEdit].timeOffset + _parent->editList[_curEdit].trackDuration, _decoder->_timeScale);
+ if (frameTime > nextEditStartTime)
+ return nextEditStartTime.msecs();
+ }
+
+ // Not past an edit boundary, so the frame time is what should be used
+ return frameTime.msecs();
}
const Graphics::Surface *QuickTimeDecoder::VideoTrackHandler::decodeNextFrame() {
@@ -422,39 +446,41 @@ const Graphics::Surface *QuickTimeDecoder::VideoTrackHandler::decodeNextFrame()
bufferNextFrame();
}
+ // Update the edit list, if applicable
+ if (endOfCurEdit()) {
+ _curEdit++;
+
+ if (atLastEdit())
+ return 0;
+
+ enterNewEditList(true);
+ }
+
const Graphics::Surface *frame = bufferNextFrame();
if (_reversed) {
- if (_holdNextFrameStartTime) {
- // Don't set the next frame start time here; we just did a seek
- _holdNextFrameStartTime = false;
+ if (_durationOverride >= 0) {
+ // Use our own duration overridden from a media seek
+ _nextFrameStartTime -= _durationOverride;
+ _durationOverride = -1;
} else {
// Just need to subtract the time
_nextFrameStartTime -= getFrameDuration();
}
} else {
- if (_holdNextFrameStartTime) {
- // Don't set the next frame start time here; we just did a seek
- _holdNextFrameStartTime = false;
- } else if (_durationOverride >= 0) {
- // Use our own duration from the edit list calculation
- _nextFrameStartTime += _durationOverride;
+ if (_durationOverride >= 0) {
+ // Use our own duration overridden from a media seek
+ _nextFrameStartTime += _durationOverride;
_durationOverride = -1;
} else {
_nextFrameStartTime += getFrameDuration();
}
-
- // Update the edit list, if applicable
- // HACK: We're also accepting the time minus one because edit lists
- // aren't as accurate as one would hope.
- if (!atLastEdit() && getRateAdjustedFrameTime() >= getCurEditTimeOffset() + getCurEditTrackDuration() - 1) {
- _curEdit++;
-
- if (!atLastEdit())
- enterNewEditList(true);
- }
}
+ // Handle forced dithering
+ if (frame && _forcedDitherPalette)
+ frame = forceDither(*frame);
+
if (frame && (_parent->scaleFactorX != 1 || _parent->scaleFactorY != 1)) {
if (!_scaledSurface) {
_scaledSurface = new Graphics::Surface();
@@ -468,6 +494,11 @@ const Graphics::Surface *QuickTimeDecoder::VideoTrackHandler::decodeNextFrame()
return frame;
}
+const byte *QuickTimeDecoder::VideoTrackHandler::getPalette() const {
+ _dirtyPalette = false;
+ return _forcedDitherPalette ? _forcedDitherPalette : _curPalette;
+}
+
bool QuickTimeDecoder::VideoTrackHandler::setReverse(bool reverse) {
_reversed = reverse;
@@ -485,11 +516,11 @@ bool QuickTimeDecoder::VideoTrackHandler::setReverse(bool reverse) {
_curEdit = _parent->editCount - 1;
_curFrame = _parent->frameCount;
_nextFrameStartTime = _parent->editList[_curEdit].trackDuration + _parent->editList[_curEdit].timeOffset;
- } else if (_holdNextFrameStartTime) {
- // We just seeked, so "pivot" around the frame that should be displayed
- _curFrame++;
- _nextFrameStartTime -= getFrameDuration();
- _curFrame++;
+ } else if (_durationOverride >= 0) {
+ // We just had a media seek, so "pivot" around the frame that should
+ // be displayed.
+ _curFrame += 2;
+ _nextFrameStartTime += _durationOverride;
} else {
// We need to put _curFrame to be the one after the one that should be displayed.
// Since we're on the frame that should be displaying right now, add one.
@@ -497,20 +528,19 @@ bool QuickTimeDecoder::VideoTrackHandler::setReverse(bool reverse) {
}
} else {
// Update the edit list, if applicable
- // HACK: We're also accepting the time minus one because edit lists
- // aren't as accurate as one would hope.
- if (!atLastEdit() && getRateAdjustedFrameTime() >= getCurEditTimeOffset() + getCurEditTrackDuration() - 1) {
+ if (!atLastEdit() && endOfCurEdit()) {
_curEdit++;
if (atLastEdit())
return true;
}
- if (_holdNextFrameStartTime) {
- // We just seeked, so "pivot" around the frame that should be displayed
+ if (_durationOverride >= 0) {
+ // We just had a media seek, so "pivot" around the frame that should
+ // be displayed.
_curFrame--;
- _nextFrameStartTime += getFrameDuration();
- }
+ _nextFrameStartTime -= _durationOverride;
+ }
// We need to put _curFrame to be the one before the one that should be displayed.
// Since we're on the frame that should be displaying right now, subtract one.
@@ -559,10 +589,8 @@ Common::SeekableReadStream *QuickTimeDecoder::VideoTrackHandler::getNextFramePac
}
}
- if (actualChunk < 0) {
- warning("Could not find data for frame %d", _curFrame);
- return 0;
- }
+ if (actualChunk < 0)
+ error("Could not find data for frame %d", _curFrame);
// Next seek to that frame
Common::SeekableReadStream *stream = _decoder->_fd;
@@ -617,30 +645,32 @@ void QuickTimeDecoder::VideoTrackHandler::enterNewEditList(bool bufferFrames) {
if (atLastEdit())
return;
+ uint32 mediaTime = _parent->editList[_curEdit].mediaTime;
uint32 frameNum = 0;
- bool done = false;
uint32 totalDuration = 0;
- uint32 prevDuration = 0;
+ _durationOverride = -1;
// Track down where the mediaTime is in the media
// This is basically time -> frame mapping
// Note that this code uses first frame = 0
- for (int32 i = 0; i < _parent->timeToSampleCount && !done; i++) {
- for (int32 j = 0; j < _parent->timeToSample[i].count; j++) {
- if (totalDuration == (uint32)_parent->editList[_curEdit].mediaTime) {
- done = true;
- prevDuration = totalDuration;
- break;
- } else if (totalDuration > (uint32)_parent->editList[_curEdit].mediaTime) {
- done = true;
- frameNum--;
- break;
- }
+ for (int32 i = 0; i < _parent->timeToSampleCount; i++) {
+ uint32 duration = _parent->timeToSample[i].count * _parent->timeToSample[i].duration;
+
+ if (totalDuration + duration >= mediaTime) {
+ uint32 frameInc = (mediaTime - totalDuration) / _parent->timeToSample[i].duration;
+ frameNum += frameInc;
+ totalDuration += frameInc * _parent->timeToSample[i].duration;
- prevDuration = totalDuration;
- totalDuration += _parent->timeToSample[i].duration;
- frameNum++;
+ // If we didn't get to the exact media time, mark an override for
+ // the time.
+ if (totalDuration != mediaTime)
+ _durationOverride = totalDuration + _parent->timeToSample[i].duration - mediaTime;
+
+ break;
}
+
+ frameNum += _parent->timeToSample[i].count;
+ totalDuration += duration;
}
if (bufferFrames) {
@@ -656,12 +686,6 @@ void QuickTimeDecoder::VideoTrackHandler::enterNewEditList(bool bufferFrames) {
}
_nextFrameStartTime = getCurEditTimeOffset();
-
- // Set an override for the duration since we came up in-between two frames
- if (prevDuration != totalDuration)
- _durationOverride = totalDuration - prevDuration;
- else
- _durationOverride = -1;
}
const Graphics::Surface *QuickTimeDecoder::VideoTrackHandler::bufferNextFrame() {
@@ -709,7 +733,12 @@ const Graphics::Surface *QuickTimeDecoder::VideoTrackHandler::bufferNextFrame()
uint32 QuickTimeDecoder::VideoTrackHandler::getRateAdjustedFrameTime() const {
// Figure out what time the next frame is at taking the edit list rate into account
- uint32 convertedTime = (Common::Rational(_nextFrameStartTime - getCurEditTimeOffset()) / _parent->editList[_curEdit].mediaRate).toInt();
+ Common::Rational offsetFromEdit = Common::Rational(_nextFrameStartTime - getCurEditTimeOffset()) / _parent->editList[_curEdit].mediaRate;
+ uint32 convertedTime = offsetFromEdit.toInt();
+
+ if ((offsetFromEdit.getNumerator() % offsetFromEdit.getDenominator()) > (offsetFromEdit.getDenominator() / 2))
+ convertedTime++;
+
return convertedTime + getCurEditTimeOffset();
}
@@ -739,4 +768,107 @@ bool QuickTimeDecoder::VideoTrackHandler::atLastEdit() const {
return _curEdit == _parent->editCount;
}
+bool QuickTimeDecoder::VideoTrackHandler::endOfCurEdit() const {
+ // We're at the end of the edit once the next frame's time would
+ // bring us past the end of the edit.
+ return getRateAdjustedFrameTime() >= getCurEditTimeOffset() + getCurEditTrackDuration();
+}
+
+bool QuickTimeDecoder::VideoTrackHandler::canDither() const {
+ for (uint i = 0; i < _parent->sampleDescs.size(); i++) {
+ VideoSampleDesc *desc = (VideoSampleDesc *)_parent->sampleDescs[i];
+
+ if (!desc || !desc->_videoCodec)
+ return false;
+ }
+
+ return true;
+}
+
+void QuickTimeDecoder::VideoTrackHandler::setDither(const byte *palette) {
+ assert(canDither());
+
+ for (uint i = 0; i < _parent->sampleDescs.size(); i++) {
+ VideoSampleDesc *desc = (VideoSampleDesc *)_parent->sampleDescs[i];
+
+ if (desc->_videoCodec->canDither(Image::Codec::kDitherTypeQT)) {
+ // Codec dither
+ desc->_videoCodec->setDither(Image::Codec::kDitherTypeQT, palette);
+ } else {
+ // Forced dither
+ _forcedDitherPalette = new byte[256 * 3];
+ memcpy(_forcedDitherPalette, palette, 256 * 3);
+ _ditherTable = Image::Codec::createQuickTimeDitherTable(_forcedDitherPalette, 256);
+ _dirtyPalette = true;
+ }
+ }
+}
+
+namespace {
+
+// Return a pixel in RGB554
+uint16 makeDitherColor(byte r, byte g, byte b) {
+ return ((r & 0xF8) << 6) | ((g & 0xF8) << 1) | (b >> 4);
+}
+
+// Default template to convert a dither color
+template<typename PixelInt>
+inline uint16 readDitherColor(PixelInt srcColor, const Graphics::PixelFormat& format, const byte *palette) {
+ byte r, g, b;
+ format.colorToRGB(srcColor, r, g, b);
+ return makeDitherColor(r, g, b);
+}
+
+// Specialized version for 8bpp
+template<>
+inline uint16 readDitherColor(byte srcColor, const Graphics::PixelFormat& format, const byte *palette) {
+ return makeDitherColor(palette[srcColor * 3], palette[srcColor * 3 + 1], palette[srcColor * 3 + 2]);
+}
+
+template<typename PixelInt>
+void ditherFrame(const Graphics::Surface &src, Graphics::Surface &dst, const byte *ditherTable, const byte *palette = 0) {
+ static const uint16 colorTableOffsets[] = { 0x0000, 0xC000, 0x4000, 0x8000 };
+
+ for (int y = 0; y < dst.h; y++) {
+ const PixelInt *srcPtr = (const PixelInt *)src.getBasePtr(0, y);
+ byte *dstPtr = (byte *)dst.getBasePtr(0, y);
+ uint16 colorTableOffset = colorTableOffsets[y & 3];
+
+ for (int x = 0; x < dst.w; x++) {
+ uint16 color = readDitherColor(*srcPtr++, src.format, palette);
+ *dstPtr++ = ditherTable[colorTableOffset + color];
+ colorTableOffset += 0x4000;
+ }
+ }
+}
+
+} // End of anonymous namespace
+
+const Graphics::Surface *QuickTimeDecoder::VideoTrackHandler::forceDither(const Graphics::Surface &frame) {
+ if (frame.format.bytesPerPixel == 1) {
+ // This should always be true, but this is for sanity
+ if (!_curPalette)
+ return &frame;
+
+ // If the palettes match, bail out
+ if (memcmp(_forcedDitherPalette, _curPalette, 256 * 3) == 0)
+ return &frame;
+ }
+
+ // Need to create a new one
+ if (!_ditherFrame) {
+ _ditherFrame = new Graphics::Surface();
+ _ditherFrame->create(frame.w, frame.h, Graphics::PixelFormat::createFormatCLUT8());
+ }
+
+ if (frame.format.bytesPerPixel == 1)
+ ditherFrame<byte>(frame, *_ditherFrame, _ditherTable, _curPalette);
+ else if (frame.format.bytesPerPixel == 2)
+ ditherFrame<uint16>(frame, *_ditherFrame, _ditherTable);
+ else if (frame.format.bytesPerPixel == 4)
+ ditherFrame<uint32>(frame, *_ditherFrame, _ditherTable);
+
+ return _ditherFrame;
+}
+
} // End of namespace Video
diff --git a/video/qt_decoder.h b/video/qt_decoder.h
index 7e87d21ae7..5a6c5eebec 100644
--- a/video/qt_decoder.h
+++ b/video/qt_decoder.h
@@ -136,10 +136,12 @@ private:
int getFrameCount() const;
uint32 getNextFrameStartTime() const;
const Graphics::Surface *decodeNextFrame();
- const byte *getPalette() const { _dirtyPalette = false; return _curPalette; }
+ const byte *getPalette() const;
bool hasDirtyPalette() const { return _curPalette; }
bool setReverse(bool reverse);
bool isReversed() const { return _reversed; }
+ bool canDither() const;
+ void setDither(const byte *palette);
Common::Rational getScaledWidth() const;
Common::Rational getScaledHeight() const;
@@ -151,12 +153,17 @@ private:
int32 _curFrame;
uint32 _nextFrameStartTime;
Graphics::Surface *_scaledSurface;
- bool _holdNextFrameStartTime;
int32 _durationOverride;
const byte *_curPalette;
mutable bool _dirtyPalette;
bool _reversed;
+ // Forced dithering of frames
+ byte *_forcedDitherPalette;
+ byte *_ditherTable;
+ Graphics::Surface *_ditherFrame;
+ const Graphics::Surface *forceDither(const Graphics::Surface &frame);
+
Common::SeekableReadStream *getNextFramePacket(uint32 &descId);
uint32 getFrameDuration();
uint32 findKeyFrame(uint32 frame) const;
@@ -166,6 +173,7 @@ private:
uint32 getCurEditTimeOffset() const;
uint32 getCurEditTrackDuration() const;
bool atLastEdit() const;
+ bool endOfCurEdit() const;
};
};
diff --git a/video/theora_decoder.cpp b/video/theora_decoder.cpp
index cb6289bd60..ba596c6032 100644
--- a/video/theora_decoder.cpp
+++ b/video/theora_decoder.cpp
@@ -360,7 +360,11 @@ static double rint(double v) {
}
bool TheoraDecoder::VorbisAudioTrack::decodeSamples() {
+#ifdef USE_TREMOR
+ ogg_int32_t **pcm;
+#else
float **pcm;
+#endif
// if there's pending, decoded audio, grab it
int ret = vorbis_synthesis_pcmout(&_vorbisDSP, &pcm);
diff --git a/video/theora_decoder.h b/video/theora_decoder.h
index b85388426b..5b683cf6af 100644
--- a/video/theora_decoder.h
+++ b/video/theora_decoder.h
@@ -33,7 +33,12 @@
#include "graphics/surface.h"
#include <theora/theoradec.h>
+
+#ifdef USE_TREMOR
+#include <tremor/ivorbiscodec.h>
+#else
#include <vorbis/codec.h>
+#endif
namespace Common {
class SeekableReadStream;
@@ -50,6 +55,7 @@ namespace Video {
*
* Decoder for Theora videos.
* Video decoder used in engines:
+ * - pegasus
* - sword25
* - wintermute
*/
diff --git a/video/video_decoder.cpp b/video/video_decoder.cpp
index dce96aae03..217b4c8456 100644
--- a/video/video_decoder.cpp
+++ b/video/video_decoder.cpp
@@ -47,6 +47,7 @@ VideoDecoder::VideoDecoder() {
_endTimeSet = false;
_nextVideoTrack = 0;
_mainAudioTrack = 0;
+ _canSetDither = true;
// Find the best format for output
_defaultHighColorFormat = g_system->getScreenFormat();
@@ -77,6 +78,7 @@ void VideoDecoder::close() {
_endTimeSet = false;
_nextVideoTrack = 0;
_mainAudioTrack = 0;
+ _canSetDither = true;
}
bool VideoDecoder::loadFile(const Common::String &filename) {
@@ -171,6 +173,7 @@ Graphics::PixelFormat VideoDecoder::getPixelFormat() const {
const Graphics::Surface *VideoDecoder::decodeNextFrame() {
_needsUpdate = false;
+ _canSetDither = false;
readNextPacket();
@@ -488,6 +491,23 @@ bool VideoDecoder::seekIntern(const Audio::Timestamp &time) {
return true;
}
+bool VideoDecoder::setDitheringPalette(const byte *palette) {
+ // If a frame was already decoded, we can't set it now.
+ if (!_canSetDither)
+ return false;
+
+ bool result = false;
+
+ for (TrackList::iterator it = _tracks.begin(); it != _tracks.end(); it++) {
+ if ((*it)->getTrackType() == Track::kTrackTypeVideo && ((VideoTrack *)*it)->canDither()) {
+ ((VideoTrack *)*it)->setDither(palette);
+ result = true;
+ }
+ }
+
+ return result;
+}
+
VideoDecoder::Track::Track() {
_paused = false;
}
@@ -530,7 +550,9 @@ Audio::Timestamp VideoDecoder::FixedRateVideoTrack::getFrameTime(uint frame) con
// (which Audio::Timestamp doesn't support).
Common::Rational frameRate = getFrameRate();
- if (frameRate == frameRate.toInt()) // The nice case (a whole number)
+ // Try to keep it in terms of the frame rate, if the frame rate is a whole
+ // number.
+ if (frameRate.getDenominator() == 1)
return Audio::Timestamp(0, frame, frameRate.toInt());
// Convert as best as possible
diff --git a/video/video_decoder.h b/video/video_decoder.h
index c3879e9144..eca15e7265 100644
--- a/video/video_decoder.h
+++ b/video/video_decoder.h
@@ -377,6 +377,25 @@ public:
*/
bool setReverse(bool reverse);
+ /**
+ * Tell the video to dither to a palette.
+ *
+ * By default, VideoDecoder will return surfaces in native, or in the case
+ * of YUV-based videos, the format set by setDefaultHighColorFormat().
+ * For video formats or codecs that support it, this will start outputting
+ * its surfaces in 8bpp with this palette.
+ *
+ * This should be called after loadStream(), but before a decodeNextFrame()
+ * call. This is enforced.
+ *
+ * The palette will be copied, so you do not need to worry about the pointer
+ * going out-of-scope.
+ *
+ * @param palette The palette to use for dithering
+ * @return true on success, false otherwise
+ */
+ bool setDitheringPalette(const byte *palette);
+
/////////////////////////////////////////
// Audio Control
/////////////////////////////////////////
@@ -604,6 +623,16 @@ protected:
* Is the video track set to play in reverse?
*/
virtual bool isReversed() const { return false; }
+
+ /**
+ * Can the video track dither?
+ */
+ virtual bool canDither() const { return false; }
+
+ /**
+ * Activate dithering mode with a palette
+ */
+ virtual void setDither(const byte *palette) {}
};
/**
@@ -901,6 +930,9 @@ private:
mutable bool _dirtyPalette;
const byte *_palette;
+ // Enforcement of not being able to set dither
+ bool _canSetDither;
+
// Default PixelFormat settings
Graphics::PixelFormat _defaultHighColorFormat;