aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2015-05-31 14:45:10 -0400
committerPaul Gilbert2015-05-31 14:45:10 -0400
commite5296ebf8dd09f603499b1894a33865ec71bb28f (patch)
treed7de032efd54dfdb3159cbc778a0c9ce8cd8aa91
parent673537bad93f0b440172a0cc263ebf19cc95ffc0 (diff)
parent141ff4d08dc24b6bb17098bd71801e2a58e6a38f (diff)
downloadscummvm-rg350-e5296ebf8dd09f603499b1894a33865ec71bb28f.tar.gz
scummvm-rg350-e5296ebf8dd09f603499b1894a33865ec71bb28f.tar.bz2
scummvm-rg350-e5296ebf8dd09f603499b1894a33865ec71bb28f.zip
Merge branch 'master' into phantom
-rw-r--r--AUTHORS16
-rw-r--r--CONTRIBUTING.md12
-rw-r--r--COPYRIGHT2
-rw-r--r--Makefile1
-rw-r--r--NEWS31
-rw-r--r--README304
-rw-r--r--audio/decoders/mp3.cpp17
-rw-r--r--audio/decoders/quicktime.cpp9
-rw-r--r--audio/fmopl.cpp6
-rw-r--r--audio/mods/protracker.cpp9
-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/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/dinguxsdl/dinguxsdl-events.cpp34
-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.cpp90
-rw-r--r--backends/graphics/opengl/opengl-graphics.h17
-rw-r--r--backends/graphics/openglsdl/openglsdl-graphics.cpp147
-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/keymapper/action.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/asset-archive.cpp3
-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/dingux/dingux.mk35
-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.cpp173
-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/inventory/inventory_manager.h)15
-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/wii/osystem_events.cpp136
-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--base/version.cpp8
-rw-r--r--common/EventMapper.cpp6
-rw-r--r--common/c++11-compat.h6
-rw-r--r--common/endian.h219
-rw-r--r--common/fft.cpp4
-rw-r--r--common/fft.h2
-rw-r--r--common/scummsys.h2
-rw-r--r--common/stream.h96
-rw-r--r--common/unzip.cpp2
-rw-r--r--common/xmlparser.cpp2
-rwxr-xr-xconfig.guess364
-rwxr-xr-xconfig.sub158
-rwxr-xr-xconfigure66
-rw-r--r--devtools/create_project/create_project.cpp14
-rw-r--r--devtools/create_translations/po_parser.cpp7
-rwxr-xr-xdevtools/credits.pl14
-rw-r--r--devtools/scumm-md5.txt55
-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/gcw0/default.gcw0.desktop16
-rwxr-xr-xdists/gcw0/opk_make.sh111
-rw-r--r--dists/gcw0/scummvm.pngbin0 -> 2656 bytes
-rwxr-xr-xdists/gcw0/scummvm.sh9
-rw-r--r--dists/gcw0/scummvmrc9
-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--engines/access/access.cpp578
-rw-r--r--engines/access/access.h296
-rw-r--r--engines/access/amazon/amazon_game.cpp786
-rw-r--r--engines/access/amazon/amazon_game.h139
-rw-r--r--engines/access/amazon/amazon_logic.cpp2230
-rw-r--r--engines/access/amazon/amazon_logic.h253
-rw-r--r--engines/access/amazon/amazon_player.cpp86
-rw-r--r--engines/access/amazon/amazon_player.h48
-rw-r--r--engines/access/amazon/amazon_resources.cpp2411
-rw-r--r--engines/access/amazon/amazon_resources.h148
-rw-r--r--engines/access/amazon/amazon_room.cpp241
-rw-r--r--engines/access/amazon/amazon_room.h72
-rw-r--r--engines/access/amazon/amazon_scripts.cpp516
-rw-r--r--engines/access/amazon/amazon_scripts.h67
-rw-r--r--engines/access/animation.cpp340
-rw-r--r--engines/access/animation.h139
-rw-r--r--engines/access/asurface.cpp346
-rw-r--r--engines/access/asurface.h166
-rw-r--r--engines/access/bubble_box.cpp281
-rw-r--r--engines/access/bubble_box.h85
-rw-r--r--engines/access/char.cpp162
-rw-r--r--engines/access/char.h64
-rw-r--r--engines/access/configure.engine3
-rw-r--r--engines/access/data.cpp76
-rw-r--r--engines/access/data.h103
-rw-r--r--engines/access/debugger.cpp164
-rw-r--r--engines/access/debugger.h64
-rw-r--r--engines/access/decompress.cpp128
-rw-r--r--engines/access/decompress.h (renamed from engines/zvision/core/menu.h)21
-rw-r--r--engines/access/detection.cpp209
-rw-r--r--engines/access/detection_tables.h91
-rw-r--r--engines/access/events.cpp373
-rw-r--r--engines/access/events.h157
-rw-r--r--engines/access/files.cpp243
-rw-r--r--engines/access/files.h142
-rw-r--r--engines/access/font.cpp179
-rw-r--r--engines/access/font.h103
-rw-r--r--engines/access/inventory.cpp536
-rw-r--r--engines/access/inventory.h140
-rw-r--r--engines/access/martian/martian_game.cpp168
-rw-r--r--engines/access/martian/martian_game.h76
-rw-r--r--engines/access/martian/martian_resources.cpp722
-rw-r--r--engines/access/martian/martian_resources.h52
-rw-r--r--engines/access/martian/martian_room.cpp141
-rw-r--r--engines/access/martian/martian_room.h66
-rw-r--r--engines/access/martian/martian_scripts.cpp48
-rw-r--r--engines/access/martian/martian_scripts.h49
-rw-r--r--engines/access/module.mk41
-rw-r--r--engines/access/player.cpp825
-rw-r--r--engines/access/player.h152
-rw-r--r--engines/access/resources.cpp109
-rw-r--r--engines/access/resources.h53
-rw-r--r--engines/access/room.cpp833
-rw-r--r--engines/access/room.h201
-rw-r--r--engines/access/screen.cpp369
-rw-r--r--engines/access/screen.h182
-rw-r--r--engines/access/scripts.cpp887
-rw-r--r--engines/access/scripts.h168
-rw-r--r--engines/access/sound.cpp326
-rw-r--r--engines/access/sound.h111
-rw-r--r--engines/access/video.cpp187
-rw-r--r--engines/access/video.h82
-rw-r--r--engines/agi/agi.cpp100
-rw-r--r--engines/agi/agi.h5
-rw-r--r--engines/agi/detection.cpp56
-rw-r--r--engines/agi/detection_tables.h174
-rw-r--r--engines/agi/font.h271
-rw-r--r--engines/agi/graphics.cpp29
-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/detection_tables.h26
-rw-r--r--engines/agos/gfx.cpp2
-rw-r--r--engines/agos/input.cpp10
-rw-r--r--engines/agos/midi.cpp89
-rw-r--r--engines/agos/midi.h8
-rw-r--r--engines/agos/rooms.cpp3
-rw-r--r--engines/agos/saveload.cpp7
-rw-r--r--engines/bbvs/bbvs.cpp98
-rw-r--r--engines/bbvs/bbvs.h78
-rw-r--r--engines/bbvs/detection.cpp2
-rw-r--r--engines/bbvs/dialogs.cpp8
-rw-r--r--engines/bbvs/dialogs.h6
-rw-r--r--engines/bbvs/gamemodule.cpp40
-rw-r--r--engines/bbvs/gamemodule.h50
-rw-r--r--engines/bbvs/graphics.cpp4
-rw-r--r--engines/bbvs/minigames/bbairguitar.cpp177
-rw-r--r--engines/bbvs/minigames/bbairguitar.h45
-rw-r--r--engines/bbvs/minigames/bbant.cpp64
-rw-r--r--engines/bbvs/minigames/bbant.h26
-rw-r--r--engines/bbvs/minigames/bbloogie.cpp68
-rw-r--r--engines/bbvs/minigames/bbloogie.h36
-rw-r--r--engines/bbvs/minigames/bbtennis.cpp44
-rw-r--r--engines/bbvs/minigames/bbtennis.h22
-rw-r--r--engines/bbvs/minigames/minigame.cpp6
-rw-r--r--engines/bbvs/minigames/minigame.h14
-rw-r--r--engines/bbvs/saveload.cpp26
-rw-r--r--engines/bbvs/scene.cpp20
-rw-r--r--engines/bbvs/spritemodule.cpp12
-rw-r--r--engines/bbvs/videoplayer.cpp4
-rw-r--r--engines/bbvs/walk.cpp24
-rw-r--r--engines/cge/vga13h.cpp2
-rw-r--r--engines/cge2/cge2.cpp2
-rw-r--r--engines/cge2/cge2.h2
-rw-r--r--engines/cge2/cge2_main.cpp24
-rw-r--r--engines/cge2/cge2_main.h2
-rw-r--r--engines/cge2/configure.engine2
-rw-r--r--engines/cge2/detection.cpp20
-rw-r--r--engines/cge2/events.cpp4
-rw-r--r--engines/cge2/hero.cpp10
-rw-r--r--engines/cge2/map.cpp2
-rw-r--r--engines/cge2/saveload.cpp4
-rw-r--r--engines/cge2/snail.cpp10
-rw-r--r--engines/cge2/spare.h2
-rw-r--r--engines/cge2/talk.cpp2
-rw-r--r--engines/cge2/vga13h.cpp8
-rw-r--r--engines/cine/detection_tables.h14
-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/fullpipe.cpp4
-rw-r--r--engines/fullpipe/gameloader.cpp2
-rw-r--r--engines/fullpipe/gfx.cpp8
-rw-r--r--engines/fullpipe/input.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.cpp14
-rw-r--r--engines/fullpipe/scene.cpp8
-rw-r--r--engines/fullpipe/scenes/scene02.cpp2
-rw-r--r--engines/fullpipe/scenes/scene04.cpp9
-rw-r--r--engines/fullpipe/scenes/scene14.cpp2
-rw-r--r--engines/fullpipe/scenes/scene15.cpp2
-rw-r--r--engines/fullpipe/scenes/scene16.cpp10
-rw-r--r--engines/fullpipe/scenes/scene23.cpp6
-rw-r--r--engines/fullpipe/scenes/scene28.cpp2
-rw-r--r--engines/fullpipe/scenes/scene29.cpp2
-rw-r--r--engines/fullpipe/scenes/scene37.cpp2
-rw-r--r--engines/fullpipe/sound.cpp2
-rw-r--r--engines/fullpipe/statics.cpp19
-rw-r--r--engines/gob/inter_v1.cpp2
-rw-r--r--engines/gob/surface.cpp7
-rw-r--r--engines/gob/surface.h2
-rw-r--r--engines/groovie/graphics.cpp25
-rw-r--r--engines/groovie/graphics.h2
-rw-r--r--engines/groovie/roq.cpp76
-rw-r--r--engines/groovie/roq.h6
-rw-r--r--engines/groovie/script.cpp69
-rw-r--r--engines/groovie/script.h1
-rw-r--r--engines/hopkins/computer.cpp2
-rw-r--r--engines/hopkins/files.cpp2
-rw-r--r--engines/hopkins/lines.cpp2
-rw-r--r--engines/hopkins/sound.cpp53
-rw-r--r--engines/hopkins/sound.h2
-rw-r--r--engines/hopkins/talk.cpp2
-rw-r--r--engines/hugo/mouse.cpp14
-rw-r--r--engines/kyra/sound_adlib.cpp11
-rw-r--r--engines/kyra/vqa.cpp2
-rw-r--r--engines/made/database.cpp6
-rw-r--r--engines/made/pmvplayer.cpp15
-rw-r--r--engines/made/redreader.cpp16
-rw-r--r--engines/made/resource.cpp4
-rw-r--r--engines/made/screenfx.cpp7
-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/mads/action.cpp7
-rw-r--r--engines/mads/action.h4
-rw-r--r--engines/mads/animation.cpp26
-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.cpp47
-rw-r--r--engines/mads/audio.h5
-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.cpp9
-rw-r--r--engines/mads/dialogs.h4
-rw-r--r--engines/mads/dragonsphere/dragonsphere_scenes.cpp4
-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.cpp57
-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.cpp8
-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.cpp121
-rw-r--r--engines/mads/menu_views.h29
-rw-r--r--engines/mads/messages.cpp22
-rw-r--r--engines/mads/messages.h8
-rw-r--r--engines/mads/msurface.cpp38
-rw-r--r--engines/mads/msurface.h15
-rw-r--r--engines/mads/nebular/dialogs_nebular.cpp184
-rw-r--r--engines/mads/nebular/dialogs_nebular.h11
-rw-r--r--engines/mads/nebular/game_nebular.cpp126
-rw-r--r--engines/mads/nebular/game_nebular.h11
-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.cpp53
-rw-r--r--engines/mads/nebular/menu_nebular.h18
-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.cpp154
-rw-r--r--engines/mads/nebular/nebular_scenes6.h6
-rw-r--r--engines/mads/nebular/nebular_scenes7.cpp67
-rw-r--r--engines/mads/nebular/nebular_scenes7.h4
-rw-r--r--engines/mads/nebular/nebular_scenes8.cpp72
-rw-r--r--engines/mads/nebular/nebular_scenes8.h4
-rw-r--r--engines/mads/nebular/sound_nebular.cpp117
-rw-r--r--engines/mads/nebular/sound_nebular.h37
-rw-r--r--engines/mads/palette.cpp76
-rw-r--r--engines/mads/palette.h16
-rw-r--r--engines/mads/phantom/game_phantom.cpp4
-rw-r--r--engines/mads/phantom/game_phantom.h4
-rw-r--r--engines/mads/phantom/phantom_scenes.cpp4
-rw-r--r--engines/mads/phantom/phantom_scenes.h4
-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.cpp24
-rw-r--r--engines/mads/scene.h8
-rw-r--r--engines/mads/scene_data.cpp10
-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.cpp36
-rw-r--r--engines/mads/sound.h10
-rw-r--r--engines/mads/sprites.cpp55
-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/cursors.cpp6
-rw-r--r--engines/mohawk/myst.cpp12
-rw-r--r--engines/mohawk/myst_graphics.cpp165
-rw-r--r--engines/mohawk/myst_graphics.h27
-rw-r--r--engines/mohawk/myst_stacks/myst.cpp20
-rw-r--r--engines/mohawk/riven_external.cpp2
-rw-r--r--engines/mohawk/video.cpp42
-rw-r--r--engines/mohawk/video.h4
-rw-r--r--engines/mortevielle/actions.cpp6
-rw-r--r--engines/mortevielle/detection_tables.h2
-rw-r--r--engines/mortevielle/dialogs.cpp6
-rw-r--r--engines/mortevielle/graphics.cpp2
-rw-r--r--engines/mortevielle/mortevielle.h6
-rw-r--r--engines/mortevielle/outtext.cpp24
-rw-r--r--engines/mortevielle/utils.cpp82
-rw-r--r--engines/neverhood/console.cpp2
-rw-r--r--engines/neverhood/menumodule.cpp2
-rw-r--r--engines/neverhood/modules/module2400.cpp9
-rw-r--r--engines/neverhood/modules/module2700_sprites.cpp56
-rw-r--r--engines/neverhood/modules/module2800.cpp15
-rw-r--r--engines/neverhood/modules/module2800_sprites.cpp10
-rw-r--r--engines/neverhood/modules/module3000.cpp12
-rw-r--r--engines/neverhood/modules/module3000_sprites.cpp36
-rw-r--r--engines/neverhood/sound.cpp2
-rw-r--r--engines/pegasus/input.cpp2
-rw-r--r--engines/pegasus/menu.cpp4
-rw-r--r--engines/pegasus/pegasus.cpp2
-rw-r--r--engines/prince/animation.cpp6
-rw-r--r--engines/prince/animation.h2
-rw-r--r--engines/prince/archive.cpp24
-rw-r--r--engines/prince/archive.h1
-rw-r--r--engines/prince/cursor.h2
-rw-r--r--engines/prince/detection.cpp6
-rw-r--r--engines/prince/detection.h38
-rw-r--r--engines/prince/graphics.cpp2
-rw-r--r--engines/prince/graphics.h2
-rw-r--r--engines/prince/hero.cpp4
-rw-r--r--engines/prince/hero.h4
-rw-r--r--engines/prince/mhwanh.cpp4
-rw-r--r--engines/prince/mob.h2
-rw-r--r--engines/prince/object.cpp2
-rw-r--r--engines/prince/object.h2
-rw-r--r--engines/prince/prince.cpp219
-rw-r--r--engines/prince/prince.h20
-rw-r--r--engines/prince/pscr.h2
-rw-r--r--engines/prince/resource.h6
-rw-r--r--engines/prince/saveload.cpp33
-rw-r--r--engines/prince/script.cpp33
-rw-r--r--engines/prince/script.h3
-rw-r--r--engines/queen/logic.cpp6
-rw-r--r--engines/queen/talk.cpp12
-rw-r--r--engines/queen/walk.cpp4
-rw-r--r--engines/saga/actor.h1
-rw-r--r--engines/saga/introproc_ite.cpp2
-rw-r--r--engines/saga/saveload.cpp29
-rw-r--r--engines/saga/scene.cpp13
-rw-r--r--engines/saga/scene.h3
-rw-r--r--engines/saga/sfuncs.cpp4
-rw-r--r--engines/sci/console.cpp443
-rw-r--r--engines/sci/console.h6
-rw-r--r--engines/sci/detection.cpp49
-rw-r--r--engines/sci/detection_tables.h73
-rw-r--r--engines/sci/engine/file.cpp3
-rw-r--r--engines/sci/engine/kernel.cpp45
-rw-r--r--engines/sci/engine/kernel.h6
-rw-r--r--engines/sci/engine/kernel_tables.h4
-rw-r--r--engines/sci/engine/kevent.cpp13
-rw-r--r--engines/sci/engine/kfile.cpp20
-rw-r--r--engines/sci/engine/kgraphics.cpp43
-rw-r--r--engines/sci/engine/kmovement.cpp27
-rw-r--r--engines/sci/engine/kparse.cpp3
-rw-r--r--engines/sci/engine/kstring.cpp10
-rw-r--r--engines/sci/engine/kvideo.cpp2
-rw-r--r--engines/sci/engine/savegame.cpp86
-rw-r--r--engines/sci/engine/savegame.h8
-rw-r--r--engines/sci/engine/script.cpp403
-rw-r--r--engines/sci/engine/script.h36
-rw-r--r--engines/sci/engine/script_patches.cpp804
-rw-r--r--engines/sci/engine/script_patches.h11
-rw-r--r--engines/sci/engine/state.cpp119
-rw-r--r--engines/sci/engine/state.h4
-rw-r--r--engines/sci/engine/vm.cpp18
-rw-r--r--engines/sci/engine/workarounds.cpp954
-rw-r--r--engines/sci/engine/workarounds.h2
-rw-r--r--engines/sci/event.cpp2
-rw-r--r--engines/sci/graphics/controls16.cpp12
-rw-r--r--engines/sci/graphics/controls16.h6
-rw-r--r--engines/sci/graphics/cursor.cpp8
-rw-r--r--engines/sci/graphics/font.cpp8
-rw-r--r--engines/sci/graphics/font.h4
-rw-r--r--engines/sci/graphics/frameout.cpp10
-rw-r--r--engines/sci/graphics/paint16.cpp25
-rw-r--r--engines/sci/graphics/paint16.h2
-rw-r--r--engines/sci/graphics/paint32.cpp2
-rw-r--r--engines/sci/graphics/palette.cpp87
-rw-r--r--engines/sci/graphics/palette.h6
-rw-r--r--engines/sci/graphics/picture.cpp88
-rw-r--r--engines/sci/graphics/portrait.cpp105
-rw-r--r--engines/sci/graphics/portrait.h2
-rw-r--r--engines/sci/graphics/ports.cpp16
-rw-r--r--engines/sci/graphics/screen.cpp399
-rw-r--r--engines/sci/graphics/screen.h95
-rw-r--r--engines/sci/graphics/text16.cpp225
-rw-r--r--engines/sci/graphics/text16.h15
-rw-r--r--engines/sci/graphics/transitions.cpp6
-rw-r--r--engines/sci/graphics/view.cpp3
-rw-r--r--engines/sci/module.mk4
-rw-r--r--engines/sci/parser/vocabulary.cpp82
-rw-r--r--engines/sci/parser/vocabulary.h12
-rw-r--r--engines/sci/resource.cpp55
-rw-r--r--engines/sci/resource.h18
-rw-r--r--engines/sci/resource_audio.cpp6
-rw-r--r--engines/sci/sci.cpp23
-rw-r--r--engines/sci/sci.h16
-rw-r--r--engines/sci/sound/midiparser_sci.cpp19
-rw-r--r--engines/sci/sound/music.cpp114
-rw-r--r--engines/sci/sound/music.h16
-rw-r--r--engines/sci/sound/soundcmd.cpp46
-rw-r--r--engines/sci/sound/soundcmd.h2
-rw-r--r--engines/scumm/actor.cpp725
-rw-r--r--engines/scumm/actor.h49
-rw-r--r--engines/scumm/boxes.cpp24
-rw-r--r--engines/scumm/cdda.cpp2
-rw-r--r--engines/scumm/debugger.cpp2
-rw-r--r--engines/scumm/detection.cpp5
-rw-r--r--engines/scumm/detection_tables.h21
-rw-r--r--engines/scumm/dialogs.cpp6
-rw-r--r--engines/scumm/file.cpp26
-rw-r--r--engines/scumm/help.cpp16
-rw-r--r--engines/scumm/input.cpp12
-rw-r--r--engines/scumm/resource_v2.cpp10
-rw-r--r--engines/scumm/room.cpp9
-rw-r--r--engines/scumm/saveload.cpp9
-rw-r--r--engines/scumm/saveload.h2
-rw-r--r--engines/scumm/script.cpp6
-rw-r--r--engines/scumm/script_v0.cpp34
-rw-r--r--engines/scumm/script_v2.cpp9
-rw-r--r--engines/scumm/script_v5.cpp4
-rw-r--r--engines/scumm/script_v6.cpp6
-rw-r--r--engines/scumm/scumm-md5.h54
-rw-r--r--engines/scumm/scumm.cpp65
-rw-r--r--engines/scumm/scumm.h6
-rw-r--r--engines/scumm/scumm_v0.h8
-rw-r--r--engines/scumm/smush/smush_player.cpp5
-rw-r--r--engines/scumm/sound.cpp4
-rw-r--r--engines/scumm/vars.cpp2
-rw-r--r--engines/scumm/verbs.cpp57
-rw-r--r--engines/sherlock/animation.cpp188
-rw-r--r--engines/sherlock/animation.h83
-rw-r--r--engines/sherlock/configure.engine3
-rw-r--r--engines/sherlock/debugger.cpp59
-rw-r--r--engines/sherlock/debugger.h53
-rw-r--r--engines/sherlock/decompress.cpp128
-rw-r--r--engines/sherlock/detection.cpp241
-rw-r--r--engines/sherlock/detection_tables.h120
-rw-r--r--engines/sherlock/events.cpp249
-rw-r--r--engines/sherlock/events.h171
-rw-r--r--engines/sherlock/inventory.cpp471
-rw-r--r--engines/sherlock/inventory.h171
-rw-r--r--engines/sherlock/journal.cpp1174
-rw-r--r--engines/sherlock/journal.h139
-rw-r--r--engines/sherlock/map.cpp565
-rw-r--r--engines/sherlock/map.h180
-rw-r--r--engines/sherlock/module.mk41
-rw-r--r--engines/sherlock/music.cpp360
-rw-r--r--engines/sherlock/music.h106
-rw-r--r--engines/sherlock/objects.cpp1166
-rw-r--r--engines/sherlock/objects.h446
-rw-r--r--engines/sherlock/people.cpp712
-rw-r--r--engines/sherlock/people.h197
-rw-r--r--engines/sherlock/resources.cpp499
-rw-r--r--engines/sherlock/resources.h217
-rw-r--r--engines/sherlock/saveload.cpp484
-rw-r--r--engines/sherlock/saveload.h147
-rw-r--r--engines/sherlock/scalpel/darts.cpp557
-rw-r--r--engines/sherlock/scalpel/darts.h136
-rw-r--r--engines/sherlock/scalpel/drivers/adlib.cpp639
-rw-r--r--engines/sherlock/scalpel/drivers/mididriver.h37
-rw-r--r--engines/sherlock/scalpel/scalpel.cpp920
-rw-r--r--engines/sherlock/scalpel/scalpel.h117
-rw-r--r--engines/sherlock/scalpel/scalpel_scene.cpp381
-rw-r--r--engines/sherlock/scalpel/scalpel_scene.h61
-rw-r--r--engines/sherlock/scalpel/scalpel_user_interface.cpp2284
-rw-r--r--engines/sherlock/scalpel/scalpel_user_interface.h227
-rw-r--r--engines/sherlock/scalpel/settings.cpp341
-rw-r--r--engines/sherlock/scalpel/settings.h63
-rw-r--r--engines/sherlock/scalpel/tsage/logo.cpp695
-rw-r--r--engines/sherlock/scalpel/tsage/logo.h223
-rw-r--r--engines/sherlock/scalpel/tsage/resources.cpp373
-rw-r--r--engines/sherlock/scalpel/tsage/resources.h139
-rw-r--r--engines/sherlock/scene.cpp1329
-rw-r--r--engines/sherlock/scene.h323
-rw-r--r--engines/sherlock/screen.cpp508
-rw-r--r--engines/sherlock/screen.h271
-rw-r--r--engines/sherlock/sherlock.cpp266
-rw-r--r--engines/sherlock/sherlock.h207
-rw-r--r--engines/sherlock/sound.cpp228
-rw-r--r--engines/sherlock/sound.h103
-rw-r--r--engines/sherlock/surface.cpp201
-rw-r--r--engines/sherlock/surface.h158
-rw-r--r--engines/sherlock/talk.cpp2135
-rw-r--r--engines/sherlock/talk.h408
-rw-r--r--engines/sherlock/tattoo/tattoo.cpp81
-rw-r--r--engines/sherlock/tattoo/tattoo.h71
-rw-r--r--engines/sherlock/tattoo/tattoo_scene.cpp401
-rw-r--r--engines/sherlock/tattoo/tattoo_scene.h77
-rw-r--r--engines/sherlock/tattoo/tattoo_user_interface.cpp150
-rw-r--r--engines/sherlock/tattoo/tattoo_user_interface.h83
-rw-r--r--engines/sherlock/user_interface.cpp56
-rw-r--r--engines/sherlock/user_interface.h130
-rw-r--r--engines/sword1/console.cpp2
-rw-r--r--engines/sword1/sound.cpp2
-rw-r--r--engines/sword25/gfx/renderobjectmanager.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/sword25.cpp1
-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/lapi.cpp3
-rw-r--r--engines/sword25/util/lua/liolib.cpp2
-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/tinsel.cpp15
-rw-r--r--engines/tony/game.cpp4
-rw-r--r--engines/tony/gfxcore.cpp119
-rw-r--r--engines/tony/mpal/lzo.cpp2
-rw-r--r--engines/tony/mpal/mpal.cpp4
-rw-r--r--engines/tony/window.cpp14
-rw-r--r--engines/toon/anim.cpp28
-rw-r--r--engines/toon/character.cpp7
-rw-r--r--engines/toon/font.cpp6
-rw-r--r--engines/toon/state.cpp2
-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.mk5
-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/ringworld2/ringworld2_airduct.cpp909
-rw-r--r--engines/tsage/ringworld2/ringworld2_airduct.h89
-rw-r--r--engines/tsage/ringworld2/ringworld2_logic.cpp2
-rw-r--r--engines/tsage/ringworld2/ringworld2_outpost.cpp4
-rw-r--r--engines/tsage/ringworld2/ringworld2_outpost.h3
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes0.cpp2
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes1.cpp2670
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes1.h184
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes3.cpp2
-rw-r--r--engines/tsage/ringworld2/ringworld2_vampire.cpp1821
-rw-r--r--engines/tsage/ringworld2/ringworld2_vampire.h179
-rw-r--r--engines/tsage/sherlock/sherlock_logo.cpp356
-rw-r--r--engines/tsage/sherlock/sherlock_logo.h78
-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_engine.cpp3
-rw-r--r--engines/wintermute/base/base_engine.h9
-rw-r--r--engines/wintermute/base/base_file_manager.cpp2
-rw-r--r--engines/wintermute/base/base_game.cpp5
-rw-r--r--engines/wintermute/base/base_game.h2
-rw-r--r--engines/wintermute/base/base_game_settings.cpp5
-rw-r--r--engines/wintermute/base/base_game_settings.h1
-rw-r--r--engines/wintermute/base/base_keyboard_state.cpp119
-rw-r--r--engines/wintermute/base/base_keyboard_state.h2
-rw-r--r--engines/wintermute/base/base_sprite.cpp15
-rw-r--r--engines/wintermute/base/base_string_table.cpp9
-rw-r--r--engines/wintermute/base/base_string_table.h1
-rw-r--r--engines/wintermute/debugger.cpp2
-rw-r--r--engines/wintermute/detection.cpp6
-rw-r--r--engines/wintermute/detection_tables.h1552
-rw-r--r--engines/wintermute/game_description.h53
-rw-r--r--engines/wintermute/math/rect32.h2
-rw-r--r--engines/wintermute/module.mk2
-rw-r--r--engines/wintermute/video/subtitle_card.cpp56
-rw-r--r--engines/wintermute/video/subtitle_card.h53
-rw-r--r--engines/wintermute/video/video_subtitler.cpp266
-rw-r--r--engines/wintermute/video/video_subtitler.h53
-rw-r--r--engines/wintermute/video/video_theora_player.cpp27
-rw-r--r--engines/wintermute/video/video_theora_player.h6
-rw-r--r--engines/wintermute/wintermute.cpp4
-rw-r--r--engines/wintermute/wintermute.h5
-rw-r--r--engines/zvision/animation/rlf_animation.cpp331
-rw-r--r--engines/zvision/animation/rlf_animation.h163
-rw-r--r--engines/zvision/configure.engine2
-rw-r--r--engines/zvision/core/clock.cpp (renamed from engines/zvision/utility/clock.cpp)3
-rw-r--r--engines/zvision/core/clock.h (renamed from engines/zvision/utility/clock.h)11
-rw-r--r--engines/zvision/core/console.cpp278
-rw-r--r--engines/zvision/core/console.h9
-rw-r--r--engines/zvision/core/events.cpp438
-rw-r--r--engines/zvision/core/save_manager.cpp206
-rw-r--r--engines/zvision/cursors/cursor.cpp94
-rw-r--r--engines/zvision/cursors/cursor_manager.cpp152
-rw-r--r--engines/zvision/detection.cpp382
-rw-r--r--engines/zvision/detection.h1
-rw-r--r--engines/zvision/file/lzss_read_stream.cpp (renamed from engines/zvision/utility/lzss_read_stream.cpp)20
-rw-r--r--engines/zvision/file/lzss_read_stream.h (renamed from engines/zvision/utility/lzss_read_stream.h)3
-rw-r--r--engines/zvision/file/save_manager.cpp292
-rw-r--r--engines/zvision/file/save_manager.h (renamed from engines/zvision/core/save_manager.h)31
-rw-r--r--engines/zvision/file/search_manager.cpp285
-rw-r--r--engines/zvision/file/search_manager.h70
-rw-r--r--engines/zvision/file/zfs_archive.cpp (renamed from engines/zvision/archives/zfs_archive.cpp)16
-rw-r--r--engines/zvision/file/zfs_archive.h (renamed from engines/zvision/archives/zfs_archive.h)5
-rw-r--r--engines/zvision/fonts/truetype_font.cpp113
-rw-r--r--engines/zvision/graphics/cursors/cursor.cpp96
-rw-r--r--engines/zvision/graphics/cursors/cursor.h (renamed from engines/zvision/cursors/cursor.h)28
-rw-r--r--engines/zvision/graphics/cursors/cursor_manager.cpp158
-rw-r--r--engines/zvision/graphics/cursors/cursor_manager.h (renamed from engines/zvision/cursors/cursor_manager.h)84
-rw-r--r--engines/zvision/graphics/effects/fog.cpp173
-rw-r--r--engines/zvision/graphics/effects/fog.h53
-rw-r--r--engines/zvision/graphics/effects/light.cpp109
-rw-r--r--engines/zvision/graphics/effects/light.h53
-rw-r--r--engines/zvision/graphics/effects/wave.cpp145
-rw-r--r--engines/zvision/graphics/effects/wave.h51
-rw-r--r--engines/zvision/graphics/graphics_effect.h83
-rw-r--r--engines/zvision/graphics/render_manager.cpp1333
-rw-r--r--engines/zvision/graphics/render_manager.h373
-rw-r--r--engines/zvision/graphics/render_table.cpp96
-rw-r--r--engines/zvision/graphics/render_table.h18
-rw-r--r--engines/zvision/module.mk45
-rw-r--r--engines/zvision/scripting/actions.cpp1011
-rw-r--r--engines/zvision/scripting/actions.h335
-rw-r--r--engines/zvision/scripting/control.cpp64
-rw-r--r--engines/zvision/scripting/control.h111
-rw-r--r--engines/zvision/scripting/controls/animation_control.cpp263
-rw-r--r--engines/zvision/scripting/controls/fist_control.cpp304
-rw-r--r--engines/zvision/scripting/controls/fist_control.h84
-rw-r--r--engines/zvision/scripting/controls/hotmov_control.cpp188
-rw-r--r--engines/zvision/scripting/controls/hotmov_control.h61
-rw-r--r--engines/zvision/scripting/controls/input_control.cpp221
-rw-r--r--engines/zvision/scripting/controls/input_control.h39
-rw-r--r--engines/zvision/scripting/controls/lever_control.cpp227
-rw-r--r--engines/zvision/scripting/controls/lever_control.h24
-rw-r--r--engines/zvision/scripting/controls/paint_control.cpp219
-rw-r--r--engines/zvision/scripting/controls/paint_control.h92
-rw-r--r--engines/zvision/scripting/controls/push_toggle_control.cpp111
-rw-r--r--engines/zvision/scripting/controls/push_toggle_control.h22
-rw-r--r--engines/zvision/scripting/controls/safe_control.cpp180
-rw-r--r--engines/zvision/scripting/controls/safe_control.h65
-rw-r--r--engines/zvision/scripting/controls/save_control.cpp123
-rw-r--r--engines/zvision/scripting/controls/save_control.h55
-rw-r--r--engines/zvision/scripting/controls/slot_control.cpp219
-rw-r--r--engines/zvision/scripting/controls/slot_control.h84
-rw-r--r--engines/zvision/scripting/controls/titler_control.cpp108
-rw-r--r--engines/zvision/scripting/controls/titler_control.h55
-rw-r--r--engines/zvision/scripting/effects/animation_effect.cpp217
-rw-r--r--engines/zvision/scripting/effects/animation_effect.h (renamed from engines/zvision/scripting/controls/animation_control.h)72
-rw-r--r--engines/zvision/scripting/effects/distort_effect.cpp104
-rw-r--r--engines/zvision/scripting/effects/distort_effect.h63
-rw-r--r--engines/zvision/scripting/effects/music_effect.cpp296
-rw-r--r--engines/zvision/scripting/effects/music_effect.h137
-rw-r--r--engines/zvision/scripting/effects/region_effect.cpp56
-rw-r--r--engines/zvision/scripting/effects/region_effect.h57
-rw-r--r--engines/zvision/scripting/effects/syncsound_effect.cpp85
-rw-r--r--engines/zvision/scripting/effects/syncsound_effect.h56
-rw-r--r--engines/zvision/scripting/effects/timer_effect.cpp (renamed from engines/zvision/scripting/controls/timer_node.cpp)42
-rw-r--r--engines/zvision/scripting/effects/timer_effect.h (renamed from engines/zvision/scripting/controls/timer_node.h)14
-rw-r--r--engines/zvision/scripting/effects/ttytext_effect.cpp172
-rw-r--r--engines/zvision/scripting/effects/ttytext_effect.h73
-rw-r--r--engines/zvision/scripting/inventory.cpp122
-rw-r--r--engines/zvision/scripting/menu.cpp761
-rw-r--r--engines/zvision/scripting/menu.h119
-rw-r--r--engines/zvision/scripting/puzzle.h14
-rw-r--r--engines/zvision/scripting/scr_file_handling.cpp373
-rw-r--r--engines/zvision/scripting/script_manager.cpp958
-rw-r--r--engines/zvision/scripting/script_manager.h238
-rw-r--r--engines/zvision/scripting/scripting_effect.h124
-rw-r--r--engines/zvision/sound/midi.cpp91
-rw-r--r--engines/zvision/sound/midi.h59
-rw-r--r--engines/zvision/sound/zork_raw.cpp264
-rw-r--r--engines/zvision/sound/zork_raw.h96
-rw-r--r--engines/zvision/strings/string_manager.cpp255
-rw-r--r--engines/zvision/text/string_manager.cpp70
-rw-r--r--engines/zvision/text/string_manager.h (renamed from engines/zvision/strings/string_manager.h)33
-rw-r--r--engines/zvision/text/subtitles.cpp115
-rw-r--r--engines/zvision/text/subtitles.h (renamed from engines/zvision/subtitles/subtitles.h)28
-rw-r--r--engines/zvision/text/text.cpp578
-rw-r--r--engines/zvision/text/text.h93
-rw-r--r--engines/zvision/text/truetype_font.cpp265
-rw-r--r--engines/zvision/text/truetype_font.h (renamed from engines/zvision/fonts/truetype_font.h)73
-rw-r--r--engines/zvision/utility/single_value_container.cpp348
-rw-r--r--engines/zvision/utility/single_value_container.h183
-rw-r--r--engines/zvision/utility/utility.cpp237
-rw-r--r--engines/zvision/utility/utility.h114
-rw-r--r--engines/zvision/video/rlf_decoder.cpp313
-rw-r--r--engines/zvision/video/rlf_decoder.h134
-rw-r--r--engines/zvision/video/video.cpp164
-rw-r--r--engines/zvision/video/zork_avi_decoder.cpp29
-rw-r--r--engines/zvision/video/zork_avi_decoder.h28
-rw-r--r--engines/zvision/zvision.cpp349
-rw-r--r--engines/zvision/zvision.h182
-rw-r--r--graphics/VectorRenderer.h2
-rw-r--r--graphics/VectorRendererSpec.cpp52
-rw-r--r--graphics/VectorRendererSpec.h2
-rw-r--r--graphics/fonts/ttf.cpp6
-rw-r--r--graphics/surface.h2
-rw-r--r--graphics/transform_struct.h2
-rw-r--r--graphics/transform_tools.h2
-rw-r--r--gui/EventRecorder.cpp1
-rw-r--r--gui/Tooltip.cpp2
-rw-r--r--gui/Tooltip.h33
-rw-r--r--gui/about.cpp4
-rw-r--r--gui/browser_osx.mm4
-rw-r--r--gui/credits.h21
-rw-r--r--gui/debugger.cpp109
-rw-r--r--gui/debugger.h4
-rw-r--r--gui/dialog.cpp2
-rw-r--r--gui/saveload-dialog.cpp17
-rw-r--r--gui/themes/scummmodern.zipbin1489429 -> 1485886 bytes
-rw-r--r--gui/themes/scummmodern/scummmodern_layout.stx4
-rw-r--r--gui/themes/translations.datbin468258 -> 470115 bytes
-rw-r--r--gui/widgets/edittext.cpp2
-rw-r--r--gui/widgets/tab.h2
-rw-r--r--icons/scummvm.infobin17326 -> 23078 bytes
-rw-r--r--icons/scummvm_drawer.infobin20738 -> 22916 bytes
-rw-r--r--image/codecs/cinepak.cpp557
-rw-r--r--image/codecs/cinepak.h18
-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/mjpeg.cpp2
-rw-r--r--image/codecs/mpeg.h2
-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--image/iff.cpp2
-rw-r--r--image/image_decoder.h2
-rw-r--r--po/be_BY.po2
-rw-r--r--po/ca_ES.po2
-rw-r--r--po/cs_CZ.po2
-rw-r--r--po/da_DA.po2
-rw-r--r--po/de_DE.po2
-rw-r--r--po/es_ES.po2
-rw-r--r--po/eu.po2
-rw-r--r--po/fi_FI.po2
-rw-r--r--po/fr_FR.po2
-rw-r--r--po/gl_ES.po2
-rw-r--r--po/hu_HU.po2
-rw-r--r--po/it_IT.po2
-rw-r--r--po/nb_NO.po2
-rw-r--r--po/nl_NL.po102
-rw-r--r--po/nn_NO.po2
-rw-r--r--po/pl_PL.po2
-rw-r--r--po/pt_BR.po2
-rw-r--r--po/ru_RU.po2
-rw-r--r--po/scummvm.pot2
-rw-r--r--po/se_SE.po2
-rw-r--r--po/uk_UA.po2
-rw-r--r--ports.mk9
-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.cpp397
-rw-r--r--video/avi_decoder.h25
-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
994 files changed, 78030 insertions, 30509 deletions
diff --git a/AUTHORS b/AUTHORS
index 37067e5e04..370f4e9401 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -257,9 +257,12 @@ ScummVM Team
Wintermute:
Einar Johan T. Somaaen
+ Tobia Tesan
ZVision:
Adrian Astley
+ Filippos Karapetis
+ Anton Yarcev
Backend Teams
-------------
@@ -523,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
@@ -556,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
@@ -651,7 +661,7 @@ Special thanks to
repository, planet and doxygen sites as well as tons
of HD space
DOSBox Team - For their awesome OPL2 and OPL3 emulator
- Yusuke Kamiyamane - For contributing some GUI icons
+ Yusuke Kamiyamane - For contributing some GUI icons
Till Kresslein - For design of modern ScummVM GUI
Jezar - For his freeverb filter implementation
Jim Leiterman - Various info on his FM-TOWNS/Marty SCUMM ports
@@ -700,8 +710,8 @@ Special thanks to
of Dreamweb and for their tremendous support.
Janusz Wisniewski and Miroslaw Liminowicz from Laboratorium Komputerowe
- Avalon for providing full source code for Soltys and letting us
- redistribute the game.
+ Avalon for providing full source code for Soltys and Sfinx and letting us
+ redistribute the games.
Jan Nedoma for providing the sources to the Wintermute-engine, and for his
support while porting the engine to ScummVM.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000000..3a6672b0cb
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,12 @@
+Thank you for considering contributing to ScummVM.
+
+Please make sure to read our guidelines for contributions on our
+[wiki](http://wiki.scummvm.org/index.php/Developer_Central). In particular:
+
+* [Coding style](http://wiki.scummvm.org/index.php/Code_Formatting_Conventions)
+* [Portability](http://wiki.scummvm.org/index.php/Coding_Conventions)
+* [Commit message style](http://wiki.scummvm.org/index.php/Commit_Guidelines)
+* License: GPLv2+
+
+If you have any questions about code, style, procedure, or anything else, feel
+free to contact us on our mailing list at scummvm-devel@lists.sourceforge.net.
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 bb23bb37ff..1422ec2818 100644
--- a/NEWS
+++ b/NEWS
@@ -2,14 +2,43 @@ For a more comprehensive changelog of the latest experimental code, see:
https://github.com/scummvm/scummvm/commits/
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.
+
+ 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.
-Broken Sword 1:
+ Broken Sword 1:
- Fix speech endianness detection on big endian systems for the mac
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.
+ 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.
+
1.7.0 (2014-07-21)
New Games:
- Added support for Chivalry is Not Dead.
diff --git a/README b/README
index 0a256b39f3..7116536222 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]
+
+ZVISION 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,10 +528,10 @@ 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
+Swedish (SW) and English US (U). ScummVM requires just the PRG section
to run and not the whole ROM.
In order to get the game working, you will have to strip out the first
@@ -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.
@@ -1441,7 +1570,7 @@ The platforms that currently have a different default directory are:
<windir>\Profiles\username\Application Data\ScummVM\Saved games\
Saved games are stored under a hidden area in Windows NT4/2000/XP/Vista/7,
-which can be accessed by running "%APPDATA%\ScummVM\Saved Games\" or by
+which can be accessed by running "%APPDATA%\ScummVM\Saved Games\" or by
enabling hidden files in Windows Explorer.
Note for Windows NT4/2000/XP/Vista/7 users: The default saved games location
@@ -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/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/fmopl.cpp b/audio/fmopl.cpp
index c18e544410..30229ea6bf 100644
--- a/audio/fmopl.cpp
+++ b/audio/fmopl.cpp
@@ -80,6 +80,12 @@ 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.
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/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/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/dinguxsdl/dinguxsdl-events.cpp b/backends/events/dinguxsdl/dinguxsdl-events.cpp
index 6f9f2a7748..cc15f2666c 100644
--- a/backends/events/dinguxsdl/dinguxsdl-events.cpp
+++ b/backends/events/dinguxsdl/dinguxsdl-events.cpp
@@ -26,18 +26,48 @@
#include "backends/events/dinguxsdl/dinguxsdl-events.h"
+#ifndef GCW0
#define PAD_UP SDLK_UP
#define PAD_DOWN SDLK_DOWN
#define PAD_LEFT SDLK_LEFT
#define PAD_RIGHT SDLK_RIGHT
#define BUT_A SDLK_LCTRL
#define BUT_B SDLK_LALT
-#define BUT_X SDLK_SPACE
-#define BUT_Y SDLK_LSHIFT
+#define BUT_X SDLK_SPACE // BUT_Y in GCW0
+#define BUT_Y SDLK_LSHIFT // BUT_X in GCW0
#define BUT_SELECT SDLK_ESCAPE
#define BUT_START SDLK_RETURN
#define TRIG_L SDLK_TAB
#define TRIG_R SDLK_BACKSPACE
+#else // GCW0
+
+/******
+ * GCW0 keymap
+ * Dingoo button
+ * A -> Left Button BUT_Y
+ * B -> right button BUT_B
+ * X -> ' ' BUT_A '0'
+ * Y -> '.' BUT_X
+ * Select -> ESC TRIG_R
+ * Start -> F5 TRIG_L
+ * L -> Shift BUT_START
+ * R -> VK BUT_SELECT
+ */
+
+#define PAD_UP SDLK_UP
+#define PAD_DOWN SDLK_DOWN
+#define PAD_LEFT SDLK_LEFT
+#define PAD_RIGHT SDLK_RIGHT
+#define BUT_A SDLK_LSHIFT
+#define BUT_B SDLK_LALT
+#define BUT_X SDLK_SPACE
+#define BUT_Y SDLK_LCTRL
+#define BUT_SELECT SDLK_BACKSPACE
+#define BUT_START SDLK_TAB
+#define TRIG_L SDLK_RETURN
+#define TRIG_R SDLK_ESCAPE
+
+#endif
bool DINGUXSdlEventSource::remapKey(SDL_Event &ev, Common::Event &event) {
if (ev.key.keysym.sym == PAD_UP) {
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 cbd06e9161..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 {
@@ -489,7 +525,7 @@ void OpenGLGraphicsManager::warpMouse(int x, int y) {
if (!_overlay) {
return;
}
-
+
// It might be confusing that we actually have to handle something
// here when the overlay is visible. This is because for very small
// resolutions we have a minimal overlay size and have to adjust
@@ -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) {
@@ -1044,8 +1093,11 @@ void OpenGLGraphicsManager::recalculateDisplayArea() {
}
// We center the screen in the middle for now.
- _displayX = (_outputScreenWidth - _displayWidth ) / 2;
- _displayY = (_outputScreenHeight - _displayHeight) / 2;
+ _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 c998f3d1f1..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) {
@@ -282,7 +327,7 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
if (!_fullscreenVideoModes.empty()) {
VideoModeArray::const_iterator i = _fullscreenVideoModes.end();
--i;
-
+
_desiredFullscreenWidth = i->width;
_desiredFullscreenHeight = i->height;
} else {
@@ -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/keymapper/action.h b/backends/keymapper/action.h
index ed4bb86ce6..17b1153c77 100644
--- a/backends/keymapper/action.h
+++ b/backends/keymapper/action.h
@@ -37,7 +37,7 @@ namespace Common {
struct HardwareInput;
class Keymap;
-#define ACTION_ID_SIZE (4)
+#define ACTION_ID_SIZE (5)
struct KeyActionEntry {
const KeyState ks;
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/asset-archive.cpp b/backends/platform/android/asset-archive.cpp
index 52c2c084bd..6680081c16 100644
--- a/backends/platform/android/asset-archive.cpp
+++ b/backends/platform/android/asset-archive.cpp
@@ -295,7 +295,6 @@ AssetFdReadStream::AssetFdReadStream(JNIEnv *env, jobject assetfd) :
jclass cls = env->GetObjectClass(_assetfd);
MID_close = env->GetMethodID(cls, "close", "()V");
assert(MID_close);
- env->DeleteLocalRef(cls);
jmethodID MID_getStartOffset =
env->GetMethodID(cls, "getStartOffset", "()J");
@@ -321,6 +320,8 @@ AssetFdReadStream::AssetFdReadStream(JNIEnv *env, jobject assetfd) :
_fd = env->GetIntField(javafd, FID_descriptor);
env->DeleteLocalRef(javafd);
+
+ env->DeleteLocalRef(cls);
}
AssetFdReadStream::~AssetFdReadStream() {
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/dingux/dingux.mk b/backends/platform/dingux/dingux.mk
index 48a9347143..1333e89ff8 100644
--- a/backends/platform/dingux/dingux.mk
+++ b/backends/platform/dingux/dingux.mk
@@ -1,6 +1,7 @@
DINGUX_EXE_STRIPPED := scummvm_stripped$(EXEEXT)
bundle_name = dingux-dist/scummvm
+gcw0_bundle = gcw0-opk
all: $(DINGUX_EXE_STRIPPED)
@@ -30,3 +31,37 @@ endif
$(CP) $(srcdir)/backends/platform/dingux/scummvm.gpe $(bundle_name)/
$(CP) $(srcdir)/backends/platform/dingux/README.DINGUX $(bundle_name)/
$(CP) $(srcdir)/backends/platform/dingux/scummvm.png $(bundle_name)/
+
+# Special target for generationg GCW-Zero OPK bundle
+$(gcw0_bundle): all
+ $(MKDIR) $(gcw0_bundle)
+ $(CP) $(DIST_FILES_DOCS) $(gcw0_bundle)/
+ $(MKDIR) $(gcw0_bundle)/themes
+ $(CP) $(DIST_FILES_THEMES) $(gcw0_bundle)/themes/
+ifdef DIST_FILES_ENGINEDATA
+ $(MKDIR) $(gcw0_bundle)/engine-data
+ $(CP) $(DIST_FILES_ENGINEDATA) $(gcw0_bundle)/engine-data/
+endif
+ifdef DYNAMIC_MODULES
+ $(MKDIR) $(gcw0_bundle)/plugins
+ $(CP) $(PLUGINS) $(gcw0_bundle)/plugins/
+endif
+ $(CP) $(EXECUTABLE) $(gcw0_bundle)/scummvm
+
+ $(CP) $(srcdir)/backends/vkeybd/packs/vkeybd_default.zip $(gcw0_bundle)/
+ $(CP) $(srcdir)/backends/vkeybd/packs/vkeybd_small.zip $(gcw0_bundle)/
+
+ $(CP) $(srcdir)/dists/gcw0/scummvm.png $(gcw0_bundle)/
+ $(CP) $(srcdir)/dists/gcw0/default.gcw0.desktop $(gcw0_bundle)/
+ $(CP) $(srcdir)/dists/gcw0/scummvmrc $(gcw0_bundle)/
+ $(CP) $(srcdir)/dists/gcw0/scummvm.sh $(gcw0_bundle)/
+
+gcw0-opk-unstripped: $(gcw0_bundle)
+ $(CP) $(PLUGINS) $(gcw0_bundle)/plugins/
+ $(CP) $(EXECUTABLE) $(gcw0_bundle)/scummvm
+ ./dists/gcw0/opk_make.sh -d $(gcw0_bundle) -o scummvm
+
+gcw-opk: $(gcw0_bundle)
+ $(STRIP) $(gcw0_bundle)/plugins/*
+ $(STRIP) $(gcw0_bundle)/scummvm
+ ./dists/gcw0/opk_make.sh -d $(gcw0_bundle) -o scummvm
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 41610dc0c7..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() {
@@ -390,7 +408,7 @@ Common::String OSystem_SDL::getSystemLanguage() const {
#else // WIN32
// Activating current locale settings
const Common::String locale = setlocale(LC_ALL, "");
-
+
// Restore default C locale to prevent issues with
// portability of sscanf(), atof(), etc.
// See bug #3615148
@@ -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/inventory/inventory_manager.h b/backends/platform/sdl/win32/win32-window.h
index f9d2ff294a..3bda697bc7 100644
--- a/engines/zvision/inventory/inventory_manager.h
+++ b/backends/platform/sdl/win32/win32-window.h
@@ -20,9 +20,18 @@
*
*/
-#ifndef ZVISION_INVENTORY_MANAGER_H
-#define ZVISION_INVENTORY_MANAGER_H
+#ifndef BACKENDS_PLATFORM_SDL_WIN32_WIN32_WINDOW_H
+#define BACKENDS_PLATFORM_SDL_WIN32_WIN32_WINDOW_H
-// TODO: Implement InventoryManager
+#ifdef WIN32
+
+#include "backends/platform/sdl/sdl-window.h"
+
+class SdlWindow_Win32 : public SdlWindow {
+public:
+ virtual void setupIcon();
+};
+
+#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/wii/osystem_events.cpp b/backends/platform/wii/osystem_events.cpp
index 0563639de3..13f5d1fbe0 100644
--- a/backends/platform/wii/osystem_events.cpp
+++ b/backends/platform/wii/osystem_events.cpp
@@ -70,73 +70,73 @@
#endif
#ifdef USE_WII_KBD
-static int keymap[][2] = {
- { KS_Return, Common::KEYCODE_RETURN },
- { KS_Up, Common::KEYCODE_UP },
- { KS_Down, Common::KEYCODE_DOWN },
- { KS_Left, Common::KEYCODE_LEFT },
- { KS_Right, Common::KEYCODE_RIGHT },
- { KS_Shift_L, Common::KEYCODE_LSHIFT },
- { KS_Shift_R, Common::KEYCODE_RSHIFT },
- { KS_Control_L, Common::KEYCODE_LCTRL },
- { KS_Control_R, Common::KEYCODE_RCTRL },
- { KS_Alt_L, Common::KEYCODE_LALT },
- { KS_Alt_R, Common::KEYCODE_RALT },
- { KS_Meta_L, Common::KEYCODE_LMETA },
- { KS_Meta_R, Common::KEYCODE_RMETA },
- { KS_KP_0, Common::KEYCODE_KP0 },
- { KS_KP_1, Common::KEYCODE_KP1 },
- { KS_KP_2, Common::KEYCODE_KP2 },
- { KS_KP_3, Common::KEYCODE_KP3 },
- { KS_KP_4, Common::KEYCODE_KP4 },
- { KS_KP_5, Common::KEYCODE_KP5 },
- { KS_KP_6, Common::KEYCODE_KP6 },
- { KS_KP_7, Common::KEYCODE_KP7 },
- { KS_KP_8, Common::KEYCODE_KP8 },
- { KS_KP_9, Common::KEYCODE_KP9 },
- { KS_Home, Common::KEYCODE_HOME },
- { KS_Insert, Common::KEYCODE_INSERT },
- { KS_End, Common::KEYCODE_END },
- { KS_Prior, Common::KEYCODE_PAGEUP },
- { KS_Next, Common::KEYCODE_PAGEDOWN },
- { KS_f1, Common::KEYCODE_F1 },
- { KS_f2, Common::KEYCODE_F2 },
- { KS_f3, Common::KEYCODE_F3 },
- { KS_f4, Common::KEYCODE_F4 },
- { KS_f5, Common::KEYCODE_F5 },
- { KS_f6, Common::KEYCODE_F6 },
- { KS_f7, Common::KEYCODE_F7 },
- { KS_f8, Common::KEYCODE_F8 },
- { KS_f9, Common::KEYCODE_F9 },
- { KS_f10, Common::KEYCODE_F10 },
- { KS_f11, Common::KEYCODE_F11 },
- { KS_f12, Common::KEYCODE_F12 },
- { KS_f13, Common::KEYCODE_F13 },
- { KS_f14, Common::KEYCODE_F14 },
- { KS_f15, Common::KEYCODE_F15 },
- { KS_F1, Common::KEYCODE_F1 },
- { KS_F2, Common::KEYCODE_F2 },
- { KS_F3, Common::KEYCODE_F3 },
- { KS_F4, Common::KEYCODE_F4 },
- { KS_F5, Common::KEYCODE_F5 },
- { KS_F6, Common::KEYCODE_F6 },
- { KS_F7, Common::KEYCODE_F7 },
- { KS_F8, Common::KEYCODE_F8 },
- { KS_F9, Common::KEYCODE_F9 },
- { KS_F10, Common::KEYCODE_F10 },
- { KS_F11, Common::KEYCODE_F11 },
- { KS_F12, Common::KEYCODE_F12 },
- { KS_F13, Common::KEYCODE_F13 },
- { KS_F14, Common::KEYCODE_F14 },
- { KS_F15, Common::KEYCODE_F15 },
- { KS_KP_Separator, Common::KEYCODE_KP_PERIOD },
- { KS_KP_Subtract, Common::KEYCODE_KP_DIVIDE },
- { KS_KP_Multiply, Common::KEYCODE_KP_MULTIPLY },
- { KS_KP_Add, Common::KEYCODE_KP_PLUS },
- { KS_KP_Subtract, Common::KEYCODE_KP_MINUS },
- { KS_KP_Equal, Common::KEYCODE_KP_EQUALS },
- { KS_KP_Enter, Common::KEYCODE_KP_ENTER },
- { 0, 0 }
+static int keymap[][3] = {
+ { KS_Return, Common::KEYCODE_RETURN, Common::ASCII_RETURN },
+ { KS_Up, Common::KEYCODE_UP, 0 },
+ { KS_Down, Common::KEYCODE_DOWN, 0 },
+ { KS_Left, Common::KEYCODE_LEFT, 0 },
+ { KS_Right, Common::KEYCODE_RIGHT, 0 },
+ { KS_Shift_L, Common::KEYCODE_LSHIFT, 0 },
+ { KS_Shift_R, Common::KEYCODE_RSHIFT, 0 },
+ { KS_Control_L, Common::KEYCODE_LCTRL, 0 },
+ { KS_Control_R, Common::KEYCODE_RCTRL, 0 },
+ { KS_Alt_L, Common::KEYCODE_LALT, 0 },
+ { KS_Alt_R, Common::KEYCODE_RALT, 0 },
+ { KS_Meta_L, Common::KEYCODE_LMETA, 0 },
+ { KS_Meta_R, Common::KEYCODE_RMETA, 0 },
+ { KS_KP_0, Common::KEYCODE_KP0, '0' },
+ { KS_KP_1, Common::KEYCODE_KP1, '1' },
+ { KS_KP_2, Common::KEYCODE_KP2, '2' },
+ { KS_KP_3, Common::KEYCODE_KP3, '3' },
+ { KS_KP_4, Common::KEYCODE_KP4, '4' },
+ { KS_KP_5, Common::KEYCODE_KP5, '5' },
+ { KS_KP_6, Common::KEYCODE_KP6, '6' },
+ { KS_KP_7, Common::KEYCODE_KP7, '7' },
+ { KS_KP_8, Common::KEYCODE_KP8, '8' },
+ { KS_KP_9, Common::KEYCODE_KP9, '9' },
+ { KS_Home, Common::KEYCODE_HOME, 0 },
+ { KS_Insert, Common::KEYCODE_INSERT, 0 },
+ { KS_End, Common::KEYCODE_END, 0 },
+ { KS_Prior, Common::KEYCODE_PAGEUP, 0 },
+ { KS_Next, Common::KEYCODE_PAGEDOWN, 0 },
+ { KS_f1, Common::KEYCODE_F1, Common::ASCII_F1 },
+ { KS_f2, Common::KEYCODE_F2, Common::ASCII_F2 },
+ { KS_f3, Common::KEYCODE_F3, Common::ASCII_F3 },
+ { KS_f4, Common::KEYCODE_F4, Common::ASCII_F4 },
+ { KS_f5, Common::KEYCODE_F5, Common::ASCII_F5 },
+ { KS_f6, Common::KEYCODE_F6, Common::ASCII_F6 },
+ { KS_f7, Common::KEYCODE_F7, Common::ASCII_F7 },
+ { KS_f8, Common::KEYCODE_F8, Common::ASCII_F8 },
+ { KS_f9, Common::KEYCODE_F9, Common::ASCII_F9 },
+ { KS_f10, Common::KEYCODE_F10, Common::ASCII_F10 },
+ { KS_f11, Common::KEYCODE_F11, Common::ASCII_F11 },
+ { KS_f12, Common::KEYCODE_F12, Common::ASCII_F12 },
+ { KS_f13, Common::KEYCODE_F13, 0 },
+ { KS_f14, Common::KEYCODE_F14, 0 },
+ { KS_f15, Common::KEYCODE_F15, 0 },
+ { KS_F1, Common::KEYCODE_F1, Common::ASCII_F1 },
+ { KS_F2, Common::KEYCODE_F2, Common::ASCII_F2 },
+ { KS_F3, Common::KEYCODE_F3, Common::ASCII_F3 },
+ { KS_F4, Common::KEYCODE_F4, Common::ASCII_F4 },
+ { KS_F5, Common::KEYCODE_F5, Common::ASCII_F5 },
+ { KS_F6, Common::KEYCODE_F6, Common::ASCII_F6 },
+ { KS_F7, Common::KEYCODE_F7, Common::ASCII_F7 },
+ { KS_F8, Common::KEYCODE_F8, Common::ASCII_F8 },
+ { KS_F9, Common::KEYCODE_F9, Common::ASCII_F9 },
+ { KS_F10, Common::KEYCODE_F10, Common::ASCII_F10 },
+ { KS_F11, Common::KEYCODE_F11, Common::ASCII_F11 },
+ { KS_F12, Common::KEYCODE_F12, Common::ASCII_F12 },
+ { KS_F13, Common::KEYCODE_F13, 0 },
+ { KS_F14, Common::KEYCODE_F14, 0 },
+ { KS_F15, Common::KEYCODE_F15, 0 },
+ { KS_KP_Separator, Common::KEYCODE_KP_PERIOD, '.' },
+ { KS_KP_Divide, Common::KEYCODE_KP_DIVIDE, '/' },
+ { KS_KP_Multiply, Common::KEYCODE_KP_MULTIPLY, '*' },
+ { KS_KP_Add, Common::KEYCODE_KP_PLUS, '+' },
+ { KS_KP_Subtract, Common::KEYCODE_KP_MINUS, '-' },
+ { KS_KP_Equal, Common::KEYCODE_KP_EQUALS, '=' },
+ { KS_KP_Enter, Common::KEYCODE_KP_ENTER, Common::ASCII_RETURN },
+ { 0, 0, 0 }
};
#endif
@@ -262,7 +262,7 @@ bool OSystem_Wii::pollKeyboard(Common::Event &event) {
while (keymap[i][0] != 0) {
if (keymap[i][0] == kbdEvent.symbol) {
event.kbd.keycode = static_cast<Common::KeyCode>(keymap[i][1]);
- event.kbd.ascii = 0;
+ event.kbd.ascii = keymap[i][2];
return true;
}
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/base/version.cpp b/base/version.cpp
index ef02ff9d21..fcb2740de9 100644
--- a/base/version.cpp
+++ b/base/version.cpp
@@ -146,4 +146,12 @@ const char *gScummVMFeatures = ""
#ifdef USE_PNG
"PNG "
#endif
+
+#ifdef ENABLE_KEYMAPPER
+ "keymapper "
+#endif
+
+#ifdef ENABLE_VKEYBD
+ "virtual keyboard "
+#endif
;
diff --git a/common/EventMapper.cpp b/common/EventMapper.cpp
index b92116cbe7..cf65946d50 100644
--- a/common/EventMapper.cpp
+++ b/common/EventMapper.cpp
@@ -45,7 +45,7 @@ List<Event> DefaultEventMapper::mapEvent(const Event &ev, EventSource *source) {
if (ev.type == EVENT_MBUTTONUP) {
if ((g_system->getMillis() - vkeybdThen) >= vkeybdTime) {
mappedEvent.type = EVENT_VIRTUAL_KEYBOARD;
-
+
// Avoid blocking event from engine.
addDelayedEvent(100, ev);
}
@@ -59,7 +59,7 @@ List<Event> DefaultEventMapper::mapEvent(const Event &ev, EventSource *source) {
#ifdef ENABLE_VKEYBD
else if (ev.kbd.hasFlags(KBD_CTRL) && ev.kbd.keycode == KEYCODE_F7) {
mappedEvent.type = EVENT_VIRTUAL_KEYBOARD;
-
+
// Avoid blocking CTRL-F7 events from engine.
addDelayedEvent(100, ev);
}
@@ -67,7 +67,7 @@ List<Event> DefaultEventMapper::mapEvent(const Event &ev, EventSource *source) {
#ifdef ENABLE_KEYMAPPER
else if (ev.kbd.hasFlags(KBD_CTRL) && ev.kbd.keycode == KEYCODE_F8) {
mappedEvent.type = EVENT_KEYMAPPER_REMAP;
-
+
// Avoid blocking CTRL-F8 events from engine.
addDelayedEvent(100, ev);
}
diff --git a/common/c++11-compat.h b/common/c++11-compat.h
index 14e0642821..a56b79514c 100644
--- a/common/c++11-compat.h
+++ b/common/c++11-compat.h
@@ -32,13 +32,19 @@
// though.
//
#if !defined(nullptr) // XCode 5.0.1 has __cplusplus=199711 but defines this
+// MSVC 2010 and newer fully support nullptr: http://msdn.microsoft.com/en-us/library/hh567368.aspx
+#if !defined(_MSC_VER) || _MSC_VER < 1600
#define nullptr 0
#endif
+#endif
//
// Replacement for the override keyword. This allows compilation of code
// which uses it, but does not feature any semantic.
//
+// MSVC 2012 and newer fully support override: http://msdn.microsoft.com/en-us/library/hh567368.aspx
+#if !defined(_MSC_VER) || _MSC_VER < 1700
#define override
+#endif
#endif
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..477f7aca62 100644
--- a/common/fft.cpp
+++ b/common/fft.cpp
@@ -61,6 +61,10 @@ FFT::~FFT() {
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/scummsys.h b/common/scummsys.h
index c30bc4a52a..0c4687e03e 100644
--- a/common/scummsys.h
+++ b/common/scummsys.h
@@ -148,7 +148,7 @@
#endif
#endif
-// The following math constants are usually defined by the system math.h header, but
+// The following math constants are usually defined by the system math.h header, but
// they are not part of the ANSI C++ standards and so can NOT be relied upon to be
// present i.e. when -std=c++11 is passed to GCC, enabling strict ANSI compliance.
// As we rely on these being present, we define them if they are not set.
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/common/unzip.cpp b/common/unzip.cpp
index 716c8c2d5e..1f4e601989 100644
--- a/common/unzip.cpp
+++ b/common/unzip.cpp
@@ -334,8 +334,10 @@ int unzGetLocalExtrafield(unzFile file, voidp buf, unsigned len);
#define SIZEZIPLOCALHEADER (0x1e)
+#if 0
const char unz_copyright[] =
" unzip 0.15 Copyright 1998 Gilles Vollant ";
+#endif
/* unz_file_info_interntal contain internal info about a file in zipfile*/
typedef struct {
diff --git a/common/xmlparser.cpp b/common/xmlparser.cpp
index c80d5e15be..67a3d36cec 100644
--- a/common/xmlparser.cpp
+++ b/common/xmlparser.cpp
@@ -69,7 +69,7 @@ bool XMLParser::loadBuffer(const byte *buffer, uint32 size, DisposeAfterUse::Fla
bool XMLParser::loadStream(SeekableReadStream *stream) {
_stream = stream;
_fileName = "File Stream";
- return true;
+ return _stream != nullptr;
}
void XMLParser::close() {
diff --git a/config.guess b/config.guess
index 43f0cdbcfd..6c32c8645c 100755
--- a/config.guess
+++ b/config.guess
@@ -1,14 +1,12 @@
#! /bin/sh
# Attempt to guess a canonical system name.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-# 2011 Free Software Foundation, Inc.
+# Copyright 1992-2014 Free Software Foundation, Inc.
-timestamp='2011-10-01'
+timestamp='2014-11-04'
# This file 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
+# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
@@ -17,26 +15,22 @@ timestamp='2011-10-01'
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-
-# Originally written by Per Bothner. Please send patches (context
-# diff format) to <config-patches@gnu.org> and include a ChangeLog
-# entry.
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
#
-# This script attempts to guess a canonical system name similar to
-# config.sub. If it succeeds, it prints the system name on stdout, and
-# exits with 0. Otherwise, it exits with 1.
+# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
#
# You can get the latest version of this script from:
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+#
+# Please send patches to <config-patches@gnu.org>.
+
me=`echo "$0" | sed -e 's,.*/,,'`
@@ -56,9 +50,7 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free
-Software Foundation, Inc.
+Copyright 1992-2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -140,12 +132,33 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+case "${UNAME_SYSTEM}" in
+Linux|GNU|GNU/*)
+ # If the system lacks a compiler, then just pick glibc.
+ # We could probably try harder.
+ LIBC=gnu
+
+ eval $set_cc_for_build
+ cat <<-EOF > $dummy.c
+ #include <features.h>
+ #if defined(__UCLIBC__)
+ LIBC=uclibc
+ #elif defined(__dietlibc__)
+ LIBC=dietlibc
+ #else
+ LIBC=gnu
+ #endif
+ EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+ ;;
+esac
+
# Note: order is significant - the case branches are not exclusive.
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:NetBSD:*:*)
# NetBSD (nbsd) targets should (where applicable) match one or
- # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
# switched to ELF, *-*-netbsd* would select the old
# object file format. This provides both forward
@@ -202,6 +215,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
echo "${machine}-${os}${release}"
exit ;;
+ *:Bitrig:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+ exit ;;
*:OpenBSD:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
@@ -304,7 +321,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
exit ;;
- arm:riscos:*:*|arm:RISCOS:*:*)
+ arm*:riscos:*:*|arm*:RISCOS:*:*)
echo arm-unknown-riscos
exit ;;
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
@@ -562,8 +579,9 @@ EOF
else
IBM_ARCH=powerpc
fi
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
+ if [ -x /usr/bin/lslpp ] ; then
+ IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
+ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
else
IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
fi
@@ -803,9 +821,15 @@ EOF
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
exit ;;
+ *:MINGW64*:*)
+ echo ${UNAME_MACHINE}-pc-mingw64
+ exit ;;
*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
+ *:MSYS*:*)
+ echo ${UNAME_MACHINE}-pc-msys
+ exit ;;
i*:windows32*:*)
# uname -m includes "-pc" on this system.
echo ${UNAME_MACHINE}-mingw32
@@ -851,15 +875,22 @@ EOF
exit ;;
*:GNU:*:*)
# the GNU system
- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit ;;
*:GNU/*:*:*)
# other systems with GNU libc and userland
- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
exit ;;
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
exit ;;
+ aarch64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ aarch64_be:Linux:*:*)
+ UNAME_MACHINE=aarch64_be
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
EV5) UNAME_MACHINE=alphaev5 ;;
@@ -871,59 +902,54 @@ EOF
EV68*) UNAME_MACHINE=alphaev68 ;;
esac
objdump --private-headers /bin/sh | grep -q ld.so.1
- if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
- echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+ if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arc:Linux:*:* | arceb:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
arm*:Linux:*:*)
eval $set_cc_for_build
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_EABI__
then
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
else
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_PCS_VFP
then
- echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
else
- echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
fi
fi
exit ;;
avr32*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
cris:Linux:*:*)
- echo cris-axis-linux-gnu
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
exit ;;
crisv32:Linux:*:*)
- echo crisv32-axis-linux-gnu
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
exit ;;
frv:Linux:*:*)
- echo frv-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
hexagon:Linux:*:*)
- echo hexagon-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
i*86:Linux:*:*)
- LIBC=gnu
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #ifdef __dietlibc__
- LIBC=dietlibc
- #endif
-EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
- echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+ echo ${UNAME_MACHINE}-pc-linux-${LIBC}
exit ;;
ia64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
m32r*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
m68*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
mips:Linux:*:* | mips64:Linux:*:*)
eval $set_cc_for_build
@@ -942,54 +968,63 @@ EOF
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
;;
- or32:Linux:*:*)
- echo or32-unknown-linux-gnu
+ openrisc*:Linux:*:*)
+ echo or1k-unknown-linux-${LIBC}
+ exit ;;
+ or32:Linux:*:* | or1k*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
padre:Linux:*:*)
- echo sparc-unknown-linux-gnu
+ echo sparc-unknown-linux-${LIBC}
exit ;;
parisc64:Linux:*:* | hppa64:Linux:*:*)
- echo hppa64-unknown-linux-gnu
+ echo hppa64-unknown-linux-${LIBC}
exit ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
- PA7*) echo hppa1.1-unknown-linux-gnu ;;
- PA8*) echo hppa2.0-unknown-linux-gnu ;;
- *) echo hppa-unknown-linux-gnu ;;
+ PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
+ PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
+ *) echo hppa-unknown-linux-${LIBC} ;;
esac
exit ;;
ppc64:Linux:*:*)
- echo powerpc64-unknown-linux-gnu
+ echo powerpc64-unknown-linux-${LIBC}
exit ;;
ppc:Linux:*:*)
- echo powerpc-unknown-linux-gnu
+ echo powerpc-unknown-linux-${LIBC}
+ exit ;;
+ ppc64le:Linux:*:*)
+ echo powerpc64le-unknown-linux-${LIBC}
+ exit ;;
+ ppcle:Linux:*:*)
+ echo powerpcle-unknown-linux-${LIBC}
exit ;;
s390:Linux:*:* | s390x:Linux:*:*)
- echo ${UNAME_MACHINE}-ibm-linux
+ echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
exit ;;
sh64*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
sh*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
sparc:Linux:*:* | sparc64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
tile*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
vax:Linux:*:*)
- echo ${UNAME_MACHINE}-dec-linux-gnu
+ echo ${UNAME_MACHINE}-dec-linux-${LIBC}
exit ;;
x86_64:Linux:*:*)
- echo x86_64-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
xtensa*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
@@ -1193,6 +1228,9 @@ EOF
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
echo i586-pc-haiku
exit ;;
+ x86_64:Haiku:*:*)
+ echo x86_64-unknown-haiku
+ exit ;;
SX-4:SUPER-UX:*:*)
echo sx4-nec-superux${UNAME_RELEASE}
exit ;;
@@ -1219,19 +1257,31 @@ EOF
exit ;;
*:Darwin:*:*)
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
- case $UNAME_PROCESSOR in
- i386)
- eval $set_cc_for_build
- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
- if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
- grep IS_64BIT_ARCH >/dev/null
- then
- UNAME_PROCESSOR="x86_64"
- fi
- fi ;;
- unknown) UNAME_PROCESSOR=powerpc ;;
- esac
+ eval $set_cc_for_build
+ if test "$UNAME_PROCESSOR" = unknown ; then
+ UNAME_PROCESSOR=powerpc
+ fi
+ if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ case $UNAME_PROCESSOR in
+ i386) UNAME_PROCESSOR=x86_64 ;;
+ powerpc) UNAME_PROCESSOR=powerpc64 ;;
+ esac
+ fi
+ fi
+ elif test "$UNAME_PROCESSOR" = i386 ; then
+ # Avoid executing cc on OS X 10.9, as it ships with a stub
+ # that puts up a graphical alert prompting to install
+ # developer tools. Any system running Mac OS X 10.7 or
+ # later (Darwin 11 and later) is required to have a 64-bit
+ # processor. This is not true of the ARM version of Darwin
+ # that Apple uses in portable devices.
+ UNAME_PROCESSOR=x86_64
+ fi
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
exit ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
@@ -1248,7 +1298,7 @@ EOF
NEO-?:NONSTOP_KERNEL:*:*)
echo neo-tandem-nsk${UNAME_RELEASE}
exit ;;
- NSE-?:NONSTOP_KERNEL:*:*)
+ NSE-*:NONSTOP_KERNEL:*:*)
echo nse-tandem-nsk${UNAME_RELEASE}
exit ;;
NSR-?:NONSTOP_KERNEL:*:*)
@@ -1317,158 +1367,10 @@ EOF
i*86:AROS:*:*)
echo ${UNAME_MACHINE}-pc-aros
exit ;;
-esac
-
-#echo '(No uname command or uname output not recognized.)' 1>&2
-#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
-
-eval $set_cc_for_build
-cat >$dummy.c <<EOF
-#ifdef _SEQUENT_
-# include <sys/types.h>
-# include <sys/utsname.h>
-#endif
-main ()
-{
-#if defined (sony)
-#if defined (MIPSEB)
- /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
- I don't know.... */
- printf ("mips-sony-bsd\n"); exit (0);
-#else
-#include <sys/param.h>
- printf ("m68k-sony-newsos%s\n",
-#ifdef NEWSOS4
- "4"
-#else
- ""
-#endif
- ); exit (0);
-#endif
-#endif
-
-#if defined (__arm) && defined (__acorn) && defined (__unix)
- printf ("arm-acorn-riscix\n"); exit (0);
-#endif
-
-#if defined (hp300) && !defined (hpux)
- printf ("m68k-hp-bsd\n"); exit (0);
-#endif
-
-#if defined (NeXT)
-#if !defined (__ARCHITECTURE__)
-#define __ARCHITECTURE__ "m68k"
-#endif
- int version;
- version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
- if (version < 4)
- printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
- else
- printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
- exit (0);
-#endif
-
-#if defined (MULTIMAX) || defined (n16)
-#if defined (UMAXV)
- printf ("ns32k-encore-sysv\n"); exit (0);
-#else
-#if defined (CMU)
- printf ("ns32k-encore-mach\n"); exit (0);
-#else
- printf ("ns32k-encore-bsd\n"); exit (0);
-#endif
-#endif
-#endif
-
-#if defined (__386BSD__)
- printf ("i386-pc-bsd\n"); exit (0);
-#endif
-
-#if defined (sequent)
-#if defined (i386)
- printf ("i386-sequent-dynix\n"); exit (0);
-#endif
-#if defined (ns32000)
- printf ("ns32k-sequent-dynix\n"); exit (0);
-#endif
-#endif
-
-#if defined (_SEQUENT_)
- struct utsname un;
-
- uname(&un);
-
- if (strncmp(un.version, "V2", 2) == 0) {
- printf ("i386-sequent-ptx2\n"); exit (0);
- }
- if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
- printf ("i386-sequent-ptx1\n"); exit (0);
- }
- printf ("i386-sequent-ptx\n"); exit (0);
-
-#endif
-
-#if defined (vax)
-# if !defined (ultrix)
-# include <sys/param.h>
-# if defined (BSD)
-# if BSD == 43
- printf ("vax-dec-bsd4.3\n"); exit (0);
-# else
-# if BSD == 199006
- printf ("vax-dec-bsd4.3reno\n"); exit (0);
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# endif
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# else
- printf ("vax-dec-ultrix\n"); exit (0);
-# endif
-#endif
-
-#if defined (alliant) && defined (i860)
- printf ("i860-alliant-bsd\n"); exit (0);
-#endif
-
- exit (1);
-}
-EOF
-
-$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
- { echo "$SYSTEM_NAME"; exit; }
-
-# Apollos put the system type in the environment.
-
-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
-
-# Convex versions that predate uname can use getsysinfo(1)
-
-if [ -x /usr/convex/getsysinfo ]
-then
- case `getsysinfo -f cpu_type` in
- c1*)
- echo c1-convex-bsd
- exit ;;
- c2*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit ;;
- c34*)
- echo c34-convex-bsd
+ x86_64:VMkernel:*:*)
+ echo ${UNAME_MACHINE}-unknown-esx
exit ;;
- c38*)
- echo c38-convex-bsd
- exit ;;
- c4*)
- echo c4-convex-bsd
- exit ;;
- esac
-fi
+esac
cat >&2 <<EOF
$0: unable to guess system type
diff --git a/config.sub b/config.sub
index 5b8736823d..7ffe373784 100755
--- a/config.sub
+++ b/config.sub
@@ -1,38 +1,31 @@
#! /bin/sh
# Configuration validation subroutine script.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-# 2011 Free Software Foundation, Inc.
+# Copyright 1992-2014 Free Software Foundation, Inc.
-timestamp='2011-10-08'
+timestamp='2014-12-03'
-# This file is (in principle) common to ALL GNU software.
-# The presence of a machine in this file suggests that SOME GNU software
-# can handle that machine. It does not imply ALL GNU software can.
-#
-# This file 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
+# This file 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 3 of the License, or
# (at your option) any later version.
#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
-# Please send patches to <config-patches@gnu.org>. Submit a context
-# diff and a properly formatted GNU ChangeLog entry.
+# Please send patches to <config-patches@gnu.org>.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
@@ -75,9 +68,7 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free
-Software Foundation, Inc.
+Copyright 1992-2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -125,13 +116,17 @@ esac
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
- linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
knetbsd*-gnu* | netbsd*-gnu* | \
kopensolaris*-gnu* | \
storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
+ android-linux)
+ os=-linux-android
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+ ;;
*)
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
if [ $basic_machine != $1 ]
@@ -154,7 +149,7 @@ case $os in
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
- -apple | -axis | -knuth | -cray | -microblaze)
+ -apple | -axis | -knuth | -cray | -microblaze*)
os=
basic_machine=$1
;;
@@ -223,6 +218,12 @@ case $os in
-isc*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
+ -lynx*178)
+ os=-lynxos178
+ ;;
+ -lynx*5)
+ os=-lynxos5
+ ;;
-lynx*)
os=-lynxos
;;
@@ -247,13 +248,16 @@ case $basic_machine in
# Some are omitted here because they have special meanings below.
1750a | 580 \
| a29k \
+ | aarch64 | aarch64_be \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
- | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
- | be32 | be64 \
+ | arc | arceb \
+ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+ | avr | avr32 \
+ | be32 | be64 \
| bfin \
- | c4x | clipper \
+ | c4x | c8051 | clipper \
| d10v | d30v | dlx | dsp16xx \
| epiphany \
| fido | fr30 | frv \
@@ -261,10 +265,11 @@ case $basic_machine in
| hexagon \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
+ | k1om \
| le32 | le64 \
| lm32 \
| m32c | m32r | m32rle | m68000 | m68k | m88k \
- | maxq | mb | microblaze | mcore | mep | metag \
+ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
@@ -278,24 +283,27 @@ case $basic_machine in
| mips64vr5900 | mips64vr5900el \
| mipsisa32 | mipsisa32el \
| mipsisa32r2 | mipsisa32r2el \
+ | mipsisa32r6 | mipsisa32r6el \
| mipsisa64 | mipsisa64el \
| mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64r6 | mipsisa64r6el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
+ | mipsr5900 | mipsr5900el \
| mipstx39 | mipstx39el \
| mn10200 | mn10300 \
| moxie \
| mt \
| msp430 \
| nds32 | nds32le | nds32be \
- | nios | nios2 \
+ | nios | nios2 | nios2eb | nios2el \
| ns16k | ns32k \
- | open8 \
- | or32 \
+ | open8 | or1k | or1knd | or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle \
| pyramid \
- | rx \
+ | riscv32 | riscv64 \
+ | rl78 | rx \
| score \
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
@@ -305,6 +313,7 @@ case $basic_machine in
| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
| ubicom32 \
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+ | visium \
| we32k \
| x86 | xc16x | xstormy16 | xtensa \
| z8k | z80)
@@ -319,8 +328,10 @@ case $basic_machine in
c6x)
basic_machine=tic6x-unknown
;;
- m6811 | m68hc11 | m6812 | m68hc12 | picochip)
- # Motorola 68HC11/12.
+ leon|leon[3-9])
+ basic_machine=sparc-$basic_machine
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
basic_machine=$basic_machine-unknown
os=-none
;;
@@ -333,7 +344,10 @@ case $basic_machine in
strongarm | thumb | xscale)
basic_machine=arm-unknown
;;
-
+ xgate)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
xscaleeb)
basic_machine=armeb-unknown
;;
@@ -356,15 +370,16 @@ case $basic_machine in
# Recognize the basic CPU types with company name.
580-* \
| a29k-* \
+ | aarch64-* | aarch64_be-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
- | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* | avr32-* \
| be32-* | be64-* \
| bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* \
- | clipper-* | craynv-* | cydra-* \
+ | c8051-* | clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
@@ -373,11 +388,13 @@ case $basic_machine in
| hexagon-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \
+ | k1om-* \
| le32-* | le64-* \
| lm32-* \
| m32c-* | m32r-* | m32rle-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
- | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+ | microblaze-* | microblazeel-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \
| mips64-* | mips64el-* \
@@ -391,23 +408,27 @@ case $basic_machine in
| mips64vr5900-* | mips64vr5900el-* \
| mipsisa32-* | mipsisa32el-* \
| mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa32r6-* | mipsisa32r6el-* \
| mipsisa64-* | mipsisa64el-* \
| mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64r6-* | mipsisa64r6el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipsr5900-* | mipsr5900el-* \
| mipstx39-* | mipstx39el-* \
| mmix-* \
| mt-* \
| msp430-* \
| nds32-* | nds32le-* | nds32be-* \
- | nios-* | nios2-* \
+ | nios-* | nios2-* | nios2eb-* | nios2el-* \
| none-* | np1-* | ns16k-* | ns32k-* \
| open8-* \
+ | or1k*-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
| pyramid-* \
- | romp-* | rs6000-* | rx-* \
+ | rl78-* | romp-* | rs6000-* | rx-* \
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
@@ -420,6 +441,7 @@ case $basic_machine in
| ubicom32-* \
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
| vax-* \
+ | visium-* \
| we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* \
| xstormy16-* | xtensa*-* \
@@ -719,7 +741,6 @@ case $basic_machine in
i370-ibm* | ibm*)
basic_machine=i370-ibm
;;
-# I'm not sure what "Sysv32" means. Should this be sysv3.2?
i*86v32)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv32
@@ -758,6 +779,9 @@ case $basic_machine in
basic_machine=m68k-isi
os=-sysv
;;
+ leon-*|leon[3-9]-*)
+ basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
+ ;;
m68knommu)
basic_machine=m68k-unknown
os=-linux
@@ -777,11 +801,15 @@ case $basic_machine in
basic_machine=ns32k-utek
os=-sysv
;;
- microblaze)
+ microblaze*)
basic_machine=microblaze-xilinx
;;
+ mingw64)
+ basic_machine=x86_64-pc
+ os=-mingw64
+ ;;
mingw32)
- basic_machine=i386-pc
+ basic_machine=i686-pc
os=-mingw32
;;
mingw32ce)
@@ -809,6 +837,10 @@ case $basic_machine in
basic_machine=powerpc-unknown
os=-morphos
;;
+ moxiebox)
+ basic_machine=moxie-unknown
+ os=-moxiebox
+ ;;
msdos)
basic_machine=i386-pc
os=-msdos
@@ -816,6 +848,10 @@ case $basic_machine in
ms1-*)
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
;;
+ msys)
+ basic_machine=i686-pc
+ os=-msys
+ ;;
mvs)
basic_machine=i370-ibm
os=-mvs
@@ -1004,7 +1040,11 @@ case $basic_machine in
basic_machine=i586-unknown
os=-pw32
;;
- rdos)
+ rdos | rdos64)
+ basic_machine=x86_64-pc
+ os=-rdos
+ ;;
+ rdos32)
basic_machine=i386-pc
os=-rdos
;;
@@ -1331,29 +1371,29 @@ case $os in
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
- | -sym* | -kopensolaris* \
+ | -sym* | -kopensolaris* | -plan9* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
| -aos* | -aros* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
- | -openbsd* | -solidbsd* \
+ | -bitrig* | -openbsd* | -solidbsd* \
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* | -cegcc* \
- | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -mingw32* | -linux-gnu* | -linux-android* \
- | -linux-newlib* | -linux-uclibc* \
- | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+ | -linux-newlib* | -linux-musl* | -linux-uclibc* \
+ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
- | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1477,9 +1517,6 @@ case $os in
-aros*)
os=-aros
;;
- -kaos*)
- os=-kaos
- ;;
-zvmoe)
os=-zvmoe
;;
@@ -1528,6 +1565,12 @@ case $basic_machine in
c4x-* | tic4x-*)
os=-coff
;;
+ c8051-*)
+ os=-elf
+ ;;
+ hexagon-*)
+ os=-elf
+ ;;
tic54x-*)
os=-coff
;;
@@ -1555,9 +1598,6 @@ case $basic_machine in
;;
m68000-sun)
os=-sunos3
- # This also exists in the configure program, but was not the
- # default.
- # os=-sunos4
;;
m68*-cisco)
os=-aout
diff --git a/configure b/configure
index 5264e32410..78f147f4b2 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"
@@ -822,9 +823,9 @@ Usage: $0 [OPTIONS]...
Configuration:
-h, --help display this help and exit
- --backend=BACKEND backend to build (android, tizen, dc, dingux, ds, gph,
- iphone, linuxmoto, maemo, n64, null, openpandora, ps2,
- psp, samsungtv, sdl, webos, wii, wince) [sdl]
+ --backend=BACKEND backend to build (android, tizen, dc, dingux, ds, gcw0,
+ gph, iphone, linuxmoto, maemo, n64, null, openpandora,
+ ps2, psp, samsungtv, sdl, webos, wii, wince) [sdl]
Installation directories:
--prefix=PREFIX install architecture-independent files in PREFIX
@@ -859,6 +860,7 @@ Special configuration feature:
dreamcast for Sega Dreamcast
ds for Nintendo DS
gamecube for Nintendo GameCube
+ gcw0 for GCW Zero
gp2x for GP2X
gp2xwiz for GP2X Wiz
iphone for Apple iPhone
@@ -1298,7 +1300,7 @@ caanoo)
_host_cpu=arm
_host_alias=arm-none-linux-gnueabi
;;
-dingux)
+dingux | gcw0)
_host_os=linux
_host_cpu=mipsel
_host_alias=mipsel-linux
@@ -1317,7 +1319,7 @@ ds)
;;
gamecube)
_host_os=gamecube
- _host_cpu=ppc
+ _host_cpu=powerpc
_host_alias=powerpc-eabi
;;
gp2x)
@@ -1385,7 +1387,7 @@ openpandora)
;;
ppc-amigaos)
_host_os=amigaos
- _host_cpu=ppc
+ _host_cpu=powerpc
;;
ps2)
_host_os=ps2
@@ -1397,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
@@ -1443,7 +1445,7 @@ webos)
;;
wii)
_host_os=wii
- _host_cpu=ppc
+ _host_cpu=powerpc
_host_alias=powerpc-eabi
;;
wince)
@@ -2003,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
;;
@@ -2046,7 +2048,7 @@ case $_host_cpu in
echo "MIPS"
DEFINES="$DEFINES -DMIPS_TARGET"
;;
- ppc*)
+ powerpc*)
echo "PowerPC"
DEFINES="$DEFINES -DPPC_TARGET"
;;
@@ -2180,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
@@ -2588,6 +2603,25 @@ if test -n "$_host"; then
add_line_to_config_h "/* #define DEBUG_WII_GDB */"
add_line_to_config_h "#define USE_WII_DI"
;;
+ gcw0)
+ DEFINES="$DEFINES -DDINGUX -DGCW0"
+ DEFINES="$DEFINES -DREDUCE_MEMORY_USAGE"
+ ASFLAGS="$ASFLAGS"
+ CXXFLAGS="$CXXFLAGS -mips32"
+ _backend="dingux"
+ _mt32emu=no
+ _optimization_level=-O3
+ # Disable alsa midi to get the port build on OpenDingux toolchain
+ _alsa=no
+ _vkeybd=yes
+ _build_hq_scalers=no
+ _keymapper=yes
+ # Force disable vorbis on dingux, it has terrible performance compared to tremor
+ _vorbis=no
+ # Force disable seq on dingux, no way to use it and it would get enabled by default with configure
+ _seq_midi=no
+ _port_mk="backends/platform/dingux/dingux.mk"
+ ;;
gp2x)
DEFINES="$DEFINES -DGP2X"
CXXFLAGS="$CXXFLAGS -march=armv4t"
@@ -2743,6 +2777,9 @@ if test -n "$_host"; then
_port_mk="backends/platform/openpandora/op-bundle.mk"
;;
ppc-amigaos)
+ # PPC Linker requires this to fix relocation errors
+ CXXFLAGS="$CXXFLAGS -mlongcall"
+
# Only static builds link successfully on buildbot
LDFLAGS=`echo $LDFLAGS | sed 's/-use-dynld//'`
LDFLAGS="$LDFLAGS -static"
@@ -3035,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
@@ -4481,6 +4521,7 @@ $_def_64bit_type_unsigned
#else
$_def_64bit_type_unsigned
#endif
+#define HAVE_INT64
EOF
fi
@@ -4509,6 +4550,8 @@ WIN32PATH=$_win32path
AMIGAOSPATH=$_amigaospath
STATICLIBPATH=$_staticlibpath
+ABI := $ABI
+
BACKEND := $_backend
MODULES += $MODULES
MODULE_DIRS += $MODULE_DIRS
@@ -4544,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..34d30e1d69 100644
--- a/devtools/create_project/create_project.cpp
+++ b/devtools/create_project/create_project.cpp
@@ -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;
@@ -335,7 +338,13 @@ int main(int argc, char *argv[]) {
// Windows only has support for the SDL backend, so we hardcode it here (along with winmm)
setup.defines.push_back("WIN32");
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
@@ -645,6 +654,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";
diff --git a/devtools/create_translations/po_parser.cpp b/devtools/create_translations/po_parser.cpp
index 7882502ca4..ecc3ba540c 100644
--- a/devtools/create_translations/po_parser.cpp
+++ b/devtools/create_translations/po_parser.cpp
@@ -332,6 +332,13 @@ PoMessageEntryList *parsePoFile(const char *file, PoMessageList& messages) {
strcat(currentBuf, stripLine(line));
}
}
+ if (currentBuf == msgstrBuf) {
+ // add last entry
+ if (*msgstrBuf != '\0' && !fuzzy) {
+ messages.insert(msgidBuf);
+ list->addMessageEntry(msgstrBuf, msgidBuf, msgctxtBuf);
+ }
+ }
fclose(inFile);
return list;
diff --git a/devtools/credits.pl b/devtools/credits.pl
index 0960011802..f82d0d4212 100755
--- a/devtools/credits.pl
+++ b/devtools/credits.pl
@@ -786,10 +786,13 @@ begin_credits("Credits");
begin_section("Wintermute");
add_person("Einar Johan T. S&oslash;m&aring;en", "somaen", "");
+ add_person("Tobia Tesan", "t0by", "");
end_section();
begin_section("ZVision");
add_person("Adrian Astley", "RichieSams", "");
+ add_person("Filippos Karapetis", "[md5]", "");
+ add_person("Anton Yarcev", "Zidane", "");
end_section();
end_section();
@@ -1091,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();
@@ -1124,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)");
@@ -1205,7 +1215,7 @@ begin_credits("Credits");
add_person("Ivan Dubrov", "", "For contributing the initial version of the Gobliiins engine");
add_person("Henrik Engqvist", "qvist", "For generously providing hosting for our buildbot, SVN repository, planet and doxygen sites as well as tons of HD space");
add_person("DOSBox Team", "", "For their awesome OPL2 and OPL3 emulator");
- add_person("Yusuke Kamiyamane", "", "For contributing some GUI icons ");
+ add_person("Yusuke Kamiyamane", "", "For contributing some GUI icons");
add_person("Till Kresslein", "Krest", "For design of modern ScummVM GUI");
add_person("", "Jezar", "For his freeverb filter implementation");
add_person("Jim Leiterman", "", "Various info on his FM-TOWNS/Marty SCUMM ports");
@@ -1266,7 +1276,7 @@ begin_credits("Credits");
add_paragraph(
"Janusz Wi&#347;niewski and Miroslaw Liminowicz from Laboratorium Komputerowe Avalon ".
- "for providing full source code for So&#322;tys and letting us redistribute the game.");
+ "for providing full source code for So&#322;tys and Sfinx and letting us redistribute the games.");
add_paragraph(
"Jan Nedoma for providing the sources to the Wintermute-engine, and for his ".
diff --git a/devtools/scumm-md5.txt b/devtools/scumm-md5.txt
index f0cb577237..305c1724ed 100644
--- a/devtools/scumm-md5.txt
+++ b/devtools/scumm-md5.txt
@@ -21,9 +21,6 @@
# - Source
# -> The source of the information, useful in case it has to be verified
#
-# TODO: We really should have a separate target for "Misc FM-TOWNS demos", so
-# that their description in the launcher doesn't start with "Zak McKracken"
-#
#
# Table of email addresse of contributors: Sometimes we need to add new
# information to this table, or need to verify the correctness of an
@@ -55,6 +52,7 @@
maniac Maniac Mansion
2d624d1b214f7faf0094daea65c6d1a6 -1 en 2gs Apple II - -
+ 2cb46375dd5cdfd023e2f07e0a21b530 -1 en C64 C64 Demo - Robert Crossfield
eea4d9ac2fb6f145945a308e8866915b -1 en C64 C64 - -
439a7f4adf510489981ac52308e7d7a2 -1 de C64 C64 - -
@@ -129,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
@@ -295,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
@@ -313,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
@@ -336,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
@@ -357,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
@@ -483,9 +485,9 @@ fbpack Fatty Bear's Fun Pack
freddi Freddi Fish 1: The Case of the Missing Kelp Seeds
d4cccb5af88f3e77f370896e9ba8c5f9 -1 All Windows HE 71 - - sev
- c0039ad982999c92d0de81910d640fa0 -1 nl Windows HE 71 - - adutchguy
+ c0039ad982999c92d0de81910d640fa0 26159 nl Windows HE 71 - - adutchguy
68530d2e15f339fbbf3150b78b4d2ffb -1 en Mac HE 73 - - satz
- 6d1baa1065ac5f7b210be8ebe4235e49 -1 nl Mac HE 73 - - daniel9
+ 6d1baa1065ac5f7b210be8ebe4235e49 26384 nl Mac HE 73 - - daniel9
c782fbbe74a987c3df8ac73cd3e289ed -1 se Mac HE 73 - - Torbjörn Andersson
5ebb57234b2fe5c5dff641e00184ad81 -1 fr Windows HE 73 - - gist974
cf8ef3a1fb483c5c4b1c584d1167b2c4 -1 de Windows HE 73 - - Oncer
@@ -516,7 +518,7 @@ freddi Freddi Fish 1: The Case of the Missing Kelp Seeds
freddi2 Freddi Fish 2: The Case of the Haunted Schoolhouse
0a295b80f9a9edf818e8e161a0e83830 -1 fr All HE 80 - - gist974, ThierryFR
fce4b8010704b103acfeea9413788f32 -1 de All HE 80 - - Joachim Eberhard
- 8e9830a6f2702be5b22c8fa0a6aaf977 -1 nl Mac HE 80 - - daniel9
+ 8e9830a6f2702be5b22c8fa0a6aaf977 65305 nl All HE 80 - - daniel9
5057fb0e99e5aa29df1836329232f101 -1 All Windows HE 80 - - sev
ac62d50e39492ee3738b4e83a5ac780f -1 nl Windows HE 80 - - joostp
151071053a1d0021198216713939521d -1 en Windows HE 80 - - vampir_raziel
@@ -564,7 +566,11 @@ freddi4 Freddi Fish 4: The Case of the Hogfish Rustlers of Briny Gulch
fa84cb1018103a4ee4e5fa8041c1d0d1 13609 de Windows - Demo - George Kormendi
ebd324dcf06a4c49e1ba5c231eee1060 -1 us All HE 99 Demo - sev
688328c5bdc4c8ec4145688dfa077bf2 -1 de All HE 99 Demo - Joachim Eberhard
- 03d3b18ee3fd68114e2a687c871e38d5 -1 us Windows HE 99 Mini Game - eriktorbjorn
+ 03d3b18ee3fd68114e2a687c871e38d5 13609 us Windows HE 99 Mini Game - eriktorbjorn
+ 9340b552b0f2dffe6d4f3d13ebebe832 13609 nl Windows HE 99 Mini Game - Ben Castricum
+ c486e4cfa7bd6f8efcd0740f96f7dde3 13609 fr Windows HE 99 Mini Game - Ben Castricum
+ 7a2b6d8e8a645c9d534c8c4edc38a9c9 13609 it Windows HE 99 Mini Game - Ben Castricum
+ 09b0be55c16cd9e88b5080bf89ff281d 13609 de Windows HE 99 Mini Game - Ben Castricum
16effd200aa6b8abe9c569c3e578814d -1 nl All HE 99 Demo - joostp
499c958affc394f2a3868f1eb568c3ee -1 nl All HE 99 Demo - adutchguy
5fdb2ac2483908b065c6e77988338a54 -1 nl Windows HE 99 Demo - Ben
@@ -577,6 +583,7 @@ freddicove Freddi Fish 5: The Case of the Creature of Coral Cove
590e6546aacd0d374b7f3a4f53013ab1 -1 All All - - - cyx
21abe302e1b1e2b66d6f5c12e241ebfd -1 ru Windows unenc Unencrypted - sev
b8955d7d23b4972229060d1592489fef -1 nl All HE 100 - - adutchguy, daniel9
+ 8f345db2f3f5a25ed6305001957e6f72 41182 nl All HE 100 - - Ben Castricum
b100abf7ff83146df50db78dbd5e9cfa -1 fr All HE 100 - - alamaz, gist974
4ce2d5b355964bbcb5e5ce73236ef868 -1 ru Windows HE 100 - - sev
@@ -624,9 +631,11 @@ farm Let's Explore the Farm with Buzzy
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
39fd6db10d0222d817025c4d3346e3b4 -1 en Mac - Demo - Joachim Eberhard
+ 6c375c2236d99f56e6c2cf540e74e474 34333 nl Windows - Demo - Kirben
bf8b52fdd9a69c67f34e8e9fec72661c -1 en Windows HE 71 Demo - khalek, sev
0557df19f046a84c2fdc63507c6616cb -1 nl Windows HE 72 Demo - adutchguy
8d479e36f35e80257dfc102cf4b8a912 34333 en Windows HE 72 Demo - khalek, sev
@@ -661,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
@@ -677,8 +687,9 @@ 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 -1 nl Mac - - - daniel9
+ 06c3cf4f31daad8b1cd93153491db9e6 79382 nl All - - - daniel9
7410a8ba9795020cd42f171c4320659e -1 fr Windows - - - gist974
20176076d708bf14407bcc9bdcd7a418 -1 ru Windows - - - sev
@@ -686,7 +697,11 @@ pajama3 Pajama Sam 3: You Are What You Eat From Your Head to Your Feet
a654fb60c3b67d6317a7894ffd9f25c5 -1 us All - Demo - sev
a9f2f04b1ecaab9495b59befffe9bf88 -1 us All - Demo - sev
0c45eb4baff0c12c3d9dfa889c8070ab 13884 de All - Demo - Joachim Eberhard
- 4fe6a2e8df3c4536b278fdd2fbcb181e -1 en Windows - Mini Game - Trekky
+ 4fe6a2e8df3c4536b278fdd2fbcb181e 13911 en Windows - Mini Game - Trekky
+ 24942a4200d99bdb4bdb78f9c7e07027 13911 nl Windows - Mini Game - Ben Castricum
+ faa89ab5e67ba4eebb4399f584f7490c 13911 fr Windows - Mini Game - Ben Castricum
+ d1a73e87564477c7c2dcc2b8f616ad0b 13911 it Windows - Mini Game - Ben Castricum
+ a8fcc3084ad5e3e569722755f205b1ef 13911 de Windows - Mini Game - Ben Castricum
679855cf61932f9bf995c8f3677380ed -1 fr Windows - Demo - Mevi
c8c5baadcbfc8d0372ed4335abace8a7 -1 fr Windows - Demo - Mevi
784b499c98d07260a30952685758636b 13911 de Windows - Demo - George Kormendi
@@ -715,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
@@ -723,6 +739,7 @@ puttrace Putt-Putt Enters the Race
62050da376483d8edcbd98cd26b6cb57 -1 ru Windows HE 99 - - sev
0ac41e2e3d2174e5a042a6b565328dba 13110 us All HE 98 Demo - sev
+ ee8cfeb76e55d43a01c25e0865a9db76 13135 nl Mac HE 98 Demo - Ben Castricum
6af2419fe3db5c2fdb091ae4e5833770 -1 nl All HE 98.5 Demo - Kirben
663743c03ae0c007f3d665cf631c0e6b 13135 de All HE 99 Demo - Joachim Eberhard
aaa587701cde7e74692c68c1024b85eb -1 nl All HE 99 Demo - joostp
@@ -812,7 +829,10 @@ PuttTime Putt-Putt Travels Through Time
59d5cfcc5e672a6e07baae01328b918b -1 fr All HE 90 Demo - Kirben
fbb697d89d2beca87360a145f467bdae -1 de All HE 90 Demo - Joachim Eberhard
6b19d0e25cbf720d05822379b8b90ed9 -1 nl All HE 90 Demo - adutchguy
- 0a6d7b81b850ed4a77811c60c9b5c555 -1 us Windows HE 99 Mini Game - eriktorbjorn
+ 0a6d7b81b850ed4a77811c60c9b5c555 18458 us Windows HE 99 Mini Game - eriktorbjorn
+ a71014c53a6d18c66ef2ea0ee42328e9 18458 nl Windows HE 99 Mini Game - Ben Castricum
+ 8dd4d590685c19bf651b5016e749ead2 18458 fr Windows HE 99 Mini Game - Ben Castricum
+ aef415cc5dc063e3668359c2657169f3 18458 de Windows HE 99 Mini Game - Ben Castricum
0ab19be9e2a3f6938226638b2a3744fe -1 us All HE 100 Demo - khalek
balloon Putt-Putt and Pep's Balloon-O-Rama
@@ -820,7 +840,7 @@ balloon Putt-Putt and Pep's Balloon-O-Rama
bab0fb81dcb12b8930c5d850b8f2a7de 12800 de Windows HE 80 - - George Kormendi
145bd3373574feb668cc2eea2ec6cf86 -1 ru Windows HE 80 - - sev
27b2ef1653089fe5b897d9cc89ce784f -1 ru Windows HE 80 - - George Kormendi
- 2232b0b9411575b1f9961713ebc9de61 -1 All Windows HE 80 - ES and NL exiltd (ES), Ben Castricum (NL)
+ 2232b0b9411575b1f9961713ebc9de61 -1 nl Windows HE 80 - - Ben Castricum
a22af0ad0e3126d19d22707b0267a37d -1 nl Windows HE 80 - - Ben Castricum
a56a05c6b865b9956639f8c51269e5ab -1 nl Mac HE 80 - - Ben Castricum
d7b247c26bf1f01f8f7daf142be84de3 -1 en Windows HE 99 Updated - iziku
@@ -874,14 +894,19 @@ 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 -1 nl Windows - - - adutchguy
+ 71fe97c3108678cf604f14abe342341b 51286 nl All - - - adutchguy
1c792d28376d45e145cb916bca0400a2 -1 nl All - Demo - joostp
7222f260253f325c21fcfa68b5bfab67 -1 us All - Demo - Kirben
732845548b1d6c2da572cb6a1bf81b07 -1 de All - Demo - Joachim Eberhard
- e62056ba675ad65d8854ab3c5ad4b3c0 -1 en Windows - Mini Game - Trekky
+ e62056ba675ad65d8854ab3c5ad4b3c0 14689 en Windows - Mini Game - Trekky
+ 22c7432dc97a821fcfccd480e93e3911 14689 nl Windows - Mini Game - Ben Castricum
+ 6b10c9977cad9de503642059359792b1 14689 fr Windows - Mini Game - Ben Castricum
+ 9684c161258d68e0d464d6cab7024b9c 14689 it Windows - Mini Game - Ben Castricum
+ 7f2578d8d33a9ff525488a2d9ba617e4 14689 de Windows - Mini Game - Ben Castricum
22de86b2f7ec6e5db745ed1123310b44 15832 fr Windows - Demo - George Kormendi
204453e33456c4faa26e276229fe5b76 14689 de Windows - Demo - George Kormendi
19bf6938a94698296bcb0c99c31c91a7 -1 gb Windows - Demo - eriktorbjorn
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/gcw0/default.gcw0.desktop b/dists/gcw0/default.gcw0.desktop
new file mode 100644
index 0000000000..46bd2be092
--- /dev/null
+++ b/dists/gcw0/default.gcw0.desktop
@@ -0,0 +1,16 @@
+[Desktop Entry]
+Name=ScummVM
+Comment=Interpreter for several adventure games
+Comment[pl]=Interpreter graficznych gier przygodowych
+Comment[sv]=Tolk för flera äventyrsspel
+Comment[he]=פרשן למספר משחקי הרפתק×ות
+Comment[de]=Interpreter für diverse Abenteuerspiele
+Comment[es]=Intérprete para varias aventuras gráficas
+Comment[ca]=Intèrpret per diverses aventures gràfiques
+Exec=scummvm.sh
+Icon=scummvm
+Terminal=false
+Type=Application
+Categories=games
+StartupNotify=false
+X-OD-Manual=README
diff --git a/dists/gcw0/opk_make.sh b/dists/gcw0/opk_make.sh
new file mode 100755
index 0000000000..b1bfd03efb
--- /dev/null
+++ b/dists/gcw0/opk_make.sh
@@ -0,0 +1,111 @@
+#!/bin/bash
+#
+# opk_make.sh
+#
+# This script is meant to ease generation of a opk file. Please consult the output
+# when running --help for a list of available parameters and an explaination of
+# those.
+#
+# Required tools when running the script:
+# bash
+# echo, cat, mv, rm, mksquashfs
+
+check_for_tool()
+{
+ which $1 &> /dev/null
+ if [ "$?" -ne "0" ];
+ then
+ cecho "ERROR: Could not find the program '$1'. Please make sure
+that it is available in your PATH since it is required to complete your request." $red
+ exit 1
+ fi
+}
+
+print_help()
+{
+ cat << EOSTREAM
+opk_make.sh - A script to package "something" into a OPK.
+
+Usage:
+ $(basename ${0}) {--directory|-d} <folder> {--opk|-o} <file> [{--help|-h}]
+
+
+Switches:
+ --directory / -d Sets the folder that is to be used for the resulting opk
+ to <folder>. This option is mandatory for the script to
+ function correctly.
+
+ --help / -h Displays this help text.
+
+ --opkname / -o Sets the output filename of the resulting opk to <file>.
+ This option is mandatory for the script to function
+ correctly.
+
+A version >=4.0 of squashfs is required to be available in your PATH.
+EOSTREAM
+}
+
+
+# Parse command line parameters
+while [ "${1}" != "" ]; do
+ if [ "${1}" = "--directory" ] || [ "${1}" = "-d" ];
+ then
+ FOLDER=$2
+ shift 2
+ elif [ "${1}" = "--help" ] || [ "${1}" = "-h" ];
+ then
+ print_help
+ exit 0
+ elif [ "${1}" = "--opkname" ] || [ "${1}" = "-o" ];
+ then
+ OPKNAME=$2
+ shift 2
+ else
+ echo "ERROR: '$1' is not a known argument. Printing --help and aborting."
+ print_help
+ exit 1
+ fi
+done
+
+
+# Probe if required variables were set
+echo "Checking if all required variables were set."
+if [ ! $OPKNAME ] || [ ! $FOLDER ];
+then
+ echo "ERROR: Not all required options were set! Please see the --help information below."
+ print_help
+ exit 1
+else
+ echo "OPKNAME set to '$OPKNAME'."
+fi
+# Check if the selected folder actually exists
+if [ ! -d $FOLDER ];
+then
+ echo "ERROR: '$FOLDER' doesn't exist or is not a folder."
+ exit 1
+else
+ echo "FOLDER set to '$FOLDER'."
+fi
+
+# Make iso from folder
+echo "Creating an iso file based on '$FOLDER'."
+
+check_for_tool mksquashfs
+if [ $(mksquashfs -version | awk 'BEGIN{r=0} $3>=4{r=1} END{print r}') -eq 0 ];
+then
+ echo "ERROR: Your squashfs version is older then version 4, please upgrade to 4.0 or later"
+ exit 1
+fi
+mksquashfs $FOLDER $OPKNAME.opk -noappend -no-exports -no-xattrs
+
+# Final message
+if [ -f $OPKNAME ];
+then
+ echo "Successfully finished creating the opk '$OPKNAME'."
+else
+ echo "There seems to have been a problem and '$OPKNAME' was not created. Please check
+the output above for any error messages. A possible cause for this is that there was
+not enough space available."
+ exit 1
+fi
+
diff --git a/dists/gcw0/scummvm.png b/dists/gcw0/scummvm.png
new file mode 100644
index 0000000000..128e59efc4
--- /dev/null
+++ b/dists/gcw0/scummvm.png
Binary files differ
diff --git a/dists/gcw0/scummvm.sh b/dists/gcw0/scummvm.sh
new file mode 100755
index 0000000000..c12a3030cc
--- /dev/null
+++ b/dists/gcw0/scummvm.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+cd `dirname $0`
+
+if [ ! -f $HOME/.scummvmrc ] ; then
+ cp ./scummvmrc $HOME/.scummvmrc
+fi
+
+exec ./scummvm
diff --git a/dists/gcw0/scummvmrc b/dists/gcw0/scummvmrc
new file mode 100644
index 0000000000..c2087c222a
--- /dev/null
+++ b/dists/gcw0/scummvmrc
@@ -0,0 +1,9 @@
+[scummvm]
+fullscreen=true
+gfx_mode=1x
+aspect_ratio=true
+themepath=./themes
+browser_lastpath=/media
+extrapath=./engine-data
+pluginspath=./plugins
+joystick_num=0
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/engines/access/access.cpp b/engines/access/access.cpp
new file mode 100644
index 0000000000..0a4e519c91
--- /dev/null
+++ b/engines/access/access.cpp
@@ -0,0 +1,578 @@
+/* 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-channels.h"
+#include "common/events.h"
+#include "engines/util.h"
+#include "graphics/scaler.h"
+#include "graphics/thumbnail.h"
+#include "access/access.h"
+
+namespace Access {
+
+AccessEngine::AccessEngine(OSystem *syst, const AccessGameDescription *gameDesc)
+ : _gameDescription(gameDesc), Engine(syst), _randomSource("Access"),
+ _useItem(_flags[99]), _startup(_flags[170]), _manScaleOff(_flags[172]) {
+ _animation = nullptr;
+ _bubbleBox = nullptr;
+ _char = nullptr;
+ _debugger = nullptr;
+ _events = nullptr;
+ _files = nullptr;
+ _inventory = nullptr;
+ _midi = nullptr;
+ _player = nullptr;
+ _room = nullptr;
+ _screen = nullptr;
+ _scripts = nullptr;
+ _sound = nullptr;
+ _video = nullptr;
+
+ _destIn = nullptr;
+ _current = nullptr;
+ _mouseMode = 0;
+ _currentMan = 0;
+ _currentManOld = -1;
+ _converseMode = 0;
+ _startAboutBox = 0;
+ _startTravelBox = 0;
+ _numAnimTimers = 0;
+ _startup = 0;
+ _currentCharFlag = false;
+ _boxSelect = false;
+ _scale = 0;
+ _scaleH1 = _scaleH2 = 0;
+ _scaleN1 = 0;
+ _scaleT1 = 0;
+ _scaleMaxY = 0;
+ _scaleI = 0;
+ _scrollCol = _scrollRow = 0;
+ _scrollX = _scrollY = 0;
+ _imgUnscaled = false;
+ _canSaveLoad = false;
+ _establish = nullptr;
+
+ _conversation = 0;
+ _currentMan = 0;
+ _newTime = 0;
+ _newDate = 0;
+ Common::fill(&_objectsTable[0], &_objectsTable[100], (SpriteResource *)nullptr);
+ Common::fill(&_establishTable[0], &_establishTable[100], false);
+ Common::fill(&_flags[0], &_flags[256], 0);
+ _establishFlag = false;
+ _establishMode = 0;
+ _establishGroup = 0;
+ _establishCtrlTblOfs = 0;
+ _lastTime = g_system->getMillis();
+ _curTime = 0;
+ _narateFile = 0;
+ _txtPages = 0;
+ _sndSubFile = 0;
+ _loadSaveSlot = -1;
+ _vidX = _vidY = 0;
+ _cheatFl = false;
+ _restartFl = false;
+ _printEnd = 0;
+ for (int i = 0; i < 100; i++)
+ _objectsTable[i] = nullptr;
+ _clearSummaryFlag = false;
+}
+
+AccessEngine::~AccessEngine() {
+ delete _animation;
+ delete _bubbleBox;
+ delete _char;
+ delete _debugger;
+ delete _events;
+ delete _files;
+ delete _inventory;
+ delete _midi;
+ delete _player;
+ delete _room;
+ delete _screen;
+ delete _scripts;
+ delete _sound;
+ delete _video;
+
+ freeCells();
+ delete _establish;
+}
+
+void AccessEngine::setVGA() {
+ initGraphics(320, 200, false);
+}
+
+void AccessEngine::initialize() {
+ // Set up debug channels
+ DebugMan.addDebugChannel(kDebugPath, "Path", "Pathfinding debug level");
+ DebugMan.addDebugChannel(kDebugScripts, "scripts", "Game scripts");
+ DebugMan.addDebugChannel(kDebugGraphics, "graphics", "Graphics handling");
+ DebugMan.addDebugChannel(kDebugSound, "sound", "Sound and Music handling");
+
+ if (isCD()) {
+ const Common::FSNode gameDataDir(ConfMan.get("path"));
+ // The CD version contains two versions of the game.
+ // - The MCGA version, in the CDROM folder
+ // - The VESA version, in the TDROM folder
+ // We use the hires version.
+ const Common::FSNode cdromDir = gameDataDir.getChild("tdrom");
+
+ for (int idx = 0; idx < 15; ++idx) {
+ Common::String folder = (idx == 0) ? "game" :
+ Common::String::format("chap%.2d", idx);
+ SearchMan.addSubDirectoryMatching(cdromDir, folder);
+ }
+ }
+
+ // Create sub-objects of the engine
+ _animation = new AnimationManager(this);
+ _bubbleBox = new BubbleBox(this);
+ _char = new CharManager(this);
+ _debugger = Debugger::init(this);
+ _events = new EventsManager(this);
+ _files = new FileManager(this);
+ _inventory = new InventoryManager(this);
+ _player = Player::init(this);
+ _screen = new Screen(this);
+ _sound = new SoundManager(this, _mixer);
+ _midi = new MusicManager(this);
+ _video = new VideoPlayer(this);
+
+ _buffer1.create(g_system->getWidth() + TILE_WIDTH, g_system->getHeight());
+ _buffer2.create(g_system->getWidth(), g_system->getHeight());
+ _vidBuf.create(160, 101);
+
+ // 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 <= 999)
+ _loadSaveSlot = saveSlot;
+ }
+}
+
+Common::Error AccessEngine::run() {
+ setVGA();
+ initialize();
+
+ playGame();
+
+ return Common::kNoError;
+}
+
+int AccessEngine::getRandomNumber(int maxNumber) {
+ return _randomSource.getRandomNumber(maxNumber);
+}
+
+void AccessEngine::loadCells(Common::Array<CellIdent> &cells) {
+ for (uint i = 0; i < cells.size(); ++i) {
+ Resource *spriteData = _files->loadFile(cells[i]);
+ _objectsTable[cells[i]._cell] = new SpriteResource(this, spriteData);
+ delete spriteData;
+ }
+}
+
+void AccessEngine::freeCells() {
+ for (int i = 0; i < 100; ++i) {
+ delete _objectsTable[i];
+ _objectsTable[i] = nullptr;
+ }
+}
+
+void AccessEngine::speakText(ASurface *s, const Common::String &msg) {
+ Common::String lines = msg;
+ Common::String line;
+ int curPage = 0;
+ int soundsLeft = 0;
+
+ while (!shouldQuit()) {
+ soundsLeft = _countTbl[curPage];
+ _events->zeroKeys();
+
+ int width = 0;
+ bool lastLine = _fonts._font2.getLine(lines, s->_maxChars * 6, line, width);
+
+ // Set font colors
+ _fonts._font2._fontColors[0] = 0;
+ _fonts._font2._fontColors[1] = 28;
+ _fonts._font2._fontColors[2] = 29;
+ _fonts._font2._fontColors[3] = 30;
+
+ _fonts._font2.drawString(s, line, s->_printOrg);
+ s->_printOrg = Common::Point(s->_printStart.x, s->_printOrg.y + 9);
+
+ if ((s->_printOrg.y > _printEnd) && (!lastLine)) {
+ _events->clearEvents();
+ while (!shouldQuit()) {
+ _sound->freeSounds();
+ _sound->loadSoundTable(0, _narateFile + 99, _sndSubFile);
+ _sound->playSound(0);
+
+ while(_sound->isSFXPlaying() && !shouldQuit())
+ _events->pollEvents();
+
+ _scripts->cmdFreeSound();
+
+ if (_events->isKeyMousePressed()) {
+ _sndSubFile += soundsLeft;
+ break;
+ } else {
+ ++_sndSubFile;
+ --soundsLeft;
+ if (soundsLeft == 0)
+ break;
+ _events->clearEvents();
+ }
+ }
+
+ s->copyBuffer(&_buffer2);
+ s->_printOrg.y = s->_printStart.y;
+ ++curPage;
+ soundsLeft = _countTbl[curPage];
+ }
+
+ if (lastLine)
+ break;
+ }
+
+ while (soundsLeft) {
+ _sound->freeSounds();
+ Resource *res = _sound->loadSound(_narateFile + 99, _sndSubFile);
+ _sound->_soundTable.push_back(SoundEntry(res, 1));
+ _sound->playSound(0);
+
+ while(_sound->isSFXPlaying() && !shouldQuit())
+ _events->pollEvents();
+
+ _scripts->cmdFreeSound();
+
+ if (_events->_leftButton) {
+ _events->debounceLeft();
+ _sndSubFile += soundsLeft;
+ break;
+ } else if (_events->isKeyPending()) {
+ _sndSubFile += soundsLeft;
+ break;
+ } else {
+ ++_sndSubFile;
+ --soundsLeft;
+ }
+ }
+}
+
+void AccessEngine::printText(ASurface *s, const Common::String &msg) {
+ Common::String lines = msg;
+ Common::String line;
+ int width = 0;
+
+ for (;;) {
+ bool lastLine = _fonts._font2.getLine(lines, s->_maxChars * 6, line, width);
+
+ // Set font colors
+ _fonts._font2._fontColors[0] = 0;
+ _fonts._font2._fontColors[1] = 28;
+ _fonts._font2._fontColors[2] = 29;
+ _fonts._font2._fontColors[3] = 30;
+ _fonts._font2.drawString(s, line, s->_printOrg);
+
+ s->_printOrg = Common::Point(s->_printStart.x, s->_printOrg.y + 9);
+
+ if (s->_printOrg.y >_printEnd && !lastLine) {
+ _events->waitKeyMouse();
+ s->copyBuffer(&_buffer2);
+ s->_printOrg.y = s->_printStart.y;
+ }
+
+ if (lastLine)
+ break;
+ }
+ _events->waitKeyMouse();
+}
+
+
+void AccessEngine::plotList() {
+ _player->calcPlayer();
+ plotList1();
+}
+
+void AccessEngine::plotList1() {
+ for (uint idx = 0; idx < _images.size(); ++idx) {
+ ImageEntry &ie = _images[idx];
+
+ _imgUnscaled = (ie._flags & IMGFLAG_UNSCALED) != 0;
+ Common::Point pt = ie._position - _screen->_bufferStart;
+ SpriteResource *sprites = ie._spritesPtr;
+ SpriteFrame *frame = sprites->getFrame(ie._frameNumber);
+
+ Common::Rect bounds(pt.x, pt.y, pt.x + frame->w, pt.y + frame->h);
+ if (!_imgUnscaled) {
+ bounds.setWidth(_screen->_scaleTable1[frame->w]);
+ bounds.setHeight(_screen->_scaleTable1[frame->h]);
+ }
+
+ // Make a copy - some of the drawing methods I've adapted need the full
+ // scaled dimensions on-screen, and handle clipping themselves
+ Common::Rect destBounds = bounds;
+
+ if (_buffer2.clip(bounds)) {
+ ie._flags |= IMGFLAG_CROPPED;
+ } else {
+ ie._flags &= ~IMGFLAG_CROPPED;
+ if (_buffer2._leftSkip != 0 || _buffer2._rightSkip != 0
+ || _buffer2._topSkip != 0 || _buffer2._bottomSkip != 0)
+ ie._flags |= IMGFLAG_CROPPED;
+
+ _newRects.push_back(bounds);
+
+ if (!_imgUnscaled) {
+ _buffer2._rightSkip /= _scale;
+ bounds.setWidth(bounds.width() / _scale);
+
+ if (ie._flags & IMGFLAG_BACKWARDS) {
+ _buffer2.sPlotB(frame, destBounds);
+ } else {
+ _buffer2.sPlotF(frame, destBounds);
+ }
+ } else {
+ if (ie._flags & IMGFLAG_BACKWARDS) {
+ _buffer2.plotB(frame, Common::Point(destBounds.left, destBounds.top));
+ } else {
+ _buffer2.plotF(frame, Common::Point(destBounds.left, destBounds.top));
+ }
+ }
+ }
+
+ ie._flags |= IMGFLAG_DRAWN;
+ }
+}
+
+void AccessEngine::copyBlocks() {
+ // Copy the block list from the previous frame
+ for (uint i = 0; i < _oldRects.size(); ++i) {
+ _screen->copyBlock(&_buffer2, _oldRects[i]);
+ }
+
+ copyRects();
+}
+
+void AccessEngine::copyRects() {
+ _oldRects.clear();
+ for (uint i = 0; i < _newRects.size(); ++i) {
+ _screen->copyBlock(&_buffer2, _newRects[i]);
+ _oldRects.push_back(_newRects[i]);
+ }
+}
+
+void AccessEngine::copyBF1BF2() {
+ _buffer2.copyRectToSurface(_buffer1, 0, 0,
+ Common::Rect(_scrollX, _scrollY,
+ _scrollX + _screen->_vWindowBytesWide,
+ _scrollY + _screen->_vWindowLinesTall));
+}
+
+void AccessEngine::copyBF2Vid() {
+ const byte *srcP = (const byte *)_buffer2.getPixels();
+ byte *destP = (byte *)_screen->getBasePtr(_screen->_windowXAdd,
+ _screen->_windowYAdd + _screen->_screenYOff);
+
+ for (int yp = 0; yp < _screen->_vWindowLinesTall; ++yp) {
+ Common::copy(srcP, srcP + _screen->_vWindowBytesWide, destP);
+ srcP += _buffer2.pitch;
+ destP += _screen->pitch;
+ }
+
+ // Add dirty rect for affected area
+ Common::Rect r(_screen->_vWindowBytesWide, _screen->_vWindowLinesTall);
+ r.moveTo(_screen->_windowXAdd, _screen->_windowYAdd + _screen->_screenYOff);
+ _screen->addDirtyRect(r);
+}
+
+void AccessEngine::playVideo(int videoNum, const Common::Point &pt) {
+ _video->setVideo(_screen, pt, FileIdent(96, videoNum), 10);
+
+ while (!shouldQuit() && !_video->_videoEnd) {
+ _video->playVideo();
+ _events->pollEventsAndWait();
+ }
+}
+
+void AccessEngine::doLoadSave() {
+ error("TODO: doLoadSave");
+}
+
+void AccessEngine::freeChar() {
+ _scripts->freeScriptData();
+ _animation->clearTimers();
+ _animation->freeAnimationData();
+}
+
+Common::Error AccessEngine::saveGameState(int slot, const Common::String &desc) {
+ Common::OutSaveFile *out = g_system->getSavefileManager()->openForSaving(
+ generateSaveName(slot));
+ if (!out)
+ return Common::kCreatingFileFailed;
+
+ AccessSavegameHeader header;
+ header._saveName = desc;
+ writeSavegameHeader(out, header);
+
+ Common::Serializer s(nullptr, out);
+ synchronize(s);
+
+ out->finalize();
+ delete out;
+
+ return Common::kNoError;
+}
+
+Common::Error AccessEngine::loadGameState(int slot) {
+ Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(
+ generateSaveName(slot));
+ if (!saveFile)
+ return Common::kReadingFailed;
+
+ Common::Serializer s(saveFile, nullptr);
+
+ // Load the savaegame header
+ AccessSavegameHeader header;
+ if (!readSavegameHeader(saveFile, header))
+ error("Invalid savegame");
+
+ if (header._thumbnail) {
+ header._thumbnail->free();
+ delete header._thumbnail;
+ }
+
+ // Load most of the savegame data
+ synchronize(s);
+ delete saveFile;
+
+ // Set extra post-load state
+ _room->_function = FN_CLEAR1;
+ _timers._timersSavedFlag = false;
+ _events->clearEvents();
+
+ return Common::kNoError;
+}
+
+Common::String AccessEngine::generateSaveName(int slot) {
+ return Common::String::format("%s.%03d", _targetName.c_str(), slot);
+}
+
+bool AccessEngine::canLoadGameStateCurrently() {
+ return _canSaveLoad;
+}
+
+bool AccessEngine::canSaveGameStateCurrently() {
+ return _canSaveLoad;
+}
+
+void AccessEngine::synchronize(Common::Serializer &s) {
+ s.syncAsUint16LE(_conversation);
+ s.syncAsUint16LE(_currentMan);
+ s.syncAsUint32LE(_newTime);
+ s.syncAsUint32LE(_newDate);
+
+ for (int i = 0; i < 256; ++i)
+ s.syncAsUint16LE(_flags[i]);
+ for (int i = 0; i < 100; ++i)
+ s.syncAsByte(_establishTable[i]);
+
+ // Synchronize sub-objects
+ _timers.synchronize(s);
+ _inventory->synchronize(s);
+ _player->synchronize(s);
+}
+
+const char *const SAVEGAME_STR = "ACCESS";
+#define SAVEGAME_STR_SIZE 6
+
+bool AccessEngine::readSavegameHeader(Common::InSaveFile *in, AccessSavegameHeader &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 > ACCESS_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 AccessEngine::writeSavegameHeader(Common::OutSaveFile *out, AccessSavegameHeader &header) {
+ // Write out a savegame header
+ out->write(SAVEGAME_STR, SAVEGAME_STR_SIZE + 1);
+
+ out->writeByte(ACCESS_SAVEGAME_VERSION);
+
+ // Write savegame name
+ out->writeString(header._saveName);
+ out->writeByte('\0');
+
+ // Write a thumbnail of the screen
+ uint8 thumbPalette[PALETTE_SIZE];
+ _screen->getPalette(thumbPalette);
+ Graphics::Surface saveThumb;
+ ::createThumbnail(&saveThumb, (const byte *)_screen->getPixels(),
+ _screen->w, _screen->h, thumbPalette);
+ Graphics::saveThumbnail(*out, saveThumb);
+ saveThumb.free();
+
+ // 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(_events->getFrameCounter());
+}
+
+bool AccessEngine::shouldQuitOrRestart() {
+ return shouldQuit() || _restartFl;
+}
+} // End of namespace Access
diff --git a/engines/access/access.h b/engines/access/access.h
new file mode 100644
index 0000000000..be007e0cb8
--- /dev/null
+++ b/engines/access/access.h
@@ -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.
+ *
+ */
+
+#ifndef ACCESS_ACCESS_H
+#define ACCESS_ACCESS_H
+
+#include "common/scummsys.h"
+#include "common/system.h"
+#include "common/error.h"
+#include "common/random.h"
+#include "common/savefile.h"
+#include "common/serializer.h"
+#include "common/util.h"
+#include "engines/engine.h"
+#include "graphics/surface.h"
+#include "access/animation.h"
+#include "access/bubble_box.h"
+#include "access/char.h"
+#include "access/data.h"
+#include "access/debugger.h"
+#include "access/events.h"
+#include "access/files.h"
+#include "access/font.h"
+#include "access/inventory.h"
+#include "access/player.h"
+#include "access/room.h"
+#include "access/screen.h"
+#include "access/scripts.h"
+#include "access/sound.h"
+#include "access/video.h"
+
+/**
+ * This is the namespace of the Access engine.
+ *
+ * Status of this engine: In Development
+ *
+ * Games using this engine:
+ * - Amazon: Guardians of Eden
+ */
+namespace Access {
+
+enum {
+ GType_Amazon = 1,
+ GType_MartianMemorandum = 2,
+ GType_Noctropolis = 3
+};
+
+enum AccessDebugChannels {
+ kDebugPath = 1 << 0,
+ kDebugScripts = 1 << 1,
+ kDebugGraphics = 1 << 2,
+ kDebugSound = 1 << 3
+};
+
+struct AccessGameDescription;
+
+extern const char *const _estTable[];
+
+#define ACCESS_SAVEGAME_VERSION 1
+
+struct AccessSavegameHeader {
+ uint8 _version;
+ Common::String _saveName;
+ Graphics::Surface *_thumbnail;
+ int _year, _month, _day;
+ int _hour, _minute;
+ int _totalFrames;
+};
+
+class AccessEngine : public Engine {
+private:
+ uint32 _lastTime, _curTime;
+
+ /**
+ * Handles basic initialization
+ */
+ void initialize();
+
+ /**
+ * Set VGA mode
+ */
+ void setVGA();
+
+protected:
+ const AccessGameDescription *_gameDescription;
+ Common::RandomSource _randomSource;
+ int _loadSaveSlot;
+
+ /**
+ * Main handler for showing game rooms
+ */
+ void doRoom();
+
+ /**
+ * Support method that generates a savegame name
+ * @param slot Slot number
+ */
+ Common::String generateSaveName(int slot);
+
+ /**
+ * Play back an entire video
+ */
+ void playVideo(int videoNum, const Common::Point &pt);
+
+ // Engine APIs
+ virtual Common::Error run();
+ virtual bool hasFeature(EngineFeature f) const;
+protected:
+ /**
+ * Play the game
+ */
+ virtual void playGame() = 0;
+
+ /**
+ * Synchronize savegame data
+ */
+ virtual void synchronize(Common::Serializer &s);
+public:
+ AnimationManager *_animation;
+ BubbleBox *_bubbleBox;
+ CharManager *_char;
+ Debugger *_debugger;
+ EventsManager *_events;
+ FileManager *_files;
+ InventoryManager *_inventory;
+ Player *_player;
+ Room *_room;
+ Screen *_screen;
+ Scripts *_scripts;
+ SoundManager *_sound;
+ MusicManager *_midi;
+ VideoPlayer *_video;
+
+ ASurface *_destIn;
+ ASurface *_current;
+ ASurface _buffer1;
+ ASurface _buffer2;
+ ASurface _vidBuf;
+ int _vidX, _vidY;
+ Common::Array<CharEntry *> _charTable;
+ SpriteResource *_objectsTable[100];
+ bool _establishTable[100];
+ bool _establishFlag;
+ int _establishMode;
+ int _establishGroup;
+ int _establishCtrlTblOfs;
+ int _numAnimTimers;
+ TimerList _timers;
+ DeathList _deaths;
+ FontManager _fonts;
+ Common::Array<Common::Rect> _newRects;
+ Common::Array<Common::Rect> _oldRects;
+ Common::Array<ExtraCell> _extraCells;
+ ImageEntryList _images;
+ int _mouseMode;
+
+ int _currentManOld;
+ int _converseMode;
+ int _startAboutBox;
+ int _startTravelBox;
+ bool _currentCharFlag;
+ bool _boxSelect;
+ int _scale;
+ int _scaleH1, _scaleH2;
+ int _scaleN1;
+ int _scaleT1;
+ int _scaleMaxY;
+ int _scaleI;
+ int _scrollX, _scrollY;
+ int _scrollCol, _scrollRow;
+ bool _imgUnscaled;
+ bool _canSaveLoad;
+
+ Resource *_establish;
+ int _printEnd;
+ int _txtPages;
+ int _narateFile;
+ int _sndSubFile;
+ int _countTbl[6];
+
+ // Fields that are included in savegames
+ int _conversation;
+ int _currentMan;
+ uint32 _newTime;
+ uint32 _newDate;
+ int _flags[256];
+
+ bool _clearSummaryFlag;
+ bool _cheatFl;
+ bool _restartFl;
+ // Fields mapped into the flags array
+ int &_useItem;
+ int &_startup;
+ int &_manScaleOff;
+
+public:
+ AccessEngine(OSystem *syst, const AccessGameDescription *gameDesc);
+ virtual ~AccessEngine();
+
+ virtual void dead(int deathId) = 0;
+
+ uint32 getFeatures() const;
+ bool isCD() const;
+ bool isDemo() const;
+ Common::Language getLanguage() const;
+ Common::Platform getPlatform() const;
+ uint16 getVersion() const;
+ uint32 getGameID() const;
+ uint32 getGameFeatures() const;
+ bool shouldQuitOrRestart();
+
+ int getRandomNumber(int maxNumber);
+
+ void loadCells(Common::Array<CellIdent> &cells);
+
+ /**
+ * Free the sprites list
+ */
+ void freeCells();
+
+ virtual void establish(int esatabIndex, int sub) = 0;
+
+ void plotList();
+ void plotList1();
+
+ void copyBlocks();
+
+ void copyRects();
+
+ void copyBF1BF2();
+
+ void copyBF2Vid();
+
+ void doLoadSave();
+
+ void freeChar();
+
+ /**
+ * Draw a string on a given surface and update text positioning
+ */
+ void printText(ASurface *s, const Common::String &msg);
+ void speakText(ASurface *s, const Common::String &msg);
+
+ /**
+ * Load a savegame
+ */
+ virtual Common::Error loadGameState(int slot);
+
+ /**
+ * Save the game
+ */
+ virtual Common::Error saveGameState(int slot, const Common::String &desc);
+
+ /**
+ * Returns true if a savegame can currently be loaded
+ */
+ bool canLoadGameStateCurrently();
+
+ /**
+ * Returns true if the game can currently be saved
+ */
+ bool canSaveGameStateCurrently();
+
+ /**
+ * Read in a savegame header
+ */
+ static bool readSavegameHeader(Common::InSaveFile *in, AccessSavegameHeader &header);
+
+ /**
+ * Write out a savegame header
+ */
+ void writeSavegameHeader(Common::OutSaveFile *out, AccessSavegameHeader &header);
+};
+
+} // End of namespace Access
+
+#endif /* ACCESS_ACCESS_H */
diff --git a/engines/access/amazon/amazon_game.cpp b/engines/access/amazon/amazon_game.cpp
new file mode 100644
index 0000000000..4c9df7b8ff
--- /dev/null
+++ b/engines/access/amazon/amazon_game.cpp
@@ -0,0 +1,786 @@
+/* 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 "access/resources.h"
+#include "access/amazon/amazon_game.h"
+#include "access/amazon/amazon_resources.h"
+#include "access/amazon/amazon_room.h"
+#include "access/amazon/amazon_scripts.h"
+
+namespace Access {
+
+namespace Amazon {
+
+AmazonEngine::AmazonEngine(OSystem *syst, const AccessGameDescription *gameDesc)
+ : AccessEngine(syst, gameDesc), _guardLocation(_flags[122]), _guardFind(_flags[128]),
+ _helpLevel(_flags[167]), _jasMayaFlag(_flags[168]), _moreHelp(_flags[169]),
+ _flashbackFlag(_flags[171]), _riverFlag(_flags[185]), _aniOutFlag(_flags[195]),
+ _badEnd(_flags[218]), _noHints(_flags[219]), _aniFlag(_flags[229]),
+ _allenFlag(_flags[237]), _noSound(_flags[239]) {
+ _ant = nullptr;
+ _cast = nullptr;
+ _guard = nullptr;
+ _jungle = nullptr;
+ _opening = nullptr;
+ _plane = nullptr;
+ _river = nullptr;
+
+ _charSegSwitch = false;
+
+ _oldTitleChapter = _chapter = 0;
+ _updateChapter = -1;
+ _rawInactiveX = 0;
+ _rawInactiveY = 0;
+ _inactiveYOff = 0;
+ _hintLevel = 0;
+
+ Common::fill(&_tileData[0], &_tileData[0] + sizeof(_tileData), 0);
+ Common::fill(&_help1[0], &_help1[0] + sizeof(_help1), 0);
+ Common::fill(&_help2[0], &_help2[0] + sizeof(_help2), 0);
+ Common::fill(&_help3[0], &_help3[0] + sizeof(_help3), 0);
+ _helpTbl[0] = _help1;
+ _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._flags = _inactive._frameNumber = _inactive._offsetY = 0;
+ _inactive._position = Common::Point(0, 0);
+}
+
+AmazonEngine::~AmazonEngine() {
+ delete _inactive._altSpritesPtr;
+
+ delete _ant;
+ delete _cast;
+ delete _guard;
+ delete _jungle;
+ delete _opening;
+ delete _plane;
+ delete _river;
+}
+
+void AmazonEngine::freeInactivePlayer() {
+ delete _inactive._altSpritesPtr;
+ _inactive._altSpritesPtr = nullptr;
+}
+
+void AmazonEngine::configSelect() {
+ // Initialize fields contained in the config file.
+ _hintLevel = 3;
+}
+
+void AmazonEngine::initObjects() {
+ _room = new AmazonRoom(this);
+ _scripts = new AmazonScripts(this);
+
+ _ant = new Ant(this);
+ _cast = new Cast(this);
+ _guard = new Guard(this);
+ _jungle = new Jungle(this);
+ _opening = new Opening(this);
+ _plane = new Plane(this);
+ _river = new River(this);
+}
+
+void AmazonEngine::playGame() {
+ // Initialize Amazon game-specific objects
+ initObjects();
+
+ // Setup the game
+ setupGame();
+ configSelect();
+
+ if (_loadSaveSlot == -1) {
+ // Do introduction
+ _opening->doIntroduction();
+ if (shouldQuit())
+ return;
+ }
+
+ do {
+ _restartFl = false;
+ _screen->clearScreen();
+ _screen->setPanel(0);
+ _screen->forceFadeOut();
+ _events->showCursor();
+
+ initVariables();
+
+ // If there's a pending savegame to load, load it
+ if (_loadSaveSlot != -1) {
+ loadGameState(_loadSaveSlot);
+ _loadSaveSlot = -1;
+ }
+
+ // Execute the room
+ _room->doRoom();
+ } while (_restartFl);
+}
+
+void AmazonEngine::setupGame() {
+ // Load death list
+ if (isDemo()) {
+ _deaths.resize(34);
+ for (int i = 0; i < 34; ++i) {
+ _deaths[i]._screenId = DEATH_SCREENS_DEMO[i];
+ _deaths[i]._msg = DEATH_TEXT_DEMO[i];
+ }
+ } else {
+ _deaths.resize(58);
+ for (int i = 0; i < 58; ++i) {
+ _deaths[i]._screenId = DEATH_SCREENS[i];
+ _deaths[i]._msg = DEATH_TEXT[i];
+ }
+ }
+ _deaths._cells.resize(13);
+ for (int i = 0; i < 13; ++i)
+ _deaths._cells[i] = CellIdent(DEATH_CELLS[i][0], DEATH_CELLS[i][1], DEATH_CELLS[i][2]);
+
+ // Miscellaneous
+ _fonts._font1.load(FONT6x6_INDEX, FONT6x6_DATA);
+ _fonts._font2.load(FONT2_INDEX, FONT2_DATA);
+
+ initVariables();
+}
+
+void AmazonEngine::initVariables() {
+ _chapter = 1;
+ // Set player room and position
+ if (isDemo())
+ _player->_roomNumber = 33;
+ else
+ _player->_roomNumber = 4;
+
+ _converseMode = 0;
+ _inventory->_startInvItem = 0;
+ _inventory->_startInvBox = 0;
+ Common::fill(&_objectsTable[0], &_objectsTable[100], (SpriteResource *)nullptr);
+ _player->_playerOff = false;
+
+ // Setup timers
+ const int TIMER_DEFAULTS[] = { 3, 10, 8, 1, 1, 1, 1, 2 };
+ for (int i = 0; i < 32; ++i) {
+ TimerEntry te;
+ te._initTm = te._timer = (i < 8) ? TIMER_DEFAULTS[i] : 1;
+ te._flag = 1;
+
+ _timers.push_back(te);
+ }
+
+ _player->_playerX = _player->_rawPlayer.x = TRAVEL_POS[_player->_roomNumber][0];
+ _player->_playerY = _player->_rawPlayer.y = TRAVEL_POS[_player->_roomNumber][1];
+ _room->_selectCommand = -1;
+ _events->setNormalCursor(CURSOR_CROSSHAIRS);
+ _mouseMode = 0;
+ _numAnimTimers = 0;
+}
+
+void AmazonEngine::establish(int screenId, int esatabIndex) {
+ _establishMode = 0;
+ _establishGroup = 0;
+ doEstablish(screenId, esatabIndex);
+}
+
+void AmazonEngine::establishCenter(int screenId, int esatabIndex) {
+ _establishMode = 1;
+ doEstablish(screenId, esatabIndex);
+}
+
+const char *const _estTable[] = { "ETEXT0.DAT", "ETEXT1.DAT", "ETEXT2.DAT", "ETEXT3.DAT" };
+
+void AmazonEngine::loadEstablish(int estabIndex) {
+ if (!_files->existFile("ETEXT.DAT")) {
+ int oldGroup = _establishGroup;
+ _establishGroup = 0;
+
+ _establish = _files->loadFile(_estTable[oldGroup]);
+ _establishCtrlTblOfs = READ_LE_UINT16(_establish->data());
+
+ int ofs = _establishCtrlTblOfs + (estabIndex * 2);
+ int idx = READ_LE_UINT16(_establish->data() + ofs);
+ _narateFile = READ_LE_UINT16(_establish->data() + idx);
+ _txtPages = READ_LE_UINT16(_establish->data() + idx + 2);
+
+ if (!_txtPages)
+ return;
+
+ _sndSubFile = READ_LE_UINT16(_establish->data() + idx + 4);
+ for (int i = 0; i < _txtPages; ++i)
+ _countTbl[i] = READ_LE_UINT16(_establish->data() + idx + 6 + (2 * i));
+ } else {
+ _establishGroup = 0;
+ _narateFile = 0;
+ _txtPages = 0;
+ _sndSubFile = 0;
+ _establish = _files->loadFile("ETEXT.DAT");
+ }
+}
+
+void AmazonEngine::doEstablish(int screenId, int estabIndex) {
+ _establishMode = 1;
+
+ _events->clearEvents();
+ _screen->forceFadeOut();
+ _screen->clearScreen();
+ _screen->setPanel(3);
+
+ if (screenId != -1) {
+ _files->loadScreen(95, screenId);
+ _buffer2.copyBuffer(_screen);
+ }
+
+ _screen->setIconPalette();
+ _screen->forceFadeIn();
+
+ _fonts._charSet._lo = 1;
+ _fonts._charSet._hi = 10;
+ _fonts._charFor._lo = 29;
+ _fonts._charFor._hi = 32;
+
+ _screen->_maxChars = 37;
+ _screen->_printOrg = _screen->_printStart = Common::Point(48, 35);
+ loadEstablish(estabIndex);
+ uint16 msgOffset;
+ if (!isCD())
+ msgOffset = READ_LE_UINT16(_establish->data() + (estabIndex * 2));
+ else
+ msgOffset = READ_LE_UINT16(_establish->data() + (estabIndex * 2) + 2);
+
+ _printEnd = 155;
+ Common::String msg((const char *)_establish->data() + msgOffset);
+
+ if ((_txtPages == 0) || !isCD()) {
+ printText(_screen, msg);
+ } else {
+ speakText(_screen, msg);
+ }
+
+ _screen->forceFadeOut();
+ _screen->clearScreen();
+
+ delete _establish;
+ _establish = nullptr;
+
+ if (_establishMode == 0)
+ _room->init4Quads();
+}
+
+const char *const _tileFiles[] = {
+ "GRAY.BLK", "RED.BLK", "LTBROWN.BLK", "DKBROWN.BLK", "VIOLET.BLK", "LITEBLUE.BLK",
+ "DARKBLUE.BLK", "CYAN.BLK", "GREEN.BLK", "OLIVE.BLK", "GRAY.BLK", "RED.BLK",
+ "LTBROWN.BLK", "DKBROWN.BLK", "VIOLET.BLK", "OLIVE.BLK"
+};
+
+void AmazonEngine::tileScreen() {
+ if (!_screen->_vesaMode)
+ return;
+
+ if (!_clearSummaryFlag && (_oldTitleChapter == _chapter))
+ return;
+
+ _oldTitleChapter = _chapter;
+ int idx = _chapter - 1;
+
+ if (!_files->existFile(_tileFiles[idx]))
+ return;
+
+ Resource *res = _files->loadFile(_tileFiles[idx]);
+ int x = res->_stream->readSint16LE();
+ int y = res->_stream->readSint16LE();
+ int size = ((x + 2) * y) + 10;
+
+ for (int i = 0; i < size; ++i)
+ _tileData[i] = res->_stream->readByte();
+
+ // CHECKME: Depending on the Vesa mode during initialization, 400 or 480
+ Common::Point tilePos;
+ for (tilePos.y = 0; tilePos.y < 480; tilePos.y += y) {
+ for (tilePos.x = 0; tilePos.x < 640; tilePos.x += x)
+ warning("TODO: DRAWOBJECT");
+ }
+
+ delete res;
+}
+
+void AmazonEngine::updateSummary(int chap) {
+ if (!_screen->_vesaMode)
+ return;
+
+ int chapter = chap;
+ if (chapter > 16)
+ chapter = 16;
+
+ if (!_clearSummaryFlag && (chapter == _updateChapter))
+ return;
+
+ _clearSummaryFlag = false;
+ int celSubFile = 0;
+ _updateChapter = chapter;
+ Common::Array<CellIdent> summaryCells;
+ loadCells(summaryCells);
+
+ for (int i = celSubFile; i < 16; ++i) {
+ if (i > 7)
+ warning("TODO: DRAWOBJECT");
+ else
+ warning("TODO: DRAWOBJECT");
+ }
+
+ delete _objectsTable[93];
+ _objectsTable[93] = nullptr;
+
+ for (int i = 1; i <= _updateChapter; ++i) {
+ celSubFile = i;
+ loadCells(summaryCells);
+ if (i > 8)
+ warning("TODO: DRAWOBJECT");
+ else
+ warning("TODO: DRAWOBJECT");
+
+ delete _objectsTable[93];
+ _objectsTable[93] = nullptr;
+ }
+}
+
+void AmazonEngine::calcIQ() {
+ int tmpIQ = 170;
+ for (int i = 0; i < 256; i++) {
+ if (_help1[i] == 1)
+ tmpIQ -= 3;
+ }
+
+ for (int i = 0; i < 256; i++) {
+ if (_help2[i] == 1)
+ tmpIQ -= 5;
+ }
+
+ for (int i = 0; i < 256; i++) {
+ if (_help3[i] == 1)
+ tmpIQ -= 10;
+ }
+
+ if (tmpIQ < 0)
+ tmpIQ = 0;
+
+ _iqValue = tmpIQ;
+
+ if (_iqValue <= 100)
+ _badEnd = 1;
+
+ if (_iqValue <= 0)
+ _noHints = 1;
+}
+
+void AmazonEngine::helpTitle() {
+ int width = _fonts._font2.stringWidth(_bubbleBox->_bubbleTitle);
+ int posX = 160 - (width / 2);
+ _fonts._font2._fontColors[0] = 0;
+ _fonts._font2._fontColors[1] = 33;
+ _fonts._font2._fontColors[2] = 34;
+ _fonts._font2._fontColors[3] = 35;
+ _fonts._font2.drawString(_screen, _bubbleBox->_bubbleTitle, Common::Point(posX, 24));
+
+ width = _fonts._font2.stringWidth(HELPLVLTXT[_helpLevel]);
+ posX = 160 - (width / 2);
+ _fonts._font2._fontColors[0] = 0;
+ _fonts._font2._fontColors[1] = 10;
+ _fonts._font2._fontColors[2] = 11;
+ _fonts._font2._fontColors[3] = 12;
+ _fonts._font2.drawString(_screen, HELPLVLTXT[_helpLevel], Common::Point(posX, 36));
+
+ Common::String iqText = "IQ: ";
+ calcIQ();
+ Common::String scoreIQ = Common::String::format("%d", _iqValue);
+ while (scoreIQ.size() < 4)
+ scoreIQ = " " + scoreIQ;
+
+ iqText += scoreIQ;
+ int index = _iqValue;
+ if (index == 170)
+ index = 169;
+
+ index /= 20;
+
+ iqText += " ";
+ iqText += IQLABELS[index];
+
+ width = _fonts._font2.stringWidth(iqText);
+ posX = 160 - (width / 2);
+ _fonts._font2._fontColors[0] = 0;
+ _fonts._font2._fontColors[1] = 10;
+ _fonts._font2._fontColors[2] = 11;
+ _fonts._font2._fontColors[3] = 12;
+ _fonts._font2.drawString(_screen, iqText, Common::Point(posX, 44));
+}
+
+void AmazonEngine::drawHelpText(const Common::String &msg) {
+ _screen->_maxChars = 39;
+ _screen->_printOrg = Common::Point(26, 58);
+ _screen->_printStart = Common::Point(26, 58);
+
+ Common::String lines = msg;
+ Common::String line;
+ int width = 0;
+ bool lastLine = false;
+ do {
+ lastLine = _fonts._font2.getLine(lines, _screen->_maxChars * 6, line, width);
+
+ // Set font colors
+ _fonts._font2._fontColors[0] = 0;
+ _fonts._font2._fontColors[1] = 27;
+ _fonts._font2._fontColors[2] = 28;
+ _fonts._font2._fontColors[3] = 29;
+
+ _fonts._font2.drawString(_screen, line, _screen->_printOrg);
+ _screen->_printOrg = Common::Point(_screen->_printStart.x, _screen->_printOrg.y + 8);
+ } while (!lastLine);
+
+ _events->showCursor();
+}
+
+void AmazonEngine::drawHelp(const Common::String str) {
+ _events->hideCursor();
+ if (_useItem == 0) {
+ _buffer2.copyBuffer(_screen);
+ if (_screen->_vesaMode) {
+ _screen->setPanel(2);
+ _screen->saveScreen();
+ }
+ _screen->savePalette();
+ _screen->fadeOut();
+ _screen->clearBuffer();
+ if (_moreHelp == 1) {
+ // Set cells
+ Common::Array<CellIdent> cells;
+ cells.push_back(CellIdent(95, 95, 3));
+ loadCells(cells);
+ }
+ }
+
+ _files->loadScreen(95, 2);
+ if (_moreHelp == 1) {
+ ASurface *oldDest = _destIn;
+ _destIn = _screen;
+ int oldClip = _screen->_clipHeight;
+ _screen->_clipHeight = 200;
+ _screen->plotImage(_objectsTable[95], 0, Common::Point(76, 168));
+ _destIn = oldDest;
+ _screen->_clipHeight = oldClip;
+ }
+
+ if ((_useItem == 0) && (_screen->_vesaMode == 0))
+ _screen->fadeIn();
+
+ helpTitle();
+ drawHelpText(str);
+}
+
+void AmazonEngine::startChapter(int chapter) {
+ _chapter = chapter;
+ assert(_chapter <= 14);
+
+ if (chapter != 1) {
+ _room->clearRoom();
+ freeChar();
+
+ _midi->newMusic(32, 0);
+ playVideo(0, Common::Point());
+ if (shouldQuit())
+ return;
+
+ _events->debounceLeft();
+ _events->zeroKeys();
+ playVideo(_chapter, Common::Point(4, 113));
+ if (shouldQuit())
+ return;
+
+ _timers[20]._timer = 500;
+ _timers[20]._initTm = 500;
+ _timers[20]._flag++;
+ _sound->freeSounds();
+
+ if (isCD()) {
+ _sound->loadSoundTable(0, 115, 0);
+ _sound->loadSoundTable(1, 115, 1);
+ _sound->playSound(0);
+ _sound->playSound(1);
+
+ _sound->freeSounds();
+ }
+
+ // Wait loop
+ while (!shouldQuit() && !_events->isKeyMousePressed() && _timers[20]._flag) {
+ _events->pollEventsAndWait();
+ }
+ }
+
+ _screen->forceFadeOut();
+ _events->debounceLeft();
+ _events->zeroKeys();
+ _screen->clearScreen();
+
+ _screen->setPanel(3);
+
+ // Set up cells for the chapter display
+ Common::Array<CellIdent> chapterCells;
+ chapterCells.push_back(CellIdent(0, 96, 17));
+ const int *chapCell = &CHAPTER_CELLS[_chapter - 1][0];
+ chapterCells.push_back(CellIdent(chapCell[0], chapCell[1], chapCell[2]));
+ loadCells(chapterCells);
+
+ // Show chapter screen
+ _files->loadScreen(96, 15);
+ _buffer2.blitFrom(*_screen);
+
+ const int *chapImg = &CHAPTER_TABLE[_chapter - 1][0];
+ _screen->plotImage(_objectsTable[0], _chapter - 1,
+ Common::Point(chapImg[1], chapImg[2]));
+ _screen->plotImage(_objectsTable[_chapter], 0,
+ Common::Point(chapImg[3], chapImg[4]));
+ if (chapter == 14)
+ _screen->plotImage(_objectsTable[_chapter], 1, Common::Point(169, 76));
+
+ _midi->newMusic(chapImg[4], 1);
+ _midi->newMusic(33, 0);
+ _screen->forceFadeIn();
+
+ _timers[20]._timer = 950;
+ _timers[20]._initTm = 950;
+ _timers[20]._flag++;
+
+ // Wait loop
+ while (!shouldQuit() && !_events->isKeyMousePressed() && _timers[20]._flag) {
+ _events->pollEventsAndWait();
+ }
+ if (shouldQuit())
+ return;
+
+ _screen->forceFadeOut();
+ _events->debounceLeft();
+ _events->zeroKeys();
+
+ _screen->clearBuffer();
+ _files->loadScreen(96, 16);
+ _buffer2.blitFrom(*_screen);
+ _screen->plotImage(_objectsTable[0], chapImg[0], Common::Point(90, 7));
+
+ _midi->newMusic(7, 1);
+ _midi->newMusic(34, 0);
+
+ _screen->forceFadeIn();
+ _buffer2.blitFrom(*_screen);
+
+ _fonts._charSet._lo = 1;
+ _fonts._charSet._hi = 10;
+ _fonts._charFor._lo = 55;
+ _fonts._charFor._hi = 0xFF;
+ _screen->_maxChars = 43;
+ _screen->_printOrg = Common::Point(31, 77);
+ _screen->_printStart = Common::Point(31, 77);
+
+ _establishGroup = 1;
+ loadEstablish(0x40 + _chapter);
+ uint16 msgOffset = READ_LE_UINT16(_establish->data() + ((0x40 + _chapter) * 2) + 2);
+ _printEnd = 170;
+
+ Common::String msg((const char *)_establish->data() + msgOffset);
+
+ if ((_txtPages == 0) || !isCD()) {
+ printText(_screen, msg);
+ } else {
+ speakText(_screen, msg);
+ }
+ if (shouldQuit())
+ return;
+
+ _screen->forceFadeOut();
+ _screen->clearBuffer();
+ freeCells();
+
+ _midi->newMusic(_chapter * 2, 1);
+
+ if (chapter != 1 && chapter != 14) {
+ _room->init4Quads();
+ }
+
+ if (chapter == 14) {
+ _conversation = 31;
+ _char->loadChar(_conversation);
+ _events->setCursor(CURSOR_ARROW);
+
+ _images.clear();
+ _oldRects.clear();
+ _scripts->_sequence = 0;
+ _scripts->searchForSequence();
+
+ if (_screen->_vesaMode) {
+ _converseMode = 1;
+ }
+ } else if (chapter != 1) {
+ _player->_roomNumber = CHAPTER_JUMP[_chapter - 1];
+ _room->_function = FN_CLEAR1;
+ _converseMode = 0;
+
+ _scripts->cmdRetPos();
+ }
+}
+
+
+void AmazonEngine::dead(int deathId) {
+ _events->hideCursor();
+ _screen->forceFadeOut();
+ _scripts->cmdFreeSound();
+ _events->debounceLeft();
+ _events->zeroKeys();
+
+ _sound->_soundTable.push_back(SoundEntry(_files->loadFile(98, 44), 1));
+
+ _screen->clearScreen();
+ _screen->setPanel(3);
+
+ if ((deathId == 10) && !isDemo()) {
+ quitGame();
+ _events->pollEvents();
+ return;
+ } else {
+ if (!isDemo())
+ _midi->newMusic(62, 0);
+ _files->_setPaletteFlag = false;
+ _files->loadScreen(94, 0);
+ _files->_setPaletteFlag = true;
+ _buffer2.blitFrom(*_screen);
+
+ if (!isDemo() || deathId != 10) {
+ for (int i = 0; i < 3; ++i) {
+ _sound->playSound(0);
+ _screen->forceFadeIn();
+ _sound->playSound(0);
+ _screen->forceFadeOut();
+
+ _events->pollEvents();
+ if (shouldQuit())
+ return;
+ }
+ }
+
+ if (!isDemo()) {
+ freeCells();
+
+ // Load the cell list for the death screen
+ DeathEntry &de = _deaths[deathId];
+ Common::Array<CellIdent> cells;
+ cells.push_back(_deaths._cells[de._screenId]);
+ loadCells(cells);
+
+ _screen->setDisplayScan();
+ _files->_setPaletteFlag = false;
+ _files->loadScreen(&_buffer2, 94, 1);
+ _screen->setIconPalette();
+
+ _buffer2.plotImage(_objectsTable[0], 0, Common::Point(105, 25));
+ _buffer2.copyTo(_screen);
+ _screen->forceFadeIn();
+
+ _fonts._charSet._hi = 10;
+ _fonts._charSet._lo = 1;
+ _fonts._charFor._lo = 55;
+ _fonts._charFor._hi = 255;
+ _screen->_maxChars = 46;
+ _screen->_printOrg = Common::Point(20, 155);
+ _screen->_printStart = Common::Point(20, 155);
+
+ Common::String &msg = de._msg;
+ _printEnd = 180;
+
+ printText(_screen, msg);
+ _screen->forceFadeOut();
+
+ _midi->newMusic(0, 1);
+ _events->showCursor();
+ _room->clearRoom();
+ freeChar();
+
+ _currentManOld = 1;
+ _player->removeSprite1();
+
+ } else {
+ _files->loadScreen(_screen, 94, _deaths[deathId]._screenId);
+ _screen->forceFadeIn();
+
+ _fonts._charSet._hi = 10;
+ _fonts._charSet._lo = 1;
+ _fonts._charFor._lo = 55;
+ _fonts._charFor._hi = 255;
+ _screen->_maxChars = 49;
+ _screen->_printOrg = Common::Point(15, 165);
+ _screen->_printStart = Common::Point(15, 165);
+
+ Common::String msg = Common::String(_deaths[deathId]._msg);
+ _printEnd = 200;
+
+ printText(_screen, msg);
+ _screen->fadeOut();
+
+ _events->showCursor();
+ _room->clearRoom();
+ freeChar();
+
+ _currentManOld = 1;
+ _player->removeSprite1();
+ }
+
+ // The original was jumping to the restart label in main
+ _restartFl = true;
+ _events->pollEvents();
+ }
+}
+
+void AmazonEngine::synchronize(Common::Serializer &s) {
+ AccessEngine::synchronize(s);
+
+ s.syncAsSint16LE(_chapter);
+ s.syncAsSint16LE(_rawInactiveX);
+ s.syncAsSint16LE(_rawInactiveY);
+ s.syncAsSint16LE(_inactiveYOff);
+
+ for (int i = 0; i < 366; ++i) {
+ s.syncAsByte(_help1[i]);
+ s.syncAsByte(_help2[i]);
+ s.syncAsByte(_help3[i]);
+ }
+
+ _river->synchronize(s);
+ _ant->synchronize(s);
+}
+
+} // End of namespace Amazon
+
+} // End of namespace Access
diff --git a/engines/access/amazon/amazon_game.h b/engines/access/amazon/amazon_game.h
new file mode 100644
index 0000000000..8f6dffe28c
--- /dev/null
+++ b/engines/access/amazon/amazon_game.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 ACCESS_AMAZON_GAME_H
+#define ACCESS_AMAZON_GAME_H
+
+#include "access/access.h"
+#include "access/amazon/amazon_logic.h"
+
+namespace Access {
+
+namespace Amazon {
+
+class AmazonEngine;
+
+class AmazonEngine : public AccessEngine {
+private:
+ byte _tileData[1455];
+ Common::Array<CellIdent> _chapterCells;
+
+ /**
+ * Setup variables for the game
+ */
+ void setupGame();
+
+ /**
+ * Initialize variables found in the config file
+ */
+ void configSelect();
+
+ void initVariables();
+ void initObjects();
+ void calcIQ();
+ void helpTitle();
+ void drawHelpText(const Common::String &msg);
+ void loadEstablish(int estabIndex);
+ void doEstablish(int screenId, int estabIndex);
+
+protected:
+ /**
+ * Play the game
+ */
+ virtual void playGame();
+
+ /**
+ * Synchronize savegame data
+ */
+ virtual void synchronize(Common::Serializer &s);
+public:
+ InactivePlayer _inactive;
+ bool _charSegSwitch;
+ byte _help1[366];
+ byte _help2[366];
+ byte _help3[366];
+ byte *_helpTbl[3];
+
+ // Fields that are mapped to flags
+ int &_guardLocation;
+ int &_guardFind;
+ int &_helpLevel;
+ int &_jasMayaFlag;
+ int &_moreHelp;
+ int &_flashbackFlag;
+ int &_riverFlag;
+ int &_aniOutFlag;
+ int &_badEnd;
+ int &_noHints;
+ int &_aniFlag;
+ int &_allenFlag;
+ int &_noSound;
+
+ // Saved fields
+ int _chapter;
+ int _rawInactiveX;
+ int _rawInactiveY;
+ int _inactiveYOff;
+
+ // Other game specific fields
+ Ant *_ant;
+ Cast *_cast;
+ Guard *_guard;
+ Jungle *_jungle;
+ Opening *_opening;
+ Plane *_plane;
+ River *_river;
+ int _hintLevel;
+ int _updateChapter;
+ int _oldTitleChapter;
+ int _iqValue;
+public:
+ AmazonEngine(OSystem *syst, const AccessGameDescription *gameDesc);
+
+ virtual ~AmazonEngine();
+
+ virtual void dead(int deathId);
+
+ /**
+ * Free the inactive player data
+ */
+ void freeInactivePlayer();
+
+ void drawHelp(const Common::String str);
+
+ virtual void establish(int esatabIndex, int sub);
+
+ void tileScreen();
+ void updateSummary(int chap);
+ void establishCenter(int screenId, int esatabIndex);
+
+ /**
+ * Show the start of a chapter
+ */
+ void startChapter(int chapter);
+};
+
+} // End of namespace Amazon
+
+} // End of namespace Access
+
+#endif /* ACCESS_ACCESS_H */
diff --git a/engines/access/amazon/amazon_logic.cpp b/engines/access/amazon/amazon_logic.cpp
new file mode 100644
index 0000000000..6dffb85e5e
--- /dev/null
+++ b/engines/access/amazon/amazon_logic.cpp
@@ -0,0 +1,2230 @@
+/* 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 "access/access.h"
+#include "access/resources.h"
+#include "access/screen.h"
+#include "access/amazon/amazon_game.h"
+#include "access/amazon/amazon_logic.h"
+#include "access/amazon/amazon_resources.h"
+
+namespace Access {
+
+namespace Amazon {
+
+PannedScene::PannedScene(AmazonEngine *vm) : AmazonManager(vm) {
+ for (int i = 0; i < PAN_SIZE; ++i) {
+ _pan[i]._pObject = nullptr;
+ _pan[i]._pImgNum = 0;
+ _pan[i]._pObjX = _pan[i]._pObjY = _pan[i]._pObjZ = 0;
+ _pan[i]._pObjXl = _pan[i]._pObjYl = 0;
+ }
+
+ _xCount = 0;
+ _xTrack = _yTrack = _zTrack = 0;
+ _xCam = _yCam = _zCam = 0;
+ _pNumObj = 0;
+}
+
+void PannedScene::pan() {
+ _zCam += _zTrack;
+ _xCam += _xTrack;
+ int tx = (_xTrack << 8) / _zCam;
+ _yCam += _yTrack;
+ int ty = (_yTrack << 8) / _zCam;
+
+ if (_vm->_timers[24]._flag != 1) {
+ ++_vm->_timers[24]._flag;
+ for (int i = 0; i < _pNumObj; i++) {
+ _pan[i]._pObjZ += _zTrack;
+ _pan[i]._pObjXl += (_pan[i]._pObjZ * tx) & 0xff;
+ _pan[i]._pObjX += ((_pan[i]._pObjZ * tx) >> 8) + (_pan[i]._pObjXl >> 8);
+ _pan[i]._pObjXl &= 0xff;
+
+ _pan[i]._pObjYl += (_pan[i]._pObjZ * ty) & 0xff;
+ _pan[i]._pObjY += ((_pan[i]._pObjZ * ty) >> 8) + (_pan[i]._pObjYl >> 8);
+ _pan[i]._pObjYl &= 0xff;
+ }
+ }
+
+ for (int i = 0; i < _pNumObj; i++) {
+ ImageEntry ie;
+ ie._flags = IMGFLAG_UNSCALED;
+ ie._position = Common::Point(_pan[i]._pObjX, _pan[i]._pObjY);
+ ie._offsetY = 255;
+ ie._spritesPtr = _pan[i]._pObject;
+ ie._frameNumber = _pan[i]._pImgNum;
+
+ _vm->_images.addToList(ie);
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+CampScene::CampScene(AmazonEngine *vm) : PannedScene(vm) {
+ _skipStart = false;
+}
+
+void CampScene::mWhileDoOpen() {
+ Screen &screen = *_vm->_screen;
+ EventsManager &events = *_vm->_events;
+
+ screen.setDisplayScan();
+ events.hideCursor();
+ screen.forceFadeOut();
+ _skipStart = false;
+ if (_vm->_conversation != 2) {
+ // Cutscene at start of chapter 1
+ screen.setPanel(3);
+ _vm->startChapter(1);
+ _vm->establishCenter(0, 1);
+ }
+
+ Resource *data = _vm->_files->loadFile(1, 0);
+ _vm->_objectsTable[1] = new SpriteResource(_vm, data);
+ delete data;
+
+ _vm->_files->_setPaletteFlag = false;
+ _vm->_files->loadScreen(1, 2);
+ _vm->_buffer2.blitFrom(*_vm->_screen);
+ _vm->_buffer1.blitFrom(*_vm->_screen);
+
+ // Load animation data
+ _vm->_animation->freeAnimationData();
+ Resource *animResource = _vm->_files->loadFile(1, 1);
+ _vm->_animation->loadAnimations(animResource);
+ delete animResource;
+
+ _xTrack = 8;
+ _yTrack = -3;
+ _zTrack = 0;
+ _xCam = _yCam = 0;
+ _zCam = 270;
+ _vm->_timers[24]._timer = _vm->_timers[24]._initTm = 1;
+ ++_vm->_timers[24]._flag;
+ _vm->_timers.updateTimers();
+
+ _pNumObj = 10;
+ for (int i = 0; i < _pNumObj; i++) {
+ _pan[i]._pObject = _vm->_objectsTable[1];
+ _pan[i]._pImgNum = OPENING_OBJS[i][0];
+ _pan[i]._pObjX = OPENING_OBJS[i][1];
+ _pan[i]._pObjY = OPENING_OBJS[i][2];
+ _pan[i]._pObjZ = OPENING_OBJS[i][3];
+ _pan[i]._pObjXl = _pan[i]._pObjYl = 0;
+ }
+
+ _vm->_oldRects.clear();
+ _vm->_newRects.clear();
+ Animation *anim = _vm->_animation->setAnimation(0);
+ _vm->_animation->setAnimTimer(anim);
+ anim = _vm->_animation->setAnimation(1);
+ _vm->_animation->setAnimTimer(anim);
+ _vm->_midi->newMusic(10, 0);
+
+ bool startFl = false;
+ while (!_vm->shouldQuit()) {
+ _vm->_images.clear();
+ _vm->_animation->animate(0);
+ _vm->_animation->animate(1);
+ pan();
+ _vm->_buffer2.copyFrom(_vm->_buffer1);
+ _vm->_newRects.clear();
+ _vm->plotList();
+ _vm->copyBlocks();
+ if (!startFl) {
+ startFl = true;
+ screen.forceFadeIn();
+ }
+
+ events.pollEventsAndWait();
+
+ if (_vm->_events->isKeyMousePressed()) {
+ _skipStart = true;
+ _vm->_midi->newMusic(10, 1);
+ break;
+ }
+
+ if (_xCam > 680) {
+ events._vbCount = 125;
+
+ while (!_vm->shouldQuit() && !events.isKeyMousePressed() && events._vbCount > 0) {
+ events.pollEventsAndWait();
+ }
+ break;
+ }
+ }
+
+ events.showCursor();
+ _vm->_buffer2.copyFrom(*_vm->_screen);
+ _vm->_buffer1.copyFrom(*_vm->_screen);
+
+ _vm->freeCells();
+ _vm->_oldRects.clear();
+ _vm->_newRects.clear();
+ _vm->_numAnimTimers = 0;
+ _vm->_images.clear();
+
+ if (_vm->_conversation == 2) {
+ // Cutscene at end of Chapter 6
+ Resource *spriteData = _vm->_files->loadFile(28, 37);
+ _vm->_objectsTable[28] = new SpriteResource(_vm, spriteData);
+ delete spriteData;
+
+ _vm->_animation->freeAnimationData();
+ animResource = _vm->_files->loadFile(28, 38);
+ _vm->_animation->loadAnimations(animResource);
+ delete animResource;
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+Opening::Opening(AmazonEngine *vm) : CampScene(vm) {
+ _pCount = 0;
+}
+
+void Opening::doIntroduction() {
+ Screen &screen = *_vm->_screen;
+
+ screen.setInitialPalettte();
+ _vm->_events->setCursor(CURSOR_ARROW);
+ _vm->_events->showCursor();
+ screen.setPanel(0);
+ screen.setPalette();
+
+ _vm->_events->setCursor(CURSOR_ARROW);
+ _vm->_events->showCursor();
+ screen.setPanel(3);
+ doTitle();
+
+ if (_vm->shouldQuit() || _skipStart || _vm->isDemo())
+ return;
+
+ screen.setPanel(3);
+ mWhileDoOpen();
+
+ if (_vm->shouldQuit() || _skipStart)
+ return;
+
+ doTent();
+}
+
+void Opening::doCredit() {
+ if (_pCount < 15)
+ return;
+
+ if (_pCount <= 75)
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], _vm->isDemo()? 24 : 0, Common::Point(90, 35));
+ else if (_pCount <= 210)
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 1, Common::Point(65, 35));
+ else if (_pCount <= 272)
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 2, Common::Point(96, 45));
+ else if (_pCount <= 334)
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 3, Common::Point(68, 54));
+ else if (_pCount <= 396)
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 4, Common::Point(103, 54));
+ else if (_pCount <= 458) {
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 5, Common::Point(8, 5));
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 12, Common::Point(88, 55));
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 6, Common::Point(194, 98));
+ } else if (_pCount <= 520) {
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 7, Common::Point(32, 13));
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 8, Common::Point(162, 80));
+ } else if (_pCount <= 580) {
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 9, Common::Point(18, 15));
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 10, Common::Point(164, 81));
+ } else
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 11, Common::Point(106, 55));
+}
+
+void Opening::doCreditDemo() {
+ if (_pCount < 15)
+ return;
+
+ if (_pCount <= 75)
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], _vm->isDemo()? 24 : 0, Common::Point(90, 35));
+ else if (_pCount <= 210)
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 25, Common::Point(82, 35));
+ else if (_pCount <= 272) {
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 23, Common::Point(77, 20));
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 4, Common::Point(50, 35));
+ } else if (_pCount <= 334) {
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 16, Common::Point(200, 70));
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 4, Common::Point(170, 85));
+ } else if (_pCount <= 396) {
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 15, Common::Point(65, 15));
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 2, Common::Point(30, 30));
+ } else if (_pCount <= 458) {
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 19, Common::Point(123, 40));
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 10, Common::Point(115, 55));
+ } else if (_pCount <= 520) {
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 18, Common::Point(50, 15));
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 9, Common::Point(40, 30));
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 0, Common::Point(40, 55));
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 20, Common::Point(198, 95));
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 3, Common::Point(160, 110));
+ } else if (_pCount <= 580) {
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 21, Common::Point(40, 10));
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 6, Common::Point(20, 25));
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 22, Common::Point(145, 50));
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 7, Common::Point(125, 65));
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 12, Common::Point(207, 90));
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 5, Common::Point(200, 105));
+ } else {
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 11, Common::Point(125, 30));
+ _vm->_buffer2.plotImage(_vm->_objectsTable[0], 4, Common::Point(115, 45));
+ }
+}
+
+void Opening::scrollTitle() {
+ _vm->copyBF1BF2();
+ _vm->_newRects.clear();
+ if (_vm->isDemo())
+ doCreditDemo();
+ else
+ doCredit();
+ _vm->copyRects();
+ _vm->copyBF2Vid();
+}
+
+void Opening::doTitle() {
+ Screen &screen = *_vm->_screen;
+
+ screen.setDisplayScan();
+
+ screen.forceFadeOut();
+ _vm->_events->hideCursor();
+
+ if (!_vm->isDemo()) {
+ _vm->_sound->loadSoundTable(0, 98, 30);
+ _vm->_sound->loadSoundTable(1, 98, 8);
+
+ _vm->_files->_setPaletteFlag = false;
+ _vm->_files->loadScreen(0, 3);
+
+ _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;
+
+ Resource *spriteData = _vm->_files->loadFile(0, 2);
+ _vm->_objectsTable[0] = new SpriteResource(_vm, spriteData);
+ delete spriteData;
+
+ _vm->_files->_setPaletteFlag = false;
+ _vm->_files->loadScreen(0, 4);
+ _vm->_sound->playSound(1);
+
+ _vm->_buffer2.copyFrom(*_vm->_screen);
+ _vm->_buffer1.copyFrom(*_vm->_screen);
+
+ const int COUNTDOWN[6] = { 2, 0x80, 1, 0x7d, 0, 0x87 };
+ for (_pCount = 0; _pCount < 3 && !_vm->shouldQuit(); ++_pCount) {
+ _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();
+ if (_vm->_events->_rightButton)
+ _skipStart = true;
+ }
+ }
+ if (_vm->shouldQuit())
+ return;
+
+ _vm->_sound->stopSound();
+ _vm->_sound->playSound(0);
+ screen.forceFadeOut();
+ _vm->_events->_vbCount = 100;
+ while (!_vm->shouldQuit() && _vm->_events->_vbCount > 0)
+ _vm->_events->pollEventsAndWait();
+ if (_vm->shouldQuit())
+ return;
+
+ _vm->_sound->freeSounds();
+ delete _vm->_objectsTable[0];
+ _vm->_objectsTable[0] = nullptr;
+
+ _vm->_files->_setPaletteFlag = false;
+ _vm->_files->loadScreen(0, 5);
+ _vm->_buffer2.blitFrom(*_vm->_screen);
+ _vm->_buffer1.blitFrom(*_vm->_screen);
+ screen.forceFadeIn();
+ _vm->_midi->newMusic(1, 0);
+ _vm->_events->_vbCount = 700;
+ while (!_vm->shouldQuit() && (_vm->_events->_vbCount > 0) && !_vm->_events->isKeyMousePressed()) {
+ _vm->_events->pollEventsAndWait();
+ }
+
+ if (_vm->_events->_rightButton) {
+ _skipStart = true;
+ _vm->_room->clearRoom();
+ _vm->_events->showCursor();
+ return;
+ }
+
+ _vm->_midi->newMusic(1, 1);
+ _vm->_midi->setLoop(false);
+ _vm->_events->zeroKeys();
+ }
+
+ _vm->_buffer1.create(_vm->_screen->w + TILE_WIDTH, _vm->_screen->h);
+ _vm->_room->loadRoom(0);
+ screen.clearScreen();
+ screen.setBufferScan();
+ _vm->_scrollRow = _vm->_scrollCol = 0;
+ _vm->_scrollX = _vm->_scrollY = 0;
+ _vm->_player->_rawPlayer = Common::Point(0, 0);
+ screen.forceFadeOut();
+ _vm->_room->buildScreen();
+ _vm->copyBF2Vid();
+ screen.forceFadeIn();
+ _vm->_oldRects.clear();
+ _vm->_newRects.clear();
+ _vm->_events->clearEvents();
+ _vm->_player->_scrollAmount = 1;
+ _pCount = 0;
+
+ while (!_vm->shouldQuit()) {
+ if (_vm->_events->isKeyMousePressed()) {
+ if (_vm->_events->_rightButton)
+ _skipStart = true;
+ _vm->_room->clearRoom();
+ _vm->_events->showCursor();
+ return;
+ }
+
+ _vm->_events->_vbCount = 4;
+ if (_vm->_scrollCol + screen._vWindowWidth != _vm->_room->_playFieldWidth) {
+ _vm->_scrollX += _vm->_player->_scrollAmount;
+
+ while (_vm->_scrollX >= TILE_WIDTH) {
+ _vm->_scrollX -= TILE_WIDTH;
+ ++_vm->_scrollCol;
+
+ _vm->_buffer1.moveBufferLeft();
+ _vm->_room->buildColumn(_vm->_scrollCol + screen._vWindowWidth, screen._vWindowBytesWide);
+ }
+ scrollTitle();
+ ++_pCount;
+
+ while (!_vm->shouldQuit() && (_vm->_events->_vbCount > 0)) {
+ _vm->_events->pollEventsAndWait();
+ }
+ continue;
+ }
+
+ _vm->_events->_vbCount = 120;
+ while (!_vm->shouldQuit() && (_vm->_events->_vbCount > 0))
+ _vm->_events->pollEventsAndWait();
+
+ while (!_vm->shouldQuit()) {
+ _pCount = 0;
+ _vm->_events->_vbCount = 3;
+ if (_vm->_scrollRow + screen._vWindowHeight >= _vm->_room->_playFieldHeight) {
+ _vm->_room->clearRoom();
+ _vm->_events->showCursor();
+ return;
+ }
+
+ _vm->_scrollY = _vm->_scrollY + _vm->_player->_scrollAmount;
+
+ while (_vm->_scrollY >= TILE_HEIGHT && !_vm->shouldQuit()) {
+ _vm->_scrollY -= TILE_HEIGHT;
+ ++_vm->_scrollRow;
+ _vm->_buffer1.moveBufferUp();
+
+ // WORKAROUND: the original was using screen._vWindowBytesWide * screen._vWindowLinesTall
+ _vm->_room->buildRow(_vm->_scrollRow + screen._vWindowHeight, screen._vWindowLinesTall);
+
+ if (_vm->_scrollRow + screen._vWindowHeight >= _vm->_room->_playFieldHeight) {
+ _vm->_room->clearRoom();
+ _vm->_events->showCursor();
+ return;
+ }
+ }
+ scrollTitle();
+ while (!_vm->shouldQuit() && (_vm->_events->_vbCount > 0))
+ _vm->_events->pollEventsAndWait();
+ }
+ }
+}
+
+void Opening::doTent() {
+ int step = 0;
+ _vm->_screen->setDisplayScan();
+ _vm->_screen->forceFadeOut();
+ _vm->_events->hideCursor();
+ _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.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 (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 (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();
+ }
+
+ _vm->_events->_vbCount = 200;
+ while (!_vm->shouldQuit() && _vm->_events->_vbCount > 0)
+ _vm->_events->pollEventsAndWait();
+
+ _vm->_events->showCursor();
+ _vm->_midi->newMusic(11, 1);
+ _vm->_sound->_soundTable.clear();
+
+ _vm->establishCenter(0, 4);
+}
+
+/*------------------------------------------------------------------------*/
+
+Plane::Plane(AmazonEngine *vm) : PannedScene(vm) {
+ _pCount = 0;
+ _planeCount = 0;
+ _propCount = 0;
+}
+
+
+void Plane::doFlyCell() {
+ SpriteResource *sprites = _vm->_objectsTable[15];
+
+ if (_pCount <= 40) {
+ _vm->_buffer2.plotImage(sprites, 3, Common::Point(70, 74));
+ } else if (_pCount <= 80) {
+ _vm->_buffer2.plotImage(sprites, 6, Common::Point(70, 74));
+ } else if (_pCount <= 120) {
+ _vm->_buffer2.plotImage(sprites, 2, Common::Point(50, 76));
+ } else if (_pCount <= 160) {
+ _vm->_buffer2.plotImage(sprites, 14, Common::Point(63, 78));
+ } else if (_pCount <= 200) {
+ _vm->_buffer2.plotImage(sprites, 5, Common::Point(86, 74));
+ } else if (_pCount <= 240) {
+ _vm->_buffer2.plotImage(sprites, 0, Common::Point(103, 76));
+ } else if (_pCount <= 280) {
+ _vm->_buffer2.plotImage(sprites, 4, Common::Point(119, 77));
+ } else {
+ _vm->_buffer2.plotImage(sprites, 1, Common::Point(111, 77));
+ }
+
+ if (_planeCount == 11 || _planeCount == 12)
+ ++_position.y;
+ else if (_planeCount >= 28)
+ --_position.y;
+
+ _vm->_buffer2.plotImage(sprites, 7, _position);
+ _vm->_buffer2.plotImage(sprites, 8 + _propCount, Common::Point(
+ _position.x + 99, _position.y + 10));
+ _vm->_buffer2.plotImage(sprites, 11 + _propCount, Common::Point(
+ _position.x + 104, _position.y + 18));
+
+ if (++_planeCount >= 30)
+ _planeCount = 0;
+ if (++_propCount >= 3)
+ _propCount = 0;
+
+ ++_xCount;
+ if (_xCount == 1)
+ ++_position.x;
+ else
+ _xCount = 0;
+}
+
+void Plane::doFallCell() {
+ if (_vm->_scaleI <= 20)
+ return;
+
+ SpriteFrame *frame = _vm->_objectsTable[20]->getFrame(_planeCount / 6);
+ Common::Rect r(115, 11, 115 + _vm->_screen->_scaleTable1[frame->w],
+ 11 + _vm->_screen->_scaleTable1[frame->h]);
+ _vm->_buffer2.sPlotF(frame, r);
+
+ _vm->_scaleI -= 3;
+ _vm->_scale = _vm->_scaleI;
+ _vm->_screen->setScaleTable(_vm->_scale);
+ ++_xCount;
+ if (_xCount == 5)
+ return;
+ _xCount = 0;
+ if (_planeCount == 18)
+ _planeCount = 0;
+ else
+ _planeCount += 6;
+}
+
+void Plane::scrollFly() {
+ _vm->copyBF1BF2();
+ _vm->_newRects.clear();
+ doFlyCell();
+ _vm->copyRects();
+ _vm->copyBF2Vid();
+}
+
+void Plane::scrollFall() {
+ _vm->copyBF1BF2();
+ _vm->_newRects.clear();
+ doFallCell();
+ _vm->copyRects();
+ _vm->copyBF2Vid();
+}
+
+void Plane::mWhileFly() {
+ Screen &screen = *_vm->_screen;
+ Player &player = *_vm->_player;
+ EventsManager &events = *_vm->_events;
+
+ events.hideCursor();
+ screen.clearScreen();
+ screen.setBufferScan();
+ screen.fadeOut();
+ _vm->_scrollX = 0;
+
+ _vm->_room->buildScreen();
+ _vm->copyBF2Vid();
+ screen.fadeIn();
+ _vm->_oldRects.clear();
+ _vm->_newRects.clear();
+ _vm->_events->clearEvents();
+
+ _vm->_scrollRow = _vm->_scrollCol = 0;
+ _vm->_scrollX = _vm->_scrollY = 0;
+ player._rawPlayer = Common::Point(0, 0);
+ player._scrollAmount = 1;
+
+ _pCount = 0;
+ _planeCount = 0;
+ _propCount = 0;
+ _xCount = 0;
+ _position = Common::Point(20, 29);
+
+ while (!_vm->shouldQuit() && !events.isKeyMousePressed() &&
+ ((_vm->_scrollCol + screen._vWindowWidth) != _vm->_room->_playFieldWidth)) {
+ events._vbCount = 4;
+ _vm->_scrollX += player._scrollAmount;
+
+ while (_vm->_scrollX >= TILE_WIDTH) {
+ _vm->_scrollX -= TILE_WIDTH;
+ ++_vm->_scrollCol;
+
+ _vm->_buffer1.moveBufferLeft();
+ _vm->_room->buildColumn(_vm->_scrollCol + screen._vWindowWidth, screen._vWindowBytesWide);
+ }
+
+ scrollFly();
+ ++_pCount;
+
+ while (!_vm->shouldQuit() && events._vbCount > 0) {
+ _vm->_sound->playSound(0);
+ events.pollEventsAndWait();
+ }
+ }
+
+ events.showCursor();
+}
+
+void Plane::mWhileFall() {
+ Screen &screen = *_vm->_screen;
+ EventsManager &events = *_vm->_events;
+
+ events.hideCursor();
+ screen.clearScreen();
+ screen.setBufferScan();
+ screen.fadeOut();
+ _vm->_scrollX = 0;
+
+ _vm->_room->buildScreen();
+ _vm->copyBF2Vid();
+ screen.fadeIn();
+ _vm->_oldRects.clear();
+ _vm->_newRects.clear();
+ _vm->_events->clearEvents();
+
+ _vm->_scrollRow = _vm->_scrollCol = 0;
+ _vm->_scrollX = _vm->_scrollY = 0;
+ _vm->_player->_scrollAmount = 3;
+ _vm->_scaleI = 255;
+
+ _xCount = 0;
+ _planeCount = 0;
+
+ while (!_vm->shouldQuit() && !events.isKeyMousePressed() &&
+ (_vm->_scrollCol + screen._vWindowWidth != _vm->_room->_playFieldWidth)) {
+ events._vbCount = 4;
+ _vm->_scrollX += _vm->_player->_scrollAmount;
+
+ while (_vm->_scrollX >= TILE_WIDTH) {
+ _vm->_scrollX -= TILE_WIDTH;
+ ++_vm->_scrollCol;
+
+ _vm->_buffer1.moveBufferLeft();
+ _vm->_room->buildColumn(_vm->_scrollCol + screen._vWindowWidth, screen._vWindowBytesWide);
+ }
+
+ scrollFall();
+
+ while (!_vm->shouldQuit() && events._vbCount > 0) {
+ events.pollEventsAndWait();
+ }
+ }
+
+ events.showCursor();
+}
+
+/*------------------------------------------------------------------------*/
+
+Jungle::Jungle(AmazonEngine *vm) : CampScene(vm) {
+ for (int i = 0; i < JUNGLE_SIZE; ++i) {
+ _jCnt[i] = _jungleX[i] = -1;
+ }
+}
+
+void Jungle::jungleMove() {
+ const static int jungleY[3] = { 27, 30, 29 };
+ int count = 1;
+ int frameOffset = 0;
+
+ if (!_vm->_timers[0]._flag) {
+ ++_vm->_timers[0]._flag;
+ _vm->_scrollX += _vm->_player->_scrollAmount;
+
+ for (int i = 0; i < 3; ++i) {
+ int newJCnt = (_jCnt[i] + 1) % 8;
+ _jCnt[i] = newJCnt;
+ _jungleX[i] += 5;
+ }
+
+ frameOffset = 4;
+ count = (_vm->_allenFlag != 1) ? 2 : 3;
+ }
+
+ for (int i = 0; i < count; ++i) {
+ ImageEntry ie;
+ ie._flags = IMGFLAG_UNSCALED;
+ ie._spritesPtr = _vm->_objectsTable[24];
+ ie._frameNumber = _jCnt[i] + frameOffset;
+ ie._position = Common::Point(_jungleX[i], jungleY[i]);
+ ie._offsetY = jungleY[i];
+
+ _vm->_images.addToList(ie);
+ frameOffset += 8;
+ }
+}
+
+void Jungle::initJWalk2() {
+ const int JUNGLE1OBJ[7][4] = {
+ { 2, 470, 0, 20 },
+ { 0, 290, 0, 50 },
+ { 1, 210, 0, 40 },
+ { 0, 500, 0, 30 },
+ { 1, 550, 0, 20 },
+ { 0, 580, 0, 60 },
+ { 1, 650, 0, 30 }
+ };
+
+ Screen &screen = *_vm->_screen;
+ screen.fadeOut();
+ _vm->_events->hideCursor();
+ screen.clearScreen();
+ _vm->_buffer2.clearBuffer();
+ screen.setBufferScan();
+
+ _vm->_scrollX = _vm->_scrollY;
+ _vm->_scrollCol = _vm->_scrollRow;
+ _vm->_room->buildScreen();
+ _vm->copyBF2Vid();
+ screen.fadeIn();
+ _vm->_events->clearEvents();
+
+ _xCount = 2;
+ _vm->_player->_scrollAmount = 5;
+ _xTrack = -10;
+ _yTrack = _zTrack = 0;
+ _xCam = 480;
+ _yCam = 0;
+ _zCam = 80;
+
+ _vm->_timers[24]._timer = 1;
+ _vm->_timers[24]._initTm = 1;
+ ++_vm->_timers[24]._flag;
+
+ _pNumObj = 7;
+ for (int i = 0; i < _pNumObj; i++) {
+ _pan[i]._pObject = _vm->_objectsTable[24];
+ _pan[i]._pImgNum = JUNGLE1OBJ[i][0];
+ _pan[i]._pObjX = JUNGLE1OBJ[i][1];
+ _pan[i]._pObjY = JUNGLE1OBJ[i][2];
+ _pan[i]._pObjZ = JUNGLE1OBJ[i][3];
+ _pan[i]._pObjXl = _pan[i]._pObjYl = 0;
+ }
+
+ _jCnt[0] = 0;
+ _jCnt[1] = 3;
+ _jCnt[2] = 5;
+
+ _jungleX[0] = 50;
+ _jungleX[1] = 16;
+ _jungleX[2] = 93;
+}
+
+void Jungle::mWhileJWalk() {
+ Screen &screen = *_vm->_screen;
+ EventsManager &events = *_vm->_events;
+ Player &player = *_vm->_player;
+
+ static const int JUNGLE_OBJ[7][4] = {
+ { 2, 77, 0, 40 },
+ { 0, 290, 0, 50 },
+ { 1, 210, 0, 70 },
+ { 0, 50, 0, 30 },
+ { 1, 70, 0, 20 },
+ { 0, -280, 0, 60 },
+ { 1, -150, 0, 30 },
+ };
+
+ screen.fadeOut();
+ events.hideCursor();
+ screen.clearScreen();
+ _vm->_buffer2.clearBuffer();
+ screen.setBufferScan();
+ _vm->_scrollX = 0;
+
+ // Build the initial jungle scene and fade it in
+ _vm->_room->buildScreen();
+ _vm->copyBF2Vid();
+ screen.fadeIn();
+
+ // Set up the player to walk horizontally
+ player._xFlag = 1;
+ player._yFlag = 0;
+ player._moveTo.x = 160;
+ player._playerMove = true;
+
+ _xCount = 2;
+ _xTrack = 10;
+ _yTrack = _zTrack = 0;
+ _xCam = 480;
+ _yCam = 0;
+ _zCam = 80;
+
+ TimerEntry *te = &_vm->_timers[24];
+ te->_initTm = te->_timer = 1;
+ te->_flag++;
+
+ _pNumObj = 7;
+ for (int i = 0; i < _pNumObj; i++) {
+ _pan[i]._pObject = _vm->_objectsTable[24];
+ _pan[i]._pImgNum = JUNGLE_OBJ[i][0];
+ _pan[i]._pObjX = JUNGLE_OBJ[i][1];
+ _pan[i]._pObjY = JUNGLE_OBJ[i][2];
+ _pan[i]._pObjZ = JUNGLE_OBJ[i][3];
+ _pan[i]._pObjXl = _pan[i]._pObjYl = 0;
+ }
+
+ while (!_vm->shouldQuit() && !events.isKeyMousePressed() && (player._xFlag != 2)) {
+ _vm->_images.clear();
+ events._vbCount = 6;
+
+ _pan[0]._pImgNum = _xCount;
+ if (_xCount == 2)
+ ++_xCount;
+ else
+ --_xCount;
+
+ player.checkMove();
+ player.checkScroll();
+ pan();
+ scrollJWalk();
+
+ while (!_vm->shouldQuit() && events._vbCount > 0) {
+ events.pollEventsAndWait();
+ }
+ }
+
+ _vm->_images.clear();
+ events.showCursor();
+}
+
+void Jungle::mWhileJWalk2() {
+ Screen &screen = *_vm->_screen;
+
+ initJWalk2();
+
+ while (!_vm->shouldQuit() && !_vm->_events->isKeyMousePressed() &&
+ (_vm->_scrollCol + screen._vWindowWidth) != _vm->_room->_playFieldWidth) {
+ _vm->_images.clear();
+ _vm->_events->_vbCount = 6;
+ _pan[0]._pImgNum = _xCount;
+
+ jungleMove();
+ while (_vm->_scrollX >= TILE_WIDTH) {
+ _vm->_scrollX -= TILE_WIDTH;
+ ++_vm->_scrollCol;
+ _vm->_buffer1.moveBufferLeft();
+ _vm->_room->buildColumn(_vm->_scrollCol + screen._vWindowWidth, screen._vWindowBytesWide);
+ }
+
+ if (_xCount == 2)
+ ++_xCount;
+ else
+ --_xCount;
+
+ pan();
+ scrollJWalk();
+
+ while (!_vm->shouldQuit() && _vm->_events->_vbCount > 0) {
+ _vm->_events->pollEventsAndWait();
+ }
+ }
+
+ _vm->_events->showCursor();
+}
+
+void Jungle::scrollJWalk() {
+ _vm->copyBF1BF2();
+ _vm->_newRects.clear();
+ _vm->plotList();
+ _vm->copyRects();
+ _vm->copyBF2Vid();
+}
+
+/*------------------------------------------------------------------------*/
+
+Guard::Guard(AmazonEngine *vm) : PannedScene(vm) {
+ _guardCel = 0;
+ _gCode1 = _gCode2 = 0;
+ _xMid = _yMid = 0;
+}
+
+void Guard::setVerticalCode() {
+ Screen &screen = *_vm->_screen;
+
+ _gCode1 = 0;
+ _gCode2 = 0;
+ if (_topLeft.x < screen._orgX1)
+ _gCode1 |= 8;
+ else if (_topLeft.x == screen._orgX1) {
+ _gCode1 |= 8;
+ _gCode1 |= 2;
+ } else
+ _gCode1 |= 2;
+
+ if (_bottomRight.x < screen._orgX1)
+ _gCode2 |= 8;
+ else if (_bottomRight.x == screen._orgX1) {
+ _gCode2 |= 8;
+ _gCode2 |= 2;
+ } else
+ _gCode2 |= 2;
+
+ if (_topLeft.y < screen._orgY1)
+ _gCode1 |= 4;
+ else if (_topLeft.y > screen._orgY2)
+ _gCode1 |= 1;
+
+ if (_bottomRight.y < screen._orgY1)
+ _gCode2 |= 4;
+ else if (_bottomRight.y > screen._orgY2)
+ _gCode2 |= 1;
+}
+
+void Guard::setHorizontalCode() {
+ Screen &screen = *_vm->_screen;
+
+ _gCode1 = 0;
+ _gCode2 = 0;
+
+ if (_topLeft.y < screen._orgY1)
+ _gCode1 |= 4;
+ else if (_topLeft.x == screen._orgX1) {
+ _gCode1 |= 4;
+ _gCode1 |= 1;
+ } else
+ _gCode1 |= 1;
+
+ if (_bottomRight.y < screen._orgY1)
+ _gCode2 |= 4;
+ else if (_bottomRight.x == screen._orgX1) {
+ _gCode2 |= 4;
+ _gCode2 |= 1;
+ } else
+ _gCode2 |= 1;
+
+ if (_topLeft.x < screen._orgX1)
+ _gCode1 |= 8;
+ else if (_topLeft.x > screen._orgX2)
+ _gCode1 |= 2;
+
+ if (_bottomRight.x < screen._orgX1)
+ _gCode2 |= 8;
+ else if (_bottomRight.x > screen._orgX2)
+ _gCode2 |= 2;
+}
+
+void Guard::chkVLine() {
+ if (_position.x > _vm->_player->_rawPlayer.x) {
+ _topLeft = _vm->_player->_rawPlayer;
+ _bottomRight = _position;
+ } else {
+ _topLeft = _position;
+ _bottomRight = _vm->_player->_rawPlayer;
+ }
+
+ if (_vm->_screen->_orgY1 > _vm->_screen->_orgY2)
+ SWAP(_vm->_screen->_orgY1, _vm->_screen->_orgY2);
+
+ for (;;) {
+ setVerticalCode();
+ int code = _gCode1 | _gCode2;
+ if (code == 10) {
+ _vm->_guardFind = 0;
+ return;
+ }
+
+ int code2 = _gCode1 & _gCode2;
+ code2 &= 5;
+ if (((code & 10) == 8) || ((code & 10) == 2) || (code2 != 0))
+ return;
+
+ int midX = (_topLeft.x + _bottomRight.x) / 2;
+ int midY = (_topLeft.y + _bottomRight.y) / 2;
+
+ if (midX < _vm->_screen->_orgX1) {
+ if ((midX == _topLeft.x) && (midY == _topLeft.y))
+ return;
+
+ _topLeft.x = midX;
+ _topLeft.y = midY;
+ } else {
+ if ((midX == _bottomRight.x) && (midY == _bottomRight.y))
+ return;
+
+ _bottomRight.x = midX;
+ _bottomRight.y = midY;
+ }
+ }
+}
+
+void Guard::chkHLine() {
+ if (_position.y > _vm->_player->_rawPlayer.y) {
+ _topLeft = _vm->_player->_rawPlayer;
+ _bottomRight = _position;
+ } else {
+ _topLeft = _position;
+ _bottomRight = _vm->_player->_rawPlayer;
+ }
+
+ if (_vm->_screen->_orgX1 > _vm->_screen->_orgX2)
+ SWAP(_vm->_screen->_orgX1, _vm->_screen->_orgX2);
+
+ while (true) {
+ setHorizontalCode();
+ int code = _gCode1 | _gCode2;
+ if (code == 5) {
+ _vm->_guardFind = 0;
+ return;
+ }
+
+ int code2 = _gCode1 & _gCode2;
+ code2 &= 10;
+ if (((code & 5) == 4) || ((code & 5) == 1) || (code2 != 0))
+ return;
+
+ int midX = (_topLeft.x + _bottomRight.x) / 2;
+ int midY = (_topLeft.y + _bottomRight.y) / 2;
+
+ if (midY < _vm->_screen->_orgY1) {
+ if ((midX == _topLeft.x) && (midY == _topLeft.y))
+ return;
+
+ _topLeft.x = midX;
+ _topLeft.y = midY;
+ } else {
+ if ((midX == _bottomRight.x) && (midY == _bottomRight.y))
+ return;
+
+ _bottomRight.x = midX;
+ _bottomRight.y = midY;
+ }
+ }
+}
+
+void Guard::guardSee() {
+ Screen &screen = *_vm->_screen;
+ int tmpY = (_vm->_scrollRow << 4) + _vm->_scrollY;
+ _vm->_flags[140] = 0;
+ if (tmpY > _position.y)
+ return;
+
+ tmpY += screen._vWindowLinesTall;
+ tmpY -= 11;
+
+ if (tmpY < _position.y)
+ return;
+
+ _vm->_guardFind = 1;
+ _vm->_flags[140] = 1;
+
+ for (uint16 idx = 0; idx < _vm->_room->_plotter._walls.size(); idx++) {
+ screen._orgX1 = _vm->_room->_plotter._walls[idx].left;
+ screen._orgY1 = _vm->_room->_plotter._walls[idx].top;
+ screen._orgX2 = _vm->_room->_plotter._walls[idx].right;
+ screen._orgY2 = _vm->_room->_plotter._walls[idx].bottom;
+ if (screen._orgX1 == screen._orgX2) {
+ chkVLine();
+ if (_vm->_guardFind == 0)
+ return;
+ } else if (screen._orgY1 == screen._orgY2) {
+ chkHLine();
+ if (_vm->_guardFind == 0)
+ return;
+ }
+ }
+}
+
+void Guard::setGuardFrame() {
+ ImageEntry ie;
+ ie._flags = IMGFLAG_UNSCALED;
+
+ if (_vm->_guardLocation == 4)
+ ie._flags |= IMGFLAG_BACKWARDS;
+ ie._spritesPtr = _vm->_objectsTable[37];
+ ie._frameNumber = _guardCel;
+ ie._position = _position;
+ ie._offsetY = 10;
+ _vm->_images.addToList(ie);
+}
+
+void Guard::doGuard() {
+ // Skip the code dealing with the guard on the boat (chapter 8)
+ // if the cheat mode is activated
+ if (_vm->_cheatFl)
+ return;
+
+ if (_vm->_timers[8]._flag) {
+ setGuardFrame();
+ return;
+ }
+
+ ++_vm->_timers[8]._flag;
+ ++_guardCel;
+ int curCel = _guardCel;
+
+ switch (_vm->_guardLocation) {
+ case 1:
+ // Guard walking down
+ if (curCel <= 8 || curCel > 13)
+ _guardCel = curCel = 8;
+
+ _position.y += _vm->_player->_walkOffDown[curCel - 8];
+ guardSee();
+ if (_position.y >= 272) {
+ _position.y = 272;
+ _vm->_guardLocation = 2;
+ }
+ break;
+ case 2:
+ // Guard walking left
+ if (curCel <= 43 || curCel > 48)
+ _guardCel = curCel = 43;
+
+ _position.x -= _vm->_player->_walkOffLeft[curCel - 43];
+ guardSee();
+ if (_position.x <= 56) {
+ _position.x = 56;
+ _vm->_guardLocation = 3;
+ }
+ break;
+ case 3:
+ // Guard walking up
+ if (curCel <= 0 || curCel > 5)
+ _guardCel = curCel = 0;
+
+ _position.y -= _vm->_player->_walkOffUp[curCel];
+ guardSee();
+ if (_position.y <= 89) {
+ _position.y = 89;
+ _vm->_guardLocation = 4;
+ if (_vm->_flags[121] == 1)
+ _vm->_guardLocation = 5;
+ }
+ break;
+ default:
+ // Guard walking right
+ if (curCel <= 43 || curCel > 48)
+ _guardCel = curCel = 43;
+
+ _position.x += _vm->_player->_walkOffRight[curCel - 43];
+ guardSee();
+ if (_position.x >= 127) {
+ _position.x = 127;
+ _vm->_guardLocation = 1;
+ }
+ break;
+ }
+
+ setGuardFrame();
+}
+
+void Guard::setPosition(const Common::Point &pt) {
+ _position = pt;
+}
+
+/*------------------------------------------------------------------------*/
+
+Cast::Cast(AmazonEngine *vm) : PannedScene(vm) {
+}
+
+void Cast::doCast(int param1) {
+ Screen &screen = *_vm->_screen;
+
+ screen.setDisplayScan();
+ _vm->_events->hideCursor();
+ screen.forceFadeOut();
+ screen._clipHeight = 173;
+ screen.clearScreen();
+ _vm->_chapter = 16;
+ _vm->tileScreen();
+ _vm->updateSummary(param1);
+ screen.setPanel(3);
+ _vm->_chapter = 14;
+
+ Resource *spriteData = _vm->_files->loadFile(91, 0);
+ _vm->_objectsTable[0] = new SpriteResource(_vm, spriteData);
+ delete spriteData;
+ spriteData = _vm->_files->loadFile(91, 1);
+ _vm->_objectsTable[1] = new SpriteResource(_vm, spriteData);
+ delete spriteData;
+
+ _vm->_files->_setPaletteFlag = false;
+ _vm->_files->loadScreen(58, 1);
+ _vm->_buffer2.blitFrom(*_vm->_screen);
+ _vm->_buffer1.blitFrom(*_vm->_screen);
+
+ _xTrack = 0;
+ _yTrack = -6;
+ _zTrack = 0;
+ _xCam = _yCam = 0;
+ _zCam = 60;
+
+ _vm->_timers[24]._timer = 1;
+ _vm->_timers[24]._initTm = 1;
+ ++_vm->_timers[24]._flag;
+
+ _pNumObj = 26;
+ for (int i = 0; i < _pNumObj; i++) {
+ _pan[i]._pObject = _vm->_objectsTable[0];
+ _pan[i]._pImgNum = CAST_END_OBJ[i][0];
+ _pan[i]._pObjX = CAST_END_OBJ[i][1];
+ _pan[i]._pObjY = CAST_END_OBJ[i][2];
+ _pan[i]._pObjZ = CAST_END_OBJ[i][3];
+ _pan[i]._pObjXl = _pan[i]._pObjYl = 0;
+ }
+
+ _pNumObj = 4;
+ for (int i = 0; i < _pNumObj; i++) {
+ _pan[26 + i]._pObject = _vm->_objectsTable[1];
+ _pan[26 + i]._pImgNum = CAST_END_OBJ1[i][0];
+ _pan[26 + i]._pObjX = CAST_END_OBJ1[i][1];
+ _pan[26 + i]._pObjY = CAST_END_OBJ1[i][2];
+ _pan[26 + i]._pObjZ = CAST_END_OBJ1[i][3];
+ _pan[26 + i]._pObjXl = _pan[26 + i]._pObjYl = 0;
+ }
+
+ _vm->_oldRects.clear();
+ _vm->_newRects.clear();
+ _vm->_numAnimTimers = 0;
+
+ _vm->_midi->newMusic(58, 0);
+ screen.forceFadeIn();
+
+ while (!_vm->shouldQuit()) {
+ _vm->_images.clear();
+ pan();
+ _vm->_buffer2.blitFrom(_vm->_buffer1);
+ _vm->_newRects.clear();
+ _vm->plotList();
+ _vm->copyBlocks();
+
+ _vm->_events->pollEvents();
+ if (_vm->_events->isKeyMousePressed())
+ break;
+
+ if (_yCam < -7550) {
+ _vm->_events->_vbCount = 50;
+
+ while (!_vm->shouldQuit() && !_vm->_events->isKeyMousePressed() && _vm->_events->_vbCount > 0) {
+ _vm->_events->pollEventsAndWait();
+ }
+
+ while (!_vm->shouldQuit() && !_vm->_midi->checkMidiDone())
+ _vm->_events->pollEventsAndWait();
+
+ break;
+ }
+ }
+
+ _vm->_midi->newMusic(58, 1);
+ _vm->_events->showCursor();
+
+ _vm->freeCells();
+ _vm->_oldRects.clear();
+ _vm->_newRects.clear();
+ _vm->_numAnimTimers = 0;
+ _vm->_images.clear();
+ screen.forceFadeOut();
+
+ _vm->quitGame();
+ _vm->_events->pollEvents();
+}
+
+/*------------------------------------------------------------------------*/
+
+River::River(AmazonEngine *vm) : PannedScene(vm) {
+ _chickenOutFl = false;
+ _rScrollRow = 0;
+ _rScrollCol = 0;
+ _rScrollX = 0;
+ _rScrollY = 0;
+ _mapOffset = 0;
+ _screenVertX = 0;
+ _saveRiver = false;
+ _deathFlag = false;
+ _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() {
+ int delta = (_vm->_scrollCol * 16) + _vm->_scrollX;
+
+ _xTrack = 9;
+ _yTrack = _zTrack = 0;
+ _xCam = 160;
+ _yCam = 0;
+ _zCam = 80;
+
+ _vm->_timers[24]._timer = 1;
+ _vm->_timers[24]._initTm = 1;
+ ++_vm->_timers[24]._flag;
+
+ _pNumObj = 23;
+ for (int i = 0; i < _pNumObj; i++) {
+ _pan[i]._pObject = _vm->_objectsTable[45];
+ _pan[i]._pImgNum = RIVER1OBJ[i][0];
+ _pan[i]._pObjX = RIVER1OBJ[i][1] + delta;
+ _pan[i]._pObjY = RIVER1OBJ[i][2];
+ _pan[i]._pObjZ = RIVER1OBJ[i][3];
+ _pan[i]._pObjXl = _pan[i]._pObjYl = 0;
+ }
+}
+
+void River::initRiver() {
+ static const int RIVERVXTBL[3] = { 6719, 7039, 8319 };
+ Screen &screen = *_vm->_screen;
+
+ _vm->_events->centerMousePos();
+ _vm->_events->restrictMouse();
+ screen.setDisplayScan();
+ screen.clearScreen();
+ screen.savePalette();
+ screen.forceFadeOut();
+
+ _vm->_files->_setPaletteFlag = false;
+ _vm->_files->loadScreen(95, 4);
+ _vm->_buffer2.blitFrom(*_vm->_screen);
+
+ screen.restorePalette();
+ screen.setBufferScan();
+ _vm->_destIn = &_vm->_buffer2;
+ _vm->_room->roomMenu();
+
+ if (_saveRiver) {
+ // Restoring a savegame, so set properties from saved fields
+ _vm->_scrollRow = _rScrollRow;
+ _vm->_scrollCol = _rScrollCol;
+ _vm->_scrollX = _rScrollX;
+ _vm->_scrollY = _rScrollY;
+ } else {
+ // Set initial scene state
+ _vm->_scrollRow = 0;
+ _vm->_scrollCol = 140;
+ _vm->_scrollX = 0;
+ _vm->_scrollY = 0;
+ }
+
+ _vm->_room->buildScreen();
+ _vm->copyBF2Vid();
+ screen.forceFadeIn();
+
+ if (!_saveRiver) {
+ // Reset draw rects
+ _vm->_oldRects.clear();
+ _vm->_newRects.clear();
+ _vm->_events->clearEvents();
+
+ }
+
+ _vm->_player->_scrollAmount = 2;
+ setRiverPan();
+ _vm->_timers[3]._timer = 1;
+ _vm->_timers[3]._initTm = 1;
+ ++_vm->_timers[3]._flag;
+
+ _canoeFrame = 0;
+ _mapPtr = (const byte *)MAPTBL[_vm->_riverFlag] + 1;
+ if (_saveRiver) {
+ _mapPtr--;
+ _mapPtr += _mapOffset;
+ } else {
+ _screenVertX = RIVERVXTBL[_vm->_riverFlag] - 320;
+ _canoeLane = 3;
+ _hitCount = 0;
+ _hitSafe = 0;
+ _canoeYPos = 71;
+ }
+
+ _riverIndex = _vm->_riverFlag;
+ _topList = RIVER_OBJECTS[_riverIndex][RIVER_START];
+ updateObstacles();
+ riverSetPhysX();
+ _canoeDir = 0;
+ _deathFlag = false;
+ _deathCount = 0;
+
+ _vm->_timers[11]._timer = 1200;
+ _vm->_timers[11]._initTm = 1200;
+ ++_vm->_timers[11]._flag;
+ _vm->_timers[12]._timer = 1500;
+ _vm->_timers[12]._initTm = 1500;
+ ++_vm->_timers[12]._flag;
+
+ _maxHits = 2 - _vm->_riverFlag;
+ _saveRiver = false;
+
+ // 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() {
+ riverSetPhysX();
+ int val = (_vm->_scrollCol + 1 - _oldScrollCol) * 16;
+ if (val < 0) {
+ val |= 0x80;
+ }
+
+ for (int i = 0; i < _pNumObj; i++)
+ _pan[i]._pObjX += val;
+}
+
+void River::checkRiverPan() {
+ int val = _vm->_scrollCol * 16 + 320;
+
+ for (int i = 0; i < _pNumObj; i++) {
+ if (_pan[i]._pObjX < val)
+ return;
+ }
+
+ setRiverPan();
+}
+
+bool River::riverJumpTest() {
+ if (_vm->_scrollCol == 120 || _vm->_scrollCol == 60 || _vm->_scrollCol == 0) {
+ int val = *++_mapPtr;
+ if (val == 0xFF)
+ return true;
+
+ _oldScrollCol = _vm->_scrollCol;
+
+ if (val == 0) {
+ _vm->_scrollCol = 139;
+ _vm->_scrollX = 14;
+ _vm->_room->buildScreen();
+ resetPositions();
+ return false;
+ }
+ } else if (_vm->_scrollCol == 105) {
+ int val1 = _mapPtr[1];
+ int val2 = _mapPtr[2];
+ _mapPtr += 3;
+ if (_canoeLane < 3) {
+ if (val1 != 0) {
+ _deathFlag = true;
+ _deathCount = 300;
+ _deathType = val2;
+ }
+ } else {
+ if (val1 != 1) {
+ _deathFlag = true;
+ _deathCount = 300;
+ _deathType = val2;
+ }
+ _oldScrollCol = _vm->_scrollCol;
+ _vm->_scrollCol = 44;
+ _vm->_scrollX = 14;
+ _vm->_room->buildScreen();
+ resetPositions();
+ return false;
+ }
+ }
+
+ _vm->_scrollX = 14;
+ --_vm->_scrollCol;
+ _vm->_buffer1.moveBufferRight();
+ _vm->_room->buildColumn(_vm->_scrollCol, 0);
+ checkRiverPan();
+ return false;
+}
+
+void River::riverSound() {
+ if (_vm->_timers[11]._flag == 0) {
+ ++_vm->_timers[11]._flag;
+ _vm->_sound->playSound(2);
+ }
+
+ if (_vm->_timers[12]._flag == 0) {
+ ++_vm->_timers[12]._flag;
+ _vm->_sound->playSound(3);
+ }
+
+ if ((_xCam >= 1300) && (_xCam <= 1320))
+ _vm->_sound->playSound(1);
+}
+
+void River::moveCanoe() {
+ EventsManager &events = *_vm->_events;
+ Common::Point pt = events.calcRawMouse();
+ Common::Point mousePos = events.getMousePos();
+
+ // Do an event polling
+ _vm->_canSaveLoad = true;
+ events.pollEvents();
+ _vm->_canSaveLoad = false;
+ if (_vm->_room->_function == FN_CLEAR1)
+ return;
+
+ if (_canoeDir) {
+ // Canoe movement in progress
+ moveCanoe2();
+ } else {
+ if (events._leftButton && pt.y >= 140) {
+ if (pt.x < RMOUSE[8][0]) {
+ // Disk icon wasn't clicked
+ _vm->_scripts->printString(BAR_MESSAGE);
+ } else {
+ // Clicked on the Disc icon. Show the ScummVM menu
+ _vm->_room->handleCommand(9);
+
+ if (_vm->_room->_function != FN_CLEAR1) {
+ _vm->_room->buildScreen();
+ _vm->copyBF2Vid();
+ }
+ }
+ } else if (events._leftButton && mousePos.x < 35 && mousePos.y < 12) {
+ // Clicked on the Skip button. So chicken out
+ _chickenOutFl = true;
+ } else if ((events._leftButton && pt.y <= _canoeYPos) ||
+ (!events._leftButton && _vm->_player->_move == UP)) {
+ // Move canoe up
+ if (_canoeLane > 0) {
+ _canoeDir = -1;
+ _canoeMoveCount = 0;
+
+ moveCanoe2();
+ }
+ } else if (events._leftButton || _vm->_player->_move == DOWN) {
+ // Move canoe down
+ if (_canoeLane < 7) {
+ _canoeDir = 1;
+ _canoeMoveCount = 0;
+
+ moveCanoe2();
+ }
+ }
+ }
+}
+
+void River::moveCanoe2() {
+ _canoeYPos += _canoeDir;
+
+ if (++_canoeMoveCount == 5) {
+ _canoeLane += _canoeDir;
+ _canoeDir = 0;
+ }
+}
+
+void River::updateObstacles() {
+ RiverStruct *cur;
+ for (cur = _topList; cur < RIVER_OBJECTS[_riverIndex][RIVER_END]; ++cur) {
+ int val = cur->_riverX + cur->_width - 1;
+ if (val < _screenVertX)
+ // Obstacle is not yet on-screen
+ break;
+
+ if (cur->_riverX < (_screenVertX + 319)) {
+ // Object is now on-screen. So set _topList/_botList to the range
+ // of river obstacles that are currently visible
+ _topList = cur;
+ _botList = cur;
+
+ while (cur < RIVER_OBJECTS[_riverIndex][RIVER_END]) {
+ ++cur;
+ val = cur->_riverX + cur->_width - 1;
+ if (val < _screenVertX || (cur->_riverX >= (_screenVertX + 319)))
+ break;
+
+ _botList = cur;
+ }
+
+ return;
+ }
+ }
+
+ cur = _topList;
+ cur--;
+ _botList = cur;
+}
+
+void River::riverSetPhysX() {
+ int xAmt = (_vm->_scrollCol * 16) + _vm->_scrollX;
+
+ for (RiverStruct *cur = _topList; cur <= _botList; ++cur) {
+ cur->_xp = xAmt - (_screenVertX - cur->_riverX);
+ }
+}
+
+bool River::checkRiverCollide() {
+ if (_hitSafe)
+ return false;
+
+ _canoeVXPos = _screenVertX + 170;
+
+ for (RiverStruct *cur = _topList; cur <= _botList; ++cur) {
+ if (cur->_lane < _canoeLane)
+ continue;
+
+ if ((cur->_lane == _canoeLane) || (cur->_lane == _canoeLane + 1)) {
+ if ((cur->_riverX + cur->_width - 1) >= _canoeVXPos &&
+ cur->_riverX < (_canoeVXPos + 124)) {
+ _vm->_sound->playSound(4);
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+void River::plotRiver() {
+ // Handle cycling through the canoe rowing frames
+ if (_vm->_timers[3]._flag == 0) {
+ ++_vm->_timers[3]._flag;
+
+ if (_canoeFrame++ == 12)
+ _canoeFrame = 0;
+ }
+
+ // Draw the canoe
+ ImageEntry ie;
+ ie._flags = IMGFLAG_UNSCALED;
+ ie._spritesPtr = _vm->_objectsTable[45];
+ ie._frameNumber = _canoeFrame;
+ ie._position.x = (_vm->_scrollCol * 16) + _vm->_scrollX + 160;
+ ie._position.y = _canoeYPos - 41;
+ ie._offsetY = 41;
+ _vm->_images.addToList(ie);
+
+ // Draw any on-screen obstacles
+ for (RiverStruct *cur = _topList; cur <= _botList; ++cur) {
+ if (cur->_id != -1) {
+ ie._flags = IMGFLAG_UNSCALED;
+ ie._spritesPtr = _vm->_objectsTable[45];
+ ie._frameNumber = cur->_id;
+ ie._position.x = cur->_xp;
+ ie._position.y = (cur->_lane * 5) + 56 - cur->_offsetY;
+ ie._offsetY = cur->_offsetY;
+ _vm->_images.addToList(ie);
+ }
+ }
+
+ // Draw the text for skipping the river
+ Font &font2 = _vm->_fonts._font2;
+ font2.drawString(_vm->_screen, "SKIP", Common::Point(5, 5));
+}
+
+void River::mWhileDownRiver() {
+ Screen &screen = *_vm->_screen;
+ _vm->_events->hideCursor();
+
+ screen.setDisplayScan();
+ screen.clearScreen();
+ screen.savePalette();
+ if (!_vm->isDemo())
+ _vm->_files->loadScreen(95, 4);
+ _vm->_buffer2.blitFrom(*_vm->_screen);
+ screen.restorePalette();
+ screen.setPalette();
+ screen.setBufferScan();
+
+ _vm->_scrollX = 0;
+ _vm->_room->buildScreen();
+ _vm->copyBF2Vid();
+
+ _vm->_player->_scrollAmount = 2;
+ _vm->_destIn = &_vm->_buffer2;
+ _xTrack = -7;
+ _yTrack = _zTrack = 0;
+ _xCam = _yCam = 0;
+ _zCam = 80;
+
+ _vm->_timers[24]._timer = 1;
+ _vm->_timers[24]._initTm = 1;
+ ++_vm->_timers[24]._flag;
+
+ _pNumObj = 14;
+ for (int i = 0; i <_pNumObj; i++) {
+ _pan[i]._pObject = _vm->_objectsTable[33];
+ _pan[i]._pImgNum = DOWNRIVEROBJ[i][0];
+ _pan[i]._pObjX = DOWNRIVEROBJ[i][1];
+ _pan[i]._pObjY = DOWNRIVEROBJ[i][2];
+ _pan[i]._pObjZ = DOWNRIVEROBJ[i][3];
+ _pan[i]._pObjXl = _pan[i]._pObjYl = 0;
+ }
+
+ _vm->_timers[3]._timer = 200;
+ _vm->_timers[3]._initTm = 200;
+ ++_vm->_timers[3]._flag;
+ _vm->_timers[4]._timer = 350;
+ _vm->_timers[4]._initTm = 350;
+ ++_vm->_timers[4]._flag;
+
+ while (!_vm->shouldQuit() && !_vm->_events->isKeyMousePressed() &&
+ (_vm->_scrollCol + screen._vWindowWidth != _vm->_room->_playFieldWidth)) {
+ _vm->_images.clear();
+ _vm->_events->_vbCount = 6;
+
+ _vm->_scrollX += _vm->_player->_scrollAmount;
+ while (_vm->_scrollX >= TILE_WIDTH) {
+ _vm->_scrollX -= TILE_WIDTH;
+ ++_vm->_scrollCol;
+ _vm->_buffer1.moveBufferLeft();
+ _vm->_room->buildColumn(_vm->_scrollCol + screen._vWindowWidth, screen._vWindowBytesWide);
+ }
+
+ pan();
+ scrollRiver();
+
+ if (!_vm->_timers[3]._flag) {
+ ++_vm->_timers[3]._flag;
+ _vm->_sound->playSound(1);
+ } else if (!_vm->_timers[4]._flag) {
+ ++_vm->_timers[4]._flag;
+ _vm->_sound->playSound(0);
+ }
+
+ while (!_vm->shouldQuit() && _vm->_events->_vbCount > 0) {
+ _vm->_events->pollEventsAndWait();
+ }
+ }
+
+ _vm->_events->showCursor();
+}
+
+void River::scrollRiver() {
+ _vm->copyBF1BF2();
+ _vm->_newRects.clear();
+ _vm->_buffer2.plotImage(_vm->_objectsTable[33], 0, Common::Point(66, 30));
+ _vm->plotList();
+ _vm->copyRects();
+ _vm->copyBF2Vid();
+}
+
+void River::scrollRiver1() {
+ _vm->copyBF1BF2();
+ _vm->_newRects.clear();
+ plotRiver();
+ _vm->plotList();
+ _vm->copyRects();
+ _vm->copyBF2Vid();
+}
+
+void River::doRiver() {
+ static const int RIVERDEATH[5] = { 22, 23, 24, 25, 26 };
+
+ initRiver();
+ _vm->_events->showCursor();
+
+ while (!_vm->shouldQuit()) {
+ _vm->_events->_vbCount = 4;
+
+ // Move the river position
+ _screenVertX -= _vm->_player->_scrollAmount;
+
+ if (_vm->_scrollX == 0) {
+ _vm->_midi->midiRepeat();
+ if (riverJumpTest()) {
+ _chickenOutFl = false;
+ return;
+ }
+ } else {
+ _vm->_scrollX -= _vm->_player->_scrollAmount;
+ }
+
+ if (_chickenOutFl) {
+ _chickenOutFl = false;
+ return;
+ }
+
+ _vm->_images.clear();
+ _vm->_animation->animate(0);
+
+ riverSound();
+ pan();
+ moveCanoe();
+
+ if (_vm->_room->_function != FN_CLEAR1) {
+ updateObstacles();
+ riverSetPhysX();
+ bool checkCollide = checkRiverCollide();
+ if (_hitSafe != 0)
+ _hitSafe -= 2;
+
+ if (checkCollide) {
+ _vm->dead(RIVERDEATH[0]);
+ return;
+ }
+
+ if (_deathFlag) {
+ if (--_deathCount == 0) {
+ _vm->dead(RIVERDEATH[_deathType]);
+ return;
+ }
+ }
+
+ // Scroll the river
+ scrollRiver1();
+
+ // Allow time for new scrolled river position to be shown
+ _vm->_canSaveLoad = true;
+ while (!_vm->shouldQuit() && _vm->_room->_function == FN_NONE &&
+ _vm->_events->_vbCount > 0) {
+ _vm->_events->pollEventsAndWait();
+ }
+ _vm->_canSaveLoad = false;
+ }
+
+ if (_vm->_room->_function == FN_CLEAR1) {
+ _vm->_scripts->_endFlag = true;
+ _vm->_scripts->_returnCode = 0;
+ _chickenOutFl = false;
+ break;
+ }
+ }
+}
+
+void River::synchronize(Common::Serializer &s) {
+ if (_vm->_player->_roomNumber == 45) {
+ if (s.isSaving()) {
+ // Set river properties to be saved out
+ _rScrollRow = _vm->_scrollRow;
+ _rScrollCol = _vm->_scrollCol;
+ _rScrollX = _vm->_scrollX;
+ _rScrollY = _vm->_scrollY;
+ _mapOffset = _mapPtr - MAPTBL[_vm->_riverFlag];
+ }
+
+ s.syncAsSint16LE(_canoeLane);
+ s.syncAsSint16LE(_canoeYPos);
+ s.syncAsSint16LE(_hitCount);
+ s.syncAsSint16LE(_riverIndex);
+ s.syncAsSint16LE(_hitSafe);
+ s.syncAsUint16LE(_rScrollRow);
+ s.syncAsUint16LE(_rScrollCol);
+ s.syncAsSint16LE(_rScrollX);
+ s.syncAsSint16LE(_rScrollY);
+ s.syncAsUint16LE(_mapOffset);
+ s.syncAsUint16LE(_screenVertX);
+
+ _saveRiver = s.isLoading();
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+Ant::Ant(AmazonEngine *vm) : AmazonManager(vm) {
+ _antDirection = ANT_RIGHT;
+ _pitDirection = ANT_RIGHT;
+ _antCel = 0;
+ _torchCel = 0;
+ _pitCel = 0;
+ _stabCel = 0;
+ _antPos = Common::Point(0, 0);
+ _antDieFl = _antEatFl = false;
+ _stabFl = false;
+ _pitPos = Common::Point(0, 0);
+}
+
+void Ant::plotTorchSpear(int indx, const int *&buf) {
+ int idx = indx;
+
+ ImageEntry ie;
+ ie._flags = IMGFLAG_UNSCALED;
+ ie._spritesPtr = _vm->_objectsTable[62];
+ ie._frameNumber = buf[(idx / 2)];
+ ie._position = Common::Point(_pitPos.x + buf[(idx / 2) + 1], _pitPos.y + buf[(idx / 2) + 2]);
+ ie._offsetY = 255;
+ _vm->_images.addToList(ie);
+}
+
+void Ant::plotPit(int indx, const int *&buf) {
+ int idx = indx;
+ ImageEntry ie;
+ ie._flags = IMGFLAG_UNSCALED;
+ ie._spritesPtr = _vm->_objectsTable[62];
+ ie._frameNumber = buf[(idx / 2)];
+ ie._position = Common::Point(_pitPos.x, _pitPos.y);
+ ie._offsetY = _pitPos.y;
+ _vm->_images.addToList(ie);
+
+ _vm->_player->_rawPlayer = _pitPos;
+ if (_vm->_inventory->_inv[INV_TORCH]._value == ITEM_IN_INVENTORY) {
+ // Player has torch
+ idx = _torchCel;
+ buf = Amazon::TORCH;
+ _vm->_timers[14]._flag = 1;
+ idx += 6;
+ if (buf[idx / 2] == -1)
+ idx = 0;
+ _torchCel = idx;
+ plotTorchSpear(idx, buf);
+ } else if (!_stabFl && (_vm->_inventory->_inv[INV_KNIFE_SPEAR]._value == ITEM_IN_INVENTORY)) {
+ // Player has spear
+ idx = 0;
+ buf = Amazon::SPEAR;
+ plotTorchSpear(idx, buf);
+ }
+}
+
+int Ant::antHandleRight(int indx, const int *&buf) {
+ int retval = indx;
+ if (_pitDirection == ANT_RIGHT) {
+ _pitDirection = ANT_LEFT;
+ _pitPos.y = 127;
+ }
+ retval = _pitCel;
+ buf = Amazon::PITWALK;
+ if (_pitPos.x < 230) {
+ if (retval == 0) {
+ retval = 48;
+ _pitPos.y = 127;
+ }
+ retval -= 6;
+ _pitPos.x -= buf[(retval / 2) + 1];
+ _pitPos.y -= buf[(retval / 2) + 2];
+ _pitCel = retval;
+ }
+ return retval;
+}
+
+int Ant::antHandleLeft(int indx, const int *&buf) {
+ int retval = indx;
+ if (_pitDirection == ANT_LEFT) {
+ _pitDirection = ANT_RIGHT;
+ _pitPos.y = 127;
+ }
+ retval = _pitCel;
+ buf = Amazon::PITWALK;
+ retval += 6;
+ if (buf[retval / 2] == -1) {
+ retval = 0;
+ _pitPos.y = 127;
+ }
+ _pitPos.x += buf[(retval / 2) + 1];
+ _pitPos.y += buf[(retval / 2) + 2];
+ _pitCel = retval;
+
+ return retval;
+}
+
+int Ant::antHandleStab(int indx, const int *&buf) {
+ int retval = indx;
+ if (_vm->_inventory->_inv[INV_KNIFE_SPEAR]._value == ITEM_IN_INVENTORY) {
+ if (_stabFl) {
+ buf = Amazon::PITSTAB;
+ retval = _stabCel;
+ if (_vm->_timers[13]._flag == 0) {
+ _vm->_timers[13]._flag = 1;
+ retval += 6;
+ _stabCel = retval;
+
+ if (buf[retval] == -1) {
+ _stabFl = false;
+ _pitCel = 0;
+ _pitPos.y = 127;
+ retval = 0;
+ buf = Amazon::PITWALK;
+ } else {
+ _pitPos.x += buf[(retval / 2) + 1];
+ _pitPos.y += buf[(retval / 2) + 2];
+ _pitCel = retval;
+ }
+ }
+ } else {
+ _stabFl = true;
+ _pitCel = 0;
+ retval = 0;
+ _stabCel = 0;
+ int dist = _pitPos.x - _antPos.x;
+ if (_antEatFl && !_antDieFl && (dist <= 80)) {
+ _antDieFl = true;
+ _antCel = 0;
+ _antPos.y = 123;
+ _vm->_sound->playSound(1);
+ }
+ }
+ }
+
+ return retval;
+}
+
+void Ant::doAnt() {
+ _antDirection = ANT_RIGHT;
+ if (_vm->_aniFlag != 1) {
+ _vm->_aniFlag = 1;
+ _antCel = 0;
+ _torchCel = 0;
+ _pitCel = 0;
+
+ _vm->_timers[15]._timer = 16;
+ _vm->_timers[15]._initTm = 16;
+ _vm->_timers[15]._flag = 1;
+
+ _vm->_timers[13]._timer = 5;
+ _vm->_timers[13]._initTm = 5;
+ _vm->_timers[13]._flag = 1;
+
+ _vm->_timers[14]._timer = 10;
+ _vm->_timers[14]._initTm = 10;
+ _vm->_timers[14]._flag = 1;
+
+ _antPos = Common::Point(-40, 123);
+ _antDieFl = _antEatFl = false;
+ _stabFl = false;
+ _pitPos = Common::Point(_vm->_player->_rawPlayer.x, 127);
+ }
+
+ const int *buf = nullptr;
+ if (_antDieFl) {
+ buf = Amazon::ANTDIE;
+ } else if (_antEatFl) {
+ buf = Amazon::ANTEAT;
+ } else if (_antPos.x > 120 && _vm->_flags[198] == 1) {
+ _antEatFl = true;
+ _vm->_flags[235] = 1;
+ _antCel = 0;
+ buf = Amazon::ANTEAT;
+ } else {
+ buf = Amazon::ANTWALK;
+ if (_vm->_inventory->_inv[INV_TORCH]._value == ITEM_IN_INVENTORY)
+ // Player has burning torch, which scares the Ant
+ _antDirection = ANT_LEFT;
+ }
+
+ int idx = _antCel;
+ if (_vm->_timers[15]._flag == 0) {
+ _vm->_timers[15]._flag = 1;
+ if (_antDirection == ANT_LEFT) {
+ if (_antPos.x > 10) {
+ if (idx == 0)
+ idx = 36;
+ else
+ idx -= 6;
+
+ _antPos -= Common::Point(buf[(idx / 2) + 1], buf[(idx / 2) + 2]);
+ _antCel = idx;
+ }
+ } else {
+ idx += 6;
+ if (buf[(idx / 2)] != -1) {
+ _antPos += Common::Point(buf[(idx / 2) + 1], buf[(idx / 2) + 2]);
+ _antCel = idx;
+ } else if (!_antDieFl) {
+ idx = 0;
+ _antPos += Common::Point(buf[(idx / 2) + 1], buf[(idx / 2) + 2]);
+ _antCel = idx;
+ } else {
+ idx -= 6;
+ if (_vm->_flags[200] == 0)
+ _vm->_flags[200] = 1;
+ }
+ }
+ }
+
+ ImageEntry ie;
+ ie._flags = IMGFLAG_UNSCALED;
+ ie._spritesPtr = _vm->_objectsTable[61];
+ ie._frameNumber = buf[(idx / 2)];
+ ie._position = Common::Point(_antPos.x, _antPos.y);
+ ie._offsetY = _antPos.y - 70;
+ _vm->_images.addToList(ie);
+ _antCel = idx;
+
+ if (_vm->_flags[196] != 1) {
+ idx = _pitCel;
+ if (_stabFl) {
+ idx = antHandleStab(idx, buf);
+ } else {
+ buf = Amazon::PITWALK;
+ if (_vm->_timers[13]._flag == 0) {
+ _vm->_timers[13]._flag = 1;
+ _vm->_events->pollEvents();
+ if (_vm->_events->_leftButton) {
+ // Handle moving the player whilst the mouse button is held down
+ Common::Point pt = _vm->_events->calcRawMouse();
+ if (pt.x < _pitPos.x)
+ idx = antHandleLeft(idx, buf);
+ else if (pt.x > _pitPos.x)
+ idx = antHandleRight(idx, buf);
+ } else {
+ // Handle movement based on keyboard keys
+ buf = Amazon::PITWALK;
+ if (_vm->_player->_move == UP)
+ idx = antHandleStab(idx, buf);
+ else if (_vm->_player->_move == LEFT)
+ idx = antHandleLeft(idx, buf);
+ else if (_vm->_player->_move == RIGHT)
+ idx = antHandleRight(idx, buf);
+ }
+ }
+ }
+ plotPit(idx, buf);
+ }
+
+ if (!_antDieFl) {
+ int dist = _pitPos.x - _antPos.x;
+ if ((_antEatFl && (dist <= 45)) || (!_antEatFl && (dist <= 80))) {
+ _vm->_flags[199] = 1;
+ _vm->_aniFlag = 0;
+ }
+ }
+}
+
+void Ant::synchronize(Common::Serializer &s) {
+ if (_vm->_player->_roomNumber == 61) {
+ s.syncAsByte(_antDirection);
+ s.syncAsByte(_pitDirection);
+ s.syncAsSint16LE(_antCel);
+ s.syncAsSint16LE(_torchCel);
+ s.syncAsSint16LE(_pitCel);
+ s.syncAsSint16LE(_stabCel);
+ s.syncAsSint16LE(_antPos.x);
+ s.syncAsSint16LE(_antPos.y);
+ s.syncAsSint16LE(_pitPos.x);
+ s.syncAsSint16LE(_pitPos.y);
+ s.syncAsByte(_antDieFl);
+ s.syncAsByte(_antEatFl);
+ s.syncAsByte(_stabFl);
+ }
+}
+
+
+} // End of namespace Amazon
+
+} // End of namespace Access
diff --git a/engines/access/amazon/amazon_logic.h b/engines/access/amazon/amazon_logic.h
new file mode 100644
index 0000000000..0d962483e6
--- /dev/null
+++ b/engines/access/amazon/amazon_logic.h
@@ -0,0 +1,253 @@
+/* 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 ACCESS_AMAZON_LOGIC_H
+#define ACCESS_AMAZON_LOGIC_H
+
+#include "common/scummsys.h"
+#include "access/scripts.h"
+#include "access/asurface.h"
+
+namespace Access {
+
+namespace Amazon {
+
+class AmazonEngine;
+
+#define PAN_SIZE 32
+
+class AmazonManager {
+protected:
+ AmazonEngine *_vm;
+public:
+ AmazonManager(AmazonEngine *vm) : _vm(vm) {}
+};
+
+class PannedScene : public AmazonManager {
+ struct PanEntry {
+ SpriteResource *_pObject;
+ int _pImgNum;
+ int _pObjX;
+ int _pObjY;
+ int _pObjZ;
+ int _pObjXl;
+ int _pObjYl;
+ };
+protected:
+ int _xCount;
+ int _xTrack;
+ int _yTrack;
+ int _zTrack;
+ int _xCam;
+ int _yCam;
+ int _zCam;
+ int _pNumObj;
+
+ PanEntry _pan[PAN_SIZE];
+public:
+ PannedScene(AmazonEngine *vm);
+
+ void pan();
+};
+
+class CampScene : public PannedScene {
+protected:
+ bool _skipStart;
+public:
+ CampScene(AmazonEngine *vm);
+
+ void mWhileDoOpen();
+};
+
+class Opening : public CampScene {
+private:
+ int _pCount;
+
+ void doTitle();
+ void doCredit();
+ void doCreditDemo();
+ void scrollTitle();
+ void doTent();
+public:
+ Opening(AmazonEngine *vm);
+
+ void doIntroduction();
+};
+
+class Plane : public PannedScene {
+public:
+ int _pCount;
+ Common::Point _position;
+ int _planeCount;
+ int _propCount;
+
+ void doFlyCell();
+ void doFallCell();
+ void scrollFly();
+ void scrollFall();
+ void mWhileFly();
+ void mWhileFall();
+public:
+ Plane(AmazonEngine *vm);
+};
+
+#define JUNGLE_SIZE 3
+class Jungle : public CampScene {
+private:
+ void initJWalk2();
+ void jungleMove();
+ void scrollJWalk();
+
+ int _jCnt[JUNGLE_SIZE];
+ int _jungleX[JUNGLE_SIZE];
+public:
+ Jungle(AmazonEngine *vm);
+
+ void mWhileJWalk();
+ void mWhileJWalk2();
+};
+
+class Guard : public PannedScene {
+private:
+ int _guardCel;
+ Common::Point _position;
+ int _gCode1;
+ int _gCode2;
+ Common::Point _topLeft;
+ Common::Point _bottomRight;
+ int _xMid, _yMid;
+
+ void chkVLine();
+ void chkHLine();
+ void setVerticalCode();
+ void setHorizontalCode();
+ void guardSee();
+ void setGuardFrame();
+public:
+ Guard(AmazonEngine *vm);
+
+ void doGuard();
+
+ void setPosition(const Common::Point &pt);
+};
+
+class Cast : public PannedScene {
+public:
+ Cast(AmazonEngine *vm);
+
+ void doCast(int param1);
+};
+
+class River : public PannedScene {
+private:
+ bool _chickenOutFl;
+ const byte *_mapPtr;
+ int _canoeVXPos;
+ int _canoeMoveCount;
+ int _canoeFrame;
+ RiverStruct *_topList;
+ RiverStruct *_botList;
+ int _canoeDir;
+ bool _saveRiver;
+ bool _deathFlag;
+ int _deathCount;
+ int _deathType;
+ int _maxHits;
+
+ // Saved fields
+ int _canoeLane;
+ int _canoeYPos;
+ int _hitCount;
+ int _riverIndex;
+ int _hitSafe;
+ int _rScrollRow;
+ int _rScrollCol;
+ int _rScrollX;
+ int _rScrollY;
+ int _mapOffset;
+ int _screenVertX;
+ int _oldScrollCol;
+
+ void initRiver();
+ void resetPositions();
+ void checkRiverPan();
+ bool riverJumpTest();
+ void riverSound();
+ void moveCanoe();
+ void moveCanoe2();
+ void updateObstacles();
+ void riverSetPhysX();
+ bool checkRiverCollide();
+ void plotRiver();
+ void scrollRiver();
+ void scrollRiver1();
+ void setRiverPan();
+public:
+ River(AmazonEngine *vm);
+
+ void doRiver();
+ void mWhileDownRiver();
+
+ void synchronize(Common::Serializer &s);
+};
+
+enum AntDirection { ANT_RIGHT = 0, ANT_LEFT = 1 };
+
+class Ant : public AmazonManager {
+private:
+ AntDirection _antDirection;
+ AntDirection _pitDirection;
+ int _antCel;
+ int _torchCel;
+ int _pitCel;
+ int _stabCel;
+ Common::Point _antPos;
+ bool _antDieFl;
+ bool _antEatFl;
+ bool _stabFl;
+ Common::Point _pitPos;
+
+ void plotTorchSpear(int indx, const int *&buf);
+ void plotPit(int indx, const int *&buf);
+ int antHandleRight(int indx, const int *&buf);
+ int antHandleLeft(int indx, const int *&buf);
+ int antHandleStab(int indx, const int *&buf);
+public:
+ Ant(AmazonEngine *vm);
+
+ void doAnt();
+
+ void synchronize(Common::Serializer &s);
+};
+
+class InactivePlayer : public ImageEntry {
+public:
+ SpriteResource *_altSpritesPtr;
+
+ InactivePlayer() { _altSpritesPtr = nullptr; }
+};
+
+} // End of namespace Amazon
+
+} // End of namespace Access
+
+#endif /* ACCESS_AMAZON_LOGIC_H */
diff --git a/engines/access/amazon/amazon_player.cpp b/engines/access/amazon/amazon_player.cpp
new file mode 100644
index 0000000000..b1ed501fce
--- /dev/null
+++ b/engines/access/amazon/amazon_player.cpp
@@ -0,0 +1,86 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+#include "access/access.h"
+#include "access/room.h"
+#include "access/amazon/amazon_game.h"
+#include "access/amazon/amazon_player.h"
+#include "access/amazon/amazon_resources.h"
+
+namespace Access {
+
+namespace Amazon {
+
+AmazonPlayer::AmazonPlayer(AccessEngine *vm) : Player(vm) {
+ _game = (AmazonEngine *)vm;
+}
+
+void AmazonPlayer::load() {
+ Player::load();
+
+ // Special scene setup for the top-down view when on the Slaver ship
+ if (_vm->_room->_roomFlag == 3) {
+ _playerOffset.x = _vm->_screen->_scaleTable1[8];
+ _playerOffset.y = _vm->_screen->_scaleTable1[11];
+ _leftDelta = 0;
+ _rightDelta = 8;
+ _upDelta = 2;
+ _downDelta = -2;
+ _scrollConst = 2;
+
+ for (int i = 0; i < PLAYER_DATA_COUNT; ++i) {
+ _walkOffRight[i] = OVEROFFR[i];
+ _walkOffLeft[i] = OVEROFFL[i];
+ _walkOffUp[i] = OVEROFFU[i];
+ _walkOffDown[i] = OVEROFFD[i];
+ _walkOffUR[i].x = OVEROFFURX[i];
+ _walkOffUR[i].y = OVEROFFURY[i];
+ _walkOffDR[i].x = OVEROFFDRX[i];
+ _walkOffDR[i].y = OVEROFFDRY[i];
+ _walkOffUL[i].x = OVEROFFULX[i];
+ _walkOffUL[i].y = OVEROFFULY[i];
+ _walkOffDL[i].x = OVEROFFDLX[i];
+ _walkOffDL[i].y = OVEROFFDLY[i];
+ }
+
+ _vm->_timers[8]._initTm = 7;
+ _vm->_timers[8]._timer = 7;
+ ++_vm->_timers[8]._flag;
+
+ _sideWalkMin = 0;
+ _sideWalkMax = 5;
+ _upWalkMin = 12;
+ _upWalkMax = 17;
+ _downWalkMin = 6;
+ _downWalkMax = 11;
+ _diagUpWalkMin = 0;
+ _diagUpWalkMax = 5;
+ _diagDownWalkMin = 0;
+ _diagDownWalkMax = 5;
+ _game->_guard->setPosition(Common::Point(56, 190));
+ }
+}
+
+} // End of namespace Amazon
+
+} // End of namespace Access
diff --git a/engines/access/amazon/amazon_player.h b/engines/access/amazon/amazon_player.h
new file mode 100644
index 0000000000..236b8bd1bd
--- /dev/null
+++ b/engines/access/amazon/amazon_player.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 ACCESS_AMAZON_PLAYER_H
+#define ACCESS_AMAZON_PLAYER_H
+
+#include "common/scummsys.h"
+#include "access/player.h"
+
+namespace Access {
+
+namespace Amazon {
+
+class AmazonEngine;
+
+class AmazonPlayer : public Player {
+private:
+ AmazonEngine *_game;
+public:
+ AmazonPlayer(AccessEngine *vm);
+
+ virtual void load();
+};
+
+} // End of namespace Amazon
+
+} // End of namespace Access
+
+#endif /* ACCESS_AMAZON_PLAYER_H */
diff --git a/engines/access/amazon/amazon_resources.cpp b/engines/access/amazon/amazon_resources.cpp
new file mode 100644
index 0000000000..2010c7d842
--- /dev/null
+++ b/engines/access/amazon/amazon_resources.cpp
@@ -0,0 +1,2411 @@
+/* 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 "access/amazon/amazon_resources.h"
+#include "access/access.h"
+
+namespace Access {
+
+namespace Amazon {
+
+const char *const FILENAMES[] = {
+ "S00.AP", "S01.AP", "S02.AP", "R03.AP", "S04.AP", "S05.AP",
+ "S06.AP", "S07.AP", "S08.AP", "S09.AP", "S10.AP", "S11.AP",
+ "S12.AP", "S13.AP", "S14.AP", "S15.AP", "S16.AP", "S17.AP",
+ "S18.AP", "S19.AP", "S20.AP", "S21.AP", "S22.AP", "S23.AP",
+ "S24.AP", "S25.AP", "S26.AP", "S27.AP", "S28.AP", "S29.AP",
+ "S30.AP", "S31.AP", "S32.AP", "S33.AP", "S34.AP", "R35.AP",
+ "S36.AP", "S37.AP", "S38.AP", "S39.AP", "S40.AP", "C26.AP",
+ "S42.AP", "S01.AP", "S44.AP", "S45.AP", "S46.AP", "S47.AP",
+ "C36.AP", nullptr, "S50.AP", nullptr, nullptr, "S53.AP",
+ "S54.AP", "S55.AP", "C35.AP", "S57.AP", "S58.AP", nullptr,
+ nullptr, "S61.AP", nullptr, nullptr, "S64.AP", "C00.AP",
+ "C01.AP", "C06.AP", "C07.AP", "C08.AP", "C05.AP", "C09.AP",
+ "C12.AP", "C03.AP", "C13.AP", "C15.AP", "C14.AP", "C16.AP",
+ "C17.AP", "C19.AP", "C20.AP", "C21.AP", "C22.AP", "C23.AP",
+ "C24.AP", "C25.AP", "C29.AP", "C30.AP", "C32.AP", "C33.AP",
+ "C34.AP", "CREDITS.AP", "MIDIDRV.AP", "SUMMARY.AP", "DEAD.AP",
+ "EST.AP", "CHAPTER.AP", "MIDI.AP", "SOUND.AP", "INV.AP",
+ // The following files are only present in the CD version
+ "NARATE01.AP", "NARATE02.AP", "NARATE03.AP", "NARATE04.AP",
+ "NARATE05.AP", "NARATE06.AP", "NARATE07.AP", "NARATE08.AP",
+ "NARATE09.AP", "NARATE10.AP", "NARATE11.AP", "NARATE12.AP",
+ "NARATE13.AP", "NARATE14.AP", "S00.AP", "TAG.AP"
+};
+
+const char *const FILENAMES_DEMO[] = {
+ "S00.AP", "S01.AP", "S02.AP", "R03.AP", "S04.AP", "S05.AP",
+ "S06.AP", "S07.AP", "S08.AP", "S09.AP", "S10.AP", "S11.AP",
+ "S12.AP", "S13.AP", "S14.AP", "S15.AP", "S16.AP", "S17.AP",
+ "S18.AP", "S19.AP", "S20.AP", "S21.AP", "S22.AP", "S23.AP",
+ "S24.AP", "S25.AP", "S26.AP", "S27.AP", "S28.AP", "S29.AP",
+ "S30.AP", "S31.AP", "S32.AP", "S33.AP", "S34.AP", "R35.AP",
+ "S36.AP", "S37.AP", "S38.AP", "S39.AP", "S40.AP", "TITLE.AP",
+ "S42.AP", "S01.AP", "S44.AP", "S45.AP", "S46.AP", "S47.AP",
+ nullptr, nullptr, "S50.AP", nullptr, nullptr, "S53.AP",
+ "S54.AP", nullptr, nullptr, "S57.AP", nullptr, nullptr,
+ nullptr, "S61.AP", nullptr, "C23.AP", "C12.AP", "C00.AP",
+ "C01.AP", "C06.AP", "C07.AP", "C08.AP", "C05.AP", "C09.AP",
+ "C12.AP", "C03.AP", "C13.AP", "C15.AP", "C14.AP", "C16.AP",
+ "C17.AP", "C19.AP", "C20.AP", "C21.AP", "C22.AP", "C23.AP",
+ "C24.AP", "C25.AP", "R49.AP", "R49.AP", "R49.AP", "R49.AP",
+ "R49.AP", "R49.AP", "R49.AP", "R49.AP", "DEAD.AP", "EST.AP",
+ "CHAPTER.AP", "MUSIC.AP", "SOUND.AP", "INV.AP"
+};
+
+const byte MOUSE0[] = {
+ // hotspot x and y, uint16 LE
+ 0, 0, 0, 0,
+ // byte 1: number of skipped pixels
+ // byte 2: number of plotted pixels
+ // then, pixels
+ 0, 2, 6, 1,
+ 0, 3, 6, 6, 1,
+ 0, 3, 6, 6, 1,
+ 0, 4, 6, 6, 6, 1,
+ 0, 4, 6, 6, 6, 1,
+ 0, 5, 6, 6, 6, 6, 1,
+ 0, 5, 6, 6, 6, 6, 1,
+ 0, 6, 6, 6, 6, 6, 6, 1,
+ 0, 6, 6, 6, 6, 6, 6, 1,
+ 0, 7, 6, 6, 6, 6, 6, 6, 1,
+ 0, 6, 6, 6, 6, 6, 6, 1,
+ 0, 5, 6, 6, 6, 6, 1,
+ 2, 3, 6, 6, 1,
+ 3, 3, 6, 6, 1,
+ 3, 3, 6, 6, 1,
+ 4, 2, 6, 1
+};
+
+const byte MOUSE1[] = {
+ // hotspot x and y, uint16 LE
+ 0x07, 0x00, 0x07, 0x00,
+ // byte 1: number of skipped pixels
+ // byte 2: number of plotted pixels
+ // then, pixels
+ 0x06, 0x01, 0x05,
+ 0x04, 0x05, 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
+ 0x03, 0x07, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0x02, 0x09, 0xFF, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xFF,
+ 0x01, 0x0B, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0x01, 0x0B, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0x00, 0x0D, 0x05, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x00, 0x05,
+ 0x01, 0x0B, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0x01, 0x0B, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0x02, 0x09, 0xFF, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xFF,
+ 0x03, 0x07, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0x04, 0x05, 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
+ 0x06, 0x01, 0x05,
+ 0x00, 0x00,
+ 0x00, 0x00,
+ 0x00, 0x00
+};
+
+const byte MOUSE2[] = {
+ // hotspot x and y, uint16 LE
+ 0x08, 0x00, 0x08, 0x00,
+ // byte 1: number of skipped pixels
+ // byte 2: number of plotted pixels
+ // then, pixels
+ 0x00, 0x00,
+ 0x00, 0x00,
+ 0x07, 0x02, 0x04, 0x05,
+ 0x07, 0x02, 0x04, 0x05,
+ 0x07, 0x02, 0x04, 0x05,
+ 0x07, 0x02, 0x04, 0x05,
+ 0x07, 0x02, 0x04, 0x05,
+ 0x02, 0x0C, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05,
+ 0x07, 0x02, 0x04, 0x05,
+ 0x07, 0x02, 0x04, 0x05,
+ 0x07, 0x02, 0x04, 0x05,
+ 0x07, 0x02, 0x04, 0x05,
+ 0x07, 0x02, 0x04, 0x05,
+ 0x00, 0x00,
+ 0x00, 0x00,
+ 0x00, 0x00
+};
+
+const byte MOUSE3[] = {
+ // hotspot x and y, uint16 LE
+ 0x00, 0x00, 0x00, 0x00,
+ // byte 1: number of skipped pixels
+ // byte 2: number of plotted pixels
+ // then, pixels
+ 0x00, 0x0B, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x00, 0x0C, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x05,
+ 0x00, 0x0C, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x05, 0x05,
+ 0x00, 0x0C, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x05,
+ 0x00, 0x0C, 0x06, 0x06, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x05,
+ 0x00, 0x0C, 0x06, 0x06, 0x06, 0x06, 0x05, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x05,
+ 0x00, 0x0C, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x05,
+ 0x00, 0x0C, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x05,
+ 0x00, 0x0C, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x05,
+ 0x00, 0x0C, 0x06, 0x06, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x05,
+ 0x00, 0x0C, 0x06, 0x06, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x05,
+ 0x00, 0x0C, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x05,
+ 0x01, 0x0B, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x00, 0x00,
+ 0x00, 0x00,
+ 0x00, 0x00
+};
+const byte CURSEYE[] = {
+ // hotspot x and y, uint16 LE
+ 0x01, 0x00, 0x08, 0x00,
+ // byte 1: number of skipped pixels
+ // byte 2: number of plotted pixels
+ // then, pixels
+ 0x04, 0x06, 0x0E, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
+ 0x03, 0x09, 0x0E, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0D, 0x0D,
+ 0x02, 0x0B, 0x0E, 0x01, 0x33, 0x33, 0x01, 0x01, 0x33, 0x34, 0x01, 0x01, 0x0D,
+ 0x01, 0x0D, 0x0E, 0x01, 0x04, 0x34, 0x01, 0x01, 0x01, 0x07, 0x33, 0x04, 0x04, 0x01, 0x0D,
+ 0x00, 0x0F, 0x0E, 0x0E, 0x01, 0x07, 0x33, 0x33, 0x01, 0x01, 0x33, 0x34, 0x07, 0x07, 0x06, 0x01, 0x0E,
+ 0x01, 0x0D, 0x0F, 0x0F, 0x06, 0x07, 0x34, 0x33, 0x33, 0x34, 0x07, 0x07, 0x06, 0x0F, 0x0E,
+ 0x03, 0x09, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0E,
+ 0x01, 0x01, 0x07,
+ 0x00, 0x03, 0x07, 0x01, 0x07,
+ 0x01, 0x01, 0x07,
+ 0x00, 0x00,
+ 0x00, 0x00,
+ 0x00, 0x00,
+ 0x00, 0x00,
+ 0x00, 0x00,
+ 0x00, 0x00
+};
+
+const byte CURSHAND[] = {
+ // hotspot x and y, uint16 LE
+ 0x02, 0x00, 0x03, 0x00,
+ // byte 1: number of skipped pixels
+ // byte 2: number of plotted pixels
+ // then, pixels
+ 0x07, 0x02, 0x17, 0x0E,
+ 0x05, 0x07, 0x0E, 0x12, 0x17, 0x0E, 0x13, 0x17, 0x0E,
+ 0x02, 0x0C, 0x07, 0x00, 0x17, 0x0E, 0x11, 0x0F, 0x0E, 0x11, 0x17, 0x0E, 0x00, 0x17,
+ 0x01, 0x0E, 0x07, 0x01, 0x07, 0x0F, 0x0E, 0x11, 0x17, 0x0E, 0x11, 0x0F, 0x0E, 0x12, 0x17, 0x0E,
+ 0x02, 0x0D, 0x07, 0x00, 0x17, 0x0F, 0x12, 0x0F, 0x0F, 0x11, 0x17, 0x0E, 0x12, 0x0F, 0x0E,
+ 0x04, 0x0B, 0x0F, 0x0E, 0x11, 0x17, 0x0E, 0x12, 0x0F, 0x0F, 0x11, 0x17, 0x0E,
+ 0x04, 0x0B, 0x17, 0x0E, 0x12, 0x17, 0x0E, 0x12, 0x17, 0x0E, 0x11, 0x0F, 0x0E,
+ 0x00, 0x0F, 0x0E, 0x0D, 0x12, 0x00, 0x17, 0x0F, 0x0F, 0x0F, 0x0F, 0x12, 0x0F, 0x0E, 0x12, 0x17, 0x0F,
+ 0x00, 0x0F, 0x0F, 0x17, 0x0D, 0x11, 0x0F, 0x0E, 0x0D, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0E, 0x0D,
+ 0x01, 0x0E, 0x0F, 0x17, 0x0F, 0x0E, 0x0F, 0x0D, 0x0D, 0x0D, 0x0D, 0x0E, 0x0F, 0x0F, 0x0E, 0x0D,
+ 0x02, 0x0D, 0x0F, 0x17, 0x0F, 0x0E, 0x0D, 0x0D, 0x0F, 0x0F, 0x0E, 0x0F, 0x0E, 0x0E, 0x12,
+ 0x03, 0x0C, 0x0F, 0x17, 0x0F, 0x0F, 0x0F, 0x0E, 0x0F, 0x0F, 0x0F, 0x0E, 0x0D, 0x12,
+ 0x04, 0x0A, 0x0F, 0x17, 0x0F, 0x0F, 0x0F, 0x0E, 0x0F, 0x0F, 0x0E, 0x0D,
+ 0x05, 0x09, 0x0F, 0x17, 0x0F, 0x0F, 0x0F, 0x0F, 0x0E, 0x0D, 0x12,
+ 0x06, 0x08, 0x17, 0x0F, 0x0F, 0x0F, 0x0F, 0x0E, 0x0D, 0x12,
+ 0x06, 0x07, 0x17, 0x0F, 0x0F, 0x0F, 0x3D, 0x0E, 0x0D
+};
+
+const byte CURSGET[] = {
+ // hotspot x and y, uint16 LE
+ 0x07, 0x00, 0x0E, 0x00,
+ // byte 1: number of skipped pixels
+ // byte 2: number of plotted pixels
+ // then, pixels
+ 0x0A, 0x05, 0x1C, 0x07, 0x0F, 0x0F, 0x0F,
+ 0x08, 0x08, 0x1C, 0x07, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0C,
+ 0x06, 0x0A, 0x1C, 0x07, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0C,
+ 0x05, 0x0A, 0x07, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0C,
+ 0x03, 0x0C, 0x07, 0x1C, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0C,
+ 0x02, 0x0D, 0x1C, 0x0F, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0C,
+ 0x01, 0x0E, 0x07, 0x0F, 0x0E, 0x0D, 0x0F, 0x0E, 0x0D, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0C,
+ 0x00, 0x0F, 0x1C, 0x0F, 0x0E, 0x0D, 0x0F, 0x0E, 0x0D, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0C,
+ 0x00, 0x0F, 0x1C, 0x0E, 0x0D, 0x0F, 0x0E, 0x0D, 0x0F, 0x0F, 0x0C, 0x0C, 0x0E, 0x0F, 0x0F, 0x0F, 0x0C,
+ 0x00, 0x0E, 0x1C, 0x0D, 0x0F, 0x0E, 0x0D, 0x0F, 0x0F, 0x0C, 0x00, 0x00, 0x0E, 0x0F, 0x0F, 0x0C,
+ 0x00, 0x0E, 0x1C, 0x0E, 0x0F, 0x0D, 0x0F, 0x0F, 0x0C, 0x00, 0x00, 0x0E, 0x1C, 0x0F, 0x0F, 0x0C,
+ 0x00, 0x0D, 0x1C, 0x0D, 0x0F, 0x0D, 0x0F, 0x0C, 0x00, 0x00, 0x00, 0x0E, 0x1C, 0x0F, 0x0C,
+ 0x01, 0x0B, 0x0E, 0x0F, 0x0E, 0x0F, 0x0C, 0x00, 0x00, 0x0E, 0x07, 0x0F, 0x0C,
+ 0x02, 0x09, 0x0E, 0x0D, 0x0F, 0x0C, 0x00, 0x07, 0x0E, 0x0F, 0x0C,
+ 0x03, 0x06, 0x0E, 0x0F, 0x0E, 0x07, 0x01, 0x07,
+ 0x07, 0x01, 0x07
+};
+
+const byte CURSCLIMB[] = {
+ // hotspot x and y, uint16 LE
+ 0x03, 0x00, 0x0E, 0x00,
+ // byte 1: number of skipped pixels
+ // byte 2: number of plotted pixels
+ // then, pixels
+ 0x06, 0x04, 0x01, 0x01, 0x01, 0x01,
+ 0x06, 0x04, 0x0F, 0x0E, 0x01, 0x01,
+ 0x06, 0x04, 0x0F, 0x0E, 0x0D, 0x01,
+ 0x07, 0x02, 0x0F, 0x0D,
+ 0x00, 0x0C, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x13, 0x12, 0x12, 0x12, 0x12, 0x11, 0x11,
+ 0x00, 0x0D, 0x0D, 0x0E, 0x00, 0x00, 0x13, 0x14, 0x13, 0x12, 0x12, 0x12, 0x11, 0x11, 0x0E,
+ 0x01, 0x0C, 0x0D, 0x0D, 0x0D, 0x0E, 0x11, 0x13, 0x13, 0x12, 0x11, 0x11, 0x0E, 0x0D,
+ 0x02, 0x0C, 0x0E, 0x0E, 0x00, 0x00, 0x00, 0x13, 0x12, 0x11, 0x00, 0x00, 0x0E, 0x0D,
+ 0x03, 0x0B, 0x04, 0x04, 0x04, 0x22, 0x21, 0x21, 0x20, 0x00, 0x00, 0x00, 0x0D,
+ 0x02, 0x0D, 0x22, 0x04, 0x20, 0x22, 0x04, 0x21, 0x04, 0x20, 0x00, 0x00, 0x00, 0x0E, 0x0E,
+ 0x03, 0x07, 0x22, 0x21, 0x20, 0x20, 0x22, 0x04, 0x20,
+ 0x04, 0x06, 0x01, 0x01, 0x00, 0x04, 0x22, 0x20,
+ 0x02, 0x09, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x04, 0x20,
+ 0x03, 0x09, 0x07, 0x01, 0x01, 0x00, 0x00, 0x00, 0x22, 0x04, 0x20,
+ 0x02, 0x0B, 0x07, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x20,
+ 0x03, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01
+};
+
+const byte CURSTALK[] = {
+ // hotspot x and y, uint16 LE
+ 0x02, 0x00, 0x0B, 0x00,
+ // byte 1: number of skipped pixels
+ // byte 2: number of plotted pixels
+ // then, pixels
+ 0x03, 0x08, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x01, 0x0C, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06,
+ 0x00, 0x0E, 0x06, 0x06, 0x06, 0x06, 0x07, 0x06, 0x07, 0x07, 0x06, 0x07, 0x07, 0x06, 0x07, 0x06,
+ 0x00, 0x0F, 0x06, 0x08, 0x08, 0x08, 0x06, 0x08, 0x06, 0x06, 0x08, 0x06, 0x06, 0x08, 0x06, 0x08, 0x06,
+ 0x00, 0x0F, 0x06, 0x06, 0x08, 0x06, 0x08, 0x06, 0x08, 0x06, 0x08, 0x06, 0x06, 0x08, 0x08, 0x06, 0x06,
+ 0x00, 0x0F, 0x06, 0x06, 0x08, 0x06, 0x08, 0x08, 0x08, 0x06, 0x08, 0x06, 0x06, 0x08, 0x06, 0x08, 0x06,
+ 0x01, 0x0E, 0x06, 0x08, 0x06, 0x08, 0x06, 0x08, 0x06, 0x08, 0x08, 0x06, 0x08, 0x06, 0x08, 0x06,
+ 0x02, 0x0C, 0x06, 0x06, 0x06, 0x07, 0x06, 0x07, 0x06, 0x06, 0x07, 0x06, 0x07, 0x06,
+ 0x04, 0x09, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06,
+ 0x07, 0x04, 0x06, 0x07, 0x07, 0x06,
+ 0x02, 0x08, 0x07, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x01, 0x06, 0x07, 0x01, 0x07, 0x06, 0x06, 0x06,
+ 0x02, 0x01, 0x07,
+ 0x00, 0x00,
+ 0x00, 0x00,
+ 0x00, 0x00
+};
+const byte CURSHELP[] = {
+ // hotspot x and y, uint16 LE
+ 0x02, 0x00, 0x0B, 0x00,
+ // byte 1: number of skipped pixels
+ // byte 2: number of plotted pixels
+ // then, pixels
+ 0x04, 0x06, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
+ 0x02, 0x0A, 0x24, 0x24, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x20, 0x20,
+ 0x01, 0x0C, 0x24, 0x22, 0x22, 0x22, 0x20, 0x20, 0x20, 0x22, 0x22, 0x22, 0x22, 0x20,
+ 0x00, 0x0E, 0x24, 0x22, 0x22, 0x22, 0x20, 0x00, 0x00, 0x00, 0x24, 0x22, 0x22, 0x22, 0x22, 0x20,
+ 0x00, 0x0E, 0x24, 0x22, 0x22, 0x22, 0x22, 0x20, 0x00, 0x00, 0x00, 0x24, 0x22, 0x22, 0x22, 0x20,
+ 0x00, 0x0E, 0x24, 0x22, 0x22, 0x22, 0x22, 0x20, 0x00, 0x00, 0x00, 0x24, 0x22, 0x22, 0x22, 0x20,
+ 0x01, 0x0D, 0x24, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x24, 0x22, 0x22, 0x22, 0x22, 0x20,
+ 0x07, 0x06, 0x24, 0x22, 0x22, 0x22, 0x22, 0x20,
+ 0x05, 0x07, 0x24, 0x22, 0x22, 0x22, 0x22, 0x20, 0x20,
+ 0x04, 0x05, 0x24, 0x22, 0x22, 0x22, 0x20,
+ 0x02, 0x07, 0x07, 0x00, 0x24, 0x20, 0x20, 0x20, 0x20,
+ 0x01, 0x03, 0x07, 0x01, 0x07,
+ 0x02, 0x07, 0x07, 0x00, 0x00, 0x24, 0x24, 0x24, 0x24,
+ 0x04, 0x06, 0x24, 0x22, 0x22, 0x22, 0x22, 0x20,
+ 0x04, 0x06, 0x24, 0x22, 0x22, 0x22, 0x22, 0x20,
+ 0x05, 0x04, 0x20, 0x20, 0x20, 0x20
+};
+const byte *const CURSORS[10] = {
+ MOUSE0, MOUSE1, MOUSE2, MOUSE3, CURSEYE, CURSHAND, CURSGET, CURSCLIMB, CURSTALK, CURSHELP
+};
+
+const int TRAVEL_POS[][2] = {
+ { -1, 0 },
+ { 228, 117 },
+ { 28, 98 },
+ { 161, 140 },
+ { 130, 139 },
+ { 884, 95 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 41, 185 },
+ { 60, 138 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 170, 155 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 108, 95 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 100, 115 },
+ { 480, 90 },
+ { 154, 63 },
+ { 0, 0 },
+ { 145, 85 },
+ { 0, 0 },
+ { 110, 107 },
+ { 0, 0 },
+ { 105, 154 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 20, 160 },
+ { 130, 314 },
+ { 0, 0 },
+ { 50, 125 },
+ { 0, 0 },
+ { 0, 0 },
+ { 123, 123 },
+ { -1, 7 },
+ { 266, 168 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { -1, 18 },
+ { -1, 19 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 203, 160 },
+ { 0, 0 },
+ { 283, 163 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 180, 165 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 }
+};
+
+const int OVEROFFR[] = { 2, 2, 1, 2, 2, 1, 0, 0, 0 };
+const int OVEROFFL[] = { 2, 2, 1, 2, 2, 1, 0, 0, 0 };
+const int OVEROFFU[] = { 1, 1, 1, 1, 1, 1, 0, 0, 0 };
+const int OVEROFFD[] = { 1, 1, 1, 1, 1, 1, 0, 0, 0 };
+const int OVEROFFURX[] = { 3, 1, 1, 2, 2, 1, 0, 0, 0 };
+const int OVEROFFURY[] = { 1, 0, 0, 1, 1, 0, 0, 0, 0 };
+const int OVEROFFDRX[] = { 1, 2, 1, 1, 2, 1, 0, 0, 0 };
+const int OVEROFFDRY[] = { 0, 1, 0, 0, 1, 1, 0, 0, 0 };
+const int OVEROFFULX[] = { 2, 1, 1, 1, 2, 1, 0, 0, 0 };
+const int OVEROFFULY[] = { 1, 0, 0, 2, 1, 0, 0, 0, 0 };
+const int OVEROFFDLX[] = { 1, 2, 1, 1, 2, 1, 0, 0, 0 };
+const int OVEROFFDLY[] = { 0, 1, 0, 0, 1, 1, 0, 0, 0 };
+
+const byte CREDITS[] = {
+ 0x2, 0xFF, 0xFF, 0x61, 0x0, 0x3, 0x0, 0x30, 0x22, 0x30, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0x0, 0x0, 0xFF, 0xFF,
+ 0x0, 0x0, 0xFF, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+const byte ALLISTER[] = {
+ 0x0, 0xFF, 0xFF, 0x61, 0x0, 0x0, 0x0, 0x36, 0x0F, 0x5E, 0x4, 0x0, 0x0,
+ 0x0, 0x4, 0x4, 0x0, 0x3, 0x0, 0xFF, 0x4, 0x0, 0x2, 0x0, 0x4, 0x0, 0x1, 0x0, 0x8C,
+ 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x0, 0x0, 0x0,
+ 0x1, 0x0, 0x62, 0x0, 0x0B, 0x0, 0x1, 0x0, 0x62, 0x0, 0x0C, 0x0, 0x1, 0x0, 0x62,
+ 0x0, 0x0D, 0x0, 0x1, 0x0, 0xFF, 0xFF
+};
+
+const byte HALL[] = {
+ 0x0, 0xFF, 0xFF, 0x61, 0x0, 0x0, 0x0, 0x40, 0x3E, 0x1A, 0x5, 0x0, 0x0,
+ 0x0, 0x5, 0x5, 0x0, 0x3, 0x0, 0xFF, 0x5, 0x0, 0x2, 0x0, 0x5, 0x0, 0x1, 0x0, 0xFF,
+ 0x30, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x0, 0x0,
+ 0x0, 0x2, 0x0, 0x62, 0x0, 0x0D, 0x0, 0x1, 0x0, 0x62, 0x0, 0x13, 0x0, 0x1, 0x0,
+ 0x62, 0x0, 0x14, 0x0, 0x2, 0x0, 0x62, 0x0, 0x4, 0x0, 0x1, 0x0, 0xFF, 0xFF
+};
+
+const byte JASONLAB[] = {
+ 0x1, 0x6, 0x0, 0x61, 0x0, 0x0D, 0x0, 0x40, 0x20, 0x0C4, 0x6, 0x0, 0x0, 0x0,
+ 0x6, 0x6, 0x0, 0x3, 0x0, 0xFF, 0x6, 0x0, 0x2, 0x0, 0x6, 0x0, 0x1, 0x0, 0xFF, 0x0,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x0, 0x0, 0x0, 0x1,
+ 0x0, 0x62, 0x0, 0x1, 0x0, 0x1, 0x0, 0x62, 0x0, 0x2, 0x0, 0x1, 0x0, 0x62, 0x0, 0x3,
+ 0x0, 0x2, 0x0, 0x62, 0x0, 0x26, 0x0, 0x1, 0x0, 0x62, 0x0, 0x0D, 0x0, 0x1, 0x0,
+ 0x62, 0x0, 0x35, 0x0, 0x2, 0x0, 0xFF, 0xFF
+};
+
+const byte ALLENLAB[] = {
+ 0x1, 0x8, 0x0, 0x61, 0x0, 0x0D, 0x0, 0x40, 0x20, 0x0C4, 0x8, 0x0, 0x0, 0x0,
+ 0x8, 0x8, 0x0, 0x3, 0x0, 0xFF, 0x8, 0x0, 0x2, 0x0, 0x8, 0x0, 0x1, 0x0, 0xFF, 0x0,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x0, 0x0, 0x0, 0x1,
+ 0x0, 0x62, 0x0, 0x7, 0x0, 0x1, 0x0, 0x62, 0x0, 0x8, 0x0, 0x2, 0x0, 0x62, 0x0, 0x9,
+ 0x0, 0x1, 0x0, 0x62, 0x0, 0x0A, 0x0, 0x1, 0x0, 0x62, 0x0, 0x0D, 0x0, 0x1, 0x0,
+ 0xFF, 0xFF
+};
+
+const byte OUTVAULT[] = {
+ 0x0, 0x9, 0x0, 0x61, 0x0, 0x2B, 0x0, 0x30, 0x18, 0x9B, 0x9, 0x0, 0x0, 0x0,
+ 0x9, 0x9, 0x0, 0x3, 0x0, 0xFF, 0x9, 0x0, 0x2, 0x0, 0x9, 0x0, 0x1, 0x0, 0x0B4, 0x10,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x0, 0x0, 0x0, 0x3,
+ 0x0, 0x62, 0x0, 0x4, 0x0, 0x1, 0x0, 0x62, 0x0, 0x5, 0x0, 0x2, 0x0, 0x62, 0x0, 0x6,
+ 0x0, 0x2, 0x0, 0x62, 0x0, 0x36, 0x0, 0x1, 0x0, 0x62, 0x0, 0x47, 0x0, 0x1, 0x0,
+ 0xFF, 0xFF
+};
+
+const byte VAULT[] = {
+ 0x0, 0xFF, 0xFF, 0x61, 0x0, 0x29, 0x0, 0x40, 0x3A, 0x37, 0x0A, 0x0,
+ 0x0, 0x0, 0x0A, 0x0A, 0x0, 0x3, 0x0, 0xFF, 0x0A, 0x0, 0x2, 0x0, 0x0A, 0x0,
+ 0x1, 0x0, 0xFF, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62,
+ 0x0, 0x0, 0x0, 0x1, 0x0, 0x62, 0x0, 0x37, 0x0, 0x2, 0x0, 0x62, 0x0, 0x39, 0x0,
+ 0x1, 0x0, 0x62, 0x0, 0x38, 0x0, 0x2, 0x0, 0x62, 0x0, 0x15, 0x0, 0x2, 0x0, 0xFF,
+ 0xFF
+};
+
+const byte LIBRARY[] = {
+ 0x1, 0xFF, 0xFF, 0x61, 0x0, 0x0C, 0x0, 0x40, 0x3A, 0x22, 0x0B, 0x0,
+ 0x0, 0x0, 0x0B, 0x0B, 0x0, 0x3, 0x0, 0xFF, 0x0B, 0x0, 0x2, 0x0, 0x0B, 0x0,
+ 0x1, 0x0, 0xFF, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62,
+ 0x0, 0x0, 0x0, 0x1, 0x0, 0x62, 0x0, 0x1, 0x0, 0x1, 0x0, 0xFF, 0xFF,
+};
+
+const byte JASAPT[] = {
+ 0x1, 0x0C, 0x0, 0x61, 0x0, 0x19, 0x0, 0x40, 0x30, 0x14, 0x0C, 0x0, 0x0,
+ 0x0, 0x0C, 0x0C, 0x0, 0x3, 0x0, 0xFF, 0x0C, 0x0, 0x2, 0x0, 0x0C, 0x0, 0x1,
+ 0x0, 0xFF, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62,
+ 0x0, 0x18, 0x0, 0x2, 0x0, 0x62, 0x0, 0x17, 0x0, 0x1, 0x0, 0x62, 0x0, 0x11,
+ 0x0, 0x1, 0x0, 0x62, 0x0, 0x0D, 0x0, 0x1, 0x0, 0xFF, 0xFF
+};
+
+const byte RANSACKED[] = {
+ 0x1, 0x0D, 0x0, 0x61, 0x0, 0x2D, 0x0, 0x40, 0x36, 0x2C, 0x0D, 0x0, 0x0,
+ 0x0, 0x0D, 0x0D, 0x0, 0x3, 0x0, 0xFF, 0x0D, 0x0, 0x2, 0x0, 0x0D, 0x0, 0x1,
+ 0x0, 0xFF, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62,
+ 0x0, 0x17, 0x0, 0x1, 0x0, 0xFF, 0xFF
+};
+
+const byte MEAN1[] = {
+ 0x1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x3E, 0x33,
+ 0xFF, 0xFF, 0x0, 0x0, 0xFF, 0x0E, 0x0, 0x5, 0x0, 0x0E, 0x0, 0x4, 0x0,
+ 0xFF, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+const byte FLYSOUTH[] = {
+ 0x1, 0xFF, 0xFF, 0x61, 0x0, 0x10, 0x0, 0x28, 0x0C, 0x5E, 0x0F, 0x0,
+ 0x0, 0x0, 0x0F, 0x0F, 0x0, 0x2, 0x0, 0xFF, 0x0F, 0x0, 0x1, 0x0, 0xFF, 0xFF,
+ 0x1, 0x0, 0xFF, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62,
+ 0x0, 0x44, 0x0, 0x1, 0x0, 0xFF, 0xFF
+};
+
+const byte CUZCO[] = {
+ 0x2, 0x10, 0x0, 0x61, 0x0, 0x10, 0x0, 0x40, 0x20, 0x30, 0x10, 0x0, 0x0,
+ 0x0, 0x10, 0x10, 0x0, 0x3, 0x0, 0xFF, 0x10, 0x0, 0x2, 0x0, 0x10, 0x0, 0x1,
+ 0x0, 0x6E, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62,
+ 0x0, 0x0, 0x0, 0x2, 0x0, 0x62, 0x0, 0x44, 0x0, 0x1, 0x0, 0xFF, 0xFF
+};
+
+const byte INAIR[] = {
+ 0x1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x28, 0x19, 0x2B,
+ 0x11, 0x0, 0x0, 0x0, 0x11, 0x11, 0x0, 0x3, 0x0, 0xFF, 0x11, 0x0, 0x2, 0x0,
+ 0x11, 0x0, 0x1, 0x0, 0xFF, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF
+};
+
+const byte GREENMONKEY[] = {
+ 0x1, 0xFF, 0xFF, 0x61, 0x0, 0x11, 0x0, 0x2D, 0x14, 0x3C, 0x12, 0x0,
+ 0x0, 0x0, 0x12, 0x12, 0x0, 0x3, 0x0, 0xFF, 0x12, 0x0, 0x2, 0x0, 0x12, 0x0,
+ 0x1, 0x0, 0xFF, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+const byte INPLANE[] = {
+ 0x2, 0x13, 0x0, 0x61, 0x0, 0x26, 0x0, 0x2D, 0x28, 0x28, 0x13, 0x0, 0x0,
+ 0x0, 0x13, 0x13, 0x0, 0x3, 0x0, 0xFF, 0x13, 0x0, 0x2, 0x0, 0x13, 0x0, 0x1,
+ 0x0, 0xFF, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x0, 0x0, 0x0,
+ 0x2, 0x0, 0x62, 0x0, 0x29, 0x0, 0x2, 0x0, 0x62, 0x0, 0x1F, 0x0, 0x1, 0x0,
+ 0x62, 0x0, 0x38, 0x0, 0x2, 0x0, 0x62, 0x0, 0x33, 0x0, 0x1, 0x0, 0xFF, 0xFF
+};
+
+const byte PILFALL[] = {
+ 0x1, 0xFF, 0xFF, 0x61, 0x0, 0x16, 0x0, 0x28, 0x0C, 0x5E, 0x14, 0x0,
+ 0x0, 0x0, 0x14, 0x14, 0x0, 0x2, 0x0, 0xFF, 0x14, 0x0, 0x1, 0x0, 0xFF, 0xFF,
+ 0x1, 0x0, 0xFF, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62,
+ 0x0, 0x3A, 0x0, 0x1, 0x0, 0xFF, 0xFF
+};
+
+const byte COCKPIT[] = {
+ 0x1, 0xFF, 0xFF, 0x61, 0x0, 0x12, 0x0, 0x3C, 0x2A, 0x29, 0x15, 0x0,
+ 0x0, 0x0, 0x15, 0x15, 0x0, 0x3, 0x0, 0xFF, 0x15, 0x0, 0x2, 0x0, 0x15, 0x0,
+ 0x1, 0x0, 0xFF, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62,
+ 0x0, 0x23, 0x0, 0x1, 0x0, 0xFF, 0xFF
+};
+
+const byte CRASH[] = {
+ 0x1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x2D, 0x64,
+ 0x16, 0x0, 0x0, 0x0, 0xFF, 0x16, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0x0, 0x0,
+ 0xFF, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0x16, 0x0, 0x2, 0x0, 0xFF,
+ 0xFF, 0x62, 0x0, 0x2A, 0x0, 0x1, 0x0, 0xFF, 0xFF
+};
+
+const byte SINKING[] = {
+ 0x2, 0xFF, 0xFF, 0x61, 0x0, 0x14, 0x0, 0x40, 0x3C, 0x19, 0x17, 0x0,
+ 0x0, 0x0, 0x17, 0x17, 0x0, 0x3, 0x0, 0xFF, 0x17, 0x0, 0x2, 0x0, 0x17, 0x0,
+ 0x1, 0x0, 0xFF, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62,
+ 0x0, 0x0, 0x0, 0x1, 0x0, 0x62, 0x0, 0x48, 0x0, 0x1, 0x0, 0x62, 0x0, 0x17, 0x0,
+ 0x1, 0x0, 0xFF, 0xFF
+};
+
+const byte JNGLWLK[] = {
+ 0x2, 0xFF, 0xFF, 0x61, 0x0, 0x17, 0x0, 0x40, 0x3F, 0x5A, 0x18, 0x0,
+ 0x0, 0x0, 0x18, 0x18, 0x0, 0x2, 0x0, 0xFF, 0x18, 0x0, 0x1, 0x0, 0xFF, 0xFF,
+ 0x0, 0x0, 0x0DC, 0x0A0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x62, 0x0, 0x0, 0x0, 0x1, 0x0, 0xFF, 0xFF
+};
+
+const byte TOWN[] = {
+ 0x2, 0x19, 0x0, 0x61, 0x0, 0x18, 0x0, 0x3E, 0x32, 0x80, 0x19, 0x0, 0x0,
+ 0x0, 0x19, 0x19, 0x0, 0x3, 0x0, 0xFF, 0x19, 0x0, 0x2, 0x0, 0x19, 0x0, 0x1,
+ 0x0, 0x64, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62,
+ 0x0, 0x0, 0x0, 0x1, 0x0, 0x62, 0x0, 0x3D, 0x0, 0x1, 0x0, 0x62, 0x0, 0x3B, 0x0,
+ 0x2, 0x0, 0xFF, 0xFF
+};
+
+const byte HOTEL[] = {
+ 0x1, 0xFF, 0xFF, 0x61, 0x0, 0x19, 0x0, 0x34, 0x28, 0x28, 0x1A, 0x0,
+ 0x0, 0x0, 0x1A, 0x1A, 0x0, 0x3, 0x0, 0xFF, 0x1A, 0x0, 0x2, 0x0, 0x1A, 0x0,
+ 0x1, 0x0, 0xFF, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62,
+ 0x0, 0x28, 0x0, 0x1, 0x0, 0x62, 0x0, 0x2B, 0x0, 0x1, 0x0, 0x62, 0x0, 0x46,
+ 0x0, 0x2, 0x0, 0x62, 0x0, 0x45, 0x0, 0x1, 0x0, 0x62, 0x0, 0x0E, 0x0, 0x1, 0x0,
+ 0xFF, 0xFF
+};
+
+const byte CANTINA[] = {
+ 0x2, 0xFF, 0xFF, 0x61, 0x0, 0x27, 0x0, 0x40, 0x3A, 0x6C, 0x1B, 0x0,
+ 0x0, 0x0, 0x1B, 0x1B, 0x0, 0x3, 0x0, 0xFF, 0x1B, 0x0, 0x2, 0x0, 0x1B, 0x0,
+ 0x1, 0x0, 0x0C8, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62,
+ 0x0, 0x0, 0x0, 0x1, 0x0, 0xFF, 0xFF
+};
+
+const byte MASSACRE[] = {
+ 0x2, 0x1D, 0x0, 0x61, 0x0, 0x32, 0x0, 0x20, 0x18, 0x73, 0x1D, 0x0, 0x0,
+ 0x0, 0x1D, 0x1D, 0x0, 0x3, 0x0, 0xFF, 0x1D, 0x0, 0x2, 0x0, 0x1D, 0x0, 0x1,
+ 0x0, 0x96, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62,
+ 0x0, 0x0, 0x0, 0x1, 0x0, 0x62, 0x0, 0x0C, 0x0, 0x1, 0x0, 0x62, 0x0, 0x3, 0x0, 0x2,
+ 0x0, 0x62, 0x0, 0x49, 0x0, 0x2, 0x0, 0x62, 0x0, 0x4A, 0x0, 0x2, 0x0, 0xFF, 0xFF
+};
+
+const byte TRADE[] = {
+ 0x1, 0xFF, 0xFF, 0x61, 0x0, 0x18, 0x0, 0x3F, 0x1C, 0x27, 0x1E, 0x0,
+ 0x0, 0x0, 0x1E, 0x1E, 0x0, 0x3, 0x0, 0xFF, 0x1E, 0x0, 0x2, 0x0, 0x1E, 0x0,
+ 0x1, 0x0, 0xFF, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+const byte BRIDGE[] = {
+ 0x2, 0x1F, 0x0, 0x61, 0x0, 0x1B, 0x0, 0x40, 0x3F, 0x78, 0x1F, 0x0, 0x0,
+ 0x0, 0x1F, 0x1F, 0x0, 0x3, 0x0, 0xFF, 0x1F, 0x0, 0x2, 0x0, 0x1F, 0x0, 0x1,
+ 0x0, 0xFF, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62,
+ 0x0, 0x0, 0x0, 0x2, 0x0, 0x62, 0x0, 0x1F, 0x0, 0x1, 0x0, 0xFF, 0xFF
+};
+
+const byte DOCK[] = {
+ 0x1, 0xFF, 0xFF, 0x61, 0x0, 0x1E, 0x0, 0x40, 0x3B, 0x4B, 0x20, 0x0,
+ 0x0, 0x0, 0xFF, 0x20, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0x1, 0x0, 0xFF, 0x0,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+const byte DRIVER[] = {
+ 0x1, 0x21, 0x0, 0x61, 0x0, 0x28, 0x0, 0x30, 0x10, 0x51, 0x21, 0x0, 0x0,
+ 0x0, 0x21, 0x21, 0x0, 0x2, 0x0, 0xFF, 0x21, 0x0, 0x1, 0x0, 0xFF, 0xFF,
+ 0x0, 0x0, 0xFF, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62,
+ 0x0, 0x2E, 0x0, 0x1, 0x0, 0x62, 0x0, 0x2F, 0x0, 0x1, 0x0, 0xFF, 0xFF
+};
+
+const byte SHORE[] = {
+ 0x2, 0x24, 0x0, 0x61, 0x0, 0x4, 0x0, 0x3E, 0x3A, 0x32, 0x24, 0x0, 0x0, 0x0,
+ 0x24, 0x24, 0x0, 0x3, 0x0, 0xFF, 0x24, 0x0, 0x2, 0x0, 0x24, 0x0, 0x1, 0x0,
+ 0x0B4, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x0,
+ 0x2D, 0x0, 0x2, 0x0, 0x62, 0x0, 0x1F, 0x0, 0x1, 0x0, 0x62, 0x0, 0x2E, 0x0,
+ 0x1, 0x0, 0x62, 0x0, 0x2F, 0x0, 0x1, 0x0, 0xFF, 0xFF
+};
+
+const byte BOAT[] = {
+ 0x3, 0xFF, 0xFF, 0x61, 0x0, 0x8, 0x0, 0x3F, 0x3F, 0xFF, 0x25, 0x0,
+ 0x0, 0x0, 0x25, 0x25, 0x0, 0x3, 0x0, 0xFF, 0x25, 0x0, 0x2, 0x0, 0x25, 0x0,
+ 0x1, 0x0, 0xFF, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x62, 0x0, 0x0, 0x0, 0x2, 0x0, 0x62, 0x0, 0x21, 0x0, 0x1, 0x0, 0x62, 0x0, 0x25,
+ 0x0, 0x1, 0x0, 0x62, 0x0, 0x1F, 0x0, 0x1, 0x0, 0x62, 0x0, 0x30, 0x0, 0x1, 0x0,
+ 0x62, 0x0, 0x32, 0x0, 0x1, 0x0, 0xFF, 0xFF
+};
+
+const byte CABIN[] = {
+ 0x1, 0xFF, 0xFF, 0x61, 0x0, 0x8, 0x0, 0x40, 0x32, 0x50, 0x26, 0x0,
+ 0x0, 0x0, 0x26, 0x26, 0x0, 0x3, 0x0, 0xFF, 0x26, 0x0, 0x2, 0x0, 0x26, 0x0,
+ 0x1, 0x0, 0xFF, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62,
+ 0x0, 0x0, 0x0, 0x1, 0x0, 0x62, 0x0, 0x22, 0x0, 0x2, 0x0, 0x62, 0x0, 0x31, 0x0,
+ 0x1, 0x0, 0xFF, 0xFF
+};
+
+const byte CAPTIVE[] = {
+ 0x2, 0x27, 0x0, 0x61, 0x0, 0x9, 0x0, 0x40, 0x3F, 0x37, 0x27, 0x0, 0x0, 0x0,
+ 0x27, 0x27, 0x0, 0x3, 0x0, 0xFF, 0x27, 0x0, 0x2, 0x0, 0x27, 0x0, 0x1, 0x0,
+ 0xFF, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x0,
+ 0x0, 0x0, 0x4, 0x0, 0x62, 0x0, 0x1B, 0x0, 0x3, 0x0, 0x62, 0x0, 0x1C, 0x0, 0x1,
+ 0x0, 0x62, 0x0, 0x1F, 0x0, 0x2, 0x0, 0x62, 0x0, 0x23, 0x0, 0x1, 0x0, 0x62,
+ 0x0, 0x32, 0x0, 0x1, 0x0, 0x62, 0x0, 0x33, 0x0, 0x1, 0x0, 0xFF, 0xFF
+};
+
+const byte VILLAGE[] = {
+ 0x2, 0x2A, 0x0, 0x61, 0x0, 0x2E, 0x0, 0x1E, 0x1B, 0x6E, 0x2A, 0x0, 0x0,
+ 0x0, 0x2A, 0x2A, 0x0, 0x3, 0x0, 0xFF, 0x2A, 0x0, 0x2, 0x0, 0x2A, 0x0, 0x1,
+ 0x0, 0x0A5, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62,
+ 0x0, 0x2D, 0x0, 0x3, 0x0, 0x62, 0x0, 0x3F, 0x0, 0x1, 0x0, 0x62, 0x0, 0x40,
+ 0x0, 0x2, 0x0, 0xFF, 0xFF
+};
+
+const byte TREE[] = {
+ 0x2, 0x2C, 0x0, 0x61, 0x0, 0x31, 0x0, 0x1E, 0x1D, 0x0BE, 0x2C, 0x0, 0x0,
+ 0x0, 0x2C, 0x2C, 0x0, 0x3, 0x0, 0xFF, 0x2C, 0x0, 0x2, 0x0, 0x2C, 0x0, 0x1,
+ 0x0, 0x50, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62,
+ 0x0, 0x0, 0x0, 0x2, 0x0, 0x62, 0x0, 0x2E, 0x0, 0x1, 0x0, 0x62, 0x0, 0x2F, 0x0,
+ 0x1, 0x0, 0x62, 0x0, 0x4, 0x0, 0x1, 0x0, 0x62, 0x0, 0x42, 0x0, 0x1, 0x0, 0xFF,
+ 0xFF
+};
+
+const byte CANOE[] = {
+ 0x1, 0x2D, 0x0, 0x61, 0x0, 0x2F, 0x0, 0x1E, 0x1D, 0x78, 0x2D, 0x0, 0x0,
+ 0x0, 0x2D, 0x2D, 0x0, 0x3, 0x0, 0xFF, 0x2D, 0x0, 0x2, 0x0, 0x2D, 0x0, 0x1,
+ 0x0, 0xFF, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62,
+ 0x0, 0x40, 0x0, 0x3, 0x0, 0x62, 0x0, 0x41, 0x0, 0x2, 0x0, 0x62, 0x0, 0x2E,
+ 0x0, 0x2, 0x0, 0x62, 0x0, 0x2F, 0x0, 0x2, 0x0, 0x62, 0x0, 0x16, 0x0, 0x1, 0x0,
+ 0xFF, 0xFF
+};
+
+const byte INTREE[] = {
+ 0x1, 0xFF, 0xFF, 0x61, 0x0, 0x33, 0x0, 0x28, 0x1E, 0x32, 0x2E, 0x0,
+ 0x0, 0x0, 0x2E, 0x2E, 0x0, 0x3, 0x0, 0xFF, 0x2E, 0x0, 0x2, 0x0, 0x2E, 0x0,
+ 0x1, 0x0, 0x0F0, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+const byte FALLS[] = {
+ 0x1, 0xFF, 0xFF, 0x61, 0x0, 0x3B, 0x0, 0x28, 0x1E, 0x32, 0x2F, 0x0,
+ 0x0, 0x0, 0x2F, 0x2F, 0x0, 0x3, 0x0, 0xFF, 0x2F, 0x0, 0x2, 0x0, 0x2F, 0x0,
+ 0x1, 0x0, 0xFF, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62,
+ 0x0, 0x4, 0x0, 0x1, 0x0, 0x62, 0x0, 0x2A, 0x0, 0x1, 0x0, 0xFF, 0xFF
+};
+
+const byte WATERFALL[] = {
+ 0x1, 0x36, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0x28, 0x1E, 0x6E, 0x36,
+ 0x0, 0x0, 0x0, 0x36, 0x36, 0x0, 0x3, 0x0, 0xFF, 0x36, 0x0, 0x2, 0x0, 0x36,
+ 0x0, 0x1, 0x0, 0xFF, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0x36, 0x0, 0x4,
+ 0x0, 0xFF, 0xFF, 0x62, 0x0, 0x1F, 0x0, 0x1, 0x0, 0xFF, 0xFF
+};
+
+const byte INWATER[] = {
+ 0x2, 0xFF, 0xFF, 0x61, 0x0, 0x36, 0x0, 0x40, 0x3F, 0x2A, 0x37, 0x0,
+ 0x0, 0x0, 0x37, 0x37, 0x0, 0x3, 0x0, 0xFF, 0x37, 0x0, 0x2, 0x0, 0x37, 0x0,
+ 0x1, 0x0, 0xFF, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62,
+ 0x0, 0x0, 0x0, 0x1, 0x0, 0x62, 0x0, 0x38, 0x0, 0x1, 0x0, 0xFF, 0xFF
+};
+
+const byte CAVE[] = {
+ 0x2, 0x39, 0x0, 0x61, 0x0, 0x37, 0x0, 0x32, 0x14, 0x73, 0x39, 0x0, 0x0,
+ 0x0, 0x39, 0x39, 0x0, 0x3, 0x0, 0xFF, 0x39, 0x0, 0x2, 0x0, 0x39, 0x0, 0x1,
+ 0x0, 0x0B4, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62,
+ 0x0, 0x0, 0x0, 0x1, 0x0, 0x62, 0x0, 0x1F, 0x0, 0x1, 0x0, 0x62, 0x0, 0x4B, 0x0,
+ 0x2, 0x0, 0x62, 0x0, 0x4C, 0x0, 0x2, 0x0, 0xFF, 0xFF
+};
+
+const byte PIT[] = {
+ 0x2, 0xFF, 0xFF, 0x61, 0x0, 0x38, 0x0, 0x41, 0x3F, 0x19, 0x3D, 0x0,
+ 0x0, 0x0, 0x3D, 0x3D, 0x0, 0x3, 0x0, 0x3E, 0x3D, 0x0, 0x4, 0x0, 0xFF, 0x3D,
+ 0x0, 0x2, 0x0, 0x3D, 0x0, 0x1, 0x0, 0x0BE, 0x0, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x62, 0x0, 0x0, 0x0, 0x2, 0x0, 0x62, 0x0, 0x27, 0x0, 0x1, 0x0,
+ 0x62, 0x0, 0x4D, 0x0, 0x2, 0x0, 0xFF, 0xFF, 0x0
+};
+
+const byte *const ROOM_TABLE[] = {
+ CREDITS, nullptr, nullptr, nullptr, ALLISTER, HALL, JASONLAB, nullptr,
+ ALLENLAB, OUTVAULT, VAULT, LIBRARY, JASAPT, RANSACKED, MEAN1, FLYSOUTH,
+ CUZCO, INAIR, GREENMONKEY, INPLANE, PILFALL, COCKPIT, CRASH, SINKING,
+ JNGLWLK, TOWN, HOTEL, CANTINA, nullptr, MASSACRE, TRADE, BRIDGE, DOCK,
+ DRIVER, nullptr, nullptr, SHORE, BOAT, CABIN, CAPTIVE, nullptr,
+ nullptr, VILLAGE, nullptr, TREE, CANOE, INTREE, FALLS, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, WATERFALL, INWATER, nullptr,
+ CAVE, nullptr, nullptr, nullptr, PIT, nullptr, nullptr
+};
+
+const char *const ROOM_DESCR[] = {
+ "Credits", nullptr, nullptr, nullptr, "Outside of Allister Center",
+ "Hall", "Jason's Lab", nullptr, "Allen's Lab", "Outside of the Vault",
+ "Inside the Vault", "Reader", "Jason's Apartment", "Jason's ransacked apartment", "Cutscene 1",
+ "TBD FLYSOUTH", "Cuzco Airport", "TBD INAIR", "Green Monkey Club", "In Plane",
+ "TBD PILFALL", "TBD COCKPIT", "TBD CRASH", "TBD SINKING", "Cutscene Jungle Walk",
+ "TBD TOWN", "TBD HOTEL", "TBD CANTINA", nullptr, "TBD MASSACRE",
+ "TBD TRADE", "TBD BRIDGE", "TBD DOCK", "TBD DRIVER", nullptr,
+ nullptr, "TBD SHORE", "TBD BOAT", "TBD CABIN", "TBD CAPTIVE",
+ nullptr, nullptr, "TBD VILLAGE", nullptr, "TBD TREE",
+ "TBD CANOE", "TBD INTREE", "TBD FALLS", nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, "TBD WATERFALL",
+ "TBD INWATER", nullptr, "Cave Bridge", nullptr, nullptr,
+ nullptr, "Pit with Ants", nullptr, nullptr
+};
+
+const byte ROOM_TABLE1_DEMO[] = {
+ 0x02, 0x61, 0x00, 0x03, 0x00, 0x30, 0x22, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xFF, 0xFF, 0xFF,
+ 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE5_DEMO[] = {
+ 0x00, 0x61, 0x00, 0x0E, 0x00, 0x36, 0x0F, 0x5E, 0x04, 0x00,
+ 0x00, 0x00, 0x04, 0x04, 0x00, 0x03, 0x00, 0xFF, 0x04, 0x00,
+ 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x8C, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x62, 0x00, 0x0B, 0x00, 0x01, 0x00, 0x62, 0x00, 0x0C, 0x00,
+ 0x01, 0x00, 0x62, 0x00, 0x0D, 0x00, 0x01, 0x00, 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE6_DEMO[] = {
+ 0x00, 0x61, 0x00, 0x0E, 0x00, 0x40, 0x3E, 0x1A, 0x05, 0x00,
+ 0x00, 0x00, 0x05, 0x05, 0x00, 0x03, 0x00, 0xFF, 0x05, 0x00,
+ 0x02, 0x00, 0x05, 0x00, 0x01, 0x00, 0xFF, 0x30, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 0x62, 0x00, 0x12, 0x00, 0x03, 0x00, 0x62, 0x00, 0x13, 0x00,
+ 0x01, 0x00, 0x62, 0x00, 0x14, 0x00, 0x02, 0x00, 0x62, 0x00,
+ 0x04, 0x00, 0x01, 0x00, 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE7_DEMO[] = {
+ 0x01, 0x61, 0x00, 0x0D, 0x00, 0x40, 0x20, 0xC4, 0x06, 0x00,
+ 0x00, 0x00, 0x06, 0x06, 0x00, 0x03, 0x00, 0xFF, 0x06, 0x00,
+ 0x02, 0x00, 0x06, 0x00, 0x01, 0x00, 0xFF, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x62, 0x00, 0x01, 0x00, 0x01, 0x00, 0x62, 0x00, 0x02, 0x00,
+ 0x01, 0x00, 0x62, 0x00, 0x03, 0x00, 0x02, 0x00, 0x62, 0x00,
+ 0x26, 0x00, 0x01, 0x00, 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE9_DEMO[] = {
+ 0x01, 0x61, 0x00, 0x0D, 0x00, 0x40, 0x20, 0xC4, 0x08, 0x00,
+ 0x00, 0x00, 0x08, 0x08, 0x00, 0x03, 0x00, 0xFF, 0x08, 0x00,
+ 0x02, 0x00, 0x08, 0x00, 0x01, 0x00, 0xFF, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x62, 0x00, 0x07, 0x00, 0x01, 0x00, 0x62, 0x00, 0x08, 0x00,
+ 0x02, 0x00, 0x62, 0x00, 0x09, 0x00, 0x01, 0x00, 0x62, 0x00,
+ 0x0A, 0x00, 0x01, 0x00, 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE10_DEMO[] = {
+ 0x00, 0x61, 0x00, 0x0E, 0x00, 0x30, 0x18, 0x9B, 0x09, 0x00,
+ 0x00, 0x00, 0x09, 0x09, 0x00, 0x03, 0x00, 0xFF, 0x09, 0x00,
+ 0x02, 0x00, 0x09, 0x00, 0x01, 0x00, 0xB4, 0x10, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x00, 0x00, 0x00, 0x03, 0x00,
+ 0x62, 0x00, 0x04, 0x00, 0x01, 0x00, 0x62, 0x00, 0x05, 0x00,
+ 0x02, 0x00, 0x62, 0x00, 0x06, 0x00, 0x02, 0x00, 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE11_DEMO[] = {
+ 0x01, 0x61, 0x00, 0x0E, 0x00, 0x40, 0x30, 0x14, 0x0A, 0x00,
+ 0x00, 0x00, 0x0A, 0x0A, 0x00, 0x03, 0x00, 0xFF, 0x0A, 0x00,
+ 0x02, 0x00, 0x0A, 0x00, 0x01, 0x00, 0xFF, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x62, 0x00, 0x15, 0x00, 0x01, 0x00, 0x62, 0x00, 0x16, 0x00,
+ 0x01, 0x00, 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE12_DEMO[] = {
+ 0x01, 0x61, 0x00, 0x0E, 0x00, 0x40, 0x3A, 0x22, 0x0B, 0x00,
+ 0x00, 0x00, 0x0B, 0x0B, 0x00, 0x03, 0x00, 0xFF, 0x0B, 0x00,
+ 0x02, 0x00, 0x0B, 0x00, 0x01, 0x00, 0xFF, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x62, 0x00, 0x01, 0x00, 0x01, 0x00, 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE13_DEMO[] = {
+ 0x01, 0x61, 0x00, 0x08, 0x00, 0x40, 0x30, 0x14, 0x0C, 0x00,
+ 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x03, 0x00, 0xFF, 0x0C, 0x00,
+ 0x02, 0x00, 0x0C, 0x00, 0x01, 0x00, 0xFF, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x00, 0x18, 0x00, 0x02, 0x00,
+ 0x62, 0x00, 0x17, 0x00, 0x01, 0x00, 0x62, 0x00, 0x11, 0x00,
+ 0x01, 0x00, 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE14_DEMO[] = {
+ 0x01, 0x61, 0x00, 0x0D, 0x00, 0x40, 0x36, 0x2C, 0x0D, 0x00,
+ 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x03, 0x00, 0xFF, 0x0D, 0x00,
+ 0x02, 0x00, 0x0D, 0x00, 0x01, 0x00, 0xFF, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE15_DEMO[] = {
+ 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x3E, 0x33, 0xFF, 0xFF,
+ 0x00, 0x00, 0xFF, 0x0E, 0x00, 0x05, 0x00, 0x0E, 0x00, 0x04,
+ 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF
+};
+
+const byte ROOM_TABLE16_DEMO[] = {
+ 0x01, 0x61, 0x00, 0x10, 0x00, 0x28, 0x0C, 0x5E, 0x0F, 0x00,
+ 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x02, 0x00, 0xFF, 0x0F, 0x00,
+ 0x01, 0x00, 0xFF, 0xFF, 0x01, 0x00, 0xFF, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE17_DEMO[] = {
+ 0x02, 0x61, 0x00, 0x10, 0x00, 0x40, 0x20, 0x30, 0x10, 0x00,
+ 0x00, 0x00, 0x10, 0x10, 0x00, 0x03, 0x00, 0xFF, 0x10, 0x00,
+ 0x02, 0x00, 0x10, 0x00, 0x01, 0x00, 0x6E, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE18_DEMO[] = {
+ 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x28, 0x19, 0x2B, 0x11, 0x00,
+ 0x00, 0x00, 0x11, 0x11, 0x00, 0x03, 0x00, 0xFF, 0x11, 0x00,
+ 0x02, 0x00, 0x11, 0x00, 0x01, 0x00, 0xFF, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE19_DEMO[] = {
+ 0x01, 0x61, 0x00, 0x11, 0x00, 0x2D, 0x14, 0x3C, 0x12, 0x00,
+ 0x00, 0x00, 0x12, 0x12, 0x00, 0x03, 0x00, 0xFF, 0x12, 0x00,
+ 0x02, 0x00, 0x12, 0x00, 0x01, 0x00, 0xFF, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE20_DEMO[] = {
+ 0x02, 0x61, 0x00, 0x12, 0x00, 0x2D, 0x28, 0x28, 0x13, 0x00,
+ 0x00, 0x00, 0x13, 0x13, 0x00, 0x03, 0x00, 0xFF, 0x13, 0x00,
+ 0x02, 0x00, 0x13, 0x00, 0x01, 0x00, 0xFF, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 0x62, 0x00, 0x29, 0x00, 0x01, 0x00, 0x62, 0x00, 0x24, 0x00,
+ 0x01, 0x00, 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE21_DEMO[] = {
+ 0x01, 0x61, 0x00, 0x16, 0x00, 0x28, 0x0C, 0x5E, 0x14, 0x00,
+ 0x00, 0x00, 0x14, 0x14, 0x00, 0x02, 0x00, 0xFF, 0x14, 0x00,
+ 0x01, 0x00, 0xFF, 0xFF, 0x01, 0x00, 0xFF, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE22_DEMO[] = {
+ 0x01, 0x61, 0x00, 0x12, 0x00, 0x3C, 0x2A, 0x29, 0x15, 0x00,
+ 0x00, 0x00, 0x15, 0x15, 0x00, 0x03, 0x00, 0xFF, 0x15, 0x00,
+ 0x02, 0x00, 0x15, 0x00, 0x01, 0x00, 0xFF, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x00, 0x23, 0x00, 0x01, 0x00,
+ 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE23_DEMO[] = {
+ 0x01, 0x61, 0x00, 0x13, 0x00, 0x40, 0x2D, 0x64, 0x16, 0x00,
+ 0x00, 0x00, 0xFF, 0x16, 0x00, 0x01, 0x00, 0xFF, 0xFF, 0x00,
+ 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x16, 0x00, 0x02,
+ 0x00, 0xFF, 0xFF, 0x62, 0x00, 0x2A, 0x00, 0x01, 0x00, 0xFF,
+ 0xFF
+};
+
+const byte ROOM_TABLE24_DEMO[] = {
+ 0x02, 0x61, 0x00, 0x14, 0x00, 0x40, 0x3C, 0x19, 0x17, 0x00,
+ 0x00, 0x00, 0x17, 0x17, 0x00, 0x03, 0x00, 0xFF, 0x17, 0x00,
+ 0x02, 0x00, 0x17, 0x00, 0x01, 0x00, 0xFF, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE25_DEMO[] = {
+ 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x3F, 0x5A, 0x18, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x00, 0x02, 0x00, 0xFF, 0x18, 0x00,
+ 0x01, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xDC, 0xA0, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE26_DEMO[] = {
+ 0x02, 0x61, 0x00, 0x17, 0x00, 0x3E, 0x32, 0x80, 0x19, 0x00,
+ 0x00, 0x00, 0x19, 0x19, 0x00, 0x03, 0x00, 0xFF, 0x19, 0x00,
+ 0x02, 0x00, 0x19, 0x00, 0x01, 0x00, 0x64, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE27_DEMO[] = {
+ 0x01, 0x61, 0x00, 0x19, 0x00, 0x34, 0x28, 0x28, 0x1A, 0x00,
+ 0x00, 0x00, 0x1A, 0x1A, 0x00, 0x03, 0x00, 0xFF, 0x1A, 0x00,
+ 0x02, 0x00, 0x1A, 0x00, 0x01, 0x00, 0xFF, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x00, 0x28, 0x00, 0x01, 0x00,
+ 0x62, 0x00, 0x2B, 0x00, 0x01, 0x00, 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE28_DEMO[] = {
+ 0x02, 0x61, 0x00, 0x18, 0x00, 0x40, 0x3A, 0x6C, 0x1B, 0x00,
+ 0x00, 0x00, 0x1B, 0x1B, 0x00, 0x03, 0x00, 0xFF, 0x1B, 0x00,
+ 0x02, 0x00, 0x1B, 0x00, 0x01, 0x00, 0xC8, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE30_DEMO[] = {
+ 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x18, 0x73, 0x1D, 0x00,
+ 0x00, 0x00, 0x1D, 0x1D, 0x00, 0x03, 0x00, 0xFF, 0x1D, 0x00,
+ 0x02, 0x00, 0x1D, 0x00, 0x01, 0x00, 0x80, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE31_DEMO[] = {
+ 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x1C, 0x27, 0x1E, 0x00,
+ 0x00, 0x00, 0x1E, 0x1E, 0x00, 0x03, 0x00, 0xFF, 0x1E, 0x00,
+ 0x02, 0x00, 0x1E, 0x00, 0x01, 0x00, 0xFF, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE32_DEMO[] = {
+ 0x02, 0x61, 0x00, 0x1B, 0x00, 0x40, 0x10, 0x78, 0x1F, 0x00,
+ 0x00, 0x00, 0x1F, 0x1F, 0x00, 0x03, 0x00, 0xFF, 0x1F, 0x00,
+ 0x02, 0x00, 0x1F, 0x00, 0x01, 0x00, 0xFE, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 0x62, 0x00, 0x1F, 0x00, 0x01, 0x00, 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE33_DEMO[] = {
+ 0x01, 0x61, 0x00, 0x1E, 0x00, 0x40, 0x3B, 0x4B, 0x20, 0x00,
+ 0x00, 0x00, 0x20, 0x20, 0x00, 0x03, 0x00, 0xFF, 0x20, 0x00,
+ 0x02, 0x00, 0x20, 0x00, 0x01, 0x00, 0xFF, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE34_DEMO[] = {
+ 0x01, 0x61, 0x00, 0x04, 0x00, 0x30, 0x10, 0x51, 0x21, 0x00,
+ 0x00, 0x00, 0x21, 0x21, 0x00, 0x02, 0x00, 0xFF, 0x21, 0x00,
+ 0x01, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x00, 0x2E, 0x00, 0x01, 0x00,
+ 0x62, 0x00, 0x2F, 0x00, 0x01, 0x00, 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE37_DEMO[] = {
+ 0x02, 0x61, 0x00, 0x04, 0x00, 0x3E, 0x3A, 0x32, 0x24, 0x00,
+ 0x00, 0x00, 0x24, 0x24, 0x00, 0x03, 0x00, 0xFF, 0x24, 0x00,
+ 0x02, 0x00, 0x24, 0x00, 0x01, 0x00, 0xB4, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x00, 0x2D, 0x00, 0x02, 0x00,
+ 0x62, 0x00, 0x1F, 0x00, 0x01, 0x00, 0x62, 0x00, 0x2E, 0x00,
+ 0x01, 0x00, 0x62, 0x00, 0x2F, 0x00, 0x01, 0x00, 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE38_DEMO[] = {
+ 0x03, 0x61, 0x00, 0x08, 0x00, 0x3F, 0x3F, 0xFF, 0x25, 0x00,
+ 0x00, 0x00, 0x25, 0x25, 0x00, 0x03, 0x00, 0xFF, 0x25, 0x00,
+ 0x02, 0x00, 0x25, 0x00, 0x01, 0x00, 0xFF, 0x40, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 0x62, 0x00, 0x21, 0x00, 0x01, 0x00, 0x62, 0x00, 0x25, 0x00,
+ 0x01, 0x00, 0x62, 0x00, 0x1F, 0x00, 0x01, 0x00, 0x62, 0x00,
+ 0x30, 0x00, 0x01, 0x00, 0x62, 0x00, 0x32, 0x00, 0x01, 0x00,
+ 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE39_DEMO[] = {
+ 0x01, 0x61, 0x00, 0x08, 0x00, 0x40, 0x32, 0x50, 0x26, 0x00,
+ 0x00, 0x00, 0x26, 0x26, 0x00, 0x03, 0x00, 0xFF, 0x26, 0x00,
+ 0x02, 0x00, 0x26, 0x00, 0x01, 0x00, 0xFF, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x62, 0x00, 0x22, 0x00, 0x02, 0x00, 0x62, 0x00, 0x31, 0x00,
+ 0x01, 0x00, 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE40_DEMO[] = {
+ 0x02, 0x61, 0x00, 0x09, 0x00, 0x40, 0x3F, 0x37, 0x27, 0x00,
+ 0x00, 0x00, 0x27, 0x27, 0x00, 0x03, 0x00, 0xFF, 0x27, 0x00,
+ 0x02, 0x00, 0x27, 0x00, 0x01, 0x00, 0xFF, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x00, 0x00, 0x00, 0x04, 0x00,
+ 0x62, 0x00, 0x1B, 0x00, 0x03, 0x00, 0x62, 0x00, 0x1C, 0x00,
+ 0x01, 0x00, 0x62, 0x00, 0x1F, 0x00, 0x02, 0x00, 0x62, 0x00,
+ 0x23, 0x00, 0x01, 0x00, 0x62, 0x00, 0x32, 0x00, 0x01, 0x00,
+ 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE43_DEMO[] = {
+ 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0x1E, 0x1B, 0x6E, 0x2A, 0x00,
+ 0x00, 0x00, 0x2A, 0x2A, 0x00, 0x03, 0x00, 0xFF, 0x2A, 0x00,
+ 0x02, 0x00, 0x2A, 0x00, 0x01, 0x00, 0xA5, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE45_DEMO[] = {
+ 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0x1E, 0x1D, 0xBE, 0x2C, 0x00,
+ 0x00, 0x00, 0x2C, 0x2C, 0x00, 0x03, 0x00, 0xFF, 0x2C, 0x00,
+ 0x02, 0x00, 0x2C, 0x00, 0x01, 0x00, 0x50, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE46_DEMO[] = {
+ 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x1E, 0x1D, 0x78, 0x2D, 0x00,
+ 0x00, 0x00, 0x2D, 0x2D, 0x00, 0x03, 0x00, 0xFF, 0x2D, 0x00,
+ 0x02, 0x00, 0x2D, 0x00, 0x01, 0x00, 0xFF, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE47_DEMO[] = {
+ 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x28, 0x1E, 0x32, 0x2E, 0x00,
+ 0x00, 0x00, 0x2E, 0x2E, 0x00, 0x03, 0x00, 0xFF, 0x2E, 0x00,
+ 0x02, 0x00, 0x2E, 0x00, 0x01, 0x00, 0xF0, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE48_DEMO[] = {
+ 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x28, 0x1E, 0x32, 0x2F, 0x00,
+ 0x00, 0x00, 0x2F, 0x2F, 0x00, 0x03, 0x00, 0xFF, 0x2F, 0x00,
+ 0x02, 0x00, 0x2F, 0x00, 0x01, 0x00, 0xFF, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE51_DEMO[] = {
+ 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x28, 0x1E, 0x32, 0xFF, 0xFF,
+ 0x00, 0x00, 0xFF, 0x32, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x04,
+ 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x32,
+ 0x00, 0x01, 0x00, 0x01, 0x00, 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE55_DEMO[] = {
+ 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x28, 0x1E, 0x6E, 0x36, 0x00,
+ 0x00, 0x00, 0x36, 0x36, 0x00, 0x03, 0x00, 0xFF, 0x36, 0x00,
+ 0x02, 0x00, 0x36, 0x00, 0x01, 0x00, 0xFF, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x36, 0x00, 0x04, 0x00, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE58_DEMO[] = {
+ 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0x32, 0x14, 0x73, 0x39, 0x00,
+ 0x00, 0x00, 0x39, 0x39, 0x00, 0x03, 0x00, 0xFF, 0x39, 0x00,
+ 0x02, 0x00, 0x39, 0x00, 0x01, 0x00, 0xB4, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0xFF, 0xFF
+};
+
+const byte ROOM_TABLE62_DEMO[] = {
+ 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0x41, 0x3F, 0x19, 0x3D, 0x00,
+ 0x00, 0x00, 0x3D, 0x3D, 0x00, 0x03, 0x00, 0x3E, 0x3D, 0x00,
+ 0x04, 0x00, 0xFF, 0x3D, 0x00, 0x02, 0x00, 0x3D, 0x00, 0x01,
+ 0x00, 0xBE, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0xFF, 0xFF, 0x00
+};
+
+const byte *const ROOM_TABLE_DEMO[] = {
+ ROOM_TABLE1_DEMO, nullptr, nullptr, nullptr, ROOM_TABLE5_DEMO,
+ ROOM_TABLE6_DEMO, ROOM_TABLE7_DEMO, nullptr, ROOM_TABLE9_DEMO, ROOM_TABLE10_DEMO,
+ ROOM_TABLE11_DEMO, ROOM_TABLE12_DEMO, ROOM_TABLE13_DEMO, ROOM_TABLE14_DEMO, ROOM_TABLE15_DEMO,
+ ROOM_TABLE16_DEMO, ROOM_TABLE17_DEMO, ROOM_TABLE18_DEMO, ROOM_TABLE19_DEMO, ROOM_TABLE20_DEMO,
+ ROOM_TABLE21_DEMO, ROOM_TABLE22_DEMO, ROOM_TABLE23_DEMO, ROOM_TABLE24_DEMO, ROOM_TABLE25_DEMO,
+ ROOM_TABLE26_DEMO, ROOM_TABLE27_DEMO, ROOM_TABLE28_DEMO, nullptr, ROOM_TABLE30_DEMO,
+ ROOM_TABLE31_DEMO, ROOM_TABLE32_DEMO, ROOM_TABLE33_DEMO, ROOM_TABLE34_DEMO, nullptr,
+ nullptr, ROOM_TABLE37_DEMO, ROOM_TABLE38_DEMO, ROOM_TABLE39_DEMO, ROOM_TABLE40_DEMO,
+ nullptr, nullptr, ROOM_TABLE43_DEMO, nullptr, ROOM_TABLE45_DEMO,
+ ROOM_TABLE46_DEMO, ROOM_TABLE47_DEMO, ROOM_TABLE48_DEMO, nullptr, nullptr,
+ ROOM_TABLE51_DEMO, nullptr, nullptr, nullptr, ROOM_TABLE55_DEMO,
+ nullptr, nullptr, ROOM_TABLE58_DEMO, nullptr, nullptr,
+ nullptr, ROOM_TABLE62_DEMO, nullptr, nullptr
+};
+
+const int ROOM_NUMB = 63;
+
+const byte ELAINE[] = {
+ 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x0, 0x0, 0x0, 0x0, 0x41, 0x41, 0x0, 0x1, 0x0, 0xFF, 0x41, 0x0, 0x2,
+ 0x0, 0x41, 0x0, 0x0, 0x0, 0x41, 0x0, 0x3, 0x0, 0x41, 0x0, 0x25, 0x0, 0x41,
+ 0x0, 0x4, 0x0, 0x41, 0x0, 0x26, 0x0, 0x41, 0x0, 0x5, 0x0, 0x41, 0x0, 0x27,
+ 0x0, 0x41, 0x0, 0x6, 0x0, 0x41, 0x0, 0x28, 0x0, 0x41, 0x0, 0x7, 0x0, 0x41,
+ 0x0, 0x29, 0x0, 0x41, 0x0, 0x8, 0x0, 0x41, 0x0, 0x2A, 0x0, 0x41, 0x0, 0x9,
+ 0x0, 0x41, 0x0, 0x2B, 0x0, 0x41, 0x0, 0x0A, 0x0, 0x41, 0x0, 0x2C, 0x0, 0x41,
+ 0x0, 0x0B, 0x0, 0x41, 0x0, 0x2D, 0x0, 0x41, 0x0, 0x0C, 0x0, 0x41, 0x0, 0x2E,
+ 0x0, 0x41, 0x0, 0x0D, 0x0, 0x41, 0x0, 0x2F, 0x0, 0x41, 0x0, 0x0E, 0x0, 0x41,
+ 0x0, 0x30, 0x0, 0x41, 0x0, 0x0F, 0x0, 0x41, 0x0, 0x31, 0x0, 0x41, 0x0, 0x10,
+ 0x0, 0x41, 0x0, 0x32, 0x0, 0x41, 0x0, 0x11, 0x0, 0x41, 0x0, 0x33, 0x0, 0x41,
+ 0x0, 0x12, 0x0, 0x41, 0x0, 0x34, 0x0, 0x41, 0x0, 0x13, 0x0, 0x41, 0x0, 0x35,
+ 0x0, 0x41, 0x0, 0x14, 0x0, 0x41, 0x0, 0x36, 0x0, 0x41, 0x0, 0x15, 0x0, 0x41,
+ 0x0, 0x37, 0x0, 0x41, 0x0, 0x16, 0x0, 0x41, 0x0, 0x38, 0x0, 0x41, 0x0, 0x17,
+ 0x0, 0x41, 0x0, 0x39, 0x0, 0x41, 0x0, 0x18, 0x0, 0x41, 0x0, 0x3A, 0x0, 0x41,
+ 0x0, 0x19, 0x0, 0x41, 0x0, 0x3B, 0x0, 0x41, 0x0, 0x1A, 0x0, 0x41, 0x0, 0x3C,
+ 0x0, 0x41, 0x0, 0x1B, 0x0, 0x41, 0x0, 0x3D, 0x0, 0x41, 0x0, 0x1C, 0x0, 0x41,
+ 0x0, 0x3E, 0x0, 0x41, 0x0, 0x1D, 0x0, 0x41, 0x0, 0x3F, 0x0, 0x41, 0x0, 0x1E,
+ 0x0, 0x41, 0x0, 0x40, 0x0, 0x41, 0x0, 0x1F, 0x0, 0x41, 0x0, 0x41, 0x0, 0x41,
+ 0x0, 0x20, 0x0, 0x41, 0x0, 0x42, 0x0, 0x41, 0x0, 0x21, 0x0, 0x41, 0x0, 0x43,
+ 0x0, 0x41, 0x0, 0x22, 0x0, 0x41, 0x0, 0x44, 0x0, 0x41, 0x0, 0x23, 0x0, 0x41,
+ 0x0, 0x45, 0x0, 0x41, 0x0, 0x24, 0x0, 0x41, 0x0, 0x46, 0x0, 0xFF, 0xFF
+};
+
+const byte LIB[] = {
+ 0x1, 0xFF, 0xFF, 0x42, 0x0, 0x2, 0x0, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x0, 0x0, 0x0, 0x0, 0x42, 0x42, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0x2,
+ 0x0, 0x42, 0x0, 0x0, 0x0, 0x42, 0x0, 0x3, 0x0, 0x42, 0x0, 0x18, 0x0, 0x42,
+ 0x0, 0x4, 0x0, 0x42, 0x0, 0x19, 0x0, 0x42, 0x0, 0x5, 0x0, 0x42, 0x0, 0x1A,
+ 0x0, 0x42, 0x0, 0x6, 0x0, 0x42, 0x0, 0x1B, 0x0, 0x42, 0x0, 0x7, 0x0, 0x42,
+ 0x0, 0x1C, 0x0, 0x42, 0x0, 0x8, 0x0, 0x42, 0x0, 0x1D, 0x0, 0x42, 0x0, 0x9,
+ 0x0, 0x42, 0x0, 0x1E, 0x0, 0x42, 0x0, 0x0A, 0x0, 0x42, 0x0, 0x1F, 0x0, 0x42,
+ 0x0, 0x0B, 0x0, 0x42, 0x0, 0x20, 0x0, 0x42, 0x0, 0x0C, 0x0, 0x42, 0x0, 0x21,
+ 0x0, 0x42, 0x0, 0x0D, 0x0, 0x42, 0x0, 0x22, 0x0, 0x42, 0x0, 0x0E, 0x0, 0x42,
+ 0x0, 0x23, 0x0, 0x42, 0x0, 0x0F, 0x0, 0x42, 0x0, 0x24, 0x0, 0x42, 0x0, 0x10,
+ 0x0, 0x42, 0x0, 0x25, 0x0, 0x42, 0x0, 0x11, 0x0, 0x42, 0x0, 0x26, 0x0, 0x42,
+ 0x0, 0x12, 0x0, 0x42, 0x0, 0x27, 0x0, 0x42, 0x0, 0x13, 0x0, 0x42, 0x0, 0x28,
+ 0x0, 0x42, 0x0, 0x14, 0x0, 0x42, 0x0, 0x29, 0x0, 0x42, 0x0, 0x15, 0x0, 0x42,
+ 0x0, 0x2A, 0x0, 0x42, 0x0, 0x16, 0x0, 0x42, 0x0, 0x2B, 0x0, 0x42, 0x0, 0x17,
+ 0x0, 0x42, 0x0, 0x2C, 0x0, 0xFF, 0xFF
+};
+
+const byte FLASHBACK[] = {
+ 0x2, 0x1B, 0x0, 0x1C, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0,
+ 0x0, 0x0, 0x0, 0xFF, 0xFF, 0xFF, 0x26, 0x0, 0x1C, 0x0, 0x0, 0x0, 0x1C,
+ 0x0, 0x5, 0x0, 0x1C, 0x0, 0x0E, 0x0, 0x1C, 0x0, 0x6, 0x0, 0x1C, 0x0, 0x0F,
+ 0x0, 0x1C, 0x0, 0x7, 0x0, 0x1C, 0x0, 0x0C, 0x0, 0x1C, 0x0, 0x8, 0x0, 0x1C,
+ 0x0, 0x0D, 0x0, 0x2, 0x0, 0x1, 0x0, 0x1C, 0x0, 0x10, 0x0, 0x2, 0x0, 0x2, 0x0, 0x1C,
+ 0x0, 0x11, 0x0, 0x1C, 0x0, 0x9, 0x0, 0x1C, 0x0, 0x12, 0x0, 0x1C, 0x0, 0x0A,
+ 0x0, 0x1C, 0x0, 0x13, 0x0, 0x1C, 0x0, 0x0B, 0x0, 0x1C, 0x0, 0x14, 0x0, 0x1C,
+ 0x0, 0x0B, 0x0, 0x1C, 0x0, 0x15, 0x0, 0x1C, 0x0, 0x0B, 0x0, 0x1C, 0x0, 0x16,
+ 0x0, 0x1C, 0x0, 0x0B, 0x0, 0x1C, 0x0, 0x17, 0x0, 0x1C, 0x0, 0x0B, 0x0, 0x1C,
+ 0x0, 0x18, 0x0, 0x1C, 0x0, 0x0B, 0x0, 0x1C, 0x0, 0x19, 0x0, 0x1C, 0x0, 0x0B,
+ 0x0, 0x1C, 0x0, 0x1A, 0x0, 0x1C, 0x0, 0x0B, 0x0, 0x1C, 0x0, 0x1B, 0x0, 0x1C,
+ 0x0, 0x0B, 0x0, 0x1C, 0x0, 0x1C, 0x0, 0x1C, 0x0, 0x0B, 0x0, 0x1C, 0x0, 0x1D,
+ 0x0, 0x1C, 0x0, 0x0B, 0x0, 0x1C, 0x0, 0x1E, 0x0, 0x1C, 0x0, 0x0B, 0x0, 0x1C,
+ 0x0, 0x1F, 0x0, 0x1C, 0x0, 0x0B, 0x0, 0x1C, 0x0, 0x20, 0x0, 0x1C, 0x0, 0x0B,
+ 0x0, 0x1C, 0x0, 0x21, 0x0, 0x1C, 0x0, 0x0B, 0x0, 0x1C, 0x0, 0x22, 0x0, 0x1C,
+ 0x0, 0x0B, 0x0, 0x1C, 0x0, 0x23, 0x0, 0x1C, 0x0, 0x0B, 0x0, 0x1C, 0x0, 0x24,
+ 0x0, 0xFF, 0xFF
+};
+
+const byte ALLENDIE[] = {
+ 0x2, 0xFF, 0xFF, 0x49, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x0, 0x0, 0x0, 0x0, 0xFF, 0xFF, 0xFF, 0x0, 0x0, 0x49, 0x0, 0x0, 0x0, 0x49,
+ 0x0, 0x4, 0x0, 0x62, 0x0, 0x1F, 0x0, 0x49, 0x0, 0x5, 0x0, 0x62, 0x0, 0x3A,
+ 0x0, 0x49, 0x0, 0x6, 0x0, 0x49, 0x0, 0x7, 0x0, 0xFF, 0xFF
+};
+
+const byte OVERBOARD[] = {
+ 0x2, 0xFF, 0xFF, 0x22, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x0, 0x0, 0x0, 0x0, 0x22, 0x22, 0x0, 0x2, 0x0, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x22, 0x0, 0x0, 0x0, 0x22, 0x0, 0x3, 0x0, 0x22, 0x0, 0x6, 0x0, 0x22,
+ 0x0, 0x4, 0x0, 0x22, 0x0, 0x7, 0x0, 0x22, 0x0, 0x5, 0x0, 0x62, 0x0, 0x1D, 0x0,
+ 0x22, 0x0, 0x5, 0x0, 0x62, 0x0, 0x24, 0x0, 0xFF, 0xFF
+};
+
+const byte PILOT2[] = {
+ 0x0, 0x12, 0x0, 0xFF, 0xFF, 0x0, 0x0, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x0, 0x0, 0x0, 0x0, 0x46, 0x46, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x46, 0x0, 0x0, 0x0, 0x46, 0x0, 0x2, 0x0, 0x46, 0x0, 0x0A, 0x0, 0x46,
+ 0x0, 0x3, 0x0, 0x46, 0x0, 0x0B, 0x0, 0x46, 0x0, 0x4, 0x0, 0x46, 0x0, 0x0C,
+ 0x0, 0x46, 0x0, 0x5, 0x0, 0x46, 0x0, 0x0D, 0x0, 0x46, 0x0, 0x6, 0x0, 0x46,
+ 0x0, 0x0E, 0x0, 0x46, 0x0, 0x7, 0x0, 0x46, 0x0, 0x0F, 0x0, 0x46, 0x0, 0x8,
+ 0x0, 0x46, 0x0, 0x10, 0x0, 0x46, 0x0, 0x9, 0x0, 0x46, 0x0, 0x11, 0x0, 0x46,
+ 0x0, 0x9, 0x0, 0x62, 0x0, 0x1F, 0x0, 0xFF, 0xFF
+};
+
+const byte TIKAGENT[] = {
+ 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x0, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x0, 0x0, 0x0, 0x0, 0x43, 0x43, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0x2,
+ 0x0, 0x43, 0x0, 0x0, 0x0, 0x43, 0x0, 0x2, 0x0, 0x43, 0x0, 0x12, 0x0, 0x43,
+ 0x0, 0x3, 0x0, 0x43, 0x0, 0x13, 0x0, 0x43, 0x0, 0x4, 0x0, 0x43, 0x0, 0x14,
+ 0x0, 0x43, 0x0, 0x5, 0x0, 0x43, 0x0, 0x15, 0x0, 0x43, 0x0, 0x6, 0x0, 0x43,
+ 0x0, 0x16, 0x0, 0x43, 0x0, 0x7, 0x0, 0x43, 0x0, 0x17, 0x0, 0x43, 0x0, 0x8,
+ 0x0, 0x43, 0x0, 0x18, 0x0, 0x43, 0x0, 0x9, 0x0, 0x43, 0x0, 0x19, 0x0, 0x43,
+ 0x0, 0x0A, 0x0, 0x43, 0x0, 0x1A, 0x0, 0x43, 0x0, 0x0B, 0x0, 0x43, 0x0, 0x1B,
+ 0x0, 0x43, 0x0, 0x0C, 0x0, 0x43, 0x0, 0x1C, 0x0, 0x43, 0x0, 0x0D, 0x0, 0x43,
+ 0x0, 0x1D, 0x0, 0x43, 0x0, 0x0E, 0x0, 0x43, 0x0, 0x1E, 0x0, 0x43, 0x0, 0x0F,
+ 0x0, 0x43, 0x0, 0x1F, 0x0, 0x43, 0x0, 0x10, 0x0, 0x43, 0x0, 0x20, 0x0, 0x43,
+ 0x0, 0x11, 0x0, 0x43, 0x0, 0x21, 0x0, 0xFF, 0xFF
+};
+
+const byte BARTENDER[] = {
+ 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x0, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x0, 0x0, 0x0, 0x0, 0x44, 0x44, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0x0,
+ 0x0, 0x44, 0x0, 0x0, 0x0, 0x44, 0x0, 0x2, 0x0, 0x44, 0x0, 0x8, 0x0, 0x44, 0x0,
+ 0x3, 0x0, 0x44, 0x0, 0x9, 0x0, 0x44, 0x0, 0x4, 0x0, 0x44, 0x0, 0x0A, 0x0, 0x44,
+ 0x0, 0x5, 0x0, 0x44, 0x0, 0x0B, 0x0, 0x44, 0x0, 0x6, 0x0, 0x44, 0x0, 0x0C,
+ 0x0, 0x44, 0x0, 0x7, 0x0, 0x44, 0x0, 0x0D, 0x0, 0xFF, 0xFF
+};
+
+const byte PILOT1[] = {
+ 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x0, 0x0, 0x0, 0x0, 0x45, 0x45, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0x0,
+ 0x0, 0x45, 0x0, 0x0, 0x0, 0x45, 0x0, 0x2, 0x0, 0x45, 0x0, 0x3, 0x0, 0xFF, 0xFF
+};
+
+const byte COOK[] = {
+ 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x0, 0x0, 0x0, 0x0, 0x47, 0x47, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF,
+ 0x2, 0x0, 0x47, 0x0, 0x0, 0x0, 0x47, 0x0, 0x2, 0x0, 0x47, 0x0, 0x10, 0x0, 0x47,
+ 0x0, 0x3, 0x0, 0x47, 0x0, 0x11, 0x0, 0x47, 0x0, 0x4, 0x0, 0x47, 0x0, 0x12,
+ 0x0, 0x47, 0x0, 0x5, 0x0, 0x47, 0x0, 0x13, 0x0, 0x47, 0x0, 0x6, 0x0, 0x47,
+ 0x0, 0x14, 0x0, 0x47, 0x0, 0x7, 0x0, 0x47, 0x0, 0x15, 0x0, 0x47, 0x0, 0x8,
+ 0x0, 0x47, 0x0, 0x16, 0x0, 0x47, 0x0, 0x9, 0x0, 0x47, 0x0, 0x17, 0x0, 0x47,
+ 0x0, 0x0A, 0x0, 0x47, 0x0, 0x18, 0x0, 0x47, 0x0, 0x0B, 0x0, 0x47, 0x0, 0x19,
+ 0x0, 0x47, 0x0, 0x0C, 0x0, 0x47, 0x0, 0x1A, 0x0, 0x47, 0x0, 0x0D, 0x0, 0x47,
+ 0x0, 0x1B, 0x0, 0x47, 0x0, 0x0E, 0x0, 0x47, 0x0, 0x1C, 0x0, 0x47, 0x0, 0x0F,
+ 0x0, 0x47, 0x0, 0x1D, 0x0, 0xFF, 0xFF
+};
+
+const byte BEXPLODE[] = {
+ 0x2, 0xFF, 0xFF, 0x28, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x0, 0x0, 0x0, 0x0, 0x28, 0x28, 0x0, 0x2, 0x0, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x28, 0x0, 0x0, 0x0, 0x28, 0x0, 0x3, 0x0, 0x28, 0x0, 0x9, 0x0, 0x28,
+ 0x0, 0x4, 0x0, 0x28, 0x0, 0x0A, 0x0, 0x28, 0x0, 0x5, 0x0, 0x28, 0x0, 0x0B,
+ 0x0, 0x28, 0x0, 0x6, 0x0, 0x62, 0x0, 0x23, 0x0, 0x28, 0x0, 0x7, 0x0, 0x62,
+ 0x0, 0x23, 0x0, 0x28, 0x0, 0x8, 0x0, 0x62, 0x0, 0x23, 0x0, 0xFF, 0xFF
+};
+
+const byte THORNICK[] = {
+ 0x2, 0x7, 0x0, 0x7, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x0, 0x0,
+ 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7, 0x0, 0x0, 0x0, 0x7, 0x0, 0x2, 0x0,
+ 0x7, 0x0, 0x5, 0x0, 0x7, 0x0, 0x3, 0x0, 0x7, 0x0, 0x6, 0x0, 0x7, 0x0, 0x3,
+ 0x0, 0x7, 0x0, 0x7, 0x0, 0x7, 0x0, 0x4, 0x0, 0x7, 0x0, 0x8, 0x0, 0xFF, 0xFF
+};
+
+const byte MAYA[] = {
+ 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0,
+ 0x0, 0x0, 0x0, 0x48, 0x48, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0x2, 0x0,
+ 0x48, 0x0, 0x0, 0x0, 0x48, 0x0, 0x2, 0x0, 0x48, 0x0, 0x13, 0x0, 0x48,
+ 0x0, 0x3, 0x0, 0x48, 0x0, 0x14, 0x0, 0x48, 0x0, 0x4, 0x0, 0x48, 0x0, 0x15,
+ 0x0, 0x48, 0x0, 0x5, 0x0, 0x48, 0x0, 0x16, 0x0, 0x48, 0x0, 0x6, 0x0, 0x48,
+ 0x0, 0x17, 0x0, 0x48, 0x0, 0x7, 0x0, 0x48, 0x0, 0x18, 0x0, 0x48, 0x0, 0x8,
+ 0x0, 0x48, 0x0, 0x19, 0x0, 0x48, 0x0, 0x9, 0x0, 0x48, 0x0, 0x1A, 0x0, 0x48,
+ 0x0, 0x0A, 0x0, 0x48, 0x0, 0x1B, 0x0, 0x48, 0x0, 0x0B, 0x0, 0x48, 0x0, 0x1C,
+ 0x0, 0x48, 0x0, 0x0C, 0x0, 0x48, 0x0, 0x1D, 0x0, 0x48, 0x0, 0x0D, 0x0, 0x48,
+ 0x0, 0x1E, 0x0, 0x48, 0x0, 0x0E, 0x0, 0x48, 0x0, 0x1F, 0x0, 0x48, 0x0, 0x0F,
+ 0x0, 0x48, 0x0, 0x20, 0x0, 0x48, 0x0, 0x10, 0x0, 0x48, 0x0, 0x21, 0x0, 0x48,
+ 0x0, 0x11, 0x0, 0x48, 0x0, 0x22, 0x0, 0x48, 0x0, 0x12, 0x0, 0x48, 0x0, 0x23,
+ 0x0, 0xFF, 0xFF
+};
+
+const byte CAPTAIN[] = {
+ 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x0, 0x0, 0x0, 0x0, 0x4A, 0x4A, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF,
+ 0x2, 0x0, 0x4A, 0x0, 0x0, 0x0, 0x4A, 0x0, 0x2, 0x0, 0x4A, 0x0, 0x0E, 0x0, 0x4A,
+ 0x0, 0x3, 0x0, 0x4A, 0x0, 0x0F, 0x0, 0x4A, 0x0, 0x4, 0x0, 0x4A, 0x0, 0x10,
+ 0x0, 0x4A, 0x0, 0x5, 0x0, 0x4A, 0x0, 0x11, 0x0, 0x4A, 0x0, 0x6, 0x0, 0x4A,
+ 0x0, 0x12, 0x0, 0x4A, 0x0, 0x7, 0x0, 0x4A, 0x0, 0x13, 0x0, 0x4A, 0x0, 0x8,
+ 0x0, 0x4A, 0x0, 0x14, 0x0, 0x4A, 0x0, 0x9, 0x0, 0x4A, 0x0, 0x15, 0x0, 0x4A,
+ 0x0, 0x0A, 0x0, 0x4A, 0x0, 0x16, 0x0, 0x4A, 0x0, 0x0B, 0x0, 0x4A, 0x0, 0x17,
+ 0x0, 0x4A, 0x0, 0x0C, 0x0, 0x4A, 0x0, 0x18, 0x0, 0x4A, 0x0, 0x0D, 0x0, 0x4A,
+ 0x0, 0x19, 0x0, 0xFF, 0xFF
+};
+
+const byte ALLEN[] = {
+ 0x3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x0, 0x0, 0x0, 0x0, 0x1E, 0x4C, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x4C, 0x0, 0x0, 0x0, 0x4C, 0x0, 0x2, 0x0, 0x4C, 0x0, 0x3, 0x0,
+ 0xFF, 0xFF
+};
+
+const byte ARCH[] = {
+ 0x1, 0x2B, 0x0, 0x4B, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0,
+ 0x0, 0x0, 0x0, 0x2B, 0x4B, 0x0, 0x40, 0x0, 0xFF, 0x4B, 0x0, 0x41, 0x0,
+ 0x4B, 0x0, 0x0, 0x0, 0x4B, 0x0, 0x2, 0x0, 0x4B, 0x0, 0x4, 0x0, 0x4B, 0x0, 0x3,
+ 0x0, 0x4B, 0x0, 0x5, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x6, 0x0, 0x4B, 0x0,
+ 0x3, 0x0, 0x4B, 0x0, 0x7, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x8, 0x0, 0x4B,
+ 0x0, 0x3, 0x0, 0x4B, 0x0, 0x9, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x0A, 0x0,
+ 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x0B, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0,
+ 0x0C, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x0D, 0x0, 0x4B, 0x0, 0x3, 0x0,
+ 0x4B, 0x0, 0x0E, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x0F, 0x0, 0x4B, 0x0,
+ 0x3, 0x0, 0x4B, 0x0, 0x10, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x11, 0x0,
+ 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x12, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0,
+ 0x13, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x14, 0x0, 0x4B, 0x0, 0x3, 0x0,
+ 0x4B, 0x0, 0x15, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x16, 0x0, 0x4B, 0x0,
+ 0x3, 0x0, 0x4B, 0x0, 0x17, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x18, 0x0,
+ 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x19, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0,
+ 0x1A, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x1B, 0x0, 0x4B, 0x0, 0x3, 0x0,
+ 0x4B, 0x0, 0x1C, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x1D, 0x0, 0x4B, 0x0,
+ 0x3, 0x0, 0x4B, 0x0, 0x1E, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x1F, 0x0,
+ 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x20, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0,
+ 0x21, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x22, 0x0, 0x4B, 0x0, 0x3, 0x0,
+ 0x4B, 0x0, 0x23, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x24, 0x0, 0x4B, 0x0,
+ 0x3, 0x0, 0x4B, 0x0, 0x25, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x26, 0x0,
+ 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x27, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0,
+ 0x28, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x29, 0x0, 0x4B, 0x0, 0x3, 0x0,
+ 0x4B, 0x0, 0x2A, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x2B, 0x0, 0x4B, 0x0,
+ 0x3, 0x0, 0x4B, 0x0, 0x2C, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x2D, 0x0,
+ 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x2E, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0,
+ 0x2F, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x30, 0x0, 0x4B, 0x0, 0x3, 0x0,
+ 0x4B, 0x0, 0x31, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x32, 0x0, 0x4B, 0x0,
+ 0x3, 0x0, 0x4B, 0x0, 0x33, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x34, 0x0,
+ 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x35, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0,
+ 0x36, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x37, 0x0, 0x4B, 0x0, 0x3, 0x0,
+ 0x4B, 0x0, 0x38, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x39, 0x0, 0x4B, 0x0,
+ 0x3, 0x0, 0x4B, 0x0, 0x3A, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x3B, 0x0,
+ 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x3C, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0,
+ 0x3D, 0x0, 0x4B, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x3E, 0x0, 0x4B, 0x0, 0x3, 0x0,
+ 0x4B, 0x0, 0x3F, 0x0, 0xFF, 0xFF
+};
+
+const byte GUARD1[] = {
+ 0x3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x0, 0x0, 0x0, 0x0, 0x4D, 0x4D, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x4D, 0x0, 0x0, 0x0, 0x4D, 0x0, 0x2, 0x0, 0x4D, 0x0, 0x3, 0x0,
+ 0xFF, 0xFF
+};
+
+const byte MCANOE[] = {
+ 0x3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x0, 0x0, 0x0, 0x0, 0x4E, 0x4E, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x4E, 0x0, 0x0, 0x0, 0x4E, 0x0, 0x2, 0x0, 0x4E, 0x0, 0x3, 0x0,
+ 0xFF, 0xFF
+};
+
+const byte CAMPFIRE[] = {
+ 0x2, 0x35, 0x0, 0x35, 0x0, 0x3, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0,
+ 0x0, 0x0, 0x0, 0x35, 0x35, 0x0, 0x1, 0x0, 0xFF, 0x35, 0x0, 0x2, 0x0, 0x35,
+ 0x0, 0x0, 0x0, 0x35, 0x0, 0x4, 0x0, 0x35, 0x0, 0x18, 0x0, 0x35, 0x0, 0x5, 0x0,
+ 0x35, 0x0, 0x19, 0x0, 0x35, 0x0, 0x6, 0x0, 0x35, 0x0, 0x1A, 0x0, 0x35, 0x0,
+ 0x7, 0x0, 0x35, 0x0, 0x1B, 0x0, 0x35, 0x0, 0x8, 0x0, 0x35, 0x0, 0x1C, 0x0,
+ 0x35, 0x0, 0x9, 0x0, 0x35, 0x0, 0x1D, 0x0, 0x35, 0x0, 0x0A, 0x0, 0x35, 0x0,
+ 0x1E, 0x0, 0x35, 0x0, 0x0B, 0x0, 0x35, 0x0, 0x1F, 0x0, 0x35, 0x0, 0x0C,
+ 0x0, 0x35, 0x0, 0x20, 0x0, 0x35, 0x0, 0x0D, 0x0, 0x35, 0x0, 0x21, 0x0, 0x35,
+ 0x0, 0x0E, 0x0, 0x35, 0x0, 0x22, 0x0, 0x35, 0x0, 0x0F, 0x0, 0x35, 0x0, 0x23,
+ 0x0, 0x35, 0x0, 0x10, 0x0, 0x35, 0x0, 0x24, 0x0, 0x35, 0x0, 0x11, 0x0, 0x35,
+ 0x0, 0x25, 0x0, 0x35, 0x0, 0x12, 0x0, 0x35, 0x0, 0x26, 0x0, 0x35, 0x0, 0x13,
+ 0x0, 0x35, 0x0, 0x27, 0x0, 0x35, 0x0, 0x14, 0x0, 0x35, 0x0, 0x28, 0x0, 0x35,
+ 0x0, 0x15, 0x0, 0x35, 0x0, 0x29, 0x0, 0x35, 0x0, 0x16, 0x0, 0x35, 0x0, 0x2A,
+ 0x0, 0x35, 0x0, 0x17, 0x0, 0x35, 0x0, 0x2B, 0x0, 0xFF, 0xFF
+};
+
+const byte COLONEL[] = {
+ 0x2, 0xFF, 0xFF, 0x0E, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x0, 0x0, 0x0, 0x0, 0x0E, 0x0E, 0x0, 0x5, 0x0, 0xFF, 0xFF, 0xFF, 0x2,
+ 0x0, 0x4F, 0x0, 0x0, 0x0, 0x4F, 0x0, 0x1, 0x0, 0x4F, 0x0, 0x2, 0x0, 0x0E, 0x0,
+ 0x8, 0x0, 0x4F, 0x0, 0x3, 0x0, 0xFF, 0xFF
+};
+
+const byte SOLDIERS[] = {
+ 0x2, 0xFF, 0xFF, 0x50, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x0, 0x0, 0x0, 0x0, 0xFF, 0xFF, 0xFF, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x50,
+ 0x0, 0x2, 0x0, 0x50, 0x0, 0x0, 0x0, 0xFF, 0xFF
+};
+
+const byte JWATER[] = {
+ 0x2, 0xFF, 0xFF, 0x51, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x0, 0x0, 0x0, 0x0, 0xFF, 0xFF, 0xFF, 0x0, 0x0, 0x51, 0x0, 0x0, 0x0, 0x51,
+ 0x0, 0x2, 0x0, 0x51, 0x0, 0x3, 0x0, 0xFF, 0xFF
+};
+
+const byte SHOOT[] = {
+ 0x2, 0xFF, 0xFF, 0x52, 0x0, 0x2, 0x0, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x0, 0x0, 0x0, 0x0, 0x38, 0x52, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0x0,
+ 0x0, 0x52, 0x0, 0x0, 0x0, 0x52, 0x0, 0x3, 0x0, 0x52, 0x0, 0x5, 0x0, 0x52,
+ 0x0, 0x4, 0x0, 0x62, 0x0, 0x1F, 0x0, 0xFF, 0xFF
+};
+
+const byte ADIE[] = {
+ 0x2, 0xFF, 0xFF, 0x53, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x0, 0x0, 0x0, 0x0, 0xFF, 0xFF, 0xFF, 0x2, 0x0, 0x53, 0x0, 0x0, 0x0, 0x53,
+ 0x0, 0x2, 0x0, 0x62, 0x0, 0x4, 0x0, 0x53, 0x0, 0x3, 0x0, 0x62, 0x0, 0x4,
+ 0x0, 0x53, 0x0, 0x4, 0x0, 0x62, 0x0, 0x4, 0x0, 0xFF, 0xFF
+};
+
+const byte DYNAMITE[] = {
+ 0x2, 0xFF, 0xFF, 0x54, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x0, 0x0, 0x0, 0x0, 0xFF, 0xFF, 0xFF, 0x2, 0x0, 0x54, 0x0, 0x0, 0x0, 0x54,
+ 0x0, 0x2, 0x0, 0x62, 0x0, 0x23, 0x0, 0xFF, 0xFF
+};
+
+const byte MAYASHOT[] = {
+ 0x3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x0, 0x0, 0x0, 0x0, 0x36, 0x55, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF,
+ 0x3, 0x0, 0x55, 0x0, 0x0, 0x0, 0x55, 0x0, 0x2, 0x0, 0x62, 0x0, 0x1F,
+ 0x0, 0xFF, 0xFF
+};
+
+const byte OFFKEV[] = {
+ 0x3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0,
+ 0x0, 0x0, 0x0, 0x4D, 0x29, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x29, 0x0, 0x0, 0x0, 0x29, 0x0, 0x2, 0x0, 0x29, 0x0, 0x3, 0x0, 0xFF, 0xFF
+};
+
+const byte VALLEY[] = {
+ 0x2, 0x3A, 0x0, 0x3A, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0,
+ 0x0, 0x0, 0x0, 0x3A, 0x3A, 0x0, 0x2, 0x0, 0xFF, 0xFF, 0xFF, 0x3, 0x0,
+ 0x3A, 0x0, 0x0, 0x0, 0x3A, 0x0, 0x3, 0x0, 0x3A, 0x0, 0x5, 0x0, 0x3A, 0x0,
+ 0x4, 0x0, 0x62, 0x0, 0x27, 0x0, 0xFF, 0xFF
+};
+
+const byte MEANWHILE1[] = {
+ 0x2, 0xFF, 0xFF, 0x0E, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x0, 0x0, 0x0, 0x0, 0x0E, 0x0E, 0x0, 0x5, 0x0, 0xFF, 0xFF, 0xFF, 0x3,
+ 0x0, 0x0E, 0x0, 0x0, 0x0, 0x0E, 0x0, 0x6, 0x0, 0x0E, 0x0, 0x0A, 0x0, 0x0E,
+ 0x0, 0x7, 0x0, 0x0E, 0x0, 0x0B, 0x0, 0x0E, 0x0, 0x8, 0x0, 0x0E, 0x0, 0x0C,
+ 0x0, 0x0E, 0x0, 0x8, 0x0, 0x0E, 0x0, 0x0D, 0x0, 0x0E, 0x0, 0x8, 0x0, 0x0E,
+ 0x0, 0x0E, 0x0, 0x0E, 0x0, 0x9, 0x0, 0x0E, 0x0, 0x0F, 0x0, 0x0E, 0x0, 0x9,
+ 0x0, 0x0E, 0x0, 0x10, 0x0, 0x0E, 0x0, 0x9, 0x0, 0x0E, 0x0, 0x11, 0x0, 0x0E,
+ 0x0, 0x9, 0x0, 0x0E, 0x0, 0x12, 0x0, 0x0E, 0x0, 0x9, 0x0, 0x62, 0x0, 0x1A,
+ 0x0, 0xFF, 0xFF
+};
+
+const byte MAYATREE[] = {
+ 0x3, 0xFF, 0xFF, 0xFF, 0xFF, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x0, 0x0, 0x0, 0x0, 0x30, 0x56, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0x0,
+ 0x0, 0x56, 0x0, 0x0, 0x0, 0x56, 0x0, 0x2, 0x0, 0x56, 0x0, 0x3, 0x0, 0xFF, 0xFF
+};
+
+const byte LOCO[] = {
+ 0x3, 0xFF, 0xFF, 0xFF, 0xFF, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x0, 0x0, 0x0, 0x0, 0x31, 0x57, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0x0,
+ 0x0, 0x57, 0x0, 0x0, 0x0, 0x57, 0x0, 0x2, 0x0, 0x57, 0x0, 0x3, 0x0, 0xFF, 0xFF
+};
+
+const byte KISS[] = {
+ 0x2, 0xFF, 0xFF, 0x3A, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x0, 0x0, 0x0, 0x0, 0x40, 0x40, 0x0, 0x5, 0x0, 0xFF, 0xFF, 0xFF, 0x0,
+ 0x0, 0x40, 0x0, 0x0, 0x0, 0x40, 0x0, 0x6, 0x0, 0x40, 0x0, 0x26, 0x0, 0x40,
+ 0x0, 0x7, 0x0, 0x40, 0x0, 0x27, 0x0, 0x40, 0x0, 0x8, 0x0, 0x40, 0x0, 0x28,
+ 0x0, 0x40, 0x0, 0x9, 0x0, 0x62, 0x0, 0x4E, 0x0, 0x40, 0x0, 0x0A, 0x0, 0x40,
+ 0x0, 0x29, 0x0, 0x40, 0x0, 0x0B, 0x0, 0x40, 0x0, 0x2A, 0x0, 0x40, 0x0, 0x0C,
+ 0x0, 0x40, 0x0, 0x2B, 0x0, 0x40, 0x0, 0x0D, 0x0, 0x40, 0x0, 0x2C, 0x0, 0x40,
+ 0x0, 0x0E, 0x0, 0x40, 0x0, 0x2D, 0x0, 0x40, 0x0, 0x0F, 0x0, 0x40, 0x0, 0x2E,
+ 0x0, 0x40, 0x0, 0x10, 0x0, 0x40, 0x0, 0x2F, 0x0, 0x40, 0x0, 0x11, 0x0, 0x40,
+ 0x0, 0x30, 0x0, 0x40, 0x0, 0x12, 0x0, 0x40, 0x0, 0x31, 0x0, 0x40, 0x0, 0x13,
+ 0x0, 0x40, 0x0, 0x32, 0x0, 0x40, 0x0, 0x14, 0x0, 0x40, 0x0, 0x33, 0x0, 0x40,
+ 0x0, 0x15, 0x0, 0x40, 0x0, 0x34, 0x0, 0x40, 0x0, 0x16, 0x0, 0x40, 0x0, 0x35,
+ 0x0, 0x40, 0x0, 0x17, 0x0, 0x40, 0x0, 0x36, 0x0, 0x40, 0x0, 0x18, 0x0, 0x40,
+ 0x0, 0x37, 0x0, 0x40, 0x0, 0x19, 0x0, 0x40, 0x0, 0x38, 0x0, 0x40, 0x0, 0x1A,
+ 0x0, 0x40, 0x0, 0x39, 0x0, 0x40, 0x0, 0x1B, 0x0, 0x40, 0x0, 0x3A, 0x0, 0x40,
+ 0x0, 0x1C, 0x0, 0x40, 0x0, 0x3B, 0x0, 0x40, 0x0, 0x1D, 0x0, 0x40, 0x0, 0x3C,
+ 0x0, 0x40, 0x0, 0x1E, 0x0, 0x40, 0x0, 0x3D, 0x0, 0x40, 0x0, 0x1F, 0x0, 0x40,
+ 0x0, 0x3E, 0x0, 0x40, 0x0, 0x20, 0x0, 0x40, 0x0, 0x3F, 0x0, 0x40, 0x0, 0x21,
+ 0x0, 0x40, 0x0, 0x40, 0x0, 0x40, 0x0, 0x22, 0x0, 0x40, 0x0, 0x41, 0x0, 0x40,
+ 0x0, 0x23, 0x0, 0x40, 0x0, 0x42, 0x0, 0x40, 0x0, 0x24, 0x0, 0x40, 0x0, 0x43,
+ 0x0, 0x40, 0x0, 0x25, 0x0, 0x40, 0x0, 0x44, 0x0, 0x40, 0x0, 0x25, 0x0, 0x40,
+ 0x0, 0x45, 0x0, 0x40, 0x0, 0x25, 0x0, 0x40, 0x0, 0x46, 0x0, 0x40, 0x0, 0x25,
+ 0x0, 0x40, 0x0, 0x47, 0x0, 0xFF, 0xFF
+};
+
+const byte ROBOT[] = {
+ 0x3, 0xFF, 0xFF, 0xFF, 0xFF, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x0, 0x0, 0x0, 0x0, 0x9, 0x58, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0x0, 0x0,
+ 0x58, 0x0, 0x0, 0x0, 0x58, 0x0, 0x0, 0x0, 0x58, 0x0, 0x2, 0x0, 0xFF, 0xFF
+};
+
+const byte ANTKILL[] = {
+ 0x3, 0xFF, 0xFF, 0xFF, 0xFF, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x0,
+ 0x0, 0x0, 0x3C, 0x59, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0x0, 0x0, 0x59,
+ 0x0, 0x0, 0x0, 0x59, 0x0, 0x2, 0x0, 0x62, 0x0, 0x0E, 0x0, 0xFF, 0xFF
+};
+
+const byte LOCOHOT[] = {
+ 0x3, 0xFF, 0xFF, 0xFF, 0xFF, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x0,
+ 0x0, 0x0, 0x19, 0x5A, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0x0, 0x0, 0x5A,
+ 0x0, 0x0, 0x0, 0x5A, 0x0, 0x2, 0x0, 0x62, 0x0, 0x3C, 0x0, 0xFF, 0xFF
+};
+
+const byte CRACK[] = {
+ 0x2, 0x38, 0x0, 0x38, 0x0, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0,
+ 0x0, 0x0, 0x0, 0xFF, 0xFF, 0xFF, 0x0, 0x0, 0x38, 0x0, 0x0, 0x0, 0x38,
+ 0x0, 0x0, 0x0, 0x38, 0x0, 0x2, 0x0, 0xFF, 0xFF
+};
+
+const byte LETTER[] = {
+ 0x3, 0xFF, 0xFF, 0xFF, 0xFF, 0x1, 0x0, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x0, 0x0, 0x0, 0x0, 0xFF, 0xFF, 0xFF, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x30,
+ 0x0, 0x0, 0x0, 0x30, 0x0, 0x1, 0x0, 0x30, 0x0, 0x0, 0x0, 0x30, 0x0, 0x6, 0x0, 0x30,
+ 0x0, 0x0, 0x0, 0x30, 0x0, 0x7, 0x0, 0x30, 0x0, 0x0, 0x0, 0x30, 0x0, 0x8, 0x0, 0x30,
+ 0x0, 0x0, 0x0, 0x30, 0x0, 0x9, 0x0, 0x30, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0A, 0x0,
+ 0x30, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0B, 0x0, 0x30, 0x0, 0x0, 0x0, 0x30, 0x0,
+ 0x0C, 0x0, 0x30, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0D, 0x0, 0x30, 0x0, 0x0, 0x0,
+ 0x30, 0x0, 0x0E, 0x0, 0x30, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0F, 0x0, 0x30, 0x0,
+ 0x0, 0x0, 0x30, 0x0, 0x10, 0x0, 0x30, 0x0, 0x0, 0x0, 0x30, 0x0, 0x2, 0x0, 0x30,
+ 0x0, 0x0, 0x0, 0x30, 0x0, 0x3, 0x0, 0x30, 0x0, 0x0, 0x0, 0x30, 0x0, 0x4, 0x0, 0x30,
+ 0x0, 0x0, 0x0, 0x30, 0x0, 0x5, 0x0, 0xFF, 0xFF
+};
+
+const byte OVERBOARD_DEMO[] = {
+ 0x02, 0xFF, 0xFF, 0x22, 0x00, 0x01, 0x00, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x02, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x22, 0x00, 0x00, 0x00, 0x22,
+ 0x00, 0x03, 0x00, 0x22, 0x00, 0x06, 0x00, 0x22, 0x00, 0x04,
+ 0x00, 0x22, 0x00, 0x07, 0x00, 0x22, 0x00, 0x05, 0x00, 0x62,
+ 0x00, 0x1D, 0x00, 0x60, 0x00, 0x00, 0x00, 0x22, 0x00, 0x06,
+ 0x00, 0x60, 0x00, 0x01, 0x00, 0x22, 0x00, 0x07, 0x00, 0xFF,
+ 0xFF
+};
+
+const byte SHORE1[] = {
+ 0x02, 0xFF, 0xFF, 0x55, 0x00, 0x01, 0x00, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x03, 0x00,
+ 0x55, 0x00, 0x00, 0x00, 0x55, 0x00, 0x02, 0x00, 0x62, 0x00,
+ 0x2E, 0x00, 0x55, 0x00, 0x02, 0x00, 0x62, 0x00, 0x2F, 0x00,
+ 0xFF, 0xFF
+};
+
+const byte CHAP8[] = {
+ 0x02, 0xFF, 0xFF, 0x60, 0x00, 0x03, 0x00, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x60, 0x00, 0x02, 0x00, 0xFF, 0xFF
+};
+
+const byte *const CHARTBL[] = {
+ ELAINE, LIB, FLASHBACK, ALLENDIE, OVERBOARD, PILOT2, TIKAGENT,
+ BARTENDER, PILOT1, COOK, BEXPLODE, THORNICK, MAYA, CAPTAIN,
+ ALLEN, ARCH, GUARD1, MCANOE, CAMPFIRE, COLONEL, SOLDIERS,
+ JWATER, SHOOT, ADIE, DYNAMITE, MAYASHOT, OFFKEV, VALLEY,
+ MEANWHILE1, MAYATREE, LOCO, KISS, ROBOT, ANTKILL, LOCOHOT,
+ CRACK, LETTER
+};
+
+const byte *const CHARTBL_DEMO[] = {
+ ELAINE, LIB, FLASHBACK, ALLENDIE, OVERBOARD_DEMO, PILOT2, TIKAGENT,
+ BARTENDER, PILOT1, COOK, BEXPLODE, THORNICK, MAYA, CAPTAIN,
+ ALLEN, ARCH, GUARD1, MCANOE, CAMPFIRE, COLONEL, SOLDIERS,
+ JWATER, SHOOT, ADIE, DYNAMITE, SHORE1, CHAP8
+};
+
+const char *const INVENTORY_NAMES[] = {
+ "RAT", "ALCOHOL", "SAFE COMBINATION", "BEAKER", "MICROFILM",
+ "VAULT KEY", "BOLT CUTTERS", "BLOWGUN", "LOVE POTION", "MONEY",
+ "DARTS", "TAPE", "JUNGLE POTION", "MOVIE", "CABINET KEY",
+ "DISPLAY CASE KEY", "FLITCH'S CAR KEYS", "COAT HANGER",
+ "CROWBAR", "COMPASS", "MAP", "LETTER OPENER", "LETTER",
+ "DECODER", "DIPPED DART", "LOADED BLOWGUN", "CARD", "JERRYCAN",
+ "CIGARETTES", "BIKE PUMP", "PARACHUTE", "PESO", "PEPPERS",
+ "MACHETE", "POISON ROOT", "AMMUNITION", "PADDLE", "FISHING NET",
+ "RAT TRAP", "CHEESE", "LOADED TRAP", "KNIFE", "CHOPPED PEPPERS",
+ "LIGHTER", "LADDER", "SMALL POLE", "JEEP KEY", "CHAIN", "ARROW",
+ "FILLED JERRY CAN", "EXPLOSIVES", "GEIGER COUNTER", "VINE",
+ "GOLD NUGGET", "HOLLOW REED", "AMAZON QUEEN KEYS", "FISHING POLE",
+ "HARPOON", "RAG", "BOTTLE OF RUM", "RAG IN BOTTLE", "MOLOTOV COCKTAIL",
+ "JUNGLE PLANT", "LADLE", "WORM", "FISH", "FIREWORKS", "BAITED POLE",
+ "FILLED LADLE", "EMERALD", "SMALL KEY", "SCROLL", "LIT EXPLOSIVES",
+ "LIGHTER", "BROKEN SPEAR", "SHOE LACES", "TORCH", "LACES AND SPEAR",
+ "KNIFE SPEAR", "GARBAGE CAN", "RAFT", "INFLATED RAFT",
+ "JASON'S CAR KEYS", "PESO BILLS", "PLANK"
+};
+
+const int FONT2_INDEX[] = {
+ 62, 2, 6,
+ 0x0000, 0x0019, 0x0021, 0x002e, 0x0041, 0x005a, 0x0073, 0x008c, 0x0093, 0x009b,
+ 0x00a3, 0x00bc, 0x00d5, 0x00dd, 0x00ea, 0x00f1, 0x00fe, 0x010b, 0x0118, 0x0125,
+ 0x0132, 0x013f, 0x014c, 0x0159, 0x0166, 0x0173, 0x0180, 0x0187, 0x018e, 0x01a7,
+ 0x01b4, 0x01cd, 0x01dc, 0x01f5, 0x0208, 0x0215, 0x0222, 0x022f, 0x023c, 0x0249,
+ 0x025c, 0x0269, 0x0276, 0x0285, 0x0292, 0x029f, 0x02b2, 0x02c5, 0x02d2, 0x02df,
+ 0x02ee, 0x02fb, 0x0308, 0x0315, 0x0322, 0x032f, 0x0342, 0x034f, 0x0362, 0x036f,
+ 0x0388, 0x03a1,
+};
+
+const byte FONT2_DATA[] = {
+ 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xf0, 0xf0, 0xf0,
+ 0x00, 0xf0, 0x00, 0x06, 0xf3, 0xc0, 0xc3, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x07, 0x1c, 0x00,
+ 0x67, 0x9e, 0xc0, 0x07, 0x1c, 0x00, 0x67, 0x9e, 0xc0, 0x07,
+ 0x1c, 0x00, 0x00, 0x00, 0x00, 0x09, 0x02, 0xc0, 0x00, 0x3f,
+ 0xfc, 0x00, 0xb2, 0xc0, 0x00, 0x3f, 0xfc, 0x00, 0x02, 0xcb,
+ 0x00, 0x3f, 0xfc, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00,
+ 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x18, 0x60,
+ 0x70, 0x70, 0x60, 0x1c, 0x00, 0x04, 0x60, 0x18, 0x1c, 0x1c,
+ 0x1c, 0x70, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x30,
+ 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xc0,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf0, 0xf0,
+ 0x00, 0x07, 0x00, 0xf0, 0x03, 0xc0, 0x0f, 0x00, 0x3c, 0x00,
+ 0xf0, 0x00, 0x00, 0x00, 0x07, 0x3f, 0xc0, 0x70, 0x70, 0x70,
+ 0x70, 0x70, 0x70, 0x3f, 0xc0, 0x00, 0x00, 0x07, 0x1f, 0x00,
+ 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0xff, 0xf0, 0x00, 0x00,
+ 0x08, 0x2b, 0xf0, 0xb0, 0x2c, 0x00, 0xa0, 0x0a, 0x00, 0xff,
+ 0xfc, 0x00, 0x00, 0x07, 0xff, 0xc0, 0x00, 0x70, 0x03, 0xc0,
+ 0x00, 0x70, 0xff, 0xc0, 0x00, 0x00, 0x07, 0x0b, 0xc0, 0x2d,
+ 0xc0, 0xb1, 0xc0, 0xaa, 0xa0, 0x01, 0xc0, 0x00, 0x00, 0x07,
+ 0xff, 0xf0, 0x70, 0x00, 0x7f, 0xc0, 0x00, 0xb0, 0xbf, 0xc0,
+ 0x00, 0x00, 0x07, 0x2f, 0xc0, 0x70, 0x00, 0x7f, 0xc0, 0x70,
+ 0x70, 0x3f, 0xc0, 0x00, 0x00, 0x08, 0xff, 0xfc, 0x00, 0xb0,
+ 0x02, 0xc0, 0x02, 0xc0, 0x0b, 0x00, 0x00, 0x00, 0x08, 0x2f,
+ 0xf0, 0xb0, 0x1c, 0x2f, 0xf0, 0xb0, 0x1c, 0x2f, 0xf0, 0x00,
+ 0x00, 0x07, 0x3f, 0xc0, 0x70, 0x70, 0x3f, 0xf0, 0x00, 0x70,
+ 0x3f, 0xc0, 0x00, 0x00, 0x03, 0xf0, 0xf0, 0x00, 0xf0, 0xf0,
+ 0x00, 0x03, 0xf0, 0xf0, 0x00, 0xf0, 0x30, 0x00, 0x09, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00,
+ 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0xff, 0x00, 0x03, 0xc0, 0x0f, 0x00, 0x3c, 0x00,
+ 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0a, 0x00, 0x40, 0x00, 0x01, 0xf0, 0x00, 0x07, 0x1c,
+ 0x00, 0x1f, 0xff, 0x00, 0x70, 0x01, 0xc0, 0x00, 0x00, 0x00,
+ 0x08, 0x7f, 0xf0, 0x70, 0x1c, 0x7f, 0xf0, 0x70, 0x1c, 0x6a,
+ 0xb0, 0x00, 0x00, 0x08, 0x2f, 0xfc, 0x70, 0x00, 0x70, 0x00,
+ 0x70, 0x00, 0x2a, 0xa8, 0x00, 0x00, 0x08, 0x7f, 0xf0, 0x70,
+ 0x1c, 0x70, 0x1c, 0x70, 0x1c, 0x6a, 0xb0, 0x00, 0x00, 0x07,
+ 0x7f, 0xf0, 0x70, 0x00, 0x7f, 0xc0, 0x70, 0x00, 0x6a, 0xa0,
+ 0x00, 0x00, 0x07, 0x7f, 0xf0, 0x70, 0x00, 0x7f, 0xc0, 0x70,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x09, 0x3f, 0xfc, 0x00, 0x70,
+ 0x00, 0x00, 0x70, 0xff, 0x00, 0x70, 0x1c, 0x00, 0x2a, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x70, 0x1c, 0x70, 0x1c, 0x7f,
+ 0xfc, 0x70, 0x1c, 0x70, 0x1c, 0x00, 0x00, 0x07, 0xff, 0xf0,
+ 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0xaa, 0xa0, 0x00, 0x00,
+ 0x08, 0x0f, 0xfc, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x70,
+ 0x70, 0x2a, 0x40, 0x00, 0x00, 0x08, 0x70, 0x2c, 0x72, 0xc0,
+ 0x7f, 0x00, 0x72, 0xc0, 0x70, 0x28, 0x00, 0x00, 0x07, 0x70,
+ 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x6a, 0xa0, 0x00,
+ 0x00, 0x0a, 0x70, 0x02, 0xc0, 0x7c, 0x09, 0xc0, 0x77, 0x2d,
+ 0xc0, 0x71, 0xb1, 0xc0, 0x60, 0xc1, 0x80, 0x00, 0x00, 0x00,
+ 0x09, 0x70, 0x07, 0x00, 0x77, 0x07, 0x00, 0x71, 0xc7, 0x00,
+ 0x70, 0x77, 0x00, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x2f, 0xf0, 0x70, 0x1c, 0x70, 0x1c, 0x70, 0x1c, 0x2a, 0xa0,
+ 0x00, 0x00, 0x08, 0x7f, 0xf0, 0x70, 0x1c, 0x7f, 0xf0, 0x70,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x08, 0x2f, 0xf0, 0x70, 0x1c,
+ 0x70, 0x1c, 0x71, 0xdc, 0x2a, 0xa0, 0x00, 0x1c, 0x00, 0x00,
+ 0x08, 0x7f, 0xf0, 0x70, 0x1c, 0x7f, 0xc0, 0x70, 0x70, 0x60,
+ 0x18, 0x00, 0x00, 0x07, 0x2f, 0xf0, 0x70, 0x00, 0x2f, 0xc0,
+ 0x00, 0xb0, 0xbf, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xf0, 0x0b,
+ 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08,
+ 0x70, 0x1c, 0x70, 0x1c, 0x70, 0x1c, 0x70, 0xdc, 0x1f, 0x1c,
+ 0x00, 0x00, 0x08, 0xf0, 0x1c, 0xb0, 0x1c, 0x70, 0xb0, 0x72,
+ 0xc0, 0x7f, 0x00, 0x00, 0x00, 0x0b, 0xf0, 0x00, 0xb0, 0xb0,
+ 0x00, 0x70, 0x70, 0xc0, 0x70, 0x72, 0x72, 0xc0, 0x7c, 0x1f,
+ 0x00, 0x00, 0x00, 0x00, 0x08, 0xf0, 0x3c, 0x1c, 0xe0, 0x07,
+ 0xc0, 0x1c, 0x70, 0x70, 0x1c, 0x00, 0x00, 0x09, 0x70, 0x07,
+ 0x00, 0x1c, 0x1c, 0x00, 0x07, 0xf0, 0x00, 0x01, 0xc0, 0x00,
+ 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x08, 0xff, 0xfc, 0x00,
+ 0x70, 0x07, 0x00, 0x1c, 0x00, 0xaa, 0xac, 0x00, 0x00, 0x09,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,
+ 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,
+};
+
+const int FONT6x6_INDEX[] = {
+ 62, 1, 6,
+ 0x0000, 0x0007, 0x000e, 0x0015, 0x001c, 0x0023, 0x002a, 0x0031, 0x0038, 0x003f,
+ 0x0046, 0x004d, 0x0054, 0x005b, 0x0062, 0x0069, 0x0070, 0x0077, 0x007e, 0x0085,
+ 0x008c, 0x0093, 0x009a, 0x00a1, 0x00a8, 0x00af, 0x00b6, 0x00bd, 0x00c4, 0x00cb,
+ 0x00d2, 0x00d9, 0x00e0, 0x00e7, 0x00ee, 0x00f5, 0x00fc, 0x0103, 0x010a, 0x0111,
+ 0x0118, 0x011f, 0x0126, 0x012d, 0x0134, 0x013b, 0x0142, 0x0149, 0x0150, 0x0157,
+ 0x015e, 0x0165, 0x016c, 0x0173, 0x017a, 0x0181, 0x0188, 0x018f, 0x0196, 0x019d,
+ 0x01a4, 0x01ab,
+};
+
+const byte FONT6x6_DATA[] = {
+ 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x30, 0x30,
+ 0x30, 0x30, 0x00, 0x30, 0x06, 0xd8, 0xd8, 0x90, 0x00, 0x00,
+ 0x00, 0x06, 0x50, 0xf8, 0x50, 0xf8, 0x50, 0x00, 0x06, 0x78,
+ 0xa0, 0x70, 0x28, 0xf0, 0x20, 0x06, 0xc8, 0xd0, 0x20, 0x58,
+ 0x98, 0x00, 0x06, 0x60, 0xd0, 0x60, 0xe8, 0xd0, 0x68, 0x06,
+ 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x06, 0x30, 0x60, 0x60,
+ 0x60, 0x30, 0x00, 0x07, 0x30, 0x18, 0x18, 0x18, 0x30, 0x00,
+ 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x20,
+ 0xf8, 0x20, 0x20, 0x00, 0x06, 0x00, 0x00, 0x00, 0x30, 0x30,
+ 0x60, 0x06, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x06, 0x00,
+ 0x00, 0x00, 0x60, 0x60, 0x00, 0x06, 0x18, 0x30, 0x60, 0xc0,
+ 0x80, 0x00, 0x06, 0x70, 0x98, 0xa8, 0xc8, 0x70, 0x00, 0x06,
+ 0x10, 0x30, 0x10, 0x10, 0x10, 0x00, 0x06, 0xf0, 0x08, 0x70,
+ 0x80, 0xf8, 0x00, 0x06, 0xf0, 0x08, 0x70, 0x08, 0xf0, 0x00,
+ 0x06, 0x30, 0x50, 0x90, 0xf8, 0x10, 0x00, 0x06, 0xf0, 0x80,
+ 0xf0, 0x08, 0xf0, 0x00, 0x06, 0x70, 0x80, 0xf0, 0x88, 0x70,
+ 0x00, 0x06, 0xf8, 0x08, 0x10, 0x20, 0x20, 0x00, 0x06, 0x70,
+ 0x88, 0x70, 0x88, 0x70, 0x00, 0x06, 0x70, 0x88, 0x78, 0x08,
+ 0x70, 0x00, 0x06, 0x60, 0x60, 0x00, 0x60, 0x60, 0x00, 0x06,
+ 0x60, 0x60, 0x00, 0x60, 0x20, 0x40, 0x06, 0x18, 0x30, 0x60,
+ 0x30, 0x18, 0x00, 0x06, 0x00, 0x78, 0x00, 0x78, 0x00, 0x00,
+ 0x06, 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0x06, 0x70, 0x98,
+ 0x30, 0x30, 0x00, 0x30, 0x06, 0x70, 0x88, 0xb8, 0xb0, 0x80,
+ 0x78, 0x06, 0x70, 0x88, 0xf8, 0x88, 0x88, 0x00, 0x06, 0xf0,
+ 0x88, 0xf0, 0x88, 0xf0, 0x00, 0x06, 0x78, 0x80, 0x80, 0x80,
+ 0x78, 0x00, 0x06, 0xf0, 0x88, 0x88, 0x88, 0xf0, 0x00, 0x06,
+ 0xf8, 0x80, 0xf0, 0x80, 0xf8, 0x00, 0x06, 0xf8, 0x80, 0xf0,
+ 0x80, 0x80, 0x00, 0x06, 0x78, 0x80, 0x98, 0x88, 0x78, 0x00,
+ 0x06, 0x88, 0x88, 0xf8, 0x88, 0x88, 0x00, 0x06, 0x70, 0x20,
+ 0x20, 0x20, 0x70, 0x00, 0x06, 0x08, 0x08, 0x08, 0x88, 0x70,
+ 0x00, 0x06, 0x90, 0xa0, 0xc0, 0xa0, 0x90, 0x00, 0x06, 0x80,
+ 0x80, 0x80, 0x80, 0xf0, 0x00, 0x06, 0x88, 0xd8, 0xa8, 0x88,
+ 0x88, 0x00, 0x06, 0x88, 0xc8, 0xa8, 0x98, 0x88, 0x00, 0x06,
+ 0x70, 0x88, 0x88, 0x88, 0x70, 0x00, 0x06, 0xf0, 0x88, 0xf0,
+ 0x80, 0x80, 0x00, 0x06, 0x70, 0x88, 0x88, 0x88, 0x70, 0x18,
+ 0x06, 0xf0, 0x88, 0xf0, 0xa0, 0x98, 0x00, 0x06, 0x78, 0x80,
+ 0x70, 0x08, 0xf0, 0x00, 0x06, 0xf8, 0x20, 0x20, 0x20, 0x20,
+ 0x00, 0x06, 0x88, 0x88, 0x88, 0x88, 0x78, 0x00, 0x06, 0x88,
+ 0x88, 0x88, 0x50, 0x20, 0x00, 0x06, 0x88, 0x88, 0xa8, 0xd8,
+ 0x88, 0x00, 0x06, 0x88, 0x50, 0x20, 0x50, 0x88, 0x00, 0x06,
+ 0x88, 0x88, 0x50, 0x20, 0x20, 0x00, 0x06, 0xf8, 0x10, 0x20,
+ 0x40, 0xf8, 0x00, 0x06, 0x78, 0x60, 0x60, 0x60, 0x78, 0x00,
+ 0x06, 0xc0, 0x60, 0x30, 0x18, 0x08, 0x00, 0x06, 0x78, 0x18,
+ 0x18, 0x18, 0x78, 0x00, 0x00, 0x52, 0x41, 0x54, 0x00, 0x41,
+ 0x4c, 0x43, 0x4f, 0x48, 0x4f, 0x4c, 0x00, 0x53, 0x41, 0x46,
+ 0x45, 0x20, 0x43, 0x4f, 0x4d, 0x42, 0x49, 0x4e, 0x41, 0x54,
+ 0x49, 0x4f, 0x4e, 0x00, 0x42, 0x45, 0x41, 0x4b, 0x45, 0x52,
+ 0x00, 0x4d, 0x49, 0x43, 0x52, 0x4f, 0x46, 0x49, 0x4c, 0x4d,
+ 0x00, 0x56, 0x41, 0x55, 0x4c, 0x54, 0x20, 0x4b, 0x45, 0x59,
+ 0x00, 0x42, 0x4f, 0x4c, 0x54, 0x20, 0x43, 0x55, 0x54, 0x54,
+ 0x45, 0x52, 0x53, 0x00, 0x42, 0x4c, 0x4f, 0x57, 0x47, 0x55,
+ 0x4e, 0x00, 0x4c, 0x4f, 0x56, 0x45, 0x20, 0x50, 0x4f, 0x54,
+ 0x49, 0x4f, 0x4e, 0x00, 0x4d, 0x4f, 0x4e, 0x45, 0x59, 0x00,
+ 0x44, 0x41, 0x52, 0x54, 0x53, 0x00, 0x54, 0x41, 0x50, 0x45,
+ 0x00, 0x4a, 0x55, 0x4e, 0x47, 0x4c, 0x45, 0x20, 0x50, 0x4f,
+ 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x4d, 0x4f, 0x56, 0x49,
+};
+
+const char *const NO_HELP_MESSAGE =
+ "WE ARE UNABLE TO PROVIDE YOU WITH ANY MORE HINTS. YOUR IQ \
+HAS DECREASED SO FAR THAT WE CAN NO LONGER PUT THE HINTS IN TERMS \
+YOU CAN UNDERSTAND.";
+const char *const NO_HINTS_MESSAGE = "THE HELP SYSTEM HAS BEEN TURNED OFF FOR THIS GAME.";
+const char *const RIVER_HIT1 = "YOU HIT THE ROCKS AND THE CANOE BEGINS TO LEAK.";
+const char *const RIVER_HIT2 = "YOU HIT THE ROCKS AND THE CANOE DEVELOPS SERIOUS LEAKS.";
+const char *const BAR_MESSAGE = "YOU ARE TOO BUSY TRYING TO KEEP FROM SINKING TO DO THAT";
+const char *const HELPLVLTXT[3] = {
+ " LEVEL 1 ",
+ " LEVEL 2 ",
+ " LEVEL 3 "
+};
+
+const char *const IQLABELS[9] = {
+ "VEGETABLE",
+ "NEANDERTHAL",
+ "LOBOTOMIZED",
+ "DENSE",
+ "AVERAGE",
+ "INTELLIGENT",
+ "MURPHYITE",
+ "BRILLIANT",
+ "GENIUS"
+};
+
+const byte DEATH_SCREENS[58] = {
+ 0, 1, 0, 0, 0, 0, 0, 0, 2, 0,
+ 0, 2, 4, 2, 1, 0, 0, 0, 0, 0,
+ 0, 2, 7, 7, 4, 6, 7, 10, 4, 2,
+ 0, 0, 0, 0, 5, 5, 3, 3, 3, 5,
+ 8, 8, 11, 9, 8, 12, 0, 1, 9, 8,
+ 8, 0, 5, 8, 0, 12, 12, 11
+};
+
+const byte DEATH_SCREENS_DEMO[34] = {
+ 1, 2, 1, 1, 1, 1, 1, 1, 4, 1,
+ 3, 4, 2, 4, 2, 1, 1, 1, 1, 1,
+ 1, 4, 2, 4, 2, 4, 2, 4, 4, 4,
+ 1, 1, 1, 1
+};
+
+const char *const DEATH_TEXT[58] = {
+ "SAM SALVADOR SPOTS YOU AND LETS YOU HAVE IT.",
+ "WHILE TAKING A MOONLIGHT SWIM YOU DISCOVER THAT PIRANHA REALLY CAN STRIP FLESH TO THE BONE.",
+ "THE GUARD FILLS YOU FULL OF HOLES BEFORE TOSSING YOU TO THE PIRANHA.",
+ "YOU'RE ONLY ABLE TO SWIM HALFWAY ACROSS THE RIVER BEFORE RUNNING OUT OF AIR. "
+ "YOU MAKE SO MUCH NOISE GASPING FOR BREATH THAT SAM EASILY FINDS YOU AND LEAVES "
+ "YOU IN THE RIVER PERMANENTLY.",
+ "SAM SALVADOR NOTICES SOMEONE HAS BEEN PLAYING WITH THE CARGO. "
+ "HE TRACKS YOU DOWN AND LETS YOU HAVE IT.",
+ "THE GUARD COMES AROUND THE CORNER. HE DECIDES THAT THREE LEAD SLUGS WILL "
+ "TEACH YOU TO BE MORE POLITE.",
+ "THE CAPTAIN IS WAITING OUTSIDE THE DOOR.",
+ "THE CAPTAIN'S RANDOM SHOOTING FINALLY FINDS ITS TARGET.",
+ "THE CRATE OUTSIDE THE WINDOW EXPLODES, DESTROYING THE SHIP. "
+ "UNFORTUNATELY, YOU'RE STILL ABOARD.",
+ "THE DOOR WAS NOT BARRED AND THE CAPTAIN WALKS RIGHT IN AND PARTS YOUR HAIR.",
+
+ "",
+ "YOU RUN OUT ON DECK, THEN REALIZE THAT MAYA IS STILL TIED UP. "
+ "AS YOU TURN TO GO BACK THE BOAT BLOWS UP.",
+ "AFTER YOU FAIL TO PROVE YOUR DIVINITY THE NATIVES EAT YOU FOR LUNCH.",
+ "THIS IS THE GENERIC DEATH SCENE",
+ "YOU ONLY MAKE IT HALFWAY ACROSS THE RIVER BEFORE THE PIRANHA STRIKE.",
+ "WITH NOTHING TO PROTECT HIM FROM THE HAIL OF BULLETS ALLEN IS QUICKLY GUNNED DOWN. "
+ "JASON AND MAYA SOON FOLLOW...",
+ "THE COMBINATION OF THE WIND AND GUNFIRE KNOCK THE CORRUGATED IRON OVER, "
+ "LEAVING YOU WITHOUT PROTECTION.",
+ "WITHOUT SUFFICIENT AMMUNITION, ALLEN IS UNABLE TO HOLD OFF THE ATTACKERS FOR LONG. "
+ "THIS RESULTS IN A SERIOUS CASE OF LEAD POISONING. ADDITIONAL AMMUNITION SHOULD "
+ "HAVE BEEN PURCHASED AT THE RIO BLANCO TRADING POST (CHAPTER 6).",
+ "ALLEN IS A MARVELOUS SHOT, BUT HIS AMMUNITION IS NOT UNLIMITED. "
+ "SOON IT IS ALL OVER.",
+ "THE PILOT FEELS YOU ARE TOO CLOSE AND PULLS THE TRIGGER.",
+
+ "THE PILOT SHOOTS YOU IN THE HEART, THEN TOSSES YOUR LIFELESS BODY OUT THE DOOR.",
+ "THE PLANE CRASHES INTO THE JUNGLE CANOPY AT 200 MPH.",
+ "THE CANOE HITS THE ROCKS AND CAPSIZES, AND THE PIRANHA MAKE YOU THEIR LUNCH GUESTS.",
+ "YOU TAKE THE WRONG BRANCH AND ACCIDENTALLY DISCOVER THE FOURTH TALLEST WATERFALL "
+ "IN SOUTH AMERICA.",
+ "YOU TAKE THE WRONG BRANCH AND DISCOVER A VERY HUNGRY TRIBE OF CANNIBALS.",
+ "YOU TAKE THE WRONG BRANCH AND BECOME LOST IN THE WINDING WATERWAYS. "
+ "YOU WANDER UNTIL YOU STARVE TO DEATH.",
+ "YOU TAKE THE WRONG BRANCH AND BECOME TRAPPED IN THE RAPIDS. "
+ "EVENTUALLY YOU AND MAYA ARE CRUSHED BETWEEN THE ROCKS.",
+ "YOU WAIT AROUND FOR SOME TIME, BUT HANS STROHEIM NEVER SPEAKS TO YOU AGAIN. "
+ "FINALLY YOU RETURN HOME KNOWING YOU HAVE FAILED.",
+ "DECIDING THAT YOU THREATEN HIM AND HIS WORK, HANS STROHEIM HAS THE NATIVES "
+ "IN THE VILLAGE KILL YOU.",
+ "YOU DO NOT GET FAR ENOUGH AWAY BEFORE THE DYNAMITE EXPLODES AND YOU ARE BLOWN "
+ "INTO A THOUSAND PIECES.",
+
+ "YOU ARE STANDING SO CLOSE TO THE ENTRANCE WHEN SANCEZ AND HIS MEN BREAK THROUGH "
+ "THE WALL THAT YOU ARE QUICKLY SPOTTED AND SHOT",
+ "THE AMAZON SENTINELS SPOT YOU AND FILL YOU FULL OF ARROWS.",
+ "SAM MAY BE UGLY, BUT HE'S NOT DEAF. HE HEARS ALL THE NOISE YOU ARE MAKING AND "
+ "CANCELS YOUR BOARDING PASS.",
+ "WITH THE BAR OFF THE DOOR THE CAPTAIN WALTZES IN AND BLOWS YOU AWAY",
+ "THE BEAR WANDERS OFF INTO THE WOODS AND DISTURBS THE TWO LOVEBIRDS. "
+ "WHEN THEY COME OUT THEY FIND YOU AND PUT YOU IN THE BIG HOUSE FOR TWENTY YEARS.",
+ "WHEN YOU DO NOT LEAVE THE SECURITY AREA QUICKLY ENOUGH YOU ARE ARRESTED AND CONVICTED "
+ "AS A COMMIE SPY. YOU EMBARK ON A NEW CAREER STAMPING OUT LICENSE PLATES.",
+ "THE HUNGRY BEAR SPOTS YOU AND DECIDES YOU WILL MAKE A NICE APPETIZER.",
+ "YOU DISTURB THE BEAR'S LUNCH AND HE EATS YOU FOR DESSERT.",
+ "AFTER FAILING TO FIND ANY LUNCH AT THE GARBAGE CAN THE BEAR EATS YOU INSTEAD.",
+ "THE SUSPICIOUS LIBRARIAN CALLS SECURITY AND YOU ARE SENT TO JAIL.",
+
+ "YOU PLUMMET 10,000 FEET TO YOUR DEATH.",
+ "EL LOCO FLIES INTO AN INSANE RAGE AND BEATS YOU TO A BLOODY PULP.",
+ "THE WOMAN WALKS OUT THE DOOR AND NEVER RETURNS. YOU SPEND THE REST OF YOUR LIFE "
+ "IN A FUTILE ATTEMPT TO LOCATE ALLEN.",
+ "YOU SLIP OFF THE PLATFORM AND FALL TO YOUR DEATH.",
+ "YOU SLIP OFF THE PLATFORM AND FALL TO YOUR DEATH.",
+ "YOU COME TOO CLOSE TO THE POWERFUL JAWS OF THE ANT AND HE SNIPS YOU IN TWO BEFORE "
+ "DEVOURING YOU.",
+ "B.O.B. HAS A FLAW IN HIS PROGRAMMING THAT DIRECTS HIM TO SHOOT FIRST AND ASK QUESTIONS LATER.",
+ "THE PLANE SINKS AND THE PIRHANA ATTACK BEFORE YOU EVEN GET OUT THE DOOR.",
+ "MAYA FALLS OFF THE END OF THE BROKEN BRIDGE.",
+ "YOUR WEIGHT IS JUST ENOUGH TO CAUSE THE REMAINING SUPPORT CABLE TO SNAP AND YOU "
+ "FALL TO THE BOTTOM OF THE GORGE.",
+
+ "EVEN WITH REPAIRS THE BRIDGE IS NOT STRONG ENOUGH TO HOLD TWO PEOPLE.",
+ "SANCHEZ AND HIS MEN FIND YOU AND HOLD FIRING SQUAD PRACTICE.",
+ "THE TWO GUARDS ARE DISTURBED IN THEIR LOVE NEST AND COME LOOKING FOR ANYONE ACTING SUSPICIOUS. "
+ "THEY FIND YOU AND SEND YOU UP THE RIVER.",
+ "THE PARACHUTE IS NOT LARGE ENOUGH TO SUPPORT YOU, AND YOU HIT THE TREES AT 140 M.P.H.",
+ "SANCHEZ AND HIS MEN FOLLOW YOU ACROSS THE BRIDGE AND CUT YOU DOWN IN A HAIL OF GUNFIRE",
+ "YOU TRIED TO STAB THE ANT BUT HIS SHELL IS TOO DIFFICULT TO PENETRATE. "
+ "YOU NOTICE A SLIGHT CUT IN THE SHELL UNDERNEATH BUT YOU CAN'T GET TO IT "
+ "AND HE SNIPS YOU INTO DELICIOUS MEATY CHUNKS.",
+ "AFTER THE ANT FINISHES SUCKING ALL OF THE SAP OUT OF THE VINE HE TURNS HIS ATTENTION BACK TO YOU "
+ "AND BITES YOUR HEAD OFF.",
+ "THE CANTINA OWNER NOTICES YOU ARE TRYING TO STEAL OBJECTS FROM THE TABLES. "
+ "TWENTY YEARS LATER YOU ARE RELEASED FROM A SOUTH AMERICAN PRISON."
+};
+
+const char *const DEATH_TEXT_DEMO[34] = {
+ "SAM SALVADOR SPOTS YOU AND LETS YOU HAVE IT.",
+ "WHILE TAKING A MOONLIGHT SWIM YOU DISCOVER THAT PIRANHA REALLY CAN STRIP FLESH TO THE BONE.",
+ "THE GUARD FILLS YOU FULL OF HOLES BEFORE TOSSING YOU TO THE PIRANHA.",
+ "YOU'RE ONLY ABLE TO SWIM HALFWAY ACROSS THE RIVER BEFORE RUNNING OUT OF AIR. YOU MAKE SO MUCH NOISE GASPING FOR BREATH THAT SAM EASILY FINDS YOU AND LEAVES YOU IN THE RIVER PERMANENTLY.",
+ "SAM SALVADOR NOTICES SOMEONE HAS BEEN PLAYING WITH THE CARGO. HE TRACKS YOU DOWN AND LETS YOU HAVE IT.",
+ "THE GUARD COMES AROUND THE CORNER. HE DECIDES THAT THREE LEAD SLUGS WILL TEACH YOU TO BE MORE POLITE.",
+ "THE CAPTAIN IS WAITING OUTSIDE THE DOOR.",
+ "THE CAPTAIN'S RANDOM SHOOTING FINALLY FINDS ITS TARGET.",
+ "THE CRATE OUTSIDE THE WINDOW EXPLODES, DESTROYING THE SHIP. UNFORTUNATELY, YOU'RE STILL ABOARD.",
+ "THE DOOR WAS NOT BARRED AND THE CAPTAIN WALKS RIGHT IN AND PARTS YOUR HAIR.",
+ "",
+ "YOU RUN OUT ON DECK, THEN REALIZE THAT MAYA IS STILL TIED UP. AS YOU TURN TO GO BACK THE BOAT BLOWS UP.",
+ "AFTER YOU FAIL TO PROVE YOUR DIVINITY THE NATIVES EAT YOU FOR LUNCH.",
+ "THIS IS THE GENERIC DEATH SCENE",
+ "YOU ONLY MAKE IT HALFWAY ACROSS THE RIVER BEFORE THE PIRANHA STRIKE.",
+ "WITH NOTHING TO PROTECT HIM FROM THE HAIL OF BULLETS ALLEN IS QUICKLY GUNNED DOWN. JASON AND MAYA SOON FOLLOW...",
+ "THE COMBINATION OF THE WIND AND GUNFIRE KNOCK THE CORRUGATED IRON OVER, LEAVING YOU WITHOUT PROTECTION.",
+ "WITHOUT SUFFICIENT AMMUNITION, ALLEN IS UNABLE TO HOLD OFF THE ATTACKERS FOR LONG. THIS RESULTS IN A SERIOUS CASE OF LEAD POISONING.",
+ "ALLEN IS A MARVELOUS SHOT, BUT HIS AMMUNITION IS NOT UNLIMITED. SOON IT IS ALL OVER.",
+ "THE PILOT FEELS YOU ARE TOO CLOSE AND PULLS THE TRIGGER.",
+ "THE PILOT SHOOTS YOU IN THE HEAD, THEN TOSSES YOUR LIFELESS",
+ "THE PLANE CRASHES INTO THE JUNGLE CANOPY AT 200 MPH.",
+ "THE CANOE HITS THE ROCKS AND CAPSIZES, AND THE PIRANHA MAKE YOU THEIR LUNCH GUESTS.",
+ "YOU ACCIDENTALLY DISCOVER THE FOURTH TALLEST WATERFALL IN SOUTH AMERICA.",
+ "YOU DISCOVER A VERY HUNGRY TRIBE OF CANNIBALS.",
+ "YOU BECOME LOST IN THE WINDING WATERWAYS AND WANDER UNTIL YOU STARVE TO DEATH.",
+ "YOU BECOME TRAPPED IN THE RAPIDS AND ARE CRUSHED BETWEEN THE ROCKS.",
+ "YOU WAIT AROUND FOR SOME TIME, BUT HANS STROHEIM NEVER SPEAKS TO YOU AGAIN. FINALLY YOU RETURN HOME KNOWING YOU HAVE FAILED.",
+ "DECIDING THAT YOU THREATEN HIM AND HIS WORK, HANS STROHEIM HAS THE NATIVES IN THE VILLAGE KILL YOU.",
+ "YOU DO NOT GET FAR ENOUGH AWAY BEFORE THE DYNAMITE EXPLODES AND YOU ARE BLOWN INTO A THOUSAND PIECES.",
+ "STANDING OUT IN THE OPEN YOU ARE EXPOSED TO THE HAIL OF BULLETS FROM SANCHEZ' MEN.",
+ "THE AMAZON SENTINELS SPOT YOU AND FILL YOU FULL OF ARROWS.",
+ "SAM MAY BE UGLY, BUT HE'S NOT DEAF. HE HEARS ALL THE NOISE YOU ARE MAKING AND CANCELS YOUR BOARDING PASS.",
+ "WITH THE BAR OFF THE DOOR THE CAPTAIN WALTZES IN AND BLOWS YOU AWAY"
+};
+
+const int DEATH_CELLS[13][3] = {
+ { 0, 94, 2 },
+ { 0, 94, 3 },
+ { 0, 94, 4 },
+ { 0, 94, 5 },
+ { 0, 94, 6 },
+ { 0, 94, 7 },
+ { 0, 94, 8 },
+ { 0, 94, 9 },
+ { 0, 94, 10 },
+ { 0, 94, 11 },
+ { 0, 94, 12 },
+ { 0, 94, 13 },
+ { 0, 94, 14 }
+};
+
+const int CHAPTER_CELLS[17][3] = {
+ { 1, 96, 18 },
+ { 2, 96, 19 },
+ { 3, 96, 20 },
+ { 4, 96, 21 },
+ { 5, 96, 22 },
+ { 6, 96, 23 },
+ { 7, 96, 24 },
+ { 8, 96, 25 },
+ { 9, 96, 26 },
+ { 10, 96, 27 },
+ { 11, 96, 28 },
+ { 12, 96, 29 },
+ { 13, 96, 30 },
+ { 14, 96, 31 }
+};
+
+const int CHAPTER_TABLE[14][5] = {
+ { 18, 136, 27, 76, 49 },
+ { 16, 134, 27, 53, 74 },
+ { 16, 136, 27, 52, 56 },
+ { 16, 135, 26, 46, 75 },
+ { 16, 135, 27, 54, 66 },
+ { 16, 137, 27, 67, 79 },
+ { 14, 136, 27, 82, 52 },
+ { 15, 136, 26, 65, 73 },
+ { 15, 137, 26, 48, 75 },
+ { 17, 135, 27, 52, 66 },
+ { 15, 135, 27, 62, 65 },
+ { 16, 135, 28, 45, 66 },
+ { 16, 135, 28, 36, 67 },
+ { 15, 135, 27, 34, 63 }
+};
+
+const int CHAPTER_JUMP[14] = {
+ 0, 12, 10, 15, 19, 25, 31, 36, 45, 46, 29, 55, 61, 0
+};
+
+const int COMBO_TABLE[85][4] = {
+ { -1, -1, -1, -1 },
+ { 12, 3, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { 24, 25, -1, -1 },
+ { 10, 24, -1, -1 },
+ { -1, -1, -1, -1 },
+ { 8, 24, -1, -1 },
+ { -1, -1, -1, -1 },
+ { 1, 3, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { 7, 25, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { 80, 81, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { 41, 42, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { 39, 40, -1, -1 },
+ { 38, 40, -1, -1 },
+ { -1, -1, -1, -1 },
+ { 32, 42, 77, 78 },
+ { -1, -1, -1, -1 },
+ { 60, 61, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { 73, 72, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { 64, 67, -1, -1 },
+ { -1, -1, -1, -1 },
+ { 59, 60, -1, -1 },
+ { 58, 60, -1, -1 },
+ { 43, 61, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { 56, 67, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { 50, 72, -1, -1 },
+ { 75, 77, -1, -1 },
+ { 74, 77, -1, -1 },
+ { -1, -1, -1, -1 },
+ { 41, 78, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { 29, 81, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 }
+};
+
+const int ANTWALK[24] = {
+ 0, 3, 0,
+ 1, 5, 0,
+ 2, 4, 0,
+ 3, 2, 0,
+ 4, 4, 0,
+ 5, 3, 0,
+ 6, 4, 0,
+ -1, -1, -1
+};
+
+const int ANTEAT[33] = {
+ 7, 0, -1,
+ 8, 0, -5,
+ 9, 0, -11,
+ 10, 0, 7,
+ 11, 0, -3,
+ 12, 0, 3,
+ 13, 0, -1,
+ 9, 0, -6,
+ 8, 0, 11,
+ 7, 0, 6,
+ -1, -1, -1
+};
+
+const int ANTDIE[21] = {
+ 14, 4, 8,
+ 15, 7, 6,
+ 16, 6, 7,
+ 17, 8, 2,
+ 18, 0, 0,
+ 19, 0, 0,
+ -1, -1, -1
+};
+
+const int PITWALK[27] = {
+ 18, 0, -1,
+ 19, -2, 1,
+ 20, -2, 1,
+ 21, -2, 1,
+ 22, -2, 0,
+ 23, -3, 0,
+ 24, -3, -1,
+ 25, -2, -1,
+ -1, -1, -1
+};
+
+const int PITSTAB[21] = {
+ 14, -2, 0,
+ 15, -4, 0,
+ 16, 3, -13,
+ 16, 0, 0,
+ 15, -3, 13,
+ 14, 4, 0,
+ -1, -1, -1
+};
+
+const int TORCH[12] = {
+ 26, -11, -7,
+ 27, -12, -2,
+ 28, -15, -4,
+ -1, -1, -1
+};
+
+const int SPEAR[3] = {30, -13, 1};
+
+const int OPENING_OBJS[10][4] = {
+ {8, -80, 120, 30},
+ {13, 229, 0, 50},
+ {12, 78, 0, 50},
+ {11, 10, 0, 50},
+ {10, 178, 97, 50},
+ {9, 92, 192, 50},
+ {14, 38, 0, 100},
+ {15, 132, 76, 100},
+ {16, 142, 0, 100},
+ {4, -280, 40, 120},
+};
+
+const byte MAP0[26] = {
+ 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 4, 0,
+ 0, 0, 1, 0, 2, 0, 0, 1, 1, 3, 0, 0,
+ 0, 0xFF
+};
+
+const byte MAP1[27] = {
+ 0, 0, 1, 0, 3, 0, 0, 1, 1, 2, 0, 0,
+ 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 4, 0,
+ 0, 0, 0xFF
+};
+
+const byte MAP2[32] = {
+ 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 1, 0,
+ 3, 0, 0, 1, 0, 4, 0, 0, 1, 1, 2, 0,
+ 0, 1, 0, 1, 0, 0, 0, 0xFF
+};
+
+const byte *const MAPTBL[3] = {MAP0, MAP1, MAP2};
+
+const int DOWNRIVEROBJ[14][4] = {
+ { 3, 77, 0, 40 },
+ { 2, 30, 0, 30 },
+ { 2, 290, 0, 50 },
+ { 1, 210, 0, 70 },
+ { 2, 350, 0, 30 },
+ { 1, 370, 0, 20 },
+ { 2, 480, 0, 60 },
+ { 3, 395, 0, 10 },
+ { 1, 550, 0, 30 },
+ { 2, 620, 0, 50 },
+ { 1, 690, 0, 10 },
+ { 2, 715, 0, 40 },
+ { 1, 770, 0, 30 },
+ { 3, 700, 0, 20 }
+};
+
+RiverStruct RIVER0OBJECTS[46] = {
+ {16, 31, 6400, 0, 4, 12},
+ {16, 31, 6200, 0, 2, 12},
+ {17, 30, 6100, 0, 3, 15},
+ {16, 31, 5970, 0, 7, 12},
+ {17, 30, 5910, 0, 5, 15},
+ {17, 30, 5730, 0, 3, 15},
+ {16, 31, 5700, 0, 7, 12},
+ {-1, 314, 5392, 0, 4, 0},
+ {17, 30, 5155, 0, 1, 15},
+ {16, 31, 5150, 0, 5, 12},
+ {16, 31, 5056, 0, 7, 12},
+ {17, 30, 4900, 0, 2, 15},
+ {17, 30, 4785, 0, 7, 15},
+ {16, 31, 4690, 0, 4, 12},
+ {16, 31, 4660, 0, 1, 12},
+ {17, 30, 4560, 0, 5, 15},
+ {16, 31, 4465, 0, 2, 12},
+ {-1, 314, 4112, 0, 4, 0},
+ {17, 30, 4005, 0, 3, 15},
+ {16, 31, 3865, 0, 6, 12},
+ {17, 30, 3605, 0, 4, 15},
+ {16, 31, 3360, 0, 1, 12},
+ {17, 30, 3105, 0, 0, 15},
+ {16, 31, 3080, 0, 7, 12},
+ {17, 30, 3014, 0, 4, 15},
+ {16, 31, 2992, 0, 3, 12},
+ {16, 31, 2976, 0, 2, 12},
+ {17, 30, 2880, 0, 7, 15},
+ {17, 30, 2860, 0, 0, 15},
+ {-1, 314, 2512, 0, 4, 0},
+ {17, 30, 2270, 0, 4, 15},
+ {16, 31, 2195, 0, 6, 12},
+ {17, 30, 1824, 0, 1, 15},
+ {16, 31, 1776, 0, 4, 12},
+ {17, 30, 1650, 0, 3, 15},
+ {16, 31, 1616, 0, 7, 12},
+ {17, 30, 1585, 0, 2, 15},
+ {-1, 314, 1232, 0, 4, 0},
+ {17, 30, 1190, 0, 2, 15},
+ {16, 31, 1120, 0, 4, 12},
+ {17, 30, 970, 0, 7, 15},
+ {16, 31, 910, 0, 5, 12},
+ {17, 30, 705, 0, 0, 15},
+ {16, 31, 550, 0, 4, 12},
+ {17, 30, 305, 0, 2, 15},
+ {16, 31, 260, 0, 7, 12}
+};
+
+RiverStruct RIVER1OBJECTS[50] = {
+ {16, 31, 6920, 0, 1, 12},
+ {16, 31, 6740, 0, 4, 12},
+ {17, 30, 6699, 0, 1, 15},
+ {16, 31, 6610, 0, 2, 12},
+ {17, 30, 6495, 0, 6, 15},
+ {17, 30, 6385, 0, 4, 15},
+ {16, 31, 6350, 0, 1, 12},
+ {17, 30, 6180, 0, 0, 15},
+ {-1, 314, 6032, 0, 4, 0},
+ {16, 31, 5800, 0, 3, 12},
+ {17, 30, 5790, 0, 6, 15},
+ {16, 31, 5530, 0, 4, 12},
+ {16, 31, 5500, 0, 7, 12},
+ {17, 30, 5495, 0, 1, 15},
+ {17, 30, 5376, 0, 0, 15},
+ {16, 31, 5328, 0, 7, 12},
+ {17, 30, 5248, 0, 2, 15},
+ {16, 31, 5248, 0, 6, 12},
+ {-1, 314, 4752, 0, 4, 0},
+ {17, 30, 4432, 0, 2, 15},
+ {16, 31, 4432, 0, 7, 12},
+ {16, 31, 4384, 0, 2, 12},
+ {17, 30, 4368, 0, 5, 15},
+ {16, 31, 4336, 0, 4, 12},
+ {17, 30, 4185, 0, 1, 15},
+ {16, 31, 4125, 0, 3, 12},
+ {17, 30, 3817, 0, 7, 15},
+ {16, 31, 3612, 0, 4, 12},
+ {16, 31, 3360, 0, 5, 12},
+ {16, 31, 3265, 0, 7, 12},
+ {17, 30, 3200, 0, 1, 15},
+ {17, 30, 3056, 0, 6, 15},
+ {-1, 314, 2832, 0, 4, 0},
+ {16, 31, 2740, 0, 3, 12},
+ {17, 30, 2694, 0, 6, 15},
+ {16, 31, 2455, 0, 0, 12},
+ {17, 30, 2285, 0, 5, 15},
+ {16, 31, 2260, 0, 2, 12},
+ {16, 31, 1904, 0, 5, 12},
+ {17, 30, 1808, 0, 1, 15},
+ {16, 31, 1744, 0, 7, 12},
+ {17, 30, 1696, 0, 4, 15},
+ {16, 31, 1568, 0, 2, 12},
+ {-1, 314, 1232, 0, 4, 0},
+ {17, 30, 970, 0, 4, 15},
+ {16, 31, 910, 0, 7, 12},
+ {17, 30, 705, 0, 0, 15},
+ {16, 31, 550, 0, 6, 12},
+ {17, 30, 305, 0, 3, 15},
+ { 16, 31, 260, 0, 1, 12 }
+};
+
+RiverStruct RIVER2OBJECTS[54] = {
+ {16, 31, 8230, 0, 6, 12},
+ {16, 31, 8115, 0, 7, 12},
+ {17, 30, 7955, 0, 4, 15},
+ {16, 31, 7890, 0, 0, 12},
+ {16, 31, 7616, 0, 2, 12},
+ {17, 30, 7472, 0, 5, 15},
+ {16, 31, 7425, 0, 4, 12},
+ {17, 30, 7360, 0, 1, 15},
+ {16, 31, 7328, 0, 6, 12},
+ {-1, 314, 6992, 0, 4, 0},
+ {16, 31, 6720, 0, 3, 12},
+ {17, 30, 6700, 0, 6, 15},
+ {16, 31, 6518, 0, 2, 12},
+ {17, 30, 6225, 0, 5, 15},
+ {16, 31, 6200, 0, 2, 12},
+ {17, 30, 5990, 0, 1, 15},
+ {16, 31, 5960, 0, 7, 12},
+ {16, 31, 5700, 0, 2, 12},
+ {17, 30, 5650, 0, 4, 15},
+ {16, 31, 5568, 0, 5, 12},
+ {17, 30, 5488, 0, 6, 15},
+ {-1, 314, 5072, 0, 4, 0},
+ {17, 30, 4825, 0, 4, 15},
+ {16, 31, 4782, 0, 2, 12},
+ {17, 30, 4660, 0, 5, 15},
+ {16, 31, 4510, 0, 7, 12},
+ {16, 31, 4495, 0, 1, 12},
+ {17, 30, 4250, 0, 2, 15},
+ {16, 31, 4195, 0, 4, 12},
+ {-1, 314, 3792, 0, 4, 0},
+ {17, 30, 3600, 0, 3, 15},
+ {16, 31, 3470, 0, 5, 12},
+ {16, 31, 3422, 0, 2, 12},
+ {17, 30, 3170, 0, 6, 15},
+ {16, 31, 2960, 0, 4, 12},
+ {17, 30, 2955, 0, 7, 15},
+ {-1, 314, 2512, 0, 4, 0},
+ {17, 30, 2415, 0, 1, 15},
+ {16, 31, 2318, 0, 0, 12},
+ {17, 30, 2275, 0, 2, 15},
+ {16, 31, 2270, 0, 6, 12},
+ {17, 30, 2026, 0, 3, 15},
+ {16, 31, 2000, 0, 0, 12},
+ {16, 31, 1840, 0, 3, 12},
+ {17, 30, 1795, 0, 7, 15},
+ {16, 31, 1634, 0, 5, 12},
+ {17, 30, 1630, 0, 1, 15},
+ {-1, 314, 1232, 0, 4, 0},
+ {17, 30, 970, 0, 2, 15},
+ {16, 31, 910, 0, 5, 12},
+ {17, 30, 705, 0, 0, 15},
+ {16, 31, 550, 0, 4, 12},
+ {17, 30, 305, 0, 3, 15},
+ {16, 31, 260, 0, 6, 12}
+};
+
+RiverStruct *RIVER_OBJECTS[3][2] = {
+ { RIVER0OBJECTS, RIVER0OBJECTS + 46 - 1},
+ { RIVER1OBJECTS, RIVER0OBJECTS + 50 - 1 },
+ { RIVER2OBJECTS, RIVER0OBJECTS + 54 - 1 }
+};
+
+const int HELP1COORDS[2][4] = {
+ { 76, 129, 168, 183 }, { 187, 240, 168, 183 }
+};
+
+const int RIVER1OBJ[23][4] = {
+ { 18, -77, 0, 30 },
+ { 18, -325, 0, 20 },
+ { 18, -450, 0, 15 },
+ { 18, -1250, 0, 25 },
+ { 19, -130, 0, 20 },
+ { 19, -410, 0, 15 },
+ { 19, -710, 0, 25 },
+ { 19, -1510, 0, 20 },
+ { 20, -350, 0, 30 },
+ { 20, -695, 0, 25 },
+ { 20, -990, 0, 20 },
+ { 20, -1300, 0, 25 },
+ { 20, -1600, 0, 30 },
+ { 21, -370, 0, 20 },
+ { 21, -650, 0, 30 },
+ { 21, -1215, 0, 40 },
+ { 21, -1815, 0, 35 },
+ { 22, -380, 0, 25 },
+ { 22, -720, 0, 35 },
+ { 22, -1020, 0, 30 },
+ { 22, -1170, 0, 25 },
+ { 22, -1770, 0, 35 },
+ { 23, -500, 63, 20 }
+};
+
+const int CAST_END_OBJ[26][4] = {
+ { 0, 118, 210, 10 },
+ { 1, 38, 250, 10 },
+ { 2, 38, 280, 10 },
+ { 3, 38, 310, 10 },
+ { 4, 38, 340, 10 },
+ { 5, 38, 370, 10 },
+ { 6, 38, 400, 10 },
+ { 7, 38, 430, 10 },
+ { 8, 38, 460, 10 },
+ { 9, 38, 490, 10 },
+ { 10, 38, 520, 10 },
+ { 11, 38, 550, 10 },
+ { 12, 38, 580, 10 },
+ { 13, 38, 610, 10 },
+ { 14, 38, 640, 10 },
+ { 15, 38, 670, 10 },
+ { 16, 38, 700, 10 },
+ { 17, 38, 730, 10 },
+ { 18, 38, 760, 10 },
+ { 19, 38, 790, 10 },
+ { 20, 95, 820, 10 },
+ { 21, 94, 850, 10 },
+ { 22, 96, 880, 10 },
+ { 23, 114, 910, 10 },
+ { 24, 114, 940, 10 },
+ { 25, 110, 970, 10 }
+};
+
+const int CAST_END_OBJ1[4][4] = {
+ { 0, 40, 1100, 10 },
+ { 2, 11, 1180, 10 },
+ { 1, 154, 1180, 10 },
+ { 3, 103, 1300, 10 }
+};
+
+} // End of namespace Amazon
+
+} // End of namespace Access
diff --git a/engines/access/amazon/amazon_resources.h b/engines/access/amazon/amazon_resources.h
new file mode 100644
index 0000000000..a952860bc2
--- /dev/null
+++ b/engines/access/amazon/amazon_resources.h
@@ -0,0 +1,148 @@
+/* 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 ACCESS_AMAZON_RESOURCES_H
+#define ACCESS_AMAZON_RESOURCES_H
+
+#include "common/scummsys.h"
+
+namespace Access {
+
+namespace Amazon {
+
+enum InventoryEnum {
+ INV_BAITED_POLE = 67, INV_TORCH = 76, INV_KNIFE_SPEAR = 78
+};
+
+struct RiverStruct {
+ int _id;
+ int _width;
+ int _riverX;
+ int _xp;
+ int _lane;
+ int _offsetY;
+};
+
+extern const char *const FILENAMES[];
+extern const char *const FILENAMES_DEMO[];
+
+extern const byte *const CURSORS[10];
+
+extern const int TRAVEL_POS[][2];
+
+extern const int OVEROFFR[];
+extern const int OVEROFFL[];
+extern const int OVEROFFU[];
+extern const int OVEROFFD[];
+extern const int OVEROFFURX[];
+extern const int OVEROFFURY[];
+extern const int OVEROFFDRX[];
+extern const int OVEROFFDRY[];
+extern const int OVEROFFULX[];
+extern const int OVEROFFULY[];
+extern const int OVEROFFDLX[];
+extern const int OVEROFFDLY[];
+
+extern const byte *const ROOM_TABLE[];
+extern const char *const ROOM_DESCR[];
+extern const byte *const ROOM_TABLE_DEMO[];
+extern const int ROOM_NUMB;
+
+extern const byte *const CHARTBL[];
+extern const byte *const CHARTBL_DEMO[];
+
+extern const char *const INVENTORY_NAMES[];
+
+extern const int FONT2_INDEX[];
+
+extern const byte FONT2_DATA[];
+
+extern const int FONT6x6_INDEX[];
+
+extern const byte FONT6x6_DATA[];
+
+extern const char *const NO_HELP_MESSAGE;
+extern const char *const NO_HINTS_MESSAGE;
+extern const char *const RIVER_HIT1;
+extern const char *const RIVER_HIT2;
+extern const char *const BAR_MESSAGE;
+extern const char *const HELPLVLTXT[3];
+extern const char *const IQLABELS[9];
+extern const byte DEATH_SCREENS[58];
+extern const byte DEATH_SCREENS_DEMO[34];
+
+extern const char *const DEATH_TEXT[58];
+extern const char *const DEATH_TEXT_DEMO[34];
+
+extern const int DEATH_CELLS[13][3];
+
+extern const int CHAPTER_CELLS[17][3];
+
+extern const int CHAPTER_TABLE[14][5];
+
+extern const int CHAPTER_JUMP[14];
+
+extern const int COMBO_TABLE[85][4];
+
+extern const int ANTWALK[24];
+
+extern const int ANTEAT[33];
+
+extern const int ANTDIE[21];
+
+extern const int PITWALK[27];
+
+extern const int PITSTAB[21];
+
+extern const int TORCH[12];
+
+extern const int SPEAR[3];
+
+extern const int OPENING_OBJS[10][4];
+
+extern const byte MAP0[26];
+extern const byte MAP1[27];
+extern const byte MAP2[32];
+
+extern const byte *const MAPTBL[3];
+
+extern const int DOWNRIVEROBJ[14][4];
+
+extern RiverStruct RIVER0OBJECTS[46];
+extern RiverStruct RIVER1OBJECTS[50];
+extern RiverStruct RIVER2OBJECTS[54];
+extern RiverStruct *RIVER_OBJECTS[3][2];
+enum { RIVER_START = 0, RIVER_END = 1 };
+
+extern const int HELP1COORDS[2][4];
+
+extern const int RIVER1OBJ[23][4];
+
+extern const int CAST_END_OBJ[26][4];
+
+extern const int CAST_END_OBJ1[4][4];
+
+} // End of namespace Amazon
+
+} // End of namespace Access
+
+#endif /* ACCESS_AMAZON_RESOURCES_H */
diff --git a/engines/access/amazon/amazon_room.cpp b/engines/access/amazon/amazon_room.cpp
new file mode 100644
index 0000000000..29742f66bd
--- /dev/null
+++ b/engines/access/amazon/amazon_room.cpp
@@ -0,0 +1,241 @@
+/* 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 "access/access.h"
+#include "access/resources.h"
+#include "access/amazon/amazon_game.h"
+#include "access/amazon/amazon_resources.h"
+#include "access/amazon/amazon_room.h"
+
+namespace Access {
+
+namespace Amazon {
+
+AmazonRoom::AmazonRoom(AccessEngine *vm) : Room(vm) {
+ _game = (AmazonEngine *)vm;
+ _antOutFlag = false;
+ _icon = nullptr;
+}
+
+AmazonRoom::~AmazonRoom() {
+}
+
+void AmazonRoom::loadRoom(int roomNumber) {
+ if (_vm->isDemo())
+ loadRoomData(ROOM_TABLE_DEMO[roomNumber]);
+ else
+ loadRoomData(ROOM_TABLE[roomNumber]);
+}
+
+void AmazonRoom::reloadRoom() {
+ loadRoom(_vm->_player->_roomNumber);
+
+ if (_roomFlag != 1) {
+ _vm->_currentMan = _roomFlag;
+ _vm->_currentManOld = _roomFlag;
+ _vm->_manScaleOff = 0;
+
+ switch (_vm->_currentMan) {
+ case 0:
+ _vm->_player->loadSprites("MAN.LZ");
+ break;
+
+ case 2:
+ _vm->_player->loadSprites("JMAN.LZ");
+ break;
+
+ case 3:
+ _vm->_player->loadSprites("OVERHEAD.LZ");
+ _vm->_manScaleOff = 1;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ reloadRoom1();
+}
+
+void AmazonRoom::reloadRoom1() {
+ if (_vm->_player->_roomNumber == 29 || _vm->_player->_roomNumber == 31
+ || _vm->_player->_roomNumber == 42 || _vm->_player->_roomNumber == 44) {
+ Resource *spriteData = _vm->_files->loadFile("MAYA.LZ");
+ _game->_inactive._altSpritesPtr = new SpriteResource(_vm, spriteData);
+ delete spriteData;
+ _vm->_currentCharFlag = false;
+ }
+
+ _selectCommand = -1;
+ _vm->_events->setNormalCursor(CURSOR_CROSSHAIRS);
+ _vm->_mouseMode = 0;
+ _vm->_boxSelect = true;
+ _vm->_player->_playerOff = false;
+
+ _vm->_screen->fadeOut();
+ _vm->_screen->clearScreen();
+ roomSet();
+
+ if (_roomFlag != 1 && (_vm->_player->_roomNumber != 61 || !_antOutFlag)) {
+ _vm->_player->load();
+ _vm->_player->calcManScale();
+ }
+
+ if (_vm->_player->_roomNumber != 20 && _vm->_player->_roomNumber != 24
+ && _vm->_player->_roomNumber != 33 && _vm->_player->_roomNumber != 45) {
+ roomMenu();
+ }
+
+ _vm->_screen->setBufferScan();
+ setupRoom();
+ setWallCodes();
+ buildScreen();
+
+ if (!_vm->_screen->_vesaMode) {
+ _vm->copyBF2Vid();
+ } else if (_vm->_player->_roomNumber != 20 && _vm->_player->_roomNumber != 24
+ && _vm->_player->_roomNumber != 33) {
+ _vm->_screen->setPalette();
+ _vm->copyBF2Vid();
+ }
+
+ // Stop player moving
+ _vm->_player->_playerMove = false;
+ _vm->_player->_frame = 0;
+
+ // Clear any dirty rects from the old scene
+ _vm->_oldRects.clear();
+ _vm->_newRects.clear();
+}
+
+void AmazonRoom::setupRoom() {
+ Room::setupRoom();
+
+ // WORKAROUND: The original engine doesn't handle vertical scrolling rooms
+ Screen &screen = *_vm->_screen;
+ if (screen._vWindowHeight == (_playFieldHeight - 1)) {
+ _vm->_scrollRow = 1;
+ _vm->_scrollY = 0;
+ }
+}
+
+void AmazonRoom::roomSet() {
+ _vm->_numAnimTimers = 0;
+ _vm->_scripts->_sequence = 1000;
+ _vm->_scripts->searchForSequence();
+ _vm->_scripts->executeScript();
+}
+
+void AmazonRoom::roomMenu() {
+ Resource *iconData = _vm->_files->loadFile("ICONS.LZ");
+ SpriteResource *spr = new SpriteResource(_vm, iconData);
+ delete iconData;
+
+ Screen &screen = *_vm->_screen;
+ screen.saveScreen();
+ screen.setDisplayScan();
+ _vm->_destIn = &screen; // TODO: Redundant
+ screen.plotImage(spr, 0, Common::Point(0, 177));
+ screen.plotImage(spr, 1, Common::Point(143, 177));
+
+ screen.restoreScreen();
+ delete spr;
+}
+
+void AmazonRoom::mainAreaClick() {
+ Common::Point &mousePos = _vm->_events->_mousePos;
+ Common::Point pt = _vm->_events->calcRawMouse();
+ Screen &screen = *_vm->_screen;
+ Player &player = *_vm->_player;
+
+ if (_selectCommand == -1) {
+ if (player._roomNumber == 42 || player._roomNumber == 44 ||
+ player._roomNumber == 31 || player._roomNumber == 29) {
+ switch (checkBoxes1(pt)) {
+ case 0:
+ // Make Jason the active player
+ _game->_jasMayaFlag = 0;
+ return;
+ case 1:
+ // Make Maya the active player
+ _game->_jasMayaFlag = 1;
+ return;
+ default:
+ break;
+ }
+ }
+
+ // WORKAROUND: In Amazon room 9, you can't leave the screen to the south due
+ // to not being able to click a Y position that's high enough
+ if (_vm->_scrollRow == 0 && pt.y > 178)
+ pt.y = 200;
+
+ player._moveTo = pt;
+ player._playerMove = true;
+ } else if (mousePos.x >= screen._windowXAdd &&
+ mousePos.x <= (screen._windowXAdd + screen._vWindowBytesWide) &&
+ mousePos.y >= screen._windowYAdd &&
+ mousePos.y <= (screen._windowYAdd + screen._vWindowLinesTall)) {
+ if (checkBoxes1(pt) >= 0) {
+ checkBoxes3();
+ }
+ }
+}
+
+void AmazonRoom::walkCursor() {
+ // WORKAROUND: For scene 29, which is a normal walkable scene, but yet can be
+ // 'exited'. This workaround ensures the scene will only be left if you click
+ // the Exit icon when the cursor is already a walk cursor
+ EventsManager &events = *_vm->_events;
+
+ if (_vm->_events->_middleButton || (_vm->_player->_roomNumber == 29 &&
+ events._normalMouse != CURSOR_CROSSHAIRS)) {
+ events.forceSetCursor(CURSOR_CROSSHAIRS);
+ _selectCommand = -1;
+ _vm->_boxSelect = true;
+ } else {
+ Room::walkCursor();
+ }
+}
+
+void AmazonRoom::init4Quads() {
+ if (!_vm->_screen->_vesaMode)
+ return;
+
+ // CHECKME: in the original, this call of tileScreen uses an useless parameter, "TILES.BLK"
+ _game->tileScreen();
+ _vm->_inventory->refreshInventory();
+ _game->updateSummary(_game->_chapter);
+
+ _vm->_screen->setPanel(0);
+ _vm->_screen->clearScreen();
+}
+
+void AmazonRoom::clearRoom() {
+ _game->freeInactivePlayer();
+ Room::clearRoom();
+}
+
+} // End of namespace Amazon
+
+} // End of namespace Access
diff --git a/engines/access/amazon/amazon_room.h b/engines/access/amazon/amazon_room.h
new file mode 100644
index 0000000000..6396f80199
--- /dev/null
+++ b/engines/access/amazon/amazon_room.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 ACCESS_AMAZON_ROOM_H
+#define ACCESS_AMAZON_ROOM_H
+
+#include "common/scummsys.h"
+#include "access/room.h"
+
+namespace Access {
+
+class AccessEngine;
+
+namespace Amazon {
+
+class AmazonEngine;
+
+class AmazonRoom : public Room {
+private:
+ AmazonEngine *_game;
+ bool _antOutFlag;
+ const byte *_icon;
+
+ void roomSet();
+protected:
+ virtual void loadRoom(int roomNumber);
+
+ virtual void reloadRoom();
+
+ virtual void reloadRoom1();
+
+ virtual void setupRoom();
+
+ virtual void mainAreaClick();
+
+ virtual void clearRoom();
+
+ virtual void walkCursor();
+public:
+ AmazonRoom(AccessEngine *vm);
+
+ virtual ~AmazonRoom();
+
+ virtual void init4Quads();
+
+ virtual void roomMenu();
+};
+
+} // End of namespace Amazon
+
+} // End of namespace Access
+
+#endif /* ACCESS_AMAZON_ROOM_H */
diff --git a/engines/access/amazon/amazon_scripts.cpp b/engines/access/amazon/amazon_scripts.cpp
new file mode 100644
index 0000000000..92acb3686d
--- /dev/null
+++ b/engines/access/amazon/amazon_scripts.cpp
@@ -0,0 +1,516 @@
+/* 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 "access/access.h"
+#include "access/resources.h"
+#include "access/amazon/amazon_game.h"
+#include "access/amazon/amazon_resources.h"
+#include "access/amazon/amazon_scripts.h"
+
+namespace Access {
+
+namespace Amazon {
+
+AmazonScripts::AmazonScripts(AccessEngine *vm) : Scripts(vm) {
+ _game = (AmazonEngine *)_vm;
+}
+
+void AmazonScripts::cLoop() {
+ searchForSequence();
+ _vm->_images.clear();
+ _vm->_buffer2.blitFrom(_vm->_buffer1);
+ _vm->_oldRects.clear();
+ _vm->_scripts->executeScript();
+ _vm->plotList1();
+ _vm->copyBlocks();
+}
+
+void AmazonScripts::mWhile1() {
+ _vm->_screen->setDisplayScan();
+ _vm->_screen->fadeOut();
+ _vm->_events->hideCursor();
+
+ _vm->_files->loadScreen(14, 0);
+ _vm->_buffer2.blitFrom(*_vm->_screen);
+ _vm->_buffer1.blitFrom(*_vm->_screen);
+ _vm->_events->showCursor();
+
+ _vm->_screen->setIconPalette();
+ _vm->_screen->forceFadeIn();
+
+ Resource *spriteData = _vm->_files->loadFile(14, 6);
+ _vm->_objectsTable[0] = new SpriteResource(_vm, spriteData);
+ delete spriteData;
+
+ _vm->_images.clear();
+ _vm->_oldRects.clear();
+ _sequence = 2100;
+
+ do {
+ cLoop();
+ _sequence = 2100;
+ } while (_vm->_flags[52] == 1);
+
+ _vm->_buffer1.copyTo(_vm->_screen);
+ _vm->_buffer2.copyTo(&_vm->_buffer1);
+
+ _game->establish(-1, 14);
+
+ spriteData = _vm->_files->loadFile(14, 7);
+ _vm->_objectsTable[1] = new SpriteResource(_vm, spriteData);
+ delete spriteData;
+
+ _vm->_sound->playSound(0);
+ _vm->_screen->setDisplayScan();
+ _vm->_events->hideCursor();
+
+ _vm->_files->loadScreen(14, 1);
+ _vm->_screen->setPalette();
+ _vm->_buffer2.blitFrom(*_vm->_screen);
+ _vm->_buffer1.blitFrom(*_vm->_screen);
+ _vm->_events->showCursor();
+
+ _vm->_screen->setIconPalette();
+ _vm->_images.clear();
+ _vm->_oldRects.clear();
+ _sequence = 2200;
+
+ _vm->_sound->loadSoundTable(0, 14, 15);
+
+ do {
+ cLoop();
+ _sequence = 2200;
+ } while (_vm->_flags[52] == 2);
+
+ _vm->_screen->setDisplayScan();
+ _vm->_events->hideCursor();
+
+ _vm->_files->loadScreen(14, 2);
+ _vm->_screen->setPalette();
+ _vm->_buffer2.blitFrom(*_vm->_screen);
+ _vm->_buffer1.blitFrom(*_vm->_screen);
+ _vm->_events->showCursor();
+
+ _vm->_screen->setIconPalette();
+ _vm->freeCells();
+
+ spriteData = _vm->_files->loadFile(14, 8);
+ _vm->_objectsTable[2] = new SpriteResource(_vm, spriteData);
+ delete spriteData;
+
+ _vm->_images.clear();
+ _vm->_oldRects.clear();
+ _sequence = 2300;
+ _vm->_sound->playSound(0);
+
+ do {
+ cLoop();
+ _sequence = 2300;
+ } while (_vm->_flags[52] == 3);
+
+ _vm->freeCells();
+ spriteData = _vm->_files->loadFile(14, 9);
+ _vm->_objectsTable[3] = new SpriteResource(_vm, spriteData);
+ delete spriteData;
+
+ _vm->_screen->setDisplayScan();
+ _vm->_events->hideCursor();
+
+ _vm->_files->loadScreen(14, 3);
+ _vm->_screen->setPalette();
+ _vm->_buffer2.blitFrom(*_vm->_screen);
+ _vm->_buffer1.blitFrom(*_vm->_screen);
+ _vm->_events->showCursor();
+
+ _vm->_screen->setIconPalette();
+ _vm->_images.clear();
+ _vm->_oldRects.clear();
+ _sequence = 2400;
+
+ do {
+ cLoop();
+ _sequence = 2400;
+ } while (_vm->_flags[52] == 4);
+}
+
+void AmazonScripts::mWhile2() {
+ _vm->_screen->setDisplayScan();
+ _vm->_screen->fadeOut();
+ _vm->_events->hideCursor();
+
+ _vm->_files->loadScreen(14, 0);
+ _vm->_buffer2.blitFrom(*_vm->_screen);
+ _vm->_buffer1.blitFrom(*_vm->_screen);
+ _vm->_events->showCursor();
+
+ _vm->_screen->setIconPalette();
+ _vm->_screen->forceFadeIn();
+
+ Resource *spriteData = _vm->_files->loadFile(14, 6);
+ _vm->_objectsTable[0] = new SpriteResource(_vm, spriteData);
+ delete spriteData;
+
+ _vm->_images.clear();
+ _vm->_oldRects.clear();
+ _sequence = 2100;
+
+ do {
+ cLoop();
+ _sequence = 2100;
+ } while (_vm->_flags[52] == 1);
+
+ _vm->_screen->fadeOut();
+ _vm->freeCells();
+ spriteData = _vm->_files->loadFile(14, 9);
+ _vm->_objectsTable[3] = new SpriteResource(_vm, spriteData);
+ delete spriteData;
+
+ _vm->_screen->setDisplayScan();
+ _vm->_events->hideCursor();
+
+ _vm->_files->loadScreen(14, 3);
+ _vm->_screen->setPalette();
+ _vm->_buffer2.blitFrom(*_vm->_screen);
+ _vm->_buffer1.blitFrom(*_vm->_screen);
+ _vm->_events->showCursor();
+
+ _vm->_screen->setIconPalette();
+ _vm->_images.clear();
+ _vm->_oldRects.clear();
+ _sequence = 2400;
+
+ do {
+ cLoop();
+ _sequence = 2400;
+ } while (_vm->_flags[52] == 4);
+}
+
+void AmazonScripts::mWhile(int param1) {
+ switch(param1) {
+ case 1:
+ mWhile1();
+ break;
+ case 2:
+ _game->_plane->mWhileFly();
+ break;
+ case 3:
+ _game->_plane->mWhileFall();
+ break;
+ case 4:
+ _game->_jungle->mWhileJWalk();
+ break;
+ case 5:
+ _game->_jungle->mWhileDoOpen();
+ break;
+ case 6:
+ _game->_river->mWhileDownRiver();
+ break;
+ case 7:
+ mWhile2();
+ break;
+ case 8:
+ _game->_jungle->mWhileJWalk2();
+ break;
+ default:
+ break;
+ }
+}
+
+void AmazonScripts::loadBackground(int param1, int param2) {
+ _vm->_files->_setPaletteFlag = false;
+ _vm->_files->loadScreen(param1, param2);
+
+ _vm->_buffer2.blitFrom(*_vm->_screen);
+ _vm->_buffer1.blitFrom(*_vm->_screen);
+
+ _vm->_screen->forceFadeIn();
+}
+
+void AmazonScripts::loadNSound(int param1, int param2) {
+ Resource *sound = _vm->_files->loadFile(param1, param2);
+ _vm->_sound->_soundTable.push_back(SoundEntry(sound, 1));
+}
+
+void AmazonScripts::setInactive() {
+ _game->_rawInactiveX = _vm->_player->_rawPlayer.x;
+ _game->_rawInactiveY = _vm->_player->_rawPlayer.y;
+ _game->_charSegSwitch = false;
+
+ mWhile(_game->_rawInactiveY);
+}
+
+void AmazonScripts::boatWalls(int param1, int param2) {
+ if (param1 == 1)
+ _vm->_room->_plotter._walls[42] = Common::Rect(96, 27, 96 + 87, 27 + 42);
+ else {
+ _vm->_room->_plotter._walls[39].bottom = _vm->_room->_plotter._walls[41].bottom = 106;
+ _vm->_room->_plotter._walls[40].left = 94;
+ }
+}
+
+void AmazonScripts::plotInactive() {
+ Player &player = *_vm->_player;
+ InactivePlayer &inactive = _game->_inactive;
+
+ if (_game->_charSegSwitch) {
+ _game->_currentCharFlag = true;
+ SWAP(inactive._altSpritesPtr, player._playerSprites);
+ _game->_charSegSwitch = false;
+ } else if (_game->_jasMayaFlag != (_game->_currentCharFlag ? 1 : 0)) {
+ if (player._playerOff) {
+ _game->_jasMayaFlag = (_game->_currentCharFlag ? 1 : 0);
+ } else {
+ _game->_currentCharFlag = (_game->_jasMayaFlag == 1);
+ int tmpX = _game->_rawInactiveX;
+ int tmpY = _game->_rawInactiveY;
+ _game->_rawInactiveX = player._rawPlayer.x;
+ _game->_rawInactiveY = player._rawPlayer.y;
+ player._rawPlayer.x = tmpX;
+ player._rawPlayer.y = tmpY;
+ _game->_inactiveYOff = player._playerOffset.y;
+ player.calcManScale();
+
+ SWAP(inactive._altSpritesPtr, player._playerSprites);
+ _vm->_room->setWallCodes();
+ }
+ }
+
+ _game->_flags[155] = 0;
+ if (_game->_rawInactiveX >= 152 && _game->_rawInactiveX <= 167 &&
+ _game->_rawInactiveY >= 158 && _game->_rawInactiveY <= 173) {
+ _game->_flags[155] = 1;
+ } else {
+ _game->_flags[160] = 0;
+ if (!_game->_jasMayaFlag && _game->_rawInactiveX >= 266 && _game->_rawInactiveX <= 290
+ && _game->_rawInactiveY >= 70 && _game->_rawInactiveY <= 87) {
+ _game->_flags[160] = 1;
+ }
+ }
+
+ inactive._flags &= ~IMGFLAG_UNSCALED;
+ inactive._flags &= ~IMGFLAG_BACKWARDS;
+ inactive._position.x = _game->_rawInactiveX;
+ inactive._position.y = _game->_rawInactiveY - _game->_inactiveYOff;
+ inactive._offsetY = _game->_inactiveYOff;
+ inactive._spritesPtr = inactive._altSpritesPtr;
+
+ _vm->_images.addToList(_game->_inactive);
+}
+
+void AmazonScripts::executeSpecial(int commandIndex, int param1, int param2) {
+ switch (commandIndex) {
+ case 0:
+ warning("TODO: DEMO - RESETAN");
+ break;
+ case 1:
+ _vm->establish(param1, param2);
+ break;
+ case 2:
+ loadBackground(param1, param2);
+ break;
+ case 3:
+ if (_vm->isDemo())
+ warning("TODO: DEMO - LOADCELLSET");
+ else
+ _game->_cast->doCast(param1);
+ break;
+ case 4:
+ if (_vm->isDemo())
+ loadNSound(param1, param2);
+ else
+ setInactive();
+ break;
+ case 5:
+ warning("TODO: DEMO - UNLOADCELLSET");
+ break;
+ case 6:
+ mWhile(param1);
+ break;
+ case 7:
+ warning("TODO: DEMO - ADDMONEY");
+ break;
+ case 8:
+ warning("TODO: DEMO - CHKMONEY");
+ break;
+ case 9:
+ _game->_guard->doGuard();
+ break;
+ case 10:
+ _vm->_midi->newMusic(param1, param2);
+ break;
+ case 11:
+ plotInactive();
+ break;
+ case 13:
+ _game->_river->doRiver();
+ break;
+ case 14:
+ _game->_ant->doAnt();
+ break;
+ case 15:
+ boatWalls(param1, param2);
+ break;
+ default:
+ warning("Unexpected Special code %d - Skipped", commandIndex);
+ }
+}
+
+typedef void(AmazonScripts::*AmazonScriptMethodPtr)();
+
+void AmazonScripts::executeCommand(int commandIndex) {
+ static const AmazonScriptMethodPtr COMMAND_LIST[] = {
+ &AmazonScripts::cmdHelp, &AmazonScripts::cmdCycleBack,
+ &AmazonScripts::cmdChapter, &AmazonScripts::cmdSetHelp,
+ &AmazonScripts::cmdCenterPanel, &AmazonScripts::cmdMainPanel,
+ &AmazonScripts::CMDRETFLASH
+ };
+
+ if (commandIndex >= 73)
+ (this->*COMMAND_LIST[commandIndex - 73])();
+ else
+ Scripts::executeCommand(commandIndex);
+}
+
+void AmazonScripts::cmdHelp() {
+ Common::String helpMessage = readString();
+
+ if (_game->_helpLevel == 0) {
+ _game->_timers.saveTimers();
+ _game->_useItem = 0;
+
+ if (_game->_noHints) {
+ printString(NO_HELP_MESSAGE);
+ return;
+ } else if (_game->_hintLevel == 0) {
+ printString(NO_HINTS_MESSAGE);
+ return;
+ }
+ }
+
+ int level = _game->_hintLevel - 1;
+ if (level < _game->_helpLevel)
+ _game->_moreHelp = 0;
+
+ _game->drawHelp(helpMessage);
+
+ while (!_vm->shouldQuit()) {
+ while (!_vm->shouldQuit() && !_vm->_events->_leftButton)
+ _vm->_events->pollEventsAndWait();
+
+ _vm->_events->debounceLeft();
+
+ static const Common::Rect butn1 = Common::Rect(HELP1COORDS[0][0], HELP1COORDS[0][2], HELP1COORDS[0][1], HELP1COORDS[0][3]);
+ static const Common::Rect butn2 = Common::Rect(HELP1COORDS[1][0], HELP1COORDS[1][2], HELP1COORDS[1][1], HELP1COORDS[1][3]);
+ const Common::Point pt = _vm->_events->_mousePos;
+
+ int choice = -1;
+ if (butn1.contains(pt))
+ choice = 0;
+ else if (butn2.contains(pt))
+ choice = 1;
+
+ if (choice < 0)
+ continue;
+
+ if (choice == 1) {
+ // Done button selected
+ _game->_helpLevel = 0;
+ _game->_moreHelp = 1;
+ _game->_useItem = 0;
+ _vm->_events->hideCursor();
+ if (_vm->_screen->_vesaMode) {
+ _vm->_screen->restoreScreen();
+ _vm->_screen->setPanel(0);
+ } else {
+ _vm->_screen->fadeOut();
+ _vm->_screen->clearBuffer();
+ }
+
+ _vm->_buffer2.copyTo(_vm->_screen);
+ _vm->_screen->restorePalette();
+ _vm->_screen->setPalette();
+ _vm->_events->showCursor();
+
+ delete _vm->_objectsTable[45];
+ _vm->_objectsTable[45] = nullptr;
+ _vm->_timers.restoreTimers();
+ break;
+ } else {
+ // More button selected
+ if ((_game->_moreHelp == 0) || (choice != 0))
+ continue;
+ ++_game->_helpLevel;
+ _game->_useItem = 1;
+ break;
+ }
+ }
+ findNull();
+}
+
+void AmazonScripts::cmdCycleBack() {
+ if (_vm->_startup == -1)
+ _vm->_screen->cyclePaletteBackwards();
+}
+void AmazonScripts::cmdChapter() {
+ if (_vm->isDemo()) {
+ cmdSetHelp();
+ } else {
+ int chapter = _data->readByte();
+ _game->startChapter(chapter);
+ }
+}
+
+void AmazonScripts::cmdSetHelp() {
+ int arrayId = (_data->readUint16LE() & 0xFF) - 1;
+ int helpId = _data->readUint16LE() & 0xFF;
+
+ byte *help = _game->_helpTbl[arrayId];
+ help[helpId] = 1;
+
+ if (_vm->_useItem == 0) {
+ _sequence = 11000;
+ searchForSequence();
+ }
+}
+
+void AmazonScripts::cmdCenterPanel() {
+ if (_vm->_screen->_vesaMode) {
+ _vm->_screen->clearScreen();
+ _vm->_screen->setPanel(3);
+ }
+}
+
+void AmazonScripts::cmdMainPanel() {
+ if (_vm->_screen->_vesaMode) {
+ _vm->_room->init4Quads();
+ _vm->_screen->setPanel(0);
+ }
+}
+
+void AmazonScripts::CMDRETFLASH() {
+ error("TODO CMDRETFLASH");
+}
+
+} // End of namespace Amazon
+
+} // End of namespace Access
diff --git a/engines/access/amazon/amazon_scripts.h b/engines/access/amazon/amazon_scripts.h
new file mode 100644
index 0000000000..e10eefb4f5
--- /dev/null
+++ b/engines/access/amazon/amazon_scripts.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.
+ *
+ */
+
+#ifndef ACCESS_AMAZON_SCRIPTS_H
+#define ACCESS_AMAZON_SCRIPTS_H
+
+#include "common/scummsys.h"
+#include "access/scripts.h"
+
+namespace Access {
+
+namespace Amazon {
+
+class AmazonEngine;
+
+class AmazonScripts : public Scripts {
+private:
+ AmazonEngine *_game;
+protected:
+ virtual void executeSpecial(int commandIndex, int param1, int param2);
+ virtual void executeCommand(int commandIndex);
+
+ void cLoop();
+ void mWhile1();
+ void mWhile2();
+ void mWhile(int param1);
+ void loadBackground(int param1, int param2);
+ void plotInactive();
+ void loadNSound(int param1, int param2);
+ void setInactive();
+ void boatWalls(int param1, int param2);
+
+ void cmdHelp();
+ void cmdCycleBack();
+ void cmdChapter();
+ void cmdSetHelp();
+ void cmdCenterPanel();
+ void cmdMainPanel();
+ void CMDRETFLASH();
+public:
+ AmazonScripts(AccessEngine *vm);
+};
+
+} // End of namespace Amazon
+
+} // End of namespace Access
+
+#endif /* ACCESS_AMAZON_SCRIPTS_H */
diff --git a/engines/access/animation.cpp b/engines/access/animation.cpp
new file mode 100644
index 0000000000..14d7c0d4cc
--- /dev/null
+++ b/engines/access/animation.cpp
@@ -0,0 +1,340 @@
+/* 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/endian.h"
+#include "common/memstream.h"
+#include "access/access.h"
+#include "access/animation.h"
+
+namespace Access {
+
+AnimationResource::AnimationResource(AccessEngine *vm, Resource *res) {
+ int count = res->_stream->readUint16LE();
+
+ Common::Array<int> offsets;
+ for (int i = 0; i < count; ++i)
+ offsets.push_back(res->_stream->readUint32LE());
+
+ _animations.reserve(count);
+ for (int i = 0; i < count; ++i) {
+ res->_stream->seek(offsets[i]);
+ Animation *anim = new Animation(vm, res->_stream);
+ _animations.push_back(anim);
+ }
+}
+
+AnimationResource::~AnimationResource() {
+ for (int i = 0; i < (int)_animations.size(); ++i)
+ delete _animations[i];
+}
+
+/*------------------------------------------------------------------------*/
+
+Animation::Animation(AccessEngine *vm, Common::SeekableReadStream *stream) : Manager(vm) {
+ uint32 startOfs = stream->pos();
+
+ _type = stream->readByte();
+ _scaling = stream->readSByte();
+ stream->readByte(); // unk
+ _frameNumber = stream->readByte();
+ _initialTicks = stream->readUint16LE();
+ stream->readUint16LE(); // unk
+ stream->readUint16LE(); // unk
+ _loopCount = stream->readSint16LE();
+ _countdownTicks = stream->readUint16LE();
+ _currentLoopCount = stream->readSint16LE();
+ stream->readUint16LE(); // unk
+
+ Common::Array<uint16> frameOffsets;
+ uint16 ofs;
+ while ((ofs = stream->readUint16LE()) != 0)
+ frameOffsets.push_back(ofs);
+
+ for (int i = 0; i < (int)frameOffsets.size(); i++) {
+ stream->seek(startOfs + frameOffsets[i]);
+
+ AnimationFrame *frame = new AnimationFrame(stream, startOfs);
+ _frames.push_back(frame);
+ }
+}
+
+Animation::~Animation() {
+ for (uint i = 0; i < _frames.size(); ++i)
+ delete _frames[i];
+}
+
+typedef void(Animation::*AnimationMethodPtr)();
+
+void Animation::animate() {
+ static const AnimationMethodPtr METHODS[8] = {
+ &Animation::anim0, &Animation::anim1, &Animation::anim2, &Animation::anim3,
+ &Animation::anim4, &Animation::animNone, &Animation::animNone, &Animation::anim7
+ };
+
+ (this->*METHODS[_type])();
+}
+
+void Animation::anim0() {
+ if (_currentLoopCount != -1) {
+ if (_countdownTicks != 0) {
+ setFrame1(calcFrame());
+ } else {
+ _countdownTicks = _initialTicks;
+ ++_frameNumber;
+ AnimationFrame *frame = calcFrame();
+
+ if (frame == nullptr) {
+ _frameNumber = 0;
+ _currentLoopCount = -1;
+ frame = calcFrame();
+ }
+
+ setFrame(frame);
+ }
+ }
+}
+
+void Animation::anim1() {
+ if (_currentLoopCount == -1 || _countdownTicks != 0) {
+ setFrame1(calcFrame());
+ } else {
+ _countdownTicks = _initialTicks;
+ ++_frameNumber;
+ AnimationFrame *frame = calcFrame();
+
+ if (frame == nullptr) {
+ --_frameNumber;
+ _currentLoopCount = -1;
+ frame = calcFrame();
+ }
+
+ setFrame(frame);
+ }
+}
+
+void Animation::anim2() {
+ if (_countdownTicks != 0) {
+ setFrame1(calcFrame());
+ } else {
+ _countdownTicks = _initialTicks;
+ ++_frameNumber;
+ AnimationFrame *frame = calcFrame();
+
+ if (frame == nullptr) {
+ _frameNumber = 0;
+ frame = calcFrame();
+ }
+
+ setFrame(frame);
+ }
+}
+
+void Animation::anim3() {
+ if (_currentLoopCount != -1) {
+ if (_countdownTicks != 0) {
+ setFrame1(calcFrame());
+ } else {
+ _countdownTicks = _initialTicks;
+ ++_frameNumber;
+ AnimationFrame *frame = calcFrame();
+
+ if (frame == nullptr) {
+ --_currentLoopCount;
+ _frameNumber = 0;
+ frame = calcFrame();
+ }
+
+ setFrame(frame);
+ }
+ }
+}
+
+void Animation::anim4() {
+ if (_currentLoopCount == -1 || _countdownTicks != 0) {
+ setFrame1(calcFrame());
+ } else {
+ _countdownTicks = _initialTicks;
+ ++_frameNumber;
+ AnimationFrame *frame = calcFrame();
+
+ if (frame == nullptr) {
+ if (--_currentLoopCount == -1) {
+ setFrame1(calcFrame());
+ return;
+ } else {
+ _frameNumber = 0;
+ frame = calcFrame();
+ }
+ }
+
+ setFrame(frame);
+ }
+}
+
+void Animation::animNone() {
+ // Empty implementation
+}
+
+void Animation::anim7() {
+ setFrame(calcFrame1());
+}
+
+AnimationFrame *Animation::calcFrame() {
+ return (_frameNumber < (int)_frames.size()) ? _frames[_frameNumber] : nullptr;
+}
+
+AnimationFrame *Animation::calcFrame1() {
+ return _frames[0];
+}
+
+void Animation::setFrame(AnimationFrame *frame) {
+ assert(frame);
+ _countdownTicks += frame->_frameDelay;
+ setFrame1(frame);
+}
+
+void Animation::setFrame1(AnimationFrame *frame) {
+ _vm->_animation->_base.x = frame->_baseX;
+ _vm->_animation->_base.y = frame->_baseY;
+
+ // Loop to add image draw requests for the parts of the frame
+ for (uint i = 0; i < frame->_parts.size(); ++i) {
+ AnimationFramePart *part = frame->_parts[i];
+ ImageEntry ie;
+
+ // Set the flags
+ ie._flags = part->_flags & ~IMGFLAG_UNSCALED;
+ if (_vm->_animation->_frameScale == -1)
+ ie._flags |= IMGFLAG_UNSCALED;
+
+ // Set the other fields
+ ie._spritesPtr = _vm->_objectsTable[part->_spritesIndex];
+ ie._frameNumber = part->_frameIndex;
+ ie._position = part->_position + _vm->_animation->_base;
+ ie._offsetY = part->_offsetY - ie._position.y;
+
+ _vm->_images.addToList(ie);
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+AnimationFrame::AnimationFrame(Common::SeekableReadStream *stream, int startOffset) {
+ uint16 nextOffset;
+
+ stream->readByte(); // unk
+ _baseX = stream->readUint16LE();
+ _baseY = stream->readUint16LE();
+ _frameDelay = stream->readUint16LE();
+ nextOffset = stream->readUint16LE();
+
+ while (nextOffset != 0) {
+ stream->seek(startOffset + nextOffset);
+
+ AnimationFramePart *framePart = new AnimationFramePart(stream);
+ _parts.push_back(framePart);
+
+ nextOffset = stream->readUint16LE();
+ }
+}
+
+AnimationFrame::~AnimationFrame() {
+ for (int i = 0; i < (int)_parts.size(); ++i)
+ delete _parts[i];
+}
+
+/*------------------------------------------------------------------------*/
+
+AnimationFramePart::AnimationFramePart(Common::SeekableReadStream *stream) {
+ _flags = stream->readByte();
+ _spritesIndex = stream->readByte();
+ _frameIndex = stream->readByte();
+ _position.x = stream->readUint16LE();
+ _position.y = stream->readUint16LE();
+ _offsetY = stream->readUint16LE();
+}
+
+/*------------------------------------------------------------------------*/
+
+AnimationManager::AnimationManager(AccessEngine *vm) : Manager(vm) {
+ _animation = nullptr;
+ _animStart = nullptr;
+ _frameScale = 0;
+}
+
+AnimationManager::~AnimationManager() {
+ delete _animation;
+}
+
+void AnimationManager::freeAnimationData() {
+ delete _animation;
+ _animation = nullptr;
+ _animStart = nullptr;
+}
+
+void AnimationManager::clearTimers() {
+ _animationTimers.clear();
+}
+
+void AnimationManager::loadAnimations(Resource *res) {
+ _animationTimers.clear();
+ delete _animation;
+ _animation = new AnimationResource(_vm, res);
+}
+
+
+Animation *AnimationManager::setAnimation(int animId) {
+ Animation *anim = findAnimation(animId);
+ if (!anim)
+ return nullptr;
+
+ anim->_countdownTicks = anim->_initialTicks;
+ anim->_frameNumber = 0;
+
+ anim->_currentLoopCount = (anim->_type != 3 && anim->_type != 4) ? 0 : anim->_loopCount;
+
+ return anim;
+}
+
+void AnimationManager::setAnimTimer(Animation *anim) {
+ _animationTimers.push_back(anim);
+}
+
+Animation *AnimationManager::findAnimation(int animId) {
+ _animStart = (_animation == nullptr) ? nullptr : _animation->getAnimation(animId);
+ return _animStart;
+}
+
+void AnimationManager::animate(int animId) {
+ Animation *anim = findAnimation(animId);
+ _frameScale = anim->_scaling;
+ anim->animate();
+}
+
+void AnimationManager::updateTimers() {
+ for (uint idx = 0; idx < _animationTimers.size(); ++idx) {
+ if (_animationTimers[idx]->_countdownTicks > 0)
+ _animationTimers[idx]->_countdownTicks--;
+ }
+}
+
+} // End of namespace Access
diff --git a/engines/access/animation.h b/engines/access/animation.h
new file mode 100644
index 0000000000..72621c4d11
--- /dev/null
+++ b/engines/access/animation.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 ACCESS_ANIMATION_H
+#define ACCESS_ANIMATION_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/memstream.h"
+#include "access/data.h"
+#include "access/files.h"
+
+namespace Access {
+
+class AnimationResource;
+class Animation;
+class AnimationFrame;
+class AnimationFramePart;
+
+class AnimationManager : public Manager {
+private:
+ Common::Array<Animation *> _animationTimers;
+ AnimationResource *_animation;
+public:
+ Animation *_animStart;
+ Common::Point _base;
+ int _frameScale;
+public:
+ AnimationManager(AccessEngine *vm);
+ ~AnimationManager();
+ void freeAnimationData();
+ void loadAnimations(Resource *res);
+
+ Animation *findAnimation(int animId);
+ Animation *setAnimation(int animId);
+
+ void animate(int animId);
+
+ /**
+ * Clear the list of currently active animations
+ */
+ void clearTimers();
+
+ /**
+ * Add an animation to the list of currently animating ones
+ */
+ void setAnimTimer(Animation *anim);
+
+ /**
+ * Update the timing of all currently active animation
+ */
+ void updateTimers();
+};
+
+class AnimationResource {
+private:
+ Common::Array<Animation *> _animations;
+public:
+ AnimationResource(AccessEngine *vm, Resource *res);
+ ~AnimationResource();
+
+ int getCount() { return _animations.size(); }
+ Animation *getAnimation(int idx) { return _animations[idx]; }
+};
+
+class Animation : public Manager {
+private:
+ Common::Array<AnimationFrame *> _frames;
+
+ void anim0();
+ void anim1();
+ void anim2();
+ void anim3();
+ void anim4();
+ void animNone();
+ void anim7();
+
+ AnimationFrame *calcFrame();
+ AnimationFrame *calcFrame1();
+ void setFrame(AnimationFrame *frame);
+ void setFrame1(AnimationFrame *frame);
+public:
+ int _type;
+ int _scaling;
+ int _frameNumber;
+ int _initialTicks;
+ int _loopCount;
+ int _countdownTicks;
+ int _currentLoopCount;
+public:
+ Animation(AccessEngine *vm, Common::SeekableReadStream *stream);
+ ~Animation();
+
+ void animate();
+};
+
+class AnimationFrame {
+public:
+ int _baseX, _baseY;
+ int _frameDelay;
+ Common::Array<AnimationFramePart *> _parts;
+public:
+ AnimationFrame(Common::SeekableReadStream *stream, int startOffset);
+ ~AnimationFrame();
+};
+
+class AnimationFramePart {
+public:
+ byte _flags;
+ int _spritesIndex;
+ int _frameIndex;
+ Common::Point _position;
+ int _offsetY;
+public:
+ AnimationFramePart(Common::SeekableReadStream *stream);
+};
+
+} // End of namespace Access
+
+#endif /* ACCESS_ANIMATION_H */
diff --git a/engines/access/asurface.cpp b/engines/access/asurface.cpp
new file mode 100644
index 0000000000..5f4372d5af
--- /dev/null
+++ b/engines/access/asurface.cpp
@@ -0,0 +1,346 @@
+/* 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/algorithm.h"
+#include "common/endian.h"
+#include "common/memstream.h"
+#include "access/access.h"
+#include "access/asurface.h"
+
+namespace Access {
+
+SpriteResource::SpriteResource(AccessEngine *vm, Resource *res) {
+ Common::Array<uint32> offsets;
+ int count = res->_stream->readUint16LE();
+
+ for (int i = 0; i < count; i++)
+ offsets.push_back(res->_stream->readUint32LE());
+ offsets.push_back(res->_size); // For easier calculations of Noctropolis sizes
+
+ // Build up the frames
+ for (int i = 0; i < count; ++i) {
+ res->_stream->seek(offsets[i]);
+ int frameSize = offsets[i + 1] - offsets[i];
+
+ SpriteFrame *frame = new SpriteFrame(vm, res->_stream, frameSize);
+ _frames.push_back(frame);
+ }
+}
+
+SpriteResource::~SpriteResource() {
+ for (uint i = 0; i < _frames.size(); ++i)
+ delete _frames[i];
+}
+
+SpriteFrame::SpriteFrame(AccessEngine *vm, Common::SeekableReadStream *stream, int frameSize) {
+ int xSize = stream->readUint16LE();
+ int ySize = stream->readUint16LE();
+ create(xSize, ySize);
+
+ // Empty surface
+ byte *data = (byte *)getPixels();
+ Common::fill(data, data + w * h, 0);
+
+ // Decode the data
+ for (int y = 0; y < h; ++y) {
+ int offset = stream->readByte();
+ int len = stream->readByte();
+ assert((offset + len) <= w);
+
+ byte *destP = (byte *)getBasePtr(offset, y);
+ stream->read(destP, len);
+ }
+}
+
+SpriteFrame::~SpriteFrame() {
+ free();
+}
+
+/*------------------------------------------------------------------------*/
+
+ImageEntry::ImageEntry() {
+ _frameNumber = 0;
+ _spritesPtr = nullptr;
+ _offsetY = 0;
+ _flags = 0;
+}
+
+/*------------------------------------------------------------------------*/
+
+static bool sortImagesY(const ImageEntry &ie1, const ImageEntry &ie2) {
+ int v = (ie1._position.y + ie1._offsetY) - (ie2._position.y + ie2._offsetY);
+ return (v < 0) || (v == 0 && ie1._position.y <= ie2._position.y);
+}
+
+void ImageEntryList::addToList(ImageEntry &ie) {
+ assert(size() < 35);
+ push_back(ie);
+ Common::sort(begin(), end(), sortImagesY);
+}
+
+/*------------------------------------------------------------------------*/
+
+int ASurface::_clipWidth;
+int ASurface::_clipHeight;
+
+ASurface::ASurface(): Graphics::Surface() {
+ _leftSkip = _rightSkip = 0;
+ _topSkip = _bottomSkip = 0;
+ _lastBoundsX = _lastBoundsY = 0;
+ _lastBoundsW = _lastBoundsH = 0;
+ _orgX1 = _orgY1 = 0;
+ _orgX2 = _orgY2 = 0;
+ _lColor = 0;
+ _maxChars = 0;
+}
+
+ASurface::~ASurface() {
+ free();
+ _savedBlock.free();
+}
+
+void ASurface::create(uint16 width, uint16 height) {
+ Graphics::Surface::create(width, height, Graphics::PixelFormat::createFormatCLUT8());
+}
+
+void ASurface::clearBuffer() {
+ byte *pSrc = (byte *)getPixels();
+ Common::fill(pSrc, pSrc + w * h, 0);
+}
+
+bool ASurface::clip(Common::Rect &r) {
+ int skip;
+ _leftSkip = _rightSkip = 0;
+ _topSkip = _bottomSkip = 0;
+
+ if (r.left > _clipWidth || r.left < 0) {
+ if (r.left >= 0)
+ return true;
+
+ skip = -r.left;
+ r.setWidth(r.width() - skip);
+ _leftSkip = skip;
+ r.moveTo(0, r.top);
+ }
+
+ int right = r.right - 1;
+ if (right < 0)
+ return true;
+ else if (right > _clipWidth) {
+ skip = right - _clipWidth;
+ r.setWidth(r.width() - skip);
+ _rightSkip = skip;
+ }
+
+ if (r.top > _clipHeight || r.top < 0) {
+ if (r.top >= 0)
+ return true;
+
+ skip = -r.top;
+ r.setHeight(r.height() - skip);
+ _topSkip = skip;
+ r.moveTo(r.left, 0);
+ }
+
+ int bottom = r.bottom - 1;
+ if (bottom < 0)
+ return true;
+ else if (bottom > _clipHeight) {
+ skip = bottom - _clipHeight;
+ _bottomSkip = skip;
+ r.setHeight(r.height() - skip);
+ }
+
+ return false;
+}
+
+void ASurface::plotImage(SpriteResource *sprite, int frameNum, const Common::Point &pt) {
+ SpriteFrame *frame = sprite->getFrame(frameNum);
+ Common::Rect r(pt.x, pt.y, pt.x + frame->w, pt.y + frame->h);
+
+ if (!clip(r)) {
+ _lastBoundsX = r.left;
+ _lastBoundsY = r.top;
+ _lastBoundsW = r.width();
+ _lastBoundsH = r.height();
+
+ plotF(frame, pt);
+ }
+}
+
+void ASurface::transBlitFrom(ASurface *src, const Common::Point &destPos) {
+ if (getPixels() == nullptr)
+ create(w, h);
+
+ for (int yp = 0; yp < src->h; ++yp) {
+ const byte *srcP = (const byte *)src->getBasePtr(0, yp);
+ byte *destP = (byte *)getBasePtr(destPos.x, destPos.y + yp);
+
+ for (int xp = 0; xp < this->w; ++xp, ++srcP, ++destP) {
+ if (*srcP != 0)
+ *destP = *srcP;
+ }
+ }
+}
+
+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;
+ int scaleXCtr = 0, scaleYCtr = 0;
+
+ for (int yCtr = 0, destY = bounds.top; yCtr < src->h; ++yCtr) {
+ // Handle skipping lines if Y scaling
+ scaleYCtr += scaleY;
+ if (scaleYCtr < SCALE_LIMIT)
+ continue;
+ scaleYCtr -= SCALE_LIMIT;
+
+ // Handle off-screen lines
+ if (destY >= this->h)
+ break;
+
+ if (destY >= 0) {
+ // Handle drawing the line
+ const byte *pSrc = (const byte *)src->getBasePtr(0, yCtr);
+ byte *pDest = (byte *)getBasePtr(bounds.left, destY);
+ scaleXCtr = 0;
+ int x = bounds.left;
+
+ for (int xCtr = 0; xCtr < src->w; ++xCtr, ++pSrc) {
+ // Handle horizontal scaling
+ scaleXCtr += scaleX;
+ if (scaleXCtr < SCALE_LIMIT)
+ continue;
+ scaleXCtr -= SCALE_LIMIT;
+
+ // Only handle on-screen pixels
+ if (x >= this->w)
+ break;
+ if (x >= 0 && *pSrc != 0)
+ *pDest = *pSrc;
+
+ ++pDest;
+ ++x;
+ }
+ }
+
+ ++destY;
+ }
+}
+
+void ASurface::transBlitFrom(ASurface &src) {
+ blitFrom(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);
+ Common::copy(srcP, srcP + src.w, destP);
+ }
+}
+
+void ASurface::copyBuffer(Graphics::Surface *src) {
+ blitFrom(*src);
+}
+
+void ASurface::plotF(SpriteFrame *frame, const Common::Point &pt) {
+ sPlotF(frame, Common::Rect(pt.x, pt.y, pt.x + frame->w, pt.y + frame->h));
+}
+
+void ASurface::plotB(SpriteFrame *frame, const Common::Point &pt) {
+ sPlotB(frame, Common::Rect(pt.x, pt.y, pt.x + frame->w, pt.y + frame->h));
+}
+
+void ASurface::sPlotF(SpriteFrame *frame, const Common::Rect &bounds) {
+ transBlitFrom(frame, bounds);
+}
+
+void ASurface::sPlotB(SpriteFrame *frame, const Common::Rect &bounds) {
+ ASurface flippedFrame;
+ frame->flipHorizontal(flippedFrame);
+
+ transBlitFrom(&flippedFrame, bounds);
+}
+
+void ASurface::copyBlock(ASurface *src, const Common::Rect &bounds) {
+ copyRectToSurface(*src, bounds.left, bounds.top, bounds);
+}
+
+void ASurface::saveBlock(const Common::Rect &bounds) {
+ _savedBounds = bounds;
+ _savedBounds.clip(Common::Rect(0, 0, this->w, this->h));
+
+ _savedBlock.free();
+ _savedBlock.create(bounds.width(), bounds.height(),
+ Graphics::PixelFormat::createFormatCLUT8());
+ _savedBlock.copyRectToSurface(*this, 0, 0, _savedBounds);
+}
+
+void ASurface::restoreBlock() {
+ if (!_savedBounds.isEmpty()) {
+ copyRectToSurface(_savedBlock, _savedBounds.left, _savedBounds.top,
+ Common::Rect(0, 0, _savedBlock.w, _savedBlock.h));
+
+ _savedBlock.free();
+ _savedBounds = Common::Rect(0, 0, 0, 0);
+ }
+}
+
+void ASurface::drawRect() {
+ Graphics::Surface::fillRect(Common::Rect(_orgX1, _orgY1, _orgX2, _orgY2), _lColor);
+}
+
+void ASurface::flipHorizontal(ASurface &dest) {
+ dest.create(this->w, this->h);
+ for (int y = 0; y < h; ++y) {
+ const byte *pSrc = (const byte *)getBasePtr(this->w - 1, y);
+ byte *pDest = (byte *)dest.getBasePtr(0, y);
+
+ for (int x = 0; x < w; ++x, --pSrc, ++pDest)
+ *pDest = *pSrc;
+ }
+}
+
+void ASurface::moveBufferLeft() {
+ byte *p = (byte *)getPixels();
+ Common::copy(p + TILE_WIDTH, p + (w * h), p);
+}
+
+void ASurface::moveBufferRight() {
+ byte *p = (byte *)getPixels();
+ Common::copy_backward(p, p + (pitch * h) - TILE_WIDTH, p + (pitch * h));
+}
+
+void ASurface::moveBufferUp() {
+ byte *p = (byte *)getPixels();
+ Common::copy(p + (pitch * TILE_HEIGHT), p + (pitch * h), p);
+}
+
+void ASurface::moveBufferDown() {
+ byte *p = (byte *)getPixels();
+ Common::copy_backward(p, p + (pitch * (h - TILE_HEIGHT)), p + (pitch * h));
+}
+
+} // End of namespace Access
diff --git a/engines/access/asurface.h b/engines/access/asurface.h
new file mode 100644
index 0000000000..4fb47b9c09
--- /dev/null
+++ b/engines/access/asurface.h
@@ -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.
+ *
+ */
+
+#ifndef ACCESS_ASURFACE_H
+#define ACCESS_ASURFACE_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/memstream.h"
+#include "common/rect.h"
+#include "graphics/surface.h"
+#include "access/data.h"
+
+namespace Access {
+
+class SpriteResource;
+class SpriteFrame;
+
+class ASurface : public Graphics::Surface {
+private:
+ Graphics::Surface _savedBlock;
+
+ void flipHorizontal(ASurface &dest);
+protected:
+ Common::Rect _savedBounds;
+public:
+ int _leftSkip, _rightSkip;
+ int _topSkip, _bottomSkip;
+ int _lastBoundsX, _lastBoundsY;
+ int _lastBoundsW, _lastBoundsH;
+ int _orgX1, _orgY1;
+ int _orgX2, _orgY2;
+ int _lColor;
+
+ Common::Point _printOrg;
+ Common::Point _printStart;
+ int _maxChars;
+public:
+ static int _clipWidth, _clipHeight;
+public:
+ ASurface();
+
+ virtual ~ASurface();
+
+ void create(uint16 width, uint16 height);
+
+ void clearBuffer();
+
+ bool clip(Common::Rect &r);
+
+ void plotImage(SpriteResource *sprite, int frameNum, const Common::Point &pt);
+
+ /**
+ * Scaled draw frame in forward orientation
+ */
+ void sPlotF(SpriteFrame *frame, const Common::Rect &bounds);
+
+ /**
+ * Scaled draw frame in backwards orientation
+ */
+ void sPlotB(SpriteFrame *frame, const Common::Rect &bounds);
+
+ /**
+ * Draw an image full-size in forward orientation
+ */
+ void plotF(SpriteFrame *frame, const Common::Point &pt);
+
+ /**
+ * Draw an image full-size in backwards orientation
+ */
+ void plotB(SpriteFrame *frame, const Common::Point &pt);
+
+ virtual void copyBlock(ASurface *src, const Common::Rect &bounds);
+
+ virtual void restoreBlock();
+
+ virtual void drawRect();
+
+ virtual void transBlitFrom(ASurface *src, const Common::Point &destPos);
+
+ virtual void transBlitFrom(ASurface *src, const Common::Rect &bounds);
+
+ virtual void transBlitFrom(ASurface &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->blitFrom(*this); }
+
+ void saveBlock(const Common::Rect &bounds);
+
+ void moveBufferLeft();
+
+ void moveBufferRight();
+
+ void moveBufferUp();
+
+ void moveBufferDown();
+};
+
+class SpriteFrame : public ASurface {
+public:
+ SpriteFrame(AccessEngine *vm, Common::SeekableReadStream *stream, int frameSize);
+ ~SpriteFrame();
+};
+
+class SpriteResource {
+public:
+ Common::Array<SpriteFrame *> _frames;
+public:
+ SpriteResource(AccessEngine *vm, Resource *res);
+ ~SpriteResource();
+
+ int getCount() { return _frames.size(); }
+
+ SpriteFrame *getFrame(int idx) { return _frames[idx]; }
+};
+
+enum ImageFlag {
+ IMGFLAG_CROPPED = 1,
+ IMGFLAG_BACKWARDS = 2,
+ IMGFLAG_DRAWN = 4,
+ IMGFLAG_UNSCALED = 8
+};
+
+class ImageEntry {
+public:
+ int _frameNumber;
+ SpriteResource *_spritesPtr;
+ int _offsetY;
+ Common::Point _position;
+ int _flags;
+public:
+ ImageEntry();
+};
+
+class ImageEntryList : public Common::Array<ImageEntry> {
+public:
+ void addToList(ImageEntry &ie);
+};
+
+} // End of namespace Access
+
+#endif /* ACCESS_ASURFACE_H */
diff --git a/engines/access/bubble_box.cpp b/engines/access/bubble_box.cpp
new file mode 100644
index 0000000000..28c211991c
--- /dev/null
+++ b/engines/access/bubble_box.cpp
@@ -0,0 +1,281 @@
+/* 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/algorithm.h"
+#include "access/bubble_box.h"
+#include "access/access.h"
+
+namespace Access {
+
+BubbleBox::BubbleBox(AccessEngine *vm) : Manager(vm) {
+ _startItem = 0;
+ _startBox = 0;
+ _charCol = _rowOff = 0;
+ _type = TYPE_2;
+ _bounds = Common::Rect(64, 32, 64 + 130, 32 + 122);
+ _bubbleDisplStr = "";
+}
+
+void BubbleBox::load(Common::SeekableReadStream *stream) {
+ _bubbleTitle.clear();
+
+ byte v;
+ while ((v = stream->readByte()) != 0)
+ _bubbleTitle += (char)v;
+
+ _bubbleDisplStr = _bubbleTitle;
+}
+
+void BubbleBox::clearBubbles() {
+ // Loop through the bubble list to restore the screen areas
+ for (uint i = 0; i < _bubbles.size(); ++i) {
+ _vm->_screen->_screenYOff = 0;
+ Common::Rect r = _bubbles[i];
+ r.left -= 2;
+ r.right = MIN(r.right, (int16)_vm->_screen->w);
+
+ _vm->_screen->copyBlock(&_vm->_buffer1, r);
+ }
+
+ // Clear the list
+ _bubbles.clear();
+}
+
+void BubbleBox::placeBubble(const Common::String &msg) {
+ _vm->_screen->_maxChars = 27;
+ placeBubble1(msg);
+}
+
+void BubbleBox::placeBubble1(const Common::String &msg) {
+ _bubbles.clear();
+ _vm->_fonts._charSet._lo = 1;
+ _vm->_fonts._charSet._hi = 8;
+ _vm->_fonts._charFor._lo = 29;
+ _vm->_fonts._charFor._hi = 32;
+
+ calcBubble(msg);
+
+ Common::Rect r = _bubbles[0];
+ r.translate(-2, 0);
+ _vm->_screen->saveBlock(r);
+ printBubble(msg);
+}
+
+void BubbleBox::calcBubble(const Common::String &msg) {
+ // Save points
+ Common::Point printOrg = _vm->_screen->_printOrg;
+ Common::Point printStart = _vm->_screen->_printStart;
+
+ // Figure out maximum width allowed
+ if (_type == TYPE_4) {
+ _vm->_fonts._printMaxX = 110;
+ } else {
+ _vm->_fonts._printMaxX = _vm->_fonts._font2.stringWidth(_bubbleDisplStr);
+ }
+
+ // Start of with a rect with the given starting x and y
+ Common::Rect bounds(printOrg.x - 2, printOrg.y - 10, printOrg.x - 2, printOrg.y - 10);
+
+ // Loop through getting lines
+ Common::String s = msg;
+ Common::String line;
+ int width = 0;
+ bool lastLine;
+ do {
+ lastLine = _vm->_fonts._font2.getLine(s, _vm->_screen->_maxChars * 6, line, width);
+ _vm->_fonts._printMaxX = MAX(width, _vm->_fonts._printMaxX);
+
+ _vm->_screen->_printOrg.y += 6;
+ _vm->_screen->_printOrg.x = _vm->_screen->_printStart.x;
+ } while (!lastLine);
+
+ if (_type == TYPE_4)
+ ++_vm->_screen->_printOrg.y += 6;
+
+ // Determine the width for the area
+ width = (((_vm->_fonts._printMaxX >> 4) + 1) << 4) + 5;
+ if (width >= 24)
+ width += 20 - ((width - 24) % 20);
+ bounds.setWidth(width);
+
+ // Determine the height for area
+ int y = _vm->_screen->_printOrg.y + 6;
+ if (_type == TYPE_4)
+ y += 6;
+ int height = y - bounds.top;
+ bounds.setHeight(height);
+
+ height -= (_type == TYPE_4) ? 30 : 24;
+ if (height >= 0)
+ bounds.setHeight(bounds.height() + 13 - (height % 13));
+
+ // Add the new bounds to the bubbles list
+ _bubbles.push_back(bounds);
+
+ // Restore points
+ _vm->_screen->_printOrg = printOrg;
+ _vm->_screen->_printStart = printStart;
+}
+
+void BubbleBox::printBubble(const Common::String &msg) {
+ drawBubble(_bubbles.size() - 1);
+
+ // Loop through drawing the lines
+ Common::String s = msg;
+ Common::String line;
+ int width = 0;
+ bool lastLine;
+ do {
+ // Get next line
+ Font &font2 = _vm->_fonts._font2;
+ lastLine = font2.getLine(s, _vm->_screen->_maxChars * 6, line, width);
+
+ // Set font colors
+ font2._fontColors[0] = 0;
+ font2._fontColors[1] = 27;
+ font2._fontColors[2] = 28;
+ font2._fontColors[3] = 29;
+
+ int xp = _vm->_screen->_printOrg.x;
+ if (_type == TYPE_4)
+ xp = (_bounds.width() - width) / 2 + _bounds.left - 4;
+
+ // Draw the text
+ font2.drawString(_vm->_screen, line, Common::Point(xp, _vm->_screen->_printOrg.y));
+
+ // Move print position
+ _vm->_screen->_printOrg.y += 6;
+ _vm->_screen->_printOrg.x = _vm->_screen->_printStart.x;
+ } while (!lastLine);
+}
+
+void BubbleBox::drawBubble(int index) {
+ _bounds = _bubbles[index];
+ doBox(0, 0);
+}
+
+void BubbleBox::doBox(int item, int box) {
+ FontManager &fonts = _vm->_fonts;
+ ASurface &screen = *_vm->_screen;
+
+ _startItem = item;
+ _startBox = box;
+
+ // Save state information
+ FontVal charSet = fonts._charSet;
+ FontVal charFor = fonts._charFor;
+ Common::Point printOrg = screen._printOrg;
+ Common::Point printStart = screen._printStart;
+ int charCol = _charCol;
+ int rowOff = _rowOff;
+
+ _vm->_screen->saveScreen();
+ _vm->_screen->setDisplayScan();
+ fonts._charFor._hi = 0xff;
+ fonts._charSet._lo = 1;
+ fonts._charSet._hi = 0;
+
+ if (_type == TYPE_4) {
+ fonts._charFor._lo = 0xFF;
+ error("TODO: filename listing");
+ return;
+ }
+
+ // Get icons data
+ Resource *iconData = _vm->_files->loadFile("ICONS.LZ");
+ SpriteResource *icons = new SpriteResource(_vm, iconData);
+ delete iconData;
+
+ // Set the up boundaries and color to use for the box background
+ _vm->_screen->_orgX1 = _bounds.left - 2;
+ _vm->_screen->_orgY1 = _bounds.top;
+ _vm->_screen->_orgX2 = _bounds.right - 2;
+ _vm->_screen->_orgY2 = _bounds.bottom;
+ _vm->_screen->_lColor = 1;
+
+ int h = _bounds.height() - (_type == TYPE_4 ? 30 : 24);
+ int ySize = (h < 0) ? 0 : (h + 12) / 13;
+ int w = _bounds.width() - 24;
+ int xSize = (w < 0) ? 0 : (w + 19) / 20;
+
+ // Draw a background for the entire area
+ screen.drawRect();
+
+ // Draw images to form the top border
+ int xp, yp;
+ screen.plotImage(icons, 20, Common::Point(screen._orgX1, screen._orgY1));
+ xp = screen._orgX1 + 12;
+ for (int x = 0; x < xSize; ++x, xp += 20)
+ screen.plotImage(icons, 24 + x, Common::Point(xp, screen._orgY1));
+ screen.plotImage(icons, 21, Common::Point(xp, screen._orgY1));
+
+ // Draw images to form the bottom border
+ yp = screen._orgY2 - (_type == TYPE_4 ? 18 : 12);
+ screen.plotImage(icons, (_type == TYPE_4) ? 72 : 22,
+ Common::Point(screen._orgX1, yp));
+ xp = screen._orgX1 + 12;
+ yp += (_type == TYPE_4) ? 4 : 8;
+
+ for (int x = 0; x < xSize; ++x, xp += 20) {
+ screen.plotImage(icons, (_type == TYPE_4 ? 62 : 34) + x,
+ Common::Point(xp, yp));
+ }
+
+ yp = screen._orgY2 - (_type == TYPE_4 ? 18 : 12);
+ screen.plotImage(icons, (_type == TYPE_4) ? 73 : 23, Common::Point(xp, yp));
+
+ if (_type == TYPE_4) {
+ // Further stuff for filename dialog
+ error("TODO: Box type 4");
+ }
+
+ // Draw images to form the sides
+ yp = screen._orgY1 + 12;
+ for (int y = 0; y < ySize; ++y, yp += 13) {
+ screen.plotImage(icons, 44 + y, Common::Point(screen._orgX1, yp));
+ screen.plotImage(icons, 53 + y, Common::Point(screen._orgX2 - 4, yp));
+ }
+
+ // Handle drawing title
+ int titleWidth = _vm->_fonts._font2.stringWidth(_bubbleDisplStr);
+ Font &font2 = _vm->_fonts._font2;
+ font2._fontColors[0] = 0;
+ font2._fontColors[1] = 3;
+ font2._fontColors[2] = 2;
+ font2._fontColors[3] = 1;
+ font2.drawString(_vm->_screen, _bubbleDisplStr, Common::Point(
+ _bounds.left + (_bounds.width() / 2) - (titleWidth / 2), _bounds.top + 1));
+
+ // Restore positional state
+ fonts._charSet = charSet;
+ fonts._charFor = charFor;
+ screen._printOrg = printOrg;
+ screen._printStart = printStart;
+ _charCol = charCol;
+ _rowOff = rowOff;
+ _vm->_screen->restoreScreen();
+
+ // Free icons data
+ delete icons;
+}
+
+} // End of namespace Access
diff --git a/engines/access/bubble_box.h b/engines/access/bubble_box.h
new file mode 100644
index 0000000000..0b3f139520
--- /dev/null
+++ b/engines/access/bubble_box.h
@@ -0,0 +1,85 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ACCESS_BUBBLE_BOX_H
+#define ACCESS_BUBBLE_BOX_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/rect.h"
+#include "common/str-array.h"
+#include "common/stream.h"
+#include "common/types.h"
+#include "graphics/surface.h"
+#include "access/data.h"
+
+namespace Access {
+
+class AccessEngine;
+
+enum BoxType { TYPE_2 = 2, TYPE_4 = 4 };
+
+class BubbleBox : public Manager {
+private:
+ int _startItem, _startBox;
+ int _charCol, _rowOff;
+ Common::Point _fileStart;
+public:
+ BoxType _type;
+ Common::Rect _bounds;
+ Common::StringArray _nameIndex;
+ Common::String _bubbleTitle;
+ Common::String _bubbleDisplStr;
+
+ Common::Array<Common::Rect> _bubbles;
+public:
+ BubbleBox(AccessEngine *vm);
+
+ void load(Common::SeekableReadStream *stream);
+
+ void clearBubbles();
+
+ void placeBubble(const Common::String &msg);
+ void placeBubble1(const Common::String &msg);
+
+ /**
+ * Calculate the size of a bubble needed to hold a given string
+ */
+ void calcBubble(const Common::String &msg);
+
+ /**
+ * Prints a text bubble and it's contents
+ */
+ void printBubble(const Common::String &msg);
+
+ /*
+ * Draws the background for a text bubble
+ * @param index Index of bounds in _bubbles array
+ */
+ void drawBubble(int index);
+
+ void doBox(int item, int box);
+};
+
+} // End of namespace Access
+
+#endif /* ACCESS_BUBBLE_BOX_H */
diff --git a/engines/access/char.cpp b/engines/access/char.cpp
new file mode 100644
index 0000000000..b359bcf13a
--- /dev/null
+++ b/engines/access/char.cpp
@@ -0,0 +1,162 @@
+/* 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/memstream.h"
+#include "access/access.h"
+#include "access/char.h"
+#include "access/amazon/amazon_resources.h"
+
+namespace Access {
+
+CharEntry::CharEntry(const byte *data) {
+ Common::MemoryReadStream s(data, 999);
+
+ _charFlag = s.readByte();
+ _estabIndex = s.readSint16LE();
+ _screenFile.load(s);
+ _paletteFile.load(s);
+ _startColor = s.readUint16LE();
+ _numColors = s.readUint16LE();
+
+ // Load cells
+ for (byte cell = s.readByte(); cell != 0xff; cell = s.readByte()) {
+ CellIdent ci;
+ ci._cell = cell;
+ ci.load(s);
+
+ _cells.push_back(ci);
+ }
+
+ _animFile.load(s);
+ _scriptFile.load(s);
+
+ for (int16 v = s.readSint16LE(); v != -1; v = s.readSint16LE()) {
+ ExtraCell ec;
+ ec._vid._fileNum = v;
+ ec._vid._subfile = s.readSint16LE();
+ ec._vidSound.load(s);
+
+ _extraCells.push_back(ec);
+ }
+}
+
+CharEntry::CharEntry() {
+ _charFlag = 0;
+ _estabIndex = 0;
+ _startColor = _numColors = 0;
+}
+
+/*------------------------------------------------------------------------*/
+
+CharManager::CharManager(AccessEngine *vm) : Manager(vm) {
+ switch (vm->getGameID()) {
+ case GType_Amazon:
+ // Setup character list
+ if (_vm->isDemo()) {
+ for (int i = 0; i < 27; ++i)
+ _charTable.push_back(CharEntry(Amazon::CHARTBL_DEMO[i]));
+ } else {
+ for (int i = 0; i < 37; ++i)
+ _charTable.push_back(CharEntry(Amazon::CHARTBL[i]));
+ }
+ break;
+ default:
+ error("Unknown game");
+ }
+
+ _charFlag = 0;
+}
+
+void CharManager::loadChar(int charId) {
+ CharEntry &ce = _charTable[charId];
+ _charFlag = ce._charFlag;
+
+ _vm->_establishFlag = false;
+ if (ce._estabIndex != -1) {
+ _vm->_establishFlag = true;
+ if (!_vm->_establishTable[ce._estabIndex]) {
+ _vm->_establishTable[ce._estabIndex] = true;
+ _vm->establish(0, ce._estabIndex);
+ }
+ }
+
+ if (_charFlag != 0 && _charFlag != 3) {
+ if (!_vm->_establishFlag)
+ _vm->_screen->fadeOut();
+
+ _vm->_files->loadScreen(ce._screenFile._fileNum, ce._screenFile._subfile);
+ _vm->_screen->setIconPalette();
+ _vm->_screen->fadeIn();
+ }
+
+ _vm->_buffer1.blitFrom(*_vm->_screen);
+ _vm->_buffer2.blitFrom(*_vm->_screen);
+ _vm->_screen->setDisplayScan();
+
+ if (_charFlag != 2 && _charFlag != 3) {
+ charMenu();
+ }
+
+ _vm->_screen->_startColor = ce._startColor;
+ _vm->_screen->_numColors = ce._numColors;
+ if (ce._paletteFile._fileNum != -1) {
+ _vm->_screen->loadPalette(ce._paletteFile._fileNum, ce._paletteFile._subfile);
+ }
+ _vm->_screen->setIconPalette();
+ _vm->_screen->setPalette();
+
+ _vm->loadCells(ce._cells);
+ if (ce._animFile._fileNum != -1) {
+ Resource *data = _vm->_files->loadFile(ce._animFile);
+ _vm->_animation->loadAnimations(data);
+ }
+
+ // Load script data
+ _vm->_scripts->freeScriptData();
+ if (ce._scriptFile._fileNum != -1) {
+ Resource *data = _vm->_files->loadFile(ce._scriptFile);
+ _vm->_scripts->setScript(data);
+ }
+
+ // Load extra cells
+ _vm->_extraCells.clear();
+ for (uint i = 0; i < ce._extraCells.size(); ++i)
+ _vm->_extraCells.push_back(ce._extraCells[i]);
+}
+
+void CharManager::charMenu() {
+ Resource *iconData = _vm->_files->loadFile("ICONS.LZ");
+ SpriteResource *spr = new SpriteResource(_vm, iconData);
+ delete iconData;
+
+ Screen &screen = *_vm->_screen;
+ screen.saveScreen();
+ screen.setDisplayScan();
+
+ screen.plotImage(spr, 17, Common::Point(0, 176));
+ screen.plotImage(spr, 18, Common::Point(155, 176));
+
+ screen.restoreScreen();
+ delete spr;
+}
+
+} // End of namespace Access
diff --git a/engines/access/char.h b/engines/access/char.h
new file mode 100644
index 0000000000..6fb4934978
--- /dev/null
+++ b/engines/access/char.h
@@ -0,0 +1,64 @@
+/* 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 ACCESS_CHAR_H
+#define ACCESS_CHAR_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "access/data.h"
+
+namespace Access {
+
+class CharEntry {
+public:
+ int _charFlag;
+ int _estabIndex;
+ FileIdent _screenFile;
+ FileIdent _paletteFile;
+ int _startColor, _numColors;
+ Common::Array<CellIdent> _cells;
+ FileIdent _animFile;
+ FileIdent _scriptFile;
+ Common::Array<ExtraCell> _extraCells;
+public:
+ CharEntry(const byte *data);
+
+ CharEntry();
+};
+
+class CharManager : public Manager {
+private:
+ void charMenu();
+public:
+ Common::Array<CharEntry> _charTable;
+ int _charFlag;
+
+public:
+ CharManager(AccessEngine *vm);
+
+ void loadChar(int charId);
+};
+
+} // End of namespace Access
+
+#endif /* ACCESS_CHAR_H */
diff --git a/engines/access/configure.engine b/engines/access/configure.engine
new file mode 100644
index 0000000000..b1defce946
--- /dev/null
+++ b/engines/access/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 access "Access" no
diff --git a/engines/access/data.cpp b/engines/access/data.cpp
new file mode 100644
index 0000000000..cf40e81ccb
--- /dev/null
+++ b/engines/access/data.cpp
@@ -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.
+ *
+ */
+
+#include "common/algorithm.h"
+#include "common/stream.h"
+#include "common/system.h"
+#include "graphics/palette.h"
+#include "access/data.h"
+
+namespace Access {
+
+TimerList::TimerList() : Common::Array<TimerEntry>() {
+ _timersSavedFlag = false;
+}
+
+void TimerList::saveTimers() {
+ if (!_timersSavedFlag /* && !_flashbackFlag */) {
+ _savedTimers = *this;
+ _timersSavedFlag = true;
+ }
+}
+
+void TimerList::restoreTimers() {
+ if (_timersSavedFlag /* && !_flashbackFlag */) {
+ clear();
+ *static_cast<Common::Array<TimerEntry> *>(this) = _savedTimers;
+ _timersSavedFlag = false;
+ }
+}
+
+void TimerList::updateTimers() {
+ for (uint i = 0; i < size(); ++i) {
+ TimerEntry &te = (*this)[i];
+ if (te._flag) {
+ if (!--te._timer) {
+ te._timer = te._initTm;
+ te._flag = 0;
+ }
+ }
+ }
+}
+
+void TimerList::synchronize(Common::Serializer &s) {
+ int count = size();
+ s.syncAsUint16LE(count);
+
+ if (!s.isSaving())
+ resize(count);
+
+ for (int i = 0; i < count; ++i) {
+ s.syncAsUint32LE((*this)[i]._initTm);
+ s.syncAsUint32LE((*this)[i]._timer);
+ s.syncAsByte((*this)[i]._flag);
+ }
+}
+
+} // End of namespace Access
diff --git a/engines/access/data.h b/engines/access/data.h
new file mode 100644
index 0000000000..19413ecd7e
--- /dev/null
+++ b/engines/access/data.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 ACCESS_DATA_H
+#define ACCESS_DATA_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/rect.h"
+#include "common/serializer.h"
+#include "common/types.h"
+#include "graphics/surface.h"
+#include "access/files.h"
+
+namespace Access {
+
+class AccessEngine;
+
+class Manager {
+protected:
+ AccessEngine *_vm;
+public:
+ Manager(AccessEngine *vm) : _vm(vm) {}
+};
+
+struct TimerEntry {
+ int _initTm;
+ int _timer;
+ byte _flag;
+
+ TimerEntry() {
+ _initTm = _timer = 0;
+ _flag = 0;
+ }
+};
+
+class TimerList : public Common::Array<TimerEntry> {
+private:
+ Common::Array<TimerEntry> _savedTimers;
+public:
+ bool _timersSavedFlag;
+public:
+ TimerList();
+
+ /**
+ * Save a copy of all current timers
+ */
+ void saveTimers();
+
+ /**
+ * Resetore the set of previously saved timers
+ */
+ void restoreTimers();
+
+ /**
+ * Update the timer list
+ */
+ void updateTimers();
+
+ /**
+ * Synchronize savegame data
+ */
+ void synchronize(Common::Serializer &s);
+};
+
+class ExtraCell {
+public:
+ FileIdent _vid;
+ FileIdent _vidSound;
+};
+
+struct DeathEntry {
+ int _screenId;
+ Common::String _msg;
+};
+
+class DeathList : public Common::Array<DeathEntry> {
+public:
+ Common::Array<CellIdent> _cells;
+};
+
+} // End of namespace Access
+
+#endif /* ACCESS_DATA_H */
diff --git a/engines/access/debugger.cpp b/engines/access/debugger.cpp
new file mode 100644
index 0000000000..6cb2bb606c
--- /dev/null
+++ b/engines/access/debugger.cpp
@@ -0,0 +1,164 @@
+/* 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/file.h"
+#include "access/access.h"
+#include "access/debugger.h"
+#include "access/amazon/amazon_game.h"
+
+namespace Access {
+
+static int 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;
+}
+
+Debugger *Debugger::init(AccessEngine *vm) {
+ switch (vm->getGameID()) {
+ case GType_Amazon:
+ return new Amazon::AmazonDebugger(vm);
+ default:
+ return new Debugger(vm);
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+Debugger::Debugger(AccessEngine *vm) : GUI::Debugger(), _vm(vm) {
+ registerCmd("continue", WRAP_METHOD(Debugger, cmdExit));
+ registerCmd("scene", WRAP_METHOD(Debugger, Cmd_LoadScene));
+ registerCmd("cheat", WRAP_METHOD(Debugger, Cmd_Cheat));
+
+ switch (vm->getGameID()) {
+ case GType_Amazon:
+ _sceneNumb = Amazon::ROOM_NUMB;
+ _sceneDescr = new Common::String[_sceneNumb];
+ for (int i = 0; i < _sceneNumb; i++)
+ _sceneDescr[i] = Common::String(Amazon::ROOM_DESCR[i]);
+ break;
+ case GType_MartianMemorandum:
+ _sceneNumb = Martian::ROOM_NUMB;
+ _sceneDescr = new Common::String[_sceneNumb];
+ for (int i = 0; i < _sceneNumb; i++)
+ _sceneDescr[i] = Common::String(Martian::ROOM_DESCR[i]);
+ break;
+ default:
+ _sceneDescr = nullptr;
+ _sceneNumb = 0;
+ break;
+ }
+}
+
+Debugger::~Debugger() {
+ delete[] _sceneDescr;
+}
+
+bool Debugger::Cmd_LoadScene(int argc, const char **argv) {
+ switch (argc) {
+ case 1:
+ debugPrintf("Current scene is: %d\n\n", _vm->_player->_roomNumber);
+
+ for (int i = 0; i < _sceneNumb; i++)
+ if (_sceneDescr[i].size())
+ debugPrintf("%d - %s\n", i, _sceneDescr[i].c_str());
+ return true;
+
+ case 2: {
+ int newRoom = strToInt(argv[1]);
+ if (newRoom < 0 || newRoom >= _sceneNumb) {
+ debugPrintf("Invalid Room Number\n");
+ return true;
+ }
+ if (!_sceneDescr[newRoom].size()) {
+ debugPrintf("Unused Room Number\n");
+ return true;
+ }
+
+ _vm->_player->_roomNumber = newRoom;
+
+ _vm->_room->_function = FN_CLEAR1;
+ _vm->freeChar();
+ _vm->_converseMode = 0;
+ _vm->_scripts->_endFlag = true;
+ _vm->_scripts->_returnCode = 0;
+
+ return false;
+ }
+ default:
+ debugPrintf("Current scene is: %d\n", _vm->_player->_roomNumber);
+ debugPrintf("Usage: %s <scene number>\n", argv[0]);
+ return true;
+ }
+}
+
+bool Debugger::Cmd_Cheat(int argc, const char **argv) {
+ if (argc != 1) {
+ debugPrintf("Usage: %s\n", argv[0]);
+ debugPrintf("Switches on/off the cheat mode\n");
+ return true;
+ }
+
+ _vm->_cheatFl = !_vm->_cheatFl;
+ debugPrintf("Cheat is now %s\n", _vm->_cheatFl ? "ON" : "OFF");
+ return true;
+}
+
+/*------------------------------------------------------------------------*/
+
+namespace Amazon {
+
+AmazonDebugger::AmazonDebugger(AccessEngine *vm) : Debugger(vm) {
+ registerCmd("chapter", WRAP_METHOD(AmazonDebugger, Cmd_StartChapter));
+}
+
+bool AmazonDebugger::Cmd_StartChapter(int argc, const char **argv) {
+ if (argc != 2) {
+ debugPrintf("Usage: %s <chapter number>\n", argv[0]);
+ return true;
+ }
+
+ // Build up a simple one line script to start the given chapter
+ byte *chapterScript = (byte *)malloc(5);
+ chapterScript[0] = SCRIPT_START_BYTE;
+ chapterScript[1] = ROOM_SCRIPT % 256;
+ chapterScript[2] = ROOM_SCRIPT / 256;
+ chapterScript[3] = 0x80 + 75; // cmdChapter
+ chapterScript[4] = strToInt(argv[1]); // chapter number
+ _vm->_scripts->setScript(new Resource(chapterScript, 5), true);
+
+ return false;
+}
+
+} // End of namespace Amazon
+
+} // End of namespace Access
diff --git a/engines/access/debugger.h b/engines/access/debugger.h
new file mode 100644
index 0000000000..f4d8df7634
--- /dev/null
+++ b/engines/access/debugger.h
@@ -0,0 +1,64 @@
+/* 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 ACCESS_DEBUGGER_H
+#define ACCESS_DEBUGGER_H
+
+#include "common/scummsys.h"
+#include "gui/debugger.h"
+#include "access/amazon/amazon_resources.h"
+#include "access/martian/martian_resources.h"
+
+namespace Access {
+
+class AccessEngine;
+
+class Debugger : public GUI::Debugger {
+protected:
+ AccessEngine *_vm;
+
+ bool Cmd_LoadScene(int argc, const char **argv);
+ bool Cmd_Cheat(int argc, const char **argv);
+ Common::String *_sceneDescr;
+ int _sceneNumb;
+public:
+ static Debugger *init(AccessEngine *vm);
+public:
+ Debugger(AccessEngine *vm);
+ virtual ~Debugger();
+};
+
+namespace Amazon {
+
+class AmazonDebugger : public Debugger {
+protected:
+ bool Cmd_StartChapter(int argc, const char **argv);
+public:
+ AmazonDebugger(AccessEngine *vm);
+ virtual ~AmazonDebugger() {}
+};
+
+} // End of namespace Amazon
+
+} // End of namespace Access
+
+#endif /* ACCESS_DEBUGGER_H */
diff --git a/engines/access/decompress.cpp b/engines/access/decompress.cpp
new file mode 100644
index 0000000000..c5656afa51
--- /dev/null
+++ b/engines/access/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 "common/debug.h"
+#include "common/endian.h"
+#include "common/util.h"
+
+#include "access/decompress.h"
+
+namespace Access {
+
+void LzwDecompressor::decompress(byte *source, byte *dest) {
+
+ _source = source;
+
+ byte litByte = 0;
+ uint16 oldCode = 0;
+ uint16 copyLength, maxCodeValue, code, nextCode, lastCode;
+
+ byte *copyBuf = new byte[8192];
+
+ struct { uint16 code; byte value; } codeTable[8192];
+ memset(codeTable, 0, sizeof(codeTable));
+
+ _codeLength = 9;
+ nextCode = 258;
+ maxCodeValue = 512;
+
+ copyLength = 0;
+ _bitPos = 0;
+
+ while (1) {
+
+ code = getCode();
+
+ if (code == 257)
+ break;
+
+ if (code == 256) {
+ _codeLength = 9;
+ nextCode = 258;
+ maxCodeValue = 512;
+ lastCode = getCode();
+ oldCode = lastCode;
+ litByte = lastCode;
+ *dest++ = litByte;
+ } else {
+ lastCode = code;
+ if (code >= nextCode) {
+ lastCode = oldCode;
+ copyBuf[copyLength++] = litByte;
+ }
+ while (lastCode > 255) {
+ copyBuf[copyLength++] = codeTable[lastCode].value;
+ lastCode = codeTable[lastCode].code;
+ }
+ litByte = lastCode;
+ copyBuf[copyLength++] = lastCode;
+ while (copyLength > 0)
+ *dest++ = copyBuf[--copyLength];
+ codeTable[nextCode].value = lastCode;
+ codeTable[nextCode].code = oldCode;
+ nextCode++;
+ oldCode = code;
+ if (nextCode >= maxCodeValue && _codeLength <= 12) {
+ _codeLength++;
+ maxCodeValue <<= 1;
+ }
+ }
+
+ }
+
+ delete[] copyBuf;
+
+}
+
+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;
+ }
+ return (hiCode << 8) | loCode;
+}
+
+uint32 decompressDBE(byte *source, byte **dest) {
+
+ uint32 destSize = READ_LE_UINT32(source + 4);
+ *dest = new byte[destSize];
+
+ debug(1, "decompressDBE() destSize = %d", destSize);
+
+ LzwDecompressor dec;
+ dec.decompress(source + 16, *dest);
+
+ debug(1, "decompressDBE() ok");
+
+ return destSize;
+}
+
+} // End of namespace Access
diff --git a/engines/zvision/core/menu.h b/engines/access/decompress.h
index 3ab6d4c2ec..eea450086b 100644
--- a/engines/zvision/core/menu.h
+++ b/engines/access/decompress.h
@@ -20,9 +20,24 @@
*
*/
-#ifndef ZVISION_MENU_H
-#define ZVISION_MENU_H
+#ifndef ACCESS_DECOMPRESS_H
+#define ACCESS_DECOMPRESS_H
-// TODO: Implement MenuHandler
+#include "common/scummsys.h"
+
+namespace Access {
+
+class LzwDecompressor {
+public:
+ void decompress(byte *source, byte *dest);
+private:
+ byte *_source;
+ byte _codeLength, _bitPos;
+ uint16 getCode();
+};
+
+uint32 decompressDBE(byte *source, byte **dest);
+
+} // End of namespace Access
#endif
diff --git a/engines/access/detection.cpp b/engines/access/detection.cpp
new file mode 100644
index 0000000000..441740c1b2
--- /dev/null
+++ b/engines/access/detection.cpp
@@ -0,0 +1,209 @@
+/* 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 "access/access.h"
+#include "access/amazon/amazon_game.h"
+#include "access/martian/martian_game.h"
+
+#include "base/plugins.h"
+#include "common/savefile.h"
+#include "common/str-array.h"
+#include "common/memstream.h"
+#include "engines/advancedDetector.h"
+#include "common/system.h"
+#include "graphics/colormasks.h"
+#include "graphics/surface.h"
+
+#define MAX_SAVES 99
+
+namespace Access {
+
+struct AccessGameDescription {
+ ADGameDescription desc;
+
+ int gameID;
+ uint32 features;
+};
+
+uint32 AccessEngine::getGameID() const {
+ return _gameDescription->gameID;
+}
+
+uint32 AccessEngine::getGameFeatures() const {
+ return _gameDescription->features;
+}
+
+uint32 AccessEngine::getFeatures() const {
+ return _gameDescription->desc.flags;
+}
+
+bool AccessEngine::isCD() const {
+ return (bool)(_gameDescription->desc.flags & ADGF_CD);
+}
+
+bool AccessEngine::isDemo() const {
+ return (bool)(_gameDescription->desc.flags & ADGF_DEMO);
+}
+
+Common::Language AccessEngine::getLanguage() const {
+ return _gameDescription->desc.language;
+}
+
+Common::Platform AccessEngine::getPlatform() const {
+ return _gameDescription->desc.platform;
+}
+
+} // End of namespace Access
+
+static const PlainGameDescriptor AccessGames[] = {
+ {"Access", "Access"},
+ {"amazon", "Amazon: Guardians of Eden"},
+ {"martian", "Martian Memorandum"},
+ {0, 0}
+};
+
+#include "access/detection_tables.h"
+
+class AccessMetaEngine : public AdvancedMetaEngine {
+public:
+ AccessMetaEngine() : AdvancedMetaEngine(Access::gameDescriptions, sizeof(Access::AccessGameDescription), AccessGames) {
+ _maxScanDepth = 3;
+ }
+
+ virtual const char *getName() const {
+ return "Access Engine";
+ }
+
+ virtual const char *getOriginalCopyright() const {
+ return "Access Engine (c) 1989-1994 Access Software";
+ }
+
+ virtual bool hasFeature(MetaEngineFeature f) const;
+ virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
+ virtual SaveStateList listSaves(const char *target) const;
+ virtual int getMaximumSaveSlot() const;
+ virtual void removeSaveState(const char *target, int slot) const;
+ SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
+};
+
+bool AccessMetaEngine::hasFeature(MetaEngineFeature f) const {
+ return
+ (f == kSupportsListSaves) ||
+ (f == kSupportsLoadingDuringStartup) ||
+ (f == kSupportsDeleteSave) ||
+ (f == kSavesSupportMetaInfo) ||
+ (f == kSavesSupportThumbnail);
+}
+
+bool Access::AccessEngine::hasFeature(EngineFeature f) const {
+ return
+ (f == kSupportsRTL) ||
+ (f == kSupportsLoadingDuringRuntime) ||
+ (f == kSupportsSavingDuringRuntime);
+}
+
+bool AccessMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
+ const Access::AccessGameDescription *gd = (const Access::AccessGameDescription *)desc;
+ if (gd) {
+ switch (gd->gameID) {
+ case Access::GType_Amazon:
+ *engine = new Access::Amazon::AmazonEngine(syst, gd);
+ break;
+ case Access::GType_MartianMemorandum:
+ *engine = new Access::Martian::MartianEngine(syst, gd);
+ break;
+ default:
+ error("Unknown game");
+ }
+ }
+ return gd != 0;
+}
+
+SaveStateList AccessMetaEngine::listSaves(const char *target) const {
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ Common::StringArray filenames;
+ Common::String saveDesc;
+ Common::String pattern = Common::String::format("%s.0??", target);
+ Access::AccessSavegameHeader 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_SAVES) {
+ Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file);
+
+ if (in) {
+ Access::AccessEngine::readSavegameHeader(in, header);
+ saveList.push_back(SaveStateDescriptor(slot, header._saveName));
+
+ header._thumbnail->free();
+ delete header._thumbnail;
+ delete in;
+ }
+ }
+ }
+
+ return saveList;
+}
+
+int AccessMetaEngine::getMaximumSaveSlot() const {
+ return MAX_SAVES;
+}
+
+void AccessMetaEngine::removeSaveState(const char *target, int slot) const {
+ Common::String filename = Common::String::format("%s.%03d", target, slot);
+ g_system->getSavefileManager()->removeSavefile(filename);
+}
+
+SaveStateDescriptor AccessMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
+ Common::String filename = Common::String::format("%s.%03d", target, slot);
+ Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(filename);
+
+ if (f) {
+ Access::AccessSavegameHeader header;
+ Access::AccessEngine::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(ACCESS)
+ REGISTER_PLUGIN_DYNAMIC(ACCESS, PLUGIN_TYPE_ENGINE, AccessMetaEngine);
+#else
+ REGISTER_PLUGIN_STATIC(ACCESS, PLUGIN_TYPE_ENGINE, AccessMetaEngine);
+#endif
diff --git a/engines/access/detection_tables.h b/engines/access/detection_tables.h
new file mode 100644
index 0000000000..88a64470c5
--- /dev/null
+++ b/engines/access/detection_tables.h
@@ -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.
+ *
+ */
+
+namespace Access {
+
+static const AccessGameDescription gameDescriptions[] = {
+ {
+ // Amazon Guardians of Eden - Floppy English
+ // 3.5" and 5.25" floppies provided by Strangerke had the same md5
+ // Except the sound file. The executable is also identical
+ {
+ "amazon",
+ 0,
+ AD_ENTRY1s("c00.ap", "dcabf69d5a0d911168cb73511ebaead0", 331481),
+ Common::EN_ANY,
+ Common::kPlatformDOS,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NONE)
+ },
+ GType_Amazon,
+ 0
+ },
+
+ // Amazon Guardians of Eden - Demo English
+ {
+ {
+ "amazon",
+ "Demo",
+ AD_ENTRY1s("c25.ap", "5baba0c052d22157499bfa05cb1ed5b7", 65458),
+ Common::EN_ANY,
+ Common::kPlatformDOS,
+ ADGF_DEMO,
+ GUIO1(GUIO_NONE)
+ },
+ GType_Amazon,
+ 0
+ },
+
+ {
+ // Amazon: Guardians of Eden - CD English
+ {
+ "amazon",
+ "CD",
+ AD_ENTRY1s("checksum.crc", "bef85478132fec74cb5d9067f3a37d24", 8),
+ Common::EN_ANY,
+ Common::kPlatformDOS,
+ ADGF_CD,
+ GUIO1(GUIO_NONE)
+ },
+ GType_Amazon,
+ 0
+ },
+
+ {
+ // Martian Memorandum
+ {
+ "martian",
+ nullptr,
+ AD_ENTRY1s("r00.ap", "af98db5ee7f9ef86c6b1f43187a3691b", 31),
+ Common::EN_ANY,
+ Common::kPlatformDOS,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NONE)
+ },
+ GType_MartianMemorandum,
+ 0
+ },
+
+ { AD_TABLE_END_MARKER, 0, 0 }
+};
+
+} // End of namespace Access
diff --git a/engines/access/events.cpp b/engines/access/events.cpp
new file mode 100644
index 0000000000..6ffe67acfb
--- /dev/null
+++ b/engines/access/events.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 "graphics/cursorman.h"
+#include "common/events.h"
+#include "common/endian.h"
+#include "engines/util.h"
+#include "access/access.h"
+#include "access/events.h"
+#include "access/player.h"
+#include "access/amazon/amazon_resources.h"
+
+#define CURSOR_WIDTH 16
+#define CURSOR_HEIGHT 16
+
+namespace Access {
+
+EventsManager::EventsManager(AccessEngine *vm) : _vm(vm) {
+ _cursorId = CURSOR_NONE;
+ _normalMouse = CURSOR_CROSSHAIRS;
+ _frameCounter = 10;
+ _priorFrameTime = 0;
+ _leftButton = _rightButton = false;
+ _middleButton = false;
+ _wheelUp = _wheelDown = false;
+ _mouseCol = _mouseRow = 0;
+ _cursorExitFlag = false;
+ _vbCount = 0;
+ _keyCode = Common::KEYCODE_INVALID;
+ _priorTimerTime = 0;
+}
+
+EventsManager::~EventsManager() {
+ _invCursor.free();
+}
+
+void EventsManager::forceSetCursor(CursorType cursorId) {
+ setNormalCursor(cursorId);
+ setCursor(cursorId);
+}
+
+void EventsManager::setNormalCursor(CursorType cursorId) {
+ _normalMouse = cursorId;
+}
+
+void EventsManager::setCursor(CursorType cursorId) {
+ if (cursorId == _cursorId)
+ return;
+ _cursorId = cursorId;
+
+ if (cursorId == CURSOR_INVENTORY) {
+ // Set the cursor
+ CursorMan.replaceCursor(_invCursor.getPixels(), _invCursor.w, _invCursor.h,
+ _invCursor.w / 2, _invCursor.h / 2, 0);
+ } else {
+ // Get a pointer to the mouse data to use, and get the cursor hotspot
+ const byte *srcP = Amazon::CURSORS[cursorId];
+ int hotspotX = (int16)READ_LE_UINT16(srcP);
+ int hotspotY = (int16)READ_LE_UINT16(srcP + 2);
+ srcP += 4;
+
+ // Create a surface to build up the cursor on
+ Graphics::Surface cursorSurface;
+ cursorSurface.create(16, 16, Graphics::PixelFormat::createFormatCLUT8());
+ byte *destP = (byte *)cursorSurface.getPixels();
+ Common::fill(destP, destP + CURSOR_WIDTH * CURSOR_HEIGHT, 0);
+
+ // Loop to build up the cursor
+ for (int y = 0; y < CURSOR_HEIGHT; ++y) {
+ destP = (byte *)cursorSurface.getBasePtr(0, y);
+ int width = CURSOR_WIDTH;
+ int skip = *srcP++;
+ int plot = *srcP++;
+ if (skip >= width)
+ break;
+
+ // Skip over pixels
+ destP += skip;
+ width -= skip;
+
+ // Write out the pixels to plot
+ while (plot > 0 && width > 0) {
+ *destP++ = *srcP++;
+ --plot;
+ --width;
+ }
+ }
+
+ // Set the cursor
+ CursorMan.replaceCursor(cursorSurface.getPixels(), CURSOR_WIDTH, CURSOR_HEIGHT,
+ hotspotX, hotspotY, 0);
+
+ // Free the cursor surface
+ cursorSurface.free();
+ }
+}
+
+void EventsManager::setCursorData(Graphics::Surface *src, const Common::Rect &r) {
+ _invCursor.create(r.width(), r.height(), Graphics::PixelFormat::createFormatCLUT8());
+ _invCursor.copyRectToSurface(*src, 0, 0, r);
+}
+
+void EventsManager::showCursor() {
+ CursorMan.showMouse(true);
+}
+
+void EventsManager::hideCursor() {
+ CursorMan.showMouse(false);
+}
+
+bool EventsManager::isCursorVisible() {
+ return CursorMan.isVisible();
+}
+
+void EventsManager::pollEvents(bool skipTimers) {
+ if (checkForNextFrameCounter()) {
+ nextFrame();
+ }
+
+ if (checkForNextTimerUpdate() && !skipTimers)
+ nextTimer();
+
+ _vm->_sound->checkSoundQueue();
+
+ _wheelUp = _wheelDown = false;
+
+ Common::Event event;
+ while (g_system->getEventManager()->pollEvent(event)) {
+ 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 {
+ keyControl(event.kbd.keycode, true);
+ }
+ return;
+ case Common::EVENT_KEYUP:
+ keyControl(event.kbd.keycode, false);
+ return;
+ case Common::EVENT_MOUSEMOVE:
+ _mousePos = event.mouse;
+ _mouseCol = _mousePos.x / 8;
+ _mouseRow = _mousePos.y / 8;
+ break;
+ case Common::EVENT_LBUTTONDOWN:
+ _leftButton = true;
+ return;
+ case Common::EVENT_LBUTTONUP:
+ _leftButton = false;
+ return;
+ case Common::EVENT_RBUTTONDOWN:
+ _rightButton = true;
+ return;
+ case Common::EVENT_RBUTTONUP:
+ _rightButton = false;
+ return;
+ case Common::EVENT_MBUTTONDOWN:
+ _middleButton = true;
+ return;
+ case Common::EVENT_MBUTTONUP:
+ _middleButton = false;
+ return;
+ case Common::EVENT_WHEELUP:
+ _wheelUp = true;
+ return;
+ case Common::EVENT_WHEELDOWN:
+ _wheelDown = true;
+ return;
+ default:
+ break;
+ }
+ }
+}
+
+void EventsManager::keyControl(Common::KeyCode keycode, bool isKeyDown) {
+ Player &player = *_vm->_player;
+
+ if (!isKeyDown) {
+ if (player._move != NONE) {
+ _keyCode = Common::KEYCODE_INVALID;
+ player._move = NONE;
+ }
+ return;
+ }
+
+ _keyCode = keycode;
+
+ switch (keycode) {
+ case Common::KEYCODE_UP:
+ case Common::KEYCODE_KP8:
+ player._move = UP;
+ break;
+ case Common::KEYCODE_DOWN:
+ case Common::KEYCODE_KP2:
+ player._move = DOWN;
+ break;
+ case Common::KEYCODE_LEFT:
+ case Common::KEYCODE_KP4:
+ player._move = LEFT;
+ break;
+ case Common::KEYCODE_RIGHT:
+ case Common::KEYCODE_KP6:
+ player._move = RIGHT;
+ break;
+ case Common::KEYCODE_KP7:
+ player._move = UPLEFT;
+ break;
+ case Common::KEYCODE_KP9:
+ player._move = UPRIGHT;
+ break;
+ case Common::KEYCODE_KP1:
+ player._move = DOWNLEFT;
+ break;
+ case Common::KEYCODE_KP3:
+ player._move = DOWNRIGHT;
+ break;
+ default:
+ break;
+ }
+}
+
+void EventsManager::pollEventsAndWait() {
+ pollEvents();
+ delay();
+}
+
+bool EventsManager::checkForNextFrameCounter() {
+ // Check for next game frame
+ uint32 milli = g_system->getMillis();
+ if ((milli - _priorFrameTime) >= GAME_FRAME_TIME) {
+ --_vbCount;
+ ++_frameCounter;
+ _priorFrameTime = milli;
+
+ return true;
+ }
+
+ return false;
+}
+
+bool EventsManager::checkForNextTimerUpdate() {
+ // Check for next timer update
+ uint32 milli = g_system->getMillis();
+ if ((milli - _priorTimerTime) >= GAME_TIMER_TIME) {
+ _priorTimerTime = milli;
+
+ return true;
+ }
+
+ return false;
+}
+
+void EventsManager::nextFrame() {
+ // Give time to the debugger
+ _vm->_debugger->onFrame();
+
+ // TODO: Refactor for dirty rects
+ _vm->_screen->updateScreen();
+}
+
+void EventsManager::nextTimer() {
+ _vm->_animation->updateTimers();
+ _vm->_timers.updateTimers();
+}
+
+void EventsManager::delay(int time) {
+ g_system->delayMillis(time);
+}
+
+void EventsManager::zeroKeys() {
+ _keyCode = Common::KEYCODE_INVALID;
+}
+
+bool EventsManager::getKey(Common::KeyState &key) {
+ if (_keyCode == Common::KEYCODE_INVALID) {
+ return false;
+ } else {
+ key = _keyCode;
+ _keyCode = Common::KEYCODE_INVALID;
+ return true;
+ }
+}
+
+bool EventsManager::isKeyPending() const {
+ return _keyCode != Common::KEYCODE_INVALID;
+}
+
+void EventsManager::debounceLeft() {
+ while (_leftButton && !_vm->shouldQuit()) {
+ pollEventsAndWait();
+ }
+}
+
+void EventsManager::clearEvents() {
+ _leftButton = _rightButton = false;
+ zeroKeys();
+}
+
+void EventsManager::waitKeyMouse() {
+ while (!_vm->shouldQuit() && !isKeyMousePressed()) {
+ pollEvents(true);
+ delay();
+ }
+}
+
+Common::Point EventsManager::calcRawMouse() {
+ Common::Point pt;
+ Screen &screen = *_vm->_screen;
+ pt.x = _mousePos.x - screen._windowXAdd +
+ (_vm->_scrollCol * TILE_WIDTH) + _vm->_scrollX;
+ pt.y = _mousePos.y - screen._screenYOff - screen._windowYAdd +
+ (_vm->_scrollRow * TILE_HEIGHT) + _vm->_scrollY;
+
+ return pt;
+}
+
+int EventsManager::checkMouseBox1(Common::Array<Common::Rect> &rects) {
+ for (uint16 i = 0; i < rects.size(); ++i) {
+ if (rects[i].left == -1)
+ return -1;
+
+ if ((_mousePos.x > rects[i].left) && (_mousePos.x < rects[i].right)
+ && (_mousePos.y > rects[i].top) && (_mousePos.y < rects[i].bottom))
+ return i;
+ }
+
+ return -1;
+}
+
+bool EventsManager::isKeyMousePressed() {
+ bool result = _leftButton || _rightButton || isKeyPending();
+ debounceLeft();
+ zeroKeys();
+
+ return result;
+}
+
+void EventsManager::centerMousePos() {
+ _mousePos = Common::Point(160, 100);
+}
+
+void EventsManager::restrictMouse() {
+ // No implementation in ScummVM
+}
+
+} // End of namespace Access
diff --git a/engines/access/events.h b/engines/access/events.h
new file mode 100644
index 0000000000..b8c5f0ee5e
--- /dev/null
+++ b/engines/access/events.h
@@ -0,0 +1,157 @@
+/* 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 ACCESS_EVENTS_H
+#define ACCESS_EVENTS_H
+
+#include "common/scummsys.h"
+#include "common/events.h"
+#include "common/stack.h"
+
+namespace Access {
+
+enum CursorType {
+ CURSOR_NONE = -1,
+ CURSOR_ARROW = 0, CURSOR_CROSSHAIRS, CURSOR_2, CURSOR_3, CURSOR_LOOK,
+ CURSOR_USE, CURSOR_TAKE, CURSOR_CLIMB, CURSOR_TALK, CURSOR_HELP,
+ CURSOR_INVENTORY = 99
+};
+
+#define GAME_FRAME_RATE 100
+#define GAME_FRAME_TIME (1000 / GAME_FRAME_RATE)
+#define GAME_TIMER_TIME 15
+
+class AccessEngine;
+
+class EventsManager {
+private:
+ AccessEngine *_vm;
+ uint32 _frameCounter;
+ uint32 _priorFrameTime;
+ uint32 _priorTimerTime;
+ Common::KeyCode _keyCode;
+
+ Graphics::Surface _invCursor;
+ bool checkForNextFrameCounter();
+ bool checkForNextTimerUpdate();
+ void nextFrame();
+ void nextTimer();
+ void keyControl(Common::KeyCode keycode, bool isKeyDown);
+public:
+ CursorType _cursorId;
+ CursorType _normalMouse;
+ bool _leftButton, _rightButton;
+ bool _middleButton;
+ bool _wheelUp, _wheelDown;
+ Common::Point _mousePos;
+ int _mouseCol, _mouseRow;
+ bool _cursorExitFlag;
+ int _vbCount;
+public:
+ /**
+ * Constructor
+ */
+ EventsManager(AccessEngine *vm);
+
+ /**
+ * Destructor
+ */
+ ~EventsManager();
+
+ /**
+ * Return frame counter
+ */
+ uint32 getFrameCounter() { return _frameCounter; }
+
+ /**
+ * Sets the cursor and reset the normal cursor
+ */
+ void forceSetCursor(CursorType cursorId);
+
+ /**
+ * Sets the normal cursor
+ */
+ void setNormalCursor(CursorType cursorId);
+
+ /**
+ * Sets the cursor
+ */
+ void setCursor(CursorType cursorId);
+
+ /**
+ * Set the image for the inventory cursor
+ */
+ void setCursorData(Graphics::Surface *src, const Common::Rect &r);
+
+ /**
+ * Return the current cursor Id
+ */
+ CursorType getCursor() const { return _cursorId; }
+
+ /**
+ * Show the mouse cursor
+ */
+ void showCursor();
+
+ /**
+ * Hide the mouse cursor
+ */
+ void hideCursor();
+
+ /**
+ * Returns if the mouse cursor is visible
+ */
+ bool isCursorVisible();
+
+ void pollEvents(bool skipTimers = false);
+
+ void pollEventsAndWait();
+
+ void zeroKeys();
+
+ bool getKey(Common::KeyState &key);
+
+ bool isKeyPending() const;
+
+ void delay(int time = 5);
+
+ void debounceLeft();
+
+ void clearEvents();
+
+ void waitKeyMouse();
+
+ Common::Point &getMousePos() { return _mousePos; }
+
+ Common::Point calcRawMouse();
+
+ int checkMouseBox1(Common::Array<Common::Rect> &rects);
+
+ bool isKeyMousePressed();
+
+ void centerMousePos();
+ void restrictMouse();
+};
+
+} // End of namespace Access
+
+#endif /* ACCESS_EVENTS_H */
diff --git a/engines/access/files.cpp b/engines/access/files.cpp
new file mode 100644
index 0000000000..4d734a67a9
--- /dev/null
+++ b/engines/access/files.cpp
@@ -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.
+ *
+ */
+
+#include "common/substream.h"
+#include "access/files.h"
+#include "access/amazon/amazon_resources.h"
+#include "access/martian/martian_resources.h"
+#include "access/access.h"
+
+namespace Access {
+
+FileIdent::FileIdent() {
+ _fileNum = -1;
+ _subfile = 0;
+}
+
+void FileIdent::load(Common::SeekableReadStream &s) {
+ _fileNum = s.readSint16LE();
+ _subfile = s.readUint16LE();
+}
+
+/*------------------------------------------------------------------------*/
+
+CellIdent:: CellIdent() {
+ _cell = 0;
+}
+
+CellIdent::CellIdent(int cell, int fileNum, int subfile) {
+ _cell = cell;
+ _fileNum = fileNum;
+ _subfile = subfile;
+}
+
+/*------------------------------------------------------------------------*/
+
+Resource::Resource() {
+ _stream = nullptr;
+ _size = 0;
+ _data = nullptr;
+}
+
+Resource::~Resource() {
+ delete[] _data;
+ delete _stream;
+}
+
+Resource::Resource(byte *p, int size) {
+ _data = p;
+ _size = size;
+ _stream = new Common::MemoryReadStream(p, size);
+}
+
+byte *Resource::data() {
+ if (_data == nullptr) {
+ _data = new byte[_size];
+ int pos = _stream->pos();
+ _stream->seek(0);
+ _stream->read(_data, _size);
+ _stream->seek(pos);
+ }
+
+ return _data;
+}
+
+/*------------------------------------------------------------------------*/
+
+FileManager::FileManager(AccessEngine *vm) : _vm(vm) {
+ switch (vm->getGameID()) {
+ case GType_Amazon:
+ if (_vm->isDemo())
+ _filenames = &Amazon::FILENAMES_DEMO[0];
+ else
+ _filenames = &Amazon::FILENAMES[0];
+ break;
+ case GType_MartianMemorandum:
+ _filenames = &Martian::FILENAMES[0];
+ break;
+ default:
+ error("Unknown game");
+ }
+
+ _fileNumber = -1;
+ _setPaletteFlag = true;
+}
+
+FileManager::~FileManager() {
+}
+
+Resource *FileManager::loadFile(int fileNum, int subfile) {
+ Resource *res = new Resource();
+ setAppended(res, fileNum);
+ gotoAppended(res, subfile);
+
+ handleFile(res);
+ return res;
+}
+
+Resource *FileManager::loadFile(const FileIdent &fileIdent) {
+ return loadFile(fileIdent._fileNum, fileIdent._subfile);
+}
+
+Resource *FileManager::loadFile(const Common::String &filename) {
+ Resource *res = new Resource();
+
+ // Open the file
+ openFile(res, filename);
+
+ // Set up stream for the entire file
+ res->_size = res->_file.size();
+ res->_stream = res->_file.readStream(res->_size);
+
+ handleFile(res);
+ return res;
+}
+
+bool FileManager::existFile(const Common::String &filename) {
+ Common::File f;
+ return f.exists(filename);
+}
+
+void FileManager::openFile(Resource *res, const Common::String &filename) {
+ // Open up the file
+ _fileNumber = -1;
+ if (!res->_file.open(filename))
+ error("Could not open file - %s", filename.c_str());
+}
+
+void FileManager::loadScreen(Graphics::Surface *dest, int fileNum, int subfile) {
+ Resource *res = loadFile(fileNum, subfile);
+ handleScreen(dest, res);
+ delete res;
+}
+
+void FileManager::handleScreen(Graphics::Surface *dest, Resource *res) {
+ _vm->_screen->loadRawPalette(res->_stream);
+ if (_setPaletteFlag)
+ _vm->_screen->setPalette();
+ _setPaletteFlag = true;
+
+ // The remainder of the file after the palette may be separately compressed,
+ // so call handleFile to handle it if it is
+ res->_size -= res->_stream->pos();
+ handleFile(res);
+
+ if (dest != _vm->_screen)
+ dest->w = _vm->_screen->w;
+
+ if (dest->w == dest->pitch) {
+ res->_stream->read((byte *)dest->getPixels(), dest->w * dest->h);
+ } else {
+ for (int y = 0; y < dest->h; ++y) {
+ byte *pDest = (byte *)dest->getBasePtr(0, y);
+ res->_stream->read(pDest, dest->w);
+ }
+ }
+
+ if (dest == _vm->_screen)
+ _vm->_screen->addDirtyRect(Common::Rect(0, 0, dest->w, dest->h));
+}
+
+void FileManager::loadScreen(int fileNum, int subfile) {
+ loadScreen(_vm->_screen, fileNum, subfile);
+}
+
+void FileManager::loadScreen(const Common::String &filename) {
+ Resource *res = loadFile(filename);
+ handleScreen(_vm->_screen, res);
+ delete res;
+}
+
+void FileManager::handleFile(Resource *res) {
+ char header[3];
+ res->_stream->read(&header[0], 3);
+ res->_stream->seek(-3, SEEK_CUR);
+
+ bool isCompressed = !strncmp(header, "DBE", 3);
+
+ // If the data is compressed, uncompress it and replace the stream
+ // in the resource with the decompressed one
+ if (isCompressed) {
+ // Read in the entire compressed data
+ byte *src = new byte[res->_size];
+ res->_stream->read(src, res->_size);
+
+ // Decompress the data
+ res->_size = decompressDBE(src, &res->_data);
+
+ // Replace the default resource stream with a stream for the decompressed data
+ delete res->_stream;
+ res->_file.close();
+ res->_stream = new Common::MemoryReadStream(res->_data, res->_size);
+
+ delete[] src;
+ }
+}
+
+void FileManager::setAppended(Resource *res, int fileNum) {
+ // Open the file for access
+ if (!res->_file.open(_filenames[fileNum]))
+ error("Could not open file %s", _filenames[fileNum]);
+
+ // If a different file has been opened then previously, load its index
+ if (_fileNumber != fileNum) {
+ _fileNumber = fileNum;
+
+ // Read in the file index
+ int count = res->_file.readUint16LE();
+ assert(count <= 100);
+ _fileIndex.resize(count);
+ for (int i = 0; i < count; ++i)
+ _fileIndex[i] = res->_file.readUint32LE();
+ }
+}
+
+void FileManager::gotoAppended(Resource *res, int subfile) {
+ uint32 offset = _fileIndex[subfile];
+ uint32 size = (subfile == (int)_fileIndex.size() - 1) ? res->_file.size() - offset :
+ _fileIndex[subfile + 1] - offset;
+
+ res->_size = size;
+ res->_stream = new Common::SeekableSubReadStream(&res->_file, offset, offset + size);
+}
+
+} // End of namespace Access
diff --git a/engines/access/files.h b/engines/access/files.h
new file mode 100644
index 0000000000..714ea44c75
--- /dev/null
+++ b/engines/access/files.h
@@ -0,0 +1,142 @@
+/* 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 ACCESS_FILES_H
+#define ACCESS_FILES_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/file.h"
+#include "graphics/surface.h"
+#include "access/decompress.h"
+
+namespace Access {
+
+class AccessEngine;
+
+struct FileIdent {
+ int _fileNum;
+ int _subfile;
+
+ FileIdent();
+ FileIdent(int fileNum, int subfile) { _fileNum = fileNum; _subfile = subfile; }
+
+ void load(Common::SeekableReadStream &s);
+};
+
+struct CellIdent : FileIdent {
+ byte _cell;
+
+ CellIdent();
+ CellIdent(int cell, int fileNum, int subfile);
+};
+
+class FileManager;
+
+class Resource {
+ friend class FileManager;
+private:
+ Common::File _file;
+ byte *_data;
+public:
+ Common::SeekableReadStream *_stream;
+ int _size;
+
+ Resource();
+ Resource(byte *data, int size);
+ ~Resource();
+ byte *data();
+};
+
+class FileManager {
+private:
+ AccessEngine *_vm;
+ const char * const *_filenames;
+
+ void openFile(Resource *res, const Common::String &filename);
+
+ /**
+ * Handles setting up the resource with a stream for the located resource
+ */
+ void handleFile(Resource *res);
+
+ /**
+ * Handles loading a screen surface and palette with decoded resource
+ */
+ void handleScreen(Graphics::Surface *dest, Resource *res);
+
+ /**
+ * Open up a sub-file container file
+ */
+ void setAppended(Resource *file, int fileNum);
+
+ /**
+ * Open up a sub-file resource within an alrady opened container file.
+ */
+ void gotoAppended(Resource *file, int subfile);
+public:
+ int _fileNumber;
+ Common::Array<uint32> _fileIndex;
+ bool _setPaletteFlag;
+public:
+ FileManager(AccessEngine *vm);
+ ~FileManager();
+
+ /**
+ * Check the existence of a given file
+ */
+ bool existFile(const Common::String &filename);
+
+ /**
+ * Load a given subfile from a container file
+ */
+ Resource *loadFile(int fileNum, int subfile);
+
+ /**
+ * Loads a resource specified by a file identifier
+ */
+ Resource *loadFile(const FileIdent &fileIdent);
+
+ /**
+ * Load a given file by name
+ */
+ Resource *loadFile(const Common::String &filename);
+
+ /**
+ * Load a given scren from a container file
+ */
+ void loadScreen(int fileNum, int subfile);
+
+ /**
+ * Load a given screen by name
+ */
+ void loadScreen(const Common::String &filename);
+
+ /**
+ * Load a screen resource onto a designated surface
+ */
+ void loadScreen(Graphics::Surface *dest, int fileNum, int subfile);
+};
+
+} // End of namespace Access
+
+#endif /* ACCESS_FILES_H */
diff --git a/engines/access/font.cpp b/engines/access/font.cpp
new file mode 100644
index 0000000000..8af183f193
--- /dev/null
+++ b/engines/access/font.cpp
@@ -0,0 +1,179 @@
+/* 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 "access/font.h"
+
+namespace Access {
+
+byte Font::_fontColors[4];
+
+Font::Font() {
+ _bitWidth = 0;
+ _height = 0;
+}
+
+Font::~Font() {
+ for (uint i = 0; i < _chars.size(); ++i)
+ _chars[i].free();
+}
+
+void Font::load(const int *fontIndex, const byte *fontData) {
+ assert(_chars.size() == 0);
+ int count = fontIndex[0];
+ _bitWidth = fontIndex[1];
+ _height = fontIndex[2];
+
+ _chars.resize(count);
+
+ for (int i = 0; i < count; ++i) {
+ const byte *pData = fontData + fontIndex[i + 3];
+ _chars[i].create(*pData++, _height, Graphics::PixelFormat::createFormatCLUT8());
+
+ for (int y = 0; y < _height; ++y) {
+ int bitsLeft = 0;
+ byte srcByte = 0;
+ byte pixel;
+
+ byte *pDest = (byte *)_chars[i].getBasePtr(0, y);
+ for (int x = 0; x < _chars[i].w; ++x, ++pDest) {
+ // Get the pixel
+ pixel = 0;
+ for (int pixelCtr = 0; pixelCtr < _bitWidth; ++pixelCtr, --bitsLeft) {
+ // No bits in current byte left, so get next byte
+ if (bitsLeft == 0) {
+ bitsLeft = 8;
+ srcByte = *pData++;
+ }
+
+ pixel = (pixel << 1) | (srcByte >> 7);
+ srcByte <<= 1;
+ }
+
+ // Write out the pixel
+ *pDest = pixel;
+ }
+ }
+ }
+}
+
+int Font::charWidth(char c) {
+ if (c < ' ')
+ return 0;
+
+ return _chars[c - ' '].w;
+}
+
+int Font::stringWidth(const Common::String &msg) {
+ int total = 0;
+
+ for (const char *c = msg.c_str(); *c != '\0'; ++c)
+ total += charWidth(*c);
+
+ return total;
+}
+
+bool Font::getLine(Common::String &s, int maxWidth, Common::String &line, int &width) {
+ assert(maxWidth > 0);
+ width = 0;
+ const char *src = s.c_str();
+ char c;
+
+ while ((c = *src) != '\0') {
+ if (c == '\r') {
+ // End of line, so return calculated line
+ line = Common::String(s.c_str(), src);
+ s = Common::String(src + 1);
+ return false;
+ }
+
+ ++src;
+ width += charWidth(c);
+ if (width < maxWidth)
+ continue;
+
+ // Reached maximum allowed size
+ // If this was the last character of the string, let it go
+ if (*src == '\0') {
+ line = Common::String(s.c_str(), src);
+ s.clear();
+ return true;
+ }
+
+ // Work backwards to find space at the start of the current word
+ // as a point to split the line on
+ while (src >= s.c_str() && *src != ' ') {
+ width -= charWidth(*src);
+ --src;
+ }
+ if (src < s.c_str())
+ error("Could not fit line");
+
+ // Split the line around the space
+ line = Common::String(s.c_str(), src);
+ s = Common::String(src + 1);
+ return false;
+ }
+
+ // Return entire string
+ line = s;
+ s = Common::String();
+ return true;
+}
+
+void Font::drawString(ASurface *s, const Common::String &msg, const Common::Point &pt) {
+ Common::Point currPt = pt;
+ const char *msgP = msg.c_str();
+
+ while (*msgP) {
+ currPt.x += drawChar(s, *msgP, currPt);
+ ++msgP;
+ }
+}
+
+int Font::drawChar(ASurface *s, char c, Common::Point &pt) {
+ Graphics::Surface &ch = _chars[c - ' '];
+
+ s->addDirtyRect(Common::Rect(pt.x, pt.y, pt.x + ch.w, pt.y + ch.h));
+
+ // Loop through the lines of the character
+ for (int y = 0; y < ch.h; ++y) {
+ byte *pSrc = (byte *)ch.getBasePtr(0, y);
+ byte *pDest = (byte *)s->getBasePtr(pt.x, pt.y + y);
+
+ // Loop through the horizontal pixels of the line
+ for (int x = 0; x < ch.w; ++x, ++pSrc, ++pDest) {
+ if (*pSrc != 0)
+ *pDest = _fontColors[*pSrc];
+ }
+ }
+
+ return ch.w;
+}
+
+/*------------------------------------------------------------------------*/
+
+FontManager::FontManager() {
+ _printMaxX = 0;
+ Common::fill(&Font::_fontColors[0], &Font::_fontColors[4], 0);
+}
+
+} // End of namespace Access
diff --git a/engines/access/font.h b/engines/access/font.h
new file mode 100644
index 0000000000..6a812051ca
--- /dev/null
+++ b/engines/access/font.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 ACCESS_FONT_H
+#define ACCESS_FONT_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/rect.h"
+#include "access/asurface.h"
+#include "access/data.h"
+
+namespace Access {
+
+struct FontVal {
+public:
+ int _lo, _hi;
+
+ FontVal() { _lo = _hi = 0; }
+};
+
+class Font {
+private:
+ int _bitWidth;
+ int _height;
+ Common::Array<Graphics::Surface> _chars;
+public:
+ static byte _fontColors[4];
+public:
+ Font();
+
+ ~Font();
+
+ /**
+ * Load the given font data
+ */
+ void load(const int *fontIndex, const byte *fontData);
+
+ /**
+ * Get the width of a given character
+ */
+ int charWidth(char c);
+
+ /**
+ * Get the width of a given string
+ */
+ int stringWidth(const Common::String &msg);
+
+ /**
+ * Get a partial string that will fit in a given width
+ * @param s Source string. Modified to remove line
+ * @param maxWidth Maximum width allowed
+ * @param line Output line
+ * @param width Calculated width of returned line
+ * @returns True if last line
+ */
+ bool getLine(Common::String &s, int maxWidth, Common::String &line, int &width);
+
+ /**
+ * Draw a string on a given surface
+ */
+ void drawString(ASurface *s, const Common::String &msg, const Common::Point &pt);
+
+ /**
+ * Draw a character on a given surface
+ */
+ int drawChar(ASurface *s, char c, Common::Point &pt);
+
+};
+
+class FontManager {
+public:
+ FontVal _charSet;
+ FontVal _charFor;
+ int _printMaxX;
+ Font _font1;
+ Font _font2;
+public:
+ FontManager();
+};
+
+} // End of namespace Access
+
+#endif /* ACCESS_FONT_H */
diff --git a/engines/access/inventory.cpp b/engines/access/inventory.cpp
new file mode 100644
index 0000000000..df499ba705
--- /dev/null
+++ b/engines/access/inventory.cpp
@@ -0,0 +1,536 @@
+/* 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 "access/inventory.h"
+#include "access/access.h"
+#include "access/resources.h"
+#include "access/amazon/amazon_resources.h"
+#include "access/martian/martian_resources.h"
+
+namespace Access {
+
+void InventoryEntry::load(const Common::String &name, const int *data) {
+ _value = ITEM_NOT_FOUND;
+ _name = name;
+ _otherItem1 = *data++;
+ _newItem1 = *data++;
+ _otherItem2 = *data++;
+ _newItem2 = *data;
+}
+
+int InventoryEntry::checkItem(int itemId) {
+ if (_otherItem1 == itemId)
+ return _newItem1;
+ else if (_otherItem2 == itemId)
+ return _newItem2;
+ else
+ return -1;
+}
+
+/*------------------------------------------------------------------------*/
+
+InventoryManager::InventoryManager(AccessEngine *vm) : Manager(vm) {
+ _startInvItem = 0;
+ _startInvBox = 0;
+ _invChangeFlag = true;
+ _invRefreshFlag = false;
+ _invModeFlag = false;
+ _startAboutItem = 0;
+ _startTravelItem = 0;
+ _iconDisplayFlag = true;
+ _boxNum = 0;
+
+ const char *const *names;
+ const int *combineP;
+
+ switch (vm->getGameID()) {
+ case GType_Amazon:
+ names = Amazon::INVENTORY_NAMES;
+ combineP = &Amazon::COMBO_TABLE[0][0];
+ _inv.resize(85);
+ break;
+ case GType_MartianMemorandum:
+ names = Martian::INVENTORY_NAMES;
+ combineP = &Martian::COMBO_TABLE[0][0];
+ _inv.resize(54);
+ break;
+ default:
+ error("Unknown game");
+ }
+
+ for (uint i = 0; i < _inv.size(); ++i, combineP += 4) {
+ _inv[i].load(names[i], combineP);
+ }
+
+ for (uint i = 0; i < 26; ++i) {
+ const int *r = INVCOORDS[i];
+ _invCoords.push_back(Common::Rect(r[0], r[2], r[1], r[3]));
+ }
+}
+
+int &InventoryManager::operator[](int idx) {
+ // WORKAROUND: At least in Amazon, some game scripts accidentally do reads
+ // beyond the length of the inventory array
+ static int invalid = 0;
+ return (idx >= (int)_inv.size()) ? invalid : _inv[idx]._value;
+}
+
+int InventoryManager::useItem() {
+ return _vm->_useItem;
+}
+
+void InventoryManager::setUseItem(int itemId) {
+ _vm->_useItem = itemId;
+}
+
+void InventoryManager::refreshInventory() {
+ // The original version was using pre-rendering for the inventory to spare some time.
+ // This is not needed on modern hardware, and it breaks a couple of things.
+ // Therefore it was removed in order to keep the same logic than for the CD version
+ // if (_vm->_screen->_vesaMode) {
+ // _invRefreshFlag = true;
+ // newDisplayInv();
+ // }
+}
+
+int InventoryManager::newDisplayInv() {
+ Screen &screen = *_vm->_screen;
+ EventsManager &events = *_vm->_events;
+ Room &room = *_vm->_room;
+ FileManager &files = *_vm->_files;
+
+ _invModeFlag = true;
+ _vm->_timers.saveTimers();
+
+ if (!room._tile && !_invRefreshFlag) {
+ saveScreens();
+ }
+
+ savedFields();
+ screen.setPanel(1);
+ events._cursorExitFlag = false;
+ getList();
+ initFields();
+
+ files.loadScreen(&_vm->_buffer1, 99, 0);
+ _vm->_buffer1.copyTo(&_vm->_buffer2);
+ _vm->copyBF2Vid();
+
+ // Set cells
+ Common::Array<CellIdent> cells;
+ cells.push_back(CellIdent(99, 99, 1));
+ _vm->loadCells(cells);
+
+ showAllItems();
+
+ if (!_invRefreshFlag) {
+ chooseItem();
+ if (_vm->_useItem != -1) {
+ int savedScale = _vm->_scale;
+ _vm->_scale = 153;
+ _vm->_screen->setScaleTable(_vm->_scale);
+ _vm->_buffer1.clearBuffer();
+
+ SpriteResource *spr = _vm->_objectsTable[99];
+ SpriteFrame *frame = spr->getFrame(_vm->_useItem);
+
+ int w = screen._scaleTable1[46];
+ int h = screen._scaleTable1[35];
+ _vm->_buffer1.sPlotF(frame, Common::Rect(0, 0, w, h));
+ events.setCursorData(&_vm->_buffer1, Common::Rect(0, 0, w, h));
+
+ _vm->_scale = savedScale;
+ screen.setScaleTable(_vm->_scale);
+ }
+ }
+
+ freeInvCells();
+ screen.setPanel(0);
+ events.debounceLeft();
+
+ restoreFields();
+ screen.restorePalette();
+ // The original was testing the vesa mode too.
+ // We removed this check as we don't use pre-rendering
+ if (!_invRefreshFlag) {
+ screen.clearScreen();
+ screen.setPalette();
+ }
+
+ if (!room._tile && !_invRefreshFlag) {
+ restoreScreens();
+ } else {
+ screen.setBufferScan();
+ room.buildScreen();
+
+ // The original was doing a check on the vesa mode at this point.
+ // We don't need it as we don't do inventory pre-rendering
+ screen.fadeOut();
+ _vm->copyBF2Vid();
+ }
+
+ events._cursorExitFlag = false;
+ screen._screenChangeFlag = false;
+ _invModeFlag = false;
+ events.debounceLeft();
+ _vm->_timers.restoreTimers();
+ _vm->_startup = 1;
+
+ int result = 0;
+ if (!_invRefreshFlag) {
+ if (_vm->_useItem == -1) {
+ result = 2;
+ events.forceSetCursor(CURSOR_CROSSHAIRS);
+ } else
+ events.forceSetCursor(CURSOR_INVENTORY);
+ }
+
+ _invRefreshFlag = false;
+ _invChangeFlag = false;
+ return result;
+}
+
+void InventoryManager::savedFields() {
+ Screen &screen = *_vm->_screen;
+ Room &room = *_vm->_room;
+
+ _fields._vWindowHeight = screen._vWindowHeight;
+ _fields._vWindowLinesTall = screen._vWindowLinesTall;
+ _fields._vWindowWidth = screen._vWindowWidth;
+ _fields._vWindowBytesWide = screen._vWindowBytesWide;
+ _fields._playFieldHeight = room._playFieldHeight;
+ _fields._playFieldWidth = room._playFieldWidth;
+ _fields._windowXAdd = screen._windowXAdd;
+ _fields._windowYAdd = screen._windowYAdd;
+ _fields._screenYOff = screen._screenYOff;
+ _fields._scrollX = _vm->_scrollX;
+ _fields._scrollY = _vm->_scrollY;
+ _fields._clipWidth = screen._clipWidth;
+ _fields._clipHeight = screen._clipHeight;
+ _fields._bufferStart = screen._bufferStart;
+ _fields._scrollCol = _vm->_scrollCol;
+ _fields._scrollRow = _vm->_scrollRow;
+}
+
+void InventoryManager::restoreFields() {
+ Screen &screen = *_vm->_screen;
+ Room &room = *_vm->_room;
+
+ screen._vWindowHeight = _fields._vWindowHeight;
+ screen._vWindowLinesTall = _fields._vWindowLinesTall;
+ screen._vWindowWidth = _fields._vWindowWidth;
+ screen._vWindowBytesWide = _fields._vWindowBytesWide;
+ room._playFieldHeight = _fields._playFieldHeight;
+ room._playFieldWidth = _fields._playFieldWidth;
+ screen._windowXAdd = _fields._windowXAdd;
+ screen._windowYAdd = _fields._windowYAdd;
+ screen._screenYOff = _fields._screenYOff;
+ _vm->_scrollX = _fields._scrollX;
+ _vm->_scrollY = _fields._scrollY;
+ screen._clipWidth = _fields._clipWidth;
+ screen._clipHeight = _fields._clipHeight;
+ screen._bufferStart = _fields._bufferStart;
+ _vm->_scrollCol = _fields._scrollCol;
+ _vm->_scrollRow = _fields._scrollRow;
+}
+
+void InventoryManager::initFields() {
+ Screen &screen = *_vm->_screen;
+ Room &room = *_vm->_room;
+
+ screen._vWindowHeight = screen.h;
+ room._playFieldHeight = screen.h;
+ screen._vWindowLinesTall = screen.h;
+ screen._clipHeight = screen.h;
+ room._playFieldWidth = screen.w;
+ screen._vWindowWidth = screen.w;
+ screen._vWindowBytesWide = screen.w;
+ screen._clipWidth = screen.w;
+
+ screen._windowXAdd = 0;
+ screen._windowYAdd = 0;
+ screen._screenYOff = 0;
+ screen._bufferStart.x = 0;
+ screen._bufferStart.y = 0;
+ _vm->_scrollX = _vm->_scrollY = 0;
+
+ _vm->_buffer1.clearBuffer();
+ _vm->_buffer2.clearBuffer();
+ // The original was doing at this point a check on vesa mode
+ // We don't need it as we don't do inventory pre-rendering
+ if (!_invRefreshFlag)
+ screen.clearBuffer();
+
+ screen.savePalette();
+}
+
+void InventoryManager::getList() {
+ _items.clear();
+ _tempLOff.clear();
+
+ for (uint i = 0; i < _inv.size(); ++i) {
+ if (_inv[i]._value == ITEM_IN_INVENTORY) {
+ _items.push_back(i);
+ _tempLOff.push_back(_inv[i]._name);
+ }
+ }
+}
+
+void InventoryManager::showAllItems() {
+ _iconDisplayFlag = true;
+
+ for (uint i = 0; i < _items.size(); ++i)
+ putInvIcon(i, _items[i]);
+}
+
+void InventoryManager::putInvIcon(int itemIndex, int itemId) {
+ SpriteResource *spr = _vm->_objectsTable[99];
+ assert(spr);
+ Common::Point pt((itemIndex % 6) * 46 + 23, (itemIndex / 6) * 35 + 15);
+ _vm->_buffer2.plotImage(spr, itemId, pt);
+
+ if (_iconDisplayFlag) {
+ _vm->_screen->copyBlock(&_vm->_buffer2, Common::Rect(pt.x, pt.y, pt.x + 46, pt.y + 35));
+ }
+}
+
+void InventoryManager::chooseItem() {
+ EventsManager &events = *_vm->_events;
+ _vm->_useItem = -1;
+
+ while (!_vm->shouldQuit()) {
+ // Check for events
+ events.pollEventsAndWait();
+
+ int selIndex;
+ // Poll events and wait for a click on a known area
+ if (!events._leftButton || ((selIndex = coordIndexOf()) == -1))
+ continue;
+
+ if (selIndex > 23) {
+ if (selIndex == 25)
+ _vm->_useItem = -1;
+ break;
+ } else if (selIndex < (int)_items.size() && _items[selIndex] != -1) {
+ _boxNum = selIndex;
+ _vm->copyBF2Vid();
+ combineItems();
+ _vm->copyBF2Vid();
+ outlineIcon(_boxNum);
+ _vm->_useItem = _items[_boxNum];
+ }
+ }
+}
+
+void InventoryManager::freeInvCells() {
+ delete _vm->_objectsTable[99];
+ _vm->_objectsTable[99] = nullptr;
+}
+
+int InventoryManager::coordIndexOf() {
+ const Common::Point pt = _vm->_events->_mousePos;
+
+ for (int i = 0; i < (int)_invCoords.size(); ++i) {
+ if (_invCoords[i].contains(pt))
+ return i;
+ }
+
+ return -1;
+}
+
+void InventoryManager::saveScreens() {
+ _vm->_buffer1.copyTo(&_savedBuffer1);
+ _vm->_screen->copyTo(&_savedScreen);
+ _vm->_newRects.push_back(Common::Rect(0, 0, _savedScreen.w, _savedScreen.h));
+
+}
+
+void InventoryManager::restoreScreens() {
+ _vm->_buffer1.w = _vm->_buffer1.pitch;
+ _savedBuffer1.copyTo(&_vm->_buffer1);
+ _savedScreen.copyTo(_vm->_screen);
+
+ _savedBuffer1.free();
+ _savedScreen.free();
+}
+
+void InventoryManager::outlineIcon(int itemIndex) {
+ Screen &screen = *_vm->_screen;
+ screen.frameRect(_invCoords[itemIndex], 7);
+
+ Common::String s = _tempLOff[itemIndex];
+ Font &font = _vm->_fonts._font2;
+ int strWidth = font.stringWidth(s);
+
+ font._fontColors[0] = 0;
+ font._fontColors[1] = 10;
+ font._fontColors[2] = 11;
+ font._fontColors[3] = 12;
+ font.drawString(&screen, s, Common::Point((screen.w - strWidth) / 2, 184));
+}
+
+void InventoryManager::combineItems() {
+ Screen &screen = *_vm->_screen;
+ EventsManager &events = *_vm->_events;
+ screen._leftSkip = screen._rightSkip = 0;
+ screen._topSkip = screen._bottomSkip = 0;
+ screen._screenYOff = 0;
+
+ Common::Point tempMouse = events._mousePos;
+ Common::Point lastMouse = events._mousePos;
+
+ Common::Rect &inv = _invCoords[_boxNum];
+ Common::Rect r(inv.left, inv.top, inv.left + 46, inv.top + 35);
+ Common::Point tempBox(inv.left, inv.top);
+ Common::Point lastBox(inv.left, inv.top);
+
+ _vm->_buffer2.copyBlock(&_vm->_buffer1, r);
+ SpriteResource *sprites = _vm->_objectsTable[99];
+ int invItem = _items[_boxNum];
+ events.pollEvents();
+
+ // Item drag handling loop if left button is held down
+ while (!_vm->shouldQuit() && events._leftButton) {
+ // Poll for events
+ events.pollEventsAndWait();
+
+ // Check positioning
+ if (lastMouse == events._mousePos)
+ continue;
+
+ lastMouse = events._mousePos;
+ Common::Rect lastRect(lastBox.x, lastBox.y, lastBox.x + 46, lastBox.y + 35);
+ screen.copyBlock(&_vm->_buffer2, lastRect);
+
+ Common::Point newPt;
+ newPt.x = MAX(events._mousePos.x - tempMouse.x + tempBox.x, 0);
+ newPt.y = MAX(events._mousePos.y - tempMouse.y + tempBox.y, 0);
+
+ screen.plotImage(sprites, invItem, newPt);
+ lastBox = newPt;
+ }
+
+ int destBox = events.checkMouseBox1(_invCoords);
+ if (destBox >= 0 && destBox != _boxNum && destBox < (int)_items.size()
+ && _items[destBox] != -1) {
+ int itemA = invItem;
+ int itemB = _items[destBox];
+
+ // Check whether the items can be combined
+ int combinedItem = _inv[itemA].checkItem(itemB);
+ if (combinedItem != -1) {
+ _inv[combinedItem]._value = 1;
+ _inv[itemA]._value = 2;
+ _inv[itemB]._value = 2;
+ _items[_boxNum] = -1;
+ _items[destBox] = combinedItem;
+ _tempLOff[destBox] = _inv[combinedItem]._name;
+ events.hideCursor();
+
+ // Shrink down the first item on top of the second item
+ zoomIcon(itemA, itemB, destBox, true);
+
+ // Shrink down the second item
+ Common::Rect destRect(_invCoords[destBox].left, _invCoords[destBox].top,
+ _invCoords[destBox].left + 46, _invCoords[destBox].top + 35);
+ _vm->_buffer2.copyBlock(&_vm->_buffer1, destRect);
+ screen._screenYOff = 0;
+ zoomIcon(itemB, -1, destBox, true);
+
+ // Exand up the new combined item from nothing to full size
+ zoomIcon(combinedItem, -1, destBox, false);
+
+ _boxNum = destBox;
+ events.showCursor();
+ return;
+ }
+ }
+
+ _iconDisplayFlag = true;
+ putInvIcon(_boxNum, invItem);
+}
+
+void InventoryManager::zoomIcon(int zoomItem, int backItem, int zoomBox, bool shrink) {
+ Screen &screen = *_vm->_screen;
+ screen._screenYOff = 0;
+ SpriteResource *sprites = _vm->_objectsTable[99];
+
+ int oldScale = _vm->_scale;
+ int zoomScale = shrink ? 255 : 1;
+ int zoomInc = shrink ? -1 : 1;
+ Common::Rect boxRect(_invCoords[zoomBox].left, _invCoords[zoomBox].top,
+ _invCoords[zoomBox].left + 46, _invCoords[zoomBox].top + 35);
+
+ while (!_vm->shouldQuit() && zoomScale != 0 && zoomScale != 256) {
+ _vm->_events->pollEventsAndWait();
+
+ _vm->_buffer2.copyBlock(&_vm->_buffer1, boxRect);
+ if (backItem != -1) {
+ _iconDisplayFlag = false;
+ putInvIcon(zoomBox, backItem);
+ }
+
+ _vm->_scale = zoomScale;
+ screen.setScaleTable(zoomScale);
+
+ int xv = screen._scaleTable1[boxRect.width() + 1];
+ if (xv) {
+ int yv = screen._scaleTable1[boxRect.height() + 1];
+ if (yv) {
+ // The zoomed size is positive in both directions, so show zoomed item
+ Common::Rect scaledBox(xv, yv);
+ scaledBox.moveTo(boxRect.left + (boxRect.width() - xv + 1) / 2,
+ boxRect.top + (boxRect.height() - yv + 1) / 2);
+
+ _vm->_buffer2.sPlotF(sprites->getFrame(zoomItem), scaledBox);
+ }
+ }
+
+ screen.copyBlock(&_vm->_buffer2, boxRect);
+
+ zoomScale += zoomInc;
+ }
+
+ if (!shrink) {
+ // Handle the final full-size version
+ _vm->_buffer2.copyBlock(&_vm->_buffer1, boxRect);
+ _vm->_buffer2.plotImage(sprites, zoomItem,
+ Common::Point(boxRect.left, boxRect.top));
+ screen.copyBlock(&_vm->_buffer2, boxRect);
+ }
+
+ _vm->_scale = oldScale;
+ screen.setScaleTable(oldScale);
+}
+
+void InventoryManager::synchronize(Common::Serializer &s) {
+ int count = _inv.size();
+ s.syncAsUint16LE(count);
+
+ if (!s.isSaving())
+ _inv.resize(count);
+
+ for (int i = 0; i < count; ++i)
+ s.syncAsUint16LE(_inv[i]._value);
+}
+
+} // End of namespace Access
diff --git a/engines/access/inventory.h b/engines/access/inventory.h
new file mode 100644
index 0000000000..6a9390eda9
--- /dev/null
+++ b/engines/access/inventory.h
@@ -0,0 +1,140 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ACCESS_INVENTORY_H
+#define ACCESS_INVENTORY_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/rect.h"
+#include "common/str-array.h"
+#include "access/data.h"
+#include "access/asurface.h"
+
+namespace Access {
+
+enum ItemState {
+ ITEM_NOT_FOUND = 0, ITEM_IN_INVENTORY = 1, ITEM_USED = 2
+};
+
+class InventoryEntry {
+public:
+ Common::String _name;
+ int _value;
+
+ int _otherItem1;
+ int _newItem1;
+ int _otherItem2;
+ int _newItem2;
+
+ void load(const Common::String &name, const int *data);
+
+ int checkItem(int itemId);
+};
+
+class InventoryManager : public Manager {
+ struct SavedFields {
+ int _vWindowHeight;
+ int _vWindowLinesTall;
+ int _vWindowWidth;
+ int _vWindowBytesWide;
+ int _playFieldHeight;
+ int _playFieldWidth;
+ int _windowXAdd;
+ int _windowYAdd;
+ int _screenYOff;
+ int _scrollX;
+ int _scrollY;
+ int _clipWidth;
+ int _clipHeight;
+ Common::Point _bufferStart;
+ int _scrollCol;
+ int _scrollRow;
+ };
+private:
+ Common::Array<int> _items;
+ Common::Array<Common::Rect> _invCoords;
+ ASurface _savedBuffer1;
+ ASurface _savedScreen;
+ SavedFields _fields;
+ bool _iconDisplayFlag;
+ Common::Array<int> _tempLPtr;
+ Common::StringArray _tempLOff;
+ int _boxNum;
+
+ void savedFields();
+
+ void restoreFields();
+
+ void initFields();
+
+ void getList();
+
+ void showAllItems();
+
+ void putInvIcon(int itemIndex, int itemId);
+
+ void chooseItem();
+
+ void freeInvCells();
+
+ int coordIndexOf();
+
+ void saveScreens();
+
+ void restoreScreens();
+
+ void outlineIcon(int itemIndex);
+
+ void combineItems();
+
+ void zoomIcon(int zoomItem, int backItem, int zoomBox, bool shrink);
+public:
+ Common::Array<InventoryEntry> _inv;
+ int _startInvItem;
+ int _startInvBox;
+ bool _invChangeFlag;
+ bool _invRefreshFlag;
+ bool _invModeFlag;
+ int _startAboutItem;
+ int _startTravelItem;
+public:
+ InventoryManager(AccessEngine *vm);
+
+ int &operator[](int idx);
+
+ int useItem();
+ void setUseItem(int itemId);
+
+ void refreshInventory();
+
+ int newDisplayInv();
+
+ /**
+ * Synchronize savegame data
+ */
+ void synchronize(Common::Serializer &s);
+};
+
+} // End of namespace Access
+
+#endif /* ACCESS_INVENTORY_H */
diff --git a/engines/access/martian/martian_game.cpp b/engines/access/martian/martian_game.cpp
new file mode 100644
index 0000000000..4e4a5135a6
--- /dev/null
+++ b/engines/access/martian/martian_game.cpp
@@ -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.
+ *
+ */
+
+#include "access/resources.h"
+#include "access/martian/martian_game.h"
+#include "access/martian/martian_resources.h"
+#include "access/martian/martian_room.h"
+#include "access/martian/martian_scripts.h"
+#include "access/amazon/amazon_resources.h"
+
+namespace Access {
+
+namespace Martian {
+
+MartianEngine::MartianEngine(OSystem *syst, const AccessGameDescription *gameDesc) : AccessEngine(syst, gameDesc) {
+}
+
+MartianEngine::~MartianEngine() {
+}
+
+void MartianEngine::playGame() {
+ // Do introduction
+ doIntroduction();
+ if (shouldQuit())
+ return;
+
+ // Setup the game
+ setupGame();
+
+ _screen->clearScreen();
+ _screen->setPanel(0);
+ _screen->forceFadeOut();
+
+ _events->showCursor();
+
+ // Setup and execute the room
+ _room = new MartianRoom(this);
+ _scripts = new MartianScripts(this);
+ _room->doRoom();
+}
+
+void MartianEngine::doIntroduction() {
+ _screen->setInitialPalettte();
+ _events->setCursor(CURSOR_ARROW);
+ _events->showCursor();
+ _screen->setPanel(0);
+
+ // TODO: Worry about implementing full intro sequence later
+ return;
+
+ doTitle();
+ if (shouldQuit())
+ return;
+
+ if (!_skipStart) {
+ _screen->setPanel(3);
+ doOpening();
+ if (shouldQuit())
+ return;
+
+ if (!_skipStart) {
+ //doTent();
+ if (shouldQuit())
+ return;
+ }
+ }
+
+ doTitle();
+}
+
+void MartianEngine::doTitle() {
+ /*
+ _screen->setDisplayScan();
+ _destIn = &_buffer2;
+
+ _screen->forceFadeOut();
+ _events->hideCursor();
+
+ _sound->queueSound(0, 98, 30);
+
+ _files->_setPaletteFlag = false;
+ _files->loadScreen(0, 3);
+
+ _buffer2.blitFrom(*_screen);
+ _buffer1.blitFrom(*_screen);
+ _screen->forceFadeIn();
+ _sound->playSound(1);
+
+ Resource *spriteData = _files->loadFile(0, 2);
+ _objectsTable[0] = new SpriteResource(this, spriteData);
+ delete spriteData;
+
+ _sound->playSound(1);
+
+ _files->_setPaletteFlag = false;
+ _files->loadScreen(0, 4);
+ _sound->playSound(1);
+
+ _buffer2.blitFrom(*_screen);
+ _buffer1.blitFrom(*_screen);
+ _sound->playSound(1);
+
+ const int COUNTDOWN[6] = { 2, 0x80, 1, 0x7d, 0, 0x87 };
+ for (_pCount = 0; _pCount < 3; ++_pCount) {
+ _buffer2.blitFrom(_buffer1);
+ int id = READ_LE_UINT16(COUNTDOWN + _pCount * 4);
+ int xp = READ_LE_UINT16(COUNTDOWN + _pCount * 4 + 2);
+ _screen->plotImage(_objectsTable[0], id, Common::Point(xp, 71));
+ }
+ // TODO: More to do
+
+ delete _objectsTable[0];
+ */
+}
+
+void MartianEngine::doOpening() {
+ warning("TODO doOpening");
+}
+
+void MartianEngine::setupGame() {
+
+ // Setup timers
+ const int TIMER_DEFAULTS[] = { 4, 10, 8, 1, 1, 1, 1, 2 };
+ for (int i = 0; i < 32; ++i) {
+ TimerEntry te;
+ te._initTm = te._timer = (i < 8) ? TIMER_DEFAULTS[i] : 1;
+ te._flag = 1;
+
+ _timers.push_back(te);
+ }
+
+ // Miscellaneous
+ // TODO: Replace with Martian fonts when located
+ _fonts._font1.load(Amazon::FONT6x6_INDEX, Amazon::FONT6x6_DATA);
+ _fonts._font2.load(Amazon::FONT2_INDEX, Amazon::FONT2_DATA);
+
+ // Set player room and position
+ _player->_roomNumber = 7;
+ _player->_playerX = _player->_rawPlayer.x = TRAVEL_POS[_player->_roomNumber][0];
+ _player->_playerY = _player->_rawPlayer.y = TRAVEL_POS[_player->_roomNumber][1];
+}
+
+void MartianEngine::drawHelp() {
+ error("TODO: drawHelp");
+}
+
+} // End of namespace Martian
+
+} // End of namespace Access
diff --git a/engines/access/martian/martian_game.h b/engines/access/martian/martian_game.h
new file mode 100644
index 0000000000..a83b67a288
--- /dev/null
+++ b/engines/access/martian/martian_game.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 ACCESS_MARTIAN_GAME_H
+#define ACCESS_MARTIAN_GAME_H
+
+#include "access/access.h"
+
+namespace Access {
+
+namespace Martian {
+
+class MartianEngine : public AccessEngine {
+private:
+ bool _skipStart;
+
+ /**
+ * Do the game introduction
+ */
+ void doIntroduction();
+
+ /**
+ * Do title sequence
+ */
+ void doTitle();
+
+ /**
+ * Do opening sequence
+ */
+ void doOpening();
+
+ /**
+ * Setup variables for the game
+ */
+ void setupGame();
+
+protected:
+ /**
+ * Play the game
+ */
+ virtual void playGame();
+
+ virtual void dead(int deathId) {}
+public:
+ MartianEngine(OSystem *syst, const AccessGameDescription *gameDesc);
+
+ virtual ~MartianEngine();
+
+ void drawHelp();
+ virtual void establish(int esatabIndex, int sub) {};
+};
+
+} // End of namespace Martian
+
+} // End of namespace Access
+
+#endif /* ACCESS_MARTIAN_GAME_H */
diff --git a/engines/access/martian/martian_resources.cpp b/engines/access/martian/martian_resources.cpp
new file mode 100644
index 0000000000..d2b5dfd5d0
--- /dev/null
+++ b/engines/access/martian/martian_resources.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.
+ *
+ */
+
+#include "access/martian/martian_resources.h"
+#include "access/access.h"
+
+namespace Access {
+
+namespace Martian {
+
+const char *const FILENAMES[] = {
+ "R00.AP", "R01.AP", "R02.AP", "R03.AP", "R04.AP", "R05.AP", "R06.AP", "R07.AP",
+ "R08.AP", "R09.AP", "R10.AP", "R11.AP", "R12.AP", "R13.AP", "R14.AP", "R15.AP",
+ "R16.AP", "R17.AP", "R18.AP", "R19.AP", "R20.AP", "R21.AP", "R22.AP", "R23.AP",
+ "R24.AP", "R25.AP", "R26.AP", "R27.AP", "R28.AP", "R29.AP", "R30.AP", "R31.AP",
+ "R32.AP", "R33.AP", "R34.AP", "R35.AP", "R36.AP", "R37.AP", "R38.AP", "R39.AP",
+ "R40.AP","TITLE.AP","R42.AP","S01.AP", "R44.AP", "R45.AP","SOUND.AP","MUSIC.AP",
+ "DEAD.AP","EST.AP", "W02.AP", "C02.AP", "C05.AP", "C04.AP", "C10.AP", "C03.AP",
+ "C07.AP", "LOVE.AP","CAFE.AP","C08.AP", "C18.AP", "C19.AP", "C21.AP", "C23.AP",
+ "C12.AP", "C16.AP","CAFE1.AP","C05A.AP","C06.AP","C11.AP", "C13.AP", "C20.AP",
+ "C16A.AP","C09.AP", "R45.AP", "R46.AP", "R47.AP", "R48.AP", "R49.AP"
+};
+
+const byte MOUSE0[] = {
+ 0, 0, 0, 0, 0, 2, 0xF7, 5, 0, 3, 0xF7, 0xF7, 5, 0, 3,
+ 0xF7, 0xF7, 5, 0, 4, 0xF7, 0xF7, 0xF7, 5, 0, 4, 0xF7,
+ 0xF7, 0xF7, 5, 0, 5, 0xF7, 0xF7, 0xF7, 0xF7, 5, 0, 5,
+ 0xF7, 0xF7, 0xF7, 0xF7, 5, 0, 6, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0xF7, 5, 0, 6, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 5, 0, 7,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 5, 0, 6, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0xF7, 5, 0, 5, 0xF7, 0xF7, 0xF7, 0xF7, 5,
+ 2, 3, 0xF7, 0xF7, 5, 3, 3, 0xF7, 0xF7, 5, 3, 3, 0xF7,
+ 0xF7, 5, 4, 2, 0xF7, 5
+};
+const byte MOUSE1[] = {
+ 7, 0, 7, 0, 6, 1, 0xF7, 4, 5, 0xFF, 0xFF, 0, 0xFF, 0xFF,
+ 3, 7, 0xFF, 0, 0, 0, 0, 0, 0xFF, 2, 9, 0xFF, 0, 0, 0,
+ 0xF7, 0, 0, 0, 0xFF, 1, 11, 0xFF, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0xFF, 1, 11, 0xFF, 0, 0, 0, 0, 0xF7, 0, 0,
+ 0, 0, 0xFF, 0, 13, 0xF7, 0, 0, 0xF7, 0, 0xF7, 0, 0xF7,
+ 0, 0xF7, 0, 0, 0xF7, 1, 11, 0xFF, 0, 0, 0, 0, 0xF7,
+ 0, 0, 0, 0, 0xFF, 1, 11, 0xFF, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0xFF, 2, 9, 0xFF, 0, 0, 0, 0xF7, 0, 0, 0, 0xFF,
+ 3, 7, 0xFF, 0, 0, 0, 0, 0, 0xFF, 4, 5, 0xFF, 0xFF, 0,
+ 0xFF, 0xFF, 6, 1, 0xF7, 0, 0, 0, 0, 0, 0
+};
+const byte MOUSE2[] = {
+ 8, 0, 8, 0, 0, 0, 0, 0, 7, 2, 4, 5, 7, 2, 4, 5, 7, 2,
+ 4, 5, 7, 2, 4, 5, 7, 2, 4, 5, 2, 12, 4, 4, 4, 4, 4,
+ 0, 4, 4, 4, 4, 4, 5, 7, 2, 4, 5, 7, 2, 4, 5, 7, 2, 4,
+ 5, 7, 2, 4, 5, 7, 2, 4, 5, 0, 0, 0, 0, 0, 0
+};
+const byte MOUSE3[] = {
+ 0, 0, 0, 0, 0, 11, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 0, 12, 6, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 5, 0, 12,
+ 6, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5, 5, 0, 12, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 5, 0, 12, 6, 6, 6, 6, 6, 5,
+ 6, 6, 6, 6, 6, 5, 0, 12, 6, 6, 6, 6, 5, 0, 0, 6, 6,
+ 6, 6, 5, 0, 12, 6, 6, 6, 6, 6, 0, 6, 6, 6, 6, 6, 5,
+ 0, 12, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 0, 12,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 0, 12, 6, 6, 6,
+ 6, 6, 5, 6, 6, 6, 6, 6, 5, 0, 12, 6, 6, 6, 6, 6, 5,
+ 6, 6, 6, 6, 6, 5, 0, 12, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 5, 1, 11, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0,
+ 0, 0, 0, 0, 0
+};
+const byte *const CURSORS[4] = { MOUSE0, MOUSE1, MOUSE2, MOUSE3 };
+
+const int TRAVEL_POS[][2] = {
+ { -1, 0 },
+ { 228, 117 },
+ { 28, 98 },
+ { 161, 140 },
+ { 160, 116 },
+ { 34, 119 },
+ { 166, 105 },
+ { 260, 126 },
+ { 37, 107 },
+ { 78, 139 },
+ { 0, 0 },
+ { 13, 112 },
+ { 0, 0 },
+ { 16, 122 },
+ { 33, 126 },
+ { 10, 160 },
+ { 150, 102 },
+ { 134, 160 },
+ { 160, 76 },
+ { 0, 0 },
+ { 0, 0 },
+ { 36, 116 },
+ { 214, 113 },
+ { 30, 127 },
+ { 143, 131 },
+ { 163, 103 },
+ { 254, 106 },
+ { 28, 161 },
+ { 11, 164 },
+ { 276, 134 },
+ { 93, 118 },
+ { 22, 150 },
+ { 282, 156 },
+ { 149, 92 },
+ { 0, 0 },
+ { 43, 410 },
+ { 0, 0 },
+ { 10, 136 },
+ { 41, 100 },
+ { 157, 97 },
+ { -1, 5 },
+ { -1, 4 },
+ { -1, 10 },
+ { -1, 7 },
+ { -1, 3 },
+ { -1, 8 },
+ { -1, 6 },
+ { -1, 20 },
+ { -1, 18 },
+ { -1, 19 },
+ { -1, 21 }
+};
+
+const char *const INVENTORY_NAMES[] = {
+ "CAMERA", "LENS", "PHOTOS", "MAIL", "GUN", "CASH", "COMLINK", "AMMO",
+ "LOCKPICK KIT", "EARRING", "RECIEPTS", "PAPER", "LADDER", "BOOTS",
+ "DOCUMENTS", "KNIFE", "DAGGER", "KEYS", "ROCK", "LOG", "SHOVEL",
+ "STONE", "REMOTE CONTROL", "FOOD AND WATER", "DOOR CARD KEY",
+ "FLASHLIGHT", "INTERLOCK KEY", "TOOLS", "REBREATHER", "JET PACK",
+ "ROD", "HCL2", "SAFE CARD KEY", "TUNING FORK", "STONE", "ROSE",
+ "KEY", "NOTE", "ALLEN WRENCH", "HOVER BOARD", "BLUE PRINTS",
+ "LETTER", "MEMORANDUM", "MARKERS", "FILM", "ANDRETTI FILM",
+ "GLASSES", "AMULET", "FACIAL KIT", "CAT FOOD", "MONKEY WRENCH",
+ "BIG DICK CARD", "BRA", "BOLT"
+};
+
+const byte ROOM_TABLE1[] = {
+ 0x00, 0x2f, 0x00, 0x0d, 0x00, 0x30, 0x22, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x01, 0x01, 0x00, 0x03, 0x00, 0xff, 0x01, 0x00,
+ 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0xc0, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x2e, 0x00, 0x05, 0x00, 0x01, 0x00, 0xff, 0xff,
+};
+const byte ROOM_TABLE2[] = {
+ 0x00, 0x2f, 0x00, 0x0d, 0x00, 0x32, 0x28, 0x25, 0x02, 0x00,
+ 0x00, 0x00, 0x02, 0x02, 0x00, 0x03, 0x00, 0xff, 0x02, 0x00,
+ 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0xc8, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x2e, 0x00, 0x06, 0x00, 0x01, 0x00, 0xff, 0xff,
+};
+const byte ROOM_TABLE3[] = {
+ 0x00, 0x2f, 0x00, 0x0f, 0x00, 0x1e, 0x19, 0x24, 0x03, 0x00,
+ 0x00, 0x00, 0x03, 0x03, 0x00, 0x03, 0x00, 0xff, 0x03, 0x00,
+ 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x78, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 0x03, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x05, 0x00,
+ 0x01, 0x00, 0x03, 0x00, 0x06, 0x00, 0x01, 0x00, 0x2e, 0x00,
+ 0x01, 0x00, 0x01, 0x00, 0xff, 0xff,
+};
+const byte ROOM_TABLE4[] = {
+ 0x00, 0x2f, 0x00, 0x06, 0x00, 0x36, 0x27, 0x32, 0x04, 0x00,
+ 0x00, 0x00, 0x04, 0x04, 0x00, 0x03, 0x00, 0xff, 0x04, 0x00,
+ 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0xc8, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x2e, 0x00, 0x07, 0x00, 0x01, 0x00, 0x2e, 0x00, 0x05, 0x00,
+ 0x01, 0x00, 0xff, 0xff,
+};
+const byte ROOM_TABLE5[] = {
+ 0x00, 0x2f, 0x00, 0x00, 0x00, 0x28, 0x19, 0x36, 0x05, 0x00,
+ 0x00, 0x00, 0x05, 0x05, 0x00, 0x03, 0x00, 0xff, 0x05, 0x00,
+ 0x02, 0x00, 0x05, 0x00, 0x01, 0x00, 0xa0, 0x20, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x2e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x2e, 0x00, 0x03, 0x00,
+ 0x01, 0x00, 0xff, 0xff,
+};
+const byte ROOM_TABLE6[] = {
+ 0x00, 0x2f, 0x00, 0x07, 0x00, 0x40, 0x36, 0x36, 0x06, 0x00,
+ 0x00, 0x00, 0x06, 0x06, 0x00, 0x03, 0x00, 0xff, 0x06, 0x00,
+ 0x02, 0x00, 0x06, 0x00, 0x01, 0x00, 0xfe, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x2e, 0x00, 0x13, 0x00, 0x01, 0x00, 0x2e, 0x00, 0x08, 0x00,
+ 0x01, 0x00, 0x2e, 0x00, 0x14, 0x00, 0x01, 0x00, 0x2e, 0x00,
+ 0x07, 0x00, 0x01, 0x00, 0xff, 0xff,
+};
+const byte ROOM_TABLE7[] = {
+ 0x00, 0x2f, 0x00, 0x0e, 0x00, 0x40, 0x32, 0x3b, 0x07, 0x00,
+ 0x00, 0x00, 0x07, 0x07, 0x00, 0x03, 0x00, 0xff, 0x07, 0x00,
+ 0x02, 0x00, 0x07, 0x00, 0x01, 0x00, 0xfe, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x2e, 0x00, 0x14, 0x00, 0x01, 0x00, 0x2e, 0x00, 0x07, 0x00,
+ 0x01, 0x00, 0xff, 0xff,
+};
+const byte ROOM_TABLE8[] = {
+ 0x00, 0x2f, 0x00, 0x0a, 0x00, 0x30, 0x22, 0x46, 0x08, 0x00,
+ 0x00, 0x00, 0x08, 0x08, 0x00, 0x03, 0x00, 0xff, 0x08, 0x00,
+ 0x02, 0x00, 0x08, 0x00, 0x01, 0x00, 0xc0, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0xff, 0xff,
+};
+const byte ROOM_TABLE9[] = {
+ 0x00, 0x2f, 0x00, 0x07, 0x00, 0x32, 0x0c, 0x29, 0x09, 0x00,
+ 0x00, 0x00, 0x09, 0x09, 0x00, 0x03, 0x00, 0xff, 0x09, 0x00,
+ 0x02, 0x00, 0x09, 0x00, 0x01, 0x00, 0xc8, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0xff, 0xff,
+};
+const byte ROOM_TABLE11[] = {
+ 0x00, 0x2f, 0x00, 0x00, 0x00, 0x40, 0x3a, 0x22, 0x0b, 0x00,
+ 0x00, 0x00, 0x0b, 0x0b, 0x00, 0x03, 0x00, 0xff, 0x0b, 0x00,
+ 0x02, 0x00, 0x0b, 0x00, 0x01, 0x00, 0xfe, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0xff, 0xff,
+};
+const byte ROOM_TABLE13[] = {
+ 0x00, 0x2f, 0x00, 0x0c, 0x00, 0x40, 0x36, 0x2c, 0x0d, 0x00,
+ 0x00, 0x00, 0x0d, 0x0d, 0x00, 0x03, 0x00, 0xff, 0x0d, 0x00,
+ 0x02, 0x00, 0x0d, 0x00, 0x01, 0x00, 0xe6, 0x40, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x2e, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x2e, 0x00, 0x07, 0x00,
+ 0x01, 0x00, 0x2e, 0x00, 0x0b, 0x00, 0x01, 0x00, 0x2e, 0x00,
+ 0x15, 0x00, 0x01, 0x00, 0xff, 0xff,
+};
+const byte ROOM_TABLE14[] = {
+ 0x00, 0x2f, 0x00, 0x05, 0x00, 0x40, 0x3e, 0x33, 0x0e, 0x00,
+ 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x03, 0x00, 0xff, 0x0e, 0x00,
+ 0x02, 0x00, 0x0e, 0x00, 0x01, 0x00, 0xfe, 0x40, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x2e, 0x00, 0x09, 0x00, 0x01, 0x00, 0x2e, 0x00, 0x07, 0x00,
+ 0x01, 0x00, 0x2e, 0x00, 0x13, 0x00, 0x01, 0x00, 0x2e, 0x00,
+ 0x0a, 0x00, 0x01, 0x00, 0xff, 0xff,
+};
+const byte ROOM_TABLE15[] = {
+ 0x00, 0x2f, 0x00, 0x0c, 0x00, 0x28, 0x0c, 0x5e, 0x0f, 0x00,
+ 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x03, 0x00, 0xff, 0x0f, 0x00,
+ 0x02, 0x00, 0x0f, 0x00, 0x01, 0x00, 0xb4, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x2e, 0x00, 0x11, 0x00, 0x01, 0x00, 0xff, 0xff,
+};
+const byte ROOM_TABLE16[] = {
+ 0x00, 0x2f, 0x00, 0x05, 0x00, 0x28, 0x1e, 0x24, 0x10, 0x00,
+ 0x00, 0x00, 0x10, 0x10, 0x00, 0x03, 0x00, 0xff, 0x10, 0x00,
+ 0x02, 0x00, 0x10, 0x00, 0x01, 0x00, 0xa0, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x2e, 0x00, 0x07, 0x00, 0x01, 0x00, 0xff, 0xff,
+};
+const byte ROOM_TABLE17[] = {
+ 0x00, 0x2f, 0x00, 0x06, 0x00, 0x28, 0x19, 0x2b, 0x11, 0x00,
+ 0x00, 0x00, 0x11, 0x11, 0x00, 0x03, 0x00, 0xff, 0x11, 0x00,
+ 0x02, 0x00, 0x11, 0x00, 0x01, 0x00, 0xa0, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x2e, 0x00, 0x05, 0x00, 0x01, 0x00, 0xff, 0xff,
+};
+const byte ROOM_TABLE18[] = {
+ 0x00, 0x2f, 0x00, 0x00, 0x00, 0x2d, 0x14, 0x3c, 0x12, 0x00,
+ 0x00, 0x00, 0x12, 0x12, 0x00, 0x03, 0x00, 0xff, 0x12, 0x00,
+ 0x02, 0x00, 0x12, 0x00, 0x01, 0x00, 0xb1, 0x40, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x2e, 0x00, 0x05, 0x00, 0x01, 0x00, 0xff, 0xff,
+};
+const byte ROOM_TABLE21[] = {
+ 0x00, 0x2f, 0x00, 0x07, 0x00, 0x3c, 0x2a, 0x29, 0x15, 0x00,
+ 0x00, 0x00, 0x15, 0x15, 0x00, 0x03, 0x00, 0xff, 0x15, 0x00,
+ 0x02, 0x00, 0x15, 0x00, 0x01, 0x00, 0xf0, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x2e, 0x00, 0x12, 0x00, 0x01, 0x00, 0x2e, 0x00, 0x07, 0x00,
+ 0x01, 0x00, 0xff, 0xff,
+};
+const byte ROOM_TABLE22[] = {
+ 0x00, 0x2f, 0x00, 0x0a, 0x00, 0x40, 0x2d, 0x27, 0x16, 0x00,
+ 0x00, 0x00, 0x16, 0x16, 0x00, 0x03, 0x00, 0xff, 0x16, 0x00,
+ 0x02, 0x00, 0x16, 0x00, 0x01, 0x00, 0xfe, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x2e, 0x00, 0x16, 0x00, 0x01, 0x00, 0x2e, 0x00, 0x07, 0x00,
+ 0x01, 0x00, 0xff, 0xff,
+};
+const byte ROOM_TABLE23[] = {
+ 0x00, 0x2f, 0x00, 0x0a, 0x00, 0x40, 0x38, 0x24, 0x17, 0x00,
+ 0x00, 0x00, 0x17, 0x17, 0x00, 0x03, 0x00, 0xff, 0x17, 0x00,
+ 0x02, 0x00, 0x17, 0x00, 0x01, 0x00, 0xfe, 0x40, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x2e, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x2e, 0x00, 0x17, 0x00,
+ 0x01, 0x00, 0xff, 0xff,
+};
+const byte ROOM_TABLE24[] = {
+ 0x00, 0x2f, 0x00, 0x06, 0x00, 0x3e, 0x10, 0x62, 0x18, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x00, 0x03, 0x00, 0xff, 0x18, 0x00,
+ 0x02, 0x00, 0x18, 0x00, 0x01, 0x00, 0xf8, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x2e, 0x00, 0x16, 0x00, 0x01, 0x00, 0xff, 0xff,
+};
+const byte ROOM_TABLE25[] = {
+ 0x00, 0x2f, 0x00, 0x0e, 0x00, 0x3e, 0x37, 0x19, 0x19, 0x00,
+ 0x00, 0x00, 0x19, 0x19, 0x00, 0x03, 0x00, 0xff, 0x19, 0x00,
+ 0x02, 0x00, 0x19, 0x00, 0x01, 0x00, 0xf8, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x2e, 0x00, 0x10, 0x00, 0x01, 0x00, 0x2e, 0x00, 0x07, 0x00,
+ 0x01, 0x00, 0xff, 0xff,
+};
+const byte ROOM_TABLE26[] = {
+ 0x00, 0x2f, 0x00, 0x06, 0x00, 0x34, 0x28, 0x28, 0x1a, 0x00,
+ 0x00, 0x00, 0x1a, 0x1a, 0x00, 0x03, 0x00, 0xff, 0x1a, 0x00,
+ 0x02, 0x00, 0x1a, 0x00, 0x01, 0x00, 0xd0, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x2e, 0x00, 0x07, 0x00, 0x01, 0x00, 0xff, 0xff,
+};
+const byte ROOM_TABLE27[] = {
+ 0x00, 0x2f, 0x00, 0x0f, 0x00, 0x1b, 0x16, 0x18, 0x1b, 0x00,
+ 0x00, 0x00, 0x1b, 0x1b, 0x00, 0x03, 0x00, 0xff, 0x1b, 0x00,
+ 0x02, 0x00, 0x1b, 0x00, 0x01, 0x00, 0x70, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x2e, 0x00, 0x0d, 0x00, 0x01, 0x00, 0x2e, 0x00, 0x07, 0x00,
+ 0x01, 0x00, 0xff, 0xff,
+};
+const byte ROOM_TABLE28[] = {
+ 0x00, 0x2f, 0x00, 0x09, 0x00, 0x25, 0x10, 0x43, 0x1c, 0x00,
+ 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x03, 0x00, 0xff, 0x1c, 0x00,
+ 0x02, 0x00, 0x1c, 0x00, 0x01, 0x00, 0x94, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0xff, 0xff,
+};
+const byte ROOM_TABLE29[] = {
+ 0x00, 0x2f, 0x00, 0x0a, 0x00, 0x20, 0x18, 0x56, 0x1d, 0x00,
+ 0x00, 0x00, 0x1d, 0x1d, 0x00, 0x03, 0x00, 0xff, 0x1d, 0x00,
+ 0x02, 0x00, 0x1d, 0x00, 0x01, 0x00, 0x80, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x2e, 0x00, 0x17, 0x00, 0x01, 0x00, 0x2e, 0x00, 0x10, 0x00,
+ 0x02, 0x00, 0xff, 0xff,
+};
+const byte ROOM_TABLE30[] = {
+ 0x00, 0x2f, 0x00, 0x07, 0x00, 0x3f, 0x1c, 0x27, 0x1e, 0x00,
+ 0x00, 0x00, 0x1e, 0x1e, 0x00, 0x03, 0x00, 0xff, 0x1e, 0x00,
+ 0x02, 0x00, 0x1e, 0x00, 0x01, 0x00, 0xfe, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0x1e, 0x00, 0x04, 0x00, 0xff, 0xff, 0x2e, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x2e, 0x00, 0x07, 0x00, 0x01, 0x00,
+ 0x2e, 0x00, 0x15, 0x00, 0x01, 0x00, 0xff, 0xff,
+};
+const byte ROOM_TABLE31[] = {
+ 0x00, 0x2f, 0x00, 0x0d, 0x00, 0x32, 0x2e, 0x69, 0x1f, 0x00,
+ 0x00, 0x00, 0x1f, 0x1f, 0x00, 0x03, 0x00, 0xff, 0x1f, 0x00,
+ 0x02, 0x00, 0x1f, 0x00, 0x01, 0x00, 0xc8, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0xff, 0xff,
+};
+const byte ROOM_TABLE32[] = {
+ 0x00, 0x2f, 0x00, 0x07, 0x00, 0x40, 0x3b, 0x4b, 0x20, 0x00,
+ 0x00, 0x00, 0x20, 0x20, 0x00, 0x03, 0x00, 0xff, 0x20, 0x00,
+ 0x02, 0x00, 0x20, 0x00, 0x01, 0x00, 0xfe, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x2e, 0x00, 0x05, 0x00, 0x01, 0x00, 0xff, 0xff,
+};
+const byte ROOM_TABLE33[] = {
+ 0x00, 0x2f, 0x00, 0x0b, 0x00, 0x30, 0x10, 0x51, 0x21, 0x00,
+ 0x00, 0x00, 0x21, 0x21, 0x00, 0x03, 0x00, 0xff, 0x21, 0x00,
+ 0x02, 0x00, 0x21, 0x00, 0x01, 0x00, 0xc0, 0x40, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0xff, 0xff,
+};
+const byte ROOM_TABLE35[] = {
+ 0x00, 0x2f, 0x00, 0x0f, 0x00, 0x1e, 0x18, 0x25, 0x23, 0x00,
+ 0x00, 0x00, 0x23, 0x23, 0x00, 0x03, 0x00, 0xff, 0x23, 0x00,
+ 0x02, 0x00, 0x23, 0x00, 0x01, 0x00, 0x78, 0x18, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x2e, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x2e, 0x00, 0x07, 0x00,
+ 0x01, 0x00, 0x2e, 0x00, 0x16, 0x00, 0x01, 0x00, 0x2e, 0x00,
+ 0x0c, 0x00, 0x01, 0x00, 0xff, 0xff,
+};
+const byte ROOM_TABLE37[] = {
+ 0x00, 0x2f, 0x00, 0x0f, 0x00, 0x3f, 0x3a, 0x1a, 0x25, 0x00,
+ 0x00, 0x00, 0x25, 0x25, 0x00, 0x03, 0x00, 0xff, 0x25, 0x00,
+ 0x02, 0x00, 0x25, 0x00, 0x01, 0x00, 0xfe, 0x40, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x2e, 0x00, 0x0d, 0x00, 0x01, 0x00, 0xff, 0xff,
+};
+const byte ROOM_TABLE38[] = {
+ 0x00, 0x2f, 0x00, 0x0d, 0x00, 0x40, 0x32, 0x32, 0x26, 0x00,
+ 0x00, 0x00, 0x26, 0x26, 0x00, 0x03, 0x00, 0xff, 0x26, 0x00,
+ 0x02, 0x00, 0x26, 0x00, 0x01, 0x00, 0xf0, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x2e, 0x00, 0x0b, 0x00, 0x01, 0x00, 0xff, 0xff,
+};
+const byte ROOM_TABLE39[] = {
+ 0x00, 0x2f, 0x00, 0x0a, 0x00, 0x3c, 0x10, 0x4c, 0x27, 0x00,
+ 0x00, 0x00, 0x27, 0x27, 0x00, 0x03, 0x00, 0xff, 0x27, 0x00,
+ 0x02, 0x00, 0x27, 0x00, 0x01, 0x00, 0xf0, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x2e, 0x00, 0x11, 0x00, 0x01, 0x00, 0x2e, 0x00, 0x0f, 0x00,
+ 0x01, 0x00, 0xff, 0xff,
+};
+const byte ROOM_TABLE47[] = {
+ 0x00, 0x2f, 0x00, 0x06, 0x00, 0x28, 0x1e, 0x32, 0x2b, 0x00,
+ 0x00, 0x00, 0x46, 0x2b, 0x00, 0x03, 0x00, 0xff, 0x2b, 0x00,
+ 0x02, 0x00, 0x2b, 0x00, 0x01, 0x00, 0xf0, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0x2b, 0x00, 0x04, 0x00, 0xff, 0xff, 0x2e, 0x00,
+ 0x04, 0x00, 0x01, 0x00, 0xff, 0xff, 0x00,
+};
+const byte *const ROOM_TABLE[] = {
+ nullptr, ROOM_TABLE1, ROOM_TABLE2, ROOM_TABLE3, ROOM_TABLE4, ROOM_TABLE5, ROOM_TABLE6,
+ ROOM_TABLE7, ROOM_TABLE8, ROOM_TABLE9, nullptr, ROOM_TABLE11, nullptr, ROOM_TABLE13,
+ ROOM_TABLE14, ROOM_TABLE15, ROOM_TABLE16, ROOM_TABLE17, ROOM_TABLE18, nullptr, nullptr,
+ ROOM_TABLE21, ROOM_TABLE22, ROOM_TABLE23, ROOM_TABLE24, ROOM_TABLE25, ROOM_TABLE26, ROOM_TABLE27,
+ ROOM_TABLE28, ROOM_TABLE29, ROOM_TABLE30, ROOM_TABLE31, ROOM_TABLE32, ROOM_TABLE33, nullptr,
+ ROOM_TABLE35, nullptr, ROOM_TABLE37, ROOM_TABLE38, ROOM_TABLE39, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, ROOM_TABLE47
+};
+
+const char *const ROOM_DESCR[] = {
+ nullptr, "TBD ROOM_TABLE1", "TBD ROOM_TABLE2", "TBD ROOM_TABLE3", "TBD ROOM_TABLE4",
+ "TBD ROOM_TABLE5", "TBD ROOM_TABLE6", "TBD ROOM_TABLE7", "TBD ROOM_TABLE8", "TBD ROOM_TABLE9",
+ nullptr, "TBD ROOM_TABLE11", nullptr, "TBD ROOM_TABLE13", "TBD ROOM_TABLE14",
+ "TBD ROOM_TABLE15", "TBD ROOM_TABLE16", "TBD ROOM_TABLE17", "TBD ROOM_TABLE18", nullptr,
+ nullptr, "TBD ROOM_TABLE21", "TBD ROOM_TABLE22", "TBD ROOM_TABLE23", "TBD ROOM_TABLE24",
+ "TBD ROOM_TABLE25", "TBD ROOM_TABLE26", "TBD ROOM_TABLE27", "TBD ROOM_TABLE28", "TBD ROOM_TABLE29",
+ "TBD ROOM_TABLE30", "TBD ROOM_TABLE31", "TBD ROOM_TABLE32", "TBD ROOM_TABLE33", nullptr,
+ "TBD ROOM_TABLE35", nullptr, "TBD ROOM_TABLE37", "TBD ROOM_TABLE38", "TBD ROOM_TABLE39",
+ nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, "TBD ROOM_TABLE47"
+};
+
+const int ROOM_NUMB = 48;
+
+const byte CHAR_TABLE0[] = {
+ 0x02, 0x31, 0x00, 0x08, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+};
+const byte CHAR_TABLE2[] = {
+ 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x32, 0x33, 0x00, 0x01, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x33, 0x00, 0x00, 0x00, 0x33,
+ 0x00, 0x02, 0x00, 0x33, 0x00, 0x0b, 0x00, 0x33, 0x00, 0x03,
+ 0x00, 0x33, 0x00, 0x0c, 0x00, 0x33, 0x00, 0x04, 0x00, 0x33,
+ 0x00, 0x0d, 0x00, 0x33, 0x00, 0x05, 0x00, 0x33, 0x00, 0x0e,
+ 0x00, 0x33, 0x00, 0x06, 0x00, 0x33, 0x00, 0x0f, 0x00, 0x33,
+ 0x00, 0x07, 0x00, 0x33, 0x00, 0x10, 0x00, 0x33, 0x00, 0x08,
+ 0x00, 0x33, 0x00, 0x11, 0x00, 0x33, 0x00, 0x09, 0x00, 0x33,
+ 0x00, 0x12, 0x00, 0x33, 0x00, 0x0a, 0x00, 0x33, 0x00, 0x13,
+ 0x00, 0xff, 0xff,
+};
+const byte CHAR_TABLE3[] = {
+ 0x02, 0x31, 0x00, 0x03, 0x00, 0x35, 0x00, 0x37, 0x00, 0x02,
+ 0x00, 0x80, 0x00, 0xf7, 0x00, 0x4b, 0x37, 0x00, 0x01, 0x00,
+ 0xff, 0x37, 0x00, 0x03, 0x00, 0x37, 0x00, 0x00, 0x00, 0xff,
+ 0xff,
+};
+const byte CHAR_TABLE4[] = {
+ 0x01, 0x31, 0x00, 0x0a, 0x00, 0x36, 0x00, 0x35, 0x00, 0x02,
+ 0x00, 0x80, 0x00, 0xf7, 0x00, 0x49, 0x35, 0x00, 0x01, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x35, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x03, 0x00, 0x35, 0x00, 0x0c, 0x00, 0x35, 0x00, 0x04,
+ 0x00, 0x35, 0x00, 0x0d, 0x00, 0x35, 0x00, 0x05, 0x00, 0x35,
+ 0x00, 0x0e, 0x00, 0x35, 0x00, 0x06, 0x00, 0x35, 0x00, 0x0f,
+ 0x00, 0x35, 0x00, 0x07, 0x00, 0x35, 0x00, 0x10, 0x00, 0x35,
+ 0x00, 0x08, 0x00, 0x35, 0x00, 0x11, 0x00, 0x35, 0x00, 0x09,
+ 0x00, 0x35, 0x00, 0x12, 0x00, 0x35, 0x00, 0x0a, 0x00, 0x35,
+ 0x00, 0x13, 0x00, 0x35, 0x00, 0x0b, 0x00, 0x35, 0x00, 0x14,
+ 0x00, 0xff, 0xff,
+};
+const byte CHAR_TABLE5[] = {
+ 0x01, 0x31, 0x00, 0x08, 0x00, 0x37, 0x00, 0x34, 0x00, 0x02,
+ 0x00, 0x80, 0x00, 0xf7, 0x00, 0x48, 0x34, 0x00, 0x01, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x34, 0x00, 0x00, 0x00, 0x43,
+ 0x00, 0x00, 0x00, 0x34, 0x00, 0x03, 0x00, 0x43, 0x00, 0x01,
+ 0x00, 0x34, 0x00, 0x04, 0x00, 0x43, 0x00, 0x02, 0x00, 0x34,
+ 0x00, 0x05, 0x00, 0x43, 0x00, 0x03, 0x00, 0x34, 0x00, 0x06,
+ 0x00, 0x43, 0x00, 0x04, 0x00, 0x34, 0x00, 0x07, 0x00, 0x43,
+ 0x00, 0x05, 0x00, 0x34, 0x00, 0x08, 0x00, 0x43, 0x00, 0x06,
+ 0x00, 0x34, 0x00, 0x09, 0x00, 0x43, 0x00, 0x07, 0x00, 0x34,
+ 0x00, 0x0a, 0x00, 0x43, 0x00, 0x08, 0x00, 0x34, 0x00, 0x0b,
+ 0x00, 0x43, 0x00, 0x09, 0x00, 0x34, 0x00, 0x0c, 0x00, 0x43,
+ 0x00, 0x0a, 0x00, 0x34, 0x00, 0x0d, 0x00, 0x43, 0x00, 0x0b,
+ 0x00, 0x34, 0x00, 0x0e, 0x00, 0x43, 0x00, 0x0c, 0x00, 0x34,
+ 0x00, 0x0f, 0x00, 0x43, 0x00, 0x0d, 0x00, 0x34, 0x00, 0x10,
+ 0x00, 0xff, 0xff,
+};
+const byte CHAR_TABLE6[] = {
+ 0x02, 0x31, 0x00, 0x03, 0x00, 0x38, 0x00, 0x44, 0x00, 0x03,
+ 0x00, 0x80, 0x00, 0xf7, 0x00, 0x4e, 0x44, 0x00, 0x01, 0x00,
+ 0xff, 0x44, 0x00, 0x02, 0x00, 0x44, 0x00, 0x00, 0x00, 0xff,
+ 0xff,
+};
+const byte CHAR_TABLE7[] = {
+ 0x02, 0x31, 0x00, 0x01, 0x00, 0x39, 0x00, 0x38, 0x00, 0x02,
+ 0x00, 0x80, 0x00, 0xf7, 0x00, 0x4c, 0x38, 0x00, 0x01, 0x00,
+ 0xff, 0x38, 0x00, 0x03, 0x00, 0x38, 0x00, 0x00, 0x00, 0xff,
+ 0xff,
+};
+const byte CHAR_TABLE8[] = {
+ 0x03, 0xff, 0xff, 0xff, 0xff, 0x3a, 0x00, 0xff, 0xff, 0xff,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x3b, 0x00, 0x01, 0x00,
+ 0xff, 0x3b, 0x00, 0x02, 0x00, 0x3b, 0x00, 0x00, 0x00, 0xff,
+ 0xff,
+};
+const byte CHAR_TABLE9[] = {
+ 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x59, 0x4a, 0x00, 0x01, 0x00,
+ 0xff, 0x4a, 0x00, 0x02, 0x00, 0x4a, 0x00, 0x00, 0x00, 0xff,
+ 0xff,
+};
+const byte CHAR_TABLE10[] = {
+ 0x01, 0x31, 0x00, 0x0a, 0x00, 0x3c, 0x00, 0x36, 0x00, 0x02,
+ 0x00, 0x80, 0x00, 0xf7, 0x00, 0x4a, 0x36, 0x00, 0x01, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x36, 0x00, 0x00, 0x00, 0x36,
+ 0x00, 0x03, 0x00, 0x36, 0x00, 0x13, 0x00, 0x36, 0x00, 0x04,
+ 0x00, 0x36, 0x00, 0x14, 0x00, 0x36, 0x00, 0x05, 0x00, 0x36,
+ 0x00, 0x15, 0x00, 0x36, 0x00, 0x06, 0x00, 0x36, 0x00, 0x16,
+ 0x00, 0x36, 0x00, 0x07, 0x00, 0x36, 0x00, 0x17, 0x00, 0x36,
+ 0x00, 0x08, 0x00, 0x36, 0x00, 0x18, 0x00, 0x36, 0x00, 0x09,
+ 0x00, 0x36, 0x00, 0x19, 0x00, 0x36, 0x00, 0x0a, 0x00, 0x36,
+ 0x00, 0x1a, 0x00, 0x36, 0x00, 0x0b, 0x00, 0x36, 0x00, 0x1b,
+ 0x00, 0x36, 0x00, 0x0c, 0x00, 0x36, 0x00, 0x1c, 0x00, 0x36,
+ 0x00, 0x0d, 0x00, 0x36, 0x00, 0x1d, 0x00, 0x36, 0x00, 0x0e,
+ 0x00, 0x36, 0x00, 0x1e, 0x00, 0x36, 0x00, 0x0f, 0x00, 0x36,
+ 0x00, 0x1f, 0x00, 0x36, 0x00, 0x10, 0x00, 0x36, 0x00, 0x20,
+ 0x00, 0x36, 0x00, 0x11, 0x00, 0x36, 0x00, 0x21, 0x00, 0x36,
+ 0x00, 0x12, 0x00, 0x36, 0x00, 0x22, 0x00, 0xff, 0xff,
+};
+const byte CHAR_TABLE11[] = {
+ 0x03, 0xff, 0xff, 0xff, 0xff, 0x3d, 0x00, 0xff, 0xff, 0xff,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x55, 0x45, 0x00, 0x01, 0x00,
+ 0xff, 0x45, 0x00, 0x02, 0x00, 0x45, 0x00, 0x00, 0x00, 0xff,
+ 0xff,
+};
+const byte CHAR_TABLE12[] = {
+ 0x03, 0xff, 0xff, 0xff, 0xff, 0x3e, 0x00, 0xff, 0xff, 0xff,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x40, 0x00, 0x01, 0x00,
+ 0xff, 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x00, 0x00, 0xff,
+ 0xff,
+};
+const byte CHAR_TABLE13[] = {
+ 0x00, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x46, 0x00, 0x02,
+ 0x00, 0x80, 0x00, 0xf7, 0x00, 0x56, 0x46, 0x00, 0x01, 0x00,
+ 0xff, 0x46, 0x00, 0x03, 0x00, 0x46, 0x00, 0x00, 0x00, 0x46,
+ 0x00, 0x04, 0x00, 0x46, 0x00, 0x0d, 0x00, 0x46, 0x00, 0x05,
+ 0x00, 0x46, 0x00, 0x0e, 0x00, 0x46, 0x00, 0x06, 0x00, 0x46,
+ 0x00, 0x0f, 0x00, 0x46, 0x00, 0x07, 0x00, 0x46, 0x00, 0x10,
+ 0x00, 0x46, 0x00, 0x08, 0x00, 0x46, 0x00, 0x11, 0x00, 0x46,
+ 0x00, 0x09, 0x00, 0x46, 0x00, 0x12, 0x00, 0x46, 0x00, 0x0a,
+ 0x00, 0x46, 0x00, 0x13, 0x00, 0x46, 0x00, 0x0b, 0x00, 0x46,
+ 0x00, 0x14, 0x00, 0x46, 0x00, 0x0c, 0x00, 0x46, 0x00, 0x15,
+ 0x00, 0xff, 0xff,
+};
+const byte CHAR_TABLE15[] = {
+ 0x00, 0xff, 0xff, 0xff, 0xff, 0x41, 0x00, 0xff, 0xff, 0xff,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x57, 0x47, 0x00, 0x01, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x47, 0x00, 0x00, 0x00, 0x47,
+ 0x00, 0x02, 0x00, 0x47, 0x00, 0x05, 0x00, 0x47, 0x00, 0x03,
+ 0x00, 0x47, 0x00, 0x06, 0x00, 0x47, 0x00, 0x04, 0x00, 0x47,
+ 0x00, 0x07, 0x00, 0xff, 0xff,
+};
+const byte CHAR_TABLE16[] = {
+ 0x03, 0xff, 0xff, 0xff, 0xff, 0x42, 0x00, 0xff, 0xff, 0xff,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x54, 0x41, 0x00, 0x01, 0x00,
+ 0xff, 0x41, 0x00, 0x02, 0x00, 0x41, 0x00, 0x00, 0x00, 0xff,
+ 0xff,
+};
+const byte CHAR_TABLE18[] = {
+ 0x02, 0x31, 0x00, 0x07, 0x00, 0x44, 0x00, 0x3c, 0x00, 0x03,
+ 0x00, 0x80, 0x00, 0xf7, 0x00, 0x50, 0x3c, 0x00, 0x01, 0x00,
+ 0xff, 0x3c, 0x00, 0x02, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xff,
+ 0xff,
+};
+const byte CHAR_TABLE19[] = {
+ 0x02, 0x31, 0x00, 0x07, 0x00, 0x45, 0x00, 0x3d, 0x00, 0x03,
+ 0x00, 0x80, 0x00, 0xf7, 0x00, 0x51, 0x3d, 0x00, 0x01, 0x00,
+ 0xff, 0x3d, 0x00, 0x02, 0x00, 0x3d, 0x00, 0x00, 0x00, 0xff,
+ 0xff,
+};
+const byte CHAR_TABLE20[] = {
+ 0x02, 0x31, 0x00, 0x02, 0x00, 0x46, 0x00, 0x48, 0x00, 0x02,
+ 0x00, 0x80, 0x00, 0xf7, 0x00, 0x58, 0x48, 0x00, 0x01, 0x00,
+ 0xff, 0x48, 0x00, 0x03, 0x00, 0x48, 0x00, 0x00, 0x00, 0xff,
+ 0xff,
+};
+const byte CHAR_TABLE21[] = {
+ 0x02, 0x31, 0x00, 0x07, 0x00, 0x47, 0x00, 0x3e, 0x00, 0x03,
+ 0x00, 0x80, 0x00, 0xf7, 0x00, 0x52, 0x3e, 0x00, 0x01, 0x00,
+ 0xff, 0x3e, 0x00, 0x02, 0x00, 0x3e, 0x00, 0x00, 0x00, 0xff,
+ 0xff,
+};
+const byte CHAR_TABLE23[] = {
+ 0x02, 0x31, 0x00, 0x08, 0x00, 0x49, 0x00, 0x3f, 0x00, 0x03,
+ 0x00, 0x80, 0x00, 0xf7, 0x00, 0x53, 0x3f, 0x00, 0x01, 0x00,
+ 0xff, 0x3f, 0x00, 0x02, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xff,
+ 0xff,
+};
+const byte CHAR_TABLE24[] = {
+ 0x02, 0x32, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x47, 0x32, 0x00, 0x02, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x32, 0x00, 0x01, 0x00, 0x32,
+ 0x00, 0x03, 0x00, 0x32, 0x00, 0x0a, 0x00, 0x32, 0x00, 0x04,
+ 0x00, 0x32, 0x00, 0x0b, 0x00, 0x32, 0x00, 0x05, 0x00, 0x32,
+ 0x00, 0x0c, 0x00, 0x32, 0x00, 0x06, 0x00, 0x32, 0x00, 0x0d,
+ 0x00, 0x32, 0x00, 0x07, 0x00, 0x32, 0x00, 0x0e, 0x00, 0x32,
+ 0x00, 0x08, 0x00, 0x32, 0x00, 0x0f, 0x00, 0x32, 0x00, 0x09,
+ 0x00, 0x32, 0x00, 0x10, 0x00, 0xff, 0xff
+};
+const byte CHAR_TABLE25[] = {
+ 0x02, 0x39, 0x00, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x39, 0x00, 0x00, 0x00, 0x39, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xFF, 0xFF
+};
+const byte CHAR_TABLE26[] = {
+ 0x01, 0x3a, 0x00, 0x01, 0x00, 0x0a, 0x00, 0xff, 0xff, 0xff,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x3a, 0x00, 0x02, 0x00,
+ 0xff, 0x3a, 0x00, 0x03, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x42,
+ 0x00, 0x00, 0x00, 0x3a, 0x00, 0x04, 0x00, 0x42, 0x00, 0x01,
+ 0x00, 0x3a, 0x00, 0x05, 0x00, 0x42, 0x00, 0x02, 0x00, 0x3a,
+ 0x00, 0x06, 0x00, 0x42, 0x00, 0x03, 0x00, 0x3a, 0x00, 0x07,
+ 0x00, 0x42, 0x00, 0x04, 0x00, 0x3a, 0x00, 0x08, 0x00, 0x42,
+ 0x00, 0x05, 0x00, 0x3a, 0x00, 0x09, 0x00, 0x42, 0x00, 0x06,
+ 0x00, 0x3a, 0x00, 0x0a, 0x00, 0x42, 0x00, 0x07, 0x00, 0x3a,
+ 0x00, 0x0b, 0x00, 0x42, 0x00, 0x08, 0x00, 0x3a, 0x00, 0x0c,
+ 0x00, 0x42, 0x00, 0x09, 0x00, 0x3a, 0x00, 0x0d, 0x00, 0x42,
+ 0x00, 0x0a, 0x00, 0x3a, 0x00, 0x0e, 0x00, 0x42, 0x00, 0x0b,
+ 0x00, 0x3a, 0x00, 0x0f, 0x00, 0x42, 0x00, 0x0c, 0x00, 0x3a,
+ 0x00, 0x10, 0x00, 0x42, 0x00, 0x0d, 0x00, 0x3a, 0x00, 0x11,
+ 0x00, 0x42, 0x00, 0x0e, 0x00, 0x3a, 0x00, 0x12, 0x00, 0x42,
+ 0x00, 0x0f, 0x00, 0x3a, 0x00, 0x13, 0x00, 0x42, 0x00, 0x10,
+ 0x00, 0x3a, 0x00, 0x14, 0x00, 0x42, 0x00, 0x11, 0x00, 0x3a,
+ 0x00, 0x15, 0x00, 0xff, 0xff
+};
+const byte CHAR_TABLE27[] = {
+ 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x58, 0x49, 0x00, 0x01, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x49, 0x00, 0x00, 0x00, 0x49,
+ 0x00, 0x02, 0x00, 0x49, 0x00, 0x0a, 0x00, 0x49, 0x00, 0x03,
+ 0x00, 0x49, 0x00, 0x0b, 0x00, 0x49, 0x00, 0x04, 0x00, 0x49,
+ 0x00, 0x0c, 0x00, 0x49, 0x00, 0x05, 0x00, 0x49, 0x00, 0x0d,
+ 0x00, 0x49, 0x00, 0x06, 0x00, 0x49, 0x00, 0x0e, 0x00, 0x49,
+ 0x00, 0x07, 0x00, 0x49, 0x00, 0x0f, 0x00, 0x49, 0x00, 0x08,
+ 0x00, 0x49, 0x00, 0x10, 0x00, 0x49, 0x00, 0x09, 0x00, 0x49,
+ 0x00, 0x11, 0x00, 0xff, 0xff,
+};
+const byte *const CHAR_TABLE[] = {
+ CHAR_TABLE0, nullptr, CHAR_TABLE2, CHAR_TABLE3, CHAR_TABLE4, CHAR_TABLE5,
+ CHAR_TABLE6, CHAR_TABLE7, CHAR_TABLE8, CHAR_TABLE9, CHAR_TABLE10,
+ CHAR_TABLE11, CHAR_TABLE12, CHAR_TABLE13, nullptr, CHAR_TABLE15,
+ CHAR_TABLE16, nullptr, CHAR_TABLE18, CHAR_TABLE19, CHAR_TABLE20,
+ CHAR_TABLE21, nullptr, CHAR_TABLE23, CHAR_TABLE24, CHAR_TABLE25,
+ CHAR_TABLE26, CHAR_TABLE27
+};
+
+// TODO: Fix that array
+const int COMBO_TABLE[54][4] = {
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 }
+};
+
+} // End of namespace Martian
+
+} // End of namespace Access
diff --git a/engines/access/martian/martian_resources.h b/engines/access/martian/martian_resources.h
new file mode 100644
index 0000000000..a52967d42a
--- /dev/null
+++ b/engines/access/martian/martian_resources.h
@@ -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.
+ *
+ */
+
+#ifndef ACCESS_MARTIAN_RESOURCES_H
+#define ACCESS_MARTIAN_RESOURCES_H
+
+#include "common/scummsys.h"
+
+namespace Access {
+
+namespace Martian {
+
+extern const char *const FILENAMES[];
+
+extern const byte *const CURSORS[4];
+
+extern const int TRAVEL_POS[][2];
+
+extern const char *const INVENTORY_NAMES[];
+
+extern const byte *const ROOM_TABLE[];
+extern const char *const ROOM_DESCR[];
+extern const int ROOM_NUMB;
+
+extern const byte *const CHAR_TABLE[];
+
+extern const int COMBO_TABLE[54][4];
+
+} // End of namespace Martian
+
+} // End of namespace Access
+
+#endif /* ACCESS_MARTIAN_RESOURCES_H */
diff --git a/engines/access/martian/martian_room.cpp b/engines/access/martian/martian_room.cpp
new file mode 100644
index 0000000000..e9d1b9d8cf
--- /dev/null
+++ b/engines/access/martian/martian_room.cpp
@@ -0,0 +1,141 @@
+/* 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 "access/access.h"
+#include "access/resources.h"
+#include "access/martian/martian_game.h"
+#include "access/martian/martian_resources.h"
+#include "access/martian/martian_room.h"
+
+namespace Access {
+
+namespace Martian {
+
+MartianRoom::MartianRoom(AccessEngine *vm) : Room(vm) {
+ _game = (MartianEngine *)vm;
+}
+
+MartianRoom::~MartianRoom() {
+}
+
+void MartianRoom::loadRoom(int roomNumber) {
+ loadRoomData(ROOM_TABLE[roomNumber]);
+}
+
+void MartianRoom::reloadRoom() {
+ loadRoom(_vm->_player->_roomNumber);
+
+ if (_roomFlag != 1) {
+ _vm->_currentMan = _roomFlag;
+ _vm->_currentManOld = _roomFlag;
+ _vm->_manScaleOff = 0;
+
+ switch (_vm->_currentMan) {
+ case 0:
+ _vm->_player->loadSprites("MAN.LZ");
+ break;
+
+ case 2:
+ _vm->_player->loadSprites("JMAN.LZ");
+ break;
+
+ case 3:
+ _vm->_player->loadSprites("OVERHEAD.LZ");
+ _vm->_manScaleOff = 1;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ reloadRoom1();
+}
+
+void MartianRoom::reloadRoom1() {
+ if (_vm->_player->_roomNumber == 29 || _vm->_player->_roomNumber == 31
+ || _vm->_player->_roomNumber == 42 || _vm->_player->_roomNumber == 44) {
+ //Resource *spriteData = _vm->_files->loadFile("MAYA.LZ");
+ //_vm->_inactive._spritesPtr = new SpriteResource(_vm, spriteData);
+ //delete spriteData;
+ _vm->_currentCharFlag = false;
+ }
+
+ _selectCommand = -1;
+ _vm->_events->setNormalCursor(CURSOR_CROSSHAIRS);
+ _vm->_mouseMode = 0;
+ _vm->_boxSelect = true;
+ _vm->_player->_playerOff = false;
+
+ _vm->_screen->fadeOut();
+ _vm->_screen->clearScreen();
+ roomSet();
+
+ // TODO: Refactor
+
+ _vm->_screen->setBufferScan();
+ setupRoom();
+ setWallCodes();
+ buildScreen();
+
+ if (!_vm->_screen->_vesaMode) {
+ _vm->copyBF2Vid();
+ } else if (_vm->_player->_roomNumber != 20 && _vm->_player->_roomNumber != 24
+ && _vm->_player->_roomNumber != 33) {
+ _vm->_screen->setPalette();
+ _vm->copyBF2Vid();
+ }
+
+ _vm->_player->_frame = 0;
+ _vm->_oldRects.clear();
+ _vm->_newRects.clear();
+}
+
+void MartianRoom::roomSet() {
+ _vm->_numAnimTimers = 0;
+ _vm->_scripts->_sequence = 1000;
+ _vm->_scripts->searchForSequence();
+ _vm->_scripts->executeScript();
+}
+
+void MartianRoom::roomMenu() {
+ Resource *iconData = _vm->_files->loadFile("ICONS.LZ");
+ SpriteResource *spr = new SpriteResource(_vm, iconData);
+ delete iconData;
+
+ _vm->_screen->saveScreen();
+ _vm->_screen->setDisplayScan();
+ _vm->_destIn = _vm->_screen; // TODO: Redundant
+ _vm->_screen->plotImage(spr, 0, Common::Point(0, 177));
+ _vm->_screen->plotImage(spr, 1, Common::Point(143, 177));
+
+ _vm->_screen->restoreScreen();
+ delete spr;
+}
+
+void MartianRoom::mainAreaClick() {
+}
+
+} // End of namespace Martian
+
+} // End of namespace Access
diff --git a/engines/access/martian/martian_room.h b/engines/access/martian/martian_room.h
new file mode 100644
index 0000000000..85529ce8f0
--- /dev/null
+++ b/engines/access/martian/martian_room.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 ACCESS_MARTIAN_ROOM_H
+#define ACCESS_MARTIAN_ROOM_H
+
+#include "common/scummsys.h"
+#include "access/room.h"
+
+namespace Access {
+
+class AccessEngine;
+
+namespace Martian {
+
+class MartianEngine;
+
+class MartianRoom : public Room {
+private:
+ MartianEngine *_game;
+
+ void roomSet();
+protected:
+ virtual void loadRoom(int roomNumber);
+
+ virtual void reloadRoom();
+
+ virtual void reloadRoom1();
+
+ virtual void mainAreaClick();
+public:
+ MartianRoom(AccessEngine *vm);
+
+ virtual ~MartianRoom();
+
+ virtual void loadRoomData(const byte *roomData) { warning("TODO - loadRoomData"); }
+
+ virtual void init4Quads() { }
+
+ virtual void roomMenu();
+};
+
+} // End of namespace Martian
+
+} // End of namespace Access
+
+#endif /* ACCESS_AMAZON_ROOM_H */
diff --git a/engines/access/martian/martian_scripts.cpp b/engines/access/martian/martian_scripts.cpp
new file mode 100644
index 0000000000..0578872092
--- /dev/null
+++ b/engines/access/martian/martian_scripts.cpp
@@ -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.
+ *
+ */
+
+#include "common/scummsys.h"
+#include "access/access.h"
+#include "access/martian/martian_game.h"
+#include "access/martian/martian_resources.h"
+#include "access/martian/martian_scripts.h"
+
+namespace Access {
+
+namespace Martian {
+
+MartianScripts::MartianScripts(AccessEngine *vm) : Scripts(vm) {
+ _game = (MartianEngine *)_vm;
+}
+
+void MartianScripts::executeSpecial(int commandIndex, int param1, int param2) {
+}
+
+typedef void(MartianScripts::*MartianScriptMethodPtr)();
+
+void MartianScripts::executeCommand(int commandIndex) {
+ Scripts::executeCommand(commandIndex);
+}
+
+} // End of namespace Martian
+
+} // End of namespace Access
diff --git a/engines/access/martian/martian_scripts.h b/engines/access/martian/martian_scripts.h
new file mode 100644
index 0000000000..fc7495fc47
--- /dev/null
+++ b/engines/access/martian/martian_scripts.h
@@ -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.
+ *
+ */
+
+#ifndef ACCESS_MARTIAN_SCRIPTS_H
+#define ACCESS_MARTIAN_SCRIPTS_H
+
+#include "common/scummsys.h"
+#include "access/scripts.h"
+
+namespace Access {
+
+namespace Martian {
+
+class MartianEngine;
+
+class MartianScripts : public Scripts {
+private:
+ MartianEngine *_game;
+protected:
+ virtual void executeSpecial(int commandIndex, int param1, int param2);
+ virtual void executeCommand(int commandIndex);
+public:
+ MartianScripts(AccessEngine *vm);
+};
+
+} // End of namespace Martian
+
+} // End of namespace Access
+
+#endif /* ACCESS_MARTIAN_SCRIPTS_H */
diff --git a/engines/access/module.mk b/engines/access/module.mk
new file mode 100644
index 0000000000..b6961aeca9
--- /dev/null
+++ b/engines/access/module.mk
@@ -0,0 +1,41 @@
+MODULE := engines/access
+
+MODULE_OBJS := \
+ animation.o \
+ asurface.o \
+ access.o \
+ bubble_box.o \
+ char.o \
+ data.o \
+ debugger.o \
+ decompress.o \
+ detection.o \
+ events.o \
+ files.o \
+ font.o \
+ inventory.o \
+ player.o \
+ resources.o \
+ room.o \
+ screen.o \
+ scripts.o \
+ sound.o \
+ video.o \
+ amazon/amazon_game.o \
+ amazon/amazon_logic.o \
+ amazon/amazon_player.o \
+ amazon/amazon_resources.o \
+ amazon/amazon_room.o \
+ amazon/amazon_scripts.o \
+ martian/martian_game.o \
+ martian/martian_resources.o \
+ martian/martian_room.o \
+ martian/martian_scripts.o
+
+# This module can be built as a plugin
+ifeq ($(ENABLE_ACCESS), DYNAMIC_PLUGIN)
+PLUGIN := 1
+endif
+
+# Include common rules
+include $(srcdir)/rules.mk
diff --git a/engines/access/player.cpp b/engines/access/player.cpp
new file mode 100644
index 0000000000..5a2b98293f
--- /dev/null
+++ b/engines/access/player.cpp
@@ -0,0 +1,825 @@
+/* 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/algorithm.h"
+#include "common/textconsole.h"
+#include "access/player.h"
+#include "access/access.h"
+#include "access/resources.h"
+#include "access/amazon/amazon_player.h"
+
+namespace Access {
+
+Player *Player::init(AccessEngine *vm) {
+ switch (vm->getGameID()) {
+ case GType_Amazon:
+ return new Amazon::AmazonPlayer(vm);
+ default:
+ return new Player(vm);
+ }
+}
+
+Player::Player(AccessEngine *vm) : Manager(vm), ImageEntry() {
+ Common::fill(&_walkOffRight[0], &_walkOffRight[PLAYER_DATA_COUNT], 0);
+ Common::fill(&_walkOffLeft[0], &_walkOffLeft[PLAYER_DATA_COUNT], 0);
+ Common::fill(&_walkOffUp[0], &_walkOffUp[PLAYER_DATA_COUNT], 0);
+ Common::fill(&_walkOffDown[0], &_walkOffDown[PLAYER_DATA_COUNT], 0);
+
+ _playerSprites = nullptr;
+ _playerSprites1 = nullptr;
+ _manPal1 = nullptr;
+ _frameNumber = 0;
+ _rawTempL = 0;
+ _rawXTemp = 0;
+ _rawYTempL = 0;
+ _rawYTemp = 0;
+ _playerXLow = 0;
+ _playerX = 0;
+ _playerYLow = 0;
+ _playerY = 0;
+ _frame = 0;
+ _playerOff = false;
+ _playerMove = false;
+ _leftDelta = _rightDelta = 0;
+ _upDelta = _downDelta = 0;
+ _scrollConst = 0;
+ _scrollFlag = false;
+ _scrollThreshold = 0;
+ _scrollAmount = 0;
+ _scrollEnd = 0;
+ _roomNumber = 0;
+ _collideFlag = false;
+ _move = NONE;
+ _playerDirection = NONE;
+ _xFlag = _yFlag = 0;
+ _inactiveYOff = 0;
+
+ _sideWalkMin = _sideWalkMax = 0;
+ _upWalkMin = _upWalkMax = 0;
+ _downWalkMin = _downWalkMax = 0;
+ _diagUpWalkMin = _diagUpWalkMax = 0;
+ _diagDownWalkMin = _diagDownWalkMax = 0;
+}
+
+Player::~Player() {
+ delete _playerSprites;
+ delete[] _manPal1;
+}
+
+void Player::load() {
+ _playerOffset.x = _vm->_screen->_scaleTable1[25];
+ _playerOffset.y = _vm->_screen->_scaleTable1[67];
+ _leftDelta = -3;
+ _rightDelta = 33;
+ _upDelta = 5;
+ _downDelta = -10;
+ _scrollConst = 5;
+
+ for (int i = 0; i < PLAYER_DATA_COUNT; ++i) {
+ _walkOffRight[i] = SIDEOFFR[i];
+ _walkOffLeft[i] = SIDEOFFL[i];
+ _walkOffUp[i] = SIDEOFFU[i];
+ _walkOffDown[i] = SIDEOFFD[i];
+ _walkOffUR[i].x = DIAGOFFURX[i];
+ _walkOffUR[i].y = DIAGOFFURY[i];
+ _walkOffDR[i].x = DIAGOFFDRX[i];
+ _walkOffDR[i].y = DIAGOFFDRY[i];
+ _walkOffUL[i].x = DIAGOFFULX[i];
+ _walkOffUL[i].y = DIAGOFFULY[i];
+ _walkOffDL[i].x = DIAGOFFDLX[i];
+ _walkOffDL[i].y = DIAGOFFDLY[i];
+ }
+
+ _sideWalkMin = 0;
+ _sideWalkMax = 7;
+ _upWalkMin = 16;
+ _upWalkMax = 23;
+ _downWalkMin = 8;
+ _downWalkMax = 15;
+ _diagUpWalkMin = 0;
+ _diagUpWalkMax = 7;
+ _diagDownWalkMin = 0;
+ _diagDownWalkMax = 7;
+
+ _playerSprites = _playerSprites1;
+ if (_manPal1) {
+ Common::copy(_manPal1 + 0x270, _manPal1 + 0x270 + 0x60, _vm->_screen->_manPal);
+ } else {
+ Common::fill(_vm->_screen->_manPal, _vm->_screen->_manPal + 0x60, 0);
+ }
+}
+
+void Player::loadSprites(const Common::String &name) {
+ freeSprites();
+
+ Resource *data = _vm->_files->loadFile(name);
+ _playerSprites1 = new SpriteResource(_vm, data);
+ delete data;
+}
+
+void Player::freeSprites() {
+ delete _playerSprites;
+ _playerSprites1 = nullptr;
+ _playerSprites = nullptr;
+}
+
+void Player::removeSprite1() {
+ if (_playerSprites1) {
+ delete _playerSprites1;
+ _playerSprites1 = nullptr;
+ }
+}
+
+void Player::calcManScale() {
+ if (!_vm->_manScaleOff) {
+ _vm->_scale = ((((_rawPlayer.y - _vm->_scaleMaxY + _vm->_scaleN1) *
+ _vm->_scaleT1 + (_vm->_scaleH2 << 8)) & 0xff00) / _vm->_scaleH1 * _vm->_scaleI) >> 8;
+ _vm->_screen->setScaleTable(_vm->_scale);
+
+ _playerOffset.x = _vm->_screen->_scaleTable1[20];
+ _playerOffset.y = _vm->_screen->_scaleTable1[67];
+ _inactiveYOff = _playerOffset.y;
+ }
+}
+
+void Player::walk() {
+ _collideFlag = false;
+ _playerDirection = NONE;
+
+ if (_playerOff)
+ return;
+ else if (_vm->_timers[0]._flag) {
+ plotCom3();
+ return;
+ }
+
+ ++_vm->_timers[0]._flag;
+ switch (_move) {
+ case UP:
+ _playerMove = false;
+ walkUp();
+ break;
+ case DOWN:
+ _playerMove = false;
+ walkDown();
+ break;
+ case LEFT:
+ _playerMove = false;
+ walkLeft();
+ break;
+ case RIGHT:
+ _playerMove = false;
+ walkRight();
+ break;
+ case UPLEFT:
+ _playerMove = false;
+ walkUpLeft();
+ break;
+ case DOWNLEFT:
+ _playerMove = false;
+ walkDownLeft();
+ break;
+ case UPRIGHT:
+ _playerMove = false;
+ walkUpRight();
+ break;
+ case DOWNRIGHT:
+ _playerMove = false;
+ walkDownRight();
+ break;
+ default:
+ checkMove();
+ break;
+ }
+}
+
+void Player::calcPlayer() {
+ Screen &scr = *_vm->_screen;
+ scr._bufferStart.x = (_vm->_scrollCol << 4) + _vm->_scrollX;
+ scr._bufferStart.y = (_vm->_scrollRow << 4) + _vm->_scrollY;
+ _playerX = _rawPlayer.x - scr._bufferStart.x;
+ _playerY = _rawPlayer.y - scr._bufferStart.y;
+}
+
+void Player::walkUp() {
+ if (_frame > _upWalkMax || _frame < _upWalkMin)
+ _frame = _upWalkMin;
+
+ _playerDirection = UP;
+ int walkOff = _walkOffUp[_frame - _upWalkMin];
+ int tempL = _rawPlayerLow.y - _vm->_screen->_scaleTable2[walkOff];
+ _rawYTempL = (byte)tempL;
+ int yTemp = _rawPlayer.y - _vm->_screen->_scaleTable1[walkOff] -
+ (tempL < 0 ? 1 : 0);
+ _rawYTemp = yTemp;
+ _rawXTemp = _rawPlayer.x;
+
+ if (_vm->_room->codeWalls()) {
+ plotCom2();
+ } else {
+ _rawPlayer.y = _rawYTemp;
+ _rawPlayerLow.y = _rawYTempL;
+
+ calcManScale();
+
+ // This code looks totally useless as 'si' is unconditionally set in plotCom
+ //if (_vm->_currentMan != 3 && (_frame == 17 || _frame == 21))
+ // warning("TODO: walkUp - si = 0?");
+
+ if (++_frame > _upWalkMax)
+ _frame = _upWalkMin;
+
+ plotCom(0);
+ }
+}
+
+void Player::walkDown() {
+ if (_frame > _downWalkMax || _frame < _downWalkMin)
+ _frame = _downWalkMin;
+
+ _playerDirection = DOWN;
+ int walkOff = _walkOffDown[_frame - _downWalkMin];
+ int tempL = _vm->_screen->_scaleTable2[walkOff] + _rawPlayerLow.y;
+ _rawYTempL = (byte)tempL;
+ _rawYTemp = _vm->_screen->_scaleTable1[walkOff] + _rawPlayer.y + (tempL >= 0x100 ? 1 : 0);
+ _rawXTemp = _rawPlayer.x;
+
+ if (_vm->_room->codeWalls()) {
+ plotCom2();
+ } else {
+ _rawPlayer.y = _rawYTemp;
+ _rawPlayerLow.y = _rawYTempL;
+
+ calcManScale();
+
+ // This code looks totally useless as 'si' is unconditionally set in plotCom
+ //if (_vm->_currentMan != 3 && (_frame == 10 || _frame == 14))
+ // warning("TODO: walkDown - si = 0?");
+
+ if (++_frame > _downWalkMax)
+ _frame = _downWalkMin;
+
+ plotCom(0);
+ }
+}
+
+void Player::walkLeft() {
+ if (_frame > _sideWalkMax || _frame < _sideWalkMin)
+ _frame = _sideWalkMin;
+
+ _playerDirection = LEFT;
+
+ bool flag = _scrollEnd == 1;
+ if (!flag) {
+ calcPlayer();
+ flag = (_playerX - _vm->_screen->_scaleTable1[_scrollConst] -
+ _vm->_player->_scrollThreshold) > 0;
+ }
+ if (flag) {
+ int walkOffset = _walkOffLeft[_frame - _sideWalkMin];
+ int tempL = _rawPlayerLow.x - _vm->_screen->_scaleTable2[walkOffset];
+ _rawTempL = (byte)tempL;
+ _rawXTemp = _rawPlayer.x - _vm->_screen->_scaleTable1[walkOffset] -
+ (tempL < 0 ? 1 : 0);
+ } else {
+ _rawXTemp = _rawPlayer.x - _vm->_screen->_scaleTable1[_scrollConst];
+ }
+ _rawYTemp = _rawPlayer.y;
+
+ if (_vm->_room->codeWalls()) {
+ plotCom2();
+ } else {
+ _rawPlayer.x = _rawXTemp;
+ _rawPlayerLow.x = _rawTempL;
+ ++_frame;
+
+ // This code looks totally useless as 'si' is unconditionally set in plotCom1
+ //if (_vm->_currentMan != 3 && (_frame == 1 || _frame == 5))
+ // warning("TODO: walkLeft - si = 0?");
+
+ if (_frame > _sideWalkMax)
+ _frame = _sideWalkMin;
+
+ plotCom1();
+ }
+}
+
+void Player::walkRight() {
+ if (_frame > _sideWalkMax || _frame < _sideWalkMin)
+ _frame = _sideWalkMin;
+
+ _playerDirection = RIGHT;
+
+ bool flag = _scrollEnd == 2;
+ if (!flag) {
+ calcPlayer();
+ flag = (_vm->_screen->_clipWidth - _playerX - _vm->_screen->_scaleTable1[_scrollConst] -
+ _vm->_player->_scrollThreshold) > 0;
+ }
+ if (flag) {
+ int walkOffset = _walkOffRight[_frame - _sideWalkMin];
+ int tempL = _rawPlayerLow.x + _vm->_screen->_scaleTable2[walkOffset];
+ _rawTempL = (byte)tempL;
+ _rawXTemp = _rawPlayer.x + _vm->_screen->_scaleTable1[walkOffset] +
+ (tempL >= 0x100 ? 1 : 0);
+ } else {
+ _rawXTemp = _rawPlayer.x + _vm->_screen->_scaleTable1[_scrollConst];
+ }
+ _rawYTemp = _rawPlayer.y;
+
+ if (_vm->_room->codeWalls()) {
+ plotCom2();
+ } else {
+ _rawPlayer.x = _rawXTemp;
+ _rawPlayerLow.x = _rawTempL;
+ ++_frame;
+
+ // Useless check removed
+ if (_frame > _sideWalkMax)
+ _frame = _sideWalkMin;
+
+ plotCom(0);
+ }
+}
+
+void Player::walkUpLeft() {
+ if (_frame > _diagUpWalkMax || _frame < _diagUpWalkMin)
+ _frame = _diagUpWalkMin;
+
+ _playerDirection = UPLEFT;
+
+ int walkOffset, tempL;
+ bool flag = _scrollEnd == 1;
+ if (!flag) {
+ calcPlayer();
+ flag = (_playerX - _vm->_screen->_scaleTable1[_scrollConst] -
+ _vm->_player->_scrollThreshold) > 0;
+ }
+ if (flag) {
+ walkOffset = _walkOffUL[_frame - _diagUpWalkMin].x;
+ tempL = _rawPlayerLow.x - _vm->_screen->_scaleTable2[walkOffset];
+ _rawTempL = (byte)tempL;
+ _rawXTemp = _rawPlayer.x - _vm->_screen->_scaleTable1[walkOffset] -
+ (tempL < 0 ? 1 : 0);
+ } else {
+ _rawXTemp = _rawPlayer.x - _vm->_screen->_scaleTable1[_scrollConst];
+ }
+
+ walkOffset = _walkOffUL[_frame - _diagUpWalkMin].y;
+ tempL = _rawPlayerLow.y - _vm->_screen->_scaleTable2[walkOffset];
+ _rawYTempL = (byte)tempL;
+ _rawYTemp = _rawPlayer.y - _vm->_screen->_scaleTable1[walkOffset] -
+ (tempL < 0 ? 1 : 0);
+
+ if (_vm->_room->codeWalls()) {
+ plotCom2();
+ } else {
+ _rawPlayer.x = _rawXTemp;
+ _rawPlayer.y = _rawYTemp;
+ _rawPlayerLow.x = _rawTempL;
+ _rawPlayerLow.y = _rawYTempL;
+
+ ++_frame;
+ calcManScale();
+
+ // This code looks totally useless as 'si' is unconditionally set in plotCom1
+ //if (_vm->_currentMan != 3 && (_frame == 1 || _frame == 5))
+ // warning("TODO: walkUpLeft - si = 0?");
+
+ if (_frame > _diagUpWalkMax)
+ _frame = _diagUpWalkMin;
+
+ plotCom1();
+ }
+}
+
+void Player::walkDownLeft() {
+ if (_frame > _diagDownWalkMax || _frame < _diagDownWalkMin)
+ _frame = _diagDownWalkMin;
+
+ _playerDirection = DOWNLEFT;
+
+ int walkOffset, tempL;
+ bool flag = _scrollEnd == 1;
+ if (!flag) {
+ calcPlayer();
+ flag = (_playerX - _vm->_screen->_scaleTable1[_scrollConst] -
+ _vm->_player->_scrollThreshold) > 0;
+ }
+ if (flag) {
+ walkOffset = _walkOffDL[_frame - _sideWalkMin].x;
+ tempL = _rawPlayerLow.x - _vm->_screen->_scaleTable2[walkOffset];
+ _rawTempL = (byte)tempL;
+ _rawXTemp = _rawPlayer.x - _vm->_screen->_scaleTable1[walkOffset] -
+ (tempL < 0 ? 1 : 0);
+ } else {
+ _rawXTemp = _rawPlayer.x - _vm->_screen->_scaleTable1[_scrollConst];
+ }
+
+ walkOffset = _walkOffDL[_frame - _diagDownWalkMin].y;
+ tempL = _rawPlayerLow.y + _vm->_screen->_scaleTable2[walkOffset];
+ _rawYTempL = (byte)tempL;
+ _rawYTemp = _rawPlayer.y + _vm->_screen->_scaleTable1[walkOffset] +
+ (tempL >= 0x100 ? 1 : 0);
+
+ if (_vm->_room->codeWalls()) {
+ plotCom2();
+ } else {
+ _rawPlayer.x = _rawXTemp;
+ _rawPlayer.y = _rawYTemp;
+ _rawPlayerLow.x = _rawTempL;
+ _rawPlayerLow.y = _rawYTempL;
+
+ ++_frame;
+ calcManScale();
+
+ // This code looks totally useless as 'si' is unconditionally set in plotCom1
+ //if (_vm->_currentMan != 3 && (_frame == 1 || _frame == 5))
+ // warning("TODO: walkDownLeft - si = 0?");
+
+ if (_frame > _diagDownWalkMax)
+ _frame = _diagDownWalkMin;
+
+ plotCom1();
+ }
+}
+
+void Player::walkUpRight() {
+ if (_frame > _diagUpWalkMax || _frame < _diagUpWalkMin)
+ _frame = _diagUpWalkMin;
+
+ _playerDirection = UPRIGHT;
+
+ int walkOffset, tempL;
+ bool flag = _scrollEnd == 1;
+ if (!flag) {
+ calcPlayer();
+ flag = (_vm->_screen->_clipWidth - _playerX - _vm->_screen->_scaleTable1[_scrollConst] -
+ _vm->_player->_scrollThreshold) > 0;
+ }
+ if (flag) {
+ walkOffset = _walkOffUR[_frame - _diagUpWalkMin].x;
+ tempL = _rawPlayerLow.x + _vm->_screen->_scaleTable2[walkOffset];
+ _rawTempL = (byte)tempL;
+ _rawXTemp = _rawPlayer.x + _vm->_screen->_scaleTable1[walkOffset] +
+ (tempL >= 0x100 ? 1 : 0);
+ } else {
+ _rawXTemp = _rawPlayer.x + _vm->_screen->_scaleTable1[_scrollConst];
+ }
+
+ walkOffset = _walkOffUL[_frame - _diagUpWalkMin].y;
+ tempL = _rawPlayerLow.y - _vm->_screen->_scaleTable2[walkOffset];
+ _rawYTempL = (byte)tempL;
+ _rawYTemp = _rawPlayer.y - _vm->_screen->_scaleTable1[walkOffset] -
+ (tempL < 0 ? 1 : 0);
+
+ if (_vm->_room->codeWalls()) {
+ plotCom2();
+ } else {
+ _rawPlayer.x = _rawXTemp;
+ _rawPlayer.y = _rawYTemp;
+ _rawPlayerLow.x = _rawTempL;
+ _rawPlayerLow.y = _rawYTempL;
+
+ ++_frame;
+ calcManScale();
+
+ // This code looks totally useless as 'si' is unconditionally set in plotCom
+ //if (_vm->_currentMan != 3 && (_frame == 1 || _frame == 5))
+ // warning("TODO: walkUpRight - si = 0?");
+
+ if (_frame > _diagUpWalkMax)
+ _frame = _diagUpWalkMin;
+
+ plotCom(0);
+ }
+}
+
+void Player::walkDownRight() {
+ if (_frame > _diagDownWalkMax || _frame < _diagDownWalkMin)
+ _frame = _diagDownWalkMin;
+
+ _playerDirection = DOWNRIGHT;
+
+ int walkOffset, tempL;
+ bool flag = _scrollEnd == 2;
+ if (!flag) {
+ calcPlayer();
+ flag = (_vm->_screen->_clipWidth - _playerX - _vm->_screen->_scaleTable1[_scrollConst] -
+ _vm->_player->_scrollThreshold) > 0;
+ }
+ if (flag) {
+ walkOffset = _walkOffUR[_frame - _diagDownWalkMin].x;
+ tempL = _rawPlayerLow.x + _vm->_screen->_scaleTable2[walkOffset];
+ _rawTempL = (byte)tempL;
+ _rawXTemp = _rawPlayer.x + _vm->_screen->_scaleTable1[walkOffset] +
+ (tempL >= 0x100 ? 1 : 0);
+ } else {
+ _rawXTemp = _rawPlayer.x + _vm->_screen->_scaleTable1[_scrollConst];
+ }
+
+ walkOffset = _walkOffDR[_frame - _diagDownWalkMin].y;
+ tempL = _rawPlayerLow.y + _vm->_screen->_scaleTable2[walkOffset];
+ _rawYTempL = (byte)tempL;
+ _rawYTemp = _rawPlayer.y + _vm->_screen->_scaleTable1[walkOffset] +
+ (tempL >= 0x100 ? 1 : 0);
+
+ if (_vm->_room->codeWalls()) {
+ plotCom2();
+ } else {
+ _rawPlayer.x = _rawXTemp;
+ _rawPlayer.y = _rawYTemp;
+ _rawPlayerLow.x = _rawTempL;
+ _rawPlayerLow.y = _rawYTempL;
+
+ calcManScale();
+
+ // This code looks totally useless as 'si' is unconditionally set in plotCom1
+ //if (_vm->_currentMan != 3 && (_frame == 1 || _frame == 5))
+ // warning("TODO: walkDownRight - si = 0?");
+
+ ++_frame;
+ if (_frame > _diagDownWalkMax)
+ _frame = _diagDownWalkMin;
+
+ plotCom(0);
+ }
+}
+
+void Player::checkMove() {
+ if (_playerMove) {
+ if (_xFlag == 0 && _yFlag == 0) {
+ int xp = (_playerOffset.x / 2) + _rawPlayer.x - _moveTo.x;
+ if (xp < 0)
+ xp = -xp;
+ int yp = _rawPlayer.y - _moveTo.y;
+ if (yp < 0)
+ yp = -yp;
+
+ if (xp >= yp)
+ _xFlag = 1;
+ else
+ _yFlag = 1;
+ }
+
+ if (_yFlag == 1) {
+ int yd = _rawPlayer.y - _moveTo.y;
+ if ((yd >= 0 && yd <= _upDelta) || (yd < 0 && -yd <= _upDelta)) {
+ ++_yFlag;
+ if (_xFlag) {
+ _playerMove = false;
+ _xFlag = _yFlag = 0;
+ } else {
+ ++_xFlag;
+ }
+ } else {
+ if (yd >= 0)
+ walkUp();
+ else
+ walkDown();
+
+ if (_collideFlag) {
+ _playerMove = false;
+ _xFlag = _yFlag = 0;
+ }
+ }
+ } else if (_xFlag == 1) {
+ int xd = (_playerOffset.x / 2) + _rawPlayer.x - _moveTo.x;
+ if ((xd >= 0 && xd <= -_leftDelta) || (xd < 0 && -xd <= -_leftDelta)) {
+ ++_xFlag;
+
+ if (_yFlag) {
+ _playerMove = false;
+ _xFlag = _yFlag = 0;
+ }
+ } else {
+ if (xd >= 0)
+ walkLeft();
+ else
+ walkRight();
+
+ if (_collideFlag) {
+ _playerMove = false;
+ _xFlag = _yFlag = 0;
+ }
+ }
+ } else if (!_yFlag) {
+ ++_yFlag;
+ } else {
+ _playerMove = false;
+ _xFlag = _yFlag = 0;
+ }
+ }
+
+ plotCom3();
+}
+
+void Player::plotCom(int flags) {
+ _flags &= ~2;
+ _flags &= ~8;
+ _flags |= flags;
+
+ plotCom3();
+}
+
+void Player::plotCom1() {
+ plotCom(2);
+}
+
+void Player::plotCom2() {
+ // WORKAROUND: Amazon has at least one cutscene with the player not properly turned off
+ if (!_playerOff && _spritesPtr != nullptr)
+ _vm->_images.addToList(*this);
+}
+
+void Player::plotCom3() {
+ // Update the base ImageEntry fields for the player
+ _position.x = _rawPlayer.x;
+ _position.y = _rawPlayer.y - _playerOffset.y;
+ _offsetY = _playerOffset.y;
+ _spritesPtr = _playerSprites;
+ _frameNumber = _frame;
+
+ plotCom2();
+}
+
+void Player::checkScrollUp() {
+ if ((_playerDirection == DOWNRIGHT || _playerDirection == DOWNLEFT ||
+ _playerDirection == DOWN) && (_vm->_screen->_clipHeight -
+ _playerY - _scrollThreshold) <= 0) {
+ // Scroll up
+ if (scrollUp()) {
+ _scrollEnd = 4;
+ _vm->_scrollY &= TILE_HEIGHT;
+ _scrollFlag = true;
+ }
+ }
+}
+
+void Player::checkScroll() {
+ _scrollFlag = false;
+ if (_playerDirection == NONE)
+ return;
+
+ if ((_playerDirection == UPLEFT || _playerDirection == DOWNLEFT ||
+ _playerDirection == LEFT) && _playerX <= _scrollThreshold) {
+ // Scroll right
+ if (!scrollRight()) {
+ if (_playerDirection == DOWNLEFT)
+ checkScrollUp();
+
+ return;
+ }
+ } else if ((_playerDirection == UPRIGHT || _playerDirection == DOWNRIGHT ||
+ _playerDirection == RIGHT) && (_vm->_screen->_clipWidth -
+ _playerX - _scrollThreshold) <= 0) {
+ // Scroll left
+ if (!scrollLeft()) {
+ if (_playerDirection == DOWNRIGHT)
+ checkScrollUp();
+
+ return;
+ }
+ }
+
+ if ((_playerDirection == UPRIGHT || _playerDirection == UPLEFT ||
+ _playerDirection == UP) && _playerY <= _scrollThreshold) {
+ scrollDown();
+ } else {
+ checkScrollUp();
+ }
+}
+
+bool Player::scrollUp() {
+ _scrollAmount = -(_vm->_screen->_clipHeight - _playerY - _scrollThreshold);
+ if ((_vm->_scrollRow + _vm->_screen->_vWindowHeight) >=
+ _vm->_room->_playFieldHeight)
+ return true;
+
+ _scrollFlag = true;
+ _vm->_scrollY = _vm->_scrollY + _scrollAmount;
+
+ while (_vm->_scrollY >= TILE_HEIGHT && !_vm->shouldQuit()) {
+ _vm->_scrollY -= TILE_HEIGHT;
+ ++_vm->_scrollRow;
+ _vm->_buffer1.moveBufferUp();
+
+ _vm->_room->buildRow(_vm->_scrollRow + _vm->_screen->_vWindowHeight,
+ _vm->_screen->_vWindowLinesTall);
+
+ if ((_vm->_scrollRow + _vm->_screen->_vWindowHeight) >=
+ _vm->_room->_playFieldHeight)
+ return true;
+
+ if (_vm->_scrollY <= TILE_HEIGHT)
+ return false;
+ }
+
+ return false;
+}
+
+bool Player::scrollDown() {
+ _scrollAmount = -(_playerY - _scrollThreshold);
+ _scrollFlag = true;
+ _vm->_scrollY -= _scrollAmount;
+ if (_vm->_scrollY >= 0)
+ return true;
+
+ do {
+ _vm->_scrollY += TILE_HEIGHT;
+ if (--_vm->_scrollRow < 0)
+ break;
+
+ _vm->_buffer1.moveBufferDown();
+ _vm->_room->buildRow(_vm->_scrollRow, 0);
+
+ if (_vm->_scrollY >= 0)
+ return false;
+ } while (!_vm->shouldQuit());
+
+ _scrollEnd = 3;
+ _vm->_scrollY = 0;
+ _vm->_scrollRow = 0;
+ return true;
+}
+
+bool Player::scrollLeft() {
+ Screen &screen = *_vm->_screen;
+ _scrollAmount = -(_vm->_screen->_clipWidth - _playerX - _scrollThreshold);
+ if ((_vm->_scrollCol + screen._vWindowWidth) == _vm->_room->_playFieldWidth) {
+ _scrollEnd = 2;
+ _vm->_scrollX = 0;
+ _scrollFlag = true;
+ return true;
+ } else {
+ _scrollFlag = true;
+ _vm->_scrollX = _vm->_scrollX + _scrollAmount;
+
+ do {
+ if (_vm->_scrollX < TILE_WIDTH)
+ return true;
+
+ _vm->_scrollX -= TILE_WIDTH;
+ ++_vm->_scrollCol;
+ _vm->_buffer1.moveBufferLeft();
+ _vm->_room->buildColumn(_vm->_scrollCol + screen._vWindowWidth,
+ screen._vWindowBytesWide);
+ } while (!_vm->shouldQuit() && (_vm->_scrollX >= TILE_WIDTH));
+
+ return (_playerDirection == UPRIGHT);
+ }
+}
+
+bool Player::scrollRight() {
+ _scrollAmount = -(_playerX - _scrollThreshold);
+ _scrollFlag = true;
+ _vm->_scrollX -= _scrollAmount;
+
+ if (_vm->_scrollX < 0) {
+ do {
+ _vm->_scrollX += TILE_WIDTH;
+ if (--_vm->_scrollCol < 0) {
+ _scrollEnd = true;
+ _vm->_scrollX = 0;
+ _vm->_scrollCol = 0;
+ return true;
+ }
+
+ _vm->_buffer1.moveBufferRight();
+ _vm->_room->buildColumn(_vm->_scrollCol, 0);
+ } while (!_vm->shouldQuit() && (_vm->_scrollX < 0));
+
+ return false;
+ }
+
+ return true;
+}
+
+void Player::synchronize(Common::Serializer &s) {
+ s.syncAsUint16LE(_roomNumber);
+ s.syncAsSint16LE(_rawPlayerLow.x);
+ s.syncAsSint16LE(_rawPlayer.x);
+ s.syncAsSint16LE(_rawPlayerLow.y);
+ s.syncAsSint16LE(_rawPlayer.y);
+}
+
+} // End of namespace Access
diff --git a/engines/access/player.h b/engines/access/player.h
new file mode 100644
index 0000000000..329cc15ed2
--- /dev/null
+++ b/engines/access/player.h
@@ -0,0 +1,152 @@
+/* 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 ACCESS_PLAYER_H
+#define ACCESS_PLAYER_H
+
+#include "common/scummsys.h"
+#include "common/rect.h"
+#include "common/serializer.h"
+#include "access/asurface.h"
+#include "access/data.h"
+
+namespace Access {
+
+#define PLAYER_DATA_COUNT 8
+
+enum Direction {
+ NONE = 0,
+ UP = 1,
+ DOWN = 2,
+ LEFT = 3,
+ RIGHT = 4,
+ UPRIGHT = 5,
+ DOWNRIGHT = 6,
+ UPLEFT = 7,
+ DOWNLEFT = 8
+};
+
+class AccessEngine;
+
+class Player : public ImageEntry, public Manager {
+protected:
+ int _leftDelta, _rightDelta;
+ int _upDelta, _downDelta;
+ int _scrollConst;
+ int _sideWalkMin, _sideWalkMax;
+ int _upWalkMin, _upWalkMax;
+ int _downWalkMin, _downWalkMax;
+ int _diagUpWalkMin, _diagUpWalkMax;
+ int _diagDownWalkMin, _diagDownWalkMax;
+ SpriteResource *_playerSprites1;
+ byte *_manPal1;
+ int _scrollEnd;
+ int _inactiveYOff;
+
+ void plotCom(int v1);
+ void plotCom1();
+ void plotCom2();
+ void plotCom3();
+
+ void walkUp();
+ void walkDown();
+ void walkLeft();
+ void walkRight();
+ void walkUpLeft();
+ void walkDownLeft();
+ void walkUpRight();
+ void walkDownRight();
+ void checkScrollUp();
+ bool scrollUp();
+ bool scrollDown();
+ bool scrollLeft();
+ bool scrollRight();
+public:
+ Direction _playerDirection;
+ SpriteResource *_playerSprites;
+ // Fields in original Player structure
+ int _walkOffRight[PLAYER_DATA_COUNT];
+ int _walkOffLeft[PLAYER_DATA_COUNT];
+ int _walkOffUp[PLAYER_DATA_COUNT];
+ int _walkOffDown[PLAYER_DATA_COUNT];
+ Common::Point _walkOffUR[PLAYER_DATA_COUNT];
+ Common::Point _walkOffDR[PLAYER_DATA_COUNT];
+ Common::Point _walkOffUL[PLAYER_DATA_COUNT];
+ Common::Point _walkOffDL[PLAYER_DATA_COUNT];
+ byte _rawTempL;
+ int _rawXTemp;
+ byte _rawYTempL;
+ int _rawYTemp;
+ Common::Point _playerOffset;
+ int _playerXLow;
+ int _playerX;
+ int _playerYLow;
+ int _playerY;
+ int _frame;
+ int _xFlag, _yFlag;
+ Direction _move;
+
+ // Additional public globals we've added to new Player class
+ bool _playerOff;
+ bool _playerMove;
+ Common::Point _moveTo;
+ bool _collideFlag;
+ bool _scrollFlag;
+ int _scrollThreshold;
+ int _scrollAmount;
+
+ // Additional globals that need to be saved
+ int _roomNumber;
+ Common::Point _rawPlayerLow;
+ Common::Point _rawPlayer;
+public:
+ Player(AccessEngine *vm);
+ virtual ~Player();
+ static Player *init(AccessEngine *vm);
+
+ virtual void load();
+
+ void loadSprites(const Common::String &name);
+
+ void freeSprites();
+
+ void removeSprite1();
+
+ void calcManScale();
+
+ void walk();
+
+ void calcPlayer();
+
+ void checkScroll();
+
+ void checkMove();
+
+ /**
+ * Synchronize savegame data
+ */
+ void synchronize(Common::Serializer &s);
+};
+
+} // End of namespace Access
+
+#endif /* ACCESS_PLAYER_H */
diff --git a/engines/access/resources.cpp b/engines/access/resources.cpp
new file mode 100644
index 0000000000..4157cdfc0d
--- /dev/null
+++ b/engines/access/resources.cpp
@@ -0,0 +1,109 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "access/resources.h"
+#include "access/access.h"
+
+namespace Access {
+
+const byte INITIAL_PALETTE[18 * 3] = {
+ 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff,
+ 0xf0, 0xf0, 0xf0,
+ 0xe0, 0xe0, 0xe0,
+ 0xd0, 0xd0, 0xd0,
+ 0xc0, 0xc0, 0xc0,
+ 0xb0, 0xb0, 0xb0,
+ 0xa0, 0xa0, 0xa0,
+ 0x90, 0x90, 0x90,
+ 0x80, 0x80, 0x80,
+ 0x70, 0x70, 0x70,
+ 0x60, 0x60, 0x60,
+ 0x50, 0x50, 0x50,
+ 0x40, 0x40, 0x40,
+ 0x30, 0x30, 0x30,
+ 0x20, 0x20, 0x20,
+ 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00
+};
+
+const int SIDEOFFR[] = { 5, 5, 5, 5, 5, 5, 5, 5, 0 };
+const int SIDEOFFL[] = { 5, 5, 5, 5, 5, 5, 5, 5, 0 };
+const int SIDEOFFU[] = { 2, 2, 2, 2, 2, 2, 2, 2, 0 };
+const int SIDEOFFD[] = { 2, 2, 2, 2, 2, 2, 2, 2, 0 };
+const int DIAGOFFURX[] = { 4, 5, 2, 2, 3, 4, 2, 2, 0 };
+const int DIAGOFFURY[] = { 2, 3, 2, 2, 2, 3, 1, 1, 0 };
+const int DIAGOFFDRX[] = { 4, 5, 4, 3, 5, 4, 5, 1, 0 };
+const int DIAGOFFDRY[] = { 3, 2, 1, 2, 2, 1, 2, 1, 0 };
+const int DIAGOFFULX[] = { 4, 5, 4, 3, 3, 2, 2, 2, 0 };
+const int DIAGOFFULY[] = { 3, 3, 1, 2, 2, 1, 1, 1, 0 };
+const int DIAGOFFDLX[] = { 4, 5, 3, 3, 5, 4, 6, 1, 0 };
+const int DIAGOFFDLY[] = { 2, 2, 1, 2, 3, 1, 2, 1, 0 };
+
+const int RMOUSE[10][2] = {
+ { 0, 35 }, { 0, 0 }, { 36, 70 }, { 71, 106 }, { 107, 141 },
+ { 142, 177 }, { 178, 212 }, { 213, 248 }, { 249, 283 }, { 284, 318 }
+};
+
+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
+};
+
+const int INVCOORDS[][4] = {
+ { 23, 68, 15, 49 },
+ { 69, 114, 15, 49 },
+ { 115, 160, 15, 49 },
+ { 161, 206, 15, 49 },
+ { 207, 252, 15, 49 },
+ { 253, 298, 15, 49 },
+ { 23, 68, 50, 84 },
+ { 69, 114, 50, 84 },
+ { 115, 160, 50, 84 },
+ { 161, 206, 50, 84 },
+ { 207, 252, 50, 84 },
+ { 253, 298, 50, 84 },
+ { 23, 68, 85, 119 },
+ { 69, 114, 85, 119 },
+ { 115, 160, 85, 119 },
+ { 161, 206, 85, 119 },
+ { 207, 252, 85, 119 },
+ { 253, 298, 85, 119 },
+ { 23, 68, 120, 154 },
+ { 69, 114, 120, 154 },
+ { 115, 160, 120, 154 },
+ { 161, 206, 120, 154 },
+ { 207, 252, 120, 154 },
+ { 253, 298, 120, 154 },
+ { 237, 298, 177, 193 },
+ { 25, 85, 177, 193 }
+};
+
+} // End of namespace Access
diff --git a/engines/access/resources.h b/engines/access/resources.h
new file mode 100644
index 0000000000..8d59b1b1f1
--- /dev/null
+++ b/engines/access/resources.h
@@ -0,0 +1,53 @@
+/* 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 ACCESS_RESOURCES_H
+#define ACCESS_RESOURCES_H
+
+#include "common/scummsys.h"
+
+namespace Access {
+
+extern const byte INITIAL_PALETTE[18 * 3];
+
+extern const int SIDEOFFR[];
+extern const int SIDEOFFL[];
+extern const int SIDEOFFU[];
+extern const int SIDEOFFD[];
+extern const int DIAGOFFURX[];
+extern const int DIAGOFFURY[];
+extern const int DIAGOFFDRX[];
+extern const int DIAGOFFDRY[];
+extern const int DIAGOFFULX[];
+extern const int DIAGOFFULY[];
+extern const int DIAGOFFDLX[];
+extern const int DIAGOFFDLY[];
+
+extern const int RMOUSE[10][2];
+
+extern const char *const GENERAL_MESSAGES[];
+
+extern const int INVCOORDS[][4];
+
+} // End of namespace Access
+
+#endif /* ACCESS_RESOURCES_H */
diff --git a/engines/access/room.cpp b/engines/access/room.cpp
new file mode 100644
index 0000000000..607259ec6f
--- /dev/null
+++ b/engines/access/room.cpp
@@ -0,0 +1,833 @@
+/* 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 "access/access.h"
+#include "access/resources.h"
+#include "access/room.h"
+
+namespace Access {
+
+Room::Room(AccessEngine *vm) : Manager(vm) {
+ _function = FN_NONE;
+ _roomFlag = 0;
+ _playField = nullptr;
+ _playFieldWidth = _playFieldHeight = 0;
+ _matrixSize = 0;
+ _tile = nullptr;
+ _selectCommand = 0;
+ _conFlag = false;
+ _selectCommand = -1;
+}
+
+Room::~Room() {
+ delete[] _playField;
+ delete[] _tile;
+}
+
+void Room::freePlayField() {
+ delete[] _playField;
+ _playField = nullptr;
+}
+
+void Room::freeTileData() {
+ delete[] _tile;
+ _tile = nullptr;
+}
+
+void Room::doRoom() {
+ bool reloadFlag = false;
+
+ while (!_vm->shouldQuit()) {
+ if (!reloadFlag) {
+ _vm->_images.clear();
+ _vm->_newRects.clear();
+ _vm->_oldRects.clear();
+ _vm->_numAnimTimers = 0;
+
+ reloadRoom();
+ }
+
+ reloadFlag = false;
+ _vm->_startup = 8;
+ _function = FN_NONE;
+
+ while (!_vm->shouldQuit()) {
+ _vm->_images.clear();
+ if (_vm->_startup != -1 && --_vm->_startup == 0) {
+ _vm->_events->showCursor();
+ _vm->_screen->fadeIn();
+ }
+
+ // Poll for events
+ _vm->_canSaveLoad = true;
+ _vm->_events->pollEventsAndWait();
+ _vm->_canSaveLoad = false;
+
+ _vm->_player->walk();
+ _vm->_midi->midiRepeat();
+ _vm->_player->checkScroll();
+
+ doCommands();
+ if (_vm->shouldQuitOrRestart())
+ return;
+
+ // DOROOMFLASHBACK jump point
+ if (_function == FN_CLEAR1) {
+ clearRoom();
+ break;
+ } else if (_function == FN_CLEAR2) {
+ clearRoom();
+ return;
+ } else if (_function == FN_RELOAD) {
+ reloadRoom1();
+ reloadFlag = true;
+ break;
+ } else if (_function == FN_BREAK) {
+ break;
+ }
+
+ if (_vm->_player->_scrollFlag) {
+ _vm->copyBF1BF2();
+ _vm->_newRects.clear();
+ _function = FN_NONE;
+ roomLoop();
+
+ if (_function == FN_CLEAR1) {
+ clearRoom();
+ break;
+ } else {
+ _vm->plotList();
+ _vm->copyRects();
+ _vm->copyBF2Vid();
+ }
+ } else {
+ _vm->copyBF1BF2();
+ _vm->_newRects.clear();
+ _function = FN_NONE;
+
+ roomLoop();
+ if (_vm->shouldQuitOrRestart())
+ return;
+
+ if (_function == FN_CLEAR1) {
+ clearRoom();
+ break;
+ } else {
+ _vm->plotList();
+
+ if (_vm->_events->_mousePos.y < 177)
+ _vm->_events->setCursor(_vm->_events->_normalMouse);
+ else
+ _vm->_events->setCursor(CURSOR_ARROW);
+
+ _vm->copyBlocks();
+ }
+ }
+ }
+ }
+}
+
+void Room::clearRoom() {
+ if (_vm->_midi->_music) {
+ _vm->_midi->stopSong();
+ _vm->_midi->freeMusic();
+ }
+
+ _vm->_sound->freeSounds();
+ _vm->_numAnimTimers = 0;
+
+ _vm->_animation->freeAnimationData();
+ _vm->_scripts->freeScriptData();
+ _vm->freeCells();
+ freePlayField();
+ freeTileData();
+ _vm->_player->freeSprites();
+}
+
+void Room::loadRoomData(const byte *roomData) {
+ RoomInfo roomInfo(roomData, _vm->getGameID(), _vm->isCD(), _vm->isDemo());
+
+ _roomFlag = roomInfo._roomFlag;
+
+ _vm->_establishFlag = false;
+ if (roomInfo._estIndex != -1) {
+ _vm->_establishFlag = true;
+ if (_vm->_establishTable[roomInfo._estIndex] != 1) {
+ _vm->_establishTable[roomInfo._estIndex] = 1;
+ _vm->establish(0, roomInfo._estIndex);
+ }
+ }
+
+ _vm->_midi->freeMusic();
+ if (roomInfo._musicFile._fileNum != -1) {
+ _vm->_midi->loadMusic(roomInfo._musicFile);
+ _vm->_midi->midiPlay();
+ _vm->_midi->setLoop(true);
+ }
+
+ _vm->_scaleH1 = roomInfo._scaleH1;
+ _vm->_scaleH2 = roomInfo._scaleH2;
+ _vm->_scaleN1 = roomInfo._scaleN1;
+ _vm->_scaleT1 = ((_vm->_scaleH1 - _vm->_scaleH2) << 8) / _vm->_scaleN1;
+
+ if (roomInfo._playFieldFile._fileNum != -1) {
+ loadPlayField(roomInfo._playFieldFile._fileNum,
+ roomInfo._playFieldFile._subfile);
+ setupRoom();
+
+ _vm->_scaleMaxY = _playFieldHeight << 4;
+ }
+
+ // Load cells
+ _vm->loadCells(roomInfo._cells);
+
+ // Load script data
+ _vm->_scripts->freeScriptData();
+ if (roomInfo._scriptFile._fileNum != -1) {
+ Resource *newScript = _vm->_files->loadFile(roomInfo._scriptFile);
+ _vm->_scripts->setScript(newScript);
+ }
+
+ // Load animation data
+ _vm->_animation->freeAnimationData();
+ if (roomInfo._animFile._fileNum != -1) {
+ Resource *anim = _vm->_files->loadFile(roomInfo._animFile);
+ _vm->_animation->loadAnimations(anim);
+ delete anim;
+ }
+
+ _vm->_scale = _vm->_scaleI = roomInfo._scaleI;
+ _vm->_screen->setScaleTable(_vm->_scale);
+ _vm->_player->_scrollThreshold = roomInfo._scrollThreshold;
+
+ // Handle loading scene palette data
+ if (roomInfo._paletteFile._fileNum != -1) {
+ _vm->_screen->_startColor = roomInfo._startColor;
+ _vm->_screen->_numColors = roomInfo._numColors;
+ _vm->_screen->loadPalette(roomInfo._paletteFile._fileNum,
+ roomInfo._paletteFile._subfile);
+ }
+
+ // Load extra cells
+ _vm->_extraCells.clear();
+ for (uint i = 0; i < roomInfo._extraCells.size(); ++i)
+ _vm->_extraCells.push_back(roomInfo._extraCells[i]);
+
+ // Load sounds for the scene
+ _vm->_sound->loadSounds(roomInfo._sounds);
+}
+
+void Room::roomLoop() {
+ _vm->_scripts->_sequence = ROOM_SCRIPT;
+ _vm->_scripts->searchForSequence();
+ _vm->_scripts->executeScript();
+}
+
+void Room::setupRoom() {
+ Screen &screen = *_vm->_screen;
+ screen.setScaleTable(_vm->_scale);
+ screen.setBufferScan();
+
+ if (_roomFlag != 2)
+ screen.setIconPalette();
+
+ if (screen._vWindowWidth == _playFieldWidth) {
+ _vm->_scrollX = 0;
+ _vm->_scrollCol = 0;
+ } else {
+ int xv = _vm->_player->_rawPlayer.x / TILE_WIDTH;
+ _vm->_scrollX = _vm->_player->_rawPlayer.x % TILE_WIDTH;
+ _vm->_scrollCol = MAX(xv - (screen._vWindowWidth / 2), 0);
+
+ int sx = _vm->_scrollCol + screen._vWindowWidth - _playFieldWidth;
+ if (sx >= 0) {
+ _vm->_scrollCol -= sx + 1;
+ }
+ }
+
+ if (screen._vWindowHeight == _playFieldHeight) {
+ _vm->_scrollY = 0;
+ _vm->_scrollRow = 0;
+ } else {
+ _vm->_scrollY = _vm->_player->_rawPlayer.y -
+ (_vm->_player->_rawPlayer.y / 16) * 16;
+ int yc = MAX((_vm->_player->_rawPlayer.y >> 4) -
+ (screen._vWindowHeight / 2), 0);
+ _vm->_scrollRow = yc;
+
+ yc = yc + screen._vWindowHeight - _playFieldHeight;
+ if (yc >= 0) {
+ _vm->_scrollRow = _playFieldHeight - screen._vWindowHeight;
+ _vm->_scrollY = 0;
+ }
+ }
+}
+
+void Room::setWallCodes() {
+ _jetFrame.clear();
+ _jetFrame.resize(_plotter._walls.size());
+
+ _vm->_player->_rawXTemp = _vm->_player->_rawPlayer.x;
+ _vm->_player->_rawYTemp = _vm->_player->_rawPlayer.y;
+}
+
+void Room::buildScreen() {
+ int scrollCol = _vm->_scrollCol;
+ int offset = 0;
+
+ // Clear current background buffer
+ _vm->_buffer1.clearBuffer();
+
+ // WORKAROUND: Original's use of '+ 1' would frequently cause memory overruns
+ int w = MIN(_vm->_screen->_vWindowWidth + 1, _playFieldWidth);
+
+ // Loop through drawing each column of tiles forming the background
+ for (int idx = 0; idx < w; offset += TILE_WIDTH, ++idx) {
+ buildColumn(_vm->_scrollCol, offset);
+ ++_vm->_scrollCol;
+ }
+
+ _vm->_scrollCol = scrollCol;
+ _vm->copyBF1BF2();
+}
+
+void Room::buildColumn(int playX, int screenX) {
+ if (playX < 0 || playX >= _playFieldWidth)
+ return;
+
+ const byte *pSrc = _playField + _vm->_scrollRow *
+ _playFieldWidth + playX;
+
+ // WORKAROUND: Original's use of '+ 1' would frequently cause memory overruns
+ int h = MIN(_vm->_screen->_vWindowHeight + 1, _playFieldHeight);
+
+ for (int y = 0; y < h; ++y) {
+ byte *pTile = _tile + (*pSrc << 8);
+ byte *pDest = (byte *)_vm->_buffer1.getBasePtr(screenX, y * TILE_HEIGHT);
+
+ for (int tileY = 0; tileY < TILE_HEIGHT; ++tileY) {
+ Common::copy(pTile, pTile + TILE_WIDTH, pDest);
+ pTile += TILE_WIDTH;
+ pDest += _vm->_buffer1.pitch;
+ }
+
+ pSrc += _playFieldWidth;
+ }
+}
+
+void Room::buildRow(int playY, int screenY) {
+ if (playY < 0 || playY >= _playFieldHeight)
+ return;
+ assert(screenY <= (_vm->_screen->h - TILE_HEIGHT));
+
+ const byte *pSrc = _playField + playY *_playFieldWidth + _vm->_scrollCol;
+
+ // WORKAROUND: Original's use of '+ 1' would frequently cause memory overruns
+ int w = MIN(_vm->_screen->_vWindowWidth + 1, _playFieldWidth);
+
+ for (int x = 0; x < w; ++x) {
+ byte *pTile = _tile + (*pSrc << 8);
+ byte *pDest = (byte *)_vm->_buffer1.getBasePtr(x * TILE_WIDTH, screenY);
+
+ for (int tileY = 0; tileY < TILE_HEIGHT; ++tileY) {
+ Common::copy(pTile, pTile + TILE_WIDTH, pDest);
+ pTile += TILE_WIDTH;
+ pDest += _vm->_buffer1.pitch;
+ }
+
+ ++pSrc;
+ }
+}
+
+void Room::loadPlayField(int fileNum, int subfile) {
+ Resource *playData = _vm->_files->loadFile(fileNum, subfile);
+ byte header[16];
+ playData->_stream->read(&header[0], 16);
+ Screen &screen = *_vm->_screen;
+
+ // Copy the new palette
+ screen.loadRawPalette(playData->_stream);
+
+ // Copy off the tile data
+ 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];
+ _playField = new byte[_matrixSize];
+ playData->_stream->read(_playField, _matrixSize);
+
+ // Load the plotter data
+ int numWalls = READ_LE_UINT16(&header[6]);
+ int numBlocks = header[8];
+ _plotter.load(playData->_stream, numWalls, numBlocks);
+
+ _playFieldWidth = header[0];
+ _playFieldHeight = header[1];
+ screen._vWindowWidth = header[3];
+ screen._vWindowBytesWide = screen._vWindowWidth << 4;
+ screen._bufferBytesWide = screen._vWindowBytesWide + 16;
+ screen._vWindowHeight = header[4];
+ screen._vWindowLinesTall = screen._vWindowHeight << 4;
+
+ _vm->_screen->setBufferScan();
+ delete playData;
+}
+
+/*------------------------------------------------------------------------*/
+
+Plotter::Plotter() {
+ _delta = _blockIn = 0;
+}
+
+void Plotter::load(Common::SeekableReadStream *stream, int wallCount, int blockCount) {
+ // Load the wall count
+ _walls.resize(wallCount);
+
+ for (int i = 0; i < wallCount; ++i)
+ _walls[i].left = stream->readSint16LE();
+ for (int i = 0; i < wallCount; ++i)
+ _walls[i].top = stream->readSint16LE();
+ for (int i = 0; i < wallCount; ++i)
+ _walls[i].right = stream->readSint16LE();
+ for (int i = 0; i < wallCount; ++i)
+ _walls[i].bottom = stream->readSint16LE();
+
+ // Load the block list
+ _blocks.resize(blockCount);
+
+ for (int i = 0; i < blockCount; ++i)
+ _blocks[i].left = stream->readSint16LE();
+ for (int i = 0; i < blockCount; ++i)
+ _blocks[i].top = stream->readSint16LE();
+ for (int i = 0; i < blockCount; ++i)
+ _blocks[i].right = stream->readSint16LE();
+ for (int i = 0; i < blockCount; ++i)
+ _blocks[i].bottom = stream->readSint16LE();
+}
+
+void Room::doCommands() {
+ int commandId = 0;
+ Common::KeyState keyState;
+
+ if (_vm->_startup != -1)
+ return;
+
+ if (_vm->_inventory->_invChangeFlag)
+ _vm->_inventory->refreshInventory();
+
+ if (_vm->_screen->_screenChangeFlag) {
+ _vm->_screen->_screenChangeFlag = false;
+ _vm->_events->_cursorExitFlag = true;
+ executeCommand(7);
+ }
+ else if (_vm->_events->_wheelUp || _vm->_events->_wheelDown) {
+ // Handle scrolling mouse wheel
+ cycleCommand(_vm->_events->_wheelUp ? 1 : -1);
+
+ } else if (_vm->_events->_middleButton) {
+ // Switch back to walking
+ handleCommand(7);
+
+ } else if (_vm->_events->_leftButton) {
+ if (_vm->_events->_mouseRow >= 22) {
+ // Mouse in user interface area
+ for (commandId = 0; commandId < 10; ++commandId) {
+ if (_vm->_events->_mousePos.x >= RMOUSE[commandId][0] &&
+ _vm->_events->_mousePos.x < RMOUSE[commandId][1])
+ break;
+ }
+ if (commandId < 10)
+ handleCommand(commandId);
+
+ } else {
+ // Mouse click in main game area
+ mainAreaClick();
+ }
+ } else if (_vm->_events->getKey(keyState)) {
+ if (keyState.keycode == Common::KEYCODE_F1)
+ handleCommand(keyState.keycode - Common::KEYCODE_F1 + 1);
+ else if (keyState.keycode >= Common::KEYCODE_F2 && keyState.keycode <= Common::KEYCODE_F10)
+ handleCommand(keyState.keycode - Common::KEYCODE_F1);
+ }
+}
+
+void Room::cycleCommand(int incr) {
+ int command = _selectCommand + incr;
+ if (command < -1)
+ command = 6;
+ else if (command == -1)
+ command = 7;
+ else if (command == 1)
+ command = (incr == 1) ? 2 : 0;
+ else if (command == 4)
+ command = (incr == 1) ? 5 : 3;
+
+ handleCommand(command);
+}
+
+void Room::handleCommand(int commandId) {
+ if (commandId == 1)
+ --commandId;
+
+ if (commandId == 9) {
+ _vm->_events->debounceLeft();
+ _vm->_canSaveLoad = true;
+ _vm->openMainMenuDialog();
+ _vm->_canSaveLoad = false;
+ } else if (commandId == _selectCommand) {
+ _vm->_events->debounceLeft();
+ commandOff();
+ } else {
+ _vm->_events->debounceLeft();
+ executeCommand(commandId);
+ }
+}
+
+void Room::executeCommand(int commandId) {
+ EventsManager &events = *_vm->_events;
+ _selectCommand = commandId;
+
+ switch (commandId) {
+ case 0:
+ events.forceSetCursor(CURSOR_LOOK);
+ break;
+ case 2:
+ events.forceSetCursor(CURSOR_USE);
+ break;
+ case 3:
+ events.forceSetCursor(CURSOR_TAKE);
+ break;
+ case 4:
+ events.setCursor(CURSOR_ARROW);
+ if (_vm->_inventory->newDisplayInv() == 2) {
+ commandOff();
+ return;
+ }
+ break;
+ case 5:
+ events.forceSetCursor(CURSOR_CLIMB);
+ break;
+ case 6:
+ events.forceSetCursor(CURSOR_TALK);
+ break;
+ case 7:
+ walkCursor();
+ return;
+ case 8:
+ events.forceSetCursor(CURSOR_HELP);
+ break;
+ default:
+ break;
+ }
+
+ // Draw the default toolbar menu at the bottom of the screen
+ roomMenu();
+ _vm->_screen->saveScreen();
+ _vm->_screen->setDisplayScan();
+
+ // Get the toolbar icons resource
+ Resource *iconData = _vm->_files->loadFile("ICONS.LZ");
+ SpriteResource *spr = new SpriteResource(_vm, iconData);
+ delete iconData;
+
+ // Draw the button as selected
+ _vm->_screen->plotImage(spr, _selectCommand + 2,
+ Common::Point(RMOUSE[_selectCommand][0], 176));
+
+ _vm->_screen->restoreScreen();
+ _vm->_boxSelect = true;
+}
+
+void Room::walkCursor() {
+ EventsManager &events = *_vm->_events;
+
+ events.forceSetCursor(CURSOR_CROSSHAIRS);
+ _vm->_scripts->_sequence = 5000;
+ _vm->_scripts->searchForSequence();
+ roomMenu();
+ _selectCommand = -1;
+
+ _conFlag = true;
+ while (_conFlag && !_vm->shouldQuitOrRestart()) {
+ _conFlag = false;
+ _vm->_scripts->executeScript();
+ }
+
+ _vm->_boxSelect = true;
+}
+
+void Room::commandOff() {
+ _selectCommand = -1;
+ _vm->_events->forceSetCursor(CURSOR_CROSSHAIRS);
+ roomMenu();
+}
+
+int Room::checkBoxes() {
+ return checkBoxes1(_vm->_player->_rawPlayer);
+}
+
+int Room::checkBoxes1(const Common::Point &pt) {
+ return checkBoxes2(pt, 0, _plotter._blocks.size());
+}
+
+int Room::checkBoxes2(const Common::Point &pt, int start, int count) {
+ for (; count > 0; --count, ++start) {
+ if (_plotter._blocks[start].contains(pt)) {
+ _plotter._blockIn = start;
+ return start;
+ }
+ }
+
+ return -1;
+}
+
+void Room::checkBoxes3() {
+ Common::Point pt = _vm->_events->calcRawMouse();
+
+ for (uint start = 0; start < _plotter._blocks.size(); ++start) {
+ if (_plotter._blocks[start].contains(pt)) {
+ _plotter._blockIn = start;
+ if (!(validateBox(start) & 0x80)) {
+ _vm->_events->debounceLeft();
+ _vm->_boxSelect = start;
+
+ _conFlag = true;
+ while (_conFlag && !_vm->shouldQuitOrRestart()) {
+ _conFlag = false;
+ _vm->_scripts->executeScript();
+ }
+
+ _vm->_boxSelect = true;
+ return;
+ }
+ }
+ }
+}
+
+int Room::validateBox(int boxId) {
+ _vm->_scripts->_sequence = boxId;
+ _vm->_scripts->searchForSequence();
+ return _vm->_scripts->executeScript();
+}
+
+void Room::swapOrg() {
+ SWAP<int>(_vm->_screen->_orgX1, _vm->_screen->_orgX2);
+ SWAP<int>(_vm->_screen->_orgY1, _vm->_screen->_orgY2);
+}
+
+int Room::calcLR(int yp) {
+ const Screen &screen = *_vm->_screen;
+
+ int yv = (yp - screen._orgY1) * (screen._orgX2 - screen._orgX1);
+ int yd = screen._orgY2 - screen._orgY1;
+
+ int rem = (yv % yd) << 1;
+ yv /= yd;
+ if (rem >= yd || rem < 0)
+ ++yv;
+
+ return yv + screen._orgX1;
+}
+
+int Room::calcUD(int xp) {
+ const Screen &screen = *_vm->_screen;
+
+ int xv = (xp - screen._orgX1) * (screen._orgY2 - screen._orgY1);
+ int xd = screen._orgX2 - screen._orgX1;
+
+ int rem = (xv % xd) << 1;
+ xv /= xd;
+ if (rem >= xd || rem < 0)
+ ++xv;
+
+ return xv + screen._orgY1;
+}
+
+bool Room::codeWalls() {
+ Screen &screen = *_vm->_screen;
+ Player &player = *_vm->_player;
+
+ if (_plotter._walls.size() == 0)
+ return false;
+
+ for (uint i = 0; i < _plotter._walls.size(); ++i) {
+ Common::Rect &r = _plotter._walls[i];
+ JetFrame &jf = _jetFrame[i];
+
+ jf._wallCode = 0;
+ jf._wallCode1 = 0;
+ screen._orgX1 = r.left;
+ screen._orgY1 = r.top;
+ screen._orgX2 = r.right;
+ screen._orgY2 = r.bottom;
+
+ if (screen._orgY2 != screen._orgY1) {
+ if (screen._orgY2 < screen._orgY1)
+ swapOrg();
+
+ if ((player._rawYTemp >= screen._orgY1) &&
+ (player._rawYTemp <= screen._orgY2)) {
+ jf._wallCode |= (calcLR(player._rawYTemp) - player._rawXTemp) < 0 ? 2 : 1;
+ jf._wallCode1 |= (calcLR(player._rawYTemp) -
+ (player._rawXTemp + player._playerOffset.x)) < 0 ? 2 : 1;
+ }
+ }
+
+ if (screen._orgX2 != screen._orgX1) {
+ if (screen._orgX2 < screen._orgX1)
+ swapOrg();
+
+ if ((player._rawXTemp >= screen._orgX1) &&
+ (player._rawXTemp <= screen._orgX2)) {
+ int y = screen._orgY2;
+ if (y != screen._orgY1)
+ y = calcUD(player._rawXTemp);
+
+ jf._wallCode |= (player._rawYTemp - y) < 0 ? 4 : 8;
+ }
+
+ int x = player._rawXTemp + player._playerOffset.x;
+ if ((x >= screen._orgX1) && (x <= screen._orgX2)) {
+ int y = screen._orgY2;
+ if (screen._orgY2 != screen._orgY1)
+ y = calcUD(player._rawXTemp + player._playerOffset.x);
+
+ jf._wallCode1 |= (player._rawYTemp - y) < 0 ? 4 : 8;
+ }
+ }
+ }
+
+ for (uint i = 0; i < _jetFrame.size(); ++i) {
+ JetFrame &jf = _jetFrame[i];
+ if (checkCode(jf._wallCode, jf._wallCodeOld) ||
+ checkCode(jf._wallCode1, jf._wallCode1Old))
+ return true;
+ }
+
+ // Copy the current wall calculations to the old properties
+ for (uint i = 0; i < _jetFrame.size(); ++i) {
+ JetFrame &jf = _jetFrame[i];
+ jf._wallCodeOld = jf._wallCode;
+ jf._wallCode1Old = jf._wallCode1;
+ }
+
+ return false;
+}
+
+bool Room::checkCode(int v1, int v2) {
+ Player &p = *_vm->_player;
+
+ if (!v1 || !v2 || (v1 == v2))
+ return false;
+
+ if (v1 & 1) {
+ if (v2 & 2) {
+ p._collideFlag = true;
+ return true;
+ }
+ } else if (v1 & 2) {
+ if (v2 & 1) {
+ p._collideFlag = true;
+ return true;
+ }
+ } else if (v1 & 4) {
+ if (v2 & 8) {
+ p._collideFlag = true;
+ return true;
+ }
+ } else if (v1 & 8) {
+ if (v2 & 4) {
+ p._collideFlag = true;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/*------------------------------------------------------------------------*/
+
+RoomInfo::RoomInfo(const byte *data, int gameType, bool isCD, bool isDemo) {
+ Common::MemoryReadStream stream(data, 999);
+
+ _roomFlag = stream.readByte();
+
+ if (gameType == GType_Amazon) {
+ if (isCD)
+ _estIndex = stream.readSint16LE();
+ else {
+ _estIndex = -1;
+ if (!isDemo)
+ stream.readSint16LE();
+ }
+ } else
+ _estIndex = -1;
+
+ _musicFile.load(stream);
+ _scaleH1 = stream.readByte();
+ _scaleH2 = stream.readByte();
+ _scaleN1 = stream.readByte();
+ _playFieldFile.load(stream);
+
+ for (byte cell = stream.readByte(); cell != 0xff; cell = stream.readByte()) {
+ CellIdent ci;
+ ci._cell = cell;
+ ci.load(stream);
+
+ _cells.push_back(ci);
+ }
+
+ _scriptFile.load(stream);
+ _animFile.load(stream);
+ _scaleI = stream.readByte();
+ _scrollThreshold = stream.readByte();
+ _paletteFile.load(stream);
+ if (_paletteFile._fileNum == -1) {
+ _startColor = _numColors = 0;
+ } else {
+ _startColor = stream.readUint16LE();
+ _numColors = stream.readUint16LE();
+ }
+
+ for (int16 v = stream.readSint16LE(); v != -1; v = stream.readSint16LE()) {
+ ExtraCell ec;
+ ec._vid._fileNum = v;
+ ec._vid._subfile = stream.readSint16LE();
+
+ _extraCells.push_back(ec);
+ }
+
+ for (int16 fileNum = stream.readSint16LE(); fileNum != -1; fileNum = stream.readSint16LE()) {
+ SoundIdent fi;
+ fi._fileNum = fileNum;
+ fi._subfile = stream.readUint16LE();
+ fi._priority = stream.readUint16LE();
+
+ _sounds.push_back(fi);
+ }
+}
+
+} // End of namespace Access
diff --git a/engines/access/room.h b/engines/access/room.h
new file mode 100644
index 0000000000..eec273e3f4
--- /dev/null
+++ b/engines/access/room.h
@@ -0,0 +1,201 @@
+/* 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 ACCESS_ROOM_H
+#define ACCESS_ROOM_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/rect.h"
+#include "access/data.h"
+
+#define TILE_WIDTH 16
+#define TILE_HEIGHT 16
+
+namespace Access {
+
+class Plotter {
+public:
+ Common::Array<Common::Rect> _walls;
+ Common::Array<Common::Rect> _blocks;
+ int _blockIn;
+ int _delta;
+public:
+ Plotter();
+
+ void load(Common::SeekableReadStream *stream, int wallCount, int blockCount);
+};
+
+class JetFrame {
+public:
+ int _wallCode;
+ int _wallCodeOld;
+ int _wallCode1;
+ int _wallCode1Old;
+
+ JetFrame() {
+ _wallCode = _wallCodeOld = 0;
+ _wallCode1 = _wallCode1Old = 0;
+ }
+};
+
+enum Function { FN_NONE = 0, FN_CLEAR1 = 1, FN_CLEAR2 = 2, FN_RELOAD = 3, FN_BREAK = 4 };
+
+class Room : public Manager {
+private:
+ void roomLoop();
+
+ void loadPlayField(int fileNum, int subfile);
+
+ void commandOff();
+
+ void swapOrg();
+ int calcLR(int yp);
+ int calcUD(int xp);
+
+ /**
+ * Cycles forwards or backwards through the list of commands
+ */
+ void cycleCommand(int incr);
+
+ bool checkCode(int v1, int v2);
+protected:
+ void loadRoomData(const byte *roomData);
+
+ /**
+ * Free the playfield data
+ */
+ void freePlayField();
+
+ /**
+ * Free tile data
+ */
+ void freeTileData();
+
+ int checkBoxes();
+ int checkBoxes1(const Common::Point &pt);
+ int checkBoxes2(const Common::Point &pt, int start, int count);
+ void checkBoxes3();
+
+ int validateBox(int boxId);
+
+ /**
+ * Inner handler for switching to a given command mode
+ */
+ void executeCommand(int commandId);
+
+ virtual void reloadRoom() = 0;
+
+ virtual void reloadRoom1() = 0;
+
+ virtual void setupRoom();
+
+ virtual void doCommands();
+
+ virtual void mainAreaClick() = 0;
+
+ virtual void walkCursor();
+public:
+ Plotter _plotter;
+ Common::Array<JetFrame> _jetFrame;
+ Function _function;
+ int _roomFlag;
+ byte *_playField;
+ int _matrixSize;
+ int _playFieldWidth;
+ int _playFieldHeight;
+ byte *_tile;
+ int _selectCommand;
+ bool _conFlag;
+public:
+ Room(AccessEngine *vm);
+
+ virtual ~Room();
+
+ void doRoom();
+
+ virtual void loadRoom(int roomNumber) = 0;
+
+ virtual void roomMenu() = 0;
+
+ /**
+ * Clear all the data used by the room
+ */
+ virtual void clearRoom();
+
+ /**
+ * Builds up a game screen
+ */
+ void buildScreen();
+
+ /**
+ * Draw a column of a game scene
+ */
+ void buildColumn(int playX, int screenX);
+
+ /**
+ * Draw a row of a game scene
+ */
+ void buildRow(int playY, int screenY);
+
+ virtual void init4Quads() = 0;
+
+ void setWallCodes();
+
+ bool codeWalls();
+
+ /**
+ * Switch to a given command mode
+ */
+ void handleCommand(int commandId);
+};
+
+class RoomInfo {
+public:
+ struct SoundIdent : FileIdent {
+ int _priority;
+ };
+public:
+ int _roomFlag;
+ int _estIndex;
+ FileIdent _musicFile;
+ int _scaleH1;
+ int _scaleH2;
+ int _scaleN1;
+ FileIdent _playFieldFile;
+ Common::Array<CellIdent> _cells;
+ FileIdent _scriptFile;
+ FileIdent _animFile;
+ int _scaleI;
+ int _scrollThreshold;
+ FileIdent _paletteFile;
+ int _startColor;
+ int _numColors;
+ Common::Array<ExtraCell> _extraCells;
+ Common::Array<SoundIdent> _sounds;
+public:
+ RoomInfo(const byte *data, int gameType, bool isCD, bool isDemo);
+};
+
+} // End of namespace Access
+
+#endif /* ACCESS_ROOM_H */
diff --git a/engines/access/screen.cpp b/engines/access/screen.cpp
new file mode 100644
index 0000000000..970a8f3079
--- /dev/null
+++ b/engines/access/screen.cpp
@@ -0,0 +1,369 @@
+/* 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/algorithm.h"
+#include "common/endian.h"
+#include "common/rect.h"
+#include "common/textconsole.h"
+#include "common/system.h"
+#include "graphics/palette.h"
+#include "access/access.h"
+#include "access/screen.h"
+#include "access/resources.h"
+
+namespace Access {
+
+#define VGA_COLOR_TRANS(x) ((x) * 255 / 63)
+
+Screen::Screen(AccessEngine *vm) : _vm(vm) {
+ create(320, 200);
+ Common::fill(&_tempPalette[0], &_tempPalette[PALETTE_SIZE], 0);
+ Common::fill(&_manPal[0], &_manPal[0x60], 0);
+ Common::fill(&_scaleTable1[0], &_scaleTable1[256], 0);
+ Common::fill(&_scaleTable2[0], &_scaleTable2[256], 0);
+ _savedPaletteCount = 0;
+ if (_vm->isCD())
+ _vesaMode = 0;
+ else
+ _vesaMode = 1;
+
+ _vesaCurrentWin = 0;
+ _currentPanel = 0;
+ _hideFlag = true;
+ _startColor = _numColors = 0;
+ _windowXAdd = _windowYAdd = 0;
+ _screenYOff = 0;
+ _screenChangeFlag = false;
+
+ _bufferBytesWide = _vWindowBytesWide = this->w;
+ _vWindowLinesTall = this->h;
+ _vWindowWidth = _vWindowHeight = 0;
+ _clipWidth = _vWindowBytesWide - 1;
+ _clipHeight = _vWindowLinesTall - 1;
+ _startCycle = 0;
+ _cycleStart = 0;
+ _endCycle = 0;
+}
+
+void Screen::clearScreen() {
+ clearBuffer();
+ if (_vesaMode)
+ _vm->_clearSummaryFlag = true;
+
+ addDirtyRect(Common::Rect(0, 0, this->w, this->h));
+}
+
+void Screen::setDisplayScan() {
+ _clipWidth = this->w - 1;
+ _clipHeight = this->h - 1;
+ _windowXAdd = _windowYAdd = 0;
+ _vm->_scrollX = _vm->_scrollY = 0;
+ _vm->_scrollCol = _vm->_scrollRow = 0;
+ _bufferStart.x = _bufferStart.y = 0;
+ _screenYOff = 0;
+}
+
+void Screen::setPanel(int num) {
+ assert(num < 4);
+ _currentPanel = num;
+ _msVirtualOffset = _virtualOffsetsTable[num];
+}
+
+void Screen::updateScreen() {
+ // 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, this->pitch, r.left, r.top,
+ r.width(), r.height());
+ }
+
+ // Signal the physical screen to update
+ g_system->updateScreen();
+ _dirtyRects.clear();
+}
+
+void Screen::setInitialPalettte() {
+ Common::copy(&INITIAL_PALETTE[0], &INITIAL_PALETTE[18 * 3], _rawPalette);
+ Common::fill(&_rawPalette[18 * 3], &_rawPalette[PALETTE_SIZE], 0);
+
+ g_system->getPaletteManager()->setPalette(INITIAL_PALETTE, 0, 18);
+}
+
+void Screen::loadPalette(int fileNum, int subfile) {
+ Resource *res = _vm->_files->loadFile(fileNum, subfile);
+ byte *palette = res->data();
+ Common::copy(palette, palette + (_numColors * 3), &_rawPalette[_startColor * 3]);
+ delete res;
+}
+
+void Screen::setPalette() {
+ g_system->getPaletteManager()->setPalette(&_rawPalette[0], 0, PALETTE_COUNT);
+}
+
+void Screen::loadRawPalette(Common::SeekableReadStream *stream) {
+ stream->read(&_rawPalette[0], PALETTE_SIZE);
+ for (byte *p = &_rawPalette[0]; p < &_rawPalette[PALETTE_SIZE]; ++p)
+ *p = VGA_COLOR_TRANS(*p);
+}
+
+void Screen::updatePalette() {
+ g_system->getPaletteManager()->setPalette(&_tempPalette[0], 0, PALETTE_COUNT);
+ updateScreen();
+}
+
+void Screen::savePalette() {
+ Common::copy(&_rawPalette[0], &_rawPalette[PALETTE_SIZE],
+ &_savedPalettes[_savedPaletteCount][0]);
+
+ if (++_savedPaletteCount == 2)
+ _savedPaletteCount = 1;
+}
+
+void Screen::restorePalette() {
+ if (--_savedPaletteCount < 0)
+ _savedPaletteCount = 0;
+
+ Common::copy(&_savedPalettes[_savedPaletteCount][0],
+ &_savedPalettes[_savedPaletteCount][PALETTE_SIZE], &_rawPalette[0]);
+}
+
+void Screen::getPalette(byte *pal) {
+ g_system->getPaletteManager()->grabPalette(pal, 0, 256);
+}
+
+void Screen::forceFadeOut() {
+ const int FADE_AMOUNT = 2;
+ bool repeatFlag;
+ byte *srcP;
+ int count;
+
+ do {
+ repeatFlag = false;
+ for (srcP = &_tempPalette[0], count = 0; count < PALETTE_SIZE; ++count, ++srcP) {
+ int v = *srcP;
+ if (v) {
+ repeatFlag = true;
+ *srcP = MAX(*srcP - FADE_AMOUNT, 0);
+ }
+ }
+
+ updatePalette();
+ _vm->_events->pollEventsAndWait();
+ } while (repeatFlag && !_vm->shouldQuit());
+}
+
+void Screen::forceFadeIn() {
+ Common::fill(&_tempPalette[0], &_tempPalette[PALETTE_SIZE], 0);
+
+ const int FADE_AMOUNT = 2;
+ bool repeatFlag;
+ do {
+ repeatFlag = false;
+ const byte *srcP = &_rawPalette[0];
+ byte *destP = &_tempPalette[0];
+
+ for (int idx = 0; idx < PALETTE_SIZE; ++idx, ++srcP, ++destP) {
+ if (*destP != *srcP) {
+ repeatFlag = true;
+ *destP = MAX((int)*destP + FADE_AMOUNT, (int)*srcP);
+ }
+ }
+
+ updatePalette();
+ _vm->_events->pollEventsAndWait();
+ } while (repeatFlag);
+}
+
+void Screen::copyBuffer(const byte *data) {
+ byte *destP = (byte *)getPixels();
+ Common::copy(data, data + (h * w), destP);
+ g_system->copyRectToScreen(destP, w, 0, 0, w, h);
+}
+
+void Screen::setBufferScan() {
+ _clipWidth = _vWindowBytesWide - 1;
+ _windowXAdd = (320 - _clipWidth) >> 1;
+ _clipHeight = _vWindowLinesTall - 1;
+ _windowYAdd = (176 - _clipHeight) >> 1;
+}
+
+void Screen::setScaleTable(int scale) {
+ int total = 0;
+ for (int idx = 0; idx < 256; ++idx) {
+ _scaleTable1[idx] = total >> 8;
+ _scaleTable2[idx] = total & 0xff;
+ total += scale;
+ }
+}
+
+void Screen::saveScreen() {
+ _screenSave._clipWidth = _clipWidth;
+ _screenSave._clipHeight = _clipHeight;
+ _screenSave._windowXAdd = _windowXAdd;
+ _screenSave._windowYAdd = _windowYAdd;
+ _screenSave._scroll.x = _vm->_scrollX;
+ _screenSave._scroll.y = _vm->_scrollY;
+ _screenSave._scrollCol = _vm->_scrollCol;
+ _screenSave._scrollRow = _vm->_scrollRow;
+ _screenSave._bufferStart.x = _bufferStart.x;
+ _screenSave._bufferStart.y = _bufferStart.y;
+ _screenSave._screenYOff = _screenYOff;
+}
+
+void Screen::restoreScreen() {
+ _clipWidth = _screenSave._clipWidth;
+ _clipHeight = _screenSave._clipHeight;
+ _windowXAdd = _screenSave._windowXAdd;
+ _windowYAdd = _screenSave._windowYAdd;
+ _vm->_scrollX = _screenSave._scroll.x;
+ _vm->_scrollY = _screenSave._scroll.y;
+ _vm->_scrollCol = _screenSave._scrollCol;
+ _vm->_scrollRow = _screenSave._scrollRow;
+ _bufferStart.x = _screenSave._bufferStart.x;
+ _bufferStart.y = _screenSave._bufferStart.y;
+ _screenYOff = _screenSave._screenYOff;
+}
+
+void Screen::copyBlock(ASurface *src, const Common::Rect &bounds) {
+ Common::Rect destBounds = bounds;
+ destBounds.translate(_windowXAdd, _windowYAdd + _screenYOff);
+
+ copyRectToSurface(*src, destBounds.left, destBounds.top, bounds);
+ addDirtyRect(destBounds);
+}
+
+void Screen::restoreBlock() {
+ if (!_savedBounds.isEmpty())
+ addDirtyRect(_savedBounds);
+ ASurface::restoreBlock();
+}
+
+void Screen::drawRect() {
+ addDirtyRect(Common::Rect(_orgX1, _orgY1, _orgX2, _orgY2));
+ ASurface::drawRect();
+}
+
+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::transBlitFrom(src, destPos);
+}
+
+void Screen::transBlitFrom(ASurface *src, const Common::Rect &bounds) {
+ addDirtyRect(bounds);
+ ASurface::transBlitFrom(src, bounds);
+}
+
+void Screen::blitFrom(Graphics::Surface &src) {
+ addDirtyRect(Common::Rect(0, 0, src.w, src.h));
+ ASurface::blitFrom(src);
+}
+
+void Screen::copyBuffer(Graphics::Surface *src) {
+ addDirtyRect(Common::Rect(0, 0, src->w, src->h));
+ ASurface::copyBuffer(src);
+}
+
+void Screen::setPaletteCycle(int startCycle, int endCycle, int timer) {
+ _startCycle = _cycleStart = startCycle;
+ _endCycle = endCycle;
+
+ TimerEntry &te = _vm->_timers[6];
+ te._timer = te._initTm = timer;
+ te._flag++;
+}
+
+void Screen::cyclePaletteForward() {
+ cyclePaletteBackwards();
+}
+
+void Screen::cyclePaletteBackwards() {
+ if (!_vm->_timers[6]._flag) {
+ _vm->_timers[6]._flag++;
+ byte *pStart = &_rawPalette[_cycleStart * 3];
+ byte *pEnd = &_rawPalette[_endCycle * 3];
+
+ for (int idx = _startCycle; idx < _endCycle; ++idx) {
+ g_system->getPaletteManager()->setPalette(pStart, idx, 1);
+
+ pStart += 3;
+ if (pStart == pEnd)
+ pStart = &_rawPalette[_cycleStart * 3];
+ }
+
+ if (--_cycleStart <= _startCycle)
+ _cycleStart = _endCycle - 1;
+
+ g_system->updateScreen();
+ g_system->delayMillis(10);
+ }
+}
+
+void Screen::addDirtyRect(const Common::Rect &r) {
+ _dirtyRects.push_back(r);
+ assert(r.isValidRect() && r.width() > 0 && r.height() > 0);
+}
+
+void Screen::mergeDirtyRects() {
+ Common::List<Common::Rect>::iterator rOuter, rInner;
+
+ // Ensure dirty rect list has at least two entries
+ rOuter = _dirtyRects.begin();
+ for (int i = 0; i < 2; ++i, ++rOuter) {
+ if (rOuter == _dirtyRects.end())
+ return;
+ }
+
+ // 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();
+}
+
+
+} // End of namespace Access
diff --git a/engines/access/screen.h b/engines/access/screen.h
new file mode 100644
index 0000000000..d45a533f9a
--- /dev/null
+++ b/engines/access/screen.h
@@ -0,0 +1,182 @@
+/* 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 ACCESS_SCREEN_H
+#define ACCESS_SCREEN_H
+
+#include "common/scummsys.h"
+#include "common/rect.h"
+#include "common/stream.h"
+#include "access/asurface.h"
+
+namespace Access {
+
+class AccessEngine;
+
+#define PALETTE_COUNT 256
+#define PALETTE_SIZE (256 * 3)
+
+struct ScreenSave {
+ int _clipWidth;
+ int _clipHeight;
+ int _windowXAdd;
+ int _windowYAdd;
+ Common::Point _scroll;
+ int _scrollCol;
+ int _scrollRow;
+ Common::Point _bufferStart;
+ int _screenYOff;
+};
+
+class Screen : public ASurface {
+private:
+ AccessEngine *_vm;
+ byte _tempPalette[PALETTE_SIZE];
+ byte _rawPalette[PALETTE_SIZE];
+ byte _savedPalettes[2][PALETTE_SIZE];
+ int _savedPaletteCount;
+ int _vesaCurrentWin;
+ int _currentPanel;
+ Common::Point _msVirtualOffset;
+ Common::Point _virtualOffsetsTable[4];
+ bool _hideFlag;
+ ScreenSave _screenSave;
+ int _startCycle;
+ int _cycleStart;
+ int _endCycle;
+ Common::List<Common::Rect> _dirtyRects;
+
+ void updatePalette();
+
+ void mergeDirtyRects();
+
+ bool unionRectangle(Common::Rect &destRect, const Common::Rect &src1, const Common::Rect &src2);
+public:
+ int _vesaMode;
+ int _startColor, _numColors;
+ Common::Point _bufferStart;
+ int _windowXAdd, _windowYAdd;
+ int _screenYOff;
+ byte _manPal[0x60];
+ byte _scaleTable1[256];
+ byte _scaleTable2[256];
+ int _vWindowWidth;
+ int _vWindowHeight;
+ int _vWindowBytesWide;
+ int _bufferBytesWide;
+ int _vWindowLinesTall;
+ bool _screenChangeFlag;
+public:
+ virtual void copyBlock(ASurface *src, const Common::Rect &bounds);
+
+ virtual void restoreBlock();
+
+ virtual void drawRect();
+
+ virtual void transBlitFrom(ASurface *src, const Common::Point &destPos);
+
+ virtual void transBlitFrom(ASurface *src, const Common::Rect &bounds);
+
+ virtual void blitFrom(Graphics::Surface &src);
+
+ virtual void copyBuffer(Graphics::Surface *src);
+
+ virtual void addDirtyRect(const Common::Rect &r);
+public:
+ Screen(AccessEngine *vm);
+
+ virtual ~Screen() {}
+
+ void setDisplayScan();
+
+ void setPanel(int num);
+
+ /**
+ * Update the underlying screen
+ */
+ void updateScreen();
+
+ /**
+ * Fade out screen
+ */
+ void forceFadeOut();
+
+ /**
+ * Fade in screen
+ */
+ void forceFadeIn();
+
+ void fadeOut() { forceFadeOut(); }
+ void fadeIn() { forceFadeIn(); }
+ void clearScreen();
+
+ /**
+ * Set the initial palette
+ */
+ void setInitialPalettte();
+
+ /**
+ * Set icon palette
+ */
+ void setIconPalette() {}
+
+ void loadPalette(int fileNum, int subfile);
+
+ void setPalette();
+
+ void loadRawPalette(Common::SeekableReadStream *stream);
+
+ void savePalette();
+
+ void restorePalette();
+
+ void getPalette(byte *pal);
+
+ /**
+ * Copy a buffer to the screen
+ */
+ void copyBuffer(const byte *data);
+
+ void setBufferScan();
+
+ void setScaleTable(int scale);
+
+ /**
+ * Save all the screen display state variables
+ */
+ void saveScreen();
+
+ /**
+ * Restores previously saved screen display state variables
+ */
+ void restoreScreen();
+
+ void setPaletteCycle(int startCycle, int endCycle, int timer);
+
+ void cyclePaletteForward();
+
+ void cyclePaletteBackwards();
+};
+
+} // End of namespace Access
+
+#endif /* ACCESS_SCREEN_H */
diff --git a/engines/access/scripts.cpp b/engines/access/scripts.cpp
new file mode 100644
index 0000000000..1bd24894d7
--- /dev/null
+++ b/engines/access/scripts.cpp
@@ -0,0 +1,887 @@
+/* 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 "access/access.h"
+#include "access/resources.h"
+#include "access/scripts.h"
+
+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);
+ _texsOrg = Common::Point(0, 0);
+}
+
+Scripts::~Scripts() {
+ freeScriptData();
+}
+
+void Scripts::setScript(Resource *res, bool restartFlag) {
+ _resource = res;
+ _data = res->_stream;
+ _endFlag = restartFlag;
+}
+
+void Scripts::freeScriptData() {
+ delete _resource;
+ _resource = nullptr;
+ _data = nullptr;
+}
+
+void Scripts::searchForSequence() {
+ assert(_data);
+
+ _data->seek(0);
+ int sequenceId;
+ do {
+ while (_data->readByte() != SCRIPT_START_BYTE) ;
+ sequenceId = _data->readUint16LE();
+ } while (sequenceId != _sequence);
+}
+
+void Scripts::charLoop() {
+ bool endFlag = _endFlag;
+ int pos = _data->pos();
+
+ _sequence = 2000;
+ searchForSequence();
+ _vm->_images.clear();
+ _vm->_buffer2.blitFrom(_vm->_buffer1);
+ _vm->_newRects.clear();
+
+ executeScript();
+ _vm->plotList1();
+ _vm->copyBlocks();
+
+ _data->seek(pos);
+ _endFlag = endFlag;
+}
+
+void Scripts::findNull() {
+ // No implementation required in ScummVM, the strings in the script files are already skipped by the use of readByte()
+}
+
+int Scripts::executeScript() {
+ assert(_data);
+ _endFlag = false;
+ _returnCode = 0;
+
+ do {
+ // Get next command, skipping over script start start if it's being pointed to
+ while ((_scriptCommand = _data->readByte()) == SCRIPT_START_BYTE)
+ _data->skip(2);
+
+ if (_scriptCommand < 0x80)
+ error("Unexpected opcode value %d", _scriptCommand);
+
+ executeCommand(_scriptCommand - 0x80);
+ } while (!_endFlag && !_vm->shouldQuitOrRestart());
+
+ return _returnCode;
+}
+
+typedef void(Scripts::*ScriptMethodPtr)();
+
+void Scripts::executeCommand(int commandIndex) {
+ static const ScriptMethodPtr COMMAND_LIST[] = {
+ &Scripts::cmdObject, &Scripts::cmdEndObject, &Scripts::cmdJumpLook,
+ &Scripts::cmdJumpHelp, &Scripts::cmdJumpGet, &Scripts::cmdJumpMove,
+ &Scripts::cmdJumpUse, &Scripts::cmdJumpTalk, &Scripts::cmdNull,
+ &Scripts::cmdPrint, &Scripts::cmdRetPos, &Scripts::cmdAnim,
+ &Scripts::cmdSetFlag, &Scripts::cmdCheckFlag, &Scripts::cmdGoto,
+ &Scripts::cmdAddScore, &Scripts::cmdSetInventory, &Scripts::cmdCheckInventory,
+ &Scripts::cmdSetTex, &Scripts::cmdNewRoom, &Scripts::cmdConverse,
+ &Scripts::cmdCheckFrame, &Scripts::cmdCheckAnim, &Scripts::cmdSnd,
+ &Scripts::cmdRetNeg, &Scripts::cmdRetPos, &Scripts::cmdCheckLoc,
+ &Scripts::cmdSetAnim, &Scripts::cmdDispInv, &Scripts::cmdSetAbout,
+ &Scripts::cmdSetTimer, &Scripts::cmdCheckTimer, &Scripts::cmdSetTravel,
+ &Scripts::cmdJumpGoto, &Scripts::cmdSetVideo, &Scripts::cmdPlayVideo,
+ &Scripts::cmdPlotImage, &Scripts::cmdSetDisplay, &Scripts::cmdSetBuffer,
+ &Scripts::cmdSetScroll, &Scripts::cmdSaveRect, &Scripts::cmdVideoEnded,
+ &Scripts::cmdSetBufVid, &Scripts::cmdPlayBufVid, &Scripts::cmdRemoveLast,
+ &Scripts::cmdDoTravel, &Scripts::cmdCheckAbout, &Scripts::cmdSpecial,
+ &Scripts::cmdSetCycle, &Scripts::cmdCycle, &Scripts::cmdCharSpeak,
+ &Scripts::cmdTexSpeak, &Scripts::cmdTexChoice, &Scripts::cmdWait,
+ &Scripts::cmdSetConPos, &Scripts::cmdCheckVFrame, &Scripts::cmdJumpChoice,
+ &Scripts::cmdReturnChoice, &Scripts::cmdClearBlock, &Scripts::cmdLoadSound,
+ &Scripts::cmdFreeSound, &Scripts::cmdSetVideoSound, &Scripts::cmdPlayVideoSound,
+ &Scripts::cmdPrintWatch, &Scripts::cmdDispAbout, &Scripts::cmdPushLocation,
+ &Scripts::cmdCheckTravel, &Scripts::cmdBlock, &Scripts::cmdPlayerOff,
+ &Scripts::cmdPlayerOn, &Scripts::cmdDead, &Scripts::cmdFadeOut,
+ &Scripts::cmdEndVideo
+ };
+
+ (this->*COMMAND_LIST[commandIndex])();
+}
+
+void Scripts::cmdObject() {
+ _vm->_bubbleBox->load(_data);
+}
+
+void Scripts::cmdEndObject() {
+ printString(GENERAL_MESSAGES[_vm->_room->_selectCommand]);
+}
+
+void Scripts::cmdJumpLook() {
+ if (_vm->_room->_selectCommand == 0)
+ cmdGoto();
+ else
+ _data->skip(2);
+}
+
+void Scripts::cmdJumpHelp() {
+ if (_vm->_room->_selectCommand == 8)
+ cmdGoto();
+ else
+ _data->skip(2);
+}
+
+void Scripts::cmdJumpGet() {
+ if (_vm->_room->_selectCommand == 3)
+ cmdGoto();
+ else
+ _data->skip(2);
+}
+
+void Scripts::cmdJumpMove() {
+ if (_vm->_room->_selectCommand == 2)
+ cmdGoto();
+ else
+ _data->skip(2);
+}
+
+void Scripts::cmdJumpUse() {
+ if (_vm->_room->_selectCommand == 4)
+ cmdGoto();
+ else
+ _data->skip(2);
+}
+
+void Scripts::cmdJumpTalk() {
+ if (_vm->_room->_selectCommand == 6)
+ cmdGoto();
+ else
+ _data->skip(2);
+}
+
+void Scripts::cmdNull() {
+}
+
+#define PRINT_TIMER 25
+
+void Scripts::cmdPrint() {
+ // Get a text line for display
+ Common::String msg = readString();
+ printString(msg);
+}
+
+void Scripts::printString(const Common::String &msg) {
+ _vm->_screen->_printOrg = Common::Point(20, 42);
+ _vm->_screen->_printStart = Common::Point(20, 42);
+ _vm->_timers[PRINT_TIMER]._timer = 50;
+ _vm->_timers[PRINT_TIMER]._initTm = 50;
+ ++_vm->_timers[PRINT_TIMER]._flag;
+
+ // Display the text in a bubble, and wait for a keypress or mouse click
+ _vm->_bubbleBox->placeBubble(msg);
+ _vm->_events->waitKeyMouse();
+
+ // Wait until the bubble display is expired
+ while (!_vm->shouldQuit() && _vm->_timers[PRINT_TIMER]._flag) {
+ _vm->_events->pollEvents();
+ }
+
+ // Restore the original screen over the text bubble
+ _vm->_screen->restoreBlock();
+}
+
+Common::String Scripts::readString() {
+ Common::String msg;
+ byte c;
+ while ((c = (char)_data->readByte()) != '\0')
+ msg += c;
+
+ return msg;
+}
+
+void Scripts::cmdRetPos() {
+ _endFlag = true;
+ _returnCode = 0;
+}
+
+void Scripts::cmdAnim() {
+ int animId = _data->readByte();
+ _vm->_animation->animate(animId);
+}
+
+void Scripts::cmdSetFlag() {
+ int flagNum = _data->readByte();
+ byte flagVal = _data->readByte();
+ assert(flagNum < 256);
+
+ _vm->_flags[flagNum] = flagVal;
+}
+
+void Scripts::cmdCheckFlag() {
+ int flagNum = _data->readUint16LE();
+ int flagVal = _data->readUint16LE();
+ assert(flagNum < 256);
+
+ if (_vm->_flags[flagNum] == flagVal)
+ cmdGoto();
+ else
+ _data->skip(2);
+}
+
+void Scripts::cmdGoto() {
+ _sequence = _data->readUint16LE();
+ searchForSequence();
+}
+
+void Scripts::cmdAddScore() {
+ if (!_vm->isDemo()) {
+ cmdSetInventory();
+ return;
+ }
+
+ _data->skip(1);
+}
+
+void Scripts::cmdSetInventory() {
+ int itemId = _data->readByte();
+ int itemVal = _data->readByte();
+
+ (*_vm->_inventory)[itemId] = itemVal;
+ _vm->_inventory->_startInvItem = 0;
+ _vm->_inventory->_startInvBox = 0;
+ _vm->_inventory->_invChangeFlag = true;
+}
+
+void Scripts::cmdCheckInventory() {
+ int itemId = _data->readUint16LE();
+ int itemVal = _data->readUint16LE();
+
+ if ((*_vm->_inventory)[itemId] == itemVal)
+ cmdGoto();
+ else
+ _data->skip(2);
+}
+
+void Scripts::cmdSetTex() {
+ _vm->_player->_playerDirection = RIGHT;
+ int posX = _data->readSint16LE() - (_vm->_player->_playerOffset.x / 2);
+ if (posX <= _vm->_player->_rawPlayer.x)
+ _vm->_player->_playerDirection = LEFT;
+
+ _vm->_player->_rawPlayer.x = posX;
+ _vm->_player->checkScroll();
+ bool scrlTemp = _vm->_player->_scrollFlag;
+
+ _vm->_player->_playerDirection = UP;
+ int posY = _data->readSint16LE();
+ if (posY <= _vm->_player->_rawPlayer.y)
+ _vm->_player->_playerDirection = DOWN;
+
+ _vm->_player->_rawPlayer.y = posY;
+ _vm->_player->_frame = 5;
+ _vm->_player->checkScroll();
+
+ _vm->_player->_scrollFlag |= scrlTemp;
+
+ _vm->_player->_position = Common::Point(_vm->_player->_rawPlayer.x, _vm->_player->_rawPlayer.y - _vm->_player->_playerOffset.y);
+ _vm->_player->_offsetY = _vm->_player->_playerOffset.y;
+ _vm->_player->_spritesPtr = _vm->_player->_playerSprites;
+ _vm->_player->_frameNumber = _vm->_player->_frame;
+
+ _vm->_room->setWallCodes();
+}
+
+#define CURRENT_ROOM 0xFF
+
+void Scripts::cmdNewRoom() {
+ int roomNumber = _data->readByte();
+ if (roomNumber != CURRENT_ROOM)
+ _vm->_player->_roomNumber = roomNumber;
+
+ _vm->_room->_function = FN_CLEAR1;
+ _vm->freeChar();
+ _vm->_converseMode = 0;
+ cmdRetPos();
+}
+
+void Scripts::cmdConverse() {
+ _vm->_conversation = _data->readUint16LE();
+ _vm->_room->clearRoom();
+ _vm->freeChar();
+ _vm->_char->loadChar(_vm->_conversation);
+ _vm->_events->setCursor(CURSOR_ARROW);
+
+ _vm->_images.clear();
+ _vm->_oldRects.clear();
+ _sequence = 0;
+ searchForSequence();
+
+ if (_vm->_screen->_vesaMode) {
+ _vm->_converseMode = 1;
+ }
+}
+
+void Scripts::cmdCheckFrame() {
+ int id = _data->readUint16LE();
+ Animation *anim = _vm->_animation->findAnimation(id);
+
+ int frame = _data->readUint16LE();
+ if (anim->_frameNumber == frame)
+ cmdGoto();
+ else
+ _data->skip(2);
+}
+
+void Scripts::cmdCheckAnim() {
+ int id = _data->readUint16LE();
+ Animation *anim = _vm->_animation->findAnimation(id);
+
+ if (anim->_currentLoopCount == -1)
+ cmdGoto();
+ else
+ _data->skip(2);
+}
+
+void Scripts::cmdSnd() {
+ int id = _data->readByte();
+ _vm->_sound->playSound(id);
+}
+
+void Scripts::cmdRetNeg() {
+ _endFlag = true;
+ _returnCode = -1;
+}
+
+void Scripts::cmdCheckLoc() {
+ int minX = _data->readUint16LE();
+ int minY = _data->readUint16LE();
+ int maxX = _data->readUint16LE();
+ int maxY = _data->readUint16LE();
+
+ int curX = _vm->_player->_rawPlayer.x + _vm->_player->_playerOffset.x;
+ int curY = _vm->_player->_rawPlayer.y;
+
+ if ((curX >= minX) && (curX <= maxX) && (curY >= minY) && (curY <= maxY))
+ cmdGoto();
+ else
+ _data->skip(2);
+}
+
+void Scripts::cmdSetAnim() {
+ int animId = _data->readByte();
+ Animation *anim = _vm->_animation->setAnimation(animId);
+
+ if (anim)
+ _vm->_animation->setAnimTimer(anim);
+}
+
+void Scripts::cmdDispInv() {
+ _vm->_inventory->newDisplayInv();
+}
+
+void Scripts::cmdSetAbout() {
+ if (!_vm->isDemo()) {
+ cmdSetTimer();
+ return;
+ }
+
+ error("TODO: DEMO - cmdSetAbout");
+}
+
+void Scripts::cmdSetTimer() {
+ int idx = _data->readUint16LE();
+ int val = _data->readUint16LE();
+
+ ++_vm->_timers[idx]._flag;
+ _vm->_timers[idx]._timer = val;
+ _vm->_timers[idx]._initTm = val;
+
+ _vm->_events->debounceLeft();
+ _vm->_events->zeroKeys();
+}
+
+void Scripts::cmdCheckTimer() {
+ int idx = _data->readUint16LE();
+
+ _vm->_canSaveLoad = true;
+ _vm->_events->pollEvents();
+ _vm->_canSaveLoad = false;
+
+ // Since the ScummVM debugger can be launched from the above point, we need
+ // to check whether the script needs to be ended here, since some commands,
+ // like the scene command, can change the current script
+ if (_endFlag)
+ return;
+
+ if ((idx == 9) && _vm->_events->isKeyPending()) {
+ _vm->_events->zeroKeys();
+ _vm->_timers[9]._timer = 0;
+ _vm->_timers[9]._flag = 0;
+ }
+
+ int val = _data->readUint16LE() & 0xFF;
+ if (_vm->_timers[idx]._flag == val)
+ cmdGoto();
+ else
+ _data->skip(2);
+}
+
+void Scripts::cmdSetTravel() {
+ if (!_vm->isDemo()) {
+ cmdJumpGoto();
+ return;
+ }
+ error("TODO: DEMO - cmdSetTravel");
+}
+
+void Scripts::cmdJumpGoto() {
+ if (_vm->_room->_selectCommand == 5)
+ cmdGoto();
+ else
+ _data->skip(2);
+}
+
+void Scripts::cmdSetVideo() {
+ Common::Point pt;
+ pt.x = _data->readSint16LE();
+ pt.y = _data->readSint16LE();
+ int cellIndex = _data->readUint16LE();
+ int rate = _data->readUint16LE();
+
+ _vm->_video->setVideo(_vm->_screen, pt, _vm->_extraCells[cellIndex]._vid, rate);
+}
+
+void Scripts::cmdPlayVideo() {
+ _vm->_video->playVideo();
+}
+
+void Scripts::cmdPlotImage() {
+ _vm->_destIn = _vm->_current;
+
+ int destX = _data->readUint16LE();
+ int destY = _data->readUint16LE();
+ int objId = _data->readUint16LE();
+ int imgId = _data->readUint16LE();
+
+ _vm->_screen->plotImage(_vm->_objectsTable[objId], imgId, Common::Point(destX, destY));
+}
+
+void Scripts::cmdSetDisplay() {
+ _vm->_screen->setDisplayScan();
+ _vm->_current = _vm->_screen;
+}
+
+void Scripts::cmdSetBuffer() {
+ _vm->_current = &_vm->_buffer2;
+}
+
+void Scripts::cmdSetScroll() {
+ _vm->_scrollCol = _data->readUint16LE();
+ _vm->_scrollRow = _data->readUint16LE();
+ _vm->_scrollX = 0;
+ _vm->_scrollY = 0;
+}
+
+void Scripts::cmdSaveRect() {
+ if (!_vm->isDemo()) {
+ cmdVideoEnded();
+ return;
+ }
+ error("TODO: DEMO - cmdSaveRect");
+}
+
+void Scripts::cmdVideoEnded() {
+ _vm->_events->pollEventsAndWait();
+
+ if (_vm->_video->_videoEnd) {
+ cmdGoto();
+ } else {
+ _data->skip(2);
+ }
+}
+
+void Scripts::cmdSetBufVid() {
+ _vm->_vidX = _data->readUint16LE();
+ _vm->_vidY = _data->readUint16LE();
+ int idx = _data->readUint16LE();
+ int rate = _data->readUint16LE();
+
+ _vm->_video->setVideo(&_vm->_vidBuf, Common::Point(0, 0), FileIdent(_vm->_extraCells[idx]._vid._fileNum, _vm->_extraCells[idx]._vid._subfile), rate);
+}
+
+void Scripts::cmdPlayBufVid() {
+ _vm->_video->playVideo();
+ _vm->_video->copyVideo();
+}
+
+void Scripts::cmdRemoveLast() {
+ --_vm->_numAnimTimers;
+}
+
+void Scripts::cmdDoTravel() {
+ if (!_vm->isDemo()) {
+ cmdSpecial();
+ return;
+ }
+ error("TODO: DEMO - cmdDoTravel");
+}
+
+void Scripts::cmdCheckAbout() {
+ if (!_vm->isDemo()) {
+ cmdSpecial();
+ return;
+ }
+ error("TODO: DEMO - cmdCheckAbout");
+}
+
+void Scripts::cmdSpecial() {
+ _specialFunction = _data->readUint16LE();
+ int p1 = _data->readUint16LE();
+ int p2 = _data->readUint16LE();
+
+ if (_specialFunction == 1) {
+ if (_vm->_establishTable[p2] == 1)
+ return;
+
+ _vm->_screen->savePalette();
+ }
+
+ executeSpecial(_specialFunction, p1, p2);
+
+ if (_specialFunction == 1) {
+ _vm->_screen->restorePalette();
+ _vm->_room->_function = FN_RELOAD;
+ }
+}
+
+void Scripts::cmdSetCycle() {
+ int startCycle = _data->readUint16LE();
+ int endCycle = _data->readUint16LE();
+ int timer = _data->readUint16LE();
+ _vm->_screen->setPaletteCycle(startCycle, endCycle, timer);
+}
+
+void Scripts::cmdCycle() {
+ if (_vm->_startup == -1)
+ _vm->_screen->cyclePaletteForward();
+}
+
+void Scripts::cmdCharSpeak() {
+ _vm->_screen->_printOrg = _charsOrg;
+ _vm->_screen->_printStart = _charsOrg;
+
+ byte v;
+ Common::String tmpStr = "";
+ while ((v = _data->readByte()) != 0)
+ tmpStr += (char)v;
+
+ _vm->_bubbleBox->placeBubble(tmpStr);
+ findNull();
+}
+
+void Scripts::cmdTexSpeak() {
+ _vm->_screen->_printOrg = _texsOrg;
+ _vm->_screen->_printStart = _texsOrg;
+ _vm->_screen->_maxChars = 20;
+
+ byte v;
+ Common::String tmpStr = "";
+ while ((v = _data->readByte()) != 0)
+ tmpStr += (char)v;
+
+ _vm->_bubbleBox->_bubbleDisplStr = Common::String("JASON");
+ _vm->_bubbleBox->placeBubble1(tmpStr);
+ findNull();
+}
+
+#define BTN_COUNT 6
+void Scripts::cmdTexChoice() {
+ static const int BTN_RANGES[BTN_COUNT][2] = {
+ { 0, 76 }, { 77, 154 }, { 155, 232 }, { 233, 276 }, { 0, 0 },
+ { 277, 319 }
+ };
+
+ _vm->_oldRects.clear();
+ _choiceStart = _data->pos() - 1;
+ _vm->_fonts._charSet._lo = 1;
+ _vm->_fonts._charSet._hi = 8;
+ _vm->_fonts._charFor._lo = 55;
+ _vm->_fonts._charFor._hi = 255;
+
+ _vm->_screen->_maxChars = 20;
+ _vm->_screen->_printOrg = _texsOrg;
+ _vm->_screen->_printStart = _texsOrg;
+
+ _vm->_bubbleBox->clearBubbles();
+ _vm->_bubbleBox->_bubbleDisplStr = Common::String("RESPONSE 1");
+
+ byte v;
+ Common::String tmpStr = "";
+ while ((v = _data->readByte()) != 0)
+ tmpStr += (char)v;
+
+ _vm->_bubbleBox->calcBubble(tmpStr);
+ _vm->_bubbleBox->printBubble(tmpStr);
+
+ Common::Array<Common::Rect> responseCoords;
+ responseCoords.push_back(_vm->_bubbleBox->_bounds);
+ _vm->_screen->_printOrg.y = _vm->_bubbleBox->_bounds.bottom + 11;
+
+ findNull();
+
+ tmpStr.clear();
+ while ((v = _data->readByte()) != 0)
+ tmpStr += (char)v;
+
+ if (tmpStr.size() != 0) {
+ _vm->_bubbleBox->_bubbleDisplStr = Common::String("RESPONSE 2");
+ _vm->_bubbleBox->calcBubble(tmpStr);
+ _vm->_bubbleBox->printBubble(tmpStr);
+ responseCoords.push_back(_vm->_bubbleBox->_bounds);
+ _vm->_screen->_printOrg.y = _vm->_bubbleBox->_bounds.bottom + 11;
+ }
+
+ findNull();
+
+ bool choice3Fl = false;
+ tmpStr.clear();
+ while ((v = _data->readByte()) != 0)
+ tmpStr += (char)v;
+
+ if (tmpStr.size() != 0) {
+ _vm->_bubbleBox->_bubbleDisplStr = Common::String("RESPONSE 3");
+ _vm->_bubbleBox->calcBubble(tmpStr);
+ _vm->_bubbleBox->printBubble(tmpStr);
+ responseCoords.push_back(_vm->_bubbleBox->_bounds);
+ _vm->_screen->_printOrg.y = _vm->_bubbleBox->_bounds.bottom + 11;
+ }
+
+ findNull();
+
+ int choice = -1;
+ do {
+ _vm->_events->pollEvents();
+ if (_vm->shouldQuit())
+ return;
+
+ charLoop();
+
+ _vm->_bubbleBox->_bubbleDisplStr = _vm->_bubbleBox->_bubbleTitle;
+ if (_vm->_events->_leftButton) {
+ if (_vm->_events->_mouseRow >= 22) {
+ _vm->_events->debounceLeft();
+ int x = _vm->_events->_mousePos.x;
+ for (int i = 0; i < BTN_COUNT; i++) {
+ if ((x >= BTN_RANGES[i][0]) && (x < BTN_RANGES[i][1])) {
+ choice = i;
+ break;
+ }
+ }
+ } else {
+ _vm->_events->debounceLeft();
+ choice = _vm->_events->checkMouseBox1(responseCoords);
+ }
+ }
+ } while ((choice == -1) || ((choice == 2) && choice3Fl));
+
+ _choice = choice + 1;
+ _vm->_bubbleBox->clearBubbles();
+}
+
+void Scripts::cmdWait() {
+ int time = _data->readSint16LE();
+ _vm->_timers[3]._timer = time;
+ _vm->_timers[3]._initTm = time;
+ _vm->_timers[3]._flag++;
+ _vm->_events->zeroKeys();
+
+ while (!_vm->shouldQuit() && !_vm->_events->isKeyMousePressed() &&
+ _vm->_timers[3]._flag) {
+ _vm->_midi->midiRepeat();
+ charLoop();
+
+ _vm->_events->pollEventsAndWait();
+ }
+
+ _vm->_events->debounceLeft();
+ _vm->_events->zeroKeys();
+}
+
+void Scripts::cmdSetConPos() {
+ int x = _data->readSint16LE();
+ int y = _data->readSint16LE();
+ _charsOrg = Common::Point(x, y);
+
+ x = _data->readSint16LE();
+ y = _data->readSint16LE();
+ _texsOrg = Common::Point(x, y);
+}
+
+void Scripts::cmdCheckVFrame() {
+ if (_vm->_video->_videoFrame == _data->readSint16LE())
+ cmdGoto();
+ else
+ _data->skip(2);
+}
+
+void Scripts::cmdJumpChoice() {
+ int val = (_data->readUint16LE() & 0xFF);
+
+ if (val == _choice) {
+ _sequence = _data->readUint16LE();
+ searchForSequence();
+ } else
+ _data->skip(2);
+}
+
+void Scripts::cmdReturnChoice() {
+ _data->seek(_choiceStart);
+}
+
+void Scripts::cmdClearBlock() {
+ _vm->_screen->restoreBlock();
+}
+
+void Scripts::cmdLoadSound() {
+ int idx = _data->readSint16LE();
+
+ _vm->_sound->_soundTable.clear();
+ Resource *sound = _vm->_files->loadFile(_vm->_extraCells[idx]._vidSound);
+ _vm->_sound->_soundTable.push_back(SoundEntry(sound, 1));
+}
+
+void Scripts::cmdFreeSound() {
+ SoundManager &sound = *_vm->_sound;
+
+ if (sound._soundTable.size() > 0 && sound._soundTable[0]._res) {
+ // Keep doing char display loop if playing sound for it
+ do {
+ if (_vm->_flags[236] == 1)
+ charLoop();
+
+ _vm->_events->pollEvents();
+ } while (!_vm->shouldQuit() && sound.isSFXPlaying());
+
+ // Free the sounds
+ while (sound._soundTable.size() > 0) {
+ delete sound._soundTable[0]._res;
+ sound._soundTable.remove_at(0);
+ }
+ }
+}
+
+void Scripts::cmdSetVideoSound() {
+ uint32 startPos = _data->pos();
+ _data->skip(4);
+ cmdLoadSound();
+ _data->seek(startPos);
+ cmdSetVideo();
+
+ _vm->_video->_soundFrame = _data->readUint16LE();
+ _vm->_video->_soundFlag = false;
+}
+
+void Scripts::cmdPlayVideoSound() {
+ _vm->_video->playVideo();
+ if (_vm->_video->_soundFrame == _vm->_video->_videoFrame &&
+ !_vm->_video->_soundFlag) {
+ _vm->_sound->playSound(0);
+ _vm->_video->_soundFlag = true;
+ }
+
+ _vm->_events->pollEventsAndWait();
+}
+
+void Scripts::cmdPrintWatch() {
+ if (!_vm->isDemo()) {
+ cmdPushLocation();
+ return;
+ }
+ error("TODO: DEMO - cmdPrintWatch");
+}
+
+void Scripts::cmdDispAbout() {
+ if (!_vm->isDemo()) {
+ cmdPushLocation();
+ return;
+ }
+ error("TODO: DEMO - cmdDispAbout");
+}
+
+void Scripts::cmdPushLocation() {
+ error("TODO cmdPushLocation");
+}
+
+void Scripts::cmdCheckTravel() {
+ if (!_vm->isDemo()) {
+ cmdPushLocation();
+ return;
+ }
+ error("TODO: DEMO - cmdCheckTravel");
+}
+
+void Scripts::cmdBlock() {
+ if (!_vm->isDemo()) {
+ cmdPushLocation();
+ return;
+ }
+ error("TODO: DEMO - cmdBlock");
+}
+
+void Scripts::cmdPlayerOff() {
+ _vm->_player->_playerOff = true;
+}
+
+void Scripts::cmdPlayerOn() {
+ _vm->_player->_playerOff = false;
+}
+
+void Scripts::cmdDead() {
+ int deathId = _data->readByte();
+ _vm->dead(deathId);
+}
+
+void Scripts::cmdFadeOut() {
+ _vm->_screen->forceFadeOut();
+}
+
+void Scripts::cmdEndVideo() {
+ _vm->_video->closeVideo();
+ _vm->_video->_videoEnd = true;
+}
+
+} // End of namespace Access
diff --git a/engines/access/scripts.h b/engines/access/scripts.h
new file mode 100644
index 0000000000..cfadf6d901
--- /dev/null
+++ b/engines/access/scripts.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 ACCESS_SCRIPTS_H
+#define ACCESS_SCRIPTS_H
+
+#include "common/scummsys.h"
+#include "common/memstream.h"
+#include "access/data.h"
+
+namespace Access {
+
+class AccessEngine;
+class Scripts;
+
+#define SCRIPT_START_BYTE 0xE0
+#define ROOM_SCRIPT 2000
+
+class Scripts : public Manager {
+private:
+ Resource *_resource;
+ int _specialFunction;
+
+ void charLoop();
+protected:
+ Common::SeekableReadStream *_data;
+
+ virtual void executeSpecial(int commandIndex, int param1, int param2) = 0;
+ virtual void executeCommand(int commandIndex);
+
+ /**
+ * Read a null terminated string from the script
+ */
+ Common::String readString();
+
+ void cmdObject();
+ void cmdEndObject();
+ void cmdJumpLook();
+ void cmdJumpHelp();
+ void cmdJumpGet();
+ void cmdJumpMove();
+ void cmdJumpUse();
+ void cmdJumpTalk();
+ void cmdNull();
+ void cmdPrint();
+ void cmdAnim();
+ void cmdSetFlag();
+ void cmdCheckFlag();
+
+ /**
+ * Jump to another script
+ */
+ void cmdGoto();
+
+ void cmdAddScore();
+ void cmdSetInventory();
+ void cmdCheckInventory();
+ void cmdSetTex();
+ void cmdNewRoom();
+ void cmdConverse();
+ void cmdCheckFrame();
+ void cmdCheckAnim();
+ void cmdSnd();
+ void cmdRetNeg();
+ void cmdCheckLoc();
+ void cmdSetAnim();
+ void cmdDispInv();
+ void cmdSetAbout();
+ void cmdSetTimer();
+ void cmdCheckTimer();
+ void cmdJumpGoto();
+ void cmdSetTravel();
+ void cmdSetVideo();
+ void cmdPlayVideo();
+ void cmdPlotImage();
+ void cmdSetDisplay();
+ void cmdSetBuffer();
+ void cmdSetScroll();
+ void cmdSaveRect();
+ void cmdVideoEnded();
+ void cmdSetBufVid();
+ void cmdPlayBufVid();
+ void cmdRemoveLast();
+ void cmdDoTravel();
+ void cmdCheckAbout();
+ void cmdSpecial();
+ void cmdSetCycle();
+ void cmdCycle();
+ void cmdCharSpeak();
+ void cmdTexSpeak();
+ void cmdTexChoice();
+ void cmdWait();
+ void cmdSetConPos();
+ void cmdCheckVFrame();
+ void cmdJumpChoice();
+ void cmdReturnChoice();
+ void cmdClearBlock();
+ void cmdLoadSound();
+ void cmdSetVideoSound();
+ void cmdPlayVideoSound();
+ void cmdPrintWatch();
+ void cmdDispAbout();
+ void cmdPushLocation();
+ void cmdCheckTravel();
+ void cmdBlock();
+ void cmdPlayerOff();
+ void cmdPlayerOn();
+ void cmdDead();
+ void cmdFadeOut();
+ void cmdEndVideo();
+ void cmdHelp();
+ void cmdCycleBack();
+ void cmdSetHelp();
+public:
+ int _sequence;
+ bool _endFlag;
+ int _returnCode;
+ int _scriptCommand;
+ int _choice;
+ int32 _choiceStart;
+ Common::Point _charsOrg, _texsOrg;
+public:
+ Scripts(AccessEngine *vm);
+
+ virtual ~Scripts();
+
+ void setScript(Resource *data, bool restartFlag = false);
+
+ void freeScriptData();
+
+ void searchForSequence();
+
+ int executeScript();
+
+ void findNull();
+
+ /**
+ * Print a given message to the screen in a bubble box
+ */
+ void printString(const Common::String &msg);
+
+ // Script commands that need to be public
+ void cmdFreeSound();
+ void cmdRetPos();
+};
+
+} // End of namespace Access
+
+#endif /* ACCESS_SCRIPTS_H */
diff --git a/engines/access/sound.cpp b/engines/access/sound.cpp
new file mode 100644
index 0000000000..da267bdc4c
--- /dev/null
+++ b/engines/access/sound.cpp
@@ -0,0 +1,326 @@
+/* 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/algorithm.h"
+#include "audio/mixer.h"
+#include "audio/decoders/raw.h"
+#include "audio/decoders/wave.h"
+#include "access/access.h"
+#include "access/sound.h"
+
+namespace Access {
+
+SoundManager::SoundManager(AccessEngine *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer) {
+}
+
+SoundManager::~SoundManager() {
+ clearSounds();
+}
+
+void SoundManager::clearSounds() {
+ debugC(1, kDebugSound, "clearSounds()");
+
+ for (uint i = 0; i < _soundTable.size(); ++i)
+ delete _soundTable[i]._res;
+
+ _soundTable.clear();
+
+ if (_mixer->isSoundHandleActive(_effectsHandle))
+ _mixer->stopHandle(_effectsHandle);
+
+ if (_queue.size())
+ _queue.remove_at(0);
+
+ while (_queue.size()) {
+ delete _queue[0];
+ _queue.remove_at(0);
+ }
+}
+
+void SoundManager::loadSoundTable(int idx, int fileNum, int subfile, int priority) {
+ debugC(1, kDebugSound, "loadSoundTable(%d, %d, %d)", idx, fileNum, subfile);
+
+ Resource *soundResource;
+
+ if (idx >= (int)_soundTable.size())
+ _soundTable.resize(idx + 1);
+
+ delete _soundTable[idx]._res;
+ soundResource = _vm->_files->loadFile(fileNum, subfile);
+ _soundTable[idx]._res = soundResource;
+ _soundTable[idx]._priority = priority;
+}
+
+Resource *SoundManager::loadSound(int fileNum, int subfile) {
+ debugC(1, kDebugSound, "loadSound(%d, %d)", fileNum, subfile);
+ return _vm->_files->loadFile(fileNum, subfile);
+}
+
+void SoundManager::playSound(int soundIndex) {
+ debugC(1, kDebugSound, "playSound(%d)", soundIndex);
+
+ int priority = _soundTable[soundIndex]._priority;
+ playSound(_soundTable[soundIndex]._res, priority);
+}
+
+void SoundManager::playSound(Resource *res, int priority) {
+ debugC(1, kDebugSound, "playSound");
+
+ byte *resourceData = res->data();
+
+ assert(res->_size >= 32);
+
+ 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);
+ Audio::RewindableAudioStream *audioStream = Audio::makeWAVStream(waveStream, DisposeAfterUse::YES);
+ _queue.push_back(audioStream);
+
+ } else if (READ_BE_UINT32(resourceData) == MKTAG('S', 'T', 'E', 'V')) {
+ // sound files have a fixed header of 32 bytes in total
+ // header content:
+ // "STEVE" - fixed header
+ // byte - sample rate
+ // 01h mapped internally to 3Ch
+ // 02h mapped internally to 78h
+ // 03h mapped internally to B5h
+ // 04h mapped internally to F1h
+ // byte - unknown
+ // word - actual sample size (should be resource-size - 32)
+ byte internalSampleRate = resourceData[5];
+ int sampleSize = READ_LE_UINT16(resourceData + 7);
+
+ assert( (sampleSize + 32) == res->_size);
+
+ int sampleRate = 0;
+ switch (internalSampleRate) {
+ case 1: // NEG(3Ch) -> C4h time constant
+ sampleRate = 16666;
+ break;
+
+ case 2: // NEG(78h) -> 88h time constant
+ sampleRate = 8334;
+ break;
+
+ case 3: // NEG(B5h) -> 4Bh time constant
+ sampleRate = 5525;
+ break;
+
+ case 4: // NEG(F1h) -> 0Fh time constant
+ sampleRate = 4150;
+ break;
+
+ default:
+ error("Unexpected internal Sample Rate %d", internalSampleRate);
+ return;
+ }
+
+ Audio::RewindableAudioStream *audioStream = Audio::makeRawStream(resourceData + 32, sampleSize, sampleRate, 0, DisposeAfterUse::NO);
+ _queue.push_back(audioStream);
+
+ } else
+ error("Unknown format");
+
+ if (!_mixer->isSoundHandleActive(_effectsHandle))
+ _mixer->playStream(Audio::Mixer::kSFXSoundType, &_effectsHandle,
+ _queue[0], -1, _mixer->kMaxChannelVolume, 0,
+ DisposeAfterUse::YES);
+}
+
+void SoundManager::checkSoundQueue() {
+ debugC(5, kDebugSound, "checkSoundQueue");
+
+ if (_queue.empty() || _mixer->isSoundHandleActive(_effectsHandle))
+ return;
+
+ _queue.remove_at(0);
+
+ if (_queue.size())
+ _mixer->playStream(Audio::Mixer::kSFXSoundType, &_effectsHandle,
+ _queue[0], -1, _mixer->kMaxChannelVolume, 0,
+ DisposeAfterUse::YES);
+}
+
+bool SoundManager::isSFXPlaying() {
+ return _mixer->isSoundHandleActive(_effectsHandle);
+}
+
+void SoundManager::loadSounds(Common::Array<RoomInfo::SoundIdent> &sounds) {
+ debugC(1, kDebugSound, "loadSounds");
+
+ clearSounds();
+
+ for (uint i = 0; i < sounds.size(); ++i) {
+ Resource *sound = loadSound(sounds[i]._fileNum, sounds[i]._subfile);
+ _soundTable.push_back(SoundEntry(sound, sounds[i]._priority));
+ }
+}
+
+void SoundManager::stopSound() {
+ debugC(3, kDebugSound, "stopSound");
+
+ _mixer->stopHandle(Audio::SoundHandle());
+}
+
+void SoundManager::freeSounds() {
+ debugC(3, kDebugSound, "freeSounds");
+
+ stopSound();
+ clearSounds();
+}
+
+/******************************************************************************************/
+
+MusicManager::MusicManager(AccessEngine *vm) : _vm(vm) {
+ _music = nullptr;
+ _tempMusic = nullptr;
+ _isLooping = false;
+
+ MidiPlayer::createDriver();
+ MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
+
+ int retValue = _driver->open();
+ if (retValue == 0) {
+ if (_nativeMT32)
+ _driver->sendMT32Reset();
+ else
+ _driver->sendGMReset();
+
+ _driver->setTimerCallback(this, &timerCallback);
+ }
+}
+
+MusicManager::~MusicManager() {
+ delete _music;
+ delete _tempMusic;
+}
+
+void MusicManager::send(uint32 b) {
+ if ((b & 0xF0) == 0xC0 && !_nativeMT32) {
+ b = (b & 0xFFFF00FF) | MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8;
+ }
+
+ Audio::MidiPlayer::send(b);
+}
+
+void MusicManager::midiPlay() {
+ debugC(1, kDebugSound, "midiPlay");
+
+ if (_music->_size < 4) {
+ error("midiPlay() wrong music resource size");
+ }
+
+ stop();
+
+ if (READ_BE_UINT32(_music->data()) != MKTAG('F', 'O', 'R', 'M')) {
+ warning("midiPlay() Unexpected signature");
+ _isPlaying = false;
+ } else {
+ _parser = MidiParser::createParser_XMIDI();
+
+ if (!_parser->loadMusic(_music->data(), _music->_size))
+ error("midiPlay() wrong music resource");
+
+ _parser->setTrack(0);
+ _parser->setMidiDriver(this);
+ _parser->setTimerRate(_driver->getBaseTempo());
+ _parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1);
+ _parser->property(MidiParser::mpSendSustainOffOnNotesOff, 1);
+
+ // Handle music looping
+ _parser->property(MidiParser::mpAutoLoop, _isLooping);
+
+ setVolume(127);
+ _isPlaying = true;
+ }
+}
+
+bool MusicManager::checkMidiDone() {
+ debugC(1, kDebugSound, "checkMidiDone");
+ return (!_isPlaying);
+}
+
+void MusicManager::midiRepeat() {
+ debugC(1, kDebugSound, "midiRepeat");
+
+ if (!_parser)
+ return;
+
+ _isLooping = true;
+ _parser->property(MidiParser::mpAutoLoop, _isLooping);
+ if (!_isPlaying)
+ _parser->setTrack(0);
+}
+
+void MusicManager::stopSong() {
+ debugC(1, kDebugSound, "stopSong");
+
+ stop();
+}
+
+void MusicManager::loadMusic(int fileNum, int subfile) {
+ debugC(1, kDebugSound, "loadMusic(%d, %d)", fileNum, subfile);
+
+ _music = _vm->_files->loadFile(fileNum, subfile);
+}
+
+void MusicManager::loadMusic(FileIdent file) {
+ debugC(1, kDebugSound, "loadMusic(%d, %d)", file._fileNum, file._subfile);
+
+ _music = _vm->_files->loadFile(file);
+}
+
+void MusicManager::newMusic(int musicId, int mode) {
+ debugC(1, kDebugSound, "newMusic(%d, %d)", musicId, mode);
+
+ if (mode == 1) {
+ stopSong();
+ freeMusic();
+ _music = _tempMusic;
+ _tempMusic = nullptr;
+ _isLooping = true;
+ } else {
+ _isLooping = (mode == 2);
+ _tempMusic = _music;
+ stopSong();
+ loadMusic(97, musicId);
+ }
+
+ if (_music)
+ midiPlay();
+}
+
+void MusicManager::freeMusic() {
+ debugC(3, kDebugSound, "freeMusic");
+
+ delete _music;
+ _music = nullptr;
+}
+
+void MusicManager::setLoop(bool loop) {
+ debugC(3, kDebugSound, "setLoop");
+
+ _isLooping = loop;
+ if (_parser)
+ _parser->property(MidiParser::mpAutoLoop, _isLooping);
+}
+} // End of namespace Access
diff --git a/engines/access/sound.h b/engines/access/sound.h
new file mode 100644
index 0000000000..90f6656e26
--- /dev/null
+++ b/engines/access/sound.h
@@ -0,0 +1,111 @@
+/* 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 ACCESS_SOUND_H
+#define ACCESS_SOUND_H
+
+#include "common/scummsys.h"
+#include "audio/audiostream.h"
+#include "audio/mixer.h"
+#include "access/files.h"
+#include "audio/midiplayer.h"
+#include "audio/midiparser.h"
+
+#define MAX_SOUNDS 20
+
+namespace Access {
+
+class AccessEngine;
+
+struct SoundEntry {
+ Resource *_res;
+ int _priority;
+
+ SoundEntry() { _res = nullptr; _priority = 0; }
+ SoundEntry(Resource *res, int priority) { _res = res; _priority = priority; }
+};
+
+class SoundManager {
+private:
+ AccessEngine *_vm;
+ Audio::Mixer *_mixer;
+ Audio::SoundHandle _effectsHandle;
+ Common::Array<Audio::RewindableAudioStream *> _queue;
+
+ void clearSounds();
+
+ void playSound(Resource *res, int priority);
+public:
+ Common::Array<SoundEntry> _soundTable;
+public:
+ SoundManager(AccessEngine *vm, Audio::Mixer *mixer);
+ ~SoundManager();
+
+ void loadSoundTable(int idx, int fileNum, int subfile, int priority = 1);
+
+ void playSound(int soundIndex);
+ void checkSoundQueue();
+ bool isSFXPlaying();
+
+ Resource *loadSound(int fileNum, int subfile);
+ void loadSounds(Common::Array<RoomInfo::SoundIdent> &sounds);
+
+ void stopSound();
+ void freeSounds();
+};
+
+class MusicManager : public Audio::MidiPlayer {
+private:
+ AccessEngine *_vm;
+
+ Resource *_tempMusic;
+
+ // MidiDriver_BASE interface implementation
+ virtual void send(uint32 b);
+
+public:
+ Resource *_music;
+
+public:
+ MusicManager(AccessEngine *vm);
+ ~MusicManager();
+
+ void midiPlay();
+
+ bool checkMidiDone();
+
+ void midiRepeat();
+
+ void stopSong();
+
+ void newMusic(int musicId, int mode);
+
+ void freeMusic();
+
+ void loadMusic(int fileNum, int subfile);
+ void loadMusic(FileIdent file);
+
+ void setLoop(bool loop);
+};
+} // End of namespace Access
+
+#endif /* ACCESS_SOUND_H*/
diff --git a/engines/access/video.cpp b/engines/access/video.cpp
new file mode 100644
index 0000000000..63d0aa5c89
--- /dev/null
+++ b/engines/access/video.cpp
@@ -0,0 +1,187 @@
+/* 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 "access/video.h"
+#include "access/access.h"
+
+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;
+ _videoEnd = false;
+
+ _header._frameCount = 0;
+ _header._width = _header._height = 0;
+ _header._flags = VIDEOFLAG_NONE;
+}
+
+VideoPlayer::~VideoPlayer() {
+ closeVideo();
+}
+
+
+void VideoPlayer::setVideo(ASurface *vidSurface, const Common::Point &pt, const FileIdent &videoFile, int rate) {
+ _vidSurface = vidSurface;
+ vidSurface->_orgX1 = pt.x;
+ vidSurface->_orgY1 = pt.y;
+ _vm->_timers[31]._timer = rate;
+ _vm->_timers[31]._initTm = rate;
+
+ // Open up video stream
+ _videoData = _vm->_files->loadFile(videoFile);
+
+ // Load in header
+ _header._frameCount = _videoData->_stream->readUint16LE();
+ _header._width = _videoData->_stream->readUint16LE();
+ _header._height = _videoData->_stream->readUint16LE();
+ _videoData->_stream->skip(1);
+ _header._flags = (VideoFlags)_videoData->_stream->readByte();
+
+ _startCoord = (byte *)vidSurface->getBasePtr(pt.x, pt.y);
+ _frameCount = _header._frameCount - 2;
+ _xCount = _header._width;
+ _scanCount = _header._height;
+ _videoFrame = 0;
+ _videoBounds = Common::Rect(pt.x, pt.y, pt.x + _header._width, pt.y + _header._height);
+
+ getFrame();
+
+ if (_header._flags == VIDEOFLAG_BG) {
+ // Draw the background
+ for (int y = 0; y < _scanCount; ++y) {
+ byte *pDest = (byte *)vidSurface->getBasePtr(pt.x, pt.y + y);
+ _videoData->_stream->read(pDest, _xCount);
+ }
+
+ if (vidSurface == _vm->_screen)
+ _vm->_newRects.push_back(Common::Rect(pt.x, pt.y, pt.x + _xCount, pt.y + _scanCount));
+
+ getFrame();
+ }
+
+ _videoEnd = false;
+}
+
+void VideoPlayer::closeVideo() {
+ delete _videoData;
+ _videoData = nullptr;
+}
+
+void VideoPlayer::getFrame() {
+ _frameSize = _videoData->_stream->readUint16LE();
+}
+
+void VideoPlayer::playVideo() {
+ if (_vm->_timers[31]._flag)
+ return;
+ ++_vm->_timers[31]._flag;
+
+ byte *pDest = _startCoord;
+ byte *pLine = _startCoord;
+ uint32 frameEnd = _videoData->_stream->pos() + _frameSize;
+
+ while ((uint32)_videoData->_stream->pos() < frameEnd) {
+ int count = _videoData->_stream->readByte();
+
+ if (count & 0x80) {
+ count &= 0x7f;
+
+ // Skip count number of pixels
+ // Loop across lines if necessary
+ while (count >= (pLine + _xCount - pDest)) {
+ count -= (pLine + _xCount - pDest);
+ pLine += _vidSurface->pitch;
+ pDest = pLine;
+ }
+
+ // Skip any remaining pixels in the new line
+ pDest += count;
+ } else {
+ // Read count number of pixels
+
+ // Load across lines if necessary
+ while (count >= (pLine + _xCount - pDest)) {
+ int lineCount = (pLine + _xCount - pDest);
+ _videoData->_stream->read(pDest, lineCount);
+ count -= lineCount;
+ pLine += _vidSurface->pitch;
+ pDest = pLine;
+ }
+
+ // Load remainder of pixels on line
+ if (count > 0) {
+ _videoData->_stream->read(pDest, count);
+ pDest += count;
+ }
+ }
+ }
+
+ // If the video is playing on the screen surface, add a dirty rect
+ if (_vidSurface == _vm->_screen)
+ _vm->_screen->addDirtyRect(_videoBounds);
+
+ getFrame();
+ if (++_videoFrame == _frameCount) {
+ closeVideo();
+ _videoEnd = true;
+ }
+}
+
+void VideoPlayer::copyVideo() {
+ _vm->_player->calcPlayer();
+
+ // Figure out the dirty rect area for the video frame
+ Common::Rect r = Common::Rect(_vm->_vidX - _vm->_screen->_bufferStart.x,
+ _vm->_vidY - _vm->_screen->_bufferStart.y,
+ _vm->_vidX - _vm->_screen->_bufferStart.x + _header._width,
+ _vm->_vidY - _vm->_screen->_bufferStart.y + _header._height);
+ if (!_vm->_screen->clip(r))
+ return;
+ _vm->_newRects.push_back(r);
+
+ int vh = _header._height;
+ int vw = _header._width;
+ int destIdx = _vm->_vidX - _vm->_screen->_bufferStart.x;
+ int srcIdx = _vm->_screen->_leftSkip;
+ for (int i = 0; i < _vm->_screen->_topSkip; i++)
+ destIdx += 160;
+
+ const byte *srcP = (const byte *)_vm->_vidBuf.getPixels() + srcIdx;
+ byte *destP = (byte *)_vm->_buffer2.getPixels() + destIdx;
+ for (int i = 0; i < vh; i++) {
+ Common::copy(srcP, srcP + vw, destP);
+ srcP += _vm->_vidBuf.pitch;
+ destP += _vm->_buffer2.pitch;
+ }
+}
+
+} // End of namespace Access
diff --git a/engines/access/video.h b/engines/access/video.h
new file mode 100644
index 0000000000..17825db367
--- /dev/null
+++ b/engines/access/video.h
@@ -0,0 +1,82 @@
+/* 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 ACCESS_VIDEO_H
+#define ACCESS_VIDEO_H
+
+#include "common/scummsys.h"
+#include "common/memstream.h"
+#include "access/data.h"
+#include "access/asurface.h"
+#include "access/files.h"
+
+namespace Access {
+
+enum VideoFlags { VIDEOFLAG_NONE = 0, VIDEOFLAG_BG = 1 };
+
+class VideoPlayer : public Manager {
+ struct VideoHeader {
+ int _frameCount;
+ int _width, _height;
+ VideoFlags _flags;
+ };
+private:
+ ASurface *_vidSurface;
+ Resource *_videoData;
+ VideoHeader _header;
+ byte *_startCoord;
+ int _frameCount;
+ int _xCount;
+ int _scanCount;
+ int _frameSize;
+ Common::Rect _videoBounds;
+
+ void getFrame();
+public:
+ int _videoFrame;
+ bool _soundFlag;
+ int _soundFrame;
+ bool _videoEnd;
+public:
+ VideoPlayer(AccessEngine *vm);
+ ~VideoPlayer();
+
+ /**
+ * Start up a video
+ */
+ void setVideo(ASurface *vidSurface, const Common::Point &pt, const FileIdent &videoFile, int rate);
+
+ /**
+ * Decodes a frame of the video
+ */
+ void playVideo();
+
+ void copyVideo();
+ /**
+ * Frees the data for a previously loaded video
+ */
+ void closeVideo();
+};
+
+} // End of namespace Access
+
+#endif /* ACCESS_VIDEO_H */
diff --git a/engines/agi/agi.cpp b/engines/agi/agi.cpp
index 6bdbabd33e..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) {
@@ -492,20 +504,19 @@ struct GameSettings {
const char *detectname;
};
-static const GameSettings agiSettings[] = {
- {"agi", "AGI game", GID_AGI, MDT_ADLIB, "OBJECT"},
- {NULL, NULL, 0, 0, NULL}
-};
-
AgiBase::AgiBase(OSystem *syst, const AGIGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
// 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();
}
@@ -554,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;
@@ -712,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 1d58900056..823ec7be66 100644
--- a/engines/agi/detection.cpp
+++ b/engines/agi/detection.cpp
@@ -138,15 +138,42 @@ 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 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
+ }
+ },
+
+ AD_EXTRA_GUI_OPTIONS_TERMINATOR
+};
+
using namespace Agi;
class AgiMetaEngine : public AdvancedMetaEngine {
@@ -154,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);
}
@@ -168,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;
@@ -227,12 +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);
- return options;
-}
-
SaveStateList AgiMetaEngine::listSaves(const char *target) const {
const uint32 AGIflag = MKTAG('A','G','I',':');
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
@@ -267,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 34651c70b2..32d0fdc06a 100644
--- a/engines/agi/graphics.cpp
+++ b/engines/agi/graphics.cpp
@@ -20,6 +20,7 @@
*
*/
+#include "common/config-manager.h"
#include "common/file.h"
#include "common/textconsole.h"
@@ -220,7 +221,7 @@ static const uint8 amigaAgiPaletteV3[16 * 3] = {
/**
* 16 color amiga-ish palette.
*/
-static const uint8 newPalette[16 * 3] = {
+static const uint8 altAmigaPalette[16 * 3] = {
0x00, 0x00, 0x00,
0x00, 0x00, 0x3f,
0x00, 0x2A, 0x00,
@@ -615,6 +616,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++) {
@@ -698,7 +701,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);
}
@@ -753,7 +756,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;
}
@@ -904,6 +907,7 @@ static const byte sciMouseCursor[] = {
0,0,0,0,0,0,1,2,2,1,0
};
+#if 0
/**
* A black and white Apple IIGS style arrow cursor (9x11).
* 0 = Transparent.
@@ -923,6 +927,7 @@ static const byte appleIIgsMouseCursor[] = {
2,2,2,0,2,1,1,2,0,
0,0,0,0,0,2,2,2,0
};
+#endif
/**
* RGB-palette for the black and white SCI and Apple IIGS arrow cursors.
@@ -1030,8 +1035,22 @@ int GfxMgr::initVideo() {
initPalette(vgaPalette, 256, 8);
else if (_vm->_renderMode == Common::kRenderEGA)
initPalette(egaPalette);
- else
- initPalette(newPalette);
+ else if (_vm->_renderMode == Common::kRenderAmiga) {
+ if (!ConfMan.getBool("altamigapalette")) {
+ // Set the correct Amiga palette
+ if (_vm->getVersion() < 0x2936)
+ // TODO: This palette isn't used for Apple IIGS games yet, as
+ // we don't set a separate render mode for them yet
+ initPalette(amigaAgiPaletteV1, 16, 4);
+ else if (_vm->getVersion() == 0x2936)
+ initPalette(amigaAgiPaletteV2, 16, 4);
+ else if (_vm->getVersion() > 0x2936)
+ initPalette(amigaAgiPaletteV3, 16, 4);
+ } else
+ // Set the old common alternative Amiga palette
+ initPalette(altAmigaPalette);
+ } else
+ error("initVideo: Unhandled render mode");
if ((_agiScreen = (uint8 *)calloc(GFX_WIDTH, GFX_HEIGHT)) == NULL)
return errNotEnoughMemory;
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 4ca8d00824..a1572d7f1f 100644
--- a/engines/agi/preagi_mickey.cpp
+++ b/engines/agi/preagi_mickey.cpp
@@ -892,6 +892,7 @@ void MickeyEngine::drawRoom() {
drawRoomAnimation();
}
+#if 0
const uint8 colorBCG[16][2] = {
{ 0x00, 0x00 }, // 0 (black, black)
{ 0, 0 },
@@ -910,6 +911,7 @@ const uint8 colorBCG[16][2] = {
{ 0, 0 },
{ 0xFF, 0xFF } // F (white, white)
};
+#endif
void MickeyEngine::drawLogo() {
// TODO: clean this up and make it work properly, the logo is drawn way off to the right
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/detection_tables.h b/engines/agos/detection_tables.h
index 77fc88c6bb..2f4709c49e 100644
--- a/engines/agos/detection_tables.h
+++ b/engines/agos/detection_tables.h
@@ -1259,6 +1259,32 @@ static const AGOSGameDescription gameDescriptions[] = {
GF_TALKIE | GF_OLD_BUNDLE | GF_PLANAR
},
+ // Simon the Sorcerer 1 - English Amiga CD32 demo, from the cover disc of
+ // issue 5 (October 1994) of Amiga CD32 Gamer
+ {
+ {
+ "simon1",
+ "CD32 Demo",
+
+ {
+ { "gameamiga", GAME_BASEFILE, "e243f9229f9728b3476e54d2cf5f18a1", 27998},
+ { "icon.pkd", GAME_ICONFILE, "565ef7a98dcc21ef526a2bb10b6f42ed", 18979},
+ { "stripped.txt", GAME_STRFILE, "94413c71c86c32ed9baaa1c74a151cb3", 243},
+ { "tbllist", GAME_TBLFILE, "f9d5bf2ce09f82289c791c3ca26e1e4b", 696},
+ { NULL, 0, NULL, 0}
+ },
+ Common::EN_ANY,
+ Common::kPlatformAmiga,
+ ADGF_CD | ADGF_DEMO,
+ GUIO2(GUIO_NOSUBTITLES, GUIO_NOMIDI)
+ },
+
+ GType_SIMON1,
+ GID_SIMON1CD32,
+ GF_TALKIE | GF_OLD_BUNDLE | GF_PLANAR
+ },
+
+
// Simon the Sorcerer 1 - English DOS Floppy Demo
{
{
diff --git a/engines/agos/gfx.cpp b/engines/agos/gfx.cpp
index 33145b7d0d..5a1f9f1917 100644
--- a/engines/agos/gfx.cpp
+++ b/engines/agos/gfx.cpp
@@ -547,7 +547,7 @@ void AGOSEngine_Simon1::drawMaskedImage(VC10_state *state) {
if ((dst[count * 2] & 0xF0) == 0x20)
dst[count * 2] = src[count * 2];
if (mask[count + state->x_skip] & 0x0F)
- if ((dst[count * 2 + 1] & 0x0F) == 0x20)
+ if ((dst[count * 2 + 1] & 0xF0) == 0x20)
dst[count * 2 + 1] = src[count * 2 + 1];
} else {
/* no transparency */
diff --git a/engines/agos/input.cpp b/engines/agos/input.cpp
index 8a4e87017a..687a8ef1cf 100644
--- a/engines/agos/input.cpp
+++ b/engines/agos/input.cpp
@@ -460,7 +460,7 @@ void AGOSEngine_Simon1::handleMouseWheelUp() {
_saveLoadEdit = false;
listSaveGames();
}
- } else {
+ } else {
AGOSEngine::handleMouseWheelUp();
}
}
@@ -472,11 +472,11 @@ void AGOSEngine_Simon1::handleMouseWheelDown() {
_saveLoadRowCurPos += 1;
if (_saveLoadRowCurPos >= _numSaveGameRows)
_saveLoadRowCurPos = _numSaveGameRows;
-
+
_saveLoadEdit = false;
listSaveGames();
}
- } else {
+ } else {
AGOSEngine::handleMouseWheelDown();
}
}
@@ -492,7 +492,7 @@ void AGOSEngine_Elvira2::handleMouseWheelUp() {
_saveLoadRowCurPos -= 3;
listSaveGames();
- } else {
+ } else {
AGOSEngine::handleMouseWheelUp();
}
}
@@ -506,7 +506,7 @@ void AGOSEngine_Elvira2::handleMouseWheelDown() {
_saveLoadRowCurPos = 1;
listSaveGames();
- } else {
+ } else {
AGOSEngine::handleMouseWheelDown();
}
}
diff --git a/engines/agos/midi.cpp b/engines/agos/midi.cpp
index c26fbe3331..e5875a8353 100644
--- a/engines/agos/midi.cpp
+++ b/engines/agos/midi.cpp
@@ -42,6 +42,8 @@ MidiPlayer::MidiPlayer() {
_driver = 0;
_map_mt32_to_gm = false;
+ _adlibPatches = NULL;
+
_enable_sfx = true;
_current = 0;
@@ -52,7 +54,7 @@ MidiPlayer::MidiPlayer() {
_paused = false;
_currentTrack = 255;
- _loopTrack = 0;
+ _loopTrackDefault = false;
_queuedTrack = 255;
_loopQueuedTrack = 0;
}
@@ -68,6 +70,7 @@ MidiPlayer::~MidiPlayer() {
}
_driver = NULL;
clearConstructs();
+ unloadAdlibPatches();
}
int MidiPlayer::open(int gameType) {
@@ -85,6 +88,12 @@ 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();
@@ -114,8 +123,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.
@@ -144,7 +155,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 +186,13 @@ void MidiPlayer::metaEvent(byte type, byte *data, uint16 length) {
return;
} else if (_current == &_sfx) {
clearConstructs(_sfx);
- } else if (_loopTrack) {
+ } else if (_current->loopTrack) {
_current->parser->jumpToTick(0);
} else if (_queuedTrack != 255) {
_currentTrack = 255;
byte destination = _queuedTrack;
_queuedTrack = 255;
- _loopTrack = _loopQueuedTrack;
+ _current->loopTrack = _loopQueuedTrack;
_loopQueuedTrack = false;
// Remember, we're still inside the locked mutex.
@@ -300,7 +320,7 @@ void MidiPlayer::setVolume(int musicVol, int sfxVol) {
void MidiPlayer::setLoop(bool loop) {
Common::StackLock lock(_mutex);
- _loopTrack = loop;
+ _loopTrackDefault = loop;
}
void MidiPlayer::queueTrack(int track, bool loop) {
@@ -355,6 +375,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,
@@ -405,7 +466,7 @@ void MidiPlayer::loadSMF(Common::File *in, int song, bool sfx) {
uint32 timerRate = _driver->getBaseTempo();
- if (!memcmp(p->data, "GMF\x1", 4)) {
+ if (isGMF) {
// The GMF header
// 3 BYTES: 'GMF'
// 1 BYTE : Major version
@@ -426,11 +487,9 @@ 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];
-
- // 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);
+ p->loopTrack = (p->data[6] != 0);
+ } else {
+ p->loopTrack = _loopTrackDefault;
}
MidiParser *parser = MidiParser::createParser_SMF();
@@ -500,6 +559,8 @@ void MidiPlayer::loadMultipleSMF(Common::File *in, bool sfx) {
p->song_sizes[i] = size;
}
+ p->loopTrack = _loopTrackDefault;
+
if (!sfx) {
_currentTrack = 255;
resetVolumeTable();
@@ -531,6 +592,7 @@ 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]);
}
@@ -575,6 +637,7 @@ 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
}
diff --git a/engines/agos/midi.h b/engines/agos/midi.h
index 3efadddc2f..7e78bfef28 100644
--- a/engines/agos/midi.h
+++ b/engines/agos/midi.h
@@ -36,6 +36,7 @@ namespace AGOS {
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
@@ -46,6 +47,7 @@ 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));
@@ -71,15 +73,19 @@ protected:
// These are only used for music.
byte _currentTrack;
- bool _loopTrack;
+ bool _loopTrackDefault;
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 _enable_sfx;
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/bbvs/bbvs.cpp b/engines/bbvs/bbvs.cpp
index d2e13e525c..11e4b6cea7 100644
--- a/engines/bbvs/bbvs.cpp
+++ b/engines/bbvs/bbvs.cpp
@@ -60,7 +60,7 @@ static const BBPoint kInventorySlotPositions[] = {
{135, 93}, {134, 145}, { 96, 224}, {128, 224}, {160, 224},
{192, 224}, {224, 224}, {240, 224}, {256, 224}, { 0, 0}
};
-
+
static const BBRect kVerbRects[6] = {
{-32, -2, 19, 27}, {-33, -33, 19, 27}, { 12, -2, 19, 27},
{ 13, -33, 19, 27}, {-10, 8, 19, 27}, {-11, -49, 19, 27}
@@ -77,7 +77,7 @@ bool WalkArea::contains(const Common::Point &pt) const {
BbvsEngine::BbvsEngine(OSystem *syst, const ADGameDescription *gd) :
Engine(syst), _gameDescription(gd) {
-
+
_random = new Common::RandomSource("bbvs");
_currActionCommandIndex = -1;
_buttheadObject = nullptr;
@@ -148,14 +148,14 @@ Common::Error BbvsEngine::run() {
_gameModule = new GameModule();
_spriteModule = new SpriteModule();
_sound = new SoundMan();
-
+
allocSnapshot();
memset(_easterEggInput, 0, sizeof(_easterEggInput));
-
+
_gameTicks = 0;
_playVideoNumber = 0;
_bootSaveSlot = -1;
-
+
memset(_inventoryItemStatus, 0, sizeof(_inventoryItemStatus));
memset(_gameVars, 0, sizeof(_gameVars));
memset(_sceneVisited, 0, sizeof(_sceneVisited));
@@ -189,7 +189,7 @@ Common::Error BbvsEngine::run() {
_playVideoNumber = 0;
}
}
-
+
writeContinueSavegame();
freeSnapshot();
@@ -282,20 +282,20 @@ void BbvsEngine::updateGame() {
inputTicks = 1;
_gameTicks = _system->getMillis();
}
-
+
if (inputTicks > 20) {
inputTicks = 20;
_gameTicks = _system->getMillis();
}
-
+
if (inputTicks == 0)
return;
-
+
if (_mouseX >= 320 || _mouseY >= 240) {
_mouseY = -1;
_mouseX = -1;
}
-
+
bool done;
do {
@@ -304,14 +304,14 @@ void BbvsEngine::updateGame() {
_mouseButtons &= ~kRightButtonClicked;
_keyCode = Common::KEYCODE_INVALID;
} while (--inputTicks && _playVideoNumber == 0 && _gameTicks > 0 && !done);
-
+
if (!done && _playVideoNumber == 0 && _gameTicks > 0) {
DrawList drawList;
buildDrawList(drawList);
_screen->drawDrawList(drawList, _spriteModule);
drawScreen();
}
-
+
_system->delayMillis(10);
}
@@ -329,7 +329,7 @@ void BbvsEngine::updateBackgroundSounds() {
_backgroundSoundsActive[i] = 0;
}
}
-}
+}
bool BbvsEngine::update(int mouseX, int mouseY, uint mouseButtons, Common::KeyCode keyCode) {
@@ -339,7 +339,7 @@ bool BbvsEngine::update(int mouseX, int mouseY, uint mouseButtons, Common::KeyCo
_bootSaveSlot = -1;
return false;
}
-
+
if (_newSceneNum != 0) {
_gameTicks = 0;
return changeScene();
@@ -413,7 +413,7 @@ bool BbvsEngine::update(int mouseX, int mouseY, uint mouseButtons, Common::KeyCo
}
updateInventory(mouseButtons & kLeftButtonClicked);
break;
-
+
case kGSVerbs:
_isSaveAllowed = false;
updateVerbs();
@@ -426,7 +426,7 @@ bool BbvsEngine::update(int mouseX, int mouseY, uint mouseButtons, Common::KeyCo
}
}
break;
-
+
case kGSWait:
case kGSWaitDialog:
_isSaveAllowed = false;
@@ -438,14 +438,14 @@ bool BbvsEngine::update(int mouseX, int mouseY, uint mouseButtons, Common::KeyCo
else
updateCommon();
break;
-
+
case kGSDialog:
_isSaveAllowed = true;
saveSnapshot();
updateDialog(mouseButtons & kLeftButtonClicked);
updateCommon();
break;
-
+
}
return true;
@@ -503,7 +503,7 @@ void BbvsEngine::buildDrawList(DrawList &drawList) {
// Verbs background
drawList.add(_gameModule->getGuiSpriteIndex(13), _verbPos.x - _cameraPos.x,
_verbPos.y - _cameraPos.y, 500);
- // Selected inventory item
+ // Selected inventory item
if (_currInventoryItem >= 0) {
drawList.add(_gameModule->getInventoryItemSpriteIndex(2 * _currInventoryItem), _verbPos.x - _cameraPos.x,
_verbPos.y - _cameraPos.y + 27, 500);
@@ -538,7 +538,7 @@ void BbvsEngine::updateVerbs() {
_mouseCursorSpriteIndex = 0;
return;
}
-
+
for (int i = 0; i < 6; ++i) {
const BBRect &verbRect = kVerbRects[i];
const int16 x = _verbPos.x + verbRect.x;
@@ -551,7 +551,7 @@ void BbvsEngine::updateVerbs() {
break;
}
}
-
+
switch (_currVerbNum) {
case kVerbLook:
case kVerbUse:
@@ -585,7 +585,7 @@ void BbvsEngine::updateDialog(bool clicked) {
_gameState = kGSScene;
return;
}
-
+
int slotX = (_mousePos.x - _cameraPos.x) / 32;
if (slotX >= _dialogSlotCount) {
@@ -597,7 +597,7 @@ void BbvsEngine::updateDialog(bool clicked) {
_mouseCursorSpriteIndex = _gameModule->getGuiSpriteIndex(5);
_activeItemType = kITDialog;
-
+
// Find the selected dialog item index
for (int i = 0; i < 50 && slotX >= 0; ++i) {
if (_dialogItemStatus[i]) {
@@ -605,7 +605,7 @@ void BbvsEngine::updateDialog(bool clicked) {
_activeItemIndex = i;
}
}
-
+
// Select the dialog item action if it was clicked
if (clicked) {
for (int i = 0; i < _gameModule->getActionsCount(); ++i) {
@@ -622,7 +622,7 @@ void BbvsEngine::updateDialog(bool clicked) {
}
void BbvsEngine::updateInventory(bool clicked) {
-
+
Common::Rect kInvButtonRects[3] = {
Common::Rect(97, 13, 97 + 20, 13 + 26),
Common::Rect(135, 15, 135 + 46, 15 + 25),
@@ -636,10 +636,10 @@ void BbvsEngine::updateInventory(bool clicked) {
if (_currVerbNum != kVerbLook && _currVerbNum != kVerbUse && _currVerbNum != kVerbInvItem)
_currVerbNum = kVerbUse;
-
+
const int16 mx = _mousePos.x - _cameraPos.x;
const int16 my = _mousePos.y - _cameraPos.y;
-
+
// Check inventory exit left/right edge of screen
if (mx < 40 || mx > 280) {
_mouseCursorSpriteIndex = _gameModule->getGuiSpriteIndex(10);
@@ -652,7 +652,7 @@ void BbvsEngine::updateInventory(bool clicked) {
return;
}
- // Check hovered/clicked inventory button
+ // Check hovered/clicked inventory button
_inventoryButtonIndex = -1;
if (kInvButtonRects[0].contains(mx, my)) {
_inventoryButtonIndex = 0;
@@ -677,10 +677,10 @@ void BbvsEngine::updateInventory(bool clicked) {
// Find hovered/clicked inventory item
int currItem = -1;
-
+
if (_currVerbNum == kVerbInvItem)
currItem = _currInventoryItem;
-
+
_activeItemType = kITEmpty;
for (int i = 0; i < 50; ++i) {
@@ -769,7 +769,7 @@ void BbvsEngine::updateScene(bool clicked) {
}
}
}
-
+
for (int i = 0; i < _gameModule->getBgObjectsCount(); ++i) {
BgObject *bgObject = _gameModule->getBgObject(i);
if (lastPriority <= bgObject->rect.bottom && bgObject->rect.contains(_mousePos)) {
@@ -921,7 +921,7 @@ bool BbvsEngine::performActionCommand(ActionCommand *actionCommand) {
return false;
case kActionCmdWalkObject:
- {
+ {
SceneObject *sceneObject = &_sceneObjects[actionCommand->sceneObjectIndex];
debug(5, "[%s] walks from (%d, %d) to (%d, %d)", sceneObject->sceneObjectDef->name,
sceneObject->x >> 16, sceneObject->y >> 16, actionCommand->walkDest.x, actionCommand->walkDest.y);
@@ -998,14 +998,14 @@ bool BbvsEngine::performActionCommand(ActionCommand *actionCommand) {
bool BbvsEngine::processCurrAction() {
bool actionsFinished = false;
-
+
if (_sceneObjectActions.size() == 0) {
-
+
for (uint i = 0; i < _currAction->actionCommands.size(); ++i) {
ActionCommand *actionCommand = &_currAction->actionCommands[i];
if (actionCommand->timeStamp != 0)
break;
-
+
if (actionCommand->cmd == kActionCmdMoveObject || actionCommand->cmd == kActionCmdAnimObject) {
SceneObjectAction *sceneObjectAction = 0;
// See if there's already an entry for the SceneObject
@@ -1027,14 +1027,14 @@ bool BbvsEngine::processCurrAction() {
sceneObjectAction->animationIndex = actionCommand->param;
}
}
-
+
if (actionCommand->cmd == kActionCmdSetCameraPos) {
_currCameraNum = actionCommand->param;
_newCameraPos = _gameModule->getCameraInit(actionCommand->param)->cameraPos;
}
}
-
+
// Delete entries for SceneObjects without anim
for (uint i = 0; i < _sceneObjectActions.size();) {
if (!_sceneObjects[_sceneObjectActions[i].sceneObjectIndex].anim)
@@ -1107,7 +1107,7 @@ void BbvsEngine::updateCommon() {
if (doActionCommands) {
ActionCommand *actionCommand = &_currAction->actionCommands[_currActionCommandIndex];
-
+
while (actionCommand->timeStamp == _currActionCommandTimeStamp &&
_currActionCommandIndex < (int)_currAction->actionCommands.size()) {
if (!performActionCommand(actionCommand)) {
@@ -1161,7 +1161,7 @@ void BbvsEngine::updateCommon() {
}
updateWalkObject(sceneObject);
}
-
+
if (sceneObject->walkCount > 0 && sceneObject->turnCount == 0) {
debug(5, "walk step, xIncr: %d, yIncr: %d", sceneObject->xIncr, sceneObject->yIncr);
sceneObject->x += sceneObject->xIncr;
@@ -1226,7 +1226,7 @@ void BbvsEngine::updateCommon() {
}
}
}
-
+
if (_cameraPos.x < _newCameraPos.x)
++_cameraPos.x;
if (_cameraPos.x > _newCameraPos.x)
@@ -1235,7 +1235,7 @@ void BbvsEngine::updateCommon() {
++_cameraPos.y;
if (_cameraPos.y > _newCameraPos.y)
--_cameraPos.y;
-
+
// Check if Butthead is inside a scene exit
if (_newSceneNum == 0 && !_currAction && _buttheadObject) {
int16 buttheadX = _buttheadObject->x >> 16;
@@ -1314,13 +1314,13 @@ void BbvsEngine::stopSounds() {
bool BbvsEngine::runMinigame(int minigameNum) {
debug(0, "BbvsEngine::runMinigame() minigameNum: %d", minigameNum);
-
+
bool fromMainGame = _currSceneNum != kMainMenu;
-
+
_sound->unloadSounds();
-
+
Minigame *minigame = 0;
-
+
switch (minigameNum) {
case kMinigameBbLoogie:
minigame = new MinigameBbLoogie(this);
@@ -1338,9 +1338,9 @@ bool BbvsEngine::runMinigame(int minigameNum) {
error("Incorrect minigame number %d", minigameNum);
break;
}
-
+
bool minigameResult = minigame->run(fromMainGame);
-
+
delete minigame;
// Check if the principal was hit with a megaloogie in the loogie minigame
@@ -1370,11 +1370,11 @@ void BbvsEngine::checkEasterEgg(char key) {
"SKCUS",
"NAMTAH"
};
-
+
static const int kEasterEggLengths[] = {
7, 5, 5, 6
};
-
+
if (_currSceneNum == kCredits) {
memcpy(&_easterEggInput[1], &_easterEggInput[0], 6);
_easterEggInput[0] = key;
diff --git a/engines/bbvs/bbvs.h b/engines/bbvs/bbvs.h
index 6a9a13905c..bbd8046a8b 100644
--- a/engines/bbvs/bbvs.h
+++ b/engines/bbvs/bbvs.h
@@ -149,7 +149,7 @@ struct BBPoint {
struct BBRect {
int16 x, y, width, height;
-};
+};
struct BBPolygon {
const BBPoint *points;
@@ -229,66 +229,66 @@ public:
private:
const ADGameDescription *_gameDescription;
Graphics::PixelFormat _pixelFormat;
-public:
+public:
Common::RandomSource *_random;
-
+
GameModule *_gameModule;
SpriteModule *_spriteModule;
SoundMan *_sound;
-
+
Screen *_screen;
-
+
int _bootSaveSlot;
-
+
int _mouseX, _mouseY;
uint _mouseButtons;
Common::KeyCode _keyCode;
-
+
int _mouseCursorSpriteIndex;
int _gameState;
int _gameTicks;
-
+
Common::Point _mousePos;
Common::Point _verbPos;
Common::Point _walkMousePos;
-
+
int _activeItemType;
int _activeItemIndex;
int _currTalkObjectIndex;
-
+
Common::Point _cameraPos, _newCameraPos;
-
+
int _newSceneNum, _prevSceneNum, _currSceneNum;
int _playVideoNumber;
-
+
int _dialogSlotCount;
byte _dialogItemStatus[kDialogItemStatusCount];
-
+
byte _gameVars[kGameVarsCount];
byte _sceneVisited[kSceneVisitedCount];
int _currVerbNum;
-
+
int _currInventoryItem;
byte _inventoryItemStatus[kInventoryItemStatusCount];
int _inventoryButtonIndex;
-
+
Action *_currAction;
uint32 _currActionCommandTimeStamp;
int _currActionCommandIndex;
-
+
Common::Array<Action*> _walkAreaActions;
-
+
SceneObject _sceneObjects[kSceneObjectsCount];
Common::Array<SceneObjectAction> _sceneObjectActions;
-
+
SceneObject *_buttheadObject, *_beavisObject;
int _currCameraNum;
-
+
byte _backgroundSoundsActive[kSceneSoundsCount];
Audio::SoundHandle _speechSoundHandle;
-
+
int _walkAreasCount;
WalkArea _walkAreas[80];
int _walkInfosCount;
@@ -298,40 +298,40 @@ public:
Common::Rect _tempWalkableRects1[256];
Common::Rect _tempWalkableRects2[256];
WalkInfo *_walkInfoPtrs[256];
-
+
WalkArea *_sourceWalkArea, *_destWalkArea;
Common::Point _sourceWalkAreaPt, _destWalkAreaPt, _finalWalkPt;
int _currWalkDistance;
bool _walkReachedDestArea;
-
+
bool _hasSnapshot;
byte *_snapshot;
Common::SeekableMemoryWriteStream *_snapshotStream;
-
+
char _easterEggInput[7];
-
+
void updateEvents();
int getRandom(int max);
void drawDebugInfo();
void drawScreen();
-
+
void updateGame();
bool evalCondition(Conditions &conditions);
bool evalCameraCondition(Conditions &conditions, int value);
int evalDialogCondition(Conditions &conditions);
void evalActionResults(ActionResults &results);
-
+
void updateBackgroundSounds();
void loadScene(int sceneNum);
void initScene(bool sounds);
- bool changeScene();
+ bool changeScene();
bool update(int mouseX, int mouseY, uint mouseButtons, Common::KeyCode keyCode);
-
+
void buildDrawList(DrawList &drawList);
-
+
void updateVerbs();
void updateDialog(bool clicked);
void updateInventory(bool clicked);
@@ -342,7 +342,7 @@ public:
void skipCurrAction();
void updateCommon();
-
+
void updateWalkableRects();
void startWalkObject(SceneObject *sceneObject);
void updateWalkObject(SceneObject *sceneObject);
@@ -360,20 +360,20 @@ public:
void walkFindPath(WalkArea *sourceWalkArea, int infoCount);
int calcDistance(const Common::Point &pt1, const Common::Point &pt2);
void walkFoundPath(int count);
-
+
void updateSceneObjectsTurnValue();
void updateDialogConditions();
-
- void playSpeech(int soundNum);
+
+ void playSpeech(int soundNum);
void stopSpeech();
-
+
void playSound(uint soundNum, bool loop = false);
void stopSound(uint soundNum);
void stopSounds();
-
+
bool runMinigame(int minigameNum);
void playVideo(int videoNum);
-
+
void runMainMenu();
void checkEasterEgg(char key);
@@ -409,13 +409,13 @@ public:
bool existsSavegame(int num);
static Common::String getSavegameFilename(const Common::String &target, int num);
static kReadSaveHeaderError readSaveHeader(Common::SeekableReadStream *in, bool loadThumbnail, SaveHeader &header);
-
+
void allocSnapshot();
void freeSnapshot();
void saveSnapshot();
-
+
void writeContinueSavegame();
-
+
};
} // End of namespace Bbvs
diff --git a/engines/bbvs/detection.cpp b/engines/bbvs/detection.cpp
index e7383163f5..3e247aad99 100644
--- a/engines/bbvs/detection.cpp
+++ b/engines/bbvs/detection.cpp
@@ -133,7 +133,7 @@ SaveStateDescriptor BbvsMetaEngine::querySaveMetaInfos(const char *target, int s
Bbvs::BbvsEngine::kReadSaveHeaderError error;
error = Bbvs::BbvsEngine::readSaveHeader(in, true, header);
delete in;
- if (error == Bbvs::BbvsEngine::kRSHENoError) {
+ if (error == Bbvs::BbvsEngine::kRSHENoError) {
SaveStateDescriptor desc(slot, header.description);
// Slot 0 is used for the "Continue" save
desc.setDeletableFlag(slot != 0);
diff --git a/engines/bbvs/dialogs.cpp b/engines/bbvs/dialogs.cpp
index 5247a58ec8..af95f06c1e 100644
--- a/engines/bbvs/dialogs.cpp
+++ b/engines/bbvs/dialogs.cpp
@@ -34,7 +34,7 @@ struct MenuButton {
static const MenuButton kMenuButtons[] = {
// Main menu
- {"New Game", kCmdNewGame},
+ {"New Game", kCmdNewGame},
{"Continue", kCmdContinue},
{"Options", kCmdOptions},
{"Mini Games", kCmdMiniGames},
@@ -61,7 +61,7 @@ MainMenu::~MainMenu() {
}
void MainMenu::init() {
- _buttons[0] = new GUI::ButtonWidget(this, 0, 0, 1, 1, "", 0, 0);
+ _buttons[0] = new GUI::ButtonWidget(this, 0, 0, 1, 1, "", 0, 0);
_buttons[1] = new GUI::ButtonWidget(this, 0, 0, 1, 1, "", 0, 0);
_buttons[2] = new GUI::ButtonWidget(this, 0, 0, 1, 1, "", 0, 0);
_buttons[3] = new GUI::ButtonWidget(this, 0, 0, 1, 1, "", 0, 0);
@@ -76,14 +76,14 @@ void MainMenu::reflowLayout() {
const int buttonWidth = screenW * 70 / 320;
const int buttonHeight = screenH * 14 / 240;
const int buttonPadding = screenW * 3 / 320;
-
+
_w = 2 * buttonWidth + buttonPadding;
_h = 3 * buttonHeight + 3 * buttonPadding;
_x = (screenW - _w) / 2;
_y = screenH - _h;
int x = 0, y = 0;
-
+
x = 0;
y = 0;
_buttons[0]->resize(x, y, buttonWidth, buttonHeight);
diff --git a/engines/bbvs/dialogs.h b/engines/bbvs/dialogs.h
index 2dce2a110b..7db0b182b7 100644
--- a/engines/bbvs/dialogs.h
+++ b/engines/bbvs/dialogs.h
@@ -67,13 +67,13 @@ protected:
BbvsEngine *_vm;
void init();
-
+
GUI::ButtonWidget *_buttons[5];
-
+
void gotoMenuScreen(int index);
bool canContinue();
void gotoScene(int sceneNum);
-
+
};
}
diff --git a/engines/bbvs/gamemodule.cpp b/engines/bbvs/gamemodule.cpp
index d6343084ab..80f0e81450 100644
--- a/engines/bbvs/gamemodule.cpp
+++ b/engines/bbvs/gamemodule.cpp
@@ -39,11 +39,11 @@ GameModule::~GameModule() {
void GameModule::load(const char *filename) {
debug(0, "GameModule::load()");
-
+
unload();
Common::File fd;
-
+
if (!fd.open(filename))
error("GameModule::load() Could not open %s", filename);
@@ -68,7 +68,7 @@ void GameModule::load(const char *filename) {
fd.seek(0x1A8);
_buttheadObjectIndex = fd.readUint32LE();
-
+
fd.close();
debug(0, "GameModule::load() OK");
@@ -177,7 +177,7 @@ int GameModule::getBgSpritePriority(int index) {
int GameModule::getSceneSoundsCount() {
return _sceneSoundsCount;
}
-
+
SceneSound *GameModule::getSceneSound(int index) {
assert(index < _sceneSoundsCount);
return &_sceneSounds[index];
@@ -257,7 +257,7 @@ void GameModule::unload() {
void GameModule::loadBgSprites(Common::SeekableReadStream &s) {
debug(0, "GameModule::loadBgSprites()");
-
+
s.seek(0x14);
_bgSpriteCount = s.readUint32LE();
uint32 bgSpriteIndicesOffs = s.readUint32LE();
@@ -275,7 +275,7 @@ void GameModule::loadBgSprites(Common::SeekableReadStream &s) {
void GameModule::loadCameraInits(Common::SeekableReadStream &s) {
debug(0, "GameModule::loadCameraInits()");
-
+
s.seek(0x20);
for (int i = 0; i < kCameraInitsCount; ++i) {
CameraInit &cameraInit = _cameraInits[i];
@@ -283,13 +283,13 @@ void GameModule::loadCameraInits(Common::SeekableReadStream &s) {
for (int j = 0; j < 8; ++j)
cameraInit.cameraLinks[j] = s.readByte();
for (int j = 0; j < 8; ++j)
- cameraInit.rects[j] = readRect(s);
+ cameraInit.rects[j] = readRect(s);
}
}
void GameModule::loadWalkRects(Common::SeekableReadStream &s) {
debug(0, "GameModule::loadWalkRects()");
-
+
s.seek(0x150);
_walkRectsCount = s.readUint32LE();
uint32 offs = s.readUint32LE();
@@ -301,7 +301,7 @@ void GameModule::loadWalkRects(Common::SeekableReadStream &s) {
void GameModule::loadSceneExits(Common::SeekableReadStream &s) {
debug(0, "GameModule::loadSceneExits()");
-
+
s.seek(0x158);
_sceneExitsCount = s.readUint32LE();
uint32 offs = s.readUint32LE();
@@ -329,13 +329,13 @@ void GameModule::loadBgObjects(Common::SeekableReadStream &s) {
void GameModule::loadAnimations(Common::SeekableReadStream &s) {
debug(0, "GameModule::loadAnimations()");
-
+
s.seek(0x168);
_animationsCount = s.readUint32LE();
uint32 offs = s.readUint32LE();
_animations = new Animation[_animationsCount];
for (int i = 0; i < _animationsCount; ++i) {
- Animation &anim = _animations[i];
+ Animation &anim = _animations[i];
s.seek(offs + i * 20);
anim.frameCount = s.readUint32LE();
uint32 frameSpriteIndicesOffs = s.readUint32LE();
@@ -363,7 +363,7 @@ void GameModule::loadAnimations(Common::SeekableReadStream &s) {
void GameModule::loadSceneObjectDefs(Common::SeekableReadStream &s) {
debug(0, "GameModule::loadSceneObjectDefs()");
-
+
s.seek(0x170);
_sceneObjectDefsCount = s.readUint32LE();
uint32 offs = s.readUint32LE();
@@ -379,7 +379,7 @@ void GameModule::loadSceneObjectDefs(Common::SeekableReadStream &s) {
void GameModule::loadSceneObjectInits(Common::SeekableReadStream &s) {
debug(0, "GameModule::loadSceneObjectInits()");
-
+
s.seek(0x178);
_sceneObjectInitsCount = s.readUint32LE();
uint32 offs = s.readUint32LE();
@@ -396,7 +396,7 @@ void GameModule::loadSceneObjectInits(Common::SeekableReadStream &s) {
void GameModule::loadActions(Common::SeekableReadStream &s) {
debug(0, "GameModule::loadActions()");
-
+
s.seek(0x180);
_actionsCount = s.readUint32LE();
uint32 offs = s.readUint32LE();
@@ -427,7 +427,7 @@ void GameModule::loadActions(Common::SeekableReadStream &s) {
void GameModule::loadGuiSpriteIndices(Common::SeekableReadStream &s) {
debug(0, "GameModule::loadGuiSpriteIndices()");
-
+
s.seek(0x188);
uint32 offs = s.readUint32LE();
s.seek(offs);
@@ -437,7 +437,7 @@ void GameModule::loadGuiSpriteIndices(Common::SeekableReadStream &s) {
void GameModule::loadInventoryItemSpriteIndices(Common::SeekableReadStream &s) {
debug(0, "GameModule::loadInventoryItemSpriteIndices()");
-
+
s.seek(0x18C);
uint32 offs = s.readUint32LE();
s.seek(offs);
@@ -447,7 +447,7 @@ void GameModule::loadInventoryItemSpriteIndices(Common::SeekableReadStream &s) {
void GameModule::loadInventoryItemInfos(Common::SeekableReadStream &s) {
debug(0, "GameModule::loadInventoryItemInfos()");
-
+
s.seek(0x190);
uint32 offs = s.readUint32LE();
s.seek(offs);
@@ -462,7 +462,7 @@ void GameModule::loadInventoryItemInfos(Common::SeekableReadStream &s) {
void GameModule::loadDialogItemSpriteIndices(Common::SeekableReadStream &s) {
debug(0, "GameModule::loadDialogItemSpriteIndices()");
-
+
s.seek(0x194);
uint32 offs = s.readUint32LE();
s.seek(offs);
@@ -473,7 +473,7 @@ void GameModule::loadDialogItemSpriteIndices(Common::SeekableReadStream &s) {
void GameModule::loadSceneSounds(Common::SeekableReadStream &s) {
debug(0, "GameModule::loadSceneSounds()");
-
+
s.seek(0x1A0);
_sceneSoundsCount = s.readUint32LE();
uint32 offs = s.readUint32LE();
@@ -487,7 +487,7 @@ void GameModule::loadSceneSounds(Common::SeekableReadStream &s) {
void GameModule::loadPreloadSounds(Common::SeekableReadStream &s) {
debug(0, "GameModule::loadPreloadSounds()");
-
+
s.seek(0x198);
_preloadSoundsCount = s.readUint32LE();
uint32 offs = s.readUint32LE();
diff --git a/engines/bbvs/gamemodule.h b/engines/bbvs/gamemodule.h
index 4d4f5b90a1..b31b95dcee 100644
--- a/engines/bbvs/gamemodule.h
+++ b/engines/bbvs/gamemodule.h
@@ -134,29 +134,29 @@ class GameModule {
public:
GameModule();
~GameModule();
-
+
void load(const char *filename);
-
+
int getFieldC();
int getButtheadObjectIndex();
-
+
int getGuiSpriteIndex(int index);
int getInventoryItemSpriteIndex(int index);
int getDialogItemSpriteIndex(int index);
-
+
int getActionsCount();
Action *getAction(int index);
-
+
InventoryItemInfo *getInventoryItemInfo(int index);
CameraInit *getCameraInit(int cameraNum);
-
+
int getSceneExitsCount();
SceneExit *getSceneExit(int index);
-
+
int getWalkRectsCount();
Common::Rect *getWalkRects();
-
+
int getSceneObjectDefsCount();
SceneObjectDef *getSceneObjectDef(int index);
@@ -170,44 +170,44 @@ public:
int getBgSpriteIndex(int index);
int getBgSpritePriority(int index);
- int getSceneSoundsCount();
+ int getSceneSoundsCount();
SceneSound *getSceneSound(int index);
- uint getSceneSoundIndex(uint soundNum);
-
+ uint getSceneSoundIndex(uint soundNum);
+
uint getPreloadSoundsCount();
uint getPreloadSound(uint index);
Animation *getAnimation(int index);
-
+
protected:
-
+
int _bgSpriteCount;
int *_bgSpriteIndices;
int16 *_bgSpritePriorities;
-
+
CameraInit _cameraInits[kCameraInitsCount];
-
+
int _walkRectsCount;
Common::Rect *_walkRects;
-
+
int _sceneExitsCount;
SceneExit *_sceneExits;
-
+
int _bgObjectsCount;
BgObject *_bgObjects;
-
+
int _animationsCount;
Animation *_animations;
-
+
int _sceneObjectDefsCount;
SceneObjectDef *_sceneObjectDefs;
-
+
int _sceneObjectInitsCount;
SceneObjectInit *_sceneObjectInits;
int _actionsCount;
Action *_actions;
-
+
int _sceneSoundsCount;
SceneSound *_sceneSounds;
@@ -218,16 +218,16 @@ protected:
int _inventoryItemSpriteIndices[kInventoryItemSpriteCount];
InventoryItemInfo _inventoryItemInfos[kInventoryItemCount];
int _dialogItemSpriteIndices[kDialogItemSpriteCount];
-
+
int _fieldC;
int _buttheadObjectIndex;
Common::Point readPoint(Common::SeekableReadStream &s);
Common::Rect readRect(Common::SeekableReadStream &s);
Conditions readConditions(Common::SeekableReadStream &s);
-
+
void unload();
-
+
void loadBgSprites(Common::SeekableReadStream &s);
void loadCameraInits(Common::SeekableReadStream &s);
void loadWalkRects(Common::SeekableReadStream &s);
@@ -243,7 +243,7 @@ protected:
void loadDialogItemSpriteIndices(Common::SeekableReadStream &s);
void loadSceneSounds(Common::SeekableReadStream &s);
void loadPreloadSounds(Common::SeekableReadStream &s);
-
+
};
} // End of namespace Bbvs
diff --git a/engines/bbvs/graphics.cpp b/engines/bbvs/graphics.cpp
index 810d910abf..43840607c8 100644
--- a/engines/bbvs/graphics.cpp
+++ b/engines/bbvs/graphics.cpp
@@ -104,9 +104,9 @@ void Screen::drawSprite(Sprite &sprite, int x, int y) {
}
if (destX + width >= _surface->w)
width = _surface->w - destX;
-
+
debug(0, "drawSprite() (%d, %d, %d, %d); skipX: %d; skipY: %d; %d", destX, destY, width, height, skipX, skipY, sprite.type);
-
+
if (sprite.type == 1) {
for (int yc = 0; yc < height; ++yc) {
byte *source = sprite.getRow(skipY + yc);
diff --git a/engines/bbvs/minigames/bbairguitar.cpp b/engines/bbvs/minigames/bbairguitar.cpp
index f2e42313e3..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[] = {
@@ -198,12 +204,12 @@ void MinigameBbAirGuitar::buildDrawList1(DrawList &drawList) {
if (_trackBarX > kTrackBarMaxX)
_trackBarX = kTrackBarMaxX;
-
+
_trackBarThumbRect.top = 208;
_trackBarThumbRect.bottom = 218;
_trackBarThumbRect.left = _trackBarX;
_trackBarThumbRect.right = _trackBarX + 6;
-
+
drawList.add(_objects[5].anim->frameIndices[0], _trackBarX, 208, 100);
if (_playerMode != 0) {
@@ -228,7 +234,7 @@ void MinigameBbAirGuitar::buildDrawList1(DrawList &drawList) {
drawList.add(_objects[i].anim->frameIndices[frameIndex], kPointsTbl2[i - 47].x, kPointsTbl2[i - 47].y, 254);
}
}
-
+
if (_backgroundSpriteIndex > 0)
drawList.add(_backgroundSpriteIndex, 0, 0, 0);
@@ -394,7 +400,7 @@ void MinigameBbAirGuitar::initObjects1() {
_track[0].noteNum = -1;
stop();
changePatch(0);
-
+
}
bool MinigameBbAirGuitar::updateStatus(int mouseX, int mouseY, uint mouseButtons) {
@@ -408,7 +414,7 @@ bool MinigameBbAirGuitar::updateStatus(int mouseX, int mouseY, uint mouseButtons
}
bool MinigameBbAirGuitar::updateStatus0(int mouseX, int mouseY, uint mouseButtons) {
-
+
if (mouseButtons & kAnyButtonDown) {
stopSound(1);
_rockTunePlaying = false;
@@ -436,14 +442,14 @@ bool MinigameBbAirGuitar::updateStatus0(int mouseX, int mouseY, uint mouseButton
}
}
-
+
return true;
}
bool MinigameBbAirGuitar::updateStatus1(int mouseX, int mouseY, uint mouseButtons) {
-
+
int currTicks = _vm->_system->getMillis();
-
+
if (_playerMode == 1 && _track[_trackIndex].ticks <= currTicks - _noteStartTime) {
noteOff(_track[_trackIndex].noteNum);
if (_trackIndex < _trackCount && _track[++_trackIndex].noteNum != -1)
@@ -481,17 +487,17 @@ bool MinigameBbAirGuitar::updateStatus1(int mouseX, int mouseY, uint mouseButton
} else {
++_vuMeterRight2;
}
-
+
if (_resetAnims && _vm->_system->getMillis() - _noteStartTime >= 1000)
resetObjs();
-
+
_objects[0].x = mouseX;
_objects[0].y = mouseY;
-
+
_trackBarMouseX = CLIP(mouseX, kTrackBarMinX, kTrackBarMaxX);
-
+
bool checkClick = false;
-
+
if (mouseButtons & kAnyButtonClicked) {
checkClick = true;
} else if (!(mouseButtons & kAnyButtonDown)) {
@@ -506,14 +512,14 @@ bool MinigameBbAirGuitar::updateStatus1(int mouseX, int mouseY, uint mouseButton
}
} else if (!_movingTrackBar)
checkClick = true;
-
+
if (checkClick) {
afterButtonReleased();
_objects[0].frameIndex = 1;
-
+
if (ptInRect(&kRect2, mouseX, mouseY)) {
-
+
if (_playerMode != 1 && ptInRect(&kPianoRect, mouseX, mouseY)) {
for (int i = 0; i <= 12; ++i) {
if (ptInPoly(&kPianoKeyAreas[i], mouseX, mouseY)) {
@@ -538,7 +544,7 @@ bool MinigameBbAirGuitar::updateStatus1(int mouseX, int mouseY, uint mouseButton
break;
}
}
-
+
if (playerButtonNum >= 0) {
_currButtonNum = playerButtonNum;
_currPlayerButtonRect = &kPlayerButtonRects[playerButtonNum];
@@ -673,12 +679,12 @@ bool MinigameBbAirGuitar::updateStatus1(int mouseX, int mouseY, uint mouseButton
}
}
}
-
+
if (_buttonClickTicks + 1000 < currTicks)
_buttonClickTicks = currTicks;
-
+
int newKind = _buttonClickTicks + 500 < currTicks ? 1 : 0;
-
+
switch (_playerMode) {
case 1:
@@ -770,20 +776,20 @@ bool MinigameBbAirGuitar::run(bool fromMainGame) {
_gameResult = false;
_gameDone = false;
initObjects();
-
+
_spriteModule = new SpriteModule();
_spriteModule->load("bbairg/bbairg.000");
Palette palette = _spriteModule->getPalette();
_vm->_screen->setPalette(palette);
-
+
loadSounds();
-
+
while (!_vm->shouldQuit() &&!_gameDone) {
_vm->updateEvents();
update();
}
-
+
_vm->_sound->unloadSounds();
delete _spriteModule;
@@ -803,15 +809,15 @@ void MinigameBbAirGuitar::update() {
inputTicks = 1;
_gameTicks = _vm->_system->getMillis();
}
-
+
if (_vm->_keyCode == Common::KEYCODE_ESCAPE) {
- _gameDone = true;
+ _gameDone = querySaveModifiedTracks();
return;
}
-
+
if (inputTicks == 0)
return;
-
+
bool done;
do {
@@ -820,9 +826,9 @@ void MinigameBbAirGuitar::update() {
_vm->_mouseButtons &= ~kRightButtonClicked;
_vm->_keyCode = Common::KEYCODE_INVALID;
} while (--inputTicks && _gameTicks > 0 && !done);
-
+
drawSprites();
-
+
_vm->_system->delayMillis(10);
}
@@ -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;
@@ -1001,7 +1009,7 @@ void MinigameBbAirGuitar::calcTotalTicks1() {
}
void MinigameBbAirGuitar::noteOn(int noteNum) {
-
+
if (_currNoteNum != -2) {
if (noteNum == _currNoteNum)
return;
@@ -1087,7 +1095,7 @@ void MinigameBbAirGuitar::noteOn(int noteNum) {
}
void MinigameBbAirGuitar::noteOff(int noteNum) {
-
+
if (_currNoteNum != noteNum)
return;
@@ -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 d4fd6ec30c..b8b92ef433 100644
--- a/engines/bbvs/minigames/bbairguitar.h
+++ b/engines/bbvs/minigames/bbairguitar.h
@@ -32,7 +32,7 @@ public:
MinigameBbAirGuitar(BbvsEngine *vm) : Minigame(vm) {};
bool run(bool fromMainGame);
public:
-
+
struct Obj {
int kind;
int x, y;
@@ -44,24 +44,24 @@ public:
int16 frameIndexAdd;
int16 unk2;
};
-
+
enum {
kMaxObjectsCount = 256,
- kMaxTracks = 2049
+ kMaxTracks = 2048
};
-
+
struct PianoKeyInfo {
int x, y;
int frameIndex;
};
-
+
struct TrackEvt {
int8 noteNum;
int16 ticks;
};
-
+
Obj _objects[kMaxObjectsCount];
-
+
int _playerMode;
bool _modified;
@@ -82,24 +82,24 @@ public:
int *_currFrameIndex;
int _btn3KindToggle;
-
+
const BBPolygon *_currPianoKeyArea;
const Rect *_currPlayerButtonRect;
-
+
bool _movingTrackBar;
int _trackBarMouseX;
int _trackBarX;
Rect _trackBarThumbRect;
-
+
int _currTrackPos, _totalTrackLength;
int _ticksDelta;
-
+
int _actionStartTrackPos, _actionTrackPos;
int _actionStartTime;
int _currNoteNum;
int _currPatchNum;
-
+
const ObjAnimation *getAnimation(int animIndex);
bool ptInRect(const Rect *r, int x, int y);
bool ptInPoly(const BBPolygon *poly, int x, int y);
@@ -109,14 +109,14 @@ public:
void buildDrawList1(DrawList &drawList);
void drawSprites();
-
+
void initObjs();
Obj *getFreeObject();
-
+
void initObjects();
void initObjects0();
void initObjects1();
-
+
bool updateStatus(int mouseX, int mouseY, uint mouseButtons);
bool updateStatus0(int mouseX, int mouseY, uint mouseButtons);
bool updateStatus1(int mouseX, int mouseY, uint mouseButtons);
@@ -124,7 +124,7 @@ public:
void updateObjs();
void update();
-
+
void play();
void record();
void setPlayerMode3();
@@ -136,11 +136,20 @@ public:
void noteOn(int noteNum);
void noteOff(int noteNum);
void resetObjs();
-
+
void loadSounds();
- void playNote(int noteNum);
+ 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/minigames/bbant.cpp b/engines/bbvs/minigames/bbant.cpp
index 9786682ada..3678934345 100644
--- a/engines/bbvs/minigames/bbant.cpp
+++ b/engines/bbvs/minigames/bbant.cpp
@@ -94,7 +94,7 @@ void MinigameBbAnt::buildDrawList1(DrawList &drawList) {
drawNumber(drawList, _score, 68, 16);
drawList.add(getAnimation(166)->frameIndices[0], 230, 2, 2000);
drawNumber(drawList, _levelTimeLeft, 280, 16);
-
+
for (int i = 0; i < _stompCount; ++i)
drawList.add(getAnimation(130)->frameIndices[0], 20 + i * 30, 230, 2000);
@@ -116,7 +116,7 @@ void MinigameBbAnt::buildDrawList3(DrawList &drawList) {
drawNumber(drawList, _hiScore, 208, 107);
}
-void MinigameBbAnt::drawMagnifyingGlass(DrawList &drawList) {
+void MinigameBbAnt::drawMagnifyingGlass(DrawList &drawList) {
scale2x(_objects[0].x - 28, _objects[0].y - 27);
drawList.clear();
drawList.add(_objects[0].anim->frameIndices[0], _objects[0].x, _objects[0].y, _objects[0].priority);
@@ -358,7 +358,7 @@ bool MinigameBbAnt::updateStatus0(int mouseX, int mouseY, uint mouseButtons) {
_objects[0].x = 0;
if (_objects[0].y < 0)
_objects[0].y = 0;
-
+
if ((mouseButtons & kLeftButtonDown) || (mouseButtons & kRightButtonDown)) {
_gameState = 1;
initObjects();
@@ -447,7 +447,7 @@ bool MinigameBbAnt::updateStatus1(int mouseX, int mouseY, uint mouseButtons) {
int maxKindCount = 0, objKind = 0;
_stompCounter2 = _stompCounter1;
-
+
for (int i = 0; i < 4; ++i)
testTbl[i] = _vm->getRandom(_bugsChanceByKind[i] - _bugsCountByKind[i]);
@@ -471,7 +471,7 @@ bool MinigameBbAnt::updateStatus1(int mouseX, int mouseY, uint mouseButtons) {
if (_stompCounter1 > 20)
--_stompCounter1;
}
-
+
return true;
}
@@ -701,7 +701,7 @@ void MinigameBbAnt::updateBugObjAnim(int objIndex) {
void MinigameBbAnt::updateObjAnim2(int objIndex) {
Obj *obj = &_objects[objIndex];
-
+
obj->animIndexIncr += _vm->getRandom(3) - 1;
if (obj->animIndexIncr < 0)
obj->animIndexIncr = 7;
@@ -736,7 +736,7 @@ bool MinigameBbAnt::isBugOutOfScreen(int objIndex) {
void MinigameBbAnt::updateObjAnim3(int objIndex) {
Obj *obj = &_objects[objIndex];
-
+
obj->animIndexIncr += _vm->getRandom(3) - 1;
if (obj->animIndexIncr < 0)
obj->animIndexIncr = 7;
@@ -752,7 +752,7 @@ void MinigameBbAnt::updateBugObj1(int objIndex) {
Obj *obj = &_objects[objIndex];
bool flag1 = false;
bool flag2 = false;
-
+
if (--obj->ticks == 0) {
++obj->frameIndex;
if (obj->anim->frameCount == obj->frameIndex) {
@@ -911,7 +911,7 @@ void MinigameBbAnt::updateStompObj(int objIndex) {
void MinigameBbAnt::updateSmokeObj(int objIndex) {
Obj *obj = &_objects[objIndex];
-
+
obj->x += obj->xIncr;
obj->y += obj->yIncr;
@@ -1047,7 +1047,7 @@ bool MinigameBbAnt::isMagGlassAtBug(int objIndex) {
Obj *obj = &_objects[objIndex];
Obj *obj0 = &_objects[0];
bool result = false;
-
+
if (obj->kind >= 1 && obj->kind <= 5) {
const BBRect &frameRect1 = obj0->anim->frameRects[0];
const int obj1X1 = obj0->x + frameRect1.x;
@@ -1102,7 +1102,7 @@ bool MinigameBbAnt::testObj5(int objIndex) {
}
void MinigameBbAnt::updateObjs(uint mouseButtons) {
-
+
for (int i = 12; i < kMaxObjectsCount; ++i) {
Obj *obj = &_objects[i];
@@ -1162,7 +1162,7 @@ void MinigameBbAnt::updateObjs(uint mouseButtons) {
}
}
-
+
}
}
@@ -1170,9 +1170,9 @@ void MinigameBbAnt::updateObjs(uint mouseButtons) {
bool MinigameBbAnt::run(bool fromMainGame) {
memset(_objects, 0, sizeof(_objects));
-
+
_numbersAnim = getAnimation(167);
-
+
_backgroundSpriteIndex = 303;
_titleScreenSpriteIndex = 304;
@@ -1187,23 +1187,23 @@ bool MinigameBbAnt::run(bool fromMainGame) {
_gameDone = false;
initObjects();
initVars();
-
+
_spriteModule = new SpriteModule();
_spriteModule->load("bbant/bbant.000");
Palette palette = _spriteModule->getPalette();
_vm->_screen->setPalette(palette);
-
+
loadSounds();
_gameTicks = 0;
playSound(12, true);
-
+
while (!_vm->shouldQuit() &&!_gameDone) {
_vm->updateEvents();
update();
}
-
+
_vm->_sound->unloadSounds();
if (!_fromMainGame)
@@ -1243,19 +1243,19 @@ void MinigameBbAnt::update() {
_vm->_mouseButtons &= ~kRightButtonClicked;
_vm->_keyCode = Common::KEYCODE_INVALID;
} while (--inputTicks && _gameTicks > 0 && !done);
-
+
drawSprites();
-
+
_vm->_system->delayMillis(10);
}
void MinigameBbAnt::scale2x(int x, int y) {
- Graphics::Surface *surface = _vm->_screen->_surface;
-
+ Graphics::Surface *surface = _vm->_screen->_surface;
+
int srcX = x + 14, srcY = y + 14;
int srcW = kScaleDim, srcH = kScaleDim;
-
+
if (srcX < 0) {
srcW += srcX;
srcX = 0;
@@ -1265,21 +1265,21 @@ void MinigameBbAnt::scale2x(int x, int y) {
srcH += srcY;
srcY = 0;
}
-
+
if (srcX + srcW >= 320)
srcW = 320 - srcX - 1;
-
+
if (srcY + srcH >= 240)
srcH = 240 - srcY - 1;
-
+
for (int yc = 0; yc < srcH; ++yc) {
byte *src = (byte*)surface->getBasePtr(srcX, srcY + yc);
memcpy(&_scaleBuf[yc * kScaleDim], src, srcW);
}
-
+
int dstX = x, dstY = y;
int dstW = 2 * kScaleDim, dstH = 2 * kScaleDim;
-
+
if (dstX < 0) {
dstW += dstX;
dstX = 0;
@@ -1289,15 +1289,15 @@ void MinigameBbAnt::scale2x(int x, int y) {
dstH += dstY;
dstY = 0;
}
-
+
if (dstX + dstW >= 320)
dstW = 320 - dstX - 1;
-
+
if (dstY + dstH >= 240)
dstH = 240 - dstY - 1;
-
+
int w = MIN(srcW * 2, dstW), h = MIN(srcH * 2, dstH);
-
+
for (int yc = 0; yc < h; ++yc) {
byte *src = _scaleBuf + kScaleDim * (yc / 2);
byte *dst = (byte*)surface->getBasePtr(dstX, dstY + yc);
diff --git a/engines/bbvs/minigames/bbant.h b/engines/bbvs/minigames/bbant.h
index be2afe688d..88b4af9c71 100644
--- a/engines/bbvs/minigames/bbant.h
+++ b/engines/bbvs/minigames/bbant.h
@@ -32,7 +32,7 @@ public:
MinigameBbAnt(BbvsEngine *vm) : Minigame(vm) {};
bool run(bool fromMainGame);
public:
-
+
struct Obj {
int kind;
int x, y, priority;
@@ -55,21 +55,21 @@ public:
int status2;
int flag;
};
-
+
enum {
kMaxObjectsCount = 256,
kScaleDim = 28
};
-
+
struct ObjInit {
const ObjAnimation *anim1;
const ObjAnimation *anim2;
const ObjAnimation *anim3;
int x, y;
};
-
+
Obj _objects[kMaxObjectsCount];
-
+
int _score, _hiScore;
int _totalBugsCount;
@@ -96,37 +96,37 @@ public:
int _countdown6;
int _countdown5;
int _countdown7;
-
+
byte _scaleBuf[kScaleDim * kScaleDim];
const ObjAnimation *getAnimation(int animIndex);
const ObjInit *getObjInit(int index);
const ObjAnimation * const *getObjKindAnimTable(int kind);
const ObjAnimation *getObjAnim(int index);
-
+
void buildDrawList0(DrawList &drawList);
void buildDrawList1(DrawList &drawList);
void buildDrawList2(DrawList &drawList);
void buildDrawList3(DrawList &drawList);
void drawMagnifyingGlass(DrawList &drawList);
-
+
void drawSprites();
void drawSprites0();
void drawSprites1();
void drawSprites2();
void drawSprites3();
-
+
Obj *getFreeObject();
-
+
void initObjects();
void initObjects0();
void initObjects1();
-
+
void initVars();
void initVars1();
void initVars2();
void initVars3();
-
+
bool updateStatus(int mouseX, int mouseY, uint mouseButtons);
bool updateStatus0(int mouseX, int mouseY, uint mouseButtons);
bool updateStatus1(int mouseX, int mouseY, uint mouseButtons);
@@ -161,7 +161,7 @@ public:
void updateObjs(uint mouseButtons);
void update();
-
+
void scale2x(int x, int y);
void loadSounds();
diff --git a/engines/bbvs/minigames/bbloogie.cpp b/engines/bbvs/minigames/bbloogie.cpp
index 4601e9ff93..68a3147f9a 100644
--- a/engines/bbvs/minigames/bbloogie.cpp
+++ b/engines/bbvs/minigames/bbloogie.cpp
@@ -117,7 +117,7 @@ void MinigameBbLoogie::buildDrawList0(DrawList &drawList) {
}
void MinigameBbLoogie::buildDrawList1(DrawList &drawList) {
-
+
for (int i = 0; i < kMaxObjectsCount; ++i) {
Obj *obj = &_objects[i];
switch (obj->kind) {
@@ -163,7 +163,7 @@ void MinigameBbLoogie::buildDrawList1(DrawList &drawList) {
}
void MinigameBbLoogie::buildDrawList2(DrawList &drawList) {
-
+
buildDrawList1(drawList);
if (_level > 0 && (_bonusDisplayDelay1 > 0 || _bonusDisplayDelay2 > 0)) {
@@ -180,7 +180,7 @@ void MinigameBbLoogie::buildDrawList2(DrawList &drawList) {
}
void MinigameBbLoogie::buildDrawList3(DrawList &drawList) {
-
+
for (int i = 0; i < kMaxObjectsCount; ++i) {
Obj *obj = &_objects[i];
if (obj->kind == 2)
@@ -191,7 +191,7 @@ void MinigameBbLoogie::buildDrawList3(DrawList &drawList) {
if (_backgroundSpriteIndex)
drawList.add(_backgroundSpriteIndex, 0, 0, 0);
-
+
drawList.add(getAnimation(10)->frameIndices[0], 230, 2, 2000);
drawNumber(drawList, _levelTimeLeft, 280, 16);
@@ -201,7 +201,7 @@ void MinigameBbLoogie::buildDrawList3(DrawList &drawList) {
int numberX2 = drawNumber(drawList, _currScore, 68, 16);
drawList.add(getAnimation(9)->frameIndices[10], numberX2, 16, 2000);
drawNumber(drawList, _dispLevelScore, numberX2 + 10, 16);
-
+
drawList.add(getAnimation(20)->frameIndices[0], 120, 70, 2000);
drawList.add(getAnimation(13)->frameIndices[0], 95, 95, 2000);
@@ -416,7 +416,7 @@ bool MinigameBbLoogie::updateStatus(int mouseX, int mouseY, uint mouseButtons) {
}
bool MinigameBbLoogie::updateStatus0(int mouseX, int mouseY, uint mouseButtons) {
-
+
_objects[0].x = mouseX;
_objects[0].y = mouseY;
@@ -445,7 +445,7 @@ bool MinigameBbLoogie::updateStatus0(int mouseX, int mouseY, uint mouseButtons)
_objects[4].kind = 0;
_objects[2].kind = 1;
}
-
+
for (int i = 0; i < kMaxObjectsCount; ++i) {
Obj *obj = &_objects[i];
if (obj->kind == 11) {
@@ -487,12 +487,12 @@ bool MinigameBbLoogie::updateStatus0(int mouseX, int mouseY, uint mouseButtons)
initVars();
_gameTicks = 0;
}
-
+
return true;
}
bool MinigameBbLoogie::updateStatus1(int mouseX, int mouseY, uint mouseButtons) {
-
+
if (--_levelTimeDelay == 0) {
_levelTimeDelay = 58;
--_levelTimeLeft;
@@ -568,9 +568,9 @@ bool MinigameBbLoogie::updateStatus2(int mouseX, int mouseY, uint mouseButtons)
}
bool MinigameBbLoogie::updateStatus3(int mouseX, int mouseY, uint mouseButtons) {
-
+
_objects[0].x = mouseX;
-
+
for (int i = 0; i < kMaxObjectsCount; ++i) {
Obj *obj = &_objects[i];
if (obj->kind == 2) {
@@ -582,7 +582,7 @@ bool MinigameBbLoogie::updateStatus3(int mouseX, int mouseY, uint mouseButtons)
}
}
}
-
+
return true;
}
@@ -620,7 +620,7 @@ void MinigameBbLoogie::updateObjs(uint mouseButtons) {
break;
}
}
-
+
if (--_carDelay == 0) {
// Car
Obj *obj = getFreeObject();
@@ -633,7 +633,7 @@ void MinigameBbLoogie::updateObjs(uint mouseButtons) {
obj->yIncr = 0;
_carDelay = _vm->getRandom(256) + 800;
}
-
+
if (--_bikeDelay == 0) {
// Bike
Obj *obj = getFreeObject();
@@ -646,7 +646,7 @@ void MinigameBbLoogie::updateObjs(uint mouseButtons) {
obj->yIncr = 0;
_bikeDelay = _vm->getRandom(512) + 500;
}
-
+
if (--_squirrelDelay == 0) {
// Squirrel
Obj *obj = getFreeObject();
@@ -662,7 +662,7 @@ void MinigameBbLoogie::updateObjs(uint mouseButtons) {
playSound(9);
_squirrelDelay = _vm->getRandom(512) + 300;
}
-
+
if (--_paperPlaneDelay == 0) {
// Paper plane
Obj *obj = getFreeObject();
@@ -685,7 +685,7 @@ void MinigameBbLoogie::updateObjs(uint mouseButtons) {
}
_paperPlaneDelay = 400;
}
-
+
if (_principalDelay >= 0 && --_principalDelay == 0) {
// Principal
Obj *obj = getFreeObject();
@@ -703,13 +703,13 @@ void MinigameBbLoogie::updateObjs(uint mouseButtons) {
_principalFirstFrameIndex = 11;
_principalLastFrameIndex = 16;
}
-
+
}
void MinigameBbLoogie::updatePlayer(int objIndex, uint mouseButtons) {
Obj *obj = &_objects[0];
-
+
switch (obj->status) {
case 1:
@@ -817,7 +817,7 @@ void MinigameBbLoogie::updateLoogie(int objIndex) {
obj->y -= kLoogieOffY[obj->unk2 / 8];
--obj->unk2;
}
-
+
if (obj->ticks-- == 0) {
obj->ticks = getAnimation(5)->frameTicks[0];
++obj->frameIndex;
@@ -832,9 +832,9 @@ void MinigameBbLoogie::updateLoogie(int objIndex) {
void MinigameBbLoogie::updateCar(int objIndex) {
Obj *obj = &_objects[objIndex];
-
+
obj->x += obj->xIncr;
-
+
if (obj->ticks-- == 0) {
if (obj->frameIndex++ == 3 || obj->frameIndex == 6)
obj->frameIndex = 0;
@@ -867,7 +867,7 @@ void MinigameBbLoogie::updateCar(int objIndex) {
void MinigameBbLoogie::updateBike(int objIndex) {
Obj *obj = &_objects[objIndex];
-
+
obj->x += obj->xIncr;
if (obj->ticks-- == 0) {
@@ -965,7 +965,7 @@ void MinigameBbLoogie::updatePaperPlane(int objIndex) {
loogieObj = findLoogieObj(loogieObjIndex++);
}
}
-
+
}
void MinigameBbLoogie::updateIndicator(int objIndex) {
@@ -995,7 +995,7 @@ void MinigameBbLoogie::updateIndicator(int objIndex) {
obj->kind = 0;
obj->anim = getAnimation(6);
}
-
+
}
void MinigameBbLoogie::updatePrincipal(int objIndex) {
@@ -1281,22 +1281,22 @@ bool MinigameBbLoogie::run(bool fromMainGame) {
_gameDone = false;
initObjects();
initVars();
-
+
_spriteModule = new SpriteModule();
_spriteModule->load("bbloogie/bbloogie.000");
Palette palette = _spriteModule->getPalette();
_vm->_screen->setPalette(palette);
-
+
loadSounds();
playSound(32, true);
-
+
while (!_vm->shouldQuit() &&!_gameDone) {
_vm->updateEvents();
update();
}
-
+
_vm->_sound->unloadSounds();
if (!_fromMainGame)
@@ -1319,15 +1319,15 @@ void MinigameBbLoogie::update() {
inputTicks = 1;
_gameTicks = _vm->_system->getMillis();
}
-
+
if (_vm->_keyCode == Common::KEYCODE_ESCAPE) {
_gameDone = true;
return;
}
-
+
if (inputTicks == 0)
return;
-
+
bool done;
do {
@@ -1336,9 +1336,9 @@ void MinigameBbLoogie::update() {
_vm->_mouseButtons &= ~kRightButtonClicked;
_vm->_keyCode = Common::KEYCODE_INVALID;
} while (--inputTicks && _gameTicks > 0 && !done);
-
+
drawSprites();
-
+
_vm->_system->delayMillis(10);
}
diff --git a/engines/bbvs/minigames/bbloogie.h b/engines/bbvs/minigames/bbloogie.h
index 1dd4049b41..04ead51a1e 100644
--- a/engines/bbvs/minigames/bbloogie.h
+++ b/engines/bbvs/minigames/bbloogie.h
@@ -32,7 +32,7 @@ public:
MinigameBbLoogie(BbvsEngine *vm) : Minigame(vm) {};
bool run(bool fromMainGame);
public:
-
+
struct Obj {
int kind;
int x, y;
@@ -44,33 +44,33 @@ public:
int16 frameIndexAdd;
int16 unk2;
};
-
+
enum {
kMaxObjectsCount = 256
};
-
+
enum {
kGSTitleScreen = 0, // Title screen
kGSMainGame = 1, // Game when called as part of the main game
kGSStandaloneGame = 2, // Game when called as standalone game
kGSScoreCountUp = 3 // Score countup and next level text
};
-
+
Obj _objects[kMaxObjectsCount];
-
+
int _playerKind;
const ObjAnimation *_playerAnim;
const uint *_playerSounds1, *_playerSounds2;
uint _playerSounds1Count, _playerSounds2Count;
-
+
int _level, _levelTimeLeft, _levelTimeDelay;
- int _numberOfHits, _currScore, _hiScore;
+ int _numberOfHits, _currScore, _hiScore;
int _doubleScore, _megaLoogieCount;
-
+
int _dispLevelScore, _nextLevelScore;
int _timeBonusCtr, _bonusDisplayDelay1, _bonusDisplayDelay2, _bonusDisplayDelay3;
-
+
int _carDelay;
int _bikeDelay;
int _squirrelDelay;
@@ -78,37 +78,37 @@ public:
int _paperPlaneDelay;
int _principalDelay;
- int _prevPrincipalStatus;
+ int _prevPrincipalStatus;
int _principalCtr, _principalFirstFrameIndex, _principalLastFrameIndex;
bool _principalAngry;
-
+
const ObjAnimation *getAnimation(int animIndex);
-
+
void buildDrawList(DrawList &drawList);
void buildDrawList0(DrawList &drawList);
void buildDrawList1(DrawList &drawList);
void buildDrawList2(DrawList &drawList);
void buildDrawList3(DrawList &drawList);
-
+
void drawSprites();
-
+
void initObjs();
Obj *getFreeObject();
Obj *findLoogieObj(int startObjIndex);
bool isHit(Obj *obj1, Obj *obj2);
bool isCursorAtObj(int objIndex);
-
+
void initObjects();
void initObjects0();
void initObjects1();
void initObjects3();
-
+
void initVars();
void initVars0();
void initVars1();
void initVars2();
void initVars3();
-
+
bool updateStatus(int mouseX, int mouseY, uint mouseButtons);
bool updateStatus0(int mouseX, int mouseY, uint mouseButtons);
bool updateStatus1(int mouseX, int mouseY, uint mouseButtons);
@@ -129,7 +129,7 @@ public:
void incNumberOfHits();
void incScore(int incrAmount);
void playRndSound();
-
+
void update();
void loadSounds();
diff --git a/engines/bbvs/minigames/bbtennis.cpp b/engines/bbvs/minigames/bbtennis.cpp
index ddd5cfc804..7763548330 100644
--- a/engines/bbvs/minigames/bbtennis.cpp
+++ b/engines/bbvs/minigames/bbtennis.cpp
@@ -86,7 +86,7 @@ void MinigameBbTennis::buildDrawList(DrawList &drawList) {
}
void MinigameBbTennis::buildDrawList0(DrawList &drawList) {
-
+
drawList.add(_objects[0].anim->frameIndices[_objects[0].frameIndex], _objects[0].x, _objects[0].y, 2000);
for (int i = 0; i < kMaxObjectsCount; ++i) {
@@ -154,7 +154,7 @@ void MinigameBbTennis::buildDrawList1(DrawList &drawList) {
break;
}
-
+
drawList.add(index, x, y, priority);
}
@@ -174,16 +174,16 @@ void MinigameBbTennis::buildDrawList1(DrawList &drawList) {
drawList.add(getAnimation(9)->frameIndices[0], 256, 52, 500);
drawList.add(getAnimation(10)->frameIndices[0], 60, 162, 500);
drawList.add(getAnimation(21)->frameIndices[0], 36, 18, 2000);
-
+
drawNumber(drawList, _score, 70, 18);
-
+
for (int i = 0; i < _numHearts; ++i)
drawList.add(getAnimation(7)->frameIndices[0], 20 + i * 20, 236, 990);
}
void MinigameBbTennis::buildDrawList2(DrawList &drawList) {
-
+
for (int i = 0; i < kMaxObjectsCount; ++i) {
Obj *obj = &_objects[i];
if (obj->kind)
@@ -384,7 +384,7 @@ bool MinigameBbTennis::updateStatus1(int mouseX, int mouseY, uint mouseButtons)
_objects[0].x = mouseX;
_objects[0].y = mouseY;
-
+
if (_allHeartsGone) {
_gameState = 2;
initObjects();
@@ -427,13 +427,13 @@ bool MinigameBbTennis::updateStatus1(int mouseX, int mouseY, uint mouseButtons)
if (_newBallTimer > 0)
--_newBallTimer;
-
+
if (++_delayDecreaseTimer == 30) {
_delayDecreaseTimer = 0;
if (_playerDecrease < 199)
++_playerDecrease;
}
-
+
updateObjs();
if (!_playedThisIsTheCoolest && _score > 3 && _vm->getRandom(10) == 1 && !isAnySoundPlaying(kAllSounds, 11)) {
@@ -482,7 +482,7 @@ void MinigameBbTennis::updateObjs() {
break;
}
}
-
+
if (_rapidFireBallsCount == 0) {
--_squirrelDelay;
if (--_squirrelDelay == 0) {
@@ -763,7 +763,7 @@ void MinigameBbTennis::updateTennisPlayer(int objIndex) {
}
++_tennisPlayerDelay;
break;
-
+
case 2:
if (--obj->ticks == 0) {
++obj->frameIndex;
@@ -1077,7 +1077,7 @@ void MinigameBbTennis::updateNetPlayer(int objIndex) {
void MinigameBbTennis::updateEnemyTennisBall(int objIndex) {
Obj *obj = &_objects[objIndex];
-
+
if (--obj->ticks == 0) {
--obj->frameIndex;
obj->ticks = getAnimation(6)->frameTicks[obj->frameIndex];
@@ -1103,7 +1103,7 @@ void MinigameBbTennis::updateEnemyTennisBall(int objIndex) {
obj->x = (int)obj->fltX;
obj->fltY = obj->fltY - obj->fltStepY;
obj->y = (int)obj->fltY;
-
+
}
void MinigameBbTennis::makeEnemyBall(int x, int y, int frameIndex) {
@@ -1184,7 +1184,7 @@ void MinigameBbTennis::hitSomething() {
bool MinigameBbTennis::run(bool fromMainGame) {
memset(_objects, 0, sizeof(_objects));
-
+
_numbersAnim = getAnimation(20);
_backgroundSpriteIndex = 272;
@@ -1201,23 +1201,23 @@ bool MinigameBbTennis::run(bool fromMainGame) {
_gameDone = false;
initObjects();
initVars();
-
+
_spriteModule = new SpriteModule();
_spriteModule->load("bbtennis/bbtennis.000");
Palette palette = _spriteModule->getPalette();
_vm->_screen->setPalette(palette);
-
+
loadSounds();
_gameTicks = 0;
playSound(29, true);
-
+
while (!_vm->shouldQuit() &&!_gameDone) {
_vm->updateEvents();
update();
}
-
+
_vm->_sound->unloadSounds();
if (!_fromMainGame)
@@ -1240,15 +1240,15 @@ void MinigameBbTennis::update() {
inputTicks = 1;
_gameTicks = _vm->_system->getMillis();
}
-
+
if (_vm->_keyCode == Common::KEYCODE_ESCAPE) {
_gameDone = true;
return;
}
-
+
if (inputTicks == 0)
return;
-
+
bool done;
do {
@@ -1257,9 +1257,9 @@ void MinigameBbTennis::update() {
_vm->_mouseButtons &= ~kRightButtonClicked;
_vm->_keyCode = Common::KEYCODE_INVALID;
} while (--inputTicks && _gameTicks > 0 && !done);
-
+
drawSprites();
-
+
_vm->_system->delayMillis(10);
}
diff --git a/engines/bbvs/minigames/bbtennis.h b/engines/bbvs/minigames/bbtennis.h
index 690bd724a0..7eac904c4d 100644
--- a/engines/bbvs/minigames/bbtennis.h
+++ b/engines/bbvs/minigames/bbtennis.h
@@ -32,7 +32,7 @@ public:
MinigameBbTennis(BbvsEngine *vm) : Minigame(vm) {};
bool run(bool fromMainGame);
public:
-
+
struct Obj {
int kind;
int x, y;
@@ -51,20 +51,20 @@ public:
int ballStepCtr;
int netPlayDirection;
};
-
+
enum {
kMaxObjectsCount = 256
};
-
+
enum {
kGSTitleScreen = 0, // Title screen
kGSMainGame = 1, // Game when called as part of the main game
kGSStandaloneGame = 2, // Game when called as standalone game
kGSScoreCountUp = 3 // Score countup and next level text
};
-
+
Obj _objects[kMaxObjectsCount];
-
+
int _numHearts;
int _squirrelDelay;
int _tennisPlayerDelay;
@@ -85,29 +85,29 @@ public:
bool _endSoundPlaying;
const ObjAnimation *getAnimation(int animIndex);
-
+
void buildDrawList(DrawList &drawList);
void buildDrawList0(DrawList &drawList);
void buildDrawList1(DrawList &drawList);
void buildDrawList2(DrawList &drawList);
-
+
void drawSprites();
-
+
void initObjs();
Obj *getFreeObject();
Obj *findTennisBall(int startObjIndex);
bool isHit(Obj *obj1, Obj *obj2);
-
+
void initObjects();
void initObjects0();
void initObjects1();
void initObjects2();
-
+
void initVars();
void initVars0();
void initVars1();
void initVars2();
-
+
bool updateStatus(int mouseX, int mouseY, uint mouseButtons);
bool updateStatus0(int mouseX, int mouseY, uint mouseButtons);
bool updateStatus1(int mouseX, int mouseY, uint mouseButtons);
diff --git a/engines/bbvs/minigames/minigame.cpp b/engines/bbvs/minigames/minigame.cpp
index aae18072d9..58d98a9df8 100644
--- a/engines/bbvs/minigames/minigame.cpp
+++ b/engines/bbvs/minigames/minigame.cpp
@@ -44,13 +44,13 @@ Minigame::~Minigame() {
int Minigame::drawNumber(DrawList &drawList, int number, int x, int y) {
int digits = 1, rightX = x;
-
+
for (int mag = 10; number / mag != 0; mag *= 10)
++digits;
-
+
rightX = x + digits * 10;
x = rightX;
-
+
while (digits--) {
const int n = number % 10;
x -= 10;
diff --git a/engines/bbvs/minigames/minigame.h b/engines/bbvs/minigames/minigame.h
index 675dec360d..1c24110519 100644
--- a/engines/bbvs/minigames/minigame.h
+++ b/engines/bbvs/minigames/minigame.h
@@ -51,30 +51,30 @@ public:
virtual ~Minigame();
virtual bool run(bool fromMainGame) = 0;
protected:
- BbvsEngine *_vm;
+ BbvsEngine *_vm;
SpriteModule *_spriteModule;
-
+
int _gameState;
int _gameTicks;
bool _gameResult;
bool _gameDone;
bool _fromMainGame;
int _hiScoreTable[kMinigameCount];
-
+
int _backgroundSpriteIndex, _titleScreenSpriteIndex;
-
+
const ObjAnimation *_numbersAnim;
-
+
int drawNumber(DrawList &drawList, int number, int x, int y);
void playSound(uint index, bool loop = false);
void stopSound(uint index);
bool isSoundPlaying(uint index);
bool isAnySoundPlaying(const uint *indices, uint count);
-
+
void saveHiscore(int minigameNum, int score);
int loadHiscore(int minigameNum);
-
+
};
} // End of namespace Bbvs
diff --git a/engines/bbvs/saveload.cpp b/engines/bbvs/saveload.cpp
index ff53cc457b..e7725713fd 100644
--- a/engines/bbvs/saveload.cpp
+++ b/engines/bbvs/saveload.cpp
@@ -73,7 +73,7 @@ void BbvsEngine::savegame(const char *filename, const char *description) {
byte descriptionLen = strlen(description);
out->writeByte(descriptionLen);
out->write(description, descriptionLen);
-
+
Graphics::saveThumbnail(*out);
// Not used yet, reserved for future usage
@@ -86,7 +86,7 @@ void BbvsEngine::savegame(const char *filename, const char *description) {
out->writeUint32LE(saveTime);
out->writeUint32LE(playTime);
// Header end
-
+
out->write(_snapshot, _snapshotStream->pos());
out->finalize();
@@ -103,15 +103,15 @@ void BbvsEngine::loadgame(const char *filename) {
SaveHeader header;
kReadSaveHeaderError errorCode = readSaveHeader(in, false, header);
-
+
if (errorCode != kRSHENoError) {
warning("Error loading savegame '%s'", filename);
delete in;
return;
}
-
+
g_engine->setTotalPlayTime(header.playTime * 1000);
-
+
memset(_sceneObjects, 0, sizeof(_sceneObjects));
for (int i = 0; i < kSceneObjectsCount; ++i) {
_sceneObjects[i].walkDestPt.x = -1;
@@ -120,7 +120,7 @@ void BbvsEngine::loadgame(const char *filename) {
_currSceneNum = 0;
_newSceneNum = in->readUint32LE();
-
+
initScene(false);
_prevSceneNum = in->readUint32LE();
@@ -157,16 +157,16 @@ void BbvsEngine::loadgame(const char *filename) {
obj->frameIndex = in->readUint32LE();
obj->frameTicks = in->readUint32LE();
obj->walkCount = in->readUint32LE();
- obj->xIncr = in->readUint32LE();
+ obj->xIncr = in->readUint32LE();
obj->yIncr = in->readUint32LE();
- obj->turnValue = in->readUint32LE();
- obj->turnCount = in->readUint32LE();
+ obj->turnValue = in->readUint32LE();
+ obj->turnCount = in->readUint32LE();
obj->turnTicks = in->readUint32LE();
obj->walkDestPt.x = in->readUint16LE();
obj->walkDestPt.y = in->readUint16LE();
obj->anim = obj->animIndex > 0 ? _gameModule->getAnimation(obj->animIndex) : 0;
}
-
+
updateWalkableRects();
// Restart scene background sounds
@@ -259,10 +259,10 @@ void BbvsEngine::saveSnapshot() {
_snapshotStream->writeUint32LE(obj->frameIndex);
_snapshotStream->writeUint32LE(obj->frameTicks);
_snapshotStream->writeUint32LE(obj->walkCount);
- _snapshotStream->writeUint32LE(obj->xIncr);
+ _snapshotStream->writeUint32LE(obj->xIncr);
_snapshotStream->writeUint32LE(obj->yIncr);
- _snapshotStream->writeUint32LE(obj->turnValue);
- _snapshotStream->writeUint32LE(obj->turnCount);
+ _snapshotStream->writeUint32LE(obj->turnValue);
+ _snapshotStream->writeUint32LE(obj->turnCount);
_snapshotStream->writeUint32LE(obj->turnTicks);
_snapshotStream->writeUint16LE(obj->walkDestPt.x);
_snapshotStream->writeUint16LE(obj->walkDestPt.y);
diff --git a/engines/bbvs/scene.cpp b/engines/bbvs/scene.cpp
index 0d86eb4dbc..a89c88fd82 100644
--- a/engines/bbvs/scene.cpp
+++ b/engines/bbvs/scene.cpp
@@ -34,7 +34,7 @@ static const int kAfterVideoSceneNum[] = {
void BbvsEngine::loadScene(int sceneNum) {
debug(0, "BbvsEngine::loadScene() sceneNum: %d", sceneNum);
-
+
Common::String sprFilename = Common::String::format("vnm/vspr%04d.vnm", sceneNum);
Common::String gamFilename = Common::String::format("vnm/game%04d.vnm", sceneNum);
@@ -42,7 +42,7 @@ void BbvsEngine::loadScene(int sceneNum) {
_spriteModule->load(sprFilename.c_str());
_gameModule->load(gamFilename.c_str());
-
+
Palette palette = _spriteModule->getPalette();
_screen->setPalette(palette);
@@ -106,10 +106,10 @@ void BbvsEngine::initScene(bool sounds) {
loadScene(_newSceneNum);
_currSceneNum = _newSceneNum;
_newSceneNum = 0;
-
+
for (int i = 0; i < _gameModule->getSceneObjectDefsCount(); ++i)
_sceneObjects[i].sceneObjectDef = _gameModule->getSceneObjectDef(i);
-
+
for (int i = 0; i < _gameModule->getSceneObjectInitsCount(); ++i) {
SceneObjectInit *soInit = _gameModule->getSceneObjectInit(i);
if (evalCondition(soInit->conditions)) {
@@ -149,10 +149,10 @@ void BbvsEngine::initScene(bool sounds) {
}
}
}
-
+
_cameraPos = _gameModule->getCameraInit(_currCameraNum)->cameraPos;
_newCameraPos = _cameraPos;
-
+
_walkAreaActions.clear();
for (int i = 0; i < _gameModule->getActionsCount(); ++i) {
Action *action = _gameModule->getAction(i);
@@ -165,7 +165,7 @@ void BbvsEngine::initScene(bool sounds) {
_activeItemIndex = 0;
_activeItemType = kITEmpty;
-
+
for (int i = 0; i < _gameModule->getActionsCount(); ++i) {
Action *action = _gameModule->getAction(i);
if (evalCondition(action->conditions)) {
@@ -183,7 +183,7 @@ void BbvsEngine::initScene(bool sounds) {
break;
}
}
-
+
if (sounds)
updateBackgroundSounds();
@@ -192,7 +192,7 @@ void BbvsEngine::initScene(bool sounds) {
bool BbvsEngine::changeScene() {
writeContinueSavegame();
-
+
if (_newSceneNum >= 27 && _newSceneNum <= 30) {
// Run minigames
stopSpeech();
@@ -221,7 +221,7 @@ bool BbvsEngine::changeScene() {
}
return true;
-
+
}
} // End of namespace Bbvs
diff --git a/engines/bbvs/spritemodule.cpp b/engines/bbvs/spritemodule.cpp
index 8eae7f9a6a..f8b0d9afd5 100644
--- a/engines/bbvs/spritemodule.cpp
+++ b/engines/bbvs/spritemodule.cpp
@@ -41,15 +41,15 @@ SpriteModule::~SpriteModule() {
void SpriteModule::load(const char *filename) {
unload();
-
+
Common::File fd;
if (!fd.open(filename))
error("SpriteModule::load() Could not open %s", filename);
-
+
fd.readUint32LE(); // Skip magic
fd.readUint32LE(); // Skip unused
fd.readUint32LE(); // Skip filesize
-
+
_paletteOffs = fd.readUint32LE();
fd.readUint32LE(); // Skip unused flagsTbl1Ofs
fd.readUint32LE(); // Skip unused flagsTbl2Ofs
@@ -57,18 +57,18 @@ void SpriteModule::load(const char *filename) {
_paletteStart = fd.readUint32LE();
_paletteCount = fd.readUint32LE();
_spritesCount = fd.readUint32LE();
-
+
debug(0, "_paletteOffs: %08X", _paletteOffs);
debug(0, "_spriteTblOffs: %08X", _spriteTblOffs);
debug(0, "_paletteStart: %d", _paletteStart);
debug(0, "_paletteCount: %d", _paletteCount);
debug(0, "_spritesCount: %d", _spritesCount);
-
+
_spriteDataSize = fd.size();
_spriteData = new byte[_spriteDataSize];
fd.seek(0);
fd.read(_spriteData, _spriteDataSize);
-
+
// Convert palette
byte *palette = _spriteData + _paletteOffs;
for (int i = 0; i < _paletteCount; ++i) {
diff --git a/engines/bbvs/videoplayer.cpp b/engines/bbvs/videoplayer.cpp
index fda9372ade..9ea73ad10b 100644
--- a/engines/bbvs/videoplayer.cpp
+++ b/engines/bbvs/videoplayer.cpp
@@ -42,7 +42,7 @@ void BbvsEngine::playVideo(int videoNum) {
warning("Couldn't switch to a RGB color video mode to play a video.");
return;
}
-
+
Video::VideoDecoder *videoDecoder = new Video::AVIDecoder();
if (!videoDecoder->loadFile(videoFilename)) {
delete videoDecoder;
@@ -74,7 +74,7 @@ void BbvsEngine::playVideo(int videoNum) {
}
delete videoDecoder;
-
+
initGraphics(320, 240, false);
}
diff --git a/engines/bbvs/walk.cpp b/engines/bbvs/walk.cpp
index 077110b867..5ef14101a0 100644
--- a/engines/bbvs/walk.cpp
+++ b/engines/bbvs/walk.cpp
@@ -46,7 +46,7 @@ static const int8 kWalkAnimTbl[32] = {
void BbvsEngine::startWalkObject(SceneObject *sceneObject) {
if (_buttheadObject != sceneObject && _beavisObject != sceneObject)
return;
-
+
initWalkAreas(sceneObject);
_sourceWalkAreaPt.x = sceneObject->x >> 16;
_sourceWalkAreaPt.y = sceneObject->y >> 16;
@@ -60,7 +60,7 @@ void BbvsEngine::startWalkObject(SceneObject *sceneObject) {
_destWalkArea = getWalkAreaAtPos(_destWalkAreaPt);
if (!_destWalkArea)
return;
-
+
if (_sourceWalkArea != _destWalkArea) {
_currWalkDistance = kMaxDistance;
walkFindPath(_sourceWalkArea, 0);
@@ -68,12 +68,12 @@ void BbvsEngine::startWalkObject(SceneObject *sceneObject) {
}
walkObject(sceneObject, _destWalkAreaPt, sceneObject->sceneObjectDef->walkSpeed);
-
+
}
void BbvsEngine::updateWalkObject(SceneObject *sceneObject) {
int animIndex;
-
+
if (sceneObject->walkCount > 0 && (sceneObject->xIncr != 0 || sceneObject->yIncr != 0)) {
if (ABS(sceneObject->xIncr) <= ABS(sceneObject->yIncr))
sceneObject->turnValue = sceneObject->yIncr >= 0 ? 0 : 4;
@@ -89,7 +89,7 @@ void BbvsEngine::updateWalkObject(SceneObject *sceneObject) {
Animation *anim = 0;
if (animIndex > 0)
anim = _gameModule->getAnimation(animIndex);
-
+
if (sceneObject->anim != anim) {
if (anim) {
sceneObject->anim = anim;
@@ -305,12 +305,12 @@ bool BbvsEngine::canButtheadWalkToDest(const Common::Point &destPt) {
}
void BbvsEngine::canWalkToDest(WalkArea *walkArea, int infoCount) {
-
+
if (_destWalkArea == walkArea) {
_walkReachedDestArea = true;
return;
}
-
+
if (_gameModule->getFieldC() <= 320 || infoCount <= 20) {
walkArea->checked = true;
for (int linkIndex = 0; linkIndex < walkArea->linksCount; ++linkIndex) {
@@ -364,10 +364,10 @@ int BbvsEngine::calcDistance(const Common::Point &pt1, const Common::Point &pt2)
void BbvsEngine::walkFoundPath(int count) {
debug(5, "BbvsEngine::walkFoundPath(%d)", count);
-
+
Common::Point midPt = _sourceWalkAreaPt;
int totalMidPtDistance = 0;
-
+
if (count > 0) {
Common::Point lastMidPt;
int halfCount = (count + 1) >> 1;
@@ -384,13 +384,13 @@ void BbvsEngine::walkFoundPath(int count) {
if (distance >= _currWalkDistance)
return;
-
+
debug(5, "BbvsEngine::walkFoundPath() distance smaller");
_currWalkDistance = distance;
Common::Point destPt = _destWalkAreaPt, newDestPt;
-
+
while (1) {
int index = 0;
@@ -408,7 +408,7 @@ void BbvsEngine::walkFoundPath(int count) {
WalkInfo *walkInfo = _walkInfoPtrs[--count];
destPt.x = walkInfo->x;
destPt.y = walkInfo->y;
-
+
if (walkInfo->direction) {
newDestPt.x = walkInfo->x;
newDestPt.y = walkInfo->y + walkInfo->delta - 1;
diff --git a/engines/cge/vga13h.cpp b/engines/cge/vga13h.cpp
index babcb7e667..4d3a103663 100644
--- a/engines/cge/vga13h.cpp
+++ b/engines/cge/vga13h.cpp
@@ -640,7 +640,7 @@ Vga::Vga(CGEEngine *vm) : _frmCnt(0), _msg(NULL), _name(NULL), _setPal(false), _
if (ConfMan.getBool("enable_color_blind"))
_mono = 1;
-
+
_oldColors = (Dac *)malloc(sizeof(Dac) * kPalCount);
_newColors = (Dac *)malloc(sizeof(Dac) * kPalCount);
diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 37d87ba09c..ee62e20ac6 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -97,7 +97,7 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
_midiNotify = nullptr;
_spriteNotify = nullptr;
_startGameSlot = 0;
-
+
_sayCap = ConfMan.getBool("subtitles");
_sayVox = !ConfMan.getBool("speech_mute");
_muteAll = ConfMan.getBool("mute");
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 50b418f294..fbe4cb3abc 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -269,7 +269,7 @@ public:
void snRoom(Sprite *spr, bool on);
void snGhost(Bitmap *bmp);
void snSay(Sprite *spr, int val);
-
+
void hide1(Sprite *spr);
Sprite *expandSprite(Sprite *spr);
void qGame();
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 3e3d615a91..4e3d229618 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -58,7 +58,7 @@ void System::touch(uint16 mask, V2D pos, Common::KeyCode keyCode) {
if (_vm->_gamePhase != kPhaseInGame)
return;
_vm->_infoLine->setText(nullptr);
-
+
if (mask & kMouseLeftUp) {
if (pos.y >= 0) { // world
if (!_vm->_talk && pos.y < _vm->_mouseTop)
@@ -184,7 +184,7 @@ Sprite *CGE2Engine::loadSprite(const char *fname, int ref, int scene, V3D &pos)
if (line.empty())
continue;
Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
-
+
char *p = token(tmpStr);
if (*p == '@') {
if (label != kNoByte)
@@ -327,7 +327,7 @@ void CGE2Engine::loadScript(const char *fname, bool onlyToolbar) {
lcnt++;
Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
-
+
ok = false; // not OK if break
V3D P;
@@ -419,7 +419,7 @@ void CGE2Engine::sceneUp(int cav) {
_map->load(_now);
_spare->takeScene(_now);
openPocket();
-
+
for (int i = 0; i < 2; i++) {
Hero *h = _heroTab[i]->_ptr;
if (h && h->_scene == _now) {
@@ -432,7 +432,7 @@ void CGE2Engine::sceneUp(int cav) {
h->setContact();
}
}
-
+
_sound->stop();
_fx->clear();
@@ -596,7 +596,7 @@ void CGE2Engine::tick() {
for (Sprite *spr = _vga->_showQ->first(); spr; spr = spr->_next) {
if (spr->_time && (--spr->_time == 0))
spr->tick();
-
+
if (_waitRef && (_waitRef == spr->_ref) && spr->seqTest(_waitSeq))
_waitRef = 0;
}
@@ -658,10 +658,10 @@ void CGE2Engine::loadUser() {
void CGE2Engine::loadHeroes() { // Original name: loadGame()
// load sprites & pocket
-
+
Sprite *s;
Hero *h = nullptr;
-
+
// initialize Andzia/Anna
s = _spare->take(142);
if (s) {
@@ -698,7 +698,7 @@ void CGE2Engine::loadPos() {
if (_resman->exist("CGE.HXY")) {
for (int cav = 0; cav < kSceneMax; cav++)
_heroTab[1]->_posTab[cav] = new V2D(this, 180, 10);
-
+
EncryptedStream file(this, "CGE.HXY");
for (int cav = 0; cav < kSceneMax; cav++) {
@@ -752,7 +752,7 @@ void CGE2Engine::cge2_main() {
runGame();
_gamePhase = kPhaseOver;
}
-
+
_vga->sunset();
} else
_vga->sunset();
@@ -767,7 +767,7 @@ char *CGE2Engine::mergeExt(char *buf, const char *name, const char *ext) {
return buf;
}
-void CGE2Engine::setEye(const V3D &e) {
+void CGE2Engine::setEye(const V3D &e) {
*_eye = e;
}
@@ -931,7 +931,7 @@ void CGE2Engine::offUse() {
// This fixes the issue of empty speech bubbles in the original.
// Now we only let this cycle pass if it randoms a valid value for getText().
int txt = 0;
- do {
+ do {
txt = kOffUseText + _sex * offUseCount + newRandom(offUseCount);
} while (_text->getText(txt) == nullptr);
diff --git a/engines/cge2/cge2_main.h b/engines/cge2/cge2_main.h
index 88cca1cc1e..4d92c33e50 100644
--- a/engines/cge2/cge2_main.h
+++ b/engines/cge2/cge2_main.h
@@ -40,7 +40,7 @@ public:
Sprite *_blinkSprite;
System(CGE2Engine *vm);
-
+
virtual void touch(uint16 mask, V2D pos, Common::KeyCode keyCode);
void tick();
private:
diff --git a/engines/cge2/configure.engine b/engines/cge2/configure.engine
index 6ccbfee088..79d091fec5 100644
--- a/engines/cge2/configure.engine
+++ b/engines/cge2/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 cge2 "CGE2" no
+add_engine cge2 "CGE2" yes
diff --git a/engines/cge2/detection.cpp b/engines/cge2/detection.cpp
index c05ce70c3d..4acdea3fde 100644
--- a/engines/cge2/detection.cpp
+++ b/engines/cge2/detection.cpp
@@ -71,6 +71,26 @@ static const ADGameDescription gameDescriptions[] = {
Common::EN_ANY, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO1(GAMEOPTION_COLOR_BLIND_DEFAULT_OFF)
},
+ {
+ "sfinx", "Freeware v1.0",
+ {
+ {"vol.cat", 0, "f158e469dccbebc5a632eb848df89779", 129024},
+ {"vol.dat", 0, "d40a6b4ae173d6930be54ba56bee15d5", 34183443},
+ AD_LISTEND
+ },
+ 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/cge2/events.cpp b/engines/cge2/events.cpp
index ed1ec66bb1..85743c8011 100644
--- a/engines/cge2/events.cpp
+++ b/engines/cge2/events.cpp
@@ -132,7 +132,7 @@ Mouse::Mouse(CGE2Engine *vm) : Sprite(vm), _busy(nullptr), _hold(nullptr), _hx(0
_busy = nullptr;
_active = false;
_flags._kill = false;
-
+
setSeq(_stdSeq8);
BitmapPtr MC = new Bitmap[2];
@@ -260,7 +260,7 @@ void EventManager::handleEvents() {
if (e._spritePtr) {
if (e._mask & kEventKeyb)
e._spritePtr->touch(e._mask, _vm->_mouse->_point, e._keyCode);
- else
+ else
e._spritePtr->touch(e._mask, _vm->_mouse->_point - e._spritePtr->_pos2D, e._keyCode);
} else if (_vm->_sys)
_vm->_sys->touch(e._mask, _vm->_mouse->_point, e._keyCode);
diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 225df54bd1..42ae67cc2b 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -205,7 +205,7 @@ Sprite *Hero::expand() {
int i = stepSize() / 2;
_maxDist = (int)sqrt(double(i * i * 2));
setCurrent();
-
+
return this;
}
@@ -558,9 +558,9 @@ int CGE2Engine::mapCross(const V2D &a, const V2D &b) {
if (p) {
if (cross(a, b, *n0, *n))
++cnt;
-
+
if (*n == *p)
- p = nullptr;
+ p = nullptr;
} else {
p = n;
}
@@ -587,7 +587,7 @@ void Hero::operator--() {
bool Sprite::works(Sprite *spr) {
if (!spr || !spr->_ext)
return false;
-
+
bool ok = false;
Action a = _vm->_heroTab[_vm->_sex]->_ptr->action();
@@ -615,7 +615,7 @@ bool Sprite::works(Sprite *spr) {
}
}
}
-
+
return ok;
}
diff --git a/engines/cge2/map.cpp b/engines/cge2/map.cpp
index 8c1f00048f..275e15f55a 100644
--- a/engines/cge2/map.cpp
+++ b/engines/cge2/map.cpp
@@ -48,7 +48,7 @@ void Map::load(int scene) {
return;
EncryptedStream file(_vm, fileName.c_str());
-
+
Common::String line;
for (line = file.readLine(); !file.eos(); line = file.readLine()) {
if (line.empty())
diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp
index fd60422dff..7735c077a6 100644
--- a/engines/cge2/saveload.cpp
+++ b/engines/cge2/saveload.cpp
@@ -104,7 +104,7 @@ bool CGE2Engine::loadGame(int slotNumber) {
saveFile->read(dataBuffer, size);
readStream = new Common::MemoryReadStream(dataBuffer, size, DisposeAfterUse::YES);
delete saveFile;
-
+
// Check to see if it's a ScummVM savegame or not
char buffer[kSavegameStrSize + 1];
readStream->read(buffer, kSavegameStrSize + 1);
@@ -132,7 +132,7 @@ bool CGE2Engine::loadGame(int slotNumber) {
delete readStream;
loadHeroes();
-
+
return true;
}
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 8e1ddf2d9b..7580ef4425 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -92,7 +92,7 @@ void CommandHandler::runCommand() {
}
_textDelay = false;
}
-
+
if (_vm->_talk && tailCmd._commandType != kCmdPause)
break;
}
@@ -332,7 +332,7 @@ void CGE2Engine::snRSeq(Sprite *spr, int val) {
void CGE2Engine::snSend(Sprite *spr, int val) {
if (!spr)
return;
-
+
// Sending", spr->_file
// from scene", spr->_scene
// to scene", val
@@ -691,7 +691,7 @@ Sprite *CGE2Engine::expandSprite(Sprite *spr) {
void CGE2Engine::qGame() {
// Write out the user's progress
saveGame(0, Common::String("Automatic Savegame"));
-
+
busy(false);
_vga->sunset();
_endGame = true;
@@ -853,13 +853,13 @@ void CGE2Engine::feedSnail(Sprite *spr, Action snq, Hero *hero) {
if (s == spr)
break;
}
-
+
_commandHandler->addCommand(c->_commandType, c->_ref, c->_val, spr);
++c;
}
}
-
+
}
} // End of namespace CGE2.
diff --git a/engines/cge2/spare.h b/engines/cge2/spare.h
index 7dc6ce60f5..24a97712ff 100644
--- a/engines/cge2/spare.h
+++ b/engines/cge2/spare.h
@@ -38,7 +38,7 @@ class Spare {
public:
Spare(CGE2Engine *vm) : _vm(vm) {}
~Spare() { clear(); }
- void store(Sprite *spr);
+ void store(Sprite *spr);
Sprite *locate(int ref);
Sprite *take(int ref);
void takeScene(int cav);
diff --git a/engines/cge2/talk.cpp b/engines/cge2/talk.cpp
index 9109da90f1..8e6be6cac2 100644
--- a/engines/cge2/talk.cpp
+++ b/engines/cge2/talk.cpp
@@ -121,7 +121,7 @@ Talk::Talk(CGE2Engine *vm, const char *text, TextBoxStyle mode, ColorBank color,
Talk::Talk(CGE2Engine *vm, ColorBank color)
: Sprite(vm), _mode(kTBPure), _created(false), _wideSpace(false), _vm(vm) {
_color = _vm->_font->_colorSet[color];
-
+
if (color == kCBRel)
_vm->setAutoColors();
}
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 227633579e..f4064f3565 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -45,13 +45,13 @@ void V3D::sync(Common::Serializer &s) {
_z.sync(s);
}
-FXP FXP::operator*(const FXP& x) const {
- FXP y;
+FXP FXP::operator*(const FXP& x) const {
+ FXP y;
int32 t1 = (v >> 8) * x.v;
int32 t2 = ((v & 0xFF) * x.v) >> 8;
y.v = t1 + t2;
- return y;
+ return y;
}
FXP FXP::operator/(const FXP& x) const {
@@ -613,7 +613,7 @@ void Sprite::gotoxyz(V2D pos) {
++trim;
}
_pos2D.x = pos.x;
-
+
if (pos.y < -kPanHeight) {
pos.y = -kPanHeight;
++trim;
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/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/fullpipe.cpp b/engines/fullpipe/fullpipe.cpp
index bb0838395d..ebaff32550 100644
--- a/engines/fullpipe/fullpipe.cpp
+++ b/engines/fullpipe/fullpipe.cpp
@@ -163,7 +163,7 @@ FullpipeEngine::FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc)
for (int i = 0; i < 11; i++)
_currSoundList1[i] = 0;
-
+
for (int i = 0; i < 200; i++)
_mapTable[i] = 0;
@@ -285,7 +285,7 @@ Common::Error FullpipeEngine::run() {
freeGameLoader();
_currentScene = 0;
_updateTicks = 0;
-
+
loadGam("fullpipe.gam");
_needRestart = false;
}
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/gfx.cpp b/engines/fullpipe/gfx.cpp
index 61fbf7192f..42846850ca 100644
--- a/engines/fullpipe/gfx.cpp
+++ b/engines/fullpipe/gfx.cpp
@@ -153,7 +153,7 @@ bool PictureObject::load(MfcArchive &file, bool bigPicture) {
if (count > 0) {
GameObject *o = new GameObject();
-
+
o->load(file);
_pictureObject2List->push_back(o);
}
@@ -286,9 +286,9 @@ bool GameObject::load(MfcArchive &file) {
_okeyCode = 0;
_flags = 0;
_field_20 = 0;
-
+
_id = file.readUint16LE();
-
+
_objectName = file.readPascalString();
_ox = file.readUint32LE();
_oy = file.readUint32LE();
@@ -498,7 +498,7 @@ bool Picture::load(MfcArchive &file) {
_x = file.readUint32LE();
_y = file.readUint32LE();
_field_44 = file.readUint16LE();
-
+
assert(g_fp->_gameProjectVersion >= 2);
_width = file.readUint32LE();
diff --git a/engines/fullpipe/input.cpp b/engines/fullpipe/input.cpp
index 7c97461a24..b681f4fbe7 100644
--- a/engines/fullpipe/input.cpp
+++ b/engines/fullpipe/input.cpp
@@ -70,7 +70,7 @@ void setInputDisabled(bool state) {
void InputController::addCursor(CursorInfo *cursor) {
CursorInfo *newc = new CursorInfo(cursor);
Common::Point p;
-
+
cursor->picture->getDimensions(&p);
newc->width = p.x;
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 49cf88434e..9573e0517b 100644
--- a/engines/fullpipe/motion.cpp
+++ b/engines/fullpipe/motion.cpp
@@ -1040,11 +1040,11 @@ MessageQueue *MovGraph::doWalkTo(StaticANIObject *subj, int xpos, int ypos, int
if (!mq || !mq->getExCommandByIndex(0))
return 0;
-
+
ExCommand *ex = mq->getExCommandByIndex(0);
- if ((ex->_messageKind != 1 && ex->_messageKind != 20) ||
- ex->_messageNum != subj->_movement->_id ||
+ if ((ex->_messageKind != 1 && ex->_messageKind != 20) ||
+ ex->_messageNum != subj->_movement->_id ||
(ex->_field_14 >= 1 && ex->_field_14 <= subj->_movement->_currDynamicPhaseIndex))
subj->playIdle();
}
@@ -1416,8 +1416,8 @@ Common::Array<MovArr *> *MovGraph::genMovArr(int x, int y, int *arrSize, int fla
movarr = new MovArr;
movarr->_link = lnk;
- movarr->_dist = ((double)(lnk->_movGraphNode1->_y - lnk->_movGraphNode2->_y) * (double)(lnk->_movGraphNode1->_y - point.y) +
- (double)(lnk->_movGraphNode2->_x - lnk->_movGraphNode1->_x) * (double)(point.x - lnk->_movGraphNode1->_x)) /
+ movarr->_dist = ((double)(lnk->_movGraphNode1->_y - lnk->_movGraphNode2->_y) * (double)(lnk->_movGraphNode1->_y - point.y) +
+ (double)(lnk->_movGraphNode2->_x - lnk->_movGraphNode1->_x) * (double)(point.x - lnk->_movGraphNode1->_x)) /
lnk->_distance / lnk->_distance;
movarr->_point = point;
@@ -1445,8 +1445,8 @@ Common::Array<MovArr *> *MovGraph::genMovArr(int x, int y, int *arrSize, int fla
} else {
movarr = new MovArr;
movarr->_link = lnk;
- movarr->_dist = ((double)(lnk->_movGraphNode1->_y - lnk->_movGraphNode2->_y) * (double)(lnk->_movGraphNode1->_y - y) +
- (double)(lnk->_movGraphNode2->_x - lnk->_movGraphNode1->_x) * (double)(x - lnk->_movGraphNode1->_x)) /
+ movarr->_dist = ((double)(lnk->_movGraphNode1->_y - lnk->_movGraphNode2->_y) * (double)(lnk->_movGraphNode1->_y - y) +
+ (double)(lnk->_movGraphNode2->_x - lnk->_movGraphNode1->_x) * (double)(x - lnk->_movGraphNode1->_x)) /
lnk->_distance / lnk->_distance;
movarr->_point.x = x;
movarr->_point.y = y;
diff --git a/engines/fullpipe/scene.cpp b/engines/fullpipe/scene.cpp
index 8463b3ab40..5a3fbe34b6 100644
--- a/engines/fullpipe/scene.cpp
+++ b/engines/fullpipe/scene.cpp
@@ -162,7 +162,7 @@ bool Scene::load(MfcArchive &file) {
Background::load(file);
_sceneId = file.readUint16LE();
-
+
_sceneName = file.readPascalString();
debug(0, "scene: <%s> %d", transCyrillic((byte *)_sceneName), _sceneId);
@@ -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/scene02.cpp b/engines/fullpipe/scenes/scene02.cpp
index 109a20a07a..fd542d580d 100644
--- a/engines/fullpipe/scenes/scene02.cpp
+++ b/engines/fullpipe/scenes/scene02.cpp
@@ -134,5 +134,5 @@ int sceneHandler02(ExCommand *ex) {
return res;
}
-
+
} // End of namespace Fullpipe
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/scene14.cpp b/engines/fullpipe/scenes/scene14.cpp
index 21dbe8101f..446f477133 100644
--- a/engines/fullpipe/scenes/scene14.cpp
+++ b/engines/fullpipe/scenes/scene14.cpp
@@ -57,7 +57,7 @@ void scene14_initScene(Scene *sc) {
ball->_flags &= 0xFFFB;
g_vars->scene14_balls.push_back(ball);
-
+
for (uint i = 0; i < 3; i++) {
ball = new StaticANIObject(ball); // create a copy
diff --git a/engines/fullpipe/scenes/scene15.cpp b/engines/fullpipe/scenes/scene15.cpp
index 452f2edeca..efc69a5fa6 100644
--- a/engines/fullpipe/scenes/scene15.cpp
+++ b/engines/fullpipe/scenes/scene15.cpp
@@ -71,7 +71,7 @@ void scene15_initScene(Scene *sc) {
grandma->hide();
g_fp->setObjectState(sO_LeftPipe_15, g_fp->getObjectEnumState(sO_LeftPipe_15, sO_IsOpened));
}
-
+
g_vars->scene15_plusminus = sc->getStaticANIObject1ById(ANI_PLUSMINUS, -1);
if (g_fp->getObjectState(sO_Guard_2) == g_fp->getObjectEnumState(sO_Guard_2, sO_Off))
diff --git a/engines/fullpipe/scenes/scene16.cpp b/engines/fullpipe/scenes/scene16.cpp
index ed3c51a6c2..df005950d2 100644
--- a/engines/fullpipe/scenes/scene16.cpp
+++ b/engines/fullpipe/scenes/scene16.cpp
@@ -57,9 +57,9 @@ void scene16_initScene(Scene *sc) {
boy[1] = new StaticANIObject(boy[0]);
sc->addStaticANIObject(boy[1], 1);
-
+
int idx = 0;
-
+
for (int i = 0; i < 3; i++) {
g_vars->scene16_figures.push_back(boy[idx]);
@@ -68,7 +68,7 @@ void scene16_initScene(Scene *sc) {
if (idx >= 2)
idx = 0;
}
-
+
g_vars->scene16_figures.push_back(sc->getStaticANIObject1ById(ANI_GIRL, -1));
for (int i = 0; i < 4; i++) {
@@ -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)
@@ -259,7 +259,7 @@ void sceneHandler16_drink() {
mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC16_BOYKICK), 0, 1);
mq->replaceKeyCode(-1, g_vars->scene16_walkingBoy->_okeyCode);
-
+
ex = new ExCommand(ANI_MAN, 34, 384, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 3u;
ex->_field_14 = 384;
diff --git a/engines/fullpipe/scenes/scene23.cpp b/engines/fullpipe/scenes/scene23.cpp
index ccfbac9223..ded467e438 100644
--- a/engines/fullpipe/scenes/scene23.cpp
+++ b/engines/fullpipe/scenes/scene23.cpp
@@ -146,7 +146,7 @@ void scene23_initScene(Scene *sc) {
sc->getStaticANIObject1ById(ANI_INV_LEVERHANDLE, -1)->hide();
}
-
+
g_fp->_currentScene = oldsc;
}
@@ -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/scenes/scene28.cpp b/engines/fullpipe/scenes/scene28.cpp
index c21ce05502..de5a96e70d 100644
--- a/engines/fullpipe/scenes/scene28.cpp
+++ b/engines/fullpipe/scenes/scene28.cpp
@@ -46,7 +46,7 @@ void scene28_initScene(Scene *sc) {
g_vars->scene28_lift6inside = false;
g_fp->_floaters->init(g_fp->getGameLoaderGameVar()->getSubVarByName("SC_28"));
-
+
g_fp->initArcadeKeys("SC_28");
}
diff --git a/engines/fullpipe/scenes/scene29.cpp b/engines/fullpipe/scenes/scene29.cpp
index 8f82e99ad1..222a541554 100644
--- a/engines/fullpipe/scenes/scene29.cpp
+++ b/engines/fullpipe/scenes/scene29.cpp
@@ -840,7 +840,7 @@ void sceneHandler29_shootersEscape() {
void sceneHandler29_manRideBack() {
g_vars->scene29_manX -= 2;
-
+
g_fp->_aniMan->setOXY(g_vars->scene29_manX, g_vars->scene29_manY);
}
diff --git a/engines/fullpipe/scenes/scene37.cpp b/engines/fullpipe/scenes/scene37.cpp
index 09da01f138..324d3ac92d 100644
--- a/engines/fullpipe/scenes/scene37.cpp
+++ b/engines/fullpipe/scenes/scene37.cpp
@@ -91,7 +91,7 @@ void scene37_initScene(Scene *sc) {
g_vars->scene37_rings.push_back(ring);
g_fp->setObjectState(sO_LeftPipe_37, g_fp->getObjectEnumState(sO_LeftPipe_37, sO_IsClosed));
-
+
Scene *oldsc = g_fp->_currentScene;
g_fp->_currentScene = sc;
diff --git a/engines/fullpipe/sound.cpp b/engines/fullpipe/sound.cpp
index a4ca06f489..230d6c39a9 100644
--- a/engines/fullpipe/sound.cpp
+++ b/engines/fullpipe/sound.cpp
@@ -62,7 +62,7 @@ bool SoundList::load(MfcArchive &file, char *fname) {
}
return true;
-
+
}
bool SoundList::loadFile(const char *fname, char *libname) {
diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp
index 717de84925..de3e1ea728 100644
--- a/engines/fullpipe/statics.cpp
+++ b/engines/fullpipe/statics.cpp
@@ -246,7 +246,7 @@ bool StaticANIObject::load(MfcArchive &file) {
void StaticANIObject::setOXY(int x, int y) {
_ox = x;
_oy = y;
-
+
if (_movement)
_movement->setOXY(x, y);
}
@@ -713,7 +713,7 @@ void StaticANIObject::setSpeed(int speed) {
void StaticANIObject::setAlpha(int alpha) {
for (uint i = 0; i < _movements.size(); i++)
_movements[i]->setAlpha(alpha);
-
+
for (uint i = 0; i < _staticsList.size(); i++)
_staticsList[i]->setAlpha(alpha);
}
@@ -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++)
@@ -1813,7 +1822,7 @@ void Movement::initStatics(StaticANIObject *ani) {
_staticsObj2 = ani->addReverseStatics(_currMovement->_staticsObj2);
_staticsObj1 = ani->addReverseStatics(_currMovement->_staticsObj1);
-
+
_mx = _currMovement->_mx;
_my = _currMovement->_my;
@@ -2279,7 +2288,7 @@ bool StaticPhase::load(MfcArchive &file) {
_initialCountdown = file.readUint16LE();
_field_6A = file.readUint16LE();
-
+
if (g_fp->_gameProjectVersion >= 12) {
_exCommand = (ExCommand *)file.readClass();
diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp
index 40134bbf17..676564a9fb 100644
--- a/engines/gob/inter_v1.cpp
+++ b/engines/gob/inter_v1.cpp
@@ -1124,8 +1124,6 @@ void Inter_v1::o1_palLoad(OpFuncParams &params) {
_vm->_draw->_vgaPalette[i].green = _vm->_game->_script->readByte();
_vm->_draw->_vgaPalette[i].blue = _vm->_game->_script->readByte();
}
-
- memcpy(_vm->_draw->_vgaPalette, _vm->_draw->_vgaPalette, 16 * 3);
break;
case 53:
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/graphics.cpp b/engines/groovie/graphics.cpp
index b85277fac7..e0c198f377 100644
--- a/engines/groovie/graphics.cpp
+++ b/engines/groovie/graphics.cpp
@@ -63,7 +63,7 @@ void GraphicsMan::update() {
// Clear the buffer when ending the fade out
if (_fading == 2)
- _foreground.fillRect(Common::Rect(640, 320), 0);
+ _foreground.fillRect(Common::Rect(640, _foreground.h), 0);
}
}
@@ -74,6 +74,22 @@ void GraphicsMan::update() {
}
}
+void GraphicsMan::switchToFullScreen(bool fullScreen) {
+ _foreground.free();
+ _background.free();
+
+ if (fullScreen) {
+ _foreground.create(640, 480, _vm->_pixelFormat);
+ _background.create(640, 480, _vm->_pixelFormat);
+ } else {
+ _vm->_system->fillScreen(0);
+ _foreground.create(640, 320, _vm->_pixelFormat);
+ _background.create(640, 320, _vm->_pixelFormat);
+ }
+
+ _changed = true;
+}
+
void GraphicsMan::change() {
_changed = true;
}
@@ -84,7 +100,7 @@ void GraphicsMan::mergeFgAndBg() {
countf = (byte *)_foreground.getPixels();
countb = (byte *)_background.getPixels();
- for (i = 640 * 320; i; i--) {
+ for (i = 640 * _foreground.h; i; i--) {
if (255 == *(countf)) {
*(countf) = *(countb);
}
@@ -94,7 +110,10 @@ void GraphicsMan::mergeFgAndBg() {
}
void GraphicsMan::updateScreen(Graphics::Surface *source) {
- _vm->_system->copyRectToScreen(source->getPixels(), 640, 0, 80, 640, 320);
+ if (!isFullScreen())
+ _vm->_system->copyRectToScreen(source->getPixels(), source->pitch, 0, 80, 640, 320);
+ else
+ _vm->_system->copyRectToScreen(source->getPixels(), source->pitch, 0, 0, 640, 480);
change();
}
diff --git a/engines/groovie/graphics.h b/engines/groovie/graphics.h
index 72ab01deb6..69934f9d68 100644
--- a/engines/groovie/graphics.h
+++ b/engines/groovie/graphics.h
@@ -38,6 +38,8 @@ public:
void update();
void change();
void mergeFgAndBg();
+ void switchToFullScreen(bool fullScreen);
+ bool isFullScreen() { return (_foreground.h == 480); }
void updateScreen(Graphics::Surface *source);
Graphics::Surface _foreground; // The main surface that most things are drawn to
Graphics::Surface _background; // Used occasionally, mostly (only?) in puzzles
diff --git a/engines/groovie/roq.cpp b/engines/groovie/roq.cpp
index 379fcabc07..f14cacd6b8 100644
--- a/engines/groovie/roq.cpp
+++ b/engines/groovie/roq.cpp
@@ -28,6 +28,7 @@
#include "groovie/groovie.h"
#include "common/debug.h"
+#include "common/debug-channels.h"
#include "common/rect.h"
#include "common/substream.h"
#include "common/textconsole.h"
@@ -46,6 +47,7 @@ namespace Groovie {
ROQPlayer::ROQPlayer(GroovieEngine *vm) :
VideoPlayer(vm), _codingTypeCount(0),
+ _fg(&_vm->_graphicsMan->_foreground),
_bg(&_vm->_graphicsMan->_background),
_firstFrame(true) {
@@ -63,6 +65,22 @@ ROQPlayer::~ROQPlayer() {
}
uint16 ROQPlayer::loadInternal() {
+ if (DebugMan.isDebugChannelEnabled(kDebugVideo)) {
+ int8 i;
+ debugN(1, "Groovie::ROQ: New ROQ: bitflags are ");
+ for (i = 15; i >= 0; i--) {
+ debugN(1, "%d", _flags & (1 << i)? 1 : 0);
+ if (i % 4 == 0) {
+ debugN(1, " ");
+ }
+ }
+ debug(1, " <- 0 ");
+ }
+
+ // Flags:
+ // - 2 For overlay videos, show the whole video
+ _flagTwo = ((_flags & (1 << 2)) != 0);
+
// Begin reading the file
debugC(1, kDebugVideo, "Groovie::ROQ: Loading video");
@@ -106,13 +124,23 @@ uint16 ROQPlayer::loadInternal() {
}
void ROQPlayer::buildShowBuf() {
+ if (_alpha)
+ _fg->copyFrom(*_bg);
+
for (int line = 0; line < _bg->h; line++) {
- uint32 *out = (uint32 *)_bg->getBasePtr(0, line);
+ uint32 *out = _alpha ? (uint32 *)_fg->getBasePtr(0, line) : (uint32 *)_bg->getBasePtr(0, line);
uint32 *in = (uint32 *)_currBuf->getBasePtr(0, line / _scaleY);
for (int x = 0; x < _bg->w; x++) {
- // Copy a pixel
- *out++ = *in;
+ // Copy a pixel, checking the alpha channel first
+ if (_alpha && !(*in & 0xFF))
+ out++;
+ else if (_fg->h == 480 && *in == _vm->_pixelFormat.RGBToColor(255, 255, 255))
+ // Handle transparency in Gamepad videos
+ // TODO: For now, we detect these videos by checking for full screen
+ out++;
+ else
+ *out++ = *in;
// Skip to the next pixel
if (!(x % _scaleX))
@@ -145,19 +173,27 @@ bool ROQPlayer::playFrameInternal() {
}
// Wait until the current frame can be shown
- waitFrame();
+ // Don't wait if we're just showing one frame
+ if (!playFirstFrame())
+ waitFrame();
if (_dirty) {
// Update the screen
- _syst->copyRectToScreen(_bg->getPixels(), _bg->pitch, 0, (_syst->getHeight() - _bg->h) / 2, _bg->w, _bg->h);
+ void *src = (_alpha) ? _fg->getPixels() : _bg->getPixels();
+ _syst->copyRectToScreen(src, _bg->pitch, 0, (_syst->getHeight() - _bg->h) / 2, _bg->w, _bg->h);
_syst->updateScreen();
+ // For overlay videos, set the background buffer when the video ends
+ if (_alpha && (!_flagTwo || (_flagTwo && _file->eos())))
+ _bg->copyFrom(*_fg);
+
// Clear the dirty flag
_dirty = false;
}
- // Return whether the video has ended
- return _file->eos();
+ // Report the end of the video if we reached the end of the file or if we
+ // just wanted to play one frame.
+ return _file->eos() || playFirstFrame();
}
bool ROQPlayer::readBlockHeader(ROQBlockHeader &blockHeader) {
@@ -277,9 +313,17 @@ bool ROQPlayer::processBlockInfo(ROQBlockHeader &blockHeader) {
_prevBuf->create(width, height, _vm->_pixelFormat);
}
+ // Switch from/to fullscreen, if needed
+ if (_bg->h != 480 && height == 480)
+ _vm->_graphicsMan->switchToFullScreen(true);
+ else if (_bg->h == 480 && height != 480)
+ _vm->_graphicsMan->switchToFullScreen(false);
+
// Clear the buffers with black
- _currBuf->fillRect(Common::Rect(width, height), _vm->_pixelFormat.RGBToColor(0, 0, 0));
- _prevBuf->fillRect(Common::Rect(width, height), _vm->_pixelFormat.RGBToColor(0, 0, 0));
+ if (!_alpha) {
+ _currBuf->fillRect(Common::Rect(width, height), _vm->_pixelFormat.RGBToColor(0, 0, 0));
+ _prevBuf->fillRect(Common::Rect(width, height), _vm->_pixelFormat.RGBToColor(0, 0, 0));
+ }
return true;
}
@@ -448,7 +492,7 @@ bool ROQPlayer::processBlockSoundMono(ROQBlockHeader &blockHeader) {
}
// Initialize the audio stream if needed
- if (!_audioStream) {
+ if (!_audioStream && !playFirstFrame()) {
_audioStream = Audio::makeQueuingAudioStream(22050, false);
Audio::SoundHandle sound_handle;
g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &sound_handle, _audioStream);
@@ -477,7 +521,10 @@ bool ROQPlayer::processBlockSoundMono(ROQBlockHeader &blockHeader) {
#ifdef SCUMM_LITTLE_ENDIAN
flags |= Audio::FLAG_LITTLE_ENDIAN;
#endif
- _audioStream->queueBuffer((byte *)buffer, blockHeader.size * 2, DisposeAfterUse::YES, flags);
+ if (!playFirstFrame())
+ _audioStream->queueBuffer((byte *)buffer, blockHeader.size * 2, DisposeAfterUse::YES, flags);
+ else
+ free(buffer);
return true;
}
@@ -491,7 +538,7 @@ bool ROQPlayer::processBlockSoundStereo(ROQBlockHeader &blockHeader) {
}
// Initialize the audio stream if needed
- if (!_audioStream) {
+ if (!_audioStream && !playFirstFrame()) {
_audioStream = Audio::makeQueuingAudioStream(22050, true);
Audio::SoundHandle sound_handle;
g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &sound_handle, _audioStream);
@@ -533,7 +580,10 @@ bool ROQPlayer::processBlockSoundStereo(ROQBlockHeader &blockHeader) {
#ifdef SCUMM_LITTLE_ENDIAN
flags |= Audio::FLAG_LITTLE_ENDIAN;
#endif
- _audioStream->queueBuffer((byte *)buffer, blockHeader.size * 2, DisposeAfterUse::YES, flags);
+ if (!playFirstFrame())
+ _audioStream->queueBuffer((byte *)buffer, blockHeader.size * 2, DisposeAfterUse::YES, flags);
+ else
+ free(buffer);
return true;
}
diff --git a/engines/groovie/roq.h b/engines/groovie/roq.h
index 7e7d38580e..ce1a3a2d58 100644
--- a/engines/groovie/roq.h
+++ b/engines/groovie/roq.h
@@ -57,6 +57,7 @@ private:
bool processBlockSoundMono(ROQBlockHeader &blockHeader);
bool processBlockSoundStereo(ROQBlockHeader &blockHeader);
bool processBlockAudioContainer(ROQBlockHeader &blockHeader);
+ bool playFirstFrame() { return _alpha && !_flagTwo; }
void paint2(byte i, int destx, int desty);
void paint4(byte i, int destx, int desty);
@@ -74,8 +75,11 @@ private:
uint32 _codebook2[256 * 4];
byte _codebook4[256 * 4];
+ // Flags
+ bool _flagTwo;
+
// Buffers
- Graphics::Surface *_bg;
+ Graphics::Surface *_fg, *_bg;
Graphics::Surface *_currBuf, *_prevBuf;
void buildShowBuf();
byte _scaleX, _scaleY;
diff --git a/engines/groovie/script.cpp b/engines/groovie/script.cpp
index 7625151082..eef97b6ff9 100644
--- a/engines/groovie/script.cpp
+++ b/engines/groovie/script.cpp
@@ -179,12 +179,20 @@ void Script::directGameLoad(int slot) {
// TODO: Return to the main script, likely reusing most of o_returnscript()
- // HACK: We set variable 0x19 to the slot to load, and set the current
- // instruction to the one that actually loads the saved game specified
- // in that variable. This will change in other versions of the game and
- // in other games.
- setVariable(0x19, slot);
- _currentInstruction = 0x287;
+ // HACK: We set the slot to load in the appropriate variable, and set the
+ // current instruction to the one that actually loads the saved game
+ // specified in that variable. This differs depending on the game and its
+ // version.
+ if (_version == kGroovieT7G) {
+ // 7th Guest
+ setVariable(0x19, slot);
+ _currentInstruction = 0x287;
+ } else {
+ // 11th Hour
+ setVariable(0xF, slot);
+ // FIXME: This bypasses a lot of the game's initialization procedure
+ _currentInstruction = 0xE78E;
+ }
// TODO: We'll probably need to start by running the beginning of the
// script to let it do the soundcard initialization and then do the
@@ -350,9 +358,10 @@ bool Script::hotspot(Common::Rect rect, uint16 address, uint8 cursor) {
// Show hotspots when debugging
if (DebugMan.isDebugChannelEnabled(kDebugHotspots)) {
- rect.translate(0, -80);
+ if (!_vm->_graphicsMan->isFullScreen())
+ rect.translate(0, -80);
_vm->_graphicsMan->_foreground.frameRect(rect, 250);
- _vm->_system->copyRectToScreen(_vm->_graphicsMan->_foreground.getPixels(), _vm->_graphicsMan->_foreground.pitch, 0, 80, 640, 320);
+ _vm->_graphicsMan->updateScreen(&_vm->_graphicsMan->_foreground);
_vm->_system->updateScreen();
}
@@ -962,7 +971,7 @@ void Script::o_strcmpnejmp_var() { // 0x21
void Script::o_copybgtofg() { // 0x22
debugC(1, kDebugScript, "COPY_BG_TO_FG");
- memcpy(_vm->_graphicsMan->_foreground.getPixels(), _vm->_graphicsMan->_background.getPixels(), 640 * 320);
+ memcpy(_vm->_graphicsMan->_foreground.getPixels(), _vm->_graphicsMan->_background.getPixels(), 640 * _vm->_graphicsMan->_foreground.h);
}
void Script::o_strcmpeqjmp() { // 0x23
@@ -1198,6 +1207,7 @@ void Script::o_copyrecttobg() { // 0x37
uint16 top = readScript16bits();
uint16 right = readScript16bits();
uint16 bottom = readScript16bits();
+ uint16 baseTop = (!_vm->_graphicsMan->isFullScreen()) ? 80 : 0;
// Sanity checks to prevent bad pointer access crashes
if (left > right) {
@@ -1216,9 +1226,9 @@ void Script::o_copyrecttobg() { // 0x37
bottom = top;
top = j;
}
- if (top < 80) {
- warning("COPYRECT top < 80... clamping");
- top = 80;
+ if (top < baseTop) {
+ warning("COPYRECT top < baseTop... clamping");
+ top = baseTop;
}
if (top >= 480) {
warning("COPYRECT top >= 480... clamping");
@@ -1243,13 +1253,13 @@ void Script::o_copyrecttobg() { // 0x37
debugC(1, kDebugScript, "COPYRECT((%d,%d)->(%d,%d))", left, top, right, bottom);
- fg = (byte *)_vm->_graphicsMan->_foreground.getBasePtr(left, top - 80);
- bg = (byte *)_vm->_graphicsMan->_background.getBasePtr(left, top - 80);
+ fg = (byte *)_vm->_graphicsMan->_foreground.getBasePtr(left, top - baseTop);
+ bg = (byte *)_vm->_graphicsMan->_background.getBasePtr(left, top - baseTop);
for (i = 0; i < height; i++) {
memcpy(bg + offset, fg + offset, width);
offset += 640;
}
- _vm->_system->copyRectToScreen(_vm->_graphicsMan->_background.getBasePtr(left, top - 80), 640, left, top, width, height);
+ _vm->_system->copyRectToScreen(_vm->_graphicsMan->_background.getBasePtr(left, top - baseTop), 640, left, top, width, height);
_vm->_graphicsMan->change();
}
@@ -1595,8 +1605,7 @@ void Script::o_hotspot_outrect() {
bool contained = rect.contains(mousepos);
if (!contained) {
- error("hotspot-outrect unimplemented");
- // TODO: what to do with address?
+ _currentInstruction = address;
}
}
@@ -1670,15 +1679,29 @@ void Script::o2_vdxtransition() {
void Script::o2_copyscreentobg() {
uint16 val = readScript16bits();
+ // TODO: Parameter
+ if (val)
+ warning("o2_copyscreentobg: Param is %d", val);
+
+ Graphics::Surface *screen = _vm->_system->lockScreen();
+ _vm->_graphicsMan->_background.copyFrom(screen->getSubArea(Common::Rect(0, 80, 640, 320)));
+ _vm->_system->unlockScreen();
+
debugC(1, kDebugScript, "CopyScreenToBG3: 0x%04X", val);
- error("Unimplemented Opcode 0x4F");
}
void Script::o2_copybgtoscreen() {
uint16 val = readScript16bits();
+ // TODO: Parameter
+ if (val)
+ warning("o2_copybgtoscreen: Param is %d", val);
+
+ Graphics::Surface *screen = _vm->_system->lockScreen();
+ _vm->_graphicsMan->_background.copyRectToSurface(*screen, 0, 80, Common::Rect(0, 0, 640, 320 - 80));
+ _vm->_system->unlockScreen();
+
debugC(1, kDebugScript, "CopyBG3ToScreen: 0x%04X", val);
- error("Unimplemented Opcode 0x50");
}
void Script::o2_setvideoskip() {
@@ -1686,6 +1709,12 @@ void Script::o2_setvideoskip() {
debugC(1, kDebugScript, "SetVideoSkip (0x%04X)", _videoSkipAddress);
}
+void Script::o2_stub42() {
+ uint8 arg = readScript8bits();
+ // TODO: Switch with 5 cases (0 - 5). Anything above 5 is a NOP
+ debugC(1, kDebugScript, "STUB42 (0x%02X)", arg);
+}
+
void Script::o2_stub52() {
uint8 arg = readScript8bits();
debugC(1, kDebugScript, "STUB52 (0x%02X)", arg);
@@ -1859,7 +1888,7 @@ Script::OpcodeFunc Script::_opcodesV2[NUM_OPCODES] = {
&Script::o_loadscript,
&Script::o_setvideoorigin, // 0x40
&Script::o_sub,
- &Script::o_cellmove,
+ &Script::o2_stub42,
&Script::o_returnscript,
&Script::o_sethotspotright, // 0x44
&Script::o_sethotspotleft,
diff --git a/engines/groovie/script.h b/engines/groovie/script.h
index 35e52593de..a9f6143509 100644
--- a/engines/groovie/script.h
+++ b/engines/groovie/script.h
@@ -238,6 +238,7 @@ private:
void o2_setvideoskip();
void o2_copyscreentobg();
void o2_copybgtoscreen();
+ void o2_stub42();
void o2_stub52();
void o2_setscriptend();
};
diff --git a/engines/hopkins/computer.cpp b/engines/hopkins/computer.cpp
index 84d5c631c7..18b16cb4c8 100644
--- a/engines/hopkins/computer.cpp
+++ b/engines/hopkins/computer.cpp
@@ -883,7 +883,7 @@ void ComputerManager::getScoreName() {
_vm->_graphicsMan->setColorPercentage(254, 0, 0, 0);
byte *ptr = _vm->_fileIO->loadFile("ALPHA.SPR");
_vm->_graphicsMan->fadeInBreakout();
-
+
// Figure out the line to put the new high score on
int scoreLine = 0;
while (scoreLine < 5 && _breakoutScore < atol(_score[scoreLine]._score.c_str()))
diff --git a/engines/hopkins/files.cpp b/engines/hopkins/files.cpp
index 6620f2878c..3100ed6cdc 100644
--- a/engines/hopkins/files.cpp
+++ b/engines/hopkins/files.cpp
@@ -74,7 +74,7 @@ int FileManager::readStream(Common::ReadStream &stream, void *buf, size_t nbytes
* It's now using the config manager and a per-engine GUI option.
*/
void FileManager::initCensorship() {
- _vm->_globals->_censorshipFl = ConfMan.getBool("enable_gore");
+ _vm->_globals->_censorshipFl = !ConfMan.getBool("enable_gore");
}
/**
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/hopkins/sound.cpp b/engines/hopkins/sound.cpp
index 773c714899..6660233740 100644
--- a/engines/hopkins/sound.cpp
+++ b/engines/hopkins/sound.cpp
@@ -261,9 +261,9 @@ void SoundManager::loadAnimSound() {
}
}
-void SoundManager::playAnimSound(int soundNumber) {
+void SoundManager::playAnimSound(int animFrame) {
if (!_vm->_globals->_censorshipFl && _specialSoundNum == 2) {
- switch (soundNumber) {
+ switch (animFrame) {
case 20:
playSample(5);
break;
@@ -273,44 +273,59 @@ void SoundManager::playAnimSound(int soundNumber) {
playSample(1);
break;
case 75:
- playSample(2);
+ // This removes the sound of the gun played while the guard is being shot, as this part of the scene has been
+ // removed in the Polish version of the game
+ if (_vm->getLanguage() != Common::PL_POL)
+ playSample(2);
+ break;
+ case 95:
+ // This fixes an original bug in the Polish version of the game, which was literally butchered for some reason
+ if (_vm->getLanguage() == Common::PL_POL)
+ playSample(3);
break;
case 109:
- playSample(3);
+ if (_vm->getLanguage() != Common::PL_POL)
+ playSample(3);
+ break;
+ case 108:
+ // This fixes an original bug in the Polish version of the game, which was literally butchered for some reason
+ if (_vm->getLanguage() == Common::PL_POL)
+ playSample(4);
break;
case 122:
- playSample(4);
+ if (_vm->getLanguage() != Common::PL_POL)
+ playSample(4);
break;
}
- } else if (_specialSoundNum == 1 && soundNumber == 17)
+ } else if (_specialSoundNum == 1 && animFrame == 17)
playSoundFile("SOUND42.WAV");
- else if (_specialSoundNum == 5 && soundNumber == 19)
+ else if (_specialSoundNum == 5 && animFrame == 19)
playWav(1);
- else if (_specialSoundNum == 14 && soundNumber == 625)
+ else if (_specialSoundNum == 14 && animFrame == 625)
playWav(1);
- else if (_specialSoundNum == 16 && soundNumber == 25)
+ else if (_specialSoundNum == 16 && animFrame == 25)
playWav(1);
else if (_specialSoundNum == 17) {
- if (soundNumber == 6)
+ if (animFrame == 6)
playSample(1);
- else if (soundNumber == 14)
+ else if (animFrame == 14)
playSample(2);
- else if (soundNumber == 67)
+ else if (animFrame == 67)
playSample(3);
- } else if (_specialSoundNum == 198 && soundNumber == 15)
+ } else if (_specialSoundNum == 198 && animFrame == 15)
playWav(1);
- else if (_specialSoundNum == 199 && soundNumber == 72)
+ else if (_specialSoundNum == 199 && animFrame == 72)
playWav(1);
- else if (_specialSoundNum == 208 && soundNumber == 40)
+ else if (_specialSoundNum == 208 && animFrame == 40)
playWav(1);
- else if (_specialSoundNum == 210 && soundNumber == 2)
+ else if (_specialSoundNum == 210 && animFrame == 2)
playWav(1);
- else if (_specialSoundNum == 211 && soundNumber == 22)
+ else if (_specialSoundNum == 211 && animFrame == 22)
playWav(1);
else if (_specialSoundNum == 229) {
- if (soundNumber == 15)
+ if (animFrame == 15)
playWav(1);
- else if (soundNumber == 91)
+ else if (animFrame == 91)
playWav(2);
}
}
diff --git a/engines/hopkins/sound.h b/engines/hopkins/sound.h
index 97cdcdc1dd..1fb4f9ae71 100644
--- a/engines/hopkins/sound.h
+++ b/engines/hopkins/sound.h
@@ -116,7 +116,7 @@ public:
~SoundManager();
void loadAnimSound();
- void playAnimSound(int soundNumber);
+ void playAnimSound(int animFrame);
void loadSample(int wavIndex, const Common::String &file);
void playSample(int wavIndex, int voiceMode = 9);
diff --git a/engines/hopkins/talk.cpp b/engines/hopkins/talk.cpp
index df7b26c82c..00c4ab0332 100644
--- a/engines/hopkins/talk.cpp
+++ b/engines/hopkins/talk.cpp
@@ -68,7 +68,7 @@ void TalkManager::startAnimatedCharacterDialogue(const Common::String &filename)
getStringFromBuffer(40, spriteFilename, (const char *)_characterBuffer);
getStringFromBuffer(0, _questionsFilename, (const char *)_characterBuffer);
getStringFromBuffer(20, _answersFilename, (const char *)_characterBuffer);
-
+
switch (_vm->_globals->_language) {
case LANG_FR:
_answersFilename = _questionsFilename = "RUE.TXT";
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..c0e0f67b8e 100644
--- a/engines/kyra/sound_adlib.cpp
+++ b/engines/kyra/sound_adlib.cpp
@@ -947,15 +947,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.
+ // audio/softsynth/opl/mame.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.
- //
- // 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/kyra/vqa.cpp b/engines/kyra/vqa.cpp
index fb51c05e51..cfd5f6ffc6 100644
--- a/engines/kyra/vqa.cpp
+++ b/engines/kyra/vqa.cpp
@@ -532,7 +532,7 @@ void VQADecoder::VQAVideoTrack::handleVQFR(Common::SeekableReadStream *stream) {
uint32 tag = readTag(stream);
uint32 i;
size = stream->readUint32BE();
-
+
switch (tag) {
case MKTAG('C','B','F','0'): // Full codebook
stream->read(_codeBook, size);
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/pmvplayer.cpp b/engines/made/pmvplayer.cpp
index 3cac017e10..6ea0dc24d0 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();
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..3f98cbb9ab 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() {
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/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 9f0e0adb6d..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];
@@ -340,9 +340,6 @@ void Animation::startAnimation(int endTrigger) {
_unkIndex = -1;
//SpriteAsset *asset = _scene->_sprites[_spriteListIndexes[_header._spritesIndex]];
- // TODO: Weird stuff with _unkList. Seems like it's treated as pointers
- // here, but in processText, it's used as POINTs?
-
loadFrame(1);
}
@@ -439,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()) {
@@ -601,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 1c61e13957..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.
@@ -37,6 +37,7 @@ AudioPlayer::AudioPlayer(Audio::Mixer *mixer, uint32 gameID) : _mixer(mixer), _g
AudioPlayer::~AudioPlayer() {
_dsrEntries.clear();
+ _filename = "";
}
bool AudioPlayer::isPlaying() const {
@@ -65,25 +66,27 @@ void AudioPlayer::setDefaultSoundGroup() {
}
void AudioPlayer::setSoundGroup(const Common::String &filename) {
- _dsrEntries.clear();
-
- _filename = filename;
- _dsrFile.open(filename);
-
- // Read header
- uint16 entryCount = _dsrFile.readUint16LE();
-
- for (uint16 i = 0; i < entryCount; i++) {
- DSREntry newEntry;
- newEntry.frequency = _dsrFile.readUint16LE();
- newEntry.channels = _dsrFile.readUint32LE();
- newEntry.compSize = _dsrFile.readUint32LE();
- newEntry.uncompSize = _dsrFile.readUint32LE();
- newEntry.offset = _dsrFile.readUint32LE();
- _dsrEntries.push_back(newEntry);
+ if (_filename != filename) {
+ _dsrEntries.clear();
+
+ _filename = filename;
+ _dsrFile.open(filename);
+
+ // Read header
+ uint16 entryCount = _dsrFile.readUint16LE();
+
+ for (uint16 i = 0; i < entryCount; i++) {
+ DSREntry newEntry;
+ newEntry.frequency = _dsrFile.readUint16LE();
+ newEntry.channels = _dsrFile.readUint32LE();
+ newEntry.compSize = _dsrFile.readUint32LE();
+ newEntry.uncompSize = _dsrFile.readUint32LE();
+ newEntry.offset = _dsrFile.readUint32LE();
+ _dsrEntries.push_back(newEntry);
+ }
+
+ _dsrFile.close();
}
-
- _dsrFile.close();
}
void AudioPlayer::playSound(int soundIndex, bool loop) {
@@ -126,4 +129,8 @@ void AudioPlayer::playSound(int soundIndex, bool loop) {
*/
}
+void AudioPlayer::stop() {
+ _mixer->stopHandle(_handle);
+}
+
} // End of namespace M4
diff --git a/engines/mads/audio.h b/engines/mads/audio.h
index 21f4bed59a..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.
@@ -46,6 +46,7 @@ public:
void setSoundGroup(const Common::String &filename);
void setDefaultSoundGroup();
void playSound(int soundIndex, bool loop = false);
+ void stop();
void setVolume(int volume);
bool isPlaying() const;
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 5ea8fb115c..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
@@ -457,6 +459,7 @@ void FullScreenDialog::display() {
_vm->_palette->setLowRange();
_vm->_screen.hLine(0, 20, MADS_SCREEN_WIDTH, 2);
_vm->_screen.hLine(0, 179, MADS_SCREEN_WIDTH, 2);
+ _vm->_screen.resetClipBounds();
_vm->_screen.copyRectToScreen(Common::Rect(0, 0, MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT));
// Restrict the screen to the area between the two 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 dbf1759d4b..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.
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 b544eff2db..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,11 +433,19 @@ 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;
}
-
- warning("TODO: handleKeypress - %d", (int)event.kbd.keycode);
}
void Game::synchronize(Common::Serializer &s, bool phase1) {
@@ -558,7 +569,7 @@ void Game::writeSavegameHeader(Common::OutSaveFile *out, MADSSavegameHeader &hea
if (!_saveThumb)
createThumbnail();
Graphics::saveThumbnail(*out, *_saveThumb);
-
+
_saveThumb->free();
delete _saveThumb;
_saveThumb = nullptr;
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..bd28645504 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:
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 6acf6cdf9f..10d5a2179a 100644
--- a/engines/mads/menu_views.cpp
+++ b/engines/mads/menu_views.cpp
@@ -1,24 +1,24 @@
/* 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.
- *
- */
+*
+* 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/game.h"
@@ -37,7 +37,7 @@ MenuView::MenuView(MADSEngine *vm) : FullScreenDialog(vm) {
}
void MenuView::show() {
- Scene &scene = _vm->_game->_scene;
+ Scene &scene = _vm->_game->_scene;
EventsManager &events = *_vm->_events;
_vm->_screenFade = SCREEN_FADE_FAST;
@@ -80,6 +80,15 @@ bool MenuView::onEvent(Common::Event &event) {
return false;
}
+Common::String MenuView::getResourceName() {
+ Common::String s(_filename);
+ s.toLowercase();
+ while (s.contains('.'))
+ s.deleteLastChar();
+
+ return s;
+}
+
/*------------------------------------------------------------------------*/
char TextView::_resourceName[100];
@@ -112,12 +121,17 @@ TextView::TextView(MADSEngine *vm) : MenuView(vm) {
}
TextView::~TextView() {
+ // Turn off palette cycling as well as any playing sound
+ Scene &scene = _vm->_game->_scene;
+ scene._cyclingActive = false;
+ _vm->_sound->stop();
}
void TextView::load() {
Common::String scriptName(_resourceName);
scriptName += ".txr";
+ _filename = scriptName;
if (!_script.open(scriptName))
error("Could not open resource %s", _resourceName);
@@ -181,7 +195,7 @@ void TextView::processCommand() {
paramP = commandStr + 10;
resetPalette();
int screenId = getParameter(&paramP);
-
+
SceneInfo *sceneInfo = SceneInfo::init(_vm);
sceneInfo->load(screenId, 0, "", 0, scene._depthSurface, scene._backgroundSurface);
scene._spriteSlots.fullRefresh();
@@ -216,7 +230,7 @@ void TextView::processCommand() {
int soundId = getParameter(&paramP);
_vm->_sound->command(soundId);
- } else if (!strncmp(commandStr, "COLOR", 5) && ((commandStr[5] == '0') ||
+ } else if (!strncmp(commandStr, "COLOR", 5) && ((commandStr[5] == '0') ||
(commandStr[5] == '1'))) {
// Set the text colors
int index = commandStr[5] - '0';
@@ -240,7 +254,8 @@ void TextView::processCommand() {
sceneInfo->_width = MADS_SCREEN_WIDTH;
sceneInfo->_height = MADS_SCENE_HEIGHT;
_spareScreens[spareIndex].setSize(MADS_SCREEN_WIDTH, MADS_SCENE_HEIGHT);
- sceneInfo->loadMadsV1Background(screenId, "", SCENEFLAG_TRANSLATE,
+
+ sceneInfo->loadMadsV1Background(screenId, "", SCENEFLAG_TRANSLATE,
_spareScreens[spareIndex]);
delete sceneInfo;
@@ -395,7 +410,7 @@ void TextView::doFrame() {
Common::copy(srcP, srcP + MADS_SCREEN_WIDTH, destP);
}
- Common::copy(linesTemp, linesTemp + _pan.y * MADS_SCREEN_WIDTH,
+ Common::copy(linesTemp, linesTemp + _pan.y * MADS_SCREEN_WIDTH,
(byte *)scene._backgroundSurface.getPixels());
delete[] linesTemp;
}
@@ -412,10 +427,10 @@ 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,
+ tl._textDisplayIndex = scene._textDisplay.add(tl._pos.x, tl._pos.y,
0x605, -1, tl._line, _font);
}
}
@@ -470,11 +485,19 @@ AnimationView::AnimationView(MADSEngine *vm) : MenuView(vm) {
_animFrameNumber = 0;
_nextCyclingActive = false;
_sceneInfo = SceneInfo::init(_vm);
+ _scrollFrameCtr = 0;
load();
}
AnimationView::~AnimationView() {
+ // Turn off palette cycling as well as any playing sound
+ Scene &scene = _vm->_game->_scene;
+ scene._cyclingActive = false;
+ _vm->_sound->stop();
+ _vm->_audio->stop();
+
+ // Delete data
delete _currentAnimation;
delete _sceneInfo;
}
@@ -484,6 +507,7 @@ void AnimationView::load() {
if (!resName.hasSuffix("."))
resName += ".res";
+ _filename = resName;
if (!_script.open(resName))
error("Could not open resource %s", resName.c_str());
@@ -505,7 +529,7 @@ void AnimationView::display() {
bool AnimationView::onEvent(Common::Event &event) {
// Wait for the Escape key or a mouse press
if (((event.type == Common::EVENT_KEYDOWN) && (event.kbd.keycode == Common::KEYCODE_ESCAPE)) ||
- (event.type == Common::EVENT_RBUTTONUP)) {
+ (event.type == Common::EVENT_LBUTTONUP)) {
scriptDone();
return true;
}
@@ -515,22 +539,32 @@ bool AnimationView::onEvent(Common::Event &event) {
void AnimationView::doFrame() {
Scene &scene = _vm->_game->_scene;
-
+
if (_resourceIndex == -1 || _currentAnimation->freeFlag()) {
if (++_resourceIndex == (int)_resources.size()) {
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();
}
}
@@ -543,7 +577,7 @@ void AnimationView::loadNextResource() {
if (resEntry._bgFlag)
palette.resetGamePalette(1, 8);
- palette._mainPalette[253 * 3] = palette._mainPalette[253 * 3 + 1]
+ palette._mainPalette[253 * 3] = palette._mainPalette[253 * 3 + 1]
= palette._mainPalette[253 * 3 + 2] = 0xb4;
palette.setPalette(&palette._mainPalette[253 * 3], 253, 1);
@@ -565,7 +599,7 @@ void AnimationView::loadNextResource() {
delete _currentAnimation;
_currentAnimation = Animation::init(_vm, &scene);
int flags = ANIMFLAG_ANIMVIEW | (resEntry._bgFlag ? ANIMFLAG_LOAD_BACKGROUND : 0);
- _currentAnimation->load(scene._backgroundSurface, scene._depthSurface,
+ _currentAnimation->load(scene._backgroundSurface, scene._depthSurface,
resEntry._resourceName, flags, &paletteCycles, _sceneInfo);
// Signal for a screen refresh
@@ -614,6 +648,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;
@@ -634,7 +683,11 @@ void AnimationView::processLines() {
if (c != '\r' && c != '\0')
_currentLine += c;
}
-
+
+ // Check for comment line
+ if (_currentLine.hasPrefix("#"))
+ continue;
+
// Process the line
while (!_currentLine.empty()) {
if (_currentLine.hasPrefix("-")) {
@@ -650,7 +703,7 @@ void AnimationView::processLines() {
}
// Add resource into list along with any set state information
- _resources.push_back(ResourceEntry(resName, _sfx, _soundFlag,
+ _resources.push_back(ResourceEntry(resName, _sfx, _soundFlag,
_bgLoadFlag, _showWhiteBars));
// Fx resets between resource entries
@@ -731,7 +784,7 @@ int AnimationView::getParameter() {
while (!_currentLine.empty()) {
char c = _currentLine[0];
-
+
if (c >= '0' && c <= '9') {
_currentLine.deleteChar(0);
result = result * 10 + (c - '0');
diff --git a/engines/mads/menu_views.h b/engines/mads/menu_views.h
index 6faa665bff..c203248ad9 100644
--- a/engines/mads/menu_views.h
+++ b/engines/mads/menu_views.h
@@ -8,12 +8,20 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
+<<<<<<< HEAD
+=======
+ *
+>>>>>>> master
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
+<<<<<<< HEAD
+=======
+ *
+>>>>>>> master
* You should have received a copy of the GNU General Public 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 +44,7 @@ class MenuView: public FullScreenDialog {
protected:
bool _breakFlag;
bool _redrawFlag;
+ Common::String _filename;
virtual void doFrame() = 0;
@@ -51,6 +60,8 @@ public:
virtual ~MenuView() {}
virtual void show();
+
+ Common::String getResourceName();
};
struct TextLine {
@@ -107,11 +118,6 @@ private:
int getParameter(const char **paramP);
/**
- * Called when the script is finished
- */
- void scriptDone();
-
- /**
* Reset the game palette
*/
void resetPalette();
@@ -119,6 +125,11 @@ protected:
virtual void display();
virtual void doFrame();
+
+ /**
+ * Called when the script is finished
+ */
+ virtual void scriptDone();
public:
/**
* Queue the given text resource for display
@@ -193,6 +204,8 @@ private:
int scanResourceIndex(const Common::String &resourceName);
+ uint _scrollFrameCtr;
+private:
void load();
void processLines();
@@ -201,15 +214,17 @@ private:
int getParameter();
- void scriptDone();
-
void loadNextResource();
+
+ void scroll();
protected:
virtual void display();
virtual void doFrame();
virtual bool onEvent(Common::Event &event);
+
+ virtual void scriptDone();
public:
/**
* Queue the given text resource for 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/msurface.cpp b/engines/mads/msurface.cpp
index 0cb4530a84..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.
@@ -87,7 +87,6 @@ void MSurface::drawSprite(const Common::Point &pt, SpriteInfo &info, const Commo
// rectangle is always 0, 0
assert(clipRect.top == 0 && clipRect.left == 0);
- // TODO: Put err* and scaled* into SpriteInfo
int errX = info.hotX * info.scaleX % 100;
int errY = info.hotY * info.scaleY % 100;
int scaledWidth = scaleValue(info.width, info.scaleX, errX);
@@ -160,7 +159,6 @@ void MSurface::drawSprite(const Common::Point &pt, SpriteInfo &info, const Commo
if (status == kStatusDraw && clipY == 0) {
// Draw previously scaled line
- // TODO Implement different drawing types (depth, shadow etc.)
byte *tempDst = dst;
for (int lineX = 0; lineX < scaledWidth; lineX++) {
byte pixel = scaledLineBuf[lineX];
@@ -186,8 +184,6 @@ void MSurface::drawSprite(const Common::Point &pt, SpriteInfo &info, const Commo
}
dst += pitch;
heightAmt--;
- // TODO depth etc.
- //depthAddress += Destination -> Width;
errY += 100;
if (errY >= 0)
@@ -312,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;
@@ -401,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);
@@ -489,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);
@@ -525,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 ebfb1f437a..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,11 +220,16 @@ 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 {
-private:
- MADSEngine *_vm;
public:
/**
* Depth style
@@ -234,7 +239,7 @@ public:
/**
* Constructor
*/
- DepthSurface(MADSEngine *vm) : _vm(vm), _depthStyle(0) {}
+ DepthSurface() : _depthStyle(0) {}
/**
* Returns the depth at a given position
diff --git a/engines/mads/nebular/dialogs_nebular.cpp b/engines/mads/nebular/dialogs_nebular.cpp
index 86244bd3bb..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();
@@ -314,13 +325,13 @@ void DialogsNebular::showDialog() {
break;
}
case DIALOG_TEXTVIEW: {
- TextView *dlg = new TextView(_vm);
+ TextView *dlg = new RexTextView(_vm);
dlg->show();
delete dlg;
- break;
+ return;
}
case DIALOG_ANIMVIEW: {
- AnimationView *dlg = new AnimationView(_vm);
+ AnimationView *dlg = new RexAnimationView(_vm);
dlg->show();
delete dlg;
break;
@@ -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;
@@ -594,14 +653,20 @@ GameDialog::GameDialog(MADSEngine *vm) : FullScreenDialog(vm) {
_vm->_events->waitCursor();
scene.clearVocab();
scene._dynamicHotspots.clear();
+ // Clear scene sprites and objects
+ scene._spriteSlots.reset();
+ _vm->_game->_screenObjects.clear();
_vm->_dialogs->_defaultPosition = Common::Point(-1, -1);
_menuSpritesIndex = 0;
}
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);
@@ -621,6 +686,7 @@ void GameDialog::display() {
GameDialog::~GameDialog() {
_vm->_screen.resetClipBounds();
+ _vm->_game->_scene._currentSceneId = RETURNING_FROM_DIALOG;
}
void GameDialog::clearLines() {
@@ -640,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);
}
}
@@ -791,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)
@@ -818,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;
@@ -905,7 +981,7 @@ void GameDialog::refreshText() {
}
if (!skipFlag) {
- _lines[i]._textDisplayIndex = scene._textDisplay.add(_lines[i]._pos.x, _lines[i]._pos.y,
+ _lines[i]._textDisplayIndex = scene._textDisplay.add(_lines[i]._pos.x, _lines[i]._pos.y,
fontColor, _lines[i]._widthAdjust, _lines[i]._msg, _lines[i]._font);
}
}
@@ -997,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();
}
}
@@ -1015,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
@@ -1061,16 +1137,25 @@ void OptionsDialog::display() {
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;
+ ScreenFade prevScreenFade = _vm->_screenFade;
+ 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;
@@ -1099,19 +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
- // TODO: Copy from temporary config
- break;
- case 9: // Cancel
- // TODO: Ignore all changes to temporary config
- break;
- default:
- break;
+ } 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;
}
}
diff --git a/engines/mads/nebular/dialogs_nebular.h b/engines/mads/nebular/dialogs_nebular.h
index d00cd87ead..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 {
@@ -116,7 +119,7 @@ class GameDialog: public FullScreenDialog {
Common::String _msg;
Font *_font;
int _widthAdjust;
-
+
DialogLine();
DialogLine(const Common::String &s);
};
@@ -130,7 +133,7 @@ protected:
int _menuSpritesIndex;
int _lineIndex;
int _textLineCount;
-
+
/**
* Display the dialog
*/
diff --git a/engines/mads/nebular/game_nebular.cpp b/engines/mads/nebular/game_nebular.cpp
index 902f42507a..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.
@@ -27,6 +27,7 @@
#include "mads/game.h"
#include "mads/screen.h"
#include "mads/msurface.h"
+#include "mads/menu_views.h"
#include "mads/nebular/game_nebular.h"
#include "mads/nebular/dialogs_nebular.h"
#include "mads/nebular/globals_nebular.h"
@@ -44,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:
@@ -78,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() {
@@ -244,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:
@@ -259,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;
}
@@ -309,7 +349,9 @@ void GameNebular::setSectionHandler() {
}
void GameNebular::checkShowDialog() {
- if (_vm->_dialogs->_pendingDialog && _player._stepEnabled && !_globals[kCopyProtectFailed]) {
+ // Loop for showing dialogs, if any need to be shown
+ if (_vm->_dialogs->_pendingDialog && (_player._stepEnabled || _winStatus)
+ && !_globals[kCopyProtectFailed]) {
_player.releasePlayerSprites();
// Make a thumbnail in case it's needed for making a savegame
@@ -428,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);
@@ -599,7 +641,7 @@ void GameNebular::doObjectAction() {
_objects.addToInventory(OBJ_DURAFAIL_CELLS);
if (_difficulty == DIFFICULTY_HARD) {
dialogs.showItem(OBJ_DURAFAIL_CELLS, 416);
- }
+ }
_globals[kHandsetCellStatus] = 0;
break;
case 3:
@@ -784,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 da607d47ee..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,20 +131,21 @@ 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
class Section1Handler : public SectionHandler {
public:
Section1Handler(MADSEngine *vm) : SectionHandler(vm) {}
- // TODO: Properly implement handler methods
virtual void preLoadSection() {}
virtual void sectionPtr2() {}
virtual void postLoadSection() {}
};
-// TODO: Properly implement handler classes
typedef Section1Handler Section2Handler;
typedef Section1Handler Section3Handler;
typedef Section1Handler Section4Handler;
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 717e3f6cf9..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.
@@ -21,6 +21,7 @@
*/
#include "common/scummsys.h"
+#include "common/config-manager.h"
#include "mads/game.h"
#include "mads/mads.h"
#include "mads/menu_views.h"
@@ -47,7 +48,7 @@ MainMenu::MainMenu(MADSEngine *vm): MenuView(vm) {
_highlightedIndex = -1;
_selectedIndex = -1;
_buttonDown = false;
-
+
for (int i = 0; i < 7; ++i)
_menuItems[i] = nullptr;
}
@@ -62,6 +63,10 @@ MainMenu::~MainMenu() {
scene._spriteSlots.reset();
}
+bool MainMenu::shouldShowQuotes() {
+ return ConfMan.hasKey("ShowQuotes") && ConfMan.getBool("ShowQuotes");
+}
+
void MainMenu::display() {
MenuView::display();
Scene &scene = _vm->_game->_scene;
@@ -80,8 +85,8 @@ void MainMenu::display() {
Common::Point pt(frame0->_offset.x - (frame0->w / 2),
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);
+ Common::Rect(pt.x, pt.y + DIALOG_TOP, pt.x + frame0->w,
+ pt.y + frame0->h + DIALOG_TOP), SCREENMODE_VGA, CAT_COMMAND, i);
}
// Set the cursor for when it's shown
@@ -101,6 +106,9 @@ void MainMenu::doFrame() {
handleAction((MADSGameAction)_selectedIndex);
} else {
for (_menuItemIndex = 0; _menuItemIndex < 6; ++_menuItemIndex) {
+ if (_menuItemIndex == 4 && !shouldShowQuotes())
+ continue;
+
if (_menuItemIndex != _selectedIndex) {
addSpriteSlot();
}
@@ -118,8 +126,11 @@ void MainMenu::doFrame() {
// If the user has chosen to skip the animation, show the full menu immediately
if (_skipFlag && _menuItemIndex >= 0) {
- // Quickly loop through all the menu items to display each's final frame
+ // Quickly loop through all the menu items to display each's final frame
for (; _menuItemIndex < 6; ++_menuItemIndex) {
+ if (_menuItemIndex == 4 && !shouldShowQuotes())
+ continue;
+
// Draw the final frame of the menuitem
_frameIndex = 0;
addSpriteSlot();
@@ -129,9 +140,12 @@ void MainMenu::doFrame() {
} else {
if ((_menuItemIndex == -1) || (_frameIndex == 0)) {
if (++_menuItemIndex == 6) {
+
// Reached end of display animation
_vm->_events->showCursor();
return;
+ } else if (_menuItemIndex == 4 && !shouldShowQuotes()) {
+ ++_menuItemIndex;
}
_frameIndex = _menuItems[_menuItemIndex]->getCount() - 1;
@@ -147,7 +161,7 @@ void MainMenu::doFrame() {
void MainMenu::addSpriteSlot() {
Scene &scene = _vm->_game->_scene;
SpriteSlots &spriteSlots = scene._spriteSlots;
-
+
int seqIndex = (_menuItemIndex < 6) ? _menuItemIndex : _frameIndex;
spriteSlots.deleteTimer(seqIndex);
@@ -241,7 +255,7 @@ bool MainMenu::onEvent(Common::Event &event) {
}
return true;
- case Common::EVENT_MOUSEMOVE:
+ case Common::EVENT_MOUSEMOVE:
if (_buttonDown) {
int menuIndex = getHighlightedItem(event.mouse);
if (menuIndex != _highlightedIndex) {
@@ -273,12 +287,12 @@ bool MainMenu::onEvent(Common::Event &event) {
default:
break;
}
-
+
return false;
}
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() {
@@ -303,7 +317,7 @@ void MainMenu::handleAction(MADSGameAction action) {
break;
case RESUME_GAME:
- // The original resumed the most recently saved game. Instead,
+ // The original resumed the most recently saved game. Instead,
// just show the load game scren
_vm->_dialogs->_pendingDialog = DIALOG_RESTORE;
return;
@@ -340,7 +354,7 @@ void AdvertView::show() {
uint32 expiryTime = g_system->getMillis() + 10 * 1000;
_vm->_palette->resetGamePalette(4, 8);
-
+
// Load the advert background onto the screen
SceneInfo *sceneInfo = SceneInfo::init(_vm);
sceneInfo->load(screenId, 0, Common::String(), 0, _vm->_game->_scene._depthSurface,
@@ -375,6 +389,21 @@ bool AdvertView::onEvent(Common::Event &event) {
return false;
}
+/*------------------------------------------------------------------------*/
+
+void RexAnimationView::scriptDone() {
+ AnimationView::scriptDone();
+
+ Common::String s = getResourceName();
+ if (s == "rexend1") {
+ TextView::execute(_vm, "ending1");
+ } else if (s == "rexend2") {
+ TextView::execute(_vm, "ending2");
+ } else if (s == "rexend3") {
+ TextView::execute(_vm, "credits");
+ }
+}
+
} // End of namespace Nebular
} // End of namespace MADS
diff --git a/engines/mads/nebular/menu_nebular.h b/engines/mads/nebular/menu_nebular.h
index 29777a7a7c..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.
@@ -80,6 +80,8 @@ private:
* Add a sprite slot for the current menuitem frame
*/
void addSpriteSlot();
+
+ bool shouldShowQuotes();
protected:
/**
* Display the menu
@@ -128,6 +130,18 @@ public:
void show();
};
+class RexAnimationView : public AnimationView {
+protected:
+ virtual void scriptDone();
+public:
+ RexAnimationView(MADSEngine *vm) : AnimationView(vm) {}
+};
+
+class RexTextView : public TextView {
+public:
+ RexTextView(MADSEngine *vm) : TextView(vm) {}
+};
+
} // End of namespace Nebular
} // End of namespace MADS
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 13ee1a3dc1..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);
@@ -3155,7 +3161,7 @@ bool Scene611::check2ChargedBatteries() {
}
bool Scene611::check4ChargedBatteries() {
- if (_game._objects.isInInventory(OBJ_DURAFAIL_CELLS) && _game._objects.isInInventory(OBJ_PHONE_CELLS)
+ if (_game._objects.isInInventory(OBJ_DURAFAIL_CELLS) && _game._objects.isInInventory(OBJ_PHONE_CELLS)
&& _globals[kDurafailRecharged])
return true;
@@ -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 930bb7c250..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);
@@ -2616,13 +2617,13 @@ void Scene752::actions() {
default:
break;
}
- } else if (_action.isAction(VERB_TAKE, NOUN_BONES) && (_action._savedFields._mainObjectSource == CAT_HOTSPOT) &&
+ } else if (_action.isAction(VERB_TAKE, NOUN_BONES) && (_action._savedFields._mainObjectSource == CAT_HOTSPOT) &&
(!_game._objects.isInInventory(OBJ_BONES) || _game._trigger)) {
switch (_game._trigger) {
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 14f36756de..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;
}
}
@@ -1098,7 +1100,7 @@ void Scene804::actions() {
_action.isAction(VERB_OPEN, NOUN_SERVICE_PANEL)) {
_scene->_nextSceneId = 805;
} else if ((_action.isAction(VERB_ACTIVATE, NOUN_REMOTE)) && _globals[kTopButtonPushed]) {
- if (!_globals[kInSpace]) {
+ if (!_globals[kInSpace]) {
// Top button pressed on panel in hanger control
if (!_globals[kBeamIsUp]) {
_globals[kFromCockpit] = true;
@@ -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 c540eb4382..240c18f6dc 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.
@@ -24,6 +24,7 @@
#include "audio/decoders/raw.h"
#include "common/algorithm.h"
#include "common/debug.h"
+#include "common/md5.h"
#include "common/memstream.h"
#include "mads/sound.h"
#include "mads/nebular/sound_nebular.h"
@@ -35,6 +36,7 @@ namespace Nebular {
bool AdlibChannel::_channelsEnabled;
AdlibChannel::AdlibChannel() {
+ _owner = nullptr;
_activeCount = 0;
_field1 = 0;
_field2 = 0;
@@ -42,6 +44,7 @@ AdlibChannel::AdlibChannel() {
_field4 = 0;
_sampleIndex = 0;
_volume = 0;
+ _volumeOffset = 0;
_field7 = 0;
_field8 = 0;
_field9 = 0;
@@ -54,11 +57,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;
@@ -94,6 +97,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;
@@ -101,17 +105,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 {
@@ -160,6 +167,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;
@@ -191,6 +199,9 @@ ASound::ASound(Audio::Mixer *mixer, FM_OPL *opl, const Common::String &filename,
_channelData[i]._freqBase = 0;
_channelData[i]._field6 = 0;
}
+
+ for (int i = 0; i < ADLIB_CHANNEL_COUNT; ++i)
+ _channels[i]._owner = this;
AdlibChannel::_channelsEnabled = false;
@@ -218,6 +229,32 @@ ASound::~ASound() {
_mixer->stopHandle(_soundHandle);
}
+void ASound::validate() {
+ Common::File f;
+ static const char *const MD5[] = {
+ "205398468de2c8873b7d4d73d5be8ddc",
+ "f9b2d944a2fb782b1af5c0ad592306d3",
+ "7431f8dad77d6ddfc24e6f3c0c4ac7df",
+ "eb1f3f5a4673d3e73d8ac1818c957cf4",
+ "f936dd853073fa44f3daac512e91c476",
+ "3dc139d3e02437a6d9b732072407c366",
+ "af0edab2934947982e9a405476702e03",
+ "8cbc25570b50ba41c9b5361cad4fbedc",
+ "a31e4783e098f633cbb6689adb41dd4f"
+ };
+
+ for (int i = 1; i <= 9; ++i) {
+ Common::String filename = Common::String::format("ASOUND.00%d", i);
+ if (!f.open(filename))
+ error("Could not process - %s", filename.c_str());
+ Common::String md5str = Common::computeStreamMD5AsString(f, 8192);
+ f.close();
+
+ if (md5str != MD5[i - 1])
+ error("Invalid sound file - %s", filename.c_str());
+ }
+}
+
void ASound::adlibInit() {
write(4, 0x60);
write(4, 0x80);
@@ -256,6 +293,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));
}
@@ -304,6 +352,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);
@@ -422,6 +471,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();
@@ -489,7 +542,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;
@@ -543,7 +596,7 @@ void ASound::pollActiveChannel() {
break;
case 8:
- chan->_field1D = *++pSrc;
+ chan->_field1D = (int8)*++pSrc;
chan->_pSrc += 2;
break;
@@ -564,7 +617,7 @@ void ASound::pollActiveChannel() {
if (chan->_fieldE) {
chan->_pSrc += 2;
} else {
- chan->_field1E = *pSrc >> 1;
+ chan->_volumeOffset = *pSrc >> 1;
updateFlag = true;
chan->_pSrc += 2;
}
@@ -608,7 +661,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;
@@ -617,7 +670,7 @@ void ASound::pollActiveChannel() {
newVal = 63;
}
- chan->_field1E = newVal;
+ chan->_volumeOffset = newVal;
updateFlag = true;
}
}
@@ -682,8 +735,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);
@@ -700,32 +753,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) {
@@ -821,6 +860,12 @@ int ASound::readBuffer(int16 *buffer, const int numSamples) {
return numSamples;
}
+void ASound::setVolume(int volume) {
+ _masterVolume = volume;
+ if (!volume)
+ command0();
+}
+
int ASound::command0() {
bool isDisabled = _isDisabled;
_isDisabled = true;
@@ -978,22 +1023,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;
}
diff --git a/engines/mads/nebular/sound_nebular.h b/engines/mads/nebular/sound_nebular.h
index abb6516030..9bc1a49458 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.
@@ -37,11 +37,15 @@ 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 +65,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 +133,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 {
private:
- struct CachedDataEntry {
- int _offset;
- byte *_data;
- };
Common::List<CachedDataEntry> _dataCache;
uint16 _randomSeed;
+ int _masterVolume;
/**
* Does the initial Adlib initialisation
@@ -318,6 +326,11 @@ public:
virtual ~ASound();
/**
+ * Validates the Adlib sound files
+ */
+ static void validate();
+
+ /**
* Execute a player command. Most commands represent sounds to play, but some
* low number commands also provide control operations.
* @param commandId Player ommand to execute.
@@ -345,6 +358,11 @@ public:
*/
int getFrameCounter() { return _frameCounter; }
+ /**
+ * Return the cached data block record for previously loaded sound data
+ */
+ CachedDataEntry &getCachedData(byte *pData);
+
// AudioStream interface
/**
* Main buffer read
@@ -365,6 +383,11 @@ public:
* Return sample rate
*/
virtual int getRate() const { return 11025; }
+
+ /**
+ * Set the volume
+ */
+ void setVolume(int volume);
};
class ASound1 : public ASound {
diff --git a/engines/mads/palette.cpp b/engines/mads/palette.cpp
index 1787b3c298..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;
}
}
}
@@ -233,7 +231,7 @@ int PaletteUsage::process(Common::Array<RGB6> &palette, uint flags) {
// CHECKME: When pressing on F1 in the first screen, newPalIndex is set to 0xFF at this point
// which is a valid value for the index. Maybe a better check would be "< 256" ?
//assert(newPalIndex != -1);
-
+
int var52 = (noUsageFlag && palette[palIndex]._u2) ? 2 : 0;
_vm->_palette->_palFlags[newPalIndex] |= var52 | rgbMask;
@@ -342,7 +340,7 @@ int PaletteUsage::checkRGB(const byte *rgb, int palStart, bool flag, int *palInd
if ((!(*flagsP & 1) || flag) && !(*flagsP & 2)) {
if (!memcmp(palP, rgb, 3)) {
*flagsP |= mask;
-
+
if (palIndex)
*palIndex = result;
match = true;
@@ -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 2384b94dec..959a726edf 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.
diff --git a/engines/mads/phantom/game_phantom.h b/engines/mads/phantom/game_phantom.h
index 654ec86ba3..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.
diff --git a/engines/mads/phantom/phantom_scenes.cpp b/engines/mads/phantom/phantom_scenes.cpp
index c8faa35fcb..57c2bb2c9b 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.
diff --git a/engines/mads/phantom/phantom_scenes.h b/engines/mads/phantom/phantom_scenes.h
index 0d7bc253dd..55218f219a 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.
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 e8ba988771..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.
@@ -31,7 +31,7 @@
namespace MADS {
Scene::Scene(MADSEngine *vm)
- : _vm(vm), _action(_vm), _depthSurface(vm),
+ : _vm(vm), _action(_vm), _depthSurface(),
_dirtyAreas(_vm), _dynamicHotspots(vm), _hotspots(vm),
_kernelMessages(vm), _sequences(vm), _sprites(vm), _spriteSlots(vm),
_textDisplay(vm), _userInterface(vm) {
@@ -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;
@@ -182,7 +182,7 @@ void Scene::loadScene(int sceneId, const Common::String &prefix, bool palFlag) {
flags |= ANIMFLAG_LOAD_BACKGROUND_ONLY;
_animationData = Animation::init(_vm, this);
- DepthSurface depthSurface(_vm);
+ DepthSurface depthSurface;
_animationData->load(_userInterface, depthSurface, prefix, flags, nullptr, nullptr);
_vm->_palette->_paletteUsage.load(&_scenePaletteUsage);
@@ -360,6 +360,9 @@ void Scene::loop() {
if (_vm->_dialogs->_pendingDialog != DIALOG_NONE && !_vm->_game->_trigger
&& _vm->_game->_player._stepEnabled)
_reloadSceneFlag = true;
+
+ if (_vm->_game->_winStatus)
+ break;
}
}
@@ -587,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();
@@ -606,7 +611,7 @@ void Scene::loadAnimation(const Common::String &resName, int trigger) {
if (_activeAnimation)
freeAnimation();
- DepthSurface depthSurface(_vm);
+ DepthSurface depthSurface;
UserInterface interfaceSurface(_vm);
_activeAnimation = Animation::init(_vm, this);
@@ -659,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 b0a5aa35c6..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);
- bgSurface.copyFrom(spr, si._position, si._depth, &depthSurface,
- si._scale, spr->getTransparencyIndex());
+ MSprite *spr = asset->getFrame(si._frameNumber);
+ bgSurface.copyFrom(spr, si._position, si._depth, &depthSurface,
+ 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 07b1451718..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 d0aa770a4d..7b9388eee3 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.
@@ -36,9 +36,19 @@ SoundManager::SoundManager(MADSEngine *vm, Audio::Mixer *mixer) {
_pollSoundEnabled = false;
_soundPollFlag = false;
_newSoundsPaused = false;
+ _masterVolume = 255;
_opl = OPL::Config::create();
_opl->init(11025);
+
+ // Validate sound files
+ switch (_vm->getGameID()) {
+ case GType_RexNebular:
+ Nebular::ASound::validate();
+ break;
+ default:
+ break;
+ }
}
SoundManager::~SoundManager() {
@@ -53,6 +63,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) {
@@ -85,15 +98,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() {
@@ -129,12 +145,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..16128f8284 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.
@@ -43,6 +43,7 @@ private:
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 6cb55aaeee..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 {
- while (size() > 0 && (*this)[size() - 1] == nullptr) {
+ 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/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/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_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/myst.cpp b/engines/mohawk/myst_stacks/myst.cpp
index c500df5ad3..ca6e7c0ee5 100644
--- a/engines/mohawk/myst_stacks/myst.cpp
+++ b/engines/mohawk/myst_stacks/myst.cpp
@@ -3201,13 +3201,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);
diff --git a/engines/mohawk/riven_external.cpp b/engines/mohawk/riven_external.cpp
index 3d0bccc47f..cda0683028 100644
--- a/engines/mohawk/riven_external.cpp
+++ b/engines/mohawk/riven_external.cpp
@@ -2513,7 +2513,7 @@ void RivenExternal::xthideinventory(uint16 argc, uint16 *argv) {
static const uint32 kMarbleCount = 6;
static const int kSmallMarbleWidth = 4;
static const int kSmallMarbleHeight = 2;
-static const int kLargeMarbleSize = 8;
+//static const int kLargeMarbleSize = 8;
static const int kMarbleHotspotSize = 13;
static const char *s_marbleNames[] = { "tred", "torange", "tyellow", "tgreen", "tblue", "tviolet" };
diff --git a/engines/mohawk/video.cpp b/engines/mohawk/video.cpp
index cebb72e24f..3f27e4a1a4 100644
--- a/engines/mohawk/video.cpp
+++ b/engines/mohawk/video.cpp
@@ -53,6 +53,8 @@ bool VideoEntry::endOfVideo() {
}
VideoManager::VideoManager(MohawkEngine* vm) : _vm(vm) {
+ // Set dithering enabled, if required
+ _enableDither = _vm->getGameType() == GType_MYST && !(_vm->getFeatures() & GF_ME);
}
VideoManager::~VideoManager() {
@@ -230,16 +232,23 @@ bool VideoManager::updateMovies() {
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");
+ delete _videoStreams[i].video;
+ _videoStreams[i].clear();
+ continue;
+ }
// Convert to the current screen format
convertedFrame = frame->convertTo(pixelFormat, _videoStreams[i]->getPalette());
frame = convertedFrame;
} else if (pixelFormat.bytesPerPixel == 1 && _videoStreams[i]->hasDirtyPalette()) {
// Set the palette when running in 8bpp mode only
- _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(_videoStreams[i]->getPalette(), 0, 256);
}
// Clip the width/height to make sure we stay on the screen (Myst does this a few times)
@@ -394,6 +403,9 @@ VideoHandle VideoManager::createVideoHandle(uint16 id, uint16 x, uint16 y, bool
entry.loop = loop;
entry.enabled = true;
+ // Enable dither if necessary
+ checkEnableDither(entry);
+
entry->start();
// Search for any deleted videos so we can take a formerly used slot
@@ -431,6 +443,10 @@ VideoHandle VideoManager::createVideoHandle(const Common::String &filename, uint
}
entry->loadStream(file);
+
+ // Enable dither if necessary
+ checkEnableDither(entry);
+
entry->setVolume(volume);
entry->start();
@@ -551,4 +567,22 @@ void VideoManager::pauseMovie(VideoHandle handle, bool pause) {
_videoStreams[handle]->pauseVideo(pause);
}
+void VideoManager::checkEnableDither(VideoEntry &entry) {
+ // If we're not dithering, bail out
+ if (!_enableDither)
+ return;
+
+ // Set the palette
+ byte palette[256 * 3];
+ g_system->getPaletteManager()->grabPalette(palette, 0, 256);
+ entry->setDitheringPalette(palette);
+
+ if (entry->getPixelFormat().bytesPerPixel != 1) {
+ if (entry.filename.empty())
+ error("Failed to set dither for video %d", entry.id);
+ else
+ error("Failed to set dither for video %s", entry.filename.c_str());
+ }
+}
+
} // End of namespace Mohawk
diff --git a/engines/mohawk/video.h b/engines/mohawk/video.h
index 43181e3e6c..deb09afe6b 100644
--- a/engines/mohawk/video.h
+++ b/engines/mohawk/video.h
@@ -124,6 +124,10 @@ private:
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(VideoEntry &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/detection_tables.h b/engines/mortevielle/detection_tables.h
index 0aa27b89eb..d244d15365 100644
--- a/engines/mortevielle/detection_tables.h
+++ b/engines/mortevielle/detection_tables.h
@@ -75,7 +75,7 @@ static const MortevielleGameDescription MortevielleGameDescriptions[] = {
// DOS English version doesn't exist. Technically, they are French or German versions,
// using English strings stored mort.dat
-
+
// English on top of French version
{
{
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 c3d1e4ae8b..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,13 +417,14 @@ public:
int _maff;
int _caff;
int _crep;
+ int _is; // ???
byte _destinationArray[7][25];
byte *_curPict;
byte *_curAnim;
byte *_rightFramePict;
-
+
PaletteManager _paletteManager;
GfxSurface _backgroundSurface;
Common::RandomSource _randomSource;
@@ -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 d5dec6a286..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);
}
/**
@@ -3097,7 +3154,7 @@ void MortevielleEngine::putObject() {
*/
void MortevielleEngine::addObjectToInventory(int objectId) {
int i;
-
+
for (i = 1; (i <= 5) && (_coreVar._inventory[i] != 0); i++)
;
@@ -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/console.cpp b/engines/neverhood/console.cpp
index 91ab3e767a..7ee6b30311 100644
--- a/engines/neverhood/console.cpp
+++ b/engines/neverhood/console.cpp
@@ -55,7 +55,7 @@ bool Console::Cmd_Scene(int argc, const char **argv) {
const char *sceneTypes[] = { "normal", "smacker", "navigation" };
- debugPrintf("Current module: %d, previous module: %d, scene %d (%s scene)\n", currentModule, previousModule, scenenNum, sceneTypes[sceneType]);
+ debugPrintf("Current module: %d, previous module: %d, scene %d (%s scene)\n", currentModule, previousModule, scenenNum, sceneTypes[sceneType]);
if (sceneType == kSceneTypeNormal) {
Scene *scene = (Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
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/neverhood/modules/module2400.cpp b/engines/neverhood/modules/module2400.cpp
index 3acb952db9..4bfc10abbf 100644
--- a/engines/neverhood/modules/module2400.cpp
+++ b/engines/neverhood/modules/module2400.cpp
@@ -168,11 +168,6 @@ static const uint32 kScene2401FileHashes2[] = {
0xD0910068, 0xD09100A8, 0
};
-static const uint32 kScene2401FileHashes3[] = {
- 0xD0910020, 0xD0910038, 0xD0910008,
- 0xD0910068, 0xD09100A8, 0
-};
-
static const NRect kScene2401Rects[] = {
{ 369, 331, 394, 389 },
{ 395, 331, 419, 389 },
@@ -264,11 +259,11 @@ void Scene2401::update() {
} else if (_pipeStatus >= 5) {
_ssWaterPipes[_pipeStatus]->setVisible(true);
_countdown1 = 8;
- playPipeSound(kScene2401FileHashes3[getSubVar(VA_CURR_WATER_PIPES_LEVEL, _pipeStatus - 5)]);
+ playPipeSound(kScene2401FileHashes2[getSubVar(VA_CURR_WATER_PIPES_LEVEL, _pipeStatus - 5)]);
} else {
_ssWaterPipes[_pipeStatus]->setVisible(true);
_countdown1 = _pipeStatus == 4 ? 16 : 8;
- playPipeSound(kScene2401FileHashes3[getSubVar(VA_GOOD_WATER_PIPES_LEVEL, _pipeStatus)]);
+ playPipeSound(kScene2401FileHashes2[getSubVar(VA_GOOD_WATER_PIPES_LEVEL, _pipeStatus)]);
}
_pipeStatus++;
}
diff --git a/engines/neverhood/modules/module2700_sprites.cpp b/engines/neverhood/modules/module2700_sprites.cpp
index e17cddc834..079e0b7afe 100644
--- a/engines/neverhood/modules/module2700_sprites.cpp
+++ b/engines/neverhood/modules/module2700_sprites.cpp
@@ -24,62 +24,6 @@
namespace Neverhood {
-static const NRect kScene2710ClipRect = { 0, 0, 626, 480 };
-
-static const uint32 kScene2710StaticSprites[] = {
- 0x0D2016C0,
- 0
-};
-
-static const NRect kScene2711ClipRect = { 0, 0, 521, 480 };
-
-static const uint32 kScene2711FileHashes1[] = {
- 0,
- 0x100801A1,
- 0x201081A0,
- 0x006800A4,
- 0x40390120,
- 0x000001B1,
- 0x001000A1,
- 0
-};
-
-static const uint32 kScene2711FileHashes2[] = {
- 0,
- 0x40403308,
- 0x71403168,
- 0x80423928,
- 0x224131A8,
- 0x50401328,
- 0x70423328,
- 0
-};
-
-static const uint32 kScene2711FileHashes3[] = {
- 0,
- 0x1088A021,
- 0x108120E5,
- 0x18A02321,
- 0x148221A9,
- 0x10082061,
- 0x188820E1,
- 0
-};
-
-static const NRect kScene2724ClipRect = { 0, 141, 640, 480 };
-
-static const uint32 kScene2724StaticSprites[] = {
- 0xC20D00A5,
- 0
-};
-
-static const NRect kScene2725ClipRect = { 0, 0, 640, 413 };
-
-static const uint32 kScene2725StaticSprites[] = {
- 0xC20E00A5,
- 0
-};
-
static const NPoint kCarShadowOffsets[] = {
{-63, 3}, {-48, 40}, {-33, 58},
{ 0, 65}, { 40, 53}, { 56, 27},
diff --git a/engines/neverhood/modules/module2800.cpp b/engines/neverhood/modules/module2800.cpp
index a59c3f8156..ab22390c7d 100644
--- a/engines/neverhood/modules/module2800.cpp
+++ b/engines/neverhood/modules/module2800.cpp
@@ -1477,21 +1477,6 @@ static const uint32 kScene2808FileHashes2[] = {
0xB0196098
};
-static const uint32 kClass428FileHashes[] = {
- 0x140022CA,
- 0x4C30A602,
- 0xB1633402,
- 0x12982135,
- 0x0540B728,
- 0x002A81E3,
- 0x08982841,
- 0x10982841,
- 0x20982841,
- 0x40982841,
- 0x80982841,
- 0x40800711
-};
-
Scene2808::Scene2808(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _countdown(0), _testTubeSetNum(which), _leaveResult(0), _isFlowing(false) {
diff --git a/engines/neverhood/modules/module2800_sprites.cpp b/engines/neverhood/modules/module2800_sprites.cpp
index f9a58de92d..ad814d2b5b 100644
--- a/engines/neverhood/modules/module2800_sprites.cpp
+++ b/engines/neverhood/modules/module2800_sprites.cpp
@@ -574,16 +574,6 @@ uint32 AsScene2806Spew::handleMessage(int messageNum, const MessageParam &param,
return messageResult;
}
-static const uint32 kScene2808FileHashes1[] = {
- 0x90B0392,
- 0x90B0192
-};
-
-static const uint32 kScene2808FileHashes2[] = {
- 0xB0396098,
- 0xB0196098
-};
-
static const uint32 kClass428FileHashes[] = {
0x140022CA,
0x4C30A602,
diff --git a/engines/neverhood/modules/module3000.cpp b/engines/neverhood/modules/module3000.cpp
index d4809611ad..0f84dbd18d 100644
--- a/engines/neverhood/modules/module3000.cpp
+++ b/engines/neverhood/modules/module3000.cpp
@@ -666,18 +666,6 @@ static const uint32 kScene3010ButtonNameHashes[] = {
0x01180951
};
-static const uint32 kScene3010DeadBoltButtonFileHashes1[] = {
- 0x301024C2,
- 0x20280580,
- 0x30200452
-};
-
-static const uint32 kScene3010DeadBoltButtonFileHashes2[] = {
- 0x50C025A8,
- 0x1020A0A0,
- 0x5000A7E8
-};
-
Scene3010::Scene3010(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _countdown(0), _doorUnlocked(false), _checkUnlocked(false) {
diff --git a/engines/neverhood/modules/module3000_sprites.cpp b/engines/neverhood/modules/module3000_sprites.cpp
index 3f883eaa72..23a388efe4 100644
--- a/engines/neverhood/modules/module3000_sprites.cpp
+++ b/engines/neverhood/modules/module3000_sprites.cpp
@@ -46,42 +46,6 @@ enum {
kCTSCount = 14
};
-static const uint32 kScene3009CannonScopeVideos[] = {
- 0x1010000D,
- 0x340A0049,
- 0x340A0049,
- 0x0282081D,
- 0x0082080D,
- 0x0882080D,
- 0x0882080D,
- 0x0282081D,
- 0x004B000B,
- 0x014B000B,
- 0x044B000B,
- 0x0282081D,
- 0x0282081D,
- 0x0282081D,
- 0x340A0049
-};
-
-static const uint32 kScene3009CannonActionVideos[] = {
- 0x00000000,
- 0x8004001B, // 1 Fire cannon at wall, it breaks (lowered)
- 0x0004001A, // 2 Fire cannon at wall, nothing happens (lowered)
- 0x1048404B, // 3 Fire cannon at emptyness (raised)
- 0x50200109, // 4 Fire cannon, robot missed (raised)
- 0x12032109, // 5 Fire cannon, robot hit (raised)
- 0x10201109, // 6 Fire cannon, no robot (raised)
- 0x000A2030, // 7 Raise the cannon
- 0x000A0028, // 8
- 0x000A0028, // 9
- 0x000A0028, // 10
- 0x040A1069, // 11
- 0x040A1069, // 12
- 0x040A1069, // 13
- 0x240A1101 // 14 Lower the cannon
-};
-
static const uint32 kSsScene3009SymbolEdgesFileHashes[] = {
0x618827A0,
0xB1A92322
diff --git a/engines/neverhood/sound.cpp b/engines/neverhood/sound.cpp
index d53243d4ba..b15bea4a64 100644
--- a/engines/neverhood/sound.cpp
+++ b/engines/neverhood/sound.cpp
@@ -560,7 +560,7 @@ int NeverhoodAudioStream::readBuffer(int16 *buffer, const int numSamples) {
} else {
while (samplesRead--) {
*buffer++ = READ_LE_UINT16(src);
- src += 2;
+ src += 2;
}
}
diff --git a/engines/pegasus/input.cpp b/engines/pegasus/input.cpp
index e1b7e25cd5..73c319bd8b 100644
--- a/engines/pegasus/input.cpp
+++ b/engines/pegasus/input.cpp
@@ -57,7 +57,7 @@ InputDeviceManager::InputDeviceManager() {
_keyMap[Common::KEYCODE_p] = false;
_keyMap[Common::KEYCODE_TILDE] = false;
_keyMap[Common::KEYCODE_BACKQUOTE] = false;
- _keyMap[Common::KEYCODE_KP7] = false;
+ _keyMap[Common::KEYCODE_KP7] = false;
_keyMap[Common::KEYCODE_BACKSPACE] = false;
_keyMap[Common::KEYCODE_KP_MULTIPLY] = false;
_keyMap[Common::KEYCODE_KP9] = false;
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/pegasus.cpp b/engines/pegasus/pegasus.cpp
index 0c8ea2e4ee..4262ad4c12 100644
--- a/engines/pegasus/pegasus.cpp
+++ b/engines/pegasus/pegasus.cpp
@@ -979,7 +979,7 @@ void PegasusEngine::doGameMenuCommand(const GameMenuCommand command) {
resetIntroTimer();
break;
case kMenuCmdPauseSave:
- result = showSaveDialog();
+ result = showSaveDialog();
if (result.getCode() != Common::kUserCanceled) {
if (result.getCode() != Common::kNoError)
diff --git a/engines/prince/animation.cpp b/engines/prince/animation.cpp
index b4bde27f69..aabdd7a623 100644
--- a/engines/prince/animation.cpp
+++ b/engines/prince/animation.cpp
@@ -132,7 +132,7 @@ int16 Animation::getPhaseOffsetX(int phaseIndex) const {
if (phaseIndex < _phaseCount) {
return _phaseList[phaseIndex]._phaseOffsetX;
} else {
- error("getPhaseOffsetX() phaseIndex: %d, phaseCount: %d", phaseIndex, _phaseCount);
+ error("getPhaseOffsetX() phaseIndex: %d, phaseCount: %d", phaseIndex, _phaseCount);
}
}
@@ -140,7 +140,7 @@ int16 Animation::getPhaseOffsetY(int phaseIndex) const {
if (phaseIndex < _phaseCount) {
return _phaseList[phaseIndex]._phaseOffsetY;
} else {
- error("getPhaseOffsetY() phaseIndex: %d, phaseCount: %d", phaseIndex, _phaseCount);
+ error("getPhaseOffsetY() phaseIndex: %d, phaseCount: %d", phaseIndex, _phaseCount);
}
}
@@ -148,7 +148,7 @@ int16 Animation::getPhaseFrameIndex(int phaseIndex) const {
if (phaseIndex < _phaseCount) {
return _phaseList[phaseIndex]._phaseToFrameIndex;
} else {
- error("getPhaseFrameIndex() phaseIndex: %d, phaseCount: %d", phaseIndex, _phaseCount);
+ error("getPhaseFrameIndex() phaseIndex: %d, phaseCount: %d", phaseIndex, _phaseCount);
}
}
diff --git a/engines/prince/animation.h b/engines/prince/animation.h
index 733acb399c..3471ffa158 100644
--- a/engines/prince/animation.h
+++ b/engines/prince/animation.h
@@ -35,7 +35,7 @@ public:
Animation();
~Animation();
bool loadStream(Common::SeekableReadStream &stream);
-
+
int16 getLoopCount() const;
int32 getPhaseCount() const;
int32 getFrameCount() const;
diff --git a/engines/prince/archive.cpp b/engines/prince/archive.cpp
index ae6a2b7546..a01f824df8 100644
--- a/engines/prince/archive.cpp
+++ b/engines/prince/archive.cpp
@@ -64,7 +64,7 @@ bool PtcArchive::open(const Common::String &filename) {
byte *fileTableEnd = fileTable + fileTableSize;
_stream->read(fileTable, fileTableSize);
decrypt(fileTable, fileTableSize);
-
+
for (byte *fileItem = fileTable; fileItem < fileTableEnd; fileItem += 32) {
FileEntry item;
Common::String name = (const char*)fileItem;
@@ -79,6 +79,28 @@ bool PtcArchive::open(const Common::String &filename) {
return true;
}
+bool PtcArchive::openTranslation(const Common::String &filename) {
+ _stream = SearchMan.createReadStreamForMember(filename);
+ if (!_stream)
+ return false;
+
+ Common::Array<Common::String> translationNames;
+ Common::String translationFileName;
+ const int kTranslationFiles = 5;
+ for (int i = 0; i < kTranslationFiles; i++) {
+ translationFileName = _stream->readLine();
+ translationNames.push_back(translationFileName);
+ }
+ FileEntry item;
+ for (int i = 0; i < kTranslationFiles; i++) {
+ item._offset = _stream->readUint32LE();
+ item._size = _stream->readUint32LE();
+ _items[translationNames[i]] = item;
+ }
+
+ return true;
+}
+
void PtcArchive::close() {
delete _stream;
_stream = nullptr;
diff --git a/engines/prince/archive.h b/engines/prince/archive.h
index e211036ed6..a640b77911 100644
--- a/engines/prince/archive.h
+++ b/engines/prince/archive.h
@@ -35,6 +35,7 @@ public:
~PtcArchive();
bool open(const Common::String &filename);
+ bool openTranslation(const Common::String &filename);
void close();
bool isOpen() const { return _stream != 0; }
diff --git a/engines/prince/cursor.h b/engines/prince/cursor.h
index 9387f344dc..fb07d01729 100644
--- a/engines/prince/cursor.h
+++ b/engines/prince/cursor.h
@@ -30,7 +30,7 @@
namespace Prince {
class Cursor {
-public:
+public:
Cursor();
~Cursor();
diff --git a/engines/prince/detection.cpp b/engines/prince/detection.cpp
index 3f83009de8..3fe7993fdb 100644
--- a/engines/prince/detection.cpp
+++ b/engines/prince/detection.cpp
@@ -55,13 +55,15 @@ bool PrinceMetaEngine::hasFeature(MetaEngineFeature f) const {
(f == kSavesSupportMetaInfo) ||
(f == kSavesSupportThumbnail) ||
(f == kSavesSupportCreationDate) ||
- (f == kSupportsListSaves);
+ (f == kSupportsListSaves) ||
+ (f == kSupportsLoadingDuringStartup);
}
bool Prince::PrinceEngine::hasFeature(EngineFeature f) const {
return
(f == kSupportsLoadingDuringRuntime) ||
- (f == kSupportsSavingDuringRuntime);
+ (f == kSupportsSavingDuringRuntime) ||
+ (f == kSupportsRTL);
}
} // End of namespace Prince
diff --git a/engines/prince/detection.h b/engines/prince/detection.h
index 5cc0d32be4..7e5bdd6b7b 100644
--- a/engines/prince/detection.h
+++ b/engines/prince/detection.h
@@ -28,9 +28,15 @@
namespace Prince {
+enum PrinceGameType {
+ kPrinceDataUNK,
+ kPrinceDataDE,
+ kPrinceDataPL
+};
+
struct PrinceGameDescription {
ADGameDescription desc;
- int gameType;
+ PrinceGameType gameType;
};
static const PlainGameDescriptor princeGames[] = {
@@ -49,7 +55,7 @@ static const PrinceGameDescription gameDescriptions[] = {
ADGF_TESTING,
GUIO1(GUIO_NONE)
},
- 0
+ kPrinceDataDE
},
{
{
@@ -61,9 +67,33 @@ static const PrinceGameDescription gameDescriptions[] = {
ADGF_TESTING,
GUIO1(GUIO_NONE)
},
- 1
+ kPrinceDataPL
+ },
+ {
+ {
+ "prince",
+ "The Prince and the Coward",
+ AD_ENTRY1s("databank.ptc", "5fa03833177331214ec1354761b1d2ee", 3565031),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_TESTING,
+ GUIO1(GUIO_NONE)
+ },
+ kPrinceDataDE
+ },
+ {
+ {
+ "prince",
+ "The Prince and the Coward",
+ AD_ENTRY1s("databank.ptc", "48ec9806bda9d152acbea8ce31c93c49", 3435298),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_TESTING,
+ GUIO1(GUIO_NONE)
+ },
+ kPrinceDataPL
},
- { AD_TABLE_END_MARKER, 0 }
+ { AD_TABLE_END_MARKER, kPrinceDataUNK }
};
const static char *directoryGlobs[] = {
diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp
index ad6a2ff85c..f556d81eab 100644
--- a/engines/prince/graphics.cpp
+++ b/engines/prince/graphics.cpp
@@ -194,7 +194,7 @@ void GraphicsMan::drawTransparentDrawNode(Graphics::Surface *screen, DrawNode *d
/**
* Similar to drawTransparentDrawNode but with additional anti-aliasing code for sprite drawing.
* Edge smoothing is based on 256 x 256 table of colors transition.
- * Algorithm is checking if currently drawing pixel is located next to the edge of sprite and if it makes jagged line.
+ * Algorithm is checking if currently drawing pixel is located next to the edge of sprite and if it makes jagged line.
* If it does then this pixel is set with color from transition table calculated of original background pixel color
* and sprite's edge pixel color.
*/
diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h
index b6f002b7da..1a1737f976 100644
--- a/engines/prince/graphics.h
+++ b/engines/prince/graphics.h
@@ -35,7 +35,7 @@ class GraphicsMan {
public:
GraphicsMan(PrinceEngine *vm);
~GraphicsMan();
-
+
void update(Graphics::Surface *screen);
void change();
diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp
index 06fba25ba9..b873e83360 100644
--- a/engines/prince/hero.cpp
+++ b/engines/prince/hero.cpp
@@ -54,7 +54,7 @@ Hero::~Hero() {
bool Hero::loadAnimSet(uint32 animSetNr) {
_animSetNr = animSetNr;
- if (animSetNr > sizeof(heroSetTable)) {
+ if (animSetNr >= ARRAYSIZE(heroSetTable)) {
return false;
}
@@ -129,7 +129,7 @@ int Hero::getScaledValue(int size) {
Graphics::Surface *Hero::zoomSprite(Graphics::Surface *heroFrame) {
Graphics::Surface *zoomedFrame = new Graphics::Surface();
zoomedFrame->create(_scaledFrameXSize, _scaledFrameYSize, Graphics::PixelFormat::createFormatCLUT8());
-
+
int sprZoomX;
int sprZoomY = _vm->_scaleValue;
uint xSource = 0;
diff --git a/engines/prince/hero.h b/engines/prince/hero.h
index d5f7d8cc7a..703ef0650d 100644
--- a/engines/prince/hero.h
+++ b/engines/prince/hero.h
@@ -129,7 +129,7 @@ public:
void drawHeroShadow(Graphics::Surface *heroFrame);
void freeOldMove();
void freeHeroAnim();
-
+
uint16 _number;
uint16 _visible;
int16 _state;
@@ -170,7 +170,7 @@ public:
int _color; // subtitles color
uint32 _animSetNr; // number of animation set
Common::Array<Animation *> _moveSet; // MoveAnims MoveSet
-
+
uint32 _moveDelay;
uint32 _shadMinus;
diff --git a/engines/prince/mhwanh.cpp b/engines/prince/mhwanh.cpp
index ef94ef71f9..608ccc23d7 100644
--- a/engines/prince/mhwanh.cpp
+++ b/engines/prince/mhwanh.cpp
@@ -38,7 +38,7 @@ MhwanhDecoder::~MhwanhDecoder() {
void MhwanhDecoder::destroy() {
if (_surface != nullptr) {
_surface->free();
- delete _surface;
+ delete _surface;
_surface = nullptr;
}
if (_palette != nullptr) {
@@ -57,7 +57,7 @@ bool MhwanhDecoder::loadStream(Common::SeekableReadStream &stream) {
_palette[i * 3] = stream.readByte();
_palette[i * 3 + 1] = stream.readByte();
_palette[i * 3 + 2] = stream.readByte();
- }
+ }
_surface = new Graphics::Surface();
_surface->create(640, 480, Graphics::PixelFormat::createFormatCLUT8());
diff --git a/engines/prince/mob.h b/engines/prince/mob.h
index cc60e36f9b..0ea610dd8f 100644
--- a/engines/prince/mob.h
+++ b/engines/prince/mob.h
@@ -50,7 +50,7 @@ public:
void setData(AttrId dataId, uint16 value);
uint16 getData(AttrId dataId);
- bool _visible;
+ bool _visible;
uint16 _type;
uint16 _mask;
Common::Rect _rect;
diff --git a/engines/prince/object.cpp b/engines/prince/object.cpp
index a9a96455b1..2dc5da68e7 100644
--- a/engines/prince/object.cpp
+++ b/engines/prince/object.cpp
@@ -79,7 +79,7 @@ bool Object::loadFromStream(Common::SeekableReadStream &stream) {
_flags = stream.readUint16LE();
_z = stream.readUint16LE();
-
+
stream.seek(pos + 16);
return true;
diff --git a/engines/prince/object.h b/engines/prince/object.h
index 68edd061a0..ff22a05805 100644
--- a/engines/prince/object.h
+++ b/engines/prince/object.h
@@ -62,7 +62,7 @@ public:
private:
void loadSurface(Common::SeekableReadStream &stream);
- Graphics::Surface *_surface;
+ Graphics::Surface *_surface;
};
} // End of namespace Prince
diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp
index 29c434e9c9..55f12a6560 100644
--- a/engines/prince/prince.cpp
+++ b/engines/prince/prince.cpp
@@ -61,6 +61,7 @@
#include "prince/animation.h"
#include "prince/option_text.h"
#include "prince/curve_values.h"
+#include "prince/detection.h"
namespace Prince {
@@ -95,7 +96,8 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc)
_tracePointFirstPointFlag(false), _coordsBuf2(nullptr), _coords2(nullptr), _coordsBuf3(nullptr), _coords3(nullptr),
_shanLen(0), _directionTable(nullptr), _currentMidi(0), _lightX(0), _lightY(0), _curveData(nullptr), _curvPos(0),
_creditsData(nullptr), _creditsDataSize(0), _currentTime(0), _zoomBitmap(nullptr), _shadowBitmap(nullptr), _transTable(nullptr),
- _flcFrameSurface(nullptr), _shadScaleValue(0), _shadLineLen(0), _scaleValue(0), _dialogImage(nullptr) {
+ _flcFrameSurface(nullptr), _shadScaleValue(0), _shadLineLen(0), _scaleValue(0), _dialogImage(nullptr), _mobTranslationData(nullptr),
+ _mobTranslationSize(0) {
// Debug/console setup
DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel");
@@ -204,6 +206,8 @@ PrinceEngine::~PrinceEngine() {
_dialogImage->free();
delete _dialogImage;
}
+
+ free(_mobTranslationData);
}
GUI::Debugger *PrinceEngine::getDebugger() {
@@ -213,11 +217,11 @@ GUI::Debugger *PrinceEngine::getDebugger() {
void PrinceEngine::init() {
const Common::FSNode gameDataDir(ConfMan.get("path"));
-
+
debugEngine("Adding all path: %s", gameDataDir.getPath().c_str());
PtcArchive *all = new PtcArchive();
- if (!all->open("all/databank.ptc"))
+ if (!all->open("all/databank.ptc"))
error("Can't open all/databank.ptc");
PtcArchive *voices = new PtcArchive();
@@ -228,11 +232,20 @@ void PrinceEngine::init() {
if (!sound->open("sound/databank.ptc"))
error("Can't open sound/databank.ptc");
+ PtcArchive *translation = new PtcArchive();
+ if (getLanguage() != Common::PL_POL && getLanguage() != Common::DE_DEU) {
+ if (!translation->openTranslation("all/prince_translation.dat"))
+ error("Can't open prince_translation.dat");
+ }
+
SearchMan.addSubDirectoryMatching(gameDataDir, "all");
SearchMan.add("all", all);
SearchMan.add("voices", voices);
SearchMan.add("sound", sound);
+ if (getLanguage() != Common::PL_POL && getLanguage() != Common::DE_DEU) {
+ SearchMan.add("translation", translation);
+ }
_graph = new GraphicsMan(this);
@@ -260,15 +273,24 @@ void PrinceEngine::init() {
_debugger = new Debugger(this, _flags);
_variaTxt = new VariaTxt();
- Resource::loadResource(_variaTxt, "variatxt.dat", true);
-
+ if (getLanguage() == Common::PL_POL || getLanguage() == Common::DE_DEU) {
+ Resource::loadResource(_variaTxt, "variatxt.dat", true);
+ } else {
+ Resource::loadResource(_variaTxt, "variatxt_translate.dat", true);
+ }
+
_cursor1 = new Cursor();
Resource::loadResource(_cursor1, "mouse1.cur", true);
_cursor3 = new Cursor();
Resource::loadResource(_cursor3, "mouse2.cur", true);
- Common::SeekableReadStream *talkTxtStream = SearchMan.createReadStreamForMember("talktxt.dat");
+ Common::SeekableReadStream *talkTxtStream;
+ if (getLanguage() == Common::PL_POL || getLanguage() == Common::DE_DEU) {
+ talkTxtStream = SearchMan.createReadStreamForMember("talktxt.dat");
+ } else {
+ talkTxtStream = SearchMan.createReadStreamForMember("talktxt_translate.dat");
+ }
if (!talkTxtStream) {
error("Can't load talkTxtStream");
return;
@@ -279,7 +301,12 @@ void PrinceEngine::init() {
delete talkTxtStream;
- Common::SeekableReadStream *invTxtStream = SearchMan.createReadStreamForMember("invtxt.dat");
+ Common::SeekableReadStream *invTxtStream;
+ if (getLanguage() == Common::PL_POL || getLanguage() == Common::DE_DEU) {
+ invTxtStream = SearchMan.createReadStreamForMember("invtxt.dat");
+ } else {
+ invTxtStream = SearchMan.createReadStreamForMember("invtxt_translate.dat");
+ }
if (!invTxtStream) {
error("Can't load invTxtStream");
return;
@@ -354,7 +381,12 @@ void PrinceEngine::init() {
_shadowLine = (byte *)malloc(kShadowLineArraySize);
- Common::SeekableReadStream *creditsDataStream = SearchMan.createReadStreamForMember("credits.dat");
+ Common::SeekableReadStream *creditsDataStream;
+ if (getLanguage() == Common::PL_POL || getLanguage() == Common::DE_DEU) {
+ creditsDataStream = SearchMan.createReadStreamForMember("credits.dat");
+ } else {
+ creditsDataStream = SearchMan.createReadStreamForMember("credits_translate.dat");
+ }
if (!creditsDataStream) {
error("Can't load creditsDataStream");
return;
@@ -363,11 +395,14 @@ void PrinceEngine::init() {
_creditsData = (byte *)malloc(_creditsDataSize);
creditsDataStream->read(_creditsData, _creditsDataSize);
delete creditsDataStream;
+
+ if (getLanguage() != Common::PL_POL && getLanguage() != Common::DE_DEU) {
+ loadMobTranslationTexts();
+ }
}
void PrinceEngine::showLogo() {
MhwanhDecoder logo;
- _system->delayMillis(1000 / kFPS * 20);
if (Resource::loadResource(&logo, "logo.raw", true)) {
loadSample(0, "LOGO.WAV");
playSample(0, 0);
@@ -375,21 +410,58 @@ void PrinceEngine::showLogo() {
_graph->change();
_graph->update(_graph->_frontScreen);
setPalette(logo.getPalette());
- _system->delayMillis(1000 / kFPS * 70);
+
+ uint32 logoStart = _system->getMillis();
+ while (_system->getMillis() < logoStart + 5000) {
+ Common::Event event;
+ Common::EventManager *eventMan = _system->getEventManager();
+ while (eventMan->pollEvent(event)) {
+ switch (event.type) {
+ case Common::EVENT_KEYDOWN:
+ if (event.kbd.keycode == Common::KEYCODE_ESCAPE) {
+ stopSample(0);
+ return;
+ }
+ break;
+ case Common::EVENT_LBUTTONDOWN:
+ stopSample(0);
+ return;
+ default:
+ break;
+ }
+ }
+
+ if (shouldQuit()) {
+ return;
+ }
+ }
}
}
Common::Error PrinceEngine::run() {
-
+ syncSoundSettings();
+ int startGameSlot = ConfMan.hasKey("save_slot") ? ConfMan.getInt("save_slot") : -1;
init();
-
- showLogo();
-
+ if (startGameSlot == -1) {
+ showLogo();
+ } else {
+ loadLocation(59); // load intro location - easiest way to set everything up
+ loadGame(startGameSlot);
+ }
mainLoop();
-
return Common::kNoError;
}
+void PrinceEngine::pauseEngineIntern(bool pause) {
+ Engine::pauseEngineIntern(pause);
+ if (pause) {
+ _midiPlayer->pause();
+ }
+ else {
+ _midiPlayer->resume();
+ }
+}
+
bool AnimListItem::loadFromStream(Common::SeekableReadStream &stream) {
int32 pos = stream.pos();
@@ -469,13 +541,17 @@ bool PrinceEngine::loadLocation(uint16 locationNr) {
loadMobPriority("mobpri");
_mobList.clear();
- if (getLanguage() == Common::DE_DEU) {
+ if (getGameType() == kPrinceDataDE) {
const Common::String mobLstName = Common::String::format("mob%02d.lst", _locationNr);
debug("name: %s", mobLstName.c_str());
Resource::loadResource(_mobList, mobLstName.c_str(), false);
- } else {
+ } else if (getGameType() == kPrinceDataPL) {
Resource::loadResource(_mobList, "mob.lst", false);
}
+ if (getLanguage() != Common::PL_POL && getLanguage() != Common::DE_DEU) {
+ // update Mob texts for translated version
+ setMobTranslationTexts();
+ }
_animList.clear();
Resource::loadResource(_animList, "anim.lst", false);
@@ -678,7 +754,11 @@ void PrinceEngine::playSample(uint16 sampleId, uint16 loopType) {
return;
}
_audioStream[sampleId]->rewind();
- _mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle[sampleId], _audioStream[sampleId], sampleId, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
+ if (sampleId < 28) {
+ _mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle[sampleId], _audioStream[sampleId], sampleId, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
+ } else {
+ _mixer->playStream(Audio::Mixer::kSpeechSoundType, &_soundHandle[sampleId], _audioStream[sampleId], sampleId, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
+ }
}
}
@@ -705,7 +785,7 @@ void PrinceEngine::freeAllSamples() {
}
bool PrinceEngine::loadSample(uint32 sampleSlot, const Common::String &streamName) {
- // FIXME: This is just a workaround streamName is a path
+ // FIXME: This is just a workaround streamName is a path
// SOUND\\SCIERKA1.WAV for now only last path component is used
Common::String normalizedPath = lastPathComponent(streamName, '\\');
@@ -730,8 +810,8 @@ bool PrinceEngine::loadSample(uint32 sampleSlot, const Common::String &streamNam
bool PrinceEngine::loadVoice(uint32 slot, uint32 sampleSlot, const Common::String &streamName) {
debugEngine("Loading wav %s slot %d", streamName.c_str(), slot);
- if (slot > kMaxTexts) {
- error("Text slot bigger than MAXTEXTS %d", kMaxTexts);
+ if (slot >= kMaxTexts) {
+ error("Text slot bigger than MAXTEXTS %d", kMaxTexts - 1);
return false;
}
@@ -756,7 +836,7 @@ bool PrinceEngine::loadVoice(uint32 slot, uint32 sampleSlot, const Common::Strin
}
id = sampleStream->readUint32LE();
- debugEngine("SetVoice slot %d time %04x", slot, id);
+ debugEngine("SetVoice slot %d time %04x", slot, id);
id <<= 3;
id /= 22050;
id += 2;
@@ -768,7 +848,7 @@ bool PrinceEngine::loadVoice(uint32 slot, uint32 sampleSlot, const Common::Strin
_secondHero->_talkTime = id;
}
- debugEngine("SetVoice slot %d time %04x", slot, id);
+ debugEngine("SetVoice slot %d time %04x", slot, id);
sampleStream->seek(SEEK_SET);
_audioStream[sampleSlot] = Audio::makeWAVStream(sampleStream, DisposeAfterUse::NO);
delete sampleStream;
@@ -947,6 +1027,45 @@ bool PrinceEngine::loadMobPriority(const char *resourceName) {
return true;
}
+void PrinceEngine::loadMobTranslationTexts() {
+ Common::SeekableReadStream *mobTranslationStream = SearchMan.createReadStreamForMember("mob_translate.dat");
+ if (!mobTranslationStream) {
+ error("Can't load mob_translate.dat");
+ }
+ _mobTranslationSize = mobTranslationStream->size();
+ _mobTranslationData = (byte *)malloc(_mobTranslationSize);
+ mobTranslationStream->read(_mobTranslationData, _mobTranslationSize);
+ delete mobTranslationStream;
+}
+
+void PrinceEngine::setMobTranslationTexts() {
+ int locationOffset = READ_UINT16(_mobTranslationData + (_locationNr - 1) * 2);
+ if (locationOffset) {
+ byte *locationText = _mobTranslationData + locationOffset;
+ for (uint i = 0; i < _mobList.size(); i++) {
+ byte c;
+ locationText++;
+ _mobList[i]._name.clear();
+ while ((c = *locationText)) {
+ _mobList[i]._name += c;
+ locationText++;
+ }
+ locationText++;
+ _mobList[i]._examText.clear();
+ c = *locationText;
+ locationText++;
+ if (c) {
+ _mobList[i]._examText += c;
+ do {
+ c = *locationText;
+ _mobList[i]._examText += c;
+ locationText++;
+ } while (c != 255);
+ }
+ }
+ }
+}
+
void PrinceEngine::keyHandler(Common::Event event) {
uint16 nChar = event.kbd.keycode;
switch (nChar) {
@@ -1506,7 +1625,7 @@ void PrinceEngine::setBackAnim(Anim &backAnim) {
}
void PrinceEngine::showBackAnims() {
- for (uint i = 0; i < kMaxBackAnims; i++) {
+ for (int i = 0; i < kMaxBackAnims; i++) {
BAS &seq = _backAnimList[i]._seq;
int activeSubAnim = seq._currRelative;
if (!_backAnimList[i].backAnims.empty()) {
@@ -1893,7 +2012,7 @@ void PrinceEngine::blackPalette() {
free(blackPalette1);
return;
}
- pause();
+ pausePrinceEngine();
}
free(paletteBackup);
free(blackPalette1);
@@ -1901,41 +2020,34 @@ void PrinceEngine::blackPalette() {
void PrinceEngine::setPalette(const byte *palette) {
if (palette != nullptr) {
- byte *blackPalette = (byte *)malloc(256 * 3);
+ byte *blackPalette_ = (byte *)malloc(256 * 3);
int fadeStep = 0;
for (int i = 0; i <= kFadeStep; i++) {
for (int j = 0; j < 256; j++) {
- blackPalette[3 * j] = palette[3 * j] * fadeStep / 4;
- blackPalette[3 * j + 1] = palette[3 * j + 1] * fadeStep / 4;
- blackPalette[3 * j + 2] = palette[3 * j + 2] * fadeStep / 4;
+ blackPalette_[3 * j] = palette[3 * j] * fadeStep / 4;
+ blackPalette_[3 * j + 1] = palette[3 * j + 1] * fadeStep / 4;
+ blackPalette_[3 * j + 2] = palette[3 * j + 2] * fadeStep / 4;
}
fadeStep++;
- _graph->setPalette(blackPalette);
+ _graph->setPalette(blackPalette_);
_system->updateScreen();
Common::Event event;
Common::EventManager *eventMan = _system->getEventManager();
eventMan->pollEvent(event);
if (shouldQuit()) {
_graph->setPalette(palette);
- free(blackPalette);
+ free(blackPalette_);
return;
}
- pause();
+ pausePrinceEngine();
}
_graph->setPalette(palette);
- free(blackPalette);
+ free(blackPalette_);
}
}
-void PrinceEngine::pause() {
- int delay = 1000 / kFPS - int32(_system->getMillis() - _currentTime);
- delay = delay < 0 ? 0 : delay;
- _system->delayMillis(delay);
- _currentTime = _system->getMillis();
-}
-
-void PrinceEngine::pause2() {
- int delay = 1000 / (kFPS * 2) - int32(_system->getMillis() - _currentTime);
+void PrinceEngine::pausePrinceEngine(int fps) {
+ int delay = 1000 / fps - int32(_system->getMillis() - _currentTime);
delay = delay < 0 ? 0 : delay;
_system->delayMillis(delay);
_currentTime = _system->getMillis();
@@ -2048,7 +2160,7 @@ void PrinceEngine::addInvObj() {
if (shouldQuit()) {
return;
}
- pause();
+ pausePrinceEngine();
}
while (_mst_shadow2 > 256) {
rememberScreenInv();
@@ -2062,7 +2174,7 @@ void PrinceEngine::addInvObj() {
if (shouldQuit()) {
return;
}
- pause();
+ pausePrinceEngine();
}
} else {
//CURSEBLINK:
@@ -2080,7 +2192,7 @@ void PrinceEngine::addInvObj() {
if (shouldQuit()) {
return;
}
- pause();
+ pausePrinceEngine();
}
while (_mst_shadow2 > 256) {
rememberScreenInv();
@@ -2094,7 +2206,7 @@ void PrinceEngine::addInvObj() {
if (shouldQuit()) {
return;
}
- pause();
+ pausePrinceEngine();
}
}
}
@@ -2110,7 +2222,7 @@ void PrinceEngine::addInvObj() {
if (shouldQuit()) {
return;
}
- pause();
+ pausePrinceEngine();
}
}
@@ -2305,6 +2417,7 @@ void PrinceEngine::moveRunHero(int heroId, int x, int y, int dir, bool runHeroFl
}
void PrinceEngine::leftMouseButton() {
+ _flags->setFlagValue(Flags::ESCAPED2, 1); // skip intro animation
_flags->setFlagValue(Flags::LMOUSE, 1);
if (_flags->getFlagValue(Flags::POWERENABLED)) {
_flags->setFlagValue(Flags::MBFLAG, 1);
@@ -2738,7 +2851,7 @@ void PrinceEngine::displayInventory() {
getDebugger()->onFrame();
_graph->update(_graph->_screenForInventory);
- pause();
+ pausePrinceEngine();
}
if (_currentPointerNumber == 2) {
@@ -2863,7 +2976,7 @@ void PrinceEngine::dialogRun() {
getDebugger()->onFrame();
_graph->update(_graph->_frontScreen);
- pause();
+ pausePrinceEngine();
}
_dialogImage->free();
delete _dialogImage;
@@ -3122,7 +3235,7 @@ void PrinceEngine::scrollCredits() {
}
_graph->change();
_graph->update(_graph->_frontScreen);
- pause2();
+ pausePrinceEngine(kFPS * 2);
}
char letter2;
byte *scan2 = scrollAdress;
@@ -4106,7 +4219,7 @@ int PrinceEngine::checkRightUpDir() {
}
bool PrinceEngine::tracePath(int x1, int y1, int x2, int y2) {
- for (int i = 0; i < kPathBitmapLen; i++) {
+ for (uint i = 0; i < kPathBitmapLen; i++) {
_roomPathBitmapTemp[i] = 0;
}
if (x1 != x2 || y1 != y2) {
@@ -4321,7 +4434,7 @@ int PrinceEngine::scanDirectionsFindNext(byte *tempCoordsBuf, int xDiff, int yDi
tempCoordsBuf += 4;
if (tempCoordsBuf == _coords) {
- direction = tempX;
+ direction = tempX;
break;
}
@@ -4726,7 +4839,7 @@ void PrinceEngine::mainLoop() {
openInventoryCheck();
- pause();
+ pausePrinceEngine();
}
}
diff --git a/engines/prince/prince.h b/engines/prince/prince.h
index 0e5bf97dde..6dce044a41 100644
--- a/engines/prince/prince.h
+++ b/engines/prince/prince.h
@@ -242,7 +242,7 @@ struct DebugChannel {
enum Type {
kScript,
- kEngine
+ kEngine
};
};
@@ -256,6 +256,7 @@ public:
virtual ~PrinceEngine();
virtual bool hasFeature(EngineFeature f) const;
+ virtual void pauseEngineIntern(bool pause);
virtual bool canSaveGameStateCurrently();
virtual bool canLoadGameStateCurrently();
virtual Common::Error saveGameState(int slot, const Common::String &desc);
@@ -285,6 +286,9 @@ public:
uint32 _talkTxtSize;
byte *_talkTxt;
+ uint32 _mobTranslationSize;
+ byte *_mobTranslationData;
+
bool loadLocation(uint16 locationNr);
bool loadAnim(uint16 animNr, bool loop);
bool loadVoice(uint32 textSlot, uint32 sampleSlot, const Common::String &name);
@@ -294,6 +298,9 @@ public:
bool loadTrans(byte *transTable, const char *resourceName);
bool loadMobPriority(const char *resourceName);
+ void loadMobTranslationTexts();
+ void setMobTranslationTexts();
+
bool loadMusic(int musNumber);
void stopMusic();
@@ -365,7 +372,7 @@ public:
static const int16 kZoomBitmapHeight = kMaxPicHeight / kZoomStep;
static const int16 kNormalWidth = 640;
static const int16 kNormalHeight = 480;
- static const int32 kTransTableSize = 256 * 256;
+ static const uint32 kTransTableSize = 256 * 256;
static const int kMaxNormAnims = 64;
static const int kMaxBackAnims = 64;
@@ -401,7 +408,7 @@ public:
int _currentPointerNumber;
static const int16 kMaxInv = 90; // max amount of inventory items in whole game
- static const int16 kMaxItems = 30; // size of inventory
+ static const uint16 kMaxItems = 30; // size of inventory
uint32 _invTxtSize;
byte *_invTxt;
@@ -530,7 +537,7 @@ public:
// Pathfinding
static const int16 kPathGridStep = 2;
- static const int32 kPathBitmapLen = (kMaxPicHeight / kPathGridStep * kMaxPicWidth / kPathGridStep) / 8;
+ static const uint32 kPathBitmapLen = (kMaxPicHeight / kPathGridStep * kMaxPicWidth / kPathGridStep) / 8;
static const int32 kTracePts = 8000;
static const int32 kPBW = kMaxPicWidth / 16; // PathBitmapWidth
static const int kMinDistance = 2500;
@@ -633,8 +640,7 @@ private:
static bool compareDrawNodes(DrawNode d1, DrawNode d2);
void runDrawNodes();
void makeShadowTable(int brightness);
- void pause();
- void pause2();
+ void pausePrinceEngine(int fps = kFPS);
uint32 getTextWidth(const char *s);
void debugEngine(const char *s, ...);
@@ -658,7 +664,7 @@ private:
Common::Array<Mob> _invMobList;
bool _flicLooped;
-
+
void mainLoop();
};
diff --git a/engines/prince/pscr.h b/engines/prince/pscr.h
index d59fa37d81..fdcdb524a9 100644
--- a/engines/prince/pscr.h
+++ b/engines/prince/pscr.h
@@ -40,7 +40,7 @@ public:
Graphics::Surface *getSurface() const { return _surface; }
private:
void loadSurface(Common::SeekableReadStream &stream);
- Graphics::Surface *_surface;
+ Graphics::Surface *_surface;
};
} // End of namespace Prince
diff --git a/engines/prince/resource.h b/engines/prince/resource.h
index b1fbd9c4f0..f42eb87842 100644
--- a/engines/prince/resource.h
+++ b/engines/prince/resource.h
@@ -41,13 +41,13 @@ namespace Resource {
bool loadResource(T *resource, const char *resourceName, bool required) {
Common::ScopedPtr<Common::SeekableReadStream> stream(SearchMan.createReadStreamForMember(resourceName));
if (!stream) {
- if (required)
+ if (required)
error("Can't load %s", resourceName);
return false;
}
return loadFromStream(*resource, *stream);
- }
+ }
template <typename T>
bool loadResource(Common::Array<T> &array, Common::SeekableReadStream &stream, bool required = true) {
@@ -82,7 +82,7 @@ namespace Resource {
}
// FIXME: This is stupid. Maybe loadFromStream should be helper method that returns initiailzed object
- while (true) {
+ while (true) {
T* t = new T();
if (!t->loadFromStream(*stream)) {
delete t;
diff --git a/engines/prince/saveload.cpp b/engines/prince/saveload.cpp
index 39a4002b40..46e598be70 100644
--- a/engines/prince/saveload.cpp
+++ b/engines/prince/saveload.cpp
@@ -172,14 +172,34 @@ void PrinceMetaEngine::removeSaveState(const char *target, int slot) const {
g_system->getSavefileManager()->removeSavefile(fileName);
}
-// TODO
bool PrinceEngine::canSaveGameStateCurrently() {
- return true;
+ if (_mouseFlag && _mouseFlag != 3) {
+ if (_mainHero->_visible) {
+ // 29 - Basement
+ if (_locationNr != 29) {
+ // No dialog box and not in inventory
+ if (!_dialogFlag && !_showInventoryFlag) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
}
-// TODO
bool PrinceEngine::canLoadGameStateCurrently() {
- return true;
+ if (_mouseFlag && _mouseFlag != 3) {
+ if (_mainHero->_visible) {
+ // 29 - Basement
+ if (_locationNr != 29) {
+ // No dialog box and not in inventory
+ if (!_dialogFlag && !_showInventoryFlag) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
}
Common::Error PrinceEngine::saveGameState(int slot, const Common::String &desc) {
@@ -480,7 +500,7 @@ bool PrinceEngine::loadGame(int slotNumber) {
saveFile->read(dataBuffer, size);
readStream = new Common::MemoryReadStream(dataBuffer, size, DisposeAfterUse::YES);
delete saveFile;
-
+
// Check to see if it's a ScummVM savegame or not
char buffer[kSavegameStrSize + 1];
readStream->read(buffer, kSavegameStrSize + 1);
@@ -505,9 +525,6 @@ bool PrinceEngine::loadGame(int slotNumber) {
syncGame(readStream, nullptr);
delete readStream;
- // TODO
- //syncSpeechSettings();
-
return true;
}
diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp
index 0e9dd27877..4ed3cee6f3 100644
--- a/engines/prince/script.cpp
+++ b/engines/prince/script.cpp
@@ -43,7 +43,7 @@ Room::Room() {}
bool Room::loadRoom(byte *roomData) {
int roomSize = 64;
Common::MemoryReadStream roomStream(roomData, roomSize);
-
+
_mobs = roomStream.readSint32LE();
_backAnim = roomStream.readSint32LE();
_obj = roomStream.readSint32LE();
@@ -131,7 +131,7 @@ bool Script::loadStream(Common::SeekableReadStream &stream) {
_scriptInfo.invObjGive = scriptDataStream.readSint32LE();
_scriptInfo.stdGiveItem = scriptDataStream.readSint32LE();
_scriptInfo.goTester = scriptDataStream.readSint32LE();
-
+
return true;
}
@@ -391,10 +391,10 @@ bool Script::loadAllMasks(Common::Array<Mask> &maskList, int offset) {
debug("Can't load %s", msStreamName.c_str());
delete msStream;
} else {
- uint32 dataSize = msStream->size();
+ int32 dataSize = msStream->size();
if (dataSize != -1) {
tempMask._data = (byte *)malloc(dataSize);
- if (msStream->read(tempMask._data, dataSize) != dataSize) {
+ if (msStream->read(tempMask._data, dataSize) != (uint32)dataSize) {
free(tempMask._data);
delete msStream;
return false;
@@ -427,7 +427,7 @@ int32 InterpreterFlags::getFlagValue(Flags::Id flagId) {
return _flags[(uint32)flagId - kFlagMask];
}
-Interpreter::Interpreter(PrinceEngine *vm, Script *script, InterpreterFlags *flags) :
+Interpreter::Interpreter(PrinceEngine *vm, Script *script, InterpreterFlags *flags) :
_vm(vm), _script(script), _flags(flags),
_stacktop(0), _opcodeNF(false), _opcodeEnd(false),
_waitFlag(0), _result(true) {
@@ -477,10 +477,10 @@ uint32 Interpreter::step(uint32 opcodePC) {
// Get the current opcode
_lastOpcode = readScript16();
- if (_lastOpcode > kNumOpcodes)
+ if (_lastOpcode >= kNumOpcodes)
error(
- "Trying to execute unknown opcode @0x%04X: %02d",
- _currentInstruction,
+ "Trying to execute unknown opcode @0x%04X: %02d",
+ _currentInstruction,
_lastOpcode);
// Execute the current opcode
@@ -570,7 +570,7 @@ int32 Interpreter::readScriptFlagValue() {
return value;
}
-Flags::Id Interpreter::readScriptFlagId() {
+Flags::Id Interpreter::readScriptFlagId() {
return (Flags::Id)readScript16();
}
@@ -722,6 +722,17 @@ void Interpreter::O_PUTBACKANIM() {
_vm->_script->installSingleBackAnim(_vm->_backAnimList, slot, room->_backAnim);
}
delete room;
+
+ // WALKAROUND: fix for turning on 'walking bird' background animation too soon,
+ // after completing 'throw a rock' mini-game in Silmaniona location.
+ // Second bird shouldn't appear when normal animation is still in use
+ // in script lines 13814 and 13848
+ if (_currentInstruction == kSecondBirdAnimationScriptFix) {
+ if (_vm->_normAnimList[1]._state == 0) {
+ _vm->_backAnimList[0].backAnims[0]._state = 1;
+ }
+ }
+
debugInterpreter("O_PUTBACKANIM roomId %d, slot %d, animId %d", roomId, slot, animId);
}
@@ -1629,7 +1640,7 @@ void Interpreter::O_BACKANIMRANGE() {
}
void Interpreter::O_CLEARPATH() {
- for (int i = 0; i < _vm->kPathBitmapLen; i++) {
+ for (uint i = 0; i < _vm->kPathBitmapLen; i++) {
_vm->_roomPathBitmap[i] = 255;
}
debugInterpreter("O_CLEARPATH");
@@ -1689,7 +1700,7 @@ void Interpreter::O_POPSTRING() {
void Interpreter::O_SETFGCODE() {
int32 offset = readScript32();
- _fgOpcodePC = _currentInstruction + offset - 4;
+ _fgOpcodePC = _currentInstruction + offset - 4;
debugInterpreter("O_SETFGCODE next %08x, offset %08x", _fgOpcodePC, offset);
}
diff --git a/engines/prince/script.h b/engines/prince/script.h
index 4799e84944..fe79cf5f96 100644
--- a/engines/prince/script.h
+++ b/engines/prince/script.h
@@ -241,7 +241,8 @@ private:
typedef void (Interpreter::*OpcodeFunc)();
static OpcodeFunc _opcodes[];
- static const int kGiveLetterScriptFix = 79002;
+ static const uint kGiveLetterScriptFix = 79002;
+ static const uint kSecondBirdAnimationScriptFix = 45658;
// Keep opcode handlers names as they are in original code
// making it easier to switch back and forth
diff --git a/engines/queen/logic.cpp b/engines/queen/logic.cpp
index d48bb8a498..664a9a15f9 100644
--- a/engines/queen/logic.cpp
+++ b/engines/queen/logic.cpp
@@ -2115,9 +2115,15 @@ void LogicInterview::setupSpecialMoveTable() {
}
void LogicGame::useJournal() {
+ _vm->input()->clearKeyVerb();
+ _vm->input()->clearMouseButton();
+
_vm->command()->clear(false);
_journal->use();
_vm->walk()->stopJoe();
+
+ _vm->input()->clearKeyVerb();
+ _vm->input()->clearMouseButton();
}
bool LogicGame::changeToSpecialRoom() {
diff --git a/engines/queen/talk.cpp b/engines/queen/talk.cpp
index 1b9d72babc..e86a53d448 100644
--- a/engines/queen/talk.cpp
+++ b/engines/queen/talk.cpp
@@ -189,7 +189,7 @@ void Talk::talk(const char *filename, int personInRoom, char *cutawayFilename) {
}
}
- if (_vm->input()->talkQuit())
+ if (_vm->input()->talkQuit() || _vm->shouldQuit())
break;
retval = _dialogueTree[level][selectedSentence].dialogueNodeValue1;
@@ -1250,15 +1250,12 @@ int16 Talk::selectSentence() {
}
_vm->input()->clearKeyVerb();
+ _vm->input()->clearMouseButton();
if (sentenceCount > 0) {
int oldZone = 0;
- while (0 == selectedSentence) {
-
- if (_vm->input()->talkQuit())
- break;
-
+ while (0 == selectedSentence && !_vm->input()->talkQuit() && !_vm->shouldQuit()) {
_vm->update();
Common::Point mouse = _vm->input()->getMousePos();
@@ -1328,6 +1325,9 @@ int16 Talk::selectSentence() {
}
}
+ _vm->input()->clearKeyVerb();
+ _vm->input()->clearMouseButton();
+
debug(6, "Selected sentence %i", selectedSentence);
arrowBobUp->active = false;
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/actor.h b/engines/saga/actor.h
index b8a5436d76..8dc27c74be 100644
--- a/engines/saga/actor.h
+++ b/engines/saga/actor.h
@@ -468,7 +468,6 @@ public:
int actorIdToIndex(uint16 id) { return (id == ID_PROTAG) ? 0 : objectIdToIndex(id); }
uint16 actorIndexToId(int index) { return (index == 0) ? ID_PROTAG : objectIndexToId(kGameObjectActor, index); }
ActorData *getActor(uint16 actorId);
- ActorData *getFirstActor() { return &_actors.front(); }
// clarification: Obj - means game object, such Hat, Spoon etc, Object - means Actor,Obj,HitZone,StepZone
diff --git a/engines/saga/introproc_ite.cpp b/engines/saga/introproc_ite.cpp
index 0c1a2ce233..0b129dbcc0 100644
--- a/engines/saga/introproc_ite.cpp
+++ b/engines/saga/introproc_ite.cpp
@@ -374,7 +374,7 @@ int Scene::ITEIntroCaveCommonProc(int param, int caveScene) {
lang = 2;
int n_dialogues = 0;
-
+
switch (caveScene) {
case 1:
n_dialogues = ARRAYSIZE(introDialogueCave1[lang]);
diff --git a/engines/saga/saveload.cpp b/engines/saga/saveload.cpp
index 90ba62070b..e659e09ce8 100644
--- a/engines/saga/saveload.cpp
+++ b/engines/saga/saveload.cpp
@@ -215,8 +215,7 @@ void SagaEngine::save(const char *fileName, const char *saveName) {
#ifdef ENABLE_IHNM
if (getGameId() == GID_IHNM) {
out->writeSint32LE(_scene->currentChapterNumber());
- // Protagonist
- out->writeSint32LE(_scene->currentProtag());
+ out->writeSint32LE(0); // obsolete, was used for the protagonist
out->writeSint32LE(_scene->getCurrentMusicTrack());
out->writeSint32LE(_scene->getCurrentMusicRepeat());
}
@@ -316,7 +315,7 @@ void SagaEngine::load(const char *fileName) {
if (getGameId() == GID_IHNM) {
int currentChapter = _scene->currentChapterNumber();
_scene->setChapterNumber(in->readSint32LE());
- _scene->setProtag(in->readSint32LE());
+ in->skip(4); // obsolete, was used for setting the protagonist
if (_scene->currentChapterNumber() != currentChapter)
_scene->changeScene(-2, 0, kTransitionFade, _scene->currentChapterNumber());
_scene->setCurrentMusicTrack(in->readSint32LE());
@@ -366,30 +365,6 @@ void SagaEngine::load(const char *fileName) {
int volume = _music->getVolume();
_music->setVolume(0);
-#ifdef ENABLE_IHNM
- // Protagonist swapping
- if (getGameId() == GID_IHNM) {
- if (_scene->currentProtag() != 0 && _scene->currentChapterNumber() != 6) {
- ActorData *actor1 = _actor->getFirstActor();
- ActorData *actor2;
- // The original gets actor2 from the current protagonist ID, but this is sometimes wrong
- // If the current protagonist ID is not correct, use the stored protagonist
- if (!_actor->validActorId(_scene->currentProtag())) {
- actor2 = _actor->_protagonist;
- } else {
- actor2 = _actor->getActor(_scene->currentProtag());
- }
-
- SWAP(actor1->_location, actor2->_location);
-
- actor2->_flags &= ~kProtagonist;
- actor1->_flags |= kProtagonist;
- _actor->_protagonist = _actor->_centerActor = actor1;
- _scene->setProtag(actor1->_id);
- }
- }
-#endif
-
_scene->clearSceneQueue();
_scene->changeScene(sceneNumber, ACTOR_NO_ENTRANCE, kTransitionNoFade);
diff --git a/engines/saga/scene.cpp b/engines/saga/scene.cpp
index f19645dd99..4fa15d09e5 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
diff --git a/engines/saga/scene.h b/engines/saga/scene.h
index 6a9571d282..410713c5d5 100644
--- a/engines/saga/scene.h
+++ b/engines/saga/scene.h
@@ -286,8 +286,6 @@ class Scene {
#endif
return _sceneLUT[sceneNumber];
}
- int currentProtag() const { return _currentProtag; }
- void setProtag(int pr) { _currentProtag = pr; }
int currentSceneNumber() const { return _sceneNumber; }
int currentChapterNumber() const { return _chapterNumber; }
void setChapterNumber(int ch) { _chapterNumber = ch; }
@@ -341,7 +339,6 @@ class Scene {
Common::Array<uint16> _sceneLUT;
SceneQueueList _sceneQueue;
bool _sceneLoaded;
- int _currentProtag;
int _sceneNumber;
int _chapterNumber;
int _outsetSceneNumber;
diff --git a/engines/saga/sfuncs.cpp b/engines/saga/sfuncs.cpp
index cb963e23ac..2175d8f40a 100644
--- a/engines/saga/sfuncs.cpp
+++ b/engines/saga/sfuncs.cpp
@@ -748,14 +748,10 @@ void Script::sfSwapActors(SCRIPTFUNC_PARAMS) {
actor1->_flags &= ~kProtagonist;
actor2->_flags |= kProtagonist;
_vm->_actor->_protagonist = _vm->_actor->_centerActor = actor2;
- if (_vm->getGameId() == GID_IHNM)
- _vm->_scene->setProtag(actorId2);
} else if (actor2->_flags & kProtagonist) {
actor2->_flags &= ~kProtagonist;
actor1->_flags |= kProtagonist;
_vm->_actor->_protagonist = _vm->_actor->_centerActor = actor1;
- if (_vm->getGameId() == GID_IHNM)
- _vm->_scene->setProtag(actorId1);
}
}
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index 565e9752c3..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
@@ -485,6 +490,7 @@ bool Console::cmdGetVersion(int argc, const char **argv) {
#endif
debugPrintf("View type: %s\n", viewTypeDesc[g_sci->getResMan()->getViewType()]);
debugPrintf("Uses palette merging: %s\n", g_sci->_gfxPalette->isMerging() ? "yes" : "no");
+ debugPrintf("Uses 16 bit color matching: %s\n", g_sci->_gfxPalette->isUsing16bitColorMatch() ? "yes" : "no");
debugPrintf("Resource volume version: %s\n", g_sci->getResMan()->getVolVersionDesc());
debugPrintf("Resource map version: %s\n", g_sci->getResMan()->getMapVersionDesc());
debugPrintf("Contains selector vocabulary (vocab.997): %s\n", hasVocab997 ? "yes" : "no");
@@ -659,11 +665,34 @@ bool Console::cmdRegisters(int argc, const char **argv) {
return true;
}
-bool Console::cmdDiskDump(int argc, const char **argv) {
- int resNumFrom = 0;
- int resNumTo = 0;
- int resNumCur = 0;
+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) {
+ bool resourceAll = false;
+ uint16 resourceNumber = 0;
+ uint32 resourceTuple = 0;
+
if (argc != 3) {
debugPrintf("Dumps the specified resource to disk as a patch file\n");
debugPrintf("Usage: %s <resource type> <resource number>\n", argv[0]);
@@ -671,43 +700,91 @@ bool Console::cmdDiskDump(int argc, const char **argv) {
cmdResourceTypes(argc, 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");
@@ -747,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");
@@ -1123,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");
@@ -2171,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);
}
@@ -2197,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'");
@@ -2729,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;
@@ -3208,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 4f28738508..9a41127f6d 100644
--- a/engines/sci/detection.cpp
+++ b/engines/sci/detection.cpp
@@ -563,31 +563,28 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const FileMap &allFiles,
// If these files aren't found, it can't be SCI
- if (!foundResMap && !foundRes000) {
+ if (!foundResMap && !foundRes000)
return 0;
- }
ResourceManager resMan;
- resMan.addAppropriateSources(fslist);
- resMan.init(true);
+ resMan.addAppropriateSourcesForDetection(fslist);
+ resMan.initForDetection();
// TODO: Add error handling.
#ifndef ENABLE_SCI32
// Is SCI32 compiled in? If not, and this is a SCI32 game,
// stop here
- if (getSciVersion() >= SCI_VERSION_2) {
- return (const ADGameDescription *)&s_fallbackDesc;
- }
+ if (getSciVersionForDetection() >= SCI_VERSION_2)
+ return 0;
#endif
ViewType gameViews = resMan.getViewType();
// Have we identified the game views? If not, stop here
- // Can't be SCI (or unsupported SCI views). Pinball Creep by sierra also uses resource.map/resource.000 files
- // but doesnt share sci format at all, if we dont return 0 here we will detect this game as SCI
- if (gameViews == kViewUnknown) {
+ // Can't be SCI (or unsupported SCI views). Pinball Creep by Sierra also uses resource.map/resource.000 files
+ // but doesn't share SCI format at all
+ if (gameViews == kViewUnknown)
return 0;
- }
// Set the platform to Amiga if the game is using Amiga views
if (gameViews == kViewAmiga)
@@ -597,9 +594,8 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const FileMap &allFiles,
Common::String sierraGameId = resMan.findSierraGameId();
// If we don't have a game id, the game is not SCI
- if (sierraGameId.empty()) {
+ if (sierraGameId.empty())
return 0;
- }
Common::String gameId = convertSierraGameId(sierraGameId, &s_fallbackDesc.flags, resMan);
strncpy(s_fallbackGameIdBuf, gameId.c_str(), sizeof(s_fallbackGameIdBuf) - 1);
@@ -795,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) {
@@ -838,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 0fddaa51b4..7cadcfc27e 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)
@@ -2603,6 +2626,29 @@ 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) },
+ // Phantasmagoria - German DOS/Windows
+ // Windows executable scanning reports "unknown" - "Sep 19 1995 09:39:48"
+ // DOS executable scanning reports "unknown" - "Sep 19 1995 16:18:34"
+ // VERSION file reports "1.100.000"
+ // Supplied by AReim1982
+ {"phantasmagoria", "", {
+ {"resmap.001", 0, "d5048f972d2e1abd5f6b6a3ea8a466b0", 11524},
+ {"ressci.001", 0, "3aae6559aa1df273bc542d5ac6330d75", 71063082},
+ {"resmap.002", 0, "ae0105261e04826324daf7dd2d534465", 12064},
+ {"ressci.002", 0, "3aae6559aa1df273bc542d5ac6330d75", 80283368},
+ {"resmap.003", 0, "50786a4f54c6432ec31b52be90b3a8ba", 12340},
+ {"ressci.003", 0, "3aae6559aa1df273bc542d5ac6330d75", 82360370},
+ {"resmap.004", 0, "4cd3bbff8b81bad85db52c0c8407bd81", 12562},
+ {"ressci.004", 0, "3aae6559aa1df273bc542d5ac6330d75", 84453560},
+ {"resmap.005", 0, "779bd12802da6cfe54ce482140824a46", 12616},
+ {"ressci.005", 0, "3aae6559aa1df273bc542d5ac6330d75", 85113663},
+ {"resmap.006", 0, "2299f97876493cc29b6a48e1cfe9619d", 12538},
+ {"ressci.006", 0, "3aae6559aa1df273bc542d5ac6330d75", 87602346},
+ {"resmap.007", 0, "06309b8043aecb85bd507b15d16cb544", 7984},
+ //{"ressci.007", 0, "3aae6559aa1df273bc542d5ac6330d75", 26898681},
+ AD_LISTEND},
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+
// Phantasmagoria - French DOS
// Supplied by Kervala in bug #6574
{"phantasmagoria", "", {
@@ -2674,6 +2720,25 @@ static const struct ADGameDescription SciGameDescriptions[] = {
AD_LISTEND},
Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ // Phantasmagoria 2 - German DOS/Windows
+ // Windows executable scanning reports "unknown" - "Dec 07 1996 15:42:02"
+ // DOS executable scanning reports "unknown" - "Dec 07 1996 08:35:12"
+ // VERSION file reports "000.1.0vu" (HEX: 30 30 30 2E 31 00 2E 30 76 FA 0D 0A)
+ // Supplied by AReim1982
+ {"phantasmagoria2", "", {
+ {"resmap.001", 0, "d62f48ff8bddb39503b97e33439482c9", 1114},
+ {"ressci.001", 0, "4ebc2b8455c74ad205ae592eec27313a", 24590716},
+ {"resmap.002", 0, "642a1f85ad8a4ce1d3850b10ad082200", 1138},
+ {"ressci.002", 0, "4ebc2b8455c74ad205ae592eec27313a", 34681672},
+ {"resmap.003", 0, "e08316864ef77735bb7f8f208110c43b", 1174},
+ {"ressci.003", 0, "4ebc2b8455c74ad205ae592eec27313a", 38930933},
+ {"resmap.004", 0, "875cf07df77fbaa1518a06ffed616c5f", 1300},
+ {"ressci.004", 0, "4ebc2b8455c74ad205ae592eec27313a", 42750325},
+ {"resmap.005", 0, "2fc48a4a5a73b726994f189da51a8b2a", 1954},
+ {"ressci.005", 0, "e94005890d22dd3b7f605a2a7c025803", 68232146},
+ AD_LISTEND},
+ Common::DE_DEU, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+
// Phantasmagoria 2 - English DOS (GOG version) - ressci.* merged in ressci.000
// Executable scanning reports "3.000.000" - "Dec 07 1996 09:29:03"
// VERSION file reports "001.0.06"
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 dddf845222..57b4d9455b 100644
--- a/engines/sci/engine/kernel.h
+++ b/engines/sci/engine/kernel.h
@@ -145,7 +145,7 @@ public:
*/
Kernel(ResourceManager *resMan, SegManager *segMan);
~Kernel();
-
+
void init();
uint getSelectorNamesSize() const;
@@ -161,7 +161,7 @@ public:
* @return The appropriate selector ID, or -1 on error
*/
int findSelector(const char *selectorName) const;
-
+
bool selectorNamesAvailable();
// Script dissection/dumping functions
@@ -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 61fb717567..c56eb09482 100644
--- a/engines/sci/engine/kfile.cpp
+++ b/engines/sci/engine/kfile.cpp
@@ -37,6 +37,7 @@
#include "sci/engine/state.h"
#include "sci/engine/kernel.h"
#include "sci/engine/savegame.h"
+#include "sci/graphics/menu.h"
#include "sci/sound/audio.h"
#include "sci/console.h"
@@ -913,6 +914,25 @@ reg_t kRestoreGame(EngineState *s, int argc, reg_t *argv) {
// code concerning this via script patch.
s->variables[VAR_GLOBAL][0xB3].setOffset(SAVEGAMEID_OFFICIALRANGE_START + savegameId);
break;
+ case GID_JONES:
+ // HACK: The code that enables certain menu items isn't called when a game is restored from the
+ // launcher, or the "Restore game" option in the game's main menu - bugs #6537 and #6723.
+ // These menu entries are disabled when the game is launched, and are enabled when a new game is
+ // started. The code for enabling these entries is is all in script 1, room1::init, but that code
+ // path is never followed in these two cases (restoring game from the menu, or restoring a game
+ // from the ScummVM launcher). Thus, we perform the calls to enable the menus ourselves here.
+ // These two are needed when restoring from the launcher
+ // FIXME: The original interpreter saves and restores the menu state, so these attributes
+ // are automatically reset there. We may want to do the same.
+ g_sci->_gfxMenu->kernelSetAttribute(257 >> 8, 257 & 0xFF, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Sierra -> About Jones
+ g_sci->_gfxMenu->kernelSetAttribute(258 >> 8, 258 & 0xFF, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Sierra -> Help
+ // The rest are normally enabled from room1::init
+ g_sci->_gfxMenu->kernelSetAttribute(769 >> 8, 769 & 0xFF, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Options -> Delete current player
+ g_sci->_gfxMenu->kernelSetAttribute(513 >> 8, 513 & 0xFF, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Game -> Save Game
+ g_sci->_gfxMenu->kernelSetAttribute(515 >> 8, 515 & 0xFF, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Game -> Restore Game
+ 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;
default:
break;
}
diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp
index c2089bcd4d..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"
@@ -354,13 +355,16 @@ reg_t kTextSize(EngineState *s, int argc, reg_t *argv) {
}
textWidth = dest[3].toUint16(); textHeight = dest[2].toUint16();
+
+ uint16 languageSplitter = 0;
+ Common::String splitText = g_sci->strSplitLanguage(text.c_str(), &languageSplitter, sep);
#ifdef ENABLE_SCI32
if (g_sci->_gfxText32)
- g_sci->_gfxText32->kernelTextSize(g_sci->strSplit(text.c_str(), sep).c_str(), font_nr, maxwidth, &textWidth, &textHeight);
+ g_sci->_gfxText32->kernelTextSize(splitText.c_str(), font_nr, maxwidth, &textWidth, &textHeight);
else
#endif
- g_sci->_gfxText16->kernelTextSize(g_sci->strSplit(text.c_str(), sep).c_str(), font_nr, maxwidth, &textWidth, &textHeight);
+ g_sci->_gfxText16->kernelTextSize(splitText.c_str(), languageSplitter, font_nr, maxwidth, &textWidth, &textHeight);
// One of the game texts in LB2 German contains loads of spaces in
// its end. We trim the text here, otherwise the graphics code will
@@ -376,7 +380,7 @@ reg_t kTextSize(EngineState *s, int argc, reg_t *argv) {
// Copy over the trimmed string...
s->_segMan->strcpy(argv[1], text.c_str());
// ...and recalculate bounding box dimensions
- g_sci->_gfxText16->kernelTextSize(g_sci->strSplit(text.c_str(), sep).c_str(), font_nr, maxwidth, &textWidth, &textHeight);
+ g_sci->_gfxText16->kernelTextSize(splitText.c_str(), languageSplitter, font_nr, maxwidth, &textWidth, &textHeight);
}
}
@@ -397,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;
}
@@ -818,16 +828,29 @@ void _k_GenericDrawControl(EngineState *s, reg_t controlObject, bool hilite) {
if (!textReference.isNull())
text = s->_segMan->getString(textReference);
+ uint16 languageSplitter = 0;
+ Common::String splitText;
+
+ switch (type) {
+ case SCI_CONTROLS_TYPE_BUTTON:
+ case SCI_CONTROLS_TYPE_TEXTEDIT:
+ splitText = g_sci->strSplitLanguage(text.c_str(), &languageSplitter, NULL);
+ break;
+ case SCI_CONTROLS_TYPE_TEXT:
+ splitText = g_sci->strSplitLanguage(text.c_str(), &languageSplitter);
+ break;
+ }
+
switch (type) {
case SCI_CONTROLS_TYPE_BUTTON:
debugC(kDebugLevelGraphics, "drawing button %04x:%04x to %d,%d", PRINT_REG(controlObject), x, y);
- g_sci->_gfxControls16->kernelDrawButton(rect, controlObject, g_sci->strSplit(text.c_str(), NULL).c_str(), fontId, style, hilite);
+ g_sci->_gfxControls16->kernelDrawButton(rect, controlObject, splitText.c_str(), languageSplitter, fontId, style, hilite);
return;
case SCI_CONTROLS_TYPE_TEXT:
alignment = readSelectorValue(s->_segMan, controlObject, SELECTOR(mode));
debugC(kDebugLevelGraphics, "drawing text %04x:%04x ('%s') to %d,%d, mode=%d", PRINT_REG(controlObject), text.c_str(), x, y, alignment);
- g_sci->_gfxControls16->kernelDrawText(rect, controlObject, g_sci->strSplit(text.c_str()).c_str(), fontId, alignment, style, hilite);
+ g_sci->_gfxControls16->kernelDrawText(rect, controlObject, splitText.c_str(), languageSplitter, fontId, alignment, style, hilite);
s->r_acc = g_sci->_gfxText16->allocAndFillReferenceRectArray();
return;
@@ -841,7 +864,7 @@ void _k_GenericDrawControl(EngineState *s, reg_t controlObject, bool hilite) {
writeSelectorValue(s->_segMan, controlObject, SELECTOR(cursor), cursorPos);
}
debugC(kDebugLevelGraphics, "drawing edit control %04x:%04x (text %04x:%04x, '%s') to %d,%d", PRINT_REG(controlObject), PRINT_REG(textReference), text.c_str(), x, y);
- g_sci->_gfxControls16->kernelDrawTextEdit(rect, controlObject, g_sci->strSplit(text.c_str(), NULL).c_str(), fontId, mode, style, cursorPos, maxChars, hilite);
+ g_sci->_gfxControls16->kernelDrawTextEdit(rect, controlObject, splitText.c_str(), languageSplitter, fontId, mode, style, cursorPos, maxChars, hilite);
return;
case SCI_CONTROLS_TYPE_ICON:
@@ -939,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());
@@ -1165,8 +1189,11 @@ reg_t kDisplay(EngineState *s, int argc, reg_t *argv) {
argc--; argc--; argv++; argv++;
text = g_sci->getKernel()->lookupText(textp, index);
}
+
+ uint16 languageSplitter = 0;
+ Common::String splitText = g_sci->strSplitLanguage(text.c_str(), &languageSplitter);
- return g_sci->_gfxPaint16->kernelDisplay(g_sci->strSplit(text.c_str()).c_str(), argc, argv);
+ return g_sci->_gfxPaint16->kernelDisplay(splitText.c_str(), languageSplitter, argc, argv);
}
reg_t kSetVideoMode(EngineState *s, int argc, reg_t *argv) {
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/kstring.cpp b/engines/sci/engine/kstring.cpp
index 56dad583e4..eef758a0d9 100644
--- a/engines/sci/engine/kstring.cpp
+++ b/engines/sci/engine/kstring.cpp
@@ -42,10 +42,12 @@ reg_t kStrCat(EngineState *s, int argc, reg_t *argv) {
Common::String s1 = s->_segMan->getString(argv[0]);
Common::String s2 = s->_segMan->getString(argv[1]);
- // The Japanese version of PQ2 splits the two strings here
- // (check bug #3396887).
- if (g_sci->getGameId() == GID_PQ2 &&
- g_sci->getLanguage() == Common::JA_JPN) {
+ // Japanese PC-9801 interpreter splits strings here
+ // see bug #5834
+ // Verified for Police Quest 2 + Quest For Glory 1
+ // However Space Quest 4 PC-9801 doesn't
+ if ((g_sci->getLanguage() == Common::JA_JPN)
+ && (getSciVersion() <= SCI_VERSION_01)) {
s1 = g_sci->strSplit(s1.c_str(), NULL);
s2 = g_sci->strSplit(s2.c_str(), NULL);
}
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 cdcdcc41e5..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,20 +638,26 @@ 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) {
- // Sync the sound object's selectors related to playing with the stored
- // ones in the playlist, as they may have been invalidated when loading.
- // Refer to bug #3104624.
+ // WORKAROUND: PQ3 (German?) scripts can set volume negative in the
+ // sound object directly without going through DoSound.
+ // Since we re-read this selector when re-playing the sound after loading,
+ // this will lead to unexpected behaviour. As a workaround we
+ // sync the sound object's selectors here. (See bug #5501)
writeSelectorValue(_segMan, (*i)->soundObj, SELECTOR(loop), (*i)->loop);
writeSelectorValue(_segMan, (*i)->soundObj, SELECTOR(priority), (*i)->priority);
if (_soundVersion >= SCI_VERSION_1_EARLY)
writeSelectorValue(_segMan, (*i)->soundObj, SELECTOR(vol), (*i)->volume);
- processPlaySound((*i)->soundObj);
+ processPlaySound((*i)->soundObj, (*i)->playBed);
}
}
}
@@ -713,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;
@@ -758,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--;
@@ -844,11 +858,29 @@ bool gamestate_save(EngineState *s, Common::WriteStream *fh, const Common::Strin
if (voc)
voc->saveLoadWithSerializer(ser);
+ // TODO: SSCI (at least JonesCD, presumably more) also stores the Menu state
+
return true;
}
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;
@@ -885,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..6034378ef6 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) {
@@ -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() {
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 8bbbd713a6..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
};
@@ -1214,6 +1218,26 @@ static const uint16 kq6CDPatchAudioTextSupportGirlInTheTower[] = {
PATCH_END
};
+// Fixes dual mode for scenes with Azure and Ariel (room 370)
+// Effectively same patch as the one for fixing "Girl In The Tower"
+// Applies to at least: PC-CD
+// Patched methods: rm370::init, caughtAtGateCD::changeState, caughtAtGateTXT::changeState, toLabyrinth::changeState
+// Fixes bug: #6750
+static const uint16 kq6CDSignatureAudioTextSupportAzureAriel[] = {
+ SIG_MAGICDWORD,
+ 0x89, 0x5a, // lsg global[5a]
+ 0x35, 0x02, // ldi 02
+ 0x1a, // eq?
+ 0x31, // bnt [jump-for-text-code]
+ SIG_END
+};
+
+static const uint16 kq6CDPatchAudioTextSupportAzureAriel[] = {
+ PATCH_ADDTOOFFSET(+4),
+ 0x12, // and
+ PATCH_END
+};
+
// Additional patch specifically for King's Quest 6
// Adds another button state for the text/audio button. We currently use the "speech" view for "dual" mode.
// View 947, loop 9, cel 0+1 -> "text"
@@ -1306,6 +1330,7 @@ static const SciScriptPatcherEntry kq6Signatures[] = {
{ false, 1009, "CD: audio + text support KQ6 Guards", 2, kq6CDSignatureAudioTextSupportGuards, kq6CDPatchAudioTextSupportGuards },
{ false, 1027, "CD: audio + text support KQ6 Stepmother", 1, kq6CDSignatureAudioTextSupportStepmother, kq6CDPatchAudioTextSupportJumpAlways },
{ false, 740, "CD: audio + text support KQ6 Girl In The Tower", 1, kq6CDSignatureAudioTextSupportGirlInTheTower, kq6CDPatchAudioTextSupportGirlInTheTower },
+ { false, 370, "CD: audio + text support KQ6 Azure & Ariel", 6, kq6CDSignatureAudioTextSupportAzureAriel, kq6CDPatchAudioTextSupportAzureAriel },
{ false, 903, "CD: audio + text support KQ6 menu", 1, kq6CDSignatureAudioTextMenuSupport, kq6CDPatchAudioTextMenuSupport },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -1400,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.
@@ -1423,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
};
@@ -1917,6 +1974,43 @@ static const SciScriptPatcherEntry pq1vgaSignatures[] = {
};
// ===========================================================================
+// At the healer's house there is a bird's nest up on the tree.
+// The player can throw rocks at it until it falls to the ground.
+// The hero will then grab the item, that is in the nest.
+//
+// When running is active, the hero will not reach the actual destination
+// and because of that, the game will get stuck.
+//
+// We just change the coordinate of the destination slightly, so that walking,
+// sneaking and running work.
+//
+// This bug was fixed by Sierra at least in the Japanese PC-9801 version.
+// Applies to at least: English floppy (1.000, 1.012)
+// Responsible method: pickItUp::changeState (script 54)
+// Fixes bug: #6407
+static const uint16 qfg1egaSignatureThrowRockAtNest[] = {
+ 0x4a, 0x04, // send 04 (nest::x)
+ 0x36, // push
+ SIG_MAGICDWORD,
+ 0x35, 0x0f, // ldi 0f (15d)
+ 0x02, // add
+ 0x36, // push
+ SIG_END
+};
+
+static const uint16 qfg1egaPatchThrowRockAtNest[] = {
+ PATCH_ADDTOOFFSET(+3),
+ 0x35, 0x12, // ldi 12 (18d)
+ PATCH_END
+};
+
+// script, description, signature patch
+static const SciScriptPatcherEntry qfg1egaSignatures[] = {
+ { true, 54, "throw rock at nest while running", 1, qfg1egaSignatureThrowRockAtNest, qfg1egaPatchThrowRockAtNest },
+ SCI_SIGNATUREENTRY_TERMINATOR
+};
+
+// ===========================================================================
// script 215 of qfg1vga pointBox::doit actually processes button-presses
// during fighting with monsters. It strangely also calls kGetEvent. Because
// the main User::doit also calls kGetEvent it's pure luck, where the event
@@ -2029,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
};
@@ -2058,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
@@ -2082,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
@@ -2108,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
@@ -2153,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
};
@@ -2224,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
};
@@ -2287,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.
@@ -2381,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
};
@@ -2413,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"
@@ -2537,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
@@ -2612,6 +3187,7 @@ ScriptPatcher::ScriptPatcher() {
_selectorIdTable[selectorNr] = -1;
_runtimeTable = NULL;
+ _isMacSci11 = false;
}
ScriptPatcher::~ScriptPatcher() {
@@ -2620,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;
@@ -2684,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 {
@@ -2711,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;
@@ -2724,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++;
@@ -2817,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;
@@ -2885,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 {
@@ -2900,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 {
@@ -3036,6 +3617,9 @@ void ScriptPatcher::processScript(uint16 scriptNr, byte *scriptData, const uint3
case GID_PQ1:
signatureTable = pq1vgaSignatures;
break;
+ case GID_QFG1:
+ signatureTable = qfg1egaSignatures;
+ break;
case GID_QFG1VGA:
signatureTable = qfg1vgaSignatures;
break;
@@ -3059,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)
@@ -3067,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) {
@@ -3102,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 0b35792949..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 7701822f6d..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;
@@ -203,59 +207,94 @@ static kLanguage charToLanguage(const char c) {
}
}
-Common::String SciEngine::getSciLanguageString(const Common::String &str, kLanguage lang, kLanguage *lang2) const {
- kLanguage secondLang = K_LANG_NONE;
-
- const char *seeker = str.c_str();
- while (*seeker) {
- if ((*seeker == '%') || (*seeker == '#')) {
- secondLang = charToLanguage(*(seeker + 1));
-
- if (secondLang != K_LANG_NONE)
+Common::String SciEngine::getSciLanguageString(const Common::String &str, kLanguage requestedLanguage, kLanguage *secondaryLanguage, uint16 *languageSplitter) const {
+ kLanguage foundLanguage = K_LANG_NONE;
+ const byte *textPtr = (const byte *)str.c_str();
+ byte curChar = 0;
+ byte curChar2 = 0;
+
+ while (1) {
+ curChar = *textPtr;
+ if (!curChar)
+ break;
+
+ if ((curChar == '%') || (curChar == '#')) {
+ curChar2 = *(textPtr + 1);
+ foundLanguage = charToLanguage(curChar2);
+
+ if (foundLanguage != K_LANG_NONE) {
+ // Return language splitter
+ if (languageSplitter)
+ *languageSplitter = curChar | ( curChar2 << 8 );
+ // Return the secondary language found in the string
+ if (secondaryLanguage)
+ *secondaryLanguage = foundLanguage;
break;
+ }
}
-
- ++seeker;
+ textPtr++;
}
- // Return the secondary language found in the string
- if (lang2)
- *lang2 = secondLang;
-
- if (secondLang == lang) {
- if (*(++seeker) == 'J') {
+ if (foundLanguage == requestedLanguage) {
+ if (curChar2 == 'J') {
// Japanese including Kanji, displayed with system font
// Convert half-width characters to full-width equivalents
Common::String fullWidth;
- byte c;
+ uint16 mappedChar;
+
+ textPtr += 2; // skip over language splitter
+
+ while (1) {
+ curChar = *textPtr;
+
+ switch (curChar) {
+ case 0: // Terminator NUL
+ return fullWidth;
+ case '\\':
+ // "\n", "\N", "\r" and "\R" were overwritten with SPACE + 0x0D in PC-9801 SSCI
+ // inside GetLongest() (text16). We do it here, because it's much cleaner and
+ // we have to process the text here anyway.
+ // Occurs for example in Police Quest 2 intro
+ curChar2 = *(textPtr + 1);
+ switch (curChar2) {
+ case 'n':
+ case 'N':
+ case 'r':
+ case 'R':
+ fullWidth += ' ';
+ fullWidth += 0x0D; // CR
+ textPtr += 2;
+ continue;
+ }
+ }
+
+ textPtr++;
- while ((c = *(++seeker))) {
- uint16 mappedChar = s_halfWidthSJISMap[c];
+ mappedChar = s_halfWidthSJISMap[curChar];
if (mappedChar) {
fullWidth += mappedChar >> 8;
fullWidth += mappedChar & 0xFF;
} else {
// Copy double-byte character
- char c2 = *(++seeker);
- if (!c2) {
- error("SJIS character %02X is missing second byte", c);
+ curChar2 = *(textPtr++);
+ if (!curChar) {
+ error("SJIS character %02X is missing second byte", curChar);
break;
}
- fullWidth += c;
- fullWidth += c2;
+ fullWidth += curChar;
+ fullWidth += curChar2;
}
}
- return fullWidth;
} else {
- return Common::String(seeker + 1);
+ return Common::String((const char *)(textPtr + 2));
}
}
- if (*seeker)
- return Common::String(str.c_str(), seeker - str.c_str());
- else
- return str;
+ if (curChar)
+ return Common::String(str.c_str(), (const char *)textPtr - str.c_str());
+
+ return str;
}
kLanguage SciEngine::getSciLanguage() {
@@ -314,25 +353,25 @@ void SciEngine::setSciLanguage() {
setSciLanguage(getSciLanguage());
}
-Common::String SciEngine::strSplit(const char *str, const char *sep) {
- kLanguage lang = getSciLanguage();
- kLanguage subLang = K_LANG_NONE;
+Common::String SciEngine::strSplitLanguage(const char *str, uint16 *languageSplitter, const char *sep) {
+ kLanguage activeLanguage = getSciLanguage();
+ kLanguage subtitleLanguage = K_LANG_NONE;
if (SELECTOR(subtitleLang) != -1)
- subLang = (kLanguage)readSelectorValue(_gamestate->_segMan, _gameObjectAddress, SELECTOR(subtitleLang));
+ subtitleLanguage = (kLanguage)readSelectorValue(_gamestate->_segMan, _gameObjectAddress, SELECTOR(subtitleLang));
- kLanguage secondLang;
- Common::String retval = getSciLanguageString(str, lang, &secondLang);
+ kLanguage foundLanguage;
+ Common::String retval = getSciLanguageString(str, activeLanguage, &foundLanguage, languageSplitter);
// Don't add subtitle when separator is not set, subtitle language is not set, or
// string contains only one language
- if ((sep == NULL) || (subLang == K_LANG_NONE) || (secondLang == K_LANG_NONE))
+ if ((sep == NULL) || (subtitleLanguage == K_LANG_NONE) || (foundLanguage == K_LANG_NONE))
return retval;
// Add subtitle, unless the subtitle language doesn't match the languages in the string
- if ((subLang == K_LANG_ENGLISH) || (subLang == secondLang)) {
+ if ((subtitleLanguage == K_LANG_ENGLISH) || (subtitleLanguage == foundLanguage)) {
retval += sep;
- retval += getSciLanguageString(str, subLang);
+ retval += getSciLanguageString(str, subtitleLanguage);
}
return retval;
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 ea4dc2fe71..aab32032f7 100644
--- a/engines/sci/engine/workarounds.cpp
+++ b/engines/sci/engine/workarounds.cpp
@@ -24,425 +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, -1, { WORKAROUND_FAKE, 0 } }, // when saving the game (may also occur in other situations) - bug #6601
- { 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
};
@@ -460,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()) {
@@ -493,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))
@@ -513,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/event.cpp b/engines/sci/event.cpp
index 511d2014bd..b1c002413d 100644
--- a/engines/sci/event.cpp
+++ b/engines/sci/event.cpp
@@ -262,7 +262,7 @@ SciEvent EventManager::getScummVMEvent() {
// Scancodify if appropriate
if (modifiers & Common::KBD_ALT)
input.character = altify(input.character);
- else if ((modifiers & Common::KBD_CTRL) && input.character > 0 && input.character < 27)
+ if (getSciVersion() <= SCI_VERSION_1_MIDDLE && (modifiers & Common::KBD_CTRL) && input.character > 0 && input.character < 27)
input.character += 96; // 0x01 -> 'a'
// If no actual key was pressed (e.g. if only a modifier key was pressed),
diff --git a/engines/sci/graphics/controls16.cpp b/engines/sci/graphics/controls16.cpp
index f2b2ccdfe6..e2e250cf9d 100644
--- a/engines/sci/graphics/controls16.cpp
+++ b/engines/sci/graphics/controls16.cpp
@@ -280,7 +280,7 @@ int GfxControls16::getPicNotValid() {
return _screen->_picNotValid;
}
-void GfxControls16::kernelDrawButton(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 style, bool hilite) {
+void GfxControls16::kernelDrawButton(Common::Rect rect, reg_t obj, const char *text, uint16 languageSplitter, int16 fontId, int16 style, bool hilite) {
int16 sci0EarlyPen = 0, sci0EarlyBack = 0;
if (!hilite) {
if (getSciVersion() == SCI_VERSION_0_EARLY) {
@@ -295,7 +295,7 @@ void GfxControls16::kernelDrawButton(Common::Rect rect, reg_t obj, const char *t
_paint16->frameRect(rect);
rect.grow(-2);
_ports->textGreyedOutput(!(style & SCI_CONTROLS_STYLE_ENABLED));
- _text16->Box(text, false, rect, SCI_TEXT16_ALIGNMENT_CENTER, fontId);
+ _text16->Box(text, languageSplitter, false, rect, SCI_TEXT16_ALIGNMENT_CENTER, fontId);
_ports->textGreyedOutput(false);
rect.grow(1);
if (style & SCI_CONTROLS_STYLE_SELECTED)
@@ -318,12 +318,12 @@ void GfxControls16::kernelDrawButton(Common::Rect rect, reg_t obj, const char *t
}
}
-void GfxControls16::kernelDrawText(Common::Rect rect, reg_t obj, const char *text, int16 fontId, TextAlignment alignment, int16 style, bool hilite) {
+void GfxControls16::kernelDrawText(Common::Rect rect, reg_t obj, const char *text, uint16 languageSplitter, int16 fontId, TextAlignment alignment, int16 style, bool hilite) {
if (!hilite) {
rect.grow(1);
_paint16->eraseRect(rect);
rect.grow(-1);
- _text16->Box(text, false, rect, alignment, fontId);
+ _text16->Box(text, languageSplitter, false, rect, alignment, fontId);
if (style & SCI_CONTROLS_STYLE_SELECTED) {
_paint16->frameRect(rect);
}
@@ -335,7 +335,7 @@ void GfxControls16::kernelDrawText(Common::Rect rect, reg_t obj, const char *tex
}
}
-void GfxControls16::kernelDrawTextEdit(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 mode, int16 style, int16 cursorPos, int16 maxChars, bool hilite) {
+void GfxControls16::kernelDrawTextEdit(Common::Rect rect, reg_t obj, const char *text, uint16 languageSplitter, int16 fontId, int16 mode, int16 style, int16 cursorPos, int16 maxChars, bool hilite) {
Common::Rect textRect = rect;
uint16 oldFontId = _text16->GetFontId();
@@ -343,7 +343,7 @@ void GfxControls16::kernelDrawTextEdit(Common::Rect rect, reg_t obj, const char
_texteditCursorVisible = false;
texteditCursorErase();
_paint16->eraseRect(rect);
- _text16->Box(text, false, textRect, SCI_TEXT16_ALIGNMENT_LEFT, fontId);
+ _text16->Box(text, languageSplitter, false, textRect, SCI_TEXT16_ALIGNMENT_LEFT, fontId);
_paint16->frameRect(rect);
if (style & SCI_CONTROLS_STYLE_SELECTED) {
_text16->SetFont(fontId);
diff --git a/engines/sci/graphics/controls16.h b/engines/sci/graphics/controls16.h
index 6a70c71aae..39ffa243fb 100644
--- a/engines/sci/graphics/controls16.h
+++ b/engines/sci/graphics/controls16.h
@@ -55,9 +55,9 @@ public:
GfxControls16(SegManager *segMan, GfxPorts *ports, GfxPaint16 *paint16, GfxText16 *text16, GfxScreen *screen);
~GfxControls16();
- void kernelDrawButton(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 style, bool hilite);
- void kernelDrawText(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 alignment, int16 style, bool hilite);
- void kernelDrawTextEdit(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 mode, int16 style, int16 cursorPos, int16 maxChars, bool hilite);
+ void kernelDrawButton(Common::Rect rect, reg_t obj, const char *text, uint16 languageSplitter, int16 fontId, int16 style, bool hilite);
+ void kernelDrawText(Common::Rect rect, reg_t obj, const char *text, uint16 languageSplitter, int16 fontId, int16 alignment, int16 style, bool hilite);
+ void kernelDrawTextEdit(Common::Rect rect, reg_t obj, const char *text, uint16 languageSplitter, int16 fontId, int16 mode, int16 style, int16 cursorPos, int16 maxChars, bool hilite);
void kernelDrawIcon(Common::Rect rect, reg_t obj, GuiResourceId viewId, int16 loopNo, int16 celNo, int16 priority, int16 style, bool hilite);
void kernelDrawList(Common::Rect rect, reg_t obj, int16 maxChars, int16 count, const char **entries, GuiResourceId fontId, int16 style, int16 upperPos, int16 cursorPos, bool isAlias, bool hilite);
void kernelTexteditChange(reg_t controlObject, reg_t eventObject);
diff --git a/engines/sci/graphics/cursor.cpp b/engines/sci/graphics/cursor.cpp
index 048ec1e9b9..1a58de073c 100644
--- a/engines/sci/graphics/cursor.cpp
+++ b/engines/sci/graphics/cursor.cpp
@@ -47,7 +47,7 @@ GfxCursor::GfxCursor(ResourceManager *resMan, GfxPalette *palette, GfxScreen *sc
_isVisible = true;
// center mouse cursor
- setPosition(Common::Point(_screen->getWidth() / 2, _screen->getHeight() / 2));
+ setPosition(Common::Point(_screen->getScriptWidth() / 2, _screen->getScriptHeight() / 2));
_moveZoneActive = false;
_zoomZoneActive = false;
@@ -151,14 +151,14 @@ void GfxCursor::kernelSetShape(GuiResourceId resourceId) {
colorMapping[0] = 0; // Black is hardcoded
colorMapping[1] = _screen->getColorWhite(); // White is also hardcoded
colorMapping[2] = SCI_CURSOR_SCI0_TRANSPARENCYCOLOR;
- colorMapping[3] = _palette->matchColor(170, 170, 170); // Grey
+ colorMapping[3] = _palette->matchColor(170, 170, 170) & SCI_PALETTE_MATCH_COLORMASK; // Grey
// TODO: Figure out if the grey color is hardcoded
// HACK for the magnifier cursor in LB1, fixes its color (bug #3487092)
if (g_sci->getGameId() == GID_LAURABOW && resourceId == 1)
colorMapping[3] = _screen->getColorWhite();
// HACK for Longbow cursors, fixes the shade of grey they're using (bug #3489101)
if (g_sci->getGameId() == GID_LONGBOW)
- colorMapping[3] = _palette->matchColor(223, 223, 223); // Light Grey
+ colorMapping[3] = _palette->matchColor(223, 223, 223) & SCI_PALETTE_MATCH_COLORMASK; // Light Grey
// Seek to actual data
resourceData += 4;
@@ -481,7 +481,7 @@ void GfxCursor::kernelSetPos(Common::Point pos) {
void GfxCursor::kernelMoveCursor(Common::Point pos) {
_coordAdjuster->moveCursor(pos);
- if (pos.x > _screen->getWidth() || pos.y > _screen->getHeight()) {
+ if (pos.x > _screen->getScriptWidth() || pos.y > _screen->getScriptHeight()) {
warning("attempt to place cursor at invalid coordinates (%d, %d)", pos.y, pos.x);
return;
}
diff --git a/engines/sci/graphics/font.cpp b/engines/sci/graphics/font.cpp
index e4684ff134..2268ec0459 100644
--- a/engines/sci/graphics/font.cpp
+++ b/engines/sci/graphics/font.cpp
@@ -48,8 +48,8 @@ GfxFontFromResource::GfxFontFromResource(ResourceManager *resMan, GfxScreen *scr
// filling info for every char
for (int16 i = 0; i < _numChars; i++) {
_chars[i].offset = READ_SCI32ENDIAN_UINT16(_resourceData + 6 + i * 2);
- _chars[i].w = _resourceData[_chars[i].offset];
- _chars[i].h = _resourceData[_chars[i].offset + 1];
+ _chars[i].width = _resourceData[_chars[i].offset];
+ _chars[i].height = _resourceData[_chars[i].offset + 1];
}
}
@@ -66,10 +66,10 @@ byte GfxFontFromResource::getHeight() {
return _fontHeight;
}
byte GfxFontFromResource::getCharWidth(uint16 chr) {
- return chr < _numChars ? _chars[chr].w : 0;
+ return chr < _numChars ? _chars[chr].width : 0;
}
byte GfxFontFromResource::getCharHeight(uint16 chr) {
- return chr < _numChars ? _chars[chr].h : 0;
+ return chr < _numChars ? _chars[chr].height : 0;
}
byte *GfxFontFromResource::getCharData(uint16 chr) {
return chr < _numChars ? _resourceData + _chars[chr].offset + 2 : 0;
diff --git a/engines/sci/graphics/font.h b/engines/sci/graphics/font.h
index 58b2ba4813..451261f315 100644
--- a/engines/sci/graphics/font.h
+++ b/engines/sci/graphics/font.h
@@ -71,9 +71,11 @@ private:
byte *_resourceData;
struct Charinfo {
- byte w, h;
+ byte width;
+ byte height;
int16 offset;
};
+
byte _fontHeight;
uint16 _numChars;
Charinfo *_chars;
diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp
index fafc734895..ccc362dc37 100644
--- a/engines/sci/graphics/frameout.cpp
+++ b/engines/sci/graphics/frameout.cpp
@@ -524,6 +524,10 @@ void GfxFrameout::showVideo() {
RobotDecoder *videoDecoder = g_sci->_robotDecoder;
uint16 x = videoDecoder->getPos().x;
uint16 y = videoDecoder->getPos().y;
+ uint16 screenWidth = _screen->getWidth();
+ uint16 screenHeight = _screen->getHeight();
+ uint16 outputWidth;
+ uint16 outputHeight;
if (videoDecoder->hasDirtyPalette())
g_system->getPaletteManager()->setPalette(videoDecoder->getPalette(), 0, 256);
@@ -532,7 +536,11 @@ void GfxFrameout::showVideo() {
if (videoDecoder->needsUpdate()) {
const Graphics::Surface *frame = videoDecoder->decodeNextFrame();
if (frame) {
- g_system->copyRectToScreen(frame->getPixels(), frame->pitch, x, y, frame->w, frame->h);
+ // We need to clip here
+ // At least Phantasmagoria shows a 640x390 video on a 630x450 screen during the intro
+ outputWidth = frame->w > screenWidth ? screenWidth : frame->w;
+ outputHeight = frame->h > screenHeight ? screenHeight : frame->h;
+ g_system->copyRectToScreen(frame->getPixels(), frame->pitch, x, y, outputWidth, outputHeight);
if (videoDecoder->hasDirtyPalette())
g_system->getPaletteManager()->setPalette(videoDecoder->getPalette(), 0, 256);
diff --git a/engines/sci/graphics/paint16.cpp b/engines/sci/graphics/paint16.cpp
index b835eb92ca..6004e9ce7a 100644
--- a/engines/sci/graphics/paint16.cpp
+++ b/engines/sci/graphics/paint16.cpp
@@ -471,12 +471,9 @@ 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, int argc, reg_t *argv) {
+reg_t GfxPaint16::kernelDisplay(const char *text, uint16 languageSplitter, int argc, reg_t *argv) {
reg_t displayArg;
TextAlignment alignment = SCI_TEXT16_ALIGNMENT_LEFT;
int16 colorPen = -1, colorBack = -1, width = -1, bRedraw = 1;
@@ -543,22 +540,6 @@ reg_t GfxPaint16::kernelDisplay(const char *text, int argc, reg_t *argv) {
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);
@@ -572,7 +553,7 @@ reg_t GfxPaint16::kernelDisplay(const char *text, int argc, reg_t *argv) {
}
// now drawing the text
- _text16->Size(rect, text, -1, width);
+ _text16->Size(rect, text, languageSplitter, -1, width);
rect.moveTo(_ports->getPort()->curLeft, _ports->getPort()->curTop);
// Note: This code has been found in SCI1 middle and newer games. It was
// previously only for SCI1 late and newer, but the LSL1 interpreter contains
@@ -588,7 +569,7 @@ reg_t GfxPaint16::kernelDisplay(const char *text, int argc, reg_t *argv) {
result = bitsSave(rect, GFX_SCREEN_MASK_VISUAL);
if (colorBack != -1)
fillRect(rect, GFX_SCREEN_MASK_VISUAL, colorBack, 0, 0);
- _text16->Box(text, false, rect, alignment, -1);
+ _text16->Box(text, languageSplitter, false, rect, alignment, -1);
if (_screen->_picNotValid == 0 && bRedraw)
bitsShow(rect);
// restoring port and cursor pos
diff --git a/engines/sci/graphics/paint16.h b/engines/sci/graphics/paint16.h
index 882f311a5b..955cfdec8f 100644
--- a/engines/sci/graphics/paint16.h
+++ b/engines/sci/graphics/paint16.h
@@ -80,7 +80,7 @@ public:
void kernelGraphUpdateBox(const Common::Rect &rect, bool hiresMode);
void kernelGraphRedrawBox(Common::Rect rect);
- reg_t kernelDisplay(const char *text, int argc, reg_t *argv);
+ reg_t kernelDisplay(const char *text, uint16 languageSplitter, int argc, reg_t *argv);
reg_t kernelPortraitLoad(const Common::String &resourceName);
void kernelPortraitShow(const Common::String &resourceName, Common::Point position, uint16 resourceNum, uint16 noun, uint16 verb, uint16 cond, uint16 seq);
diff --git a/engines/sci/graphics/paint32.cpp b/engines/sci/graphics/paint32.cpp
index 7d106b5b02..a210a469f1 100644
--- a/engines/sci/graphics/paint32.cpp
+++ b/engines/sci/graphics/paint32.cpp
@@ -46,7 +46,7 @@ void GfxPaint32::fillRect(Common::Rect rect, byte color) {
Common::Rect clipRect = rect;
clipRect.clip(_screen->getWidth(), _screen->getHeight());
-
+
for (y = clipRect.top; y < clipRect.bottom; y++) {
for (x = clipRect.left; x < clipRect.right; x++) {
_screen->putPixel(x, y, GFX_SCREEN_MASK_VISUAL, color, 0, 0);
diff --git a/engines/sci/graphics/palette.cpp b/engines/sci/graphics/palette.cpp
index a3624c7959..59abef5550 100644
--- a/engines/sci/graphics/palette.cpp
+++ b/engines/sci/graphics/palette.cpp
@@ -65,14 +65,21 @@ GfxPalette::GfxPalette(ResourceManager *resMan, GfxScreen *screen)
// the real merging done in earlier games. If we use the copying over, we
// will get issues because some views have marked all colors as being used
// and those will overwrite the current palette in that case
- if (getSciVersion() < SCI_VERSION_1_1)
+ if (getSciVersion() < SCI_VERSION_1_1) {
_useMerging = true;
- else if (getSciVersion() == SCI_VERSION_1_1)
+ _use16bitColorMatch = true;
+ } else if (getSciVersion() == SCI_VERSION_1_1) {
// there are some games that use inbetween SCI1.1 interpreter, so we have
// to detect if the current game is merging or copying
_useMerging = _resMan->detectPaletteMergingSci11();
- else // SCI32
+ _use16bitColorMatch = _useMerging;
+ // Note: Laura Bow 2 floppy uses the new palette format and is detected
+ // as 8 bit color matching because of that.
+ } else {
+ // SCI32
_useMerging = false;
+ _use16bitColorMatch = false; // not verified that SCI32 uses 8-bit color matching
+ }
palVaryInit();
@@ -120,6 +127,10 @@ bool GfxPalette::isMerging() {
return _useMerging;
}
+bool GfxPalette::isUsing16bitColorMatch() {
+ return _use16bitColorMatch;
+}
+
// meant to get called only once during init of engine
void GfxPalette::setDefault() {
if (_resMan->getViewType() == kViewEga)
@@ -464,8 +475,8 @@ bool GfxPalette::merge(Palette *newPalette, bool force, bool forceRealMerge) {
// check if exact color could be matched
res = matchColor(newPalette->colors[i].r, newPalette->colors[i].g, newPalette->colors[i].b);
- if (res & 0x8000) { // exact match was found
- newPalette->mapping[i] = res & 0xFF;
+ if (res & SCI_PALETTE_MATCH_PERFECT) { // exact match was found
+ newPalette->mapping[i] = res & SCI_PALETTE_MATCH_COLORMASK;
continue;
}
@@ -486,8 +497,8 @@ bool GfxPalette::merge(Palette *newPalette, bool force, bool forceRealMerge) {
// if still no luck - set an approximate color
if (j == 256) {
- newPalette->mapping[i] = res & 0xFF;
- _sysPalette.colors[res & 0xFF].used |= 0x10;
+ newPalette->mapping[i] = res & SCI_PALETTE_MATCH_COLORMASK;
+ _sysPalette.colors[res & SCI_PALETTE_MATCH_COLORMASK].used |= 0x10;
}
}
@@ -509,29 +520,47 @@ void GfxPalette::drewPicture(GuiResourceId pictureId) {
}
}
-uint16 GfxPalette::matchColor(byte r, byte g, byte b) {
- byte found = 0xFF;
- int diff = 0x2FFFF, cdiff;
- int16 dr,dg,db;
-
- for (int i = 1; i < 255; i++) {
- if ((!_sysPalette.colors[i].used))
- continue;
- dr = _sysPalette.colors[i].r - r;
- dg = _sysPalette.colors[i].g - g;
- db = _sysPalette.colors[i].b - b;
-// minimum squares match
- cdiff = (dr*dr) + (dg*dg) + (db*db);
-// minimum sum match (Sierra's)
-// cdiff = ABS(dr) + ABS(dg) + ABS(db);
- if (cdiff < diff) {
- if (cdiff == 0)
- return i | 0x8000; // setting this flag to indicate exact match
- found = i;
- diff = cdiff;
+uint16 GfxPalette::matchColor(byte matchRed, byte matchGreen, byte matchBlue) {
+ int16 colorNr;
+ int16 differenceRed, differenceGreen, differenceBlue;
+ int16 differenceTotal = 0;
+ int16 bestDifference = 0x7FFF;
+ uint16 bestColorNr = 255;
+
+ if (_use16bitColorMatch) {
+ // used by SCI0 to SCI1, also by the first few SCI1.1 games
+ for (colorNr = 0; colorNr < 256; colorNr++) {
+ if ((!_sysPalette.colors[colorNr].used))
+ continue;
+ differenceRed = ABS(_sysPalette.colors[colorNr].r - matchRed);
+ differenceGreen = ABS(_sysPalette.colors[colorNr].g - matchGreen);
+ differenceBlue = ABS(_sysPalette.colors[colorNr].b - matchBlue);
+ differenceTotal = differenceRed + differenceGreen + differenceBlue;
+ if (differenceTotal <= bestDifference) {
+ bestDifference = differenceTotal;
+ bestColorNr = colorNr;
+ }
+ }
+ } else {
+ // SCI1.1, starting with QfG3 introduced a bug in the matching code
+ // we have to implement it as well, otherwise some colors will be "wrong" in comparison to the original interpreter
+ // See Space Quest 5 bug #6455
+ for (colorNr = 0; colorNr < 256; colorNr++) {
+ if ((!_sysPalette.colors[colorNr].used))
+ continue;
+ differenceRed = (uint8)ABS<int8>(_sysPalette.colors[colorNr].r - matchRed);
+ differenceGreen = (uint8)ABS<int8>(_sysPalette.colors[colorNr].g - matchGreen);
+ differenceBlue = (uint8)ABS<int8>(_sysPalette.colors[colorNr].b - matchBlue);
+ differenceTotal = differenceRed + differenceGreen + differenceBlue;
+ if (differenceTotal <= bestDifference) {
+ bestDifference = differenceTotal;
+ bestColorNr = colorNr;
+ }
}
}
- return found;
+ if (differenceTotal == 0) // original interpreter does not do this, instead it does 2 calls for merges in the worst case
+ return bestColorNr | SCI_PALETTE_MATCH_PERFECT; // we set this flag, so that we can optimize during palette merge
+ return bestColorNr;
}
void GfxPalette::getSys(Palette *pal) {
@@ -621,7 +650,7 @@ void GfxPalette::kernelSetIntensity(uint16 fromColor, uint16 toColor, uint16 int
}
int16 GfxPalette::kernelFindColor(uint16 r, uint16 g, uint16 b) {
- return matchColor(r, g, b) & 0xFF;
+ return matchColor(r, g, b) & SCI_PALETTE_MATCH_COLORMASK;
}
// Returns true, if palette got changed
diff --git a/engines/sci/graphics/palette.h b/engines/sci/graphics/palette.h
index 347695deb8..500a45eccf 100644
--- a/engines/sci/graphics/palette.h
+++ b/engines/sci/graphics/palette.h
@@ -31,6 +31,10 @@ namespace Sci {
class ResourceManager;
class GfxScreen;
+// Special flag implemented by us for optimization in palette merge
+#define SCI_PALETTE_MATCH_PERFECT 0x8000
+#define SCI_PALETTE_MATCH_COLORMASK 0xFF
+
enum ColorRemappingType {
kRemappingNone = 0,
kRemappingByRange = 1,
@@ -46,6 +50,7 @@ public:
~GfxPalette();
bool isMerging();
+ bool isUsing16bitColorMatch();
void setDefault();
void createFromData(byte *data, int bytesLeft, Palette *paletteOut);
@@ -124,6 +129,7 @@ private:
bool _sysPaletteChanged;
bool _useMerging;
+ bool _use16bitColorMatch;
Common::Array<PalSchedule> _schedules;
diff --git a/engines/sci/graphics/picture.cpp b/engines/sci/graphics/picture.cpp
index 434a490109..d7ef84dc1e 100644
--- a/engines/sci/graphics/picture.cpp
+++ b/engines/sci/graphics/picture.cpp
@@ -88,10 +88,13 @@ void GfxPicture::draw(int16 animationNr, bool mirroredFlag, bool addToFlag, int1
}
void GfxPicture::reset() {
+ int16 startY = _ports->getPort()->top;
+ int16 startX = 0;
int16 x, y;
- for (y = _ports->getPort()->top; y < _screen->getHeight(); y++) {
- for (x = 0; x < _screen->getWidth(); x++) {
- _screen->putPixel(x, y, GFX_SCREEN_MASK_ALL, 255, 0, 0);
+ _screen->vectorAdjustCoordinate(&startX, &startY);
+ for (y = startY; y < _screen->getHeight(); y++) {
+ for (x = startX; x < _screen->getWidth(); x++) {
+ _screen->vectorPutPixel(x, y, GFX_SCREEN_MASK_ALL, 255, 0, 0);
}
}
}
@@ -246,7 +249,7 @@ void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos
int16 y, lastY, x, leftX, rightX;
int pixelCount;
uint16 width, height;
-
+
// if the picture is not an overlay and we are also not in EGA mode, use priority 0
if (!isEGA && !_addToFlag)
priority = 0;
@@ -362,7 +365,7 @@ void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos
ptr = celBitmap;
ptr += skipCelBitmapPixels;
ptr += skipCelBitmapLines * width;
-
+
if ((!isEGA) || (priority < 16)) {
// VGA + EGA, EGA only checks priority, when given priority is below 16
if (!_mirroredFlag) {
@@ -482,6 +485,8 @@ enum {
PIC_OPX_VGA_PRIORITY_TABLE_EXPLICIT = 4
};
+//#define DEBUG_PICTURE_DRAW 1
+
#ifdef DEBUG_PICTURE_DRAW
const char *picOpcodeNames[] = {
"Set color",
@@ -589,6 +594,9 @@ void GfxPicture::drawVectorData(byte *data, int dataSize) {
while (curPos < dataSize) {
#ifdef DEBUG_PICTURE_DRAW
debug("Picture op: %X (%s) at %d", data[curPos], picOpcodeNames[data[curPos] - 0xF0], curPos);
+ _screen->copyToScreen();
+ g_system->updateScreen();
+ g_system->delayMillis(400);
#endif
switch (pic_op = data[curPos++]) {
case PIC_OP_SET_COLOR:
@@ -934,17 +942,17 @@ void GfxPicture::vectorFloodFill(int16 x, int16 y, byte color, byte priority, by
Common::Point p, p1;
byte screenMask = _screen->getDrawingMask(color, priority, control);
byte matchedMask, matchMask;
- int16 w, e, a_set, b_set;
bool isEGA = (_resMan->getViewType() == kViewEga);
p.x = x + curPort->left;
p.y = y + curPort->top;
- stack.push(p);
- byte searchColor = _screen->getVisual(p.x, p.y);
- byte searchPriority = _screen->getPriority(p.x, p.y);
- byte searchControl = _screen->getControl(p.x, p.y);
+ _screen->vectorAdjustCoordinate(&p.x, &p.y);
+
+ byte searchColor = _screen->vectorGetVisual(p.x, p.y);
+ byte searchPriority = _screen->vectorGetPriority(p.x, p.y);
+ byte searchControl = _screen->vectorGetControl(p.x, p.y);
if (isEGA) {
// In EGA games a pixel in the framebuffer is only 4 bits. We store
@@ -991,22 +999,31 @@ void GfxPicture::vectorFloodFill(int16 x, int16 y, byte color, byte priority, by
}
// hard borders for filling
- int l = curPort->rect.left + curPort->left;
- int t = curPort->rect.top + curPort->top;
- int r = curPort->rect.right + curPort->left - 1;
- int b = curPort->rect.bottom + curPort->top - 1;
+ int16 borderLeft = curPort->rect.left + curPort->left;
+ int16 borderTop = curPort->rect.top + curPort->top;
+ int16 borderRight = curPort->rect.right + curPort->left - 1;
+ int16 borderBottom = curPort->rect.bottom + curPort->top - 1;
+ int16 curToLeft, curToRight, a_set, b_set;
+
+ // Translate coordinates, if required (needed for Macintosh 480x300)
+ _screen->vectorAdjustCoordinate(&borderLeft, &borderTop);
+ _screen->vectorAdjustCoordinate(&borderRight, &borderBottom);
+ //return;
+
+ stack.push(p);
+
while (stack.size()) {
p = stack.pop();
- if ((matchedMask = _screen->isFillMatch(p.x, p.y, matchMask, searchColor, searchPriority, searchControl, isEGA)) == 0) // already filled
+ if ((matchedMask = _screen->vectorIsFillMatch(p.x, p.y, matchMask, searchColor, searchPriority, searchControl, isEGA)) == 0) // already filled
continue;
- _screen->putPixel(p.x, p.y, screenMask, color, priority, control);
- w = p.x;
- e = p.x;
+ _screen->vectorPutPixel(p.x, p.y, screenMask, color, priority, control);
+ curToLeft = p.x;
+ curToRight = p.x;
// moving west and east pointers as long as there is a matching color to fill
- while (w > l && (matchedMask = _screen->isFillMatch(w - 1, p.y, matchMask, searchColor, searchPriority, searchControl, isEGA)))
- _screen->putPixel(--w, p.y, screenMask, color, priority, control);
- while (e < r && (matchedMask = _screen->isFillMatch(e + 1, p.y, matchMask, searchColor, searchPriority, searchControl, isEGA)))
- _screen->putPixel(++e, p.y, screenMask, color, priority, control);
+ while (curToLeft > borderLeft && (matchedMask = _screen->vectorIsFillMatch(curToLeft - 1, p.y, matchMask, searchColor, searchPriority, searchControl, isEGA)))
+ _screen->vectorPutPixel(--curToLeft, p.y, screenMask, color, priority, control);
+ while (curToRight < borderRight && (matchedMask = _screen->vectorIsFillMatch(curToRight + 1, p.y, matchMask, searchColor, searchPriority, searchControl, isEGA)))
+ _screen->vectorPutPixel(++curToRight, p.y, screenMask, color, priority, control);
#if 0
// debug code for floodfill
_screen->copyToScreen();
@@ -1015,10 +1032,10 @@ void GfxPicture::vectorFloodFill(int16 x, int16 y, byte color, byte priority, by
#endif
// checking lines above and below for possible flood targets
a_set = b_set = 0;
- while (w <= e) {
- if (p.y > t && (matchedMask = _screen->isFillMatch(w, p.y - 1, matchMask, searchColor, searchPriority, searchControl, isEGA))) { // one line above
+ while (curToLeft <= curToRight) {
+ if (p.y > borderTop && (matchedMask = _screen->vectorIsFillMatch(curToLeft, p.y - 1, matchMask, searchColor, searchPriority, searchControl, isEGA))) { // one line above
if (a_set == 0) {
- p1.x = w;
+ p1.x = curToLeft;
p1.y = p.y - 1;
stack.push(p1);
a_set = 1;
@@ -1026,16 +1043,16 @@ void GfxPicture::vectorFloodFill(int16 x, int16 y, byte color, byte priority, by
} else
a_set = 0;
- if (p.y < b && (matchedMask = _screen->isFillMatch(w, p.y + 1, matchMask, searchColor, searchPriority, searchControl, isEGA))) { // one line below
+ if (p.y < borderBottom && (matchedMask = _screen->vectorIsFillMatch(curToLeft, p.y + 1, matchMask, searchColor, searchPriority, searchControl, isEGA))) { // one line below
if (b_set == 0) {
- p1.x = w;
+ p1.x = curToLeft;
p1.y = p.y + 1;
stack.push(p1);
b_set = 1;
}
} else
b_set = 0;
- w++;
+ curToLeft++;
}
}
}
@@ -1173,7 +1190,7 @@ void GfxPicture::vectorPatternBox(Common::Rect box, byte color, byte prio, byte
for (y = box.top; y < box.bottom; y++) {
for (x = box.left; x < box.right; x++) {
- _screen->putPixel(x, y, flag, color, prio, control);
+ _screen->vectorPutPixel(x, y, flag, color, prio, control);
}
}
}
@@ -1186,7 +1203,7 @@ void GfxPicture::vectorPatternTexturedBox(Common::Rect box, byte color, byte pri
for (y = box.top; y < box.bottom; y++) {
for (x = box.left; x < box.right; x++) {
if (*textureData) {
- _screen->putPixel(x, y, flag, color, prio, control);
+ _screen->vectorPutPixel(x, y, flag, color, prio, control);
}
textureData++;
}
@@ -1203,7 +1220,7 @@ void GfxPicture::vectorPatternCircle(Common::Rect box, byte size, byte color, by
for (y = box.top; y < box.bottom; y++) {
for (x = box.left; x < box.right; x++) {
if (bitmap & 1) {
- _screen->putPixel(x, y, flag, color, prio, control);
+ _screen->vectorPutPixel(x, y, flag, color, prio, control);
}
bitNo++;
if (bitNo == 8) {
@@ -1222,12 +1239,12 @@ void GfxPicture::vectorPatternTexturedCircle(Common::Rect box, byte size, byte c
byte bitNo = 0;
const bool *textureData = &vectorPatternTextures[vectorPatternTextureOffset[texture]];
int y, x;
-
+
for (y = box.top; y < box.bottom; y++) {
for (x = box.left; x < box.right; x++) {
if (bitmap & 1) {
if (*textureData) {
- _screen->putPixel(x, y, flag, color, prio, control);
+ _screen->vectorPutPixel(x, y, flag, color, prio, control);
}
textureData++;
}
@@ -1252,7 +1269,10 @@ void GfxPicture::vectorPattern(int16 x, int16 y, byte color, byte priority, byte
rect.top = y; rect.left = x;
rect.setHeight((size*2)+1); rect.setWidth((size*2)+2);
_ports->offsetRect(rect);
- rect.clip(_screen->getWidth(), _screen->getHeight());
+ rect.clip(_screen->getScriptWidth(), _screen->getScriptHeight());
+
+ _screen->vectorAdjustCoordinate(&rect.left, &rect.top);
+ _screen->vectorAdjustCoordinate(&rect.right, &rect.bottom);
if (code & SCI_PATTERN_CODE_RECTANGLE) {
// Rectangle
diff --git a/engines/sci/graphics/portrait.cpp b/engines/sci/graphics/portrait.cpp
index 488450485d..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");
@@ -134,34 +160,34 @@ void Portrait::init() {
// raw lip-sync ID table follows
uint32 lipSyncIDTableSize;
-
+
lipSyncIDTableSize = READ_LE_UINT32(data);
data += 4;
assert( lipSyncIDTableSize == (_lipSyncIDCount * 4) );
_lipSyncIDTable = data;
data += lipSyncIDTableSize;
-
+
// raw lip-sync frame table follows
uint32 lipSyncDataTableSize;
uint32 lipSyncDataTableLastOffset;
byte lipSyncData;
uint16 lipSyncDataNr;
uint16 lipSyncCurOffset;
-
+
lipSyncDataTableSize = READ_LE_UINT32(data);
data += 4;
assert( lipSyncDataTableSize == 0x220 ); // always this size, just a safety-check
-
+
_lipSyncData = data;
lipSyncDataTableLastOffset = lipSyncDataTableSize - 1;
_lipSyncDataOffsetTable = new uint16[ _lipSyncIDCount ];
-
+
lipSyncDataNr = 0;
lipSyncCurOffset = 0;
while ( (lipSyncCurOffset < lipSyncDataTableSize) && (lipSyncDataNr < _lipSyncIDCount) ) {
// We are currently at the start of ID-frame data
_lipSyncDataOffsetTable[lipSyncDataNr] = lipSyncCurOffset;
-
+
// Look for end of ID-frame data
lipSyncData = *data++; lipSyncCurOffset++;
while ( (lipSyncData != 0xFF) && (lipSyncCurOffset < lipSyncDataTableLastOffset) ) {
@@ -195,15 +221,16 @@ void Portrait::doit(Common::Point position, uint16 resourceId, uint16 noun, uint
Resource *syncResource = _resMan->findResource(syncResourceId, true);
uint syncOffset = 0;
#endif
-
+
#ifdef DEBUG_PORTRAIT
// prints out the current lip sync ASCII data
char debugPrint[4000];
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
@@ -246,7 +273,7 @@ void Portrait::doit(Common::Point position, uint16 resourceId, uint16 noun, uint
warning("kPortrait: no rave resource %d %X", resourceId, audioNumber);
return;
}
-
+
// Do animation depending on rave resource till audio is done playing
int16 raveTicks;
uint16 raveID;
@@ -264,7 +291,7 @@ void Portrait::doit(Common::Point position, uint16 resourceId, uint16 noun, uint
raveTicks = raveGetTicks(raveResource, &raveOffset);
if (raveTicks < 0)
break;
-
+
// get lipSyncID
raveID = raveGetID(raveResource, &raveOffset);
if (raveID) {
@@ -272,7 +299,15 @@ void Portrait::doit(Common::Point position, uint16 resourceId, uint16 noun, uint
} else {
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,12 +317,13 @@ 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));
}
-
+
if (raveLipSyncData) {
// lip sync data is
// Tick:Byte, Bitmap-Nr:BYTE
@@ -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,7 +346,14 @@ 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--;
@@ -319,7 +364,7 @@ void Portrait::doit(Common::Point position, uint16 resourceId, uint16 noun, uint
} else {
warning("kPortrait: rave lip sync data tried to draw non-existent bitmap %d", raveLipSyncBitmapNr);
}
-
+
raveLipSyncTicks = *raveLipSyncData++;
}
}
@@ -372,7 +417,7 @@ void Portrait::doit(Common::Point position, uint16 resourceId, uint16 noun, uint
}
}
#endif
-
+
// Reset the portrait bitmap to "closed mouth" state (rave.dll seems to do the same)
drawBitmap(0);
bitsShow();
@@ -393,10 +438,10 @@ int16 Portrait::raveGetTicks(Resource *resource, uint *offset) {
byte *curData = resource->data + curOffset;
byte curByte;
uint16 curValue = 0;
-
+
if (curOffset >= resource->size)
return -1;
-
+
while (curOffset < resource->size) {
curByte = *curData++; curOffset++;
if ( curByte == ' ' )
@@ -418,7 +463,7 @@ uint16 Portrait::raveGetID(Resource *resource, uint *offset) {
byte *curData = resource->data + curOffset;
byte curByte = 0;
uint16 curValue = 0;
-
+
while (curOffset < resource->size) {
curByte = *curData++; curOffset++;
if ( curByte == ' ' )
@@ -429,7 +474,7 @@ uint16 Portrait::raveGetID(Resource *resource, uint *offset) {
curValue |= curByte;
}
}
-
+
*offset = curOffset;
return curValue;
}
@@ -440,17 +485,17 @@ byte *Portrait::raveGetLipSyncData(uint16 raveID) {
byte *lipSyncIDPtr = _lipSyncIDTable;
byte lipSyncIDByte1, lipSyncIDByte2;
uint16 lipSyncID;
-
+
lipSyncIDPtr++; // skip over first byte
while (lipSyncIDNr < _lipSyncIDCount) {
lipSyncIDByte1 = *lipSyncIDPtr++;
lipSyncIDByte2 = *lipSyncIDPtr++;
lipSyncID = ( lipSyncIDByte1 << 8 ) | lipSyncIDByte2;
-
+
if ( lipSyncID == raveID ) {
return _lipSyncData + _lipSyncDataOffsetTable[lipSyncIDNr];
}
-
+
lipSyncIDNr++;
lipSyncIDPtr += 2; // ID is every 4 bytes
}
diff --git a/engines/sci/graphics/portrait.h b/engines/sci/graphics/portrait.h
index 877b253bcf..e0888daa86 100644
--- a/engines/sci/graphics/portrait.h
+++ b/engines/sci/graphics/portrait.h
@@ -72,7 +72,7 @@ private:
Common::String _resourceName;
byte *_fileData;
-
+
uint32 _lipSyncIDCount;
byte *_lipSyncIDTable;
diff --git a/engines/sci/graphics/ports.cpp b/engines/sci/graphics/ports.cpp
index 56c63a7b12..bcc991081e 100644
--- a/engines/sci/graphics/ports.cpp
+++ b/engines/sci/graphics/ports.cpp
@@ -63,10 +63,10 @@ void GfxPorts::init(bool usesOldGfxFunctions, GfxPaint16 *paint16, GfxText16 *te
openPort(_menuPort);
setPort(_menuPort);
_text16->SetFont(0);
- _menuPort->rect = Common::Rect(0, 0, _screen->getWidth(), _screen->getHeight());
- _menuBarRect = Common::Rect(0, 0, _screen->getWidth(), 9);
- _menuRect = Common::Rect(0, 0, _screen->getWidth(), 10);
- _menuLine = Common::Rect(0, 9, _screen->getWidth(), 10);
+ _menuPort->rect = Common::Rect(0, 0, _screen->getScriptWidth(), _screen->getScriptHeight());
+ _menuBarRect = Common::Rect(0, 0, _screen->getScriptWidth(), 9);
+ _menuRect = Common::Rect(0, 0, _screen->getScriptWidth(), 10);
+ _menuLine = Common::Rect(0, 9, _screen->getScriptWidth(), 10);
_wmgrPort = new Port(1);
_windowsById.resize(2);
@@ -122,13 +122,13 @@ void GfxPorts::init(bool usesOldGfxFunctions, GfxPaint16 *paint16, GfxText16 *te
} else {
_wmgrPort->rect.bottom = _screen->getHeight();
}
- _wmgrPort->rect.right = _screen->getWidth();
+ _wmgrPort->rect.right = _screen->getScriptWidth();
_wmgrPort->rect.moveTo(0, 0);
_wmgrPort->curTop = 0;
_wmgrPort->curLeft = 0;
_windowList.push_front(_wmgrPort);
- _picWind = addWindow(Common::Rect(0, offTop, _screen->getWidth(), _screen->getHeight()), 0, 0, SCI_WINDOWMGR_STYLE_TRANSPARENT | SCI_WINDOWMGR_STYLE_NOFRAME, 0, true);
+ _picWind = addWindow(Common::Rect(0, offTop, _screen->getScriptWidth(), _screen->getScriptHeight()), 0, 0, SCI_WINDOWMGR_STYLE_TRANSPARENT | SCI_WINDOWMGR_STYLE_NOFRAME, 0, true);
// For SCI0 games till kq4 (.502 - not including) we set _picWind top to offTop instead
// Because of the menu/status bar
if (_usesOldGfxFunctions)
@@ -321,13 +321,13 @@ Window *GfxPorts::addWindow(const Common::Rect &dims, const Common::Rect *restor
// their interpreter even in the newer VGA games.
r.left = r.left & 0xFFFE;
- if (r.width() > _screen->getWidth()) {
+ if (r.width() > _screen->getScriptWidth()) {
// We get invalid dimensions at least at the end of sq3 (script bug!).
// Same happens very often in lsl5, sierra sci didnt fix it but it looked awful.
// Also happens frequently in the demo of GK1.
warning("Fixing too large window, left: %d, right: %d", dims.left, dims.right);
r.left = 0;
- r.right = _screen->getWidth() - 1;
+ r.right = _screen->getScriptWidth() - 1;
if ((style != _styleUser) && !(style & SCI_WINDOWMGR_STYLE_NOFRAME))
r.right--;
}
diff --git a/engines/sci/graphics/screen.cpp b/engines/sci/graphics/screen.cpp
index c5c94d7991..ca5b5b3b8c 100644
--- a/engines/sci/graphics/screen.cpp
+++ b/engines/sci/graphics/screen.cpp
@@ -37,7 +37,15 @@ GfxScreen::GfxScreen(ResourceManager *resMan) : _resMan(resMan) {
// Scale the screen, if needed
_upscaledHires = GFX_SCREEN_UPSCALED_DISABLED;
-
+
+ // we default to scripts running at 320x200
+ _scriptWidth = 320;
+ _scriptHeight = 200;
+ _width = 0;
+ _height = 0;
+ _displayWidth = 0;
+ _displayHeight = 0;
+
// King's Quest 6 and Gabriel Knight 1 have hires content, gk1/cd was able
// to provide that under DOS as well, but as gk1/floppy does support
// upscaled hires scriptswise, but doesn't actually have the hires content
@@ -50,10 +58,34 @@ GfxScreen::GfxScreen(ResourceManager *resMan) : _resMan(resMan) {
_upscaledHires = GFX_SCREEN_UPSCALED_640x480;
#endif
}
+
+ // Japanese versions of games use hi-res font on upscaled version of the game.
+ if ((g_sci->getLanguage() == Common::JA_JPN) && (getSciVersion() <= SCI_VERSION_1_1))
+ _upscaledHires = GFX_SCREEN_UPSCALED_640x400;
+ // Macintosh SCI0 games used 480x300, while the scripts were running at 320x200
if (g_sci->getPlatform() == Common::kPlatformMacintosh) {
- if (getSciVersion() <= SCI_VERSION_01)
+ if (getSciVersion() <= SCI_VERSION_01) {
_upscaledHires = GFX_SCREEN_UPSCALED_480x300;
+ _width = 480;
+ _height = 300; // regular visual, priority and control map are 480x300 (this is different than other upscaled SCI games)
+ }
+
+ // Some Mac SCI1/1.1 games only take up 190 rows and do not
+ // have the menu bar.
+ // TODO: Verify that LSL1 and LSL5 use height 190
+ switch (g_sci->getGameId()) {
+ case GID_FREDDYPHARKAS:
+ case GID_KQ5:
+ case GID_KQ6:
+ case GID_LSL1:
+ case GID_LSL5:
+ case GID_SQ1:
+ _scriptHeight = 190;
+ break;
+ default:
+ break;
+ }
}
#ifdef ENABLE_SCI32
@@ -65,76 +97,77 @@ GfxScreen::GfxScreen(ResourceManager *resMan) : _resMan(resMan) {
#endif
if (_resMan->detectHires()) {
- _width = 640;
- _pitch = 640;
- _height = 480;
- } else {
- _width = 320;
- _pitch = 320;
- _height = getLowResScreenHeight();
+ _scriptWidth = 640;
+ _scriptHeight = 480;
}
#ifdef ENABLE_SCI32
- // Phantasmagoria 1 sets a window area of 630x450
+ // Phantasmagoria 1 effectively outputs 630x450
+ // Coordinate translation has to use this resolution as well
if (g_sci->getGameId() == GID_PHANTASMAGORIA) {
_width = 630;
_height = 450;
}
#endif
- // Japanese versions of games use hi-res font on upscaled version of the game.
- if ((g_sci->getLanguage() == Common::JA_JPN) && (getSciVersion() <= SCI_VERSION_1_1))
- _upscaledHires = GFX_SCREEN_UPSCALED_640x400;
+ // if not yet set, set those to script-width/height
+ if (!_width)
+ _width = _scriptWidth;
+ if (!_height)
+ _height = _scriptHeight;
- _pixels = _pitch * _height;
+ _pixels = _width * _height;
switch (_upscaledHires) {
case GFX_SCREEN_UPSCALED_480x300:
// Space Quest 3, Hoyle 1+2 on MAC use this one
- // TODO: Sierra's upscaling worked differently. We need to figure out the exact algo
_displayWidth = 480;
_displayHeight = 300;
- for (int i = 0; i <= _height; i++)
+ for (int i = 0; i <= _scriptHeight; i++)
_upscaledHeightMapping[i] = (i * 3) >> 1;
- for (int i = 0; i <= _width; i++)
+ for (int i = 0; i <= _scriptWidth; i++)
_upscaledWidthMapping[i] = (i * 3) >> 1;
break;
case GFX_SCREEN_UPSCALED_640x400:
// Police Quest 2 and Quest For Glory on PC9801 (Japanese)
_displayWidth = 640;
_displayHeight = 400;
- for (int i = 0; i <= _height; i++)
+ for (int i = 0; i <= _scriptHeight; i++)
_upscaledHeightMapping[i] = i * 2;
- for (int i = 0; i <= _width; i++)
+ for (int i = 0; i <= _scriptWidth; i++)
_upscaledWidthMapping[i] = i * 2;
break;
case GFX_SCREEN_UPSCALED_640x440:
// used by King's Quest 6 on Windows
_displayWidth = 640;
_displayHeight = 440;
- for (int i = 0; i <= _height; i++)
+ for (int i = 0; i <= _scriptHeight; i++)
_upscaledHeightMapping[i] = (i * 11) / 5;
- for (int i = 0; i <= _width; i++)
+ for (int i = 0; i <= _scriptWidth; i++)
_upscaledWidthMapping[i] = i * 2;
break;
case GFX_SCREEN_UPSCALED_640x480:
// Gabriel Knight 1 (VESA, Mac)
_displayWidth = 640;
_displayHeight = 480;
- for (int i = 0; i <= _height; i++)
+ for (int i = 0; i <= _scriptHeight; i++)
_upscaledHeightMapping[i] = (i * 12) / 5;
- for (int i = 0; i <= _width; i++)
+ for (int i = 0; i <= _scriptWidth; i++)
_upscaledWidthMapping[i] = i * 2;
break;
default:
- _displayWidth = _pitch;
- _displayHeight = _height;
+ if (!_displayWidth)
+ _displayWidth = _width;
+ if (!_displayHeight)
+ _displayHeight = _height;
memset(&_upscaledHeightMapping, 0, sizeof(_upscaledHeightMapping) );
memset(&_upscaledWidthMapping, 0, sizeof(_upscaledWidthMapping) );
break;
}
_displayPixels = _displayWidth * _displayHeight;
+
+ // Allocate visual, priority, control and display screen
_visualScreen = (byte *)calloc(_pixels, 1);
_priorityScreen = (byte *)calloc(_pixels, 1);
_controlScreen = (byte *)calloc(_pixels, 1);
@@ -179,6 +212,36 @@ GfxScreen::GfxScreen(ResourceManager *resMan) : _resMan(resMan) {
error("Unknown SCI1.1 Mac game");
} else
initGraphics(_displayWidth, _displayHeight, _displayWidth > 320);
+
+ // Initialize code pointers
+ _vectorAdjustCoordinatePtr = &GfxScreen::vectorAdjustCoordinateNOP;
+ _vectorAdjustLineCoordinatesPtr = &GfxScreen::vectorAdjustLineCoordinatesNOP;
+ _vectorIsFillMatchPtr = &GfxScreen::vectorIsFillMatchNormal;
+ _vectorPutPixelPtr = &GfxScreen::putPixelNormal;
+ _vectorPutLinePixelPtr = &GfxScreen::putPixel;
+ _vectorGetPixelPtr = &GfxScreen::getPixelNormal;
+ _putPixelPtr = &GfxScreen::putPixelNormal;
+ _getPixelPtr = &GfxScreen::getPixelNormal;
+
+ switch (_upscaledHires) {
+ case GFX_SCREEN_UPSCALED_480x300:
+ _vectorAdjustCoordinatePtr = &GfxScreen::vectorAdjustCoordinate480x300Mac;
+ _vectorAdjustLineCoordinatesPtr = &GfxScreen::vectorAdjustLineCoordinates480x300Mac;
+ // vectorPutPixel -> we already adjust coordinates for vector code, that's why we can set pixels directly
+ // vectorGetPixel -> see vectorPutPixel
+ _vectorPutLinePixelPtr = &GfxScreen::vectorPutLinePixel480x300Mac;
+ _putPixelPtr = &GfxScreen::putPixelAllUpscaled;
+ _getPixelPtr = &GfxScreen::getPixelUpscaled;
+ break;
+ case GFX_SCREEN_UPSCALED_640x400:
+ case GFX_SCREEN_UPSCALED_640x440:
+ case GFX_SCREEN_UPSCALED_640x480:
+ _vectorPutPixelPtr = &GfxScreen::putPixelDisplayUpscaled;
+ _putPixelPtr = &GfxScreen::putPixelDisplayUpscaled;
+ break;
+ case GFX_SCREEN_UPSCALED_DISABLED:
+ break;
+ }
}
GfxScreen::~GfxScreen() {
@@ -188,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);
}
@@ -232,7 +307,7 @@ void GfxScreen::copyRectToScreen(const Common::Rect &rect, int16 x, int16 y) {
} else {
int rectHeight = _upscaledHeightMapping[rect.bottom] - _upscaledHeightMapping[rect.top];
int rectWidth = _upscaledWidthMapping[rect.right] - _upscaledWidthMapping[rect.left];
-
+
g_system->copyRectToScreen(_activeScreen + _upscaledHeightMapping[rect.top] * _displayWidth + _upscaledWidthMapping[rect.left], _displayWidth, _upscaledWidthMapping[x], _upscaledHeightMapping[y], rectWidth, rectHeight);
}
}
@@ -248,43 +323,162 @@ byte GfxScreen::getDrawingMask(byte color, byte prio, byte control) {
return flag;
}
-void GfxScreen::putPixel(int x, int y, byte drawMask, byte color, byte priority, byte control) {
- int offset = y * _pitch + x;
+void GfxScreen::vectorAdjustCoordinateNOP(int16 *x, int16 *y) {
+}
- if (drawMask & GFX_SCREEN_MASK_VISUAL) {
- _visualScreen[offset] = color;
- if (!_upscaledHires) {
- _displayScreen[offset] = color;
+void GfxScreen::vectorAdjustCoordinate480x300Mac(int16 *x, int16 *y) {
+ *x = _upscaledWidthMapping[*x];
+ *y = _upscaledHeightMapping[*y];
+}
+
+void GfxScreen::vectorAdjustLineCoordinatesNOP(int16 *left, int16 *top, int16 *right, int16 *bottom, byte drawMask, byte color, byte priority, byte control) {
+}
+
+void GfxScreen::vectorAdjustLineCoordinates480x300Mac(int16 *left, int16 *top, int16 *right, int16 *bottom, byte drawMask, byte color, byte priority, byte control) {
+ int16 displayLeft = _upscaledWidthMapping[*left];
+ int16 displayRight = _upscaledWidthMapping[*right];
+ int16 displayTop = _upscaledHeightMapping[*top];
+ int16 displayBottom = _upscaledHeightMapping[*bottom];
+
+ if (displayLeft < displayRight) {
+ // one more pixel to the left, one more pixel to the right
+ if (displayLeft > 0)
+ vectorPutLinePixel(displayLeft - 1, displayTop, drawMask, color, priority, control);
+ vectorPutLinePixel(displayRight + 1, displayBottom, drawMask, color, priority, control);
+ } else if (displayLeft > displayRight) {
+ if (displayRight > 0)
+ vectorPutLinePixel(displayRight - 1, displayBottom, drawMask, color, priority, control);
+ vectorPutLinePixel(displayLeft + 1, displayTop, drawMask, color, priority, control);
+ }
+ *left = displayLeft;
+ *top = displayTop;
+ *right = displayRight;
+ *bottom = displayBottom;
+}
+
+byte GfxScreen::vectorIsFillMatchNormal(int16 x, int16 y, byte screenMask, byte checkForColor, byte checkForPriority, byte checkForControl, bool isEGA) {
+ int offset = y * _width + x;
+ byte match = 0;
+
+ if (screenMask & GFX_SCREEN_MASK_VISUAL) {
+ if (!isEGA) {
+ if (*(_visualScreen + offset) == checkForColor)
+ match |= GFX_SCREEN_MASK_VISUAL;
} else {
- putScaledPixelOnDisplay(x, y, color);
+ // In EGA games a pixel in the framebuffer is only 4 bits. We store
+ // a full byte per pixel to allow undithering, but when comparing
+ // pixels for flood-fill purposes, we should only compare the
+ // visible color of a pixel.
+
+ byte EGAcolor = *(_visualScreen + offset);
+ if ((x ^ y) & 1)
+ EGAcolor = (EGAcolor ^ (EGAcolor >> 4)) & 0x0F;
+ else
+ EGAcolor = EGAcolor & 0x0F;
+ if (EGAcolor == checkForColor)
+ match |= GFX_SCREEN_MASK_VISUAL;
}
}
+ if ((screenMask & GFX_SCREEN_MASK_PRIORITY) && *(_priorityScreen + offset) == checkForPriority)
+ match |= GFX_SCREEN_MASK_PRIORITY;
+ if ((screenMask & GFX_SCREEN_MASK_CONTROL) && *(_controlScreen + offset) == checkForControl)
+ match |= GFX_SCREEN_MASK_CONTROL;
+ return match;
+}
+
+// Special 480x300 Mac putPixel for vector line drawing, also draws an additional pixel below the actual one
+void GfxScreen::vectorPutLinePixel480x300Mac(int16 x, int16 y, byte drawMask, byte color, byte priority, byte control) {
+ int offset = y * _width + x;
+
+ if (drawMask & GFX_SCREEN_MASK_VISUAL) {
+ _visualScreen[offset] = color;
+ _visualScreen[offset + _width] = color;
+ _displayScreen[offset] = color;
+ // also set pixel below actual pixel
+ _displayScreen[offset + _displayWidth] = color;
+ }
+ if (drawMask & GFX_SCREEN_MASK_PRIORITY) {
+ _priorityScreen[offset] = priority;
+ _priorityScreen[offset + _width] = priority;
+ }
+ if (drawMask & GFX_SCREEN_MASK_CONTROL) {
+ _controlScreen[offset] = control;
+ _controlScreen[offset + _width] = control;
+ }
+}
+
+// Directly sets a pixel on various screens, display is not upscaled
+void GfxScreen::putPixelNormal(int16 x, int16 y, byte drawMask, byte color, byte priority, byte control) {
+ int offset = y * _width + x;
+
+ if (drawMask & GFX_SCREEN_MASK_VISUAL) {
+ _visualScreen[offset] = color;
+ _displayScreen[offset] = color;
+ }
if (drawMask & GFX_SCREEN_MASK_PRIORITY)
_priorityScreen[offset] = priority;
if (drawMask & GFX_SCREEN_MASK_CONTROL)
_controlScreen[offset] = control;
}
+// Directly sets a pixel on various screens, display IS upscaled
+void GfxScreen::putPixelDisplayUpscaled(int16 x, int16 y, byte drawMask, byte color, byte priority, byte control) {
+ int offset = y * _width + x;
+
+ if (drawMask & GFX_SCREEN_MASK_VISUAL) {
+ _visualScreen[offset] = color;
+ putScaledPixelOnScreen(_displayScreen, x, y, color);
+ }
+ if (drawMask & GFX_SCREEN_MASK_PRIORITY)
+ _priorityScreen[offset] = priority;
+ if (drawMask & GFX_SCREEN_MASK_CONTROL)
+ _controlScreen[offset] = control;
+}
+
+// Directly sets a pixel on various screens, ALL screens ARE upscaled
+void GfxScreen::putPixelAllUpscaled(int16 x, int16 y, byte drawMask, byte color, byte priority, byte control) {
+ if (drawMask & GFX_SCREEN_MASK_VISUAL) {
+ putScaledPixelOnScreen(_visualScreen, x, y, color);
+ putScaledPixelOnScreen(_displayScreen, x, y, color);
+ }
+ if (drawMask & GFX_SCREEN_MASK_PRIORITY)
+ putScaledPixelOnScreen(_priorityScreen, x, y, priority);
+ if (drawMask & GFX_SCREEN_MASK_CONTROL)
+ putScaledPixelOnScreen(_controlScreen, x, y, control);
+}
+
/**
* This is used to put font pixels onto the screen - we adjust differently, so that we won't
* do triple pixel lines in any case on upscaled hires. That way the font will not get distorted
* Sierra SCI didn't do this
*/
-void GfxScreen::putFontPixel(int startingY, int x, int y, byte color) {
- int actualY = startingY + y;
+void GfxScreen::putFontPixel(int16 startingY, int16 x, int16 y, byte color) {
+ int16 actualY = startingY + y;
if (_fontIsUpscaled) {
// Do not scale ourselves, but put it on the display directly
putPixelOnDisplay(x, actualY, color);
} else {
- int offset = actualY * _pitch + x;
+ int offset = actualY * _width + x;
_visualScreen[offset] = color;
switch (_upscaledHires) {
case GFX_SCREEN_UPSCALED_DISABLED:
_displayScreen[offset] = color;
break;
+ case GFX_SCREEN_UPSCALED_640x400:
+ case GFX_SCREEN_UPSCALED_640x440:
+ case GFX_SCREEN_UPSCALED_640x480: {
+ // to 1-> 4 pixels upscaling for all of those, so that fonts won't look weird
+ int displayOffset = (_upscaledHeightMapping[startingY] + y * 2) * _displayWidth + x * 2;
+ _displayScreen[displayOffset] = color;
+ _displayScreen[displayOffset + 1] = color;
+ displayOffset += _displayWidth;
+ _displayScreen[displayOffset] = color;
+ _displayScreen[displayOffset + 1] = color;
+ break;
+ }
default:
- putScaledPixelOnDisplay(x, actualY, color);
+ putScaledPixelOnScreen(_displayScreen, x, actualY, color);
break;
}
}
@@ -295,12 +489,15 @@ void GfxScreen::putFontPixel(int startingY, int x, int y, byte color) {
* only used on upscaled-Hires games where hires content needs to get drawn ONTO
* the upscaled display screen (like japanese fonts, hires portraits, etc.).
*/
-void GfxScreen::putPixelOnDisplay(int x, int y, byte color) {
+void GfxScreen::putPixelOnDisplay(int16 x, int16 y, byte color) {
int offset = y * _displayWidth + x;
_displayScreen[offset] = color;
}
-void GfxScreen::putScaledPixelOnDisplay(int x, int y, byte color) {
+//void GfxScreen::putScaledPixelOnDisplay(int16 x, int16 y, byte color) {
+//}
+
+void GfxScreen::putScaledPixelOnScreen(byte *screen, int16 x, int16 y, byte data) {
int displayOffset = _upscaledHeightMapping[y] * _displayWidth + _upscaledWidthMapping[x];
int heightOffsetBreak = (_upscaledHeightMapping[y + 1] - _upscaledHeightMapping[y]) * _displayWidth;
int heightOffset = 0;
@@ -308,7 +505,7 @@ void GfxScreen::putScaledPixelOnDisplay(int x, int y, byte color) {
do {
int widthOffset = 0;
do {
- _displayScreen[displayOffset + heightOffset + widthOffset] = color;
+ screen[displayOffset + heightOffset + widthOffset] = data;
widthOffset++;
} while (widthOffset != widthOffsetBreak);
heightOffset += _displayWidth;
@@ -329,16 +526,18 @@ void GfxScreen::drawLine(Common::Point startPoint, Common::Point endPoint, byte
int16 top = CLIP<int16>(startPoint.y, 0, maxHeight);
int16 right = CLIP<int16>(endPoint.x, 0, maxWidth);
int16 bottom = CLIP<int16>(endPoint.y, 0, maxHeight);
-
+
//set_drawing_flag
byte drawMask = getDrawingMask(color, priority, control);
+ vectorAdjustLineCoordinates(&left, &top, &right, &bottom, drawMask, color, priority, control);
+
// horizontal line
if (top == bottom) {
if (right < left)
SWAP(right, left);
for (int i = left; i <= right; i++)
- putPixel(i, top, drawMask, color, priority, control);
+ vectorPutLinePixel(i, top, drawMask, color, priority, control);
return;
}
// vertical line
@@ -346,20 +545,20 @@ void GfxScreen::drawLine(Common::Point startPoint, Common::Point endPoint, byte
if (top > bottom)
SWAP(top, bottom);
for (int i = top; i <= bottom; i++)
- putPixel(left, i, drawMask, color, priority, control);
+ vectorPutLinePixel(left, i, drawMask, color, priority, control);
return;
}
// sloped line - draw with Bresenham algorithm
- int dy = bottom - top;
- int dx = right - left;
- int stepy = dy < 0 ? -1 : 1;
- int stepx = dx < 0 ? -1 : 1;
+ int16 dy = bottom - top;
+ int16 dx = right - left;
+ int16 stepy = dy < 0 ? -1 : 1;
+ int16 stepx = dx < 0 ? -1 : 1;
dy = ABS(dy) << 1;
dx = ABS(dx) << 1;
// setting the 1st and last pixel
- putPixel(left, top, drawMask, color, priority, control);
- putPixel(right, bottom, drawMask, color, priority, control);
+ vectorPutLinePixel(left, top, drawMask, color, priority, control);
+ vectorPutLinePixel(right, bottom, drawMask, color, priority, control);
// drawing the line
if (dx > dy) { // going horizontal
int fraction = dy - (dx >> 1);
@@ -370,7 +569,7 @@ void GfxScreen::drawLine(Common::Point startPoint, Common::Point endPoint, byte
}
left += stepx;
fraction += dy;
- putPixel(left, top, drawMask, color, priority, control);
+ vectorPutLinePixel(left, top, drawMask, color, priority, control);
}
} else { // going vertical
int fraction = dx - (dy >> 1);
@@ -381,7 +580,7 @@ void GfxScreen::drawLine(Common::Point startPoint, Common::Point endPoint, byte
}
top += stepy;
fraction += dx;
- putPixel(left, top, drawMask, color, priority, control);
+ vectorPutLinePixel(left, top, drawMask, color, priority, control);
}
}
}
@@ -394,46 +593,14 @@ void GfxScreen::putKanjiChar(Graphics::FontSJIS *commonFont, int16 x, int16 y, u
commonFont->drawChar(displayPtr, chr, _displayWidth, 1, color, 0, -1, -1);
}
-byte GfxScreen::getVisual(int x, int y) {
- return _visualScreen[y * _pitch + x];
+byte GfxScreen::getPixelNormal(byte *screen, int16 x, int16 y) {
+ return screen[y * _width + x];
}
-byte GfxScreen::getPriority(int x, int y) {
- return _priorityScreen[y * _pitch + x];
-}
-
-byte GfxScreen::getControl(int x, int y) {
- return _controlScreen[y * _pitch + x];
-}
-
-byte GfxScreen::isFillMatch(int16 x, int16 y, byte screenMask, byte t_color, byte t_pri, byte t_con, bool isEGA) {
- int offset = y * _pitch + x;
- byte match = 0;
-
- if (screenMask & GFX_SCREEN_MASK_VISUAL) {
- if (!isEGA) {
- if (*(_visualScreen + offset) == t_color)
- match |= GFX_SCREEN_MASK_VISUAL;
- } else {
- // In EGA games a pixel in the framebuffer is only 4 bits. We store
- // a full byte per pixel to allow undithering, but when comparing
- // pixels for flood-fill purposes, we should only compare the
- // visible color of a pixel.
-
- byte c = *(_visualScreen + offset);
- if ((x ^ y) & 1)
- c = (c ^ (c >> 4)) & 0x0F;
- else
- c = c & 0x0F;
- if (c == t_color)
- match |= GFX_SCREEN_MASK_VISUAL;
- }
- }
- if ((screenMask & GFX_SCREEN_MASK_PRIORITY) && *(_priorityScreen + offset) == t_pri)
- match |= GFX_SCREEN_MASK_PRIORITY;
- if ((screenMask & GFX_SCREEN_MASK_CONTROL) && *(_controlScreen + offset) == t_con)
- match |= GFX_SCREEN_MASK_CONTROL;
- return match;
+byte GfxScreen::getPixelUpscaled(byte *screen, int16 x, int16 y) {
+ int16 mappedX = _upscaledWidthMapping[x];
+ int16 mappedY = _upscaledHeightMapping[y];
+ return screen[mappedY * _width + mappedX];
}
int GfxScreen::bitsGetDataSize(Common::Rect rect, byte mask) {
@@ -469,14 +636,14 @@ void GfxScreen::bitsSave(Common::Rect rect, byte mask, byte *memoryPtr) {
memcpy(memoryPtr, (void *)&mask, sizeof(mask)); memoryPtr += sizeof(mask);
if (mask & GFX_SCREEN_MASK_VISUAL) {
- bitsSaveScreen(rect, _visualScreen, _pitch, memoryPtr);
+ bitsSaveScreen(rect, _visualScreen, _width, memoryPtr);
bitsSaveDisplayScreen(rect, memoryPtr);
}
if (mask & GFX_SCREEN_MASK_PRIORITY) {
- bitsSaveScreen(rect, _priorityScreen, _pitch, memoryPtr);
+ bitsSaveScreen(rect, _priorityScreen, _width, memoryPtr);
}
if (mask & GFX_SCREEN_MASK_CONTROL) {
- bitsSaveScreen(rect, _controlScreen, _pitch, memoryPtr);
+ bitsSaveScreen(rect, _controlScreen, _width, memoryPtr);
}
if (mask & GFX_SCREEN_MASK_DISPLAY) {
if (!_upscaledHires)
@@ -530,14 +697,14 @@ void GfxScreen::bitsRestore(byte *memoryPtr) {
memcpy((void *)&mask, memoryPtr, sizeof(mask)); memoryPtr += sizeof(mask);
if (mask & GFX_SCREEN_MASK_VISUAL) {
- bitsRestoreScreen(rect, memoryPtr, _visualScreen, _pitch);
+ bitsRestoreScreen(rect, memoryPtr, _visualScreen, _width);
bitsRestoreDisplayScreen(rect, memoryPtr);
}
if (mask & GFX_SCREEN_MASK_PRIORITY) {
- bitsRestoreScreen(rect, memoryPtr, _priorityScreen, _pitch);
+ bitsRestoreScreen(rect, memoryPtr, _priorityScreen, _width);
}
if (mask & GFX_SCREEN_MASK_CONTROL) {
- bitsRestoreScreen(rect, memoryPtr, _controlScreen, _pitch);
+ bitsRestoreScreen(rect, memoryPtr, _controlScreen, _width);
}
if (mask & GFX_SCREEN_MASK_DISPLAY) {
if (!_upscaledHires)
@@ -612,21 +779,22 @@ void GfxScreen::dither(bool addToFlag) {
byte color, ditheredColor;
byte *visualPtr = _visualScreen;
byte *displayPtr = _displayScreen;
-
+
if (!_unditheringEnabled) {
// Do dithering on visual and display-screen
for (y = 0; y < _height; y++) {
- for (x = 0; x < _pitch; x++) {
+ for (x = 0; x < _width; x++) {
color = *visualPtr;
if (color & 0xF0) {
color ^= color << 4;
color = ((x^y) & 1) ? color >> 4 : color & 0x0F;
switch (_upscaledHires) {
case GFX_SCREEN_UPSCALED_DISABLED:
+ case GFX_SCREEN_UPSCALED_480x300:
*displayPtr = color;
break;
default:
- putScaledPixelOnDisplay(x, y, color);
+ putScaledPixelOnScreen(_displayScreen, x, y, color);
break;
}
*visualPtr = color;
@@ -639,7 +807,7 @@ void GfxScreen::dither(bool addToFlag) {
memset(&_ditheredPicColors, 0, sizeof(_ditheredPicColors));
// Do dithering on visual screen and put decoded but undithered byte onto display-screen
for (y = 0; y < _height; y++) {
- for (x = 0; x < _pitch; x++) {
+ for (x = 0; x < _width; x++) {
color = *visualPtr;
if (color & 0xF0) {
color ^= color << 4;
@@ -654,10 +822,11 @@ void GfxScreen::dither(bool addToFlag) {
}
switch (_upscaledHires) {
case GFX_SCREEN_UPSCALED_DISABLED:
+ case GFX_SCREEN_UPSCALED_480x300:
*displayPtr = ditheredColor;
break;
default:
- putScaledPixelOnDisplay(x, y, ditheredColor);
+ putScaledPixelOnScreen(_displayScreen, x, y, ditheredColor);
break;
}
color = ((x^y) & 1) ? color >> 4 : color & 0x0F;
@@ -685,8 +854,8 @@ int16 *GfxScreen::unditherGetDitheredBgColors() {
}
void GfxScreen::debugShowMap(int mapNo) {
- // We cannot really support changing maps when in upscaledHires mode
- if (_upscaledHires)
+ // We cannot really support changing maps when display screen has a different resolution than visual screen
+ if ((_width != _displayWidth) || (_height != _displayHeight))
return;
switch (mapNo) {
@@ -779,8 +948,8 @@ void GfxScreen::adjustBackUpscaledCoordinates(int16 &y, int16 &x, Sci32ViewNativ
switch (_upscaledHires) {
case GFX_SCREEN_UPSCALED_480x300:
- x = (x << 1) / 3;
- y = (y << 1) / 3;
+ x = (x * 4) / 6;
+ y = (y * 4) / 6;
break;
case GFX_SCREEN_UPSCALED_640x400:
x /= 2;
@@ -816,26 +985,4 @@ int16 GfxScreen::kernelPicNotValid(int16 newPicNotValid) {
return oldPicNotValid;
}
-uint16 GfxScreen::getLowResScreenHeight() {
- // Some Mac SCI1/1.1 games only take up 190 rows and do not
- // have the menu bar.
- // TODO: Verify that LSL1 and LSL5 use height 190
- if (g_sci->getPlatform() == Common::kPlatformMacintosh) {
- switch (g_sci->getGameId()) {
- case GID_FREDDYPHARKAS:
- case GID_KQ5:
- case GID_KQ6:
- case GID_LSL1:
- case GID_LSL5:
- case GID_SQ1:
- return 190;
- default:
- break;
- }
- }
-
- // Everything else is 200
- return 200;
-}
-
} // End of namespace Sci
diff --git a/engines/sci/graphics/screen.h b/engines/sci/graphics/screen.h
index e266a4ed16..1c946ef02f 100644
--- a/engines/sci/graphics/screen.h
+++ b/engines/sci/graphics/screen.h
@@ -69,11 +69,14 @@ public:
uint16 getWidth() { return _width; }
uint16 getHeight() { return _height; }
+ uint16 getScriptWidth() { return _scriptWidth; }
+ uint16 getScriptHeight() { return _scriptHeight; }
uint16 getDisplayWidth() { return _displayWidth; }
uint16 getDisplayHeight() { return _displayHeight; }
byte getColorWhite() { return _colorWhite; }
byte getColorDefaultVectorData() { return _colorDefaultVectorData; }
+ void clearForRestoreGame();
void copyToScreen();
void copyFromScreen(byte *buffer);
void kernelSyncWithFramebuffer();
@@ -81,11 +84,51 @@ public:
void copyDisplayRectToScreen(const Common::Rect &rect);
void copyRectToScreen(const Common::Rect &rect, int16 x, int16 y);
+ // calls to code pointers
+ void inline vectorAdjustCoordinate (int16 *x, int16 *y) {
+ (this->*_vectorAdjustCoordinatePtr)(x, y);
+ }
+ void inline vectorAdjustLineCoordinates (int16 *left, int16 *top, int16 *right, int16 *bottom, byte drawMask, byte color, byte priority, byte control) {
+ (this->*_vectorAdjustLineCoordinatesPtr)(left, top, right, bottom, drawMask, color, priority, control);
+ }
+ byte inline vectorIsFillMatch (int16 x, int16 y, byte screenMask, byte t_color, byte t_pri, byte t_con, bool isEGA) {
+ return (this->*_vectorIsFillMatchPtr)(x, y, screenMask, t_color, t_pri, t_con, isEGA);
+ }
+ void inline vectorPutPixel(int16 x, int16 y, byte drawMask, byte color, byte priority, byte control) {
+ (this->*_vectorPutPixelPtr)(x, y, drawMask, color, priority, control);
+ }
+ void inline vectorPutLinePixel(int16 x, int16 y, byte drawMask, byte color, byte priority, byte control) {
+ (this->*_vectorPutLinePixelPtr)(x, y, drawMask, color, priority, control);
+ }
+ byte inline vectorGetVisual(int16 x, int16 y) {
+ return (this->*_vectorGetPixelPtr)(_visualScreen, x, y);
+ }
+ byte inline vectorGetPriority(int16 x, int16 y) {
+ return (this->*_vectorGetPixelPtr)(_priorityScreen, x, y);
+ }
+ byte inline vectorGetControl(int16 x, int16 y) {
+ return (this->*_vectorGetPixelPtr)(_controlScreen, x, y);
+ }
+
+
+ void inline putPixel(int16 x, int16 y, byte drawMask, byte color, byte priority, byte control) {
+ (this->*_putPixelPtr)(x, y, drawMask, color, priority, control);
+ }
+
+ byte inline getVisual(int16 x, int16 y) {
+ return (this->*_getPixelPtr)(_visualScreen, x, y);
+ }
+ byte inline getPriority(int16 x, int16 y) {
+ return (this->*_getPixelPtr)(_priorityScreen, x, y);
+ }
+ byte inline getControl(int16 x, int16 y) {
+ return (this->*_getPixelPtr)(_controlScreen, x, y);
+ }
+
byte getDrawingMask(byte color, byte prio, byte control);
- void putPixel(int x, int y, byte drawMask, byte color, byte prio, byte control);
- void putFontPixel(int startingY, int x, int y, byte color);
- void putPixelOnDisplay(int x, int y, byte color);
- void putScaledPixelOnDisplay(int x, int y, byte color);
+ //void putPixel(int16 x, int16 y, byte drawMask, byte color, byte prio, byte control);
+ void putFontPixel(int16 startingY, int16 x, int16 y, byte color);
+ void putPixelOnDisplay(int16 x, int16 y, byte color);
void drawLine(Common::Point startPoint, Common::Point endPoint, byte color, byte prio, byte control);
void drawLine(int16 left, int16 top, int16 right, int16 bottom, byte color, byte prio, byte control) {
drawLine(Common::Point(left, top), Common::Point(right, bottom), color, prio, control);
@@ -101,10 +144,6 @@ public:
void enableUndithering(bool flag);
void putKanjiChar(Graphics::FontSJIS *commonFont, int16 x, int16 y, uint16 chr, byte color);
- byte getVisual(int x, int y);
- byte getPriority(int x, int y);
- byte getControl(int x, int y);
- byte isFillMatch(int16 x, int16 y, byte drawMask, byte t_color, byte t_pri, byte t_con, bool isEGA);
int bitsGetDataSize(Common::Rect rect, byte mask);
void bitsSave(Common::Rect rect, byte mask, byte *memoryPtr);
@@ -135,9 +174,10 @@ public:
private:
uint16 _width;
- uint16 _pitch;
uint16 _height;
uint _pixels;
+ uint16 _scriptWidth;
+ uint16 _scriptHeight;
uint16 _displayWidth;
uint16 _displayHeight;
uint _displayPixels;
@@ -190,8 +230,8 @@ private:
* This here holds a translation for vertical+horizontal coordinates between native
* (visual) and actual (display) screen.
*/
- int _upscaledHeightMapping[SCI_SCREEN_UPSCALEDMAXHEIGHT + 1];
- int _upscaledWidthMapping[SCI_SCREEN_UPSCALEDMAXWIDTH + 1];
+ int16 _upscaledHeightMapping[SCI_SCREEN_UPSCALEDMAXHEIGHT + 1];
+ int16 _upscaledWidthMapping[SCI_SCREEN_UPSCALEDMAXWIDTH + 1];
/**
* This defines whether or not the font we're drawing is already scaled
@@ -199,7 +239,38 @@ private:
*/
bool _fontIsUpscaled;
- uint16 getLowResScreenHeight();
+ // dynamic code
+ void (GfxScreen::*_vectorAdjustCoordinatePtr) (int16 *x, int16 *y);
+ void vectorAdjustCoordinateNOP (int16 *x, int16 *y);
+ void vectorAdjustCoordinate480x300Mac (int16 *x, int16 *y);
+
+ void (GfxScreen::*_vectorAdjustLineCoordinatesPtr) (int16 *left, int16 *top, int16 *right, int16 *bottom, byte drawMask, byte color, byte priority, byte control);
+ void vectorAdjustLineCoordinatesNOP (int16 *left, int16 *top, int16 *right, int16 *bottom, byte drawMask, byte color, byte priority, byte control);
+ void vectorAdjustLineCoordinates480x300Mac (int16 *left, int16 *top, int16 *right, int16 *bottom, byte drawMask, byte color, byte priority, byte control);
+
+ byte (GfxScreen::*_vectorIsFillMatchPtr) (int16 x, int16 y, byte screenMask, byte t_color, byte t_pri, byte t_con, bool isEGA);
+ byte vectorIsFillMatchNormal (int16 x, int16 y, byte screenMask, byte t_color, byte t_pri, byte t_con, bool isEGA);
+ byte vectorIsFillMatch480x300Mac (int16 x, int16 y, byte screenMask, byte t_color, byte t_pri, byte t_con, bool isEGA);
+
+ void (GfxScreen::*_vectorPutPixelPtr) (int16 x, int16 y, byte drawMask, byte color, byte priority, byte control);
+ void vectorPutPixel480x300Mac (int16 x, int16 y, byte drawMask, byte color, byte priority, byte control);
+
+ void (GfxScreen::*_vectorPutLinePixelPtr) (int16 x, int16 y, byte drawMask, byte color, byte priority, byte control);
+ void vectorPutLinePixel480x300Mac (int16 x, int16 y, byte drawMask, byte color, byte priority, byte control);
+
+ byte (GfxScreen::*_vectorGetPixelPtr) (byte *screen, int16 x, int16 y);
+
+ void (GfxScreen::*_putPixelPtr) (int16 x, int16 y, byte drawMask, byte color, byte priority, byte control);
+ void putPixelNormal (int16 x, int16 y, byte drawMask, byte color, byte priority, byte control);
+ void putPixelDisplayUpscaled (int16 x, int16 y, byte drawMask, byte color, byte priority, byte control);
+ void putPixelAllUpscaled (int16 x, int16 y, byte drawMask, byte color, byte priority, byte control);
+
+ byte (GfxScreen::*_getPixelPtr) (byte *screen, int16 x, int16 y);
+ byte getPixelNormal (byte *screen, int16 x, int16 y);
+ byte getPixelUpscaled (byte *screen, int16 x, int16 y);
+
+ // pixel helper
+ void putScaledPixelOnScreen(byte *screen, int16 x, int16 y, byte color);
};
} // End of namespace Sci
diff --git a/engines/sci/graphics/text16.cpp b/engines/sci/graphics/text16.cpp
index 245d6996cb..f463dff4b1 100644
--- a/engines/sci/graphics/text16.cpp
+++ b/engines/sci/graphics/text16.cpp
@@ -143,18 +143,30 @@ int16 GfxText16::CodeProcessing(const char *&text, GuiResourceId orgFontId, int1
return textCodeSize;
}
-static const uint16 text16_punctuationSjis[] = {
- 0x9F82, 0xA182, 0xA382, 0xA582, 0xA782, 0xC182, 0xA782, 0xC182, 0xE182, 0xE382, 0xE582, 0xEC82,
- 0x4083, 0x4283, 0x4483, 0x4683, 0x4883, 0x6283, 0x8383, 0x8583, 0x8783, 0x8E83, 0x9583, 0x9683,
- 0x5B81, 0x4181, 0x4281, 0x7681, 0x7881, 0x4981, 0x4881, 0
+// Has actually punctuation and characters in it, that may not be the first in a line
+static const uint16 text16_shiftJIS_punctuation[] = {
+ 0x9F82, 0xA182, 0xA382, 0xA582, 0xA782, 0xC182, 0xE182, 0xE382, 0xE582, 0xEC82, 0x4083, 0x4283,
+ 0x4483, 0x4683, 0x4883, 0x6283, 0x8383, 0x8583, 0x8783, 0x8E83, 0x9583, 0x9683, 0x5B81, 0x4181,
+ 0x4281, 0x7681, 0x7881, 0x4981, 0x4881, 0
};
// return max # of chars to fit maxwidth with full words, does not include
// breaking space
-int16 GfxText16::GetLongest(const char *text, int16 maxWidth, GuiResourceId orgFontId) {
+// Also adjusts text pointer to the new position for the caller
+//
+// Special cases in games:
+// Laura Bow 2 - Credits in the game menu - all the text lines start with spaces (bug #5159)
+// Act 6 Coroner questionaire - the text of all control buttons has trailing spaces
+// "Detective Ryan Hanrahan O'Riley" contains even more spaces (bug #5334)
+// Conquests of Camelot - talking with Cobb - one text box of the dialogue contains a longer word,
+// that will be broken into 2 lines (bug #5159)
+int16 GfxText16::GetLongest(const char *&textPtr, int16 maxWidth, GuiResourceId orgFontId) {
uint16 curChar = 0;
- int16 maxChars = 0, curCharCount = 0;
- uint16 width = 0;
+ const char *textStartPtr = textPtr;
+ const char *lastSpacePtr = NULL;
+ int16 lastSpaceCharCount = 0;
+ int16 curCharCount = 0, resultCharCount = 0;
+ uint16 curWidth = 0, tempWidth = 0;
GuiResourceId previousFontId = GetFontId();
int16 previousPenColor = _ports->_curPort->penClr;
@@ -162,35 +174,38 @@ int16 GfxText16::GetLongest(const char *text, int16 maxWidth, GuiResourceId orgF
if (!_font)
return 0;
- while (width <= maxWidth) {
- curChar = (*(const byte *)text++);
+ while (1) {
+ curChar = (*(const byte *)textPtr);
if (_font->isDoubleByte(curChar)) {
- curChar |= (*(const byte *)text++) << 8;
- curCharCount++;
+ curChar |= (*(const byte *)(textPtr + 1)) << 8;
}
switch (curChar) {
case 0x7C:
if (getSciVersion() >= SCI_VERSION_1_1) {
- curCharCount++;
- curCharCount += CodeProcessing(text, orgFontId, previousPenColor, false);
+ curCharCount++; textPtr++;
+ curCharCount += CodeProcessing(textPtr, orgFontId, previousPenColor, false);
continue;
}
break;
// We need to add 0xD, 0xA and 0xD 0xA to curCharCount and then exit
- // which means, we split text like
- // 'Mature, experienced software analyst available.' 0xD 0xA
- // 'Bug installation a proven speciality. "No version too clean."' (normal game text, this is from lsl2)
- // and 0xA '-------' 0xA (which is the official sierra subtitle separator)
+ // which means, we split text like for example
+ // - 'Mature, experienced software analyst available.' 0xD 0xA
+ // 'Bug installation a proven speciality. "No version too clean."' (normal game text, this is from lsl2)
+ // - 0xA '-------' 0xA (which is the official sierra subtitle separator) (found in multilingual versions)
// Sierra did it the same way.
case 0xD:
// Check, if 0xA is following, if so include it as well
- if ((*(const unsigned char *)text) == 0xA)
- curCharCount++;
+ if ((*(const byte *)(textPtr + 1)) == 0xA) {
+ curCharCount++; textPtr++;
+ }
// it's meant to pass through here
case 0xA:
case 0x9781: // this one is used by SQ4/japanese as line break as well
- curCharCount++;
+ curCharCount++; textPtr++;
+ if (curChar > 0xFF) {
+ curCharCount++; textPtr++;
+ }
// and it's also meant to pass through here
case 0:
SetFont(previousFontId);
@@ -198,55 +213,86 @@ int16 GfxText16::GetLongest(const char *text, int16 maxWidth, GuiResourceId orgF
return curCharCount;
case ' ':
- maxChars = curCharCount; // return count up to (but not including) breaking space
+ lastSpaceCharCount = curCharCount; // return count up to (but not including) breaking space
+ lastSpacePtr = textPtr + 1; // remember position right after the current space
break;
}
- // Sometimes this can go off the screen, like for example bug #3040161.
- // However, we only perform this for non-Japanese games, as these require
- // special handling, done after this loop.
- if (width + _font->getCharWidth(curChar) > maxWidth && g_sci->getLanguage() != Common::JA_JPN)
+ tempWidth += _font->getCharWidth(curChar);
+
+ // Width is too large? -> break out
+ if (tempWidth > maxWidth)
break;
- width += _font->getCharWidth(curChar);
- curCharCount++;
+
+ // still fits, remember width
+ curWidth = tempWidth;
+
+ // go to next character
+ curCharCount++; textPtr++;
+ if (curChar > 0xFF) {
+ // Double-Byte
+ curCharCount++; textPtr++;
+ }
}
- // Text without spaces, probably Kanji/Japanese
- if (maxChars == 0) {
- maxChars = curCharCount;
+ if (lastSpaceCharCount) {
+ // Break and at least one space was found before that
+ resultCharCount = lastSpaceCharCount;
- uint16 nextChar;
+ // additionally skip over all spaces, that are following that space, but don't count them for displaying purposes
+ textPtr = lastSpacePtr;
+ while (*textPtr == ' ')
+ textPtr++;
- // We remove the last char only, if maxWidth was actually equal width
- // before adding the last char. Otherwise we won't get the same cutting
- // as in sierra pc98 sci.
- if (maxWidth == (width - _font->getCharWidth(curChar))) {
- maxChars--;
- if (curChar > 0xFF)
- maxChars--;
- nextChar = curChar;
- } else {
- nextChar = (*(const byte *)text++);
- if (_font->isDoubleByte(nextChar))
- nextChar |= (*(const byte *)text++) << 8;
- }
- // sierra checked the following character against a punctuation kanji table
- if (nextChar > 0xFF) {
- // if the character is punctuation, we go back one character
- uint nonBreakingNr = 0;
- while (text16_punctuationSjis[nonBreakingNr]) {
- if (text16_punctuationSjis[nonBreakingNr] == nextChar) {
- maxChars--;
- if (curChar > 0xFF)
- maxChars--; // go back 2 chars, when last char was double byte
+ } else {
+ // Break without spaces found, we split the very first word - may also be Kanji/Japanese
+ if (curChar > 0xFF) {
+ // current charracter is Japanese
+
+ // PC-9801 SCI actually added the last character, which shouldn't fit anymore, still onto the
+ // screen in case maxWidth wasn't fully reached with the last character
+ if (( maxWidth - 1 ) > curWidth) {
+ curCharCount += 2; textPtr += 2;
+
+ curChar = (*(const byte *)textPtr);
+ if (_font->isDoubleByte(curChar)) {
+ curChar |= (*(const byte *)(textPtr + 1)) << 8;
+ }
+ }
+
+ // But it also checked, if the current character is not inside a punctuation table and it even
+ // went backwards in case it found multiple ones inside that table.
+ uint nonBreakingPos = 0;
+
+ while (1) {
+ // Look up if character shouldn't be the first on a new line
+ nonBreakingPos = 0;
+ while (text16_shiftJIS_punctuation[nonBreakingPos]) {
+ if (text16_shiftJIS_punctuation[nonBreakingPos] == curChar)
+ break;
+ nonBreakingPos++;
+ }
+ if (!text16_shiftJIS_punctuation[nonBreakingPos]) {
+ // character is fine
break;
}
- nonBreakingNr++;
+ // Character is not acceptable, seek backward in the text
+ curCharCount -= 2; textPtr -= 2;
+ if (textPtr < textStartPtr)
+ error("Seeking back went too far, data corruption?");
+
+ curChar = (*(const byte *)textPtr);
+ if (!_font->isDoubleByte(curChar))
+ error("Non double byte while seeking back");
+ curChar |= (*(const byte *)(textPtr + 1)) << 8;
}
}
+
+ // We split the word in that case
+ resultCharCount = curCharCount;
}
SetFont(previousFontId);
_ports->penColor(previousPenColor);
- return maxChars;
+ return resultCharCount;
}
void GfxText16::Width(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight, bool restoreFont) {
@@ -303,7 +349,7 @@ void GfxText16::DrawString(const char *str, GuiResourceId orgFontId, int16 orgPe
Draw(str, 0, (int16)strlen(str), orgFontId, orgPenColor);
}
-int16 GfxText16::Size(Common::Rect &rect, const char *text, GuiResourceId fontId, int16 maxWidth) {
+int16 GfxText16::Size(Common::Rect &rect, const char *text, uint16 languageSplitter, GuiResourceId fontId, int16 maxWidth) {
GuiResourceId previousFontId = GetFontId();
int16 previousPenColor = _ports->_curPort->penClr;
int16 charCount;
@@ -315,12 +361,12 @@ int16 GfxText16::Size(Common::Rect &rect, const char *text, GuiResourceId fontId
else
fontId = previousFontId;
- if (g_sci->getLanguage() == Common::JA_JPN)
- SwitchToFont900OnSjis(text);
-
rect.top = rect.left = 0;
if (maxWidth < 0) { // force output as single line
+ if (g_sci->getLanguage() == Common::JA_JPN)
+ SwitchToFont900OnSjis(text, languageSplitter);
+
StringWidth(text, fontId, textWidth, textHeight);
rect.bottom = textHeight;
rect.right = textWidth;
@@ -328,17 +374,20 @@ int16 GfxText16::Size(Common::Rect &rect, const char *text, GuiResourceId fontId
// rect.right=found widest line with RTextWidth and GetLongest
// rect.bottom=num. lines * GetPointSize
rect.right = (maxWidth ? maxWidth : 192);
- const char *curPos = text;
- while (*curPos) {
- charCount = GetLongest(curPos, rect.right, fontId);
+ const char *curTextPos = text; // in work position for GetLongest()
+ const char *curTextLine = text; // starting point of current line
+ while (*curTextPos) {
+ // We need to check for Shift-JIS every line
+ if (g_sci->getLanguage() == Common::JA_JPN)
+ SwitchToFont900OnSjis(curTextPos, languageSplitter);
+
+ charCount = GetLongest(curTextPos, rect.right, fontId);
if (charCount == 0)
break;
- Width(curPos, 0, charCount, fontId, textWidth, textHeight, false);
+ Width(curTextLine, 0, charCount, fontId, textWidth, textHeight, false);
maxTextWidth = MAX(textWidth, maxTextWidth);
totalHeight += textHeight;
- curPos += charCount;
- while (*curPos == ' ')
- curPos++; // skip over breaking spaces
+ curTextLine = curTextPos;
}
rect.bottom = totalHeight;
rect.right = maxWidth ? maxWidth : MIN(rect.right, maxTextWidth);
@@ -405,34 +454,38 @@ void GfxText16::Show(const char *text, int16 from, int16 len, GuiResourceId orgF
}
// Draws a text in rect.
-void GfxText16::Box(const char *text, bool show, const Common::Rect &rect, TextAlignment alignment, GuiResourceId fontId) {
+void GfxText16::Box(const char *text, uint16 languageSplitter, bool show, const Common::Rect &rect, TextAlignment alignment, GuiResourceId fontId) {
int16 textWidth, maxTextWidth, textHeight, charCount;
int16 offset = 0;
int16 hline = 0;
GuiResourceId previousFontId = GetFontId();
int16 previousPenColor = _ports->_curPort->penClr;
bool doubleByteMode = false;
+ const char *curTextPos = text;
+ const char *curTextLine = text;
if (fontId != -1)
SetFont(fontId);
else
fontId = previousFontId;
- if (g_sci->getLanguage() == Common::JA_JPN) {
- if (SwitchToFont900OnSjis(text))
- doubleByteMode = true;
- }
-
// Reset reference code rects
_codeRefRects.clear();
_codeRefTempRect.left = _codeRefTempRect.top = -1;
maxTextWidth = 0;
- while (*text) {
- charCount = GetLongest(text, rect.width(), fontId);
+ while (*curTextPos) {
+ // We need to check for Shift-JIS every line
+ // Police Quest 2 PC-9801 often draws English + Japanese text during the same call
+ if (g_sci->getLanguage() == Common::JA_JPN) {
+ if (SwitchToFont900OnSjis(curTextPos, languageSplitter))
+ doubleByteMode = true;
+ }
+
+ charCount = GetLongest(curTextPos, rect.width(), fontId);
if (charCount == 0)
break;
- Width(text, 0, charCount, fontId, textWidth, textHeight, true);
+ Width(curTextLine, 0, charCount, fontId, textWidth, textHeight, true);
maxTextWidth = MAX<int16>(maxTextWidth, textWidth);
switch (alignment) {
case SCI_TEXT16_ALIGNMENT_RIGHT:
@@ -451,15 +504,13 @@ void GfxText16::Box(const char *text, bool show, const Common::Rect &rect, TextA
_ports->moveTo(rect.left + offset, rect.top + hline);
if (show) {
- Show(text, 0, charCount, fontId, previousPenColor);
+ Show(curTextLine, 0, charCount, fontId, previousPenColor);
} else {
- Draw(text, 0, charCount, fontId, previousPenColor);
+ Draw(curTextLine, 0, charCount, fontId, previousPenColor);
}
hline += textHeight;
- text += charCount;
- while (*text == ' ')
- text++; // skip over breaking spaces
+ curTextLine = curTextPos;
}
SetFont(previousFontId);
_ports->penColor(previousPenColor);
@@ -521,11 +572,13 @@ void GfxText16::DrawStatus(const char *text) {
// Sierra did this in their PC98 interpreter only, they identify a text as being
// sjis and then switch to font 900
-bool GfxText16::SwitchToFont900OnSjis(const char *text) {
+bool GfxText16::SwitchToFont900OnSjis(const char *text, uint16 languageSplitter) {
byte firstChar = (*(const byte *)text++);
- if (((firstChar >= 0x81) && (firstChar <= 0x9F)) || ((firstChar >= 0xE0) && (firstChar <= 0xEF))) {
- SetFont(900);
- return true;
+ if (languageSplitter != 0x6a23) { // #j prefix as language splitter
+ if (((firstChar >= 0x81) && (firstChar <= 0x9F)) || ((firstChar >= 0xE0) && (firstChar <= 0xEF))) {
+ SetFont(900);
+ return true;
+ }
}
return false;
}
@@ -554,9 +607,9 @@ reg_t GfxText16::allocAndFillReferenceRectArray() {
return NULL_REG;
}
-void GfxText16::kernelTextSize(const char *text, int16 font, int16 maxWidth, int16 *textWidth, int16 *textHeight) {
+void GfxText16::kernelTextSize(const char *text, uint16 languageSplitter, int16 font, int16 maxWidth, int16 *textWidth, int16 *textHeight) {
Common::Rect rect(0, 0, 0, 0);
- Size(rect, text, font, maxWidth);
+ Size(rect, text, languageSplitter, font, maxWidth);
*textWidth = rect.width();
*textHeight = rect.height();
}
diff --git a/engines/sci/graphics/text16.h b/engines/sci/graphics/text16.h
index ab0cb13a64..2724d97347 100644
--- a/engines/sci/graphics/text16.h
+++ b/engines/sci/graphics/text16.h
@@ -51,15 +51,20 @@ public:
void ClearChar(int16 chr);
- int16 GetLongest(const char *text, int16 maxWidth, GuiResourceId orgFontId);
+ int16 GetLongest(const char *&text, int16 maxWidth, GuiResourceId orgFontId);
void Width(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight, bool restoreFont);
void StringWidth(const char *str, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight);
void ShowString(const char *str, GuiResourceId orgFontId, int16 orgPenColor);
void DrawString(const char *str, GuiResourceId orgFontId, int16 orgPenColor);
- int16 Size(Common::Rect &rect, const char *text, GuiResourceId fontId, int16 maxWidth);
+ int16 Size(Common::Rect &rect, const char *text, uint16 textLanguage, GuiResourceId fontId, int16 maxWidth);
void Draw(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 orgPenColor);
void Show(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 orgPenColor);
- void Box(const char *text, bool show, const Common::Rect &rect, TextAlignment alignment, GuiResourceId fontId);
+ void Box(const char *text, uint16 languageSplitter, bool show, const Common::Rect &rect, TextAlignment alignment, GuiResourceId fontId);
+
+ void Box(const char *text, bool show, const Common::Rect &rect, TextAlignment alignment, GuiResourceId fontId) {
+ Box(text, 0, show, rect, alignment, fontId);
+ }
+
void DrawString(const char *text);
void DrawStatus(const char *text);
@@ -67,13 +72,13 @@ public:
reg_t allocAndFillReferenceRectArray();
- void kernelTextSize(const char *text, int16 font, int16 maxWidth, int16 *textWidth, int16 *textHeight);
+ void kernelTextSize(const char *text, uint16 textLanguage, int16 font, int16 maxWidth, int16 *textWidth, int16 *textHeight);
void kernelTextFonts(int argc, reg_t *argv);
void kernelTextColors(int argc, reg_t *argv);
private:
void init();
- bool SwitchToFont900OnSjis(const char *text);
+ bool SwitchToFont900OnSjis(const char *text, uint16 languageSplitter);
GfxCache *_cache;
GfxPorts *_ports;
diff --git a/engines/sci/graphics/transitions.cpp b/engines/sci/graphics/transitions.cpp
index 5e7dbc6c15..ccc7a4389a 100644
--- a/engines/sci/graphics/transitions.cpp
+++ b/engines/sci/graphics/transitions.cpp
@@ -339,10 +339,10 @@ void GfxTransitions::pixelation(bool blackoutFlag) {
do {
mask = (mask & 1) ? (mask >> 1) ^ 0xB400 : mask >> 1;
- if (mask >= _screen->getWidth() * _screen->getHeight())
+ if (mask >= _screen->getScriptWidth() * _screen->getScriptHeight())
continue;
- pixelRect.left = mask % _screen->getWidth(); pixelRect.right = pixelRect.left + 1;
- pixelRect.top = mask / _screen->getWidth(); pixelRect.bottom = pixelRect.top + 1;
+ pixelRect.left = mask % _screen->getScriptWidth(); pixelRect.right = pixelRect.left + 1;
+ pixelRect.top = mask / _screen->getScriptWidth(); pixelRect.bottom = pixelRect.top + 1;
pixelRect.clip(_picRect);
if (!pixelRect.isEmpty())
copyRectToScreen(pixelRect, blackoutFlag);
diff --git a/engines/sci/graphics/view.cpp b/engines/sci/graphics/view.cpp
index f3f352e5b8..da61ecf4c3 100644
--- a/engines/sci/graphics/view.cpp
+++ b/engines/sci/graphics/view.cpp
@@ -283,6 +283,7 @@ void GfxView::initData(GuiResourceId resourceId) {
_isScaleable = false;
break;
case 0x40:
+ case 0x4F: // LSL6 Polish, seems to be garbage - bug #6718
case 0:
break; // don't do anything, we already have _isScaleable set
default:
@@ -366,7 +367,7 @@ void GfxView::initData(GuiResourceId resourceId) {
default:
error("ViewType was not detected, can't continue");
}
-
+
// Inject our own views
// Currently only used for Dual mode (speech + text) for games, that do not have a "dual" icon already
// Which is Laura Bow 2 + King's Quest 6
diff --git a/engines/sci/module.mk b/engines/sci/module.mk
index 6b6058c819..33392e3b42 100644
--- a/engines/sci/module.mk
+++ b/engines/sci/module.mk
@@ -76,8 +76,8 @@ MODULE_OBJS := \
sound/drivers/midi.o \
sound/drivers/pcjr.o \
video/seq_decoder.o
-
-
+
+
ifdef ENABLE_SCI32
MODULE_OBJS += \
engine/kgraphics32.o \
diff --git a/engines/sci/parser/vocabulary.cpp b/engines/sci/parser/vocabulary.cpp
index 3344b79e26..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() {
@@ -535,10 +537,7 @@ bool Vocabulary::tokenizeString(ResultWordListList &retval, const char *sentence
if (Common::isAlnum(c) || (c == '-' && wordLen) || (c >= 0x80)) {
currentWord[wordLen] = lowerCaseMap[c];
++wordLen;
- } else if (c == '\'' && wordLen && (sentence[pos_in_sentence] == 's' || sentence[pos_in_sentence] == 'S')) {
- // Skip apostrophe-s at the end of the word, if it exists
- pos_in_sentence++; // skip the 's'
- } else {
+ } else if (c == ' ' || c == '\0') {
// Continue on this word. Words may contain a '-', but may not start with
// one.
@@ -741,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.cpp b/engines/sci/resource.cpp
index 17195c14b8..10740a8b7b 100644
--- a/engines/sci/resource.cpp
+++ b/engines/sci/resource.cpp
@@ -55,6 +55,11 @@ SciVersion getSciVersion() {
return s_sciVersion;
}
+SciVersion getSciVersionForDetection() {
+ assert(!g_sci);
+ return s_sciVersion;
+}
+
const char *getSciVersionDesc(SciVersion version) {
switch (version) {
case SCI_VERSION_NONE:
@@ -88,9 +93,6 @@ const char *getSciVersionDesc(SciVersion version) {
//////////////////////////////////////////////////////////////////////
-
-#undef SCI_REQUIRE_RESOURCE_FILES
-
//#define SCI_VERBOSE_RESMAN 1
static const char *const s_errorDescriptions[] = {
@@ -639,7 +641,7 @@ int ResourceManager::addAppropriateSources() {
return 1;
}
-int ResourceManager::addAppropriateSources(const Common::FSList &fslist) {
+int ResourceManager::addAppropriateSourcesForDetection(const Common::FSList &fslist) {
ResourceSource *map = 0;
Common::Array<ResourceSource *> sci21Maps;
@@ -858,7 +860,7 @@ void ResourceManager::freeResourceSources() {
ResourceManager::ResourceManager() {
}
-void ResourceManager::init(bool initFromFallbackDetector) {
+void ResourceManager::init() {
_memoryLocked = 0;
_memoryLRU = 0;
_LRU.clear();
@@ -890,25 +892,24 @@ void ResourceManager::init(bool initFromFallbackDetector) {
debugC(1, kDebugLevelResMan, "resMan: Detected volume version %d: %s", _volVersion, versionDescription(_volVersion));
if ((_mapVersion == kResVersionUnknown) && (_volVersion == kResVersionUnknown)) {
- warning("Volume and map version not detected, assuming that this is not a sci game");
+ warning("Volume and map version not detected, assuming that this is not a SCI game");
_viewType = kViewUnknown;
return;
}
scanNewSources();
- if (!initFromFallbackDetector) {
- if (!addAudioSources()) {
- // FIXME: This error message is not always correct.
- // OTOH, it is nice to be able to detect missing files/sources
- // So we should definitely fix addAudioSources so this error
- // only pops up when necessary. Disabling for now.
- //error("Somehow I can't seem to find the sound files I need (RESOURCE.AUD/RESOURCE.SFX), aborting");
- }
- addScriptChunkSources();
- scanNewSources();
+ if (!addAudioSources()) {
+ // FIXME: This error message is not always correct.
+ // OTOH, it is nice to be able to detect missing files/sources
+ // So we should definitely fix addAudioSources so this error
+ // only pops up when necessary. Disabling for now.
+ //error("Somehow I can't seem to find the sound files I need (RESOURCE.AUD/RESOURCE.SFX), aborting");
}
+ addScriptChunkSources();
+ scanNewSources();
+
detectSciVersion();
debugC(1, kDebugLevelResMan, "resMan: Detected %s", getSciVersionDesc(getSciVersion()));
@@ -943,6 +944,22 @@ void ResourceManager::init(bool initFromFallbackDetector) {
}
}
+void ResourceManager::initForDetection() {
+ assert(!g_sci);
+
+ _memoryLocked = 0;
+ _memoryLRU = 0;
+ _LRU.clear();
+ _resMap.clear();
+ _audioMapSCI1 = NULL;
+
+ _mapVersion = detectMapVersion();
+ _volVersion = detectVolVersion();
+
+ scanNewSources();
+ detectSciVersion();
+}
+
ResourceManager::~ResourceManager() {
// freeing resources
ResourceMap::iterator itr = _resMap.begin();
@@ -1645,6 +1662,9 @@ int ResourceManager::readResourceMapSCI1(ResourceSource *map) {
do {
type = fileStream->readByte() & 0x1F;
resMap[type].wOffset = fileStream->readUint16LE();
+ if (fileStream->eos())
+ return SCI_ERROR_RESMAP_NOT_FOUND;
+
resMap[prevtype].wSize = (resMap[type].wOffset
- resMap[prevtype].wOffset) / nEntrySize;
prevtype = type;
@@ -2330,6 +2350,9 @@ bool ResourceManager::detectPaletteMergingSci11() {
// Old palette format used in palette resource? -> it's merging
if ((data[0] == 0 && data[1] == 1) || (data[0] == 0 && data[1] == 0 && READ_LE_UINT16(data + 29) == 0))
return true;
+ // Hardcoded: Laura Bow 2 floppy uses new palette resource, but still palette merging + 16 bit color matching
+ if ((g_sci->getGameId() == GID_LAURABOW2) && (!g_sci->isCD()) && (!g_sci->isDemo()))
+ return true;
return false;
}
return false;
diff --git a/engines/sci/resource.h b/engines/sci/resource.h
index e90f52a3ce..ef48998b04 100644
--- a/engines/sci/resource.h
+++ b/engines/sci/resource.h
@@ -312,10 +312,22 @@ public:
/**
* Initializes the resource manager.
*/
- void init(bool initFromFallbackDetector = false);
+ void init();
+ /**
+ * Similar to the function above, only called from the fallback detector
+ */
+ void initForDetection();
+
+ /**
+ * Adds all of the resource files for a game
+ */
int addAppropriateSources();
- int addAppropriateSources(const Common::FSList &fslist); // TODO: Switch from FSList to Common::Archive?
+
+ /**
+ * Similar to the function above, only called from the fallback detector
+ */
+ int addAppropriateSourcesForDetection(const Common::FSList &fslist); // TODO: Switch from FSList to Common::Archive?
/**
* Looks up a resource's data.
@@ -584,6 +596,7 @@ public:
Track *getDigitalTrack();
int getChannelFilterMask(int hardwareMask, bool wantsRhythm);
byte getInitialVoiceCount(byte channel);
+ byte getSoundPriority() const { return _soundPriority; }
private:
SciVersion _soundVersion;
@@ -591,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 66778f0914..3a43774492 100644
--- a/engines/sci/resource_audio.cpp
+++ b/engines/sci/resource_audio.cpp
@@ -110,7 +110,7 @@ bool Resource::loadFromAudioVolumeSCI11(Common::SeekableReadStream *file) {
unalloc();
return false;
}
-
+
_headerSize = file->readByte();
if (type == kResourceTypeAudio) {
@@ -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 fc723f18cf..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");
@@ -219,7 +220,7 @@ Common::Error SciEngine::run() {
// Add the after market GM patches for the specified game, if they exist
_resMan->addNewGMPatch(_gameId);
_gameObjectAddress = _resMan->findGameObject();
-
+
_scriptPatcher = new ScriptPatcher();
SegManager *segMan = new SegManager(_resMan, _scriptPatcher);
@@ -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,
@@ -896,7 +885,7 @@ void SciEngine::syncSoundSettings() {
bool SciEngine::speechAndSubtitlesEnabled() {
bool subtitlesOn = ConfMan.getBool("subtitles");
bool speechOn = !ConfMan.getBool("speech_mute");
-
+
if (isCD() && subtitlesOn && speechOn)
return true;
return false;
@@ -936,7 +925,7 @@ void SciEngine::updateScummVMAudioOptions() {
// depending on the in-game settings
if (isCD() && getSciVersion() == SCI_VERSION_1_1) {
uint16 ingameSetting = _gamestate->variables[VAR_GLOBAL][90].getOffset();
-
+
switch (ingameSetting) {
case 1:
// subtitles
diff --git a/engines/sci/sci.h b/engines/sci/sci.h
index 48bc4819d2..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 {
@@ -314,13 +315,16 @@ public:
* if NULL is passed no subtitle will be added to the returned string
* @return processed string
*/
- Common::String strSplit(const char *str, const char *sep = "\r----------\r");
+ Common::String strSplitLanguage(const char *str, uint16 *splitLanguage, const char *sep = "\r----------\r");
+ Common::String strSplit(const char *str, const char *sep = "\r----------\r") {
+ return strSplitLanguage(str, NULL, sep);
+ }
kLanguage getSciLanguage();
void setSciLanguage(kLanguage lang);
void setSciLanguage();
- Common::String getSciLanguageString(const Common::String &str, kLanguage lang, kLanguage *lang2 = NULL) const;
+ Common::String getSciLanguageString(const Common::String &str, kLanguage lang, kLanguage *lang2 = NULL, uint16 *languageSplitter = NULL) const;
// Check if vocabulary needs to get switched (in multilingual parser games)
void checkVocabularySwitch();
@@ -429,6 +433,12 @@ extern SciEngine *g_sci;
SciVersion getSciVersion();
/**
+ * Same as above, but this version doesn't assert on unknown SCI versions.
+ * Only used by the fallback detector
+ */
+SciVersion getSciVersionForDetection();
+
+/**
* Convenience function converting an SCI version into a human-readable string.
*/
const char *getSciVersionDesc(SciVersion version);
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 362cca699d..dca73c3f51 100644
--- a/engines/sci/sound/music.cpp
+++ b/engines/sci/sound/music.cpp
@@ -142,8 +142,10 @@ void SciMusic::init() {
_driverLastChannel = _pMidiDrv->getLastChannel();
if (getSciVersion() <= SCI_VERSION_0_LATE)
_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 6149bb799e..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];
@@ -264,8 +271,11 @@ private:
int _driverFirstChannel;
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/actor.cpp b/engines/scumm/actor.cpp
index 116a953b0b..0d7ea39ec2 100644
--- a/engines/scumm/actor.cpp
+++ b/engines/scumm/actor.cpp
@@ -33,6 +33,7 @@
#include "scumm/resource.h"
#include "scumm/saveload.h"
#include "scumm/scumm_v7.h"
+#include "scumm/scumm_v0.h"
#include "scumm/he/sound_he.h"
#include "scumm/he/sprite_he.h"
#include "scumm/usage_bits.h"
@@ -42,12 +43,66 @@ namespace Scumm {
byte Actor::kInvalidBox = 0;
-static const byte v0ActorTalkArray[0x19] = {
- 0x00, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x00, 0x46, 0x06,
- 0x06, 0x06, 0x06, 0xFF, 0xFF,
- 0x06, 0xC0, 0x06, 0x06, 0x00,
- 0xC0, 0xC0, 0x00, 0x06, 0x06
+static const byte v0ActorDemoTalk[25] = {
+ 0x00,
+ 0x06, // Syd
+ 0x06, // Razor
+ 0x06, // Dave
+ 0x06, // Michael
+ 0x06, // Bernard
+ 0x06, // Wendy
+ 0x00, // Jeff
+ 0x46, // Radiation Suit
+ 0x06, // Dr Fred
+ 0x06, // Nurse Edna
+ 0x06, // Weird Ed
+ 0x06, // Dead Cousin Ted
+ 0xE2, // Purple Tentacle
+ 0xE2, // Green Tentacle
+ 0x06, // Meteor police
+ 0xC0, // Meteor
+ 0x06, // Mark Eteer
+ 0x06, // Talkshow Host
+ 0x00, // Plant
+ 0xC0, // Meteor Radiation
+ 0xC0, // Edsel (small, outro)
+ 0x00, // Meteor (small, intro)
+ 0x06, // Sandy (Lab)
+ 0x06, // Sandy (Cut-Scene)
+};
+
+static const byte v0ActorTalk[25] = {
+ 0x00,
+ 0x06, // Syd
+ 0x06, // Razor
+ 0x06, // Dave
+ 0x06, // Michael
+ 0x06, // Bernard
+ 0x06, // Wendy
+ 0x00, // Jeff
+ 0x46, // Radiation Suit
+ 0x06, // Dr Fred
+ 0x06, // Nurse Edna
+ 0x06, // Weird Ed
+ 0x06, // Dead Cousin Ted
+ 0xFF, // Purple Tentacle
+ 0xFF, // Green Tentacle
+ 0x06, // Meteor police
+ 0xC0, // Meteor
+ 0x06, // Mark Eteer
+ 0x06, // Talkshow Host
+ 0x00, // Plant
+ 0xC0, // Meteor Radiation
+ 0xC0, // Edsel (small, outro)
+ 0x00, // Meteor (small, intro)
+ 0x06, // Sandy (Lab)
+ 0x06, // Sandy (Cut-Scene)
+};
+
+static const byte v0WalkboxSlantedModifier[0x16] = {
+ 0x00,0x01,0x02,0x03,0x03,0x04,0x05,0x06,
+ 0x06,0x07,0x08,0x09,0x09,0x0A,0x0B,
+ 0x0C,0x0C,0x0D,0x0E,0x0F,0x10,0x10
};
Actor::Actor(ScummEngine *scumm, int id) :
@@ -182,6 +237,20 @@ void Actor_v0::initActor(int mode) {
_costCommand = 0xFF;
_miscflags = 0;
_speaking = 0;
+
+ _walkCountModulo = 0;
+ _newWalkBoxEntered = false;
+ _walkDirX = 0;
+ _walkDirY = 0;
+ _walkYCountGreaterThanXCount = 0;
+ _walkXCount = 0;
+ _walkXCountInc = 0;
+ _walkYCount = 0;
+ _walkYCountInc = 0;
+ _walkMaxXYCountInc = 0;
+
+ _tmp_WalkBox = 0;
+ _tmp_NewWalkBoxEntered = 0;
_animFrameRepeat = 0;
for (int i = 0; i < 8; ++i) {
@@ -189,6 +258,12 @@ void Actor_v0::initActor(int mode) {
_limbFrameRepeat[i] = 0;
_limb_flipped[i] = false;
}
+
+ if (_vm->_game.features & GF_DEMO) {
+ _sound[0] = v0ActorDemoTalk[_number];
+ } else {
+ _sound[0] = v0ActorTalk[_number];
+ }
}
void Actor::setBox(int box) {
@@ -249,9 +324,12 @@ void Actor::stopActorMoving() {
if (_walkScript)
_vm->stopScript(_walkScript);
- _moving = 0;
- if (_vm->_game.version == 0)
+ if (_vm->_game.version == 0) {
+ _moving = 2;
setDirection(_facing);
+ } else {
+ _moving = 0;
+ }
}
void Actor::setActorWalkSpeed(uint newSpeedX, uint newSpeedY) {
@@ -339,9 +417,6 @@ int Actor::actorWalkStep() {
int distX, distY;
int nextFacing;
- if (_vm->_game.version == 0)
- ((Actor_v0 *)this)->_animFrameRepeat = -1;
-
_needRedraw = true;
nextFacing = updateActorDirection(true);
@@ -350,10 +425,6 @@ int Actor::actorWalkStep() {
startWalkAnim(1, nextFacing);
}
_moving |= MF_IN_LEG;
-
- // V0: Don't move during the turn
- if (_vm->_game.version == 0)
- return 0;
}
if (_walkbox != _walkdata.curbox && _vm->checkXYInBoxBounds(_walkdata.curbox, _pos.x, _pos.y)) {
@@ -368,13 +439,28 @@ int Actor::actorWalkStep() {
return 0;
}
- tmpX = (_pos.x << 16) + _walkdata.xfrac + (_walkdata.deltaXFactor >> 8) * _scalex;
- _walkdata.xfrac = (uint16)tmpX;
- _pos.x = (tmpX >> 16);
+ if (_vm->_game.version <= 2) {
+ if (_walkdata.deltaXFactor != 0) {
+ if (_walkdata.deltaXFactor > 0)
+ _pos.x += 1;
+ else
+ _pos.x -= 1;
+ }
+ if (_walkdata.deltaYFactor != 0) {
+ if (_walkdata.deltaYFactor > 0)
+ _pos.y += 1;
+ else
+ _pos.y -= 1;
+ }
+ } else {
+ tmpX = (_pos.x << 16) + _walkdata.xfrac + (_walkdata.deltaXFactor >> 8) * _scalex;
+ _walkdata.xfrac = (uint16)tmpX;
+ _pos.x = (tmpX >> 16);
- tmpY = (_pos.y << 16) + _walkdata.yfrac + (_walkdata.deltaYFactor >> 8) * _scaley;
- _walkdata.yfrac = (uint16)tmpY;
- _pos.y = (tmpY >> 16);
+ tmpY = (_pos.y << 16) + _walkdata.yfrac + (_walkdata.deltaYFactor >> 8) * _scaley;
+ _walkdata.yfrac = (uint16)tmpY;
+ _pos.y = (tmpY >> 16);
+ }
if (ABS(_pos.x - _walkdata.cur.x) > distX) {
_pos.x = _walkdata.next.x;
@@ -384,17 +470,118 @@ int Actor::actorWalkStep() {
_pos.y = _walkdata.next.y;
}
- if (_vm->_game.version >= 4 && _vm->_game.version <= 6 && _pos == _walkdata.next) {
+ if ((_vm->_game.version <= 2 || (_vm->_game.version >= 4 && _vm->_game.version <= 6)) && _pos == _walkdata.next) {
_moving &= ~MF_IN_LEG;
return 0;
}
- if (_vm->_game.version == 0)
- ((Actor_v0 *)this)->animateActor(newDirToOldDir(_facing));
-
return 1;
}
+bool Actor_v0::calcWalkDistances() {
+ _walkDirX = 0;
+ _walkDirY = 0;
+ _walkYCountGreaterThanXCount = 0;
+ uint16 A = 0;
+
+ if (_CurrentWalkTo.x >= _tmp_Dest.x) {
+ A = _CurrentWalkTo.x - _tmp_Dest.x;
+ _walkDirX = 1;
+ } else {
+ A = _tmp_Dest.x - _CurrentWalkTo.x;
+ }
+
+ _walkXCountInc = A;
+
+ if (_CurrentWalkTo.y >= _tmp_Dest.y) {
+ A = _CurrentWalkTo.y - _tmp_Dest.y;
+ _walkDirY = 1;
+ } else {
+ A = _tmp_Dest.y - _CurrentWalkTo.y;
+ }
+
+ _walkYCountInc = A;
+ if (!_walkXCountInc && !_walkYCountInc)
+ return true;
+
+ if (_walkXCountInc <= _walkYCountInc)
+ _walkYCountGreaterThanXCount = 1;
+
+ // 2FCC
+ A = _walkXCountInc;
+ if (A <= _walkYCountInc)
+ A = _walkYCountInc;
+
+ _walkMaxXYCountInc = A;
+ _walkXCount = _walkXCountInc;
+ _walkYCount = _walkYCountInc;
+ _walkCountModulo = _walkMaxXYCountInc;
+
+ return false;
+}
+
+byte Actor_v0::actorWalkX() {
+ byte A = _walkXCount;
+ A += _walkXCountInc;
+ if (A >= _walkCountModulo) {
+ if (!_walkDirX) {
+ _tmp_Dest.x--;
+ } else {
+ _tmp_Dest.x++;
+ }
+
+ A -= _walkCountModulo;
+ }
+ // 2EAC
+ _walkXCount = A;
+ setTmpFromActor();
+ if (updateWalkbox() == kInvalidBox) {
+ // 2EB9
+ setActorFromTmp();
+
+ return 3;
+ }
+ // 2EBF
+ if (_tmp_Dest.x == _CurrentWalkTo.x)
+ return 1;
+
+ return 0;
+}
+
+byte Actor_v0::actorWalkY() {
+ byte A = _walkYCount;
+ A += _walkYCountInc;
+ if (A >= _walkCountModulo) {
+ if (!_walkDirY) {
+ _tmp_Dest.y--;
+ } else {
+ _tmp_Dest.y++;
+ }
+
+ A -= _walkCountModulo;
+ }
+ // 2EEB
+ _walkYCount = A;
+ setTmpFromActor();
+ if (updateWalkbox() == kInvalidBox) {
+ // 2EF8
+ setActorFromTmp();
+ return 4;
+ }
+ // 2EFE
+ if (_walkYCountInc != 0) {
+ if (_walkYCountInc == 0xFF) {
+ setActorFromTmp();
+ return 4;
+ }
+ }
+ // 2F0D
+ if (_CurrentWalkTo.y == _tmp_Dest.y)
+ return 1;
+
+ return 0;
+}
+
void Actor::startWalkActor(int destX, int destY, int dir) {
AdjustBoxResult abr;
@@ -447,9 +634,16 @@ void Actor::startWalkActor(int destX, int destY, int dir) {
_walkdata.dest.y = abr.y;
_walkdata.destbox = abr.box;
_walkdata.destdir = dir;
- _moving = (_moving & MF_IN_LEG) | MF_NEW_LEG;
- _walkdata.point3.x = 32000;
+
+ if (_vm->_game.version == 0) {
+ ((Actor_v0*)this)->_newWalkBoxEntered = true;
+ } else if (_vm->_game.version <= 2) {
+ _moving = (_moving & ~(MF_LAST_LEG | MF_IN_LEG)) | MF_NEW_LEG;
+ } else {
+ _moving = (_moving & MF_IN_LEG) | MF_NEW_LEG;
+ }
+ _walkdata.point3.x = 32000;
_walkdata.curbox = _walkbox;
}
@@ -567,88 +761,206 @@ void Actor::walkActor() {
calcMovementFactor(_walkdata.dest);
}
-bool Actor_v2::checkWalkboxesHaveDirectPath(Common::Point &foundPath) {
- // only MM v0 supports walking in direct line between walkboxes.
- // MM v1 already does not support it anymore.
- return false;
-}
+void Actor_v0::walkActor() {
+ actorSetWalkTo();
-bool Actor_v0::intersectLineSegments(const Common::Point &line1Start, const Common::Point &line1End,
- const Common::Point &line2Start, const Common::Point &line2End, Common::Point &result)
-{
- const Common::Point v1 = line1End - line1Start; // line1(n1) = line1Start + n1 * v1
- const Common::Point v2 = line2End - line2Start; // line2(n2) = line2Start + n2 * v2
+ _needRedraw = true;
+ if (_NewWalkTo != _CurrentWalkTo) {
+ _CurrentWalkTo = _NewWalkTo;
- double det = v2.x * v1.y - v1.x * v2.y;
- if (det == 0)
- return false;
+L2A33:;
+ _moving &= 0xF0;
+ _tmp_Dest = _pos;
- double n1 = ((double)v2.x * (line2Start.y - line1Start.y) -
- (double)v2.y * (line2Start.x - line1Start.x)) / det;
- double n2 = ((double)v1.x * (line2Start.y - line1Start.y) -
- (double)v1.y * (line2Start.x - line1Start.x)) / det;
+ byte tmp = calcWalkDistances();
+ _moving &= 0xF0;
+ _moving |= tmp;
- // both coefficients have to be in [0, 1], otherwise the intersection is
- // not inside of at least one of the two line segments
- if (n1 < 0.0 || n1 > 1.0 || n2 < 0.0 || n2 > 1.0)
- return false;
+ if (!_walkYCountGreaterThanXCount) {
+ if (_walkDirX) {
+ _targetFacing = getAngleFromPos(V12_X_MULTIPLIER*1, V12_Y_MULTIPLIER*0, false);
+ } else {
+ _targetFacing = getAngleFromPos(V12_X_MULTIPLIER*-1, V12_Y_MULTIPLIER*0, false);
+ }
+ } else {
+ if (_walkDirY) {
+ _targetFacing = getAngleFromPos(V12_X_MULTIPLIER*0, V12_Y_MULTIPLIER*1, false);
+ } else {
+ _targetFacing = getAngleFromPos(V12_X_MULTIPLIER*0, V12_Y_MULTIPLIER*-1, false);
+ }
+ }
- result.x = line1Start.x + (int)(n1 * v1.x);
- result.y = line1Start.y + (int)(n1 * v1.y);
- return true;
-}
+ directionUpdate();
+
+ if (_moving & 0x80)
+ return;
-/*
- * MM v0 allows the actor to walk in a direct line between boxes to the target
- * if actor and target share a horizontal or vertical corridor.
- * If such a corridor is found the actor is not forced to go horizontally or
- * vertically from one box to the next but can also walk diagonally.
- *
- * Note: the original v0 interpreter sets the target destination for diagonal
- * walking only once and then rechecks whenever the actor reaches a new box if the
- * walk destination is still suitable for the current box.
- * ScummVM does not perform such a check, so it is possible to leave the walkboxes
- * in some cases, for example L-shaped rooms like the swimming pool (actor walks over water)
- * or the medical room (actor walks over examination table).
- * To solve this we intersect the new walk destination with the actor's walkbox borders,
- * so a recheck is done when the actor leaves his box. This is done by the
- * intersectLineSegments() routine calls.
- */
-bool Actor_v0::checkWalkboxesHaveDirectPath(Common::Point &foundPath) {
- BoxCoords boxCoords = _vm->getBoxCoordinates(_walkbox);
- BoxCoords curBoxCoords = _vm->getBoxCoordinates(_walkdata.curbox);
-
- // check if next walkbox is left or right to actor's box
- if (boxCoords.ll.x > curBoxCoords.lr.x || boxCoords.lr.x < curBoxCoords.ll.x) {
- // determine horizontal corridor gates
- int gateUpper = MAX(boxCoords.ul.y, curBoxCoords.ul.y);
- int gateLower = MIN(boxCoords.ll.y, curBoxCoords.ll.y);
-
- // check if actor and target are in the same horizontal corridor between the boxes
- if ((_pos.y >= gateUpper && _pos.y <= gateLower) &&
- (_walkdata.dest.y >= gateUpper && _walkdata.dest.y <= gateLower)) {
- if (boxCoords.ll.x > curBoxCoords.lr.x) // next box is left
- return intersectLineSegments(_pos, _walkdata.dest, boxCoords.ll, boxCoords.ul, foundPath);
- else // next box is right
- return intersectLineSegments(_pos, _walkdata.dest, boxCoords.lr, boxCoords.ur, foundPath);
- }
- // check if next walkbox is above or below actor's box
- } else if (boxCoords.ul.y > curBoxCoords.ll.y || boxCoords.ll.y < curBoxCoords.ul.y) {
- // determine vertical corridor gates
- int gateLeft = MAX(boxCoords.ll.x, curBoxCoords.ll.x);
- int gateRight = MIN(boxCoords.lr.x, curBoxCoords.lr.x);
-
- // check if actor and target are in the same vertical corridor between the boxes
- if ((_pos.x >= gateLeft && _pos.x <= gateRight) &&
- (_walkdata.dest.x >= gateLeft && _walkdata.dest.x <= gateRight)) {
- if (boxCoords.ul.y > curBoxCoords.ll.y) // next box is above
- return intersectLineSegments(_pos, _walkdata.dest, boxCoords.ul, boxCoords.ur, foundPath);
- else // next box is below
- return intersectLineSegments(_pos, _walkdata.dest, boxCoords.ll, boxCoords.lr, foundPath);
+ animateActor(newDirToOldDir(_facing));
+
+ } else {
+ // 2A0A
+ if ((_moving & 0x7F) != 1) {
+
+ if (_NewWalkTo == _pos)
+ return;
}
}
- return false;
+ // 2A9A
+ if (_moving == 2)
+ return;
+
+ if ((_moving & 0x0F) == 1)
+ return stopActorMoving();
+
+ // 2AAD
+ if (_moving & 0x80) {
+ directionUpdate();
+
+ if (_moving & 0x80)
+ return;
+
+ animateActor(newDirToOldDir(_facing));
+ }
+
+ if ((_moving & 0x0F) == 3) {
+L2C36:;
+ setTmpFromActor();
+
+ if (!_walkDirX) {
+ _pos.x--;
+ } else {
+ _pos.x++;
+ }
+
+ // 2C51
+ if (updateWalkbox() != kInvalidBox) {
+
+ setActorFromTmp();
+ goto L2A33;
+ }
+
+ setActorFromTmp();
+
+ if (_CurrentWalkTo.y == _tmp_Dest.y) {
+ stopActorMoving();
+ return;
+ }
+
+ if (!_walkDirY) {
+ _tmp_Dest.y--;
+ } else {
+ _tmp_Dest.y++;
+ }
+
+ setTmpFromActor();
+
+ byte A = updateWalkbox();
+ if (A == 0xFF) {
+ setActorFromTmp();
+ stopActorMoving();
+ return;
+ }
+ // 2C98: Yes, an exact copy of what just occured.. the original does this, so im doing it...
+ // Just to keep me sane when going over it :)
+ if (A == 0xFF) {
+ setActorFromTmp();
+ stopActorMoving();
+ return;
+ }
+ return;
+ }
+
+ // 2ADA
+ if ((_moving & 0x0F) == 4) {
+L2CA3:;
+ setTmpFromActor();
+
+ if (!_walkDirY) {
+ _pos.y--;
+ } else {
+ _pos.y++;
+ }
+ if (updateWalkbox() == kInvalidBox) {
+ // 2CC7
+ setActorFromTmp();
+ if (_CurrentWalkTo.x == _tmp_Dest.x) {
+ stopActorMoving();
+ return;
+ }
+
+ if (!_walkDirX) {
+ _tmp_Dest.x--;
+ } else {
+ _tmp_Dest.x++;
+ }
+ setTmpFromActor();
+
+ if (updateWalkbox() == kInvalidBox) {
+ setActorFromTmp();
+ stopActorMoving();
+ }
+
+ return;
+ } else {
+ setActorFromTmp();
+ goto L2A33;
+ }
+ }
+
+ if ((_moving & 0x0F) == 0) {
+ // 2AE8
+ byte A = actorWalkX();
+
+ if (A == 1) {
+ A = actorWalkY();
+ if (A == 1) {
+ _moving &= 0xF0;
+ _moving |= A;
+ } else {
+ if (A == 4)
+ stopActorMoving();
+ }
+
+ return;
+
+ } else {
+ // 2B0C
+ if (A == 3) {
+ _moving &= 0xF0;
+ _moving |= A;
+
+ if (_walkDirY) {
+ _targetFacing = getAngleFromPos(V12_X_MULTIPLIER*0, V12_Y_MULTIPLIER*1, false);
+ } else {
+ _targetFacing = getAngleFromPos(V12_X_MULTIPLIER*0, V12_Y_MULTIPLIER*-1, false);
+ }
+
+ directionUpdate();
+ animateActor(newDirToOldDir(_facing));
+ goto L2C36;
+
+ } else {
+ // 2B39
+ A = actorWalkY();
+ if (A != 4)
+ return;
+
+ _moving &= 0xF0;
+ _moving |= A;
+
+ if (_walkDirX) {
+ _targetFacing = getAngleFromPos(V12_X_MULTIPLIER*1, V12_Y_MULTIPLIER*0, false);
+ } else {
+ _targetFacing = getAngleFromPos(V12_X_MULTIPLIER*-1, V12_Y_MULTIPLIER*0, false);
+ }
+
+ directionUpdate();
+ animateActor(newDirToOldDir(_facing));
+ goto L2CA3;
+ }
+ }
+ }
}
void Actor_v2::walkActor() {
@@ -697,10 +1009,8 @@ void Actor_v2::walkActor() {
_walkdata.curbox = next_box;
- if (!checkWalkboxesHaveDirectPath(foundPath)) {
- getClosestPtOnBox(_vm->getBoxCoordinates(_walkdata.curbox), _pos.x, _pos.y, tmp.x, tmp.y);
- getClosestPtOnBox(_vm->getBoxCoordinates(_walkbox), tmp.x, tmp.y, foundPath.x, foundPath.y);
- }
+ getClosestPtOnBox(_vm->getBoxCoordinates(_walkdata.curbox), _pos.x, _pos.y, tmp.x, tmp.y);
+ getClosestPtOnBox(_vm->getBoxCoordinates(_walkbox), tmp.x, tmp.y, foundPath.x, foundPath.y);
}
calcMovementFactor(foundPath);
}
@@ -972,7 +1282,7 @@ void Actor::setDirection(int direction) {
}
void Actor_v0::setDirection(int direction) {
- int dir = newDirToOldDir( direction );
+ int dir = newDirToOldDir(direction);
int res = 0;
switch (dir) {
@@ -985,18 +1295,16 @@ void Actor_v0::setDirection(int direction) {
break;
case 2:
- res = 6; // Face Away
+ res = 6; // Face Camera
break;
default:
- res = 7; // Face Camera
+ res = 7; // Face Away
break;
}
_animFrameRepeat = -1;
animateActor(res);
- if (_moving)
- animateCostume();
}
void Actor::faceToObject(int obj) {
@@ -1017,8 +1325,14 @@ void Actor::turnToDirection(int newdir) {
return;
if (_vm->_game.version <= 6) {
- _moving = MF_TURN;
_targetFacing = newdir;
+
+ if (_vm->_game.version == 0) {
+ setDirection(newdir);
+ return;
+ }
+ _moving = MF_TURN;
+
} else {
_moving &= ~MF_TURN;
if (newdir != _facing) {
@@ -1085,8 +1399,14 @@ void Actor::putActor(int dstX, int dstY, int newRoom) {
}
// V0 always sets the actor to face the camera upon entering a room
- if (_vm->_game.version == 0)
+ if (_vm->_game.version == 0) {
+ _walkdata.dest = _pos;
+
+ ((Actor_v0*)this)->_newWalkBoxEntered = true;
+ ((Actor_v0*)this)->_CurrentWalkTo = _pos;
+
setDirection(oldDirToNewDir(2));
+ }
}
static bool inBoxQuickReject(const BoxCoords &box, int x, int y, int threshold) {
@@ -1200,6 +1520,59 @@ static int checkXYInBoxBounds(int boxnum, int x, int y, int &destX, int &destY)
return dist;
}
+AdjustBoxResult Actor_v0::adjustPosInBorderWalkbox(AdjustBoxResult box) {
+ AdjustBoxResult Result = box;
+ BoxCoords BoxCoord = _vm->getBoxCoordinates(box.box);
+
+ byte boxMask = _vm->getMaskFromBox(box.box);
+ if (!(boxMask & 0x80))
+ return Result;
+
+ int16 A;
+ boxMask &= 0x7C;
+ if (boxMask == 0x0C)
+ A = 2;
+ else {
+ if (boxMask != 0x08)
+ return Result;
+
+ A = 1;
+ }
+
+ // 1BC6
+ byte Modifier = box.y - BoxCoord.ul.y;
+ assert(Modifier < 0x16);
+
+ if (A == 1) {
+ // 1BCF
+ A = BoxCoord.ur.x - v0WalkboxSlantedModifier[ Modifier ];
+ if (A < box.x)
+ return box;
+
+ if (A < 0xA0 || A == 0xA0)
+ A = 0;
+
+ Result.x = A;
+ } else {
+ // 1BED
+ A = BoxCoord.ul.x + v0WalkboxSlantedModifier[ Modifier ];
+
+ if (A < box.x || A == box.x)
+ Result.x = A;
+ }
+
+ return Result;
+}
+
+AdjustBoxResult Actor_v0::adjustXYToBeInBox(int dstX, int dstY) {
+ AdjustBoxResult Result = Actor_v2::adjustXYToBeInBox(dstX, dstY);
+
+ if (Result.box == kInvalidBox)
+ return Result;
+
+ return adjustPosInBorderWalkbox(Result);
+}
+
AdjustBoxResult Actor_v2::adjustXYToBeInBox(const int dstX, const int dstY) {
AdjustBoxResult abr;
@@ -1410,6 +1783,7 @@ void Actor::showActor() {
Actor_v0 *a = ((Actor_v0 *)this);
a->_costCommand = a->_costCommandNew = 0xFF;
+ _walkdata.dest = a->_CurrentWalkTo;
for (int i = 0; i < 8; ++i) {
a->_limbFrameRepeat[i] = 0;
@@ -1451,34 +1825,6 @@ void ScummEngine::showActors() {
}
}
-// bits 0..5: sound, bit 6: ???
-static const byte v0ActorSounds[24] = {
- 0x06, // Syd
- 0x06, // Razor
- 0x06, // Dave
- 0x06, // Michael
- 0x06, // Bernard
- 0x06, // Wendy
- 0x00, // Jeff
- 0x46, // Radiation Suit
- 0x06, // Dr Fred
- 0x06, // Nurse Edna
- 0x06, // Weird Ed
- 0x06, // Dead Cousin Ted
- 0xFF, // Purple Tentacle
- 0xFF, // Green Tentacle
- 0x06, // Meteor police
- 0xC0, // Meteor
- 0x06, // Mark Eteer
- 0x06, // Talkshow Host
- 0x00, // Plant
- 0xC0, // Meteor Radiation
- 0xC0, // Edsel (small, outro)
- 0x00, // Meteor (small, intro)
- 0x06, // Sandy (Lab)
- 0x06, // Sandy (Cut-Scene)
-};
-
/* Used in Scumm v5 only. Play sounds associated with actors */
void ScummEngine::playActorSounds() {
int i, j;
@@ -1488,7 +1834,7 @@ void ScummEngine::playActorSounds() {
if (_actors[i]->_cost.soundCounter && _actors[i]->isInCurrentRoom()) {
_currentScript = 0xFF;
if (_game.version == 0) {
- sound = v0ActorSounds[i - 1] & 0x3F;
+ sound = _actors[i]->_sound[0] & 0x3F;
} else {
sound = _actors[i]->_sound[0];
}
@@ -1642,13 +1988,13 @@ void ScummEngine::processActors() {
continue;
// Sound
- if (a0->_moving && _currentRoom != 1 && _currentRoom != 44) {
+ if (a0->_moving != 2 && _currentRoom != 1 && _currentRoom != 44) {
if (a0->_cost.soundPos == 0)
a0->_cost.soundCounter++;
// Is this the correct location?
// 0x073C
- if (v0ActorTalkArray[a0->_number] & 0x3F)
+ if (a0->_sound[0] & 0x3F)
a0->_cost.soundPos = (a0->_cost.soundPos + 1) % 3;
}
}
@@ -1659,8 +2005,17 @@ void ScummEngine::processActors() {
// would hence cause regressions. See also the other big
// comment further up in this method for some details.
if (a->_costume) {
- a->drawActorCostume();
- a->animateCostume();
+
+ // Unfortunately in V0, the 'animateCostume' call happens right after the call to 'walkActor' (which is before drawing the actor)...
+ // doing it the other way with V0, causes animation glitches (when beginnning to walk, as the costume hasnt been updated).
+ // Updating the costume directly after 'walkActor' and again, after drawing... causes frame skipping
+ if (_game.version == 0) {
+ a->animateCostume();
+ a->drawActorCostume();
+ } else {
+ a->drawActorCostume();
+ a->animateCostume();
+ }
}
}
}
@@ -1948,7 +2303,7 @@ void Actor::startAnimActor(int f) {
void Actor_v0::startAnimActor(int f) {
if (f == _talkStartFrame) {
- if (v0ActorTalkArray[_number] & 0x40)
+ if (_sound[0] & 0x40)
return;
_speaking = 1;
@@ -2054,7 +2409,7 @@ void Actor_v0::animateCostume() {
}
void Actor_v0::speakCheck() {
- if (v0ActorTalkArray[_number] & 0x80)
+ if (_sound[0] & 0x80)
return;
int cmd = newDirToOldDir(_facing);
@@ -2897,6 +3252,70 @@ void Actor_v0::animateActor(int anim) {
}
}
+byte Actor_v0::updateWalkbox() {
+ if (_vm->checkXYInBoxBounds(_walkbox, _pos.x, _pos.y))
+ return 0;
+
+ int numBoxes = _vm->getNumBoxes() - 1;
+ for (int i = 0; i <= numBoxes; i++) {
+ if (_vm->checkXYInBoxBounds(i, _pos.x, _pos.y) == true) {
+ if (_walkdata.curbox == i) {
+ setBox(i);
+ directionUpdate();
+
+ _newWalkBoxEntered = true;
+ return i;
+ }
+ }
+ }
+
+ return kInvalidBox;
+}
+
+void Actor_v0::directionUpdate() {
+
+ int nextFacing = updateActorDirection(true);
+ if (_facing != nextFacing) {
+ // 2A89
+ setDirection(nextFacing);
+
+ // Still need to turn?
+ if (_facing != _targetFacing) {
+ _moving |= 0x80;
+ return;
+ }
+ }
+
+ _moving &= ~0x80;
+}
+
+void Actor_v0::setTmpFromActor() {
+ _tmp_Pos = _pos;
+ _pos = _tmp_Dest;
+ _tmp_WalkBox = _walkbox;
+ _tmp_NewWalkBoxEntered = _newWalkBoxEntered;
+}
+
+void Actor_v0::setActorFromTmp() {
+ _pos = _tmp_Pos;
+ _tmp_Dest = _tmp_Pos;
+ _walkbox = _tmp_WalkBox;
+ _newWalkBoxEntered = _tmp_NewWalkBoxEntered;
+}
+
+void Actor_v0::actorSetWalkTo() {
+
+ if (_newWalkBoxEntered == false)
+ return;
+
+ _newWalkBoxEntered = false;
+
+ int nextBox = ((ScummEngine_v0*)_vm)->walkboxFindTarget(this, _walkdata.destbox, _walkdata.dest);
+ if (nextBox != kInvalidBox) {
+ _walkdata.curbox = nextBox;
+ }
+}
+
void Actor_v0::saveLoadWithSerializer(Serializer *ser) {
Actor::saveLoadWithSerializer(ser);
@@ -2910,6 +3329,20 @@ void Actor_v0::saveLoadWithSerializer(Serializer *ser) {
MKLINE(Actor_v0, _animFrameRepeat, sleByte, VER(89)),
MKARRAY(Actor_v0, _limbFrameRepeatNew[0], sleInt8, 8, VER(89)),
MKARRAY(Actor_v0, _limbFrameRepeat[0], sleInt8, 8, VER(90)),
+ MKLINE(Actor_v0, _CurrentWalkTo.x, sleInt16, VER(97)),
+ MKLINE(Actor_v0, _CurrentWalkTo.y, sleInt16, VER(97)),
+ MKLINE(Actor_v0, _NewWalkTo.x, sleInt16, VER(97)),
+ MKLINE(Actor_v0, _NewWalkTo.y, sleInt16, VER(97)),
+ MKLINE(Actor_v0, _walkCountModulo, sleInt8, VER(97)),
+ MKLINE(Actor_v0, _newWalkBoxEntered, sleByte, VER(97)),
+ MKLINE(Actor_v0, _walkDirX, sleByte, VER(97)),
+ MKLINE(Actor_v0, _walkDirY, sleByte, VER(97)),
+ MKLINE(Actor_v0, _walkYCountGreaterThanXCount, sleByte, VER(97)),
+ MKLINE(Actor_v0, _walkXCount, sleByte, VER(97)),
+ MKLINE(Actor_v0, _walkXCountInc, sleByte, VER(97)),
+ MKLINE(Actor_v0, _walkYCount, sleByte, VER(97)),
+ MKLINE(Actor_v0, _walkYCountInc, sleByte, VER(97)),
+ MKLINE(Actor_v0, _walkMaxXYCountInc, sleByte, VER(97)),
MKEND()
};
diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h
index 46dc7d0295..c1a3f23318 100644
--- a/engines/scumm/actor.h
+++ b/engines/scumm/actor.h
@@ -333,7 +333,6 @@ public:
protected:
virtual bool isPlayer();
virtual void prepareDrawActorCostume(BaseCostumeRenderer *bcr);
- virtual bool checkWalkboxesHaveDirectPath(Common::Point &foundPath);
};
enum ActorV0MiscFlags {
@@ -349,11 +348,32 @@ enum ActorV0MiscFlags {
class Actor_v0 : public Actor_v2 {
public:
+ Common::Point _CurrentWalkTo, _NewWalkTo;
+
byte _costCommandNew;
byte _costCommand;
byte _miscflags;
byte _speaking;
+ byte _walkCountModulo;
+ bool _newWalkBoxEntered;
+
+ byte _walkDirX;
+ byte _walkDirY;
+
+ byte _walkYCountGreaterThanXCount;
+ byte _walkXCount;
+ byte _walkXCountInc;
+ byte _walkYCount;
+ byte _walkYCountInc;
+
+ byte _walkMaxXYCountInc;
+
+ Common::Point _tmp_Pos;
+ Common::Point _tmp_Dest;
+ byte _tmp_WalkBox;
+ bool _tmp_NewWalkBoxEntered;
+
int8 _animFrameRepeat;
int8 _limbFrameRepeatNew[8];
int8 _limbFrameRepeat[8];
@@ -363,23 +383,32 @@ public:
public:
Actor_v0(ScummEngine *scumm, int id) : Actor_v2(scumm, id) {}
- virtual void initActor(int mode);
- virtual void animateActor(int anim);
- virtual void animateCostume();
+ void initActor(int mode);
+ void animateActor(int anim);
+ void animateCostume();
void limbFrameCheck(int limb);
+ void directionUpdate();
void speakCheck();
- virtual void setDirection(int direction);
+ void setDirection(int direction);
void startAnimActor(int f);
+ bool calcWalkDistances();
+ void walkActor();
+ void actorSetWalkTo();
+ byte actorWalkX();
+ byte actorWalkY();
+ byte updateWalkbox();
+
+ AdjustBoxResult adjustXYToBeInBox(int dstX, int dstY);
+ AdjustBoxResult adjustPosInBorderWalkbox(AdjustBoxResult box);
+
+ void setTmpFromActor();
+ void setActorFromTmp();
+
// Used by the save/load system:
virtual void saveLoadWithSerializer(Serializer *ser);
-
-protected:
- bool intersectLineSegments(const Common::Point &line1Start, const Common::Point &line1End,
- const Common::Point &line2Start, const Common::Point &line2End, Common::Point &result);
- virtual bool checkWalkboxesHaveDirectPath(Common::Point &foundPath);
};
diff --git a/engines/scumm/boxes.cpp b/engines/scumm/boxes.cpp
index 70c8f2e032..087d8425ac 100644
--- a/engines/scumm/boxes.cpp
+++ b/engines/scumm/boxes.cpp
@@ -1158,6 +1158,30 @@ bool ScummEngine::areBoxesNeighbors(int box1nr, int box2nr) {
return false;
}
+byte ScummEngine_v0::walkboxFindTarget(Actor *a, int destbox, Common::Point walkdest) {
+ Actor_v0 *Actor = (Actor_v0*)a;
+
+ byte nextBox = getNextBox(a->_walkbox, destbox);
+
+ if (nextBox != 0xFF && nextBox == destbox && areBoxesNeighbors(a->_walkbox, nextBox)) {
+
+ Actor->_NewWalkTo = walkdest;
+ return nextBox;
+ }
+
+ if (nextBox != 0xFF && nextBox != a->_walkbox) {
+
+ getClosestPtOnBox(getBoxCoordinates(nextBox), a->getPos().x, a->getPos().y, Actor->_NewWalkTo.x, Actor->_NewWalkTo.y);
+
+ } else {
+ if (walkdest.x == -1)
+ Actor->_NewWalkTo = Actor->_CurrentWalkTo;
+ else
+ Actor->_NewWalkTo = walkdest;
+ }
+ return nextBox;
+}
+
bool ScummEngine_v0::areBoxesNeighbors(int box1nr, int box2nr) {
int i;
const int numOfBoxes = getNumBoxes();
diff --git a/engines/scumm/cdda.cpp b/engines/scumm/cdda.cpp
index adb414ecce..d797712a31 100644
--- a/engines/scumm/cdda.cpp
+++ b/engines/scumm/cdda.cpp
@@ -46,7 +46,7 @@ private:
public:
CDDAStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse);
virtual ~CDDAStream();
-
+
int readBuffer(int16 *buffer, const int numSamples);
bool isStereo() const { return true; }
int getRate() const { return 44100; }
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.cpp b/engines/scumm/detection.cpp
index a7922b232e..45647c9bed 100644
--- a/engines/scumm/detection.cpp
+++ b/engines/scumm/detection.cpp
@@ -244,7 +244,7 @@ static Common::String generateFilenameForDetection(const char *pattern, Filename
case kGenRoomNum:
result = Common::String::format(pattern, 0);
break;
-
+
case kGenDiskNumSteam:
case kGenRoomNumSteam: {
const SteamIndexFile *indexFile = lookUpSteamIndexFile(pattern, platform);
@@ -323,6 +323,8 @@ static BaseScummFile *openDiskImage(const Common::FSNode &node, const GameFilena
gs.gameid = gfp->gameid;
gs.id = (Common::String(gfp->gameid) == "maniac" ? GID_MANIAC : GID_ZAK);
gs.platform = gfp->platform;
+ if (strcmp(gfp->pattern, "maniacdemo.d64") == 0)
+ gs.features |= GF_DEMO;
// determine second disk file name
Common::String disk2(disk1);
@@ -502,6 +504,7 @@ static void computeGameSettingsFromMD5(const Common::FSList &fslist, const GameF
// (since they have identical MD5):
if (dr.game.id == GID_MANIAC && !strcmp(gfp->pattern, "%02d.MAN")) {
dr.extra = "V1 Demo";
+ dr.game.features = GF_DEMO;
}
// HACK: Try to detect languages for translated games
diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h
index 791963e237..d42a7251d9 100644
--- a/engines/scumm/detection_tables.h
+++ b/engines/scumm/detection_tables.h
@@ -207,6 +207,7 @@ static const Engines::ObsoleteGameID obsoleteGameIDsTable[] = {
static const GameSettings gameVariantsTable[] = {
{"maniac", "Apple II", 0, GID_MANIAC, 0, 0, MDT_APPLEIIGS, 0, Common::kPlatformApple2GS, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
{"maniac", "C64", 0, GID_MANIAC, 0, 0, MDT_C64, 0, Common::kPlatformC64, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI) },
+ {"maniac", "C64 Demo", 0, GID_MANIAC, 0, 0, MDT_C64, GF_DEMO, Common::kPlatformC64, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI) },
{"maniac", "V1", "v1", GID_MANIAC, 1, 0, MDT_PCSPK | MDT_PCJR, 0, Common::kPlatformDOS, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
{"maniac", "V1 Demo", "v1", GID_MANIAC, 1, 0, MDT_PCSPK | MDT_PCJR, GF_DEMO, Common::kPlatformDOS, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
{"maniac", "NES", 0, GID_MANIAC, 1, 0, MDT_NONE, 0, Common::kPlatformNES, GUIO3(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_NOASPECT)},
@@ -309,7 +310,7 @@ static const GameSettings gameVariantsTable[] = {
// Changed o_getResourceSize to cover all resource types
{"farm", "", 0, GID_HEGAME, 6, 73, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
{"puttzoo", "", 0, GID_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)},
@@ -448,6 +449,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "maniac", "%02d.MAN", kGenRoomNum, UNK_LANG, UNK, "V1 Demo" },
{ "maniac", "maniac1.d64", kGenUnchanged, UNK_LANG, Common::kPlatformC64, "C64" }, // ... and maniac2.d64
{ "maniac", "maniac1.dsk", kGenUnchanged, UNK_LANG, Common::kPlatformApple2GS, "Apple II" }, // ... and maniac2.dsk
+ { "maniac", "maniacdemo.d64", kGenUnchanged, UNK_LANG, Common::kPlatformC64, "C64 Demo" },
{ "maniac", "Maniac Mansion (E).prg", kGenUnchanged, Common::EN_GRB, Common::kPlatformNES, "NES" },
{ "maniac", "Maniac Mansion (F).prg", kGenUnchanged, Common::FR_FRA, Common::kPlatformNES, "NES" },
{ "maniac", "Maniac Mansion (SW).prg", kGenUnchanged, Common::SE_SWE, Common::kPlatformNES, "NES" },
@@ -664,6 +666,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "dog", "Springparadijs", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 },
{ "farm", "farm", kGenHEPC, UNK_LANG, UNK, 0 },
+ { "farm", "farm", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "farm", "farmdemo", kGenHEPC, UNK_LANG, UNK, 0 },
{ "farm", "Farm Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
@@ -680,12 +683,13 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "freddi", "Freddi Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "freddi", "Freddi Fish", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "freddi", "FreddiD", kGenHEPC, Common::NL_NLD, UNK, 0 },
+ { "freddi", "FreddiE", kGenHEPC, UNK_LANG, UNK, 0 },
{ "freddi", "Freddi Fisk", kGenHEMac, Common::SE_SWE, Common::kPlatformMacintosh, 0 },
{ "freddi", "FRITZI", kGenHEPC, Common::DE_DEU, UNK, 0 },
{ "freddi", "Marine Malice", kGenHEMac, Common::FR_FRA, Common::kPlatformMacintosh, 0 },
{ "freddi", "MM-DEMO", kGenHEPC, UNK_LANG, UNK, 0 },
- { "freddi2", "freddi2", kGenHEPC, UNK_LANG, UNK, 0 },
+ { "freddi2", "freddi2", kGenHEPC, UNK_LANG, Common::kPlatformWindows, 0 },
{ "freddi2", "FF2-demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "freddi2", "ff2-demo", kGenHEPC, UNK_LANG, Common::kPlatformWindows, 0 },
{ "freddi2", "FFHSDemo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
@@ -747,7 +751,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "lost", "lost", kGenHEPC, UNK_LANG, UNK, 0 },
{ "lost", "Lost and Found", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "lost", "smaller", kGenHEPC, UNK_LANG, UNK, 0 },
- { "lost", "verloren", kGenHEPC, Common::NL_NLD, UNK, 0 },
+ { "lost", "verloren", kGenHEPC, Common::NL_NLD, Common::kPlatformWindows, 0 },
{ "lost", "Verloren", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 },
{ "maze", "maze", kGenHEPC, UNK_LANG, UNK, 0 },
@@ -792,7 +796,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "pajama2", "PJ2 Demo", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 },
{ "pajama2", "PS2DEMO", kGenHEPC, Common::HE_ISR, UNK, 0 },
- { "pajama3", "pajama3", kGenHEPC, UNK_LANG, UNK, 0 },
+ { "pajama3", "pajama3", kGenHEPC, UNK_LANG, Common::kPlatformWindows, 0 },
{ "pajama3", "FPJ3Demo", kGenHEPC, Common::FR_FRA, UNK, 0 },
{ "pajama3", "GPJ3Demo", kGenHEPC, Common::DE_DEU, UNK, 0 },
{ "pajama3", "PajamaHTF", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
@@ -808,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 },
@@ -826,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 },
@@ -854,7 +860,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "putttime", "PuttTijd", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 },
{ "putttime", "Putt Time", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "putttime", "PuttTTT", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
- { "putttime", "PuttTTT", kGenHEPC, UNK_LANG, UNK, 0 },
+ { "putttime", "PuttTTT", kGenHEPC, UNK_LANG, Common::kPlatformWindows, 0 },
{ "putttime", "TIJDDEMO", kGenHEPC, Common::NL_NLD, Common::kPlatformWindows, 0 },
{ "putttime", "TijdDemo", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 },
{ "putttime", "timedemo", kGenHEPC, UNK_LANG, UNK, 0 },
@@ -891,7 +897,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "socks", "socks", kGenHEPC, UNK_LANG, UNK, 0 },
{ "socks", "SockWorks", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
- { "socks", "SokkenSoep", kGenHEPC, Common::NL_NLD, UNK, 0 },
+ { "socks", "SokkenSoep", kGenHEPC, Common::NL_NLD, Common::kPlatformWindows, 0 },
{ "socks", "SokkenSoep", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 },
{ "spyfox", "spyfox", kGenHEPC, UNK_LANG, Common::kPlatformWindows, 0 },
@@ -916,12 +922,13 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "spyfox", "JR-Demo", kGenHEMac, Common::FR_FRA, Common::kPlatformMacintosh, 0 },
{ "spyfox", "game", kGenHEIOS, Common::EN_ANY, Common::kPlatformIOS, 0 },
- { "spyfox2", "spyfox2", kGenHEPC, UNK_LANG, UNK, 0 },
+ { "spyfox2", "spyfox2", kGenHEPC, UNK_LANG, Common::kPlatformWindows, 0 },
{ "spyfox2", "sf2-demo", kGenHEPC, UNK_LANG, UNK, 0 },
{ "spyfox2", "sf2demo", kGenHEPC, UNK_LANG, Common::kPlatformWindows, 0 },
{ "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/dialogs.cpp b/engines/scumm/dialogs.cpp
index 52120949cc..c22525b6f2 100644
--- a/engines/scumm/dialogs.cpp
+++ b/engines/scumm/dialogs.cpp
@@ -180,9 +180,9 @@ static const ResString string_map_table_v345[] = {
// I18N: You may specify 'Yes' symbol at the end of the line, like this:
// "Moechten Sie wirklich neu starten? (J/N)J"
// Will react to J as 'Yes'
- {5, _s("Are you sure you want to restart? (Y/N)")},
+ {5, _s("Are you sure you want to restart? (Y/N)Y")},
// I18N: you may specify 'Yes' symbol at the end of the line. See previous comment
- {6, _s("Are you sure you want to quit? (Y/N)")},
+ {6, _s("Are you sure you want to quit? (Y/N)Y")},
// Added in SCUMM4
{7, _s("Save")},
@@ -460,7 +460,7 @@ const Common::String InfoDialog::queryResString(int stringno) {
tmp += chr;
}
}
- return tmp;
+ return _(tmp);
}
#pragma mark -
diff --git a/engines/scumm/file.cpp b/engines/scumm/file.cpp
index 475ffa3238..96b46aa21a 100644
--- a/engines/scumm/file.cpp
+++ b/engines/scumm/file.cpp
@@ -221,6 +221,15 @@ static const int maniacResourcesPerFile[55] = {
3, 10, 1, 0, 0
};
+static const int maniacDemoResourcesPerFile[55] = {
+ 0, 12, 0, 2, 1, 12, 1, 13, 6, 0,
+ 31, 0, 1, 0, 0, 0, 0, 1, 1, 1,
+ 0, 1, 0, 0, 2, 0, 0, 1, 0, 0,
+ 2, 7, 1, 11, 0, 0, 5, 1, 0, 0,
+ 1, 0, 1, 3, 4, 3, 1, 0, 0, 1,
+ 2, 2, 0, 0, 0
+};
+
static const int zakResourcesPerFile[59] = {
0, 29, 12, 14, 13, 4, 4, 10, 7, 4,
14, 19, 5, 4, 7, 6, 11, 9, 4, 4,
@@ -253,9 +262,17 @@ ScummDiskImage::ScummDiskImage(const char *disk1, const char *disk2, GameSetting
_numGlobalObjects = 256;
_numRooms = 55;
_numCostumes = 25;
- _numScripts = 160;
- _numSounds = 70;
- _resourcesPerFile = maniacResourcesPerFile;
+
+ if (_game.features & GF_DEMO) {
+ _numScripts = 55;
+ _numSounds = 40;
+ _resourcesPerFile = maniacDemoResourcesPerFile;
+ } else {
+ _numScripts = 160;
+ _numSounds = 70;
+ _resourcesPerFile = maniacResourcesPerFile;
+ }
+
} else {
_numGlobalObjects = 775;
_numRooms = 59;
@@ -327,6 +344,9 @@ bool ScummDiskImage::open(const Common::String &filename) {
extractIndex(0); // Fill in resource arrays
+ if (_game.features & GF_DEMO)
+ return true;
+
openDisk(2);
if (_game.platform == Common::kPlatformApple2GS) {
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/input.cpp b/engines/scumm/input.cpp
index 824dfec144..86048af57c 100644
--- a/engines/scumm/input.cpp
+++ b/engines/scumm/input.cpp
@@ -452,8 +452,16 @@ void ScummEngine_v2::processKeyboard(Common::KeyState lastKeyHit) {
lastKeyHit = Common::KeyState(Common::KEYCODE_ESCAPE);
// F7 is used to skip cutscenes in the Commodote 64 version of Maniac Mansion
} else if (_game.id == GID_MANIAC &&_game.platform == Common::kPlatformC64) {
- if (lastKeyHit.keycode == Common::KEYCODE_F7 && lastKeyHit.hasFlags(0))
- lastKeyHit = Common::KeyState(Common::KEYCODE_ESCAPE);
+ // Demo always F7 to be pressed to restart
+ if (_game.features & GF_DEMO) {
+ if (_roomResource != 0x2D && lastKeyHit.keycode == Common::KEYCODE_F7 && lastKeyHit.hasFlags(0)) {
+ restart();
+ return;
+ }
+ } else {
+ if (lastKeyHit.keycode == Common::KEYCODE_F7 && lastKeyHit.hasFlags(0))
+ lastKeyHit = Common::KeyState(Common::KEYCODE_ESCAPE);
+ }
// 'B' is used to skip cutscenes in the NES version of Maniac Mansion
} else if (_game.id == GID_MANIAC &&_game.platform == Common::kPlatformNES) {
if (lastKeyHit.keycode == Common::KEYCODE_b && lastKeyHit.hasFlags(Common::KBD_SHIFT))
diff --git a/engines/scumm/resource_v2.cpp b/engines/scumm/resource_v2.cpp
index 7ccdfa4780..87dc132ff0 100644
--- a/engines/scumm/resource_v2.cpp
+++ b/engines/scumm/resource_v2.cpp
@@ -34,8 +34,14 @@ void ScummEngine_v2::readClassicIndexFile() {
_numGlobalObjects = 256;
_numRooms = 55;
_numCostumes = 25;
- _numScripts = 160;
- _numSounds = 70;
+ if (_game.features & GF_DEMO) {
+ _numScripts = 55;
+ _numSounds = 40;
+ } else {
+ _numScripts = 160;
+ _numSounds = 70;
+ }
+
} else if (_game.platform == Common::kPlatformNES) {
_numGlobalObjects = 775;
_numRooms = 55;
diff --git a/engines/scumm/room.cpp b/engines/scumm/room.cpp
index 3828629997..4b59e22408 100644
--- a/engines/scumm/room.cpp
+++ b/engines/scumm/room.cpp
@@ -614,6 +614,15 @@ void ScummEngine_v3old::setupRoomSubBlocks() {
}
} else {
_roomWidth = READ_LE_UINT16(&(rmhd->old.width));
+
+ // WORKAROUND: Fix bad width value for room 64 (book of maps) in
+ // Indy3. A specific version of this game (DOS/EGA v1.0, according to
+ // scumm-md5.txt) has a wrong width of 1793 stored in the data files,
+ // which causes a strange situation in which the book view may scroll
+ // towards the right depending on Indy's position from the previous room.
+ // Fixes bug #6679.
+ if (_game.id == GID_INDY3 && _roomResource == 64 && _roomWidth == 1793)
+ _roomWidth = 320;
_roomHeight = READ_LE_UINT16(&(rmhd->old.height));
}
_numObjectsInRoom = roomptr[20];
diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp
index 7eadb042fb..e5673c1803 100644
--- a/engines/scumm/saveload.cpp
+++ b/engines/scumm/saveload.cpp
@@ -109,7 +109,12 @@ Common::Error ScummEngine::saveGameState(int slot, const Common::String &desc) {
}
bool ScummEngine::canSaveGameStateCurrently() {
- // FIXME: For now always allow loading in V0-V3 games
+ // Disallow saving in v0-v3 games when a 'prequel' to a cutscene is shown.
+ // This is a blank screen with text, and while this is shown, saving should
+ // be disabled, as no room is set.
+ if (_game.version <= 3 && _currentScript == 0xFF && _roomResource == 0 && _currentRoom == 0)
+ return false;
+
// TODO: Should we disallow saving in some more places,
// e.g. when a SAN movie is playing? Not sure whether the
// original EXE allowed this.
@@ -144,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/saveload.h b/engines/scumm/saveload.h
index 01ed21ece5..753287e217 100644
--- a/engines/scumm/saveload.h
+++ b/engines/scumm/saveload.h
@@ -47,7 +47,7 @@ namespace Scumm {
* only saves/loads those which are valid for the version of the savegame
* which is being loaded/saved currently.
*/
-#define CURRENT_VER 96
+#define CURRENT_VER 97
/**
* An auxillary macro, used to specify savegame versions. We use this instead
diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp
index 2fe5333bfc..c9b37d43b1 100644
--- a/engines/scumm/script.cpp
+++ b/engines/scumm/script.cpp
@@ -1164,8 +1164,10 @@ void ScummEngine_v0::walkToActorOrObject(int object) {
VAR(7) = y;
// actor must not move if frozen
- if (a->_miscflags & kActorMiscFlagFreeze)
+ if (a->_miscflags & kActorMiscFlagFreeze) {
a->stopActorMoving();
+ a->_newWalkBoxEntered = false;
+ }
}
bool ScummEngine_v0::checkPendingWalkAction() {
@@ -1179,7 +1181,7 @@ bool ScummEngine_v0::checkPendingWalkAction() {
Actor_v0 *a = (Actor_v0 *)derefActor(actor, "checkPendingWalkAction");
// wait until walking or turning action is finished
- if (a->_moving)
+ if (a->_moving != 2)
return true;
// after walking and turning finally execute the script
diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp
index a7999a2695..609cbd1e89 100644
--- a/engines/scumm/script_v0.cpp
+++ b/engines/scumm/script_v0.cpp
@@ -172,7 +172,7 @@ void ScummEngine_v0::setupOpcodes() {
/* 6C */
OPCODE(0x6c, o_stopCurrentScript);
OPCODE(0x6d, o2_putActorInRoom);
- OPCODE(0x6e, o2_dummy);
+ OPCODE(0x6e, o_screenPrepare);
OPCODE(0x6f, o2_ifState08);
/* 70 */
OPCODE(0x70, o_lights);
@@ -589,9 +589,9 @@ void ScummEngine_v0::o_loadRoomWithEgo() {
return;
}
- // The original interpreter seems to set the actors new room X/Y to the last rooms X/Y
- // This fixes a problem with MM: script 158 in room 12, the 'Oompf!' script
- // This scripts runs before the actor position is set to the correct location
+ // The original interpreter sets the actors new room X/Y to the last rooms X/Y
+ // This fixes a problem with MM: script 158 in room 12, the 'Oomph!' script
+ // This scripts runs before the actor position is set to the correct room entry location
a->putActor(a->getPos().x, a->getPos().y, room);
_egoPositioned = false;
@@ -633,12 +633,21 @@ void ScummEngine_v0::setMode(byte mode) {
switch (_currentMode) {
case kModeCutscene:
+ if (_game.features & GF_DEMO) {
+ if (VAR(11) != 0)
+ _drawDemo = true;
+ }
_redrawSentenceLine = false;
// Note: do not change freeze state here
state = USERSTATE_SET_IFACE |
USERSTATE_SET_CURSOR;
+
break;
case kModeKeypad:
+ if (_game.features & GF_DEMO) {
+ if (VAR(11) != 0)
+ _drawDemo = true;
+ }
_redrawSentenceLine = false;
state = USERSTATE_SET_IFACE |
USERSTATE_SET_CURSOR | USERSTATE_CURSOR_ON |
@@ -646,6 +655,12 @@ void ScummEngine_v0::setMode(byte mode) {
break;
case kModeNormal:
case kModeNoNewKid:
+ if (_game.features & GF_DEMO) {
+ resetVerbs();
+ _activeVerb = kVerbWalkTo;
+ _redrawSentenceLine = true;
+ _drawDemo = false;
+ }
state = USERSTATE_SET_IFACE | USERSTATE_IFACE_ALL |
USERSTATE_SET_CURSOR | USERSTATE_CURSOR_ON |
USERSTATE_SET_FREEZE;
@@ -707,17 +722,14 @@ void ScummEngine_v0::o_animateActor() {
}
a->animateActor(anim);
- a->animateCostume();
}
void ScummEngine_v0::o_getActorMoving() {
getResultPos();
int act = getVarOrDirectByte(PARAM_1);
Actor *a = derefActor(act, "o_getActorMoving");
- if (a->_moving)
- setResult(1);
- else
- setResult(2);
+
+ setResult(a->_moving);
}
void ScummEngine_v0::o_putActorAtObject() {
@@ -970,6 +982,10 @@ void ScummEngine_v0::o_setOwnerOf() {
setOwnerOf(obj, owner);
}
+void ScummEngine_v0::o_screenPrepare() {
+
+}
+
void ScummEngine_v0::resetSentence() {
_activeVerb = kVerbWalkTo;
_activeObject = 0;
diff --git a/engines/scumm/script_v2.cpp b/engines/scumm/script_v2.cpp
index 74d0aa2483..a7ec2e644f 100644
--- a/engines/scumm/script_v2.cpp
+++ b/engines/scumm/script_v2.cpp
@@ -1390,7 +1390,14 @@ void ScummEngine_v2::o2_loadRoomWithEgo() {
a = derefActor(VAR(VAR_EGO), "o2_loadRoomWithEgo");
- a->putActor(0, 0, room);
+ // The original interpreter sets the actors new room X/Y to the last rooms X/Y
+ // This fixes a problem with MM: script 161 in room 12, the 'Oomph!' script
+ // This scripts runs before the actor position is set to the correct room entry location
+ if ((_game.id == GID_MANIAC) && (_game.platform != Common::kPlatformNES)) {
+ a->putActor(a->getPos().x, a->getPos().y, room);
+ } else {
+ a->putActor(0, 0, room);
+ }
_egoPositioned = false;
x = (int8)fetchScriptByte();
diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp
index 91afa859a9..4a53ca3fed 100644
--- a/engines/scumm/script_v5.cpp
+++ b/engines/scumm/script_v5.cpp
@@ -2497,10 +2497,6 @@ void ScummEngine_v5::walkActorToActor(int actor, int toActor, int dist) {
y = abr.y;
}
a->startWalkActor(x, y, -1);
-
- // WORKAROUND: See bug #2971126 for details on why this is here.
- if (_game.version == 0)
- o5_breakHere();
}
void ScummEngine_v5::o5_walkActorToActor() {
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 0eeff57ff7..1cbefee105 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 Wed Jun 25 10:34:07 2014
+ This file was generated by the md5table tool on Sun May 10 14:23:43 2015
DO NOT EDIT MANUALLY!
*/
@@ -20,15 +20,16 @@ static const MD5Table md5table[] = {
{ "0354ee0d14cde1264ec762261c04c14a", "loom", "Steam", "Steam", 585728, Common::EN_ANY, Common::kPlatformWindows },
{ "035deab53b47bc43abc763560d0f8d4b", "atlantis", "Floppy", "Demo", -1, Common::EN_ANY, Common::kPlatformDOS },
{ "037385a953789190298494d92b89b3d0", "catalog", "HE 72", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows },
- { "03d3b18ee3fd68114e2a687c871e38d5", "freddi4", "HE 99", "Mini Game", -1, Common::EN_USA, Common::kPlatformWindows },
+ { "03d3b18ee3fd68114e2a687c871e38d5", "freddi4", "HE 99", "Mini Game", 13609, Common::EN_USA, Common::kPlatformWindows },
{ "0425954a9db5c340861672892c3e678d", "samnmax", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "04401d747f1a2c1c4b388daff71ed378", "ft", "", "", 535405461, Common::DE_DEU, Common::kPlatformMacintosh },
{ "04687cdf7f975a89d2474929f7b80946", "indy3", "FM-TOWNS", "", 7552, Common::EN_ANY, Common::kPlatformFMTowns },
{ "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", "", "", -1, Common::NL_NLD, Common::kPlatformMacintosh },
+ { "06c3cf4f31daad8b1cd93153491db9e6", "pajama3", "", "", 79382, Common::NL_NLD, Common::kPlatformUnknown },
{ "07433205acdca3bc553d0e731588b35f", "airport", "", "", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "07a1eefd8ca95d77310311446c0f53d0", "brstorm", "", "", 5433, Common::EN_ANY, Common::kPlatformUnknown },
{ "07b810e37be7489263f7bc7627d4765d", "freddi4", "unenc", "Unencrypted", -1, Common::RU_RUS, Common::kPlatformWindows },
@@ -37,10 +38,11 @@ static const MD5Table md5table[] = {
{ "08656dd9698ddf1023ba9bf8a195e37b", "monkey", "VGA", "VGA", -1, Common::EN_ANY, Common::kPlatformDOS },
{ "08cc5c3eedaf72ebe12734eee94f7fa2", "balloon", "HE 80", "", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "09820417db26687bb7fe0c83cc4c553b", "ft", "", "Version A", 19697, Common::EN_ANY, Common::kPlatformUnknown },
+ { "09b0be55c16cd9e88b5080bf89ff281d", "freddi4", "HE 99", "Mini Game", 13609, Common::DE_DEU, Common::kPlatformWindows },
{ "0a212fa35fa8421f31c1f3961272caf0", "monkey", "VGA", "VGA", -1, Common::DE_DEU, Common::kPlatformAmiga },
{ "0a295b80f9a9edf818e8e161a0e83830", "freddi2", "HE 80", "", -1, Common::FR_FRA, Common::kPlatformUnknown },
{ "0a41311d462b6639fc45297b9044bf16", "monkey", "No AdLib", "EGA", -1, Common::ES_ESP, Common::kPlatformAtariST },
- { "0a6d7b81b850ed4a77811c60c9b5c555", "PuttTime", "HE 99", "Mini Game", -1, Common::EN_USA, Common::kPlatformWindows },
+ { "0a6d7b81b850ed4a77811c60c9b5c555", "PuttTime", "HE 99", "Mini Game", 18458, Common::EN_USA, Common::kPlatformWindows },
{ "0aa050f4ad79402fbe9c4f78fb8ac494", "loom", "PC-Engine", "", 6532, Common::EN_ANY, Common::kPlatformPCEngine },
{ "0ab19be9e2a3f6938226638b2a3744fe", "PuttTime", "HE 100", "Demo", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "0ac41e2e3d2174e5a042a6b565328dba", "puttrace", "HE 98", "Demo", 13110, Common::EN_USA, Common::kPlatformUnknown },
@@ -66,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 },
@@ -112,12 +115,15 @@ static const MD5Table md5table[] = {
{ "2108d83dcf09f8adb4bc524669c8cf51", "PuttTime", "HE 99", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "21a6592322f92550f144f68a8a4e685e", "dig", "", "", -1, Common::FR_FRA, Common::kPlatformMacintosh },
{ "21abe302e1b1e2b66d6f5c12e241ebfd", "freddicove", "unenc", "Unencrypted", -1, Common::RU_RUS, Common::kPlatformWindows },
- { "2232b0b9411575b1f9961713ebc9de61", "balloon", "HE 80", "", -1, Common::UNK_LANG, Common::kPlatformWindows },
+ { "2232b0b9411575b1f9961713ebc9de61", "balloon", "HE 80", "", -1, Common::NL_NLD, Common::kPlatformWindows },
{ "225e18566e810c634bf7de63e7568e3e", "mustard", "", "", -1, Common::EN_USA, Common::kPlatformUnknown },
+ { "22c7432dc97a821fcfccd480e93e3911", "spyfox2", "", "Mini Game", 14689, Common::NL_NLD, Common::kPlatformWindows },
{ "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 },
{ "2723fea3dae0cb47768c424b145ae0e7", "tentacle", "Floppy", "Floppy", 7932, Common::EN_ANY, Common::kPlatformDOS },
{ "27b2ef1653089fe5b897d9cc89ce784f", "balloon", "HE 80", "", -1, Common::RU_RUS, Common::kPlatformWindows },
@@ -132,6 +138,7 @@ static const MD5Table md5table[] = {
{ "2a446817ffcabfef8716e0c456ecaf81", "puttzoo", "", "Demo", -1, Common::DE_DEU, Common::kPlatformWindows },
{ "2a8658dbd13d84d1bce64a71a35995eb", "pajama2", "HE 99", "Demo", -1, Common::HE_ISR, Common::kPlatformWindows },
{ "2c04aacffb8428f30ccf4f734fbe3adc", "activity", "", "", -1, Common::EN_ANY, Common::kPlatformDOS },
+ { "2cb46375dd5cdfd023e2f07e0a21b530", "maniac", "C64", "Demo", -1, Common::EN_ANY, Common::kPlatformC64 },
{ "2ccd8891ce4d3f1a334d21bff6a88ca2", "monkey", "CD", "", 9455, Common::EN_ANY, Common::kPlatformMacintosh },
{ "2d1e891fe52df707c30185e52c50cd92", "monkey", "CD", "CD", 8955, Common::EN_ANY, Common::kPlatformDOS },
{ "2d388339d6050d8ccaa757b64633954e", "indyloom", "FM-TOWNS", "Demo", 7520, Common::EN_ANY, Common::kPlatformFMTowns },
@@ -160,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 },
@@ -172,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 },
@@ -185,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 },
@@ -230,7 +239,7 @@ static const MD5Table md5table[] = {
{ "4f580a021eee026f3b4589e17d130d78", "freddi4", "", "", -1, Common::UNK_LANG, Common::kPlatformUnknown },
{ "4fa6870d9bc8c313b65d54b1da5a1891", "pajama", "", "", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "4fbbe9f64b8bc547503a379a301183ce", "tentacle", "", "CD", -1, Common::IT_ITA, Common::kPlatformUnknown },
- { "4fe6a2e8df3c4536b278fdd2fbcb181e", "pajama3", "", "Mini Game", -1, Common::EN_ANY, Common::kPlatformWindows },
+ { "4fe6a2e8df3c4536b278fdd2fbcb181e", "pajama3", "", "Mini Game", 13911, Common::EN_ANY, Common::kPlatformWindows },
{ "5057fb0e99e5aa29df1836329232f101", "freddi2", "HE 80", "", -1, Common::UNK_LANG, Common::kPlatformWindows },
{ "507bb360688dc4180fdf0d7597352a69", "freddi", "HE 73", "", 26402, Common::SE_SWE, Common::kPlatformWindows },
{ "50b831f11b8c4b83784cf81f4dcc69ea", "spyfox", "HE 101", "", -1, Common::EN_ANY, Common::kPlatformWii },
@@ -246,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 },
@@ -302,6 +312,7 @@ static const MD5Table md5table[] = {
{ "6a60d395b78b205c93a956100b1bf5ae", "pajama2", "HE 98.5", "", -1, Common::DE_DEU, Common::kPlatformUnknown },
{ "6a8133b63d46f6663fbcbb49d5a2edb1", "atlantis", "Steam", "Steam", 520548, Common::EN_ANY, Common::kPlatformMacintosh },
{ "6af2419fe3db5c2fdb091ae4e5833770", "puttrace", "HE 98.5", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown },
+ { "6b10c9977cad9de503642059359792b1", "spyfox2", "", "Mini Game", 14689, Common::FR_FRA, Common::kPlatformWindows },
{ "6b19d0e25cbf720d05822379b8b90ed9", "PuttTime", "HE 90", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "6b257bb2827dd894b8109a50a1a18b5a", "freddicove", "HE 100", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "6b27dbcd8d5697d5c918eeca0f68ef6a", "puttrace", "HE CUP", "Preview", 3901484, Common::UNK_LANG, Common::kPlatformUnknown },
@@ -310,7 +321,8 @@ static const MD5Table md5table[] = {
{ "6bca7a1a96d16e52b8f3c42b50dbdca3", "fbear", "HE 62", "", -1, Common::JA_JPN, Common::kPlatform3DO },
{ "6bf70eee5de3d24d2403e0dd3d267e8a", "spyfox", "", "", 49221, Common::UNK_LANG, Common::kPlatformWindows },
{ "6c2bff0e327f2962e809c2e1a82d7309", "monkey", "VGA", "VGA", -1, Common::EN_ANY, Common::kPlatformAmiga },
- { "6d1baa1065ac5f7b210be8ebe4235e49", "freddi", "HE 73", "", -1, Common::NL_NLD, Common::kPlatformMacintosh },
+ { "6c375c2236d99f56e6c2cf540e74e474", "farm", "", "Demo", 34333, Common::NL_NLD, Common::kPlatformWindows },
+ { "6d1baa1065ac5f7b210be8ebe4235e49", "freddi", "HE 73", "", 26384, Common::NL_NLD, Common::kPlatformMacintosh },
{ "6dead580b0ff14d5f7b33b4219f04159", "samnmax", "", "Demo", 16556335, Common::EN_ANY, Common::kPlatformMacintosh },
{ "6df20c50c1ab19799de9be7ae7716881", "fbear", "HE 62", "Demo", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "6e959d65358eedf9b68b81e304b97fa4", "tentacle", "", "CD", 7932, Common::DE_DEU, Common::kPlatformUnknown },
@@ -324,7 +336,7 @@ static const MD5Table md5table[] = {
{ "70b0719ac3a5b47ae233c561823d5b96", "puttzoo", "", "", -1, Common::NL_NLD, Common::kPlatformMacintosh },
{ "71523b539491527d9860f4407faf0411", "monkey", "Demo", "EGA Demo", 7607, Common::EN_ANY, Common::kPlatformDOS },
{ "71d384e7676c53d513ddd333eae1d82c", "Blues123time", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown },
- { "71fe97c3108678cf604f14abe342341b", "spyfox2", "", "", -1, Common::NL_NLD, Common::kPlatformWindows },
+ { "71fe97c3108678cf604f14abe342341b", "spyfox2", "", "", 51286, Common::NL_NLD, Common::kPlatformUnknown },
{ "7222f260253f325c21fcfa68b5bfab67", "spyfox2", "", "Demo", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "72ac6bc980d5101c2142189d746bd62f", "spyfox", "HE 99", "", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "732845548b1d6c2da572cb6a1bf81b07", "spyfox2", "", "Demo", -1, Common::DE_DEU, Common::kPlatformUnknown },
@@ -348,6 +360,7 @@ static const MD5Table md5table[] = {
{ "78c07ca088526d8d4446a4c2cb501203", "freddi3", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformUnknown },
{ "7974365d3dc0f43a2748c975f91ff042", "monkey2", "", "", -1, Common::ES_ESP, Common::kPlatformDOS },
{ "79b05f628586837e7166e82b2279bb50", "loom", "PC-Engine", "", -1, Common::JA_JPN, Common::kPlatformPCEngine },
+ { "7a2b6d8e8a645c9d534c8c4edc38a9c9", "freddi4", "HE 99", "Mini Game", 13609, Common::IT_ITA, Common::kPlatformWindows },
{ "7b4ee071eecadc2d8cd0c3509110825c", "puttzoo", "HE 100", "Remastered", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "7bad72e332a59f9fcc1d437f4edad32a", "puttcircus", "", "", -1, Common::RU_RUS, Common::kPlatformUnknown },
{ "7c2e76087027eeee9c8f8985f93a1cc5", "freddi4", "", "Demo", 13584, Common::EN_ANY, Common::kPlatformUnknown },
@@ -357,6 +370,7 @@ static const MD5Table md5table[] = {
{ "7e151c17adf624f1966c8fc5827c95e9", "puttputt", "HE 61", "", -1, Common::EN_ANY, Common::kPlatform3DO },
{ "7ea2da67ebabea4ac20cee9f4f9d2934", "airport", "", "Demo", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "7edd665bbede7ea8b7233f8e650be6f8", "samnmax", "", "CD", -1, Common::FR_FRA, Common::kPlatformUnknown },
+ { "7f2578d8d33a9ff525488a2d9ba617e4", "spyfox2", "", "Mini Game", 14689, Common::DE_DEU, Common::kPlatformWindows },
{ "7f45ddd6dbfbf8f80c0c0efea4c295bc", "maniac", "V1", "V1", 1972, Common::EN_ANY, Common::kPlatformDOS },
{ "7f945525abcd48015adf1632637a44a1", "pajama", "", "Demo", -1, Common::FR_FRA, Common::kPlatformUnknown },
{ "7fbcff27c323499beaedd605e1ebd47d", "indy3", "Steam", "Steam", 561152, Common::EN_ANY, Common::kPlatformWindows },
@@ -368,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 },
@@ -389,13 +404,15 @@ static const MD5Table md5table[] = {
{ "8afb3cf9f95abf208358e984f0c9e738", "funpack", "", "", -1, Common::EN_ANY, Common::kPlatform3DO },
{ "8bdb0bf87b5e303dd35693afb9351215", "ft", "", "", -1, Common::DE_DEU, Common::kPlatformUnknown },
{ "8d479e36f35e80257dfc102cf4b8a912", "farm", "HE 72", "Demo", 34333, Common::EN_ANY, Common::kPlatformWindows },
+ { "8dd4d590685c19bf651b5016e749ead2", "PuttTime", "HE 99", "Mini Game", 18458, Common::FR_FRA, Common::kPlatformWindows },
{ "8de13897f0121c79d29a2377159f9ad0", "socks", "HE 99", "Updated", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "8e3241ddd6c8dadf64305e8740d45e13", "balloon", "HE 100", "Updated", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "8e4ee4db46954bfe2912e259a16fad82", "monkey2", "", "", -1, Common::FR_FRA, Common::kPlatformDOS },
{ "8e9417564f33790815445b2136efa667", "atlantis", "", "CD", 11915, Common::JA_JPN, Common::kPlatformMacintosh },
- { "8e9830a6f2702be5b22c8fa0a6aaf977", "freddi2", "HE 80", "", -1, Common::NL_NLD, Common::kPlatformMacintosh },
+ { "8e9830a6f2702be5b22c8fa0a6aaf977", "freddi2", "HE 80", "", 65305, Common::NL_NLD, Common::kPlatformUnknown },
{ "8eb84cee9b429314c7f0bdcf560723eb", "monkey", "FM-TOWNS", "", 9925, Common::EN_ANY, Common::kPlatformFMTowns },
{ "8ee63cafb1fe9d62aa0d5a23117e70e7", "freddi2", "HE 100", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown },
+ { "8f345db2f3f5a25ed6305001957e6f72", "freddicove", "HE 100", "", 41182, Common::NL_NLD, Common::kPlatformUnknown },
{ "8f3758ff98c9c5d78e5d635222cad026", "atlantis", "Floppy", "Floppy", -1, Common::IT_ITA, Common::kPlatformDOS },
{ "8fec68383202d38c0d25e9e3b757c5df", "comi", "Demo", "Demo", 18041, Common::UNK_LANG, Common::kPlatformWindows },
{ "8ffd618a776a4c0d8922bb28b09f8ce8", "airport", "", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows },
@@ -409,11 +426,13 @@ static const MD5Table md5table[] = {
{ "92b078d9d6d9d751da9c26b8b3075779", "tentacle", "Floppy", "Floppy", -1, Common::FR_FRA, Common::kPlatformDOS },
{ "92e7727e67f5cd979d8a1070e4eb8cb3", "puttzoo", "HE 98.5", "Updated", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "92fc0073a4cf259ff36070ecb8628ba8", "thinkerk", "", "", -1, Common::EN_USA, Common::kPlatformUnknown },
+ { "9340b552b0f2dffe6d4f3d13ebebe832", "freddi4", "HE 99", "Mini Game", 13609, Common::NL_NLD, Common::kPlatformWindows },
{ "94aaedbb8f26d71ed3ad6dd34490e29e", "tentacle", "Floppy", "Floppy", -1, Common::FR_FRA, Common::kPlatformDOS },
{ "94db6519da85b8d08c976d8e9a858ea7", "baseball", "HE CUP", "Preview", 10044774, Common::UNK_LANG, Common::kPlatformUnknown },
{ "95818b178d473c989ac753574e8892aa", "readtime", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "95b3806e043be08668c54c3ffe98650f", "BluesABCTime", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "95be99181bd0f10fef4872c2d4a771cb", "zak", "V1", "", -1, Common::DE_DEU, Common::kPlatformC64 },
+ { "9684c161258d68e0d464d6cab7024b9c", "spyfox2", "", "Mini Game", 14689, Common::IT_ITA, Common::kPlatformWindows },
{ "96a3069a3c63caa7329588ce1fef41ee", "spyozon", "", "", -1, Common::RU_RUS, Common::kPlatformUnknown },
{ "9708cf716ed8bcc9ff3fcfc69413b746", "puttputt", "HE 62", "", -1, Common::EN_ANY, Common::kPlatformDOS },
{ "9778341eefc6feb447ca07e7be21791c", "puttrace", "HE 99", "Demo", -1, Common::IT_ITA, Common::kPlatformWindows },
@@ -459,9 +478,11 @@ static const MD5Table md5table[] = {
{ "a59a438cb182124c30c4447d8ed469e9", "freddi", "HE 100", "", 34837, Common::NB_NOR, Common::kPlatformWii },
{ "a5c5388da9bf0e6662fdca8813a79d13", "farm", "", "", 86962, Common::EN_ANY, Common::kPlatformWindows },
{ "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 },
{ "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 },
{ "a99c39ba65b6086be28aef576da69595", "spyozon", "", "Demo", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "a9f2f04b1ecaab9495b59befffe9bf88", "pajama3", "", "Demo", -1, Common::EN_USA, Common::kPlatformUnknown },
@@ -478,6 +499,7 @@ static const MD5Table md5table[] = {
{ "acad97ab1c6fc2a5b2d98abf6db4a190", "tentacle", "Floppy", "Floppy", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "ae94f110a14ce71fc515d5b648827a8f", "tentacle", "Floppy", "Floppy", -1, Common::ES_ESP, Common::kPlatformDOS },
{ "aeec382acef62e122bf0d5b14581cfa4", "zak", "V1", "", -1, Common::IT_ITA, Common::kPlatformC64 },
+ { "aef415cc5dc063e3668359c2657169f3", "PuttTime", "HE 99", "Mini Game", 18458, Common::DE_DEU, Common::kPlatformWindows },
{ "aefa244ea034b7cd2041f0a44be7d9ba", "pajama3", "", "", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "af2bd1a43b50b55915d87994e093203d", "freddi", "HE 99", "Updated", 34829, Common::DE_DEU, Common::kPlatformWindows },
{ "b100abf7ff83146df50db78dbd5e9cfa", "freddicove", "HE 100", "", -1, Common::FR_FRA, Common::kPlatformUnknown },
@@ -505,7 +527,7 @@ static const MD5Table md5table[] = {
{ "be83e882b44f2767bc08d4f766ebc347", "maniac", "V2", "V2", -1, Common::DE_DEU, Common::kPlatformAtariST },
{ "bf8b52fdd9a69c67f34e8e9fec72661c", "farm", "HE 71", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "bfdf584b01503f0762baded581f6a0a2", "SoccerMLS", "", "", -1, Common::EN_ANY, Common::kPlatformWindows },
- { "c0039ad982999c92d0de81910d640fa0", "freddi", "HE 71", "", -1, Common::NL_NLD, Common::kPlatformWindows },
+ { "c0039ad982999c92d0de81910d640fa0", "freddi", "HE 71", "", 26159, Common::NL_NLD, Common::kPlatformWindows },
{ "c13225cb1bbd3bc9fe578301696d8021", "monkey", "SEGA", "", -1, Common::EN_ANY, Common::kPlatformSegaCD },
{ "c20848f53c2d48bfacdc840993843765", "freddi2", "HE 80", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "c225bec1b6c0798a2b8c89ac226dc793", "pajama", "HE 101", "", -1, Common::EN_ANY, Common::kPlatformWii },
@@ -516,6 +538,7 @@ static const MD5Table md5table[] = {
{ "c3b22fa4654bb580b20325ebf4174841", "puttzoo", "", "", -1, Common::NL_NLD, Common::kPlatformWindows },
{ "c3df37df9d3b481b45f75283a9907c47", "loom", "EGA", "EGA", -1, Common::IT_ITA, Common::kPlatformDOS },
{ "c4787c3e8b5e2dfda90850ee800af00f", "zak", "V2", "V2", -1, Common::FR_FRA, Common::kPlatformDOS },
+ { "c486e4cfa7bd6f8efcd0740f96f7dde3", "freddi4", "HE 99", "Mini Game", 13609, Common::FR_FRA, Common::kPlatformWindows },
{ "c4ffae9fac495475d6bc3343ccc8faf9", "Soccer2004", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "c5cc7cba02a2fbd539c4439e775b0536", "puttzoo", "HE 99", "Updated", 43470, Common::DE_DEU, Common::kPlatformWindows },
{ "c5d10e190d4b4d59114b824f2fdbd00e", "loom", "FM-TOWNS", "", 7540, Common::EN_ANY, Common::kPlatformFMTowns },
@@ -555,6 +578,7 @@ static const MD5Table md5table[] = {
{ "d06fbe28818fef7bfc45c2cdf0c0849d", "zak", "V2", "V2", -1, Common::DE_DEU, Common::kPlatformDOS },
{ "d0ad929def3e9cfe39dea55bd12098d4", "puttcircus", "", "", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "d0b531227a27c6662018d2bd05aac52a", "monkey", "VGA", "VGA", 8357, Common::DE_DEU, Common::kPlatformDOS },
+ { "d1a73e87564477c7c2dcc2b8f616ad0b", "pajama3", "", "Mini Game", 13911, Common::IT_ITA, Common::kPlatformWindows },
{ "d220d154aafbfa12bd6f3ab1b2dae420", "puttzoo", "", "Demo", -1, Common::DE_DEU, Common::kPlatformMacintosh },
{ "d2cc8e31bce61e6cf2951249e10638fe", "basketball", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "d37c55388294b66e53e7ced3af88fa68", "freddi2", "HE 100", "Updated Demo", -1, Common::EN_ANY, Common::kPlatformUnknown },
@@ -602,7 +626,7 @@ static const MD5Table md5table[] = {
{ "e534d29afb3c6e0ee9dc3d53c5956714", "atlantis", "Floppy", "Floppy", -1, Common::DE_DEU, Common::kPlatformAmiga },
{ "e5563c8358443c4352fcddf7402a5e0a", "pajama2", "HE 98.5", "", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "e5c112140ad6574997de033a8e2a2964", "readtime", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown },
- { "e62056ba675ad65d8854ab3c5ad4b3c0", "spyfox2", "", "Mini Game", -1, Common::EN_ANY, Common::kPlatformWindows },
+ { "e62056ba675ad65d8854ab3c5ad4b3c0", "spyfox2", "", "Mini Game", 14689, Common::EN_ANY, Common::kPlatformWindows },
{ "e63a0b9249b5ca4cc4d3ac34305ae360", "freddi", "HE 99", "", -1, Common::NB_NOR, Common::kPlatformWindows },
{ "e689bdf67f98b1d760ce4487ec0e8d06", "indy3", "EGA", "EGA", -1, Common::FR_FRA, Common::kPlatformAmiga },
{ "e6cd81b25ab1453a8a6d3482118c391e", "pass", "", "", 7857, Common::EN_ANY, Common::kPlatformDOS },
@@ -620,11 +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 },
{ "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 },
@@ -632,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 },
@@ -649,6 +676,7 @@ static const MD5Table md5table[] = {
{ "fa30c4a7a806629626269b6dcab59a15", "BluesBirthday", "HE CUP", "Preview", 7819264, Common::UNK_LANG, Common::kPlatformUnknown },
{ "fa3cb1541f9d7cf99ccbae6249bc150c", "maniac", "NES", "", -1, Common::IT_ITA, Common::kPlatformNES },
{ "fa84cb1018103a4ee4e5fa8041c1d0d1", "freddi4", "", "Demo", 13609, Common::DE_DEU, Common::kPlatformWindows },
+ { "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 },
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 475b146a7b..99b4e695bb 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -716,7 +716,7 @@ ScummEngine_v2::ScummEngine_v2(OSystem *syst, const DetectorResult &dr)
ScummEngine_v0::ScummEngine_v0(OSystem *syst, const DetectorResult &dr)
: ScummEngine_v2(syst, dr) {
-
+ _drawDemo = false;
_currentMode = 0;
_currentLights = 0;
@@ -731,6 +731,9 @@ ScummEngine_v0::ScummEngine_v0(OSystem *syst, const DetectorResult &dr)
VAR_ACTIVE_OBJECT2 = 0xFF;
VAR_IS_SOUND_RUNNING = 0xFF;
VAR_ACTIVE_VERB = 0xFF;
+
+ if (strcmp(dr.fp.pattern, "maniacdemo.d64") == 0 )
+ _game.features |= GF_DEMO;
}
ScummEngine_v6::ScummEngine_v6(OSystem *syst, const DetectorResult &dr)
@@ -1091,8 +1094,13 @@ Common::Error ScummEngine::init() {
const char *tmpBuf1, *tmpBuf2;
assert(_game.id == GID_MANIAC || _game.id == GID_ZAK);
if (_game.id == GID_MANIAC) {
- tmpBuf1 = "maniac1.d64";
- tmpBuf2 = "maniac2.d64";
+ if (_game.features & GF_DEMO) {
+ tmpBuf1 = "maniacdemo.d64";
+ tmpBuf2 = "maniacdemo.d64";
+ } else {
+ tmpBuf1 = "maniac1.d64";
+ tmpBuf2 = "maniac2.d64";
+ }
} else {
tmpBuf1 = "zak1.d64";
tmpBuf2 = "zak2.d64";
@@ -2572,7 +2580,7 @@ void ScummEngine::runBootscript() {
int args[NUM_SCRIPT_LOCAL];
memset(args, 0, sizeof(args));
args[0] = _bootParam;
- if (_game.id == GID_MANIAC && (_game.features & GF_DEMO))
+ if (_game.id == GID_MANIAC && (_game.features & GF_DEMO) && (_game.platform != Common::kPlatformC64))
runScript(9, 0, 0, args);
else
runScript(1, 0, 0, args);
@@ -2589,9 +2597,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 af118a89a1..30b4d61880 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -642,7 +642,7 @@ protected:
byte _opcode;
byte _currentScript;
int _scummStackPos;
- int _vmStack[150];
+ int _vmStack[256];
OpcodeEntry _opcodes[256];
@@ -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);
@@ -1362,7 +1362,7 @@ public:
byte VAR_SCRIPT_CYCLE; // Used in runScript()/runObjectScript()
byte VAR_NUM_SCRIPT_CYCLES; // Used in runAllScripts()
-
+
byte VAR_QUIT_SCRIPT; // Used in confirmExitDialog()
// Exists both in V7 and in V72HE:
diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h
index 80d047ab9f..4098d639c4 100644
--- a/engines/scumm/scumm_v0.h
+++ b/engines/scumm/scumm_v0.h
@@ -46,6 +46,7 @@ protected:
};
protected:
+ bool _drawDemo;
byte _currentMode;
byte _currentLights;
@@ -67,6 +68,8 @@ public:
virtual void resetScumm();
+ byte walkboxFindTarget(Actor *a, int destbox, Common::Point walkdest);
+
protected:
virtual void resetRoomObject(ObjectData *od, const byte *room, const byte *searchptr = NULL);
@@ -99,6 +102,8 @@ protected:
virtual void handleMouseOver(bool updateInventory);
int verbPrepIdType(int verbid);
void resetVerbs();
+ void verbDemoMode();
+ void verbDrawDemoString(int VerbDemoNumber);
void clearSentenceLine();
void flushSentenceLine();
@@ -116,7 +121,7 @@ protected:
void resetSentence();
- virtual bool areBoxesNeighbors(int box1nr, int box2nr);
+ bool areBoxesNeighbors(int box1nr, int box2nr);
bool ifEqualActiveObject2Common(bool checkType);
@@ -161,6 +166,7 @@ protected:
void o_cutscene();
void o_endCutscene();
void o_setOwnerOf();
+ void o_screenPrepare();
byte VAR_ACTIVE_OBJECT2;
byte VAR_IS_SOUND_RUNNING;
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/sound.cpp b/engines/scumm/sound.cpp
index cb428d1c15..84d2b37f96 100644
--- a/engines/scumm/sound.cpp
+++ b/engines/scumm/sound.cpp
@@ -1066,9 +1066,9 @@ void Sound::playCDTrackInternal(int track, int numLoops, int startFrame, int dur
Common::File *cddaFile = new Common::File();
if (cddaFile->open("CDDA.SOU")) {
Audio::Timestamp start = Audio::Timestamp(0, startFrame, 75);
- Audio::Timestamp end = Audio::Timestamp(0, startFrame + duration, 75);
+ Audio::Timestamp end = Audio::Timestamp(0, startFrame + duration, 75);
Audio::SeekableAudioStream *stream = makeCDDAStream(cddaFile, DisposeAfterUse::YES);
-
+
_mixer->playStream(Audio::Mixer::kMusicSoundType, &_loomSteamCDAudioHandle,
Audio::makeLoopingAudioStream(stream, start, end, (numLoops < 1) ? numLoops + 1 : numLoops));
} else {
diff --git a/engines/scumm/vars.cpp b/engines/scumm/vars.cpp
index a903ac5804..a6be5c3f3a 100644
--- a/engines/scumm/vars.cpp
+++ b/engines/scumm/vars.cpp
@@ -715,7 +715,7 @@ void ScummEngine_v99he::resetScummVars() {
VAR(140) = 0;
#endif
}
-
+
if (_game.id == GID_PUTTZOO && _game.heversion == 100 && _game.platform == Common::kPlatformWindows) {
// Specific to Nimbus Games version.
VAR(156) = 1;
diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp
index fdb98a8019..fe936b550c 100644
--- a/engines/scumm/verbs.cpp
+++ b/engines/scumm/verbs.cpp
@@ -80,6 +80,19 @@ static const VerbSettings v0VerbTable_German[] = {
{kVerbWhatIs, 13, 2, "Was ist"}
};
+struct VerbDemo {
+ int color;
+ const char *str;
+};
+static VerbDemo v0DemoStr[] = {
+ {7, " MANIAC MANSION DEMO DISK "},
+ {5, " from Lucasfilm Games "},
+ {5, " Copyright = 1987 by Lucasfilm Ltd. "},
+ {5, " All Rights Reserved. "},
+ {0, " "},
+ {16, " Press F7 to return to menu. "}
+};
+
int ScummEngine_v0::verbPrepIdType(int verbid) {
switch (verbid) {
case kVerbUse: // depends on object1
@@ -93,6 +106,44 @@ int ScummEngine_v0::verbPrepIdType(int verbid) {
}
}
+void ScummEngine_v0::verbDemoMode() {
+ int i;
+
+ for (i = 1; i < 16; i++)
+ killVerb(i);
+
+ for (i = 0; i < 6; i++) {
+ verbDrawDemoString(i);
+ }
+}
+
+void ScummEngine_v0::verbDrawDemoString(int VerbDemoNumber) {
+ byte string[80];
+ const char *ptr = v0DemoStr[VerbDemoNumber].str;
+ int i = 0, len = 0;
+
+ // Maximum length of printable characters
+ int maxChars = 40;
+ while (*ptr) {
+ if (*ptr != '@')
+ len++;
+ if (len > maxChars) {
+ break;
+ }
+
+ string[i++] = *ptr++;
+
+ }
+ string[i] = 0;
+
+ _string[2].charset = 1;
+ _string[2].ypos = _virtscr[kVerbVirtScreen].topline + (8 * VerbDemoNumber);
+ _string[2].xpos = 0;
+ _string[2].right = _virtscr[kVerbVirtScreen].w - 1;
+ _string[2].color = v0DemoStr[VerbDemoNumber].color;
+ drawString(2, (byte *)string);
+}
+
void ScummEngine_v0::resetVerbs() {
VirtScreen *virt = &_virtscr[kVerbVirtScreen];
VerbSlot *vs;
@@ -708,7 +759,6 @@ void ScummEngine_v0::verbExec() {
Actor_v0 *a = (Actor_v0 *)derefActor(VAR(VAR_EGO), "verbExec");
int x = _virtualMouse.x / V12_X_MULTIPLIER;
int y = _virtualMouse.y / V12_Y_MULTIPLIER;
- //actorSetPosInBox();
// 0xB31
VAR(6) = x;
@@ -717,7 +767,6 @@ void ScummEngine_v0::verbExec() {
if (a->_miscflags & kActorMiscFlagFreeze)
return;
- a->stopActorMoving();
a->startWalkActor(VAR(6), VAR(7), -1);
}
@@ -856,6 +905,10 @@ void ScummEngine_v0::checkExecVerbs() {
}
}
}
+
+ if (_drawDemo && _game.features & GF_DEMO) {
+ verbDemoMode();
+ }
if (_redrawSentenceLine)
drawSentenceLine();
diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp
new file mode 100644
index 0000000000..21d63633d3
--- /dev/null
+++ b/engines/sherlock/animation.cpp
@@ -0,0 +1,188 @@
+/* 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, 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);
+
+ // 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 fname = _soundLibraryFilename.empty() ?
+ Common::String::format("%s%01d", filename.c_str(), soundNumber) :
+ Common::String::format("%s%02d", filename.c_str(), soundNumber);
+
+ if (sound._voices)
+ sound.playSound(fname, 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();
+}
+
+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) {
+ const int *frames = &NO_FRAMES;
+
+ if (_soundLibraryFilename.empty()) {
+ for (uint idx = 0; idx < _prologueNames.size(); ++idx) {
+ if (filename.equalsIgnoreCase(_prologueNames[idx])) {
+ frames = &_prologueFrames[idx][0];
+ break;
+ }
+ }
+ } else {
+ 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..b7811d3fa8
--- /dev/null
+++ b/engines/sherlock/animation.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 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);
+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, int minDelay, int fade, bool setPalette, 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..cfbea2bc24
--- /dev/null
+++ b/engines/sherlock/debugger.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.
+ *
+ */
+
+#include "sherlock/debugger.h"
+#include "sherlock/sherlock.h"
+
+namespace Sherlock {
+
+Debugger::Debugger(SherlockEngine *vm) : GUI::Debugger(), _vm(vm) {
+ registerCmd("continue", WRAP_METHOD(Debugger, cmdExit));
+ registerCmd("scene", WRAP_METHOD(Debugger, cmdScene));
+}
+
+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;
+ }
+}
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/debugger.h b/engines/sherlock/debugger.h
new file mode 100644
index 0000000000..e6a3aba828
--- /dev/null
+++ b/engines/sherlock/debugger.h
@@ -0,0 +1,53 @@
+/* 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;
+
+class Debugger : public GUI::Debugger {
+private:
+ SherlockEngine *_vm;
+
+ /**
+ * 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);
+public:
+ Debugger(SherlockEngine *vm);
+ virtual ~Debugger() {}
+};
+
+} // 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..ea68d79a1b
--- /dev/null
+++ b/engines/sherlock/detection.cpp
@@ -0,0 +1,241 @@
+/* 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;
+}
+
+} // 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..208b6710af
--- /dev/null
+++ b/engines/sherlock/detection_tables.h
@@ -0,0 +1,120 @@
+/* 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 - 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..b238605e13
--- /dev/null
+++ b/engines/sherlock/events.cpp
@@ -0,0 +1,249 @@
+/* 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;
+
+ if (_vm->_interactiveFl)
+ loadCursors("rmouse.vgs");
+}
+
+Events::~Events() {
+ delete _cursorImages;
+}
+
+void Events::loadCursors(const Common::String &filename) {
+ hideCursor();
+ delete _cursorImages;
+
+ _cursorImages = new ImageFile(filename);
+ _cursorId = INVALID_CURSOR;
+}
+
+void Events::setCursor(CursorId cursorId) {
+ if (cursorId == _cursorId)
+ return;
+
+ _cursorId = cursorId;
+
+ // Set the cursor data
+ Graphics::Surface &s = (*_cursorImages)[cursorId]._frame;
+
+ setCursor(s);
+}
+
+void Events::setCursor(const Graphics::Surface &src) {
+ CursorMan.replaceCursor(src.getPixels(), src.w, src.h, 0, 0, 0xff);
+ showCursor();
+}
+
+void Events::animateCursorIfNeeded() {
+ if (_cursorId >= WAIT && _cursorId < (WAIT + 3)) {
+ CursorId newId = (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);
+}
+
+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::mousePos() const {
+ return g_system->getEventManager()->getMousePos();
+}
+
+Common::KeyState Events::getKey() {
+ return _pendingKeys.pop();
+}
+
+void Events::clearEvents() {
+ _pendingKeys.clear();
+ _mouseButtons = 0;
+ _pressed = _released = false;
+ _rightPressed = _rightReleased = false;
+ _oldButtons = _oldRightButton = 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));
+
+ 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 true;
+ }
+}
+
+void Events::setButtonState() {
+ _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..b35109fefe
--- /dev/null
+++ b/engines/sherlock/events.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.
+ *
+ */
+
+#ifndef SHERLOCK_EVENTS_H
+#define SHERLOCK_EVENTS_H
+
+#include "common/scummsys.h"
+#include "common/events.h"
+#include "common/stack.h"
+#include "sherlock/resources.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;
+ Common::Stack<Common::KeyState> _pendingKeys;
+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);
+
+ /**
+ * 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();
+
+ /**
+ * Get the current mouse position
+ */
+ Common::Point mousePos() const;
+
+ uint32 getFrameCounter() const { return _frameCounter; }
+
+ 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/inventory.cpp b/engines/sherlock/inventory.cpp
new file mode 100644
index 0000000000..a8ecb64102
--- /dev/null
+++ b/engines/sherlock/inventory.cpp
@@ -0,0 +1,471 @@
+/* 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_user_interface.h"
+
+namespace Sherlock {
+
+InventoryItem::InventoryItem(int requiredFlag, const Common::String &name,
+ const Common::String &description, const Common::String &examine) :
+ _requiredFlag(requiredFlag), _name(name), _description(description),
+ _examine(examine), _lookFlag(0) {
+}
+
+void InventoryItem::synchronize(Common::Serializer &s) {
+ s.syncAsSint16LE(_requiredFlag);
+ s.syncAsSint16LE(_lookFlag);
+ s.syncString(_name);
+ s.syncString(_description);
+ s.syncString(_examine);
+}
+
+/*----------------------------------------------------------------*/
+
+Inventory::Inventory(SherlockEngine *vm) : Common::Array<InventoryItem>(), _vm(vm) {
+ Common::fill(&_invShapes[0], &_invShapes[MAX_VISIBLE_INVENTORY], (ImageFile *)nullptr);
+ _invGraphicsLoaded = false;
+ _invIndex = 0;
+ _holdings = 0;
+ _invMode = INVMODE_EXIT;
+ for (int i = 0; i < 6; ++i)
+ _invShapes[i] = nullptr;
+}
+
+Inventory::~Inventory() {
+ freeGraphics();
+}
+
+void Inventory::freeInv() {
+ freeGraphics();
+
+ _names.clear();
+ _invGraphicsLoaded = false;
+}
+
+void Inventory::freeGraphics() {
+ for (uint idx = 0; idx < MAX_VISIBLE_INVENTORY; ++idx)
+ delete _invShapes[idx];
+
+ Common::fill(&_invShapes[0], &_invShapes[MAX_VISIBLE_INVENTORY], (ImageFile *)nullptr);
+ _invGraphicsLoaded = false;
+}
+
+void Inventory::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();
+}
+
+void Inventory::loadGraphics() {
+ if (_invGraphicsLoaded)
+ return;
+
+ // Default all inventory slots to empty
+ Common::fill(&_invShapes[0], &_invShapes[MAX_VISIBLE_INVENTORY], (ImageFile *)nullptr);
+
+ for (int idx = _invIndex; (idx < _holdings) && (idx - _invIndex) < MAX_VISIBLE_INVENTORY; ++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 fName = Common::String::format("item%02d.vgs", invNum + 1);
+
+ _invShapes[idx - _invIndex] = new ImageFile(fName);
+ }
+
+ _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());
+}
+
+void Inventory::putInv(InvSlamMode slamIt) {
+ Screen &screen = *_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 - 6)) {
+ --_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) < MAX_VISIBLE_INVENTORY; ++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, 235);
+ } 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 Inventory::drawInventory(InvNewMode mode) {
+ Screen &screen = *_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
+ screen.makeButton(Common::Rect(Scalpel::INVENTORY_POINTS[0][0], CONTROLS_Y1, Scalpel::INVENTORY_POINTS[0][1],
+ CONTROLS_Y1 + 10), Scalpel::INVENTORY_POINTS[0][2] - screen.stringWidth("Exit") / 2, "Exit");
+ screen.makeButton(Common::Rect(Scalpel::INVENTORY_POINTS[1][0], CONTROLS_Y1, Scalpel::INVENTORY_POINTS[1][1],
+ CONTROLS_Y1 + 10), Scalpel::INVENTORY_POINTS[1][2] - screen.stringWidth("Look") / 2, "Look");
+ screen.makeButton(Common::Rect(Scalpel::INVENTORY_POINTS[2][0], CONTROLS_Y1, Scalpel::INVENTORY_POINTS[2][1],
+ CONTROLS_Y1 + 10), Scalpel::INVENTORY_POINTS[2][2] - screen.stringWidth("Use") / 2, "Use");
+ screen.makeButton(Common::Rect(Scalpel::INVENTORY_POINTS[3][0], CONTROLS_Y1, Scalpel::INVENTORY_POINTS[3][1],
+ CONTROLS_Y1 + 10), Scalpel::INVENTORY_POINTS[3][2] - screen.stringWidth("Give") / 2, "Give");
+ screen.makeButton(Common::Rect(Scalpel::INVENTORY_POINTS[4][0], CONTROLS_Y1, Scalpel::INVENTORY_POINTS[4][1],
+ CONTROLS_Y1 + 10), Scalpel::INVENTORY_POINTS[4][2], "^^");
+ screen.makeButton(Common::Rect(Scalpel::INVENTORY_POINTS[5][0], CONTROLS_Y1, Scalpel::INVENTORY_POINTS[5][1],
+ CONTROLS_Y1 + 10), Scalpel::INVENTORY_POINTS[5][2], "^");
+ screen.makeButton(Common::Rect(Scalpel::INVENTORY_POINTS[6][0], CONTROLS_Y1, Scalpel::INVENTORY_POINTS[6][1],
+ CONTROLS_Y1 + 10), Scalpel::INVENTORY_POINTS[6][2], "_");
+ screen.makeButton(Common::Rect(Scalpel::INVENTORY_POINTS[7][0], CONTROLS_Y1, Scalpel::INVENTORY_POINTS[7][1],
+ CONTROLS_Y1 + 10), Scalpel::INVENTORY_POINTS[7][2], "__");
+
+ if (tempMode == INVENTORY_DONT_DISPLAY)
+ mode = LOOK_INVENTORY_MODE;
+ _invMode = (InvMode)mode;
+
+ if (mode != PLAIN_INVENTORY) {
+ ui._oldKey = Scalpel::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);
+ ((Scalpel::ScalpelUserInterface *)_vm->_ui)->_oldUse = -1;
+}
+
+void Inventory::invCommands(bool slamIt) {
+ Screen &screen = *_vm->_screen;
+ UserInterface &ui = *_vm->_ui;
+
+ if (slamIt) {
+ screen.buttonPrint(Common::Point(Scalpel::INVENTORY_POINTS[0][2], CONTROLS_Y1),
+ _invMode == INVMODE_EXIT ? COMMAND_HIGHLIGHTED :COMMAND_FOREGROUND,
+ true, "Exit");
+ screen.buttonPrint(Common::Point(Scalpel::INVENTORY_POINTS[1][2], CONTROLS_Y1),
+ _invMode == INVMODE_LOOK ? COMMAND_HIGHLIGHTED :COMMAND_FOREGROUND,
+ true, "Look");
+ screen.buttonPrint(Common::Point(Scalpel::INVENTORY_POINTS[2][2], CONTROLS_Y1),
+ _invMode == INVMODE_USE ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND,
+ true, "Use");
+ screen.buttonPrint(Common::Point(Scalpel::INVENTORY_POINTS[3][2], CONTROLS_Y1),
+ _invMode == INVMODE_GIVE ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND,
+ true, "Give");
+ screen.print(Common::Point(Scalpel::INVENTORY_POINTS[4][2], CONTROLS_Y1 + 1),
+ _invIndex == 0 ? COMMAND_NULL : COMMAND_FOREGROUND,
+ "^^");
+ screen.print(Common::Point(Scalpel::INVENTORY_POINTS[5][2], CONTROLS_Y1 + 1),
+ _invIndex == 0 ? COMMAND_NULL : COMMAND_FOREGROUND,
+ "^");
+ screen.print(Common::Point(Scalpel::INVENTORY_POINTS[6][2], CONTROLS_Y1 + 1),
+ (_holdings - _invIndex <= 6) ? COMMAND_NULL : COMMAND_FOREGROUND,
+ "_");
+ screen.print(Common::Point(Scalpel::INVENTORY_POINTS[7][2], CONTROLS_Y1 + 1),
+ (_holdings - _invIndex <= 6) ? COMMAND_NULL : COMMAND_FOREGROUND,
+ "__");
+ if (_invMode != INVMODE_LOOK)
+ ui.clearInfo();
+ } else {
+ screen.buttonPrint(Common::Point(Scalpel::INVENTORY_POINTS[0][2], CONTROLS_Y1),
+ _invMode == INVMODE_EXIT ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND,
+ false, "Exit");
+ screen.buttonPrint(Common::Point(Scalpel::INVENTORY_POINTS[1][2], CONTROLS_Y1),
+ _invMode == INVMODE_LOOK ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND,
+ false, "Look");
+ screen.buttonPrint(Common::Point(Scalpel::INVENTORY_POINTS[2][2], CONTROLS_Y1),
+ _invMode == INVMODE_USE ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND,
+ false, "Use");
+ screen.buttonPrint(Common::Point(Scalpel::INVENTORY_POINTS[3][2], CONTROLS_Y1),
+ _invMode == INVMODE_GIVE ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND,
+ false, "Give");
+ screen.gPrint(Common::Point(Scalpel::INVENTORY_POINTS[4][2], CONTROLS_Y1),
+ _invIndex == 0 ? COMMAND_NULL : COMMAND_FOREGROUND,
+ "^^");
+ screen.gPrint(Common::Point(Scalpel::INVENTORY_POINTS[5][2], CONTROLS_Y1),
+ _invIndex == 0 ? COMMAND_NULL : COMMAND_FOREGROUND,
+ "^");
+ screen.gPrint(Common::Point(Scalpel::INVENTORY_POINTS[6][2], CONTROLS_Y1),
+ (_holdings - _invIndex < 7) ? COMMAND_NULL : COMMAND_FOREGROUND,
+ "_");
+ screen.gPrint(Common::Point(Scalpel::INVENTORY_POINTS[7][2], CONTROLS_Y1),
+ (_holdings - _invIndex < 7) ? COMMAND_NULL : COMMAND_FOREGROUND,
+ "__");
+ }
+}
+
+void Inventory::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 Inventory::refreshInv() {
+ if (IS_ROSE_TATTOO)
+ return;
+
+ Screen &screen = *_vm->_screen;
+ Talk &talk = *_vm->_talk;
+ Scalpel::ScalpelUserInterface &ui = *(Scalpel::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();
+ }
+}
+
+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;
+
+ 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(Common::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..02f570f5da
--- /dev/null
+++ b/engines/sherlock/inventory.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.
+ *
+ */
+
+#ifndef SHERLOCK_INVENTORY_H
+#define SHERLOCK_INVENTORY_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/serializer.h"
+#include "common/str-array.h"
+#include "sherlock/objects.h"
+#include "sherlock/resources.h"
+
+namespace Sherlock {
+
+#define MAX_VISIBLE_INVENTORY 6
+
+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;
+
+ InventoryItem() : _requiredFlag(0), _lookFlag(0) {}
+ InventoryItem(int requiredFlag, const Common::String &name,
+ const Common::String &description, const Common::String &examine);
+
+ /**
+ * Synchronize the data for an inventory item
+ */
+ void synchronize(Common::Serializer &s);
+};
+
+class Inventory : public Common::Array<InventoryItem> {
+private:
+ SherlockEngine *_vm;
+ Common::StringArray _names;
+
+ /**
+ * Copy the passed object into the inventory
+ */
+ void copyToInventory(Object &obj);
+public:
+ ImageFile *_invShapes[MAX_VISIBLE_INVENTORY];
+ 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:
+ Inventory(SherlockEngine *vm);
+ ~Inventory();
+
+ /**
+ * Free inventory data
+ */
+ void freeInv();
+
+ /**
+ * Load the list of names the inventory items correspond to, if not already loaded,
+ * and then calls loadGraphics to load the associated graphics
+ */
+ void loadInv();
+
+ /**
+ * 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);
+
+ /**
+ * Display the character's inventory. The slamIt parameter specifies:
+ */
+ void putInv(InvSlamMode slamIt);
+
+ /**
+ * 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();
+
+ /**
+ * 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(Common::Serializer &s);
+};
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp
new file mode 100644
index 0000000000..b4b05da991
--- /dev/null
+++ b/engines/sherlock/journal.cpp
@@ -0,0 +1,1174 @@
+/* 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"
+
+namespace Sherlock {
+
+#define JOURNAL_BUTTONS_Y 178
+#define LINES_PER_PAGE 11
+#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 }
+};
+
+/*----------------------------------------------------------------*/
+
+Journal::Journal(SherlockEngine *vm) : _vm(vm) {
+ // Initialize fields
+ _maxPage = 0;
+ _index = 0;
+ _sub = 0;
+ _up = _down = false;
+ _page = 1;
+
+ if (_vm->_interactiveFl) {
+ // Load the journal directory and location names
+ loadJournalLocations();
+ }
+}
+
+void Journal::record(int converseNum, int statementNum, bool replyOnly) {
+ int saveIndex = _index;
+ int saveSub = _sub;
+
+ // 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 Journal::loadJournalLocations() {
+ Resources &res = *_vm->_res;
+
+ _directory.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;
+
+ // Load in the locations stored in journal.txt
+ Common::SeekableReadStream *loc = res.load("journal.txt");
+
+ _locations.clear();
+ while (loc->pos() < loc->size()) {
+ Common::String line;
+ char c;
+ while ((c = loc->readByte()) != 0)
+ line += c;
+
+ _locations.push_back(line);
+ }
+
+ delete loc;
+}
+
+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 alrady 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[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 = "@" + _locations[newLocation - 1] + ":";
+
+ // 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 ";
+
+ switch (talk._talkTo) {
+ case 1:
+ journalString += "me";
+ break;
+ case 2:
+ journalString += "the Inspector";
+ break;
+ default:
+ journalString += people._characters[talk._talkTo]._name;
+ break;
+ }
+ 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();
+
+ while (*replyP) {
+ byte 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 == '}') {
+ // 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 == 2)
+ 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 (c == 0)
+ journalString += "Holmes";
+ else if (c == 1)
+ journalString += "I";
+ else if (c == 2)
+ 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 {
+ // 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_CARRIAGE_RETURN]) {
+ journalString += "\n";
+ }
+
+ // 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_CARRIAGE_RETURN] &&
+ !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::drawJournalFrame() {
+ Resources &res = *_vm->_res;
+ Screen &screen = *_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]);
+
+ // Set the palette and print the title
+ screen.setPalette(palette);
+ screen.gPrint(Common::Point(111, 18), BUTTON_BOTTOM, "Watson's Journal");
+ screen.gPrint(Common::Point(110, 17), INV_FOREGROUND, "Watson's Journal");
+
+ // 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("Exit") / 2, "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("Back 10") / 2, "Back 10");
+ 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("Up") / 2, "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("Down") / 2, "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("Ahead 10") / 2, "Ahead 10");
+ 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("Search") / 2, "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("First Page") / 2, "First Page");
+ 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("Last Page") / 2, "Last Page");
+
+ // 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("Print Text") / 2, "Print Text");
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[8][2], JOURNAL_BUTTONS_Y + 11),
+ COMMAND_NULL, false, "Print Text");
+}
+
+void Journal::drawInterface() {
+ Screen &screen = *_vm->_screen;
+
+ drawJournalFrame();
+
+ 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 Journal::doArrows() {
+ Screen &screen = *_vm->_screen;
+ byte color;
+
+ color = (_page > 1) ? COMMAND_FOREGROUND : COMMAND_NULL;
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[1][2], JOURNAL_BUTTONS_Y), color, false, "Back 10");
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[2][2], JOURNAL_BUTTONS_Y), color, false, "Up");
+
+ color = _down ? COMMAND_FOREGROUND : COMMAND_NULL;
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[3][2], JOURNAL_BUTTONS_Y), color, false, "Down");
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[4][2], JOURNAL_BUTTONS_Y), color, false, "Ahead 10");
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[7][2], JOURNAL_BUTTONS_Y + 11), color, false, "Last Page");
+
+ color = _journal.size() > 0 ? COMMAND_FOREGROUND : COMMAND_NULL;
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[5][2], JOURNAL_BUTTONS_Y + 11), color, false, "Search");
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[8][2], JOURNAL_BUTTONS_Y + 11), COMMAND_NULL, false, "Print Text");
+
+ color = _page > 1 ? COMMAND_FOREGROUND : COMMAND_NULL;
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[6][2], JOURNAL_BUTTONS_Y + 11), color, false, "First Page");
+}
+
+bool Journal::drawJournal(int direction, int howFar) {
+ Events &events = *_vm->_events;
+ 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)
+ drawJournalFrame();
+
+ screen.gPrint(Common::Point(235, 21), 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 {
+ // Animate the glass mouse cursor
+ int cursorNum = (int)events.getCursor() + 1;
+ if (cursorNum > (WAIT + 2))
+ cursorNum = WAIT;
+ events.setCursor((CursorId)cursorNum);
+
+ // 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);
+ drawJournalFrame();
+ }
+
+ screen.gPrint(Common::Point(235, 21), PEN_COLOR, "Page %d", _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), PEN_COLOR, "%s", lineStart.c_str());
+ }
+
+ // Print out the found keyword
+ Common::String lineMatch(matchP, matchP + _find.size());
+ screen.gPrint(Common::Point(53 + width, yp), INV_FOREGROUND, "%s", lineMatch.c_str());
+ width += screen.stringWidth(lineMatch.c_str());
+
+ // Print remainder of line
+ screen.gPrint(Common::Point(53 + width, yp), 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), 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), 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;
+}
+
+JournalButton Journal::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 Journal::handleEvents(int key) {
+ Events &events = *_vm->_events;
+ Screen &screen = *_vm->_screen;
+ bool doneFlag = false;
+
+ Common::Point pt = events.mousePos();
+ JournalButton btn = getHighlightedButton(pt);
+ byte color;
+
+ if (events._pressed || events._released) {
+ // Exit button
+ color = (btn == BTN_EXIT) ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND;
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[0][2], JOURNAL_BUTTONS_Y), color, true, "Exit");
+
+ // Back 10 button
+ if (btn == BTN_BACK10) {
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[1][2], JOURNAL_BUTTONS_Y), COMMAND_HIGHLIGHTED, true, "Back 10");
+ } else if (_page > 1) {
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[1][2], JOURNAL_BUTTONS_Y), COMMAND_FOREGROUND, true, "Back 10");
+ }
+
+ // Up button
+ if (btn == BTN_UP) {
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[2][2], JOURNAL_BUTTONS_Y), COMMAND_HIGHLIGHTED, true, "Up");
+ } else if (_up) {
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[2][2], JOURNAL_BUTTONS_Y), COMMAND_FOREGROUND, true, "Up");
+ }
+
+ // Down button
+ if (btn == BTN_DOWN) {
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[3][2], JOURNAL_BUTTONS_Y), COMMAND_HIGHLIGHTED, true, "Down");
+ } else if (_down) {
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[3][2], JOURNAL_BUTTONS_Y), COMMAND_FOREGROUND, true, "Down");
+ }
+
+ // Ahead 10 button
+ if (btn == BTN_AHEAD110) {
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[4][2], JOURNAL_BUTTONS_Y), COMMAND_HIGHLIGHTED, true, "Ahead 10");
+ } else if (_down) {
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[4][2], JOURNAL_BUTTONS_Y), COMMAND_FOREGROUND, true, "Ahead 10");
+ }
+
+ // 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, "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, "First Page");
+
+ // 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, "Last Page");
+
+ // Print Text button
+ screen.buttonPrint(Common::Point(JOURNAL_POINTS[8][2], JOURNAL_BUTTONS_Y + 11), COMMAND_NULL, true, "Print Text");
+ }
+
+ 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;
+
+ drawJournalFrame();
+ 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;
+
+ drawJournalFrame();
+ 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 Journal::getSearchString(bool printError) {
+ enum Button { BTN_NONE, BTN_EXIT, BTN_BACKWARD, BTN_FORWARD };
+
+ Events &events = *_vm->_events;
+ Screen &screen = *_vm->_screen;
+ Talk &talk = *_vm->_talk;
+ int xp;
+ int yp = 174;
+ bool flag = false;
+ Common::String name;
+ int done = 0;
+ byte color;
+
+ // 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("Exit") / 2, "Exit");
+ screen.makeButton(Common::Rect(SEARCH_POINTS[1][0], yp, SEARCH_POINTS[1][1], yp + 10),
+ SEARCH_POINTS[1][2] - screen.stringWidth("Backward") / 2, "Backward");
+ screen.makeButton(Common::Rect(SEARCH_POINTS[2][0], yp, SEARCH_POINTS[2][1], yp + 10),
+ SEARCH_POINTS[2][2] - screen.stringWidth("Forward") / 2, "Forward");
+ screen.gPrint(Common::Point(SEARCH_POINTS[0][2] - screen.stringWidth("Exit") / 2, yp),
+ COMMAND_FOREGROUND, "E");
+ screen.gPrint(Common::Point(SEARCH_POINTS[1][2] - screen.stringWidth("Backward") / 2, yp),
+ COMMAND_FOREGROUND, "B");
+ screen.gPrint(Common::Point(SEARCH_POINTS[2][2] - screen.stringWidth("Forward") / 2, yp),
+ COMMAND_FOREGROUND, "F");
+
+ 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("Text Not Found !")) / 2, 185),
+ INV_FOREGROUND, "Text Not Found !");
+ } 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("Exit") / 2, 175), color, "Exit");
+
+ 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("Backward") / 2, 175), color, "Backward");
+
+ 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("Forward") / 2, 175), color, "Forward");
+ }
+
+ 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
+ drawJournalFrame();
+ drawJournal(0, 0);
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+
+ return done;
+}
+
+void Journal::resetPosition() {
+ _index = _sub = _up = _down = 0;
+ _page = 1;
+}
+
+void Journal::synchronize(Common::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..d62b8338c0
--- /dev/null
+++ b/engines/sherlock/journal.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_JOURNAL_H
+#define SHERLOCK_JOURNAL_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/rect.h"
+#include "common/serializer.h"
+#include "common/str-array.h"
+#include "common/stream.h"
+
+namespace Sherlock {
+
+#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
+};
+
+
+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 SherlockEngine;
+
+class Journal {
+private:
+ SherlockEngine *_vm;
+ Common::Array<JournalEntry> _journal;
+ Common::StringArray _directory;
+ Common::StringArray _locations;
+ Common::StringArray _lines;
+ int _maxPage;
+ int _index;
+ int _sub;
+ bool _up, _down;
+ int _page;
+ Common::String _find;
+
+ /**
+ * Load the list of location names that the journal will make reference to
+ */
+ void loadJournalLocations();
+
+ /**
+ * 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);
+
+ /**
+ * Display the arrows that can be used to scroll up and down pages
+ */
+ void doArrows();
+
+ /**
+ * Displays a page of the journal at the current index
+ */
+ bool drawJournal(int direction, int howFar);
+
+ /**
+ * Show the search submenu and allow the player to enter a search string
+ */
+ int getSearchString(bool printError);
+
+ /**
+ * Draw the journal background, frame, and interface buttons
+ */
+ void drawJournalFrame();
+
+ /**
+ * Returns the button, if any, that is under the specified position
+ */
+ JournalButton getHighlightedButton(const Common::Point &pt);
+public:
+ Journal(SherlockEngine *vm);
+
+ /**
+ * Records statements that are said, in the order which they are said. The player
+ * can then read the journal to review them
+ */
+ void record(int converseNum, int statementNum, bool replyOnly = false);
+
+ /**
+ * Display the journal
+ */
+ void drawInterface();
+
+ /**
+ * Handle events whilst the journal is being displayed
+ */
+ bool handleEvents(int key);
+
+ /**
+ * Reset viewing position to the start of the journal
+ */
+ void resetPosition();
+
+ /**
+ * Synchronize the data for a savegame
+ */
+ void synchronize(Common::Serializer &s);
+};
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp
new file mode 100644
index 0000000000..ffbca3fb42
--- /dev/null
+++ b/engines/sherlock/map.cpp
@@ -0,0 +1,565 @@
+/* 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/map.h"
+#include "sherlock/sherlock.h"
+#include "common/system.h"
+
+namespace Sherlock {
+
+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];
+}
+
+/*----------------------------------------------------------------*/
+
+Map::Map(SherlockEngine *vm): _vm(vm), _topLine(g_system->getWidth(), 12) {
+ _active = false;
+ _mapCursors = nullptr;
+ _shapes = nullptr;
+ _iconShapes = nullptr;
+ _point = 0;
+ _placesShown = false;
+ _cursorIndex = -1;
+ _drawMap = false;
+ _overPos = Common::Point(13000, 12600);
+ _charPoint = 0;
+ _oldCharPoint = 0;
+ _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 Map::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 Map::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 Map::loadData() {
+ // TODO: Remove this
+ if (_vm->getGameID() == GType_RoseTattoo)
+ return;
+
+ // Load the list of location names
+ Common::SeekableReadStream *txtStream = _vm->_res->load(
+ _vm->getGameID() == GType_SerratedScalpel ? "chess.txt" : "map.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 Map::show() {
+ Events &events = *_vm->_events;
+ People &people = *_vm->_people;
+ Screen &screen = *_vm->_screen;
+ Common::Point lDrawn(-1, -1);
+ 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("bigmap.vgs");
+ screen.setPalette(bigMap._palette);
+
+ // Load need sprites
+ setupSprites();
+
+ 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));
+
+ _drawMap = true;
+ _charPoint = -1;
+ _point = -1;
+ people[AL]._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();
+
+ // 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;
+
+ 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));
+
+ 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[AL]._walkCount == 0) {
+ people._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[AL]._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[AL]._position;
+
+ // Reset font
+ screen.setFont(oldFont);
+
+ _active = false;
+ return _charPoint;
+}
+
+void Map::setupSprites() {
+ Events &events = *_vm->_events;
+ People &people = *_vm->_people;
+ Scene &scene = *_vm->_scene;
+ _savedPos.x = -1;
+
+ _mapCursors = new ImageFile("omouse.vgs");
+ _cursorIndex = 0;
+ events.setCursor((*_mapCursors)[_cursorIndex]._frame);
+
+ _shapes = new ImageFile("mapicon.vgs");
+ _iconShapes = new ImageFile("overicon.vgs");
+ _iconSave.create((*_shapes)[4]._width, (*_shapes)[4]._height);
+ Person &p = people[AL];
+ 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 Map::freeSprites() {
+ delete _mapCursors;
+ delete _shapes;
+ delete _iconShapes;
+ _iconSave.free();
+}
+
+void Map::showPlaces() {
+ 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 (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));
+ }
+ }
+ }
+ }
+}
+
+void Map::saveTopLine() {
+ _topLine.blitFrom(_vm->_screen->_backBuffer1, Common::Point(0, 0), Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, 12));
+}
+
+void Map::eraseTopLine() {
+ Screen &screen = *_vm->_screen;
+ screen._backBuffer1.blitFrom(_topLine, Common::Point(0, 0));
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, _topLine.h());
+}
+
+void Map::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[AL]._imageFrame, _lDrawnPos);
+
+ bool flipped = people[AL]._sequenceNumber == MAP_DOWNLEFT || people[AL]._sequenceNumber == MAP_LEFT
+ || people[AL]._sequenceNumber == MAP_UPLEFT;
+ screen._backBuffer1.transBlitFrom(*people[AL]._imageFrame, _lDrawnPos, flipped);
+ }
+
+ if (highlighted) {
+ int xp = (SHERLOCK_SCREEN_WIDTH - screen.stringWidth(name)) / 2;
+ screen.gPrint(Common::Point(xp + 2, 2), 0, "%s", name.c_str());
+ screen.gPrint(Common::Point(xp + 1, 1), 0, "%s", name.c_str());
+ screen.gPrint(Common::Point(xp, 0), 12, "%s", name.c_str());
+
+ screen.slamArea(xp, 0, width + 2, 15);
+ }
+}
+
+void Map::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[AL].adjustSprite();
+
+ _lDrawnPos.x = hPos.x = people[AL]._position.x / 100 - _bigPos.x;
+ _lDrawnPos.y = hPos.y = people[AL]._position.y / 100 - people[AL].frameHeight() - _bigPos.y;
+
+ // Draw the person icon
+ saveIcon(people[AL]._imageFrame, hPos);
+ if (people[AL]._sequenceNumber == MAP_DOWNLEFT || people[AL]._sequenceNumber == MAP_LEFT
+ || people[AL]._sequenceNumber == MAP_UPLEFT)
+ screen._backBuffer1.transBlitFrom(*people[AL]._imageFrame, hPos, true);
+ else
+ screen._backBuffer1.transBlitFrom(*people[AL]._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[AL]._imageFrame, Common::Point(people[AL]._position.x / 100 - _bigPos.x,
+ people[AL]._position.y / 100 - people[AL].frameHeight() - _bigPos.y),
+ &people[AL]._oldPosition.x, &people[AL]._oldPosition.y, &people[AL]._oldSize.x, &people[AL]._oldSize.y);
+
+ if (osPos.x != -1)
+ screen.slamArea(osPos.x, osPos.y, osSize.x, osSize.y);
+ }
+}
+
+void Map::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._walkTo.clear();
+ Common::Point destPos = people._walkDest;
+
+ // Check for any intermediate points between the two locations
+ if (path[0] || _charPoint > 50 || _oldCharPoint > 50) {
+ people[AL]._sequenceNumber = -1;
+
+ if (_charPoint == 51 || _oldCharPoint == 51) {
+ people.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._walkTo.clear();
+
+ if (reversePath) {
+ for (int idx = (int)tempPath.size() - 1; idx >= 0; --idx)
+ people._walkTo.push(tempPath[idx]);
+ } else {
+ for (int idx = 0; idx < (int)tempPath.size(); ++idx)
+ people._walkTo.push(tempPath[idx]);
+ }
+
+ people._walkDest = people._walkTo.pop() + Common::Point(12, 6);
+ people.setWalking();
+ }
+ } else {
+ people[AL]._walkCount = 0;
+ }
+
+ // Store the final destination icon position
+ people._walkTo.push(destPos);
+}
+
+void Map::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 Map::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 Map::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();
+ }
+}
+
+void Map::synchronize(Common::Serializer &s) {
+ s.syncAsSint16LE(_bigPos.x);
+ s.syncAsSint16LE(_bigPos.y);
+ s.syncAsSint16LE(_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..e0c7d038c4
--- /dev/null
+++ b/engines/sherlock/map.h
@@ -0,0 +1,180 @@
+/* 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 "common/scummsys.h"
+#include "common/array.h"
+#include "common/rect.h"
+#include "common/serializer.h"
+#include "common/str.h"
+#include "common/str-array.h"
+#include "sherlock/surface.h"
+#include "sherlock/objects.h"
+
+namespace Sherlock {
+
+class SherlockEngine;
+
+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 Map {
+private:
+ SherlockEngine *_vm;
+ 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;
+private:
+ /**
+ * 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:
+ bool _active;
+ Point32 _overPos;
+ Point32 _bigPos;
+ int _charPoint, _oldCharPoint;
+ bool _frameChangeFlag;
+public:
+ Map(SherlockEngine *vm);
+
+ 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
+ */
+ int show();
+
+ /**
+ * Synchronize the data for a savegame
+ */
+ void synchronize(Common::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..1a38d56511
--- /dev/null
+++ b/engines/sherlock/module.mk
@@ -0,0 +1,41 @@
+MODULE := engines/sherlock
+
+MODULE_OBJS = \
+ scalpel/darts.o \
+ scalpel/scalpel.o \
+ scalpel/drivers/adlib.o \
+ scalpel/tsage/logo.o \
+ scalpel/tsage/resources.o \
+ scalpel/scalpel_scene.o \
+ scalpel/scalpel_user_interface.o \
+ scalpel/settings.o \
+ tattoo/tattoo.o \
+ tattoo/tattoo_scene.o \
+ tattoo/tattoo_user_interface.o \
+ animation.o \
+ debugger.o \
+ detection.o \
+ events.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..0735f41d9a
--- /dev/null
+++ b/engines/sherlock/music.cpp
@@ -0,0 +1,360 @@
+/* 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 "sherlock/sherlock.h"
+#include "sherlock/music.h"
+#include "sherlock/scalpel/drivers/mididriver.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;
+}
+
+void MidiParser_SH::parseNextEvent(EventInfo &info) {
+// warning("parseNextEvent");
+
+ // An attempt to remap MT32 instruments to GMIDI. Only partially successful, it still
+ // does not sound even close to the real MT32. Oddly enough, on the actual hardware MT32
+ // and SB sound very differently.
+ static const byte mt32Map[128] = {
+ 0, 1, 0, 2, 4, 4, 5, 3, /* 0-7 */
+ 16, 17, 18, 16, 16, 19, 20, 21, /* 8-15 */
+ 6, 6, 6, 7, 7, 7, 8, 112, /* 16-23 */
+ 62, 62, 63, 63 , 38, 38, 39, 39, /* 24-31 */
+ 88, 95, 52, 98, 97, 99, 14, 54, /* 32-39 */
+ 102, 96, 53, 102, 81, 100, 14, 80, /* 40-47 */
+ 48, 48, 49, 45, 41, 40, 42, 42, /* 48-55 */
+ 43, 46, 45, 24, 25, 28, 27, 104, /* 56-63 */
+ 32, 32, 34, 33, 36, 37, 35, 35, /* 64-71 */
+ 79, 73, 72, 72, 74, 75, 64, 65, /* 72-79 */
+ 66, 67, 71, 71, 68, 69, 70, 22, /* 80-87 */
+ 56, 59, 57, 57, 60, 60, 58, 61, /* 88-95 */
+ 61, 11, 11, 98, 14, 9, 14, 13, /* 96-103 */
+ 12, 107, 107, 77, 78, 78, 76, 76, /* 104-111 */
+ 47, 117, 127, 118, 118, 116, 115, 119, /* 112-119 */
+ 115, 112, 55, 124, 123, 0, 14, 117 /* 120-127 */
+ };
+
+ // 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;
+ // don't do this here, it breaks adlib
+ //info.basic.param1 = mt32Map[idx & 0x7f]; // remap MT32 to GM
+ 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
+ warning("System META event 0xFC");
+
+ byte type = *(_position._playPos++);
+ switch (type) {
+ case 0x80: // end of track, triggers looping
+ warning("META event triggered looping");
+ jumpToTick(0, true, true, false);
+ break;
+ case 0x81: // end of track, stop playing
+ warning("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 *data, uint32 size) {
+ warning("loadMusic");
+ unloadMusic();
+
+ byte *headerPtr = data;
+ byte *pos = data;
+ uint16 headerSize = READ_LE_UINT16(headerPtr);
+ assert(headerSize == 0x7F);
+
+ // Skip over header
+ pos += headerSize;
+
+ _lastEvent = 0;
+ _trackEnd = data + size;
+
+ _numTracks = 1;
+ _tracks[0] = pos;
+
+ _ppqn = 1;
+ setTempo(16667);
+ setTrack(0);
+
+ return true;
+}
+
+/*----------------------------------------------------------------*/
+
+Music::Music(SherlockEngine *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer) {
+ if (_vm->_interactiveFl)
+ _vm->_res->addToCache("MUSIC.LIB");
+
+ MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
+
+ _musicType = MidiDriver::getMusicType(dev);
+
+ _driver = NULL;
+
+ switch (_musicType) {
+ case MT_ADLIB:
+ _driver = MidiDriver_AdLib_create();
+ break;
+ default:
+ _driver = MidiDriver::createMidi(dev);
+ break;
+ }
+
+ if (_driver) {
+ assert(_driver);
+
+ int ret = _driver->open();
+ if (ret == 0) {
+ _driver->sendGMReset();
+ _driver->setTimerCallback(&_midiParser, &_midiParser.timerCallback);
+ }
+ _midiParser.setMidiDriver(_driver);
+ _midiParser.setTimerRate(_driver->getBaseTempo());
+ }
+
+ _musicPlaying = false;
+ _musicOn = true;
+}
+
+bool Music::loadSong(int songNumber) {
+ warning("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]) + ".MUS";
+
+ freeSong(); // free any song that is currently loaded
+
+ if (!playMusic(songName))
+ return false;
+
+ stopMusic();
+ startSong();
+ return true;
+}
+
+bool Music::loadSong(const Common::String &songName) {
+ warning("TODO: Music::loadSong");
+ return false;
+}
+
+void Music::syncMusicSettings() {
+ _musicOn = !ConfMan.getBool("mute") && !ConfMan.getBool("music_mute");
+}
+
+bool Music::playMusic(const Common::String &name) {
+ if (!_musicOn)
+ return false;
+
+ warning("Sound::playMusic %s", name.c_str());
+ Common::SeekableReadStream *stream = _vm->_res->load(name, "MUSIC.LIB");
+
+ byte *data = new byte[stream->size()];
+ int32 dataSize = stream->size();
+ assert(data);
+
+ stream->read(data, dataSize);
+ 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 (dataSize < 14) {
+ warning("not enough data in music file");
+ return false;
+ }
+
+ byte *dataPos = data;
+ if (memcmp(" ", dataPos, 12)) {
+ warning("Expected header not found in music file");
+ return false;
+ }
+ dataPos += 12;
+ dataSize -= 12;
+
+ uint16 headerSize = READ_LE_UINT16(dataPos);
+ if (headerSize != 0x7F) {
+ warning("music header is not as expected");
+ return false;
+ }
+
+ if (_musicType == MT_ADLIB) {
+ if (_driver)
+ MidiDriver_AdLib_newMusicData(_driver, dataPos, dataSize);
+ }
+
+ _midiParser.loadMusic(dataPos, dataSize);
+ return true;
+}
+
+void Music::stopMusic() {
+ // TODO
+ warning("TODO: Sound::stopMusic");
+
+ _musicPlaying = false;
+}
+
+void Music::startSong() {
+ if (!_musicOn)
+ return;
+
+ // TODO
+ warning("TODO: Sound::startSong");
+ _musicPlaying = true;
+}
+
+void Music::freeSong() {
+ // TODO
+ warning("TODO: Sound::freeSong");
+}
+
+void Music::waitTimerRoland(uint time) {
+ // TODO
+ warning("TODO: Sound::waitTimerRoland");
+}} // End of namespace Sherlock
+
diff --git a/engines/sherlock/music.h b/engines/sherlock/music.h
new file mode 100644
index 0000000000..0ebc3e94e2
--- /dev/null
+++ b/engines/sherlock/music.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_MUSIC_H
+#define SHERLOCK_MUSIC_H
+
+#include "audio/midiplayer.h"
+#include "audio/midiparser.h"
+//#include "audio/mididrv.h"
+#include "sherlock/scalpel/drivers/mididriver.h"
+
+namespace Sherlock {
+
+class SherlockEngine;
+
+class MidiParser_SH : public MidiParser {
+protected:
+ virtual void parseNextEvent(EventInfo &info);
+
+ uint8 _beats;
+ uint8 _lastEvent;
+ byte *_data;
+ byte *_trackEnd;
+public:
+ MidiParser_SH();
+ virtual bool loadMusic(byte *data, uint32 size);
+};
+
+class Music {
+private:
+ SherlockEngine *_vm;
+ Audio::Mixer *_mixer;
+ MidiParser_SH _midiParser;
+ MidiDriver *_driver;
+
+public:
+ bool _musicPlaying;
+ bool _musicOn;
+
+private:
+ MusicType _musicType;
+
+public:
+ Music(SherlockEngine *vm, Audio::Mixer *mixer);
+
+ /**
+ * 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();
+
+ /**
+ * Play the specified music resource
+ */
+ bool playMusic(const Common::String &name);
+
+ /**
+ * Stop playing the music
+ */
+ void stopMusic();
+
+ void waitTimerRoland(uint time);
+};
+
+} // End of namespace Sherlock
+
+#endif
+
diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp
new file mode 100644
index 0000000000..8818f805a5
--- /dev/null
+++ b/engines/sherlock/objects.cpp
@@ -0,0 +1,1166 @@
+/* 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/objects.h"
+#include "sherlock/sherlock.h"
+#include "sherlock/people.h"
+#include "sherlock/scene.h"
+#include "common/util.h"
+
+namespace Sherlock {
+
+#define START_FRAME 0
+
+#define UPPER_LIMIT 0
+#define LOWER_LIMIT CONTROLS_Y
+#define LEFT_LIMIT 0
+#define RIGHT_LIMIT SHERLOCK_SCREEN_WIDTH
+
+// Distance to walk around WALK_AROUND boxes
+#define CLEAR_DIST_X 5
+#define CLEAR_DIST_Y 0
+
+SherlockEngine *Sprite::_vm;
+
+void Sprite::clear() {
+ _name = "";
+ _description = "";
+ _examine.clear();
+ _pickUp = "";
+ _walkSequences.clear();
+ _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;
+ _numFrames = 0;
+ _altImages = nullptr;
+ _altSequences = false;
+ 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 > _numFrames)
+ imageNumber = 1;
+
+ // Get the images to use
+ ImageFile *images = _altSequences ? _altImages : _images;
+ assert(images);
+
+ // Set the frame pointer
+ _imageFrame = &(*images)[imageNumber];
+}
+
+void Sprite::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._walkTo.empty()) {
+ people._walkDest = people._walkTo.pop();
+ people.setWalking();
+ } else {
+ people.gotoStand(*this);
+ }
+ }
+ }
+
+ if (_type == CHARACTER && !map._active) {
+ if ((_position.y / 100) > LOWER_LIMIT) {
+ _position.y = LOWER_LIMIT * 100;
+ people.gotoStand(*this);
+ }
+
+ if ((_position.y / 100) < UPPER_LIMIT) {
+ _position.y = UPPER_LIMIT * 100;
+ people.gotoStand(*this);
+ }
+
+ if ((_position.x / 100) < LEFT_LIMIT) {
+ _position.x = LEFT_LIMIT * 100;
+ people.gotoStand(*this);
+ }
+ } 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 (_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 / 100 - 5, _position.y / 100 - 2,
+ _position.x / 100 + 5, _position.y / 100 + 2);
+ Exit *exit = scene.checkForExit(charRect);
+
+ if (exit) {
+ scene._goToScene = exit->_scene;
+
+ if (exit->_people.x != 0) {
+ people._hSavedPos = exit->_people;
+ people._hSavedFacing = exit->_peopleDir;
+
+ if (people._hSavedFacing > 100 && people._hSavedPos.x < 1)
+ people._hSavedPos.x = 100;
+ }
+ }
+ }
+}
+
+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 / 100, _position.y / 100);
+
+ if (!talk._talkCounter && _type == CHARACTER) {
+ pt = _walkCount ? _position + _delta : _position;
+ pt.x /= 100;
+ pt.y /= 100;
+
+ 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 {
+ people.gotoStand(*this);
+ }
+ break;
+
+ case TALK_EVERY:
+ if (obj._aType == TALK_EVERY) {
+ obj._type = HIDDEN;
+ obj.setFlagsAndToggles();
+ talk.talkTo(obj._use[0]._target);
+ } else {
+ people.gotoStand(*this);
+ }
+ break;
+
+ case FLAG_SET:
+ obj.setFlagsAndToggles();
+ obj._type = HIDDEN;
+ break;
+
+ case WALK_AROUND:
+ if (objBounds.contains(people._walkTo.front())) {
+ // Reached zone
+ people.gotoStand(*this);
+ } 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[AL]._imageFrame->_frame.w / 2;
+ people._walkDest = walkPos;
+ people._walkTo.push(walkPos);
+ people.setWalking();
+ }
+ break;
+
+ case DELTA:
+ _position.x += 200;
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+/*----------------------------------------------------------------*/
+
+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.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;
+}
+
+/*----------------------------------------------------------------*/
+
+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() {
+ _cAnimNum = _cAnimSpeed = 0;
+ _useFlag = 0;
+}
+
+void UseType::load(Common::SeekableReadStream &s, bool isRoseTattoo) {
+ char buffer[12];
+
+ if (isRoseTattoo) {
+ s.read(buffer, 12);
+ _verb = Common::String(buffer);
+ }
+
+ _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.readSint16LE();
+
+ if (!isRoseTattoo)
+ s.skip(6);
+
+ s.read(buffer, 12);
+ _target = Common::String(buffer);
+}
+
+/*----------------------------------------------------------------*/
+
+SherlockEngine *Object::_vm;
+bool Object::_countCAnimFrames;
+
+void Object::setVm(SherlockEngine *vm) {
+ _vm = vm;
+ _countCAnimFrames = false;
+}
+
+Object::Object() {
+ _sequenceOffset = 0;
+ _sequences = nullptr;
+ _images = nullptr;
+ _imageFrame = nullptr;
+ _walkCount = 0;
+ _allow = 0;
+ _frameNumber = 0;
+ _sequenceNumber = 0;
+ _type = INVALID;
+ _pickup = 0;
+ _defaultCommand = 0;
+ _lookFlag = 0;
+ _pickupFlag = 0;
+ _requiredFlag = 0;
+ _status = 0;
+ _misc = 0;
+ _maxFrames = 0;
+ _flags = 0;
+ _aOpen._cAnimNum = 0;
+ _aOpen._cAnimSpeed = 0;
+ _aType = OBJECT;
+ _lookFrames = 0;
+ _seqCounter = 0;
+ _lookFacing = 0;
+ _lookcAnim = 0;
+ _seqStack = 0;
+ _seqTo = 0;
+ _descOffset = 0;
+ _seqCounter2 = 0;
+ _seqSize = 0;
+
+ _quickDraw = 0;
+ _scaleVal = 0;
+ _requiredFlag1 = 0;
+ _gotoSeq = 0;
+ _talkSeq = 0;
+ _restoreSlot = 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();
+
+ _pickup = isRoseTattoo ? 0 : s.readByte();
+ _defaultCommand = isRoseTattoo ? 0 : s.readByte();
+ _lookFlag = s.readSint16LE();
+ _pickupFlag = isRoseTattoo ? 0 : s.readSint16LE();
+ _requiredFlag = 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();
+ _lookPosition.x = s.readUint16LE();
+ _lookPosition.y = isRoseTattoo ? s.readSint16LE() : s.readByte();
+ _lookFacing = 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();
+ _requiredFlag1 = 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);
+ }
+}
+
+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::checkObject() {
+ Scene &scene = *_vm->_scene;
+ Sound &sound = *_vm->_sound;
+ int checkFrame = _allow ? MAX_FRAME : FRAMES_END;
+ bool codeFound;
+
+ if (_seqTo) {
+ byte *ptr = &_sequences[_frameNumber];
+ if (*ptr == _seqTo) {
+ // The sequence is completed
+ *ptr = _seqTo + SEQ_TO_CODE + 128; // Reset to normal
+ _seqTo = 0;
+ } else {
+ // Continue doing sequence
+ if (*ptr > _seqTo)
+ *ptr -= 1;
+ else
+ *ptr += 1;
+
+ return;
+ }
+ }
+
+ ++_frameNumber;
+
+ do {
+ // Check for end of sequence
+ codeFound = checkEndOfSequence();
+
+ if (_sequences[_frameNumber] >= 128 && _frameNumber < checkFrame) {
+ codeFound = true;
+ int v = _sequences[_frameNumber];
+
+ if (v >= 228) {
+ // Goto code found
+ v -= 228;
+ _seqCounter2 = _seqCounter;
+ _seqStack = _frameNumber + 1;
+ setObjSequence(v, false);
+ } else if (v >= SOUND_CODE && (v < (SOUND_CODE + 30))) {
+ codeFound = true;
+ ++_frameNumber;
+ v -= SOUND_CODE;
+
+ if (sound._soundOn && !_countCAnimFrames) {
+ if (!scene._sounds[v - 1]._name.empty() && sound._digitized)
+ sound.playLoadedSound(v - 1, 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 {
+ v -= 128;
+
+ // 68-99 is a squence code
+ if (v > SEQ_TO_CODE) {
+ 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 (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], nullptr);
+ }
+
+ if (_use[v]._useFlag)
+ _vm->setFlags(_use[v]._useFlag);
+ }
+
+ ++_frameNumber;
+ }
+ }
+ } while (codeFound);
+}
+
+bool Object::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 {
+ 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 Object::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 Object::checkNameForCodes(const Common::String &name, const char *const messages[]) {
+ Map &map = *_vm->_map;
+ 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;
+ }
+
+ default:
+ if (ch >= '0' && ch <= '9') {
+ scene._goToScene = atoi(name.c_str() + 1);
+
+ if (scene._goToScene < 97 && map[scene._goToScene].x) {
+ map._overPos.x = map[scene._goToScene].x * 100 - 600;
+ map._overPos.y = map[scene._goToScene].y * 100 + 900;
+ }
+
+ const char *p;
+ if ((p = strchr(name.c_str(), ',')) != nullptr) {
+ ++p;
+
+ Common::String s(p, p + 3);
+ people._hSavedPos.x = atoi(s.c_str());
+
+ s = Common::String(p + 3, p + 6);
+ people._hSavedPos.y = atoi(s.c_str());
+
+ s = Common::String(p + 6, p + 9);
+ people._hSavedFacing = atoi(s.c_str());
+ if (people._hSavedFacing == 0)
+ people._hSavedFacing = 10;
+ } else if ((p = strchr(name.c_str(), '/')) != nullptr) {
+ people._hSavedPos = Common::Point(1, 0);
+ people._hSavedFacing = 100 + atoi(p + 1);
+ }
+ } else {
+ scene._goToScene = 100;
+ }
+
+ people[AL]._position = Common::Point(0, 0);
+ break;
+ }
+ } else if (name.hasPrefix("!")) {
+ // Message attached to canimation
+ int messageNum = atoi(name.c_str() + 1);
+ ui._infoFlag = true;
+ ui.clearInfo();
+ screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", messages[messageNum]);
+ ui._menuCounter = 25;
+ } else if (name.hasPrefix("@")) {
+ // Message attached to canimation
+ ui._infoFlag = true;
+ ui.clearInfo();
+ screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", name.c_str() + 1);
+ printed = true;
+ ui._menuCounter = 25;
+ }
+
+ return printed;
+}
+
+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;
+
+ _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(const char *const messages[]) {
+ 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], nullptr)) {
+ 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();
+ screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", messages[message]);
+ 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.goAllTheWay();
+ ui._menuCounter = 25;
+ ui._temp1 = 1;
+ }
+
+ for (int idx = 0; idx < NAMES_COUNT && !talk._talkToAbort; ++idx) {
+ if (checkNameForCodes(_use[0]._names[idx], nullptr)) {
+ 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), INFO_FOREGROUND, "Picked up %s", itemName.c_str());
+ ui._menuCounter = 25;
+ }
+ }
+
+ return numObjects;
+}
+
+const Common::Rect Object::getNewBounds() const {
+ Common::Point 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) {
+ char buffer[12];
+ s.read(buffer, 12);
+ _name = Common::String(buffer);
+
+ if (isRoseTattoo) {
+ Common::fill(&_sequences[0], &_sequences[30], 0);
+ _size = s.readUint32LE();
+ } else {
+ s.read(_sequences, 30);
+ }
+
+ _position.x = s.readSint16LE();
+ _position.y = s.readSint16LE();
+
+ if (isRoseTattoo) {
+ _flags = s.readByte();
+ _scaleVal = s.readSint16LE();
+ } else {
+ _size = s.readUint32LE();
+ _type = (SpriteType)s.readUint16LE();
+ _flags = s.readByte();
+ }
+
+ _goto.x = s.readSint16LE();
+ _goto.y = s.readSint16LE();
+ _gotoDir = s.readSint16LE();
+ _teleportPos.x = s.readSint16LE();
+ _teleportPos.y = s.readSint16LE();
+ _teleportDir = s.readSint16LE();
+}
+
+/*----------------------------------------------------------------*/
+
+CAnimStream::CAnimStream() {
+ _stream = nullptr;
+ _frameSize = 0;
+ _images = nullptr;
+ _imageFrame = nullptr;
+ _flags = 0;
+ _scaleVal = 0;
+ _zPlacement = 0;
+}
+
+void CAnimStream::getNextFrame() {
+ // TODO
+}
+
+/*----------------------------------------------------------------*/
+
+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..d671066a23
--- /dev/null
+++ b/engines/sherlock/objects.h
@@ -0,0 +1,446 @@
+/* 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/resources.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 100
+
+// 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)
+
+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; }
+};
+
+
+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];
+
+ /**
+ * Load the data for the action
+ */
+ void load(Common::SeekableReadStream &s);
+};
+
+struct UseType {
+ int _cAnimNum;
+ int _cAnimSpeed;
+ Common::String _names[NAMES_COUNT];
+ int _useFlag; // Which flag USE will set (if any)
+ Common::String _target;
+ Common::String _verb;
+
+ UseType();
+
+ /**
+ * Load the data for the UseType
+ */
+ void load(Common::SeekableReadStream &s, bool isRoseTattoo);
+};
+
+
+class Sprite {
+private:
+ static SherlockEngine *_vm;
+public:
+ Common::String _name;
+ Common::String _description;
+ Common::String _examine; // Examine in-depth description
+ Common::String _pickUp; // Message for if you can't pick up object
+
+ WalkSequences _walkSequences; // Holds animation sequences
+ ImageFile *_images; // Sprite images
+ ImageFrame *_imageFrame; // Pointer to shape in the images
+ int _walkCount; // Character walk counter
+ int _allow; // Allowed menu commands - ObjectAllow
+ int _frameNumber; // Frame number in rame sequence to draw
+ int _sequenceNumber; // Sequence being used
+ Point32 _position; // Current position
+ Point32 _delta; // Momvement delta
+ Common::Point _oldPosition; // Old position
+ Common::Point _oldSize; // Image's old size
+ Common::Point _goto; // Walk destination
+ SpriteType _type; // Type of object
+ Common::Point _noShapeSize; // Size of a NO_SHAPE
+ int _status; // Status: open/closed, moved/not moved
+ int8 _misc; // Miscellaneous use
+ int _numFrames; // How many frames the object has
+
+ // Rose Tattoo fields
+ int _startSeq; // Frame sequence starts at
+ int _flags; // Flags for the sprite
+ int _aType; // Tells if this is an object, person, talk, etc.
+ int _lookFrames; // How many frames to play of a canim before pausing
+ int _seqCounter; // How many times the sequence has been run
+ Common::Point _lookPosition; // Where to look when examining object
+ int _lookFacing; // Direction to face when examining object
+ int _lookCAnim;
+ int _seqStack; // Allow 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 description text for scene
+ int _seqCounter2; // Counter of calling frame sequence
+ uint _seqSize; // Size of sequence
+ UseType _use[6];
+ int _quickDraw; // Flag telling whether to use quick draw routine or not
+ int _scaleVal; // Tells how to scale the sprite
+ int _requiredFlags1; // This flag must also be set, or the sprite is hidden
+ 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
+
+ ImageFrame *_stopFrames[8]; // Stop/rest frame for each direction
+ ImageFile *_altImages; // Images used for alternate NPC sequences
+ bool _altSequences; // 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() { clear(); }
+
+ 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();
+
+ /**
+ * This adjusts the sprites position, as well as it's animation sequence:
+ */
+ void adjustSprite();
+
+ /**
+ * Checks the sprite's position to see if it's collided with any special objects
+ */
+ void checkSprite();
+
+ /**
+ * Return frame width
+ */
+ int frameWidth() const { return _imageFrame ? _imageFrame->_frame.w : 0; }
+
+ /**
+ * Return frame height
+ */
+ int frameHeight() const { return _imageFrame ? _imageFrame->_frame.h : 0; }
+};
+
+enum { OBJ_BEHIND = 1, OBJ_FLIPPED = 2, OBJ_FORWARD = 4, TURNON_OBJ = 0x20, TURNOFF_OBJ = 0x40 };
+#define USE_COUNT 4
+
+class Object {
+private:
+ static SherlockEngine *_vm;
+
+ /**
+ * 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;
+
+ static void setVm(SherlockEngine *vm);
+public:
+ Common::String _name; // Name
+ Common::String _description; // Description lines
+ Common::String _examine; // Examine in-depth description
+ int _sequenceOffset;
+ uint8 *_sequences; // Holds animation sequences
+ ImageFile *_images; // Sprite images
+ ImageFrame *_imageFrame; // Pointer to shape in the images
+ int _walkCount; // Character walk counter
+ int _allow; // Allowed menu commands - ObjectAllow
+ int _frameNumber; // Frame number in rame sequence to draw
+ int _sequenceNumber; // Sequence being used
+ SpriteType _type; // Object type
+ Common::Point _position; // Current position
+ Common::Point _delta; // Momvement amount
+ Common::Point _oldPosition; // Old position
+ Common::Point _oldSize; // Image's old size
+ Common::Point _goto; // Walk destination
+
+ int _pickup;
+ int _defaultCommand; // Default right-click command
+ int _lookFlag; // Which flag LOOK will set (if any)
+ int _requiredFlag; // 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
+ Common::Point _lookPosition; // Where to walk when examining object
+ int _lookFacing; // Direction to face 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
+
+ // Serrated Scalpel fields
+ int _pickupFlag; // Which flag PICKUP will set (if any)
+ ActionType _aOpen; // Holds data for moving object
+ ActionType _aClose;
+ ActionType _aMove;
+
+ // Rose Tattoo fields
+ int _quickDraw;
+ int _scaleVal;
+ int _requiredFlag1;
+ int _gotoSeq;
+ int _talkSeq;
+ int _restoreSlot;
+
+ Object();
+
+ /**
+ * Load the data for the object
+ */
+ void load(Common::SeekableReadStream &s, bool isRoseTattoo);
+
+ /**
+ * Toggle the type of an object between hidden and active
+ */
+ void toggleHidden();
+
+ /**
+ * 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, const char *const messages[]);
+
+ /**
+ * 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(const char *const messages[]);
+
+ /**
+ * 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;
+};
+
+struct CAnim {
+ Common::String _name; // Name
+ Common::Point _position; // Position
+ int _size; // Size of uncompressed animation
+ int _flags; // Tells if can be walked behind
+ Common::Point _goto; // coords holmes should walk to before starting canim
+ int _gotoDir;
+ Common::Point _teleportPos; // Location Holmes shoul teleport to after
+ int _teleportDir; // 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);
+};
+
+struct CAnimStream {
+ Common::SeekableReadStream *_stream; // Stream to read frames from
+ int _frameSize; // Temporary used to store the frame size
+
+ void *_images; // TOOD: FIgure out hwo to hook up ImageFile with streaming support
+ 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
+
+ CAnimStream();
+
+ void getNextFrame();
+};
+
+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..0ef49ffefb
--- /dev/null
+++ b/engines/sherlock/people.cpp
@@ -0,0 +1,712 @@
+/* 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"
+
+namespace Sherlock {
+
+// Walk speeds
+#define MWALK_SPEED 2
+#define XWALK_SPEED 4
+#define YWALK_SPEED 1
+
+// 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
+#define NUM_IN_WALK_LIB 10
+const char *const WALK_LIB_NAMES[10] = {
+ "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), _npcIndex(0), _npcStack(0), _npcPause(false) {
+ Common::fill(&_npcPath[0], &_npcPath[MAX_NPC_PATH], 0);
+ _tempX = _tempScaleVal = 0;
+}
+
+void Person::clearNPC() {
+ Common::fill(&_npcPath[0], &_npcPath[MAX_NPC_PATH], 0);
+ _npcIndex = _npcStack = 0;
+ _npcName = "";
+}
+
+/*----------------------------------------------------------------*/
+
+People::People(SherlockEngine *vm) : _vm(vm), _player(_data[0]) {
+ _holmesOn = true;
+ _oldWalkSequence = -1;
+ _allowWalkAbort = false;
+ _portraitLoaded = false;
+ _portraitsOn = true;
+ _clearingThePortrait = false;
+ _srcZone = _destZone = 0;
+ _talkPics = nullptr;
+ _portraitSide = 0;
+ _speakerFlip = false;
+ _holmesFlip = false;
+ _holmesQuotient = 0;
+ _hSavedPos = Common::Point(-1, -1);
+ _hSavedFacing = -1;
+ _forceWalkReload = false;
+ _useWalkLib = false;
+ _walkControl = 0;
+
+ _portrait._sequences = new byte[32];
+}
+
+People::~People() {
+ for (int idx = 0; idx < MAX_CHARACTERS; ++idx) {
+ if (_data[idx]._walkLoaded)
+ delete _data[PLAYER]._images;
+ }
+
+ delete _talkPics;
+ delete[] _portrait._sequences;
+}
+
+void People::reset() {
+ _data[0]._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) {
+ Sprite &p = _data[idx];
+
+ p._type = (idx == 0) ? CHARACTER : INVALID;
+ if (IS_SERRATED_SCALPEL)
+ p._position = Point32(10000, 11000);
+ else
+ p._position = Point32(36000, 29000);
+
+ p._sequenceNumber = STOP_DOWNRIGHT;
+ p._imageFrame = nullptr;
+ p._frameNumber = 1;
+ p._delta = Common::Point(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._altSequences = 0;
+ p._centerWalk = true;
+ p._adjust = Common::Point(0, 0);
+
+ // Load the default walk sequences
+ 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++);
+ }
+ }
+ }
+
+ // Reset any walk path in progress when Sherlock leaves scenes
+ _walkTo.clear();
+}
+
+bool People::loadWalk() {
+ Resources &res = *_vm->_res;
+ bool result = false;
+
+ if (IS_SERRATED_SCALPEL) {
+ if (_data[PLAYER]._walkLoaded) {
+ return false;
+ } else {
+ _data[PLAYER]._images = new ImageFile("walk.vgs");
+ _data[PLAYER].setImageFrame();
+ _data[PLAYER]._walkLoaded = true;
+
+ result = true;
+ }
+ } else {
+ for (int idx = 0; idx < MAX_CHARACTERS; ++idx) {
+ if (!_data[idx]._walkLoaded && (_data[idx]._type == CHARACTER || _data[idx]._type == HIDDEN_CHARACTER)) {
+ if (_data[idx]._type == HIDDEN_CHARACTER)
+ _data[idx]._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 (!_data[0]._walkVGSName.compareToIgnoreCase(WALK_LIB_NAMES[libNum])) {
+ _useWalkLib = true;
+ break;
+ }
+ }
+
+ // Load the images for the character
+ _data[idx]._images = new ImageFile(_data[idx]._walkVGSName, false);
+ _data[idx]._numFrames = _data[idx]._images->size();
+
+ // Load walk sequence data
+ Common::String fname = Common::String(_data[idx]._walkVGSName.c_str(), strchr(_data[idx]._walkVGSName.c_str(), '.'));
+ fname += ".SEQ";
+
+ // Load the walk sequence data
+ Common::SeekableReadStream *stream = res.load(fname, _useWalkLib ? "walk.lib" : "vgs.lib");
+
+ _data[idx]._walkSequences.resize(stream->readByte());
+
+ for (uint seqNum = 0; seqNum < _data[idx]._walkSequences.size(); ++seqNum)
+ _data[idx]._walkSequences[seqNum].load(*stream);
+
+ // Close the sequences resource
+ delete stream;
+ _useWalkLib = false;
+
+ _data[idx]._frameNumber = 0;
+ _data[idx].setImageFrame();
+
+ // Set the stop Frames pointers
+ for (int dirNum = 0; dirNum < 8; ++dirNum) {
+ int count = 0;
+ while (_data[idx]._walkSequences[dirNum + 8][count] != 0)
+ ++count;
+ count += 2;
+ count = _data[idx]._walkSequences[dirNum + 8][count] - 1;
+ _data[idx]._stopFrames[dirNum] = &(*_data[idx]._images)[count];
+ }
+
+ result = true;
+ _data[idx]._walkLoaded = true;
+ } else if (_data[idx]._type != CHARACTER) {
+ _data[idx]._walkLoaded = false;
+ }
+ }
+ }
+
+ _forceWalkReload = false;
+ return result;
+}
+
+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;
+}
+
+void People::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
+ _player._walkCount = 0;
+ oldDirection = _player._sequenceNumber;
+ oldFrame = _player._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 = _player._imageFrame->_frame.w / 2))
+ _walkDest.x -= temp;
+
+ delta = Common::Point(
+ ABS(_player._position.x / 100 - _walkDest.x),
+ ABS(_player._position.y / 100 - _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 < (_player._position.x / 100)) {
+ _player._sequenceNumber = (map._active ? (int)MAP_LEFT : (int)WALK_LEFT);
+ _player._delta.x = speed.x * -100;
+ } else {
+ _player._sequenceNumber = (map._active ? (int)MAP_RIGHT : (int)WALK_RIGHT);
+ _player._delta.x = speed.x * 100;
+ }
+
+ // 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
+ _player._delta.y = (delta.y * 100) / (delta.x / speed.x);
+ if (_walkDest.y < (_player._position.y / 100))
+ _player._delta.y = -_player._delta.y;
+
+ // Set how many times we should add the delta to the player's position
+ _player._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
+ _player._delta = Common::Point(0, 0);
+ _player._position = Common::Point(_walkDest.x * 100, _walkDest.y * 100);
+ _player._walkCount = 1;
+ }
+
+ // See if the sequence needs to be changed for diagonal walking
+ if (_player._delta.y > 150) {
+ if (!map._active) {
+ switch (_player._sequenceNumber) {
+ case WALK_LEFT:
+ _player._sequenceNumber = WALK_DOWNLEFT;
+ break;
+ case WALK_RIGHT:
+ _player._sequenceNumber = WALK_DOWNRIGHT;
+ break;
+ }
+ }
+ } else if (_player._delta.y < -150) {
+ if (!map._active) {
+ switch (_player._sequenceNumber) {
+ case WALK_LEFT:
+ _player._sequenceNumber = WALK_UPLEFT;
+ break;
+ case WALK_RIGHT:
+ _player._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 < (_player._position.y / 100)) {
+ _player._sequenceNumber = WALK_UP;
+ _player._delta.y = speed.y * -100;
+ } else {
+ _player._sequenceNumber = WALK_DOWN;
+ _player._delta.y = speed.y * 100;
+ }
+
+ // If we're on the overhead map, set the sequence so we keep moving
+ // in the same direction
+ if (map._active)
+ _player._sequenceNumber = (oldDirection == -1) ? MAP_RIGHT : oldDirection;
+
+ // Set the delta x
+ _player._delta.x = (delta.x * 100) / (delta.y / speed.y);
+ if (_walkDest.x < (_player._position.x / 100))
+ _player._delta.x = -_player._delta.x;
+
+ _player._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 (_player._sequenceNumber != _oldWalkSequence)
+ _player._frameNumber = 0;
+ _oldWalkSequence = _player._sequenceNumber;
+
+ if (!_player._walkCount)
+ gotoStand(_player);
+
+ // 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 (_player._sequenceNumber == oldDirection)
+ _player._frameNumber = oldFrame;
+}
+
+void People::gotoStand(Sprite &sprite) {
+ Map &map = *_vm->_map;
+ _walkTo.clear();
+ sprite._walkCount = 0;
+
+ switch (sprite._sequenceNumber) {
+ case WALK_UP:
+ sprite._sequenceNumber = STOP_UP;
+ break;
+ case WALK_DOWN:
+ sprite._sequenceNumber = STOP_DOWN;
+ break;
+ case TALK_LEFT:
+ case WALK_LEFT:
+ sprite._sequenceNumber = STOP_LEFT;
+ break;
+ case TALK_RIGHT:
+ case WALK_RIGHT:
+ sprite._sequenceNumber = STOP_RIGHT;
+ break;
+ case WALK_UPRIGHT:
+ sprite._sequenceNumber = STOP_UPRIGHT;
+ break;
+ case WALK_UPLEFT:
+ sprite._sequenceNumber = STOP_UPLEFT;
+ break;
+ case WALK_DOWNRIGHT:
+ sprite._sequenceNumber = STOP_DOWNRIGHT;
+ break;
+ case WALK_DOWNLEFT:
+ sprite._sequenceNumber = STOP_DOWNLEFT;
+ break;
+ default:
+ break;
+ }
+
+ // Only restart frame at 0 if the sequence number has changed
+ if (_oldWalkSequence != -1 || sprite._sequenceNumber == STOP_UP)
+ sprite._frameNumber = 0;
+
+ if (map._active) {
+ sprite._sequenceNumber = 0;
+ _player._position.x = (map[map._charPoint].x - 6) * 100;
+ _player._position.y = (map[map._charPoint].x + 10) * 100;
+ }
+
+ _oldWalkSequence = -1;
+ _allowWalkAbort = true;
+}
+
+void People::walkToCoords(const Common::Point &destPos, int destDir) {
+ Events &events = *_vm->_events;
+ Scene &scene = *_vm->_scene;
+ Talk &talk = *_vm->_talk;
+
+ CursorId oldCursor = events.getCursor();
+ events.setCursor(WAIT);
+
+ _walkDest = Common::Point(destPos.x / 100 + 10, destPos.y / 100);
+ _allowWalkAbort = true;
+ goAllTheWay();
+
+ // Keep calling doBgAnim until the walk is done
+ do {
+ events.pollEventsAndWait();
+ scene.doBgAnim();
+ } while (!_vm->shouldQuit() && _player._walkCount);
+
+ if (!talk._talkToAbort) {
+ // Put player exactly on destination position, and set direction
+ _player._position = destPos;
+ _player._sequenceNumber = destDir;
+ gotoStand(_player);
+
+ // Draw Holmes facing the new direction
+ scene.doBgAnim();
+
+ if (!talk._talkToAbort)
+ events.setCursor(oldCursor);
+ }
+}
+
+void People::goAllTheWay() {
+ Scene &scene = *_vm->_scene;
+ Common::Point srcPt(_player._position.x / 100 + _player.frameWidth() / 2,
+ _player._position.y / 100);
+
+ // 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);
+
+ // 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[_destZone];
+ const Common::Point destCenter((destRect.left + destRect.right) / 2,
+ (destRect.top + destRect.bottom) / 2);
+ const Common::Point delta = _walkDest - destCenter;
+ Common::Point pt(destCenter.x * 100, destCenter.y * 100);
+
+ // Move along the line until the zone is left
+ do {
+ pt += delta;
+ } while (destRect.contains(pt.x / 100, pt.y / 100));
+
+ // Set the new walk destination to the last point that was in the
+ // zone just before it was left
+ _walkDest = Common::Point((pt.x - delta.x * 2) / 100,
+ (pt.y - delta.y * 2) / 100);
+ }
+
+ // 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];
+
+ int count = scene._walkData[i];
+ ++i;
+
+ // See how many points there are between the src and dest zones
+ if (!count || count == -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) {
+ i += 3 * (count - 1);
+ for (int idx = 0; idx < count; ++idx, i -= 3) {
+ _walkTo.push(Common::Point(READ_LE_UINT16(&scene._walkData[i]),
+ scene._walkData[i + 2]));
+ }
+ } else {
+ for (int idx = 0; idx < count; ++idx, i += 3) {
+ _walkTo.push(Common::Point(READ_LE_UINT16(&scene._walkData[i]), scene._walkData[i + 2]));
+ }
+ }
+
+ // Final position
+ _walkTo.push(_walkDest);
+
+ // Start walking
+ _walkDest = _walkTo.pop();
+ setWalking();
+ }
+ }
+}
+
+int People::findSpeaker(int speaker) {
+ Scene &scene = *_vm->_scene;
+
+ 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(_characters[speaker]._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::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 People::synchronize(Common::Serializer &s) {
+ s.syncAsByte(_holmesOn);
+
+ if (IS_SERRATED_SCALPEL) {
+ s.syncAsSint16LE(_player._position.x);
+ s.syncAsSint16LE(_player._position.y);
+ s.syncAsSint16LE(_player._sequenceNumber);
+ } else {
+ for (int idx = 0; idx < MAX_CHARACTERS; ++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()) {
+ _hSavedPos = _player._position;
+ _hSavedFacing = _player._sequenceNumber;
+ }
+}
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h
new file mode 100644
index 0000000000..013727d8ba
--- /dev/null
+++ b/engines/sherlock/people.h
@@ -0,0 +1,197 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SHERLOCK_PEOPLE_H
+#define SHERLOCK_PEOPLE_H
+
+#include "common/scummsys.h"
+#include "common/serializer.h"
+#include "common/queue.h"
+#include "sherlock/objects.h"
+
+namespace Sherlock {
+
+enum PeopleId {
+ PLAYER = 0,
+ AL = 0,
+ PEG = 1,
+ MAX_CHARACTERS = 6,
+ MAX_NPC = 5,
+ MAX_NPC_PATH = 200
+};
+
+// Animation sequence identifiers for characters
+enum {
+ 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
+};
+
+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
+};
+
+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 {
+public:
+ bool _walkLoaded;
+ Common::String _portrait;
+
+ // NPC related fields
+ int _npcIndex;
+ int _npcStack;
+ bool _npcPause;
+ byte _npcPath[MAX_NPC_PATH];
+ Common::String _npcName;
+ int _tempX;
+ int _tempScaleVal;
+
+ // Rose Tattoo fields
+ Common::String _walkVGSName; // Name of walk library person is using
+public:
+ Person();
+
+ /**
+ * Clear the NPC related data
+ */
+ void clearNPC();
+};
+
+class SherlockEngine;
+
+class People {
+private:
+ SherlockEngine *_vm;
+ Person _data[MAX_CHARACTERS];
+ int _oldWalkSequence;
+ int _srcZone, _destZone;
+public:
+ Common::Array<PersonData> _characters;
+ ImageFile *_talkPics;
+ Common::Point _walkDest;
+ Common::Point _hSavedPos;
+ int _hSavedFacing;
+ Common::Queue<Common::Point> _walkTo;
+ Person &_player;
+ 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:
+ People(SherlockEngine *vm);
+ ~People();
+
+ Person &operator[](PeopleId id) {
+ assert(id < MAX_CHARACTERS);
+ return _data[id];
+ }
+ Person &operator[](int idx) {
+ assert(idx < MAX_CHARACTERS);
+ return _data[idx];
+ }
+
+ /**
+ * Reset the player data
+ */
+ void reset();
+
+ /**
+ * Load the walking images for Sherlock
+ */
+ bool loadWalk();
+
+ /**
+ * If the walk data has been loaded, then it will be freed
+ */
+ bool freeWalk();
+
+ /**
+ * Set the variables for moving a character from one poisition to another
+ * in a straight line - goAllTheWay must have been previously called to
+ * check for any obstacles in the path.
+ */
+ void setWalking();
+
+ /**
+ * Bring a moving character to a standing position. If the Scalpel chessboard
+ * is being displayed, then the chraracter will always face down.
+ */
+ void gotoStand(Sprite &sprite);
+
+ /**
+ * Walk to the co-ordinates passed, and then face the given direction
+ */
+ void walkToCoords(const Common::Point &destPos, int destDir);
+
+ /**
+ * 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();
+
+ /**
+ * Finds the scene background object corresponding to a specified speaker
+ */
+ int findSpeaker(int speaker);
+
+ /**
+ * Turn off any currently active portraits, and removes them from being drawn
+ */
+ void clearTalking();
+
+ /**
+ * Setup the data for an animating speaker portrait at the top of the screen
+ */
+ void setTalking(int speaker);
+
+ /**
+ * Synchronize the data for a savegame
+ */
+ void synchronize(Common::Serializer &s);
+};
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp
new file mode 100644
index 0000000000..2e6a0c2d7c
--- /dev/null
+++ b/engines/sherlock/resources.cpp
@@ -0,0 +1,499 @@
+/* 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) {
+ addToCache("vgs.lib");
+ addToCache("talk.lib");
+ addToCache("journal.txt");
+
+ if (IS_SERRATED_SCALPEL) {
+ addToCache("sequence.txt");
+ addToCache("portrait.lib");
+ }
+ }
+}
+
+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 = 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);
+ }
+}
+
+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(_vm->getGameID() == GType_SerratedScalpel);
+
+ 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 = (_vm->getGameID() == GType_RoseTattoo) ? 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 = (_vm->getGameID() == GType_RoseTattoo) ? 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));
+}
+
+/*----------------------------------------------------------------*/
+
+SherlockEngine *ImageFile::_vm;
+
+void ImageFile::setVm(SherlockEngine *vm) {
+ _vm = vm;
+}
+
+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];
+ stream.read(data, frame._size);
+ decompressFrame(frame, data);
+ delete[] data;
+
+ push_back(frame);
+ }
+}
+
+void ImageFile::loadPalette(Common::SeekableReadStream &stream) {
+ // Check for palette
+ int v1 = stream.readUint16LE() + 1;
+ int v2 = stream.readUint16LE() + 1;
+ stream.skip(1); // Skip paletteBase byte
+ bool rleEncoded = stream.readByte() == 1;
+ int palSize = v1 * v2;
+
+ if ((palSize - 12) == PALETTE_SIZE && !rleEncoded) {
+ // Found palette, so read it in
+ stream.seek(2 + 12, SEEK_CUR);
+ 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(-6, SEEK_CUR);
+ }
+}
+
+void ImageFile::decompressFrame(ImageFrame &frame, const byte *src) {
+ frame._frame.create(frame._width, frame._height, Graphics::PixelFormat::createFormatCLUT8());
+
+ if (frame._paletteBase) {
+ // Nibble-packed
+ byte *pDest = (byte *)frame._frame.getPixels();
+ for (uint idx = 0; idx < frame._size; ++idx, ++src) {
+ *pDest++ = *src & 0xF;
+ *pDest++ = (*src >> 4);
+ }
+ } else if (frame._rleEncoded && _vm->getGameID() == GType_RoseTattoo) {
+ // Rose Tattoo run length encoding doesn't use the RLE marker byte
+ byte *dst = (byte *)frame._frame.getPixels();
+
+ for (int yp = 0; yp < frame._height; ++yp) {
+ int xSize = frame._width;
+ while (xSize > 0) {
+ // Skip a given number of pixels
+ byte skip = *src++;
+ dst += 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)
+ *dst++ = *src++;
+ }
+ assert(xSize == 0);
+ }
+ } else if (frame._rleEncoded) {
+ // RLE encoded
+ byte *dst = (byte *)frame._frame.getPixels();
+
+ int frameSize = frame._width * frame._height;
+ while (frameSize > 0) {
+ if (*src == frame._rleMarker) {
+ byte rleColor = src[1];
+ byte rleCount = src[2];
+ src += 3;
+ frameSize -= rleCount;
+ while (rleCount--)
+ *dst++ = rleColor;
+ } else {
+ *dst++ = *src++;
+ --frameSize;
+ }
+ }
+ assert(frameSize == 0);
+ } else {
+ // Uncompressed frame
+ Common::copy(src, src + frame._width * frame._height,
+ (byte *)frame._frame.getPixels());
+ }
+}
+
+/*----------------------------------------------------------------*/
+
+int ImageFrame::sDrawXSize(int scaleVal) const {
+ int width = _width;
+ int scale = scaleVal == 0 ? 1 : scaleVal;
+
+ if (scaleVal >= 256)
+ --width;
+
+ int result = width * 256 / scale;
+ if (scaleVal >= 256)
+ ++result;
+
+ return result;
+}
+
+int ImageFrame::sDrawYSize(int scaleVal) const {
+ int height = _height;
+ int scale = scaleVal == 0 ? 1 : scaleVal;
+
+ if (scaleVal >= 256)
+ --height;
+
+ int result = height * 256 / scale;
+ if (scaleVal >= 256)
+ ++result;
+
+ return result;
+}
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/resources.h b/engines/sherlock/resources.h
new file mode 100644
index 0000000000..5c071e3922
--- /dev/null
+++ b/engines/sherlock/resources.h
@@ -0,0 +1,217 @@
+/* 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);
+};
+
+struct ImageFrame {
+ uint32 _size;
+ uint16 _width, _height;
+ int _paletteBase;
+ bool _rleEncoded;
+ Common::Point _offset;
+ byte _rleMarker;
+ Graphics::Surface _frame;
+
+ /**
+ * 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;
+};
+
+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);
+
+ /**
+ * Decompress a single frame for the sprite
+ */
+ void decompressFrame(ImageFrame &frame, const byte *src);
+public:
+ byte _palette[256 * 3];
+public:
+ ImageFile(const Common::String &name, bool skipPal = false, bool animImages = false);
+ ImageFile(Common::SeekableReadStream &stream, bool skipPal = false);
+ ~ImageFile();
+ static void setVm(SherlockEngine *vm);
+};
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp
new file mode 100644
index 0000000000..ddf4917a34
--- /dev/null
+++ b/engines/sherlock/saveload.cpp
@@ -0,0 +1,484 @@
+/* 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 "common/system.h"
+#include "graphics/scaler.h"
+#include "graphics/thumbnail.h"
+
+namespace Sherlock {
+
+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
+};
+
+static const char *const EMPTY_SAVEGAME_SLOT = "-EMPTY-";
+static const char *const SAVEGAME_STR = "SHLK";
+#define SAVEGAME_STR_SIZE 4
+
+/*----------------------------------------------------------------*/
+
+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::drawInterface() {
+ Screen &screen = *_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;
+}
+
+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) {
+ readSavegameHeader(in, header);
+ 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 > SHERLOCK_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(SHERLOCK_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;
+ }
+
+ uint8 thumbPalette[PALETTE_SIZE];
+ _vm->_screen->getPalette(thumbPalette);
+ _saveThumb = new Graphics::Surface();
+ ::createThumbnail(_saveThumb, (const byte *)_vm->_screen->getPixels(), SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT, thumbPalette);
+}
+
+int SaveManager::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 SaveManager::highlightButtons(int btnIndex) {
+ Screen &screen = *_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");
+}
+
+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
+ Common::Serializer s(saveFile, nullptr);
+ 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
+ Common::Serializer s(nullptr, out);
+ 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(Common::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::checkGameOnScreen(int slot) {
+ Screen &screen = *_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 SaveManager::promptForDescription(int slot) {
+ Events &events = *_vm->_events;
+ Scene &scene = *_vm->_scene;
+ Screen &screen = *_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;
+}
+
+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..a7ed852a5f
--- /dev/null
+++ b/engines/sherlock/saveload.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_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
+#define SHERLOCK_SAVEGAME_VERSION 1
+
+enum SaveMode { SAVEMODE_NONE = 0, SAVEMODE_LOAD = 1, SAVEMODE_SAVE = 2 };
+
+extern const int ENV_POINTS[6][3];
+
+struct SherlockSavegameHeader {
+ uint8 _version;
+ Common::String _saveName;
+ Graphics::Surface *_thumbnail;
+ int _year, _month, _day;
+ int _hour, _minute;
+ int _totalFrames;
+};
+
+class SherlockEngine;
+
+class SaveManager {
+private:
+ 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(Common::Serializer &s);
+public:
+ Common::StringArray _savegames;
+ int _savegameIndex;
+ SaveMode _envMode;
+ bool _justLoaded;
+public:
+ SaveManager(SherlockEngine *vm, const Common::String &target);
+ ~SaveManager();
+
+ /**
+ * Shows the in-game dialog interface for loading and saving games
+ */
+ void drawInterface();
+
+ /**
+ * 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);
+
+ /**
+ * 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);
+
+ /**
+ * 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/darts.cpp b/engines/sherlock/scalpel/darts.cpp
new file mode 100644
index 0000000000..8d78335a55
--- /dev/null
+++ b/engines/sherlock/scalpel/darts.cpp
@@ -0,0 +1,557 @@
+/* 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)
+ setFlagsForDarts(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), 0);
+ screen._backBuffer1.fillRect(Common::Rect(DARTBARVX, DARTHEIGHTY, DARTBARVX + 10, DARTHEIGHTY + DARTBARSIZE), 0);
+ 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;
+}
+
+void Darts::setFlagsForDarts(int flagNum) {
+ _vm->_flags[ABS(flagNum)] = flagNum >= 0;
+}
+
+} // End of namespace Scalpel
+
+} // End of namespace Scalpel
diff --git a/engines/sherlock/scalpel/darts.h b/engines/sherlock/scalpel/darts.h
new file mode 100644
index 0000000000..42990f8056
--- /dev/null
+++ b/engines/sherlock/scalpel/darts.h
@@ -0,0 +1,136 @@
+/* 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/resources.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);
+
+ /**
+ * 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 setFlagsForDarts(int flagNum);
+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..db1151c841
--- /dev/null
+++ b/engines/sherlock/scalpel/drivers/adlib.cpp
@@ -0,0 +1,639 @@
+/* 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 adlib_Operator1Register[SHERLOCK_ADLIB_VOICES_COUNT] = {
+ 0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12
+};
+
+byte adlib_Operator2Register[SHERLOCK_ADLIB_VOICES_COUNT] = {
+ 0x03, 0x04, 0x05, 0x0B, 0x0C, 0x0D, 0x13, 0x14, 0x15
+};
+
+struct adlib_percussionChannelEntry {
+ byte requiredNote;
+ byte replacementNote;
+};
+
+// hardcoded, dumped from ADHOM.DRV
+const adlib_percussionChannelEntry adlib_percussionChannelTable[SHERLOCK_ADLIB_VOICES_COUNT] = {
+ { 0x00, 0x00 },
+ { 0x00, 0x00 },
+ { 0x00, 0x00 },
+ { 0x00, 0x00 },
+ { 0x00, 0x00 },
+ { 0x00, 0x00 },
+ { 0x24, 0x0C },
+ { 0x38, 0x01 },
+ { 0x26, 0x1E }
+};
+
+struct adlib_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 adlib_InstrumentEntry adlib_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 adlib_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_AdLib : public MidiDriver_Emulated {
+public:
+ MidiDriver_AdLib(Audio::Mixer *mixer)
+ : MidiDriver_Emulated(mixer), _masterVolume(15), _opl(0) {
+ memset(_voiceChannelMapping, 0, sizeof(_voiceChannelMapping));
+ }
+ virtual ~MidiDriver_AdLib() { }
+
+ // MidiDriver
+ int open();
+ void close();
+ void send(uint32 b);
+ MidiChannel *allocateChannel() { return NULL; }
+ MidiChannel *getPercussionChannel() { return NULL; }
+
+ // AudioStream
+ bool isStereo() const { return false; }
+ int getRate() const { return _mixer->getOutputRate(); }
+ int getPolyphony() const { return SHERLOCK_ADLIB_VOICES_COUNT; }
+ bool hasRhythmChannel() const { return false; }
+
+ // MidiDriver_Emulated
+ void generateSamples(int16 *buf, int len);
+
+ 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 adlib_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;
+
+ // 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];
+
+protected:
+ void onTimer();
+
+private:
+ void resetAdLib();
+ void resetAdLib_OperatorRegisters(byte baseRegister, byte value);
+ void resetAdLib_FMVoiceChannelRegisters(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_AdLib::open() {
+ int rate = _mixer->getOutputRate();
+
+ debug(3, "ADLIB: Starting driver");
+
+ _opl = OPL::Config::create(OPL::Config::kOpl2);
+
+ if (!_opl)
+ return -1;
+
+ _opl->init(rate);
+
+ MidiDriver_Emulated::open();
+
+ _mixer->playStream(Audio::Mixer::kPlainSoundType, &_mixerSoundHandle, this, -1, _mixer->kMaxChannelVolume, 0, DisposeAfterUse::NO);
+
+ return 0;
+}
+
+void MidiDriver_AdLib::close() {
+ _mixer->stopHandle(_mixerSoundHandle);
+
+ delete _opl;
+}
+
+void MidiDriver_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_AdLib::onTimer() {
+ 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_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_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
+ resetAdLib_OperatorRegisters(0x20, 0);
+ resetAdLib_OperatorRegisters(0x60, 0);
+ resetAdLib_OperatorRegisters(0x80, 0);
+ resetAdLib_FMVoiceChannelRegisters(0xA0, 0);
+ resetAdLib_FMVoiceChannelRegisters(0xB0, 0);
+ resetAdLib_FMVoiceChannelRegisters(0xC0, 0);
+ resetAdLib_OperatorRegisters(0xE0, 0);
+ resetAdLib_OperatorRegisters(0x40, 0x3F);
+}
+
+void MidiDriver_AdLib::resetAdLib_OperatorRegisters(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_AdLib::resetAdLib_FMVoiceChannelRegisters(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_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:
+ warning("pitch bend change");
+ pitchBendChange(channel, op1, op2);
+ break;
+ case 0xf0: // SysEx
+ warning("SysEx: %x", b);
+ break;
+ default:
+ warning("ADLIB: Unknown event %02x", command);
+ }
+}
+
+void MidiDriver_AdLib::generateSamples(int16 *data, int len) {
+ _opl->readBuffer(data, len);
+}
+
+void MidiDriver_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
+ warning("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;
+ }
+ warning("MIDI channel not mapped/all FM voice channels busy %d", MIDIchannel);
+
+ } else {
+ // Percussion channel
+ warning("percussion!");
+ for (byte FMvoiceChannel = 0; FMvoiceChannel < SHERLOCK_ADLIB_VOICES_COUNT; FMvoiceChannel++) {
+ if (_voiceChannelMapping[FMvoiceChannel] == MIDIchannel) {
+ if (note == adlib_percussionChannelTable[FMvoiceChannel].requiredNote) {
+ _channels[FMvoiceChannel].inUse = true;
+ _channels[FMvoiceChannel].currentNote = note;
+
+ voiceOnOff(FMvoiceChannel, true, adlib_percussionChannelTable[FMvoiceChannel].replacementNote, velocity);
+ return;
+ }
+ }
+ }
+ warning("percussion MIDI channel not mapped/all FM voice channels busy");
+ }
+}
+
+void MidiDriver_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, adlib_percussionChannelTable[FMvoiceChannel].replacementNote, 0);
+ }
+ return;
+ }
+ }
+ }
+}
+
+void MidiDriver_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 - bad note!!!");
+ return;
+ }
+ frequency = adlib_FrequencyLookUpTable[frequencyOffset];
+
+ if (keyOn) {
+ // adjust register 40h
+ if (_channels[FMvoiceChannel].currentInstrumentPtr) {
+ regValue40h = _channels[FMvoiceChannel].currentInstrumentPtr->reg40op2;
+ }
+ regValue40h = regValue40h - (velocity >> 3);
+ op2RegAdjust = adlib_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_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_AdLib::programChange(byte MIDIchannel, byte op1) {
+ const adlib_InstrumentEntry *instrumentPtr;
+ byte op1Reg = 0;
+ byte op2Reg = 0;
+
+ // setup instrument
+ instrumentPtr = &adlib_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 = adlib_Operator1Register[FMvoiceChannel];
+ op2Reg = adlib_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_AdLib::setRegister(int reg, int value) {
+ _opl->write(0x220, reg);
+ _opl->write(0x221, value);
+}
+
+uint32 MidiDriver_AdLib::property(int prop, uint32 param) {
+ return 0;
+}
+
+MidiDriver *MidiDriver_AdLib_create() {
+ return new MidiDriver_AdLib(g_system->getMixer());
+}
+
+void MidiDriver_AdLib_newMusicData(MidiDriver *driver, byte *musicData, int32 musicDataSize) {
+ static_cast<MidiDriver_AdLib *>(driver)->newMusicData(musicData, musicDataSize);
+}
+
+} // End of namespace Sci
diff --git a/engines/sherlock/scalpel/drivers/mididriver.h b/engines/sherlock/scalpel/drivers/mididriver.h
new file mode 100644
index 0000000000..64213315e8
--- /dev/null
+++ b/engines/sherlock/scalpel/drivers/mididriver.h
@@ -0,0 +1,37 @@
+/* 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_SOFTSEQ_MIDIDRIVER_H
+#define SHERLOCK_SOFTSEQ_MIDIDRIVER_H
+
+#include "sherlock/sherlock.h"
+#include "audio/mididrv.h"
+#include "common/error.h"
+
+namespace Sherlock {
+
+extern MidiDriver *MidiDriver_AdLib_create();
+extern void MidiDriver_AdLib_newMusicData(MidiDriver *driver, byte *musicData, int32 musicDataSize);
+
+} // End of namespace Sci
+
+#endif // SHERLOCK_SOFTSEQ_MIDIDRIVER_H
diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp
new file mode 100644
index 0000000000..43b69068ab
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel.cpp
@@ -0,0 +1,920 @@
+/* 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/tsage/logo.h"
+#include "sherlock/sherlock.h"
+#include "sherlock/music.h"
+#include "sherlock/animation.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
+
+const char PEOPLE_PORTRAITS[MAX_PEOPLE][5] = {
+ { "HOLM" }, // Sherlock Holmes
+ { "WATS" }, // Dr. Watson
+ { "LEST" }, // Inspector Lestrade
+ { "CON1" }, // Constable O'Brien
+ { "CON2" }, // Constable Lewis
+ { "SHEI" }, // Sheila Parker
+ { "HENR" }, // Henry Carruthers
+ { "LESL" }, // Lesley (flower girl)
+ { "USH1" }, // Usher #1
+ { "USH2" }, // Usher #2
+ { "FRED" }, // Fredrick Epstein
+ { "WORT" }, // Mrs. Worthington
+ { "COAC" }, // Coach
+ { "PLAY" }, // Player
+ { "WBOY" }, // Tim (Waterboy)
+ { "JAME" }, // James Sanders
+ { "BELL" }, // Belle (perfumerie)
+ { "GIRL" }, // Cleaning Girl (perfumerie)
+ { "EPST" }, // Epstien in the Opera Balcony
+ { "WIGG" }, // Wiggins
+ { "PAUL" }, // Paul (Brumwell / Carroway)
+ { "BART" }, // Bartender
+ { "DIRT" }, // Dirty Drunk
+ { "SHOU" }, // Shouting Drunk
+ { "STAG" }, // Staggering Drunk
+ { "BOUN" }, // Bouncer
+ { "SAND" }, // James Sanders - At Home
+ { "CORO" }, // The Coroner
+ { "EQUE" }, // The Equestrian Shop Keeper
+ { "GEOR" }, // George Blackwood
+ { "LARS" }, // Lars
+ { "PARK" }, // Sheila Parker (happy)
+ { "CHEM" }, // Chemist
+ { "GREG" }, // Inspector Gregson
+ { "LAWY" }, // Jacob Farthington Lawyer
+ { "MYCR" }, // Mycroft
+ { "SHER" }, // Old Sherman
+ { "CHMB" }, // Richard Chemist Stock boy
+ { "BARM" }, // Barman
+ { "DAND" }, // Dandy Player
+ { "ROUG" }, // Rough-looking Player
+ { "SPEC" }, // Spectator
+ { "HUNT" }, // Robert Hunt
+ { "VIOL" }, // Violet Secretary
+ { "PETT" }, // Pettigrew
+ { "APPL" }, // Augie (apple seller)
+ { "ANNA" }, // Anna Carroway
+ { "GUAR" }, // Guard
+ { "ANTO" }, // Antonio Caruso
+ { "TOBY" }, // Toby the Dog
+ { "KING" }, // Simon Kingsley
+ { "ALFR" }, // Alfred Tobacco Clerk
+ { "LADY" }, // Lady Brumwell
+ { "ROSA" }, // Madame Rosa
+ { "LADB" }, // Lady Brumwell
+ { "MOOR" }, // Joseph Moorehead
+ { "BEAL" }, // Mrs. Beale
+ { "LION" }, // Felix the Lion
+ { "HOLL" }, // Hollingston
+ { "CALL" }, // Constable Callaghan
+ { "JERE" }, // Sergeant Jeremy Duncan
+ { "LORD" }, // Lord Brumwell
+ { "NIGE" }, // Nigel Jameson
+ { "JONA" }, // Jonas (newspaper seller)
+ { "DUGA" }, // Constable Dugan
+ { "INSP" } // Inspector Lestrade (Scotland Yard)
+};
+
+const char *const PEOPLE_NAMES[MAX_PEOPLE] = {
+ "Sherlock Holmes",
+ "Dr. Watson",
+ "Inspector Lestrade",
+ "Constable O'Brien",
+ "Constable Lewis",
+ "Sheila Parker",
+ "Henry Carruthers",
+ "Lesley",
+ "An Usher",
+ "An Usher",
+ "Fredrick Epstein",
+ "Mrs. Worthington",
+ "The Coach",
+ "A Player",
+ "Tim",
+ "James Sanders",
+ "Belle",
+ "Cleaning Girl",
+ "Fredrick Epstein",
+ "Wiggins",
+ "Paul",
+ "The Bartender",
+ "A Dirty Drunk",
+ "A Shouting Drunk",
+ "A Staggering Drunk",
+ "The Bouncer",
+ "James Sanders",
+ "The Coroner",
+ "Reginald Snipes",
+ "George Blackwood",
+ "Lars",
+ "Sheila Parker",
+ "The Chemist",
+ "Inspector Gregson",
+ "Jacob Farthington",
+ "Mycroft",
+ "Old Sherman",
+ "Richard",
+ "The Barman",
+ "A Dandy Player",
+ "A Rough-looking Player",
+ "A Spectator",
+ "Robert Hunt",
+ "Violet",
+ "Pettigrew",
+ "Augie",
+ "Anna Carroway",
+ "A Guard",
+ "Antonio Caruso",
+ "Toby the Dog",
+ "Simon Kingsley",
+ "Alfred",
+ "Lady Brumwell",
+ "Madame Rosa",
+ "Lady Brumwell",
+ "Joseph Moorehead",
+ "Mrs. Beale",
+ "Felix",
+ "Hollingston",
+ "Constable Callaghan",
+ "Sergeant Duncan",
+ "Lord Brumwell",
+ "Nigel Jaimeson",
+ "Jonas",
+ "Constable Dugan",
+ "Inspector Lestrade"
+};
+
+static const byte PEOPLE_STILL_SEQUENCES[MAX_PEOPLE][MAX_TALK_SEQUENCES] = {
+ { 1, 0, 0 }, // Sherlock Holmes
+ { 6, 0, 0 }, // Dr. Watson
+ { 4, 0, 0 }, // Inspector Lestrade
+ { 2, 0, 0 }, // Constable #1
+ { 2, 0, 0 }, // Constable #2
+ { 2, 0, 0 }, // Sheila Parker
+ { 3, 0, 0 }, // Henry Carruthers
+ { 9, 0, 0 }, // Lesly (flower girl)
+ { 13, 0, 0 }, // Usher #1
+ { 2, 0, 0 }, // Usher #2
+ { 4, 0, 0 }, // Fredrick Epstein
+ { 9, 0, 0 }, // Mrs.Worthington
+ { 2, 0, 0 }, // Coach
+ { 8, 0, 0 }, // Player
+ { 13, 0, 0 }, // Waterboy
+ { 6, 0, 0 }, // James Sanders
+ { 1, 0, 0 }, // Belle (perfumerie)
+ { 20, 0, 0 }, // Cleaning Girl (perfumerie)
+ { 17, 0, 0 }, // Epstien in the Opera Balcony
+ { 3, 0, 0 }, // Wiggins
+ { 2, 0, 0 }, // Paul (Brumwell/Carroway)
+ { 1, 0, 0 }, // Bartender
+ { 1, 0, 0 }, // Dirty Drunk
+ { 1, 0, 0 }, // Shouting Drunk
+ { 1, 0, 0 }, // Staggering Drunk
+ { 1, 0, 0 }, // Bouncer
+ { 6, 0, 0 }, // James Sanders - At Home
+ { 6, 0, 0 }, // The Coroner
+ { 1, 0, 0 }, // The Equestrian Shop Keeper
+ { 1, 0, 0 }, // George Blackwood
+ { 7, 0, 0 }, // Lars
+ { 1, 0, 0 }, // Sheila Parker
+ { 8, 0, 0 }, // Chemist
+ { 6, 0, 0 }, // Inspector Gregson
+ { 1, 0, 0 }, // Lawyer
+ { 1, 0, 0 }, // Mycroft
+ { 7, 0, 0 }, // Old Sherman
+ { 1, 0, 0 }, // Stock Boy in Chemist Shop
+ { 1, 0, 0 }, // Barman
+ { 1, 0, 0 }, // Dandy Player
+ { 1, 0, 0 }, // Rough-looking Player
+ { 1, 0, 0 }, // Spectator
+ { 1, 0, 0 }, // Robert Hunt
+ { 3, 0, 0 }, // Violet Secretary
+ { 1, 0, 0 }, // Pettigrew
+ { 8, 0, 0 }, // Augie (apple seller)
+ { 16, 0, 0 }, // Anna Carroway
+ { 1, 0, 0 }, // Guard
+ { 8, 0, 0 }, // Antonio Caruso
+ { 1, 0, 0 }, // Toby the Dog
+ { 13, 0, 0 }, // Simon Kingsley
+ { 2, 0, 0 }, // Alfred Tobacco Clerk
+ { 1, 0, 0 }, // Lady Brumwell
+ { 1, 0, 0 }, // Madame Rosa
+ { 1, 0, 0 }, // Lady Brumwell
+ { 1, 0, 0 }, // Joseph Moorehead
+ { 5, 0, 0 }, // Mrs. Beale
+ { 1, 0, 0 }, // Felix the Lion
+ { 1, 0, 0 }, // Hollingston
+ { 1, 0, 0 }, // Constable Callaghan
+ { 2, 0, 0 }, // Sergeant Jeremy Duncan
+ { 1, 0, 0 }, // Lord Brumwell
+ { 1, 0, 0 }, // Nigel Jameson
+ { 1, 0, 0 }, // Jonas (newspaper seller)
+ { 1, 0, 0 }, // Constable Dugan
+ { 4, 0, 0 } // Inspector Lestrade (Yard)
+};
+
+static const byte PEOPLE_TALK_SEQUENCES[MAX_PEOPLE][MAX_TALK_SEQUENCES] = {
+ { 1, 0, 0 }, // Sherlock Holmes
+ { 5, 5, 6, 7, 8, 7, 8, 6, 0, 0 }, // Dr. Watson
+ { 2, 0, 0 }, // Inspector Lestrade
+ { 1, 0, 0 }, // Constable #1
+ { 1, 0, 0 }, // Constable #2
+ { 2, 3, 0, 0 }, // Sheila Parker
+ { 3, 0, 0 }, // Henry Carruthers
+ { 1, 2, 3, 2, 1, 2, 3, 0, 0 }, // Lesly (flower girl)
+ { 13, 14, 0, 0 }, // Usher #1
+ { 2, 0, 0 }, // Usher #2
+ { 1, 2, 3, 4, 3, 4, 3, 2, 0, 0 }, // Fredrick Epstein
+ { 8, 0, 0 }, // Mrs.Worthington
+ { 1, 2, 3, 4, 5, 4, 3, 2, 0, 0 }, // Coach
+ { 7, 8, 0, 0 }, // Player
+ { 12, 13, 0, 0 }, // Waterboy
+ { 3, 4, 0, 0 }, // James Sanders
+ { 4, 5, 0, 0 }, // Belle (perfumerie)
+ { 14, 15, 16, 17, 18, 19, 20, 20, 20, 0, 0 }, // Cleaning Girl (perfumerie)
+ { 16, 17, 18, 18, 18, 17, 17, 0, 0 }, // Epstien in the Opera Balcony
+ { 2, 3, 0, 0 }, // Wiggins
+ { 1, 2, 0, 0 }, // Paul (Brumwell/Carroway)
+ { 1, 0, 0 }, // Bartender
+ { 1, 0, 0 }, // Dirty Drunk
+ { 1, 0, 0 }, // Shouting Drunk
+ { 1, 0, 0 }, // Staggering Drunk
+ { 1, 0, 0 }, // Bouncer
+ { 5, 6, 0, 0 }, // James Sanders - At Home
+ { 4, 5, 0, 0 }, // The Coroner
+ { 1, 0, 0 }, // The Equestrian Shop Keeper
+ { 1, 0, 0 }, // George Blackwood
+ { 5, 6, 0, 0 }, // Lars
+ { 1, 0, 0 }, // Sheila Parker
+ { 8, 9, 0, 0 }, // Chemist
+ { 5, 6, 0, 0 }, // Inspector Gregson
+ { 1, 0, 0 }, // Lawyer
+ { 1, 0, 0 }, // Mycroft
+ { 7, 8, 0, 0 }, // Old Sherman
+ { 1, 0, 0 }, // Stock Boy in Chemist Shop
+ { 1, 0, 0 }, // Barman
+ { 1, 0, 0 }, // Dandy Player
+ { 1, 0, 0 }, // Rough-looking Player
+ { 1, 0, 0 }, // Spectator
+ { 1, 0, 0 }, // Robert Hunt
+ { 3, 4, 0, 0 }, // Violet Secretary
+ { 1, 0, 0 }, // Pettigrew
+ { 14, 15, 0, 0 }, // Augie (apple seller)
+ { 3, 4, 5, 6, 0, 0 }, // Anna Carroway
+ { 4, 5, 6, 0, 0 }, // Guard
+ { 7, 8, 0, 0 }, // Antonio Caruso
+ { 1, 0, 0 }, // Toby the Dog
+ { 13, 14, 0, 0 }, // Simon Kingsley
+ { 2, 3, 0, 0 }, // Alfred Tobacco Clerk
+ { 3, 4, 0, 0 }, // Lady Brumwell
+ { 1, 30, 0, 0 }, // Madame Rosa
+ { 3, 4, 0, 0 }, // Lady Brumwell
+ { 1, 0, 0 }, // Joseph Moorehead
+ { 14, 15, 16, 17, 18, 19, 20, 0, 0 }, // Mrs. Beale
+ { 1, 0, 0 }, // Felix the Lion
+ { 1, 0, 0 }, // Hollingston
+ { 1, 0, 0 }, // Constable Callaghan
+ { 1, 1, 2, 2, 0, 0 }, // Sergeant Jeremy Duncan
+ { 9, 10, 0, 0 }, // Lord Brumwell
+ { 1, 2, 0, 138, 3, 4, 0, 138, 0, 0 }, // Nigel Jameson
+ { 1, 8, 0, 0 }, // Jonas (newspaper seller)
+ { 1, 0, 0 }, // Constable Dugan
+ { 2, 0, 0 } // Inspector Lestrade (Yard)
+};
+
+/*----------------------------------------------------------------*/
+
+ScalpelEngine::ScalpelEngine(OSystem *syst, const SherlockGameDescription *gameDesc) :
+ SherlockEngine(syst, gameDesc) {
+ _darts = nullptr;
+ _mapResult = 0;
+}
+
+ScalpelEngine::~ScalpelEngine() {
+ delete _darts;
+}
+
+void ScalpelEngine::initialize() {
+ 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
+ _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_NAMES[idx], PEOPLE_PORTRAITS[idx],
+ PEOPLE_STILL_SEQUENCES[idx], PEOPLE_TALK_SEQUENCES[idx]));
+
+ _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() {
+ if (isDemo() && _interactiveFl)
+ return;
+
+ if (!TsAGE::Logo::show(this))
+ return;
+ if (!showCityCutscene())
+ return;
+ if (!showAlleyCutscene())
+ return;
+ if (!showStreetCutscene())
+ return;
+ if (!showOfficeCutscene())
+ return;
+
+ _events->clearEvents();
+ _music->stopMusic();
+}
+
+bool ScalpelEngine::showCityCutscene() {
+ byte palette[PALETTE_SIZE];
+
+ _music->playMusic("prolog1.mus");
+ _animation->_gfxLibraryFilename = "title.lib";
+ _animation->_soundLibraryFilename = "title.snd";
+ bool finished = _animation->play("26open1", 1, 255, true, 2);
+
+ if (finished) {
+ ImageFile titleImages("title2.vgs", true);
+ _screen->_backBuffer1.blitFrom(*_screen);
+ _screen->_backBuffer2.blitFrom(*_screen);
+
+ // London, England
+ _screen->_backBuffer1.transBlitFrom(titleImages[0], Common::Point(10, 11));
+ _screen->randomTransition();
+ finished = _events->delay(1000, true);
+
+ // November, 1888
+ if (finished) {
+ _screen->_backBuffer1.transBlitFrom(titleImages[1], Common::Point(101, 102));
+ _screen->randomTransition();
+ finished = _events->delay(5000, true);
+ }
+
+ // Transition out the title
+ _screen->_backBuffer1.blitFrom(_screen->_backBuffer2);
+ _screen->randomTransition();
+ }
+
+ if (finished)
+ finished = _animation->play("26open2", 1, 0, false, 2);
+
+ if (finished) {
+ ImageFile titleImages("title.vgs", true);
+ _screen->_backBuffer1.blitFrom(*_screen);
+ _screen->_backBuffer2.blitFrom(*_screen);
+
+ // The Lost Files of
+ _screen->_backBuffer1.transBlitFrom(titleImages[0], Common::Point(75, 6));
+ // Sherlock Holmes
+ _screen->_backBuffer1.transBlitFrom(titleImages[1], Common::Point(34, 21));
+ // copyright
+ _screen->_backBuffer1.transBlitFrom(titleImages[2], Common::Point(4, 190));
+
+ _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...
+ _screen->transBlitFrom(titleImages[3], Common::Point(72, 51));
+ _screen->fadeIn(palette, 3);
+ finished = _events->delay(3000, true);
+ }
+ }
+
+ _animation->_gfxLibraryFilename = "";
+ _animation->_soundLibraryFilename = "";
+ return finished;
+}
+
+bool ScalpelEngine::showAlleyCutscene() {
+ byte palette[PALETTE_SIZE];
+ _music->playMusic("prolog2.mus");
+
+ _animation->_gfxLibraryFilename = "TITLE.LIB";
+ _animation->_soundLibraryFilename = "TITLE.SND";
+
+ bool finished = _animation->play("27PRO1", 1, 3, true, 2);
+ if (finished)
+ finished = _animation->play("27PRO2", 1, 0, false, 2);
+
+ if (finished) {
+ showLBV("scream.lbv");
+ finished = _events->delay(6000);
+ }
+
+ if (finished)
+ finished = _animation->play("27PRO3", 1, 0, true, 2);
+
+ if (finished) {
+ _screen->getPalette(palette);
+ _screen->fadeToBlack(2);
+ }
+
+ if (finished) {
+ ImageFile titleImages("title3.vgs", true);
+ // "Early the following morning on Baker Street..."
+ _screen->_backBuffer1.transBlitFrom(titleImages[0], Common::Point(35, 51), false, 0);
+ _screen->fadeIn(palette, 3);
+ finished = _events->delay(1000);
+ }
+
+ _animation->_gfxLibraryFilename = "";
+ _animation->_soundLibraryFilename = "";
+ return finished;
+}
+
+bool ScalpelEngine::showStreetCutscene() {
+ _animation->_gfxLibraryFilename = "TITLE.LIB";
+ _animation->_soundLibraryFilename = "TITLE.SND";
+
+ _music->playMusic("PROLOG3.MUS");
+
+ bool finished = _animation->play("14KICK", 1, 3, true, 2);
+
+ if (finished)
+ finished = _animation->play("14NOTE", 1, 0, false, 2);
+
+ _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);
+ _screen->setPalette(creditsImages._palette);
+ 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;
+}
+
+bool ScalpelEngine::showOfficeCutscene() {
+ _music->playMusic("PROLOG4.MUS");
+ _animation->_gfxLibraryFilename = "TITLE2.LIB";
+ _animation->_soundLibraryFilename = "TITLE.SND";
+
+ bool finished = _animation->play("COFF1", 1, 3, true, 3);
+ if (finished)
+ finished = _animation->play("COFF2", 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", 1, 0, true, 3);
+
+ if (finished)
+ finished = _animation->play("COFF4", 1, 0, false, 3);
+
+ if (finished)
+ finished = scrollCredits();
+
+ if (finished)
+ _screen->fadeToBlack(3);
+
+ _animation->_gfxLibraryFilename = "";
+ _animation->_soundLibraryFilename = "";
+ return finished;
+}
+
+void ScalpelEngine::loadInventory() {
+ Inventory &inv = *_inventory;
+
+ // Initial inventory
+ inv._holdings = 2;
+ inv.push_back(InventoryItem(0, "Message", "A message requesting help", "_ITEM03A"));
+ inv.push_back(InventoryItem(0, "Holmes Card", "A number of business cards", "_ITEM07A"));
+
+ // Hidden items
+ inv.push_back(InventoryItem(95, "Tickets", "Opera Tickets", "_ITEM10A"));
+ inv.push_back(InventoryItem(138, "Cuff Link", "Cuff Link", "_ITEM04A"));
+ inv.push_back(InventoryItem(138, "Wire Hook", "Wire Hook", "_ITEM06A"));
+ inv.push_back(InventoryItem(150, "Note", "Note", "_ITEM13A"));
+ inv.push_back(InventoryItem(481, "Open Watch", "An open pocket watch", "_ITEM62A"));
+ inv.push_back(InventoryItem(481, "Paper", "A piece of paper with numbers on it", "_ITEM44A"));
+ inv.push_back(InventoryItem(532, "Letter", "A letter folded many times", "_ITEM68A"));
+ inv.push_back(InventoryItem(544, "Tarot", "Tarot Cards", "_ITEM71A"));
+ inv.push_back(InventoryItem(544, "Ornate Key", "An ornate key", "_ITEM70A"));
+ inv.push_back(InventoryItem(586, "Pawn ticket", "A pawn ticket", "_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->_hSavedPos = Common::Point(-1, -1);
+ _people->_hSavedFacing = -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", 1, 3, true, 4);
+ _animation->play("final2", 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", 1, 3, true, 4);
+ _animation->play("finalr2", 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", 1, 0, false, 4);
+ _animation->play("finale2", 1, 0, false, 4);
+ _animation->play("finale3", 1, 0, false, 4);
+
+ _useEpilogue2 = true;
+ _animation->play("finale4", 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", 1, 3, true, 4);
+ _animation->play("SUBWAY2", 1, 0, false, 4);
+ _animation->play("SUBWAY3", 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", 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)[AL]._position.x / 100, (*_people)[AL]._position.y / 100);
+
+ // 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._player;
+
+ Common::Point pt((*_people)[AL]._position.x / 100, (*_people)[AL]._position.y / 100);
+ int frameNum = player._walkSequences[player._sequenceNumber][player._frameNumber] +
+ player._walkSequences[player._sequenceNumber][0] - 2;
+
+ switch ((*_people)[AL]._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[AL]._images)[frameNum];
+
+ // Draw the mirror image of Holmes
+ bool flipped = people[AL]._sequenceNumber == WALK_LEFT || people[AL]._sequenceNumber == STOP_LEFT
+ || people[AL]._sequenceNumber == WALK_UPRIGHT || people[AL]._sequenceNumber == STOP_UPRIGHT
+ || people[AL]._sequenceNumber == WALK_DOWNLEFT || people[AL]._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)[AL]._position.x / 100, (*_people)[AL]._position.y / 100);
+
+ // 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 Scalpel
diff --git a/engines/sherlock/scalpel/scalpel.h b/engines/sherlock/scalpel/scalpel.h
new file mode 100644
index 0000000000..8743bfb7a9
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel.h
@@ -0,0 +1,117 @@
+/* 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 { 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 ScalpelEngine : public SherlockEngine {
+private:
+ Darts *_darts;
+ int _mapResult;
+
+ /**
+ * Show the starting city cutscene which shows the game title
+ */
+ bool showCityCutscene();
+
+ /**
+ * Show the back alley where the initial murder takes place
+ */
+ bool showAlleyCutscene();
+
+ /**
+ * Show the Baker Street outside cutscene
+ */
+ bool showStreetCutscene();
+
+ /**
+ * Show Holmes and Watson at the breakfast table, lestrade's note, and then the scrolling credits
+ */
+ bool showOfficeCutscene();
+
+ /**
+ * 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_scene.cpp b/engines/sherlock/scalpel/scalpel_scene.cpp
new file mode 100644
index 0000000000..b6a42419d8
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_scene.cpp
@@ -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.
+ *
+ */
+
+#include "sherlock/scalpel/scalpel_scene.h"
+#include "sherlock/scalpel/scalpel.h"
+#include "sherlock/events.h"
+#include "sherlock/people.h"
+#include "sherlock/screen.h"
+
+namespace Sherlock {
+
+namespace Scalpel {
+
+void ScalpelScene::checkBgShapes() {
+ People &people = *_vm->_people;
+ Person &holmes = people._player;
+ 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();
+
+ 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;
+
+ 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[AL]._oldPosition.x, people[AL]._oldPosition.y,
+ people[AL]._oldPosition.x + people[AL]._oldSize.x,
+ people[AL]._oldPosition.y + people[AL]._oldSize.y);
+ Common::Point pt(bounds.left, bounds.top);
+
+ if (people[AL]._type == CHARACTER)
+ screen.restoreBackground(bounds);
+ else if (people[AL]._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[AL]._type == CHARACTER && people._holmesOn)
+ people[AL].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[AL]._type == CHARACTER && people[AL]._walkLoaded) {
+ // If Holmes is too far to the right, move him back so he's on-screen
+ int xRight = SHERLOCK_SCREEN_WIDTH - 2 - people[AL]._imageFrame->_frame.w;
+ int tempX = MIN(people[AL]._position.x / FIXED_INT_MULTIPLIER, xRight);
+
+ bool flipped = people[AL]._sequenceNumber == WALK_LEFT || people[AL]._sequenceNumber == STOP_LEFT ||
+ people[AL]._sequenceNumber == WALK_UPLEFT || people[AL]._sequenceNumber == STOP_UPLEFT ||
+ people[AL]._sequenceNumber == WALK_DOWNRIGHT || people[AL]._sequenceNumber == STOP_DOWNRIGHT;
+ screen._backBuffer->transBlitFrom(*people[AL]._imageFrame,
+ Common::Point(tempX, people[AL]._position.y / FIXED_INT_MULTIPLIER - people[AL]._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[AL]._type != INVALID && ((_goToScene == -1 || _canimShapes.empty()))) {
+ if (people[AL]._type == REMOVE) {
+ screen.slamRect(Common::Rect(
+ people[AL]._oldPosition.x, people[AL]._oldPosition.y,
+ people[AL]._oldPosition.x + people[AL]._oldSize.x,
+ people[AL]._oldPosition.y + people[AL]._oldSize.y
+ ));
+ people[AL]._type = INVALID;
+ } else {
+ screen.flushImage(people[AL]._imageFrame,
+ Common::Point(people[AL]._position.x / FIXED_INT_MULTIPLIER,
+ people[AL]._position.y / FIXED_INT_MULTIPLIER - people[AL].frameHeight()),
+ &people[AL]._oldPosition.x, &people[AL]._oldPosition.y,
+ &people[AL]._oldSize.x, &people[AL]._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);
+ }
+}
+
+} // 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..e5a442f44f
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_scene.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_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 {
+
+class ScalpelScene : public Scene {
+private:
+ void doBgAnimCheckCursor();
+protected:
+ /**
+ * 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();
+public:
+ ScalpelScene(SherlockEngine *vm) : Scene(vm) {}
+
+ /**
+ * Draw all objects and characters.
+ */
+ virtual void doBgAnim();
+};
+
+} // 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..295cddb3c9
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_user_interface.cpp
@@ -0,0 +1,2284 @@
+/* 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/sherlock.h"
+#include "sherlock/scalpel/settings.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 char *const MOPEN[] = {
+ "This cannot be opened", "It is already open", "It is locked", "Wait for Watson", " ", "."
+};
+const char *const MCLOSE[] = {
+ "This cannot be closed", "It is already closed", "The safe door is in the way"
+};
+const char *const MMOVE[] = {
+ "This cannot be moved", "It is bolted to the floor", "It is too heavy", "The other crate is in the way"
+};
+const char *const MPICK[] = {
+ "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"
+};
+const char *const MUSE[] = {
+ "You can't do that", "It had no effect", "You can't reach it", "OK, the door looks bigger! Happy?",
+ "Doors don't smoke"
+};
+
+/*----------------------------------------------------------------*/
+
+
+ScalpelUserInterface::ScalpelUserInterface(SherlockEngine *vm): UserInterface(vm) {
+ if (_vm->_interactiveFl) {
+ _controls = new ImageFile("menu.all");
+ _controlPanel = new ImageFile("controls.vgs");
+ } else {
+ _controls = nullptr;
+ _controlPanel = nullptr;
+ }
+
+ _keyPress = '\0';
+ _lookHelp = 0;
+ _bgFound = 0;
+ _oldBgFound = -1;
+ _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() {
+ _oldKey = -1;
+ _help = _oldHelp = -1;
+ _oldTemp = _temp = -1;
+}
+
+void ScalpelUserInterface::drawInterface(int bufferNum) {
+ Screen &screen = *_vm->_screen;
+
+ if (bufferNum & 1)
+ screen._backBuffer1.transBlitFrom((*_controlPanel)[0], Common::Point(0, CONTROLS_Y));
+ if (bufferNum & 2)
+ screen._backBuffer2.transBlitFrom((*_controlPanel)[0], Common::Point(0, 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(Common::Rect(pt.x, pt.y, pt.x + 1, pt.y + 1));
+ _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._walkDest = pt;
+ people._allowWalkAbort = false;
+ people.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]);
+
+ 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) {
+ Screen &screen = *_vm->_screen;
+ Common::Point pt(MENU_POINTS[num][0], MENU_POINTS[num][1]);
+ Graphics::Surface &frame = (*_controls)[num]._frame;
+
+ 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]);
+ 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.walkToCoords(Common::Point(obj._lookPosition.x, obj._lookPosition.y * 100), obj._lookFacing);
+ }
+
+ 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._rightPressed) && !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;
+ SaveManager &saves = *_vm->_saves;
+ Scene &scene = *_vm->_scene;
+ Screen &screen = *_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;
+ Inventory &inv = *_vm->_inventory;
+ Scene &scene = *_vm->_scene;
+ Screen &screen = *_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();
+
+ 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, "Exit");
+
+ if (found >= 0 && found <= 3) {
+ screen.buttonPrint(Common::Point(INVENTORY_POINTS[1][2], CONTROLS_Y1), colors[1], true, "Look");
+ screen.buttonPrint(Common::Point(INVENTORY_POINTS[2][2], CONTROLS_Y1), colors[2], true, "Use");
+ screen.buttonPrint(Common::Point(INVENTORY_POINTS[3][2], CONTROLS_Y1), colors[3], true, "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, 235);
+
+ _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, MUSE, _find, giveFl);
+ else
+ // Now inv object has been highlighted
+ checkUseAction(&scene._bgShapes[_find]._use[0], "*SELF*", MUSE, _find, giveFl);
+
+ _selector = _oldSelector = -1;
+ }
+ }
+ }
+ }
+}
+
+void ScalpelUserInterface::doLookControl() {
+ Events &events = *_vm->_events;
+ Inventory &inv = *_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]);
+ 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;
+ Inventory &inv = *_vm->_inventory;
+ SaveManager &saves = *_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 (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, MOPEN, _temp);
+ if (_menuMode != TALK_MODE && !talk._talkToAbort) {
+ _menuMode = STD_MODE;
+ restoreButton(OPEN_MODE - 1);
+ _key = _oldKey = -1;
+ }
+ break;
+
+ case ALLOW_CLOSE:
+ checkAction(obj._aClose, MCLOSE, _temp);
+ if (_menuMode != TALK_MODE && !talk._talkToAbort) {
+ _menuMode = STD_MODE;
+ restoreButton(CLOSE_MODE - 1);
+ _key = _oldKey = -1;
+ }
+ break;
+
+ case ALLOW_MOVE:
+ checkAction(obj._aMove, MMOVE, _temp);
+ 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(MPICK);
+
+ if (!talk._talkToAbort && _menuMode != TALK_MODE) {
+ _key = _oldKey = -1;
+ _menuMode = STD_MODE;
+ restoreButton(PICKUP_MODE - 1);
+ }
+ }
+ }
+ }
+}
+
+void ScalpelUserInterface::doTalkControl() {
+ Events &events = *_vm->_events;
+ Journal &journal = *_vm->_journal;
+ People &people = *_vm->_people;
+ Screen &screen = *_vm->_screen;
+ Sound &sound = *_vm->_sound;
+ Talk &talk = *_vm->_talk;
+ Common::Point mousePos = events.mousePos();
+
+ _key = _oldKey = -1;
+ _keyboardInput = false;
+
+ 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, "Exit");
+ else if (_endKeyActive)
+ screen.buttonPrint(Common::Point(119, CONTROLS_Y), COMMAND_FOREGROUND, true, "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, "Up");
+ else if (talk._moreTalkUp)
+ screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_FOREGROUND, true, "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, "Down");
+ else if (talk._moreTalkDown)
+ screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_FOREGROUND, true, "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, "Exit");
+ screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_NULL, true, "Up");
+ screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_NULL, true, "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;
+ }
+
+ 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, "Exit");
+ else
+ screen.buttonPrint(Common::Point(119, CONTROLS_Y), COMMAND_NULL, true, "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;
+ Journal &journal = *_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;
+ Inventory &inv = *_vm->_inventory;
+ Screen &screen = *_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]);
+
+ 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,
+ const char *const messages[], int objNum, bool giveMode) {
+ Events &events = *_vm->_events;
+ Inventory &inv = *_vm->_inventory;
+ Scene &scene = *_vm->_scene;
+ Screen &screen = *_vm->_screen;
+ Talk &talk = *_vm->_talk;
+ bool printed = messages == nullptr;
+
+ 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], messages)) {
+ 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 (messages == nullptr) {
+ screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "You can't do that.");
+ } else {
+ screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", messages[0]);
+ }
+
+ _infoFlag = true;
+ _menuCounter = 30;
+ }
+
+ events.setCursor(ARROW);
+}
+
+void ScalpelUserInterface::checkAction(ActionType &action, const char *const messages[], int objNum) {
+ Events &events = *_vm->_events;
+ People &people = *_vm->_people;
+ Scene &scene = *_vm->_scene;
+ Screen &screen = *_vm->_screen;
+ Talk &talk = *_vm->_talk;
+ Common::Point pt(-1, -1);
+
+ if (objNum >= 1000)
+ // Ignore actions done on characters
+ return;
+
+ if (!action._cAnimSpeed) {
+ // Invalid action, to print error message
+ _infoFlag = true;
+ clearInfo();
+ screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", messages[action._cAnimNum]);
+ _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._teleportPos;
+ dir = anim._teleportDir;
+ } else {
+ pt = anim._goto;
+ dir = anim._gotoDir;
+ }
+ }
+ } else {
+ pt = Common::Point(-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), messages)) {
+ 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.walkToCoords(pt, dir);
+
+ if (!talk._talkToAbort) {
+ // Ensure Holmes is on the exact intended location
+ people[AL]._position = pt;
+ people[AL]._sequenceNumber = dir;
+ people.gotoStand(people[AL]);
+
+ 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.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, messages)) {
+ 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], messages)) {
+ if (!talk._talkToAbort)
+ printed = true;
+ }
+ }
+
+ // Unless we're leaving the scene, print a "Done" message unless the printed flag has been set
+ if (scene._goToScene != 1 && !printed && !talk._talkToAbort) {
+ _infoFlag = true;
+ clearInfo();
+ screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "Done...");
+
+ // Set how long to show the message
+ _menuCounter = 30;
+ }
+ }
+ }
+
+ // Reset cursor back to arrow
+ events.setCursor(ARROW);
+}
+
+} // 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..552bcf00c5
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_user_interface.h
@@ -0,0 +1,227 @@
+/* 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 _bgFound, _oldBgFound;
+ int _help, _oldHelp;
+ char _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, const char *const messages[],
+ int objNum, bool giveMode);
+
+ /**
+ * Called for OPEN, CLOSE, and MOVE actions are being done
+ */
+ void checkAction(ActionType &action, const char *const messages[], int objNum);
+
+ /**
+ * 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();
+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..aa8033d25e
--- /dev/null
+++ b/engines/sherlock/scalpel/settings.cpp
@@ -0,0 +1,341 @@
+/* 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_user_interface.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;
+ Screen &screen = *_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;
+ Screen &screen = *_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..239543b017
--- /dev/null
+++ b/engines/sherlock/scalpel/tsage/logo.cpp
@@ -0,0 +1,695 @@
+/* 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 = false;
+ _frame = 0;
+ _numFrames = 0;
+ _frameChange = 0;
+ _angle = _changeCtr = 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())
+ 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 yDiff = 0;
+ 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();
+
+ events.wait(2);
+ events.setButtonState();
+
+ // 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();
+
+ 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;
+
+ // Initialize counter
+ _counter = 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 _counter >= 442;
+}
+
+void Logo::nextFrame() {
+ Screen &screen = *_vm->_screen;
+
+ 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();
+ screen.clear();
+ }
+ break;
+
+ case 13: {
+ // Load the new palette
+ byte palette[PALETTE_SIZE];
+ Common::copy(&_palette2[0], &_palette2[PALETTE_SIZE], &palette[0]);
+ _lib.getPalette(palette, 12);
+ screen.setPalette(palette);
+ break;
+ }
+
+ case 14:
+ _objects[0].setVisage(12, 1);
+ _objects[0]._frame = 1;
+ _objects[0]._numFrames = 7;
+ _objects[0]._position = Common::Point(170, 142);
+ _objects[0].setDestination(Common::Point(158, 71));
+ break;
+
+ case 15:
+ // Wait until the logo has expanded upwards to form EA logo
+ if (_objects[0].isMoving())
+ --_counter;
+ break;
+
+ case 16:
+ fade(_palette3, 40);
+ break;
+
+ case 20:
+ // Show the 'Electronic Arts' company name
+ _objects[1].setVisage(14, 1);
+ _objects[1]._frame = 1;
+ _objects[1]._position = Common::Point(152, 98);
+ break;
+
+ case 140:
+ // Start sequence of positioning and size hand cursor in an arc
+ _objects[2].setVisage(18, 1);
+ _objects[2]._frame = 1;
+ _objects[2]._position = Common::Point(33, 91);
+ break;
+
+ case 145:
+ _objects[2]._frame = 2;
+ _objects[2]._position = Common::Point(44, 124);
+ break;
+
+ case 150:
+ _objects[2]._frame = 3;
+ _objects[2]._position = Common::Point(64, 153);
+ break;
+
+ case 155:
+ _objects[2]._frame = 4;
+ _objects[2]._position = Common::Point(87, 174);
+ break;
+
+ case 160:
+ _objects[2]._frame = 5;
+ _objects[2]._position = Common::Point(114, 191);
+ break;
+
+ case 165:
+ _objects[2]._frame = 6;
+ _objects[2]._position = Common::Point(125, 184);
+ break;
+
+ case 170:
+ _objects[2]._frame = 7;
+ _objects[2]._position = Common::Point(154, 187);
+ break;
+
+ case 175:
+ _objects[2]._frame = 8;
+ _objects[2]._position = Common::Point(181, 182);
+ break;
+
+ case 180:
+ _objects[2]._frame = 9;
+ _objects[2]._position = Common::Point(191, 167);
+ break;
+
+ case 185:
+ _objects[2]._frame = 10;
+ _objects[2]._position = Common::Point(190, 150);
+ break;
+
+ case 190:
+ _objects[2]._frame = 11;
+ _objects[2]._position = Common::Point(182, 139);
+ break;
+
+ case 195:
+ _objects[2]._frame = 11;
+ _objects[2]._position = Common::Point(170, 130);
+ break;
+
+ case 200:
+ _objects[2]._frame = 11;
+ _objects[2]._position = Common::Point(158, 121);
+ break;
+
+ case 205:
+ // Show a highlighting of the company name
+ _objects[2].remove();
+ _objects[3].setVisage(19, 1);
+ _objects[3]._position = Common::Point(155, 94);
+ break;
+
+ case 213:
+ _objects[3]._frame = 2;
+ _objects[3]._position = Common::Point(155, 94);
+ break;
+
+ case 221:
+ _objects[1].remove();
+ break;
+
+ case 222:
+ _objects[3]._frame = 3;
+ _objects[3]._position = Common::Point(155, 94);
+ break;
+
+ case 230:
+ _objects[3]._frame = 4;
+ _objects[3]._position = Common::Point(155, 94);
+ break;
+
+ case 238:
+ _objects[3]._frame = 5;
+ _objects[3]._position = Common::Point(155, 94);
+ break;
+
+ case 246:
+ _objects[3]._frame = 6;
+ _objects[3]._position = Common::Point(155, 94);
+ break;
+
+ case 254:
+ _objects[3]._frame = 7;
+ _objects[3]._position = Common::Point(155, 94);
+ break;
+
+ case 262:
+ _objects[3]._frame = 8;
+ _objects[3]._position = Common::Point(155, 94);
+ break;
+
+ default:
+ break;
+ }
+}
+
+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..68b7353a15
--- /dev/null
+++ b/engines/sherlock/scalpel/tsage/logo.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_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(); }
+};
+
+class Logo {
+private:
+ ScalpelEngine *_vm;
+ TLib _lib;
+ int _counter;
+ byte _originalPalette[PALETTE_SIZE];
+ byte _palette1[PALETTE_SIZE];
+ byte _palette2[PALETTE_SIZE];
+ byte _palette3[PALETTE_SIZE];
+ Object _objects[4];
+
+ Logo(ScalpelEngine *vm);
+ ~Logo();
+
+ void nextFrame();
+
+ bool finished() const;
+
+ /**
+ * 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..76fb7ae3a7
--- /dev/null
+++ b/engines/sherlock/scene.cpp
@@ -0,0 +1,1329 @@
+/* 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/scalpel/scalpel.h"
+#include "sherlock/scalpel/scalpel_scene.h"
+#include "sherlock/screen.h"
+#include "sherlock/tattoo/tattoo.h"
+#include "sherlock/tattoo/tattoo_scene.h"
+
+namespace Sherlock {
+
+static const int FS_TRANS[8] = {
+ STOP_UP, STOP_UPRIGHT, STOP_RIGHT, STOP_DOWNRIGHT, STOP_DOWN,
+ STOP_DOWNLEFT, STOP_LEFT, 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 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();
+
+ _people.x = s.readSint16LE();
+ _people.y = s.readSint16LE();
+ _peopleDir = s.readUint16LE();
+
+ if (isRoseTattoo)
+ _allow = s.readSint16LE();
+}
+
+/*----------------------------------------------------------------*/
+
+void SceneEntry::load(Common::SeekableReadStream &s) {
+ _startPosition.x = s.readSint16LE();
+ _startPosition.y = s.readSint16LE();
+ _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();
+}
+
+/*----------------------------------------------------------------*/
+
+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();
+}
+
+/*----------------------------------------------------------------*/
+
+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) {
+ for (int idx = 0; idx < SCENES_COUNT; ++idx)
+ Common::fill(&_sceneStats[idx][0], &_sceneStats[idx][65], false);
+ _currentScene = -1;
+ _goToScene = -1;
+ _loadingSavedGame = false;
+ _walkedInScene = false;
+ _version = 0;
+ _lzwMode = false;
+ _invGraphicItems = 0;
+ _cAnimFramePause = 0;
+ _restoreFlag = false;
+ _animating = 0;
+ _doBgAnimDone = true;
+ _tempFadeStyle = 0;
+ _exitZone = -1;
+}
+
+Scene::~Scene() {
+ freeScene();
+}
+
+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 = Common::String::format("res%02d.rrm", _goToScene);
+ _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._walkDest = Common::Point(people[AL]._position.x / FIXED_INT_MULTIPLIER,
+ people[AL]._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->_talk->freeTalkVars();
+ _vm->_inventory->freeInv();
+ _vm->_music->freeSong();
+ _vm->_sound->freeLoadedSounds();
+
+ if (!_loadingSavedGame)
+ saveSceneStatus();
+ else
+ _loadingSavedGame = false;
+
+ _sequenceBuffer.clear();
+ _descText.clear();
+ _walkData.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;
+ Map &map = *_vm->_map;
+ Music &music = *_vm->_music;
+ People &people = *_vm->_people;
+ Resources &res = *_vm->_res;
+ SaveManager &saves = *_vm->_saves;
+ Screen &screen = *_vm->_screen;
+ Sound &sound = *_vm->_sound;
+ Talk &talk = *_vm->_talk;
+ 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();
+
+ // 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);
+ }
+ }
+ }
+
+ if (IS_ROSE_TATTOO) {
+ // Set the NPC paths for the scene
+ setNPCPath(0);
+
+ // Handle loading music for the scene
+ if (sound._midiDrvLoaded) {
+ if (talk._scriptMoreFlag != 1 && talk._scriptMoreFlag != 3)
+ sound._nextSongName = Common::String::format("res%02d", _currentScene);
+
+ // If it's a new song, then start it up
+ if (sound._currentSongName.compareToIgnoreCase(sound._nextSongName)) {
+ if (music.loadSong(sound._nextSongName)) {
+ sound.setMIDIVolume(sound._musicVolume);
+ if (music._musicOn)
+ music.startSong();
+ }
+ }
+ }
+ }
+
+ //
+ // Load the room resource file for the scene
+ //
+
+ Common::String rrmFile = filename + ".rrm";
+ flag = _vm->_res->exists(rrmFile);
+ if (flag) {
+ Common::SeekableReadStream *rrmStream = _vm->_res->load(rrmFile);
+
+ rrmStream->seek(39);
+ if (IS_SERRATED_SCALPEL) {
+ _version = rrmStream->readByte();
+ _lzwMode = _version == 10;
+ } else {
+ _lzwMode = 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) {
+ screen.initPaletteFade(bgHeader._bytesWritten);
+ rrmStream->read(screen._cMap, PALETTE_SIZE);
+ screen.translatePalette(screen._cMap);
+ screen.setupBGArea(screen._cMap);
+
+ screen.initScrollVars();
+
+ // Read in background
+ if (_lzwMode) {
+ res.decompress(*rrmStream, (byte *)screen._backBuffer1.getPixels(), SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCREEN_HEIGHT);
+ } else {
+ rrmStream->read(screen._backBuffer1.getPixels(), SHERLOCK_SCREEN_WIDTH * 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 = !_lzwMode ? rrmStream : res.decompress(*rrmStream, bgHeader._numStructs * 625);
+
+ _bgShapes.resize(bgHeader._numStructs);
+ for (int idx = 0; idx < bgHeader._numStructs; ++idx)
+ _bgShapes[idx].load(*infoStream, _vm->getGameID() == GType_RoseTattoo);
+
+ if (_lzwMode)
+ delete infoStream;
+
+ // Load description text
+ _descText.resize(bgHeader._descSize);
+ if (_lzwMode)
+ res.decompress(*rrmStream, (byte *)&_descText[0], bgHeader._descSize);
+ else
+ rrmStream->read(&_descText[0], bgHeader._descSize);
+
+ // Load sequences
+ _sequenceBuffer.resize(bgHeader._seqSize);
+ if (_lzwMode)
+ res.decompress(*rrmStream, &_sequenceBuffer[0], bgHeader._seqSize);
+ else
+ rrmStream->read(&_sequenceBuffer[0], bgHeader._seqSize);
+ } else if (!_lzwMode) {
+ // 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 = _lzwMode ?
+ 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 = _lzwMode ?
+ res.decompress(*rrmStream, animSize * bgHeader._numcAnimations) :
+ rrmStream->readStream(animSize * bgHeader._numcAnimations);
+
+ _cAnim.resize(bgHeader._numcAnimations);
+ for (uint idx = 0; idx < _cAnim.size(); ++idx)
+ _cAnim[idx].load(*canimStream, IS_ROSE_TATTOO);
+
+ delete canimStream;
+ }
+
+ // Read in the room bounding areas
+ int size = rrmStream->readUint16LE();
+ Common::SeekableReadStream *boundsStream = !_lzwMode ? 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 (_lzwMode)
+ 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
+ assert(_zones.size() < MAX_ZONES);
+ for (uint idx1 = 0; idx1 < _zones.size(); ++idx1) {
+ for (uint idx2 = 0; idx2 < _zones.size(); ++idx2)
+ _walkDirectory[idx1][idx2] = rrmStream->readSint16LE();
+ }
+
+ // Read in the walk data
+ size = rrmStream->readUint16LE();
+ Common::SeekableReadStream *walkStream = !_lzwMode ? rrmStream :
+ res.decompress(*rrmStream, size);
+
+ _walkData.resize(size);
+ walkStream->read(&_walkData[0], size);
+
+ if (_lzwMode)
+ delete walkStream;
+
+ 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
+ _exitZone = -1;
+ 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 = !_lzwMode ? rrmStream :
+ res.decompress(*rrmStream, SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT);
+
+ bgStream->read(screen._backBuffer1.getPixels(), SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT);
+
+ if (_lzwMode)
+ delete bgStream;
+ }
+
+ // Backup the image and set the palette
+ screen._backBuffer2.blitFrom(screen._backBuffer1);
+ screen.setPalette(screen._cMap);
+
+ delete rrmStream;
+ }
+
+ // 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;
+
+ if (!_vm->isDemo()) {
+ // Reset the previous map location and position on overhead map
+ map._oldCharPoint = _currentScene;
+
+ if (IS_SERRATED_SCALPEL) {
+ map._overPos.x = (map[_currentScene].x - 6) * FIXED_INT_MULTIPLIER;
+ map._overPos.y = (map[_currentScene].y + 9) * FIXED_INT_MULTIPLIER;
+
+ }
+ }
+
+ 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];
+
+ if (o._requiredFlag) {
+ if (!_vm->readFlags(_bgShapes[idx]._requiredFlag)) {
+ // 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 (_bgShapes[idx]._requiredFlag > 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;
+ Common::Point &hSavedPos = people._hSavedPos;
+ int &hSavedFacing = people._hSavedFacing;
+
+ 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
+ hSavedPos = Common::Point(16000, 10000);
+ hSavedFacing = 4;
+ } else {
+ // setup entrance info
+ hSavedPos = _entrance._startPosition;
+ 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[PLAYER]._position = hSavedPos;
+ people[PLAYER]._sequenceNumber = hSavedFacing;
+ } 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[PLAYER]._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[PLAYER]._position.x / FIXED_INT_MULTIPLIER,
+ people[PLAYER]._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)
+ screen.randomTransition();
+ else
+ screen.blitFrom(screen._backBuffer1);
+ screen.update();
+
+ // Start any initial animation for the scene
+ if (cAnimNum != -1) {
+ CAnim &c = _cAnim[cAnimNum];
+ Common::Point pt = c._goto;
+
+ c._goto = Common::Point(-1, -1);
+ people[AL]._position = Common::Point(0, 0);
+
+ startCAnim(cAnimNum, 1);
+ c._goto = 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();
+}
+
+void Scene::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();
+}
+
+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::startCAnim(int cAnimNum, int playRate) {
+ Events &events = *_vm->_events;
+ Map &map = *_vm->_map;
+ People &people = *_vm->_people;
+ Resources &res = *_vm->_res;
+ Talk &talk = *_vm->_talk;
+ UserInterface &ui = *_vm->_ui;
+ Common::Point 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._teleportPos;
+ walkDir = cAnim._teleportDir;
+ tpPos = cAnim._goto;
+ tpDir = cAnim._gotoDir;
+ } else {
+ // Forward direction
+ walkPos = cAnim._goto;
+ walkDir = cAnim._gotoDir;
+ tpPos = cAnim._teleportPos;
+ tpDir = cAnim._teleportDir;
+ }
+
+ 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[AL]._position != walkPos)
+ people.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[AL]._type = REMOVE;
+
+ Common::String fname = cAnim._name + ".vgs";
+ if (!res.isInCache(fname)) {
+ // Set up RRM scene data
+ Common::SeekableReadStream *rrmStream = res.load(_rrmName);
+ rrmStream->seek(44 + cAnimNum * 4);
+ rrmStream->seek(rrmStream->readUint32LE());
+
+ // Load the canimation into the cache
+ Common::SeekableReadStream *imgStream = !_lzwMode ? rrmStream->readStream(cAnim._size) :
+ Resources::decompressLZ(*rrmStream, cAnim._size);
+ res.addToCache(fname, *imgStream);
+
+ delete imgStream;
+ delete rrmStream;
+ }
+
+ // Now load the resource as an image
+ cObj._images = new ImageFile(fname);
+ cObj._imageFrame = &(*cObj._images)[0];
+ cObj._maxFrames = cObj._images->size();
+
+ int frames = 0;
+ if (playRate < 0) {
+ // Reverse direction
+ // Count number of frames
+ while (cObj._sequences[frames] && frames < MAX_FRAME)
+ ++frames;
+ } else {
+ // Forward direction
+ Object::_countCAnimFrames = true;
+
+ while (cObj._type == ACTIVE_BG_SHAPE) {
+ cObj.checkObject();
+ ++frames;
+
+ if (frames >= 1000)
+ error("CAnim has infinite loop sequence");
+ }
+
+ if (frames > 1)
+ --frames;
+
+ Object::_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[AL]._type = CHARACTER;
+ }
+
+ // Teleport to ending coordinates if necessary
+ if (tpPos.x != -1) {
+ people[AL]._position = tpPos; // Place the player
+ people[AL]._sequenceNumber = tpDir;
+ people.gotoStand(people[AL]);
+ }
+
+ 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[AL]._position = tpPos;
+ people[AL]._sequenceNumber = tpDir;
+
+ people.gotoStand(people[AL]);
+ }
+
+ events.setCursor(oldCursor);
+
+ return 1;
+}
+
+int Scene::findBgShape(const Common::Rect &r) {
+ 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 (r.intersects(o.getNewBounds()))
+ return idx;
+ } else if (o._type == NO_SHAPE) {
+ if (r.intersects(o.getNoShapeBounds()))
+ 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;
+}
+
+int Scene::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;
+}
+
+void Scene::synchronize(Common::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::setNPCPath(int npc) {
+ People &people = *_vm->_people;
+ Talk &talk = *_vm->_talk;
+
+ 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 (uint idx = 0; idx < MAX_NPC; ++idx)
+ people[idx + 1]._type = INVALID;
+
+ // Call the path script for the scene
+ Common::String pathFile = Common::String::format("PATH%.2dA", _currentScene);
+ talk.talkTo(pathFile);
+}
+
+void Scene::checkBgShapes() {
+ People &people = *_vm->_people;
+ Person &holmes = people._player;
+ 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..37a1b32740
--- /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 SCENES_COUNT 63
+#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);
+};
+
+class Exit: public Common::Rect {
+public:
+ int _scene;
+ int _allow;
+ Common::Point _people;
+ int _peopleDir;
+
+ Common::String _dest;
+ int _image; // Arrow image to use
+
+ /**
+ * Load the data for the object
+ */
+ void load(Common::SeekableReadStream &s, bool isRoseTattoo);
+};
+
+struct SceneEntry {
+ Common::Point _startPosition;
+ int _startDir;
+ int _allow;
+
+ /**
+ * Load the data for the object
+ */
+ void load(Common::SeekableReadStream &s);
+};
+
+struct SceneSound {
+ Common::String _name;
+ int _priority;
+
+ /**
+ * Load the data for the object
+ */
+ void load(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);
+};
+
+struct SceneTripEntry {
+ bool _flag;
+ int _sceneNumber;
+ int _numTimes;
+
+ SceneTripEntry() : _flag(false), _sceneNumber(0), _numTimes(0) {}
+ SceneTripEntry(bool flag, int sceneNumber, int numTimes) : _flag(flag),
+ _sceneNumber(sceneNumber), _numTimes(numTimes) {}
+};
+
+class Scene {
+private:
+ Common::String _rrmName;
+ bool _loadingSavedGame;
+
+ /**
+ * Loads the data associated for a given scene. The .BGD 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.
+ */
+ bool loadScene(const Common::String &filename);
+
+ /**
+ * 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;
+
+ /**
+ * 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
+ */
+ void drawAllShapes();
+
+ Scene(SherlockEngine *vm);
+public:
+ int _currentScene;
+ int _goToScene;
+ bool _sceneStats[SCENES_COUNT][65];
+ bool _savedStats[SCENES_COUNT][9];
+ bool _walkedInScene;
+ int _version;
+ bool _lzwMode;
+ 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<byte> _walkData;
+ Common::Array<Exit> _exits;
+ int _exitZone;
+ 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;
+ Common::Array<SceneTripEntry> _sceneTripCounters;
+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);
+
+ /**
+ * 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
+ */
+ int startCAnim(int cAnimNum, int playRate);
+
+ /**
+ * 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);
+
+ /**
+ * Attempts to find a background shape within the passed bounds. If found,
+ * it will return the shape number, or -1 on failure.
+ */
+ int findBgShape(const Common::Rect &r);
+
+ /**
+ * 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.
+ */
+ int closestZone(const Common::Point &pt);
+
+ /**
+ * Synchronize the data for a savegame
+ */
+ void synchronize(Common::Serializer &s);
+
+ /**
+ * 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);
+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();
+};
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp
new file mode 100644
index 0000000000..a3af5559c7
--- /dev/null
+++ b/engines/sherlock/screen.cpp
@@ -0,0 +1,508 @@
+/* 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 "common/system.h"
+#include "common/util.h"
+#include "graphics/palette.h"
+
+namespace Sherlock {
+
+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;
+ _font = nullptr;
+ _fontHeight = 0;
+ Common::fill(&_cMap[0], &_cMap[PALETTE_SIZE], 0);
+ Common::fill(&_sMap[0], &_sMap[PALETTE_SIZE], 0);
+ Common::fill(&_tMap[0], &_tMap[PALETTE_SIZE], 0);
+ setFont(IS_SERRATED_SCALPEL ? 1 : 4);
+
+ // Rose Tattoo specific fields
+ _fadeBytesRead = _fadeBytesToRead = 0;
+ _oldFadePercent = 0;
+ _scrollSize = 0;
+ _scrollSpeed = 0;
+ _currentScroll = 0;
+ _targetScroll = 0;
+ _flushScreen = false;
+}
+
+Screen::~Screen() {
+ delete _font;
+}
+
+void Screen::setFont(int fontNumb) {
+ // Interactive demo doesn't use fonts
+ if (!_vm->_interactiveFl)
+ return;
+
+ _fontNumber = fontNumb;
+ Common::String fname = Common::String::format("FONT%d.VGS", fontNumb + 1);
+
+ // Discard any previous font and read in new one
+ delete _font;
+ _font = new ImageFile(fname);
+
+ // Iterate through the frames to find the tallest font character
+ _fontHeight = 0;
+ for (uint idx = 0; idx < _font->size(); ++idx)
+ _fontHeight = MAX((uint16)_fontHeight, (*_font)[idx]._frame.h);
+}
+
+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::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::restoreBackground(const Common::Rect &r) {
+ if (r.width() > 0 && r.height() > 0) {
+ Common::Rect tempRect = r;
+ tempRect.clip(Common::Rect(0, 0, this->w(), SHERLOCK_SCENE_HEIGHT));
+
+ if (tempRect.isValidRect())
+ _backBuffer1.blitFrom(_backBuffer2, Common::Point(tempRect.left, tempRect.top), tempRect);
+ }
+}
+
+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 tempRect = r;
+ tempRect.clip(Common::Rect(0, 0, this->w(), this->h()));
+
+ if (tempRect.isValidRect())
+ blitFrom(*_backBuffer, Common::Point(tempRect.left, tempRect.top), tempRect);
+ }
+}
+
+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::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);
+}
+
+int Screen::stringWidth(const Common::String &str) {
+ int width = 0;
+
+ for (const char *c = str.c_str(); *c; ++c)
+ width += charWidth(*c);
+
+ return width;
+}
+
+int Screen::charWidth(char c) {
+ if (c == ' ')
+ return 5;
+ else if (Common::isPrint(c))
+ return (*_font)[c - 33]._frame.w + 1;
+ else
+ return 0;
+}
+
+void Screen::writeString(const Common::String &str, const Common::Point &pt, byte color) {
+ Common::Point charPos = pt;
+
+ for (const char *c = str.c_str(); *c; ++c) {
+ if (*c == ' ')
+ charPos.x += 5;
+ else {
+ assert(Common::isPrint(*c));
+ ImageFrame &frame = (*_font)[*c - 33];
+ _backBuffer->transBlitFrom(frame, charPos, false, color);
+ charPos.x += frame._frame.w + 1;
+ }
+ }
+}
+
+void Screen::vgaBar(const Common::Rect &r, int color) {
+ _backBuffer->fillRect(r, color);
+ slamRect(r);
+}
+
+void Screen::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 Screen::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 Screen::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 Screen::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);
+}
+
+void Screen::setDisplayBounds(const Common::Rect &r) {
+ assert(r.left == 0 && r.top == 0);
+ _sceneSurface.setPixels(_backBuffer1.getPixels(), r.width(), r.height());
+
+ _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(Common::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;
+}
+
+/**
+ * Creates a grey-scale version of the passed palette
+ */
+void Screen::setupBGArea(const byte cMap[PALETTE_SIZE]) {
+ warning("TODO");
+}
+
+/**
+ * Initializes scroll variables
+ */
+void Screen::initScrollVars() {
+ _scrollSize = 0;
+ _currentScroll = 0;
+ _targetScroll = 0;
+}
+
+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..8fda9cbb9c
--- /dev/null
+++ b/engines/sherlock/screen.h
@@ -0,0 +1,271 @@
+/* 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 "common/serializer.h"
+#include "sherlock/surface.h"
+#include "sherlock/resources.h"
+
+namespace Sherlock {
+
+#define PALETTE_SIZE 768
+#define PALETTE_COUNT 256
+#define VGA_COLOR_TRANS(x) ((x) * 255 / 63)
+
+enum {
+ INFO_BLACK = 1,
+ INFO_FOREGROUND = 11,
+ INFO_BACKGROUND = 1,
+ BORDER_COLOR = 237,
+ INV_FOREGROUND = 14,
+ INV_BACKGROUND = 1,
+ COMMAND_HIGHLIGHTED = 10,
+ COMMAND_FOREGROUND = 15,
+ COMMAND_BACKGROUND = 4,
+ COMMAND_NULL = 248,
+ BUTTON_TOP = 233,
+ BUTTON_MIDDLE = 244,
+ BUTTON_BOTTOM = 248,
+ TALK_FOREGROUND = 12,
+ TALK_NULL = 16,
+ PEN_COLOR = 250
+};
+
+class SherlockEngine;
+
+class Screen : public Surface {
+private:
+ SherlockEngine *_vm;
+ int _fontNumber;
+ Common::List<Common::Rect> _dirtyRects;
+ uint32 _transitionSeed;
+ ImageFile *_font;
+ int _fontHeight;
+ Surface _sceneSurface;
+
+ // Rose Tattoo fields
+ int _fadeBytesRead, _fadeBytesToRead;
+ int _oldFadePercent;
+ byte _lookupTable[PALETTE_COUNT];
+ byte _lookupTable1[PALETTE_COUNT];
+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);
+
+ /**
+ * Draws the given string into the back buffer using the images stored in _font
+ */
+ void writeString(const Common::String &str, const Common::Point &pt, byte color);
+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];
+ int _currentScroll, _targetScroll;
+ int _scrollSize, _scrollSpeed;
+ bool _flushScreen;
+public:
+ Screen(SherlockEngine *vm);
+ virtual ~Screen();
+
+ /**
+ * Set the font to use for writing text on the screen
+ */
+ void setFont(int fontNumber);
+
+ /**
+ * Handles updating any dirty areas of the screen Surface object to the physical screen
+ */
+ void update();
+
+ /**
+ * 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();
+
+ /**
+ * 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);
+
+ /**
+ * Returns the width of a string in pixels
+ */
+ int stringWidth(const Common::String &str);
+
+ /**
+ * Returns the width of a character in pixels
+ */
+ int charWidth(char c);
+
+ /**
+ * Fills an area on the back buffer, and then copies it to the screen
+ */
+ void vgaBar(const Common::Rect &r, int color);
+
+ /**
+ * 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);
+
+ /**
+ * 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();
+
+ int fontNumber() const { return _fontNumber; }
+
+ /**
+ * Synchronize the data for a savegame
+ */
+ void synchronize(Common::Serializer &s);
+
+ // Rose Tattoo specific methods
+ void initPaletteFade(int bytesToRead);
+
+ int fadeRead(Common::SeekableReadStream &stream, byte *buf, int totalSize);
+
+ void setupBGArea(const byte cMap[PALETTE_SIZE]);
+
+ void initScrollVars();
+
+ /**
+ * 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..d3a409a67b
--- /dev/null
+++ b/engines/sherlock/sherlock.cpp
@@ -0,0 +1,266 @@
+/* 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;
+ _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 _journal;
+ delete _map;
+ delete _music;
+ delete _people;
+ delete _saves;
+ delete _scene;
+ delete _screen;
+ delete _sound;
+ delete _talk;
+ delete _ui;
+ delete _inventory;
+ delete _res;
+}
+
+void SherlockEngine::initialize() {
+ DebugMan.addDebugChannel(kDebugScript, "scripts", "Script debug level");
+
+ ImageFile::setVm(this);
+ Object::setVm(this);
+ Sprite::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 = new Debugger(this);
+ _events = new Events(this);
+ _inventory = new Inventory(this);
+ _map = new Map(this);
+ _music = new Music(this, _mixer);
+ _journal = new Journal(this);
+ _people = new People(this);
+ _saves = new SaveManager(this, _targetName);
+ _scene = Scene::init(this);
+ _screen = new Screen(this);
+ _sound = new Sound(this, _mixer);
+ _talk = Talk::init(this);
+ _ui = UserInterface::init(this);
+
+ // Load game settings
+ loadConfig();
+}
+
+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 >= 1 && 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->_hSavedPos.x == -1) {
+ _canLoadSave = true;
+ _scene->doBgAnim();
+ _canLoadSave = false;
+ }
+ }
+
+ _scene->freeScene();
+ _people->freeWalk();
+
+}
+
+void SherlockEngine::handleInput() {
+ _canLoadSave = true;
+ _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::loadConfig() {
+ // Load sound settings
+ syncSoundSettings();
+
+ ConfMan.registerDefault("font", 1);
+
+ _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(Common::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..e71c729893
--- /dev/null
+++ b/engines/sherlock/sherlock.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_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/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 {
+ kDebugScript = 1 << 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_HEIGHT (IS_SERRATED_SCALPEL ? 138 : 480)
+
+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;
+ 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 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);
+
+ /**
+ * Saves game configuration information
+ */
+ void saveConfig();
+
+ /**
+ * Synchronize the data for a savegame
+ */
+ void synchronize(Common::Serializer &s);
+};
+
+#define IS_ROSE_TATTOO (_vm->getGameID() == GType_RoseTattoo)
+#define IS_SERRATED_SCALPEL (_vm->getGameID() == GType_SerratedScalpel)
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp
new file mode 100644
index 0000000000..390576e98e
--- /dev/null
+++ b/engines/sherlock/sound.cpp
@@ -0,0 +1,228 @@
+/* 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"
+
+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;
+ _midiDrvLoaded = false;
+ _musicVolume = 0;
+
+ _soundOn = true;
+ _speechOn = true;
+
+ _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('.'))
+ filename += ".SND";
+
+ Common::String libFilename(libraryFilename);
+ Common::SeekableReadStream *stream = libFilename.empty() ? res.load(filename) : res.load(filename, libFilename);
+
+ if (!stream)
+ error("Unable to find sound file '%s'", filename.c_str());
+
+ 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
+
+ Audio::AudioStream *audioStream = Audio::makeRawStream(decoded, (size - 2) * 2, rate, Audio::FLAG_UNSIGNED, DisposeAfterUse::YES);
+ _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 (_mixer->isSoundHandleActive(_effectsHandle) && (_curPriority > _vm->_scene->_sounds[bufNum]._priority))
+ return;
+
+ stopSound();
+ playSound(_vm->_scene->_sounds[bufNum]._name, waitType, _vm->_scene->_sounds[bufNum]._priority);
+
+ return;
+}
+
+void Sound::freeLoadedSounds() {
+ // As sounds are played with DisposeAfterUse::YES, stopping the sounds also
+ // frees them
+ stopSound();
+}
+
+void Sound::stopSound() {
+ _mixer->stopHandle(_effectsHandle);
+}
+
+void Sound::stopSndFuncPtr(int v1, int v2) {
+ // TODO
+ warning("TODO: Sound::stopSndFuncPtr");
+}
+
+void Sound::freeDigiSound() {
+ delete[] _digiBuf;
+ _digiBuf = nullptr;
+ _diskSoundPlaying = false;
+ _soundPlaying = false;
+}
+
+void Sound::setMIDIVolume(int volume) {
+ // TODO
+}
+
+} // End of namespace Sherlock
+
diff --git a/engines/sherlock/sound.h b/engines/sherlock/sound.h
new file mode 100644
index 0000000000..e1c0777763
--- /dev/null
+++ b/engines/sherlock/sound.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_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
+};
+
+class Sound {
+private:
+ SherlockEngine *_vm;
+ Audio::Mixer *_mixer;
+ Audio::SoundHandle _effectsHandle;
+ 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;
+ bool _midiDrvLoaded;
+ Common::String _currentSongName, _nextSongName;
+ int _musicVolume;
+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();
+ void setMIDIVolume(int volume);
+};
+
+} // End of namespace Sherlock
+
+#endif
+
diff --git a/engines/sherlock/surface.cpp b/engines/sherlock/surface.cpp
new file mode 100644
index 0000000000..5a9e59e01b
--- /dev/null
+++ b/engines/sherlock/surface.cpp
@@ -0,0 +1,201 @@
+/* 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) : _freePixels(true) {
+ create(width, height);
+}
+
+Surface::Surface() : _freePixels(false) {
+}
+
+Surface::~Surface() {
+ if (_freePixels)
+ _surface.free();
+}
+
+void Surface::create(uint16 width, uint16 height) {
+ if (_freePixels)
+ _surface.free();
+
+ _surface.create(width, height, Graphics::PixelFormat::createFormatCLUT8());
+ _freePixels = true;
+}
+
+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) {
+ transBlitFrom(src._frame, pt + src._offset, flipped, overrideColor);
+}
+
+void Surface::transBlitFrom(const Surface &src, const Common::Point &pt,
+ bool flipped, int overrideColor) {
+ const Graphics::Surface &s = src._surface;
+ transBlitFrom(s, pt, flipped, overrideColor);
+}
+
+void Surface::transBlitFrom(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()));
+
+ // Draw loop
+ const int TRANSPARENCY = 0xFF;
+ 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;
+ }
+ }
+}
+
+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);
+}
+
+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) {
+ _surface.format = Graphics::PixelFormat::createFormatCLUT8();
+ _surface.w = _surface.pitch = width;
+ _surface.h = height;
+ _surface.setPixels(pixels);
+}
+
+void Surface::maskArea(const ImageFrame &src, const Common::Point &pt, int scrollX) {
+ // 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..663f87f37f
--- /dev/null
+++ b/engines/sherlock/surface.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.
+ *
+ */
+
+#ifndef SHERLOCK_GRAPHICS_H
+#define SHERLOCK_GRAPHICS_H
+
+#include "common/rect.h"
+#include "graphics/surface.h"
+
+namespace Sherlock {
+
+struct ImageFrame;
+
+class Surface {
+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);
+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);
+
+ /**
+ * 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);
+
+ /**
+ * 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);
+
+ /**
+ * 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);
+
+ /**
+ * 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 maskArea(const ImageFrame &src, const Common::Point &pt, int scrollX);
+
+ /**
+ * Clear the screen
+ */
+ void clear();
+
+ /**
+ * Free the underlying surface
+ */
+ void free();
+
+ /**
+ * Set the pixels for the surface to an existing data block
+ */
+ void setPixels(byte *pixels, int width, int height);
+
+ 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..59897e2c2a
--- /dev/null
+++ b/engines/sherlock/talk.cpp
@@ -0,0 +1,2135 @@
+/* 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_user_interface.h"
+
+namespace Sherlock {
+
+#define SPEAKER_REMOVE 0x80
+
+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_CARRIAGE_RETURN
+ 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
+};
+
+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_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
+ 0, // OP_CARRIAGE_RETURN
+ 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
+ 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
+};
+
+/*----------------------------------------------------------------*/
+
+SequenceEntry::SequenceEntry() {
+ _objNum = 0;
+ _frameNumber = 0;
+ _seqTo = 0;
+}
+
+/*----------------------------------------------------------------*/
+
+void Statement::synchronize(Common::SeekableReadStream &s) {
+ 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();
+}
+
+/*----------------------------------------------------------------*/
+
+TalkHistoryEntry::TalkHistoryEntry() {
+ Common::fill(&_data[0], &_data[16], false);
+}
+
+/*----------------------------------------------------------------*/
+
+TalkSequences::TalkSequences(const byte *data) {
+ Common::copy(data, data + MAX_TALK_SEQUENCES, _data);
+}
+
+void TalkSequences::clear() {
+ Common::fill(&_data[0], &_data[MAX_TALK_SEQUENCES], 0);
+}
+
+/*----------------------------------------------------------------*/
+
+Talk *Talk::init(SherlockEngine *vm) {
+ if (vm->getGameID() == GType_SerratedScalpel)
+ return new ScalpelTalk(vm);
+ else
+ return new TattooTalk(vm);
+}
+
+Talk::Talk(SherlockEngine *vm) : _vm(vm) {
+ _talkCounter = 0;
+ _talkToAbort = false;
+ _speaker = 0;
+ _talkIndex = 0;
+ _talkTo = 0;
+ _scriptSelect = 0;
+ _converseNum = -1;
+ _talkStealth = 0;
+ _talkToFlag = -1;
+ _moreTalkDown = _moreTalkUp = false;
+ _scriptMoreFlag = 0;
+ _scriptSaveIndex = -1;
+ _opcodes = IS_SERRATED_SCALPEL ? SCALPEL_OPCODES : TATTOO_OPCODES;
+
+ _charCount = 0;
+ _line = 0;
+ _yp = 0;
+ _wait = 0;
+ _pauseFlag = false;
+ _seqCount = 0;
+ _scriptStart = _scriptEnd = nullptr;
+}
+
+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
+ if (scene._canimShapes.size() > 0 || 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[AL]._walkCount || people._walkTo.size() > 0) {
+ // Only interrupt if an action if trying to do an action, and not just
+ // if the player is walking around the scene
+ if (people._allowWalkAbort)
+ abortFlag = true;
+
+ people.gotoStand(people._player);
+ }
+
+ 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)
+ ((Scalpel::ScalpelUserInterface *)_vm->_ui)->restoreButton((int)(savedMode - 1));
+ }
+
+ // 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("^")) {
+ clearSequences();
+ pushSequence(_talkTo);
+ setStillSeq(_talkTo);
+ _talkIndex = select;
+ ui._selector = ui._oldSelector = -1;
+
+ if (!ui._windowOpen) {
+ // Draw the talk interface on the back buffer
+ drawInterface();
+ displayTalk(false);
+ } else {
+ displayTalk(true);
+ }
+
+ byte color = ui._endKeyActive ? COMMAND_FOREGROUND : COMMAND_NULL;
+
+ // 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, "Exit");
+ } else {
+ screen.buttonPrint(Common::Point(119, CONTROLS_Y), color, false, "Exit");
+
+ if (!ui._slideWindows) {
+ screen.slamRect(Common::Rect(0, CONTROLS_Y,
+ SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
+ } else {
+ ui.summonWindow();
+ }
+
+ ui._windowOpen = true;
+ }
+
+ // 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.banishWindow();
+ ui._windowBounds.top = CONTROLS_Y1;
+ ui._menuMode = STD_MODE;
+ }
+
+ 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 (_vm->getGameID() == GType_SerratedScalpel && 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;
+ Screen &screen = *_vm->_screen;
+ UserInterface &ui = *_vm->_ui;
+ Object &obj = scene._bgShapes[objNum];
+
+ ui._windowBounds.top = CONTROLS_Y;
+ ui._infoFlag = true;
+ _speaker = SPEAKER_REMOVE;
+ loadTalkFile(scene._bgShapes[objNum]._name);
+
+ // 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(obj._name);
+ } else if (statement._statement.hasPrefix("*")) {
+ // Character being spoken to will speak first
+ clearSequences();
+ pushSequence(_talkTo);
+ setStillSeq(_talkTo);
+
+ events.setCursor(WAIT);
+ if (obj._lookPosition.y != 0)
+ // Need to walk to character first
+ people.walkToCoords(Common::Point(obj._lookPosition.x, obj._lookPosition.y * 100),
+ obj._lookFacing);
+ events.setCursor(ARROW);
+
+ if (!_talkToAbort)
+ talkTo(obj._name);
+ } else {
+ // Holmes will be speaking first
+ clearSequences();
+ pushSequence(_talkTo);
+ setStillSeq(_talkTo);
+
+ _talkToFlag = false;
+ events.setCursor(WAIT);
+ if (obj._lookPosition.y != 0)
+ // Walk over to person to talk to
+ people.walkToCoords(Common::Point(obj._lookPosition.x, obj._lookPosition.y * 100),
+ obj._lookFacing);
+ 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 {
+ drawInterface();
+
+ events._pressed = events._released = false;
+ _talkIndex = select;
+ displayTalk(false);
+ ui._selector = ui._oldSelector = -1;
+
+ if (!ui._slideWindows) {
+ screen.slamRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH,
+ SHERLOCK_SCREEN_HEIGHT));
+ } else {
+ ui.summonWindow();
+ }
+
+ ui._windowOpen = true;
+ }
+
+ _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].synchronize(*talkStream);
+
+ 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::drawInterface() {
+ Screen &screen = *_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) {
+ screen.makeButton(Common::Rect(99, CONTROLS_Y, 139, CONTROLS_Y + 10),
+ 119 - screen.stringWidth("Exit") / 2, "Exit");
+ screen.makeButton(Common::Rect(140, CONTROLS_Y, 180, CONTROLS_Y + 10),
+ 159 - screen.stringWidth("Up") / 2, "Up");
+ screen.makeButton(Common::Rect(181, CONTROLS_Y, 221, CONTROLS_Y + 10),
+ 200 - screen.stringWidth("Down") / 2, "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 Talk::displayTalk(bool slamIt) {
+ Screen &screen = *_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
+ if (_moreTalkUp) {
+ if (slamIt) {
+ screen.print(Common::Point(5, CONTROLS_Y + 13), INV_FOREGROUND, "~");
+ screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_FOREGROUND, true, "Up");
+ } else {
+ screen.gPrint(Common::Point(5, CONTROLS_Y + 12), INV_FOREGROUND, "~");
+ screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_FOREGROUND, false, "Up");
+ }
+ } else {
+ if (slamIt) {
+ screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_NULL, true, "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, "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 ? TALK_NULL : 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, "Down");
+ } else {
+ screen.gPrint(Common::Point(5, 189), INV_FOREGROUND, "|");
+ screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_FOREGROUND, false, "Down");
+ }
+ } else {
+ if (slamIt) {
+ screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_NULL, true, "Down");
+ screen.vgaBar(Common::Rect(5, 189, 16, 199), INV_BACKGROUND);
+ } else {
+ screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_NULL, false, "Down");
+ screen._backBuffer1.fillRect(Common::Rect(5, 189, 16, 199), INV_BACKGROUND);
+ }
+ }
+
+ return done;
+}
+
+int Talk::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 Talk::clearSequences() {
+ _sequenceStack.clear();
+}
+
+void Talk::pullSequence() {
+ Scene &scene = *_vm->_scene;
+
+ if (_sequenceStack.empty())
+ 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)
+ 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::setSequence(int speaker) {
+ 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;
+ }
+ }
+ }
+ }
+}
+
+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;
+ bool openTalkWindow = false;
+
+ _savedSequences.clear();
+
+ _scriptStart = (const byte *)script.c_str();
+ _scriptEnd = _scriptStart + script.size();
+ const byte *str = _scriptStart;
+ _yp = CONTROLS_Y + 12;
+ _charCount = 0;
+ _line = 0;
+ _wait = 0;
+ _pauseFlag = false;
+ _seqCount = 0;
+ _noTextYet = true;
+ _endStr = false;
+
+ 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);
+ ui.clearWindow();
+
+ // Need to switch speakers?
+ if (str[0] == _opcodes[OP_SWITCH_SPEAKER]) {
+ _speaker = str[1] - 1;
+ str += 2;
+ pullSequence();
+ pushSequence(_speaker);
+ setSequence(_speaker);
+ } else {
+ setSequence(_speaker);
+ }
+
+ // 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;
+ }
+
+ // Remove portrait?
+ if (str[0] == _opcodes[OP_REMOVE_PORTRAIT]) {
+ _speaker = 255;
+ } else {
+ // Nope, so set the first speaker
+ people.setTalking(_speaker);
+ }
+ }
+
+ 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 (c >= 128 && c <= 227 && _opcodeTable[c - 128]) {
+ // Handle control code
+ switch ((this->*_opcodeTable[c - 128])(str)) {
+ case RET_EXIT:
+ return;
+ case RET_CONTINUE:
+ continue;
+ default:
+ break;
+ }
+
+ ++str;
+ } else {
+ // If the window isn't yet open, draw the window before printing starts
+ if (!ui._windowOpen && _noTextYet) {
+ _noTextYet = false;
+ drawInterface();
+
+ if (_talkTo != -1) {
+ screen.buttonPrint(Common::Point(119, CONTROLS_Y), COMMAND_NULL, false, "Exit");
+ screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_NULL, false, "Up");
+ screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_NULL, false, "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] != '{' && str[idx] < _opcodes[0]);
+
+ if (str[idx] || width >= 298) {
+ if (str[idx] < _opcodes[0] && 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 (str[0] < _opcodes[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;
+ }
+ }
+
+ // 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_CARRIAGE_RETURN])) {
+ 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) {
+ // Handling pausing
+ 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;
+ }
+
+ // 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;
+ }
+
+ _pauseFlag = false;
+ }
+ } 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 (_speaker >= 0 && _speaker < SPEAKER_REMOVE)
+ people.clearTalking();
+ }
+}
+
+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 (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;
+}
+
+void Talk::popStack() {
+ if (!_scriptStack.empty()) {
+ ScriptStackEntry scriptEntry = _scriptStack.pop();
+ _scriptName = scriptEntry._name;
+ _scriptSaveIndex = scriptEntry._currentIndex;
+ _scriptSelect = scriptEntry._select;
+ _scriptMoreFlag = 1;
+ }
+}
+
+void Talk::synchronize(Common::Serializer &s) {
+ for (int idx = 0; idx < MAX_TALK_FILES; ++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::cmdGotoScene(const byte *&str) {
+ Map &map = *_vm->_map;
+ People &people = *_vm->_people;
+ Scene &scene = *_vm->_scene;
+ scene._goToScene = str[1] - 1;
+
+ if (scene._goToScene != 100) {
+ // Not going to the map overview
+ map._oldCharPoint = scene._goToScene;
+ map._overPos.x = map[scene._goToScene].x * 100 - 600;
+ map._overPos.y = map[scene._goToScene].y * 100 + 900;
+
+ // Run a canimation?
+ if (str[2] > 100) {
+ people._hSavedFacing = str[2];
+ people._hSavedPos = Common::Point(160, 100);
+ }
+ }
+ str += 6;
+
+ _scriptMoreFlag = (scene._goToScene == 100) ? 2 : 1;
+ _scriptSaveIndex = str - _scriptStart;
+ _endStr = true;
+ _wait = 0;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn Talk::cmdHolmesOff(const byte *&str) {
+ People &people = *_vm->_people;
+ people[PLAYER]._type = REMOVE;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn Talk::cmdHolmesOn(const byte *&str) {
+ People &people = *_vm->_people;
+ people[PLAYER]._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::cmdSwitchSpeaker(const byte *&str) {
+ People &people = *_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);
+ setSequence(_speaker);
+
+ 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.walkToCoords(animation._goto, animation._gotoDir);
+
+ return _talkToAbort ? RET_EXIT : RET_SUCCESS;
+}
+
+OpcodeReturn Talk::cmdWalkToCoords(const byte *&str) {
+ People &people = *_vm->_people;
+ ++str;
+
+ people.walkToCoords(Common::Point(((str[0] - 1) * 256 + str[1] - 1) * 100,
+ str[2] * 100), str[3] - 1);
+ if (_talkToAbort)
+ return RET_EXIT;
+
+ str += 3;
+ return RET_SUCCESS;
+}
+
+/*----------------------------------------------------------------*/
+
+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::cmdCarriageReturn,
+ 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;
+}
+
+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, 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::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;
+ Screen &screen = *_vm->_screen;
+
+ drawInterface();
+ events._pressed = events._released = false;
+ events.clearKeyboard();
+ _noTextYet = false;
+
+ if (_speaker != -1) {
+ screen.buttonPrint(Common::Point(119, CONTROLS_Y), COMMAND_NULL, false, "Exit");
+ screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_NULL, false, "Up");
+ screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_NULL, false, "Down");
+ }
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn ScalpelTalk::cmdCarriageReturn(const byte *&str) {
+ return RET_SUCCESS;
+}
+
+/*----------------------------------------------------------------*/
+
+TattooTalk::TattooTalk(SherlockEngine *vm) : Talk(vm) {
+ static OpcodeMethod OPCODE_METHODS[] = {
+ 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,
+ (OpcodeMethod)&TattooTalk::cmdSwitchSpeaker,
+
+ (OpcodeMethod)&TattooTalk::cmdRunCAnimation,
+ (OpcodeMethod)&TattooTalk::cmdCallTalkFile,
+ (OpcodeMethod)&TattooTalk::cmdPause,
+ (OpcodeMethod)&TattooTalk::cmdMouseOnOff,
+ (OpcodeMethod)&TattooTalk::cmdSetWalkControl,
+ (OpcodeMethod)&TattooTalk::cmdAdjustObjectSequence,
+ (OpcodeMethod)&TattooTalk::cmdWalkToCoords,
+ (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,
+ nullptr,
+ (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
+ };
+
+ _opcodeTable = OPCODE_METHODS;
+}
+
+OpcodeReturn TattooTalk::cmdMouseOnOff(const byte *&str) { error("TODO: script opcode"); }
+
+OpcodeReturn TattooTalk::cmdNextSong(const byte *&str) {
+ Sound &sound = *_vm->_sound;
+
+ // Get the name of the next song to play
+ ++str;
+ sound._nextSongName = "";
+ for (int idx = 0; idx < 8; ++idx) {
+ if (str[idx] != '~')
+ sound._nextSongName += str[idx];
+ else
+ break;
+ }
+ str += 7;
+
+ return RET_SUCCESS;
+}
+
+OpcodeReturn TattooTalk::cmdNPCLabelGoto(const byte *&str) { error("TODO: script opcode"); }
+OpcodeReturn TattooTalk::cmdNPCLabelIfFlagGoto(const byte *&str) { error("TODO: script opcode"); }
+OpcodeReturn TattooTalk::cmdNPCLabelSet(const byte *&str) { error("TODO: script opcode"); }
+OpcodeReturn TattooTalk::cmdPassword(const byte *&str) { error("TODO: script opcode"); }
+OpcodeReturn TattooTalk::cmdPlaySong(const byte *&str) { error("TODO: script opcode"); }
+OpcodeReturn TattooTalk::cmdRestorePeopleSequence(const byte *&str) { error("TODO: script opcode"); }
+OpcodeReturn TattooTalk::cmdSetNPCDescOnOff(const byte *&str) { error("TODO: script opcode"); }
+OpcodeReturn TattooTalk::cmdSetNPCInfoLine(const byte *&str) { error("TODO: script opcode"); }
+OpcodeReturn TattooTalk::cmdSetNPCOff(const byte *&str) { error("TODO: script opcode"); }
+OpcodeReturn TattooTalk::cmdSetNPCOn(const byte *&str) { error("TODO: script opcode"); }
+OpcodeReturn TattooTalk::cmdSetNPCPathDest(const byte *&str) { error("TODO: script opcode"); }
+OpcodeReturn TattooTalk::cmdSetNPCPathPause(const byte *&str) { error("TODO: script opcode"); }
+OpcodeReturn TattooTalk::cmdSetNPCPathPauseTakingNotes(const byte *&str) { error("TODO: script opcode"); }
+OpcodeReturn TattooTalk::cmdSetNPCPathPauseLookingHolmes(const byte *&str) { error("TODO: script opcode"); }
+OpcodeReturn TattooTalk::cmdSetNPCPosition(const byte *&str) { error("TODO: script opcode"); }
+OpcodeReturn TattooTalk::cmdSetNPCTalkFile(const byte *&str) { error("TODO: script opcode"); }
+OpcodeReturn TattooTalk::cmdSetNPCVerb(const byte *&str) { error("TODO: script opcode"); }
+OpcodeReturn TattooTalk::cmdSetNPCVerbCAnimation(const byte *&str) { error("TODO: script opcode"); }
+OpcodeReturn TattooTalk::cmdSetNPCVerbScript(const byte *&str) { error("TODO: script opcode"); }
+OpcodeReturn TattooTalk::cmdSetNPCVerbTarget(const byte *&str) { error("TODO: script opcode"); }
+
+OpcodeReturn TattooTalk::cmdSetNPCWalkGraphics(const byte *&str) {
+ ++str;
+ int npc = *str - 1;
+ People &people = *_vm->_people;
+ Person &person = people[npc];
+
+ // 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) { error("TODO: script opcode"); }
+OpcodeReturn TattooTalk::cmdSetTalkSequence(const byte *&str) { error("TODO: script opcode"); }
+OpcodeReturn TattooTalk::cmdSetWalkControl(const byte *&str) { error("TODO: script opcode"); }
+OpcodeReturn TattooTalk::cmdTalkInterruptsDisable(const byte *&str) { error("TODO: script opcode"); }
+OpcodeReturn TattooTalk::cmdTalkInterruptsEnable(const byte *&str) { error("TODO: script opcode"); }
+OpcodeReturn TattooTalk::cmdTurnSoundsOff(const byte *&str) { error("TODO: script opcode"); }
+OpcodeReturn TattooTalk::cmdWalkHolmesAndNPCToCAnimation(const byte *&str) { error("TODO: script opcode"); }
+OpcodeReturn TattooTalk::cmdWalkNPCToCAnimation(const byte *&str) { error("TODO: script opcode"); }
+OpcodeReturn TattooTalk::cmdWalkNPCToCoords(const byte *&str) { error("TODO: script opcode"); }
+OpcodeReturn TattooTalk::cmdWalkHomesAndNPCToCoords(const byte *&str) { error("TODO: script opcode"); }
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h
new file mode 100644
index 0000000000..ebfe8f1732
--- /dev/null
+++ b/engines/sherlock/talk.h
@@ -0,0 +1,408 @@
+/* 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/serializer.h"
+#include "common/stream.h"
+#include "common/stack.h"
+
+namespace Sherlock {
+
+#define MAX_TALK_SEQUENCES 11
+#define MAX_TALK_FILES 500
+
+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_CARRIAGE_RETURN = 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_HOLMES_AND_NPC_TO_COORDS = 45,
+ OP_SET_NPC_TALK_FILE = 46,
+ OP_TURN_NPC_OFF = 47,
+ OP_TURN_NPC_ON = 48,
+ OP_NPC_DESC_ON_OFF = 49,
+ OP_NPC_PATH_PAUSE_TAKING_NOTES = 50,
+ OP_NPC_PATH_PAUSE_LOOKING_HOLMES = 51,
+ OP_ENABLE_TALK_INTERRUPTS = 52,
+ OP_DISABLE_TALK_INTERRUPTS = 53,
+ OP_SET_NPC_INFO_LINE = 54,
+ OP_SET_NPC_POSITION = 54,
+ OP_NPC_PATH_LABEL = 55,
+ OP_PATH_GOTO_LABEL = 56,
+ OP_PATH_IF_FLAG_GOTO_LABEL = 57,
+ OP_NPC_WALK_GRAPHICS = 58,
+ OP_NPC_VERB = 59,
+ OP_NPC_VERB_CANIM = 60,
+ OP_NPC_VERB_SCRIPT = 61,
+ OP_RESTORE_PEOPLE_SEQUENCE = 62,
+ OP_NPC_VERB_TARGET = 63,
+ OP_TURN_SOUNDS_OFF = 64
+};
+
+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;
+
+ /**
+ * Load the data for a single statement within a talk file
+ */
+ void synchronize(Common::SeekableReadStream &s);
+};
+
+struct TalkHistoryEntry {
+ bool _data[16];
+
+ TalkHistoryEntry();
+ bool &operator[](int index) { return _data[index]; }
+};
+
+struct TalkSequences {
+ byte _data[MAX_TALK_SEQUENCES];
+
+ TalkSequences() { clear(); }
+ TalkSequences(const byte *data);
+
+ byte &operator[](int idx) { return _data[idx]; }
+ void clear();
+};
+
+class Talk {
+ friend class Scalpel::ScalpelUserInterface;
+private:
+ /**
+ * Remove any voice commands from a loaded statement list
+ */
+ void stripVoiceCommands();
+
+ /**
+ * Form a table of the display indexes for statements
+ */
+ void setTalkMap();
+
+ /**
+ * 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);
+
+ /**
+ * 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);
+
+ /**
+ * 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);
+protected:
+ SherlockEngine *_vm;
+ OpcodeMethod *_opcodeTable;
+ Common::Stack<SequenceEntry> _savedSequences;
+ Common::Stack<SequenceEntry> _sequenceStack;
+ Common::Stack<ScriptStackEntry> _scriptStack;
+ Common::Array<Statement> _statements;
+ TalkHistoryEntry _talkHistory[MAX_TALK_FILES];
+ 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 cmdGotoScene(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 cmdSwitchSpeaker(const byte *&str);
+ OpcodeReturn cmdToggleObject(const byte *&str);
+ OpcodeReturn cmdWalkToCAnimation(const byte *&str);
+ OpcodeReturn cmdWalkToCoords(const byte *&str);
+public:
+ bool _talkToAbort;
+ int _talkCounter;
+ int _talkTo;
+ int _scriptMoreFlag;
+ 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);
+
+ /**
+ * 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();
+
+ /**
+ * Draws the interface for conversation display
+ */
+ void drawInterface();
+
+ /**
+ * 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);
+
+ /**
+ * Change the sequence of the scene background object associated with the current speaker.
+ */
+ void setSequence(int speaker);
+
+ /**
+ * 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(Common::Serializer &s);
+};
+
+class ScalpelTalk : public Talk {
+protected:
+ OpcodeReturn cmdAssignPortraitLocation(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 cmdCarriageReturn(const byte *&str);
+public:
+ ScalpelTalk(SherlockEngine *vm);
+ virtual ~ScalpelTalk() {}
+};
+
+class TattooTalk : public Talk {
+protected:
+ OpcodeReturn cmdMouseOnOff(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);
+public:
+ TattooTalk(SherlockEngine *vm);
+ virtual ~TattooTalk() {}
+};
+
+} // 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..368b24bfcd
--- /dev/null
+++ b/engines/sherlock/tattoo/tattoo.cpp
@@ -0,0 +1,81 @@
+/* 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.h"
+#include "engines/util.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+TattooEngine::TattooEngine(OSystem *syst, const SherlockGameDescription *gameDesc) :
+ SherlockEngine(syst, gameDesc) {
+ _creditsActive = false;
+}
+
+void TattooEngine::showOpening() {
+ // TODO
+}
+
+void TattooEngine::initialize() {
+ initGraphics(640, 480, true);
+
+ // Initialize the base engine
+ SherlockEngine::initialize();
+
+ _flags.resize(100 * 8);
+
+ // Add some more files to the cache
+ _res->addToCache("walk.lib");
+
+ // Starting scene
+ _scene->_goToScene = 91;
+
+ // Load an initial palette
+ loadInitialPalette();
+}
+
+void TattooEngine::startScene() {
+ // TODO
+}
+
+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::drawCredits() {
+ // TODO
+}
+
+void TattooEngine::eraseCredits() {
+ // TODO
+}
+
+} // End of namespace Tattoo
+
+} // End of namespace Scalpel
diff --git a/engines/sherlock/tattoo/tattoo.h b/engines/sherlock/tattoo/tattoo.h
new file mode 100644
index 0000000000..bb6310dbe3
--- /dev/null
+++ b/engines/sherlock/tattoo/tattoo.h
@@ -0,0 +1,71 @@
+/* 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"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+class TattooEngine : public SherlockEngine {
+private:
+ /**
+ * Loads the initial palette for the game
+ */
+ void loadInitialPalette();
+protected:
+ /**
+ * Initialize the engine
+ */
+ virtual void initialize();
+
+ virtual void showOpening();
+
+ /**
+ * Starting a scene within the game
+ */
+ virtual void startScene();
+public:
+ bool _creditsActive;
+public:
+ TattooEngine(OSystem *syst, const SherlockGameDescription *gameDesc);
+ virtual ~TattooEngine() {}
+
+ /**
+ * Draw credits on the screen
+ */
+ void drawCredits();
+
+ /**
+ * Erase any area of the screen covered by credits
+ */
+ void eraseCredits();
+};
+
+} // 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..2a13b2a450
--- /dev/null
+++ b/engines/sherlock/tattoo/tattoo_scene.cpp
@@ -0,0 +1,401 @@
+/* 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.h"
+#include "sherlock/tattoo/tattoo_user_interface.h"
+#include "sherlock/events.h"
+#include "sherlock/people.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+TattooScene::TattooScene(SherlockEngine *vm) : Scene(vm) {
+ _arrowZone = -1;
+ _mask = _mask1 = nullptr;
+ _maskCounter = 0;
+}
+
+void TattooScene::checkBgShapes() {
+ People &people = *_vm->_people;
+ Person &holmes = people._player;
+ 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();
+
+ // Check for any active playing animation
+ if (_activeCAnim._images && _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;
+ UserInterface &ui = *_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 && _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);
+ }
+}
+
+void TattooScene::doBgAnimEraseBackground() {
+ TattooEngine &vm = *((TattooEngine *)_vm);
+ People &people = *_vm->_people;
+ Screen &screen = *_vm->_screen;
+ TattooUserInterface &ui = *((TattooUserInterface *)_vm->_ui);
+
+ static const int16 OFFSETS[16] = { -1, -2, -3, -3, -2, -1, -1, 0, 1, 2, 3, 3, 2, 1, 0, 0 };
+
+ if (_mask != nullptr) {
+ if (screen._backBuffer1.w() > screen.w())
+ screen.blitFrom(screen._backBuffer1, Common::Point(0, 0), Common::Rect(screen._currentScroll, 0,
+ screen._currentScroll + screen.w(), screen.h()));
+ else
+ screen.blitFrom(screen._backBuffer1);
+
+ switch (_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
+ ui.doBgAnimRestoreUI();
+
+ // Restore background for any areas covered by characters and shapes
+ for (uint 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 < _bgShapes.size(); ++idx) {
+ Object &obj = _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(*obj._imageFrame, 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 < _bgShapes.size(); ++idx) {
+ Object &obj = _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) <
+ (SHERLOCK_SCREEN_WIDTH / 8) && people[people._walkControl]._delta.x < 0) {
+
+ screen._targetScroll = (short)(people[people._walkControl]._position.x / FIXED_INT_MULTIPLIER -
+ SHERLOCK_SCREEN_WIDTH / 8 - 250);
+ if (screen._targetScroll < 0)
+ screen._targetScroll = 0;
+ }
+
+ if ((people[people._walkControl]._position.x / FIXED_INT_MULTIPLIER - screen._currentScroll) > (SHERLOCK_SCREEN_WIDTH / 4 * 3)
+ && people[people._walkControl]._delta.x > 0)
+ screen._targetScroll = (short)(people[people._walkControl]._position.x / FIXED_INT_MULTIPLIER -
+ SHERLOCK_SCREEN_WIDTH / 4 * 3 + 250);
+
+ if (screen._targetScroll > screen._scrollSize)
+ screen._targetScroll = screen._scrollSize;
+
+ ui.doScroll();
+}
+
+void TattooScene::doBgAnim() {
+ TattooUserInterface &ui = *((TattooUserInterface *)_vm->_ui);
+
+ doBgAnimCheckCursor();
+
+// Events &events = *_vm->_events;
+ People &people = *_vm->_people;
+// Scene &scene = *_vm->_scene;
+ Screen &screen = *_vm->_screen;
+ Talk &talk = *_vm->_talk;
+
+ screen.setDisplayBounds(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT));
+ talk._talkToAbort = false;
+
+ // Check the characters and sprites for updates
+ for (uint 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();
+ }
+
+ // Erase any affected background areas
+ doBgAnimEraseBackground();
+
+ doBgAnimUpdateBgObjectsAndAnim();
+
+ ui.drawInterface();
+}
+
+void TattooScene::doBgAnimUpdateBgObjectsAndAnim() {
+ People &people = *_vm->_people;
+ Screen &screen = *_vm->_screen;
+
+ 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 (uint idx = 0; idx < MAX_CHARACTERS; ++idx) {
+ if (people[idx]._type == CHARACTER)
+ people[idx].adjustSprite();
+ }
+
+ if ((_activeCAnim._images != nullptr) && (_activeCAnim._zPlacement != REMOVE)) {
+ _activeCAnim.getNextFrame();
+ }
+
+ // Flag the bg shapes which need to be redrawn
+ checkBgShapes();
+ drawAllShapes();
+
+
+ if (_mask != nullptr) {
+ switch (_currentScene) {
+ case 7:
+ screen._backBuffer1.maskArea((*_mask)[0], Common::Point(_maskOffset.x - SHERLOCK_SCREEN_WIDTH, 110), screen._currentScroll);
+ screen._backBuffer1.maskArea((*_mask)[0], Common::Point(_maskOffset.x, 110), screen._currentScroll);
+ screen._backBuffer1.maskArea((*_mask)[0], Common::Point(_maskOffset.x + SHERLOCK_SCREEN_WIDTH, 110), screen._currentScroll);
+ break;
+
+ case 8:
+ screen._backBuffer1.maskArea((*_mask)[0], Common::Point(_maskOffset.x - SHERLOCK_SCREEN_WIDTH, 180), screen._currentScroll);
+ screen._backBuffer1.maskArea((*_mask)[0], Common::Point(_maskOffset.x, 180), screen._currentScroll);
+ screen._backBuffer1.maskArea((*_mask)[0], Common::Point(_maskOffset.x + SHERLOCK_SCREEN_WIDTH, 180), screen._currentScroll);
+ if (!_vm->readFlags(880))
+ screen._backBuffer1.maskArea((*_mask1)[0], Common::Point(940, 300), screen._currentScroll);
+ break;
+
+ case 18:
+ screen._backBuffer1.maskArea((*_mask)[0], Common::Point(_maskOffset.x, 203), screen._currentScroll);
+ if (!_vm->readFlags(189))
+ screen._backBuffer1.maskArea((*_mask1)[0], Common::Point(124 + _maskOffset.x, 239), screen._currentScroll);
+ break;
+
+ case 53:
+ screen._backBuffer1.maskArea((*_mask)[0], Common::Point(_maskOffset.x, 110), screen._currentScroll);
+ screen._backBuffer1.maskArea((*_mask)[0], Common::Point(_maskOffset.x - SHERLOCK_SCREEN_WIDTH, 110), screen._currentScroll);
+ break;
+
+ case 68:
+ screen._backBuffer1.maskArea((*_mask)[0], Common::Point(_maskOffset.x, 203), screen._currentScroll);
+ screen._backBuffer1.maskArea((*_mask1)[0], Common::Point(124 + _maskOffset.x, 239), screen._currentScroll);
+ break;
+ }
+ }
+}
+
+
+void TattooScene::updateBackground() {
+ People &people = *_vm->_people;
+ Screen &screen = *_vm->_screen;
+
+ Scene::updateBackground();
+
+ if (_mask != nullptr) {
+ switch (_currentScene) {
+ case 7:
+ screen._backBuffer1.maskArea((*_mask)[0], Common::Point(_maskOffset.x - SHERLOCK_SCREEN_WIDTH, 110), screen._currentScroll);
+ screen._backBuffer1.maskArea((*_mask)[0], Common::Point(_maskOffset.x, 110), screen._currentScroll);
+ screen._backBuffer1.maskArea((*_mask)[0], Common::Point(_maskOffset.x + SHERLOCK_SCREEN_WIDTH, 110), screen._currentScroll);
+ break;
+
+ case 8:
+ screen._backBuffer1.maskArea((*_mask)[0], Common::Point(_maskOffset.x - SHERLOCK_SCREEN_WIDTH, 180), screen._currentScroll);
+ screen._backBuffer1.maskArea((*_mask)[0], Common::Point(_maskOffset.x, 180), screen._currentScroll);
+ screen._backBuffer1.maskArea((*_mask)[0], Common::Point(_maskOffset.x + SHERLOCK_SCREEN_WIDTH, 180), screen._currentScroll);
+ if (!_vm->readFlags(880))
+ screen._backBuffer1.maskArea((*_mask1)[0], Common::Point(940, 300), screen._currentScroll);
+ break;
+
+ case 18:
+ screen._backBuffer1.maskArea((*_mask)[0], Common::Point(0, 203), screen._currentScroll);
+ if (!_vm->readFlags(189))
+ screen._backBuffer1.maskArea((*_mask1)[0], Common::Point(124, 239), screen._currentScroll);
+ break;
+
+ case 53:
+ screen._backBuffer1.maskArea((*_mask)[0], Common::Point(_maskOffset.x, 110), screen._currentScroll);
+ break;
+
+ case 68:
+ screen._backBuffer1.maskArea((*_mask)[0], Common::Point(0, 203), screen._currentScroll);
+ screen._backBuffer1.maskArea((*_mask1)[0], Common::Point(124, 239), screen._currentScroll);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ screen._flushScreen = true;
+
+ for (int idx = 0; idx < MAX_CHARACTERS; ++idx) {
+ Person &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 == 256) {
+ 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 == 256)
+ 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 == 256)
+ 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;
+}
+
+
+} // 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..de28306c1b
--- /dev/null
+++ b/engines/sherlock/tattoo/tattoo_scene.h
@@ -0,0 +1,77 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SHERLOCK_TATTOO_SCENE_H
+#define SHERLOCK_TATTOO_SCENE_H
+
+#include "common/scummsys.h"
+#include "sherlock/scene.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+class TattooScene : public Scene {
+private:
+ int _arrowZone;
+ int _maskCounter;
+ Common::Point _maskOffset;
+private:
+ void doBgAnimCheckCursor();
+
+ void doBgAnimEraseBackground();
+
+ /**
+ * Update the background objects and canimations as part of doBgAnim
+ */
+ void doBgAnimUpdateBgObjectsAndAnim();
+protected:
+ /**
+ * 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();
+public:
+ ImageFile *_mask, *_mask1;
+ CAnimStream _activeCAnim;
+public:
+ TattooScene(SherlockEngine *vm);
+
+ /**
+ * 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();
+
+};
+
+} // 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..e76322833f
--- /dev/null
+++ b/engines/sherlock/tattoo/tattoo_user_interface.cpp
@@ -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.
+ *
+ */
+
+#include "sherlock/tattoo/tattoo_user_interface.h"
+#include "sherlock/tattoo/tattoo_scene.h"
+#include "sherlock/tattoo/tattoo.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+TattooUserInterface::TattooUserInterface(SherlockEngine *vm): UserInterface(vm) {
+ _menuBuffer = nullptr;
+ _invMenuBuffer = nullptr;
+ _tagBuffer = nullptr;
+ _invGraphic = nullptr;
+}
+
+void TattooUserInterface::handleInput() {
+ // TODO
+ _vm->_events->pollEventsAndWait();
+}
+
+void TattooUserInterface::drawInterface(int bufferNum) {
+ Screen &screen = *_vm->_screen;
+ TattooEngine &vm = *((TattooEngine *)_vm);
+
+ if (_invMenuBuffer != nullptr) {
+ Common::Rect r = _invMenuBounds;
+ r.grow(-3);
+ r.translate(-screen._currentScroll, 0);
+ _grayAreas.clear();
+ _grayAreas.push_back(r);
+
+ drawGrayAreas();
+ screen._backBuffer1.transBlitFrom(*_invMenuBuffer, Common::Point(_invMenuBounds.left, _invMenuBounds.top));
+ }
+
+ if (_menuBuffer != nullptr) {
+ Common::Rect r = _menuBounds;
+ r.grow(-3);
+ r.translate(-screen._currentScroll, 0);
+ _grayAreas.clear();
+ _grayAreas.push_back(r);
+
+ drawGrayAreas();
+ screen._backBuffer1.transBlitFrom(*_menuBuffer, Common::Point(_invMenuBounds.left, _invMenuBounds.top));
+ }
+
+ // See if we need to draw a Text Tag floating with the cursor
+ if (_tagBuffer != nullptr)
+ screen._backBuffer1.transBlitFrom(*_tagBuffer, Common::Point(_tagBounds.left, _tagBounds.top));
+
+ // See if we need to draw an Inventory Item Graphic floating with the cursor
+ if (_invGraphic != nullptr)
+ screen._backBuffer1.transBlitFrom(*_invGraphic, Common::Point(_invGraphicBounds.left, _invGraphicBounds.top));
+
+ if (vm._creditsActive)
+ vm.drawCredits();
+}
+
+void TattooUserInterface::doBgAnimRestoreUI() {
+ TattooScene &scene = *((TattooScene *)_vm->_scene);
+ Screen &screen = *_vm->_screen;
+
+ // If _oldMenuBounds was set, then either a new menu has been opened or the current menu has been closed.
+ // Either way, we need to restore the area where the menu was displayed
+ if (_oldMenuBounds.width() > 0)
+ screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(_oldMenuBounds.left, _oldMenuBounds.top),
+ _oldMenuBounds);
+
+ if (_oldInvMenuBounds.width() > 0)
+ screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(_oldInvMenuBounds.left, _oldInvMenuBounds.top),
+ _oldInvMenuBounds);
+
+ if (_menuBuffer != nullptr)
+ screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(_menuBounds.left, _menuBounds.top), _menuBounds);
+ if (_invMenuBuffer != nullptr)
+ screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(_invMenuBounds.left, _invMenuBounds.top), _invMenuBounds);
+
+ // If there is a Text Tag being display, restore the area underneath it
+ if (_oldTagBounds.width() > 0)
+ screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(_oldTagBounds.left, _oldTagBounds.top),
+ _oldTagBounds);
+
+ // If there is an Inventory being shown, restore the graphics underneath it
+ if (_oldInvGraphicBounds.width() > 0)
+ screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(_oldInvGraphicBounds.left, _oldInvGraphicBounds.top),
+ _oldInvGraphicBounds);
+
+ // If a canimation is active, restore the graphics underneath it
+ if (scene._activeCAnim._images != nullptr)
+ 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;
+ int oldScroll = screen._currentScroll;
+
+ // If we're already at the target scroll position, nothing needs to be done
+ if (screen._targetScroll == screen._currentScroll)
+ return;
+
+ screen._flushScreen = true;
+ if (screen._targetScroll > screen._currentScroll) {
+ screen._currentScroll += screen._scrollSpeed;
+ if (screen._currentScroll > screen._targetScroll)
+ screen._currentScroll = screen._targetScroll;
+ } else if (screen._targetScroll < screen._currentScroll) {
+ screen._currentScroll -= screen._scrollSpeed;
+ if (screen._currentScroll < screen._targetScroll)
+ screen._currentScroll = screen._targetScroll;
+ }
+
+ if (_menuBuffer != nullptr)
+ _menuBounds.translate(screen._currentScroll - oldScroll, 0);
+ if (_invMenuBuffer != nullptr)
+ _invMenuBounds.translate(screen._currentScroll - oldScroll, 0);
+}
+
+void TattooUserInterface::drawGrayAreas() {
+ // TODO
+}
+
+} // 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..2125f1ba07
--- /dev/null
+++ b/engines/sherlock/tattoo/tattoo_user_interface.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 SHERLOCK_TATTOO_UI_H
+#define SHERLOCK_TATTOO_UI_H
+
+#include "common/scummsys.h"
+#include "sherlock/user_interface.h"
+
+namespace Sherlock {
+
+namespace Tattoo {
+
+class TattooUserInterface : public UserInterface {
+private:
+ Common::Rect _menuBounds;
+ Common::Rect _oldMenuBounds;
+ Common::Rect _invMenuBounds;
+ Common::Rect _oldInvMenuBounds;
+ Common::Rect _tagBounds;
+ Common::Rect _oldTagBounds;
+ Common::Rect _invGraphicBounds;
+ Common::Rect _oldInvGraphicBounds;
+ Surface *_menuBuffer;
+ Surface *_invMenuBuffer;
+ Surface *_tagBuffer;
+ Surface *_invGraphic;
+ Common::Array<Common::Rect> _grayAreas;
+private:
+ /**
+ * Draws designated areas of the screen that are meant to be grayed out using grayscale colors
+ */
+ void drawGrayAreas();
+public:
+ TattooUserInterface(SherlockEngine *vm);
+
+ /**
+ * 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();
+public:
+ virtual ~TattooUserInterface() {}
+
+ /**
+ * 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);
+};
+
+} // 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..9fff7cc999
--- /dev/null
+++ b/engines/sherlock/user_interface.cpp
@@ -0,0 +1,56 @@
+/* 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/sherlock.h"
+#include "sherlock/scalpel/scalpel_user_interface.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;
+
+ _key = _oldKey = '\0';
+ _selector = _oldSelector = -1;
+ _temp = _oldTemp = 0;
+ _temp1 = 0;
+ _lookHelp = 0;
+}
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h
new file mode 100644
index 0000000000..042997a3e2
--- /dev/null
+++ b/engines/sherlock/user_interface.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_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"
+
+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
+};
+
+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;
+
+ // 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
+ char _key, _oldKey;
+ int _selector, _oldSelector;
+ int _temp, _oldTemp;
+ int _temp1;
+ int _lookHelp;
+public:
+ static UserInterface *init(SherlockEngine *vm);
+ virtual ~UserInterface() {}
+
+ /**
+ * 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() {}
+
+ /**
+ * Print the previously selected object's decription
+ */
+ virtual void printObjectDesc() {}
+};
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sword1/console.cpp b/engines/sword1/console.cpp
index 7fabc62192..3a4b51965b 100644
--- a/engines/sword1/console.cpp
+++ b/engines/sword1/console.cpp
@@ -36,7 +36,7 @@ SwordConsole::SwordConsole(SwordEngine *vm) : GUI::Debugger(), _vm(vm) {
SwordConsole::~SwordConsole() {
}
-
+
bool SwordConsole::Cmd_SpeechEndianness(int argc, const char **argv) {
if (argc == 1) {
debugPrintf("Using %s speech\n", _vm->_sound->_bigEndianSpeech ? "be" : "le");
diff --git a/engines/sword1/sound.cpp b/engines/sword1/sound.cpp
index 9140bddb65..4deaf06edc 100644
--- a/engines/sword1/sound.cpp
+++ b/engines/sword1/sound.cpp
@@ -144,7 +144,7 @@ void Sound::checkSpeechFileEndianness() {
debug(8, "Speech endianness heuristic: average = %f for BE and %f for LE (%d samples)", be_diff, le_diff, maxSamples);
}
}
-
+
double Sound::endiannessHeuristicValue(int16* data, uint32 dataSize, uint32 &maxSamples) {
if (!data)
return 50000.; // the heuristic value for the wrong endianess is about 21000 (1/3rd of the 16 bits range)
diff --git a/engines/sword25/gfx/renderobjectmanager.cpp b/engines/sword25/gfx/renderobjectmanager.cpp
index 4927b4c58e..8aeecad6b1 100644
--- a/engines/sword25/gfx/renderobjectmanager.cpp
+++ b/engines/sword25/gfx/renderobjectmanager.cpp
@@ -107,7 +107,7 @@ bool RenderObjectManager::render() {
if (!_currQueue->exists(*it))
_uta->addRect((*it)._bbox);
}
-
+
// Add rectangles of objects which are different from the previous frame
for (RenderObjectQueue::iterator it = _currQueue->begin(); it != _currQueue->end(); ++it) {
if (!_prevQueue->exists(*it))
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/sword25.cpp b/engines/sword25/sword25.cpp
index bb0aab3ad4..76142c2534 100644
--- a/engines/sword25/sword25.cpp
+++ b/engines/sword25/sword25.cpp
@@ -57,7 +57,6 @@ DECLARE_SINGLETON(Sword25::RenderObjectRegistry);
namespace Sword25 {
-const char *const PACKAGE_MANAGER = "archiveFS";
const char *const DEFAULT_SCRIPT_FILE = "/system/boot.lua";
Sword25Engine::Sword25Engine(OSystem *syst, const ADGameDescription *gameDesc):
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/lapi.cpp b/engines/sword25/util/lua/lapi.cpp
index b97e90012c..d7ebdcbe12 100644
--- a/engines/sword25/util/lua/lapi.cpp
+++ b/engines/sword25/util/lua/lapi.cpp
@@ -30,11 +30,12 @@
#include "common/textconsole.h"
+#if 0
const char lua_ident[] =
"Lua: " LUA_RELEASE " " LUA_COPYRIGHT " \n"
"Authors: " LUA_AUTHORS " \n"
"URL: www.lua.org\n";
-
+#endif
#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base))
diff --git a/engines/sword25/util/lua/liolib.cpp b/engines/sword25/util/lua/liolib.cpp
index 0d27f9677f..403dea2ec2 100644
--- a/engines/sword25/util/lua/liolib.cpp
+++ b/engines/sword25/util/lua/liolib.cpp
@@ -24,7 +24,7 @@
#define IO_OUTPUT 2
-static const char *const fnames[] = {"input", "output"};
+//static const char *const fnames[] = {"input", "output"};
static int pushresult (lua_State *L, int i, const char *filename) {
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 78b0a815e8..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/tinsel.cpp b/engines/tinsel/tinsel.cpp
index 31610a8467..57d8432f0e 100644
--- a/engines/tinsel/tinsel.cpp
+++ b/engines/tinsel/tinsel.cpp
@@ -821,7 +821,8 @@ const char *const TinselEngine::_textFiles[][3] = {
TinselEngine::TinselEngine(OSystem *syst, const TinselGameDescription *gameDesc) :
- Engine(syst), _gameDescription(gameDesc), _random("tinsel") {
+ Engine(syst), _gameDescription(gameDesc), _random("tinsel"),
+ _sound(0), _midiMusic(0), _pcmMusic(0), _bmv(0) {
_vm = this;
_config = new Config(this);
@@ -846,13 +847,6 @@ TinselEngine::TinselEngine(OSystem *syst, const TinselGameDescription *gameDesc)
if (cd_num >= 0)
_system->getAudioCDManager()->openCD(cd_num);
- _midiMusic = new MidiMusicPlayer();
- _pcmMusic = new PCMMusicPlayer();
-
- _sound = new SoundManager(this);
-
- _bmv = new BMVPlayer();
-
_mousePos.x = 0;
_mousePos.y = 0;
_keyHandler = NULL;
@@ -896,6 +890,11 @@ void TinselEngine::initializePath(const Common::FSNode &gamePath) {
}
Common::Error TinselEngine::run() {
+ _midiMusic = new MidiMusicPlayer();
+ _pcmMusic = new PCMMusicPlayer();
+ _sound = new SoundManager(this);
+ _bmv = new BMVPlayer();
+
// Initialize backend
if (getGameID() == GID_DW2) {
#ifndef DW2_EXACT_SIZE
diff --git a/engines/tony/game.cpp b/engines/tony/game.cpp
index c102242dfd..0a2c62330b 100644
--- a/engines/tony/game.cpp
+++ b/engines/tony/game.cpp
@@ -1557,14 +1557,14 @@ void RMPointer::updateCursor() {
for (int i = 0; i < 64; i++) {
uint16 *lineP = src;
for (int j = 0; j < 64; j++) {
- lineP[j] = RMGfxTargetBuffer::_precalcTable[lineP[j] & 0x7FFF];
+ lineP[j] = RMGfxTargetBuffer::_precalcTable[lineP[j]];
}
src += 64;
}
}
// Get the raw pixel data and set the cursor to it
- Graphics::PixelFormat pixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0);
+ Graphics::PixelFormat pixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
CursorMan.replaceCursor(cursorData, 64, 64, _cursorHotspot._x, _cursorHotspot._y, 0, 1, &pixelFormat);
}
diff --git a/engines/tony/gfxcore.cpp b/engines/tony/gfxcore.cpp
index 9254d59df6..2a32926c53 100644
--- a/engines/tony/gfxcore.cpp
+++ b/engines/tony/gfxcore.cpp
@@ -422,11 +422,11 @@ uint16 *RMGfxTargetBuffer::_precalcTable = NULL;
* called if the user selects the black & white option.
*/
void RMGfxTargetBuffer::createBWPrecalcTable() {
- _precalcTable = new uint16[0x8000];
+ _precalcTable = new uint16[0x10000];
- for (int i = 0; i < 0x8000; i++) {
- int r = (i >> 10) & 0x1F;
- int g = (i >> 5) & 0x1F;
+ for (int i = 0; i < 0x10000; i++) {
+ int r = (i >> 11) & 0x1F;
+ int g = (i >> 6) & 0x1F;
int b = i & 0x1F;
int min = MIN(r, MIN(g, b));
@@ -434,11 +434,11 @@ void RMGfxTargetBuffer::createBWPrecalcTable() {
min = (min + max) / 2;
- r = CLIP(min + 8 - 8, 0, 31);
- g = CLIP(min + 5 - 8, 0, 31);
- b = CLIP(min + 0 - 8, 0, 31);
+ r = CLIP(min + 8 - 8, 0, 0x1f);
+ g = CLIP(min + 5 - 8, 0, 0x1f);
+ b = CLIP(min + 0 - 8, 0, 0x1f);
- _precalcTable[i] = (r << 10) | (g << 5) | b;
+ _precalcTable[i] = (r << 11) | (g << 6) | b;
}
}
@@ -512,8 +512,9 @@ int RMGfxSourceBufferPal::loadPalette(const byte *buf) {
void RMGfxSourceBufferPal::preparePalette() {
for (int i = 0; i < 256; i++) {
- _palFinal[i] = (((int)_pal[i * 3 + 0] >> 3) << 10) |
- (((int)_pal[i * 3 + 1] >> 3) << 5) |
+ // we convert 555 to 565 here.
+ _palFinal[i] = (((int)_pal[i * 3 + 0] >> 3) << 11) |
+ (((int)_pal[i * 3 + 1] >> 3) << 6) |
(((int)_pal[i * 3 + 2] >> 3) << 0);
}
}
@@ -665,8 +666,8 @@ void RMGfxSourceBuffer8::create(int dimx, int dimy) {
RMGfxBuffer::create(dimx, dimy, 8);
}
-#define GETRED(x) (((x) >> 10) & 0x1F)
-#define GETGREEN(x) (((x) >> 5) & 0x1F)
+#define GETRED(x) (((x) >> 11) & 0x1F)
+#define GETGREEN(x) (((x) >> 5) & 0x3F)
#define GETBLUE(x) ((x) & 0x1F)
/****************************************************************************\
@@ -684,13 +685,13 @@ int RMGfxSourceBuffer8AB::calcTrasp(int fore, int back) {
if (r > 0x1F)
r = 0x1F;
- if (g > 0x1F)
- g = 0x1F;
+ if (g > 0x3F)
+ g = 0x3F;
if (b > 0x1F)
b = 0x1F;
- return (r << 10) | (g << 5) | b;
+ return (r << 11) | (g << 5) | b;
}
void RMGfxSourceBuffer8AB::draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) {
@@ -802,8 +803,8 @@ void RMGfxSourceBuffer8RLE::preparePalette() {
// Handle RGB alpha blending
if (_alphaBlendColor != -1) {
- _alphaR = (_palFinal[_alphaBlendColor] >> 10) & 0x1F;
- _alphaG = (_palFinal[_alphaBlendColor] >> 5) & 0x1F;
+ _alphaR = (_palFinal[_alphaBlendColor] >> 11) & 0x1F;
+ _alphaG = (_palFinal[_alphaBlendColor] >> 5) & 0x3F;
_alphaB = (_palFinal[_alphaBlendColor]) & 0x1F;
}
}
@@ -1054,15 +1055,15 @@ RLEByteDoAlpha2:
if (n > nLength)
n = nLength;
for (int i = 0; i < n; i++) {
- int r = (*dst >> 10) & 0x1F;
- int g = (*dst >> 5) & 0x1F;
+ int r = (*dst >> 11) & 0x1F;
+ int g = (*dst >> 5) & 0x3F;
int b = *dst & 0x1F;
r = (r >> 2) + (_alphaR >> 1);
g = (g >> 2) + (_alphaG >> 1);
b = (b >> 2) + (_alphaB >> 1);
- *dst ++ = (r << 10) | (g << 5) | b;
+ *dst ++ = (r << 11) | (g << 5) | b;
}
nLength -= n;
@@ -1158,15 +1159,15 @@ RLEByteFlippedDoAlpha2:
if (n > nLength)
n = nLength;
for (int i = 0; i < n; i++) {
- int r = (*dst >> 10) & 0x1F;
- int g = (*dst >> 5) & 0x1F;
+ int r = (*dst >> 11) & 0x1F;
+ int g = (*dst >> 5) & 0x3F;
int b = *dst & 0x1F;
r = (r >> 2) + (_alphaR >> 1);
g = (g >> 2) + (_alphaG >> 1);
b = (b >> 2) + (_alphaB >> 1);
- *dst-- = (r << 10) | (g << 5) | b;
+ *dst-- = (r << 11) | (g << 5) | b;
}
nLength -= n;
@@ -1302,15 +1303,15 @@ RLEWordDoAlpha2:
n = nLength;
for (int i = 0; i < n; i++) {
- int r = (*dst >> 10) & 0x1F;
- int g = (*dst >> 5) & 0x1F;
+ int r = (*dst >> 11) & 0x1F;
+ int g = (*dst >> 5) & 0x3F;
int b = *dst & 0x1F;
r = (r >> 2) + (_alphaR >> 1);
g = (g >> 2) + (_alphaG >> 1);
b = (b >> 2) + (_alphaB >> 1);
- *dst++ = (r << 10) | (g << 5) | b;
+ *dst++ = (r << 11) | (g << 5) | b;
}
nLength -= n;
@@ -1416,15 +1417,15 @@ RLEWordFlippedDoAlpha2:
n = nLength;
for (int i = 0; i < n; i++) {
- int r = (*dst >> 10) & 0x1F;
- int g = (*dst >> 5) & 0x1F;
+ int r = (*dst >> 11) & 0x1F;
+ int g = (*dst >> 5) & 0x3F;
int b = *dst & 0x1F;
r = (r >> 2) + (_alphaR >> 1);
g = (g >> 2) + (_alphaG >> 1);
b = (b >> 2) + (_alphaB >> 1);
- *dst-- = (r << 10) | (g << 5) | b;
+ *dst-- = (r << 11) | (g << 5) | b;
}
nLength -= n;
@@ -1543,15 +1544,15 @@ RLEWordDoAlpha2:
// @@@ SHOULD NOT BE THERE !!!!!
for (int i = 0; i < n; i++) {
- int r = (*dst >> 10) & 0x1F;
- int g = (*dst >> 5) & 0x1F;
+ int r = (*dst >> 11) & 0x1F;
+ int g = (*dst >> 5) & 0x3F;
int b = *dst & 0x1F;
r = (r >> 2) + (_alphaR >> 1);
g = (g >> 2) + (_alphaG >> 1);
b = (b >> 2) + (_alphaB >> 1);
- *dst++ = (r << 10) | (g << 5) | b;
+ *dst++ = (r << 11) | (g << 5) | b;
}
nLength -= n;
@@ -1570,19 +1571,19 @@ RLEWordDoCopy2:
n = nLength;
for (int i = 0; i < n; i++) {
- int r = (*dst >> 10) & 0x1F;
- int g = (*dst >> 5) & 0x1F;
+ int r = (*dst >> 11) & 0x1F;
+ int g = (*dst >> 5) & 0x3F;
int b = *dst & 0x1F;
- int r2 = (_palFinal[*src] >> 10) & 0x1F;
- int g2 = (_palFinal[*src] >> 5) & 0x1F;
+ int r2 = (_palFinal[*src] >> 11) & 0x1F;
+ int g2 = (_palFinal[*src] >> 5) & 0x3F;
int b2 = _palFinal[*src] & 0x1F;
r = (r >> 1) + (r2 >> 1);
g = (g >> 1) + (g2 >> 1);
b = (b >> 1) + (b2 >> 1);
- *dst ++ = (r << 10) | (g << 5) | b;
+ *dst ++ = (r << 11) | (g << 5) | b;
src++;
}
@@ -1732,14 +1733,14 @@ void RMGfxSourceBuffer8AA::drawAA(RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *pri
g /= 5;
b /= 5;
- if (r > 31)
- r = 31;
- if (g > 31)
- g = 31;
- if (b > 31)
- b = 31;
+ if (r > 0x1f)
+ r = 0x1f;
+ if (g > 0x3f)
+ g = 0x3f;
+ if (b > 0x1f)
+ b = 0x1f;
- mybuf[0] = (r << 10) | (g << 5) | b;
+ mybuf[0] = (r << 11) | (g << 5) | b;
}
}
@@ -1773,14 +1774,14 @@ void RMGfxSourceBuffer8AA::drawAA(RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *pri
g /= 6;
b /= 6;
- if (r > 31)
- r = 31;
- if (g > 31)
- g = 31;
- if (b > 31)
- b = 31;
+ if (r > 0x1f)
+ r = 0x1f;
+ if (g > 0x3f)
+ g = 0x3f;
+ if (b > 0x1f)
+ b = 0x1f;
- mybuf[0] = (r << 10) | (g << 5) | b;
+ mybuf[0] = (r << 11) | (g << 5) | b;
}
}
@@ -1948,8 +1949,17 @@ void RMGfxSourceBuffer16::prepareImage() {
// Color space conversion if necessary!
uint16 *buf = (uint16 *)_buf;
- for (int i = 0; i < _dimx * _dimy; i++)
- buf[i] = FROM_LE_16(buf[i]) & 0x7FFF;
+ // convert 555 to 565
+ for (int i = 0; i < _dimx * _dimy; i++) {
+ uint16 pixel = FROM_LE_16(buf[i]);
+ int r = (pixel >> 10) & 0x1F;
+ int g = (pixel >> 5) & 0x1F;
+ int b = pixel & 0x1F;
+
+ pixel = (r << 11) | (g << 6) | b;
+
+ buf[i] = pixel;
+ }
}
RMGfxSourceBuffer16::RMGfxSourceBuffer16(int dimx, int dimy)
@@ -1983,7 +1993,8 @@ void RMGfxBox::setColor(byte r, byte g, byte b) {
r >>= 3;
g >>= 3;
b >>= 3;
- _wFillColor = (r << 10) | (g << 5) | b;
+ // These are hard-coded colors, so we convert 555 to 565.
+ _wFillColor = (r << 11) | (g << 6) | b;
}
void RMGfxBox::draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) {
diff --git a/engines/tony/mpal/lzo.cpp b/engines/tony/mpal/lzo.cpp
index 314d6f3ed5..6cc2333315 100644
--- a/engines/tony/mpal/lzo.cpp
+++ b/engines/tony/mpal/lzo.cpp
@@ -116,7 +116,7 @@ int lzo1x_decompress(const byte *in, uint32 in_len, byte *out, uint32 *out_len)
*op++ = *ip++;
*op++ = *ip++;
*op++ = *ip++;
- do
+ do
*op++ = *ip++;
while (--t > 0);
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 5c50a50a57..3b3687419b 100644
--- a/engines/tony/window.cpp
+++ b/engines/tony/window.cpp
@@ -53,9 +53,9 @@ RMWindow::~RMWindow() {
* Initializes the graphics window
*/
void RMWindow::init() {
- Graphics::PixelFormat pixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0);
+ Graphics::PixelFormat pixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
initGraphics(RM_SX, RM_SY, true, &pixelFormat);
-
+
reset();
}
@@ -83,7 +83,7 @@ void RMWindow::copyRectToScreen(const byte *buf, int pitch, int x, int y, int w,
for (int i = 0; i < h; i++) {
uint16 *dst = (uint16 *)screen->getBasePtr(x, y + i);
for (int j = 0; j < w; j++) {
- dst[j] = RMGfxTargetBuffer::_precalcTable[src[j] & 0x7FFF];
+ dst[j] = RMGfxTargetBuffer::_precalcTable[src[j]];
}
src += (pitch / 2);
}
@@ -291,8 +291,8 @@ void RMSnapshot::grabScreenshot(byte *lpBuf, int dezoom, uint16 *lpDestBuf) {
cursrc = &src[RM_SKIPX + x];
*curOut++ = ((*cursrc) & 0x1F) << 3;
- *curOut++ = (((*cursrc) >> 5) & 0x1F) << 3;
- *curOut++ = (((*cursrc) >> 10) & 0x1F) << 3;
+ *curOut++ = (((*cursrc) >> 5) & 0x3F) << 3;
+ *curOut++ = (((*cursrc) >> 11) & 0x1F) << 3;
if (lpDestBuf)
*lpDestBuf++ = *cursrc;
@@ -319,8 +319,8 @@ void RMSnapshot::grabScreenshot(byte *lpBuf, int dezoom, uint16 *lpDestBuf) {
curv = v;
sommab += cursrc[curv * RM_BBX + u] & 0x1F;
- sommag += (cursrc[curv * RM_BBX + u] >> 5) & 0x1F;
- sommar += (cursrc[curv * RM_BBX + u] >> 10) & 0x1F;
+ sommag += (cursrc[curv * RM_BBX + u] >> 6) & 0x1F;
+ sommar += (cursrc[curv * RM_BBX + u] >> 11) & 0x1F;
}
}
_rgb[k + 0] = (byte)(sommab * 8 / (dezoom * dezoom));
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 51e8dee19f..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);
}
@@ -1059,7 +1064,7 @@ void Character::playAnim(int32 animId, int32 unused, int32 flags) {
_specialAnim->loadAnimation(animName);
_animSpecialId = animId;
-
+
if (_animationInstance) {
_animationInstance->setAnimation(_specialAnim);
_animationInstance->setAnimationRange(0, _specialAnim->_numFrames - 1);
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/state.cpp b/engines/toon/state.cpp
index 6ac5808219..000f94d659 100644
--- a/engines/toon/state.cpp
+++ b/engines/toon/state.cpp
@@ -115,7 +115,7 @@ State::State(void) {
#endif
memset(_conversationState, 0, sizeof(Conversation) * 60);
-
+
_conversationData = nullptr;
_currentConversationId = -1;
_exitConversation = true;
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 3fc30f9f8f..e23b157a95 100644
--- a/engines/tsage/module.mk
+++ b/engines/tsage/module.mk
@@ -35,16 +35,19 @@ MODULE_OBJS := \
ringworld/ringworld_scenes8.o \
ringworld/ringworld_scenes10.o \
ringworld/ringworld_speakers.o \
+ ringworld2/ringworld2_airduct.o \
ringworld2/ringworld2_dialogs.o \
ringworld2/ringworld2_logic.o \
+ ringworld2/ringworld2_outpost.o \
ringworld2/ringworld2_scenes0.o \
ringworld2/ringworld2_scenes1.o \
ringworld2/ringworld2_scenes2.o \
ringworld2/ringworld2_scenes3.o \
- ringworld2/ringworld2_outpost.o \
ringworld2/ringworld2_speakers.o \
+ 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/ringworld2/ringworld2_airduct.cpp b/engines/tsage/ringworld2/ringworld2_airduct.cpp
new file mode 100644
index 0000000000..136e8d5d1b
--- /dev/null
+++ b/engines/tsage/ringworld2/ringworld2_airduct.cpp
@@ -0,0 +1,909 @@
+/* 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/ringworld2/ringworld2_airduct.h"
+
+namespace TsAGE {
+
+namespace Ringworld2 {
+
+/*--------------------------------------------------------------------------
+ * Scene 1200 - Air Ducts Maze
+ *
+ *--------------------------------------------------------------------------*/
+
+Scene1200::Scene1200() {
+ _nextCrawlDirection = 0;
+ _field414 = 0;
+ _field416 = 0;
+ _field418 = 0;
+ _field41A = 0;
+ _fixupMaze = false;
+}
+
+void Scene1200::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_nextCrawlDirection);
+ s.syncAsSint16LE(_field414);
+ s.syncAsSint16LE(_field416);
+ s.syncAsSint16LE(_field418);
+ s.syncAsSint16LE(_field41A);
+ s.syncAsSint16LE(_fixupMaze);
+}
+
+Scene1200::LaserPanel::LaserPanel() {
+}
+
+void Scene1200::LaserPanel::Jumper::init(int state) {
+ _state = state;
+
+ SceneActor::postInit();
+ setup(1003, 1, 1);
+ fixPriority(255);
+
+ switch (_state) {
+ case 1:
+ switch (R2_GLOBALS._ductMazePanel1State) {
+ case 1:
+ setFrame2(2);
+ setPosition(Common::Point(129, 101));
+ break;
+ case 2:
+ setFrame2(3);
+ setPosition(Common::Point(135, 95));
+ break;
+ default:
+ break;
+ }
+ break;
+ case 2:
+ switch (R2_GLOBALS._ductMazePanel2State) {
+ case 1:
+ setFrame2(2);
+ setPosition(Common::Point(152, 101));
+ break;
+ case 2:
+ setFrame2(3);
+ setPosition(Common::Point(158, 122));
+ break;
+ case 3:
+ setFrame2(3);
+ setPosition(Common::Point(135, 122));
+ break;
+ default:
+ break;
+ }
+ break;
+ case 3:
+ switch (R2_GLOBALS._ductMazePanel3State) {
+ case 1:
+ setFrame2(3);
+ setPosition(Common::Point(158, 95));
+ break;
+ case 2:
+ setFrame2(2);
+ setPosition(Common::Point(175, 101));
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ setDetails(1200, 12, -1, -1, 2, (SceneItem *) NULL);
+}
+
+bool Scene1200::LaserPanel::Jumper::startAction(CursorType action, Event &event) {
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ R2_GLOBALS._sound2.play(260);
+ switch (_state) {
+ case 1:
+ if (R2_GLOBALS._ductMazePanel1State == 1) {
+ R2_GLOBALS._ductMazePanel1State = 2;
+ setFrame2(3);
+ setPosition(Common::Point(135, 95));
+ } else {
+ R2_GLOBALS._ductMazePanel1State = 1;
+ setFrame2(2);
+ setPosition(Common::Point(129, 101));
+ }
+ break;
+ case 2:
+ ++R2_GLOBALS._ductMazePanel2State;
+ if (R2_GLOBALS._ductMazePanel2State == 4)
+ R2_GLOBALS._ductMazePanel2State = 1;
+
+ switch (R2_GLOBALS._ductMazePanel2State) {
+ case 1:
+ setFrame2(2);
+ setPosition(Common::Point(152, 101));
+ break;
+ case 2:
+ setFrame2(3);
+ setPosition(Common::Point(158, 122));
+ break;
+ case 3:
+ setFrame2(3);
+ setPosition(Common::Point(135, 122));
+ break;
+ default:
+ break;
+ }
+ break;
+ case 3:
+ if (R2_GLOBALS._ductMazePanel3State == 1) {
+ R2_GLOBALS._ductMazePanel3State = 2;
+ setFrame2(2);
+ setPosition(Common::Point(175, 101));
+ } else {
+ R2_GLOBALS._ductMazePanel3State = 1;
+ setFrame2(3);
+ setPosition(Common::Point(158, 95));
+ }
+ break;
+ default:
+ break;
+ }
+
+ Scene1200 *scene = (Scene1200 *)R2_GLOBALS._sceneManager._scene;
+ scene->_field418 = 0;
+
+ if ((R2_GLOBALS._ductMazePanel1State == 1) && (R2_GLOBALS._ductMazePanel2State == 1) && (R2_GLOBALS._ductMazePanel3State == 1))
+ scene->_field418 = 1;
+ else if ((R2_GLOBALS._ductMazePanel1State == 2) && (R2_GLOBALS._ductMazePanel2State == 1) && (R2_GLOBALS._ductMazePanel3State == 1))
+ scene->_field418 = 2;
+ else if ((R2_GLOBALS._ductMazePanel1State == 2) && (R2_GLOBALS._ductMazePanel2State == 1) && (R2_GLOBALS._ductMazePanel3State == 2))
+ scene->_field418 = 3;
+ else if ((R2_GLOBALS._ductMazePanel1State == 2) && (R2_GLOBALS._ductMazePanel2State == 3) && (R2_GLOBALS._ductMazePanel3State == 1))
+ scene->_field418 = 4;
+
+ return true;
+}
+
+void Scene1200::LaserPanel::postInit(SceneObjectList *OwnerList) {
+ Scene1200 *scene = (Scene1200 *)R2_GLOBALS._sceneManager._scene;
+
+ scene->_field41A = 1;
+ R2_GLOBALS._events.setCursor(CURSOR_USE);
+ setup2(1003, 1, 1, 100, 40);
+ setup3(1200, 11, -1, -1);
+ R2_GLOBALS._sound2.play(259);
+ _jumper1.init(1);
+ _jumper2.init(2);
+ _jumper3.init(3);
+
+ R2_GLOBALS._player._canWalk = false;
+}
+
+void Scene1200::LaserPanel::remove() {
+ Scene1200 *scene = (Scene1200 *)R2_GLOBALS._sceneManager._scene;
+
+ scene->_field41A = 0;
+ scene->_sceneAreas.remove(&_jumper1);
+ scene->_sceneAreas.remove(&_jumper2);
+ scene->_sceneAreas.remove(&_jumper3);
+ _jumper1.remove();
+ _jumper2.remove();
+ _jumper3.remove();
+
+ ModalWindow::remove();
+ R2_GLOBALS._player._canWalk = true;
+}
+
+void Scene1200::postInit(SceneObjectList *OwnerList) {
+ loadScene(1200);
+ SceneExt::postInit();
+
+ if (R2_GLOBALS._sceneManager._previousScene < 3200)
+ R2_GLOBALS._sound1.play(257);
+
+ _nextCrawlDirection = CRAWL_EAST;
+ _field414 = 0;
+ _field416 = 0;
+ _field418 = 0;
+ _field41A = 0;
+
+ if ((R2_GLOBALS._ductMazePanel1State == 1) && (R2_GLOBALS._ductMazePanel2State == 1) && (R2_GLOBALS._ductMazePanel3State == 1))
+ _field418 = 1;
+ else if ((R2_GLOBALS._ductMazePanel1State == 2) && (R2_GLOBALS._ductMazePanel2State == 1) && (R2_GLOBALS._ductMazePanel3State == 1))
+ _field418 = 2;
+ else if ((R2_GLOBALS._ductMazePanel1State == 2) && (R2_GLOBALS._ductMazePanel2State == 1) && (R2_GLOBALS._ductMazePanel3State == 2))
+ _field418 = 3;
+ else if ((R2_GLOBALS._ductMazePanel1State == 2) && (R2_GLOBALS._ductMazePanel2State == 3) && (R2_GLOBALS._ductMazePanel3State == 1))
+ _field418 = 4;
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._player.setup(3156, 1, 6);
+ R2_GLOBALS._player.setPosition(Common::Point(160, 70));
+ R2_GLOBALS._player._numFrames = 10;
+ R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA] = 1200;
+
+ _actor1.postInit();
+ _actor1.hide();
+
+ _mazeUI.setDisplayBounds(Rect(110, 20, 210, 120));
+
+ _mazeUI.postInit();
+ _mazeUI.load(1);
+ _mazeUI.setMazePosition(R2_GLOBALS._ventCellPos);
+
+ R2_GLOBALS._player.enableControl();
+ _item1.setDetails(Rect(0, 0, 320, 200), 1200, 0, 1, 2, 1, NULL);
+}
+
+void Scene1200::signal() {
+ switch (_sceneMode++) {
+ case 1:
+ // No break on purpose
+ case 1200:
+ // No break on purpose
+ case 1201:
+ // No break on purpose
+ case 1202:
+ // No break on purpose
+ case 1203:
+ R2_GLOBALS._player.enableControl();
+ // CHECKME: The original is calling _eventManager.waitEvent();
+ _sceneMode = 2;
+ break;
+ case 10:
+ _field416 = 1;
+ _field414 = 6;
+ R2_GLOBALS._player._numFrames = 5;
+ R2_GLOBALS._player.setStrip(1);
+ R2_GLOBALS._player.setFrame(5);
+ R2_GLOBALS._player.animate(ANIM_MODE_6, this);
+ break;
+ case 11:
+ // No break on purpose
+ case 21:
+ // No break on purpose
+ case 31:
+ // No break on purpose
+ case 41:
+ _field416 = 0;
+ break;
+ case 12:
+ _field414 = 14;
+ R2_GLOBALS._player._numFrames = 10;
+ R2_GLOBALS._player.setup(3155, 1, 4);
+ R2_GLOBALS._player.setPosition(Common::Point(160, 70));
+ R2_GLOBALS._player.animate(ANIM_MODE_2, NULL);
+ break;
+ case 13:
+ // No break on purpose
+ case 16:
+ // No break on purpose
+ case 23:
+ // No break on purpose
+ case 26:
+ // No break on purpose
+ case 33:
+ // No break on purpose
+ case 36:
+ // No break on purpose
+ case 43:
+ // No break on purpose
+ case 46:
+ R2_GLOBALS._player.setFrame(4);
+ _sceneMode = 1;
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+ break;
+ case 15:
+ // No break on purpose
+ case 25:
+ // No break on purpose
+ case 35:
+ // No break on purpose
+ case 45:
+ _field414 = 20;
+ R2_GLOBALS._player.animate(ANIM_MODE_2, NULL);
+ break;
+ case 20:
+ _field416 = 1;
+ _field414 = 6;
+ R2_GLOBALS._player._numFrames = 5;
+ R2_GLOBALS._player.setStrip(2);
+ R2_GLOBALS._player.setFrame(5);
+ R2_GLOBALS._player.animate(ANIM_MODE_6, this);
+ break;
+ case 22:
+ _field414 = 14;
+ R2_GLOBALS._player._numFrames = 10;
+ R2_GLOBALS._player.setup(3155, 2, 4);
+ R2_GLOBALS._player.setPosition(Common::Point(160, 70));
+ R2_GLOBALS._player.animate(ANIM_MODE_2, NULL);
+ break;
+ case 30:
+ _field416 = 1;
+ _field414 = 6;
+ R2_GLOBALS._player._numFrames = 5;
+ R2_GLOBALS._player.setStrip(3);
+ R2_GLOBALS._player.setFrame(5);
+ R2_GLOBALS._player.animate(ANIM_MODE_6, this);
+ break;
+ case 32:
+ _field414 = 14;
+ R2_GLOBALS._player._numFrames = 10;
+ R2_GLOBALS._player.setup(3155, 3, 4);
+ R2_GLOBALS._player.setPosition(Common::Point(160, 70));
+ R2_GLOBALS._player.animate(ANIM_MODE_2, NULL);
+ break;
+ case 40:
+ _field416 = 1;
+ _field414 = 6;
+ R2_GLOBALS._player._numFrames = 5;
+ R2_GLOBALS._player.setStrip(4);
+ R2_GLOBALS._player.setFrame(5);
+ R2_GLOBALS._player.animate(ANIM_MODE_6, this);
+ break;
+ case 42:
+ _field414 = 14;
+ R2_GLOBALS._player._numFrames = 10;
+ R2_GLOBALS._player.setup(3155, 4, 4);
+ R2_GLOBALS._player.setPosition(Common::Point(160, 70));
+ R2_GLOBALS._player.animate(ANIM_MODE_2, NULL);
+ break;
+ case 50:
+ // No break on purpose
+ case 55:
+ // No break on purpose
+ case 60:
+ R2_GLOBALS._player.setup(3156, 5, 1);
+ R2_GLOBALS._player._numFrames = 5;
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 51:
+ // No break on purpose
+ case 56:
+ // No break on purpose
+ case 117:
+ R2_GLOBALS._player.setup(3157, 1, 1);
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 52:
+ // No break on purpose
+ case 82:
+ // No break on purpose
+ case 118:
+ R2_GLOBALS._player.setup(3156, 3, 6);
+ _sceneMode = 1;
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+ break;
+ case 57:
+ // No break on purpose
+ case 91:
+ // No break on purpose
+ case 96:
+ R2_GLOBALS._player.setup(3157, 2, 1);
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 58:
+ // No break on purpose
+ case 92:
+ // No break on purpose
+ case 122:
+ R2_GLOBALS._player.setup(3156, 2, 6);
+ _sceneMode = 1;
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+ break;
+ case 61:
+ R2_GLOBALS._player.setup(3157, 4, 5);
+ R2_GLOBALS._player.animate(ANIM_MODE_6, this);
+ break;
+ case 62:
+ // No break on purpose
+ case 72:
+ // No break on purpose
+ case 98:
+ R2_GLOBALS._player.setup(3156, 4, 6);
+ _sceneMode = 1;
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+ break;
+ case 70:
+ // No break on purpose
+ case 75:
+ // No break on purpose
+ case 80:
+ R2_GLOBALS._player.setup(3156, 6, 1);
+ R2_GLOBALS._player._numFrames = 5;
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 71:
+ // No break on purpose
+ case 76:
+ // No break on purpose
+ case 97:
+ R2_GLOBALS._player.setup(3157, 3, 1);
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 77:
+ // No break on purpose
+ case 111:
+ // No break on purpose
+ case 116:
+ R2_GLOBALS._player.setup(3157, 4, 1);
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 78:
+ // No break on purpose
+ case 102:
+ // No break on purpose
+ case 112:
+ R2_GLOBALS._player.setup(3156, 1, 6);
+ _sceneMode = 1;
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+ break;
+ case 81:
+ R2_GLOBALS._player.setup(3157, 2, 5);
+ R2_GLOBALS._player.animate(ANIM_MODE_6, this);
+ break;
+ case 90:
+ // No break on purpose
+ case 95:
+ // No break on purpose
+ case 100:
+ R2_GLOBALS._player.setup(3156, 7, 1);
+ R2_GLOBALS._player._numFrames = 5;
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 101:
+ R2_GLOBALS._player.setup(3157, 1, 5);
+ R2_GLOBALS._player.animate(ANIM_MODE_6, this);
+ break;
+ case 110:
+ // No break on purpose
+ case 115:
+ // No break on purpose
+ case 120:
+ R2_GLOBALS._player.setup(3156, 8, 1);
+ R2_GLOBALS._player._numFrames = 5;
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 121:
+ R2_GLOBALS._player.setup(3157, 3, 5);
+ R2_GLOBALS._player.animate(ANIM_MODE_6, this);
+ break;
+ default:
+ // CHECKME: The original is walling _eventManager.waitEvent();
+ _sceneMode = 2;
+ break;
+ }
+}
+
+void Scene1200::process(Event &event) {
+ if (_field414 != 0)
+ return;
+
+ Scene::process(event);
+
+ if (!R2_GLOBALS._player._canWalk)
+ return;
+
+ if (event.eventType == EVENT_BUTTON_DOWN) {
+ Common::Point cellPos = R2_GLOBALS._ventCellPos;
+ _mazeUI.pixelToCellXY(cellPos);
+
+ int cellId = _mazeUI.getCellFromPixelXY(event.mousePos);
+ switch (R2_GLOBALS._events.getCursor()) {
+ case CURSOR_WALK:
+ event.handled = true;
+ if ((event.mousePos.x > 179) && (event.mousePos.x < 210) && (event.mousePos.y > 50) && (event.mousePos.y < 89))
+ startCrawling(CRAWL_EAST);
+
+ if ((event.mousePos.x > 109) && (event.mousePos.x < 140) && (event.mousePos.y > 50) && (event.mousePos.y < 89))
+ startCrawling(CRAWL_WEST);
+
+ if ((event.mousePos.x > 140) && (event.mousePos.x < 179) && (event.mousePos.y > 89) && (event.mousePos.y < 120))
+ startCrawling(CRAWL_SOUTH);
+
+ if ((event.mousePos.x > 140) && (event.mousePos.x < 179) && (event.mousePos.y > 19) && (event.mousePos.y < 50))
+ startCrawling(CRAWL_NORTH);
+ break;
+ case CURSOR_USE:
+ if (cellId > 36) {
+ if ( ((cellPos.x == 3) && (cellPos.y == 33))
+ || ((cellPos.x == 7) && (cellPos.y == 33))
+ || ((cellPos.x == 33) && (cellPos.y == 41))
+ || ((cellPos.x == 5) && (cellPos.y == 5))
+ || ((cellPos.x == 13) && (cellPos.y == 21))
+ || ((cellPos.x == 17) && (cellPos.y == 21))
+ || ((cellPos.x == 17) && (cellPos.y == 5))
+ || ((cellPos.x == 17) && (cellPos.y == 9))
+ || ((cellPos.x == 29) && (cellPos.y == 17))
+ || ((cellPos.x == 33) && (cellPos.y == 17))
+ || ((cellPos.x == 35) && (cellPos.y == 17))
+ || ((cellPos.x == 41) && (cellPos.y == 21)) ) {
+ _laserPanel.postInit();
+ event.handled = true;
+ }
+ }
+
+ if ((cellId == 1) || (cellId == 4) || (cellId == 11) || (cellId == 14)) {
+ if ( ((cellPos.x == 3) && (cellPos.y == 9))
+ || ((cellPos.x == 11) && (cellPos.y == 27))
+ || ((cellPos.x == 17) && (cellPos.y == 7))
+ || ((cellPos.x == 17) && (cellPos.y == 27))
+ || ((cellPos.x == 17) && (cellPos.y == 33))
+ || (cellPos.x == 33) ) {
+ switch (cellPos.x) {
+ case 3:
+ R2_GLOBALS._sceneManager.changeScene(3150);
+ break;
+ case 33:
+ if (R2_GLOBALS._scientistConvIndex >= 4)
+ R2_GLOBALS._sceneManager.changeScene(3250);
+ else
+ SceneItem::display(1200, 6, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
+ break;
+ default:
+ SceneItem::display(1200, 5, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
+ break;
+ }
+ event.handled = true;
+ }
+ }
+ break;
+ case CURSOR_LOOK:
+ if ((cellId == 1) || (cellId == 4) || (cellId == 11) || (cellId == 14)) {
+ event.handled = true;
+ switch (cellPos.x) {
+ case 3:
+ // It was your cell.
+ SceneItem::display(1200, 8, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
+ break;
+ case 9:
+ R2_GLOBALS._sceneManager.changeScene(3240);
+ break;
+ case 11:
+ if (cellPos.y == 27)
+ R2_GLOBALS._sceneManager.changeScene(3210);
+ else
+ // A vent grill
+ SceneItem::display(1200, 10, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
+ break;
+ case 17:
+ switch (cellPos.y) {
+ case 5:
+ R2_GLOBALS._sceneManager.changeScene(3230);
+ break;
+ case 21:
+ R2_GLOBALS._sceneManager.changeScene(3220);
+ break;
+ case 33:
+ R2_GLOBALS._sceneManager.changeScene(3200);
+ break;
+ default:
+ // A vent grill
+ SceneItem::display(1200, 10, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
+ break;
+ }
+ break;
+ case 33:
+ R2_GLOBALS._sceneManager.changeScene(3245);
+ break;
+ default:
+ SceneItem::display(1200, 10, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
+ break;
+ }
+ }
+ if (cellId > 36) {
+ // "An anti-pest laser"
+ event.handled = true;
+ SceneItem::display(1200, 9, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
+ }
+ break;
+ case CURSOR_TALK:
+ event.handled = true;
+ break;
+ default:
+ return;
+ }
+ } else if (event.eventType == EVENT_KEYPRESS) {
+ if (_field414) {
+ event.handled = false;
+ return;
+ }
+
+ switch (event.kbd.keycode) {
+ case Common::KEYCODE_KP8:
+ case Common::KEYCODE_UP:
+ startCrawling(CRAWL_NORTH);
+ break;
+ case Common::KEYCODE_KP4:
+ case Common::KEYCODE_LEFT:
+ startCrawling(CRAWL_WEST);
+ break;
+ case Common::KEYCODE_KP6:
+ case Common::KEYCODE_RIGHT:
+ startCrawling(CRAWL_EAST);
+ break;
+ case Common::KEYCODE_KP2:
+ case Common::KEYCODE_DOWN:
+ startCrawling(CRAWL_SOUTH);
+ break;
+ default:
+ event.handled = false;
+ return;
+ break;
+ }
+ } else
+ return;
+}
+
+void Scene1200::dispatch() {
+ Rect tmpRect;
+ Scene::dispatch();
+
+ if (_fixupMaze) {
+ _mazeUI.setMazePosition(R2_GLOBALS._ventCellPos);
+ //_mazeUI.draw();
+ _fixupMaze = false;
+ }
+
+ if (_field414 != 0) {
+ tmpRect.set(110, 20, 210, 120);
+ _field414--;
+
+ switch (_nextCrawlDirection) {
+ case CRAWL_EAST:
+ R2_GLOBALS._ventCellPos.x += 2;
+ break;
+ case CRAWL_WEST:
+ R2_GLOBALS._ventCellPos.x -= 2;
+ break;
+ case CRAWL_SOUTH:
+ R2_GLOBALS._ventCellPos.y += 2;
+ break;
+ case CRAWL_NORTH:
+ R2_GLOBALS._ventCellPos.y -= 2;
+ break;
+ default:
+ break;
+ }
+
+ _mazeUI.setMazePosition(R2_GLOBALS._ventCellPos);
+ //_mazeUI.draw();
+
+ if (_field416 != 0) {
+ switch(_nextCrawlDirection) {
+ case CRAWL_EAST:
+ R2_GLOBALS._player.setPosition(Common::Point(R2_GLOBALS._player._position.x - 2, R2_GLOBALS._player._position.y));
+ break;
+ case CRAWL_WEST:
+ R2_GLOBALS._player.setPosition(Common::Point(R2_GLOBALS._player._position.x + 2, R2_GLOBALS._player._position.y));
+ break;
+ case CRAWL_SOUTH:
+ R2_GLOBALS._player.setPosition(Common::Point(R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y - 2));
+ break;
+ case CRAWL_NORTH:
+ R2_GLOBALS._player.setPosition(Common::Point(R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y + 2));
+ break;
+ default:
+ break;
+ }
+ }
+ if (_field414 == 0) {
+ if (_field416 == 0)
+ R2_GLOBALS._player.animate(ANIM_MODE_NONE, NULL);
+ signal();
+ }
+ }
+}
+
+void Scene1200::saveCharacter(int characterIndex) {
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ SceneExt::saveCharacter(characterIndex);
+}
+
+void Scene1200::startCrawling(CrawlDirection dir) {
+ Common::Point cellPos = R2_GLOBALS._ventCellPos;
+ _mazeUI.pixelToCellXY(cellPos);
+
+ switch (dir) {
+ case CRAWL_EAST:
+ if ( ((_mazeUI.getCellFromPixelXY(Common::Point(200, 50)) > 36) || (_mazeUI.getCellFromPixelXY(Common::Point(200, 88)) > 36))
+ && ( ((cellPos.x == 3) && (cellPos.y == 33) && (_field418 != 4))
+ || ((cellPos.x == 13) && (cellPos.y == 21) && (_field418 != 2))
+ || ((cellPos.x == 29) && (cellPos.y == 17) && (_field418 != 1))
+ || ((cellPos.x == 33) && (cellPos.y == 41)) )
+ ) {
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 1200;
+ setAction(&_sequenceManager, this, 1200, &_actor1, NULL);
+ } else if (_mazeUI.getCellFromPixelXY(Common::Point(200, 69)) == 36) {
+ switch (_nextCrawlDirection) {
+ case CRAWL_EAST:
+ if (R2_GLOBALS._player._visage == 3155)
+ _sceneMode = 15;
+ else
+ _sceneMode = 10;
+ break;
+ case CRAWL_WEST:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 76;
+ else
+ _sceneMode = 75;
+ break;
+ case CRAWL_SOUTH:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 101;
+ else
+ _sceneMode = 100;
+ break;
+ case CRAWL_NORTH:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 111;
+ else
+ _sceneMode = 110;
+ break;
+ default:
+ break;
+ }
+ R2_GLOBALS._player.disableControl();
+ _nextCrawlDirection = 1;
+ signal();
+ }
+ break;
+ case CRAWL_WEST:
+ if ( ((_mazeUI.getCellFromPixelXY(Common::Point(120, 50)) > 36) || (_mazeUI.getCellFromPixelXY(Common::Point(120, 88)) > 36))
+ && ( ((cellPos.x == 7) && (cellPos.y == 33) && (_field418 != 4))
+ || ((cellPos.x == 17) && (cellPos.y == 21) && (_field418 != 2))
+ || ((cellPos.x == 33) && (cellPos.y == 17) && (_field418 != 1))
+ || ((cellPos.x == 5) && (cellPos.y == 5)) )
+ ) {
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 1201;
+ setAction(&_sequenceManager, this, 1201, &_actor1, NULL);
+ } else if (_mazeUI.getCellFromPixelXY(Common::Point(120, 69)) == 36) {
+ switch (_nextCrawlDirection) {
+ case CRAWL_EAST:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 56;
+ else
+ _sceneMode = 55;
+ break;
+ case CRAWL_WEST:
+ if (R2_GLOBALS._player._visage == 3155)
+ _sceneMode = 25;
+ else
+ _sceneMode = 20;
+ break;
+ case CRAWL_SOUTH:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 91;
+ else
+ _sceneMode = 90;
+ break;
+ case CRAWL_NORTH:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 121;
+ else
+ _sceneMode = 120;
+ break;
+ default:
+ break;
+ }
+ R2_GLOBALS._player.disableControl();
+ _nextCrawlDirection = 2;
+ signal();
+ }
+ break;
+ case CRAWL_SOUTH:
+ if ( ((_mazeUI.getCellFromPixelXY(Common::Point(140, 110)) > 36) || (_mazeUI.getCellFromPixelXY(Common::Point(178, 110)) > 36))
+ && ( ((cellPos.x == 17) && (cellPos.y == 5) && (_field418 != 3))
+ || ((cellPos.x == 41) && (cellPos.y == 21)) )
+ ) {
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 1203;
+ setAction(&_sequenceManager, this, 1203, &_actor1, NULL);
+ } else if (_mazeUI.getCellFromPixelXY(Common::Point(160, 110)) == 36) {
+ switch (_nextCrawlDirection) {
+ case CRAWL_EAST:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 51;
+ else
+ _sceneMode = 50;
+ break;
+ case CRAWL_WEST:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 81;
+ else
+ _sceneMode = 80;
+ break;
+ case CRAWL_SOUTH:
+ if (R2_GLOBALS._player._visage == 3155)
+ _sceneMode = 35;
+ else
+ _sceneMode = 30;
+ break;
+ case CRAWL_NORTH:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 116;
+ else
+ _sceneMode = 115;
+ break;
+ default:
+ break;
+ }
+ R2_GLOBALS._player.disableControl();
+ _nextCrawlDirection = 3;
+ signal();
+ }
+ break;
+ case CRAWL_NORTH:
+ if ( ((_mazeUI.getCellFromPixelXY(Common::Point(140, 30)) > 36) || (_mazeUI.getCellFromPixelXY(Common::Point(178, 30)) > 36))
+ && ( ((cellPos.x == 17) && (cellPos.y == 9) && (_field418 != 3))
+ || ((cellPos.x == 35) && (cellPos.y == 17)) )
+ ) {
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 1202;
+ setAction(&_sequenceManager, this, 1202, &_actor1, NULL);
+ } else if (_mazeUI.getCellFromPixelXY(Common::Point(160, 30)) == 36) {
+ switch (_nextCrawlDirection) {
+ case CRAWL_EAST:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 61;
+ else
+ _sceneMode = 60;
+ break;
+ case CRAWL_WEST:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 71;
+ else
+ _sceneMode = 70;
+ break;
+ case CRAWL_SOUTH:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 96;
+ else
+ _sceneMode = 95;
+ break;
+ case CRAWL_NORTH:
+ if (R2_GLOBALS._player._visage == 3155)
+ _sceneMode = 45;
+ else
+ _sceneMode = 40;
+ break;
+ default:
+ _sceneMode = 1;
+ R2_GLOBALS._player.setup(3156, 4, 6);
+ break;
+ }
+ R2_GLOBALS._player.disableControl();
+ _nextCrawlDirection = 4;
+ signal();
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+} // End of namespace Ringworld2
+} // End of namespace TsAGE
diff --git a/engines/tsage/ringworld2/ringworld2_airduct.h b/engines/tsage/ringworld2/ringworld2_airduct.h
new file mode 100644
index 0000000000..89dfe778d0
--- /dev/null
+++ b/engines/tsage/ringworld2/ringworld2_airduct.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 TSAGE_RINGWORLD2_AIRDUCT_H
+#define TSAGE_RINGWORLD2_AIRDUCT_H
+
+#include "tsage/events.h"
+#include "tsage/core.h"
+#include "tsage/scenes.h"
+#include "tsage/globals.h"
+#include "tsage/sound.h"
+#include "tsage/ringworld2/ringworld2_logic.h"
+
+namespace TsAGE {
+
+namespace Ringworld2 {
+
+using namespace TsAGE;
+
+class Scene1200 : public SceneExt {
+ enum CrawlDirection { CRAWL_EAST = 1, CRAWL_WEST = 2, CRAWL_SOUTH = 3, CRAWL_NORTH = 4 };
+
+ class LaserPanel: public ModalWindow {
+ public:
+ class Jumper : public SceneActorExt {
+ public:
+ void init(int state);
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ Jumper _jumper1;
+ Jumper _jumper2;
+ Jumper _jumper3;
+
+ LaserPanel();
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ };
+
+public:
+ NamedHotspot _item1;
+ SceneActor _actor1;
+ LaserPanel _laserPanel;
+ MazeUI _mazeUI;
+ SequenceManager _sequenceManager;
+
+ int _nextCrawlDirection;
+ int _field414;
+ int _field416;
+ int _field418;
+ int _field41A;
+ bool _fixupMaze;
+
+ Scene1200();
+ void synchronize(Serializer &s);
+
+ void startCrawling(CrawlDirection dir);
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void process(Event &event);
+ virtual void dispatch();
+ virtual void saveCharacter(int characterIndex);
+};
+
+} // End of namespace Ringworld2
+} // End of namespace TsAGE
+
+#endif
diff --git a/engines/tsage/ringworld2/ringworld2_logic.cpp b/engines/tsage/ringworld2/ringworld2_logic.cpp
index a04fd56917..d24541932f 100644
--- a/engines/tsage/ringworld2/ringworld2_logic.cpp
+++ b/engines/tsage/ringworld2/ringworld2_logic.cpp
@@ -32,7 +32,9 @@
#include "tsage/ringworld2/ringworld2_scenes1.h"
#include "tsage/ringworld2/ringworld2_scenes2.h"
#include "tsage/ringworld2/ringworld2_scenes3.h"
+#include "tsage/ringworld2/ringworld2_airduct.h"
#include "tsage/ringworld2/ringworld2_outpost.h"
+#include "tsage/ringworld2/ringworld2_vampire.h"
namespace TsAGE {
diff --git a/engines/tsage/ringworld2/ringworld2_outpost.cpp b/engines/tsage/ringworld2/ringworld2_outpost.cpp
index 5766102c9a..cad21b4623 100644
--- a/engines/tsage/ringworld2/ringworld2_outpost.cpp
+++ b/engines/tsage/ringworld2/ringworld2_outpost.cpp
@@ -21,8 +21,6 @@
*/
#include "graphics/cursorman.h"
-
-#include "tsage/scenes.h"
#include "tsage/tsage.h"
#include "tsage/staticres.h"
#include "tsage/ringworld2/ringworld2_outpost.h"
@@ -4607,7 +4605,7 @@ void Scene1337::subD1940(bool flag) {
}
void Scene1337::subD1975(int arg1, int arg2) {
- // No implementation required in ScummVM: Mouse handling with tons of caching
+ // No implementation required in ScummVM: Mouse handling with tons of caching
}
void Scene1337::OptionsDialog::show() {
diff --git a/engines/tsage/ringworld2/ringworld2_outpost.h b/engines/tsage/ringworld2/ringworld2_outpost.h
index b3e663356e..6c6952c196 100644
--- a/engines/tsage/ringworld2/ringworld2_outpost.h
+++ b/engines/tsage/ringworld2/ringworld2_outpost.h
@@ -23,15 +23,12 @@
#ifndef TSAGE_RINGWORLD2_OUTPOST_H
#define TSAGE_RINGWORLD2_OUTPOST_H
-#include "common/scummsys.h"
-#include "tsage/converse.h"
#include "tsage/events.h"
#include "tsage/core.h"
#include "tsage/scenes.h"
#include "tsage/globals.h"
#include "tsage/sound.h"
#include "tsage/ringworld2/ringworld2_logic.h"
-#include "tsage/ringworld2/ringworld2_speakers.h"
namespace TsAGE {
diff --git a/engines/tsage/ringworld2/ringworld2_scenes0.cpp b/engines/tsage/ringworld2/ringworld2_scenes0.cpp
index b82565332a..573cbbb29a 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes0.cpp
+++ b/engines/tsage/ringworld2/ringworld2_scenes0.cpp
@@ -627,7 +627,7 @@ void Scene125::postInit(SceneObjectList *OwnerList) {
SceneExt::postInit();
_palette.loadPalette(0);
- if (R2_GLOBALS._sceneManager._previousScene != 125)
+ if ((R2_GLOBALS._sceneManager._previousScene != 125) && (R2_GLOBALS._sceneManager._previousScene != 1337) && (R2_GLOBALS._sceneManager._previousScene != 1330))
// Save the prior scene to return to when the console is turned off
R2_GLOBALS._player._oldCharacterScene[R2_QUINN] = R2_GLOBALS._sceneManager._previousScene;
diff --git a/engines/tsage/ringworld2/ringworld2_scenes1.cpp b/engines/tsage/ringworld2/ringworld2_scenes1.cpp
index 51879f1eed..81dc05e2a4 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes1.cpp
+++ b/engines/tsage/ringworld2/ringworld2_scenes1.cpp
@@ -1321,885 +1321,6 @@ void Scene1100::saveCharacter(int characterIndex) {
}
/*--------------------------------------------------------------------------
- * Scene 1200 - Air Ducts Maze
- *
- *--------------------------------------------------------------------------*/
-
-Scene1200::Scene1200() {
- _nextCrawlDirection = 0;
- _field414 = 0;
- _field416 = 0;
- _field418 = 0;
- _field41A = 0;
- _fixupMaze = false;
-}
-
-void Scene1200::synchronize(Serializer &s) {
- SceneExt::synchronize(s);
-
- s.syncAsSint16LE(_nextCrawlDirection);
- s.syncAsSint16LE(_field414);
- s.syncAsSint16LE(_field416);
- s.syncAsSint16LE(_field418);
- s.syncAsSint16LE(_field41A);
- s.syncAsSint16LE(_fixupMaze);
-}
-
-Scene1200::LaserPanel::LaserPanel() {
-}
-
-void Scene1200::LaserPanel::Jumper::init(int state) {
- _state = state;
-
- SceneActor::postInit();
- setup(1003, 1, 1);
- fixPriority(255);
-
- switch (_state) {
- case 1:
- switch (R2_GLOBALS._ductMazePanel1State) {
- case 1:
- setFrame2(2);
- setPosition(Common::Point(129, 101));
- break;
- case 2:
- setFrame2(3);
- setPosition(Common::Point(135, 95));
- break;
- default:
- break;
- }
- break;
- case 2:
- switch (R2_GLOBALS._ductMazePanel2State) {
- case 1:
- setFrame2(2);
- setPosition(Common::Point(152, 101));
- break;
- case 2:
- setFrame2(3);
- setPosition(Common::Point(158, 122));
- break;
- case 3:
- setFrame2(3);
- setPosition(Common::Point(135, 122));
- break;
- default:
- break;
- }
- break;
- case 3:
- switch (R2_GLOBALS._ductMazePanel3State) {
- case 1:
- setFrame2(3);
- setPosition(Common::Point(158, 95));
- break;
- case 2:
- setFrame2(2);
- setPosition(Common::Point(175, 101));
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
-
- setDetails(1200, 12, -1, -1, 2, (SceneItem *) NULL);
-}
-
-bool Scene1200::LaserPanel::Jumper::startAction(CursorType action, Event &event) {
- if (action != CURSOR_USE)
- return SceneActor::startAction(action, event);
-
- R2_GLOBALS._sound2.play(260);
- switch (_state) {
- case 1:
- if (R2_GLOBALS._ductMazePanel1State == 1) {
- R2_GLOBALS._ductMazePanel1State = 2;
- setFrame2(3);
- setPosition(Common::Point(135, 95));
- } else {
- R2_GLOBALS._ductMazePanel1State = 1;
- setFrame2(2);
- setPosition(Common::Point(129, 101));
- }
- break;
- case 2:
- ++R2_GLOBALS._ductMazePanel2State;
- if (R2_GLOBALS._ductMazePanel2State == 4)
- R2_GLOBALS._ductMazePanel2State = 1;
-
- switch (R2_GLOBALS._ductMazePanel2State) {
- case 1:
- setFrame2(2);
- setPosition(Common::Point(152, 101));
- break;
- case 2:
- setFrame2(3);
- setPosition(Common::Point(158, 122));
- break;
- case 3:
- setFrame2(3);
- setPosition(Common::Point(135, 122));
- break;
- default:
- break;
- }
- break;
- case 3:
- if (R2_GLOBALS._ductMazePanel3State == 1) {
- R2_GLOBALS._ductMazePanel3State = 2;
- setFrame2(2);
- setPosition(Common::Point(175, 101));
- } else {
- R2_GLOBALS._ductMazePanel3State = 1;
- setFrame2(3);
- setPosition(Common::Point(158, 95));
- }
- break;
- default:
- break;
- }
-
- Scene1200 *scene = (Scene1200 *)R2_GLOBALS._sceneManager._scene;
- scene->_field418 = 0;
-
- if ((R2_GLOBALS._ductMazePanel1State == 1) && (R2_GLOBALS._ductMazePanel2State == 1) && (R2_GLOBALS._ductMazePanel3State == 1))
- scene->_field418 = 1;
- else if ((R2_GLOBALS._ductMazePanel1State == 2) && (R2_GLOBALS._ductMazePanel2State == 1) && (R2_GLOBALS._ductMazePanel3State == 1))
- scene->_field418 = 2;
- else if ((R2_GLOBALS._ductMazePanel1State == 2) && (R2_GLOBALS._ductMazePanel2State == 1) && (R2_GLOBALS._ductMazePanel3State == 2))
- scene->_field418 = 3;
- else if ((R2_GLOBALS._ductMazePanel1State == 2) && (R2_GLOBALS._ductMazePanel2State == 3) && (R2_GLOBALS._ductMazePanel3State == 1))
- scene->_field418 = 4;
-
- return true;
-}
-
-void Scene1200::LaserPanel::postInit(SceneObjectList *OwnerList) {
- Scene1200 *scene = (Scene1200 *)R2_GLOBALS._sceneManager._scene;
-
- scene->_field41A = 1;
- R2_GLOBALS._events.setCursor(CURSOR_USE);
- setup2(1003, 1, 1, 100, 40);
- setup3(1200, 11, -1, -1);
- R2_GLOBALS._sound2.play(259);
- _jumper1.init(1);
- _jumper2.init(2);
- _jumper3.init(3);
-
- R2_GLOBALS._player._canWalk = false;
-}
-
-void Scene1200::LaserPanel::remove() {
- Scene1200 *scene = (Scene1200 *)R2_GLOBALS._sceneManager._scene;
-
- scene->_field41A = 0;
- scene->_sceneAreas.remove(&_jumper1);
- scene->_sceneAreas.remove(&_jumper2);
- scene->_sceneAreas.remove(&_jumper3);
- _jumper1.remove();
- _jumper2.remove();
- _jumper3.remove();
-
- ModalWindow::remove();
- R2_GLOBALS._player._canWalk = true;
-}
-
-void Scene1200::postInit(SceneObjectList *OwnerList) {
- loadScene(1200);
- SceneExt::postInit();
-
- if (R2_GLOBALS._sceneManager._previousScene < 3200)
- R2_GLOBALS._sound1.play(257);
-
- _nextCrawlDirection = CRAWL_EAST;
- _field414 = 0;
- _field416 = 0;
- _field418 = 0;
- _field41A = 0;
-
- if ((R2_GLOBALS._ductMazePanel1State == 1) && (R2_GLOBALS._ductMazePanel2State == 1) && (R2_GLOBALS._ductMazePanel3State == 1))
- _field418 = 1;
- else if ((R2_GLOBALS._ductMazePanel1State == 2) && (R2_GLOBALS._ductMazePanel2State == 1) && (R2_GLOBALS._ductMazePanel3State == 1))
- _field418 = 2;
- else if ((R2_GLOBALS._ductMazePanel1State == 2) && (R2_GLOBALS._ductMazePanel2State == 1) && (R2_GLOBALS._ductMazePanel3State == 2))
- _field418 = 3;
- else if ((R2_GLOBALS._ductMazePanel1State == 2) && (R2_GLOBALS._ductMazePanel2State == 3) && (R2_GLOBALS._ductMazePanel3State == 1))
- _field418 = 4;
-
- R2_GLOBALS._player.postInit();
- R2_GLOBALS._player.disableControl();
- R2_GLOBALS._player.setup(3156, 1, 6);
- R2_GLOBALS._player.setPosition(Common::Point(160, 70));
- R2_GLOBALS._player._numFrames = 10;
- R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA] = 1200;
-
- _actor1.postInit();
- _actor1.hide();
-
- _mazeUI.setDisplayBounds(Rect(110, 20, 210, 120));
-
- _mazeUI.postInit();
- _mazeUI.load(1);
- _mazeUI.setMazePosition(R2_GLOBALS._ventCellPos);
-
- R2_GLOBALS._player.enableControl();
- _item1.setDetails(Rect(0, 0, 320, 200), 1200, 0, 1, 2, 1, NULL);
-}
-
-void Scene1200::signal() {
- switch (_sceneMode++) {
- case 1:
- // No break on purpose
- case 1200:
- // No break on purpose
- case 1201:
- // No break on purpose
- case 1202:
- // No break on purpose
- case 1203:
- R2_GLOBALS._player.enableControl();
- // CHECKME: The original is calling _eventManager.waitEvent();
- _sceneMode = 2;
- break;
- case 10:
- _field416 = 1;
- _field414 = 6;
- R2_GLOBALS._player._numFrames = 5;
- R2_GLOBALS._player.setStrip(1);
- R2_GLOBALS._player.setFrame(5);
- R2_GLOBALS._player.animate(ANIM_MODE_6, this);
- break;
- case 11:
- // No break on purpose
- case 21:
- // No break on purpose
- case 31:
- // No break on purpose
- case 41:
- _field416 = 0;
- break;
- case 12:
- _field414 = 14;
- R2_GLOBALS._player._numFrames = 10;
- R2_GLOBALS._player.setup(3155, 1, 4);
- R2_GLOBALS._player.setPosition(Common::Point(160, 70));
- R2_GLOBALS._player.animate(ANIM_MODE_2, NULL);
- break;
- case 13:
- // No break on purpose
- case 16:
- // No break on purpose
- case 23:
- // No break on purpose
- case 26:
- // No break on purpose
- case 33:
- // No break on purpose
- case 36:
- // No break on purpose
- case 43:
- // No break on purpose
- case 46:
- R2_GLOBALS._player.setFrame(4);
- _sceneMode = 1;
- setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
- break;
- case 15:
- // No break on purpose
- case 25:
- // No break on purpose
- case 35:
- // No break on purpose
- case 45:
- _field414 = 20;
- R2_GLOBALS._player.animate(ANIM_MODE_2, NULL);
- break;
- case 20:
- _field416 = 1;
- _field414 = 6;
- R2_GLOBALS._player._numFrames = 5;
- R2_GLOBALS._player.setStrip(2);
- R2_GLOBALS._player.setFrame(5);
- R2_GLOBALS._player.animate(ANIM_MODE_6, this);
- break;
- case 22:
- _field414 = 14;
- R2_GLOBALS._player._numFrames = 10;
- R2_GLOBALS._player.setup(3155, 2, 4);
- R2_GLOBALS._player.setPosition(Common::Point(160, 70));
- R2_GLOBALS._player.animate(ANIM_MODE_2, NULL);
- break;
- case 30:
- _field416 = 1;
- _field414 = 6;
- R2_GLOBALS._player._numFrames = 5;
- R2_GLOBALS._player.setStrip(3);
- R2_GLOBALS._player.setFrame(5);
- R2_GLOBALS._player.animate(ANIM_MODE_6, this);
- break;
- case 32:
- _field414 = 14;
- R2_GLOBALS._player._numFrames = 10;
- R2_GLOBALS._player.setup(3155, 3, 4);
- R2_GLOBALS._player.setPosition(Common::Point(160, 70));
- R2_GLOBALS._player.animate(ANIM_MODE_2, NULL);
- break;
- case 40:
- _field416 = 1;
- _field414 = 6;
- R2_GLOBALS._player._numFrames = 5;
- R2_GLOBALS._player.setStrip(4);
- R2_GLOBALS._player.setFrame(5);
- R2_GLOBALS._player.animate(ANIM_MODE_6, this);
- break;
- case 42:
- _field414 = 14;
- R2_GLOBALS._player._numFrames = 10;
- R2_GLOBALS._player.setup(3155, 4, 4);
- R2_GLOBALS._player.setPosition(Common::Point(160, 70));
- R2_GLOBALS._player.animate(ANIM_MODE_2, NULL);
- break;
- case 50:
- // No break on purpose
- case 55:
- // No break on purpose
- case 60:
- R2_GLOBALS._player.setup(3156, 5, 1);
- R2_GLOBALS._player._numFrames = 5;
- R2_GLOBALS._player.animate(ANIM_MODE_5, this);
- break;
- case 51:
- // No break on purpose
- case 56:
- // No break on purpose
- case 117:
- R2_GLOBALS._player.setup(3157, 1, 1);
- R2_GLOBALS._player.animate(ANIM_MODE_5, this);
- break;
- case 52:
- // No break on purpose
- case 82:
- // No break on purpose
- case 118:
- R2_GLOBALS._player.setup(3156, 3, 6);
- _sceneMode = 1;
- setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
- break;
- case 57:
- // No break on purpose
- case 91:
- // No break on purpose
- case 96:
- R2_GLOBALS._player.setup(3157, 2, 1);
- R2_GLOBALS._player.animate(ANIM_MODE_5, this);
- break;
- case 58:
- // No break on purpose
- case 92:
- // No break on purpose
- case 122:
- R2_GLOBALS._player.setup(3156, 2, 6);
- _sceneMode = 1;
- setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
- break;
- case 61:
- R2_GLOBALS._player.setup(3157, 4, 5);
- R2_GLOBALS._player.animate(ANIM_MODE_6, this);
- break;
- case 62:
- // No break on purpose
- case 72:
- // No break on purpose
- case 98:
- R2_GLOBALS._player.setup(3156, 4, 6);
- _sceneMode = 1;
- setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
- break;
- case 70:
- // No break on purpose
- case 75:
- // No break on purpose
- case 80:
- R2_GLOBALS._player.setup(3156, 6, 1);
- R2_GLOBALS._player._numFrames = 5;
- R2_GLOBALS._player.animate(ANIM_MODE_5, this);
- break;
- case 71:
- // No break on purpose
- case 76:
- // No break on purpose
- case 97:
- R2_GLOBALS._player.setup(3157, 3, 1);
- R2_GLOBALS._player.animate(ANIM_MODE_5, this);
- break;
- case 77:
- // No break on purpose
- case 111:
- // No break on purpose
- case 116:
- R2_GLOBALS._player.setup(3157, 4, 1);
- R2_GLOBALS._player.animate(ANIM_MODE_5, this);
- break;
- case 78:
- // No break on purpose
- case 102:
- // No break on purpose
- case 112:
- R2_GLOBALS._player.setup(3156, 1, 6);
- _sceneMode = 1;
- setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
- break;
- case 81:
- R2_GLOBALS._player.setup(3157, 2, 5);
- R2_GLOBALS._player.animate(ANIM_MODE_6, this);
- break;
- case 90:
- // No break on purpose
- case 95:
- // No break on purpose
- case 100:
- R2_GLOBALS._player.setup(3156, 7, 1);
- R2_GLOBALS._player._numFrames = 5;
- R2_GLOBALS._player.animate(ANIM_MODE_5, this);
- break;
- case 101:
- R2_GLOBALS._player.setup(3157, 1, 5);
- R2_GLOBALS._player.animate(ANIM_MODE_6, this);
- break;
- case 110:
- // No break on purpose
- case 115:
- // No break on purpose
- case 120:
- R2_GLOBALS._player.setup(3156, 8, 1);
- R2_GLOBALS._player._numFrames = 5;
- R2_GLOBALS._player.animate(ANIM_MODE_5, this);
- break;
- case 121:
- R2_GLOBALS._player.setup(3157, 3, 5);
- R2_GLOBALS._player.animate(ANIM_MODE_6, this);
- break;
- default:
- // CHECKME: The original is walling _eventManager.waitEvent();
- _sceneMode = 2;
- break;
- }
-}
-
-void Scene1200::process(Event &event) {
- if (_field414 != 0)
- return;
-
- Scene::process(event);
-
- if (!R2_GLOBALS._player._canWalk)
- return;
-
- if (event.eventType == EVENT_BUTTON_DOWN) {
- Common::Point cellPos = R2_GLOBALS._ventCellPos;
- _mazeUI.pixelToCellXY(cellPos);
-
- int cellId = _mazeUI.getCellFromPixelXY(event.mousePos);
- switch (R2_GLOBALS._events.getCursor()) {
- case CURSOR_WALK:
- event.handled = true;
- if ((event.mousePos.x > 179) && (event.mousePos.x < 210) && (event.mousePos.y > 50) && (event.mousePos.y < 89))
- startCrawling(CRAWL_EAST);
-
- if ((event.mousePos.x > 109) && (event.mousePos.x < 140) && (event.mousePos.y > 50) && (event.mousePos.y < 89))
- startCrawling(CRAWL_WEST);
-
- if ((event.mousePos.x > 140) && (event.mousePos.x < 179) && (event.mousePos.y > 89) && (event.mousePos.y < 120))
- startCrawling(CRAWL_SOUTH);
-
- if ((event.mousePos.x > 140) && (event.mousePos.x < 179) && (event.mousePos.y > 19) && (event.mousePos.y < 50))
- startCrawling(CRAWL_NORTH);
- break;
- case CURSOR_USE:
- if (cellId > 36) {
- if ( ((cellPos.x == 3) && (cellPos.y == 33))
- || ((cellPos.x == 7) && (cellPos.y == 33))
- || ((cellPos.x == 33) && (cellPos.y == 41))
- || ((cellPos.x == 5) && (cellPos.y == 5))
- || ((cellPos.x == 13) && (cellPos.y == 21))
- || ((cellPos.x == 17) && (cellPos.y == 21))
- || ((cellPos.x == 17) && (cellPos.y == 5))
- || ((cellPos.x == 17) && (cellPos.y == 9))
- || ((cellPos.x == 29) && (cellPos.y == 17))
- || ((cellPos.x == 33) && (cellPos.y == 17))
- || ((cellPos.x == 35) && (cellPos.y == 17))
- || ((cellPos.x == 41) && (cellPos.y == 21)) ) {
- _laserPanel.postInit();
- event.handled = true;
- }
- }
-
- if ((cellId == 1) || (cellId == 4) || (cellId == 11) || (cellId == 14)) {
- if ( ((cellPos.x == 3) && (cellPos.y == 9))
- || ((cellPos.x == 11) && (cellPos.y == 27))
- || ((cellPos.x == 17) && (cellPos.y == 7))
- || ((cellPos.x == 17) && (cellPos.y == 27))
- || ((cellPos.x == 17) && (cellPos.y == 33))
- || (cellPos.x == 33) ) {
- switch (cellPos.x) {
- case 3:
- R2_GLOBALS._sceneManager.changeScene(3150);
- break;
- case 33:
- if (R2_GLOBALS._scientistConvIndex >= 4)
- R2_GLOBALS._sceneManager.changeScene(3250);
- else
- SceneItem::display(1200, 6, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
- break;
- default:
- SceneItem::display(1200, 5, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
- break;
- }
- event.handled = true;
- }
- }
- break;
- case CURSOR_LOOK:
- if ((cellId == 1) || (cellId == 4) || (cellId == 11) || (cellId == 14)) {
- event.handled = true;
- switch (cellPos.x) {
- case 3:
- // It was your cell.
- SceneItem::display(1200, 8, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
- break;
- case 9:
- R2_GLOBALS._sceneManager.changeScene(3240);
- break;
- case 11:
- if (cellPos.y == 27)
- R2_GLOBALS._sceneManager.changeScene(3210);
- else
- // A vent grill
- SceneItem::display(1200, 10, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
- break;
- case 17:
- switch (cellPos.y) {
- case 5:
- R2_GLOBALS._sceneManager.changeScene(3230);
- break;
- case 21:
- R2_GLOBALS._sceneManager.changeScene(3220);
- break;
- case 33:
- R2_GLOBALS._sceneManager.changeScene(3200);
- break;
- default:
- // A vent grill
- SceneItem::display(1200, 10, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
- break;
- }
- break;
- case 33:
- R2_GLOBALS._sceneManager.changeScene(3245);
- break;
- default:
- SceneItem::display(1200, 10, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
- break;
- }
- }
- if (cellId > 36) {
- // "An anti-pest laser"
- event.handled = true;
- SceneItem::display(1200, 9, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
- }
- break;
- case CURSOR_TALK:
- event.handled = true;
- break;
- default:
- return;
- }
- } else if (event.eventType == EVENT_KEYPRESS) {
- if (_field414) {
- event.handled = false;
- return;
- }
-
- switch (event.kbd.keycode) {
- case Common::KEYCODE_KP8:
- case Common::KEYCODE_UP:
- startCrawling(CRAWL_NORTH);
- break;
- case Common::KEYCODE_KP4:
- case Common::KEYCODE_LEFT:
- startCrawling(CRAWL_WEST);
- break;
- case Common::KEYCODE_KP6:
- case Common::KEYCODE_RIGHT:
- startCrawling(CRAWL_EAST);
- break;
- case Common::KEYCODE_KP2:
- case Common::KEYCODE_DOWN:
- startCrawling(CRAWL_SOUTH);
- break;
- default:
- event.handled = false;
- return;
- break;
- }
- } else
- return;
-}
-
-void Scene1200::dispatch() {
- Rect tmpRect;
- Scene::dispatch();
-
- if (_fixupMaze) {
- _mazeUI.setMazePosition(R2_GLOBALS._ventCellPos);
- //_mazeUI.draw();
- _fixupMaze = false;
- }
-
- if (_field414 != 0) {
- tmpRect.set(110, 20, 210, 120);
- _field414--;
-
- switch (_nextCrawlDirection) {
- case CRAWL_EAST:
- R2_GLOBALS._ventCellPos.x += 2;
- break;
- case CRAWL_WEST:
- R2_GLOBALS._ventCellPos.x -= 2;
- break;
- case CRAWL_SOUTH:
- R2_GLOBALS._ventCellPos.y += 2;
- break;
- case CRAWL_NORTH:
- R2_GLOBALS._ventCellPos.y -= 2;
- break;
- default:
- break;
- }
-
- _mazeUI.setMazePosition(R2_GLOBALS._ventCellPos);
- //_mazeUI.draw();
-
- if (_field416 != 0) {
- switch(_nextCrawlDirection) {
- case CRAWL_EAST:
- R2_GLOBALS._player.setPosition(Common::Point(R2_GLOBALS._player._position.x - 2, R2_GLOBALS._player._position.y));
- break;
- case CRAWL_WEST:
- R2_GLOBALS._player.setPosition(Common::Point(R2_GLOBALS._player._position.x + 2, R2_GLOBALS._player._position.y));
- break;
- case CRAWL_SOUTH:
- R2_GLOBALS._player.setPosition(Common::Point(R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y - 2));
- break;
- case CRAWL_NORTH:
- R2_GLOBALS._player.setPosition(Common::Point(R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y + 2));
- break;
- default:
- break;
- }
- }
- if (_field414 == 0) {
- if (_field416 == 0)
- R2_GLOBALS._player.animate(ANIM_MODE_NONE, NULL);
- signal();
- }
- }
-}
-
-void Scene1200::saveCharacter(int characterIndex) {
- R2_GLOBALS._sound1.fadeOut2(NULL);
- SceneExt::saveCharacter(characterIndex);
-}
-
-void Scene1200::startCrawling(CrawlDirection dir) {
- Common::Point cellPos = R2_GLOBALS._ventCellPos;
- _mazeUI.pixelToCellXY(cellPos);
-
- switch (dir) {
- case CRAWL_EAST:
- if ( ((_mazeUI.getCellFromPixelXY(Common::Point(200, 50)) > 36) || (_mazeUI.getCellFromPixelXY(Common::Point(200, 88)) > 36))
- && ( ((cellPos.x == 3) && (cellPos.y == 33) && (_field418 != 4))
- || ((cellPos.x == 13) && (cellPos.y == 21) && (_field418 != 2))
- || ((cellPos.x == 29) && (cellPos.y == 17) && (_field418 != 1))
- || ((cellPos.x == 33) && (cellPos.y == 41)) )
- ) {
- R2_GLOBALS._player.disableControl();
- _sceneMode = 1200;
- setAction(&_sequenceManager, this, 1200, &_actor1, NULL);
- } else if (_mazeUI.getCellFromPixelXY(Common::Point(200, 69)) == 36) {
- switch (_nextCrawlDirection) {
- case CRAWL_EAST:
- if (R2_GLOBALS._player._visage == 3155)
- _sceneMode = 15;
- else
- _sceneMode = 10;
- break;
- case CRAWL_WEST:
- if (R2_GLOBALS._player._visage == 3156)
- _sceneMode = 76;
- else
- _sceneMode = 75;
- break;
- case CRAWL_SOUTH:
- if (R2_GLOBALS._player._visage == 3156)
- _sceneMode = 101;
- else
- _sceneMode = 100;
- break;
- case CRAWL_NORTH:
- if (R2_GLOBALS._player._visage == 3156)
- _sceneMode = 111;
- else
- _sceneMode = 110;
- break;
- default:
- break;
- }
- R2_GLOBALS._player.disableControl();
- _nextCrawlDirection = 1;
- signal();
- }
- break;
- case CRAWL_WEST:
- if ( ((_mazeUI.getCellFromPixelXY(Common::Point(120, 50)) > 36) || (_mazeUI.getCellFromPixelXY(Common::Point(120, 88)) > 36))
- && ( ((cellPos.x == 7) && (cellPos.y == 33) && (_field418 != 4))
- || ((cellPos.x == 17) && (cellPos.y == 21) && (_field418 != 2))
- || ((cellPos.x == 33) && (cellPos.y == 17) && (_field418 != 1))
- || ((cellPos.x == 5) && (cellPos.y == 5)) )
- ) {
- R2_GLOBALS._player.disableControl();
- _sceneMode = 1201;
- setAction(&_sequenceManager, this, 1201, &_actor1, NULL);
- } else if (_mazeUI.getCellFromPixelXY(Common::Point(120, 69)) == 36) {
- switch (_nextCrawlDirection) {
- case CRAWL_EAST:
- if (R2_GLOBALS._player._visage == 3156)
- _sceneMode = 56;
- else
- _sceneMode = 55;
- break;
- case CRAWL_WEST:
- if (R2_GLOBALS._player._visage == 3155)
- _sceneMode = 25;
- else
- _sceneMode = 20;
- break;
- case CRAWL_SOUTH:
- if (R2_GLOBALS._player._visage == 3156)
- _sceneMode = 91;
- else
- _sceneMode = 90;
- break;
- case CRAWL_NORTH:
- if (R2_GLOBALS._player._visage == 3156)
- _sceneMode = 121;
- else
- _sceneMode = 120;
- break;
- default:
- break;
- }
- R2_GLOBALS._player.disableControl();
- _nextCrawlDirection = 2;
- signal();
- }
- break;
- case CRAWL_SOUTH:
- if ( ((_mazeUI.getCellFromPixelXY(Common::Point(140, 110)) > 36) || (_mazeUI.getCellFromPixelXY(Common::Point(178, 110)) > 36))
- && ( ((cellPos.x == 17) && (cellPos.y == 5) && (_field418 != 3))
- || ((cellPos.x == 41) && (cellPos.y == 21)) )
- ) {
- R2_GLOBALS._player.disableControl();
- _sceneMode = 1203;
- setAction(&_sequenceManager, this, 1203, &_actor1, NULL);
- } else if (_mazeUI.getCellFromPixelXY(Common::Point(160, 110)) == 36) {
- switch (_nextCrawlDirection) {
- case CRAWL_EAST:
- if (R2_GLOBALS._player._visage == 3156)
- _sceneMode = 51;
- else
- _sceneMode = 50;
- break;
- case CRAWL_WEST:
- if (R2_GLOBALS._player._visage == 3156)
- _sceneMode = 81;
- else
- _sceneMode = 80;
- break;
- case CRAWL_SOUTH:
- if (R2_GLOBALS._player._visage == 3155)
- _sceneMode = 35;
- else
- _sceneMode = 30;
- break;
- case CRAWL_NORTH:
- if (R2_GLOBALS._player._visage == 3156)
- _sceneMode = 116;
- else
- _sceneMode = 115;
- break;
- default:
- break;
- }
- R2_GLOBALS._player.disableControl();
- _nextCrawlDirection = 3;
- signal();
- }
- break;
- case CRAWL_NORTH:
- if ( ((_mazeUI.getCellFromPixelXY(Common::Point(140, 30)) > 36) || (_mazeUI.getCellFromPixelXY(Common::Point(178, 30)) > 36))
- && ( ((cellPos.x == 17) && (cellPos.y == 9) && (_field418 != 3))
- || ((cellPos.x == 35) && (cellPos.y == 17)) )
- ) {
- R2_GLOBALS._player.disableControl();
- _sceneMode = 1202;
- setAction(&_sequenceManager, this, 1202, &_actor1, NULL);
- } else if (_mazeUI.getCellFromPixelXY(Common::Point(160, 30)) == 36) {
- switch (_nextCrawlDirection) {
- case CRAWL_EAST:
- if (R2_GLOBALS._player._visage == 3156)
- _sceneMode = 61;
- else
- _sceneMode = 60;
- break;
- case CRAWL_WEST:
- if (R2_GLOBALS._player._visage == 3156)
- _sceneMode = 71;
- else
- _sceneMode = 70;
- break;
- case CRAWL_SOUTH:
- if (R2_GLOBALS._player._visage == 3156)
- _sceneMode = 96;
- else
- _sceneMode = 95;
- break;
- case CRAWL_NORTH:
- if (R2_GLOBALS._player._visage == 3155)
- _sceneMode = 45;
- else
- _sceneMode = 40;
- break;
- default:
- _sceneMode = 1;
- R2_GLOBALS._player.setup(3156, 4, 6);
- break;
- }
- R2_GLOBALS._player.disableControl();
- _nextCrawlDirection = 4;
- signal();
- }
- break;
- default:
- break;
- }
-}
-
-/*--------------------------------------------------------------------------
* Scene 1500 - Cutscene: Ship landing
*
*--------------------------------------------------------------------------*/
@@ -8849,1796 +7970,5 @@ void Scene1945::signal() {
R2_GLOBALS._player._canWalk = false;
}
-/*--------------------------------------------------------------------------
- * Scene 1950 - Flup Tube Corridor Maze
- *
- *--------------------------------------------------------------------------*/
-
-Scene1950::KeypadWindow::KeypadWindow() {
- _buttonIndex = 0;
-}
-
-void Scene1950::KeypadWindow::synchronize(Serializer &s) {
- SceneArea::synchronize(s);
-
- s.syncAsSint16LE(_buttonIndex);
-}
-
-Scene1950::KeypadWindow::KeypadButton::KeypadButton() {
- _buttonIndex = 0;
- _pressed = false;
- _toggled = false;
-}
-
-void Scene1950::KeypadWindow::KeypadButton::synchronize(Serializer &s) {
- SceneActor::synchronize(s);
-
- s.syncAsSint16LE(_buttonIndex);
- s.syncAsSint16LE(_pressed);
- s.syncAsSint16LE(_toggled);
-}
-
-void Scene1950::KeypadWindow::KeypadButton::init(int indx) {
- Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
-
- _buttonIndex = indx;
- _pressed = false;
- _toggled = false;
-
- postInit();
- setup(1971, 2, 1);
- fixPriority(249);
- setPosition(Common::Point(((_buttonIndex % 4) * 22) + 127, ((_buttonIndex / 4) * 19) + 71));
- scene->_sceneAreas.push_front(this);
-}
-
-void Scene1950::KeypadWindow::KeypadButton::process(Event &event) {
- if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == CURSOR_USE)
- && (_bounds.contains(event.mousePos)) && !_pressed) {
- R2_GLOBALS._sound2.play(227);
- if (!_toggled) {
- setFrame(2);
- _toggled = true;
- } else {
- setFrame(1);
- _toggled = false;
- }
- _pressed = true;
- event.handled = true;
- }
-
- if ((event.eventType == EVENT_BUTTON_UP) && _pressed) {
- _pressed = false;
- event.handled = true;
- Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
- scene->doButtonPress(_buttonIndex);
- }
-}
-
-bool Scene1950::KeypadWindow::KeypadButton::startAction(CursorType action, Event &event) {
- if (action == CURSOR_USE)
- return false;
- return SceneActor::startAction(action, event);
-}
-
-void Scene1950::KeypadWindow::remove() {
- Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
- for (_buttonIndex = 0; _buttonIndex < 16; ++_buttonIndex) {
- scene->_sceneAreas.remove(&_buttons[_buttonIndex]);
- _buttons[_buttonIndex].remove();
- }
-
- ModalWindow::remove();
-
- if (!R2_GLOBALS.getFlag(37))
- R2_GLOBALS._sound2.play(278);
-
- R2_GLOBALS._player.disableControl(CURSOR_WALK);
- scene->_eastExit._enabled = true;
-
- if (!R2_GLOBALS.getFlag(37)) {
- if (R2_GLOBALS.getFlag(36)) {
- scene->_sceneMode = 1964;
- scene->setAction(&scene->_sequenceManager, scene, 1964, &R2_GLOBALS._player, NULL);
- } else {
- scene->_sceneMode = 1965;
- scene->setAction(&scene->_sequenceManager, scene, 1965, &R2_GLOBALS._player, NULL);
- }
- }
-}
-
-void Scene1950::KeypadWindow::setup2(int visage, int stripFrameNum, int frameNum, int posX, int posY) {
- Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
-
- if (R2_GLOBALS._player._mover)
- R2_GLOBALS._player.addMover(NULL);
- R2_GLOBALS._player._canWalk = false;
-
- ModalWindow::setup2(visage, stripFrameNum, frameNum, posX, posY);
-
- _object1.fixPriority(248);
- scene->_eastExit._enabled = false;
- setup3(1950, 27, 28, 27);
-
- for (_buttonIndex = 0; _buttonIndex < 16; _buttonIndex++)
- _buttons[_buttonIndex].init(_buttonIndex);
-}
-
-void Scene1950::KeypadWindow::setup3(int resNum, int lookLineNum, int talkLineNum, int useLineNum) {
- // Copy of Scene1200::LaserPanel::proc13()
- _areaActor.setDetails(resNum, lookLineNum, talkLineNum, useLineNum, 2, (SceneItem *) NULL);
-}
-
-/*--------------------------------------------------------------------------*/
-
-bool Scene1950::Keypad::startAction(CursorType action, Event &event) {
- if ((action != CURSOR_USE) || (R2_GLOBALS.getFlag(37)))
- return SceneHotspot::startAction(action, event);
-
- Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
-
- R2_GLOBALS._player.disableControl();
- if (R2_GLOBALS.getFlag(36)) {
- scene->_sceneMode = 1962;
- scene->setAction(&scene->_sequenceManager, scene, 1962, &R2_GLOBALS._player, NULL);
- } else {
- scene->_sceneMode = 1963;
- scene->setAction(&scene->_sequenceManager, scene, 1963, &R2_GLOBALS._player, NULL);
- }
- return true;
-}
-
-bool Scene1950::Door::startAction(CursorType action, Event &event) {
- if (action != R2_SCRITH_KEY)
- return SceneActor::startAction(action, event);
-
- Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
-
- R2_GLOBALS._player.disableControl();
- R2_INVENTORY.setObjectScene(R2_SCRITH_KEY, 0);
- scene->_sceneMode = 1958;
- scene->setAction(&scene->_sequenceManager, scene, 1958, &R2_GLOBALS._player, &scene->_door, NULL);
- return true;
-}
-
-bool Scene1950::Scrolls::startAction(CursorType action, Event &event) {
- if ((action != CURSOR_USE) || (R2_INVENTORY.getObjectScene(R2_ANCIENT_SCROLLS) != 1950))
- return SceneActor::startAction(action, event);
-
- Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
-
- R2_GLOBALS._player.disableControl();
- scene->_sceneMode = 1968;
- scene->setAction(&scene->_sequenceManager, scene, 1968, &R2_GLOBALS._player, NULL);
-
- return true;
-}
-
-bool Scene1950::Gem::startAction(CursorType action, Event &event) {
- if ((action != CURSOR_USE) || (!R2_GLOBALS.getFlag(37)))
- return SceneActor::startAction(action, event);
-
- Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
-
- R2_GLOBALS._player.disableControl();
- scene->_sceneMode = 1967;
- scene->setAction(&scene->_sequenceManager, scene, 1967, &R2_GLOBALS._player, NULL);
-
- return true;
-}
-
-/*--------------------------------------------------------------------------*/
-
-Scene1950::Vampire::Vampire() {
- _deadPosition = Common::Point(0, 0);
- _deltaX = 0;
- _deltaY = 0;
- _vampireMode = 0;
-}
-
-void Scene1950::Vampire::synchronize(Serializer &s) {
- SceneActor::synchronize(s);
-
- s.syncAsSint16LE(_deadPosition.x);
- s.syncAsSint16LE(_deadPosition.y);
- s.syncAsSint16LE(_deltaX);
- s.syncAsSint16LE(_deltaY);
- s.syncAsSint16LE(_vampireMode);
-}
-
-void Scene1950::Vampire::signal() {
- Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
-
- switch (_vampireMode) {
- case 19: {
- _vampireMode = 0;
- setVisage(1960);
- if (R2_GLOBALS._flubMazeEntryDirection == 3)
- setStrip(2);
- else
- setStrip(1);
-
- NpcMover *mover = new NpcMover();
- addMover(mover, &scene->_vampireDestPos, scene);
- }
- break;
- case 20: {
- // Non fatal shot
- _vampireMode = 19;
- R2_GLOBALS._player.setVisage(22);
- if (R2_GLOBALS._flubMazeEntryDirection == 3)
- R2_GLOBALS._player.setStrip(1);
- else
- R2_GLOBALS._player.setStrip(2);
- R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
- R2_GLOBALS._vampireData[scene->_vampireIndex - 1]._shotsRequired--;
-
- if (R2_GLOBALS._flubMazeEntryDirection == 3)
- _deadPosition.x = _position.x + 10;
- else
- _deadPosition.x = _position.x - 10;
- _deadPosition.y = _position.y - 4;
-
- setVisage(1961);
-
- if (R2_GLOBALS._flubMazeEntryDirection == 3)
- setStrip(2);
- else
- setStrip(1);
-
- animate(ANIM_MODE_2, NULL);
- Common::Point pt = _deadPosition;
- PlayerMover *mover = new PlayerMover();
- addMover(mover, &pt, this);
-
- R2_GLOBALS._player.enableControl();
- }
- break;
- case 21: {
- // Fatal shot
- R2_GLOBALS._player.setVisage(22);
- if (R2_GLOBALS._flubMazeEntryDirection == 3)
- R2_GLOBALS._player.setStrip(1);
- else
- R2_GLOBALS._player.setStrip(2);
- R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
-
- setVisage(1961);
- if (R2_GLOBALS._flubMazeEntryDirection == 3)
- setStrip(4);
- else
- setStrip(3);
- setDetails(1950, 15, -1, 17, 2, (SceneItem *) NULL);
- addMover(NULL);
- _numFrames = 8;
- R2_GLOBALS._sound2.play(226);
- animate(ANIM_MODE_5, NULL);
- fixPriority(10);
-
- R2_GLOBALS._vampireData[scene->_vampireIndex - 1]._isAlive = false;
- R2_GLOBALS._vampireData[scene->_vampireIndex - 1]._shotsRequired--;
- R2_GLOBALS._vampireData[scene->_vampireIndex - 1]._position = _position;
- _deltaX = (_position.x - R2_GLOBALS._player._position.x) / 2;
- _deltaY = (_position.y - R2_GLOBALS._player._position.y) / 2;
-
- byte vampireCount = 0;
- for (byte i = 0; i < 18; ++i) {
- if (!R2_GLOBALS._vampireData[i]._isAlive)
- ++vampireCount;
- }
-
- if (vampireCount == 18) {
- R2_GLOBALS.setFlag(36);
- _vampireMode = 23;
- Common::Point pt(R2_GLOBALS._player._position.x + _deltaX, R2_GLOBALS._player._position.y + _deltaY);
- NpcMover *mover = new NpcMover();
- R2_GLOBALS._player.addMover(mover, &pt, this);
- } else if (vampireCount == 1) {
- _vampireMode = 22;
- Common::Point pt(R2_GLOBALS._player._position.x + _deltaX, R2_GLOBALS._player._position.y + _deltaY);
- NpcMover *mover = new NpcMover();
- R2_GLOBALS._player.addMover(mover, &pt, this);
- } else {
- R2_GLOBALS._player.enableControl(CURSOR_WALK);
- }
-
- if (R2_GLOBALS._flubMazeEntryDirection == 3)
- scene->_eastExit._enabled = true;
- else
- scene->_westExit._enabled = true;
-
- scene->_vampireActive = false;
- }
- break;
- case 22:
- SceneItem::display(1950, 18, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
- R2_GLOBALS._player.enableControl(CURSOR_WALK);
- break;
- case 23:
- SceneItem::display(1950, 25, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
- scene->_sceneMode = R2_GLOBALS._flubMazeEntryDirection;
- scene->setAction(&scene->_sequenceManager, scene, 1960, &R2_GLOBALS._player, NULL);
- break;
- default:
- break;
- }
-}
-
-bool Scene1950::Vampire::startAction(CursorType action, Event &event) {
- Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
-
- if (!R2_GLOBALS._vampireData[scene->_vampireIndex - 1]._isAlive ||
- (action != R2_PHOTON_STUNNER))
- return SceneActor::startAction(action, event);
-
- R2_GLOBALS._player.disableControl();
-
- if (R2_GLOBALS._vampireData[scene->_vampireIndex - 1]._shotsRequired <= 1)
- _vampireMode = 21;
- else
- _vampireMode = 20;
-
- R2_GLOBALS._player.setVisage(25);
- if (R2_GLOBALS._flubMazeEntryDirection == 3)
- R2_GLOBALS._player.setStrip(2);
- else
- R2_GLOBALS._player.setStrip(1);
- R2_GLOBALS._player.animate(ANIM_MODE_5, this);
- R2_GLOBALS._sound3.play(99);
-
- return true;
-}
-
-/*--------------------------------------------------------------------------*/
-
-void Scene1950::NorthExit::changeScene() {
- Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
-
- _enabled = false;
- R2_GLOBALS._player.disableControl(CURSOR_WALK);
- R2_GLOBALS._flubMazeEntryDirection = 1;
- scene->_sceneMode = 11;
-
- Common::Point pt(160, 127);
- PlayerMover *mover = new PlayerMover();
- R2_GLOBALS._player.addMover(mover, &pt, scene);
-}
-
-void Scene1950::UpExit::changeScene() {
- Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
-
- _enabled = false;
- R2_GLOBALS._player.disableControl(CURSOR_WALK);
- R2_GLOBALS._flubMazeEntryDirection = 2;
- scene->_sceneMode = 12;
-
- if (!scene->_upExitStyle) {
- if (R2_GLOBALS.getFlag(36))
- scene->setAction(&scene->_sequenceManager, scene, 1953, &R2_GLOBALS._player, NULL);
- else
- scene->setAction(&scene->_sequenceManager, scene, 1970, &R2_GLOBALS._player, NULL);
- } else {
- if (R2_GLOBALS.getFlag(36))
- scene->setAction(&scene->_sequenceManager, scene, 1952, &R2_GLOBALS._player, NULL);
- else
- scene->setAction(&scene->_sequenceManager, scene, 1969, &R2_GLOBALS._player, NULL);
- }
-}
-
-void Scene1950::EastExit::changeScene() {
- Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
-
- _enabled = false;
- R2_GLOBALS._player.disableControl(CURSOR_WALK);
- R2_GLOBALS._flubMazeEntryDirection = 3;
- scene->_sceneMode = 13;
-
- if (scene->_vampireActive)
- R2_GLOBALS._player.animate(ANIM_MODE_9);
-
- Common::Point pt(340, 160);
- NpcMover *mover = new NpcMover();
- R2_GLOBALS._player.addMover(mover, &pt, scene);
-}
-
-void Scene1950::DownExit::changeScene() {
- Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
-
- _enabled = false;
- R2_GLOBALS._player.disableControl(CURSOR_WALK);
- R2_GLOBALS._flubMazeEntryDirection = 4;
- scene->_sceneMode = 14;
-
- if (R2_GLOBALS.getFlag(36))
- scene->setAction(&scene->_sequenceManager, scene, 1956, &R2_GLOBALS._player, NULL);
- else
- scene->setAction(&scene->_sequenceManager, scene, 1973, &R2_GLOBALS._player, NULL);
-}
-
-void Scene1950::SouthExit::changeScene() {
- Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
-
- _enabled = false;
- R2_GLOBALS._player.disableControl(CURSOR_WALK);
- R2_GLOBALS._flubMazeEntryDirection = 5;
- scene->_sceneMode = 15;
-
- Common::Point pt(160, 213);
- NpcMover *mover = new NpcMover();
- R2_GLOBALS._player.addMover(mover, &pt, scene);
-}
-
-void Scene1950::WestExit::changeScene() {
- Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
-
- _enabled = false;
- R2_GLOBALS._player.disableControl(CURSOR_WALK);
- R2_GLOBALS._flubMazeEntryDirection = 6;
-
- if (R2_GLOBALS._flubMazeArea == 2) {
- // In the very first corridor area after the Scrith Door
- if ((R2_GLOBALS.getFlag(36)) && (R2_INVENTORY.getObjectScene(R2_SAPPHIRE_BLUE) == 2) && (R2_INVENTORY.getObjectScene(R2_ANCIENT_SCROLLS) == 2)) {
- scene->_sceneMode = 1961;
- Common::Point pt(-20, 160);
- NpcMover *mover = new NpcMover();
- R2_GLOBALS._player.addMover(mover, &pt, scene);
- } else {
- if (!R2_GLOBALS.getFlag(36))
- SceneItem::display(1950, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
- if ((R2_INVENTORY.getObjectScene(R2_SAPPHIRE_BLUE) == 1950) || (R2_INVENTORY.getObjectScene(R2_ANCIENT_SCROLLS) == 1950))
- SceneItem::display(1950, 34, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
- scene->_sceneMode = 0;
- Common::Point pt(30, 160);
- NpcMover *mover = new NpcMover();
- R2_GLOBALS._player.addMover(mover, &pt, scene);
- }
- } else {
- if (scene->_vampireActive)
- R2_GLOBALS._player.animate(ANIM_MODE_9);
-
- scene->_sceneMode = 16;
- Common::Point pt(-20, 160);
- NpcMover *mover = new NpcMover();
- R2_GLOBALS._player.addMover(mover, &pt, scene);
- }
-}
-
-void Scene1950::ShaftExit::changeScene() {
- Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
-
- _enabled = false;
- R2_GLOBALS._player.disableControl(CURSOR_WALK);
- R2_GLOBALS._flubMazeEntryDirection = 0;
- scene->_sceneMode = 1951;
- scene->setAction(&scene->_sequenceManager, scene, 1951, &R2_GLOBALS._player, NULL);
-}
-
-void Scene1950::DoorExit::changeScene() {
- Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
-
- _enabled = false;
- R2_GLOBALS._player.disableControl(CURSOR_WALK);
- R2_GLOBALS._flubMazeEntryDirection = 3;
- if (R2_GLOBALS._player._visage == 22) {
- scene->_sceneMode = 1975;
- scene->setAction(&scene->_sequenceManager, scene, 1975, &R2_GLOBALS._player, NULL);
- } else {
- SceneItem::display(1950, 22, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
- R2_GLOBALS._flubMazeEntryDirection = 0;
- scene->_sceneMode = 0;
- Common::Point pt(250, 150);
- NpcMover *mover = new NpcMover();
- R2_GLOBALS._player.addMover(mover, &pt, scene);
- _enabled = true;
- }
-}
-
-/*--------------------------------------------------------------------------*/
-
-Scene1950::Scene1950() {
- _upExitStyle = false;
- _removeFlag = false;
- _vampireActive = false;
- _vampireDestPos = Common::Point(0, 0);
- _vampireIndex = 0;
-}
-
-void Scene1950::synchronize(Serializer &s) {
- SceneExt::synchronize(s);
-
- s.syncAsSint16LE(_upExitStyle);
- s.syncAsSint16LE(_removeFlag);
- s.syncAsSint16LE(_vampireActive);
- s.syncAsSint16LE(_vampireDestPos.x);
- s.syncAsSint16LE(_vampireDestPos.y);
- s.syncAsSint16LE(_vampireIndex);
-}
-
-void Scene1950::initArea() {
- _northExit._enabled = false;
- _upExit._enabled = false;
- _eastExit._enabled = false;
- _downExit._enabled = false;
- _southExit._enabled = false;
- _westExit._enabled = false;
- _shaftExit._enabled = false;
- _doorExit._enabled = false;
- _northExit._insideArea = false;
- _upExit._insideArea = false;
- _eastExit._insideArea = false;
- _downExit._insideArea = false;
- _southExit._insideArea = false;
- _westExit._insideArea = false;
- _shaftExit._insideArea = false;
- _doorExit._insideArea = false;
- _northExit._moving = false;
- _upExit._moving = false;
- _eastExit._moving = false;
- _downExit._moving = false;
- _southExit._moving = false;
- _westExit._moving = false;
- _shaftExit._moving = false;
- _doorExit._moving = false;
- _upExitStyle = false;
-
- switch (R2_GLOBALS._flubMazeArea - 1) {
- case 0:
- loadScene(1948);
- break;
- case 1:
- // No break on purpose
- case 8:
- // No break on purpose
- case 10:
- // No break on purpose
- case 12:
- // No break on purpose
- case 16:
- // No break on purpose
- case 19:
- // No break on purpose
- case 23:
- // No break on purpose
- case 30:
- // No break on purpose
- case 44:
- // No break on purpose
- case 72:
- // No break on purpose
- case 74:
- // No break on purpose
- case 86:
- // No break on purpose
- case 96:
- // No break on purpose
- case 103:
- loadScene(1950);
- break;
- case 2:
- // No break on purpose
- case 29:
- loadScene(1965);
- break;
- case 3:
- // No break on purpose
- case 9:
- // No break on purpose
- case 11:
- // No break on purpose
- case 15:
- // No break on purpose
- case 24:
- // No break on purpose
- case 39:
- // No break on purpose
- case 45:
- // No break on purpose
- case 71:
- // No break on purpose
- case 73:
- // No break on purpose
- case 75:
- // No break on purpose
- case 79:
- // No break on purpose
- case 85:
- // No break on purpose
- case 87:
- // No break on purpose
- case 95:
- loadScene(1955);
- break;
- case 4:
- // No break on purpose
- case 6:
- // No break on purpose
- case 13:
- // No break on purpose
- case 27:
- // No break on purpose
- case 41:
- // No break on purpose
- case 48:
- // No break on purpose
- case 50:
- // No break on purpose
- case 54:
- // No break on purpose
- case 76:
- // No break on purpose
- case 80:
- // No break on purpose
- case 90:
- // No break on purpose
- case 104:
- loadScene(1975);
- break;
- case 5:
- // No break on purpose
- case 7:
- // No break on purpose
- case 14:
- // No break on purpose
- case 28:
- // No break on purpose
- case 32:
- // No break on purpose
- case 47:
- // No break on purpose
- case 53:
- loadScene(1997);
- break;
- case 17:
- // No break on purpose
- case 20:
- // No break on purpose
- case 25:
- // No break on purpose
- case 31:
- // No break on purpose
- case 33:
- // No break on purpose
- case 46:
- loadScene(1995);
- break;
- case 18:
- // No break on purpose
- case 22:
- // No break on purpose
- case 26:
- // No break on purpose
- case 36:
- // No break on purpose
- case 38:
- // No break on purpose
- case 43:
- // No break on purpose
- case 51:
- // No break on purpose
- case 70:
- // No break on purpose
- case 78:
- // No break on purpose
- case 84:
- // No break on purpose
- case 89:
- // No break on purpose
- case 101:
- loadScene(1970);
- break;
- case 21:
- // No break on purpose
- case 34:
- // No break on purpose
- case 57:
- // No break on purpose
- case 58:
- // No break on purpose
- case 59:
- // No break on purpose
- case 62:
- // No break on purpose
- case 65:
- loadScene(1980);
- break;
- case 35:
- // No break on purpose
- case 61:
- // No break on purpose
- case 77:
- // No break on purpose
- case 83:
- loadScene(1982);
- break;
- case 37:
- // No break on purpose
- case 52:
- // No break on purpose
- case 82:
- // No break on purpose
- case 88:
- // No break on purpose
- case 92:
- // No break on purpose
- case 97:
- // No break on purpose
- case 100:
- loadScene(1962);
- break;
- case 40:
- // No break on purpose
- case 102:
- loadScene(1960);
- break;
- case 42:
- // No break on purpose
- case 55:
- // No break on purpose
- case 60:
- // No break on purpose
- case 66:
- // No break on purpose
- case 68:
- // No break on purpose
- case 69:
- // No break on purpose
- case 93:
- // No break on purpose
- case 98:
- loadScene(1990);
- break;
- case 49:
- // No break on purpose
- case 81:
- // No break on purpose
- case 91:
- // No break on purpose
- case 94:
- // No break on purpose
- case 99:
- loadScene(1967);
- break;
- case 56:
- // No break on purpose
- case 63:
- // No break on purpose
- case 64:
- // No break on purpose
- case 67:
- loadScene(1985);
- _upExitStyle = true;
- break;
- default:
- break;
- }
-
- if (R2_GLOBALS._flubMazeArea != 1)
- R2_GLOBALS._walkRegions.load(1950);
-
- switch (R2_GLOBALS._flubMazeArea - 1) {
- case 0:
- _shaftExit._enabled = true;
- if ((R2_INVENTORY.getObjectScene(R2_SCRITH_KEY) == 0) && (R2_INVENTORY.getObjectScene(R2_SAPPHIRE_BLUE) == 1950))
- _doorExit._enabled = true;
- R2_GLOBALS._walkRegions.disableRegion(2);
- R2_GLOBALS._walkRegions.disableRegion(3);
- R2_GLOBALS._walkRegions.disableRegion(4);
- R2_GLOBALS._walkRegions.disableRegion(5);
- R2_GLOBALS._walkRegions.disableRegion(6);
- break;
- case 1:
- // No break on purpose
- case 2:
- // No break on purpose
- case 3:
- // No break on purpose
- case 8:
- // No break on purpose
- case 9:
- // No break on purpose
- case 10:
- // No break on purpose
- case 11:
- // No break on purpose
- case 12:
- // No break on purpose
- case 15:
- // No break on purpose
- case 16:
- // No break on purpose
- case 19:
- // No break on purpose
- case 23:
- // No break on purpose
- case 24:
- // No break on purpose
- case 29:
- // No break on purpose
- case 30:
- // No break on purpose
- case 39:
- // No break on purpose
- case 40:
- // No break on purpose
- case 44:
- // No break on purpose
- case 45:
- // No break on purpose
- case 71:
- // No break on purpose
- case 72:
- // No break on purpose
- case 73:
- // No break on purpose
- case 74:
- // No break on purpose
- case 75:
- // No break on purpose
- case 79:
- // No break on purpose
- case 85:
- // No break on purpose
- case 86:
- // No break on purpose
- case 87:
- // No break on purpose
- case 95:
- // No break on purpose
- case 96:
- // No break on purpose
- case 102:
- // No break on purpose
- case 103:
- _eastExit._enabled = true;
- _westExit._enabled = true;
- break;
- case 4:
- // No break on purpose
- case 6:
- // No break on purpose
- case 13:
- // No break on purpose
- case 17:
- // No break on purpose
- case 20:
- // No break on purpose
- case 25:
- // No break on purpose
- case 27:
- // No break on purpose
- case 31:
- // No break on purpose
- case 33:
- // No break on purpose
- case 37:
- // No break on purpose
- case 41:
- // No break on purpose
- case 46:
- // No break on purpose
- case 48:
- // No break on purpose
- case 50:
- // No break on purpose
- case 52:
- // No break on purpose
- case 54:
- // No break on purpose
- case 76:
- // No break on purpose
- case 80:
- // No break on purpose
- case 82:
- // No break on purpose
- case 88:
- // No break on purpose
- case 90:
- // No break on purpose
- case 92:
- // No break on purpose
- case 97:
- // No break on purpose
- case 100:
- // No break on purpose
- case 104:
- _westExit._enabled = true;
- R2_GLOBALS._walkRegions.disableRegion(6);
- R2_GLOBALS._walkRegions.disableRegion(9);
- break;
- case 5:
- // No break on purpose
- case 7:
- // No break on purpose
- case 14:
- // No break on purpose
- case 18:
- // No break on purpose
- case 22:
- // No break on purpose
- case 26:
- // No break on purpose
- case 28:
- // No break on purpose
- case 32:
- // No break on purpose
- case 36:
- // No break on purpose
- case 38:
- // No break on purpose
- case 43:
- // No break on purpose
- case 47:
- // No break on purpose
- case 49:
- // No break on purpose
- case 51:
- // No break on purpose
- case 53:
- // No break on purpose
- case 70:
- // No break on purpose
- case 78:
- // No break on purpose
- case 81:
- // No break on purpose
- case 84:
- // No break on purpose
- case 89:
- // No break on purpose
- case 91:
- // No break on purpose
- case 94:
- // No break on purpose
- case 99:
- // No break on purpose
- case 101:
- _eastExit._enabled = true;
- R2_GLOBALS._walkRegions.disableRegion(1);
- R2_GLOBALS._walkRegions.disableRegion(7);
- R2_GLOBALS._walkRegions.disableRegion(13);
- break;
- default:
- R2_GLOBALS._walkRegions.disableRegion(1);
- R2_GLOBALS._walkRegions.disableRegion(6);
- R2_GLOBALS._walkRegions.disableRegion(7);
- R2_GLOBALS._walkRegions.disableRegion(9);
- R2_GLOBALS._walkRegions.disableRegion(13);
- break;
- }
-
- _northDoorway.remove();
- _northDoorway.removeObject();
- _southDoorway.remove();
-
- switch (R2_GLOBALS._flubMazeArea - 4) {
- case 0:
- // No break on purpose
- case 3:
- // No break on purpose
- case 16:
- // No break on purpose
- case 22:
- // No break on purpose
- case 24:
- // No break on purpose
- case 32:
- // No break on purpose
- case 33:
- // No break on purpose
- case 45:
- // No break on purpose
- case 46:
- // No break on purpose
- case 48:
- // No break on purpose
- case 51:
- // No break on purpose
- case 56:
- // No break on purpose
- case 59:
- // No break on purpose
- case 67:
- // No break on purpose
- case 68:
- // No break on purpose
- case 70:
- // No break on purpose
- case 73:
- // No break on purpose
- case 82:
- // No break on purpose
- case 90:
- _northExit._enabled = true;
- _northDoorway.setup(1950, (R2_GLOBALS._flubMazeArea % 2) + 1, 1, 160, 137, 25);
- //visage,strip,frame,px,py,priority,effect
- _southDoorway.postInit();
- _southDoorway.setVisage(1950);
- _southDoorway.setStrip((((R2_GLOBALS._flubMazeArea - 1) / 35) % 2) + 1);
- _southDoorway.setFrame(2);
- _southDoorway.setPosition(Common::Point(160, 167));
- _southDoorway.fixPriority(220);
- R2_GLOBALS._walkRegions.disableRegion(3);
- R2_GLOBALS._walkRegions.disableRegion(4);
- break;
- case 7:
- // No break on purpose
- case 10:
- // No break on purpose
- case 23:
- // No break on purpose
- case 29:
- // No break on purpose
- case 31:
- // No break on purpose
- case 39:
- // No break on purpose
- case 40:
- // No break on purpose
- case 52:
- // No break on purpose
- case 53:
- // No break on purpose
- case 55:
- // No break on purpose
- case 63:
- // No break on purpose
- case 65:
- // No break on purpose
- case 66:
- // No break on purpose
- case 75:
- // No break on purpose
- case 77:
- // No break on purpose
- case 81:
- // No break on purpose
- case 87:
- // No break on purpose
- case 89:
- // No break on purpose
- case 97:
- _southExit._enabled = true;
-
- _southDoorway.postInit();
- _southDoorway.setVisage(1950);
- _southDoorway.setStrip((((R2_GLOBALS._flubMazeArea - 1) / 35) % 2) + 1);
- _southDoorway.setFrame(3);
- _southDoorway.setPosition(Common::Point(160, 167));
- _southDoorway.fixPriority(220);
- break;
- case 58:
- // No break on purpose
- case 74:
- // No break on purpose
- case 80:
- _northExit._enabled = true;
- _southExit._enabled = true;
-
- _northDoorway.setup(1950, (R2_GLOBALS._flubMazeArea % 2) + 1, 1, 160, 137, 25);
-
- _southDoorway.postInit();
- _southDoorway.setVisage(1950);
- _southDoorway.setStrip((((R2_GLOBALS._flubMazeArea - 1) / 35) % 2) + 1);
- _southDoorway.setFrame(3);
- _southDoorway.setPosition(Common::Point(160, 167));
- _southDoorway.fixPriority(220);
- R2_GLOBALS._walkRegions.disableRegion(3);
- R2_GLOBALS._walkRegions.disableRegion(4);
- break;
- default:
- _southDoorway.postInit();
- _southDoorway.setVisage(1950);
- _southDoorway.setStrip(((R2_GLOBALS._flubMazeArea - 1) / 35) % 2 + 1);
- _southDoorway.setFrame(2);
- _southDoorway.setPosition(Common::Point(160, 167));
- _southDoorway.fixPriority(220);
- break;
- }
-
- switch (R2_GLOBALS._flubMazeArea - 3) {
- case 0:
- // No break on purpose
- case 3:
- // No break on purpose
- case 5:
- // No break on purpose
- case 12:
- // No break on purpose
- case 15:
- // No break on purpose
- case 18:
- // No break on purpose
- case 19:
- // No break on purpose
- case 23:
- // No break on purpose
- case 26:
- // No break on purpose
- case 27:
- // No break on purpose
- case 29:
- // No break on purpose
- case 30:
- // No break on purpose
- case 31:
- // No break on purpose
- case 32:
- // No break on purpose
- case 44:
- // No break on purpose
- case 45:
- // No break on purpose
- case 51:
- // No break on purpose
- case 55:
- // No break on purpose
- case 56:
- // No break on purpose
- case 57:
- // No break on purpose
- case 60:
- // No break on purpose
- case 63:
- _upExit._enabled = true;
- break;
- case 54:
- // No break on purpose
- case 61:
- // No break on purpose
- case 62:
- // No break on purpose
- case 65:
- _upExit._enabled = true;
- // No break on purpose
- case 35:
- // No break on purpose
- case 38:
- // No break on purpose
- case 40:
- // No break on purpose
- case 47:
- // No break on purpose
- case 50:
- // No break on purpose
- case 53:
- // No break on purpose
- case 58:
- // No break on purpose
- case 64:
- // No break on purpose
- case 66:
- // No break on purpose
- case 67:
- // No break on purpose
- case 79:
- // No break on purpose
- case 80:
- // No break on purpose
- case 86:
- // No break on purpose
- case 89:
- // No break on purpose
- case 90:
- // No break on purpose
- case 91:
- // No break on purpose
- case 92:
- // No break on purpose
- case 95:
- // No break on purpose
- case 96:
- // No break on purpose
- case 97:
- // No break on purpose
- case 98:
- // No break on purpose
- case 100:
- _downExit._enabled = true;
- R2_GLOBALS._walkRegions.disableRegion(4);
- R2_GLOBALS._walkRegions.disableRegion(5);
- R2_GLOBALS._walkRegions.disableRegion(6);
- R2_GLOBALS._walkRegions.disableRegion(10);
- R2_GLOBALS._walkRegions.disableRegion(11);
- default:
- break;
- }
- R2_GLOBALS._uiElements.draw();
-}
-
-void Scene1950::enterArea() {
- R2_GLOBALS._player.disableControl();
- R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
-
- _vampire.remove();
- _door.remove();
- _scrolls.remove();
-
- _vampireActive = false;
- _vampireIndex = 0;
-
- // Certain areas have a vampire in them
- switch (R2_GLOBALS._flubMazeArea) {
- case 10:
- _vampireIndex = 1;
- break;
- case 13:
- _vampireIndex = 2;
- break;
- case 16:
- _vampireIndex = 3;
- break;
- case 17:
- _vampireIndex = 4;
- break;
- case 24:
- _vampireIndex = 5;
- break;
- case 25:
- _vampireIndex = 6;
- break;
- case 31:
- _vampireIndex = 7;
- break;
- case 40:
- _vampireIndex = 8;
- break;
- case 45:
- _vampireIndex = 9;
- break;
- case 46:
- _vampireIndex = 10;
- break;
- case 73:
- _vampireIndex = 11;
- break;
- case 75:
- _vampireIndex = 12;
- break;
- case 80:
- _vampireIndex = 13;
- break;
- case 87:
- _vampireIndex = 14;
- break;
- case 88:
- _vampireIndex = 15;
- break;
- case 96:
- _vampireIndex = 16;
- break;
- case 97:
- _vampireIndex = 17;
- break;
- case 104:
- _vampireIndex = 18;
- break;
- default:
- break;
- }
-
- if (_vampireIndex != 0) {
- _vampire.postInit();
- _vampire._numFrames = 6;
- _vampire._moveRate = 6;
- _vampire._moveDiff = Common::Point(3, 2);
- _vampire._effect = EFFECT_SHADED;
-
- if (!R2_GLOBALS._vampireData[_vampireIndex - 1]._isAlive) {
- // Show vampire ashes
- _vampire.setPosition(Common::Point(R2_GLOBALS._vampireData[_vampireIndex - 1]._position));
- _vampire.animate(ANIM_MODE_NONE, NULL);
- _vampire.addMover(NULL);
- _vampire.setVisage(1961);
- _vampire.setStrip(4);
- _vampire.setFrame(10);
- _vampire.fixPriority(10);
- _vampire.setDetails(1950, 15, -1, 17, 2, (SceneItem *) NULL);
- } else {
- // Start the vampire
- _vampire.setVisage(1960);
- _vampire.setPosition(Common::Point(160, 130));
- _vampire.animate(ANIM_MODE_2, NULL);
- _vampire.setDetails(1950, 12, -1, 14, 2, (SceneItem *) NULL);
- _vampireActive = true;
- }
- }
- if ((R2_GLOBALS._flubMazeArea == 1) && (R2_INVENTORY.getObjectScene(R2_SCRITH_KEY) != 0)) {
- // Show doorway at the right hand side of the very first flub corridor
- _door.postInit();
- _door.setVisage(1948);
- _door.setStrip(3);
- _door.setPosition(Common::Point(278, 155));
- _door.fixPriority(100);
- _door.setDetails(1950, 19, 20, 23, 2, (SceneItem *) NULL);
- }
-
- if (R2_GLOBALS._flubMazeArea == 102) {
- R2_GLOBALS._walkRegions.load(1951);
- R2_GLOBALS._walkRegions.disableRegion(1);
- R2_GLOBALS._walkRegions.disableRegion(5);
- R2_GLOBALS._walkRegions.disableRegion(6);
- R2_GLOBALS._walkRegions.disableRegion(7);
-
- _cube.postInit();
- _cube.setVisage(1970);
- _cube.setStrip(1);
- if (R2_GLOBALS.getFlag(37))
- _cube.setFrame(3);
- else
- _cube.setFrame(1);
- _cube.setPosition(Common::Point(193, 158));
- _cube.setDetails(1950, 3, 4, 5, 2, (SceneItem *) NULL);
-
- _pulsingLights.postInit();
- _pulsingLights.setVisage(1970);
- _pulsingLights.setStrip(3);
- _pulsingLights.animate(ANIM_MODE_2, NULL);
- _pulsingLights._numFrames = 6;
- _pulsingLights.setPosition(Common::Point(194, 158));
- _pulsingLights.fixPriority(159);
-
- _keypad.setDetails(Rect(188, 124, 199, 133), 1950, 27, 28, -1, 2, NULL);
-
- if (R2_INVENTORY.getObjectScene(R2_SAPPHIRE_BLUE) == 1950) {
- _gem.postInit();
- _gem.setVisage(1970);
- _gem.setStrip(1);
- _gem.setFrame(2);
- _gem.fixPriority(160);
- }
-
- if (R2_GLOBALS.getFlag(37)) {
- _gem.setPosition(Common::Point(192, 118));
- _gem.setDetails(1950, 9, 4, -1, 2, (SceneItem *) NULL);
- } else {
- _containmentField.postInit();
- _containmentField.setVisage(1970);
- _containmentField.setStrip(4);
- _containmentField._numFrames = 4;
- _containmentField.animate(ANIM_MODE_8, 0, NULL);
- _containmentField.setPosition(Common::Point(192, 121));
- _containmentField.fixPriority(159);
- _containmentField.setDetails(1950, 6, 7, 8, 2, (SceneItem *) NULL);
-
- _gem.setPosition(Common::Point(192, 109));
- _gem.setDetails(1950, 9, 7, 8, 2, (SceneItem *) NULL);
- }
-
- _scrolls.postInit();
- _scrolls.setVisage(1972);
- _scrolls.setStrip(1);
- _scrolls.setPosition(Common::Point(76, 94));
- _scrolls.fixPriority(25);
- _scrolls.setDetails(1950, 30, -1, -1, 2, (SceneItem *) NULL);
- if (R2_INVENTORY.getObjectScene(R2_ANCIENT_SCROLLS) == 2)
- _scrolls.setFrame(2);
- else
- _scrolls.setFrame(1);
-
- _removeFlag = true;
- } else if (_removeFlag) {
- _cube.remove();
- _containmentField.remove();
- _gem.remove();
- _pulsingLights.remove();
- _scrolls.remove();
-
- R2_GLOBALS._sceneItems.remove(&_background);
- _background.setDetails(Rect(0, 0, 320, 200), 1950, 0, 1, 2, 2, NULL);
-
- _removeFlag = false;
- }
-
- switch (R2_GLOBALS._flubMazeEntryDirection) {
- case 0:
- _sceneMode = 1950;
- if (R2_INVENTORY.getObjectScene(R2_SCRITH_KEY) == 0)
- // The original uses CURSOR_ARROW. CURSOR_WALK is much more coherent
- R2_GLOBALS._player.enableControl(CURSOR_WALK);
- else
- setAction(&_sequenceManager, this, 1950, &R2_GLOBALS._player, NULL);
-
- break;
- case 1: {
- _sceneMode = R2_GLOBALS._flubMazeEntryDirection;
- R2_GLOBALS._player.setPosition(Common::Point(160, 213));
- Common::Point pt(160, 160);
- NpcMover *mover = new NpcMover();
- R2_GLOBALS._player.addMover(mover, &pt, this);
- }
- break;
- case 2:
- _sceneMode = R2_GLOBALS._flubMazeEntryDirection;
- if (R2_GLOBALS.getFlag(36))
- setAction(&_sequenceManager, this, 1957, &R2_GLOBALS._player, NULL);
- else
- setAction(&_sequenceManager, this, 1974, &R2_GLOBALS._player, NULL);
- break;
- case 3:
- // Entering from the left
- if (!_vampireActive) {
- _sceneMode = R2_GLOBALS._flubMazeEntryDirection;
- R2_GLOBALS._player.setPosition(Common::Point(-20, 160));
- Common::Point pt(30, 160);
- NpcMover *mover = new NpcMover();
- R2_GLOBALS._player.addMover(mover, &pt, this);
- } else {
- _sceneMode = 18;
- _eastExit._enabled = false;
- _vampireDestPos = Common::Point(60, 152);
- R2_GLOBALS._player.enableControl(CURSOR_USE);
- R2_GLOBALS._player._canWalk = false;
-
- _vampire.setStrip(2);
- NpcMover *mover = new NpcMover();
- _vampire.addMover(mover, &_vampireDestPos, this);
-
- R2_GLOBALS._player.setPosition(Common::Point(-20, 160));
- Common::Point pt2(30, 160);
- NpcMover *mover2 = new NpcMover();
- R2_GLOBALS._player.addMover(mover2, &pt2, NULL);
- }
- break;
- case 4:
- _sceneMode = R2_GLOBALS._flubMazeEntryDirection;
- if (!_upExitStyle) {
- if (R2_GLOBALS.getFlag(36))
- setAction(&_sequenceManager, this, 1955, &R2_GLOBALS._player, NULL);
- else
- setAction(&_sequenceManager, this, 1972, &R2_GLOBALS._player, NULL);
- } else {
- if (R2_GLOBALS.getFlag(36))
- setAction(&_sequenceManager, this, 1954, &R2_GLOBALS._player, NULL);
- else
- setAction(&_sequenceManager, this, 1971, &R2_GLOBALS._player, NULL);
- }
- break;
- case 5: {
- _sceneMode = R2_GLOBALS._flubMazeEntryDirection;
- R2_GLOBALS._player.setPosition(Common::Point(160, 127));
- Common::Point pt(160, 160);
- NpcMover *mover = new NpcMover();
- R2_GLOBALS._player.addMover(mover, &pt, this);
- }
- break;
- case 6:
- // Entering from the right
- if (!_vampireActive) {
- _sceneMode = R2_GLOBALS._flubMazeEntryDirection;
- if (R2_GLOBALS._flubMazeArea == 1) {
- setAction(&_sequenceManager, this, 1961, &R2_GLOBALS._player, NULL);
- } else {
- R2_GLOBALS._player.setPosition(Common::Point(340, 160));
- Common::Point pt(289, 160);
- NpcMover *mover = new NpcMover();
- R2_GLOBALS._player.addMover(mover, &pt, this);
- }
- } else {
- _sceneMode = 17;
- _westExit._enabled = false;
- _vampireDestPos = Common::Point(259, 152);
-
- R2_GLOBALS._player.enableControl(CURSOR_USE);
- R2_GLOBALS._player._canWalk = false;
-
- _vampire.setStrip(1);
- NpcMover *mover = new NpcMover();
- _vampire.addMover(mover, &_vampireDestPos, this);
-
- R2_GLOBALS._player.setPosition(Common::Point(340, 160));
- Common::Point pt2(289, 160);
- NpcMover *mover2 = new NpcMover();
- R2_GLOBALS._player.addMover(mover2, &pt2, NULL);
- }
- break;
- default:
- break;
- }
-}
-
-void Scene1950::doButtonPress(int indx) {
- Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
- R2_GLOBALS._player.disableControl();
-
- int prevIndex = indx - 1;
- if ((indx / 4) == (prevIndex / 4)) {
- if (prevIndex < 0)
- prevIndex = 3;
- } else {
- prevIndex += 4;
- }
-
- assert(prevIndex >= 0 && prevIndex < 16);
- if (!_KeypadWindow._buttons[prevIndex]._toggled) {
- _KeypadWindow._buttons[prevIndex].setFrame(2);
- _KeypadWindow._buttons[prevIndex]._toggled = true;
- } else {
- _KeypadWindow._buttons[prevIndex].setFrame(1);
- _KeypadWindow._buttons[prevIndex]._toggled = false;
- }
-
- prevIndex = indx + 1;
- if ((indx / 4) == (prevIndex / 4)) {
- if (prevIndex > 15)
- prevIndex = 12;
- } else {
- prevIndex -= 4;
- }
-
- assert(prevIndex >= 0 && prevIndex < 16);
- if (!_KeypadWindow._buttons[prevIndex]._toggled) {
- _KeypadWindow._buttons[prevIndex].setFrame(2);
- _KeypadWindow._buttons[prevIndex]._toggled = true;
- } else {
- _KeypadWindow._buttons[prevIndex].setFrame(1);
- _KeypadWindow._buttons[prevIndex]._toggled = false;
- }
-
- prevIndex = indx - 4;
- if (prevIndex < 0)
- prevIndex += 16;
-
- assert(prevIndex >= 0 && prevIndex < 16);
- if (!_KeypadWindow._buttons[prevIndex]._toggled) {
- _KeypadWindow._buttons[prevIndex].setFrame(2);
- _KeypadWindow._buttons[prevIndex]._toggled = true;
- } else {
- _KeypadWindow._buttons[prevIndex].setFrame(1);
- _KeypadWindow._buttons[prevIndex]._toggled = false;
- }
-
- prevIndex = indx + 4;
- if (prevIndex > 15)
- prevIndex -= 16;
-
- assert(prevIndex >= 0 && prevIndex < 16);
- if (!_KeypadWindow._buttons[prevIndex]._toggled) {
- _KeypadWindow._buttons[prevIndex].setFrame(2);
- _KeypadWindow._buttons[prevIndex]._toggled = true;
- } else {
- _KeypadWindow._buttons[prevIndex].setFrame(1);
- _KeypadWindow._buttons[prevIndex]._toggled = false;
- }
-
- // Check whether all the buttons are highlighted
- int cpt = 0;
- for (prevIndex = 0; prevIndex < 16; prevIndex++) {
- if (_KeypadWindow._buttons[prevIndex]._toggled)
- ++cpt;
- }
-
- if (cpt != 16) {
- R2_GLOBALS._player.enableControl();
- R2_GLOBALS._player._canWalk = false;
- } else {
- R2_GLOBALS.setFlag(37);
- _sceneMode = 24;
- setAction(&_sequenceManager, scene, 1976, NULL);
- }
-}
-
-void Scene1950::postInit(SceneObjectList *OwnerList) {
- _upExitStyle = false;
- _removeFlag = false;
- _vampireActive = false;
- _vampireIndex = 0;
- if (R2_GLOBALS._sceneManager._previousScene == 300)
- R2_GLOBALS._flubMazeArea = 103;
-
- initArea();
- SceneExt::postInit();
- R2_GLOBALS._sound1.play(105);
-
- _northExit.setDetails(Rect(130, 46, 189, 135), SHADECURSOR_UP, 1950);
- _northExit.setDest(Common::Point(160, 145));
-
- _upExit.setDetails(Rect(208, 0, 255, 73), EXITCURSOR_N, 1950);
- _upExit.setDest(Common::Point(200, 151));
-
- _eastExit.setDetails(Rect(305, 95, 320, 147), EXITCURSOR_E, 1950);
- _eastExit.setDest(Common::Point(312, 160));
-
- _downExit.setDetails(Rect(208, 99, 255, 143), EXITCURSOR_S, 1950);
- _downExit.setDest(Common::Point(200, 151));
-
- _southExit.setDetails(Rect(113, 154, 206, 168), SHADECURSOR_DOWN, 1950);
- _southExit.setDest(Common::Point(160, 165));
-
- _westExit.setDetails(Rect(0, 95, 14, 147), EXITCURSOR_W, 1950);
- _westExit.setDest(Common::Point(7, 160));
-
- _shaftExit.setDetails(Rect(72, 54, 120, 128), EXITCURSOR_NW, 1950);
- _shaftExit.setDest(Common::Point(120, 140));
-
- _doorExit.setDetails(Rect(258, 60, 300, 145), EXITCURSOR_NE, 1950);
- _doorExit.setDest(Common::Point(268, 149));
-
- R2_GLOBALS._player.postInit();
- if ( (R2_INVENTORY.getObjectScene(R2_TANNER_MASK) == 0) && (R2_INVENTORY.getObjectScene(R2_PURE_GRAIN_ALCOHOL) == 0)
- && (R2_INVENTORY.getObjectScene(R2_SOAKED_FACEMASK) == 0) && (!R2_GLOBALS.getFlag(36)) )
- R2_GLOBALS._player.setVisage(22);
- else
- R2_GLOBALS._player.setVisage(20);
-
- R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
- _background.setDetails(Rect(0, 0, 320, 200), 1950, 0, 1, 2, 1, NULL);
-
- enterArea();
-}
-
-void Scene1950::remove() {
- R2_GLOBALS._sound1.stop();
- R2_GLOBALS._sound2.fadeOut2(NULL);
- SceneExt::remove();
-}
-
-void Scene1950::signal() {
- switch (_sceneMode) {
- case 11:
- R2_GLOBALS._flubMazeArea += 7;
- initArea();
- enterArea();
- break;
- case 12:
- // Moving up a ladder within the Flub maze
- R2_GLOBALS._flubMazeArea += 35;
- initArea();
- enterArea();
- break;
- case 1975:
- SceneItem::display(1950, 21, SET_WIDTH, 280, SET_X, 160, SET_POS_MODE, 1,
- SET_Y, 20, SET_EXT_BGCOLOR, 7, LIST_END);
- // No break on purpose
- case 13:
- // Moving east within the Flub maze
- ++R2_GLOBALS._flubMazeArea;
- initArea();
- enterArea();
- break;
- case 14:
- // Moving down a ladder within the Flub maze
- R2_GLOBALS._flubMazeArea -= 35;
- initArea();
- enterArea();
- break;
- case 15:
- R2_GLOBALS._flubMazeArea -= 7;
- initArea();
- enterArea();
- break;
- case 16:
- // Moving west within the Flub maze
- // No break on purpose
- case 1961:
- --R2_GLOBALS._flubMazeArea;
- initArea();
- enterArea();
- break;
- case 17: {
- _sceneMode = 13;
- R2_GLOBALS._flubMazeEntryDirection = 3;
- _vampireActive = false;
- R2_GLOBALS._player.disableControl(CURSOR_WALK);
- R2_GLOBALS._player._canWalk = true;
- R2_GLOBALS._player.setVisage(22);
- R2_GLOBALS._player.animate(ANIM_MODE_9);
- Common::Point pt(340, 160);
- NpcMover *mover = new NpcMover();
- R2_GLOBALS._player.addMover(mover, &pt, this);
- Common::Point pt2(289, 160);
- NpcMover *mover2 = new NpcMover();
- _vampire.addMover(mover2, &pt2, NULL);
- }
- break;
- case 18: {
- _sceneMode = 16;
- R2_GLOBALS._flubMazeEntryDirection = 6;
- _vampireActive = false;
- R2_GLOBALS._player.disableControl(CURSOR_WALK);
- R2_GLOBALS._player._canWalk = true;
- R2_GLOBALS._player.setVisage(22);
- R2_GLOBALS._player.animate(ANIM_MODE_9);
- Common::Point pt(-20, 160);
- NpcMover *mover = new NpcMover();
- R2_GLOBALS._player.addMover(mover, &pt, this);
- Common::Point pt2(30, 160);
- NpcMover *mover2 = new NpcMover();
- _vampire.addMover(mover2, &pt2, NULL);
- }
- break;
- case 24:
- _KeypadWindow.remove();
- _sceneMode = 1966;
- _cube.setFrame(3);
- setAction(&_sequenceManager, this, 1966, &_containmentField, &_gem, NULL);
- break;
- case 1951:
- R2_GLOBALS._sound1.fadeOut2(NULL);
- R2_GLOBALS._sceneManager.changeScene(1945);
- break;
- case 1958:
- SceneItem::display(1950, 24, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
- R2_GLOBALS._player.enableControl(CURSOR_WALK);
- _doorExit._enabled = true;
- break;
- case 1959:
- R2_INVENTORY.setObjectScene(R2_SOAKED_FACEMASK, 0);
- R2_GLOBALS._player.enableControl(CURSOR_WALK);
- _doorExit._enabled = true;
- break;
- case 1962:
- // No break on purpose
- case 1963:
- R2_GLOBALS._player.enableControl();
- _KeypadWindow.setup2(1971, 1, 1, 160, 135);
- break;
- case 1964:
- // No break on purpose
- case 1965:
- if (!R2_GLOBALS.getFlag(37))
- SceneItem::display(1950, 26, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
-
- R2_GLOBALS._player.enableControl();
- break;
- case 1966:
- _containmentField.remove();
- if (R2_GLOBALS.getFlag(36)) {
- _sceneMode = 1964;
- setAction(&_sequenceManager, this, 1964, &R2_GLOBALS._player, NULL);
- } else {
- _sceneMode = 1965;
- setAction(&_sequenceManager, this, 1965, &R2_GLOBALS._player, NULL);
- }
- _gem.setDetails(1950, 9, -1, -1, 2, (SceneItem *) NULL);
- break;
- case 1967: {
- _sceneMode = 0;
- R2_INVENTORY.setObjectScene(R2_SAPPHIRE_BLUE, 2);
- _gem.remove();
- if (R2_GLOBALS.getFlag(36))
- R2_GLOBALS._player.setVisage(20);
- else
- R2_GLOBALS._player.setVisage(22);
-
- R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
- // This is a hack to work around a pathfinding issue. original destination is (218, 165)
- Common::Point pt(128, 165);
- NpcMover *mover = new NpcMover();
- R2_GLOBALS._player.addMover(mover, &pt, this);
- }
- break;
- case 1968:
- R2_GLOBALS._player.enableControl();
- R2_INVENTORY.setObjectScene(R2_ANCIENT_SCROLLS, 2);
- _scrolls.setFrame(2);
- if (R2_GLOBALS.getFlag(36))
- R2_GLOBALS._player.setVisage(20);
- else
- R2_GLOBALS._player.setVisage(22);
- R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
- break;
- default:
- R2_GLOBALS._player.enableControl(CURSOR_WALK);
- break;
- }
-}
-
-void Scene1950::process(Event &event) {
- if ( (event.eventType == EVENT_BUTTON_DOWN)
- && (R2_GLOBALS._player._uiEnabled)
- && (R2_GLOBALS._events.getCursor() == R2_SOAKED_FACEMASK)
- && (R2_GLOBALS._player._bounds.contains(event.mousePos))
- && (R2_INVENTORY.getObjectScene(R2_SCRITH_KEY) == 0)) {
- event.handled = true;
- R2_GLOBALS._player.disableControl();
- _shaftExit._enabled = false;
- _doorExit._enabled = false;
- _sceneMode = 1959;
- setAction(&_sequenceManager, this, 1959, &R2_GLOBALS._player, NULL);
- }
-
- Scene::process(event);
-}
-
} // End of namespace Ringworld2
} // End of namespace TsAGE
diff --git a/engines/tsage/ringworld2/ringworld2_scenes1.h b/engines/tsage/ringworld2/ringworld2_scenes1.h
index 0b6738060c..e6f5e0ab97 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes1.h
+++ b/engines/tsage/ringworld2/ringworld2_scenes1.h
@@ -135,53 +135,6 @@ public:
virtual void saveCharacter(int characterIndex);
};
-class Scene1200 : public SceneExt {
- enum CrawlDirection { CRAWL_EAST = 1, CRAWL_WEST = 2, CRAWL_SOUTH = 3, CRAWL_NORTH = 4 };
-
- class LaserPanel: public ModalWindow {
- public:
- class Jumper : public SceneActorExt {
- public:
- void init(int state);
- virtual bool startAction(CursorType action, Event &event);
- };
-
- Jumper _jumper1;
- Jumper _jumper2;
- Jumper _jumper3;
-
- LaserPanel();
-
- virtual void postInit(SceneObjectList *OwnerList = NULL);
- virtual void remove();
- };
-
-public:
- NamedHotspot _item1;
- SceneActor _actor1;
- LaserPanel _laserPanel;
- MazeUI _mazeUI;
- SequenceManager _sequenceManager;
-
- int _nextCrawlDirection;
- int _field414;
- int _field416;
- int _field418;
- int _field41A;
- bool _fixupMaze;
-
- Scene1200();
- void synchronize(Serializer &s);
-
- void startCrawling(CrawlDirection dir);
-
- virtual void postInit(SceneObjectList *OwnerList = NULL);
- virtual void signal();
- virtual void process(Event &event);
- virtual void dispatch();
- virtual void saveCharacter(int characterIndex);
-};
-
class Scene1500 : public SceneExt {
public:
SceneActor _starship;
@@ -880,143 +833,6 @@ public:
virtual void signal();
};
-class Scene1950 : public SceneExt {
- /* Windows */
- class KeypadWindow: public ModalWindow {
- public:
- class KeypadButton : public SceneActor {
- public:
- int _buttonIndex;
- bool _pressed;
- bool _toggled;
-
- KeypadButton();
- void synchronize(Serializer &s);
-
- void init(int indx);
- virtual void process(Event &event);
- virtual bool startAction(CursorType action, Event &event);
- };
-
- SceneActor _areaActor;
- KeypadButton _buttons[16];
-
- int _buttonIndex;
-
- KeypadWindow();
- virtual void synchronize(Serializer &s);
- virtual void remove();
- virtual void setup2(int visage, int stripFrameNum, int frameNum, int posX, int posY);
- virtual void setup3(int resNum, int lookLineNum, int talkLineNum, int useLineNum);
- };
-
- class Keypad : public NamedHotspot {
- public:
- virtual bool startAction(CursorType action, Event &event);
- };
-
- /* Actors */
- class Door : public SceneActor {
- public:
- virtual bool startAction(CursorType action, Event &event);
- };
- class Scrolls : public SceneActor {
- public:
- virtual bool startAction(CursorType action, Event &event);
- };
- class Gem : public SceneActor {
- public:
- virtual bool startAction(CursorType action, Event &event);
- };
- class Vampire : public SceneActor {
- public:
- Common::Point _deadPosition;
- int _deltaX;
- int _deltaY;
- int _vampireMode;
-
- Vampire();
- void synchronize(Serializer &s);
-
- virtual void signal();
- virtual bool startAction(CursorType action, Event &event);
- };
-
- /* Exits */
- class NorthExit : public SceneExit {
- public:
- virtual void changeScene();
- };
- class UpExit : public SceneExit {
- public:
- virtual void changeScene();
- };
- class EastExit : public SceneExit {
- public:
- virtual void changeScene();
- };
- class DownExit : public SceneExit {
- public:
- virtual void changeScene();
- };
- class SouthExit : public SceneExit {
- public:
- virtual void changeScene();
- };
- class WestExit : public SceneExit {
- public:
- virtual void changeScene();
- };
- class ShaftExit : public SceneExit {
- public:
- virtual void changeScene();
- };
- class DoorExit : public SceneExit {
- public:
- virtual void changeScene();
- };
-private:
- void initArea();
- void enterArea();
- void doButtonPress(int indx);
-public:
- NamedHotspot _background;
- Keypad _keypad;
- SceneActor _southDoorway;
- SceneObject _northDoorway;
- Door _door;
- Scrolls _scrolls;
- SceneActor _containmentField;
- Gem _gem;
- SceneActor _cube;
- SceneActor _pulsingLights;
- Vampire _vampire;
- KeypadWindow _KeypadWindow;
- NorthExit _northExit;
- UpExit _upExit;
- EastExit _eastExit;
- DownExit _downExit;
- SouthExit _southExit;
- WestExit _westExit;
- ShaftExit _shaftExit;
- DoorExit _doorExit;
- SequenceManager _sequenceManager;
-
- bool _upExitStyle;
- bool _removeFlag;
- bool _vampireActive;
- Common::Point _vampireDestPos;
- int _vampireIndex;
-
- Scene1950();
- void synchronize(Serializer &s);
-
- virtual void postInit(SceneObjectList *OwnerList = NULL);
- virtual void remove();
- virtual void signal();
- virtual void process(Event &event);
-};
-
} // End of namespace Ringworld2
} // End of namespace TsAGE
diff --git a/engines/tsage/ringworld2/ringworld2_scenes3.cpp b/engines/tsage/ringworld2/ringworld2_scenes3.cpp
index 9eaead630b..8610e0c8bc 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes3.cpp
+++ b/engines/tsage/ringworld2/ringworld2_scenes3.cpp
@@ -3878,7 +3878,7 @@ void Scene3500::dispatch() {
Scene::dispatch();
// WORKAROUND: The _mazeUI wasn't originally added to the scene in postInit.
- // This is only needed to fix old savegames
+ // This is only needed to fix old savegames
if (!R2_GLOBALS._sceneObjects->contains(&_mazeUI))
_mazeUI.draw();
diff --git a/engines/tsage/ringworld2/ringworld2_vampire.cpp b/engines/tsage/ringworld2/ringworld2_vampire.cpp
new file mode 100644
index 0000000000..9d3b7f91a5
--- /dev/null
+++ b/engines/tsage/ringworld2/ringworld2_vampire.cpp
@@ -0,0 +1,1821 @@
+/* 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/ringworld2/ringworld2_vampire.h"
+
+namespace TsAGE {
+
+namespace Ringworld2 {
+
+/*--------------------------------------------------------------------------
+ * Scene 1950 - Flup Tube Corridor Maze
+ *
+ *--------------------------------------------------------------------------*/
+
+Scene1950::KeypadWindow::KeypadWindow() {
+ _buttonIndex = 0;
+}
+
+void Scene1950::KeypadWindow::synchronize(Serializer &s) {
+ SceneArea::synchronize(s);
+
+ s.syncAsSint16LE(_buttonIndex);
+}
+
+Scene1950::KeypadWindow::KeypadButton::KeypadButton() {
+ _buttonIndex = 0;
+ _pressed = false;
+ _toggled = false;
+}
+
+void Scene1950::KeypadWindow::KeypadButton::synchronize(Serializer &s) {
+ SceneActor::synchronize(s);
+
+ s.syncAsSint16LE(_buttonIndex);
+ s.syncAsSint16LE(_pressed);
+ s.syncAsSint16LE(_toggled);
+}
+
+void Scene1950::KeypadWindow::KeypadButton::init(int indx) {
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ _buttonIndex = indx;
+ _pressed = false;
+ _toggled = false;
+
+ postInit();
+ setup(1971, 2, 1);
+ fixPriority(249);
+ setPosition(Common::Point(((_buttonIndex % 4) * 22) + 127, ((_buttonIndex / 4) * 19) + 71));
+ scene->_sceneAreas.push_front(this);
+}
+
+void Scene1950::KeypadWindow::KeypadButton::process(Event &event) {
+ if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == CURSOR_USE)
+ && (_bounds.contains(event.mousePos)) && !_pressed) {
+ R2_GLOBALS._sound2.play(227);
+ if (!_toggled) {
+ setFrame(2);
+ _toggled = true;
+ } else {
+ setFrame(1);
+ _toggled = false;
+ }
+ _pressed = true;
+ event.handled = true;
+ }
+
+ if ((event.eventType == EVENT_BUTTON_UP) && _pressed) {
+ _pressed = false;
+ event.handled = true;
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+ scene->doButtonPress(_buttonIndex);
+ }
+}
+
+bool Scene1950::KeypadWindow::KeypadButton::startAction(CursorType action, Event &event) {
+ if (action == CURSOR_USE)
+ return false;
+ return SceneActor::startAction(action, event);
+}
+
+void Scene1950::KeypadWindow::remove() {
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+ for (_buttonIndex = 0; _buttonIndex < 16; ++_buttonIndex) {
+ scene->_sceneAreas.remove(&_buttons[_buttonIndex]);
+ _buttons[_buttonIndex].remove();
+ }
+
+ ModalWindow::remove();
+
+ if (!R2_GLOBALS.getFlag(37))
+ R2_GLOBALS._sound2.play(278);
+
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
+ scene->_eastExit._enabled = true;
+
+ if (!R2_GLOBALS.getFlag(37)) {
+ if (R2_GLOBALS.getFlag(36)) {
+ scene->_sceneMode = 1964;
+ scene->setAction(&scene->_sequenceManager, scene, 1964, &R2_GLOBALS._player, NULL);
+ } else {
+ scene->_sceneMode = 1965;
+ scene->setAction(&scene->_sequenceManager, scene, 1965, &R2_GLOBALS._player, NULL);
+ }
+ }
+}
+
+void Scene1950::KeypadWindow::setup2(int visage, int stripFrameNum, int frameNum, int posX, int posY) {
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ if (R2_GLOBALS._player._mover)
+ R2_GLOBALS._player.addMover(NULL);
+ R2_GLOBALS._player._canWalk = false;
+
+ ModalWindow::setup2(visage, stripFrameNum, frameNum, posX, posY);
+
+ _object1.fixPriority(248);
+ scene->_eastExit._enabled = false;
+ setup3(1950, 27, 28, 27);
+
+ for (_buttonIndex = 0; _buttonIndex < 16; _buttonIndex++)
+ _buttons[_buttonIndex].init(_buttonIndex);
+}
+
+void Scene1950::KeypadWindow::setup3(int resNum, int lookLineNum, int talkLineNum, int useLineNum) {
+ // Copy of Scene1200::LaserPanel::proc13()
+ _areaActor.setDetails(resNum, lookLineNum, talkLineNum, useLineNum, 2, (SceneItem *) NULL);
+}
+
+/*--------------------------------------------------------------------------*/
+
+bool Scene1950::Keypad::startAction(CursorType action, Event &event) {
+ if ((action != CURSOR_USE) || (R2_GLOBALS.getFlag(37)))
+ return SceneHotspot::startAction(action, event);
+
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_GLOBALS._player.disableControl();
+ if (R2_GLOBALS.getFlag(36)) {
+ scene->_sceneMode = 1962;
+ scene->setAction(&scene->_sequenceManager, scene, 1962, &R2_GLOBALS._player, NULL);
+ } else {
+ scene->_sceneMode = 1963;
+ scene->setAction(&scene->_sequenceManager, scene, 1963, &R2_GLOBALS._player, NULL);
+ }
+ return true;
+}
+
+bool Scene1950::Door::startAction(CursorType action, Event &event) {
+ if (action != R2_SCRITH_KEY)
+ return SceneActor::startAction(action, event);
+
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_GLOBALS._player.disableControl();
+ R2_INVENTORY.setObjectScene(R2_SCRITH_KEY, 0);
+ scene->_sceneMode = 1958;
+ scene->setAction(&scene->_sequenceManager, scene, 1958, &R2_GLOBALS._player, &scene->_door, NULL);
+ return true;
+}
+
+bool Scene1950::Scrolls::startAction(CursorType action, Event &event) {
+ if ((action != CURSOR_USE) || (R2_INVENTORY.getObjectScene(R2_ANCIENT_SCROLLS) != 1950))
+ return SceneActor::startAction(action, event);
+
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 1968;
+ scene->setAction(&scene->_sequenceManager, scene, 1968, &R2_GLOBALS._player, NULL);
+
+ return true;
+}
+
+bool Scene1950::Gem::startAction(CursorType action, Event &event) {
+ if ((action != CURSOR_USE) || (!R2_GLOBALS.getFlag(37)))
+ return SceneActor::startAction(action, event);
+
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 1967;
+ scene->setAction(&scene->_sequenceManager, scene, 1967, &R2_GLOBALS._player, NULL);
+
+ return true;
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene1950::Vampire::Vampire() {
+ _deadPosition = Common::Point(0, 0);
+ _deltaX = 0;
+ _deltaY = 0;
+ _vampireMode = 0;
+}
+
+void Scene1950::Vampire::synchronize(Serializer &s) {
+ SceneActor::synchronize(s);
+
+ s.syncAsSint16LE(_deadPosition.x);
+ s.syncAsSint16LE(_deadPosition.y);
+ s.syncAsSint16LE(_deltaX);
+ s.syncAsSint16LE(_deltaY);
+ s.syncAsSint16LE(_vampireMode);
+}
+
+void Scene1950::Vampire::signal() {
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (_vampireMode) {
+ case 19: {
+ _vampireMode = 0;
+ setVisage(1960);
+ if (R2_GLOBALS._flubMazeEntryDirection == 3)
+ setStrip(2);
+ else
+ setStrip(1);
+
+ NpcMover *mover = new NpcMover();
+ addMover(mover, &scene->_vampireDestPos, scene);
+ }
+ break;
+ case 20: {
+ // Non fatal shot
+ _vampireMode = 19;
+ R2_GLOBALS._player.setVisage(22);
+ if (R2_GLOBALS._flubMazeEntryDirection == 3)
+ R2_GLOBALS._player.setStrip(1);
+ else
+ R2_GLOBALS._player.setStrip(2);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._vampireData[scene->_vampireIndex - 1]._shotsRequired--;
+
+ if (R2_GLOBALS._flubMazeEntryDirection == 3)
+ _deadPosition.x = _position.x + 10;
+ else
+ _deadPosition.x = _position.x - 10;
+ _deadPosition.y = _position.y - 4;
+
+ setVisage(1961);
+
+ if (R2_GLOBALS._flubMazeEntryDirection == 3)
+ setStrip(2);
+ else
+ setStrip(1);
+
+ animate(ANIM_MODE_2, NULL);
+ Common::Point pt = _deadPosition;
+ PlayerMover *mover = new PlayerMover();
+ addMover(mover, &pt, this);
+
+ R2_GLOBALS._player.enableControl();
+ }
+ break;
+ case 21: {
+ // Fatal shot
+ R2_GLOBALS._player.setVisage(22);
+ if (R2_GLOBALS._flubMazeEntryDirection == 3)
+ R2_GLOBALS._player.setStrip(1);
+ else
+ R2_GLOBALS._player.setStrip(2);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+
+ setVisage(1961);
+ if (R2_GLOBALS._flubMazeEntryDirection == 3)
+ setStrip(4);
+ else
+ setStrip(3);
+ setDetails(1950, 15, -1, 17, 2, (SceneItem *) NULL);
+ addMover(NULL);
+ _numFrames = 8;
+ R2_GLOBALS._sound2.play(226);
+ animate(ANIM_MODE_5, NULL);
+ fixPriority(10);
+
+ R2_GLOBALS._vampireData[scene->_vampireIndex - 1]._isAlive = false;
+ R2_GLOBALS._vampireData[scene->_vampireIndex - 1]._shotsRequired--;
+ R2_GLOBALS._vampireData[scene->_vampireIndex - 1]._position = _position;
+ _deltaX = (_position.x - R2_GLOBALS._player._position.x) / 2;
+ _deltaY = (_position.y - R2_GLOBALS._player._position.y) / 2;
+
+ byte vampireCount = 0;
+ for (byte i = 0; i < 18; ++i) {
+ if (!R2_GLOBALS._vampireData[i]._isAlive)
+ ++vampireCount;
+ }
+
+ if (vampireCount == 18) {
+ R2_GLOBALS.setFlag(36);
+ _vampireMode = 23;
+ Common::Point pt(R2_GLOBALS._player._position.x + _deltaX, R2_GLOBALS._player._position.y + _deltaY);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else if (vampireCount == 1) {
+ _vampireMode = 22;
+ Common::Point pt(R2_GLOBALS._player._position.x + _deltaX, R2_GLOBALS._player._position.y + _deltaY);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else {
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
+ }
+
+ if (R2_GLOBALS._flubMazeEntryDirection == 3)
+ scene->_eastExit._enabled = true;
+ else
+ scene->_westExit._enabled = true;
+
+ scene->_vampireActive = false;
+ }
+ break;
+ case 22:
+ SceneItem::display(1950, 18, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
+ break;
+ case 23:
+ SceneItem::display(1950, 25, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
+ scene->_sceneMode = R2_GLOBALS._flubMazeEntryDirection;
+ scene->setAction(&scene->_sequenceManager, scene, 1960, &R2_GLOBALS._player, NULL);
+ break;
+ default:
+ break;
+ }
+}
+
+bool Scene1950::Vampire::startAction(CursorType action, Event &event) {
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ if (!R2_GLOBALS._vampireData[scene->_vampireIndex - 1]._isAlive ||
+ (action != R2_PHOTON_STUNNER))
+ return SceneActor::startAction(action, event);
+
+ R2_GLOBALS._player.disableControl();
+
+ if (R2_GLOBALS._vampireData[scene->_vampireIndex - 1]._shotsRequired <= 1)
+ _vampireMode = 21;
+ else
+ _vampireMode = 20;
+
+ R2_GLOBALS._player.setVisage(25);
+ if (R2_GLOBALS._flubMazeEntryDirection == 3)
+ R2_GLOBALS._player.setStrip(2);
+ else
+ R2_GLOBALS._player.setStrip(1);
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ R2_GLOBALS._sound3.play(99);
+
+ return true;
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene1950::NorthExit::changeScene() {
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
+ R2_GLOBALS._flubMazeEntryDirection = 1;
+ scene->_sceneMode = 11;
+
+ Common::Point pt(160, 127);
+ PlayerMover *mover = new PlayerMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+}
+
+void Scene1950::UpExit::changeScene() {
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
+ R2_GLOBALS._flubMazeEntryDirection = 2;
+ scene->_sceneMode = 12;
+
+ if (!scene->_upExitStyle) {
+ if (R2_GLOBALS.getFlag(36))
+ scene->setAction(&scene->_sequenceManager, scene, 1953, &R2_GLOBALS._player, NULL);
+ else
+ scene->setAction(&scene->_sequenceManager, scene, 1970, &R2_GLOBALS._player, NULL);
+ } else {
+ if (R2_GLOBALS.getFlag(36))
+ scene->setAction(&scene->_sequenceManager, scene, 1952, &R2_GLOBALS._player, NULL);
+ else
+ scene->setAction(&scene->_sequenceManager, scene, 1969, &R2_GLOBALS._player, NULL);
+ }
+}
+
+void Scene1950::EastExit::changeScene() {
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
+ R2_GLOBALS._flubMazeEntryDirection = 3;
+ scene->_sceneMode = 13;
+
+ if (scene->_vampireActive)
+ R2_GLOBALS._player.animate(ANIM_MODE_9);
+
+ Common::Point pt(340, 160);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+}
+
+void Scene1950::DownExit::changeScene() {
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
+ R2_GLOBALS._flubMazeEntryDirection = 4;
+ scene->_sceneMode = 14;
+
+ if (R2_GLOBALS.getFlag(36))
+ scene->setAction(&scene->_sequenceManager, scene, 1956, &R2_GLOBALS._player, NULL);
+ else
+ scene->setAction(&scene->_sequenceManager, scene, 1973, &R2_GLOBALS._player, NULL);
+}
+
+void Scene1950::SouthExit::changeScene() {
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
+ R2_GLOBALS._flubMazeEntryDirection = 5;
+ scene->_sceneMode = 15;
+
+ Common::Point pt(160, 213);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+}
+
+void Scene1950::WestExit::changeScene() {
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
+ R2_GLOBALS._flubMazeEntryDirection = 6;
+
+ if (R2_GLOBALS._flubMazeArea == 2) {
+ // In the very first corridor area after the Scrith Door
+ if ((R2_GLOBALS.getFlag(36)) && (R2_INVENTORY.getObjectScene(R2_SAPPHIRE_BLUE) == 2) && (R2_INVENTORY.getObjectScene(R2_ANCIENT_SCROLLS) == 2)) {
+ scene->_sceneMode = 1961;
+ Common::Point pt(-20, 160);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+ } else {
+ if (!R2_GLOBALS.getFlag(36))
+ SceneItem::display(1950, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
+ if ((R2_INVENTORY.getObjectScene(R2_SAPPHIRE_BLUE) == 1950) || (R2_INVENTORY.getObjectScene(R2_ANCIENT_SCROLLS) == 1950))
+ SceneItem::display(1950, 34, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
+ scene->_sceneMode = 0;
+ Common::Point pt(30, 160);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+ }
+ } else {
+ if (scene->_vampireActive)
+ R2_GLOBALS._player.animate(ANIM_MODE_9);
+
+ scene->_sceneMode = 16;
+ Common::Point pt(-20, 160);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+ }
+}
+
+void Scene1950::ShaftExit::changeScene() {
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
+ R2_GLOBALS._flubMazeEntryDirection = 0;
+ scene->_sceneMode = 1951;
+ scene->setAction(&scene->_sequenceManager, scene, 1951, &R2_GLOBALS._player, NULL);
+}
+
+void Scene1950::DoorExit::changeScene() {
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
+ R2_GLOBALS._flubMazeEntryDirection = 3;
+ if (R2_GLOBALS._player._visage == 22) {
+ scene->_sceneMode = 1975;
+ scene->setAction(&scene->_sequenceManager, scene, 1975, &R2_GLOBALS._player, NULL);
+ } else {
+ SceneItem::display(1950, 22, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
+ R2_GLOBALS._flubMazeEntryDirection = 0;
+ scene->_sceneMode = 0;
+ Common::Point pt(250, 150);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+ _enabled = true;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene1950::Scene1950() {
+ _upExitStyle = false;
+ _removeFlag = false;
+ _vampireActive = false;
+ _vampireDestPos = Common::Point(0, 0);
+ _vampireIndex = 0;
+}
+
+void Scene1950::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_upExitStyle);
+ s.syncAsSint16LE(_removeFlag);
+ s.syncAsSint16LE(_vampireActive);
+ s.syncAsSint16LE(_vampireDestPos.x);
+ s.syncAsSint16LE(_vampireDestPos.y);
+ s.syncAsSint16LE(_vampireIndex);
+}
+
+void Scene1950::initArea() {
+ _northExit._enabled = false;
+ _upExit._enabled = false;
+ _eastExit._enabled = false;
+ _downExit._enabled = false;
+ _southExit._enabled = false;
+ _westExit._enabled = false;
+ _shaftExit._enabled = false;
+ _doorExit._enabled = false;
+ _northExit._insideArea = false;
+ _upExit._insideArea = false;
+ _eastExit._insideArea = false;
+ _downExit._insideArea = false;
+ _southExit._insideArea = false;
+ _westExit._insideArea = false;
+ _shaftExit._insideArea = false;
+ _doorExit._insideArea = false;
+ _northExit._moving = false;
+ _upExit._moving = false;
+ _eastExit._moving = false;
+ _downExit._moving = false;
+ _southExit._moving = false;
+ _westExit._moving = false;
+ _shaftExit._moving = false;
+ _doorExit._moving = false;
+ _upExitStyle = false;
+
+ switch (R2_GLOBALS._flubMazeArea - 1) {
+ case 0:
+ loadScene(1948);
+ break;
+ case 1:
+ // No break on purpose
+ case 8:
+ // No break on purpose
+ case 10:
+ // No break on purpose
+ case 12:
+ // No break on purpose
+ case 16:
+ // No break on purpose
+ case 19:
+ // No break on purpose
+ case 23:
+ // No break on purpose
+ case 30:
+ // No break on purpose
+ case 44:
+ // No break on purpose
+ case 72:
+ // No break on purpose
+ case 74:
+ // No break on purpose
+ case 86:
+ // No break on purpose
+ case 96:
+ // No break on purpose
+ case 103:
+ loadScene(1950);
+ break;
+ case 2:
+ // No break on purpose
+ case 29:
+ loadScene(1965);
+ break;
+ case 3:
+ // No break on purpose
+ case 9:
+ // No break on purpose
+ case 11:
+ // No break on purpose
+ case 15:
+ // No break on purpose
+ case 24:
+ // No break on purpose
+ case 39:
+ // No break on purpose
+ case 45:
+ // No break on purpose
+ case 71:
+ // No break on purpose
+ case 73:
+ // No break on purpose
+ case 75:
+ // No break on purpose
+ case 79:
+ // No break on purpose
+ case 85:
+ // No break on purpose
+ case 87:
+ // No break on purpose
+ case 95:
+ loadScene(1955);
+ break;
+ case 4:
+ // No break on purpose
+ case 6:
+ // No break on purpose
+ case 13:
+ // No break on purpose
+ case 27:
+ // No break on purpose
+ case 41:
+ // No break on purpose
+ case 48:
+ // No break on purpose
+ case 50:
+ // No break on purpose
+ case 54:
+ // No break on purpose
+ case 76:
+ // No break on purpose
+ case 80:
+ // No break on purpose
+ case 90:
+ // No break on purpose
+ case 104:
+ loadScene(1975);
+ break;
+ case 5:
+ // No break on purpose
+ case 7:
+ // No break on purpose
+ case 14:
+ // No break on purpose
+ case 28:
+ // No break on purpose
+ case 32:
+ // No break on purpose
+ case 47:
+ // No break on purpose
+ case 53:
+ loadScene(1997);
+ break;
+ case 17:
+ // No break on purpose
+ case 20:
+ // No break on purpose
+ case 25:
+ // No break on purpose
+ case 31:
+ // No break on purpose
+ case 33:
+ // No break on purpose
+ case 46:
+ loadScene(1995);
+ break;
+ case 18:
+ // No break on purpose
+ case 22:
+ // No break on purpose
+ case 26:
+ // No break on purpose
+ case 36:
+ // No break on purpose
+ case 38:
+ // No break on purpose
+ case 43:
+ // No break on purpose
+ case 51:
+ // No break on purpose
+ case 70:
+ // No break on purpose
+ case 78:
+ // No break on purpose
+ case 84:
+ // No break on purpose
+ case 89:
+ // No break on purpose
+ case 101:
+ loadScene(1970);
+ break;
+ case 21:
+ // No break on purpose
+ case 34:
+ // No break on purpose
+ case 57:
+ // No break on purpose
+ case 58:
+ // No break on purpose
+ case 59:
+ // No break on purpose
+ case 62:
+ // No break on purpose
+ case 65:
+ loadScene(1980);
+ break;
+ case 35:
+ // No break on purpose
+ case 61:
+ // No break on purpose
+ case 77:
+ // No break on purpose
+ case 83:
+ loadScene(1982);
+ break;
+ case 37:
+ // No break on purpose
+ case 52:
+ // No break on purpose
+ case 82:
+ // No break on purpose
+ case 88:
+ // No break on purpose
+ case 92:
+ // No break on purpose
+ case 97:
+ // No break on purpose
+ case 100:
+ loadScene(1962);
+ break;
+ case 40:
+ // No break on purpose
+ case 102:
+ loadScene(1960);
+ break;
+ case 42:
+ // No break on purpose
+ case 55:
+ // No break on purpose
+ case 60:
+ // No break on purpose
+ case 66:
+ // No break on purpose
+ case 68:
+ // No break on purpose
+ case 69:
+ // No break on purpose
+ case 93:
+ // No break on purpose
+ case 98:
+ loadScene(1990);
+ break;
+ case 49:
+ // No break on purpose
+ case 81:
+ // No break on purpose
+ case 91:
+ // No break on purpose
+ case 94:
+ // No break on purpose
+ case 99:
+ loadScene(1967);
+ break;
+ case 56:
+ // No break on purpose
+ case 63:
+ // No break on purpose
+ case 64:
+ // No break on purpose
+ case 67:
+ loadScene(1985);
+ _upExitStyle = true;
+ break;
+ default:
+ break;
+ }
+
+ if (R2_GLOBALS._flubMazeArea != 1)
+ R2_GLOBALS._walkRegions.load(1950);
+
+ switch (R2_GLOBALS._flubMazeArea - 1) {
+ case 0:
+ _shaftExit._enabled = true;
+ if ((R2_INVENTORY.getObjectScene(R2_SCRITH_KEY) == 0) && (R2_INVENTORY.getObjectScene(R2_SAPPHIRE_BLUE) == 1950))
+ _doorExit._enabled = true;
+ R2_GLOBALS._walkRegions.disableRegion(2);
+ R2_GLOBALS._walkRegions.disableRegion(3);
+ R2_GLOBALS._walkRegions.disableRegion(4);
+ R2_GLOBALS._walkRegions.disableRegion(5);
+ R2_GLOBALS._walkRegions.disableRegion(6);
+ break;
+ case 1:
+ // No break on purpose
+ case 2:
+ // No break on purpose
+ case 3:
+ // No break on purpose
+ case 8:
+ // No break on purpose
+ case 9:
+ // No break on purpose
+ case 10:
+ // No break on purpose
+ case 11:
+ // No break on purpose
+ case 12:
+ // No break on purpose
+ case 15:
+ // No break on purpose
+ case 16:
+ // No break on purpose
+ case 19:
+ // No break on purpose
+ case 23:
+ // No break on purpose
+ case 24:
+ // No break on purpose
+ case 29:
+ // No break on purpose
+ case 30:
+ // No break on purpose
+ case 39:
+ // No break on purpose
+ case 40:
+ // No break on purpose
+ case 44:
+ // No break on purpose
+ case 45:
+ // No break on purpose
+ case 71:
+ // No break on purpose
+ case 72:
+ // No break on purpose
+ case 73:
+ // No break on purpose
+ case 74:
+ // No break on purpose
+ case 75:
+ // No break on purpose
+ case 79:
+ // No break on purpose
+ case 85:
+ // No break on purpose
+ case 86:
+ // No break on purpose
+ case 87:
+ // No break on purpose
+ case 95:
+ // No break on purpose
+ case 96:
+ // No break on purpose
+ case 102:
+ // No break on purpose
+ case 103:
+ _eastExit._enabled = true;
+ _westExit._enabled = true;
+ break;
+ case 4:
+ // No break on purpose
+ case 6:
+ // No break on purpose
+ case 13:
+ // No break on purpose
+ case 17:
+ // No break on purpose
+ case 20:
+ // No break on purpose
+ case 25:
+ // No break on purpose
+ case 27:
+ // No break on purpose
+ case 31:
+ // No break on purpose
+ case 33:
+ // No break on purpose
+ case 37:
+ // No break on purpose
+ case 41:
+ // No break on purpose
+ case 46:
+ // No break on purpose
+ case 48:
+ // No break on purpose
+ case 50:
+ // No break on purpose
+ case 52:
+ // No break on purpose
+ case 54:
+ // No break on purpose
+ case 76:
+ // No break on purpose
+ case 80:
+ // No break on purpose
+ case 82:
+ // No break on purpose
+ case 88:
+ // No break on purpose
+ case 90:
+ // No break on purpose
+ case 92:
+ // No break on purpose
+ case 97:
+ // No break on purpose
+ case 100:
+ // No break on purpose
+ case 104:
+ _westExit._enabled = true;
+ R2_GLOBALS._walkRegions.disableRegion(6);
+ R2_GLOBALS._walkRegions.disableRegion(9);
+ break;
+ case 5:
+ // No break on purpose
+ case 7:
+ // No break on purpose
+ case 14:
+ // No break on purpose
+ case 18:
+ // No break on purpose
+ case 22:
+ // No break on purpose
+ case 26:
+ // No break on purpose
+ case 28:
+ // No break on purpose
+ case 32:
+ // No break on purpose
+ case 36:
+ // No break on purpose
+ case 38:
+ // No break on purpose
+ case 43:
+ // No break on purpose
+ case 47:
+ // No break on purpose
+ case 49:
+ // No break on purpose
+ case 51:
+ // No break on purpose
+ case 53:
+ // No break on purpose
+ case 70:
+ // No break on purpose
+ case 78:
+ // No break on purpose
+ case 81:
+ // No break on purpose
+ case 84:
+ // No break on purpose
+ case 89:
+ // No break on purpose
+ case 91:
+ // No break on purpose
+ case 94:
+ // No break on purpose
+ case 99:
+ // No break on purpose
+ case 101:
+ _eastExit._enabled = true;
+ R2_GLOBALS._walkRegions.disableRegion(1);
+ R2_GLOBALS._walkRegions.disableRegion(7);
+ R2_GLOBALS._walkRegions.disableRegion(13);
+ break;
+ default:
+ R2_GLOBALS._walkRegions.disableRegion(1);
+ R2_GLOBALS._walkRegions.disableRegion(6);
+ R2_GLOBALS._walkRegions.disableRegion(7);
+ R2_GLOBALS._walkRegions.disableRegion(9);
+ R2_GLOBALS._walkRegions.disableRegion(13);
+ break;
+ }
+
+ _northDoorway.remove();
+ _northDoorway.removeObject();
+ _southDoorway.remove();
+
+ switch (R2_GLOBALS._flubMazeArea - 4) {
+ case 0:
+ // No break on purpose
+ case 3:
+ // No break on purpose
+ case 16:
+ // No break on purpose
+ case 22:
+ // No break on purpose
+ case 24:
+ // No break on purpose
+ case 32:
+ // No break on purpose
+ case 33:
+ // No break on purpose
+ case 45:
+ // No break on purpose
+ case 46:
+ // No break on purpose
+ case 48:
+ // No break on purpose
+ case 51:
+ // No break on purpose
+ case 56:
+ // No break on purpose
+ case 59:
+ // No break on purpose
+ case 67:
+ // No break on purpose
+ case 68:
+ // No break on purpose
+ case 70:
+ // No break on purpose
+ case 73:
+ // No break on purpose
+ case 82:
+ // No break on purpose
+ case 90:
+ _northExit._enabled = true;
+ _northDoorway.setup(1950, (R2_GLOBALS._flubMazeArea % 2) + 1, 1, 160, 137, 25);
+ //visage,strip,frame,px,py,priority,effect
+ _southDoorway.postInit();
+ _southDoorway.setVisage(1950);
+ _southDoorway.setStrip((((R2_GLOBALS._flubMazeArea - 1) / 35) % 2) + 1);
+ _southDoorway.setFrame(2);
+ _southDoorway.setPosition(Common::Point(160, 167));
+ _southDoorway.fixPriority(220);
+ R2_GLOBALS._walkRegions.disableRegion(3);
+ R2_GLOBALS._walkRegions.disableRegion(4);
+ break;
+ case 7:
+ // No break on purpose
+ case 10:
+ // No break on purpose
+ case 23:
+ // No break on purpose
+ case 29:
+ // No break on purpose
+ case 31:
+ // No break on purpose
+ case 39:
+ // No break on purpose
+ case 40:
+ // No break on purpose
+ case 52:
+ // No break on purpose
+ case 53:
+ // No break on purpose
+ case 55:
+ // No break on purpose
+ case 63:
+ // No break on purpose
+ case 65:
+ // No break on purpose
+ case 66:
+ // No break on purpose
+ case 75:
+ // No break on purpose
+ case 77:
+ // No break on purpose
+ case 81:
+ // No break on purpose
+ case 87:
+ // No break on purpose
+ case 89:
+ // No break on purpose
+ case 97:
+ _southExit._enabled = true;
+
+ _southDoorway.postInit();
+ _southDoorway.setVisage(1950);
+ _southDoorway.setStrip((((R2_GLOBALS._flubMazeArea - 1) / 35) % 2) + 1);
+ _southDoorway.setFrame(3);
+ _southDoorway.setPosition(Common::Point(160, 167));
+ _southDoorway.fixPriority(220);
+ break;
+ case 58:
+ // No break on purpose
+ case 74:
+ // No break on purpose
+ case 80:
+ _northExit._enabled = true;
+ _southExit._enabled = true;
+
+ _northDoorway.setup(1950, (R2_GLOBALS._flubMazeArea % 2) + 1, 1, 160, 137, 25);
+
+ _southDoorway.postInit();
+ _southDoorway.setVisage(1950);
+ _southDoorway.setStrip((((R2_GLOBALS._flubMazeArea - 1) / 35) % 2) + 1);
+ _southDoorway.setFrame(3);
+ _southDoorway.setPosition(Common::Point(160, 167));
+ _southDoorway.fixPriority(220);
+ R2_GLOBALS._walkRegions.disableRegion(3);
+ R2_GLOBALS._walkRegions.disableRegion(4);
+ break;
+ default:
+ _southDoorway.postInit();
+ _southDoorway.setVisage(1950);
+ _southDoorway.setStrip(((R2_GLOBALS._flubMazeArea - 1) / 35) % 2 + 1);
+ _southDoorway.setFrame(2);
+ _southDoorway.setPosition(Common::Point(160, 167));
+ _southDoorway.fixPriority(220);
+ break;
+ }
+
+ switch (R2_GLOBALS._flubMazeArea - 3) {
+ case 0:
+ // No break on purpose
+ case 3:
+ // No break on purpose
+ case 5:
+ // No break on purpose
+ case 12:
+ // No break on purpose
+ case 15:
+ // No break on purpose
+ case 18:
+ // No break on purpose
+ case 19:
+ // No break on purpose
+ case 23:
+ // No break on purpose
+ case 26:
+ // No break on purpose
+ case 27:
+ // No break on purpose
+ case 29:
+ // No break on purpose
+ case 30:
+ // No break on purpose
+ case 31:
+ // No break on purpose
+ case 32:
+ // No break on purpose
+ case 44:
+ // No break on purpose
+ case 45:
+ // No break on purpose
+ case 51:
+ // No break on purpose
+ case 55:
+ // No break on purpose
+ case 56:
+ // No break on purpose
+ case 57:
+ // No break on purpose
+ case 60:
+ // No break on purpose
+ case 63:
+ _upExit._enabled = true;
+ break;
+ case 54:
+ // No break on purpose
+ case 61:
+ // No break on purpose
+ case 62:
+ // No break on purpose
+ case 65:
+ _upExit._enabled = true;
+ // No break on purpose
+ case 35:
+ // No break on purpose
+ case 38:
+ // No break on purpose
+ case 40:
+ // No break on purpose
+ case 47:
+ // No break on purpose
+ case 50:
+ // No break on purpose
+ case 53:
+ // No break on purpose
+ case 58:
+ // No break on purpose
+ case 64:
+ // No break on purpose
+ case 66:
+ // No break on purpose
+ case 67:
+ // No break on purpose
+ case 79:
+ // No break on purpose
+ case 80:
+ // No break on purpose
+ case 86:
+ // No break on purpose
+ case 89:
+ // No break on purpose
+ case 90:
+ // No break on purpose
+ case 91:
+ // No break on purpose
+ case 92:
+ // No break on purpose
+ case 95:
+ // No break on purpose
+ case 96:
+ // No break on purpose
+ case 97:
+ // No break on purpose
+ case 98:
+ // No break on purpose
+ case 100:
+ _downExit._enabled = true;
+ R2_GLOBALS._walkRegions.disableRegion(4);
+ R2_GLOBALS._walkRegions.disableRegion(5);
+ R2_GLOBALS._walkRegions.disableRegion(6);
+ R2_GLOBALS._walkRegions.disableRegion(10);
+ R2_GLOBALS._walkRegions.disableRegion(11);
+ default:
+ break;
+ }
+ R2_GLOBALS._uiElements.draw();
+}
+
+void Scene1950::enterArea() {
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+
+ _vampire.remove();
+ _door.remove();
+ _scrolls.remove();
+
+ _vampireActive = false;
+ _vampireIndex = 0;
+
+ // Certain areas have a vampire in them
+ switch (R2_GLOBALS._flubMazeArea) {
+ case 10:
+ _vampireIndex = 1;
+ break;
+ case 13:
+ _vampireIndex = 2;
+ break;
+ case 16:
+ _vampireIndex = 3;
+ break;
+ case 17:
+ _vampireIndex = 4;
+ break;
+ case 24:
+ _vampireIndex = 5;
+ break;
+ case 25:
+ _vampireIndex = 6;
+ break;
+ case 31:
+ _vampireIndex = 7;
+ break;
+ case 40:
+ _vampireIndex = 8;
+ break;
+ case 45:
+ _vampireIndex = 9;
+ break;
+ case 46:
+ _vampireIndex = 10;
+ break;
+ case 73:
+ _vampireIndex = 11;
+ break;
+ case 75:
+ _vampireIndex = 12;
+ break;
+ case 80:
+ _vampireIndex = 13;
+ break;
+ case 87:
+ _vampireIndex = 14;
+ break;
+ case 88:
+ _vampireIndex = 15;
+ break;
+ case 96:
+ _vampireIndex = 16;
+ break;
+ case 97:
+ _vampireIndex = 17;
+ break;
+ case 104:
+ _vampireIndex = 18;
+ break;
+ default:
+ break;
+ }
+
+ if (_vampireIndex != 0) {
+ _vampire.postInit();
+ _vampire._numFrames = 6;
+ _vampire._moveRate = 6;
+ _vampire._moveDiff = Common::Point(3, 2);
+ _vampire._effect = EFFECT_SHADED;
+
+ if (!R2_GLOBALS._vampireData[_vampireIndex - 1]._isAlive) {
+ // Show vampire ashes
+ _vampire.setPosition(Common::Point(R2_GLOBALS._vampireData[_vampireIndex - 1]._position));
+ _vampire.animate(ANIM_MODE_NONE, NULL);
+ _vampire.addMover(NULL);
+ _vampire.setVisage(1961);
+ _vampire.setStrip(4);
+ _vampire.setFrame(10);
+ _vampire.fixPriority(10);
+ _vampire.setDetails(1950, 15, -1, 17, 2, (SceneItem *) NULL);
+ } else {
+ // Start the vampire
+ _vampire.setVisage(1960);
+ _vampire.setPosition(Common::Point(160, 130));
+ _vampire.animate(ANIM_MODE_2, NULL);
+ _vampire.setDetails(1950, 12, -1, 14, 2, (SceneItem *) NULL);
+ _vampireActive = true;
+ }
+ }
+ if ((R2_GLOBALS._flubMazeArea == 1) && (R2_INVENTORY.getObjectScene(R2_SCRITH_KEY) != 0)) {
+ // Show doorway at the right hand side of the very first flub corridor
+ _door.postInit();
+ _door.setVisage(1948);
+ _door.setStrip(3);
+ _door.setPosition(Common::Point(278, 155));
+ _door.fixPriority(100);
+ _door.setDetails(1950, 19, 20, 23, 2, (SceneItem *) NULL);
+ }
+
+ if (R2_GLOBALS._flubMazeArea == 102) {
+ R2_GLOBALS._walkRegions.load(1951);
+ R2_GLOBALS._walkRegions.disableRegion(1);
+ R2_GLOBALS._walkRegions.disableRegion(5);
+ R2_GLOBALS._walkRegions.disableRegion(6);
+ R2_GLOBALS._walkRegions.disableRegion(7);
+
+ _cube.postInit();
+ _cube.setVisage(1970);
+ _cube.setStrip(1);
+ if (R2_GLOBALS.getFlag(37))
+ _cube.setFrame(3);
+ else
+ _cube.setFrame(1);
+ _cube.setPosition(Common::Point(193, 158));
+ _cube.setDetails(1950, 3, 4, 5, 2, (SceneItem *) NULL);
+
+ _pulsingLights.postInit();
+ _pulsingLights.setVisage(1970);
+ _pulsingLights.setStrip(3);
+ _pulsingLights.animate(ANIM_MODE_2, NULL);
+ _pulsingLights._numFrames = 6;
+ _pulsingLights.setPosition(Common::Point(194, 158));
+ _pulsingLights.fixPriority(159);
+
+ _keypad.setDetails(Rect(188, 124, 199, 133), 1950, 27, 28, -1, 2, NULL);
+
+ if (R2_INVENTORY.getObjectScene(R2_SAPPHIRE_BLUE) == 1950) {
+ _gem.postInit();
+ _gem.setVisage(1970);
+ _gem.setStrip(1);
+ _gem.setFrame(2);
+ _gem.fixPriority(160);
+ }
+
+ if (R2_GLOBALS.getFlag(37)) {
+ _gem.setPosition(Common::Point(192, 118));
+ _gem.setDetails(1950, 9, 4, -1, 2, (SceneItem *) NULL);
+ } else {
+ _containmentField.postInit();
+ _containmentField.setVisage(1970);
+ _containmentField.setStrip(4);
+ _containmentField._numFrames = 4;
+ _containmentField.animate(ANIM_MODE_8, 0, NULL);
+ _containmentField.setPosition(Common::Point(192, 121));
+ _containmentField.fixPriority(159);
+ _containmentField.setDetails(1950, 6, 7, 8, 2, (SceneItem *) NULL);
+
+ _gem.setPosition(Common::Point(192, 109));
+ _gem.setDetails(1950, 9, 7, 8, 2, (SceneItem *) NULL);
+ }
+
+ _scrolls.postInit();
+ _scrolls.setVisage(1972);
+ _scrolls.setStrip(1);
+ _scrolls.setPosition(Common::Point(76, 94));
+ _scrolls.fixPriority(25);
+ _scrolls.setDetails(1950, 30, -1, -1, 2, (SceneItem *) NULL);
+ if (R2_INVENTORY.getObjectScene(R2_ANCIENT_SCROLLS) == 2)
+ _scrolls.setFrame(2);
+ else
+ _scrolls.setFrame(1);
+
+ _removeFlag = true;
+ } else if (_removeFlag) {
+ _cube.remove();
+ _containmentField.remove();
+ _gem.remove();
+ _pulsingLights.remove();
+ _scrolls.remove();
+
+ R2_GLOBALS._sceneItems.remove(&_background);
+ _background.setDetails(Rect(0, 0, 320, 200), 1950, 0, 1, 2, 2, NULL);
+
+ _removeFlag = false;
+ }
+
+ switch (R2_GLOBALS._flubMazeEntryDirection) {
+ case 0:
+ _sceneMode = 1950;
+ if (R2_INVENTORY.getObjectScene(R2_SCRITH_KEY) == 0)
+ // The original uses CURSOR_ARROW. CURSOR_WALK is much more coherent
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
+ else
+ setAction(&_sequenceManager, this, 1950, &R2_GLOBALS._player, NULL);
+
+ break;
+ case 1: {
+ _sceneMode = R2_GLOBALS._flubMazeEntryDirection;
+ R2_GLOBALS._player.setPosition(Common::Point(160, 213));
+ Common::Point pt(160, 160);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 2:
+ _sceneMode = R2_GLOBALS._flubMazeEntryDirection;
+ if (R2_GLOBALS.getFlag(36))
+ setAction(&_sequenceManager, this, 1957, &R2_GLOBALS._player, NULL);
+ else
+ setAction(&_sequenceManager, this, 1974, &R2_GLOBALS._player, NULL);
+ break;
+ case 3:
+ // Entering from the left
+ if (!_vampireActive) {
+ _sceneMode = R2_GLOBALS._flubMazeEntryDirection;
+ R2_GLOBALS._player.setPosition(Common::Point(-20, 160));
+ Common::Point pt(30, 160);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else {
+ _sceneMode = 18;
+ _eastExit._enabled = false;
+ _vampireDestPos = Common::Point(60, 152);
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+
+ _vampire.setStrip(2);
+ NpcMover *mover = new NpcMover();
+ _vampire.addMover(mover, &_vampireDestPos, this);
+
+ R2_GLOBALS._player.setPosition(Common::Point(-20, 160));
+ Common::Point pt2(30, 160);
+ NpcMover *mover2 = new NpcMover();
+ R2_GLOBALS._player.addMover(mover2, &pt2, NULL);
+ }
+ break;
+ case 4:
+ _sceneMode = R2_GLOBALS._flubMazeEntryDirection;
+ if (!_upExitStyle) {
+ if (R2_GLOBALS.getFlag(36))
+ setAction(&_sequenceManager, this, 1955, &R2_GLOBALS._player, NULL);
+ else
+ setAction(&_sequenceManager, this, 1972, &R2_GLOBALS._player, NULL);
+ } else {
+ if (R2_GLOBALS.getFlag(36))
+ setAction(&_sequenceManager, this, 1954, &R2_GLOBALS._player, NULL);
+ else
+ setAction(&_sequenceManager, this, 1971, &R2_GLOBALS._player, NULL);
+ }
+ break;
+ case 5: {
+ _sceneMode = R2_GLOBALS._flubMazeEntryDirection;
+ R2_GLOBALS._player.setPosition(Common::Point(160, 127));
+ Common::Point pt(160, 160);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 6:
+ // Entering from the right
+ if (!_vampireActive) {
+ _sceneMode = R2_GLOBALS._flubMazeEntryDirection;
+ if (R2_GLOBALS._flubMazeArea == 1) {
+ setAction(&_sequenceManager, this, 1961, &R2_GLOBALS._player, NULL);
+ } else {
+ R2_GLOBALS._player.setPosition(Common::Point(340, 160));
+ Common::Point pt(289, 160);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ } else {
+ _sceneMode = 17;
+ _westExit._enabled = false;
+ _vampireDestPos = Common::Point(259, 152);
+
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+
+ _vampire.setStrip(1);
+ NpcMover *mover = new NpcMover();
+ _vampire.addMover(mover, &_vampireDestPos, this);
+
+ R2_GLOBALS._player.setPosition(Common::Point(340, 160));
+ Common::Point pt2(289, 160);
+ NpcMover *mover2 = new NpcMover();
+ R2_GLOBALS._player.addMover(mover2, &pt2, NULL);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene1950::doButtonPress(int indx) {
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+ R2_GLOBALS._player.disableControl();
+
+ int prevIndex = indx - 1;
+ if ((indx / 4) == (prevIndex / 4)) {
+ if (prevIndex < 0)
+ prevIndex = 3;
+ } else {
+ prevIndex += 4;
+ }
+
+ assert(prevIndex >= 0 && prevIndex < 16);
+ if (!_KeypadWindow._buttons[prevIndex]._toggled) {
+ _KeypadWindow._buttons[prevIndex].setFrame(2);
+ _KeypadWindow._buttons[prevIndex]._toggled = true;
+ } else {
+ _KeypadWindow._buttons[prevIndex].setFrame(1);
+ _KeypadWindow._buttons[prevIndex]._toggled = false;
+ }
+
+ prevIndex = indx + 1;
+ if ((indx / 4) == (prevIndex / 4)) {
+ if (prevIndex > 15)
+ prevIndex = 12;
+ } else {
+ prevIndex -= 4;
+ }
+
+ assert(prevIndex >= 0 && prevIndex < 16);
+ if (!_KeypadWindow._buttons[prevIndex]._toggled) {
+ _KeypadWindow._buttons[prevIndex].setFrame(2);
+ _KeypadWindow._buttons[prevIndex]._toggled = true;
+ } else {
+ _KeypadWindow._buttons[prevIndex].setFrame(1);
+ _KeypadWindow._buttons[prevIndex]._toggled = false;
+ }
+
+ prevIndex = indx - 4;
+ if (prevIndex < 0)
+ prevIndex += 16;
+
+ assert(prevIndex >= 0 && prevIndex < 16);
+ if (!_KeypadWindow._buttons[prevIndex]._toggled) {
+ _KeypadWindow._buttons[prevIndex].setFrame(2);
+ _KeypadWindow._buttons[prevIndex]._toggled = true;
+ } else {
+ _KeypadWindow._buttons[prevIndex].setFrame(1);
+ _KeypadWindow._buttons[prevIndex]._toggled = false;
+ }
+
+ prevIndex = indx + 4;
+ if (prevIndex > 15)
+ prevIndex -= 16;
+
+ assert(prevIndex >= 0 && prevIndex < 16);
+ if (!_KeypadWindow._buttons[prevIndex]._toggled) {
+ _KeypadWindow._buttons[prevIndex].setFrame(2);
+ _KeypadWindow._buttons[prevIndex]._toggled = true;
+ } else {
+ _KeypadWindow._buttons[prevIndex].setFrame(1);
+ _KeypadWindow._buttons[prevIndex]._toggled = false;
+ }
+
+ // Check whether all the buttons are highlighted
+ int cpt = 0;
+ for (prevIndex = 0; prevIndex < 16; prevIndex++) {
+ if (_KeypadWindow._buttons[prevIndex]._toggled)
+ ++cpt;
+ }
+
+ if (cpt != 16) {
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ } else {
+ R2_GLOBALS.setFlag(37);
+ _sceneMode = 24;
+ setAction(&_sequenceManager, scene, 1976, NULL);
+ }
+}
+
+void Scene1950::postInit(SceneObjectList *OwnerList) {
+ _upExitStyle = false;
+ _removeFlag = false;
+ _vampireActive = false;
+ _vampireIndex = 0;
+ if (R2_GLOBALS._sceneManager._previousScene == 300)
+ R2_GLOBALS._flubMazeArea = 103;
+
+ initArea();
+ SceneExt::postInit();
+ R2_GLOBALS._sound1.play(105);
+
+ _northExit.setDetails(Rect(130, 46, 189, 135), SHADECURSOR_UP, 1950);
+ _northExit.setDest(Common::Point(160, 145));
+
+ _upExit.setDetails(Rect(208, 0, 255, 73), EXITCURSOR_N, 1950);
+ _upExit.setDest(Common::Point(200, 151));
+
+ _eastExit.setDetails(Rect(305, 95, 320, 147), EXITCURSOR_E, 1950);
+ _eastExit.setDest(Common::Point(312, 160));
+
+ _downExit.setDetails(Rect(208, 99, 255, 143), EXITCURSOR_S, 1950);
+ _downExit.setDest(Common::Point(200, 151));
+
+ _southExit.setDetails(Rect(113, 154, 206, 168), SHADECURSOR_DOWN, 1950);
+ _southExit.setDest(Common::Point(160, 165));
+
+ _westExit.setDetails(Rect(0, 95, 14, 147), EXITCURSOR_W, 1950);
+ _westExit.setDest(Common::Point(7, 160));
+
+ _shaftExit.setDetails(Rect(72, 54, 120, 128), EXITCURSOR_NW, 1950);
+ _shaftExit.setDest(Common::Point(120, 140));
+
+ _doorExit.setDetails(Rect(258, 60, 300, 145), EXITCURSOR_NE, 1950);
+ _doorExit.setDest(Common::Point(268, 149));
+
+ R2_GLOBALS._player.postInit();
+ if ( (R2_INVENTORY.getObjectScene(R2_TANNER_MASK) == 0) && (R2_INVENTORY.getObjectScene(R2_PURE_GRAIN_ALCOHOL) == 0)
+ && (R2_INVENTORY.getObjectScene(R2_SOAKED_FACEMASK) == 0) && (!R2_GLOBALS.getFlag(36)) )
+ R2_GLOBALS._player.setVisage(22);
+ else
+ R2_GLOBALS._player.setVisage(20);
+
+ R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
+ _background.setDetails(Rect(0, 0, 320, 200), 1950, 0, 1, 2, 1, NULL);
+
+ enterArea();
+}
+
+void Scene1950::remove() {
+ R2_GLOBALS._sound1.stop();
+ R2_GLOBALS._sound2.fadeOut2(NULL);
+ SceneExt::remove();
+}
+
+void Scene1950::signal() {
+ switch (_sceneMode) {
+ case 11:
+ R2_GLOBALS._flubMazeArea += 7;
+ initArea();
+ enterArea();
+ break;
+ case 12:
+ // Moving up a ladder within the Flub maze
+ R2_GLOBALS._flubMazeArea += 35;
+ initArea();
+ enterArea();
+ break;
+ case 1975:
+ SceneItem::display(1950, 21, SET_WIDTH, 280, SET_X, 160, SET_POS_MODE, 1,
+ SET_Y, 20, SET_EXT_BGCOLOR, 7, LIST_END);
+ // No break on purpose
+ case 13:
+ // Moving east within the Flub maze
+ ++R2_GLOBALS._flubMazeArea;
+ initArea();
+ enterArea();
+ break;
+ case 14:
+ // Moving down a ladder within the Flub maze
+ R2_GLOBALS._flubMazeArea -= 35;
+ initArea();
+ enterArea();
+ break;
+ case 15:
+ R2_GLOBALS._flubMazeArea -= 7;
+ initArea();
+ enterArea();
+ break;
+ case 16:
+ // Moving west within the Flub maze
+ // No break on purpose
+ case 1961:
+ --R2_GLOBALS._flubMazeArea;
+ initArea();
+ enterArea();
+ break;
+ case 17: {
+ _sceneMode = 13;
+ R2_GLOBALS._flubMazeEntryDirection = 3;
+ _vampireActive = false;
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
+ R2_GLOBALS._player._canWalk = true;
+ R2_GLOBALS._player.setVisage(22);
+ R2_GLOBALS._player.animate(ANIM_MODE_9);
+ Common::Point pt(340, 160);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ Common::Point pt2(289, 160);
+ NpcMover *mover2 = new NpcMover();
+ _vampire.addMover(mover2, &pt2, NULL);
+ }
+ break;
+ case 18: {
+ _sceneMode = 16;
+ R2_GLOBALS._flubMazeEntryDirection = 6;
+ _vampireActive = false;
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
+ R2_GLOBALS._player._canWalk = true;
+ R2_GLOBALS._player.setVisage(22);
+ R2_GLOBALS._player.animate(ANIM_MODE_9);
+ Common::Point pt(-20, 160);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ Common::Point pt2(30, 160);
+ NpcMover *mover2 = new NpcMover();
+ _vampire.addMover(mover2, &pt2, NULL);
+ }
+ break;
+ case 24:
+ _KeypadWindow.remove();
+ _sceneMode = 1966;
+ _cube.setFrame(3);
+ setAction(&_sequenceManager, this, 1966, &_containmentField, &_gem, NULL);
+ break;
+ case 1951:
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ R2_GLOBALS._sceneManager.changeScene(1945);
+ break;
+ case 1958:
+ SceneItem::display(1950, 24, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
+ _doorExit._enabled = true;
+ break;
+ case 1959:
+ R2_INVENTORY.setObjectScene(R2_SOAKED_FACEMASK, 0);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
+ _doorExit._enabled = true;
+ break;
+ case 1962:
+ // No break on purpose
+ case 1963:
+ R2_GLOBALS._player.enableControl();
+ _KeypadWindow.setup2(1971, 1, 1, 160, 135);
+ break;
+ case 1964:
+ // No break on purpose
+ case 1965:
+ if (!R2_GLOBALS.getFlag(37))
+ SceneItem::display(1950, 26, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
+
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1966:
+ _containmentField.remove();
+ if (R2_GLOBALS.getFlag(36)) {
+ _sceneMode = 1964;
+ setAction(&_sequenceManager, this, 1964, &R2_GLOBALS._player, NULL);
+ } else {
+ _sceneMode = 1965;
+ setAction(&_sequenceManager, this, 1965, &R2_GLOBALS._player, NULL);
+ }
+ _gem.setDetails(1950, 9, -1, -1, 2, (SceneItem *) NULL);
+ break;
+ case 1967: {
+ _sceneMode = 0;
+ R2_INVENTORY.setObjectScene(R2_SAPPHIRE_BLUE, 2);
+ _gem.remove();
+ if (R2_GLOBALS.getFlag(36))
+ R2_GLOBALS._player.setVisage(20);
+ else
+ R2_GLOBALS._player.setVisage(22);
+
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ // This is a hack to work around a pathfinding issue. original destination is (218, 165)
+ Common::Point pt(128, 165);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 1968:
+ R2_GLOBALS._player.enableControl();
+ R2_INVENTORY.setObjectScene(R2_ANCIENT_SCROLLS, 2);
+ _scrolls.setFrame(2);
+ if (R2_GLOBALS.getFlag(36))
+ R2_GLOBALS._player.setVisage(20);
+ else
+ R2_GLOBALS._player.setVisage(22);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ break;
+ default:
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
+ break;
+ }
+}
+
+void Scene1950::process(Event &event) {
+ if ( (event.eventType == EVENT_BUTTON_DOWN)
+ && (R2_GLOBALS._player._uiEnabled)
+ && (R2_GLOBALS._events.getCursor() == R2_SOAKED_FACEMASK)
+ && (R2_GLOBALS._player._bounds.contains(event.mousePos))
+ && (R2_INVENTORY.getObjectScene(R2_SCRITH_KEY) == 0)) {
+ event.handled = true;
+ R2_GLOBALS._player.disableControl();
+ _shaftExit._enabled = false;
+ _doorExit._enabled = false;
+ _sceneMode = 1959;
+ setAction(&_sequenceManager, this, 1959, &R2_GLOBALS._player, NULL);
+ }
+
+ Scene::process(event);
+}
+
+} // End of namespace Ringworld2
+} // End of namespace TsAGE
diff --git a/engines/tsage/ringworld2/ringworld2_vampire.h b/engines/tsage/ringworld2/ringworld2_vampire.h
new file mode 100644
index 0000000000..ca7aa34544
--- /dev/null
+++ b/engines/tsage/ringworld2/ringworld2_vampire.h
@@ -0,0 +1,179 @@
+/* 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_RINGWORLD2_VAMPIRE_H
+#define TSAGE_RINGWORLD2_VAMPIRE_H
+
+#include "tsage/events.h"
+#include "tsage/core.h"
+#include "tsage/scenes.h"
+#include "tsage/globals.h"
+#include "tsage/sound.h"
+#include "tsage/ringworld2/ringworld2_logic.h"
+
+namespace TsAGE {
+
+namespace Ringworld2 {
+
+using namespace TsAGE;
+
+class Scene1950 : public SceneExt {
+ /* Windows */
+ class KeypadWindow: public ModalWindow {
+ public:
+ class KeypadButton : public SceneActor {
+ public:
+ int _buttonIndex;
+ bool _pressed;
+ bool _toggled;
+
+ KeypadButton();
+ void synchronize(Serializer &s);
+
+ void init(int indx);
+ virtual void process(Event &event);
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ SceneActor _areaActor;
+ KeypadButton _buttons[16];
+
+ int _buttonIndex;
+
+ KeypadWindow();
+ virtual void synchronize(Serializer &s);
+ virtual void remove();
+ virtual void setup2(int visage, int stripFrameNum, int frameNum, int posX, int posY);
+ virtual void setup3(int resNum, int lookLineNum, int talkLineNum, int useLineNum);
+ };
+
+ class Keypad : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ /* Actors */
+ class Door : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Scrolls : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Gem : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Vampire : public SceneActor {
+ public:
+ Common::Point _deadPosition;
+ int _deltaX;
+ int _deltaY;
+ int _vampireMode;
+
+ Vampire();
+ void synchronize(Serializer &s);
+
+ virtual void signal();
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ /* Exits */
+ class NorthExit : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+ class UpExit : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+ class EastExit : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+ class DownExit : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+ class SouthExit : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+ class WestExit : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+ class ShaftExit : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+ class DoorExit : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+private:
+ void initArea();
+ void enterArea();
+ void doButtonPress(int indx);
+public:
+ NamedHotspot _background;
+ Keypad _keypad;
+ SceneActor _southDoorway;
+ SceneObject _northDoorway;
+ Door _door;
+ Scrolls _scrolls;
+ SceneActor _containmentField;
+ Gem _gem;
+ SceneActor _cube;
+ SceneActor _pulsingLights;
+ Vampire _vampire;
+ KeypadWindow _KeypadWindow;
+ NorthExit _northExit;
+ UpExit _upExit;
+ EastExit _eastExit;
+ DownExit _downExit;
+ SouthExit _southExit;
+ WestExit _westExit;
+ ShaftExit _shaftExit;
+ DoorExit _doorExit;
+ SequenceManager _sequenceManager;
+
+ bool _upExitStyle;
+ bool _removeFlag;
+ bool _vampireActive;
+ Common::Point _vampireDestPos;
+ int _vampireIndex;
+
+ Scene1950();
+ void synchronize(Serializer &s);
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+ virtual void process(Event &event);
+};
+
+} // End of namespace Ringworld2
+} // End of namespace TsAGE
+
+#endif
diff --git a/engines/tsage/sherlock/sherlock_logo.cpp b/engines/tsage/sherlock/sherlock_logo.cpp
new file mode 100644
index 0000000000..437fdc6d94
--- /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, 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, 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, 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, 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/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_engine.cpp b/engines/wintermute/base/base_engine.cpp
index 7c2e9c8468..2166a3e070 100644
--- a/engines/wintermute/base/base_engine.cpp
+++ b/engines/wintermute/base/base_engine.cpp
@@ -61,10 +61,11 @@ BaseEngine::~BaseEngine() {
delete _classReg;
}
-void BaseEngine::createInstance(const Common::String &targetName, const Common::String &gameId, Common::Language lang) {
+void BaseEngine::createInstance(const Common::String &targetName, const Common::String &gameId, Common::Language lang, WMETargetExecutable targetExecutable) {
instance()._targetName = targetName;
instance()._gameId = gameId;
instance()._language = lang;
+ instance()._targetExecutable = targetExecutable;
instance().init();
}
diff --git a/engines/wintermute/base/base_engine.h b/engines/wintermute/base/base_engine.h
index dd82cf9c29..0f4a6b0775 100644
--- a/engines/wintermute/base/base_engine.h
+++ b/engines/wintermute/base/base_engine.h
@@ -34,6 +34,8 @@
#include "common/random.h"
#include "common/language.h"
+#include "engines/wintermute/game_description.h"
+
namespace Wintermute {
class BaseFileManager;
@@ -53,10 +55,12 @@ class BaseEngine : public Common::Singleton<Wintermute::BaseEngine> {
Common::RandomSource *_rnd;
SystemClassRegistry *_classReg;
Common::Language _language;
+ WMETargetExecutable _targetExecutable;
public:
BaseEngine();
~BaseEngine();
- static void createInstance(const Common::String &targetName, const Common::String &gameId, Common::Language lang);
+ static void createInstance(const Common::String &targetName, const Common::String &gameId, Common::Language lang, WMETargetExecutable targetExecutable = LATEST_VERSION);
+
void setGameRef(BaseGame *gameRef) { _gameRef = gameRef; }
Common::RandomSource *getRandomSource() { return _rnd; }
@@ -73,6 +77,9 @@ public:
const char *getGameTargetName() const { return _targetName.c_str(); }
Common::String getGameId() const { return _gameId; }
Common::Language getLanguage() const { return _language; }
+ WMETargetExecutable getTargetExecutable() const {
+ return _targetExecutable;
+ }
};
} // End of namespace Wintermute
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_game.cpp b/engines/wintermute/base/base_game.cpp
index 8df39c825a..668053bb3a 100644
--- a/engines/wintermute/base/base_game.cpp
+++ b/engines/wintermute/base/base_game.cpp
@@ -3896,6 +3896,11 @@ void BaseGame::expandStringByStringTable(char **str) const {
_settings->expandStringByStringTable(str);
}
+//////////////////////////////////////////////////////////////////////////
+void BaseGame::expandStringByStringTable(Common::String &str) const {
+ _settings->expandStringByStringTable(str);
+}
+
char *BaseGame::getKeyFromStringTable(const char *str) const {
return _settings->getKeyFromStringTable(str);
}
diff --git a/engines/wintermute/base/base_game.h b/engines/wintermute/base/base_game.h
index cdbbff6c93..e535cc9618 100644
--- a/engines/wintermute/base/base_game.h
+++ b/engines/wintermute/base/base_game.h
@@ -123,6 +123,7 @@ public:
inline BaseObject *getMainObject() { return _mainObject; }
inline BaseFont *getSystemFont() { return _systemFont; }
+ inline BaseFont *getVideoFont() { return _videoFont; }
bool initInput();
bool initLoop();
@@ -140,6 +141,7 @@ public:
// String Table
void expandStringByStringTable(char **str) const;
+ void expandStringByStringTable(Common::String &str) const;
char *getKeyFromStringTable(const char *str) const;
void LOG(bool res, const char *fmt, ...);
diff --git a/engines/wintermute/base/base_game_settings.cpp b/engines/wintermute/base/base_game_settings.cpp
index 61c5894be3..996bada997 100644
--- a/engines/wintermute/base/base_game_settings.cpp
+++ b/engines/wintermute/base/base_game_settings.cpp
@@ -215,6 +215,11 @@ void BaseGameSettings::expandStringByStringTable(char **str) const {
_stringTable->expand(str);
}
+//////////////////////////////////////////////////////////////////////////
+void BaseGameSettings::expandStringByStringTable(Common::String &str) const {
+ _stringTable->expand(str);
+}
+
char *BaseGameSettings::getKeyFromStringTable(const char *str) const {
return _stringTable->getKey(str);
}
diff --git a/engines/wintermute/base/base_game_settings.h b/engines/wintermute/base/base_game_settings.h
index 2059cb075e..15afb06450 100644
--- a/engines/wintermute/base/base_game_settings.h
+++ b/engines/wintermute/base/base_game_settings.h
@@ -46,6 +46,7 @@ public:
bool loadSettings(const char *filename);
bool loadStringTable(const char *filename, bool clearOld);
void expandStringByStringTable(char **str) const;
+ void expandStringByStringTable(Common::String &str) const;
char *getKeyFromStringTable(const char *str) const;
bool persist(BasePersistenceManager *persistMgr);
diff --git a/engines/wintermute/base/base_keyboard_state.cpp b/engines/wintermute/base/base_keyboard_state.cpp
index 61087c5836..f672c83d39 100644
--- a/engines/wintermute/base/base_keyboard_state.cpp
+++ b/engines/wintermute/base/base_keyboard_state.cpp
@@ -262,27 +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,
- kVkLeft = 37,
- kVkUp = 38,
- kVkRight = 39,
- kVkDown = 40
-};
+}
//////////////////////////////////////////////////////////////////////////
Common::KeyCode BaseKeyboardState::vKeyToKeyCode(uint32 vkey) {
@@ -290,22 +355,42 @@ Common::KeyCode BaseKeyboardState::vKeyToKeyCode(uint32 vkey) {
switch (vkey) {
case kVkEscape:
return Common::KEYCODE_ESCAPE;
- break;
case kVkSpace:
return Common::KEYCODE_SPACE;
- break;
+ case kVkHome:
+ return Common::KEYCODE_HOME;
case kVkLeft:
return Common::KEYCODE_LEFT;
- break;
case kVkRight:
return Common::KEYCODE_RIGHT;
- break;
case kVkUp:
return Common::KEYCODE_UP;
- break;
case kVkDown:
return Common::KEYCODE_DOWN;
- break;
+ case kVkF1:
+ return Common::KEYCODE_F1;
+ case kVkF2:
+ return Common::KEYCODE_F2;
+ case kVkF3:
+ return Common::KEYCODE_F3;
+ case kVkF4:
+ return Common::KEYCODE_F4;
+ case kVkF5:
+ return Common::KEYCODE_F5;
+ case kVkF6:
+ return Common::KEYCODE_F6;
+ case kVkF7:
+ return Common::KEYCODE_F7;
+ case kVkF8:
+ return Common::KEYCODE_F8;
+ case kVkF9:
+ return Common::KEYCODE_F9;
+ case kVkF10:
+ return Common::KEYCODE_F10;
+ case kVkF11:
+ return Common::KEYCODE_F11;
+ case kVkF12:
+ return Common::KEYCODE_F12;
default:
warning("Unknown VKEY: %d", vkey);
return (Common::KeyCode)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_sprite.cpp b/engines/wintermute/base/base_sprite.cpp
index 04060bff32..09e138a1fd 100644
--- a/engines/wintermute/base/base_sprite.cpp
+++ b/engines/wintermute/base/base_sprite.cpp
@@ -41,6 +41,7 @@
#include "engines/wintermute/base/scriptables/script_value.h"
#include "engines/wintermute/base/scriptables/script.h"
#include "engines/wintermute/base/scriptables/script_stack.h"
+#include "engines/wintermute/game_description.h"
namespace Wintermute {
@@ -347,9 +348,17 @@ void BaseSprite::reset() {
} else {
_currentFrame = -1;
}
-
- killAllSounds();
-
+ if (BaseEngine::instance().getTargetExecutable() >= WME_1_8_6) {
+ /*
+ * This was added in WME 1.8.6
+ *
+ * 5MA and possibly other games ship with pre-1.8.6 WME, and
+ * depends (e.g.: menu sounds, etc) on this not being triggered.
+ *
+ * See bug #6647
+ */
+ killAllSounds();
+ }
_lastFrameTime = 0;
_finished = false;
_moveX = _moveY = 0;
diff --git a/engines/wintermute/base/base_string_table.cpp b/engines/wintermute/base/base_string_table.cpp
index 89407a7b0e..4c750ebc93 100644
--- a/engines/wintermute/base/base_string_table.cpp
+++ b/engines/wintermute/base/base_string_table.cpp
@@ -147,6 +147,15 @@ void BaseStringTable::expand(char **str) const {
}
}
+//////////////////////////////////////////////////////////////////////////
+void BaseStringTable::expand(Common::String &str) const {
+ char *tmp = new char[str.size()+1];
+ strcpy(tmp, str.c_str());
+ expand(&tmp);
+ str = tmp;
+ delete[] tmp;
+}
+
//////////////////////////////////////////////////////////////////////////
const char *BaseStringTable::expandStatic(const char *string) const {
diff --git a/engines/wintermute/base/base_string_table.h b/engines/wintermute/base/base_string_table.h
index cdcf11917d..cfa3eeb226 100644
--- a/engines/wintermute/base/base_string_table.h
+++ b/engines/wintermute/base/base_string_table.h
@@ -41,6 +41,7 @@ class BaseStringTable : public BaseClass {
public:
bool loadFile(const char *filename, bool deleteAll = true);
void expand(char **str) const;
+ void expand(Common::String &str) const;
const char *expandStatic(const char *string) const;
bool addString(const char *key, const char *val, bool reportDuplicities = true);
BaseStringTable(BaseGame *inGame);
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/wintermute/detection.cpp b/engines/wintermute/detection.cpp
index a659c434d0..aca682ae99 100644
--- a/engines/wintermute/detection.cpp
+++ b/engines/wintermute/detection.cpp
@@ -74,7 +74,7 @@ static const char *directoryGlobs[] = {
class WintermuteMetaEngine : public AdvancedMetaEngine {
public:
- WintermuteMetaEngine() : AdvancedMetaEngine(Wintermute::gameDescriptions, sizeof(ADGameDescription), Wintermute::wintermuteGames, gameGuiOptions) {
+ WintermuteMetaEngine() : AdvancedMetaEngine(Wintermute::gameDescriptions, sizeof(WMEGameDescription), Wintermute::wintermuteGames, gameGuiOptions) {
_singleid = "wintermute";
_guioptions = GUIO2(GUIO_NOMIDI, GAMEOPTION_SHOW_FPS);
_maxScanDepth = 2;
@@ -127,8 +127,8 @@ public:
virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
assert(syst);
assert(engine);
-
- *engine = new Wintermute::WintermuteEngine(syst, desc);
+ const WMEGameDescription *gd = (const WMEGameDescription *)desc;
+ *engine = new Wintermute::WintermuteEngine(syst, gd);
return true;
}
diff --git a/engines/wintermute/detection_tables.h b/engines/wintermute/detection_tables.h
index 8206ca9643..4e3320159a 100644
--- a/engines/wintermute/detection_tables.h
+++ b/engines/wintermute/detection_tables.h
@@ -90,1342 +90,458 @@ static const PlainGameDescriptor wintermuteGames[] = {
{0, 0}
};
-static const ADGameDescription gameDescriptions[] = {
+// Duplicates WME_ENTRY1s, for consistency
+#define WME_ENTRY1s(f1, h1, s1) { {f1, 0, h1, s1}, AD_LISTEND }
+#define WME_ENTRY2s(f1, h1, s1, f2, h2, s2) { {f1, 0, h1, s1}, {f2, 0, h2, s2}, AD_LISTEND }
+#define WME_ENTRY3s(f1, h1, s1, f2, h2, s2, f3, h3, s3) { {f1, 0, h1, s1}, {f2, 0, h2, s2}, {f3, 0, h3, s3}, AD_LISTEND }
+
+#define WME_PLATENTRY(shortName, extraName, hashEntry, lang, plat, status, version) \
+ { \
+ { \
+ shortName, \
+ extraName, \
+ hashEntry, \
+ lang, \
+ plat, \
+ status, \
+ GUIO0(), \
+ }, \
+ version \
+ }
+
+// Convenience variant, as most of the games are Windows-games
+#define WME_WINENTRY(shortName, extraName, hashEntry, lang, status, version) \
+ { \
+ { \
+ shortName, \
+ extraName, \
+ hashEntry, \
+ lang, \
+ Common::kPlatformWindows, \
+ status, \
+ GUIO0(), \
+ }, \
+ version \
+ }
+
+/* To add new entries:
+ * Make sure you have a target name defined at the top of the file
+ *
+ * If the game has only one language, and can be detected using only one file,
+ * then use WME_WINENTRY, with WME_ENTRY1s as exemplified below.
+ *
+ * If the game has more than one language, and the main data file is common across
+ * the versions, then you should use WME_WINENTRY with WME_ENTRY2s/WME_ENTRY3s, with
+ * the language file as the first hit, and the data file as the second. (Make sure to
+ * NOT create a WME_ENTRY1s matching the same data file as the 2/3 file match)
+ */
+
+static const WMEGameDescription gameDescriptions[] = {
// Five Lethal Demons
- {
- "5ld",
- "",
- AD_ENTRY1s("data.dcp", "1037a77cbd001e0644898addc022322c", 15407750),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("5ld", "",
+ WME_ENTRY1s("data.dcp", "1037a77cbd001e0644898addc022322c", 15407750), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Five Magical Amulets
- {
- "5ma",
- "",
- AD_ENTRY1s("data.dcp", "0134e92bcd5fd2837df3971087e96067", 163316498),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("5ma", "",
+ WME_ENTRY1s("data.dcp", "0134e92bcd5fd2837df3971087e96067", 163316498), Common::EN_ANY, ADGF_UNSTABLE, WME_1_7_0),
// Actual Destination
- {
- "actualdest",
- "",
- AD_ENTRY1s("data.dcp", "6926f44b26f21ceb1d840eaab9aeb510", 9081740),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("actualdest", "",
+ WME_ENTRY1s("data.dcp", "6926f44b26f21ceb1d840eaab9aeb510", 9081740), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Boredom of Agustin Cordes
- {
- "agustin",
- "",
- AD_ENTRY1s("data.dcp", "abb79c16c9b92e9b06525a4c7c3f5861", 2461949),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("agustin", "",
+ WME_ENTRY1s("data.dcp", "abb79c16c9b92e9b06525a4c7c3f5861", 2461949), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Beyond the Threshold
- {
- "bthreshold",
- "",
- AD_ENTRY1s("data.dcp", "d49bf9ccb2e74507447c82d6ad3e2bc4", 12773712),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("bthreshold", "",
+ WME_ENTRY1s("data.dcp", "d49bf9ccb2e74507447c82d6ad3e2bc4", 12773712), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Bickadoodle
- {
- "bickadoodle",
- "",
- AD_ENTRY1s("data.dcp", "84db4d1594cac95e25614985775d10a8", 35303844),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("bickadoodle", "",
+ WME_ENTRY1s("data.dcp", "84db4d1594cac95e25614985775d10a8", 35303844), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Bickadoodle (Ver 1.1)
- {
- "bickadoodle",
- "Version 1.1",
- AD_ENTRY1s("data.dcp", "8bb52ac9a9ee129c5059e8e808b669d7", 35337760),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("bickadoodle", "Version 1.1",
+ WME_ENTRY1s("data.dcp", "8bb52ac9a9ee129c5059e8e808b669d7", 35337760), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
+ // Bickadoodle (Ver 1.2)
+ WME_WINENTRY("bickadoodle", "Version 1.2",
+ WME_ENTRY1s("data.dcp", "1796a48f3ed72dd785ce93334ab883cc", 35337760), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Bickadoodle (download from http://aethericgames.com/games/bickadoodle/download-bickadoodle/)
- {
- "bickadoodle",
- "",
- AD_ENTRY1s("data.dcp", "1584d83577c32add0fce27fae91141a2", 35337728),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("bickadoodle", "",
+ WME_ENTRY1s("data.dcp", "1584d83577c32add0fce27fae91141a2", 35337728), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Book of Gron Part One
- {
- "bookofgron",
- "",
- AD_ENTRY1s("data.dcp", "e61b2ebee044a82fa0f8ca0fce2c8946", 83129531),
- Common::RU_RUS,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("bookofgron", "",
+ WME_ENTRY1s("data.dcp", "e61b2ebee044a82fa0f8ca0fce2c8946", 83129531), Common::RU_RUS, ADGF_UNSTABLE, LATEST_VERSION),
// Carol Reed 4 - East Side Story (Demo)
- {
- "carolreed4",
- "Demo",
- AD_ENTRY1s("data.dcp", "b3f8b09bb4b05ee3e9d14697525257f9", 59296246),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE |
- ADGF_DEMO,
- GUIO0()
- },
+ WME_WINENTRY("carolreed4", "Demo",
+ WME_ENTRY1s("data.dcp", "b3f8b09bb4b05ee3e9d14697525257f9", 59296246), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION),
// Carol Reed 4 - East Side Story
- {
- "carolreed4",
- "",
- AD_ENTRY1s("data.dcp", "b26377797f060afc2d440d820100c1ce", 529320536),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE |
- ADGF_DEMO,
- GUIO0()
- },
+ WME_WINENTRY("carolreed4", "",
+ WME_ENTRY1s("data.dcp", "b26377797f060afc2d440d820100c1ce", 529320536), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION),
// Carol Reed 5 - The Colour of Murder
- {
- "carolreed5",
- "",
- AD_ENTRY1s("data.dcp", "3fcfca44209545d0e26774156427b494", 603660415),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("carolreed5", "",
+ WME_ENTRY1s("data.dcp", "3fcfca44209545d0e26774156427b494", 603660415), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Carol Reed 6 - Black Circle
- {
- "carolreed6",
- "",
- AD_ENTRY1s("data.dcp", "0e4c532beecf23d85012168753f41189", 456258147),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("carolreed6", "",
+ WME_ENTRY1s("data.dcp", "0e4c532beecf23d85012168753f41189", 456258147), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Carol Reed 7 - Blue Madonna (Demo)
- {
- "carolreed7",
- "Demo",
- AD_ENTRY1s("data.dcp", "0372ad0c775266f6355e9e8ae397a2f1", 103719442),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE |
- ADGF_DEMO,
- GUIO0()
- },
+ WME_WINENTRY("carolreed7", "Demo",
+ WME_ENTRY1s("data.dcp", "0372ad0c775266f6355e9e8ae397a2f1", 103719442), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION),
// Carol Reed 7 - Blue Madonna
- {
- "carolreed7",
- "",
- AD_ENTRY1s("data.dcp", "24e3db3e2fabfc956713796d87a3efb0", 495471147),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("carolreed7", "",
+ WME_ENTRY1s("data.dcp", "24e3db3e2fabfc956713796d87a3efb0", 495471147), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Carol Reed 8 - Amber's Blood
- {
- "carolreed8",
- "",
- AD_ENTRY1s("data.dcp", "859d16b0d5b9b255e470cbded2c6cedc", 502714557),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("carolreed8", "",
+ WME_ENTRY1s("data.dcp", "859d16b0d5b9b255e470cbded2c6cedc", 502714557), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Carol Reed 9 - Cold Case Summer
- {
- "carolreed9",
- "",
- AD_ENTRY1s("data.dcp", "2b343b48a7aee508d728a546b414a255", 620005266),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("carolreed9", "",
+ WME_ENTRY1s("data.dcp", "2b343b48a7aee508d728a546b414a255", 620005266), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Chivalry is Not Dead
- {
- "chivalry",
- "",
- AD_ENTRY1s("data.dcp", "ebd0915d9a12df5224be22f53bb23eb6", 7278306),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_TESTING,
- GUIO0()
- },
+ WME_WINENTRY("chivalry", "",
+ WME_ENTRY1s("data.dcp", "ebd0915d9a12df5224be22f53bb23eb6", 7278306), Common::EN_ANY, ADGF_TESTING, LATEST_VERSION),
// Chivalry is Not Dead (Version from deirdrakai.com)
- {
- "chivalry",
- "",
- AD_ENTRY1s("data.dcp", "ae6d91b9517f4d2851a8ad94c96951c8", 7278302),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_TESTING,
- GUIO0()
- },
+ WME_WINENTRY("chivalry", "",
+ WME_ENTRY1s("data.dcp", "ae6d91b9517f4d2851a8ad94c96951c8", 7278302), Common::EN_ANY, ADGF_TESTING, LATEST_VERSION),
// Conspiracao Dumont
- {
- "conspiracao",
- "",
- AD_ENTRY1s("ConspiracaoDumont.exe", "106f3f2c8f18bb5ffffeed634ace256c", 32908032),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE |
- ADGF_DEMO,
- GUIO0()
- },
+ WME_WINENTRY("conspiracao", "",
+ WME_ENTRY1s("ConspiracaoDumont.exe", "106f3f2c8f18bb5ffffeed634ace256c", 32908032), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION),
// Corrosion: Cold Winter Waiting
- {
- "corrosion",
- "",
- AD_ENTRY1s("data.dcp", "ae885b1a8faa0b27f43c0e8f0df02fc9", 525931618),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_TESTING,
- GUIO0()
- },
+ WME_WINENTRY("corrosion", "",
+ WME_ENTRY1s("data.dcp", "ae885b1a8faa0b27f43c0e8f0df02fc9", 525931618), Common::EN_ANY, ADGF_TESTING, LATEST_VERSION),
// Dead City (Czech)
- {
- "deadcity",
- "",
- {
- // The Czech data are in data.dcp, so in this case we'll have to
- // just detect the english version twice, to give the user a choice.
- {"english.dcp", 0, "c591046d6de7e381d76f70e0787b2b1f", 415935},
- {"data.dcp", 0, "7ebfd50d1a22370ed7b079bcaa631d62", 9070205},
- AD_LISTEND
- },
- Common::CZ_CZE,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ // The Czech data are in data.dcp, so in this case we'll have to
+ // just detect the english version twice, to give the user a choice.
+ WME_WINENTRY("deadcity", "",
+ WME_ENTRY2s("english.dcp", "c591046d6de7e381d76f70e0787b2b1f", 415935,
+ "data.dcp", "7ebfd50d1a22370ed7b079bcaa631d62", 9070205), Common::CZ_CZE, ADGF_UNSTABLE, LATEST_VERSION),
// Dead City (English)
- {
- "deadcity",
- "",
- {
- {"english.dcp", 0, "c591046d6de7e381d76f70e0787b2b1f", 415935},
- {"data.dcp", 0, "7ebfd50d1a22370ed7b079bcaa631d62", 9070205},
- AD_LISTEND
- },
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("deadcity", "",
+ WME_ENTRY2s("english.dcp", "c591046d6de7e381d76f70e0787b2b1f", 415935,
+ "data.dcp", "7ebfd50d1a22370ed7b079bcaa631d62", 9070205), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Dead City (Italian)
- {
- "deadcity",
- "",
- {
- {"italian.dcp", 0, "92d8efb94436bec7bd1b7fe0b548192e", 454037},
- {"data.dcp", 0, "7ebfd50d1a22370ed7b079bcaa631d62", 9070205},
- AD_LISTEND
- },
- Common::IT_ITA,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("deadcity", "",
+ WME_ENTRY2s("italian.dcp", "92d8efb94436bec7bd1b7fe0b548192e", 454037,
+ "data.dcp", "7ebfd50d1a22370ed7b079bcaa631d62", 9070205), Common::IT_ITA, ADGF_UNSTABLE, LATEST_VERSION),
// Dead City (Russian)
- {
- "deadcity",
- "",
- {
- {"russian.dcp", 0, "a0ae71e9e1185596fffb07ad2c951eb9", 653317},
- {"data.dcp", 0, "7ebfd50d1a22370ed7b079bcaa631d62", 9070205},
- AD_LISTEND
- },
- Common::RU_RUS,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("deadcity", "",
+ WME_ENTRY2s("russian.dcp", "a0ae71e9e1185596fffb07ad2c951eb9", 653317,
+ "data.dcp", "7ebfd50d1a22370ed7b079bcaa631d62", 9070205), Common::RU_RUS, ADGF_UNSTABLE, LATEST_VERSION),
// Dirty Split (Czech)
- {
- "dirtysplit",
- "",
- {
- {"czech.dcp", 0, "08a71446467cf8f9444cfea446b46ad6", 127697934},
- {"data.dcp", 0, "8b4b81b718bf65f30a67fc0b1e329eb5", 88577623},
- },
- Common::CZ_CZE,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("dirtysplit", "",
+ WME_ENTRY2s("czech.dcp", "08a71446467cf8f9444cfea446b46ad6", 127697934,
+ "data.dcp", "8b4b81b718bf65f30a67fc0b1e329eb5", 88577623), Common::CZ_CZE, ADGF_UNSTABLE, LATEST_VERSION),
// Dirty Split (English)
- {
- "dirtysplit",
- "",
- AD_ENTRY1s("data.dcp", "8f3dae199361ece0f59fb20cfff6eed3", 88577621),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("dirtysplit", "",
+ WME_ENTRY1s("data.dcp", "8f3dae199361ece0f59fb20cfff6eed3", 88577621), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Dirty Split (French)
- {
- "dirtysplit",
- "",
- {
- {"french.dcp", 0, "a0508dedebd0fe478d0158fa4c2a1136", 125534323},
- {"data.dcp", 0, "e6d70c7f5d181b761cfcf974adf9186a", 88577623},
- AD_LISTEND
- },
- Common::FR_FRA,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("dirtysplit", "",
+ WME_ENTRY2s("french.dcp", "a0508dedebd0fe478d0158fa4c2a1136", 125534323,
+ "data.dcp", "e6d70c7f5d181b761cfcf974adf9186a", 88577623), Common::FR_FRA, ADGF_UNSTABLE, LATEST_VERSION),
// Dirty Split (German)
- {
- "dirtysplit",
- "",
- AD_ENTRY1s("data.dcp", "139d8a25579e969f8b37d20e6e3de5f9", 92668291),
- Common::DE_DEU,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("dirtysplit", "",
+ WME_ENTRY1s("data.dcp", "139d8a25579e969f8b37d20e6e3de5f9", 92668291), Common::DE_DEU, ADGF_UNSTABLE, LATEST_VERSION),
// Dirty Split (Italian)
- {
- "dirtysplit",
- "",
- {
- {"italian.dcp", 0, "8108807fbd8af70be1ec452d0fd1131b", 125513726},
- {"data.dcp", 0, "35a150e22af274185883fdbb142c6fb1", 88577623},
- },
- Common::IT_ITA,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("dirtysplit", "",
+ WME_ENTRY2s("italian.dcp", "8108807fbd8af70be1ec452d0fd1131b", 125513726,
+ "data.dcp", "35a150e22af274185883fdbb142c6fb1", 88577623), Common::IT_ITA, ADGF_UNSTABLE, LATEST_VERSION),
// Dirty Split (Spanish)
- {
- "dirtysplit",
- "",
- {
- {"spanish.dcp", 0, "b3982c0a5e85b42e1e38240fef004aa4", 164428596},
- {"data.dcp", 0, "63766d6c68b9f00b632ea1736fc8a95c", 88577621},
- },
- Common::ES_ESP,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("dirtysplit", "",
+ WME_ENTRY2s("spanish.dcp", "b3982c0a5e85b42e1e38240fef004aa4", 164428596,
+ "data.dcp", "63766d6c68b9f00b632ea1736fc8a95c", 88577621), Common::ES_ESP, ADGF_UNSTABLE, LATEST_VERSION),
// Des Reves Elastiques Avec Mille Insectes Nommes Georges
- {
- "dreaming",
- "",
- AD_ENTRY1s("data.dcp", "4af26d97ea063fc1277ce30ae431de90", 8804073),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("dreaming", "",
+ WME_ENTRY1s("data.dcp", "4af26d97ea063fc1277ce30ae431de90", 8804073), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Dreamscape
- {
- "dreamscape",
- "",
- AD_ENTRY1s("data.dcp", "7a5752ed4446c862be9f02d7932acf54", 17034377),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("dreamscape", "",
+ WME_ENTRY1s("data.dcp", "7a5752ed4446c862be9f02d7932acf54", 17034377), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Escape from the Mansion
- {
- "escapemansion",
- "Beta 1",
- AD_ENTRY1s("data.dcp", "d8e348b2312cc36a929cad75f12e0b3a", 21452380),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("escapemansion", "Beta 1",
+ WME_ENTRY1s("data.dcp", "d8e348b2312cc36a929cad75f12e0b3a", 21452380), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Escape from the Mansion
- {
- "escapemansion",
- "Beta 2",
- AD_ENTRY1s("data.dcp", "ded5fa6c5f2afdaf2cafb53e52cd3dd8", 21455763),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("escapemansion", "Beta 2",
+ WME_ENTRY1s("data.dcp", "ded5fa6c5f2afdaf2cafb53e52cd3dd8", 21455763), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Escape from the Mansion
- {
- "escapemansion",
- "1.3",
- AD_ENTRY1s("data.dcp", "1e5d231b56c8a228cd15cb690f50253e", 29261972),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("escapemansion", "1.3",
+ WME_ENTRY1s("data.dcp", "1e5d231b56c8a228cd15cb690f50253e", 29261972), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Four
- {
- "four",
- "",
- AD_ENTRY1s("data.dcp", "ec05cd5e37c9a524053b8859635a4234", 62599855),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("four", "",
+ WME_ENTRY1s("data.dcp", "ec05cd5e37c9a524053b8859635a4234", 62599855), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Framed
- {
- "framed",
- "",
- AD_ENTRY1s("data.dcp", "e7259fb36f2c6f9f28242291e0c3de98", 34690568),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("framed", "",
+ WME_ENTRY1s("data.dcp", "e7259fb36f2c6f9f28242291e0c3de98", 34690568), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Ghost in the Sheet
- {
- "ghostsheet",
- "",
- {
- {"english.dcp", 0, "e6d0aad2c89996bcabe416105a3d6d3a", 12221017},
- {"data.dcp", 0, "b2f8b05328e4881e15e98e845b63f451", 168003},
- AD_LISTEND
- },
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("ghostsheet", "",
+ WME_ENTRY2s("english.dcp", "e6d0aad2c89996bcabe416105a3d6d3a", 12221017,
+ "data.dcp", "b2f8b05328e4881e15e98e845b63f451", 168003), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Ghost in the Sheet (Demo)
- {
- "ghostsheet",
- "Demo",
- AD_ENTRY1s("data.dcp", "dc1f6595f412ac25a52eaf47dad4ab81", 169083),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE |
- ADGF_DEMO,
- GUIO0()
- },
+ WME_WINENTRY("ghostsheet", "Demo",
+ WME_ENTRY1s("data.dcp", "dc1f6595f412ac25a52eaf47dad4ab81", 169083), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION),
// Hamlet or the last game without MMORPS features, shaders and product placement
- {
- "hamlet",
- "",
- AD_ENTRY1s("data.dcp", "f624add957a77c9930529fb28cc2450f", 88183022),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("hamlet", "",
+
+ WME_ENTRY1s("data.dcp", "f624add957a77c9930529fb28cc2450f", 88183022), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Helga Deep In Trouble (English)
- {
- "helga",
- "",
- {
- {"english.dcp", 0, "bfa136b21bdbc7d8691c0770a6d40bc3", 135931},
- {"data.dcp", 0, "25cb955a60b58326f2eeda1ce288fb37", 183251259},
- AD_LISTEND
- },
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("helga", "",
+ WME_ENTRY2s("english.dcp", "bfa136b21bdbc7d8691c0770a6d40bc3", 135931,
+ "data.dcp", "25cb955a60b58326f2eeda1ce288fb37", 183251259), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Helga Deep In Trouble (Demo) (English)
- {
- "helga",
- "Demo",
- {
- {"english.dcp", 0, "b3a93e678f0ef97200f691cd1724643f", 135864},
- {"data.dcp", 0, "45134ed93bc391edf148b79cdcbf2a09", 154266028},
- AD_LISTEND
- },
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE |
- ADGF_DEMO,
- GUIO0()
- },
+ WME_WINENTRY("helga", "Demo",
+ WME_ENTRY2s("english.dcp", "b3a93e678f0ef97200f691cd1724643f", 135864,
+ "data.dcp", "45134ed93bc391edf148b79cdcbf2a09", 154266028), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION),
// James Peris: No License Nor Control (English)
- {
- "jamesperis",
- "",
- AD_ENTRY1s("data.dcp", "a420961e170cb7d168a0d2bae2fe5218", 225294032),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("jamesperis", "",
+ WME_ENTRY1s("data.dcp", "a420961e170cb7d168a0d2bae2fe5218", 225294032), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// James Peris: No License Nor Control (Spanish)
- {
- "jamesperis",
- "",
- AD_ENTRY1s("data.dcp", "a420961e170cb7d168a0d2bae2fe5218", 225294032),
- Common::ES_ESP,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("jamesperis", "",
+ WME_ENTRY1s("data.dcp", "a420961e170cb7d168a0d2bae2fe5218", 225294032), Common::ES_ESP, ADGF_UNSTABLE, LATEST_VERSION),
// James Peris: No License Nor Control (Demo) (English)
- {
- "jamesperis",
- "Demo",
- AD_ENTRY1s("data.dcp", "edb9f9c7a08993c1e28f4e477b5f9830", 116113507),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE |
- ADGF_DEMO,
- GUIO0()
- },
+ WME_WINENTRY("jamesperis", "Demo",
+ WME_ENTRY1s("data.dcp", "edb9f9c7a08993c1e28f4e477b5f9830", 116113507), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION),
// James Peris: No License Nor Control (Demo) (Spanish)
- {
- "jamesperis",
- "Demo",
- AD_ENTRY1s("data.dcp", "edb9f9c7a08993c1e28f4e477b5f9830", 116113507),
- Common::ES_ESP,
- Common::kPlatformWindows,
- ADGF_UNSTABLE |
- ADGF_DEMO,
- GUIO0()
- },
+ WME_WINENTRY("jamesperis", "Demo",
+ WME_ENTRY1s("data.dcp", "edb9f9c7a08993c1e28f4e477b5f9830", 116113507), Common::ES_ESP, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION),
// J.U.L.I.A. (English)
- {
- "julia",
- "",
- AD_ENTRY1s("data.dcp", "c2264b4f8fcd132d2913ff5b6076a24f", 10109741),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("julia", "",
+ WME_ENTRY1s("data.dcp", "c2264b4f8fcd132d2913ff5b6076a24f", 10109741), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// J.U.L.I.A. (English, Bundle in a box-version)
- {
- "julia",
- "Version 1.2",
- AD_ENTRY1s("data.dcp", "fe90023ccc22f35185b40b910e0d03a2", 10101373),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("julia", "Version 1.2",
+ WME_ENTRY1s("data.dcp", "fe90023ccc22f35185b40b910e0d03a2", 10101373), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// J.U.L.I.A. (English) (Demo)
- {
- "julia",
- "Demo",
- AD_ENTRY1s("data.dcp", "f0bbc3394555a9811f6050dae428cab6", 7655237),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE |
- ADGF_DEMO,
- GUIO0()
- },
+ WME_WINENTRY("julia", "Demo",
+ WME_ENTRY1s("data.dcp", "f0bbc3394555a9811f6050dae428cab6", 7655237), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION),
// J.U.L.I.A. (English) (Greenlight Demo)
- {
- "julia",
- "Greenlight Demo",
- AD_ENTRY1s("data.dcp", "4befd448d36b0dae9c3ab1aa7cb8b78d", 7271886),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE |
- ADGF_DEMO,
- GUIO0()
- },
+ WME_WINENTRY("julia", "Greenlight Demo",
+ WME_ENTRY1s("data.dcp", "4befd448d36b0dae9c3ab1aa7cb8b78d", 7271886), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION),
// Kulivocko (Czech)
- {
- "kulivocko",
- "",
- AD_ENTRY1s("data.dcp", "44306dc470e9b27474043932eccee02f", 155106392),
- Common::CZ_CZE,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("kulivocko", "",
+ WME_ENTRY1s("data.dcp", "44306dc470e9b27474043932eccee02f", 155106392), Common::CZ_CZE, ADGF_UNSTABLE, LATEST_VERSION),
// Kulivocko (Czech) (Demo)
- {
- "kulivocko",
- "Demo",
- AD_ENTRY1s("data.dcp", "63b164bdfadecbb0deb5da691afb8154", 48362234),
- Common::CZ_CZE,
- Common::kPlatformWindows,
- ADGF_UNSTABLE |
- ADGF_DEMO,
- GUIO0()
- },
+ WME_WINENTRY("kulivocko", "Demo",
+ WME_ENTRY1s("data.dcp", "63b164bdfadecbb0deb5da691afb8154", 48362234), Common::CZ_CZE, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION),
// Life In 3 Minutes
- {
- "lifein3minutes",
- "",
- AD_ENTRY1s("data.dcp", "c6368950e37a95bf098b02b4eaa5b929", 141787214),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("lifein3minutes", "",
+ WME_ENTRY1s("data.dcp", "c6368950e37a95bf098b02b4eaa5b929", 141787214), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Looky Demo (English)
- {
- "looky",
- "Demo",
- {
- {"english.dcp", 0, "1388e1dd320f4d553dea3b0316812f9d", 1358442},
- {"data.dcp", 0, "7074bcd7bc7ad7eb04c271aafb964c32", 13815660},
- AD_LISTEND
- },
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE |
- ADGF_DEMO,
- GUIO0()
- },
+ WME_WINENTRY("looky", "Demo",
+ WME_ENTRY2s("english.dcp", "1388e1dd320f4d553dea3b0316812f9d", 1358442,
+ "data.dcp", "7074bcd7bc7ad7eb04c271aafb964c32", 13815660), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION),
// Looky Demo (German)
- {
- "looky",
- "Demo",
- {
- {"german.dcp", 0, "606c048426dfbe94442b59fd34a5c76e", 14339496},
- {"data.dcp", 0, "7074bcd7bc7ad7eb04c271aafb964c32", 13815660},
- AD_LISTEND
- },
- Common::DE_DEU,
- Common::kPlatformWindows,
- ADGF_UNSTABLE |
- ADGF_DEMO,
- GUIO0()
- },
+ WME_WINENTRY("looky", "Demo",
+ WME_ENTRY2s("german.dcp", "606c048426dfbe94442b59fd34a5c76e", 14339496,
+ "data.dcp", "7074bcd7bc7ad7eb04c271aafb964c32", 13815660), Common::DE_DEU, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION),
// Looky (German)
- {
- "looky",
- "",
- {
- {"german.dcp", 0, "bf4c2b8c26342342441a6d64934ab832", 107027865},
- {"data.dcp", 0, "50de0beaa5ad621aa9f020df901d1e74", 1342214},
- AD_LISTEND
- },
- Common::DE_DEU,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("looky", "",
+ WME_ENTRY2s("german.dcp", "bf4c2b8c26342342441a6d64934ab832", 107027865,
+ "data.dcp", "50de0beaa5ad621aa9f020df901d1e74", 1342214), Common::DE_DEU, ADGF_UNSTABLE, LATEST_VERSION),
// Mirage
- {
- "mirage",
- "",
- AD_ENTRY1s("data.dcp", "d230b0b99c0aa77b9ecd094d8ee5573b", 17844056),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("mirage", "",
+ WME_ENTRY1s("data.dcp", "d230b0b99c0aa77b9ecd094d8ee5573b", 17844056), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Oknytt
- {
- "oknytt",
- "Version 1.0",
- AD_ENTRY1s("data.dcp", "6456cf8f429905c83f07509f9da536dd", 109502959),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("oknytt", "Version 1.0",
+ WME_ENTRY1s("data.dcp", "6456cf8f429905c83f07509f9da536dd", 109502959), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Night Train Demo
- {
- "nighttrain",
- "",
- AD_ENTRY1s("data.dcp", "5a027ef84b083a730c9a4c85ec1d3a32", 131760816),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE |
- ADGF_DEMO,
- GUIO0()
- },
+ WME_WINENTRY("nighttrain", "",
+ WME_ENTRY1s("data.dcp", "5a027ef84b083a730c9a4c85ec1d3a32", 131760816), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION),
// Paintaria
- {
- "paintaria",
- "",
- AD_ENTRY1s("data.dcp", "354c08440c98150ff0d4008dd2865880", 48326040),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("paintaria", "",
+ WME_ENTRY1s("data.dcp", "354c08440c98150ff0d4008dd2865880", 48326040), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Pigeons in the Park
- {
- "pigeons",
- "",
- AD_ENTRY1s("data.dcp", "9143a5b6ff8206aefe3c4c643add3ec7", 2611100),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("pigeons", "",
+ WME_ENTRY1s("data.dcp", "9143a5b6ff8206aefe3c4c643add3ec7", 2611100), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Project: Doom
- {
- "projectdoom",
- "",
- AD_ENTRY1s("data.dcp", "d5894b65a40706845434b99870bcab92", 99223761),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("projectdoom", "",
+ WME_ENTRY1s("data.dcp", "d5894b65a40706845434b99870bcab92", 99223761), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Project Joe
- {
- "projectjoe",
- "",
- AD_ENTRY1s("data.dcp", "ada3c08542901295076b5349e655e73f", 160780037),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE |
- ADGF_DEMO,
- GUIO0()
- },
+ WME_WINENTRY("projectjoe", "",
+ WME_ENTRY1s("data.dcp", "ada3c08542901295076b5349e655e73f", 160780037), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION),
// Project Lonely Robot
- {
- "lonelyrobot",
- "beta",
- AD_ENTRY1s("data.dcp", "a0cf7ad5bab957416dcda454e9f28ef0", 3420120),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE |
- ADGF_DEMO,
- GUIO0()
- },
+ WME_WINENTRY("lonelyrobot", "beta",
+ WME_ENTRY1s("data.dcp", "a0cf7ad5bab957416dcda454e9f28ef0", 3420120), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION),
// Reversion: The Escape Version 1.0
- {
- "reversion1",
- "Version 1.0",
- AD_ENTRY1s("data.dcp", "cd616f98ebfd047e0c540b50b4b70761", 254384531),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("reversion1", "Version 1.0",
+ WME_ENTRY1s("data.dcp", "cd616f98ebfd047e0c540b50b4b70761", 254384531), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Reversion: The Escape Version 1.1 (Chinese)
- {
- "reversion1",
- "Version 1.1",
- {
- {"chinese.dcp", 0, "cf97150739499a4c15f51dc534ff85a1", 6330561},
- {"data.dcp", 0, "cb9865dc7e1db2990a8cf4bc13cf4999", 257643032},
- AD_LISTEND
- },
- Common::ZH_CNA,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("reversion1", "Version 1.1",
+ WME_ENTRY2s("chinese.dcp", "cf97150739499a4c15f51dc534ff85a1", 6330561,
+ "data.dcp", "cb9865dc7e1db2990a8cf4bc13cf4999", 257643032), Common::ZH_CNA, ADGF_UNSTABLE, LATEST_VERSION),
// Reversion: The Escape Version 1.1 (English)
- {
- "reversion1",
- "Version 1.1",
- {
- {"english.dcp", 0, "7b2f061d7c91365c5d04605f1de032b3", 5702699},
- {"data.dcp", 0, "cb9865dc7e1db2990a8cf4bc13cf4999", 257643032},
- AD_LISTEND
- },
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("reversion1", "Version 1.1",
+ WME_ENTRY2s("english.dcp", "7b2f061d7c91365c5d04605f1de032b3", 5702699,
+ "data.dcp", "cb9865dc7e1db2990a8cf4bc13cf4999", 257643032), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Reversion: The Escape Version 1.1 (French)
- {
- "reversion1",
- "Version 1.1",
- {
- {"french.dcp", 0, "214204b6022c5ed67fada44557690faf", 6327400},
- {"data.dcp", 0, "cb9865dc7e1db2990a8cf4bc13cf4999", 257643032},
- AD_LISTEND
- },
- Common::FR_FRA,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("reversion1", "Version 1.1",
+ WME_ENTRY2s("french.dcp", "214204b6022c5ed67fada44557690faf", 6327400,
+ "data.dcp", "cb9865dc7e1db2990a8cf4bc13cf4999", 257643032), Common::FR_FRA, ADGF_UNSTABLE, LATEST_VERSION),
// Reversion: The Escape Version 1.1 (German)
- {
- "reversion1",
- "Version 1.1",
- {
- {"german.dcp", 0, "96677823b36d580a4a29e3659071071c", 6340699},
- {"data.dcp", 0, "cb9865dc7e1db2990a8cf4bc13cf4999", 257643032},
- AD_LISTEND
- },
- Common::DE_DEU,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("reversion1", "Version 1.1",
+ WME_ENTRY2s("german.dcp", "96677823b36d580a4a29e3659071071c", 6340699,
+ "data.dcp", "cb9865dc7e1db2990a8cf4bc13cf4999", 257643032), Common::DE_DEU, ADGF_UNSTABLE, LATEST_VERSION),
// Reversion: The Escape Version 1.1 (Italian)
- {
- "reversion1",
- "Version 1.1",
- {
- {"italian.dcp", 0, "9ce80c1835108f10170a02969f71efe1", 6301836},
- {"data.dcp", 0, "cb9865dc7e1db2990a8cf4bc13cf4999", 257643032},
- AD_LISTEND
- },
- Common::IT_ITA,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("reversion1", "Version 1.1",
+ WME_ENTRY2s("italian.dcp", "9ce80c1835108f10170a02969f71efe1", 6301836,
+ "data.dcp", "cb9865dc7e1db2990a8cf4bc13cf4999", 257643032), Common::IT_ITA, ADGF_UNSTABLE, LATEST_VERSION),
// Reversion: The Escape Version 1.1 (Portuguese)
- {
- "reversion1",
- "Version 1.1",
- {
- {"portugues.dcp", 0, "8772501afa2c630a7c697eb99e9c7bda", 5053303},
- {"data.dcp", 0, "cb9865dc7e1db2990a8cf4bc13cf4999", 257643032},
- AD_LISTEND
- },
- Common::PT_BRA,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("reversion1", "Version 1.1",
+ WME_ENTRY2s("portugues.dcp", "8772501afa2c630a7c697eb99e9c7bda", 5053303,
+ "data.dcp", "cb9865dc7e1db2990a8cf4bc13cf4999", 257643032), Common::PT_BRA, ADGF_UNSTABLE, LATEST_VERSION),
// Reversion: The Escape Version 1.3 (Chinese)
- {
- "reversion1",
- "Version 1.3",
- {
- {"xlanguage_nz.dcp", 0, "92c4065156e464211685bf799b3279fd", 5130600},
- {"data.dcp", 0, "9ebb12f6fd7c038d079f81beb3bd96d5", 254185907},
- AD_LISTEND
- },
- Common::ZH_CNA,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("reversion1", "Version 1.3",
+ WME_ENTRY2s("xlanguage_nz.dcp", "92c4065156e464211685bf799b3279fd", 5130600,
+ "data.dcp", "9ebb12f6fd7c038d079f81beb3bd96d5", 254185907), Common::ZH_CNA, ADGF_UNSTABLE, LATEST_VERSION),
// Reversion: The Escape Version 1.3 (English)
- {
- "reversion1",
- "Version 1.3",
- {
- {"xlanguage_en.dcp", 0, "05845e1283920a6e4044f2a54f7a9519", 4818543},
- {"data.dcp", 0, "9ebb12f6fd7c038d079f81beb3bd96d5", 254185907},
- AD_LISTEND
- },
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("reversion1", "Version 1.3",
+ WME_ENTRY2s("xlanguage_en.dcp", "05845e1283920a6e4044f2a54f7a9519", 4818543,
+ "data.dcp", "9ebb12f6fd7c038d079f81beb3bd96d5", 254185907), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Reversion: The Escape Version 1.3 (French)
- {
- "reversion1",
- "Version 1.3",
- {
- {"xlanguage_fr.dcp", 0, "441795490e9307eb2ed07830779881ac", 5425959},
- {"data.dcp", 0, "9ebb12f6fd7c038d079f81beb3bd96d5", 254185907},
- AD_LISTEND
- },
- Common::FR_FRA,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("reversion1", "Version 1.3",
+ WME_ENTRY2s("xlanguage_fr.dcp", "441795490e9307eb2ed07830779881ac", 5425959,
+ "data.dcp", "9ebb12f6fd7c038d079f81beb3bd96d5", 254185907), Common::FR_FRA, ADGF_UNSTABLE, LATEST_VERSION),
// Reversion: The Escape Version 1.3 (German)
- {
- "reversion1",
- "Version 1.3",
- {
- {"xlanguage_de.dcp", 0, "b588041015b93e54b4c246ca77d01e76", 5423798},
- {"data.dcp", 0, "9ebb12f6fd7c038d079f81beb3bd96d5", 254185907},
- AD_LISTEND
- },
- Common::DE_DEU,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("reversion1", "Version 1.3",
+ WME_ENTRY2s("xlanguage_de.dcp", "b588041015b93e54b4c246ca77d01e76", 5423798,
+ "data.dcp", "9ebb12f6fd7c038d079f81beb3bd96d5", 254185907), Common::DE_DEU, ADGF_UNSTABLE, LATEST_VERSION),
// Reversion: The Escape Version 1.3 (Italian)
- {
- "reversion1",
- "Version 1.3",
- {
- {"xlanguage_it.dcp", 0, "a1f4199079b75ee10cded41f05b45d5f", 5386424},
- {"data.dcp", 0, "9ebb12f6fd7c038d079f81beb3bd96d5", 254185907},
- AD_LISTEND
- },
- Common::IT_ITA,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("reversion1", "Version 1.3",
+ WME_ENTRY2s("xlanguage_it.dcp", "a1f4199079b75ee10cded41f05b45d5f", 5386424,
+ "data.dcp", "9ebb12f6fd7c038d079f81beb3bd96d5", 254185907), Common::IT_ITA, ADGF_UNSTABLE, LATEST_VERSION),
// Reversion: The Escape Version 1.3 (Portuguese)
- {
- "reversion1",
- "Version 1.3",
- {
- {"xlanguage_pt.dcp", 0, "3d653debd37e56756a79401e1004c4d2", 4149165},
- {"data.dcp", 0, "9ebb12f6fd7c038d079f81beb3bd96d5", 254185907},
- AD_LISTEND
- },
- Common::PT_BRA,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("reversion1", "Version 1.3",
+ WME_ENTRY2s("xlanguage_pt.dcp", "3d653debd37e56756a79401e1004c4d2", 4149165,
+ "data.dcp", "9ebb12f6fd7c038d079f81beb3bd96d5", 254185907), Common::PT_BRA, ADGF_UNSTABLE, LATEST_VERSION),
// Reversion: The Escape Version 1.3.2369 (Chinese)
- {
- "reversion1",
- "Version 1.3.2369",
- {
- {"xlanguage_nz.dcp", 0, "7146dfa43ffdf0886e034fffe2c8a0c0", 13722261},
- {"data.dcp", 0, "aecb5deeea7b0baa871fbd0cef35a648", 254219204},
- AD_LISTEND
- },
- Common::ZH_CNA,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("reversion1", "Version 1.3.2369",
+ WME_ENTRY2s("xlanguage_nz.dcp", "7146dfa43ffdf0886e034fffe2c8a0c0", 13722261,
+ "data.dcp", "aecb5deeea7b0baa871fbd0cef35a648", 254219204), Common::ZH_CNA, ADGF_UNSTABLE, LATEST_VERSION),
// Reversion: The Escape Version 1.3.2369 (English)
- {
- "reversion1",
- "Version 1.3.2369",
- {
- {"xlanguage_en.dcp", 0, "64b6fa7eedc09c231f6ce046e77fee05", 11339619},
- {"data.dcp", 0, "aecb5deeea7b0baa871fbd0cef35a648", 254219204},
- AD_LISTEND
- },
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("reversion1", "Version 1.3.2369",
+ WME_ENTRY2s("xlanguage_en.dcp", "64b6fa7eedc09c231f6ce046e77fee05", 11339619,
+ "data.dcp", "aecb5deeea7b0baa871fbd0cef35a648", 254219204), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Reversion: The Escape Version 1.3.2369 (French)
- {
- "reversion1",
- "Version 1.3.2369",
- {
- {"xlanguage_fr.dcp", 0, "d561d562224afea809153a1fd9fdb0c0", 11963210},
- {"data.dcp", 0, "aecb5deeea7b0baa871fbd0cef35a648", 254219204},
- AD_LISTEND
- },
- Common::FR_FRA,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("reversion1", "Version 1.3.2369",
+ WME_ENTRY2s("xlanguage_fr.dcp", "d561d562224afea809153a1fd9fdb0c0", 11963210,
+ "data.dcp", "aecb5deeea7b0baa871fbd0cef35a648", 254219204), Common::FR_FRA, ADGF_UNSTABLE, LATEST_VERSION),
// Reversion: The Escape Version 1.3.2369 (German)
- {
- "reversion1",
- "Version 1.3.2369",
- {
- {"xlanguage_de.dcp", 0, "4e3f614c36bd6bae74b8cc83e663a8f0", 14040310},
- {"data.dcp", 0, "aecb5deeea7b0baa871fbd0cef35a648", 254219204},
- AD_LISTEND
- },
- Common::DE_DEU,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("reversion1", "Version 1.3.2369",
+ WME_ENTRY2s("xlanguage_de.dcp", "4e3f614c36bd6bae74b8cc83e663a8f0", 14040310,
+ "data.dcp", "aecb5deeea7b0baa871fbd0cef35a648", 254219204), Common::DE_DEU, ADGF_UNSTABLE, LATEST_VERSION),
// Reversion: The Escape Version 1.3.2369 (Italian)
- {
- "reversion1",
- "Version 1.3.2369",
- {
- {"xlanguage_it.dcp", 0, "10d09b7fe61946f09dd91d5e8d090f94", 11913752},
- {"data.dcp", 0, "aecb5deeea7b0baa871fbd0cef35a648", 254219204},
- AD_LISTEND
- },
- Common::IT_ITA,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("reversion1", "Version 1.3.2369",
+ WME_ENTRY2s("xlanguage_it.dcp", "10d09b7fe61946f09dd91d5e8d090f94", 11913752,
+ "data.dcp", "aecb5deeea7b0baa871fbd0cef35a648", 254219204), Common::IT_ITA, ADGF_UNSTABLE, LATEST_VERSION),
// Reversion: The Escape Version 1.3.2369 (Latvian)
- {
- "reversion1",
- "Version 1.3.2369",
- {
- {"xlanguage_lv.dcp", 0, "704359ab5040b0dab6545064d7aa6eb9", 11414925},
- {"data.dcp", 0, "aecb5deeea7b0baa871fbd0cef35a648", 254219204},
- AD_LISTEND
- },
- Common::LV_LAT,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("reversion1", "Version 1.3.2369",
+ WME_ENTRY2s("xlanguage_lv.dcp", "704359ab5040b0dab6545064d7aa6eb9", 11414925,
+ "data.dcp", "aecb5deeea7b0baa871fbd0cef35a648", 254219204), Common::LV_LAT, ADGF_UNSTABLE, LATEST_VERSION),
// Reversion: The Escape Version 1.3.2369 (Polish)
- {
- "reversion1",
- "Version 1.3.2369",
- {
- {"xlanguage_pl.dcp", 0, "c4ad33f57e1e998169552d521c1d6638", 11532215},
- {"data.dcp", 0, "aecb5deeea7b0baa871fbd0cef35a648", 254219204},
- AD_LISTEND
- },
- Common::PL_POL,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("reversion1", "Version 1.3.2369",
+ WME_ENTRY2s("xlanguage_pl.dcp", "c4ad33f57e1e998169552d521c1d6638", 11532215,
+ "data.dcp", "aecb5deeea7b0baa871fbd0cef35a648", 254219204), Common::PL_POL, ADGF_UNSTABLE, LATEST_VERSION),
// Reversion: The Escape Version 1.3.2369 (Portuguese)
- {
- "reversion1",
- "Version 1.3.2369",
- {
- {"xlanguage_pt.dcp", 0, "886886b6b14aadac844078de856799a6", 10620797},
- {"data.dcp", 0, "aecb5deeea7b0baa871fbd0cef35a648", 254219204},
- AD_LISTEND
- },
- Common::PT_BRA,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("reversion1", "Version 1.3.2369",
+ WME_ENTRY2s("xlanguage_pt.dcp", "886886b6b14aadac844078de856799a6", 10620797,
+ "data.dcp", "aecb5deeea7b0baa871fbd0cef35a648", 254219204), Common::PT_BRA, ADGF_UNSTABLE, LATEST_VERSION),
// Reversion: The Meeting (Chinese)
- {
- "reversion2",
- "",
- {
- {"xlanguage_nz.dcp", 0, "8c3709474a87a7876109025dff41ff3f", 8746015},
- {"data.dcp", 0, "cb9865dc7e1db2990a8cf4bc13cf4999", 257643032},
- AD_LISTEND
- },
- Common::ZH_CNA,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("reversion2", "",
+ WME_ENTRY2s("xlanguage_nz.dcp", "8c3709474a87a7876109025dff41ff3f", 8746015,
+ "data.dcp", "cb9865dc7e1db2990a8cf4bc13cf4999", 257643032), Common::ZH_CNA, ADGF_UNSTABLE, LATEST_VERSION),
// Reversion: The Meeting (English)
- {
- "reversion2",
- "",
- {
- {"xlanguage_en.dcp", 0, "ca357d86618d1ab76a21c913f4403cbd", 8414976},
- {"data.dcp", 0, "f7938cbfdc48f07934550245a3286921", 255672016},
- AD_LISTEND
- },
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("reversion2", "",
+ WME_ENTRY2s("xlanguage_en.dcp", "ca357d86618d1ab76a21c913f4403cbd", 8414976,
+ "data.dcp", "f7938cbfdc48f07934550245a3286921", 255672016), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Reversion: The Meeting (Spanish)
- {
- "reversion2",
- "",
- AD_ENTRY1s("data.dcp", "f7938cbfdc48f07934550245a3286921", 255672016),
- Common::ES_ESP,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("reversion2", "",
+ WME_ENTRY1s("data.dcp", "f7938cbfdc48f07934550245a3286921", 255672016), Common::ES_ESP, ADGF_UNSTABLE, LATEST_VERSION),
// Reversion: The Meeting Version 2.0.2412 (Chinese)
- {
- "reversion2",
- "Version 2.0.2412",
- {
- {"data.dcp", 0, "f4ffc4df24b7bebad56a24930f33a2bc", 255766600},
- {"xlanguage_nz.dcp", 0, "17c79af4928e24484bee77a7e807cc2a", 10737127},
- {"Linux.dcp", 0, "21858bd77dc86b03f701fd47900e2f51", 984535},
- AD_LISTEND
- },
- Common::ZH_CNA,
- Common::kPlatformLinux,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_PLATENTRY("reversion2", "Version 2.0.2412",
+ WME_ENTRY3s("data.dcp", "f4ffc4df24b7bebad56a24930f33a2bc", 255766600,
+ "xlanguage_nz.dcp", "17c79af4928e24484bee77a7e807cc2a", 10737127,
+ "Linux.dcp", "21858bd77dc86b03f701fd47900e2f51", 984535), Common::ZH_CNA, Common::kPlatformLinux, ADGF_UNSTABLE, LATEST_VERSION),
// Reversion: The Meeting Version 2.0.2412 (English)
- {
- "reversion2",
- "Version 2.0.2412",
- {
- {"data.dcp", 0, "f4ffc4df24b7bebad56a24930f33a2bc", 255766600},
- {"xlanguage_en.dcp", 0, "0598bf752ce93b42bcaf1094df537c7b", 8533057},
- {"Linux.dcp", 0, "21858bd77dc86b03f701fd47900e2f51", 984535},
- AD_LISTEND
- },
- Common::EN_ANY,
- Common::kPlatformLinux,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_PLATENTRY("reversion2", "Version 2.0.2412",
+ WME_ENTRY3s("data.dcp", "f4ffc4df24b7bebad56a24930f33a2bc", 255766600,
+ "xlanguage_en.dcp", "0598bf752ce93b42bcaf1094df537c7b", 8533057,
+ "Linux.dcp", "21858bd77dc86b03f701fd47900e2f51", 984535), Common::EN_ANY, Common::kPlatformLinux, ADGF_UNSTABLE, LATEST_VERSION),
// Rhiannon: Curse of the four Branches
- {
- "rhiannon",
- "",
- AD_ENTRY1s("data.dcp", "870f348900b735f1cc79c0608ce32b0e", 1046169851),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("rhiannon", "",
+ WME_ENTRY1s("data.dcp", "870f348900b735f1cc79c0608ce32b0e", 1046169851), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Rhiannon: Curse of the four Branches (English PC DVD)
- {
- "rhiannon",
- "DVD",
- AD_ENTRY1s("data.dcp", "6736bbc921bb6ce5161b3ad095a97bd4", 1053441028),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("rhiannon", "DVD",
+ WME_ENTRY1s("data.dcp", "6736bbc921bb6ce5161b3ad095a97bd4", 1053441028), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// 1 1/2 Ritter: Auf der Suche nach der hinreissenden Herzelinde
- {
- "ritter",
- "",
- AD_ENTRY1s("data.dcp", "5ac416cee605d3a30f4d59687b1cdab2", 364260278),
- Common::DE_DEU,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("ritter", "",
+ WME_ENTRY1s("data.dcp", "5ac416cee605d3a30f4d59687b1cdab2", 364260278), Common::DE_DEU, ADGF_UNSTABLE, LATEST_VERSION),
// Satan and Son
- {
- "satanandson",
- "",
- AD_ENTRY1s("data.dcp", "16a6ba8174b697bbba9299619d1e20c4", 67539054),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE |
- ADGF_DEMO,
- GUIO0()
- },
+ WME_WINENTRY("satanandson", "",
+ WME_ENTRY1s("data.dcp", "16a6ba8174b697bbba9299619d1e20c4", 67539054), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION),
// Rosemary
- {
- "rosemary",
- "",
- AD_ENTRY1s("data.dcp", "4f2631138bd4d27587d9043f8aeff3df", 29483643),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("rosemary", "",
+ WME_ENTRY1s("data.dcp", "4f2631138bd4d27587d9043f8aeff3df", 29483643), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Securanote
- {
- "securanote",
- "",
- AD_ENTRY1s("data.dcp", "5213d3e59b9e95b7fbd5c56f7de5341a", 2625554),
- Common::EN_ANY,
- Common::kPlatformIOS,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_PLATENTRY("securanote", "",
+ WME_ENTRY1s("data.dcp", "5213d3e59b9e95b7fbd5c56f7de5341a", 2625554), Common::EN_ANY, Common::kPlatformIOS, ADGF_UNSTABLE, LATEST_VERSION),
// Shaban
- {
- "shaban",
- "",
- AD_ENTRY1s("data.dcp", "35f702ca9baabc5c620e0be230195c8a", 755388466),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("shaban", "",
+ WME_ENTRY1s("data.dcp", "35f702ca9baabc5c620e0be230195c8a", 755388466), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// The Shine of a Star
- {
- "shinestar",
- "",
- AD_ENTRY1s("data.dcp", "f05abe9e2427a5e4f73648fa09c4ba8e", 94113060),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("shinestar", "",
+ WME_ENTRY1s("data.dcp", "f05abe9e2427a5e4f73648fa09c4ba8e", 94113060), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Sofia's Debt
- {
- "sofiasdebt",
- "",
- AD_ENTRY1s("SD.exe", "e9515f9ba1a2925bb6733476a826a650", 9915047),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("sofiasdebt", "",
+ WME_ENTRY1s("SD.exe", "e9515f9ba1a2925bb6733476a826a650", 9915047), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Space Invaders (Demo)
- {
- "spaceinvaders",
- "Demo",
- AD_ENTRY1s("data.dcp", "3f27adefdf72f2c1601cf555c80a509f", 1308361),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE |
- ADGF_DEMO,
- GUIO0()
- },
+ WME_WINENTRY("spaceinvaders", "Demo",
+ WME_ENTRY1s("data.dcp", "3f27adefdf72f2c1601cf555c80a509f", 1308361), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION),
// Space Madness
- {
- "spacemadness",
- "1.0.2",
- AD_ENTRY1s("data.dcp", "b9b83135dc7a9e1b4b5f50195dbeb630", 39546622),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("spacemadness", "1.0.2",
+ WME_ENTRY1s("data.dcp", "b9b83135dc7a9e1b4b5f50195dbeb630", 39546622), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// The Ancient Mark - Episode 1
- {
- "theancientmark1",
- "",
- AD_ENTRY1s("data.dcp", "ca04c26f03b2bd307368b306b297ddd7", 364664692),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("theancientmark1", "",
+ WME_ENTRY1s("data.dcp", "ca04c26f03b2bd307368b306b297ddd7", 364664692), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// The Box
- {
- "thebox",
- "",
- AD_ENTRY1s("data.dcp", "ec5f0c7e8174e307701447b53afe7e2f", 108372483),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("thebox", "",
+ WME_ENTRY1s("data.dcp", "ec5f0c7e8174e307701447b53afe7e2f", 108372483), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// The Kite (Version 1.1)
- {
- "thekite",
- "Version 1.1",
- AD_ENTRY1s("data.dcp", "92d29428f464469bda2d81b03d4d5c3e", 47332296),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("thekite", "Version 1.1",
+ WME_ENTRY1s("data.dcp", "92d29428f464469bda2d81b03d4d5c3e", 47332296), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// The Kite (Version 1.2.e)
- {
- "thekite",
- "Version 1.2.e",
- AD_ENTRY1s("data.dcp", "92451578b1bdd2b32a1db592a4f6d5fc", 47360539),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("thekite", "Version 1.2.e",
+ WME_ENTRY1s("data.dcp", "92451578b1bdd2b32a1db592a4f6d5fc", 47360539), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// The Kite (Version 1.2.i) (Italian)
- {
- "thekite",
- "Version 1.2.i",
- AD_ENTRY1s("data.dcp", "d3435b106a1b3b4c1df8ad596d271586", 47509274),
- Common::IT_ITA,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("thekite", "Version 1.2.i",
+ WME_ENTRY1s("data.dcp", "d3435b106a1b3b4c1df8ad596d271586", 47509274), Common::IT_ITA, ADGF_UNSTABLE, LATEST_VERSION),
// The Kite (Version 1.2.r) (Russian)
- {
- "thekite",
- "Version 1.2.r",
- AD_ENTRY1s("data.dcp", "d531e097dd884737469da014ed882cde", 47554582 ),
- Common::RU_RUS,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("thekite", "Version 1.2.r",
+ WME_ENTRY1s("data.dcp", "d531e097dd884737469da014ed882cde", 47554582 ), Common::RU_RUS, ADGF_UNSTABLE, LATEST_VERSION),
// The Kite (Version 1.3.e)
- {
- "thekite",
- "Version 1.3.e",
- AD_ENTRY1s("data.dcp", "9761827b51370263b7623721545d7627", 47382987),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("thekite", "Version 1.3.e",
+ WME_ENTRY1s("data.dcp", "9761827b51370263b7623721545d7627", 47382987), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Fairy Tales About Toshechka and Boshechka
- {
- "tib",
- "",
- AD_ENTRY1s("data.dcp", "87d296ef3f46570ed18f000d3885db77", 340264526),
- Common::RU_RUS,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("tib", "",
+ WME_ENTRY1s("data.dcp", "87d296ef3f46570ed18f000d3885db77", 340264526), Common::RU_RUS, ADGF_UNSTABLE, LATEST_VERSION),
// The Trader of Stories
- {
- "tradestory",
- "Demo",
- AD_ENTRY1s("data.dcp", "0a0b51191636cc8ead89b905281c3218", 40401902),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE |
- ADGF_DEMO,
- GUIO0()
- },
+ WME_WINENTRY("tradestory", "Demo",
+ WME_ENTRY1s("data.dcp", "0a0b51191636cc8ead89b905281c3218", 40401902), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION),
// the white chamber (multi-language)
- {
- "twc",
- "",
- AD_ENTRY1s("data.dcp", "0011d01142547c61e51ba24dc42b579e", 186451273),
- Common::UNK_LANG,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("twc", "",
+ WME_ENTRY1s("data.dcp", "0011d01142547c61e51ba24dc42b579e", 186451273), Common::UNK_LANG, ADGF_UNSTABLE, LATEST_VERSION),
// Vsevolod Prologue (Demo)
- {
- "vsevolod",
- "Prologue",
- AD_ENTRY1s("data.dcp", "f2dcffd2692dbfcc9371fa1a87970fe7", 388669493),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE |
- ADGF_DEMO,
- GUIO0()
- },
+ WME_WINENTRY("vsevolod", "Prologue",
+ WME_ENTRY1s("data.dcp", "f2dcffd2692dbfcc9371fa1a87970fe7", 388669493), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION),
// War
- {
- "war",
- "",
- AD_ENTRY1s("data.dcp", "003e317cda6d0137bbd5e5d7f089ee4d", 32591890),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("war", "",
+ WME_ENTRY1s("data.dcp", "003e317cda6d0137bbd5e5d7f089ee4d", 32591890), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Wilma Tetris
- {
- "wtetris",
- "",
- AD_ENTRY1s("data.dcp", "946e3a0496e6c12fb344c9ed861ff015", 2780093),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
+ WME_WINENTRY("wtetris", "",
+ WME_ENTRY1s("data.dcp", "946e3a0496e6c12fb344c9ed861ff015", 2780093), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
// Zilm: A Game of Reflex 1.0
+ WME_WINENTRY("Zilm", "1.0",
+ WME_ENTRY1s("data.dcp", "098dffaf03d8adbb4cb5633e4733e63c", 351726), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION),
{
- "Zilm",
- "1.0",
- AD_ENTRY1s("data.dcp", "098dffaf03d8adbb4cb5633e4733e63c", 351726),
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_UNSTABLE,
- GUIO0()
- },
- AD_TABLE_END_MARKER
+ AD_TABLE_END_MARKER,
+ LATEST_VERSION
+ }
};
} // End of namespace Wintermute
+#undef WEM_ENTRY1s
+#undef WEM_ENTRY2s
+#undef WEM_ENTRY3s
+#undef WME_WINENTRY
+#undef WME_PLATENTRY
+
diff --git a/engines/wintermute/game_description.h b/engines/wintermute/game_description.h
new file mode 100644
index 0000000000..313fff8bbf
--- /dev/null
+++ b/engines/wintermute/game_description.h
@@ -0,0 +1,53 @@
+/* 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 WINTERMUTE_GAME_DESCRIPTION_H
+#define WINTERMUTE_GAME_DESCRIPTION_H
+
+#include "engines/advancedDetector.h"
+
+namespace Wintermute {
+
+enum WMETargetExecutable {
+ OLDEST_VERSION,
+ WME_1_0_0,
+ WME_1_1_0,
+ WME_1_2_0,
+ WME_1_3_0,
+ WME_1_4_0,
+ WME_1_5_0,
+ WME_1_6_0,
+ WME_1_7_0,
+ WME_1_8_0,
+ WME_1_8_6,
+ WME_1_9_0,
+ LATEST_VERSION
+};
+
+struct WMEGameDescription {
+ ADGameDescription adDesc;
+ WMETargetExecutable targetExecutable;
+};
+
+}
+
+#endif /* WINTERMUTE_GAME_DESCRIPTION_H_ */
diff --git a/engines/wintermute/math/rect32.h b/engines/wintermute/math/rect32.h
index 93b5c68a30..00326d6747 100644
--- a/engines/wintermute/math/rect32.h
+++ b/engines/wintermute/math/rect32.h
@@ -50,7 +50,7 @@ struct Point32 {
y -= delta.y;
return *this;
}
-
+
operator FloatPoint() {
return FloatPoint(x,y);
}
diff --git a/engines/wintermute/module.mk b/engines/wintermute/module.mk
index 1b6c52e0b7..4c95314a02 100644
--- a/engines/wintermute/module.mk
+++ b/engines/wintermute/module.mk
@@ -108,7 +108,9 @@ MODULE_OBJS := \
utils/path_util.o \
utils/string_util.o \
utils/utils.o \
+ video/subtitle_card.o \
video/video_player.o \
+ video/video_subtitler.o \
video/video_theora_player.o \
debugger.o \
wintermute.o \
diff --git a/engines/wintermute/video/subtitle_card.cpp b/engines/wintermute/video/subtitle_card.cpp
new file mode 100644
index 0000000000..5d882502fd
--- /dev/null
+++ b/engines/wintermute/video/subtitle_card.cpp
@@ -0,0 +1,56 @@
+/* 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 file is based on Wintermute Engine
+ * http://dead-code.org/redir.php?target=wme
+ * Copyright (c) 2011 Jan Nedoma
+ */
+
+#include "engines/wintermute/video/subtitle_card.h"
+#include "engines/wintermute/base/base_game.h"
+
+namespace Wintermute {
+
+SubtitleCard::SubtitleCard(BaseGame *inGame,
+ const Common::String &text,
+ const uint &startFrame,
+ const uint &endFrame) : _gameRef(inGame),
+ _startFrame(startFrame),
+ _endFrame(endFrame) {
+ _text = text;
+ _gameRef->expandStringByStringTable(_text);
+}
+
+uint32 SubtitleCard::getStartFrame() const {
+ return _startFrame;
+}
+
+uint32 SubtitleCard::getEndFrame() const {
+ return _endFrame;
+}
+
+Common::String SubtitleCard::getText() const {
+ return _text;
+}
+
+} // End of namespace Wintermute
diff --git a/engines/wintermute/video/subtitle_card.h b/engines/wintermute/video/subtitle_card.h
new file mode 100644
index 0000000000..629df77287
--- /dev/null
+++ b/engines/wintermute/video/subtitle_card.h
@@ -0,0 +1,53 @@
+/* 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 file is based on Wintermute Engine
+ * http://dead-code.org/redir.php?target=wme
+ * Copyright (c) 2011 Jan Nedoma
+ */
+
+#ifndef WINTERMUTE_SUBTITLECARD_H
+#define WINTERMUTE_SUBTITLECARD_H
+
+#include "common/str.h"
+
+namespace Wintermute {
+
+class BaseGame;
+
+class SubtitleCard {
+public:
+ SubtitleCard(BaseGame *inGame, const Common::String &text, const uint &startFrame, const uint &endFrame);
+ uint32 getEndFrame() const;
+ uint32 getStartFrame() const;
+ Common::String getText() const;
+private:
+ BaseGame *_gameRef;
+ uint32 _endFrame;
+ uint32 _startFrame;
+ Common::String _text;
+};
+
+} // End of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/video/video_subtitler.cpp b/engines/wintermute/video/video_subtitler.cpp
new file mode 100644
index 0000000000..95d938574b
--- /dev/null
+++ b/engines/wintermute/video/video_subtitler.cpp
@@ -0,0 +1,266 @@
+/* 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 file is based on Wintermute Engine
+ * http://dead-code.org/redir.php?target=wme
+ * Copyright (c) 2011 Jan Nedoma
+ */
+
+#include "engines/wintermute/video/video_subtitler.h"
+#include "engines/wintermute/base/base_file_manager.h"
+#include "engines/wintermute/utils/path_util.h"
+#include "engines/wintermute/base/font/base_font.h"
+#include "engines/wintermute/base/base_game.h"
+#include "engines/wintermute/base/gfx/base_renderer.h"
+
+namespace Wintermute {
+
+VideoSubtitler::VideoSubtitler(BaseGame *inGame): BaseClass(inGame) {
+ _lastSample = -1;
+ _currentSubtitle = 0;
+ _showSubtitle = false;
+}
+
+VideoSubtitler::~VideoSubtitler(void) {
+ _subtitles.clear();
+}
+
+bool VideoSubtitler::loadSubtitles(const Common::String &filename, const Common::String &subtitleFile) {
+ if (filename.size() == 0) {
+ return false;
+ }
+
+ _subtitles.clear();
+
+ _lastSample = -1;
+ _currentSubtitle = 0;
+ _showSubtitle = false;
+
+ Common::String newFile;
+
+ /*
+ * Okay, the expected behaviour is this: either we are
+ * provided with a subtitle file to use by the script when
+ * calling PlayTheora(), or we try to autodetect a suitable
+ * one which, for /some/path/movie/ogg is to be called
+ * /some/path/movie.sub
+ */
+ if (subtitleFile.size() != 0) {
+ newFile = subtitleFile;
+ } else {
+ Common::String path = PathUtil::getDirectoryName(filename);
+ Common::String name = PathUtil::getFileNameWithoutExtension(filename);
+ Common::String ext = ".SUB";
+ newFile = PathUtil::combine(path, name + ext);
+ }
+
+ Common::SeekableReadStream *file = BaseFileManager::getEngineInstance()->openFile(newFile, true, false);
+
+ if (file == nullptr) {
+ return false; // no subtitles
+ }
+
+ int fileSize = file->size();
+ char *buffer = new char[fileSize];
+
+ file->read(buffer, fileSize);
+
+ /* This is where we parse .sub files.
+ * Subtitles cards are in the form
+ * {StartFrame}{EndFrame} FirstLine | SecondLine \n
+ */
+ int pos = 0;
+
+ while (pos < fileSize) {
+ char *tokenStart = 0;
+ int tokenLength = 0;
+ int tokenPos = -1;
+ int lineLength = 0;
+ int start = -1;
+ int end = -1;
+ bool inToken = false;
+
+ while (pos + lineLength < fileSize &&
+ buffer[pos + lineLength] != '\n' &&
+ buffer[pos + lineLength] != '\0') {
+ // Measure the line until we hit EOL, EOS or just hit the boundary
+ lineLength++;
+ }
+
+ int realLength;
+
+ if (pos + lineLength >= fileSize) {
+ realLength = lineLength - 0;
+ } else {
+ // If we got here the above loop exited after hitting "\0" "\n"
+ realLength = lineLength - 1;
+ }
+
+ Common::String cardText;
+ char *fileLine = (char *)&buffer[pos];
+
+ for (int i = 0; i < realLength; i++) {
+ if (fileLine[i] == '{') {
+ if (!inToken) {
+ // We've hit the start of a Start/EndFrame token
+ inToken = true;
+ tokenStart = fileLine + i + 1;
+ tokenLength = 0;
+ tokenPos++;
+ } else {
+ // Actually, we were already inside an (invalid) one.
+ tokenLength++;
+ }
+ } else if (fileLine[i] == '}') {
+ if (inToken) {
+ // we were /inside/ a {.*} token, so this is the end of the block
+ inToken = false;
+ char *token = new char[tokenLength + 1];
+ strncpy(token, tokenStart, tokenLength);
+ token[tokenLength] = '\0';
+ if (tokenPos == 0) {
+ // Was this StartFrame...
+ start = atoi(token);
+ } else if (tokenPos == 1) {
+ // Or the EndFrame?
+ end = atoi(token);
+ }
+ delete[] token;
+ } else {
+ // This char is part of the plain text, just append it
+ cardText += fileLine[i];
+ }
+ } else {
+ if (inToken) {
+ tokenLength++;
+ } else {
+ if (fileLine[i] == '|') {
+ // The pipe character signals a linebreak in the text
+ cardText += '\n';
+ } else {
+ // This char is part of the plain text, just append it
+ cardText += fileLine[i];
+ }
+ }
+ }
+ }
+
+ if (start != -1 && cardText.size() > 0 && (start != 1 || end != 1)){
+ // Add a subtitlecard based on the line we have just parsed
+ _subtitles.push_back(SubtitleCard(_gameRef, cardText, start, end));
+ }
+
+ pos += lineLength + 1;
+ }
+
+ delete[] buffer;
+ // Succeeded loading subtitles!
+
+ return true;
+}
+
+void VideoSubtitler::display() {
+ if (_showSubtitle) {
+
+ BaseFont *font;
+
+ if (_gameRef->getVideoFont() == nullptr) {
+ font = _gameRef->getSystemFont();
+ } else {
+ font = _gameRef->getVideoFont();
+ }
+
+ int textHeight = font->getTextHeight(
+ (const byte *)_subtitles[_currentSubtitle].getText().c_str(),
+ _gameRef->_renderer->getWidth());
+
+ font->drawText(
+ (const byte *)_subtitles[_currentSubtitle].getText().c_str(),
+ 0,
+ (_gameRef->_renderer->getHeight() - textHeight - 5),
+ (_gameRef->_renderer->getWidth()),
+ TAL_CENTER);
+ }
+}
+
+void VideoSubtitler::update(uint32 frame) {
+ if (_subtitles.size() == 0) {
+ // Edge case: we have loaded subtitles early on... from a blank file.
+ return;
+ }
+
+ if ((int32)frame != _lastSample) {
+ /*
+ * If the frame count hasn't advanced the previous state still matches
+ * the current frame (obviously).
+ */
+
+ _lastSample = frame;
+ // Otherwise, we update _lastSample; see above.
+
+ _showSubtitle = false;
+
+ bool overdue = (frame > _subtitles[_currentSubtitle].getEndFrame());
+ bool hasNext = (_currentSubtitle + 1 < _subtitles.size());
+ bool nextStarted = false;
+ if (hasNext) {
+ nextStarted = (_subtitles[_currentSubtitle + 1].getStartFrame() <= frame);
+ }
+
+ while (_currentSubtitle < _subtitles.size() &&
+ overdue && hasNext && nextStarted) {
+ /*
+ * We advance until we get past all overdue subtitles.
+ * We should exit the cycle when we either reach the first
+ * subtitle which is not overdue whose subsequent subtitle
+ * has not started yet (aka the one we must display now or
+ * the one which WILL be displayed when its time comes)
+ * and / or when we reach the last one.
+ */
+
+ _currentSubtitle++;
+
+ overdue = (frame > _subtitles[_currentSubtitle].getEndFrame());
+ hasNext = (_currentSubtitle + 1 < _subtitles.size());
+ if (hasNext) {
+ nextStarted = (_subtitles[_currentSubtitle + 1].getStartFrame() <= frame);
+ } else {
+ nextStarted = false;
+ }
+ }
+
+ bool currentValid = (_subtitles[_currentSubtitle].getEndFrame() != 0);
+ /*
+ * No idea why we do this check, carried over from Mnemonic's code.
+ * Possibly a workaround for buggy subtitles or some kind of sentinel? :-\
+ */
+
+ bool currentStarted = frame >= _subtitles[_currentSubtitle].getStartFrame();
+
+ if (currentStarted && !overdue && currentValid) {
+ _showSubtitle = true;
+ }
+ }
+}
+
+} // End of namespace Wintermute
diff --git a/engines/wintermute/video/video_subtitler.h b/engines/wintermute/video/video_subtitler.h
new file mode 100644
index 0000000000..94f22909a1
--- /dev/null
+++ b/engines/wintermute/video/video_subtitler.h
@@ -0,0 +1,53 @@
+/* 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 file is based on Wintermute Engine
+ * http://dead-code.org/redir.php?target=wme
+ * Copyright (c) 2011 Jan Nedoma
+ */
+
+#ifndef WINTERMUTE_VIDSUBTITLER_H
+#define WINTERMUTE_VIDSUBTITLER_H
+
+#include "engines/wintermute/base/base.h"
+#include "engines/wintermute/video/subtitle_card.h"
+
+namespace Wintermute {
+
+class VideoSubtitler : public BaseClass {
+public:
+ VideoSubtitler(BaseGame *inGame);
+ virtual ~VideoSubtitler(void);
+ bool loadSubtitles(const Common::String &filename, const Common::String &subtitleFile);
+ void display();
+ void update(uint32 frame);
+private:
+ Common::Array<SubtitleCard> _subtitles;
+ int32 _lastSample;
+ bool _showSubtitle;
+ uint32 _currentSubtitle;
+};
+
+} // End of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/video/video_theora_player.cpp b/engines/wintermute/video/video_theora_player.cpp
index e1553580ec..22c235c848 100644
--- a/engines/wintermute/video/video_theora_player.cpp
+++ b/engines/wintermute/video/video_theora_player.cpp
@@ -85,14 +85,14 @@ void VideoTheoraPlayer::SetDefaults() {
_volume = 100;
_theoraDecoder = nullptr;
- // TODO: Add subtitles-support
- //_subtitler = nullptr;
+ _subtitler = new VideoSubtitler(_gameRef);
+ _foundSubtitles = false;
}
//////////////////////////////////////////////////////////////////////////
VideoTheoraPlayer::~VideoTheoraPlayer(void) {
cleanup();
-// SAFE_DELETE(_subtitler);
+ delete _subtitler;
}
//////////////////////////////////////////////////////////////////////////
@@ -130,6 +130,9 @@ bool VideoTheoraPlayer::initialize(const Common::String &filename, const Common:
warning("VideoTheoraPlayer::initialize - Theora support not compiled in, video will be skipped: %s", filename.c_str());
return STATUS_FAILED;
#endif
+
+ _foundSubtitles = _subtitler->loadSubtitles(_filename, subtitleFile);
+
_theoraDecoder->loadStream(_file);
if (!_theoraDecoder->isVideoLoaded()) {
@@ -214,7 +217,10 @@ bool VideoTheoraPlayer::play(TVideoPlayback type, int x, int y, bool freezeGame,
_state = THEORA_STATE_PLAYING;
_looping = looping;
_playbackType = type;
-
+ if (_subtitler && _foundSubtitles && _gameRef->_subtitles) {
+ _subtitler->update(_theoraDecoder->getFrameCount());
+ _subtitler->display();
+ }
_startTime = startTime;
_volume = volume;
_posX = x;
@@ -256,7 +262,7 @@ bool VideoTheoraPlayer::play(TVideoPlayback type, int x, int y, bool freezeGame,
#if 0 // Stubbed for now as theora isn't seekable
if (StartTime) SeekToTime(StartTime);
- Update();
+ update();
#endif
return STATUS_FAILED;
}
@@ -289,6 +295,10 @@ bool VideoTheoraPlayer::update() {
}
if (_theoraDecoder) {
+ if (_subtitler && _foundSubtitles && _gameRef->_subtitles) {
+ _subtitler->update(_theoraDecoder->getCurFrame());
+ }
+
if (_theoraDecoder->endOfVideo() && _looping) {
warning("Should loop movie %s, hacked for now", _filename.c_str());
_theoraDecoder->rewind();
@@ -412,11 +422,10 @@ bool VideoTheoraPlayer::display(uint32 alpha) {
} else {
res = STATUS_FAILED;
}
- // TODO: Add subtitles-support
-/* if (m_Subtitler && _gameRef->m_VideoSubtitles) {
- m_Subtitler->display();
- }*/
+ if (_subtitler && _foundSubtitles && _gameRef->_subtitles) {
+ _subtitler->display();
+ }
return res;
}
diff --git a/engines/wintermute/video/video_theora_player.h b/engines/wintermute/video/video_theora_player.h
index 8274a1444f..0b9b3d487a 100644
--- a/engines/wintermute/video/video_theora_player.h
+++ b/engines/wintermute/video/video_theora_player.h
@@ -31,6 +31,7 @@
#include "engines/wintermute/base/base.h"
#include "engines/wintermute/persistent.h"
+#include "engines/wintermute/video/video_subtitler.h"
#include "video/video_decoder.h"
#include "common/stream.h"
#include "graphics/surface.h"
@@ -59,7 +60,7 @@ public:
Common::String _filename;
BaseSurface *_texture;
- //CVidSubtitler *_subtitler;
+ VideoSubtitler *_subtitler;
// control methods
bool initialize(const Common::String &filename, const Common::String &subtitleFile = Common::String());
@@ -137,9 +138,10 @@ private:
bool _playbackStarted;
+ bool _foundSubtitles;
+
// helpers
void SetDefaults();
-
};
} // End of namespace Wintermute
diff --git a/engines/wintermute/wintermute.cpp b/engines/wintermute/wintermute.cpp
index 81b6e53c9f..e35bb60c3d 100644
--- a/engines/wintermute/wintermute.cpp
+++ b/engines/wintermute/wintermute.cpp
@@ -53,7 +53,7 @@ WintermuteEngine::WintermuteEngine() : Engine(g_system) {
_gameDescription = nullptr;
}
-WintermuteEngine::WintermuteEngine(OSystem *syst, const ADGameDescription *desc)
+WintermuteEngine::WintermuteEngine(OSystem *syst, const WMEGameDescription *desc)
: Engine(syst), _gameDescription(desc) {
// Put your engine in a sane state, but do nothing big yet;
// in particular, do not load data from files; rather, if you
@@ -133,7 +133,7 @@ Common::Error WintermuteEngine::run() {
}
int WintermuteEngine::init() {
- BaseEngine::createInstance(_targetName, _gameDescription->gameid, _gameDescription->language);
+ BaseEngine::createInstance(_targetName, _gameDescription->adDesc.gameid, _gameDescription->adDesc.language, _gameDescription->targetExecutable);
_game = new AdGame(_targetName);
if (!_game) {
return 1;
diff --git a/engines/wintermute/wintermute.h b/engines/wintermute/wintermute.h
index 017809d56a..f8f5fc7deb 100644
--- a/engines/wintermute/wintermute.h
+++ b/engines/wintermute/wintermute.h
@@ -26,6 +26,7 @@
#include "engines/engine.h"
#include "engines/advancedDetector.h"
#include "gui/debugger.h"
+#include "engines/wintermute/game_description.h"
namespace Wintermute {
@@ -44,7 +45,7 @@ enum {
class WintermuteEngine : public Engine {
public:
- WintermuteEngine(OSystem *syst, const ADGameDescription *desc);
+ WintermuteEngine(OSystem *syst, const WMEGameDescription *desc);
WintermuteEngine();
~WintermuteEngine();
@@ -67,7 +68,7 @@ private:
int messageLoop();
GUI::Debugger *_debugger;
BaseGame *_game;
- const ADGameDescription *_gameDescription;
+ const WMEGameDescription *_gameDescription;
friend class Console;
};
diff --git a/engines/zvision/animation/rlf_animation.cpp b/engines/zvision/animation/rlf_animation.cpp
deleted file mode 100644
index 945461e7b2..0000000000
--- a/engines/zvision/animation/rlf_animation.cpp
+++ /dev/null
@@ -1,331 +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 "zvision/animation/rlf_animation.h"
-
-#include "common/str.h"
-#include "common/file.h"
-#include "common/textconsole.h"
-#include "common/debug.h"
-#include "common/endian.h"
-
-#include "graphics/colormasks.h"
-
-
-namespace ZVision {
-
-RlfAnimation::RlfAnimation(const Common::String &fileName, bool stream)
- : _stream(stream),
- _lastFrameRead(0),
- _frameCount(0),
- _width(0),
- _height(0),
- _frameTime(0),
- _frames(0),
- _currentFrame(-1),
- _frameBufferByteSize(0) {
- if (!_file.open(fileName)) {
- warning("RLF animation file %s could not be opened", fileName.c_str());
- return;
- }
-
- if (!readHeader()) {
- warning("%s is not a RLF animation file. Wrong magic number", fileName.c_str());
- return;
- }
-
- _currentFrameBuffer.create(_width, _height, Graphics::createPixelFormat<565>());
- _frameBufferByteSize = _width * _height * sizeof(uint16);
-
- if (!stream) {
- _frames = new Frame[_frameCount];
-
- // Read in each frame
- for (uint i = 0; i < _frameCount; ++i) {
- _frames[i] = readNextFrame();
- }
- }
-}
-
-RlfAnimation::~RlfAnimation() {
- for (uint i = 0; i < _frameCount; ++i) {
- delete[] _frames[i].encodedData;
- }
- delete[] _frames;
- _currentFrameBuffer.free();
-}
-
-bool RlfAnimation::readHeader() {
- if (_file.readUint32BE() != MKTAG('F', 'E', 'L', 'R')) {
- return false;
- }
-
- // Read the header
- _file.readUint32LE(); // Size1
- _file.readUint32LE(); // Unknown1
- _file.readUint32LE(); // Unknown2
- _frameCount = _file.readUint32LE(); // Frame count
-
- // Since we don't need any of the data, we can just seek right to the
- // entries we need rather than read in all the individual entries.
- _file.seek(136, SEEK_CUR);
-
- //// Read CIN header
- //_file.readUint32BE(); // Magic number FNIC
- //_file.readUint32LE(); // Size2
- //_file.readUint32LE(); // Unknown3
- //_file.readUint32LE(); // Unknown4
- //_file.readUint32LE(); // Unknown5
- //_file.seek(0x18, SEEK_CUR); // VRLE
- //_file.readUint32LE(); // LRVD
- //_file.readUint32LE(); // Unknown6
- //_file.seek(0x18, SEEK_CUR); // HRLE
- //_file.readUint32LE(); // ELHD
- //_file.readUint32LE(); // Unknown7
- //_file.seek(0x18, SEEK_CUR); // HKEY
- //_file.readUint32LE(); // ELRH
-
- //// Read MIN info header
- //_file.readUint32BE(); // Magic number FNIM
- //_file.readUint32LE(); // Size3
- //_file.readUint32LE(); // OEDV
- //_file.readUint32LE(); // Unknown8
- //_file.readUint32LE(); // Unknown9
- //_file.readUint32LE(); // Unknown10
- _width = _file.readUint32LE(); // Width
- _height = _file.readUint32LE(); // Height
-
- // Read time header
- _file.readUint32BE(); // Magic number EMIT
- _file.readUint32LE(); // Size4
- _file.readUint32LE(); // Unknown11
- _frameTime = _file.readUint32LE() / 10; // Frame time in microseconds
-
- return true;
-}
-
-RlfAnimation::Frame RlfAnimation::readNextFrame() {
- RlfAnimation::Frame frame;
-
- _file.readUint32BE(); // Magic number MARF
- uint32 size = _file.readUint32LE(); // Size
- _file.readUint32LE(); // Unknown1
- _file.readUint32LE(); // Unknown2
- uint32 type = _file.readUint32BE(); // Either ELHD or ELRH
- uint32 headerSize = _file.readUint32LE(); // Offset from the beginning of this frame to the frame data. Should always be 28
- _file.readUint32LE(); // Unknown3
-
- frame.encodedSize = size - headerSize;
- frame.encodedData = new int8[frame.encodedSize];
- _file.read(frame.encodedData, frame.encodedSize);
-
- if (type == MKTAG('E', 'L', 'H', 'D')) {
- frame.type = Masked;
- } else if (type == MKTAG('E', 'L', 'R', 'H')) {
- frame.type = Simple;
- _completeFrames.push_back(_lastFrameRead);
- } else {
- warning("Frame %u doesn't have type that can be decoded", _lastFrameRead);
- }
-
- _lastFrameRead++;
- return frame;
-}
-
-void RlfAnimation::seekToFrame(int frameNumber) {
- assert(!_stream);
- assert(frameNumber < (int)_frameCount || frameNumber >= -1);
-
- if (frameNumber == -1) {
- _currentFrame = -1;
- return;
- }
-
- int closestFrame = _currentFrame;
- int distance = (int)frameNumber - _currentFrame;
- for (uint i = 0; i < _completeFrames.size(); ++i) {
- int newDistance = (int)frameNumber - (int)(_completeFrames[i]);
- if (newDistance > 0 && (closestFrame == -1 || newDistance < distance)) {
- closestFrame = _completeFrames[i];
- distance = newDistance;
- }
- }
-
- for (int i = closestFrame; i <= frameNumber; ++i) {
- applyFrameToCurrent(i);
- }
-
- _currentFrame = frameNumber;
-}
-
-const Graphics::Surface *RlfAnimation::getFrameData(uint frameNumber) {
- assert(!_stream);
- assert(frameNumber < _frameCount);
-
- // Since this method is so expensive, first check to see if we can use
- // getNextFrame() it's cheap.
- if ((int)frameNumber == _currentFrame) {
- return &_currentFrameBuffer;
- } else if (_currentFrame + 1 == (int)frameNumber) {
- return getNextFrame();
- }
-
- seekToFrame(frameNumber);
- return &_currentFrameBuffer;
-}
-
-const Graphics::Surface *RlfAnimation::getNextFrame() {
- assert(_currentFrame + 1 < (int)_frameCount);
-
- if (_stream) {
- applyFrameToCurrent(readNextFrame());
- } else {
- applyFrameToCurrent(_currentFrame + 1);
- }
-
- _currentFrame++;
- return &_currentFrameBuffer;
-}
-
-void RlfAnimation::applyFrameToCurrent(uint frameNumber) {
- if (_frames[frameNumber].type == Masked) {
- decodeMaskedRunLengthEncoding(_frames[frameNumber].encodedData, (int8 *)_currentFrameBuffer.getPixels(), _frames[frameNumber].encodedSize, _frameBufferByteSize);
- } else if (_frames[frameNumber].type == Simple) {
- decodeSimpleRunLengthEncoding(_frames[frameNumber].encodedData, (int8 *)_currentFrameBuffer.getPixels(), _frames[frameNumber].encodedSize, _frameBufferByteSize);
- }
-}
-
-void RlfAnimation::applyFrameToCurrent(const RlfAnimation::Frame &frame) {
- if (frame.type == Masked) {
- decodeMaskedRunLengthEncoding(frame.encodedData, (int8 *)_currentFrameBuffer.getPixels(), frame.encodedSize, _frameBufferByteSize);
- } else if (frame.type == Simple) {
- decodeSimpleRunLengthEncoding(frame.encodedData, (int8 *)_currentFrameBuffer.getPixels(), frame.encodedSize, _frameBufferByteSize);
- }
-}
-
-void RlfAnimation::decodeMaskedRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const {
- uint32 sourceOffset = 0;
- uint32 destOffset = 0;
-
- while (sourceOffset < sourceSize) {
- int8 numberOfSamples = source[sourceOffset];
- sourceOffset++;
-
- // If numberOfSamples is negative, the next abs(numberOfSamples) samples should
- // be copied directly from source to dest
- if (numberOfSamples < 0) {
- numberOfSamples = ABS(numberOfSamples);
-
- while (numberOfSamples > 0) {
- if (sourceOffset + 1 >= sourceSize) {
- return;
- } else if (destOffset + 1 >= destSize) {
- debug(2, "Frame decoding overflow\n\tsourceOffset=%u\tsourceSize=%u\n\tdestOffset=%u\tdestSize=%u", sourceOffset, sourceSize, destOffset, destSize);
- 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);
-
- sourceOffset += 2;
- destOffset += 2;
- numberOfSamples--;
- }
-
- // If numberOfSamples is >= 0, move destOffset forward ((numberOfSamples * 2) + 2)
- // This function assumes the dest buffer has been memset with 0's.
- } else {
- if (sourceOffset + 1 >= sourceSize) {
- return;
- } else if (destOffset + 1 >= destSize) {
- debug(2, "Frame decoding overflow\n\tsourceOffset=%u\tsourceSize=%u\n\tdestOffset=%u\tdestSize=%u", sourceOffset, sourceSize, destOffset, destSize);
- return;
- }
-
- destOffset += (numberOfSamples * 2) + 2;
- }
- }
-}
-
-void RlfAnimation::decodeSimpleRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const {
- uint32 sourceOffset = 0;
- uint32 destOffset = 0;
-
- while (sourceOffset < sourceSize) {
- int8 numberOfSamples = source[sourceOffset];
- sourceOffset++;
-
- // If numberOfSamples is negative, the next abs(numberOfSamples) samples should
- // be copied directly from source to dest
- if (numberOfSamples < 0) {
- numberOfSamples = ABS(numberOfSamples);
-
- while (numberOfSamples > 0) {
- if (sourceOffset + 1 >= sourceSize) {
- return;
- } else if (destOffset + 1 >= destSize) {
- debug(2, "Frame decoding overflow\n\tsourceOffset=%u\tsourceSize=%u\n\tdestOffset=%u\tdestSize=%u", sourceOffset, sourceSize, destOffset, destSize);
- 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);
-
- sourceOffset += 2;
- destOffset += 2;
- numberOfSamples--;
- }
-
- // If numberOfSamples is >= 0, copy one sample from source to the
- // next (numberOfSamples + 2) dest spots
- } else {
- if (sourceOffset + 1 >= sourceSize) {
- 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);
- sourceOffset += 2;
-
- numberOfSamples += 2;
- while (numberOfSamples > 0) {
- if (destOffset + 1 >= destSize) {
- debug(2, "Frame decoding overflow\n\tsourceOffset=%u\tsourceSize=%u\n\tdestOffset=%u\tdestSize=%u", sourceOffset, sourceSize, destOffset, destSize);
- return;
- }
-
- WRITE_UINT16(dest + destOffset, sampleColor);
- destOffset += 2;
- numberOfSamples--;
- }
- }
- }
-}
-
-} // End of namespace ZVision
diff --git a/engines/zvision/animation/rlf_animation.h b/engines/zvision/animation/rlf_animation.h
deleted file mode 100644
index 4bb779301b..0000000000
--- a/engines/zvision/animation/rlf_animation.h
+++ /dev/null
@@ -1,163 +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.
- *
- */
-
-#ifndef ZVISION_RLF_ANIMATION_H
-#define ZVISION_RLF_ANIMATION_H
-
-#include "common/file.h"
-
-#include "graphics/surface.h"
-
-
-namespace Common {
-class String;
-}
-
-namespace ZVision {
-
-class RlfAnimation {
-public:
- RlfAnimation(const Common::String &fileName, bool stream = true);
- ~RlfAnimation();
-
-private:
- enum EncodingType {
- Masked,
- Simple
- };
-
- struct Frame {
- EncodingType type;
- int8 *encodedData;
- uint32 encodedSize;
- };
-
-private:
- Common::File _file;
- bool _stream;
- uint _lastFrameRead;
-
- uint _frameCount;
- uint _width;
- uint _height;
- uint32 _frameTime; // In milliseconds
- Frame *_frames;
- Common::Array<uint> _completeFrames;
-
- int _currentFrame;
- Graphics::Surface _currentFrameBuffer;
- uint32 _frameBufferByteSize;
-
-public:
- uint frameCount() { return _frameCount; }
- uint width() { return _width; }
- uint height() { return _height; }
- uint32 frameTime() { return _frameTime; }
-
- /**
- * Seeks to the frameNumber and updates the internal Surface with
- * the new frame data. If frameNumber == -1, it only sets _currentFrame,
- * the internal Surface is unchanged. This function requires _stream = false
- *
- * @param frameNumber The frame number to seek to
- */
- void seekToFrame(int frameNumber);
-
- /**
- * Returns the pixel data of the frame specified. It will try to use
- * getNextFrame() if possible. If not, it uses seekToFrame() to
- * update the internal Surface and then returns a pointer to it.
- * This function requires _stream = false
- *
- * @param frameNumber The frame number to get data for
- * @return A pointer to the pixel data. Do NOT delete this.
- */
- const Graphics::Surface *getFrameData(uint frameNumber);
- /**
- * Returns the pixel data of the next frame. It is up to the user to
- * check if the next frame is valid before calling this.
- * IE. Use endOfAnimation()
- *
- * @return A pointer to the pixel data. Do NOT delete this.
- */
- const Graphics::Surface *getNextFrame();
-
- /**
- * @return Is the currentFrame is the last frame in the animation?
- */
- bool endOfAnimation() { return _currentFrame == (int)_frameCount - 1; }
-
-private:
- /**
- * Reads in the header of the RLF file
- *
- * @return Will return false if the header magic number is wrong
- */
- bool readHeader();
- /**
- * Reads the next frame from the RLF file, stores the data in
- * a Frame object, then returns the object
- *
- * @return A Frame object representing the frame data
- */
- Frame readNextFrame();
-
- /**
- * Applies the frame corresponding to frameNumber on top of _currentFrameBuffer.
- * This function requires _stream = false so it can look up the Frame object
- * referenced by frameNumber.
- *
- * @param frameNumber The frame number to apply to _currentFrameBuffer
- */
- void applyFrameToCurrent(uint frameNumber);
- /**
- * Applies the data from a Frame object on top of a _currentFrameBuffer.
- *
- * @param frame A Frame object to apply to _currentFrameBuffer
- */
- void applyFrameToCurrent(const RlfAnimation::Frame &frame);
-
- /**
- * Decode frame data that uses masked run length encoding. This is the encoding
- * used by P-frames.
- *
- * @param source The source pixel data
- * @param dest The destination buffer
- * @param sourceSize The size of the source pixel data
- * @param destSize The size of the destination buffer
- */
- void decodeMaskedRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const;
- /**
- * Decode frame data that uses simple run length encoding. This is the encoding
- * used by I-frames.
- *
- * @param source The source pixel data
- * @param dest The destination buffer
- * @param sourceSize The size of the source pixel data
- * @param destSize The size of the destination buffer
- */
- void decodeSimpleRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const;
-};
-
-} // End of namespace ZVision
-
-#endif
diff --git a/engines/zvision/configure.engine b/engines/zvision/configure.engine
index 02e31943af..38a5959995 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 "ZVision" yes "" "" "freetype2 16bit"
diff --git a/engines/zvision/utility/clock.cpp b/engines/zvision/core/clock.cpp
index 45ab23ab65..1425d550b7 100644
--- a/engines/zvision/utility/clock.cpp
+++ b/engines/zvision/core/clock.cpp
@@ -22,11 +22,10 @@
#include "common/scummsys.h"
-#include "zvision/utility/clock.h"
+#include "zvision/core/clock.h"
#include "common/system.h"
-
namespace ZVision {
Clock::Clock(OSystem *system)
diff --git a/engines/zvision/utility/clock.h b/engines/zvision/core/clock.h
index 6ae0f86161..cbf52be560 100644
--- a/engines/zvision/utility/clock.h
+++ b/engines/zvision/core/clock.h
@@ -47,24 +47,31 @@ public:
* when the last update() was called.
*/
void update();
+
/**
* Get the delta time since the last frame. (The time between update() calls)
*
* @return Delta time since the last frame (in milliseconds)
*/
- uint32 getDeltaTime() const { return _deltaTime; }
+ uint32 getDeltaTime() const {
+ return _deltaTime;
+ }
+
/**
* Get the time from the program starting to the last update() call
*
* @return Time from program start to last update() call (in milliseconds)
*/
- uint32 getLastMeasuredTime() { return _lastTime; }
+ uint32 getLastMeasuredTime() {
+ return _lastTime;
+ }
/**
* Pause the clock. Any future delta times will take this pause into account.
* Has no effect if the clock is already paused.
*/
void start();
+
/**
* Un-pause the clock.
* Has no effect if the clock is already un-paused.
diff --git a/engines/zvision/core/console.cpp b/engines/zvision/core/console.cpp
index e610f34474..f5cacb582c 100644
--- a/engines/zvision/core/console.cpp
+++ b/engines/zvision/core/console.cpp
@@ -1,24 +1,24 @@
/* 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.
- *
- */
+*
+* 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"
@@ -27,11 +27,10 @@
#include "zvision/zvision.h"
#include "zvision/scripting/script_manager.h"
#include "zvision/graphics/render_manager.h"
-#include "zvision/strings/string_manager.h"
+#include "zvision/text/string_manager.h"
#include "zvision/video/zork_avi_decoder.h"
#include "zvision/sound/zork_raw.h"
-#include "zvision/utility/utility.h"
-#include "zvision/cursors/cursor.h"
+#include "zvision/graphics/cursors/cursor.h"
#include "common/system.h"
#include "common/file.h"
@@ -41,11 +40,9 @@
#include "audio/mixer.h"
-
namespace ZVision {
Console::Console(ZVision *engine) : GUI::Debugger(), _engine(engine) {
- registerCmd("loadimage", WRAP_METHOD(Console, cmdLoadImage));
registerCmd("loadvideo", WRAP_METHOD(Console, cmdLoadVideo));
registerCmd("loadsound", WRAP_METHOD(Console, cmdLoadSound));
registerCmd("raw2wav", WRAP_METHOD(Console, cmdRawToWav));
@@ -53,26 +50,17 @@ Console::Console(ZVision *engine) : GUI::Debugger(), _engine(engine) {
registerCmd("generaterendertable", WRAP_METHOD(Console, cmdGenerateRenderTable));
registerCmd("setpanoramafov", WRAP_METHOD(Console, cmdSetPanoramaFoV));
registerCmd("setpanoramascale", WRAP_METHOD(Console, cmdSetPanoramaScale));
- registerCmd("changelocation", WRAP_METHOD(Console, cmdChangeLocation));
+ registerCmd("location", WRAP_METHOD(Console, cmdLocation));
registerCmd("dumpfile", WRAP_METHOD(Console, cmdDumpFile));
- registerCmd("parseallscrfiles", WRAP_METHOD(Console, cmdParseAllScrFiles));
- registerCmd("rendertext", WRAP_METHOD(Console, cmdRenderText));
-}
-
-bool Console::cmdLoadImage(int argc, const char **argv) {
- if (argc == 4)
- _engine->getRenderManager()->renderImageToScreen(argv[1], atoi(argv[2]), atoi(argv[3]));
- else {
- debugPrintf("Use loadimage <fileName> <destinationX> <destinationY> to load an image to the screen\n");
- return true;
- }
-
- return true;
+ 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) {
if (argc != 2) {
- debugPrintf("Use loadvideo <fileName> to load a video to the screen\n");
+ debugPrintf("Use %s <fileName> to load a video to the screen\n", argv[0]);
return true;
}
@@ -94,18 +82,20 @@ 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;
_engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &handle, soundStream, -1, 100, 0, DisposeAfterUse::YES, false, false);
} else {
- debugPrintf("Use loadsound <fileName> [<rate> <isStereo: 1 or 0>] to load a sound\n");
+ debugPrintf("Use %s <fileName> [<rate> <isStereo: 1 or 0>] to load a sound\n", argv[0]);
return true;
}
@@ -114,17 +104,58 @@ bool Console::cmdLoadSound(int argc, const char **argv) {
bool Console::cmdRawToWav(int argc, const char **argv) {
if (argc != 3) {
- debugPrintf("Use raw2wav <rawFilePath> <wavFileName> to dump a .RAW file to .WAV\n");
+ debugPrintf("Use %s <rawFilePath> <wavFileName> to dump a .RAW file to .WAV\n", argv[0]);
return true;
}
- convertRawToWav(argv[1], _engine, argv[2]);
+ Common::File file;
+ if (!_engine->getSearchManager()->openFile(file, argv[1])) {
+ warning("File not found: %s", argv[1]);
+ return true;
+ }
+
+ Audio::AudioStream *audioStream = makeRawZorkStream(argv[1], _engine);
+
+ Common::DumpFile output;
+ output.open(argv[2]);
+
+ output.writeUint32BE(MKTAG('R', 'I', 'F', 'F'));
+ output.writeUint32LE(file.size() * 2 + 36);
+ output.writeUint32BE(MKTAG('W', 'A', 'V', 'E'));
+ output.writeUint32BE(MKTAG('f', 'm', 't', ' '));
+ output.writeUint32LE(16);
+ output.writeUint16LE(1);
+ uint16 numChannels;
+ if (audioStream->isStereo()) {
+ numChannels = 2;
+ output.writeUint16LE(2);
+ } else {
+ numChannels = 1;
+ output.writeUint16LE(1);
+ }
+ output.writeUint32LE(audioStream->getRate());
+ output.writeUint32LE(audioStream->getRate() * numChannels * 2);
+ output.writeUint16LE(numChannels * 2);
+ output.writeUint16LE(16);
+ output.writeUint32BE(MKTAG('d', 'a', 't', 'a'));
+ 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;
+
+
return true;
}
bool Console::cmdSetRenderState(int argc, const char **argv) {
if (argc != 2) {
- debugPrintf("Use setrenderstate <RenderState: panorama, tilt, flat> to change the current render state\n");
+ debugPrintf("Use %s <RenderState: panorama, tilt, flat> to change the current render state\n", argv[0]);
return true;
}
@@ -137,7 +168,7 @@ bool Console::cmdSetRenderState(int argc, const char **argv) {
else if (renderState.matchString("flat", true))
_engine->getRenderManager()->getRenderTable()->setRenderState(RenderTable::FLAT);
else
- debugPrintf("Use setrenderstate <RenderState: panorama, tilt, flat> to change the current render state\n");
+ debugPrintf("Use %s <RenderState: panorama, tilt, flat> to change the current render state\n", argv[0]);
return true;
}
@@ -150,7 +181,7 @@ bool Console::cmdGenerateRenderTable(int argc, const char **argv) {
bool Console::cmdSetPanoramaFoV(int argc, const char **argv) {
if (argc != 2) {
- debugPrintf("Use setpanoramafov <fieldOfView> to change the current panorama field of view\n");
+ debugPrintf("Use %s <fieldOfView> to change the current panorama field of view\n", argv[0]);
return true;
}
@@ -161,7 +192,7 @@ bool Console::cmdSetPanoramaFoV(int argc, const char **argv) {
bool Console::cmdSetPanoramaScale(int argc, const char **argv) {
if (argc != 2) {
- debugPrintf("Use setpanoramascale <scale> to change the current panorama scale\n");
+ debugPrintf("Use %s <scale> to change the current panorama scale\n", argv[0]);
return true;
}
@@ -170,9 +201,14 @@ bool Console::cmdSetPanoramaScale(int argc, const char **argv) {
return true;
}
-bool Console::cmdChangeLocation(int argc, const char **argv) {
+bool Console::cmdLocation(int argc, const char **argv) {
+ Location curLocation = _engine->getScriptManager()->getCurrentLocation();
+ 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 changelocation <char: world> <char: room> <char:node> <char:view> <int: x position> to change your location\n");
+ debugPrintf("Use %s <char: world> <char: room> <char:node> <char:view> <int: x offset> to change your location\n", argv[0]);
return true;
}
@@ -181,36 +217,152 @@ bool Console::cmdChangeLocation(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 dumpfile <fileName> to dump a file\n");
+ debugPrintf("Use %s <fileName> to dump a file\n", argv[0]);
return true;
}
- writeFileContentsToFile(argv[1], argv[1]);
+ Common::File f;
+ if (!_engine->getSearchManager()->openFile(f, argv[1])) {
+ warning("File not found: %s", argv[1]);
+ return true;
+ }
+
+ dumpFile(&f, argv[1]);
return true;
}
-bool Console::cmdParseAllScrFiles(int argc, const char **argv) {
- Common::ArchiveMemberList list;
- SearchMan.listMatchingMembers(list, "*.scr");
+bool Console::cmdDumpFiles(int argc, const char **argv) {
+ Common::String fileName;
+ Common::SeekableReadStream *in;
+
+ 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());
- for (Common::ArchiveMemberList::iterator iter = list.begin(); iter != list.end(); ++iter) {
- _engine->getScriptManager()->parseScrFile((*iter)->getName());
+ in = iter->_value.arch->createReadStreamForMember(iter->_value.name);
+ if (in)
+ dumpFile(in, fileName.c_str());
+ delete in;
}
return true;
}
-bool Console::cmdRenderText(int argc, const char **argv) {
- if (argc != 7) {
- debugPrintf("Use rendertext <text> <fontNumber> <destX> <destY> <maxWidth> <1 or 0: wrap> to render text\n");
+bool Console::cmdDumpImage(int argc, const char **argv) {
+ if (argc != 2) {
+ debugPrintf("Use %s <TGA/TGZ name> to dump a ZVision 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;
}
- StringManager::TextStyle style = _engine->getStringManager()->getTextStyle(atoi(argv[2]));
- _engine->getRenderManager()->renderTextToWorkingWindow(333, Common::String(argv[1]), style.font, atoi(argv[3]), atoi(argv[4]), style.color, atoi(argv[5]), -1, Graphics::kTextAlignLeft, atoi(argv[6]) == 0 ? false : 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 29523c57ee..ac834185a0 100644
--- a/engines/zvision/core/console.h
+++ b/engines/zvision/core/console.h
@@ -37,7 +37,6 @@ public:
private:
ZVision *_engine;
- bool cmdLoadImage(int argc, const char **argv);
bool cmdLoadVideo(int argc, const char **argv);
bool cmdLoadSound(int argc, const char **argv);
bool cmdRawToWav(int argc, const char **argv);
@@ -45,10 +44,12 @@ private:
bool cmdGenerateRenderTable(int argc, const char **argv);
bool cmdSetPanoramaFoV(int argc, const char **argv);
bool cmdSetPanoramaScale(int argc, const char **argv);
- bool cmdChangeLocation(int argc, const char **argv);
+ bool cmdLocation(int argc, const char **argv);
bool cmdDumpFile(int argc, const char **argv);
- bool cmdParseAllScrFiles(int argc, const char **argv);
- bool cmdRenderText(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 83d6c17dec..cc1c00b6d0 100644
--- a/engines/zvision/core/events.cpp
+++ b/engines/zvision/core/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.
@@ -25,10 +25,12 @@
#include "zvision/zvision.h"
#include "zvision/core/console.h"
-#include "zvision/cursors/cursor_manager.h"
+#include "zvision/graphics/cursors/cursor_manager.h"
#include "zvision/graphics/render_manager.h"
#include "zvision/scripting/script_manager.h"
-#include "zvision/animation/rlf_animation.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"
@@ -36,29 +38,190 @@
#include "engines/util.h"
-
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 (_menu->getEnable() & kMenubarSave)
+ _scriptManager->changeLocation('g', 'j', 's', 'e', 0);
+ break;
+ case Common::KEYCODE_r:
+ if (_menu->getEnable() & kMenubarRestore)
+ _scriptManager->changeLocation('g', 'j', 'r', 'e', 0);
+ break;
+ case Common::KEYCODE_p:
+ if (_menu->getEnable() & kMenubarSettings)
+ _scriptManager->changeLocation('g', 'j', 'p', 'e', 0);
+ break;
+ case Common::KEYCODE_q:
+ if (_menu->getEnable() & kMenubarExit)
+ ifQuit();
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+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
+ _renderManager->showDebugMsg(Common::String::format("IMNOTDEAF cheat or debug, not implemented"));
+ }
+
+ if (checkCode("3100OPB")) {
+ _renderManager->showDebugMsg(Common::String::format("Current location: %c%c%c%c",
+ _scriptManager->getStateValue(StateKey_World),
+ _scriptManager->getStateValue(StateKey_Room),
+ _scriptManager->getStateValue(StateKey_Node),
+ _scriptManager->getStateValue(StateKey_View)));
+ }
+
+ if (checkCode("KILLMENOW")) {
+ _scriptManager->changeLocation('g', 'j', 'd', 'e', 0);
+ _scriptManager->setStateValue(2201, 35);
+ }
+
+ if (checkCode("MIKESPANTS")) {
+ _scriptManager->changeLocation('g', 'j', 't', 'm', 0);
+ }
+
+ // There are 3 more cheats in script files:
+ // - "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);
+ _scriptManager->setStateValue(224, 1);
+ }
+
+ if (checkCode("77MASSAVE")) {
+ _renderManager->showDebugMsg(Common::String::format("Current location: %c%c%c%c",
+ _scriptManager->getStateValue(StateKey_World),
+ _scriptManager->getStateValue(StateKey_Room),
+ _scriptManager->getStateValue(StateKey_Node),
+ _scriptManager->getStateValue(StateKey_View)));
+ }
+
+ if (checkCode("IDKFA")) {
+ _scriptManager->changeLocation('t', 'w', '3', 'f', 0);
+ _scriptManager->setStateValue(249, 1);
+ }
+
+ if (checkCode("309NEWDORMA")) {
+ _scriptManager->changeLocation('g', 'j', 'g', 'j', 0);
+ }
+
+ if (checkCode("HELLOSAILOR")) {
+ Audio::AudioStream *soundStream;
+ if (loc == "vb10") {
+ soundStream = makeRawZorkStream("v000hpta.raw", this);
+ } else {
+ soundStream = makeRawZorkStream("v000hnta.raw", this);
+ }
+ Audio::SoundHandle handle;
+ _mixer->playStream(Audio::Mixer::kPlainSoundType, &handle, soundStream);
+ }
+ }
+
+ 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 (_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() {
while (_eventMan->pollEvent(_event)) {
switch (_event.type) {
case Common::EVENT_LBUTTONDOWN:
- onMouseDown(_event.mouse);
+ _cursorManager->cursorDown(true);
+ _scriptManager->setStateValue(StateKey_LMouse, 1);
+ _menu->onMouseDown(_event.mouse);
+ _scriptManager->addEvent(_event);
break;
case Common::EVENT_LBUTTONUP:
- onMouseUp(_event.mouse);
+ _cursorManager->cursorDown(false);
+ _scriptManager->setStateValue(StateKey_LMouse, 0);
+ _menu->onMouseUp(_event.mouse);
+ _scriptManager->addEvent(_event);
break;
case Common::EVENT_RBUTTONDOWN:
- // TODO: Inventory logic
+ _cursorManager->cursorDown(true);
+ _scriptManager->setStateValue(StateKey_RMouse, 1);
+
+ if (getGameId() == GID_NEMESIS)
+ _scriptManager->inventoryCycle();
+ break;
+
+ case Common::EVENT_RBUTTONUP:
+ _cursorManager->cursorDown(false);
+ _scriptManager->setStateValue(StateKey_RMouse, 0);
break;
case Common::EVENT_MOUSEMOVE:
onMouseMove(_event.mouse);
break;
- case Common::EVENT_KEYDOWN:
+ case Common::EVENT_KEYDOWN: {
switch (_event.kbd.keycode) {
case Common::KEYCODE_d:
if (_event.kbd.hasFlags(Common::KBD_CTRL)) {
@@ -67,18 +230,57 @@ void ZVision::processEvents() {
_console->onFrame();
}
break;
- case Common::KEYCODE_q:
- if (_event.kbd.hasFlags(Common::KBD_CTRL))
- quitGame();
+
+ case Common::KEYCODE_LEFT:
+ case Common::KEYCODE_RIGHT:
+ if (_renderManager->getRenderTable()->getRenderState() == RenderTable::PANORAMA)
+ _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)
+ _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;
}
- _scriptManager->onKeyDown(_event.kbd);
- break;
+ uint8 vkKey = getZvisionKey(_event.kbd.keycode);
+
+ _scriptManager->setStateValue(StateKey_KeyPress, vkKey);
+
+ _scriptManager->addEvent(_event);
+ shortKeys(_event);
+ cheatCodes(vkKey);
+ }
+ break;
case Common::EVENT_KEYUP:
- _scriptManager->onKeyUp(_event.kbd);
+ _scriptManager->addEvent(_event);
+ switch (_event.kbd.keycode) {
+ case Common::KEYCODE_LEFT:
+ case Common::KEYCODE_RIGHT:
+ if (_renderManager->getRenderTable()->getRenderState() == RenderTable::PANORAMA)
+ _keyboardVelocity = 0;
+ break;
+ case Common::KEYCODE_UP:
+ case Common::KEYCODE_DOWN:
+ if (_renderManager->getRenderTable()->getRenderState() == RenderTable::TILT)
+ _keyboardVelocity = 0;
+ break;
+ default:
+ break;
+ }
break;
default:
break;
@@ -86,24 +288,11 @@ void ZVision::processEvents() {
}
}
-void ZVision::onMouseDown(const Common::Point &pos) {
- _cursorManager->cursorDown(true);
-
- Common::Point imageCoord(_renderManager->screenSpaceToImageSpace(pos));
- _scriptManager->onMouseDown(pos, imageCoord);
-}
-
-void ZVision::onMouseUp(const Common::Point &pos) {
- _cursorManager->cursorDown(false);
-
- Common::Point imageCoord(_renderManager->screenSpaceToImageSpace(pos));
- _scriptManager->onMouseUp(pos, imageCoord);
-}
-
void ZVision::onMouseMove(const Common::Point &pos) {
+ _menu->onMouseMove(pos);
Common::Point imageCoord(_renderManager->screenSpaceToImageSpace(pos));
- bool cursorWasChanged = _scriptManager->onMouseMove(pos, imageCoord);
+ bool cursorWasChanged = false;
// Graph of the function governing rotation velocity:
//
@@ -135,52 +324,183 @@ void ZVision::onMouseMove(const Common::Point &pos) {
// |
// ^
- if (_workingWindow.contains(pos)) {
+ // 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) {
- // Linear function of distance to the left edge (y = -mx + b)
- // We use fixed point math to get better accuracy
- Common::Rational velocity = (Common::Rational(MAX_ROTATION_SPEED, ROTATION_SCREEN_EDGE_OFFSET) * (pos.x - _workingWindow.left)) - MAX_ROTATION_SPEED;
- _renderManager->setBackgroundVelocity(velocity.toInt());
- _cursorManager->setLeftCursor();
+ if (clippedPos.x >= _workingWindow.left && clippedPos.x < _workingWindow.left + ROTATION_SCREEN_EDGE_OFFSET) {
+
+ int16 mspeed = _scriptManager->getStateValue(StateKey_RotateSpeed) >> 4;
+ 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) {
- // Linear function of distance to the right edge (y = mx)
- // We use fixed point math to get better accuracy
- Common::Rational velocity = Common::Rational(MAX_ROTATION_SPEED, ROTATION_SCREEN_EDGE_OFFSET) * (pos.x - _workingWindow.right + ROTATION_SCREEN_EDGE_OFFSET);
- _renderManager->setBackgroundVelocity(velocity.toInt());
- _cursorManager->setRightCursor();
+ } 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 = 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;
} else {
- _renderManager->setBackgroundVelocity(0);
+ _mouseVelocity = 0;
}
} else if (renderState == RenderTable::TILT) {
- if (pos.y >= _workingWindow.top && pos.y < _workingWindow.top + ROTATION_SCREEN_EDGE_OFFSET) {
- // Linear function of distance to top edge
- // We use fixed point math to get better accuracy
- Common::Rational velocity = (Common::Rational(MAX_ROTATION_SPEED, ROTATION_SCREEN_EDGE_OFFSET) * (pos.y - _workingWindow.top)) - MAX_ROTATION_SPEED;
- _renderManager->setBackgroundVelocity(velocity.toInt());
- _cursorManager->setUpCursor();
+ if (clippedPos.y >= _workingWindow.top && clippedPos.y < _workingWindow.top + ROTATION_SCREEN_EDGE_OFFSET) {
+
+ int16 mspeed = _scriptManager->getStateValue(StateKey_RotateSpeed) >> 4;
+ 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) {
- // Linear function of distance to the bottom edge (y = mx)
- // We use fixed point math to get better accuracy
- Common::Rational velocity = Common::Rational(MAX_ROTATION_SPEED, ROTATION_SCREEN_EDGE_OFFSET) * (pos.y - _workingWindow.bottom + ROTATION_SCREEN_EDGE_OFFSET);
- _renderManager->setBackgroundVelocity(velocity.toInt());
- _cursorManager->setDownCursor();
+ } 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 = 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;
} else {
- _renderManager->setBackgroundVelocity(0);
+ _mouseVelocity = 0;
}
+ } else {
+ _mouseVelocity = 0;
}
} else {
- _renderManager->setBackgroundVelocity(0);
+ _mouseVelocity = 0;
}
if (!cursorWasChanged) {
- _cursorManager->revertToIdle();
+ _cursorManager->changeCursor(CursorIndex_Idle);
+ }
+}
+
+uint8 ZVision::getZvisionKey(Common::KeyCode scummKeyCode) {
+ if (scummKeyCode >= Common::KEYCODE_a && scummKeyCode <= Common::KEYCODE_z)
+ return 0x41 + scummKeyCode - Common::KEYCODE_a;
+ if (scummKeyCode >= Common::KEYCODE_0 && scummKeyCode <= Common::KEYCODE_9)
+ return 0x30 + scummKeyCode - Common::KEYCODE_0;
+ if (scummKeyCode >= Common::KEYCODE_F1 && scummKeyCode <= Common::KEYCODE_F15)
+ return 0x70 + scummKeyCode - Common::KEYCODE_F1;
+ if (scummKeyCode >= Common::KEYCODE_KP0 && scummKeyCode <= Common::KEYCODE_KP9)
+ return 0x60 + scummKeyCode - Common::KEYCODE_KP0;
+
+ switch (scummKeyCode) {
+ case Common::KEYCODE_BACKSPACE:
+ return 0x8;
+ case Common::KEYCODE_TAB:
+ return 0x9;
+ case Common::KEYCODE_CLEAR:
+ return 0xC;
+ case Common::KEYCODE_RETURN:
+ return 0xD;
+ case Common::KEYCODE_CAPSLOCK:
+ return 0x14;
+ case Common::KEYCODE_ESCAPE:
+ return 0x1B;
+ case Common::KEYCODE_SPACE:
+ return 0x20;
+ case Common::KEYCODE_PAGEUP:
+ return 0x21;
+ case Common::KEYCODE_PAGEDOWN:
+ return 0x22;
+ case Common::KEYCODE_END:
+ return 0x23;
+ case Common::KEYCODE_HOME:
+ return 0x24;
+ case Common::KEYCODE_LEFT:
+ return 0x25;
+ case Common::KEYCODE_UP:
+ return 0x26;
+ case Common::KEYCODE_RIGHT:
+ return 0x27;
+ case Common::KEYCODE_DOWN:
+ return 0x28;
+ case Common::KEYCODE_PRINT:
+ return 0x2A;
+ case Common::KEYCODE_INSERT:
+ return 0x2D;
+ case Common::KEYCODE_DELETE:
+ return 0x2E;
+ case Common::KEYCODE_HELP:
+ return 0x2F;
+ case Common::KEYCODE_KP_MULTIPLY:
+ return 0x6A;
+ case Common::KEYCODE_KP_PLUS:
+ return 0x6B;
+ case Common::KEYCODE_KP_MINUS:
+ return 0x6D;
+ case Common::KEYCODE_KP_PERIOD:
+ return 0x6E;
+ case Common::KEYCODE_KP_DIVIDE:
+ return 0x6F;
+ case Common::KEYCODE_NUMLOCK:
+ return 0x90;
+ case Common::KEYCODE_SCROLLOCK:
+ return 0x91;
+ case Common::KEYCODE_LSHIFT:
+ return 0xA0;
+ case Common::KEYCODE_RSHIFT:
+ return 0xA1;
+ case Common::KEYCODE_LCTRL:
+ return 0xA2;
+ case Common::KEYCODE_RCTRL:
+ return 0xA3;
+ case Common::KEYCODE_MENU:
+ return 0xA5;
+ case Common::KEYCODE_LEFTBRACKET:
+ return 0xDB;
+ case Common::KEYCODE_RIGHTBRACKET:
+ return 0xDD;
+ case Common::KEYCODE_SEMICOLON:
+ return 0xBA;
+ case Common::KEYCODE_BACKSLASH:
+ return 0xDC;
+ case Common::KEYCODE_QUOTE:
+ return 0xDE;
+ case Common::KEYCODE_SLASH:
+ return 0xBF;
+ case Common::KEYCODE_TILDE:
+ return 0xC0;
+ case Common::KEYCODE_COMMA:
+ return 0xBC;
+ case Common::KEYCODE_PERIOD:
+ return 0xBE;
+ case Common::KEYCODE_MINUS:
+ return 0xBD;
+ case Common::KEYCODE_PLUS:
+ return 0xBB;
+ default:
+ return 0;
+ }
+
+ 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/core/save_manager.cpp b/engines/zvision/core/save_manager.cpp
deleted file mode 100644
index 07fb7637e7..0000000000
--- a/engines/zvision/core/save_manager.cpp
+++ /dev/null
@@ -1,206 +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 "zvision/core/save_manager.h"
-
-#include "zvision/zvision.h"
-#include "zvision/scripting/script_manager.h"
-#include "zvision/graphics/render_manager.h"
-
-#include "common/system.h"
-
-#include "graphics/surface.h"
-#include "graphics/thumbnail.h"
-
-#include "gui/message.h"
-
-
-namespace ZVision {
-
-const uint32 SaveManager::SAVEGAME_ID = MKTAG('Z', 'E', 'N', 'G');
-
-void SaveManager::saveGame(uint slot, const Common::String &saveName) {
- // The games only support 20 slots
- assert(slot <= 1 && slot <= 20);
-
- Common::SaveFileManager *saveFileManager = g_system->getSavefileManager();
- Common::OutSaveFile *file = saveFileManager->openForSaving(_engine->generateSaveFileName(slot));
-
- // Write out the savegame header
- file->writeUint32BE(SAVEGAME_ID);
-
- // Write version
- file->writeByte(SAVE_VERSION);
-
- // Write savegame name
- file->writeString(saveName);
- file->writeByte(0);
-
- // We can't call writeGameSaveData because the save menu is actually
- // a room, so writeGameSaveData would save us in the save menu.
- // However, an auto save is performed before each room change, so we
- // can copy the data from there. We can guarantee that an auto save file will
- // exist before this is called because the save menu can only be accessed
- // after the first room (the main menu) has loaded.
- Common::InSaveFile *autoSaveFile = saveFileManager->openForLoading(_engine->generateAutoSaveFileName());
-
- // Skip over the header info
- autoSaveFile->readSint32BE(); // SAVEGAME_ID
- autoSaveFile->readByte(); // Version
- autoSaveFile->seek(5, SEEK_CUR); // The string "auto" with terminating NULL
-
- // Read the rest to a buffer
- uint32 size = autoSaveFile->size() - autoSaveFile->pos();
- byte *buffer = new byte[size];
- autoSaveFile->read(buffer, size);
-
- // Then write the buffer to the new file
- file->write(buffer, size);
-
- // Cleanup
- delete[] buffer;
- file->finalize();
- delete file;
-}
-
-void SaveManager::autoSave() {
- Common::OutSaveFile *file = g_system->getSavefileManager()->openForSaving(_engine->generateAutoSaveFileName());
-
- // Write out the savegame header
- file->writeUint32BE(SAVEGAME_ID);
-
- // Version
- file->writeByte(SAVE_VERSION);
-
- file->writeString("auto");
- file->writeByte(0);
-
- writeSaveGameData(file);
-
- // Cleanup
- file->finalize();
- delete file;
-}
-
-void SaveManager::writeSaveGameData(Common::OutSaveFile *file) {
- // Create a thumbnail and save it
- Graphics::saveThumbnail(*file);
-
- // Write out the save date/time
- TimeDate td;
- g_system->getTimeAndDate(td);
- file->writeSint16LE(td.tm_year + 1900);
- file->writeSint16LE(td.tm_mon + 1);
- file->writeSint16LE(td.tm_mday);
- file->writeSint16LE(td.tm_hour);
- file->writeSint16LE(td.tm_min);
-
- ScriptManager *scriptManager = _engine->getScriptManager();
- // Write out the current location
- Location currentLocation = scriptManager->getCurrentLocation();
- file->writeByte(currentLocation.world);
- file->writeByte(currentLocation.room);
- file->writeByte(currentLocation.node);
- file->writeByte(currentLocation.view);
- file->writeUint32LE(currentLocation.offset);
-
- // Write out the current state table values
- scriptManager->serializeStateTable(file);
-
- // Write out any controls needing to save state
- scriptManager->serializeControls(file);
-}
-
-Common::Error SaveManager::loadGame(uint slot) {
- // The games only support 20 slots
- assert(slot <= 1 && slot <= 20);
-
- Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(_engine->generateSaveFileName(slot));
- if (saveFile == 0) {
- return Common::kPathDoesNotExist;
- }
-
- // Read the header
- SaveGameHeader header;
- if (!readSaveGameHeader(saveFile, header)) {
- return Common::kUnknownError;
- }
-
- char world = (char)saveFile->readByte();
- char room = (char)saveFile->readByte();
- char node = (char)saveFile->readByte();
- char view = (char)saveFile->readByte();
- uint32 offset = (char)saveFile->readUint32LE();
-
- ScriptManager *scriptManager = _engine->getScriptManager();
- // Update the state table values
- scriptManager->deserializeStateTable(saveFile);
-
- // Load the room
- scriptManager->changeLocation(world, room, node, view, offset);
-
- // Update the controls
- scriptManager->deserializeControls(saveFile);
-
- return Common::kNoError;
-}
-
-bool SaveManager::readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header) {
- if (in->readUint32BE() != SAVEGAME_ID) {
- warning("File is not a ZVision save file. Aborting load");
- return false;
- }
-
- // Read in the version
- header.version = in->readByte();
-
- // 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");
- dialog.runModal();
- }
-
- // Read in the save name
- header.saveName.clear();
- char ch;
- while ((ch = (char)in->readByte()) != '\0')
- header.saveName += ch;
-
- // Get the thumbnail
- header.thumbnail = Graphics::loadThumbnail(*in);
- if (!header.thumbnail)
- return false;
-
- // Read in save date/time
- header.saveYear = in->readSint16LE();
- header.saveMonth = in->readSint16LE();
- header.saveDay = in->readSint16LE();
- header.saveHour = in->readSint16LE();
- header.saveMinutes = in->readSint16LE();
-
- return true;
-}
-
-} // End of namespace ZVision
diff --git a/engines/zvision/cursors/cursor.cpp b/engines/zvision/cursors/cursor.cpp
deleted file mode 100644
index 9b9b9a3f71..0000000000
--- a/engines/zvision/cursors/cursor.cpp
+++ /dev/null
@@ -1,94 +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 "zvision/cursors/cursor.h"
-
-#include "common/str.h"
-#include "common/file.h"
-
-
-namespace ZVision {
-
-ZorkCursor::ZorkCursor()
- : _width(0),
- _height(0),
- _hotspotX(0),
- _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(const ZorkCursor &other) {
- _width = other._width;
- _height = other._height;
- _hotspotX = other._hotspotX;
- _hotspotY = other._hotspotY;
-
- _surface.copyFrom(other._surface);
-}
-
-ZorkCursor &ZorkCursor::operator=(const ZorkCursor &other) {
- _width = other._width;
- _height = other._height;
- _hotspotX = other._hotspotX;
- _hotspotY = other._hotspotY;
-
- _surface.free();
- _surface.copyFrom(other._surface);
-
- return *this;
-}
-
-ZorkCursor::~ZorkCursor() {
- _surface.free();
-}
-
-} // End of namespace ZVision
diff --git a/engines/zvision/cursors/cursor_manager.cpp b/engines/zvision/cursors/cursor_manager.cpp
deleted file mode 100644
index 7f70c8b4e3..0000000000
--- a/engines/zvision/cursors/cursor_manager.cpp
+++ /dev/null
@@ -1,152 +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 "zvision/cursors/cursor_manager.h"
-
-#include "zvision/zvision.h"
-
-#include "common/system.h"
-
-#include "graphics/pixelformat.h"
-#include "graphics/cursorman.h"
-
-
-namespace ZVision {
-
-const char *CursorManager::_cursorNames[NUM_CURSORS] = { "active", "arrow", "backward", "downarrow", "forward", "handpt", "handpu", "hdown", "hleft",
- "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",
- "g0gac091.zcr", "g0gac101.zcr", "g0gac011.zcr", "g0gac111.zcr", "g0gac121.zcr", "g0gac131.zcr", "g0gac141.zcr", "g0gac151.zcr", "g0gac161.zcr" };
-
-const char *CursorManager::_zNemCursorFileNames[NUM_CURSORS] = { "00act", "arrow", "back", "down", "forw", "handpt", "handpu", "hdown", "hleft",
- "hright", "hup", "00idle", "left", "right", "ssurr", "stilt", "turn", "up" };
-
-
-CursorManager::CursorManager(ZVision *engine, const Graphics::PixelFormat *pixelFormat)
- : _engine(engine),
- _pixelFormat(pixelFormat),
- _cursorIsPushed(false) {
- // WARNING: The index IDLE_CURSOR_INDEX is hardcoded. If you change the order of _cursorNames/_zgiCursorFileNames/_zNemCursorFileNames, you HAVE to change the index accordingly
- if (_engine->getGameId() == GID_NEMESIS) {
- Common::String name(Common::String::format("%sa.zcr", _zNemCursorFileNames[IDLE_CURSOR_INDEX]));
- _idleCursor = ZorkCursor(name);
- } else if (_engine->getGameId() == GID_GRANDINQUISITOR) {
- _idleCursor = ZorkCursor(_zgiCursorFileNames[IDLE_CURSOR_INDEX]);
- }
-}
-
-void CursorManager::initialize() {
- revertToIdle();
- CursorMan.showMouse(true);
-}
-
-void CursorManager::changeCursor(const Common::String &cursorName) {
- changeCursor(cursorName, _cursorIsPushed);
-}
-
-void CursorManager::changeCursor(const Common::String &cursorName, bool pushed) {
- if (_currentCursor.equals(cursorName) && _cursorIsPushed == pushed)
- return;
-
- if (_cursorIsPushed != pushed)
- _cursorIsPushed = pushed;
-
- if (cursorName == "idle" && !pushed) {
- CursorMan.replaceCursor(_idleCursor.getSurface(), _idleCursor.getWidth(), _idleCursor.getHeight(), _idleCursor.getHotspotX(), _idleCursor.getHotspotY(), _idleCursor.getKeyColor(), false, _pixelFormat);
- return;
- }
-
- for (int i = 0; i < NUM_CURSORS; ++i) {
- if (_engine->getGameId() == GID_NEMESIS) {
- if (cursorName.equals(_cursorNames[i])) {
- _currentCursor = cursorName;
-
- // ZNem uses a/b at the end of the file to signify not pushed/pushed respectively
- Common::String pushedFlag = pushed ? "b" : "a";
- Common::String name = Common::String::format("%s%s.zcr", _zNemCursorFileNames[i], pushedFlag.c_str());
-
- changeCursor(ZorkCursor(name));
- return;
- }
- } else if (_engine->getGameId() == GID_GRANDINQUISITOR) {
- if (cursorName.equals(_cursorNames[i])) {
- _currentCursor = cursorName;
-
- if (!pushed) {
- changeCursor(ZorkCursor(_zgiCursorFileNames[i]));
- } else {
- // ZGI flips not pushed/pushed between a/c and b/d
- // It flips the 4th character of the name
- char buffer[25];
- strcpy(buffer, _zgiCursorFileNames[i]);
- buffer[3] += 2;
- changeCursor(ZorkCursor(buffer));
- }
- return;
- }
- }
- }
-
- // If we get here, something went wrong
- warning("No cursor found for identifier %s", cursorName.c_str());
-}
-
-void CursorManager::changeCursor(const ZorkCursor &cursor) {
- CursorMan.replaceCursor(cursor.getSurface(), cursor.getWidth(), cursor.getHeight(), cursor.getHotspotX(), cursor.getHotspotY(), cursor.getKeyColor(), false, _pixelFormat);
-}
-
-void CursorManager::cursorDown(bool pushed) {
- if (_cursorIsPushed == pushed)
- return;
-
- _cursorIsPushed = pushed;
- changeCursor(_currentCursor, pushed);
-}
-
-void CursorManager::setLeftCursor() {
- changeCursor("leftarrow");
-}
-
-void CursorManager::setRightCursor() {
- changeCursor("rightarrow");
-}
-
-void CursorManager::setUpCursor() {
- changeCursor("zuparrow");
-}
-
-void CursorManager::setDownCursor() {
- changeCursor("downarrow");
-}
-
-void CursorManager::revertToIdle() {
- _currentCursor = "idle";
- if (!_cursorIsPushed)
- CursorMan.replaceCursor(_idleCursor.getSurface(), _idleCursor.getWidth(), _idleCursor.getHeight(), _idleCursor.getHotspotX(), _idleCursor.getHotspotY(), _idleCursor.getKeyColor(), false, _pixelFormat);
- else
- changeCursor(_currentCursor, _cursorIsPushed);
-}
-
-} // End of namespace ZVision
diff --git a/engines/zvision/detection.cpp b/engines/zvision/detection.cpp
index 9961db1215..c817cbf3e9 100644
--- a/engines/zvision/detection.cpp
+++ b/engines/zvision/detection.cpp
@@ -26,13 +26,14 @@
#include "zvision/zvision.h"
#include "zvision/detection.h"
+#include "zvision/file/save_manager.h"
+#include "zvision/scripting/script_manager.h"
#include "common/translation.h"
#include "common/savefile.h"
#include "common/str-array.h"
#include "common/system.h"
-
namespace ZVision {
uint32 ZVision::getFeatures() const {
@@ -45,7 +46,6 @@ Common::Language ZVision::getLanguage() const {
} // End of namespace ZVision
-
static const PlainGameDescriptor zVisionGames[] = {
{"zvision", "ZVision Game"},
{"znemesis", "Zork Nemesis: The Forbidden Lands"},
@@ -53,9 +53,14 @@ static const PlainGameDescriptor zVisionGames[] = {
{0, 0}
};
-
namespace ZVision {
+#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 ZVisionGameDescription gameDescriptions[] = {
{
@@ -67,21 +72,156 @@ static const ZVisionGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO4(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_DOUBLE_FPS, GAMEOPTION_ENABLE_VENUS, GAMEOPTION_DISABLE_ANIM_WHILE_TURNING)
},
GID_NEMESIS
},
{
- // Zork Grand Inquisitor English version
+ // Zork Nemesis French version
{
- "zgi",
+ "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,
- GUIO1(GUIO_NONE)
+ 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
},
@@ -99,16 +239,63 @@ static const char *directoryGlobs[] = {
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 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_DOUBLE_FPS,
+ {
+ _s("Double FPS"),
+ _s("Increase game FPS from 30 to 60"),
+ "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 panoramic mode"),
+ "noanimwhileturning",
+ false
+ }
+ },
+
+ {
+ GAMEOPTION_USE_HIRES_MPEG_MOVIES,
+ {
+ _s("Use the hires MPEG movies"),
+ _s("Use the hires MPEG movies of the DVD version, instead of the lowres AVI ones"),
+ "mpegmovies",
+ true
+ }
+ },
+
+ AD_EXTRA_GUI_OPTIONS_TERMINATOR
};
class ZVisionMetaEngine : public AdvancedMetaEngine {
public:
- ZVisionMetaEngine() : AdvancedMetaEngine(ZVision::gameDescriptions, sizeof(ZVision::ZVisionGameDescription), zVisionGames) {
+ ZVisionMetaEngine() : AdvancedMetaEngine(ZVision::gameDescriptions, sizeof(ZVision::ZVisionGameDescription), zVisionGames, optionsList) {
_maxScanDepth = 2;
_directoryGlobs = directoryGlobs;
_singleid = "zvision";
@@ -124,7 +311,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;
SaveStateList listSaves(const char *target) const;
virtual int getMaximumSaveSlot() const;
void removeSaveState(const char *target, int slot) const;
@@ -132,24 +318,40 @@ public:
};
bool ZVisionMetaEngine::hasFeature(MetaEngineFeature f) const {
- return false;
- /*
- (f == kSupportsListSaves) ||
- (f == kSupportsLoadingDuringStartup) ||
- (f == kSupportsDeleteSave) ||
- (f == kSavesSupportMetaInfo) ||
- (f == kSavesSupportThumbnail) ||
- (f == kSavesSupportCreationDate) ||
- (f == kSavesSupportPlayTime);
- */
+ return
+ (f == kSupportsListSaves) ||
+ (f == kSupportsLoadingDuringStartup) ||
+ (f == kSupportsDeleteSave) ||
+ (f == kSavesSupportMetaInfo) ||
+ (f == kSavesSupportThumbnail) ||
+ (f == kSavesSupportCreationDate);
+ //(f == kSavesSupportPlayTime);
}
-/*bool ZVision::ZVision::hasFeature(EngineFeature f) const {
- return
- (f == kSupportsRTL) ||
- (f == kSupportsLoadingDuringRuntime) ||
- (f == kSupportsSavingDuringRuntime);
-}*/
+bool ZVision::ZVision::hasFeature(EngineFeature f) const {
+ return
+ (f == kSupportsRTL) ||
+ (f == kSupportsLoadingDuringRuntime) ||
+ (f == kSupportsSavingDuringRuntime);
+}
+
+Common::Error ZVision::ZVision::loadGameState(int slot) {
+ return _saveManager->loadGame(slot);
+}
+
+Common::Error ZVision::ZVision::saveGameState(int slot, const Common::String &desc) {
+ _saveManager->saveGame(slot, desc, false);
+ return Common::kNoError;
+}
+
+bool ZVision::ZVision::canLoadGameStateCurrently() {
+ return !_videoIsPlaying;
+}
+
+bool ZVision::ZVision::canSaveGameStateCurrently() {
+ Location currentLocation = _scriptManager->getCurrentLocation();
+ return !_videoIsPlaying && currentLocation.world != 'g' && !(currentLocation.room == 'j' || currentLocation.room == 'a');
+}
bool ZVisionMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
const ZVision::ZVisionGameDescription *gd = (const ZVision::ZVisionGameDescription *)desc;
@@ -159,37 +361,36 @@ 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);
- return options;
-}
-
SaveStateList ZVisionMetaEngine::listSaves(const char *target) const {
- //Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
- /*ZVision::ZVision::SaveHeader header;
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ ZVision::SaveGameHeader header;
Common::String pattern = target;
pattern += ".???";
Common::StringArray filenames;
filenames = saveFileMan->listSavefiles(pattern.c_str());
- Common::sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)*/
+ Common::sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)*/
SaveStateList saveList;
-/* for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); file++) {
- // Obtain the last 3 digits of the filename, since they correspond to the save slot
- int slotNum = atoi(file->c_str() + file->size() - 3);
-
- if (slotNum >= 0 && slotNum <= 999) {
- Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
- if (in) {
- if (ZVision::ZVision::readSaveHeader(in, false, header) == ZVision::ZVision::kRSHENoError) {
- saveList.push_back(SaveStateDescriptor(slotNum, header.description));
- }
- delete in;
- }
- }
- }*/
+ // We only use readSaveGameHeader() here, which doesn't need an engine callback
+ ZVision::SaveManager *zvisionSaveMan = new ZVision::SaveManager(NULL);
+
+ for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); file++) {
+ // Obtain the last 3 digits of the filename, since they correspond to the save slot
+ int slotNum = atoi(file->c_str() + file->size() - 3);
+
+ if (slotNum >= 0 && slotNum <= 999) {
+ Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
+ if (in) {
+ if (zvisionSaveMan->readSaveGameHeader(in, header)) {
+ saveList.push_back(SaveStateDescriptor(slotNum, header.saveName));
+ }
+ delete in;
+ }
+ }
+ }
+
+ delete zvisionSaveMan;
return saveList;
}
@@ -199,9 +400,8 @@ int ZVisionMetaEngine::getMaximumSaveSlot() const {
}
void ZVisionMetaEngine::removeSaveState(const char *target, int slot) const {
- /*
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
- Common::String filename = ZVision::ZVision::getSavegameFilename(target, slot);
+ Common::String filename = Common::String::format("%s.%03u", target, slot);
saveFileMan->removeSavefile(filename.c_str());
@@ -209,63 +409,67 @@ void ZVisionMetaEngine::removeSaveState(const char *target, int slot) const {
Common::String pattern = target;
pattern += ".???";
filenames = saveFileMan->listSavefiles(pattern.c_str());
- Common::sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
+ Common::sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
- // Obtain the last 3 digits of the filename, since they correspond to the save slot
- int slotNum = atoi(file->c_str() + file->size() - 3);
-
- // Rename every slot greater than the deleted slot,
- if (slotNum > slot) {
- saveFileMan->renameSavefile(file->c_str(), filename.c_str());
- filename = ZVision::ZVision::getSavegameFilename(target, ++slot);
- }
+ // Obtain the last 3 digits of the filename, since they correspond to the save slot
+ int slotNum = atoi(file->c_str() + file->size() - 3);
+
+ // Rename every slot greater than the deleted slot,
+ if (slotNum > slot) {
+ saveFileMan->renameSavefile(file->c_str(), filename.c_str());
+ filename = Common::String::format("%s.%03u", target, ++slot);
+ }
}
- */
}
SaveStateDescriptor ZVisionMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
- /*
- Common::String filename = ZVision::ZVision::getSavegameFilename(target, slot);
+ Common::String filename = Common::String::format("%s.%03u", target, slot);
Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(filename.c_str());
if (in) {
- ZVision::ZVision::SaveHeader header;
- ZVision::ZVision::kReadSaveHeaderError error;
+ ZVision::SaveGameHeader header;
- error = ZVision::ZVision::readSaveHeader(in, true, header);
- delete in;
+ // We only use readSaveGameHeader() here, which doesn't need an engine callback
+ ZVision::SaveManager *zvisionSaveMan = new ZVision::SaveManager(NULL);
+ bool successfulRead = zvisionSaveMan->readSaveGameHeader(in, header);
+ delete zvisionSaveMan;
+ delete in;
- if (error == ZVision::ZVision::kRSHENoError) {
- SaveStateDescriptor desc(slot, header.description);
+ if (successfulRead) {
+ SaveStateDescriptor desc(slot, header.saveName);
- desc.setThumbnail(header.thumbnail);
+ // Do not allow save slot 0 (used for auto-saving) to be deleted or
+ // overwritten.
+ desc.setDeletableFlag(slot != 0);
+ desc.setWriteProtectedFlag(slot == 0);
- if (header.version > 0) {
- int day = (header.saveDate >> 24) & 0xFF;
- int month = (header.saveDate >> 16) & 0xFF;
- int year = header.saveDate & 0xFFFF;
+ desc.setThumbnail(header.thumbnail);
- desc.setSaveDate(year, month, day);
+ if (header.version > 0) {
+ int day = header.saveDay;
+ int month = header.saveMonth;
+ int year = header.saveYear;
- int hour = (header.saveTime >> 16) & 0xFF;
- int minutes = (header.saveTime >> 8) & 0xFF;
+ desc.setSaveDate(year, month, day);
- desc.setSaveTime(hour, minutes);
+ int hour = header.saveHour;
+ int minutes = header.saveMinutes;
- desc.setPlayTime(header.playTime * 1000);
- }
+ desc.setSaveTime(hour, minutes);
- return desc;
- }
+ //desc.setPlayTime(header.playTime * 1000);
+ }
+
+ return desc;
+ }
}
- */
return SaveStateDescriptor();
}
#if PLUGIN_ENABLED_DYNAMIC(ZVISION)
- REGISTER_PLUGIN_DYNAMIC(ZVISION, PLUGIN_TYPE_ENGINE, ZVisionMetaEngine);
+REGISTER_PLUGIN_DYNAMIC(ZVISION, PLUGIN_TYPE_ENGINE, ZVisionMetaEngine);
#else
- REGISTER_PLUGIN_STATIC(ZVISION, PLUGIN_TYPE_ENGINE, ZVisionMetaEngine);
+REGISTER_PLUGIN_STATIC(ZVISION, PLUGIN_TYPE_ENGINE, ZVisionMetaEngine);
#endif
diff --git a/engines/zvision/detection.h b/engines/zvision/detection.h
index a788e710b7..f80cac79ec 100644
--- a/engines/zvision/detection.h
+++ b/engines/zvision/detection.h
@@ -25,7 +25,6 @@
#include "engines/advancedDetector.h"
-
namespace ZVision {
enum ZVisionGameId {
diff --git a/engines/zvision/utility/lzss_read_stream.cpp b/engines/zvision/file/lzss_read_stream.cpp
index e094188ef6..ca10af7d72 100644
--- a/engines/zvision/utility/lzss_read_stream.cpp
+++ b/engines/zvision/file/lzss_read_stream.cpp
@@ -22,18 +22,18 @@
#include "common/scummsys.h"
-#include "zvision/utility/lzss_read_stream.h"
-
+#include "zvision/file/lzss_read_stream.h"
namespace ZVision {
LzssReadStream::LzssReadStream(Common::SeekableReadStream *source)
- : _source(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);
+ : _source(source),
+ // It's convention to set the starting cursor position to blockSize - 16
+ _windowCursor(0x0FEE),
+ _eosFlag(false) {
+ // 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) {
@@ -69,9 +69,9 @@ uint32 LzssReadStream::decompressBytes(byte *destination, uint32 numberOfBytes)
}
uint16 length = (high & 0xF) + 2;
- uint16 offset = low | ((high & 0xF0)<<4);
+ uint16 offset = low | ((high & 0xF0) << 4);
- for(int j = 0; j <= length; ++j) {
+ for (int j = 0; j <= length; ++j) {
byte temp = _window[(offset + j) & 0xFFF];
_window[_windowCursor] = temp;
destination[destinationCursor++] = temp;
diff --git a/engines/zvision/utility/lzss_read_stream.h b/engines/zvision/file/lzss_read_stream.h
index b51cf3905f..1420621f13 100644
--- a/engines/zvision/utility/lzss_read_stream.h
+++ b/engines/zvision/file/lzss_read_stream.h
@@ -26,7 +26,6 @@
#include "common/stream.h"
#include "common/array.h"
-
namespace Common {
class SeekableReadStream;
}
@@ -64,7 +63,7 @@ private:
*
* @param numberOfBytes How many bytes to decompress. This is a count of source bytes, not destination bytes
*/
- uint32 decompressBytes(byte* destination, uint32 numberOfBytes);
+ uint32 decompressBytes(byte *destination, uint32 numberOfBytes);
};
}
diff --git a/engines/zvision/file/save_manager.cpp b/engines/zvision/file/save_manager.cpp
new file mode 100644
index 0000000000..63b54269de
--- /dev/null
+++ b/engines/zvision/file/save_manager.cpp
@@ -0,0 +1,292 @@
+/* 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 "zvision/zvision.h"
+#include "zvision/file/save_manager.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/graphics/render_manager.h"
+
+#include "common/system.h"
+#include "common/translation.h"
+
+#include "graphics/surface.h"
+#include "graphics/thumbnail.h"
+
+#include "gui/message.h"
+#include "gui/saveload.h"
+
+namespace ZVision {
+
+const uint32 SaveManager::SAVEGAME_ID = MKTAG('Z', 'E', 'N', 'G');
+
+bool SaveManager::scummVMSaveLoadDialog(bool isSave) {
+ GUI::SaveLoadChooser *dialog;
+ Common::String desc;
+ int slot;
+
+ if (isSave) {
+ dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true);
+
+ slot = dialog->runModalWithCurrentTarget();
+ desc = dialog->getResultString();
+
+ if (desc.empty()) {
+ // create our own description for the saved game, the user didnt enter it
+ desc = dialog->createDefaultSaveDescription(slot);
+ }
+
+ if (desc.size() > 28)
+ desc = Common::String(desc.c_str(), 28);
+ } else {
+ dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false);
+ slot = dialog->runModalWithCurrentTarget();
+ }
+
+ delete dialog;
+
+ if (slot < 0)
+ return false;
+
+ if (isSave) {
+ saveGame(slot, desc, false);
+ return true;
+ } else {
+ Common::ErrorCode result = loadGame(slot).getCode();
+ return (result == Common::kNoError);
+ }
+}
+
+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, useSaveBuffer);
+
+ if (useSaveBuffer)
+ file->write(_tempSave->getData(), _tempSave->size());
+ else
+ _engine->getScriptManager()->serialize(file);
+
+ file->finalize();
+ delete file;
+
+ if (useSaveBuffer)
+ flushSaveBuffer();
+
+ _lastSaveTime = g_system->getMillis();
+}
+
+void SaveManager::autoSave() {
+ saveGame(0, "Auto save", false);
+}
+
+void SaveManager::writeSaveGameHeader(Common::OutSaveFile *file, const Common::String &saveName, bool useSaveBuffer) {
+ file->writeUint32BE(SAVEGAME_ID);
+
+ // Write version
+ file->writeByte(SAVE_VERSION);
+
+ // Write savegame name
+ file->writeString(saveName);
+ file->writeByte(0);
+
+ // Save the game thumbnail
+ if (useSaveBuffer)
+ file->write(_tempThumbnail->getData(), _tempThumbnail->size());
+ else
+ Graphics::saveThumbnail(*file);
+
+ // Write out the save date/time
+ TimeDate td;
+ g_system->getTimeAndDate(td);
+ file->writeSint16LE(td.tm_year + 1900);
+ file->writeSint16LE(td.tm_mon + 1);
+ file->writeSint16LE(td.tm_mday);
+ file->writeSint16LE(td.tm_hour);
+ file->writeSint16LE(td.tm_min);
+}
+
+Common::Error SaveManager::loadGame(int slot) {
+ Common::SeekableReadStream *saveFile = NULL;
+
+ 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)) {
+ return Common::kUnknownError;
+ }
+
+ ScriptManager *scriptManager = _engine->getScriptManager();
+ // Update the state table values
+ scriptManager->deserialize(saveFile);
+
+ delete saveFile;
+ if (header.thumbnail)
+ delete header.thumbnail;
+
+ if (_engine->getGameId() == GID_NEMESIS && scriptManager->getCurrentLocation() == "tv2f") {
+ // WORKAROUND for script bug #6793: location tv2f (stairs) has two states:
+ // 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);
+ }
+ }
+
+ return Common::kNoError;
+}
+
+bool SaveManager::readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header) {
+ uint32 tag = in->readUint32BE();
+ // Check if it's original savegame than fill header structure
+ if (tag == MKTAG('Z', 'N', 'S', 'G')) {
+ header.saveYear = 0;
+ header.saveMonth = 0;
+ header.saveDay = 0;
+ header.saveHour = 0;
+ header.saveMinutes = 0;
+ header.saveName = "Original Save";
+ header.thumbnail = NULL;
+ header.version = SAVE_ORIGINAL;
+ in->seek(-4, SEEK_CUR);
+ return true;
+ }
+ if (tag != SAVEGAME_ID) {
+ warning("File is not a ZVision save file. Aborting load");
+ return false;
+ }
+
+ // Read in the version
+ header.version = in->readByte();
+
+ // 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");
+ dialog.runModal();
+ }
+
+ // Read in the save name
+ header.saveName.clear();
+ char ch;
+ while ((ch = (char)in->readByte()) != '\0')
+ header.saveName += ch;
+
+ // Get the thumbnail
+ header.thumbnail = Graphics::loadThumbnail(*in);
+ if (!header.thumbnail)
+ return false;
+
+ // Read in save date/time
+ header.saveYear = in->readSint16LE();
+ header.saveMonth = in->readSint16LE();
+ header.saveDay = in->readSint16LE();
+ header.saveHour = in->readSint16LE();
+ header.saveMinutes = in->readSint16LE();
+
+ return true;
+}
+
+Common::SeekableReadStream *SaveManager::getSlotFile(uint slot) {
+ Common::SeekableReadStream *saveFile = g_system->getSavefileManager()->openForLoading(_engine->generateSaveFileName(slot));
+ if (saveFile == NULL) {
+ // Try to load standard save file
+ Common::String filename;
+ if (_engine->getGameId() == GID_GRANDINQUISITOR)
+ filename = Common::String::format("inqsav%u.sav", slot);
+ else if (_engine->getGameId() == GID_NEMESIS)
+ filename = Common::String::format("nemsav%u.sav", slot);
+
+ saveFile = _engine->getSearchManager()->openFile(filename);
+ if (saveFile == NULL) {
+ Common::File *tmpFile = new Common::File;
+ if (!tmpFile->open(filename)) {
+ delete tmpFile;
+ } else {
+ saveFile = tmpFile;
+ }
+ }
+
+ }
+
+ return saveFile;
+}
+
+void SaveManager::prepareSaveBuffer() {
+ delete _tempThumbnail;
+ _tempThumbnail = new Common::MemoryWriteStreamDynamic;
+ Graphics::saveThumbnail(*_tempThumbnail);
+
+ delete _tempSave;
+ _tempSave = new Common::MemoryWriteStreamDynamic;
+ _engine->getScriptManager()->serialize(_tempSave);
+}
+
+void SaveManager::flushSaveBuffer() {
+ delete _tempThumbnail;
+ _tempThumbnail = NULL;
+
+ delete _tempSave;
+ _tempSave = NULL;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/core/save_manager.h b/engines/zvision/file/save_manager.h
index 43fb0c0faf..9e816373ea 100644
--- a/engines/zvision/core/save_manager.h
+++ b/engines/zvision/file/save_manager.h
@@ -24,6 +24,7 @@
#define ZVISION_SAVE_MANAGER_H
#include "common/savefile.h"
+#include "common/memstream.h"
namespace Common {
class String;
@@ -47,21 +48,32 @@ struct SaveGameHeader {
class SaveManager {
public:
- SaveManager(ZVision *engine) : _engine(engine) {}
+ 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 {
+ SAVE_ORIGINAL = 0,
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();
/**
@@ -72,18 +84,23 @@ 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, 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(int slot);
+
+ Common::SeekableReadStream *getSlotFile(uint slot);
+ bool readSaveGameHeader(Common::SeekableReadStream *in, SaveGameHeader &header);
+ void prepareSaveBuffer();
+ void flushSaveBuffer();
+ bool scummVMSaveLoadDialog(bool isSave);
private:
- void writeSaveGameData(Common::OutSaveFile *file);
- bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header);
+ 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
new file mode 100644
index 0000000000..821b85b053
--- /dev/null
+++ b/engines/zvision/file/search_manager.cpp
@@ -0,0 +1,285 @@
+/* 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/debug.h"
+#include "common/fs.h"
+#include "common/stream.h"
+
+#include "zvision/file/search_manager.h"
+#include "zvision/file/zfs_archive.h"
+
+namespace ZVision {
+
+SearchManager::SearchManager(const Common::String &rootPath, int depth) {
+ _root = rootPath;
+ if (_root[_root.size() - 1] == '\\' || _root[_root.size() - 1] == '/')
+ _root.deleteLastChar();
+
+ Common::FSNode fsNode(_root);
+
+ listDirRecursive(_dirList, fsNode, depth);
+
+ for (Common::List<Common::String>::iterator it = _dirList.begin(); it != _dirList.end();) {
+ if ((*it).hasSuffix("\\") || (*it).hasSuffix("/"))
+ (*it).deleteLastChar();
+
+ if (it->size() == _root.size())
+ it = _dirList.erase(it);
+ else if (it->size() > _root.size()) {
+ *it = Common::String(it->c_str() + _root.size() + 1);
+ it++;
+ } else
+ it++;
+ }
+}
+
+SearchManager::~SearchManager() {
+ Common::List<Common::Archive *>::iterator it = _archList.begin();
+ while (it != _archList.end()) {
+ delete *it;
+ it++;
+ }
+
+ _archList.clear();
+}
+
+void SearchManager::addFile(const Common::String &name, Common::Archive *arch) {
+ bool addArch = true;
+ Common::List<Common::Archive *>::iterator it = _archList.begin();
+ while (it != _archList.end()) {
+ if (*it == arch) {
+ addArch = false;
+ break;
+ }
+ it++;
+ }
+ if (addArch)
+ _archList.push_back(arch);
+
+ Common::String lowerCaseName = name;
+ lowerCaseName.toLowercase();
+
+ SearchManager::Node nod;
+ nod.name = lowerCaseName;
+ nod.arch = arch;
+
+ SearchManager::MatchList::iterator fit = _files.find(lowerCaseName);
+
+ if (fit == _files.end()) {
+ _files[lowerCaseName] = nod;
+ } else {
+ Common::SeekableReadStream *stream = fit->_value.arch->createReadStreamForMember(fit->_value.name);
+ if (stream) {
+ if (stream->size() < 10)
+ fit->_value.arch = arch;
+ delete stream;
+ } else {
+ _files[lowerCaseName] = nod;
+ }
+ }
+}
+
+Common::File *SearchManager::openFile(const Common::String &name) {
+ Common::String lowerCaseName = name;
+ lowerCaseName.toLowercase();
+
+ SearchManager::MatchList::iterator fit = _files.find(lowerCaseName);
+
+ if (fit != _files.end()) {
+ Common::File *tmp = new Common::File();
+ tmp->open(fit->_value.name, *fit->_value.arch);
+ return tmp;
+ }
+ return NULL;
+}
+
+bool SearchManager::openFile(Common::File &file, const Common::String &name) {
+ Common::String lowerCaseName = name;
+ lowerCaseName.toLowercase();
+
+ SearchManager::MatchList::iterator fit = _files.find(lowerCaseName);
+
+ if (fit != _files.end())
+ return file.open(fit->_value.name, *fit->_value.arch);
+ return false;
+}
+
+bool SearchManager::hasFile(const Common::String &name) {
+ Common::String lowerCaseName = name;
+ lowerCaseName.toLowercase();
+
+ SearchManager::MatchList::iterator fit = _files.find(lowerCaseName);
+
+ if (fit != _files.end())
+ return true;
+ return false;
+}
+
+bool SearchManager::loadZix(const Common::String &name) {
+ Common::File file;
+ if (!file.open(name))
+ return false;
+
+ Common::String line;
+
+ while (!file.eos()) {
+ line = file.readLine();
+ if (line.matchString("----------*", true))
+ break;
+ }
+
+ if (file.eos())
+ error("Corrupt ZIX file: %s", name.c_str());
+
+ Common::Array<Common::Archive *> archives;
+
+ while (!file.eos()) {
+ line = file.readLine();
+ line.trim();
+ if (line.matchString("----------*", true))
+ break;
+ else if (line.matchString("DIR:*", true) || line.matchString("CD0:*", true) || line.matchString("CD1:*", true) || line.matchString("CD2:*", true)) {
+ Common::Archive *arc;
+
+ Common::String path(line.c_str() + 5);
+ for (uint i = 0; i < path.size(); 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);
+
+ if (path.size() && path[0] == '.')
+ path.deleteChar(0);
+ if (path.size() && path[0] == '/')
+ path.deleteChar(0);
+ 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);
+ }
+ }
+
+ if (file.eos())
+ error("Corrupt ZIX file: %s", name.c_str());
+
+ while (!file.eos()) {
+ line = file.readLine();
+ line.trim();
+ uint dr = 0;
+ char buf[32];
+ if (sscanf(line.c_str(), "%u %s", &dr, buf) == 2) {
+ if (dr <= archives.size() && dr > 0) {
+ addFile(Common::String(buf), archives[dr - 1]);
+ }
+ }
+ }
+
+ return true;
+}
+
+void SearchManager::addDir(const Common::String &name) {
+ Common::String path;
+ for (Common::List<Common::String>::iterator it = _dirList.begin(); it != _dirList.end(); ++it)
+ if (name.equalsIgnoreCase(*it)) {
+ path = *it;
+ break;
+ }
+
+ if (path.size() == 0)
+ return;
+
+ path = Common::String::format("%s/%s", _root.c_str(), path.c_str());
+
+ Common::FSDirectory *dir = new Common::FSDirectory(path);
+
+ Common::ArchiveMemberList list;
+ dir->listMatchingMembers(list, "*.zfs");
+
+ for (Common::ArchiveMemberList::iterator iter = list.begin(); iter != list.end(); ++iter) {
+ Common::String flname = (*iter)->getName();
+
+ ZfsArchive *zfs = new ZfsArchive(Common::String::format("%s/%s", name.c_str(), flname.c_str()));
+
+ Common::ArchiveMemberList zfslist;
+ zfs->listMembers(zfslist);
+
+ for (Common::ArchiveMemberList::iterator ziter = zfslist.begin(); ziter != zfslist.end(); ++ziter) {
+ Common::String zfsFileName = (*ziter)->getName();
+ addFile(zfsFileName, zfs);
+ }
+ }
+
+ list.clear();
+ dir->listMembers(list);
+
+ for (Common::ArchiveMemberList::iterator iter = list.begin(); iter != list.end(); ++iter) {
+ Common::String flname = (*iter)->getName();
+ addFile(flname, dir);
+ }
+}
+
+void SearchManager::listDirRecursive(Common::List<Common::String> &_list, const Common::FSNode &fsNode, int depth) {
+ Common::FSList fsList;
+ if (fsNode.getChildren(fsList)) {
+
+ _list.push_back(fsNode.getPath());
+
+ if (depth > 1)
+ for (Common::FSList::const_iterator it = fsList.begin(); it != fsList.end(); ++it)
+ listDirRecursive(_list, *it, depth - 1);
+ }
+}
+
+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
new file mode 100644
index 0000000000..0d0ab14d31
--- /dev/null
+++ b/engines/zvision/file/search_manager.h
@@ -0,0 +1,70 @@
+/* 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_SEARCH_MANAGER_H
+#define ZVISION_SEARCH_MANAGER_H
+
+#include "common/str.h"
+#include "common/hash-str.h"
+#include "common/hashmap.h"
+#include "common/archive.h"
+#include "common/file.h"
+#include "common/list.h"
+
+namespace ZVision {
+
+class SearchManager {
+public:
+ SearchManager(const Common::String &rootPath, int depth);
+ ~SearchManager();
+
+ void addFile(const Common::String &name, Common::Archive *arch);
+ void addDir(const Common::String &name);
+
+ Common::File *openFile(const Common::String &name);
+ bool openFile(Common::File &file, const Common::String &name);
+ bool hasFile(const Common::String &name);
+
+ bool loadZix(const Common::String &name);
+
+ struct Node {
+ Common::String name;
+ Common::Archive *arch;
+ };
+
+ typedef Common::HashMap<Common::String, Node, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> MatchList;
+
+ 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;
+};
+
+}
+
+#endif // ZVISION_SEARCH_MANAGER_H
diff --git a/engines/zvision/archives/zfs_archive.cpp b/engines/zvision/file/zfs_archive.cpp
index f5fa6fc9bf..3a385cd8fd 100644
--- a/engines/zvision/archives/zfs_archive.cpp
+++ b/engines/zvision/file/zfs_archive.cpp
@@ -21,17 +21,17 @@
*/
#include "common/scummsys.h"
-
-#include "zvision/archives/zfs_archive.h"
-
#include "common/memstream.h"
#include "common/debug.h"
#include "common/file.h"
+#include "zvision/file/zfs_archive.h"
+
namespace ZVision {
ZfsArchive::ZfsArchive(const Common::String &fileName) : _fileName(fileName) {
Common::File zfsFile;
+ memset(&_header, 0, sizeof(_header));
if (!zfsFile.open(_fileName)) {
warning("ZFSArchive::ZFSArchive(): Could not find the archive file");
@@ -52,7 +52,7 @@ ZfsArchive::ZfsArchive(const Common::String &fileName, Common::SeekableReadStrea
ZfsArchive::~ZfsArchive() {
debug(1, "ZfsArchive Destructor Called");
ZfsEntryHeaderMap::iterator it = _entryHeaders.begin();
- for ( ; it != _entryHeaders.end(); ++it) {
+ for (; it != _entryHeaders.end(); ++it) {
delete it->_value;
}
}
@@ -79,7 +79,7 @@ void ZfsArchive::readHeaders(Common::SeekableReadStream *stream) {
// Read in each entry header
for (uint32 i = 0; i < _header.filesPerBlock; ++i) {
ZfsEntryHeader entryHeader;
-
+
entryHeader.name = readEntryName(stream);
entryHeader.offset = stream->readUint32LE();
entryHeader.id = stream->readUint32LE();
@@ -138,10 +138,10 @@ Common::SeekableReadStream *ZfsArchive::createReadStreamForMember(const Common::
zfsArchive.seek(entryHeader->offset);
// This *HAS* to be malloc (not new[]) because MemoryReadStream uses free() to free the memory
- byte* buffer = (byte *)malloc(entryHeader->size);
+ byte *buffer = (byte *)malloc(entryHeader->size);
zfsArchive.read(buffer, entryHeader->size);
// Decrypt the data in place
- if (_header.xorKey != 0)
+ if (_header.xorKey[0] + _header.xorKey[1] + _header.xorKey[2] + _header.xorKey[3] != 0)
unXor(buffer, entryHeader->size, _header.xorKey);
return new Common::MemoryReadStream(buffer, entryHeader->size, DisposeAfterUse::YES);
@@ -153,5 +153,3 @@ void ZfsArchive::unXor(byte *buffer, uint32 length, const byte *xorKey) const {
}
} // End of namespace ZVision
-
-
diff --git a/engines/zvision/archives/zfs_archive.h b/engines/zvision/file/zfs_archive.h
index 3509cfee26..fe0221416d 100644
--- a/engines/zvision/archives/zfs_archive.h
+++ b/engines/zvision/file/zfs_archive.h
@@ -27,7 +27,6 @@
#include "common/hashmap.h"
#include "common/hash-str.h"
-
namespace Common {
class String;
}
@@ -40,7 +39,7 @@ struct ZfsHeader {
uint32 maxNameLength;
uint32 filesPerBlock;
uint32 fileCount;
- byte xorKey[4];
+ uint8 xorKey[4];
uint32 fileSectionOffset;
};
@@ -53,7 +52,7 @@ struct ZfsEntryHeader {
uint32 unknown;
};
-typedef Common::HashMap<Common::String, ZfsEntryHeader*, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ZfsEntryHeaderMap;
+typedef Common::HashMap<Common::String, ZfsEntryHeader *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ZfsEntryHeaderMap;
class ZfsArchive : public Common::Archive {
public:
diff --git a/engines/zvision/fonts/truetype_font.cpp b/engines/zvision/fonts/truetype_font.cpp
deleted file mode 100644
index ba4d72bde8..0000000000
--- a/engines/zvision/fonts/truetype_font.cpp
+++ /dev/null
@@ -1,113 +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 "zvision/fonts/truetype_font.h"
-
-#include "zvision/zvision.h"
-#include "zvision/graphics/render_manager.h"
-
-#include "common/debug.h"
-#include "common/file.h"
-#include "common/system.h"
-
-#include "graphics/font.h"
-#include "graphics/fonts/ttf.h"
-#include "graphics/surface.h"
-
-
-namespace ZVision {
-
-TruetypeFont::TruetypeFont(ZVision *engine, int32 fontHeight)
- : _fontHeight(fontHeight),
- _font(0),
- _lineHeight(0) {
-}
-
-TruetypeFont::~TruetypeFont(void) {
- delete _font;
-}
-
-bool TruetypeFont::loadFile(const Common::String &filename) {
- Common::File file;
-
- bool fileOpened = false;
- if (!Common::File::exists(filename)) {
- debug("TTF font file %s was not found. Reverting to arial.ttf", filename.c_str());
- fileOpened = file.open("arial.ttf");
- } else {
- fileOpened = file.open(filename);
- }
-
- if (!fileOpened) {
- debug("TTF file could not be opened");
- return false;
- }
-
- _font = Graphics::loadTTFFont(file, _fontHeight);
- _lineHeight = _font->getFontHeight();
-
- return true;
-}
-
-Graphics::Surface *TruetypeFont::drawTextToSurface(const Common::String &text, uint16 textColor, int maxWidth, int maxHeight, Graphics::TextAlign align, bool wrap) {
- if (text.equals("")) {
- return nullptr;
- }
-
- Graphics::Surface *surface = new Graphics::Surface();
-
- if (!wrap) {
- int width = MIN(_font->getStringWidth(text), maxWidth);
- surface->create(width, _lineHeight, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));
- // TODO: Add better alpha support by getting the pixels from the backbuffer.
- // However doing that requires some kind of caching system so future text doesn't try to use this text as it's alpha background.
- surface->fillRect(Common::Rect(0, 0, surface->w, surface->h), 0);
-
- _font->drawString(surface, text, 0, 0, maxWidth, textColor, align);
- return surface;
- }
-
- Common::Array<Common::String> lines;
- _font->wordWrapText(text, maxWidth, lines);
-
- while (maxHeight > 0 && (int)lines.size() * _lineHeight > maxHeight) {
- lines.pop_back();
- }
- if (lines.size() == 0) {
- return nullptr;
- }
-
- surface->create(maxWidth, lines.size() * _lineHeight, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));
- surface->fillRect(Common::Rect(0, 0, surface->w, surface->h), 0);
-
- int heightOffset = 0;
- for (Common::Array<Common::String>::iterator it = lines.begin(); it != lines.end(); it++) {
- _font->drawString(surface, *it, 0, 0 + heightOffset, maxWidth, textColor, align);
- heightOffset += _lineHeight;
- }
-
- return surface;
-}
-
-} // End of namespace ZVision
diff --git a/engines/zvision/graphics/cursors/cursor.cpp b/engines/zvision/graphics/cursors/cursor.cpp
new file mode 100644
index 0000000000..2c011668ac
--- /dev/null
+++ b/engines/zvision/graphics/cursors/cursor.cpp
@@ -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.
+*
+*/
+
+#include "common/scummsys.h"
+
+#include "zvision/graphics/cursors/cursor.h"
+
+#include "common/str.h"
+#include "common/file.h"
+
+namespace ZVision {
+
+ZorkCursor::ZorkCursor()
+ : _width(0),
+ _height(0),
+ _hotspotX(0),
+ _hotspotY(0) {
+}
+
+ZorkCursor::ZorkCursor(ZVision *engine, const Common::String &fileName)
+ : _width(0),
+ _height(0),
+ _hotspotX(0),
+ _hotspotY(0) {
+ Common::File file;
+ if (!engine->getSearchManager()->openFile(file, fileName))
+ error("Cursor file %s does not exist", fileName.c_str());
+
+ 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, engine->_resourcePixelFormat);
+ uint32 bytesRead = file.read(_surface.getPixels(), dataSize);
+ assert(bytesRead == dataSize);
+
+#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) {
+ _width = other._width;
+ _height = other._height;
+ _hotspotX = other._hotspotX;
+ _hotspotY = other._hotspotY;
+
+ _surface.copyFrom(other._surface);
+}
+
+ZorkCursor &ZorkCursor::operator=(const ZorkCursor &other) {
+ _width = other._width;
+ _height = other._height;
+ _hotspotX = other._hotspotX;
+ _hotspotY = other._hotspotY;
+
+ _surface.free();
+ _surface.copyFrom(other._surface);
+
+ return *this;
+}
+
+ZorkCursor::~ZorkCursor() {
+ _surface.free();
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/cursors/cursor.h b/engines/zvision/graphics/cursors/cursor.h
index be9fae64da..6e0083520a 100644
--- a/engines/zvision/cursors/cursor.h
+++ b/engines/zvision/graphics/cursors/cursor.h
@@ -24,7 +24,7 @@
#define ZVISION_CURSOR_H
#include "graphics/surface.h"
-
+#include "zvision/zvision.h"
namespace Common {
class String;
@@ -39,7 +39,7 @@ namespace ZVision {
class ZorkCursor {
public:
ZorkCursor();
- ZorkCursor(const Common::String &fileName);
+ ZorkCursor(ZVision *engine, const Common::String &fileName);
ZorkCursor(const ZorkCursor &other);
~ZorkCursor();
@@ -53,12 +53,24 @@ private:
public:
ZorkCursor &operator=(const ZorkCursor &other);
- uint16 getWidth() const { return _width; }
- uint16 getHeight() const { return _height; }
- uint16 getHotspotX() const { return _hotspotX; }
- uint16 getHotspotY() const { return _hotspotY; }
- byte getKeyColor() const { return 0; }
- const byte *getSurface() const { return (const byte *)_surface.getPixels(); }
+ uint16 getWidth() const {
+ return _width;
+ }
+ uint16 getHeight() const {
+ return _height;
+ }
+ uint16 getHotspotX() const {
+ return _hotspotX;
+ }
+ uint16 getHotspotY() const {
+ return _hotspotY;
+ }
+ byte getKeyColor() const {
+ return 0;
+ }
+ const byte *getSurface() const {
+ return (const byte *)_surface.getPixels();
+ }
};
} // End of namespace ZVision
diff --git a/engines/zvision/graphics/cursors/cursor_manager.cpp b/engines/zvision/graphics/cursors/cursor_manager.cpp
new file mode 100644
index 0000000000..eeab18f4ba
--- /dev/null
+++ b/engines/zvision/graphics/cursors/cursor_manager.cpp
@@ -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.
+*
+*/
+
+#include "common/scummsys.h"
+
+#include "zvision/graphics/cursors/cursor_manager.h"
+
+#include "zvision/zvision.h"
+
+#include "common/system.h"
+
+#include "graphics/pixelformat.h"
+#include "graphics/cursorman.h"
+
+namespace ZVision {
+
+const char *CursorManager::_cursorNames[NUM_CURSORS] = { "active", "arrow", "backward", "downarrow", "forward", "handpt", "handpu", "hdown", "hleft",
+ "hright", "hup", "idle", "leftarrow", "rightarrow", "suggest_surround", "suggest_tilt", "turnaround", "zuparrow"
+ };
+
+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"
+ };
+
+const char *CursorManager::_zNemCursorFileNames[NUM_CURSORS] = { "00act", "arrow", "back", "down", "forw", "handpt", "handpu", "hdown", "hleft",
+ "hright", "hup", "00idle", "left", "right", "ssurr", "stilt", "turn", "up"
+ };
+
+CursorManager::CursorManager(ZVision *engine, const Graphics::PixelFormat pixelFormat)
+ : _engine(engine),
+ _pixelFormat(pixelFormat),
+ _cursorIsPushed(false),
+ _item(0),
+ _lastitem(0),
+ _currentCursor(CursorIndex_Idle) {
+ 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]);
+ _cursors[i][1] = ZorkCursor(_engine, name); // Down cursor
+ } else if (_engine->getGameId() == GID_GRANDINQUISITOR) {
+ _cursors[i][0] = ZorkCursor(_engine, _zgiCursorFileNames[i]); // Up cursor
+ char buffer[25];
+ memset(buffer, 0, 25);
+ strncpy(buffer, _zgiCursorFileNames[i], 24);
+ buffer[3] += 2;
+ _cursors[i][1] = ZorkCursor(_engine, buffer); // Down cursor
+ }
+ }
+}
+
+void CursorManager::setItemID(int id) {
+ if (id != _item) {
+ if (id) {
+ Common::String file;
+ if (_engine->getGameId() == GID_NEMESIS) {
+ file = Common::String::format("%2.2d%s%c.zcr", id, "idle", 'a');
+ _cursors[NUM_CURSORS][0] = ZorkCursor(_engine, file);
+ file = Common::String::format("%2.2d%s%c.zcr", id, "idle", 'b');
+ _cursors[NUM_CURSORS][1] = ZorkCursor(_engine, file);
+ file = Common::String::format("%2.2d%s%c.zcr", id, "act", 'a');
+ _cursors[NUM_CURSORS + 1][0] = ZorkCursor(_engine, file);
+ file = Common::String::format("%2.2d%s%c.zcr", id, "act", 'b');
+ _cursors[NUM_CURSORS + 1][0] = ZorkCursor(_engine, file);
+ } else if (_engine->getGameId() == GID_GRANDINQUISITOR) {
+ file = Common::String::format("g0b%cc%2.2x1.zcr", 'a' , id);
+ _cursors[NUM_CURSORS][0] = ZorkCursor(_engine, file);
+ file = Common::String::format("g0b%cc%2.2x1.zcr", 'c' , id);
+ _cursors[NUM_CURSORS][1] = ZorkCursor(_engine, file);
+ file = Common::String::format("g0b%cc%2.2x1.zcr", 'b' , id);
+ _cursors[NUM_CURSORS + 1][0] = ZorkCursor(_engine, file);
+ file = Common::String::format("g0b%cc%2.2x1.zcr", 'd' , id);
+ _cursors[NUM_CURSORS + 1][1] = ZorkCursor(_engine, file);
+ } else
+ return;
+ }
+ _item = id;
+ changeCursor(CursorIndex_Idle);
+ }
+}
+
+void CursorManager::initialize() {
+ changeCursor(_cursors[CursorIndex_Idle][_cursorIsPushed]);
+ showMouse(true);
+}
+
+void CursorManager::changeCursor(const ZorkCursor &cursor) {
+ CursorMan.replaceCursor(cursor.getSurface(), cursor.getWidth(), cursor.getHeight(), cursor.getHotspotX(), cursor.getHotspotY(), cursor.getKeyColor(), false, &_pixelFormat);
+}
+
+void CursorManager::cursorDown(bool pushed) {
+ if (_cursorIsPushed == pushed)
+ return;
+
+ _cursorIsPushed = pushed;
+
+ changeCursor(_cursors[_currentCursor][_cursorIsPushed]);
+}
+
+void CursorManager::changeCursor(int id) {
+ 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;
+ _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])) {
+ return i;
+ }
+ }
+
+ return CursorIndex_Idle;
+}
+
+void CursorManager::showMouse(bool vis) {
+ CursorMan.showMouse(vis);
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/cursors/cursor_manager.h b/engines/zvision/graphics/cursors/cursor_manager.h
index 0576517f58..35c605baf8 100644
--- a/engines/zvision/cursors/cursor_manager.h
+++ b/engines/zvision/graphics/cursors/cursor_manager.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.
@@ -23,11 +23,10 @@
#ifndef ZVISION_CURSOR_MANAGER_H
#define ZVISION_CURSOR_MANAGER_H
-#include "zvision/cursors/cursor.h"
+#include "zvision/graphics/cursors/cursor.h"
#include "common/str.h"
-
namespace Graphics {
struct PixelFormat;
}
@@ -37,6 +36,21 @@ namespace ZVision {
class ZVision;
/**
+ * Mostly usable cursors
+ */
+enum CursorIndex {
+ CursorIndex_Active = 0,
+ CursorIndex_DownArr = 3,
+ CursorIndex_HandPu = 6,
+ CursorIndex_Idle = 11,
+ CursorIndex_Left = 12,
+ CursorIndex_Right = 13,
+ CursorIndex_UpArr = 17,
+ CursorIndex_ItemIdle = 18,
+ CursorIndex_ItemAct = 19
+};
+
+/**
* Class to manage cursor changes. The actual changes have to be done
* through CursorMan. Otherwise the cursor will disappear after GMM
* or debug console.
@@ -44,20 +58,20 @@ class ZVision;
*/
class CursorManager {
public:
- CursorManager(ZVision *engine, const Graphics::PixelFormat *pixelFormat);
+ CursorManager(ZVision *engine, const Graphics::PixelFormat pixelFormat);
private:
- enum {
- NUM_CURSORS = 18,
- // WARNING: The index 11 is hardcoded. If you change the order of _cursorNames/_zgiCursorFileNames/_zNemCursorFileNames, you HAVE to change the index accordingly
- IDLE_CURSOR_INDEX = 11
- };
+ static const int NUM_CURSORS = 18;
+
+ // 18 default cursors in up/down states, +2 for items idle/act cursors
+ ZorkCursor _cursors[NUM_CURSORS + 2][2];
ZVision *_engine;
- const Graphics::PixelFormat *_pixelFormat;
- ZorkCursor _idleCursor;
- Common::String _currentCursor;
+ const Graphics::PixelFormat _pixelFormat;
bool _cursorIsPushed;
+ int _item;
+ int _lastitem;
+ int _currentCursor;
static const char *_cursorNames[];
static const char *_zgiCursorFileNames[];
@@ -68,19 +82,30 @@ public:
void initialize();
/**
- * Parses a cursor name into a cursor file then creates and shows that cursor.
- * It will use the current _isCursorPushed state to choose the correct cursor
+ * Change cursor to specified cursor ID. If item setted to not 0 and cursor id idle/acrive/handpu change cursor to item.
+ *
+ * @param id Wanted cursor id.
+ */
+
+ void changeCursor(int id);
+
+ /**
+ * Return founded id for string contains cursor name
*
- * @param cursorName The name of a cursor. This *HAS* to correspond to one of the entries in _cursorNames[]
+ * @param name Cursor name
+ * @return Id of cursor or idle cursor id if not found
*/
- void changeCursor(const Common::String &cursorName);
+
+ int getCursorId(const Common::String &name);
+
/**
- * Parses a cursor name into a cursor file then creates and shows that cursor.
+ * Load cursor for item by id, and try to change cursor to item cursor if it's not 0
*
- * @param cursorName The name of a cursor. This *HAS* to correspond to one of the entries in _cursorNames[]
- * @param pushed Should the cursor be pushed (true) or not pushed (false) (Another way to say it: down or up)
+ * @param id Item id or 0 for no item cursor
*/
- void changeCursor(const Common::String &cursorName, bool pushed);
+
+ void setItemID(int id);
+
/**
* Change the cursor to a certain push state. If the cursor is already in the specified push state, nothing will happen.
*
@@ -88,17 +113,12 @@ public:
*/
void cursorDown(bool pushed);
- /** Set the cursor to 'Left Arrow'. It will retain the current _isCursorPushed state */
- void setLeftCursor();
- /** Set the cursor to 'Right Arrow'. It will retain the current _isCursorPushed state */
- void setRightCursor();
- /** Set the cursor to 'Up Arrow'. It will retain the current _isCursorPushed state */
- void setUpCursor();
- /** Set the cursor to 'Down Arrow'. It will retain the current _isCursorPushed state */
- void setDownCursor();
-
- /** Set the cursor to 'Idle'. It will retain the current _isCursorPushed state */
- void revertToIdle();
+ /**
+ * Show or hide mouse cursor.
+ *
+ * @param vis Should the cursor be showed (true) or hide (false)
+ */
+ void showMouse(bool vis);
private:
/**
diff --git a/engines/zvision/graphics/effects/fog.cpp b/engines/zvision/graphics/effects/fog.cpp
new file mode 100644
index 0000000000..7b65f60f24
--- /dev/null
+++ b/engines/zvision/graphics/effects/fog.cpp
@@ -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.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/graphics/effects/fog.h"
+
+#include "zvision/zvision.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/scripting/script_manager.h"
+
+namespace ZVision {
+
+FogFx::FogFx(ZVision *engine, uint32 key, Common::Rect region, bool ported, EffectMap *Map, const Common::String &clouds):
+ GraphicsEffect(engine, key, region, ported) {
+
+ _map = Map;
+
+ _r = 0;
+ _g = 0;
+ _b = 0;
+
+ _pos = 0;
+
+ if (_engine->getSearchManager()->hasFile(clouds))
+ _engine->getRenderManager()->readImageToSurface(clouds, _fog);
+ else
+ _engine->getRenderManager()->readImageToSurface("cloud.tga", _fog);
+
+ _mp.resize(_fog.h);
+ for (int16 i = 0; i < _fog.h; i++) {
+ _mp[i].resize(_fog.w);
+ for (int16 j = 0; j < _fog.w; j++)
+ _mp[i][j] = true;
+ }
+
+ for (uint8 i = 0; i < 32; i++)
+ _colorMap[i] = 0;
+}
+
+FogFx::~FogFx() {
+ if (_map)
+ delete _map;
+
+ for (uint16 i = 0; i < _mp.size(); i++)
+ _mp[i].clear();
+ _mp.clear();
+}
+
+const Graphics::Surface *FogFx::draw(const Graphics::Surface &srcSubRect) {
+ _surface.copyFrom(srcSubRect);
+ EffectMap::iterator it = _map->begin();
+
+ uint32 cnt = 0;
+
+ for (uint16 j = 0; j < _surface.h; j++) {
+ uint16 *lineBuf = (uint16 *)_surface.getBasePtr(0, j);
+
+ for (uint16 i = 0; i < _surface.w; i++) {
+ if (it->inEffect) {
+ // Not 100% equivalent, but looks nice and not buggy
+ uint8 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->_resourcePixelFormat.colorToRGB(_colorMap[fogColor & 0x1F], dr, dg, db);
+ uint16 fr = dr + sr;
+ if (fr > 255)
+ fr = 255;
+ uint16 fg = dg + sg;
+ if (fg > 255)
+ fg = 255;
+ uint16 fb = db + sb;
+ if (fb > 255)
+ fb = 255;
+ lineBuf[i] = _engine->_resourcePixelFormat.RGBToColor(fr, fg, fb);
+ }
+ cnt++;
+ if (cnt >= it->count) {
+ it++;
+ cnt = 0;
+ }
+ if (it == _map->end())
+ break;
+ }
+ if (it == _map->end())
+ break;
+ }
+
+ return &_surface;
+}
+
+void FogFx::update() {
+ _pos += _engine->getScriptManager()->getStateValue(StateKey_EF9_Speed);
+ _pos %= _fog.w;
+
+ uint8 dr = _engine->getScriptManager()->getStateValue(StateKey_EF9_R);
+ uint8 dg = _engine->getScriptManager()->getStateValue(StateKey_EF9_G);
+ uint8 db = _engine->getScriptManager()->getStateValue(StateKey_EF9_B);
+ dr = CLIP((int)dr, 0, 31);
+ dg = CLIP((int)dg, 0, 31);
+ db = CLIP((int)db, 0, 31);
+
+ if (dr != _r || dg != _g || db != _b) {
+ if (_r > dr)
+ _r--;
+ else if (_r < dr)
+ _r++;
+
+ if (_g > dg)
+ _g--;
+ else if (_g < dg)
+ _g++;
+
+ if (_b > db)
+ _b--;
+ else if (_b < db)
+ _b++;
+
+ // Not 100% equivalent, but looks nice and not buggy
+
+ _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 = (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);
+ }
+ }
+
+ for (uint16 j = 0; j < _fog.h; j++) {
+ uint16 *pix = (uint16 *)_fog.getBasePtr(0, j);
+
+ for (uint16 i = 0; i < _fog.w; i++) {
+ if (_mp[j][i]) {
+ if ((pix[i] & 0x1F) == 0x1F) {
+ pix[i]--;
+ _mp[j][i] = false;
+ } else
+ pix[i]++;
+ } else {
+ if ((pix[i] & 0x1F) == 0) {
+ pix[i]++;
+ _mp[j][i] = true;
+ } else
+ pix[i]--;
+ }
+ }
+ }
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/graphics/effects/fog.h b/engines/zvision/graphics/effects/fog.h
new file mode 100644
index 0000000000..498347609e
--- /dev/null
+++ b/engines/zvision/graphics/effects/fog.h
@@ -0,0 +1,53 @@
+/* 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_FOG_H
+#define ZVISION_FOG_H
+
+#include "zvision/graphics/graphics_effect.h"
+
+namespace ZVision {
+
+class ZVision;
+
+// 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);
+ ~FogFx();
+
+ const Graphics::Surface *draw(const Graphics::Surface &srcSubRect);
+
+ void update();
+
+private:
+ EffectMap *_map;
+ Graphics::Surface _fog;
+ uint8 _r, _g, _b;
+ int32 _pos;
+ Common::Array< Common::Array< bool > > _mp;
+ uint16 _colorMap[32];
+};
+} // End of namespace ZVision
+
+#endif // ZVISION_FOG_H
diff --git a/engines/zvision/graphics/effects/light.cpp b/engines/zvision/graphics/effects/light.cpp
new file mode 100644
index 0000000000..39341687f8
--- /dev/null
+++ b/engines/zvision/graphics/effects/light.cpp
@@ -0,0 +1,109 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/graphics/effects/light.h"
+
+#include "zvision/zvision.h"
+#include "zvision/graphics/render_manager.h"
+
+namespace ZVision {
+
+LightFx::LightFx(ZVision *engine, uint32 key, Common::Rect region, bool ported, EffectMap *Map, int8 delta, int8 minD, int8 maxD):
+ GraphicsEffect(engine, key, region, ported) {
+ _map = Map;
+ _delta = delta;
+ _up = true;
+ _pos = 0;
+
+ _minD = minD;
+ if (_minD < -delta)
+ _minD = -delta;
+
+ _maxD = maxD;
+ if (_maxD > delta)
+ _maxD = delta;
+}
+
+LightFx::~LightFx() {
+ if (_map)
+ delete _map;
+}
+
+const Graphics::Surface *LightFx::draw(const Graphics::Surface &srcSubRect) {
+ _surface.copyFrom(srcSubRect);
+ EffectMap::iterator it = _map->begin();
+ uint32 cnt = 0;
+
+ uint32 dcolor = 0;
+
+ if (_pos < 0) {
+ uint8 cc = ((-_pos) & 0x1F) << 3;
+ dcolor = _engine->_resourcePixelFormat.RGBToColor(cc, cc, cc);
+ } else {
+ uint8 cc = (_pos & 0x1F) << 3;
+ dcolor = _engine->_resourcePixelFormat.RGBToColor(cc, cc, cc);
+ }
+
+ for (uint16 j = 0; j < _surface.h; j++) {
+ uint16 *lineBuf = (uint16 *)_surface.getBasePtr(0, j);
+
+ for (uint16 i = 0; i < _surface.w; i++) {
+ if (it->inEffect) {
+ if (_pos < 0) {
+ lineBuf[i] -= dcolor;
+ } else {
+ lineBuf[i] += dcolor;
+ }
+ }
+ cnt++;
+ if (cnt >= it->count) {
+ it++;
+ cnt = 0;
+ }
+ if (it == _map->end())
+ break;
+ }
+ if (it == _map->end())
+ break;
+ }
+
+ return &_surface;
+}
+
+void LightFx::update() {
+ if (_up)
+ _pos++;
+ else
+ _pos--;
+
+ if (_pos <= _minD) {
+ _up = !_up;
+ _pos = _minD;
+ } else if (_pos >= _maxD) {
+ _up = !_up;
+ _pos = _maxD;
+ }
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/graphics/effects/light.h b/engines/zvision/graphics/effects/light.h
new file mode 100644
index 0000000000..cd73a585ec
--- /dev/null
+++ b/engines/zvision/graphics/effects/light.h
@@ -0,0 +1,53 @@
+/* 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 LIGHTFX_H_INCLUDED
+#define LIGHTFX_H_INCLUDED
+
+#include "zvision/graphics/graphics_effect.h"
+
+namespace ZVision {
+
+class ZVision;
+
+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);
+ ~LightFx();
+
+ const Graphics::Surface *draw(const Graphics::Surface &srcSubRect);
+
+ void update();
+
+private:
+ EffectMap *_map;
+ int32 _delta;
+ bool _up;
+ int32 _pos;
+
+ int8 _minD;
+ int8 _maxD;
+};
+} // End of namespace ZVision
+
+#endif // LIGHTFX_H_INCLUDED
diff --git a/engines/zvision/graphics/effects/wave.cpp b/engines/zvision/graphics/effects/wave.cpp
new file mode 100644
index 0000000000..d2887b3112
--- /dev/null
+++ b/engines/zvision/graphics/effects/wave.cpp
@@ -0,0 +1,145 @@
+/* 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 "zvision/graphics/effects/wave.h"
+
+#include "zvision/zvision.h"
+#include "zvision/graphics/render_manager.h"
+
+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):
+ GraphicsEffect(engine, key, region, ported) {
+
+ _frame = 0;
+ _frameCount = frames;
+
+ _ampls.resize(_frameCount);
+ _halfWidth = _region.width() / 2;
+ _halfHeight = _region.height() / 2;
+
+ int32 frmsize = _halfWidth * _halfHeight;
+
+ float phase = 0;
+
+ int16 quarterWidth = _halfWidth / 2;
+ int16 quarterHeight = _halfHeight / 2;
+
+ for (int16 i = 0; i < _frameCount; i++) {
+ _ampls[i].resize(frmsize);
+
+ for (int16 y = 0; y < _halfHeight; y++)
+ for (int16 x = 0; x < _halfWidth; x++) {
+ int16 dx = (x - quarterWidth);
+ int16 dy = (y - quarterHeight);
+
+ _ampls[i][x + y * _halfWidth] = (int8)(ampl * sin(sqrt(dx * dx / (float)centerX + dy * dy / (float)centerY) / (-waveln * 3.1415926) + phase));
+ }
+ phase += spd;
+ }
+}
+
+WaveFx::~WaveFx() {
+ for (uint16 i = 0; i < _ampls.size(); i++)
+ _ampls[i].clear();
+ _ampls.clear();
+}
+
+const Graphics::Surface *WaveFx::draw(const Graphics::Surface &srcSubRect) {
+ for (int16 y = 0; y < _halfHeight; y++) {
+ uint16 *abc = (uint16 *)_surface.getBasePtr(0, y);
+ uint16 *abc2 = (uint16 *)_surface.getBasePtr(0, _halfHeight + y);
+ uint16 *abc3 = (uint16 *)_surface.getBasePtr(_halfWidth, y);
+ uint16 *abc4 = (uint16 *)_surface.getBasePtr(_halfWidth, _halfHeight + y);
+
+ for (int16 x = 0; x < _halfWidth; x++) {
+ int8 amnt = _ampls[_frame][x + _halfWidth * y];
+
+ int16 nX = x + amnt;
+ int16 nY = y + amnt;
+
+ if (nX < 0)
+ nX = 0;
+ if (nX >= _region.width())
+ nX = _region.width() - 1;
+ if (nY < 0)
+ nY = 0;
+ if (nY >= _region.height())
+ nY = _region.height() - 1;
+ *abc = *(const uint16 *)srcSubRect.getBasePtr(nX, nY);
+
+ nX = x + amnt + _halfWidth;
+ nY = y + amnt;
+
+ if (nX < 0)
+ nX = 0;
+ if (nX >= _region.width())
+ nX = _region.width() - 1;
+ if (nY < 0)
+ nY = 0;
+ if (nY >= _region.height())
+ nY = _region.height() - 1;
+ *abc3 = *(const uint16 *)srcSubRect.getBasePtr(nX, nY);
+
+ nX = x + amnt;
+ nY = y + amnt + _halfHeight;
+
+ if (nX < 0)
+ nX = 0;
+ if (nX >= _region.width())
+ nX = _region.width() - 1;
+ if (nY < 0)
+ nY = 0;
+ if (nY >= _region.height())
+ nY = _region.height() - 1;
+ *abc2 = *(const uint16 *)srcSubRect.getBasePtr(nX, nY);
+
+ nX = x + amnt + _halfWidth;
+ nY = y + amnt + _halfHeight;
+
+ if (nX < 0)
+ nX = 0;
+ if (nX >= _region.width())
+ nX = _region.width() - 1;
+ if (nY < 0)
+ nY = 0;
+ if (nY >= _region.height())
+ nY = _region.height() - 1;
+ *abc4 = *(const uint16 *)srcSubRect.getBasePtr(nX, nY);
+
+ abc++;
+ abc2++;
+ abc3++;
+ abc4++;
+ }
+ }
+
+ return &_surface;
+}
+
+void WaveFx::update() {
+ _frame = (_frame + 1) % _frameCount;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/graphics/effects/wave.h b/engines/zvision/graphics/effects/wave.h
new file mode 100644
index 0000000000..8e912372d7
--- /dev/null
+++ b/engines/zvision/graphics/effects/wave.h
@@ -0,0 +1,51 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef WAVEFX_H_INCLUDED
+#define WAVEFX_H_INCLUDED
+
+#include "common/array.h"
+#include "zvision/graphics/graphics_effect.h"
+
+namespace ZVision {
+
+class ZVision;
+
+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);
+ ~WaveFx();
+
+ const Graphics::Surface *draw(const Graphics::Surface &srcSubRect);
+
+ void update();
+
+private:
+ int16 _frame;
+ int16 _frameCount;
+ int16 _halfWidth, _halfHeight;
+ Common::Array< Common::Array< int8 > > _ampls;
+};
+} // End of namespace ZVision
+
+#endif // WAVEFX_H_INCLUDED
diff --git a/engines/zvision/graphics/graphics_effect.h b/engines/zvision/graphics/graphics_effect.h
new file mode 100644
index 0000000000..bfa266b11d
--- /dev/null
+++ b/engines/zvision/graphics/graphics_effect.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 GRAPHICS_EFFECT_H_INCLUDED
+#define GRAPHICS_EFFECT_H_INCLUDED
+
+#include "common/rect.h"
+#include "common/list.h"
+#include "graphics/surface.h"
+
+#include "zvision/zvision.h"
+
+namespace ZVision {
+
+class ZVision;
+
+class GraphicsEffect {
+public:
+
+ 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 ~GraphicsEffect() {}
+
+ uint32 getKey() {
+ return _key;
+ }
+
+ Common::Rect getRegion() {
+ return _region;
+ }
+
+ bool isPort() {
+ return _ported;
+ }
+
+ virtual const Graphics::Surface *draw(const Graphics::Surface &srcSubRect) {
+ return &_surface;
+ }
+
+ virtual void update() {}
+
+protected:
+ ZVision *_engine;
+ uint32 _key;
+ Common::Rect _region;
+ bool _ported;
+ Graphics::Surface _surface;
+
+// Static member functions
+public:
+
+};
+
+struct EffectMapUnit {
+ uint32 count;
+ bool inEffect;
+};
+
+typedef Common::List<EffectMapUnit> EffectMap;
+
+} // End of namespace ZVision
+
+#endif // GRAPHICS_EFFECT_H_INCLUDED
diff --git a/engines/zvision/graphics/render_manager.cpp b/engines/zvision/graphics/render_manager.cpp
index aed30ea12c..ce0a02a1ad 100644
--- a/engines/zvision/graphics/render_manager.cpp
+++ b/engines/zvision/graphics/render_manager.cpp
@@ -1,30 +1,33 @@
/* 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.
- *
- */
+*
+* 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 "zvision/zvision.h"
#include "zvision/graphics/render_manager.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/text/text.h"
-#include "zvision/utility/lzss_read_stream.h"
+#include "zvision/file/lzss_read_stream.h"
#include "common/file.h"
#include "common/system.h"
@@ -34,200 +37,153 @@
#include "image/tga.h"
-
namespace ZVision {
-RenderManager::RenderManager(OSystem *system, uint32 windowWidth, uint32 windowHeight, const Common::Rect workingWindow, const Graphics::PixelFormat pixelFormat)
- : _system(system),
- _workingWidth(workingWindow.width()),
- _workingHeight(workingWindow.height()),
- _screenCenterX(_workingWidth / 2),
- _screenCenterY(_workingHeight / 2),
- _workingWindow(workingWindow),
- _pixelFormat(pixelFormat),
- _backgroundWidth(0),
- _backgroundHeight(0),
- _backgroundInverseVelocity(0),
- _backgroundOffset(0, 0),
- _accumulatedVelocityMilliseconds(0),
- _renderTable(_workingWidth, _workingHeight) {
-
- _workingWindowBuffer.create(_workingWidth, _workingHeight, _pixelFormat);
- _backBuffer.create(windowWidth, windowHeight, pixelFormat);
+RenderManager::RenderManager(ZVision *engine, uint32 windowWidth, uint32 windowHeight, const Common::Rect workingWindow, const Graphics::PixelFormat pixelFormat, bool doubleFPS)
+ : _engine(engine),
+ _system(engine->_system),
+ _screenCenterX(_workingWindow.width() / 2),
+ _screenCenterY(_workingWindow.height() / 2),
+ _workingWindow(workingWindow),
+ _pixelFormat(pixelFormat),
+ _backgroundWidth(0),
+ _backgroundHeight(0),
+ _backgroundOffset(0),
+ _renderTable(_workingWindow.width(), _workingWindow.height()),
+ _doubleFPS(doubleFPS),
+ _subid(0) {
+
+ _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);
+
+ _menuArea = Common::Rect(0, 0, windowWidth, workingWindow.top);
+
+ initSubArea(windowWidth, windowHeight, workingWindow);
}
RenderManager::~RenderManager() {
- _workingWindowBuffer.free();
- _currentBackground.free();
- _backBuffer.free();
-
- for (AlphaEntryMap::iterator iter = _alphaDataEntries.begin(); iter != _alphaDataEntries.end(); ++iter) {
- iter->_value.data->free();
- delete iter->_value.data;
- }
-}
-
-void RenderManager::update(uint deltaTimeInMillis) {
- // An inverse velocity of 0 would be infinitely fast, so we'll let 0 mean no velocity.
- if (_backgroundInverseVelocity != 0) {
- _accumulatedVelocityMilliseconds += deltaTimeInMillis;
-
- uint absVelocity = uint(abs(_backgroundInverseVelocity));
-
- int numberOfSteps = 0;
- while (_accumulatedVelocityMilliseconds >= absVelocity) {
- _accumulatedVelocityMilliseconds -= absVelocity;
- numberOfSteps++;
- }
-
- // Choose the direction of movement using the sign of the velocity
- moveBackground(_backgroundInverseVelocity < 0 ? -numberOfSteps : numberOfSteps);
- }
+ _currentBackgroundImage.free();
+ _backgroundSurface.free();
+ _effectSurface.free();
+ _warpedSceneSurface.free();
+ _menuSurface.free();
+ _subtitleSurface.free();
}
-void RenderManager::renderBackbufferToScreen() {
- if (!_workingWindowDirtyRect.isEmpty()) {
- RenderTable::RenderState state = _renderTable.getRenderState();
- if (state == RenderTable::PANORAMA || state == RenderTable::TILT) {
- _renderTable.mutateImage((uint16 *)_workingWindowBuffer.getPixels(), (uint16 *)_backBuffer.getBasePtr(_workingWindow.left + _workingWindowDirtyRect.left, _workingWindow.top + _workingWindowDirtyRect.top), _backBuffer.w, _workingWindowDirtyRect);
- } else {
- _backBuffer.copyRectToSurface(_workingWindowBuffer.getBasePtr(_workingWindowDirtyRect.left, _workingWindowDirtyRect.top), _workingWindowBuffer.pitch, _workingWindow.left + _workingWindowDirtyRect.left, _workingWindow.top + _workingWindowDirtyRect.top, _workingWindowDirtyRect.width(), _workingWindowDirtyRect.height());
- }
-
- // Translate the working window dirty rect to screen coords
- _workingWindowDirtyRect.translate(_workingWindow.left, _workingWindow.top);
- // Then extend the backbuffer dirty rect to contain it
- if (_backBufferDirtyRect.isEmpty()) {
- _backBufferDirtyRect = _workingWindowDirtyRect;
- } else {
- _backBufferDirtyRect.extend(_workingWindowDirtyRect);
- }
-
- // Clear the dirty rect
- _workingWindowDirtyRect = Common::Rect();
- }
-
- // TODO: Add menu rendering
+void RenderManager::renderSceneToScreen() {
+ Graphics::Surface *out = &_warpedSceneSurface;
+ Graphics::Surface *in = &_backgroundSurface;
+ Common::Rect outWndDirtyRect;
- // Render alpha entries
- processAlphaEntries();
+ // If we have graphical effects, we apply them using a temporary buffer
+ if (!_effects.empty()) {
+ bool copied = false;
+ Common::Rect windowRect(_workingWindow.width(), _workingWindow.height());
- if (!_backBufferDirtyRect.isEmpty()) {
- _system->copyRectToScreen(_backBuffer.getBasePtr(_backBufferDirtyRect.left, _backBufferDirtyRect.top), _backBuffer.pitch, _backBufferDirtyRect.left, _backBufferDirtyRect.top, _backBufferDirtyRect.width(), _backBufferDirtyRect.height());
- _backBufferDirtyRect = Common::Rect();
- }
-}
+ for (EffectsList::iterator it = _effects.begin(); it != _effects.end(); it++) {
+ Common::Rect rect = (*it)->getRegion();
+ Common::Rect screenSpaceLocation = rect;
-void RenderManager::processAlphaEntries() {
- // TODO: Add dirty rectangling support. AKA only draw an entry if the _backbufferDirtyRect intersects/contains the entry Rect
-
- for (AlphaEntryMap::iterator iter = _alphaDataEntries.begin(); iter != _alphaDataEntries.end(); ++iter) {
- uint32 destOffset = 0;
- uint32 sourceOffset = 0;
- uint16 *backbufferPtr = (uint16 *)_backBuffer.getBasePtr(iter->_value.destX + _workingWindow.left, iter->_value.destY + _workingWindow.top);
- uint16 *entryPtr = (uint16 *)iter->_value.data->getPixels();
+ if ((*it)->isPort()) {
+ screenSpaceLocation = transformBackgroundSpaceRectToScreenSpace(screenSpaceLocation);
+ }
- for (int32 y = 0; y < iter->_value.height; ++y) {
- for (int32 x = 0; x < iter->_value.width; ++x) {
- uint16 color = entryPtr[sourceOffset + x];
- if (color != iter->_value.alphaColor) {
- backbufferPtr[destOffset + x] = color;
+ if (windowRect.intersects(screenSpaceLocation)) {
+ if (!copied) {
+ copied = true;
+ _effectSurface.copyFrom(_backgroundSurface);
+ in = &_effectSurface;
+ }
+ const Graphics::Surface *post;
+ if ((*it)->isPort())
+ post = (*it)->draw(_currentBackgroundImage.getSubArea(rect));
+ else
+ 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 {
+ _backgroundSurfaceDirtyRect.extend(screenSpaceLocation);
}
}
-
- destOffset += _backBuffer.w;
- sourceOffset += iter->_value.width;
}
+ }
- if (_backBufferDirtyRect.isEmpty()) {
- _backBufferDirtyRect = Common::Rect(iter->_value.destX + _workingWindow.left, iter->_value.destY + _workingWindow.top, iter->_value.destX + _workingWindow.left + iter->_value.width, iter->_value.destY + _workingWindow.top + iter->_value.height);
- } else {
- _backBufferDirtyRect.extend(Common::Rect(iter->_value.destX + _workingWindow.left, iter->_value.destY + _workingWindow.top, iter->_value.destX + _workingWindow.left + iter->_value.width, iter->_value.destY + _workingWindow.top + iter->_value.height));
+ RenderTable::RenderState state = _renderTable.getRenderState();
+ if (state == RenderTable::PANORAMA || state == RenderTable::TILT) {
+ if (!_backgroundSurfaceDirtyRect.isEmpty()) {
+ _renderTable.mutateImage(&_warpedSceneSurface, in);
+ out = &_warpedSceneSurface;
+ outWndDirtyRect = Common::Rect(_workingWindow.width(), _workingWindow.height());
}
+ } else {
+ out = in;
+ outWndDirtyRect = _backgroundSurfaceDirtyRect;
}
-}
-void RenderManager::clearWorkingWindowTo555Color(uint16 color) {
- uint32 workingWindowSize = _workingWidth * _workingHeight;
- byte r, g, b;
- Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0).colorToRGB(color, r, g, b);
- uint16 colorIn565 = _pixelFormat.RGBToColor(r, g, b);
- uint16 *bufferPtr = (uint16 *)_workingWindowBuffer.getPixels();
-
- for (uint32 i = 0; i < workingWindowSize; ++i) {
- bufferPtr[i] = colorIn565;
+ if (!outWndDirtyRect.isEmpty()) {
+ 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::renderSubRectToScreen(Graphics::Surface &surface, int16 destinationX, int16 destinationY, bool wrap) {
- int16 subRectX = 0;
- int16 subRectY = 0;
-
- // Take care of negative destinations
- if (destinationX < 0) {
- subRectX = -destinationX;
- destinationX = 0;
- } else if (destinationX >= surface.w) {
- // Take care of extreme positive destinations
- destinationX -= surface.w;
- }
-
- // Take care of negative destinations
- if (destinationY < 0) {
- subRectY = -destinationY;
- destinationY = 0;
- } else if (destinationY >= surface.h) {
- // Take care of extreme positive destinations
- destinationY -= surface.h;
- }
-
- if (wrap) {
- _backgroundWidth = surface.w;
- _backgroundHeight = surface.h;
-
- if (destinationX > 0) {
- // Move destinationX to 0
- subRectX = surface.w - destinationX;
- destinationX = 0;
- }
-
- if (destinationY > 0) {
- // Move destinationY to 0
- subRectY = surface.h - destinationY;
- destinationY = 0;
- }
- }
+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;
+}
- // Clip subRect to working window bounds
- Common::Rect subRect(subRectX, subRectY, subRectX + _workingWidth, subRectY + _workingHeight);
+void RenderManager::renderImageToBackground(const Common::String &fileName, int16 destX, int16 destY) {
+ Graphics::Surface surface;
+ readImageToSurface(fileName, surface);
- if (!wrap) {
- // Clip to image bounds
- subRect.clip(surface.w, surface.h);
- }
+ blitSurfaceToBkg(surface, destX, destY);
+ surface.free();
+}
- // Check destRect for validity
- if (!subRect.isValidRect() || subRect.isEmpty())
- return;
+void RenderManager::renderImageToBackground(const Common::String &fileName, int16 destX, int16 destY, uint32 keycolor) {
+ Graphics::Surface surface;
+ readImageToSurface(fileName, surface);
- copyRectToWorkingWindow((const uint16 *)surface.getBasePtr(subRect.left, subRect.top), destinationX, destinationY, surface.w, subRect.width(), subRect.height());
+ blitSurfaceToBkg(surface, destX, destY, keycolor);
+ surface.free();
}
-void RenderManager::renderImageToScreen(const Common::String &fileName, int16 destinationX, int16 destinationY, bool wrap) {
+void RenderManager::renderImageToBackground(const Common::String &fileName, int16 destX, int16 destY, int16 keyX, int16 keyY) {
Graphics::Surface surface;
readImageToSurface(fileName, surface);
- renderSubRectToScreen(surface, destinationX, destinationY, wrap);
-}
+ uint16 keycolor = *(uint16 *)surface.getBasePtr(keyX, keyY);
-void RenderManager::renderImageToScreen(Graphics::Surface &surface, int16 destinationX, int16 destinationY, bool wrap) {
- renderSubRectToScreen(surface, destinationX, destinationY, wrap);
+ blitSurfaceToBkg(surface, destX, destY, keycolor);
+ surface.free();
}
void RenderManager::readImageToSurface(const Common::String &fileName, Graphics::Surface &destination) {
+ bool isTransposed = _renderTable.getRenderState() == RenderTable::PANORAMA;
+ readImageToSurface(fileName, destination, isTransposed);
+}
+
+void RenderManager::readImageToSurface(const Common::String &fileName, Graphics::Surface &destination, bool transposed) {
Common::File file;
- if (!file.open(fileName)) {
+ if (!_engine->getSearchManager()->openFile(file, fileName)) {
warning("Could not open file %s", fileName.c_str());
return;
}
@@ -240,10 +196,8 @@ void RenderManager::readImageToSurface(const Common::String &fileName, Graphics:
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;
+ destination.format = _engine->_resourcePixelFormat;
bool isTGZ;
@@ -252,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;
@@ -279,7 +237,7 @@ void RenderManager::readImageToSurface(const Common::String &fileName, Graphics:
}
// Flip the width and height if transposed
- if (isTransposed) {
+ if (transposed) {
uint16 temp = imageHeight;
imageHeight = imageWidth;
imageWidth = temp;
@@ -288,12 +246,12 @@ 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
// Otherwise, just do a simple copy
- if (isTransposed) {
+ if (transposed) {
uint16 *dest = (uint16 *)destination.getPixels();
for (uint32 y = 0; y < imageHeight; ++y) {
@@ -304,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
@@ -313,214 +271,947 @@ void RenderManager::readImageToSurface(const Common::String &fileName, Graphics:
} else {
tga.destroy();
}
-
- // Convert in place to RGB 565 from RGB 555
- destination.convertToInPlace(_pixelFormat);
}
-void RenderManager::copyRectToWorkingWindow(const uint16 *buffer, int32 destX, int32 destY, int32 imageWidth, int32 width, int32 height) {
- uint32 destOffset = 0;
- uint32 sourceOffset = 0;
- uint16 *workingWindowBufferPtr = (uint16 *)_workingWindowBuffer.getBasePtr(destX, destY);
+const Common::Point RenderManager::screenSpaceToImageSpace(const Common::Point &point) {
+ if (_workingWindow.contains(point)) {
+ // Convert from screen space to working window space
+ Common::Point newPoint(point - Common::Point(_workingWindow.left, _workingWindow.top));
+
+ RenderTable::RenderState state = _renderTable.getRenderState();
+ if (state == RenderTable::PANORAMA || state == RenderTable::TILT) {
+ newPoint = _renderTable.convertWarpedCoordToFlatCoord(newPoint);
+ }
- for (int32 y = 0; y < height; ++y) {
- for (int32 x = 0; x < width; ++x) {
- workingWindowBufferPtr[destOffset + x] = buffer[sourceOffset + x];
+ if (state == RenderTable::PANORAMA) {
+ newPoint += (Common::Point(_backgroundOffset - _screenCenterX, 0));
+ } else if (state == RenderTable::TILT) {
+ newPoint += (Common::Point(0, _backgroundOffset - _screenCenterY));
}
- destOffset += _workingWidth;
- sourceOffset += imageWidth;
+ if (_backgroundWidth)
+ newPoint.x %= _backgroundWidth;
+ if (_backgroundHeight)
+ newPoint.y %= _backgroundHeight;
+
+ if (newPoint.x < 0)
+ newPoint.x += _backgroundWidth;
+ if (newPoint.y < 0)
+ newPoint.y += _backgroundHeight;
+
+ return newPoint;
+ } else {
+ return Common::Point(0, 0);
}
+}
+
+RenderTable *RenderManager::getRenderTable() {
+ return &_renderTable;
+}
+
+void RenderManager::setBackgroundImage(const Common::String &fileName) {
+ 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 (_backgroundOffset != offset)
+ _backgroundDirtyRect = Common::Rect(_backgroundWidth, _backgroundHeight);
+ _backgroundOffset = offset;
- if (_workingWindowDirtyRect.isEmpty()) {
- _workingWindowDirtyRect = Common::Rect(destX, destY, destX + width, destY + height);
+ _engine->getScriptManager()->setStateValue(StateKey_ViewPos, offset);
+}
+
+uint32 RenderManager::getCurrentBackgroundOffset() {
+ RenderTable::RenderState state = _renderTable.getRenderState();
+
+ if (state == RenderTable::PANORAMA) {
+ return _backgroundOffset;
+ } else if (state == RenderTable::TILT) {
+ return _backgroundOffset;
} else {
- _workingWindowDirtyRect.extend(Common::Rect(destX, destY, destX + width, destY + height));
+ return 0;
+ }
+}
+
+Graphics::Surface *RenderManager::tranposeSurface(const Graphics::Surface *surface) {
+ Graphics::Surface *tranposedSurface = new Graphics::Surface();
+ tranposedSurface->create(surface->h, surface->w, surface->format);
+
+ const uint16 *source = (const uint16 *)surface->getPixels();
+ uint16 *dest = (uint16 *)tranposedSurface->getPixels();
+
+ for (uint32 y = 0; y < tranposedSurface->h; ++y) {
+ uint32 columnIndex = y * tranposedSurface->w;
+
+ for (uint32 x = 0; x < tranposedSurface->w; ++x) {
+ dest[columnIndex + x] = source[x * surface->w + y];
+ }
}
- // TODO: Remove this from release. It's here to make sure code that uses this function clips their destinations correctly
- assert(_workingWindowDirtyRect.width() <= _workingWidth && _workingWindowDirtyRect.height() <= _workingHeight);
+ return tranposedSurface;
}
-void RenderManager::copyRectToWorkingWindow(const uint16 *buffer, int32 destX, int32 destY, int32 imageWidth, int32 width, int32 height, int16 alphaColor, uint32 idNumber) {
- AlphaDataEntry entry;
- entry.alphaColor = alphaColor;
- entry.data = new Graphics::Surface();
- entry.data->create(width, height, _pixelFormat);
- entry.destX = destX;
- entry.destY = destY;
- entry.width = width;
- entry.height = height;
+void RenderManager::scaleBuffer(const void *src, void *dst, uint32 srcWidth, uint32 srcHeight, byte bytesPerPixel, uint32 dstWidth, uint32 dstHeight) {
+ assert(bytesPerPixel == 1 || bytesPerPixel == 2);
- uint32 sourceOffset = 0;
- uint32 destOffset = 0;
- uint16 *surfacePtr = (uint16 *)entry.data->getPixels();
+ const float xscale = (float)srcWidth / (float)dstWidth;
+ const float yscale = (float)srcHeight / (float)dstHeight;
- for (int32 y = 0; y < height; ++y) {
- for (int32 x = 0; x < width; ++x) {
- surfacePtr[destOffset + x] = buffer[sourceOffset + x];
+ if (bytesPerPixel == 1) {
+ const byte *srcPtr = (const byte *)src;
+ byte *dstPtr = (byte *)dst;
+ for (uint32 y = 0; y < dstHeight; ++y) {
+ for (uint32 x = 0; x < dstWidth; ++x) {
+ *dstPtr = srcPtr[(int)(x * xscale) + (int)(y * yscale) * srcWidth];
+ dstPtr++;
+ }
}
+ } else if (bytesPerPixel == 2) {
+ const uint16 *srcPtr = (const uint16 *)src;
+ uint16 *dstPtr = (uint16 *)dst;
+ for (uint32 y = 0; y < dstHeight; ++y) {
+ for (uint32 x = 0; x < dstWidth; ++x) {
+ *dstPtr = srcPtr[(int)(x * xscale) + (int)(y * yscale) * srcWidth];
+ dstPtr++;
+ }
+ }
+ }
+}
+
+void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, const Common::Rect &_srcRect , Graphics::Surface &dst, int _x, int _y) {
+ Common::Rect srcRect = _srcRect;
+ if (srcRect.isEmpty())
+ srcRect = Common::Rect(src.w, src.h);
+ srcRect.clip(src.w, src.h);
+ Common::Rect dstRect = Common::Rect(-_x + srcRect.left , -_y + srcRect.top, -_x + srcRect.left + dst.w, -_y + srcRect.top + dst.h);
+ srcRect.clip(dstRect);
+
+ 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 *)srcAdapted->getBasePtr(srcRect.left, srcRect.top);
+
+ int xx = _x;
+ int yy = _y;
+
+ if (xx < 0)
+ xx = 0;
+ if (yy < 0)
+ yy = 0;
+
+ if (_x >= dst.w || _y >= dst.h) {
+ srcAdapted->free();
+ delete srcAdapted;
+ return;
+ }
+
+ byte *dstBuffer = (byte *)dst.getBasePtr(xx, yy);
- destOffset += width;
- sourceOffset += imageWidth;
+ int32 w = srcRect.width();
+ int32 h = srcRect.height();
+
+ for (int32 y = 0; y < h; y++) {
+ memcpy(dstBuffer, srcBuffer, w * srcAdapted->format.bytesPerPixel);
+ srcBuffer += srcAdapted->pitch;
+ dstBuffer += dst.pitch;
}
- _alphaDataEntries[idNumber] = entry;
+ srcAdapted->free();
+ delete srcAdapted;
}
-Common::Rect RenderManager::renderTextToWorkingWindow(uint32 idNumber, const Common::String &text, TruetypeFont *font, int destX, int destY, uint16 textColor, int maxWidth, int maxHeight, Graphics::TextAlign align, bool wrap) {
- AlphaDataEntry entry;
- entry.alphaColor = 0;
- entry.destX = destX;
- entry.destY = destY;
+void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, const Common::Rect &_srcRect , Graphics::Surface &dst, int _x, int _y, uint32 colorkey) {
+ Common::Rect srcRect = _srcRect;
+ if (srcRect.isEmpty())
+ srcRect = Common::Rect(src.w, src.h);
+ srcRect.clip(src.w, src.h);
+ Common::Rect dstRect = Common::Rect(-_x + srcRect.left , -_y + srcRect.top, -_x + srcRect.left + dst.w, -_y + srcRect.top + dst.h);
+ srcRect.clip(dstRect);
+
+ if (srcRect.isEmpty() || !srcRect.isValidRect())
+ return;
- // Draw the text to the working window
- entry.data = font->drawTextToSurface(text, textColor, maxWidth, maxHeight, align, wrap);
- entry.width = entry.data->w;
- entry.height = entry.data->h;
+ Graphics::Surface *srcAdapted = src.convertTo(dst.format);
+ uint32 keycolor = colorkey & ((1 << (src.format.bytesPerPixel << 3)) - 1);
- _alphaDataEntries[idNumber] = entry;
+ // Copy srcRect from src surface to dst surface
+ const byte *srcBuffer = (const byte *)srcAdapted->getBasePtr(srcRect.left, srcRect.top);
- return Common::Rect(destX, destY, destX + entry.width, destY + entry.height);
-}
+ int xx = _x;
+ int yy = _y;
-const Common::Point RenderManager::screenSpaceToImageSpace(const Common::Point &point) {
- // Convert from screen space to working window space
- Common::Point newPoint(point - Common::Point(_workingWindow.left, _workingWindow.top));
+ if (xx < 0)
+ xx = 0;
+ if (yy < 0)
+ yy = 0;
- RenderTable::RenderState state = _renderTable.getRenderState();
- if (state == RenderTable::PANORAMA || state == RenderTable::TILT) {
- newPoint = _renderTable.convertWarpedCoordToFlatCoord(newPoint);
+ if (_x >= dst.w || _y >= dst.h) {
+ srcAdapted->free();
+ delete srcAdapted;
+ return;
}
- if (state == RenderTable::PANORAMA) {
- newPoint -= (Common::Point(_screenCenterX, 0) - _backgroundOffset);
- } else if (state == RenderTable::TILT) {
- newPoint -= (Common::Point(0, _screenCenterY) - _backgroundOffset);
+ byte *dstBuffer = (byte *)dst.getBasePtr(xx, yy);
+
+ int32 w = srcRect.width();
+ int32 h = srcRect.height();
+
+ for (int32 y = 0; y < h; y++) {
+ 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)
+ *dstTemp = *srcTemp;
+ srcTemp++;
+ dstTemp++;
+ }
+ }
+ break;
+
+ case 2: {
+ const uint16 *srcTemp = (const uint16 *)srcBuffer;
+ uint16 *dstTemp = (uint16 *)dstBuffer;
+ for (int32 x = 0; x < w; x++) {
+ if (*srcTemp != keycolor)
+ *dstTemp = *srcTemp;
+ srcTemp++;
+ dstTemp++;
+ }
+ }
+ break;
+
+ case 4: {
+ const uint32 *srcTemp = (const uint32 *)srcBuffer;
+ uint32 *dstTemp = (uint32 *)dstBuffer;
+ for (int32 x = 0; x < w; x++) {
+ if (*srcTemp != keycolor)
+ *dstTemp = *srcTemp;
+ srcTemp++;
+ dstTemp++;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ srcBuffer += srcAdapted->pitch;
+ dstBuffer += dst.pitch;
}
- if (newPoint.x < 0)
- newPoint.x += _backgroundWidth;
- else if (newPoint.x >= _backgroundWidth)
- newPoint.x -= _backgroundWidth;
- if (newPoint.y < 0)
- newPoint.y += _backgroundHeight;
- else if (newPoint.y >= _backgroundHeight)
- newPoint.y -= _backgroundHeight;
+ srcAdapted->free();
+ delete srcAdapted;
+}
+
+void RenderManager::blitSurfaceToBkg(const Graphics::Surface &src, int x, int y, int32 colorkey) {
+ Common::Rect empt;
+ if (colorkey >= 0)
+ blitSurfaceToSurface(src, empt, _currentBackgroundImage, x, y, colorkey);
+ else
+ blitSurfaceToSurface(src, empt, _currentBackgroundImage, x, y);
+ Common::Rect dirty(src.w, src.h);
+ dirty.translate(x, y);
+ if (_backgroundDirtyRect.isEmpty())
+ _backgroundDirtyRect = dirty;
+ else
+ _backgroundDirtyRect.extend(dirty);
+}
+
+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 {
+ 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, colorkey);
+ tmp->free();
+ delete tmp;
+ }
+}
- return newPoint;
+void RenderManager::blitSurfaceToMenu(const Graphics::Surface &src, int x, int y, int32 colorkey) {
+ Common::Rect empt;
+ if (colorkey >= 0)
+ blitSurfaceToSurface(src, empt, _menuSurface, x, y, colorkey);
+ else
+ blitSurfaceToSurface(src, empt, _menuSurface, x, y);
+ Common::Rect dirty(src.w, src.h);
+ dirty.translate(x, y);
+ if (_menuSurfaceDirtyRect.isEmpty())
+ _menuSurfaceDirtyRect = dirty;
+ else
+ _menuSurfaceDirtyRect.extend(dirty);
}
-const Common::Point RenderManager::imageSpaceToWorkingWindowSpace(const Common::Point &point) {
- Common::Point newPoint(point);
+Graphics::Surface *RenderManager::getBkgRect(Common::Rect &rect) {
+ Common::Rect dst = rect;
+ dst.clip(_backgroundWidth, _backgroundHeight);
+
+ if (dst.isEmpty() || !dst.isValidRect())
+ return NULL;
+ Graphics::Surface *srf = new Graphics::Surface;
+ srf->create(dst.width(), dst.height(), _currentBackgroundImage.format);
+
+ srf->copyRectToSurface(_currentBackgroundImage, 0, 0, Common::Rect(dst));
+
+ return srf;
+}
+
+Graphics::Surface *RenderManager::loadImage(Common::String file) {
+ Graphics::Surface *tmp = new Graphics::Surface;
+ readImageToSurface(file, *tmp);
+ return tmp;
+}
+
+Graphics::Surface *RenderManager::loadImage(Common::String file, bool transposed) {
+ Graphics::Surface *tmp = new Graphics::Surface;
+ readImageToSurface(file, *tmp, transposed);
+ return tmp;
+}
+
+void RenderManager::prepareBackground() {
+ _backgroundDirtyRect.clip(_backgroundWidth, _backgroundHeight);
RenderTable::RenderState state = _renderTable.getRenderState();
+
if (state == RenderTable::PANORAMA) {
- newPoint += (Common::Point(_screenCenterX, 0) - _backgroundOffset);
+ // 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);
+
+ // Render the visible portion
+ if (!drawRect.isEmpty()) {
+ blitSurfaceToSurface(_currentBackgroundImage, drawRect, _backgroundSurface, _screenCenterX - _backgroundOffset + drawRect.left, drawRect.top);
+ }
+
+ // Mark the dirty portion of the surface
+ _backgroundSurfaceDirtyRect = _backgroundDirtyRect;
+ _backgroundSurfaceDirtyRect.translate(_screenCenterX - _backgroundOffset, 0);
+
+ // 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(_currentBackgroundImage, drawRect, _backgroundSurface, _screenCenterX - (_backgroundOffset + _backgroundWidth) + drawRect.left, drawRect.top);
+
+ Common::Rect tmp = _backgroundDirtyRect;
+ tmp.translate(_screenCenterX - (_backgroundOffset + _backgroundWidth), 0);
+ if (!tmp.isEmpty())
+ _backgroundSurfaceDirtyRect.extend(tmp);
+
+ } else if (_backgroundWidth - _backgroundOffset < _screenCenterX) {
+ viewPort.moveTo(-(_screenCenterX + _backgroundWidth - _backgroundOffset), 0);
+ drawRect = _backgroundDirtyRect;
+ drawRect.clip(viewPort);
+
+ if (!drawRect.isEmpty())
+ blitSurfaceToSurface(_currentBackgroundImage, drawRect, _backgroundSurface, _screenCenterX + _backgroundWidth - _backgroundOffset + drawRect.left, drawRect.top);
+
+ Common::Rect tmp = _backgroundDirtyRect;
+ tmp.translate(_screenCenterX + _backgroundWidth - _backgroundOffset, 0);
+ if (!tmp.isEmpty())
+ _backgroundSurfaceDirtyRect.extend(tmp);
+
+ }
} else if (state == RenderTable::TILT) {
- newPoint += (Common::Point(0, _screenCenterY) - _backgroundOffset);
+ // 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(_currentBackgroundImage, drawRect, _backgroundSurface, drawRect.left, _screenCenterY - _backgroundOffset + drawRect.top);
+
+ // Mark the dirty portion of the surface
+ _backgroundSurfaceDirtyRect = _backgroundDirtyRect;
+ _backgroundSurfaceDirtyRect.translate(0, _screenCenterY - _backgroundOffset);
+
+ } else {
+ if (!_backgroundDirtyRect.isEmpty())
+ blitSurfaceToSurface(_currentBackgroundImage, _backgroundDirtyRect, _backgroundSurface, _backgroundDirtyRect.left, _backgroundDirtyRect.top);
+ _backgroundSurfaceDirtyRect = _backgroundDirtyRect;
}
- return newPoint;
+ // Clear the dirty rect since everything is clean now
+ _backgroundDirtyRect = Common::Rect();
+
+ _backgroundSurfaceDirtyRect.clip(_workingWindow.width(), _workingWindow.height());
+}
+
+void RenderManager::clearMenuSurface() {
+ _menuSurfaceDirtyRect = Common::Rect(0, 0, _menuSurface.w, _menuSurface.h);
+ _menuSurface.fillRect(_menuSurfaceDirtyRect, 0);
}
-bool RenderManager::clipRectToWorkingWindow(Common::Rect &rect) {
- if (!_workingWindow.contains(rect)) {
- return false;
+void RenderManager::clearMenuSurface(const Common::Rect &r) {
+ if (_menuSurfaceDirtyRect.isEmpty())
+ _menuSurfaceDirtyRect = r;
+ else
+ _menuSurfaceDirtyRect.extend(r);
+ _menuSurface.fillRect(r, 0);
+}
+
+void RenderManager::renderMenuToScreen() {
+ 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();
}
+}
- // We can't clip against the actual working window rect because it's in screen space
- // But rect is in working window space
- rect.clip(_workingWidth, _workingHeight);
- return true;
+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);
}
-RenderTable *RenderManager::getRenderTable() {
- return &_renderTable;
+uint16 RenderManager::createSubArea(const Common::Rect &area) {
+ _subid++;
+
+ OneSubtitle sub;
+ sub.redraw = false;
+ sub.timer = -1;
+ sub.todelete = false;
+ sub.r = area;
+
+ _subsList[_subid] = sub;
+
+ return _subid;
}
-void RenderManager::setBackgroundImage(const Common::String &fileName) {
- readImageToSurface(fileName, _currentBackground);
+uint16 RenderManager::createSubArea() {
+ Common::Rect r(_subtitleArea.left, _subtitleArea.top, _subtitleArea.right, _subtitleArea.bottom);
+ r.translate(-_workingWindow.left, -_workingWindow.top);
+ return createSubArea(r);
+}
- moveBackground(0);
+void RenderManager::deleteSubArea(uint16 id) {
+ if (_subsList.contains(id))
+ _subsList[id].todelete = true;
}
-void RenderManager::setBackgroundPosition(int offset) {
- RenderTable::RenderState state = _renderTable.getRenderState();
- if (state == RenderTable::TILT) {
- _backgroundOffset.x = 0;
- _backgroundOffset.y = offset;
- } else if (state == RenderTable::PANORAMA) {
- _backgroundOffset.x = offset;
- _backgroundOffset.y = 0;
- } else {
- _backgroundOffset.x = 0;
- _backgroundOffset.y = 0;
+void RenderManager::deleteSubArea(uint16 id, int16 delay) {
+ if (_subsList.contains(id))
+ _subsList[id].timer = delay;
+}
+
+void RenderManager::updateSubArea(uint16 id, const Common::String &txt) {
+ if (_subsList.contains(id)) {
+ OneSubtitle *sub = &_subsList[id];
+ sub->txt = txt;
+ sub->redraw = true;
}
}
-void RenderManager::setBackgroundVelocity(int velocity) {
- // setBackgroundVelocity(0) will be called quite often, so make sure
- // _backgroundInverseVelocity isn't already 0 to prevent an extraneous assignment
- if (velocity == 0) {
- if (_backgroundInverseVelocity != 0) {
- _backgroundInverseVelocity = 0;
+void RenderManager::processSubs(uint16 deltatime) {
+ bool redraw = false;
+ for (SubtitleMap::iterator it = _subsList.begin(); it != _subsList.end(); it++) {
+ if (it->_value.timer != -1) {
+ it->_value.timer -= deltatime;
+ if (it->_value.timer <= 0)
+ it->_value.todelete = true;
+ }
+ if (it->_value.todelete) {
+ _subsList.erase(it);
+ redraw = true;
+ } else if (it->_value.redraw) {
+ redraw = true;
}
- } else {
- _backgroundInverseVelocity = 1000 / velocity;
}
-}
-void RenderManager::moveBackground(int offset) {
- RenderTable::RenderState state = _renderTable.getRenderState();
- if (state == RenderTable::TILT) {
- _backgroundOffset += Common::Point(0, offset);
+ if (redraw) {
+ _subtitleSurface.fillRect(Common::Rect(_subtitleSurface.w, _subtitleSurface.h), 0);
+
+ for (SubtitleMap::iterator it = _subsList.begin(); it != _subsList.end(); it++) {
+ OneSubtitle *sub = &it->_value;
+ if (sub->txt.size()) {
+ 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;
+ }
- _backgroundOffset.y = CLIP<int16>(_backgroundOffset.y, _screenCenterY, (int16)_backgroundHeight - _screenCenterY);
+ Common::Rect rect(
+ _subtitleArea.left,
+ _subtitleArea.top,
+ _subtitleArea.left + _subtitleSurface.w,
+ _subtitleArea.top + _subtitleSurface.h
+ );
+ copyToScreen(_subtitleSurface, rect, 0, 0);
+ }
+}
- renderImageToScreen(_currentBackground, 0, _screenCenterY - _backgroundOffset.y, true);
- } else if (state == RenderTable::PANORAMA) {
- _backgroundOffset += Common::Point(offset, 0);
+Common::Point RenderManager::getBkgSize() {
+ return Common::Point(_backgroundWidth, _backgroundHeight);
+}
- if (_backgroundOffset.x <= -_backgroundWidth)
- _backgroundOffset.x += _backgroundWidth;
- else if (_backgroundOffset.x >= _backgroundWidth)
- _backgroundOffset.x -= _backgroundWidth;
+void RenderManager::addEffect(GraphicsEffect *_effect) {
+ _effects.push_back(_effect);
+}
- renderImageToScreen(_currentBackground, _screenCenterX - _backgroundOffset.x, 0, true);
- } else {
- renderImageToScreen(_currentBackground, 0, 0);
+void RenderManager::deleteEffect(uint32 ID) {
+ for (EffectsList::iterator it = _effects.begin(); it != _effects.end(); it++) {
+ if ((*it)->getKey() == ID) {
+ delete *it;
+ it = _effects.erase(it);
+ }
}
}
-uint32 RenderManager::getCurrentBackgroundOffset() {
+Common::Rect RenderManager::transformBackgroundSpaceRectToScreenSpace(const Common::Rect &src) {
+ Common::Rect tmp = src;
RenderTable::RenderState state = _renderTable.getRenderState();
if (state == RenderTable::PANORAMA) {
- return _backgroundOffset.x;
+ 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 - _backgroundOffset - _backgroundWidth, 0);
+ } else {
+ tmp.translate(_screenCenterX - _backgroundOffset, 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 + (_backgroundWidth - _backgroundOffset), 0);
+ } else {
+ tmp.translate(_screenCenterX - _backgroundOffset, 0);
+ }
+ } else {
+ tmp.translate(_screenCenterX - _backgroundOffset, 0);
+ }
} else if (state == RenderTable::TILT) {
- return _backgroundOffset.y;
- } else {
- return 0;
+ tmp.translate(0, (_screenCenterY - _backgroundOffset));
}
+
+ return tmp;
}
-Graphics::Surface *RenderManager::tranposeSurface(const Graphics::Surface *surface) {
- Graphics::Surface *tranposedSurface = new Graphics::Surface();
- tranposedSurface->create(surface->h, surface->w, surface->format);
+EffectMap *RenderManager::makeEffectMap(const Common::Point &xy, int16 depth, const Common::Rect &rect, int8 *_minComp, int8 *_maxComp) {
+ Common::Rect bkgRect(_backgroundWidth, _backgroundHeight);
+ if (!bkgRect.contains(xy))
+ return NULL;
+
+ if (!bkgRect.intersects(rect))
+ return NULL;
+
+ uint16 color = *(uint16 *)_currentBackgroundImage.getBasePtr(xy.x, xy.y);
+ uint8 stC1, stC2, stC3;
+ _currentBackgroundImage.format.colorToRGB(color, stC1, stC2, stC3);
+ EffectMap *newMap = new EffectMap;
+
+ EffectMapUnit unit;
+ unit.count = 0;
+ unit.inEffect = false;
+
+ int16 w = rect.width();
+ int16 h = rect.height();
+
+ bool first = true;
+
+ uint8 minComp = MIN(MIN(stC1, stC2), stC3);
+ uint8 maxComp = MAX(MAX(stC1, stC2), stC3);
+
+ uint8 depth8 = depth << 3;
+
+ for (int16 j = 0; j < h; 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;
+ _currentBackgroundImage.format.colorToRGB(curClr, cC1, cC2, cC3);
+
+ bool use = false;
+
+ if (curClr == color)
+ use = true;
+ else if (curClr > color) {
+ if ((cC1 - stC1 < depth8) &&
+ (cC2 - stC2 < depth8) &&
+ (cC3 - stC3 < depth8))
+ use = true;
+ } else { /* if (curClr < color) */
+ if ((stC1 - cC1 < depth8) &&
+ (stC2 - cC2 < depth8) &&
+ (stC3 - cC3 < depth8))
+ use = true;
+ }
- const uint16 *source = (const uint16 *)surface->getPixels();
- uint16 *dest = (uint16 *)tranposedSurface->getPixels();
+ if (first) {
+ unit.inEffect = use;
+ first = false;
+ }
- for (uint32 y = 0; y < tranposedSurface->h; ++y) {
- uint32 columnIndex = y * tranposedSurface->w;
+ if (use) {
+ uint8 cMinComp = MIN(MIN(cC1, cC2), cC3);
+ uint8 cMaxComp = MAX(MAX(cC1, cC2), cC3);
+ if (cMinComp < minComp)
+ minComp = cMinComp;
+ if (cMaxComp > maxComp)
+ maxComp = cMaxComp;
+ }
- for (uint32 x = 0; x < tranposedSurface->w; ++x) {
- dest[columnIndex + x] = source[x * surface->w + y];
+ if (unit.inEffect == use)
+ unit.count++;
+ else {
+ newMap->push_back(unit);
+ unit.count = 1;
+ unit.inEffect = use;
+ }
}
}
+ newMap->push_back(unit);
- return tranposedSurface;
+ if (_minComp) {
+ if (minComp - depth8 < 0)
+ *_minComp = -(minComp >> 3);
+ else
+ *_minComp = -depth;
+ }
+ if (_maxComp) {
+ if ((int16)maxComp + (int16)depth8 > 255)
+ *_maxComp = (255 - maxComp) >> 3;
+ else
+ *_maxComp = depth;
+ }
+
+ return newMap;
+}
+
+EffectMap *RenderManager::makeEffectMap(const Graphics::Surface &surf, uint16 transp) {
+ EffectMapUnit unit;
+ unit.count = 0;
+ unit.inEffect = false;
+
+ int16 w = surf.w;
+ int16 h = surf.h;
+
+ EffectMap *newMap = new EffectMap;
+
+ bool first = true;
+
+ for (int16 j = 0; j < h; j++) {
+ const uint16 *pix = (const uint16 *)surf.getBasePtr(0, j);
+ for (int16 i = 0; i < w; i++) {
+ bool use = false;
+ if (pix[i] != transp)
+ use = true;
+
+ if (first) {
+ unit.inEffect = use;
+ first = false;
+ }
+
+ if (unit.inEffect == use)
+ unit.count++;
+ else {
+ newMap->push_back(unit);
+ unit.count = 1;
+ unit.inEffect = use;
+ }
+ }
+ }
+ newMap->push_back(unit);
+
+ return newMap;
+}
+
+void RenderManager::markDirty() {
+ _backgroundDirtyRect = Common::Rect(_backgroundWidth, _backgroundHeight);
+}
+
+#if 0
+void RenderManager::bkgFill(uint8 r, uint8 g, uint8 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 9feff4c030..33d8a88e78 100644
--- a/engines/zvision/graphics/render_manager.h
+++ b/engines/zvision/graphics/render_manager.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.
@@ -24,13 +24,14 @@
#define ZVISION_RENDER_MANAGER_H
#include "zvision/graphics/render_table.h"
-#include "zvision/fonts/truetype_font.h"
+#include "zvision/text/truetype_font.h"
#include "common/rect.h"
#include "common/hashmap.h"
#include "graphics/surface.h"
+#include "graphics_effect.h"
class OSystem;
@@ -47,171 +48,131 @@ namespace ZVision {
class RenderManager {
public:
- RenderManager(OSystem *system, 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 AlphaDataEntry {
- Graphics::Surface *data;
- uint16 alphaColor;
- uint16 destX;
- uint16 destY;
- uint16 width;
- uint16 height;
+ struct OneSubtitle {
+ Common::Rect r;
+ Common::String txt;
+ int16 timer;
+ bool todelete;
+ bool redraw;
};
- typedef Common::HashMap<uint32, AlphaDataEntry> AlphaEntryMap;
+ typedef Common::HashMap<uint16, OneSubtitle> SubtitleMap;
+ typedef Common::List<GraphicsEffect *> EffectsList;
private:
+ ZVision *_engine;
OSystem *_system;
const Graphics::PixelFormat _pixelFormat;
- // A buffer the exact same size as the workingWindow
- // This buffer stores everything un-warped, then does a warp at the end of the frame
- Graphics::Surface _workingWindowBuffer;
- // A buffer representing the entire screen. Any graphical updates are first done with this buffer
- // before actually being blitted to the screen
- Graphics::Surface _backBuffer;
- // A list of Alpha Entries that need to be blitted to the backbuffer
- AlphaEntryMap _alphaDataEntries;
-
- // A rectangle representing the portion of the working window where the pixels have been changed since last frame
- Common::Rect _workingWindowDirtyRect;
- // A rectangle representing the portion of the backbuffer where the pixels have been changed since last frame
- Common::Rect _backBufferDirtyRect;
-
- /** Width of the working window. Saved to prevent extraneous calls to _workingWindow.width() */
- const int _workingWidth;
- /** Height of the working window. Saved to prevent extraneous calls to _workingWindow.height() */
- const int _workingHeight;
- /** Center of the screen in the x direction */
- const int _screenCenterX;
- /** Center of the screen in the y direction */
- const int _screenCenterY;
-
/**
* 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;
- /** Used to warp the background image */
- RenderTable _renderTable;
+ Common::Rect _workingWindow;
- Graphics::Surface _currentBackground;
- /** The (x1,y1) coordinates of the subRectangle of the background that is currently displayed on the screen */
- Common::Point _backgroundOffset;
+ // Center of the screen in the x direction
+ const int _screenCenterX;
+ // Center of the screen in the y direction
+ const int _screenCenterY;
+
+ /** A buffer for background image that's being used to create the background */
+ Graphics::Surface _currentBackgroundImage;
+ Common::Rect _backgroundDirtyRect;
+
+ /**
+ * 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;
- /**
- * The "velocity" at which the background image is panning. We actually store the inverse of velocity (ms/pixel instead of pixels/ms)
- * because it allows you to accumulate whole pixels 'steps' instead of rounding pixels every frame
- */
- int _backgroundInverseVelocity;
- /** Holds any 'leftover' milliseconds between frames */
- uint _accumulatedVelocityMilliseconds;
+ // 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;
-public:
- void initialize();
- /**
- * Rotates the background image in accordance to the current _backgroundInverseVelocity
- *
- * @param deltaTimeInMillis The amount of time that has passed since the last frame
- */
- void update(uint deltaTimeInMillis);
+ // A buffer for subtitles
+ Graphics::Surface _subtitleSurface;
- /**
- * Renders the current state of the backbuffer to the screen
- */
- void renderBackbufferToScreen();
+ // Rectangle for subtitles area
+ Common::Rect _subtitleArea;
- /**
- * Renders all AlphaEntries to the backbuffer
- */
- void processAlphaEntries();
- /**
- * Clears the AlphaEntry list
- */
- void clearAlphaEntries() { _alphaDataEntries.clear(); }
- /**
- * Removes a specific AlphaEntry from the list
- *
- * @param idNumber The id number identifing the AlphaEntry
- */
- void removeAlphaEntry(uint32 idNumber) { _alphaDataEntries.erase(idNumber); }
+ // A buffer for menu drawing
+ Graphics::Surface _menuSurface;
+ Common::Rect _menuSurfaceDirtyRect;
- /**
- * Copies a sub-rectangle of a buffer to the working window
- *
- * @param buffer The pixel data to copy to the working window
- * @param destX The X destination in the working window where the subRect of data should be put
- * @param destY The Y destination in the working window where the subRect of data should be put
- * @param imageWidth The width of the source image
- * @param width The width of the sub rectangle
- * @param height The height of the sub rectangle
- */
- void copyRectToWorkingWindow(const uint16 *buffer, int32 destX, int32 destY, int32 imageWidth, int32 width, int32 height);
- /**
- * Copies a sub-rectangle of a buffer to the working window with binary alpha support.
- *
- * @param buffer The pixel data to copy to the working window
- * @param destX The X destination in the working window where the subRect of data should be put
- * @param destY The Y destination in the working window where the subRect of data should be put
- * @param imageWidth The width of the source image
- * @param width The width of the sub rectangle
- * @param height The height of the sub rectangle
- * @param alphaColor The color to interpret as meaning 'transparent'
- * @param idNumber A unique identifier for the data being copied over.
- */
- void copyRectToWorkingWindow(const uint16 *buffer, int32 destX, int32 destY, int32 imageWidth, int32 width, int32 height, int16 alphaColor, uint32 idNumber);
+ // Rectangle for menu area
+ Common::Rect _menuArea;
+
+ // A buffer used for apply graphics effects
+ Graphics::Surface _effectSurface;
+
+ // A buffer to store the result of the panorama / tilt warps
+ Graphics::Surface _warpedSceneSurface;
- /**
- * Renders the supplied text to the working window
- *
- * @param idNumber A unique identifier for the text
- * @param text The text to be rendered
- * @param font The font to use to render the text
- * @param destX The X destination in the working window where the text should be rendered
- * @param destY The Y destination in the working window where the text should be rendered
- * @param textColor The color to render the text with (in RBG 565)
- * @param maxWidth The max width the text should take up.
- * @param maxHeight The max height the text should take up.
- * @param align The alignment of the text within the bounds of maxWidth
- * @param wrap If true, any words extending past maxWidth will wrap to a new line. If false, ellipses will be rendered to show that the text didn't fit
- * @return A rectangle representing where the text was drawn in the working window
- */
- Common::Rect renderTextToWorkingWindow(uint32 idNumber, const Common::String &text, TruetypeFont *font, int destX, int destY, uint16 textColor, int maxWidth, int maxHeight = -1, Graphics::TextAlign align = Graphics::kTextAlignLeft, bool wrap = true);
+
+ /** Used to warp the background image */
+ RenderTable _renderTable;
+
+ // Internal subtitles counter
+ uint16 _subid;
+
+ // Subtitle list
+ SubtitleMap _subsList;
+
+ // Visual effects list
+ EffectsList _effects;
+
+ bool _doubleFPS;
+
+public:
+ void initialize();
/**
- * Fills the entire workingWindow with the specified color. Internally, the color
- * will be converted to RGB 565 and then blitted.
- *
- * @param color The color to fill the working window with. (In RGB 555)
+ * Renders the scene to the screen
*/
- void clearWorkingWindowTo555Color(uint16 color);
+ 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 backbuffer. Actual screen updates won't happen until the end of the frame.
- * The image will be clipped to fit inside the working window. Coords are in working window space, not screen space!
+ * Blits the image or a portion of the image to the background.
*
* @param fileName Name of the image file
* @param destinationX X position where the image should be put. Coords are in working window space, not screen space!
* @param destinationY Y position where the image should be put. Coords are in working window space, not screen space!
*/
- void renderImageToScreen(const Common::String &fileName, int16 destinationX, int16 destinationY, bool wrap = false);
+ void renderImageToBackground(const Common::String &fileName, int16 destinationX, int16 destinationY);
/**
- * Blits the image or a portion of the image to the backbuffer. Actual screen updates won't happen until the end of the frame.
- * The image will be clipped to fit inside the working window. Coords are in working window space, not screen space!
+ * Blits the image or a portion of the image to the background.
*
- * @param stream Surface to read the image data from
- * @param destinationX X position where the image should be put. Coords are in working window space, not screen space!
- * @param destinationY Y position where the image should be put. Coords are in working window space, not screen space!
+ * @param fileName Name of the image file
+ * @param destX X position where the image should be put. Coords are in working window space, not screen space!
+ * @param destY Y position where the image should be put. Coords are in working window space, not screen space!
+ * @param colorkey Transparent color
*/
- void renderImageToScreen(Graphics::Surface &surface, int16 destinationX, int16 destinationY, bool wrap = false);
+ void renderImageToBackground(const Common::String &fileName, int16 destX, int16 destY, uint32 colorkey);
+
+ /**
+ * Blits the image or a portion of the image to the background.
+ *
+ * @param fileName Name of the image file
+ * @param destX X position where the image should be put. Coords are in working window space, not screen space!
+ * @param destY Y position where the image should be put. Coords are in working window space, not screen space!
+ * @param keyX X position of transparent color
+ * @param keyY Y position of transparent color
+ */
+ void renderImageToBackground(const Common::String &fileName, int16 destX, int16 destY, int16 keyX, int16 keyY);
/**
* Sets the current background image to be used by the RenderManager and immediately
@@ -234,41 +195,18 @@ public:
void setBackgroundPosition(int offset);
/**
- * Set the background scroll velocity. Negative velocities correspond to left / up scrolling and
- * positive velocities correspond to right / down scrolling
- *
- * @param velocity Velocity
- */
- void setBackgroundVelocity(int velocity);
-
- /**
* Converts a point in screen coordinate space to image coordinate space
*
* @param point Point in screen coordinate space
* @return Point in image coordinate space
*/
const Common::Point screenSpaceToImageSpace(const Common::Point &point);
- /**
- * Converts a point in image coordinate space to ***PRE-WARP***
- * working window coordinate space
- *
- * @param point Point in image coordinate space
- * @return Point in PRE-WARP working window coordinate space
- */
- const Common::Point imageSpaceToWorkingWindowSpace(const Common::Point &point);
-
- /**
- * Clip a rectangle to the working window. If it returns false, the original rect
- * is not inside the working window.
- *
- * @param rect The rectangle to clip against the working window
- * @return Is rect at least partially inside the working window (true) or completely outside (false)
- */
- bool clipRectToWorkingWindow(Common::Rect &rect);
+ // Return pointer of RenderTable object
RenderTable *getRenderTable();
+
+ // Return current background offset
uint32 getCurrentBackgroundOffset();
- const Graphics::Surface *getBackBuffer() { return &_backBuffer; }
/**
* Creates a copy of surface and transposes the data.
@@ -281,25 +219,62 @@ public:
*/
static Graphics::Surface *tranposeSurface(const Graphics::Surface *surface);
-private:
- /**
- * Renders a subRectangle of an image to the backbuffer. The destinationRect and SubRect
- * will be clipped to image bound and to working window bounds
- *
- * @param buffer Pointer to (0, 0) of the image data
- * @param imageWidth The width of the original image (not of the subRectangle)
- * @param imageHeight The width of the original image (not of the subRectangle)
- * @param horizontalPitch The horizontal pitch of the original image
- * @param destinationX The x coordinate (in working window space) of where to put the final image
- * @param destinationY The y coordinate (in working window space) of where to put the final image
- * @param subRectangle A rectangle representing the part of the image that should be rendered
- * @param wrap Should the image wrap (tile) if it doesn't completely fill the screen?
- */
- void renderSubRectToScreen(Graphics::Surface &surface, int16 destinationX, int16 destinationY, bool wrap);
+ // Scale buffer (nearest)
+ void scaleBuffer(const void *src, void *dst, uint32 srcWidth, uint32 srcHeight, byte bytesPerPixel, uint32 dstWidth, uint32 dstHeight);
+
+ // 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);
+
+ // Blitting surface-to-background methods
+ 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, int32 colorkey = -1);
+
+ // Blitting surface-to-menu methods
+ 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();
+
+ // Delete subtitle by ID
+ void deleteSubArea(uint16 id);
+ void deleteSubArea(uint16 id, int16 delay);
+
+ // Update subtitle area
+ void updateSubArea(uint16 id, const Common::String &txt);
+
+ // Processing subtitles
+ void processSubs(uint16 deltatime);
+
+ // Return background size
+ Common::Point getBkgSize();
+
+ // Return portion of background as new surface
+ Graphics::Surface *getBkgRect(Common::Rect &rect);
+
+ // Load image into new surface
+ Graphics::Surface *loadImage(Common::String file);
+ Graphics::Surface *loadImage(Common::String file, bool transposed);
+
+ // Clear whole/area of menu surface
+ void clearMenuSurface();
+ void clearMenuSurface(const Common::Rect &r);
+
+ // Copy menu buffer to screen
+ void renderMenuToScreen();
+
+ // Copy needed portion of background surface to workingWindow surface
+ 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.
@@ -310,17 +285,55 @@ private:
void readImageToSurface(const Common::String &fileName, Graphics::Surface &destination);
/**
- * Move the background image by an offset. If we are currently in Panorama mode,
- * the offset will correspond to a horizontal motion. If we are currently in Tilt mode,
- * the offset will correspond to a vertical motion. This function should not be called
- * if we are in Flat mode.
- *
- * The RenderManager will take care of wrapping the image.
- * Ex: If the image has width 1400px, it is legal to offset 1500px.
+ * 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.
*
- * @param offset The amount to move the background
+ * @param fileName The name of a .tga file
+ * @param destination A reference to the Surface to store the pixel data in
+ * @param transposed Transpose flag
*/
- void moveBackground(int offset);
+ void readImageToSurface(const Common::String &fileName, Graphics::Surface &destination, bool transposed);
+
+ // Add visual effect to effects list
+ void addEffect(GraphicsEffect *_effect);
+
+ // Delete effect(s) by ID (ID equal to slot of action:region that create this effect)
+ void deleteEffect(uint32 ID);
+
+ // Create "mask" for effects - (color +/- depth) will be selected as not transparent. Like color selection
+ // xy - base color
+ // depth - +/- of base color
+ // rect - rectangle where select pixels
+ // minD - if not NULL will recieve real bottom border of depth
+ // maxD - if not NULL will recieve real top border of depth
+ EffectMap *makeEffectMap(const Common::Point &xy, int16 depth, const Common::Rect &rect, int8 *minD, int8 *maxD);
+
+ // Create "mask" for effects by simple transparent color
+ EffectMap *makeEffectMap(const Graphics::Surface &surf, uint16 transp);
+
+ // Return background rectangle in screen coordinates
+ Common::Rect transformBackgroundSpaceRectToScreenSpace(const Common::Rect &src);
+
+ // Mark whole background surface as dirty
+ void markDirty();
+
+#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 49b934dc37..df73247344 100644
--- a/engines/zvision/graphics/render_table.cpp
+++ b/engines/zvision/graphics/render_table.cpp
@@ -21,23 +21,22 @@
*/
#include "common/scummsys.h"
-
#include "zvision/graphics/render_table.h"
-
#include "common/rect.h"
-
#include "graphics/colormasks.h"
-
namespace ZVision {
RenderTable::RenderTable(uint numColumns, uint numRows)
- : _numRows(numRows),
- _numColumns(numColumns),
- _renderState(FLAT) {
+ : _numRows(numRows),
+ _numColumns(numColumns),
+ _renderState(FLAT) {
assert(numRows != 0 && numColumns != 0);
_internalBuffer = new Common::Point[numRows * numColumns];
+
+ memset(&_panoramaOptions, 0, sizeof(_panoramaOptions));
+ memset(&_tiltOptions, 0, sizeof(_tiltOptions));
}
RenderTable::~RenderTable() {
@@ -52,10 +51,11 @@ void RenderTable::setRenderState(RenderState newState) {
_panoramaOptions.fieldOfView = 27.0f;
_panoramaOptions.linearScale = 0.55f;
_panoramaOptions.reverse = false;
+ _panoramaOptions.zeroPoint = 0;
break;
case TILT:
_tiltOptions.fieldOfView = 27.0f;
- _tiltOptions.linearScale = 0.55f;
+ _tiltOptions.linearScale = 0.65f;
_tiltOptions.reverse = false;
break;
case FLAT:
@@ -81,28 +81,7 @@ 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) {
+void RenderTable::mutateImage(uint16 *sourceBuffer, uint16 *destBuffer, uint32 destWidth, const Common::Rect &subRect) {
uint32 destOffset = 0;
for (int16 y = subRect.top; y < subRect.bottom; ++y) {
@@ -123,6 +102,28 @@ void RenderTable::mutateImage(uint16 *sourceBuffer, uint16* destBuffer, uint32 d
}
}
+void RenderTable::mutateImage(Graphics::Surface *dstBuf, Graphics::Surface *srcBuf) {
+ uint32 destOffset = 0;
+
+ uint16 *sourceBuffer = (uint16 *)srcBuf->getPixels();
+ uint16 *destBuffer = (uint16 *)dstBuf->getPixels();
+
+ for (int16 y = 0; y < srcBuf->h; ++y) {
+ uint32 sourceOffset = y * _numColumns;
+
+ for (int16 x = 0; x < srcBuf->w; ++x) {
+ uint32 index = sourceOffset + x;
+
+ // RenderTable only stores offsets from the original coordinates
+ uint32 sourceYIndex = y + _internalBuffer[index].y;
+ uint32 sourceXIndex = x + _internalBuffer[index].x;
+
+ destBuffer[destOffset] = sourceBuffer[sourceYIndex * _numColumns + sourceXIndex];
+ destOffset++;
+ }
+ }
+}
+
void RenderTable::generateRenderTable() {
switch (_renderState) {
case ZVision::RenderTable::PANORAMA:
@@ -177,6 +178,7 @@ void RenderTable::generateTiltLookupTable() {
float fovInRadians = (_tiltOptions.fieldOfView * M_PI / 180.0f);
float cylinderRadius = halfWidth / tan(fovInRadians);
+ _tiltOptions.gap = cylinderRadius * atan2((float)(halfHeight / cylinderRadius), 1.0f) * _tiltOptions.linearScale;
for (uint y = 0; y < _numRows; ++y) {
@@ -221,6 +223,18 @@ void RenderTable::setPanoramaReverse(bool reverse) {
_panoramaOptions.reverse = reverse;
}
+bool RenderTable::getPanoramaReverse() {
+ return _panoramaOptions.reverse;
+}
+
+void RenderTable::setPanoramaZeroPoint(uint16 point) {
+ _panoramaOptions.zeroPoint = point;
+}
+
+uint16 RenderTable::getPanoramaZeroPoint() {
+ return _panoramaOptions.zeroPoint;
+}
+
void RenderTable::setTiltFoV(float fov) {
assert(fov > 0.0f);
@@ -237,4 +251,26 @@ void RenderTable::setTiltReverse(bool reverse) {
_tiltOptions.reverse = reverse;
}
+float RenderTable::getTiltGap() {
+ return _tiltOptions.gap;
+}
+
+float RenderTable::getAngle() {
+ if (_renderState == TILT)
+ return _tiltOptions.fieldOfView;
+ else if (_renderState == PANORAMA)
+ return _panoramaOptions.fieldOfView;
+ else
+ return 1.0;
+}
+
+float RenderTable::getLinscale() {
+ if (_renderState == TILT)
+ return _tiltOptions.linearScale;
+ else if (_renderState == PANORAMA)
+ return _panoramaOptions.linearScale;
+ else
+ return 1.0;
+}
+
} // End of namespace ZVision
diff --git a/engines/zvision/graphics/render_table.h b/engines/zvision/graphics/render_table.h
index f066187ad1..7455d9ba39 100644
--- a/engines/zvision/graphics/render_table.h
+++ b/engines/zvision/graphics/render_table.h
@@ -24,7 +24,7 @@
#define ZVISION_RENDER_TABLE_H
#include "common/rect.h"
-
+#include "graphics/surface.h"
namespace ZVision {
@@ -49,6 +49,7 @@ private:
float fieldOfView;
float linearScale;
bool reverse;
+ uint16 zeroPoint;
} _panoramaOptions;
// TODO: See if tilt and panorama need to have separate options
@@ -56,25 +57,36 @@ private:
float fieldOfView;
float linearScale;
bool reverse;
+ float gap;
} _tiltOptions;
public:
- RenderState getRenderState() { return _renderState; }
+ RenderState getRenderState() {
+ return _renderState;
+ }
void setRenderState(RenderState newState);
const Common::Point convertWarpedCoordToFlatCoord(const Common::Point &point);
- void mutateImage(uint16 *sourceBuffer, uint16* destBuffer, uint32 destWidth, const Common::Rect &subRect);
+ void mutateImage(uint16 *sourceBuffer, uint16 *destBuffer, uint32 destWidth, const Common::Rect &subRect);
+ void mutateImage(Graphics::Surface *dstBuf, Graphics::Surface *srcBuf);
void generateRenderTable();
void setPanoramaFoV(float fov);
void setPanoramaScale(float scale);
void setPanoramaReverse(bool reverse);
+ void setPanoramaZeroPoint(uint16 point);
+ uint16 getPanoramaZeroPoint();
+ bool getPanoramaReverse();
void setTiltFoV(float fov);
void setTiltScale(float scale);
void setTiltReverse(bool reverse);
+ float getTiltGap();
+ float getAngle();
+ float getLinscale();
+
private:
void generatePanoramaLookupTable();
void generateTiltLookupTable();
diff --git a/engines/zvision/module.mk b/engines/zvision/module.mk
index 2e298f24c6..93fba2879d 100644
--- a/engines/zvision/module.mk
+++ b/engines/zvision/module.mk
@@ -1,32 +1,51 @@
MODULE := engines/zvision
MODULE_OBJS := \
- animation/rlf_animation.o \
- archives/zfs_archive.o \
core/console.o \
+ core/clock.o \
core/events.o \
- core/save_manager.o \
- cursors/cursor.o \
- cursors/cursor_manager.o \
detection.o \
- fonts/truetype_font.o \
+ file/lzss_read_stream.o \
+ file/save_manager.o \
+ file/search_manager.o \
+ file/zfs_archive.o \
+ graphics/cursors/cursor_manager.o \
+ graphics/cursors/cursor.o \
+ graphics/effects/fog.o \
+ graphics/effects/light.o \
+ graphics/effects/wave.o \
graphics/render_manager.o \
graphics/render_table.o \
scripting/actions.o \
scripting/control.o \
- scripting/controls/animation_control.o \
+ scripting/controls/fist_control.o \
+ scripting/controls/hotmov_control.o \
scripting/controls/input_control.o \
scripting/controls/lever_control.o \
+ scripting/controls/paint_control.o \
scripting/controls/push_toggle_control.o \
- scripting/controls/timer_node.o \
+ scripting/controls/safe_control.o \
+ scripting/controls/save_control.o \
+ 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/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 \
- strings/string_manager.o \
- utility/clock.o \
- utility/lzss_read_stream.o \
- utility/single_value_container.o \
- utility/utility.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 \
zvision.o
diff --git a/engines/zvision/scripting/actions.cpp b/engines/zvision/scripting/actions.cpp
index 517278e155..9a8b734e0c 100644
--- a/engines/zvision/scripting/actions.cpp
+++ b/engines/zvision/scripting/actions.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,380 +21,1075 @@
*/
#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/controls/timer_node.h"
-#include "zvision/scripting/controls/animation_control.h"
-
-#include "common/file.h"
-
-#include "audio/decoders/wave.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/graphics_effect.h"
+#include "zvision/graphics/effects/fog.h"
+#include "zvision/graphics/effects/light.h"
+#include "zvision/graphics/effects/wave.h"
+#include "zvision/graphics/cursors/cursor_manager.h"
namespace ZVision {
+ResultAction::ResultAction(ZVision *engine, int32 slotkey) : _engine(engine), _slotKey(slotkey), _scriptManager(engine->getScriptManager()) {
+}
+
//////////////////////////////////////////////////////////////////////////////
// ActionAdd
//////////////////////////////////////////////////////////////////////////////
-ActionAdd::ActionAdd(const Common::String &line) {
- sscanf(line.c_str(), "%*[^(](%u,%u)", &_key, &_value);
+ActionAdd::ActionAdd(ZVision *engine, int32 slotkey, const Common::String &line) :
+ ResultAction(engine, slotkey) {
+ _key = 0;
+ _value = 0;
+
+ sscanf(line.c_str(), "%u,%d", &_key, &_value);
}
-bool ActionAdd::execute(ZVision *engine) {
- engine->getScriptManager()->addToStateValue(_key, _value);
+bool ActionAdd::execute() {
+ _scriptManager->setStateValue(_key, _scriptManager->getStateValue(_key) + _value);
return true;
}
-
//////////////////////////////////////////////////////////////////////////////
// ActionAssign
//////////////////////////////////////////////////////////////////////////////
-ActionAssign::ActionAssign(const Common::String &line) {
- sscanf(line.c_str(), "%*[^(](%u, %u)", &_key, &_value);
+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(_scriptManager, buf);
}
-bool ActionAssign::execute(ZVision *engine) {
- engine->getScriptManager()->setStateValue(_key, _value);
- return true;
+ActionAssign::~ActionAssign() {
+ delete _value;
}
+bool ActionAssign::execute() {
+ _scriptManager->setStateValue(_key, _value->getValue());
+ return true;
+}
//////////////////////////////////////////////////////////////////////////////
// ActionAttenuate
//////////////////////////////////////////////////////////////////////////////
-ActionAttenuate::ActionAttenuate(const Common::String &line) {
- sscanf(line.c_str(), "%*[^(](%u, %d)", &_key, &_attenuation);
+ActionAttenuate::ActionAttenuate(ZVision *engine, int32 slotkey, const Common::String &line) :
+ ResultAction(engine, slotkey) {
+ _key = 0;
+ _attenuation = 0;
+
+ sscanf(line.c_str(), "%u, %d", &_key, &_attenuation);
}
-bool ActionAttenuate::execute(ZVision *engine) {
- // TODO: Implement
+bool ActionAttenuate::execute() {
+ 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;
}
-
//////////////////////////////////////////////////////////////////////////////
// ActionChangeLocation
//////////////////////////////////////////////////////////////////////////////
-ActionChangeLocation::ActionChangeLocation(const Common::String &line) {
- sscanf(line.c_str(), "%*[^(](%c,%c,%c%c,%u)", &_world, &_room, &_node, &_view, &_offset);
+ActionChangeLocation::ActionChangeLocation(ZVision *engine, int32 slotkey, const Common::String &line) :
+ ResultAction(engine, slotkey) {
+ _world = 'g';
+ _room = 'a';
+ _node = 'r';
+ _view = 'y';
+ _offset = 0;
+
+ sscanf(line.c_str(), "%c, %c, %c%c, %u", &_world, &_room, &_node, &_view, &_offset);
}
-bool ActionChangeLocation::execute(ZVision *engine) {
+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;
}
-
//////////////////////////////////////////////////////////////////////////////
// ActionCrossfade
//////////////////////////////////////////////////////////////////////////////
-ActionCrossfade::ActionCrossfade(const Common::String &line) {
+ActionCrossfade::ActionCrossfade(ZVision *engine, int32 slotkey, const Common::String &line) :
+ ResultAction(engine, slotkey) {
+ _keyOne = 0;
+ _keyTwo = 0;
+ _oneStartVolume = 0;
+ _twoStartVolume = 0;
+ _oneEndVolume = 0;
+ _twoEndVolume = 0;
+ _timeInMillis = 0;
+
sscanf(line.c_str(),
- "%*[^(](%u %u %u %u %u %u %u)",
- &_keyOne, &_keyTwo, &_oneStartVolume, &_twoStartVolume, &_oneEndVolume, &_twoEndVolume, &_timeInMillis);
+ "%u %u %d %d %d %d %d",
+ &_keyOne, &_keyTwo, &_oneStartVolume, &_twoStartVolume, &_oneEndVolume, &_twoEndVolume, &_timeInMillis);
+}
+
+bool ActionCrossfade::execute() {
+ if (_keyOne) {
+ 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);
+
+ mus->setFade(_timeInMillis, (_oneEndVolume * 255) / 100);
+ }
+ }
+
+ if (_keyTwo) {
+ 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);
+
+ mus->setFade(_timeInMillis, (_twoEndVolume * 255) / 100);
+ }
+ }
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionCursor
+//////////////////////////////////////////////////////////////////////////////
+
+ActionCursor::ActionCursor(ZVision *engine, int32 slotkey, const Common::String &line) :
+ ResultAction(engine, slotkey) {
+ Common::String up = line;
+ up.toUppercase();
+ _action = 0;
+
+ if (up[0] == 'B')
+ _action = 2;
+ else if (up[0] == 'I')
+ _action = 3;
+ else if (up[0] == 'U')
+ _action = 0;
+ else if (up[0] == 'H')
+ _action = 1;
}
-bool ActionCrossfade::execute(ZVision *engine) {
- // TODO: Implement
+bool ActionCursor::execute() {
+ switch (_action) {
+ case 1:
+ _engine->getCursorManager()->showMouse(false);
+ break;
+ default:
+ _engine->getCursorManager()->showMouse(true);
+ break;
+ }
return true;
}
+//////////////////////////////////////////////////////////////////////////////
+// ActionDelayRender
+//////////////////////////////////////////////////////////////////////////////
+
+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() {
+ _engine->setRenderDelay(_framesToDelay);
+ return true;
+}
//////////////////////////////////////////////////////////////////////////////
// ActionDisableControl
//////////////////////////////////////////////////////////////////////////////
-ActionDisableControl::ActionDisableControl(const Common::String &line) {
- sscanf(line.c_str(), "%*[^(](%u)", &_key);
+ActionDisableControl::ActionDisableControl(ZVision *engine, int32 slotkey, const Common::String &line) :
+ ResultAction(engine, slotkey) {
+ _key = 0;
+
+ sscanf(line.c_str(), "%u", &_key);
+}
+
+bool ActionDisableControl::execute() {
+ _scriptManager->setStateFlag(_key, Puzzle::DISABLED);
+ return true;
}
-bool ActionDisableControl::execute(ZVision *engine) {
- debug("Disabling control %u", _key);
-
- ScriptManager *scriptManager = engine->getScriptManager();
- scriptManager->setStateFlags(_key, scriptManager->getStateFlags(_key) | ScriptManager::DISABLED);
+//////////////////////////////////////////////////////////////////////////////
+// ActionDisplayMessage
+//////////////////////////////////////////////////////////////////////////////
+ActionDisplayMessage::ActionDisplayMessage(ZVision *engine, int32 slotkey, const Common::String &line) :
+ ResultAction(engine, slotkey) {
+ _control = 0;
+ _msgid = 0;
+
+ sscanf(line.c_str(), "%hd %hd", &_control, &_msgid);
+}
+
+bool ActionDisplayMessage::execute() {
+ Control *ctrl = _scriptManager->getControl(_control);
+ if (ctrl && ctrl->getType() == Control::CONTROL_TITLER) {
+ TitlerControl *titler = (TitlerControl *)ctrl;
+ titler->setString(_msgid);
+ }
return true;
}
+//////////////////////////////////////////////////////////////////////////////
+// ActionDissolve
+//////////////////////////////////////////////////////////////////////////////
+
+ActionDissolve::ActionDissolve(ZVision *engine) :
+ ResultAction(engine, 0) {
+}
+
+bool ActionDissolve::execute() {
+ // Cause black screen flick
+ // _engine->getRenderManager()->bkgFill(0, 0, 0);
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// 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) {
+ _distSlot = 0;
+ _speed = 0;
+ _startAngle = 60.0;
+ _endAngle = 60.0;
+ _startLineScale = 1.0;
+ _endLineScale = 1.0;
+
+ sscanf(line.c_str(), "%hd %hd %f %f %f %f", &_distSlot, &_speed, &_startAngle, &_endAngle, &_startLineScale, &_endLineScale);
+}
+
+ActionDistort::~ActionDistort() {
+ _scriptManager->killSideFx(_distSlot);
+}
+
+bool ActionDistort::execute() {
+ if (_scriptManager->getSideFX(_distSlot))
+ return true;
+
+ _scriptManager->addSideFX(new DistortNode(_engine, _distSlot, _speed, _startAngle, _endAngle, _startLineScale, _endLineScale));
+
+ return true;
+}
//////////////////////////////////////////////////////////////////////////////
// ActionEnableControl
//////////////////////////////////////////////////////////////////////////////
-ActionEnableControl::ActionEnableControl(const Common::String &line) {
- sscanf(line.c_str(), "%*[^(](%u)", &_key);
+ActionEnableControl::ActionEnableControl(ZVision *engine, int32 slotkey, const Common::String &line) :
+ ResultAction(engine, slotkey) {
+ _key = 0;
+
+ sscanf(line.c_str(), "%u", &_key);
+}
+
+bool ActionEnableControl::execute() {
+ _scriptManager->unsetStateFlag(_key, Puzzle::DISABLED);
+ return true;
}
-bool ActionEnableControl::execute(ZVision *engine) {
- debug("Enabling control %u", _key);
+//////////////////////////////////////////////////////////////////////////////
+// ActionFlushMouseEvents
+//////////////////////////////////////////////////////////////////////////////
- ScriptManager *scriptManager = engine->getScriptManager();
- scriptManager->setStateFlags(_key, scriptManager->getStateFlags(_key) & ~ScriptManager::DISABLED);
+ActionFlushMouseEvents::ActionFlushMouseEvents(ZVision *engine, int32 slotkey) :
+ ResultAction(engine, slotkey) {
+}
+bool ActionFlushMouseEvents::execute() {
+ _scriptManager->flushEvent(Common::EVENT_LBUTTONUP);
+ _scriptManager->flushEvent(Common::EVENT_LBUTTONDOWN);
return true;
}
+//////////////////////////////////////////////////////////////////////////////
+// ActionInventory
+//////////////////////////////////////////////////////////////////////////////
+
+ActionInventory::ActionInventory(ZVision *engine, int32 slotkey, const Common::String &line) :
+ ResultAction(engine, slotkey) {
+ _type = -1;
+ _key = 0;
+
+ char buf[25];
+ sscanf(line.c_str(), "%24s %d", buf, &_key);
+
+ if (strcmp(buf, "add") == 0) {
+ _type = 0;
+ } else if (strcmp(buf, "addi") == 0) {
+ _type = 1;
+ } else if (strcmp(buf, "drop") == 0) {
+ _type = 2;
+ } else if (strcmp(buf, "dropi") == 0) {
+ _type = 3;
+ } else if (strcmp(buf, "cycle") == 0) {
+ _type = 4;
+ }
+
+}
+
+bool ActionInventory::execute() {
+ switch (_type) {
+ case 0: // add
+ _scriptManager->inventoryAdd(_key);
+ break;
+ case 1: // addi
+ _scriptManager->inventoryAdd(_scriptManager->getStateValue(_key));
+ break;
+ case 2: // drop
+ if (_key >= 0)
+ _scriptManager->inventoryDrop(_key);
+ else
+ _scriptManager->inventoryDrop(_scriptManager->getStateValue(StateKey_InventoryItem));
+ break;
+ case 3: // dropi
+ _scriptManager->inventoryDrop(_scriptManager->getStateValue(_key));
+ break;
+ case 4: // cycle
+ _scriptManager->inventoryCycle();
+ break;
+ default:
+ break;
+ }
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionKill - only used by ZGI
+//////////////////////////////////////////////////////////////////////////////
+
+ActionKill::ActionKill(ZVision *engine, int32 slotkey, const Common::String &line) :
+ ResultAction(engine, slotkey) {
+ _key = 0;
+ _type = 0;
+ char keytype[25];
+ sscanf(line.c_str(), "%24s", keytype);
+ if (keytype[0] == '"') {
+ if (!scumm_stricmp(keytype, "\"ANIM\""))
+ _type = ScriptingEffect::SCRIPTING_EFFECT_ANIM;
+ else if (!scumm_stricmp(keytype, "\"AUDIO\""))
+ _type = ScriptingEffect::SCRIPTING_EFFECT_AUDIO;
+ else if (!scumm_stricmp(keytype, "\"DISTORT\""))
+ _type = ScriptingEffect::SCRIPTING_EFFECT_DISTORT;
+ else if (!scumm_stricmp(keytype, "\"PANTRACK\""))
+ _type = ScriptingEffect::SCRIPTING_EFFECT_PANTRACK;
+ else if (!scumm_stricmp(keytype, "\"REGION\""))
+ _type = ScriptingEffect::SCRIPTING_EFFECT_REGION;
+ else if (!scumm_stricmp(keytype, "\"TIMER\""))
+ _type = ScriptingEffect::SCRIPTING_EFFECT_TIMER;
+ else if (!scumm_stricmp(keytype, "\"TTYTEXT\""))
+ _type = ScriptingEffect::SCRIPTING_EFFECT_TTYTXT;
+ else if (!scumm_stricmp(keytype, "\"ALL\""))
+ _type = ScriptingEffect::SCRIPTING_EFFECT_ALL;
+ } else
+ _key = atoi(keytype);
+}
+
+bool ActionKill::execute() {
+ if (_type)
+ _scriptManager->killSideFxType((ScriptingEffect::ScriptingEffectType)_type);
+ else
+ _scriptManager->killSideFx(_key);
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionMenuBarEnable
+//////////////////////////////////////////////////////////////////////////////
+
+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->getMenuHandler()->setEnable(_menus);
+ return true;
+}
//////////////////////////////////////////////////////////////////////////////
// ActionMusic
//////////////////////////////////////////////////////////////////////////////
-ActionMusic::ActionMusic(const Common::String &line) : _volume(255) {
- uint type;
- char fileNameBuffer[26];
- uint loop;
- uint 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;
+ char volumeBuffer[15];
+
+ // Volume is optional. If it doesn't appear, assume full volume
+ strcpy(volumeBuffer, "100");
- sscanf(line.c_str(), "%*[^:]:%*[^:]:%u(%u %25s %u %u)", &_key, &type, fileNameBuffer, &loop, &volume);
+ sscanf(line.c_str(), "%u %24s %u %14s", &type, fileNameBuffer, &loop, volumeBuffer);
- // type 4 are midi sound effect files
+ // 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) {
- _soundType = Audio::Mixer::kSFXSoundType;
- _fileName = Common::String::format("midi/%s/%u.wav", fileNameBuffer, loop);
- _loop = false;
+ _midi = true;
+ int note;
+ int prog;
+ sscanf(line.c_str(), "%u %d %d %14s", &type, &prog, &note, volumeBuffer);
+ _volume = new ValueSlot(_scriptManager, volumeBuffer);
+ _note = note;
+ _prog = prog;
} else {
- // TODO: See what the other types are so we can specify the correct Mixer::SoundType. In the meantime use kPlainSoundType
- _soundType = Audio::Mixer::kPlainSoundType;
+ _midi = false;
_fileName = Common::String(fileNameBuffer);
_loop = loop == 1 ? true : false;
+ 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);
}
- // 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;
- }
+ // 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);
+
}
-bool ActionMusic::execute(ZVision *engine) {
- Audio::RewindableAudioStream *audioStream;
+ActionMusic::~ActionMusic() {
+ if (!_universe)
+ _scriptManager->killSideFx(_slotKey);
+ delete _volume;
+}
- if (_fileName.contains(".wav")) {
- Common::File *file = new Common::File();
- if (file->open(_fileName)) {
- audioStream = Audio::makeWAVStream(file, DisposeAfterUse::YES);
- } else {
- warning("Unable to open %s", _fileName.c_str());
- return false;
- }
- } else {
- audioStream = makeRawZorkStream(_fileName, engine);
+bool ActionMusic::execute() {
+ if (_scriptManager->getSideFX(_slotKey)) {
+ _scriptManager->killSideFx(_slotKey);
+ _scriptManager->setStateValue(_slotKey, 2);
}
-
- if (_loop) {
- Audio::LoopingAudioStream *loopingAudioStream = new Audio::LoopingAudioStream(audioStream, 0, DisposeAfterUse::YES);
- engine->_mixer->playStream(_soundType, 0, loopingAudioStream, -1, _volume);
+
+ uint volume = _volume->getValue();
+
+ if (_midi) {
+ _scriptManager->addSideFX(new MusicMidiNode(_engine, _slotKey, _prog, _note, volume));
} else {
- engine->_mixer->playStream(_soundType, 0, audioStream, -1, _volume);
+ if (!_engine->getSearchManager()->hasFile(_fileName))
+ return true;
+
+ // 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;
}
+//////////////////////////////////////////////////////////////////////////////
+// ActionPanTrack
+//////////////////////////////////////////////////////////////////////////////
+
+ActionPanTrack::ActionPanTrack(ZVision *engine, int32 slotkey, const Common::String &line) :
+ ResultAction(engine, slotkey),
+ _pos(0),
+ _musicSlot(0) {
+
+ sscanf(line.c_str(), "%u %d", &_musicSlot, &_pos);
+}
+
+ActionPanTrack::~ActionPanTrack() {
+ _scriptManager->killSideFx(_slotKey);
+}
+
+bool ActionPanTrack::execute() {
+ if (_scriptManager->getSideFX(_slotKey))
+ return true;
+
+ _scriptManager->addSideFX(new PanTrackNode(_engine, _slotKey, _musicSlot, _pos));
+
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionPreferences
+//////////////////////////////////////////////////////////////////////////////
+
+ActionPreferences::ActionPreferences(ZVision *engine, int32 slotkey, const Common::String &line) :
+ ResultAction(engine, slotkey) {
+ if (line.compareToIgnoreCase("save") == 0)
+ _save = true;
+ else
+ _save = false;
+}
+
+bool ActionPreferences::execute() {
+ if (_save)
+ _engine->saveSettings();
+ else
+ _engine->loadSettings();
+
+ return true;
+}
//////////////////////////////////////////////////////////////////////////////
// ActionPreloadAnimation
//////////////////////////////////////////////////////////////////////////////
-ActionPreloadAnimation::ActionPreloadAnimation(const Common::String &line) {
- char fileName[26];
+ActionPreloadAnimation::ActionPreloadAnimation(ZVision *engine, int32 slotkey, const Common::String &line) :
+ ResultAction(engine, slotkey) {
+ _mask = 0;
+ _framerate = 0;
- // The two %*u are always 0 and dont seem to have a use
- sscanf(line.c_str(), "%*[^:]:%*[^:]:%u(%25s %*u %*u %u %u)", &_key, fileName, &_mask, &_framerate);
+ char fileName[25];
+
+ // 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);
+
+ // 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);
}
-bool ActionPreloadAnimation::execute(ZVision *engine) {
- // TODO: We ignore the mask and framerate atm. Mask refers to a key color used for binary alpha. We assume the framerate is the default framerate embedded in the videos
-
- // TODO: Check if the Control already exists
+ActionPreloadAnimation::~ActionPreloadAnimation() {
+ _scriptManager->deleteSideFx(_slotKey);
+}
- // Create the control, but disable it until PlayPreload is called
- ScriptManager *scriptManager = engine->getScriptManager();
- scriptManager->addControl(new AnimationControl(engine, _key, _fileName));
- scriptManager->setStateFlags(_key, scriptManager->getStateFlags(_key) | ScriptManager::DISABLED);
+bool ActionPreloadAnimation::execute() {
+ AnimationEffect *nod = (AnimationEffect *)_scriptManager->getSideFX(_slotKey);
+ if (!nod) {
+ nod = new AnimationEffect(_engine, _slotKey, _fileName, _mask, _framerate, false);
+ _scriptManager->addSideFX(nod);
+ } else
+ nod->stop();
+ _scriptManager->setStateValue(_slotKey, 2);
return true;
}
+//////////////////////////////////////////////////////////////////////////////
+// ActionUnloadAnimation
+//////////////////////////////////////////////////////////////////////////////
+
+ActionUnloadAnimation::ActionUnloadAnimation(ZVision *engine, int32 slotkey, const Common::String &line) :
+ ResultAction(engine, slotkey) {
+ _key = 0;
+
+ sscanf(line.c_str(), "%u", &_key);
+}
+
+bool ActionUnloadAnimation::execute() {
+ AnimationEffect *nod = (AnimationEffect *)_scriptManager->getSideFX(_key);
+
+ if (nod && nod->getType() == ScriptingEffect::SCRIPTING_EFFECT_ANIM)
+ _scriptManager->deleteSideFx(_key);
+
+ return true;
+}
//////////////////////////////////////////////////////////////////////////////
// ActionPlayAnimation
//////////////////////////////////////////////////////////////////////////////
-ActionPlayAnimation::ActionPlayAnimation(const Common::String &line) {
- char fileName[26];
+ActionPlayAnimation::ActionPlayAnimation(ZVision *engine, int32 slotkey, const Common::String &line) :
+ ResultAction(engine, slotkey) {
+ _x = 0;
+ _y = 0;
+ _x2 = 0;
+ _y2 = 0;
+ _start = 0;
+ _end = 0;
+ _loopCount = 0;
+ _mask = 0;
+ _framerate = 0;
+
+ char fileName[25];
// The two %*u are always 0 and dont seem to have a use
sscanf(line.c_str(),
- "%*[^:]:%*[^:]:%u(%25s %u %u %u %u %u %u %u %*u %*u %u %u)",
- &_key, fileName, &_x, &_y, &_width, &_height, &_start, &_end, &_loopCount, &_mask, &_framerate);
+ "%24s %u %u %u %u %u %u %d %*u %*u %d %d",
+ fileName, &_x, &_y, &_x2, &_y2, &_start, &_end, &_loopCount, &_mask, &_framerate);
+
+ // 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;
}
-bool ActionPlayAnimation::execute(ZVision *engine) {
- // TODO: Implement
- return true;
+ActionPlayAnimation::~ActionPlayAnimation() {
+ _scriptManager->deleteSideFx(_slotKey);
}
+bool ActionPlayAnimation::execute() {
+ AnimationEffect *nod = (AnimationEffect *)_scriptManager->getSideFX(_slotKey);
+
+ if (!nod) {
+ nod = new AnimationEffect(_engine, _slotKey, _fileName, _mask, _framerate);
+ _scriptManager->addSideFX(nod);
+ } else
+ nod->stop();
+
+ if (nod)
+ nod->addPlayNode(_slotKey, _x, _y, _x2, _y2, _start, _end, _loopCount);
+
+ return true;
+}
//////////////////////////////////////////////////////////////////////////////
// ActionPlayPreloadAnimation
//////////////////////////////////////////////////////////////////////////////
-ActionPlayPreloadAnimation::ActionPlayPreloadAnimation(const Common::String &line) {
+ActionPlayPreloadAnimation::ActionPlayPreloadAnimation(ZVision *engine, int32 slotkey, const Common::String &line) :
+ ResultAction(engine, slotkey) {
+ _controlKey = 0;
+ _x1 = 0;
+ _y1 = 0;
+ _x2 = 0;
+ _y2 = 0;
+ _startFrame = 0;
+ _endFrame = 0;
+ _loopCount = 0;
+
sscanf(line.c_str(),
- "%*[^:]:%*[^:]:%u(%u %u %u %u %u %u %u %u)",
- &_animationKey, &_controlKey, &_x1, &_y1, &_x2, &_y2, &_startFrame, &_endFrame, &_loopCount);
+ "%u %u %u %u %u %u %u %u",
+ &_controlKey, &_x1, &_y1, &_x2, &_y2, &_startFrame, &_endFrame, &_loopCount);
}
-bool ActionPlayPreloadAnimation::execute(ZVision *engine) {
- // Find the control
- AnimationControl *control = (AnimationControl *)engine->getScriptManager()->getControl(_controlKey);
+bool ActionPlayPreloadAnimation::execute() {
+ AnimationEffect *nod = (AnimationEffect *)_scriptManager->getSideFX(_controlKey);
- // Set the needed values within the control
- control->setAnimationKey(_animationKey);
- control->setLoopCount(_loopCount);
- control->setXPos(_x1);
- control->setYPost(_y1);
-
- // Enable the control. ScriptManager will take care of the rest
- control->enable();
+ if (nod)
+ nod->addPlayNode(_slotKey, _x1, _y1, _x2, _y2, _startFrame, _endFrame, _loopCount);
return true;
}
-
//////////////////////////////////////////////////////////////////////////////
// ActionQuit
//////////////////////////////////////////////////////////////////////////////
-bool ActionQuit::execute(ZVision *engine) {
- engine->quitGame();
+bool ActionQuit::execute() {
+ _engine->quitGame();
return true;
}
+//////////////////////////////////////////////////////////////////////////////
+// ActionRegion - only used by Zork: Nemesis
+//////////////////////////////////////////////////////////////////////////////
+
+ActionRegion::ActionRegion(ZVision *engine, int32 slotkey, const Common::String &line) :
+ ResultAction(engine, slotkey) {
+ _delay = 0;
+ _type = 0;
+ _unk1 = 0;
+ _unk2 = 0;
+
+ char art[64];
+ char custom[64];
+
+ int32 x1 = 0, x2 = 0, y1 = 0, y2 = 0;
+
+ sscanf(line.c_str(), "%s %d %d %d %d %hu %hu %hu %hu %s", art, &x1, &y1, &x2, &y2, &_delay, &_type, &_unk1, &_unk2, custom);
+ _art = Common::String(art);
+ _custom = Common::String(custom);
+ _rect = Common::Rect(x1, y1, x2 + 1, y2 + 1);
+}
+
+ActionRegion::~ActionRegion() {
+ _scriptManager->killSideFx(_slotKey);
+}
+
+bool ActionRegion::execute() {
+ if (_scriptManager->getSideFX(_slotKey))
+ return true;
+
+ 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);
+ effect = new WaveFx(_engine, _slotKey, _rect, _unk1, frames, centerX, centerY, amplitude, waveln, speed);
+ }
+ break;
+ case 1: {
+ uint16 aX, aY, aD;
+ if (_engine->getRenderManager()->getRenderTable()->getRenderState() == RenderTable::PANORAMA)
+ sscanf(_art.c_str(), "useart[%hu,%hu,%hu]", &aY, &aX, &aD);
+ else
+ sscanf(_art.c_str(), "useart[%hu,%hu,%hu]", &aX, &aY, &aD);
+ int8 minD;
+ int8 maxD;
+ EffectMap *_map = _engine->getRenderManager()->makeEffectMap(Common::Point(aX, aY), aD, _rect, &minD, &maxD);
+ effect = new LightFx(_engine, _slotKey, _rect, _unk1, _map, atoi(_custom.c_str()), minD, maxD);
+ }
+ break;
+ case 9: {
+ int16 dum1;
+ int32 dum2;
+ char buf[64];
+ sscanf(_custom.c_str(), "%hd,%d,%s", &dum1, &dum2, buf);
+ Graphics::Surface tempMask;
+ _engine->getRenderManager()->readImageToSurface(_art, tempMask);
+ if (_rect.width() != tempMask.w)
+ _rect.setWidth(tempMask.w);
+ if (_rect.height() != tempMask.h)
+ _rect.setHeight(tempMask.h);
+
+ EffectMap *_map = _engine->getRenderManager()->makeEffectMap(tempMask, 0);
+ effect = new FogFx(_engine, _slotKey, _rect, _unk1, _map, Common::String(buf));
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (effect) {
+ _scriptManager->addSideFX(new RegionNode(_engine, _slotKey, effect, _delay));
+ _engine->getRenderManager()->addEffect(effect);
+ }
+
+ return true;
+}
//////////////////////////////////////////////////////////////////////////////
// ActionRandom
//////////////////////////////////////////////////////////////////////////////
-ActionRandom::ActionRandom(const Common::String &line) {
- sscanf(line.c_str(), "%*[^:]:%*[^:]:%u, %u)", &_key, &_max);
+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(_scriptManager, maxBuffer);
+}
+
+ActionRandom::~ActionRandom() {
+ delete _max;
}
-bool ActionRandom::execute(ZVision *engine) {
- uint randNumber = engine->getRandomSource()->getRandomNumber(_max);
- engine->getScriptManager()->setStateValue(_key, randNumber);
+bool ActionRandom::execute() {
+ uint randNumber = _engine->getRandomSource()->getRandomNumber(_max->getValue());
+ _scriptManager->setStateValue(_slotKey, randNumber);
return true;
}
+//////////////////////////////////////////////////////////////////////////////
+// ActionRestoreGame
+//////////////////////////////////////////////////////////////////////////////
+
+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(-1);
+ return false;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionRotateTo
+//////////////////////////////////////////////////////////////////////////////
+
+ActionRotateTo::ActionRotateTo(ZVision *engine, int32 slotkey, const Common::String &line) :
+ ResultAction(engine, slotkey) {
+ _time = 0;
+ _toPos = 0;
+
+ sscanf(line.c_str(), "%d, %d", &_toPos, &_time);
+}
+
+bool ActionRotateTo::execute() {
+ _engine->getRenderManager()->rotateTo(_toPos, _time);
+
+ return true;
+}
//////////////////////////////////////////////////////////////////////////////
// ActionSetPartialScreen
//////////////////////////////////////////////////////////////////////////////
-ActionSetPartialScreen::ActionSetPartialScreen(const Common::String &line) {
- char fileName[26];
- uint color;
+ActionSetPartialScreen::ActionSetPartialScreen(ZVision *engine, int32 slotkey, const Common::String &line) :
+ ResultAction(engine, slotkey) {
+ _x = 0;
+ _y = 0;
+
+ char fileName[25];
- sscanf(line.c_str(), "%*[^(](%u %u %25s %*u %u)", &_x, &_y, fileName, &color);
+ sscanf(line.c_str(), "%u %u %24s %*u %d", &_x, &_y, fileName, &_backgroundColor);
_fileName = Common::String(fileName);
- if (color > 0xFFFF) {
+ if (_backgroundColor > 65535) {
warning("Background color for ActionSetPartialScreen is bigger than a uint16");
}
- _backgroundColor = color;
}
-bool ActionSetPartialScreen::execute(ZVision *engine) {
- RenderManager *renderManager = engine->getRenderManager();
-
- if (_backgroundColor > 0) {
- renderManager->clearWorkingWindowTo555Color(_backgroundColor);
+bool ActionSetPartialScreen::execute() {
+ RenderManager *renderManager = _engine->getRenderManager();
+
+ if (_engine->getGameId() == GID_NEMESIS) {
+ if (_backgroundColor)
+ renderManager->renderImageToBackground(_fileName, _x, _y, 0, 0);
+ else
+ renderManager->renderImageToBackground(_fileName, _x, _y);
+ } else {
+ if (_backgroundColor >= 0)
+ renderManager->renderImageToBackground(_fileName, _x, _y, _backgroundColor);
+ else if (_backgroundColor == -2)
+ renderManager->renderImageToBackground(_fileName, _x, _y, 0, 0);
+ else
+ renderManager->renderImageToBackground(_fileName, _x, _y);
}
- renderManager->renderImageToScreen(_fileName, _x, _y);
return true;
}
-
//////////////////////////////////////////////////////////////////////////////
// ActionSetScreen
//////////////////////////////////////////////////////////////////////////////
-ActionSetScreen::ActionSetScreen(const Common::String &line) {
- char fileName[26];
- sscanf(line.c_str(), "%*[^(](%25[^)])", fileName);
+ActionSetScreen::ActionSetScreen(ZVision *engine, int32 slotkey, const Common::String &line) :
+ ResultAction(engine, slotkey) {
+ char fileName[25];
+ sscanf(line.c_str(), "%24s", fileName);
_fileName = Common::String(fileName);
}
-bool ActionSetScreen::execute(ZVision *engine) {
- engine->getRenderManager()->setBackgroundImage(_fileName);
+bool ActionSetScreen::execute() {
+ _engine->getRenderManager()->setBackgroundImage(_fileName);
return true;
}
+//////////////////////////////////////////////////////////////////////////////
+// ActionStop
+//////////////////////////////////////////////////////////////////////////////
+
+ActionStop::ActionStop(ZVision *engine, int32 slotkey, const Common::String &line) :
+ ResultAction(engine, slotkey) {
+ _key = 0;
+ sscanf(line.c_str(), "%u", &_key);
+}
+
+bool ActionStop::execute() {
+ _scriptManager->stopSideFx(_key);
+ return true;
+}
//////////////////////////////////////////////////////////////////////////////
// ActionStreamVideo
//////////////////////////////////////////////////////////////////////////////
-ActionStreamVideo::ActionStreamVideo(const Common::String &line) {
- char fileName[26];
- uint skippable;
+ActionStreamVideo::ActionStreamVideo(ZVision *engine, int32 slotkey, const Common::String &line) :
+ ResultAction(engine, slotkey) {
+ _x1 = 0;
+ _x2 = 0;
+ _y1 = 0;
+ _y2 = 0;
+ _flags = 0;
- sscanf(line.c_str(), "%*[^(](%25s %u %u %u %u %u %u)", fileName, &_x1, &_y1, &_x2, &_y2, &_flags, &skippable);
+ char fileName[25];
+ uint skipline = 0; //skipline - render video with skip every second line, not skippable.
+
+ sscanf(line.c_str(), "%24s %u %u %u %u %u %u", fileName, &_x1, &_y1, &_x2, &_y2, &_flags, &skipline);
_fileName = Common::String(fileName);
- _skippable = (skippable == 0) ? false : true;
+ _skippable = true;
}
-bool ActionStreamVideo::execute(ZVision *engine) {
- ZorkAVIDecoder decoder;
- if (!decoder.loadFile(_fileName)) {
+bool ActionStreamVideo::execute() {
+ 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;
+ 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
+
+ decoder = _engine->loadAnimation(_fileName);
+ Subtitle *sub = (subtitleExists) ? new Subtitle(_engine, subname, switchToHires) : NULL;
+
+ _engine->getCursorManager()->showMouse(false);
+
+ 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);
}
- Common::Rect destRect;
- if ((_flags & DIFFERENT_DIMENSIONS) == DIFFERENT_DIMENSIONS) {
- destRect = Common::Rect(_x1, _y1, _x2, _y2);
+ _engine->playVideo(*decoder, destRect, _skippable, sub);
+
+ if (switchToHires) {
+ _engine->initScreen();
+ _engine->getRenderManager()->initSubArea(WINDOW_WIDTH, WINDOW_HEIGHT, _engine->_workingWindow);
}
- engine->playVideo(decoder, destRect, _skippable);
+ _engine->getCursorManager()->showMouse(true);
+
+ delete decoder;
+ delete sub;
+
return true;
}
+//////////////////////////////////////////////////////////////////////////////
+// ActionSyncSound
+//////////////////////////////////////////////////////////////////////////////
+
+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 %24s", &_syncto, &notUsed, fileName);
+
+ _fileName = Common::String(fileName);
+}
+
+bool ActionSyncSound::execute() {
+ ScriptingEffect *fx = _scriptManager->getSideFX(_syncto);
+ if (!fx)
+ return true;
+
+ if (!(fx->getType() & ScriptingEffect::SCRIPTING_EFFECT_ANIM))
+ return true;
+
+ _scriptManager->addSideFX(new SyncSoundNode(_engine, _slotKey, _fileName, _syncto));
+ return true;
+}
//////////////////////////////////////////////////////////////////////////////
// ActionTimer
//////////////////////////////////////////////////////////////////////////////
-ActionTimer::ActionTimer(const Common::String &line) {
- sscanf(line.c_str(), "%*[^:]:%*[^:]:%u(%u)", &_key, &_time);
+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(_scriptManager, timeBuffer);
+}
+
+ActionTimer::~ActionTimer() {
+ delete _time;
+ _scriptManager->killSideFx(_slotKey);
+}
+
+bool ActionTimer::execute() {
+ if (_scriptManager->getSideFX(_slotKey))
+ return true;
+ _scriptManager->addSideFX(new TimerNode(_engine, _slotKey, _time->getValue()));
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionTtyText
+//////////////////////////////////////////////////////////////////////////////
+
+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 %63s %u", &x1, &y1, &x2, &y2, filename, &_delay);
+ _r = Common::Rect(x1, y1, x2, y2);
+ _filename = Common::String(filename);
+}
+
+ActionTtyText::~ActionTtyText() {
+ _scriptManager->killSideFx(_slotKey);
}
-bool ActionTimer::execute(ZVision *engine) {
- engine->getScriptManager()->addControl(new TimerNode(engine, _key, _time));
+bool ActionTtyText::execute() {
+ if (_scriptManager->getSideFX(_slotKey))
+ return true;
+ _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 01457d21cc..ff19fc54fc 100644
--- a/engines/zvision/scripting/actions.h
+++ b/engines/zvision/scripting/actions.h
@@ -24,14 +24,16 @@
#define ZVISION_ACTIONS_H
#include "common/str.h"
+#include "common/rect.h"
#include "audio/mixer.h"
-
namespace ZVision {
// Forward declaration of ZVision. This file is included before ZVision is declared
class ZVision;
+class ScriptManager;
+class ValueSlot;
/**
* The base class that represents any action that a Puzzle can take.
@@ -39,6 +41,7 @@ class ZVision;
*/
class ResultAction {
public:
+ ResultAction(ZVision *engine, int32 slotkey);
virtual ~ResultAction() {}
/**
* This is called by the script system whenever a Puzzle's criteria are found to be true.
@@ -48,75 +51,48 @@ public:
* @param engine A pointer to the base engine so the ResultAction can access all the necessary methods
* @return Should the script system continue to test any remaining puzzles (true) or immediately break and go on to the next frame (false)
*/
- virtual bool execute(ZVision *engine) = 0;
-};
-
-
-// The different types of actions
-// DEBUG,
-// DISABLE_CONTROL,
-// DISABLE_VENUS,
-// DISPLAY_MESSAGE,
-// DISSOLVE,
-// DISTORT,
-// ENABLE_CONTROL,
-// FLUSH_MOUSE_EVENTS,
-// INVENTORY,
-// KILL,
-// MENU_BAR_ENABLE,
-// MUSIC,
-// PAN_TRACK,
-// PLAY_PRELOAD,
-// PREFERENCES,
-// QUIT,
-// RANDOM,
-// REGION,
-// RESTORE_GAME,
-// ROTATE_TO,
-// SAVE_GAME,
-// SET_PARTIAL_SCREEN,
-// SET_SCREEN,
-// SET_VENUS,
-// STOP,
-// STREAM_VIDEO,
-// SYNC_SOUND,
-// TTY_TEXT,
-// UNIVERSE_MUSIC,
+ virtual bool execute() = 0;
+protected:
+ ZVision *_engine;
+ ScriptManager *_scriptManager;
+ int32 _slotKey;
+};
class ActionAdd : public ResultAction {
public:
- ActionAdd(const Common::String &line);
- bool execute(ZVision *engine);
+ ActionAdd(ZVision *engine, int32 slotkey, const Common::String &line);
+ bool execute();
private:
uint32 _key;
- uint _value;
+ int _value;
};
class ActionAssign : public ResultAction {
public:
- ActionAssign(const Common::String &line);
- bool execute(ZVision *engine);
+ ActionAssign(ZVision *engine, int32 slotkey, const Common::String &line);
+ ~ActionAssign();
+ bool execute();
private:
uint32 _key;
- uint _value;
+ ValueSlot *_value;
};
class ActionAttenuate : public ResultAction {
public:
- ActionAttenuate(const Common::String &line);
- bool execute(ZVision *engine);
+ ActionAttenuate(ZVision *engine, int32 slotkey, const Common::String &line);
+ bool execute();
private:
uint32 _key;
- int _attenuation;
+ int32 _attenuation;
};
class ActionChangeLocation : public ResultAction {
public:
- ActionChangeLocation(const Common::String &line);
- bool execute(ZVision *engine);
+ ActionChangeLocation(ZVision *engine, int32 slotkey, const Common::String &line);
+ bool execute();
private:
char _world;
@@ -128,121 +104,169 @@ private:
class ActionCrossfade : public ResultAction {
public:
- ActionCrossfade(const Common::String &line);
- bool execute(ZVision *engine);
+ ActionCrossfade(ZVision *engine, int32 slotkey, const Common::String &line);
+ bool execute();
private:
uint32 _keyOne;
uint32 _keyTwo;
- uint _oneStartVolume;
- uint _twoStartVolume;
- uint _oneEndVolume;
- uint _twoEndVolume;
- uint _timeInMillis;
+ int32 _oneStartVolume;
+ int32 _twoStartVolume;
+ int32 _oneEndVolume;
+ int32 _twoEndVolume;
+ int32 _timeInMillis;
};
-class ActionDebug : public ResultAction {
+class ActionCursor : public ResultAction {
public:
- ActionDebug(const Common::String &line);
- bool execute(ZVision *engine);
+ ActionCursor(ZVision *engine, int32 slotkey, const Common::String &line);
+ bool execute();
private:
+ uint8 _action;
};
class ActionDelayRender : public ResultAction {
public:
- ActionDelayRender(const Common::String &line);
- bool execute(ZVision *engine);
+ ActionDelayRender(ZVision *engine, int32 slotkey, const Common::String &line);
+ bool execute();
private:
- // TODO: Check if this should actually be frames or if it should be milliseconds/seconds
- uint32 framesToDelay;
+ uint32 _framesToDelay;
};
class ActionDisableControl : public ResultAction {
public:
- ActionDisableControl(const Common::String &line);
- bool execute(ZVision *engine);
+ ActionDisableControl(ZVision *engine, int32 slotkey, const Common::String &line);
+ bool execute();
private:
uint32 _key;
};
-class ActionDisableVenus : public ResultAction {
+class ActionDisplayMessage : public ResultAction {
public:
- ActionDisableVenus(const Common::String &line);
- bool execute(ZVision *engine);
+ ActionDisplayMessage(ZVision *engine, int32 slotkey, const Common::String &line);
+ bool execute();
private:
+ int16 _control;
+ int16 _msgid;
};
-class ActionDisplayMessage : public ResultAction {
+class ActionDissolve : public ResultAction {
public:
- ActionDisplayMessage(const Common::String &line);
- bool execute(ZVision *engine);
+ ActionDissolve(ZVision *engine);
+ bool execute();
+};
+
+class ActionDistort : public ResultAction {
+public:
+ ActionDistort(ZVision *engine, int32 slotkey, const Common::String &line);
+ ~ActionDistort();
+ bool execute();
private:
+ int16 _distSlot;
+ int16 _speed;
+ float _startAngle;
+ float _endAngle;
+ float _startLineScale;
+ float _endLineScale;
};
-class ActionDissolve : public ResultAction {
+class ActionEnableControl : public ResultAction {
public:
- ActionDissolve();
- bool execute(ZVision *engine);
+ ActionEnableControl(ZVision *engine, int32 slotkey, const Common::String &line);
+ bool execute();
+
+private:
+ uint32 _key;
};
-class ActionDistort : public ResultAction {
+class ActionFlushMouseEvents : public ResultAction {
public:
- ActionDistort(const Common::String &line);
- bool execute(ZVision *engine);
+ ActionFlushMouseEvents(ZVision *engine, int32 slotkey);
+ bool execute();
+};
+class ActionInventory : public ResultAction {
+public:
+ ActionInventory(ZVision *engine, int32 slotkey, const Common::String &line);
+ bool execute();
private:
+ int8 _type;
+ int32 _key;
};
-class ActionEnableControl : public ResultAction {
+class ActionKill : public ResultAction {
public:
- ActionEnableControl(const Common::String &line);
- bool execute(ZVision *engine);
+ ActionKill(ZVision *engine, int32 slotkey, const Common::String &line);
+ bool execute();
private:
uint32 _key;
+ uint32 _type;
+};
+
+class ActionMenuBarEnable : public ResultAction {
+public:
+ ActionMenuBarEnable(ZVision *engine, int32 slotkey, const Common::String &line);
+ bool execute();
+private:
+ uint16 _menus;
};
class ActionMusic : public ResultAction {
public:
- ActionMusic(const Common::String &line);
- bool execute(ZVision *engine);
+ ActionMusic(ZVision *engine, int32 slotkey, const Common::String &line, bool global);
+ ~ActionMusic();
+ bool execute();
private:
- uint32 _key;
- Audio::Mixer::SoundType _soundType;
Common::String _fileName;
bool _loop;
- byte _volume;
+ ValueSlot *_volume;
+ bool _universe;
+ bool _midi;
+ int8 _note;
+ int8 _prog;
+};
+
+class ActionPanTrack : public ResultAction {
+public:
+ ActionPanTrack(ZVision *engine, int32 slotkey, const Common::String &line);
+ ~ActionPanTrack();
+ bool execute();
+
+private:
+ int32 _pos;
+ uint32 _musicSlot;
};
class ActionPlayAnimation : public ResultAction {
public:
- ActionPlayAnimation(const Common::String &line);
- bool execute(ZVision *engine);
+ ActionPlayAnimation(ZVision *engine, int32 slotkey, const Common::String &line);
+ ~ActionPlayAnimation();
+ bool execute();
private:
- uint32 _key;
Common::String _fileName;
uint32 _x;
uint32 _y;
- uint32 _width;
- uint32 _height;
+ uint32 _x2;
+ uint32 _y2;
uint32 _start;
uint32 _end;
- uint _mask;
- uint _framerate;
- uint _loopCount;
+ int32 _mask;
+ int32 _framerate;
+ int32 _loopCount;
};
class ActionPlayPreloadAnimation : public ResultAction {
public:
- ActionPlayPreloadAnimation(const Common::String &line);
- bool execute(ZVision *engine);
+ ActionPlayPreloadAnimation(ZVision *engine, int32 slotkey, const Common::String &line);
+ bool execute();
private:
uint32 _animationKey;
@@ -258,64 +282,119 @@ private:
class ActionPreloadAnimation : public ResultAction {
public:
- ActionPreloadAnimation(const Common::String &line);
- bool execute(ZVision *engine);
+ ActionPreloadAnimation(ZVision *engine, int32 slotkey, const Common::String &line);
+ ~ActionPreloadAnimation();
+ bool execute();
private:
- uint32 _key;
Common::String _fileName;
- uint _mask;
- uint _framerate;
+ int32 _mask;
+ int32 _framerate;
+};
+
+class ActionPreferences : public ResultAction {
+public:
+ ActionPreferences(ZVision *engine, int32 slotkey, const Common::String &line);
+ bool execute();
+
+private:
+ bool _save;
};
class ActionQuit : public ResultAction {
public:
- ActionQuit() {}
- bool execute(ZVision *engine);
+ ActionQuit(ZVision *engine, int32 slotkey) : ResultAction(engine, slotkey) {}
+ bool execute();
};
-// TODO: See if this exists in ZGI. It doesn't in ZNem
+class ActionRegion : public ResultAction {
+public:
+ ActionRegion(ZVision *engine, int32 slotkey, const Common::String &line);
+ ~ActionRegion();
+ bool execute();
+
+private:
+ Common::String _art;
+ Common::String _custom;
+ Common::Rect _rect;
+ uint16 _delay;
+ uint16 _type;
+ uint16 _unk1;
+ uint16 _unk2;
+};
+
+// Only used by ZGI (locations cd6e, cd6k, dg2f, dg4e, dv1j)
class ActionUnloadAnimation : public ResultAction {
public:
- ActionUnloadAnimation(const Common::String &line);
- bool execute(ZVision *engine);
+ ActionUnloadAnimation(ZVision *engine, int32 slotkey, const Common::String &line);
+ bool execute();
+private:
+ uint32 _key;
};
class ActionRandom : public ResultAction {
public:
- ActionRandom(const Common::String &line);
- bool execute(ZVision *engine);
+ ActionRandom(ZVision *engine, int32 slotkey, const Common::String &line);
+ ~ActionRandom();
+ bool execute();
private:
- uint32 _key;
- uint _max;
+ ValueSlot *_max;
+};
+
+class ActionRestoreGame : public ResultAction {
+public:
+ ActionRestoreGame(ZVision *engine, int32 slotkey, const Common::String &line);
+ bool execute();
+
+private:
+ Common::String _fileName;
+};
+
+class ActionRotateTo : public ResultAction {
+public:
+ ActionRotateTo(ZVision *engine, int32 slotkey, const Common::String &line);
+ bool execute();
+
+private:
+ int32 _toPos;
+ int32 _time;
};
class ActionSetPartialScreen : public ResultAction {
public:
- ActionSetPartialScreen(const Common::String &line);
- bool execute(ZVision *engine);
+ ActionSetPartialScreen(ZVision *engine, int32 slotkey, const Common::String &line);
+ bool execute();
private:
uint _x;
uint _y;
Common::String _fileName;
- uint16 _backgroundColor;
+ int32 _backgroundColor;
};
class ActionSetScreen : public ResultAction {
public:
- ActionSetScreen(const Common::String &line);
- bool execute(ZVision *engine);
+ ActionSetScreen(ZVision *engine, int32 slotkey, const Common::String &line);
+ bool execute();
private:
Common::String _fileName;
};
+class ActionStop : public ResultAction {
+public:
+ ActionStop(ZVision *engine, int32 slotkey, const Common::String &line);
+ bool execute();
+
+private:
+ uint32 _key;
+};
+
class ActionStreamVideo : public ResultAction {
public:
- ActionStreamVideo(const Common::String &line);
- bool execute(ZVision *engine);
+ ActionStreamVideo(ZVision *engine, int32 slotkey, const Common::String &line);
+ bool execute();
private:
enum {
@@ -331,16 +410,36 @@ private:
bool _skippable;
};
-class ActionTimer : public ResultAction {
+class ActionSyncSound : public ResultAction {
public:
- ActionTimer(const Common::String &line);
- bool execute(ZVision *engine);
+ ActionSyncSound(ZVision *engine, int32 slotkey, const Common::String &line);
+ bool execute();
private:
- uint32 _key;
- uint _time;
+ int _syncto;
+ Common::String _fileName;
};
+class ActionTimer : public ResultAction {
+public:
+ ActionTimer(ZVision *engine, int32 slotkey, const Common::String &line);
+ ~ActionTimer();
+ bool execute();
+private:
+ ValueSlot *_time;
+};
+
+class ActionTtyText : public ResultAction {
+public:
+ ActionTtyText(ZVision *engine, int32 slotkey, const Common::String &line);
+ ~ActionTtyText();
+ bool execute();
+
+private:
+ Common::String _filename;
+ uint32 _delay;
+ Common::Rect _r;
+};
} // End of namespace ZVision
#endif
diff --git a/engines/zvision/scripting/control.cpp b/engines/zvision/scripting/control.cpp
index 2343c83c56..81123eb99b 100644
--- a/engines/zvision/scripting/control.cpp
+++ b/engines/zvision/scripting/control.cpp
@@ -23,34 +23,15 @@
#include "common/scummsys.h"
#include "zvision/scripting/control.h"
+#include "zvision/scripting/script_manager.h"
#include "zvision/zvision.h"
#include "zvision/graphics/render_manager.h"
-#include "zvision/utility/utility.h"
#include "common/stream.h"
-
namespace ZVision {
-void Control::enable() {
- if (!_enabled) {
- _enabled = true;
- return;
- }
-
- debug("Control %u is already enabled", _key);
-}
-
-void Control::disable() {
- if (_enabled) {
- _enabled = false;
- return;
- }
-
- debug("Control %u is already disabled", _key);
-}
-
void Control::parseFlatControl(ZVision *engine) {
engine->getRenderManager()->getRenderTable()->setRenderState(RenderTable::FLAT);
}
@@ -61,7 +42,7 @@ void Control::parsePanoramaControl(ZVision *engine, Common::SeekableReadStream &
// Loop until we find the closing brace
Common::String line = stream.readLine();
- trimCommentsAndWhiteSpace(&line);
+ engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
while (!stream.eos() && !line.contains('}')) {
if (line.matchString("angle*", true)) {
@@ -79,23 +60,26 @@ void Control::parsePanoramaControl(ZVision *engine, Common::SeekableReadStream &
renderTable->setPanoramaReverse(true);
}
} else if (line.matchString("zeropoint*", true)) {
- // TODO: Implement
+ uint point;
+ sscanf(line.c_str(), "zeropoint(%u)", &point);
+ renderTable->setPanoramaZeroPoint(point);
}
line = stream.readLine();
- trimCommentsAndWhiteSpace(&line);
+ engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
}
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);
// Loop until we find the closing brace
Common::String line = stream.readLine();
- trimCommentsAndWhiteSpace(&line);
+ engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
while (!stream.eos() && !line.contains('}')) {
if (line.matchString("angle*", true)) {
@@ -115,10 +99,40 @@ void Control::parseTiltControl(ZVision *engine, Common::SeekableReadStream &stre
}
line = stream.readLine();
- trimCommentsAndWhiteSpace(&line);
+ engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
}
renderTable->generateRenderTable();
}
+void Control::getParams(const Common::String &inputStr, Common::String &parameter, Common::String &values) {
+ const char *chrs = inputStr.c_str();
+ uint lbr;
+
+ for (lbr = 0; lbr < inputStr.size(); lbr++)
+ if (chrs[lbr] == '(')
+ break;
+
+ if (lbr >= inputStr.size())
+ return;
+
+ uint rbr;
+
+ for (rbr = lbr + 1; rbr < inputStr.size(); rbr++)
+ if (chrs[rbr] == ')')
+ break;
+
+ if (rbr >= inputStr.size())
+ return;
+
+ parameter = Common::String(chrs, chrs + lbr);
+ values = Common::String(chrs + lbr + 1, chrs + rbr);
+}
+
+void Control::setVenus() {
+ if (_venusId >= 0)
+ if (_engine->getScriptManager()->getStateValue(_venusId) > 0)
+ _engine->getScriptManager()->setStateValue(StateKey_Venus, _venusId);
+}
+
} // End of namespace ZVision
diff --git a/engines/zvision/scripting/control.h b/engines/zvision/scripting/control.h
index ffeacb273d..108b83fd00 100644
--- a/engines/zvision/scripting/control.h
+++ b/engines/zvision/scripting/control.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.
@@ -24,7 +24,7 @@
#define ZVISION_CONTROL_H
#include "common/keyboard.h"
-
+#include "common/str.h"
namespace Common {
class SeekableReadStream;
@@ -36,16 +36,39 @@ 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:
- Control() : _engine(0), _key(0), _enabled(false) {}
- Control(ZVision *engine, uint32 key) : _engine(engine), _key(key), _enabled(false) {}
+
+ enum ControlType {
+ CONTROL_UNKNOW,
+ CONTROL_INPUT,
+ CONTROL_PUSHTGL,
+ CONTROL_SLOT,
+ CONTROL_LEVER,
+ CONTROL_SAVE,
+ CONTROL_SAFE,
+ CONTROL_FIST,
+ CONTROL_TITLER,
+ CONTROL_HOTMOV,
+ CONTROL_PAINT
+ };
+
+ Control(ZVision *engine, uint32 key, ControlType type) : _engine(engine), _key(key), _type(type), _venusId(-1) {}
virtual ~Control() {}
- uint32 getKey() { return _key; }
+ uint32 getKey() {
+ return _key;
+ }
+
+ ControlType getType() {
+ return _type;
+ }
- virtual void enable();
- virtual void disable();
virtual void focus() {}
virtual void unfocus() {}
/**
@@ -54,14 +77,18 @@ public:
* @param screenSpacePos The position of the mouse in screen space
* @param backgroundImageSpacePos The position of the mouse in background image space
*/
- virtual void onMouseDown(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {}
+ virtual bool onMouseDown(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ return false;
+ }
/**
* Called when LeftMouse is lifted. Default is NOP.
*
* @param screenSpacePos The position of the mouse in screen space
* @param backgroundImageSpacePos The position of the mouse in background image space
*/
- virtual void onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {}
+ virtual bool onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ return false;
+ }
/**
* Called on every MouseMove. Default is NOP.
*
@@ -69,78 +96,52 @@ public:
* @param backgroundImageSpacePos The position of the mouse in background image space
* @return Was the cursor changed?
*/
- virtual bool onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) { return false; }
+ virtual bool onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ return false;
+ }
/**
* Called when a key is pressed. Default is NOP.
*
* @param keycode The key that was pressed
*/
- virtual void onKeyDown(Common::KeyState keyState) {}
+ virtual bool onKeyDown(Common::KeyState keyState) {
+ return false;
+ }
/**
* Called when a key is released. Default is NOP.
*
* @param keycode The key that was pressed
*/
- virtual void onKeyUp(Common::KeyState keyState) {}
+ virtual bool onKeyUp(Common::KeyState keyState) {
+ return false;
+ }
/**
* Processes the node given the deltaTime since last frame. Default is NOP.
*
* @param deltaTimeInMillis The number of milliseconds that have passed since last frame
* @return If true, the node can be deleted after process() finishes
*/
- virtual bool process(uint32 deltaTimeInMillis) { return false; }
- /**
- * Serialize a Control for save game use. This should only be used if a Control needs
- * to save values that would be different from initialization. AKA a TimerNode needs to
- * store the amount of time left on the timer. Any Controls overriding this *MUST* write
- * their key as the first data outputted. The default implementation is NOP.
- *
- * NOTE: If this method is overridden, you MUST also override deserialize()
- * and needsSerialization()
- *
- * @param stream Stream to write any needed data to
- */
- virtual void serialize(Common::WriteStream *stream) {}
- /**
- * De-serialize data from a save game stream. This should only be implemented if the
- * Control also implements serialize(). The calling method assumes the size of the
- * data read from the stream exactly equals that written in serialize(). The default
- * implementation is NOP.
- *
- * NOTE: If this method is overridden, you MUST also override serialize()
- * and needsSerialization()
- *
- * @param stream Save game file stream
- */
- virtual void deserialize(Common::SeekableReadStream *stream) {}
- /**
- * If a Control overrides serialize() and deserialize(), this should return true
- *
- * @return Does the Control need save game serialization?
- */
- virtual inline bool needsSerialization() { return false; }
+ virtual bool process(uint32 deltaTimeInMillis) {
+ return false;
+ }
+
+ void setVenus();
protected:
- ZVision * _engine;
+ ZVision *_engine;
uint32 _key;
- bool _enabled;
+ int32 _venusId;
+ void getParams(const Common::String &inputStr, Common::String &parameter, Common::String &values);
// Static member functions
public:
static void parseFlatControl(ZVision *engine);
static void parsePanoramaControl(ZVision *engine, Common::SeekableReadStream &stream);
static void parseTiltControl(ZVision *engine, Common::SeekableReadStream &stream);
+private:
+ ControlType _type;
};
-// TODO: Implement InputControl
-// TODO: Implement SaveControl
-// TODO: Implement SlotControl
-// TODO: Implement SafeControl
-// TODO: Implement FistControl
-// TODO: Implement HotMovieControl
-// TODO: Implement PaintControl
-// TODO: Implement TilterControl
-
} // End of namespace ZVision
#endif
diff --git a/engines/zvision/scripting/controls/animation_control.cpp b/engines/zvision/scripting/controls/animation_control.cpp
deleted file mode 100644
index e351e81d25..0000000000
--- a/engines/zvision/scripting/controls/animation_control.cpp
+++ /dev/null
@@ -1,263 +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 "zvision/scripting/controls/animation_control.h"
-
-#include "zvision/zvision.h"
-#include "zvision/graphics/render_manager.h"
-#include "zvision/scripting/script_manager.h"
-#include "zvision/animation/rlf_animation.h"
-#include "zvision/video/zork_avi_decoder.h"
-
-#include "video/video_decoder.h"
-
-#include "graphics/surface.h"
-
-
-namespace ZVision {
-
-AnimationControl::AnimationControl(ZVision *engine, uint32 controlKey, const Common::String &fileName)
- : Control(engine, controlKey),
- _fileType(RLF),
- _loopCount(1),
- _currentLoop(0),
- _accumulatedTime(0),
- _cachedFrame(0),
- _cachedFrameNeedsDeletion(false) {
- if (fileName.hasSuffix(".rlf")) {
- _fileType = RLF;
- _animation.rlf = new RlfAnimation(fileName, false);
- } else if (fileName.hasSuffix(".avi")) {
- _fileType = AVI;
- _animation.avi = new ZorkAVIDecoder();
- _animation.avi->loadFile(fileName);
- } else {
- warning("Unrecognized animation file type: %s", fileName.c_str());
- }
-
- _cachedFrame = new Graphics::Surface();
-}
-
-AnimationControl::~AnimationControl() {
- if (_fileType == RLF) {
- delete _animation.rlf;
- } else if (_fileType == AVI) {
- delete _animation.avi;
- }
-
- _cachedFrame->free();
- delete _cachedFrame;
-}
-
-bool AnimationControl::process(uint32 deltaTimeInMillis) {
- if (!_enabled) {
- return false;
- }
-
- bool finished = false;
-
- if (_fileType == RLF) {
- _accumulatedTime += deltaTimeInMillis;
-
- uint32 frameTime = _animation.rlf->frameTime();
- if (_accumulatedTime >= frameTime) {
- while (_accumulatedTime >= frameTime) {
- _accumulatedTime -= frameTime;
-
- // Make sure the frame is inside the working window
- // If it's not, then just return
-
- RenderManager *renderManager = _engine->getRenderManager();
- Common::Point workingWindowPoint = renderManager->imageSpaceToWorkingWindowSpace(Common::Point(_x, _y));
- Common::Rect subRect(workingWindowPoint.x, workingWindowPoint.y, workingWindowPoint.x + _animation.rlf->width(), workingWindowPoint.y + _animation.rlf->height());
-
- // If the clip returns false, it means the animation is outside the working window
- if (!renderManager->clipRectToWorkingWindow(subRect)) {
- return false;
- }
-
- const Graphics::Surface *frame = _animation.rlf->getNextFrame();
-
- // Animation frames for PANORAMAs are transposed, so un-transpose them
- RenderTable::RenderState state = renderManager->getRenderTable()->getRenderState();
- if (state == RenderTable::PANORAMA) {
- Graphics::Surface *tranposedFrame = RenderManager::tranposeSurface(frame);
-
- renderManager->copyRectToWorkingWindow((uint16 *)tranposedFrame->getBasePtr(tranposedFrame->w - subRect.width(), tranposedFrame->h - subRect.height()), subRect.left, subRect.top, _animation.rlf->width(), subRect.width(), subRect.height());
-
- // If the background can move, we need to cache the last frame so it can be rendered during background movement
- if (state == RenderTable::PANORAMA || state == RenderTable::TILT) {
- if (_cachedFrameNeedsDeletion) {
- _cachedFrame->free();
- delete _cachedFrame;
- _cachedFrameNeedsDeletion = false;
- }
- _cachedFrame = tranposedFrame;
- _cachedFrameNeedsDeletion = true;
- } else {
- // Cleanup
- tranposedFrame->free();
- delete tranposedFrame;
- }
- } else {
- renderManager->copyRectToWorkingWindow((const uint16 *)frame->getBasePtr(frame->w - subRect.width(), frame->h - subRect.height()), subRect.left, subRect.top, _animation.rlf->width(), subRect.width(), subRect.height());
-
- // If the background can move, we need to cache the last frame so it can be rendered during background movement
- if (state == RenderTable::PANORAMA || state == RenderTable::TILT) {
- if (_cachedFrameNeedsDeletion) {
- _cachedFrame->free();
- delete _cachedFrame;
- _cachedFrameNeedsDeletion = false;
- }
- _cachedFrame->copyFrom(*frame);
- }
- }
-
- // Check if we should continue looping
- if (_animation.rlf->endOfAnimation()) {
- _animation.rlf->seekToFrame(-1);
- if (_loopCount > 0) {
- _currentLoop++;
- if (_currentLoop >= _loopCount) {
- finished = true;
- }
- }
- }
- }
- } else {
- // If the background can move, we have to keep rendering animation frames, otherwise the animation flickers during background movement
- RenderManager *renderManager = _engine->getRenderManager();
- RenderTable::RenderState state = renderManager->getRenderTable()->getRenderState();
-
- if (state == RenderTable::PANORAMA || state == RenderTable::TILT) {
- Common::Point workingWindowPoint = renderManager->imageSpaceToWorkingWindowSpace(Common::Point(_x, _y));
- Common::Rect subRect(workingWindowPoint.x, workingWindowPoint.y, workingWindowPoint.x + _cachedFrame->w, workingWindowPoint.y + _cachedFrame->h);
-
- // If the clip returns false, it means the animation is outside the working window
- if (!renderManager->clipRectToWorkingWindow(subRect)) {
- return false;
- }
-
- renderManager->copyRectToWorkingWindow((uint16 *)_cachedFrame->getBasePtr(_cachedFrame->w - subRect.width(), _cachedFrame->h - subRect.height()), subRect.left, subRect.top, _cachedFrame->w, subRect.width(), subRect.height());
- }
- }
- } else if (_fileType == AVI) {
- if (!_animation.avi->isPlaying()) {
- _animation.avi->start();
- }
-
- if (_animation.avi->needsUpdate()) {
- const Graphics::Surface *frame = _animation.avi->decodeNextFrame();
-
- if (frame) {
- // Make sure the frame is inside the working window
- // If it's not, then just return
-
- RenderManager *renderManager = _engine->getRenderManager();
- Common::Point workingWindowPoint = renderManager->imageSpaceToWorkingWindowSpace(Common::Point(_x, _y));
- Common::Rect subRect(workingWindowPoint.x, workingWindowPoint.y, workingWindowPoint.x + frame->w, workingWindowPoint.y + frame->h);
-
- // If the clip returns false, it means the animation is outside the working window
- if (!renderManager->clipRectToWorkingWindow(subRect)) {
- return false;
- }
-
- // Animation frames for PANORAMAs are transposed, so un-transpose them
- RenderTable::RenderState state = renderManager->getRenderTable()->getRenderState();
- if (state == RenderTable::PANORAMA) {
- Graphics::Surface *tranposedFrame = RenderManager::tranposeSurface(frame);
-
- renderManager->copyRectToWorkingWindow((uint16 *)tranposedFrame->getBasePtr(tranposedFrame->w - subRect.width(), tranposedFrame->h - subRect.height()), subRect.left, subRect.top, frame->w, subRect.width(), subRect.height());
-
- // If the background can move, we need to cache the last frame so it can be rendered during background movement
- if (state == RenderTable::PANORAMA || state == RenderTable::TILT) {
- if (_cachedFrameNeedsDeletion) {
- _cachedFrame->free();
- delete _cachedFrame;
- _cachedFrameNeedsDeletion = false;
- }
- _cachedFrame = tranposedFrame;
- _cachedFrameNeedsDeletion = true;
- } else {
- // Cleanup
- tranposedFrame->free();
- delete tranposedFrame;
- }
- } else {
- renderManager->copyRectToWorkingWindow((const uint16 *)frame->getBasePtr(frame->w - subRect.width(), frame->h - subRect.height()), subRect.left, subRect.top, frame->w, subRect.width(), subRect.height());
-
- // If the background can move, we need to cache the last frame so it can be rendered during background movement
- if (state == RenderTable::PANORAMA || state == RenderTable::TILT) {
- if (_cachedFrameNeedsDeletion) {
- _cachedFrame->free();
- delete _cachedFrame;
- _cachedFrameNeedsDeletion = false;
- }
- _cachedFrame->copyFrom(*frame);
- }
- }
- } else {
- // If the background can move, we have to keep rendering animation frames, otherwise the animation flickers during background movement
- RenderManager *renderManager = _engine->getRenderManager();
- RenderTable::RenderState state = renderManager->getRenderTable()->getRenderState();
-
- if (state == RenderTable::PANORAMA || state == RenderTable::TILT) {
- Common::Point workingWindowPoint = renderManager->imageSpaceToWorkingWindowSpace(Common::Point(_x, _y));
- Common::Rect subRect(workingWindowPoint.x, workingWindowPoint.y, workingWindowPoint.x + _cachedFrame->w, workingWindowPoint.y + _cachedFrame->h);
-
- // If the clip returns false, it means the animation is outside the working window
- if (!renderManager->clipRectToWorkingWindow(subRect)) {
- return false;
- }
-
- renderManager->copyRectToWorkingWindow((uint16 *)_cachedFrame->getBasePtr(_cachedFrame->w - subRect.width(), _cachedFrame->h - subRect.height()), subRect.left, subRect.top, _cachedFrame->w, subRect.width(), subRect.height());
- }
- }
- }
-
- // Check if we should continue looping
- if (_animation.avi->endOfVideo()) {
- _animation.avi->rewind();
- if (_loopCount > 0) {
- _currentLoop++;
- if (_currentLoop >= _loopCount) {
- _animation.avi->stop();
- finished = true;
- }
- }
- }
- }
-
- // If we're done, set _animation key = 2 (Why 2? I don't know. It's just the value that they used)
- // Then disable the control. DON'T delete it. It can be re-used
- if (finished) {
- _engine->getScriptManager()->setStateValue(_animationKey, 2);
- disable();
- _currentLoop = 0;
- }
-
- return false;
-}
-
-} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/fist_control.cpp b/engines/zvision/scripting/controls/fist_control.cpp
new file mode 100644
index 0000000000..f79c82dc79
--- /dev/null
+++ b/engines/zvision/scripting/controls/fist_control.cpp
@@ -0,0 +1,304 @@
+/* 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 "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/scripting/controls/fist_control.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/graphics/cursors/cursor_manager.h"
+#include "zvision/video/rlf_decoder.h"
+
+#include "common/stream.h"
+#include "common/file.h"
+#include "common/system.h"
+#include "graphics/surface.h"
+#include "video/video_decoder.h"
+
+namespace ZVision {
+
+FistControl::FistControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
+ : Control(engine, key, CONTROL_FIST) {
+ _cursor = CursorIndex_Idle;
+ _animation = NULL;
+ _soundKey = 0;
+ _fiststatus = 0;
+ _order = 0;
+ _fistnum = 0;
+
+ _animationId = 0;
+
+ clearFistArray(_fistsUp);
+ clearFistArray(_fistsDwn);
+
+ _numEntries = 0;
+ _entries.clear();
+
+ _anmRect = Common::Rect();
+
+ // Loop until we find the closing brace
+ Common::String line = stream.readLine();
+ _engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
+ Common::String param;
+ Common::String values;
+ getParams(line, param, values);
+
+ while (!stream.eos() && !line.contains('}')) {
+ if (param.matchString("sound_key", true)) {
+ _soundKey = atoi(values.c_str());
+ } else if (param.matchString("cursor", true)) {
+ _cursor = _engine->getCursorManager()->getCursorId(values);
+ } else if (param.matchString("descfile", true)) {
+ readDescFile(values);
+ } else if (param.matchString("animation_id", true)) {
+ _animationId = atoi(values.c_str());
+ } else if (param.matchString("venus_id", true)) {
+ _venusId = atoi(values.c_str());
+ }
+
+ line = stream.readLine();
+ _engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
+ getParams(line, param, values);
+ }
+}
+
+FistControl::~FistControl() {
+ if (_animation)
+ delete _animation;
+
+ clearFistArray(_fistsUp);
+ clearFistArray(_fistsDwn);
+ _entries.clear();
+}
+
+bool FistControl::process(uint32 deltaTimeInMillis) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ if (_animation && _animation->isPlaying()) {
+ if (_animation->endOfVideo()) {
+ _animation->stop();
+ _engine->getScriptManager()->setStateValue(_animationId, 2);
+ return false;
+ }
+
+ 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;
+}
+
+bool FistControl::onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ if (mouseIn(screenSpacePos, backgroundImageSpacePos) >= 0) {
+ _engine->getCursorManager()->changeCursor(_cursor);
+ return true;
+ }
+
+ return false;
+}
+
+bool FistControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ int fistNumber = mouseIn(screenSpacePos, backgroundImageSpacePos);
+
+ if (fistNumber >= 0) {
+ setVenus();
+
+ uint32 oldStatus = _fiststatus;
+ _fiststatus ^= (1 << fistNumber);
+
+ for (int i = 0; i < _numEntries; i++)
+ if (_entries[i]._bitsStrt == oldStatus && _entries[i]._bitsEnd == _fiststatus) {
+ 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);
+ break;
+ }
+
+ _engine->getScriptManager()->setStateValue(_key, _fiststatus);
+ }
+
+ return false;
+}
+
+void FistControl::readDescFile(const Common::String &fileName) {
+ Common::File file;
+ if (!_engine->getSearchManager()->openFile(file, fileName)) {
+ warning("Desc file %s could could be opened", fileName.c_str());
+ return;
+ }
+
+ Common::String line;
+ Common::String param;
+ Common::String values;
+
+ while (!file.eos()) {
+ line = file.readLine();
+ getFistParams(line, param, values);
+
+ if (param.matchString("animation_id", true)) {
+ // Not used
+ } else if (param.matchString("animation", true)) {
+ _animation = _engine->loadAnimation(values);
+ } else if (param.matchString("anim_rect", true)) {
+ int left, top, right, bottom;
+ sscanf(values.c_str(), "%d %d %d %d", &left, &top, &right, &bottom);
+ _anmRect = Common::Rect(left, top, right, bottom);
+ } else if (param.matchString("num_fingers", true)) {
+ sscanf(values.c_str(), "%d", &_fistnum);
+ _fistsUp.resize(_fistnum);
+ _fistsDwn.resize(_fistnum);
+ } else if (param.matchString("entries", true)) {
+ sscanf(values.c_str(), "%d", &_numEntries);
+ _entries.resize(_numEntries);
+ } else if (param.matchString("eval_order_ascending", true)) {
+ sscanf(values.c_str(), "%d", &_order);
+ } else if (param.matchString("up_hs_num_*", true)) {
+ int fist, num;
+ num = atoi(values.c_str());
+
+ sscanf(param.c_str(), "up_hs_num_%d", &fist);
+ _fistsUp[fist].resize(num);
+ } else if (param.matchString("up_hs_*", true)) {
+ int16 fist, box, x1, y1, x2, y2;
+ sscanf(param.c_str(), "up_hs_%hd_%hd", &fist, &box);
+ sscanf(values.c_str(), "%hd %hd %hd %hd", &x1, &y1, &x2, &y2);
+ (_fistsUp[fist])[box] = Common::Rect(x1, y1, x2, y2);
+ } else if (param.matchString("down_hs_num_*", true)) {
+ int fist, num;
+ num = atoi(values.c_str());
+
+ sscanf(param.c_str(), "down_hs_num_%d", &fist);
+ _fistsDwn[fist].resize(num);
+ } else if (param.matchString("down_hs_*", true)) {
+ int16 fist, box, x1, y1, x2, y2;
+ sscanf(param.c_str(), "down_hs_%hd_%hd", &fist, &box);
+ sscanf(values.c_str(), "%hd %hd %hd %hd", &x1, &y1, &x2, &y2);
+ (_fistsDwn[fist])[box] = Common::Rect(x1, y1, x2, y2);
+ } else {
+ int entry, start, end, sound;
+ char bitsStart[33];
+ char bitsEnd[33];
+ entry = atoi(param.c_str());
+ if (sscanf(values.c_str(), "%s %s %d %d (%d)", bitsStart, bitsEnd, &start, &end, &sound) == 5) {
+ _entries[entry]._bitsStrt = readBits(bitsStart);
+ _entries[entry]._bitsEnd = readBits(bitsEnd);
+ _entries[entry]._anmStrt = start;
+ _entries[entry]._anmEnd = end;
+ _entries[entry]._sound = sound;
+ }
+ }
+ }
+ file.close();
+}
+
+void FistControl::clearFistArray(Common::Array< Common::Array<Common::Rect> > &arr) {
+ for (uint i = 0; i < arr.size(); i++)
+ arr[i].clear();
+
+ arr.clear();
+}
+
+uint32 FistControl::readBits(const char *str) {
+ uint32 bfield = 0;
+ int len = strlen(str);
+ for (int i = 0; i < len; i++)
+ if (str[i] != '0')
+ bfield |= (1 << i);
+ return bfield;
+}
+
+int FistControl::mouseIn(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (_order) {
+ for (int i = 0; i < _fistnum; i++) {
+ if (((_fiststatus >> i) & 1) == 1) {
+ for (uint j = 0; j < _fistsDwn[i].size(); j++)
+ if ((_fistsDwn[i])[j].contains(backgroundImageSpacePos))
+ return i;
+ } else {
+ for (uint j = 0; j < _fistsUp[i].size(); j++)
+ if ((_fistsUp[i])[j].contains(backgroundImageSpacePos))
+ return i;
+ }
+ }
+ } else {
+ for (int i = _fistnum - 1; i >= 0; i--) {
+ if (((_fiststatus >> i) & 1) == 1) {
+ for (uint j = 0; j < _fistsDwn[i].size(); j++)
+ if ((_fistsDwn[i])[j].contains(backgroundImageSpacePos))
+ return i;
+ } else {
+ for (uint j = 0; j < _fistsUp[i].size(); j++)
+ if ((_fistsUp[i])[j].contains(backgroundImageSpacePos))
+ return i;
+ }
+ }
+ }
+ return -1;
+}
+
+void FistControl::getFistParams(const Common::String &inputStr, Common::String &parameter, Common::String &values) {
+ const char *chrs = inputStr.c_str();
+ uint lbr;
+
+ for (lbr = 0; lbr < inputStr.size(); lbr++)
+ if (chrs[lbr] == ':')
+ break;
+
+ if (lbr >= inputStr.size())
+ return;
+
+ uint rbr;
+
+ for (rbr = lbr + 1; rbr < inputStr.size(); rbr++)
+ if (chrs[rbr] == '~')
+ break;
+
+ if (rbr >= inputStr.size())
+ return;
+
+ parameter = Common::String(chrs, chrs + lbr);
+ values = Common::String(chrs + lbr + 1, chrs + rbr);
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/fist_control.h b/engines/zvision/scripting/controls/fist_control.h
new file mode 100644
index 0000000000..d7cbcb1f71
--- /dev/null
+++ b/engines/zvision/scripting/controls/fist_control.h
@@ -0,0 +1,84 @@
+/* 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_FIST_CONTROL_H
+#define ZVISION_FIST_CONTROL_H
+
+#include "zvision/scripting/control.h"
+
+#include "common/array.h"
+#include "common/rect.h"
+
+namespace Video {
+ class VideoDecoder;
+}
+
+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);
+ ~FistControl();
+
+private:
+ uint32 _fiststatus;
+ int _fistnum;
+ int16 _cursor;
+ int _order;
+
+ Common::Array< Common::Array<Common::Rect> > _fistsUp;
+ Common::Array< Common::Array<Common::Rect> > _fistsDwn;
+
+ int32 _numEntries;
+
+ struct entries {
+ uint32 _bitsStrt;
+ uint32 _bitsEnd;
+ int32 _anmStrt;
+ int32 _anmEnd;
+ int32 _sound;
+ };
+
+ Common::Array<entries> _entries;
+
+ Video::VideoDecoder *_animation;
+ Common::Rect _anmRect;
+ int32 _soundKey;
+ int32 _animationId;
+
+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 readDescFile(const Common::String &fileName);
+ void clearFistArray(Common::Array< Common::Array<Common::Rect> > &arr);
+ uint32 readBits(const char *str);
+ int mouseIn(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+ void getFistParams(const Common::String &inputStr, Common::String &parameter, Common::String &values);
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/controls/hotmov_control.cpp b/engines/zvision/scripting/controls/hotmov_control.cpp
new file mode 100644
index 0000000000..182447a990
--- /dev/null
+++ b/engines/zvision/scripting/controls/hotmov_control.cpp
@@ -0,0 +1,188 @@
+/* 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 "zvision/scripting/controls/hotmov_control.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/graphics/cursors/cursor_manager.h"
+
+#include "common/stream.h"
+#include "common/file.h"
+#include "common/system.h"
+#include "graphics/surface.h"
+#include "video/video_decoder.h"
+
+namespace ZVision {
+
+HotMovControl::HotMovControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
+ : Control(engine, key, CONTROL_HOTMOV) {
+ _animation = NULL;
+ _cycle = 0;
+ _frames.clear();
+ _cyclesCount = 0;
+ _framesCount = 0;
+
+ _engine->getScriptManager()->setStateValue(_key, 0);
+
+ // Loop until we find the closing brace
+ Common::String line = stream.readLine();
+ _engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
+ Common::String param;
+ Common::String values;
+ getParams(line, param, values);
+
+ while (!stream.eos() && !line.contains('}')) {
+ if (param.matchString("hs_frame_list", true)) {
+ readHsFile(values);
+ } else if (param.matchString("rectangle", true)) {
+ int x;
+ int y;
+ int width;
+ int height;
+
+ sscanf(values.c_str(), "%d %d %d %d", &x, &y, &width, &height);
+
+ _rectangle = Common::Rect(x, y, width, height);
+ } else if (param.matchString("num_frames", true)) {
+ _framesCount = atoi(values.c_str());
+ } else if (param.matchString("num_cycles", true)) {
+ _cyclesCount = atoi(values.c_str());
+ } else if (param.matchString("animation", true)) {
+ char filename[64];
+ 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());
+ }
+
+ line = stream.readLine();
+ _engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
+ getParams(line, param, values);
+ }
+}
+
+HotMovControl::~HotMovControl() {
+ if (_animation)
+ delete _animation;
+
+ _frames.clear();
+}
+
+bool HotMovControl::process(uint32 deltaTimeInMillis) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ if (_cycle < _cyclesCount) {
+ if (_animation && _animation->endOfVideo()) {
+ _cycle++;
+
+ if (_cycle == _cyclesCount) {
+ _engine->getScriptManager()->setStateValue(_key, 2);
+ return false;
+ }
+
+ _animation->rewind();
+ }
+
+ if (_animation && _animation->needsUpdate()) {
+ const Graphics::Surface *frameData = _animation->decodeNextFrame();
+ if (frameData)
+ _engine->getRenderManager()->blitSurfaceToBkgScaled(*frameData, _rectangle);
+ }
+ }
+
+ return false;
+}
+
+bool HotMovControl::onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ if (!_animation)
+ return false;
+
+ if (_cycle < _cyclesCount) {
+ if (_frames[_animation->getCurFrame()].contains(backgroundImageSpacePos)) {
+ _engine->getCursorManager()->changeCursor(CursorIndex_Active);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool HotMovControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ if (!_animation)
+ return false;
+
+ if (_cycle < _cyclesCount) {
+ if (_frames[_animation->getCurFrame()].contains(backgroundImageSpacePos)) {
+ setVenus();
+ _engine->getScriptManager()->setStateValue(_key, 1);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void HotMovControl::readHsFile(const Common::String &fileName) {
+ if (_framesCount == 0)
+ return;
+
+ Common::File file;
+ if (!_engine->getSearchManager()->openFile(file, fileName)) {
+ warning("HS file %s could could be opened", fileName.c_str());
+ return;
+ }
+
+ Common::String line;
+
+ _frames.resize(_framesCount);
+
+ while (!file.eos()) {
+ line = file.readLine();
+
+ int frame;
+ int x;
+ int y;
+ int width;
+ int height;
+
+ sscanf(line.c_str(), "%d:%d %d %d %d~", &frame, &x, &y, &width, &height);
+
+ if (frame >= 0 && frame < _framesCount)
+ _frames[frame] = Common::Rect(x, y, width, height);
+ }
+ file.close();
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/hotmov_control.h b/engines/zvision/scripting/controls/hotmov_control.h
new file mode 100644
index 0000000000..99d1fd0979
--- /dev/null
+++ b/engines/zvision/scripting/controls/hotmov_control.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 ZVISION_HOTMOV_CONTROL_H
+#define ZVISION_HOTMOV_CONTROL_H
+
+#include "zvision/scripting/control.h"
+
+#include "common/array.h"
+#include "common/rect.h"
+
+namespace Video {
+ class VideoDecoder;
+}
+
+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);
+ ~HotMovControl();
+
+private:
+ int32 _framesCount;
+ int32 _cycle;
+ int32 _cyclesCount;
+ Video::VideoDecoder *_animation;
+ Common::Rect _rectangle;
+ Common::Array<Common::Rect> _frames;
+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 readHsFile(const Common::String &fileName);
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/controls/input_control.cpp b/engines/zvision/scripting/controls/input_control.cpp
index a35548d02e..df0c77ba96 100644
--- a/engines/zvision/scripting/controls/input_control.cpp
+++ b/engines/zvision/scripting/controls/input_control.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.
@@ -23,120 +23,249 @@
#include "common/scummsys.h"
#include "zvision/scripting/controls/input_control.h"
+#include "zvision/graphics/cursors/cursor_manager.h"
#include "zvision/zvision.h"
#include "zvision/scripting/script_manager.h"
-#include "zvision/strings/string_manager.h"
+#include "zvision/text/string_manager.h"
#include "zvision/graphics/render_manager.h"
-#include "zvision/utility/utility.h"
#include "common/str.h"
#include "common/stream.h"
#include "common/rect.h"
-
+#include "video/video_decoder.h"
namespace ZVision {
InputControl::InputControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
- : Control(engine, key),
- _nextTabstop(0),
- _focused(false),
- _textChanged(false),
- _cursorOffset(0) {
+ : Control(engine, key, CONTROL_INPUT),
+ _background(0),
+ _nextTabstop(0),
+ _focused(false),
+ _textChanged(false),
+ _cursorOffset(0),
+ _enterPressed(false),
+ _readOnly(false),
+ _txtWidth(0),
+ _animation(NULL) {
// Loop until we find the closing brace
Common::String line = stream.readLine();
- trimCommentsAndWhiteSpace(&line);
+ _engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
+ Common::String param;
+ Common::String values;
+ getParams(line, param, values);
while (!stream.eos() && !line.contains('}')) {
- if (line.matchString("*rectangle*", true)) {
+ if (param.matchString("rectangle", true)) {
int x1;
int y1;
int x2;
int y2;
- sscanf(line.c_str(), "%*[^(](%d %d %d %d)", &x1, &y1, &x2, &y2);
+ sscanf(values.c_str(), "%d %d %d %d", &x1, &y1, &x2, &y2);
_textRectangle = Common::Rect(x1, y1, x2, y2);
- } else if (line.matchString("*aux_hotspot*", true)) {
+ } else if (param.matchString("aux_hotspot", true)) {
int x1;
int y1;
int x2;
int y2;
- sscanf(line.c_str(), "%*[^(](%d %d %d %d)", &x1, &y1, &x2, &y2);
+ sscanf(values.c_str(), "%d %d %d %d", &x1, &y1, &x2, &y2);
_headerRectangle = Common::Rect(x1, y1, x2, y2);
- } else if (line.matchString("*string_init*", true)) {
+ } else if (param.matchString("string_init", true)) {
uint fontFormatNumber;
- sscanf(line.c_str(), "%*[^(](%u)", &fontFormatNumber);
+ sscanf(values.c_str(), "%u", &fontFormatNumber);
- _textStyle = _engine->getStringManager()->getTextStyle(fontFormatNumber);
- } else if (line.matchString("*next_tabstop*", true)) {
- sscanf(line.c_str(), "%*[^(](%u)", &_nextTabstop);
- } else if (line.matchString("*cursor_animation*", true)) {
- char fileName[26];
+ _stringInit.readAllStyles(_engine->getStringManager()->getTextLine(fontFormatNumber));
+ } else if (param.matchString("chooser_init_string", true)) {
+ uint fontFormatNumber;
- sscanf(line.c_str(), "%*[^(](%25s %*u)", fileName);
+ sscanf(values.c_str(), "%u", &fontFormatNumber);
- _cursorAnimationFileName = Common::String(fileName);
- } else if (line.matchString("*cursor_dimensions*", true)) {
+ _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)) {
// Ignore, use the dimensions in the animation file
- } else if (line.matchString("*cursor_animation_frames*", true)) {
+ } else if (param.matchString("cursor_animation_frames", true)) {
// Ignore, use the frame count in the animation file
- } else if (line.matchString("*focus*", true)) {
+ } else if (param.matchString("cursor_animation", true)) {
+ char fileName[25];
+
+ sscanf(values.c_str(), "%24s %*u", fileName);
+
+ _animation = _engine->loadAnimation(fileName);
+ _animation->start();
+ } else if (param.matchString("focus", true)) {
_focused = true;
+ _engine->getScriptManager()->setFocusControlKey(_key);
+ } else if (param.matchString("venus_id", true)) {
+ _venusId = atoi(values.c_str());
}
line = stream.readLine();
- trimCommentsAndWhiteSpace(&line);
+ _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) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ if (_textRectangle.contains(backgroundImageSpacePos)) {
+ if (!_readOnly) {
+ // Save
+ _engine->getScriptManager()->focusControl(_key);
+ setVenus();
+ } else {
+ // Restore
+ if (_currentInputText.size()) {
+ setVenus();
+ _enterPressed = true;
+ }
+ }
}
+ return false;
}
-void InputControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
- _engine->getScriptManager()->focusControl(_key);
+bool InputControl::onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ if (_textRectangle.contains(backgroundImageSpacePos)) {
+ if (!_readOnly) {
+ // Save
+ _engine->getCursorManager()->changeCursor(CursorIndex_Active);
+ return true;
+ } else {
+ // Restore
+ if (_currentInputText.size()) {
+ _engine->getCursorManager()->changeCursor(CursorIndex_Active);
+ _engine->getScriptManager()->focusControl(_key);
+ return true;
+ }
+ }
+ }
+ return false;
}
-void InputControl::onKeyDown(Common::KeyState keyState) {
+bool InputControl::onKeyDown(Common::KeyState keyState) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
if (!_focused) {
- return;
+ return false;
}
if (keyState.keycode == Common::KEYCODE_BACKSPACE) {
- _currentInputText.deleteLastChar();
+ if (!_readOnly) {
+ _currentInputText.deleteLastChar();
+ _textChanged = true;
+ }
+ } else if (keyState.keycode == Common::KEYCODE_RETURN) {
+ _enterPressed = true;
} else if (keyState.keycode == Common::KEYCODE_TAB) {
- _focused = false;
+ unfocus();
// Focus the next input control
_engine->getScriptManager()->focusControl(_nextTabstop);
+ // Don't process this event for other controls
+ return true;
} else {
- // Otherwise, append the new character to the end of the current text
-
- uint16 asciiValue = keyState.ascii;
- // We only care about text values
- if (asciiValue >= 32 && asciiValue <= 126) {
- _currentInputText += (char)asciiValue;
- _textChanged = true;
+ if (!_readOnly) {
+ // Otherwise, append the new character to the end of the current text
+ uint16 asciiValue = keyState.ascii;
+ // We only care about text values
+ if (asciiValue >= 32 && asciiValue <= 126) {
+ _currentInputText += (char)asciiValue;
+ _textChanged = true;
+ }
}
}
+ return false;
}
bool InputControl::process(uint32 deltaTimeInMillis) {
- if (!_focused) {
+ 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
- Common::Rect destRect = _engine->getRenderManager()->renderTextToWorkingWindow(_key, _currentInputText, _textStyle.font, _textRectangle.left, _textRectangle.top, _textStyle.color, _textRectangle.width());
- _cursorOffset = destRect.left - _textRectangle.left;
+ Graphics::Surface txt;
+ txt.copyFrom(*_background);
+
+ int32 oldTxtWidth = _txtWidth;
+
+ if (!_readOnly || !_focused)
+ _txtWidth = _engine->getTextRenderer()->drawText(_currentInputText, _stringInit, txt);
+ else
+ _txtWidth = _engine->getTextRenderer()->drawText(_currentInputText, _stringChooserInit, txt);
+
+ 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();
}
- // Render the next frame of the animation
- // TODO: Implement animation handling
+ if (_animation && !_readOnly && _focused) {
+ if (_animation->endOfVideo())
+ _animation->rewind();
+ if (_animation->needsUpdate()) {
+ const Graphics::Surface *srf = _animation->decodeNextFrame();
+ 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);
+ }
+ }
+
+ _textChanged = false;
+ return false;
+}
+
+bool InputControl::enterPress() {
+ if (_enterPressed) {
+ _enterPressed = false;
+ return true;
+ }
return false;
}
+void InputControl::setText(const Common::String &_str) {
+ _currentInputText = _str;
+ _textChanged = true;
+}
+
+const Common::String InputControl::getText() {
+ return _currentInputText;
+}
+
+void InputControl::setReadOnly(bool readonly) {
+ _readOnly = readonly;
+}
+
} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/input_control.h b/engines/zvision/scripting/controls/input_control.h
index 32432438bb..9b48514e16 100644
--- a/engines/zvision/scripting/controls/input_control.h
+++ b/engines/zvision/scripting/controls/input_control.h
@@ -24,35 +24,60 @@
#define ZVISION_INPUT_CONTROL_H
#include "zvision/scripting/control.h"
-#include "zvision/strings/string_manager.h"
+#include "zvision/text/text.h"
+#include "zvision/text/string_manager.h"
#include "common/rect.h"
+namespace Video {
+ class VideoDecoder;
+}
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;
- StringManager::TextStyle _textStyle;
+ TextStyleState _stringInit;
+ TextStyleState _stringChooserInit;
uint32 _nextTabstop;
- Common::String _cursorAnimationFileName;
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() { _focused = true; }
- void unfocus() { _focused = false; }
- void onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
- void onKeyDown(Common::KeyState keyState);
+ void focus() {
+ _focused = true;
+ _textChanged = true;
+ }
+ void unfocus() {
+ _focused = false;
+ _textChanged = true;
+ }
+ bool onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+ bool onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+ bool onKeyDown(Common::KeyState keyState);
bool process(uint32 deltaTimeInMillis);
+ void setText(const Common::String &_str);
+ const Common::String getText();
+ bool enterPress();
+ void setReadOnly(bool);
};
} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/lever_control.cpp b/engines/zvision/scripting/controls/lever_control.cpp
index 9724e661b7..0f105b424c 100644
--- a/engines/zvision/scripting/controls/lever_control.cpp
+++ b/engines/zvision/scripting/controls/lever_control.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.
@@ -27,130 +27,128 @@
#include "zvision/zvision.h"
#include "zvision/scripting/script_manager.h"
#include "zvision/graphics/render_manager.h"
-#include "zvision/cursors/cursor_manager.h"
-#include "zvision/animation/rlf_animation.h"
-#include "zvision/video/zork_avi_decoder.h"
-#include "zvision/utility/utility.h"
+#include "zvision/graphics/cursors/cursor_manager.h"
#include "common/stream.h"
#include "common/file.h"
#include "common/tokenizer.h"
#include "common/system.h"
-
#include "graphics/surface.h"
-
+#include "video/video_decoder.h"
namespace ZVision {
LeverControl::LeverControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
- : Control(engine, key),
- _frameInfo(0),
- _frameCount(0),
- _startFrame(0),
- _currentFrame(0),
- _lastRenderedFrame(0),
- _mouseIsCaptured(false),
- _isReturning(false),
- _accumulatedTime(0),
- _returnRoutesCurrentFrame(0) {
+ : Control(engine, key, CONTROL_LEVER),
+ _frameInfo(0),
+ _frameCount(0),
+ _startFrame(0),
+ _currentFrame(0),
+ _lastRenderedFrame(0),
+ _mouseIsCaptured(false),
+ _isReturning(false),
+ _accumulatedTime(0),
+ _returnRoutesCurrentFrame(0),
+ _animation(NULL),
+ _cursor(CursorIndex_Active),
+ _mirrored(false) {
// Loop until we find the closing brace
Common::String line = stream.readLine();
- trimCommentsAndWhiteSpace(&line);
+ _engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
+
+ Common::String param;
+ Common::String values;
+ getParams(line, param, values);
while (!stream.eos() && !line.contains('}')) {
- if (line.matchString("*descfile*", true)) {
+ if (param.matchString("descfile", true)) {
char levFileName[25];
- sscanf(line.c_str(), "%*[^(](%25[^)])", levFileName);
+ sscanf(values.c_str(), "%24s", levFileName);
parseLevFile(levFileName);
- } else if (line.matchString("*cursor*", true)) {
+ } else if (param.matchString("cursor", true)) {
char cursorName[25];
- sscanf(line.c_str(), "%*[^(](%25[^)])", cursorName);
+ sscanf(values.c_str(), "%24s", cursorName);
- _cursorName = Common::String(cursorName);
+ _cursor = _engine->getCursorManager()->getCursorId(Common::String(cursorName));
}
line = stream.readLine();
- trimCommentsAndWhiteSpace(&line);
+ _engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
+ getParams(line, param, values);
}
renderFrame(_currentFrame);
}
LeverControl::~LeverControl() {
- if (_fileType == AVI) {
- delete _animation.avi;
- } else if (_fileType == RLF) {
- delete _animation.rlf;
- }
-
+ if (_animation)
+ delete _animation;
+
delete[] _frameInfo;
}
void LeverControl::parseLevFile(const Common::String &fileName) {
Common::File file;
- if (!file.open(fileName)) {
+ if (!_engine->getSearchManager()->openFile(file, fileName)) {
warning("LEV file %s could could be opened", fileName.c_str());
return;
}
- Common::String line = file.readLine();
+ Common::String line;
+ Common::String param;
+ Common::String values;
while (!file.eos()) {
- if (line.matchString("*animation_id*", true)) {
+ line = file.readLine();
+ getLevParams(line, param, values);
+
+ if (param.matchString("animation_id", true)) {
// Not used
- } else if (line.matchString("*filename*", true)) {
- char fileNameBuffer[25];
- sscanf(line.c_str(), "%*[^:]:%25[^~]~", fileNameBuffer);
-
- Common::String animationFileName(fileNameBuffer);
-
- if (animationFileName.hasSuffix(".avi")) {
- _animation.avi = new ZorkAVIDecoder();
- _animation.avi->loadFile(animationFileName);
- _fileType = AVI;
- } else if (animationFileName.hasSuffix(".rlf")) {
- _animation.rlf = new RlfAnimation(animationFileName, false);
- _fileType = RLF;
- }
- } else if (line.matchString("*skipcolor*", true)) {
+ } else if (param.matchString("filename", true)) {
+ _animation = _engine->loadAnimation(values);
+ } else if (param.matchString("skipcolor", true)) {
// Not used
- } else if (line.matchString("*anim_coords*", true)) {
+ } else if (param.matchString("anim_coords", true)) {
int left, top, right, bottom;
- sscanf(line.c_str(), "%*[^:]:%d %d %d %d~", &left, &top, &right, &bottom);
+ sscanf(values.c_str(), "%d %d %d %d", &left, &top, &right, &bottom);
_animationCoords.left = left;
_animationCoords.top = top;
_animationCoords.right = right;
_animationCoords.bottom = bottom;
- } else if (line.matchString("*mirrored*", true)) {
+ } else if (param.matchString("mirrored", true)) {
uint mirrored;
- sscanf(line.c_str(), "%*[^:]:%u~", &mirrored);
+ sscanf(values.c_str(), "%u", &mirrored);
_mirrored = mirrored == 0 ? false : true;
- } else if (line.matchString("*frames*", true)) {
- sscanf(line.c_str(), "%*[^:]:%u~", &_frameCount);
+ } else if (param.matchString("frames", true)) {
+ sscanf(values.c_str(), "%u", &_frameCount);
_frameInfo = new FrameInfo[_frameCount];
- } else if (line.matchString("*elsewhere*", true)) {
+ } else if (param.matchString("elsewhere", true)) {
// Not used
- } else if (line.matchString("*out_of_control*", true)) {
+ } else if (param.matchString("out_of_control", true)) {
// Not used
- } else if (line.matchString("*start_pos*", true)) {
- sscanf(line.c_str(), "%*[^:]:%u~", &_startFrame);
+ } else if (param.matchString("start_pos", true)) {
+ sscanf(values.c_str(), "%u", &_startFrame);
_currentFrame = _startFrame;
- } else if (line.matchString("*hotspot_deltas*", true)) {
+ } else if (param.matchString("hotspot_deltas", true)) {
uint x;
uint y;
- sscanf(line.c_str(), "%*[^:]:%u %u~", &x, &y);
+ sscanf(values.c_str(), "%u %u", &x, &y);
_hotspotDelta.x = x;
_hotspotDelta.y = y;
+ } else if (param.matchString("venus_id", true)) {
+ _venusId = atoi(values.c_str());
} else {
uint frameNumber;
uint x, y;
+ line.toLowercase();
+
if (sscanf(line.c_str(), "%u:%u %u", &frameNumber, &x, &y) == 3) {
_frameInfo[frameNumber].hotspot.left = x;
_frameInfo[frameNumber].hotspot.top = y;
@@ -158,13 +156,13 @@ void LeverControl::parseLevFile(const Common::String &fileName) {
_frameInfo[frameNumber].hotspot.bottom = y + _hotspotDelta.y;
}
- Common::StringTokenizer tokenizer(line, " ^=()");
+ Common::StringTokenizer tokenizer(line, " ^=()~");
tokenizer.nextToken();
tokenizer.nextToken();
Common::String token = tokenizer.nextToken();
while (!tokenizer.empty()) {
- if (token == "D") {
+ if (token == "d") {
token = tokenizer.nextToken();
uint angle;
@@ -172,7 +170,7 @@ void LeverControl::parseLevFile(const Common::String &fileName) {
sscanf(token.c_str(), "%u,%u", &toFrame, &angle);
_frameInfo[frameNumber].directions.push_back(Direction(angle, toFrame));
- } else if (token.hasPrefix("P")) {
+ } else if (token.hasPrefix("p")) {
// Format: P(<from> to <to>)
tokenizer.nextToken();
tokenizer.nextToken();
@@ -186,26 +184,26 @@ void LeverControl::parseLevFile(const Common::String &fileName) {
}
}
- line = file.readLine();
+ // Don't read lines in this place because last will not be parsed.
}
}
-void LeverControl::onMouseDown(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
- if (!_enabled) {
- return;
- }
-
+bool LeverControl::onMouseDown(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
if (_frameInfo[_currentFrame].hotspot.contains(backgroundImageSpacePos)) {
+ setVenus();
_mouseIsCaptured = true;
_lastMousePos = backgroundImageSpacePos;
}
+ return false;
}
-void LeverControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
- if (!_enabled) {
- return;
- }
-
+bool LeverControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
if (_mouseIsCaptured) {
_mouseIsCaptured = false;
_engine->getScriptManager()->setStateValue(_key, _currentFrame);
@@ -214,20 +212,19 @@ void LeverControl::onMouseUp(const Common::Point &screenSpacePos, const Common::
_returnRoutesCurrentProgress = _frameInfo[_currentFrame].returnRoute.begin();
_returnRoutesCurrentFrame = _currentFrame;
}
+ return false;
}
bool LeverControl::onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
- if (!_enabled) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
return false;
- }
-
+
bool cursorWasChanged = false;
if (_mouseIsCaptured) {
- // Make sure the square distance between the last point and the current point is greater than 64
+ // Make sure the square distance between the last point and the current point is greater than 16
// This is a heuristic. This determines how responsive the lever is to mouse movement.
- // TODO: Fiddle with the heuristic to get a good lever responsiveness 'feel'
- if (_lastMousePos.sqrDist(backgroundImageSpacePos) >= 64) {
+ if (_lastMousePos.sqrDist(backgroundImageSpacePos) >= 16) {
int angle = calculateVectorAngle(_lastMousePos, backgroundImageSpacePos);
_lastMousePos = backgroundImageSpacePos;
@@ -235,12 +232,15 @@ 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(_cursorName);
+ _engine->getCursorManager()->changeCursor(_cursor);
cursorWasChanged = true;
}
@@ -248,9 +248,8 @@ bool LeverControl::onMouseMove(const Common::Point &screenSpacePos, const Common
}
bool LeverControl::process(uint32 deltaTimeInMillis) {
- if (!_enabled) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
return false;
- }
if (_isReturning) {
_accumulatedTime += deltaTimeInMillis;
@@ -276,7 +275,7 @@ bool LeverControl::process(uint32 deltaTimeInMillis) {
renderFrame(_returnRoutesCurrentFrame);
}
}
-
+
return false;
}
@@ -301,7 +300,7 @@ int LeverControl::calculateVectorAngle(const Common::Point &pointOne, const Comm
// Calculate the angle using arctan
// Then convert to degrees. (180 / 3.14159 = 57.2958)
- int angle = int(atan((float)yDist / (float)xDist) * 57);
+ int angle = int(atan((float)yDist / (float)abs(xDist)) * 57);
// Calculate what quadrant pointTwo is in
uint quadrant = ((yDist > 0 ? 1 : 0) << 1) | (xDist < 0 ? 1 : 0);
@@ -350,16 +349,16 @@ int LeverControl::calculateVectorAngle(const Common::Point &pointOne, const Comm
// Convert the local angles to unit circle angles
switch (quadrant) {
case 0:
- angle = 180 + angle;
+ angle = -angle;
break;
case 1:
- // Do nothing
+ angle = angle + 180;
break;
case 2:
- angle = 180 + angle;
+ angle = 360 - angle;
break;
case 3:
- angle = 360 + angle;
+ angle = 180 + angle;
break;
}
@@ -377,26 +376,36 @@ void LeverControl::renderFrame(uint frameNumber) {
_lastRenderedFrame = frameNumber;
}
- const uint16 *frameData = 0;
- int x = _animationCoords.left;
- int y = _animationCoords.top;
- int width = 0;
- int height = 0;
-
- if (_fileType == RLF) {
- // getFrameData() will automatically optimize to getNextFrame() / getPreviousFrame() if it can
- frameData = (const uint16 *)_animation.rlf->getFrameData(frameNumber)->getPixels();
- width = _animation.rlf->width(); // Use the animation width instead of _animationCoords.width()
- height = _animation.rlf->height(); // Use the animation height instead of _animationCoords.height()
- } else if (_fileType == AVI) {
- _animation.avi->seekToFrame(frameNumber);
- const Graphics::Surface *surface = _animation.avi->decodeNextFrame();
- frameData = (const uint16 *)surface->getPixels();
- width = surface->w;
- height = surface->h;
- }
+ const Graphics::Surface *frameData;
+
+ _animation->seekToFrame(frameNumber);
+ frameData = _animation->decodeNextFrame();
+ if (frameData)
+ _engine->getRenderManager()->blitSurfaceToBkgScaled(*frameData, _animationCoords);
+}
+
+void LeverControl::getLevParams(const Common::String &inputStr, Common::String &parameter, Common::String &values) {
+ const char *chrs = inputStr.c_str();
+ uint lbr;
+
+ for (lbr = 0; lbr < inputStr.size(); lbr++)
+ if (chrs[lbr] == ':')
+ break;
+
+ if (lbr >= inputStr.size())
+ return;
+
+ uint rbr;
+
+ for (rbr = lbr + 1; rbr < inputStr.size(); rbr++)
+ if (chrs[rbr] == '~')
+ break;
+
+ if (rbr >= inputStr.size())
+ return;
- _engine->getRenderManager()->copyRectToWorkingWindow(frameData, x, y, width, width, height);
+ parameter = Common::String(chrs, chrs + lbr);
+ values = Common::String(chrs + lbr + 1, chrs + rbr);
}
} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/lever_control.h b/engines/zvision/scripting/controls/lever_control.h
index 49e4fd3806..8787234c51 100644
--- a/engines/zvision/scripting/controls/lever_control.h
+++ b/engines/zvision/scripting/controls/lever_control.h
@@ -28,22 +28,19 @@
#include "common/list.h"
#include "common/rect.h"
+namespace Video {
+ class VideoDecoder;
+}
namespace ZVision {
-class ZorkAVIDecoder;
-class RlfAnimation;
-
+// 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);
~LeverControl();
private:
- enum FileType {
- RLF = 1,
- AVI = 2
- };
struct Direction {
Direction(uint a, uint t) : angle(a), toFrame(t) {}
@@ -64,13 +61,9 @@ private:
};
private:
- union {
- RlfAnimation *rlf;
- ZorkAVIDecoder *avi;
- } _animation;
- FileType _fileType;
+ Video::VideoDecoder *_animation;
- Common::String _cursorName;
+ int _cursor;
Common::Rect _animationCoords;
bool _mirrored;
uint _frameCount;
@@ -88,8 +81,8 @@ private:
uint32 _accumulatedTime;
public:
- void onMouseDown(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
- void onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+ bool onMouseDown(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+ bool onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
bool onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
bool process(uint32 deltaTimeInMillis);
@@ -120,6 +113,7 @@ private:
*/
static int calculateVectorAngle(const Common::Point &pointOne, const Common::Point &pointTwo);
void renderFrame(uint frameNumber);
+ void getLevParams(const Common::String &inputStr, Common::String &parameter, Common::String &values);
};
} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/paint_control.cpp b/engines/zvision/scripting/controls/paint_control.cpp
new file mode 100644
index 0000000000..62dde3d170
--- /dev/null
+++ b/engines/zvision/scripting/controls/paint_control.cpp
@@ -0,0 +1,219 @@
+/* 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 "zvision/scripting/controls/paint_control.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/graphics/cursors/cursor_manager.h"
+#include "zvision/graphics/render_manager.h"
+
+namespace ZVision {
+
+PaintControl::PaintControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
+ : Control(engine, key, CONTROL_PAINT) {
+
+ _cursor = CursorIndex_Active;
+ _paint = NULL;
+ _bkg = NULL;
+ _brush = NULL;
+ _colorKey = 0;
+ _mouseDown = false;
+
+ // Loop until we find the closing brace
+ Common::String line = stream.readLine();
+ _engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
+ Common::String param;
+ Common::String values;
+ getParams(line, param, values);
+
+ while (!stream.eos() && !line.contains('}')) {
+ if (param.matchString("rectangle", true)) {
+ int x;
+ int y;
+ int width;
+ int height;
+
+ sscanf(values.c_str(), "%d %d %d %d", &x, &y, &width, &height);
+
+ _rectangle = Common::Rect(x, y, width + x, height + y);
+ } else if (param.matchString("cursor", true)) {
+ _cursor = _engine->getCursorManager()->getCursorId(values);
+ } else if (param.matchString("brush_file", true)) {
+ _brush = _engine->getRenderManager()->loadImage(values, false);
+ } else if (param.matchString("venus_id", true)) {
+ _venusId = atoi(values.c_str());
+ } else if (param.matchString("paint_file", true)) {
+ _paint = _engine->getRenderManager()->loadImage(values, false);
+ } else if (param.matchString("eligible_objects", true)) {
+ char buf[256];
+ memset(buf, 0, 256);
+ strncpy(buf, values.c_str(), 255);
+
+ char *curpos = buf;
+ char *strend = buf + strlen(buf);
+ while (true) {
+ char *st = curpos;
+
+ if (st >= strend)
+ break;
+
+ while (*curpos != ' ' && curpos < strend)
+ curpos++;
+
+ *curpos = 0;
+ curpos++;
+
+ int obj = atoi(st);
+
+ _eligibleObjects.push_back(obj);
+ }
+ }
+
+ line = stream.readLine();
+ _engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
+ getParams(line, param, values);
+ }
+
+ if (_paint) {
+ _colorKey = _paint->format.RGBToColor(255, 0, 255);
+ _bkg = new Graphics::Surface;
+ _bkg->create(_rectangle.width(), _rectangle.height(), _paint->format);
+ _bkg->fillRect(Common::Rect(_rectangle.width(), _rectangle.height()), _colorKey);
+
+ Graphics::Surface *tmp = new Graphics::Surface;
+ tmp->create(_rectangle.width(), _rectangle.height(), _paint->format);
+ _engine->getRenderManager()->blitSurfaceToSurface(*_paint, _rectangle, *tmp, 0, 0);
+ _paint->free();
+ delete _paint;
+ _paint = tmp;
+ }
+}
+
+PaintControl::~PaintControl() {
+ // Clear the state value back to 0
+ //_engine->getScriptManager()->setStateValue(_key, 0);
+ if (_paint) {
+ _paint->free();
+ delete _paint;
+ }
+ if (_brush) {
+ _brush->free();
+ delete _brush;
+ }
+ if (_bkg) {
+ _bkg->free();
+ delete _bkg;
+ }
+}
+
+bool PaintControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ _mouseDown = false;
+
+ return false;
+}
+
+bool PaintControl::onMouseDown(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ if (_rectangle.contains(backgroundImageSpacePos)) {
+ int mouseItem = _engine->getScriptManager()->getStateValue(StateKey_InventoryItem);
+
+ if (eligeblity(mouseItem)) {
+ setVenus();
+ _mouseDown = true;
+ }
+ }
+
+ return false;
+}
+
+bool PaintControl::onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ if (_rectangle.contains(backgroundImageSpacePos)) {
+ int mouseItem = _engine->getScriptManager()->getStateValue(StateKey_InventoryItem);
+
+ if (eligeblity(mouseItem)) {
+ _engine->getCursorManager()->changeCursor(_cursor);
+
+ if (_mouseDown) {
+ Common::Rect bkgRect = paint(backgroundImageSpacePos);
+ if (!bkgRect.isEmpty()) {
+ Common::Rect imgRect = bkgRect;
+ imgRect.translate(-_rectangle.left, -_rectangle.top);
+
+ Graphics::Surface imgUpdate = _bkg->getSubArea(imgRect);
+
+ _engine->getRenderManager()->blitSurfaceToBkg(imgUpdate, bkgRect.left, bkgRect.top, _colorKey);
+ }
+ }
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool PaintControl::eligeblity(int itemId) {
+ for (Common::List<int>::iterator it = _eligibleObjects.begin(); it != _eligibleObjects.end(); it++)
+ if (*it == itemId)
+ return true;
+ return false;
+}
+
+Common::Rect PaintControl::paint(const Common::Point &point) {
+ Common::Rect paintRect = Common::Rect(_brush->w, _brush->h);
+ paintRect.moveTo(point);
+ paintRect.clip(_rectangle);
+
+ if (!paintRect.isEmpty()) {
+ Common::Rect brushRect = paintRect;
+ brushRect.translate(-point.x, -point.y);
+
+ Common::Rect bkgRect = paintRect;
+ bkgRect.translate(-_rectangle.left, -_rectangle.top);
+
+ for (int yy = 0; yy < brushRect.height(); yy++) {
+ uint16 *mask = (uint16 *)_brush->getBasePtr(brushRect.left, brushRect.top + yy);
+ uint16 *from = (uint16 *)_paint->getBasePtr(bkgRect.left, bkgRect.top + yy);
+ uint16 *to = (uint16 *)_bkg->getBasePtr(bkgRect.left, bkgRect.top + yy);
+ for (int xx = 0; xx < brushRect.width(); xx++) {
+ if (*mask != 0)
+ *(to + xx) = *(from + xx);
+
+ mask++;
+ }
+ }
+
+ }
+ return paintRect;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/paint_control.h b/engines/zvision/scripting/controls/paint_control.h
new file mode 100644
index 0000000000..8c01f0e68a
--- /dev/null
+++ b/engines/zvision/scripting/controls/paint_control.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 ZVISION_PAINT_CONTROL_H
+#define ZVISION_PAINT_CONTROL_H
+
+#include "zvision/scripting/control.h"
+
+#include "graphics/surface.h"
+
+#include "common/rect.h"
+#include "common/list.h"
+
+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);
+ ~PaintControl();
+
+ /**
+ * @param screenSpacePos The position of the mouse in screen space
+ * @param backgroundImageSpacePos The position of the mouse in background image space
+ */
+ bool onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+
+ /**
+ * @param screenSpacePos The position of the mouse in screen space
+ * @param backgroundImageSpacePos The position of the mouse in background image space
+ */
+ bool onMouseDown(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+ /**
+ * Called on every MouseMove. Tests if the mouse is inside _hotspot, and if so, sets the cursor.
+ *
+ * @param engine The base engine
+ * @param screenSpacePos The position of the mouse in screen space
+ * @param backgroundImageSpacePos The position of the mouse in background image space
+ * @return Was the cursor changed?
+ */
+ bool onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+
+ bool process(uint32 deltaTimeInMillis) {
+ return false;
+ };
+
+private:
+ /**
+ * The area that will trigger the event
+ * This is in image space coordinates, NOT screen space
+ */
+
+ uint32 _colorKey;
+
+ Graphics::Surface *_paint;
+ Graphics::Surface *_bkg;
+ Graphics::Surface *_brush;
+
+ Common::List<int> _eligibleObjects;
+
+ int _cursor;
+ Common::Rect _rectangle;
+
+ bool _mouseDown;
+
+ bool eligeblity(int itemId);
+ Common::Rect paint(const Common::Point &point);
+
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/controls/push_toggle_control.cpp b/engines/zvision/scripting/controls/push_toggle_control.cpp
index 82736b7576..f51a28d644 100644
--- a/engines/zvision/scripting/controls/push_toggle_control.cpp
+++ b/engines/zvision/scripting/controls/push_toggle_control.cpp
@@ -26,73 +26,122 @@
#include "zvision/zvision.h"
#include "zvision/scripting/script_manager.h"
-#include "zvision/cursors/cursor_manager.h"
-#include "zvision/utility/utility.h"
+#include "zvision/graphics/cursors/cursor_manager.h"
#include "common/stream.h"
-
namespace ZVision {
PushToggleControl::PushToggleControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
- : Control(engine, key) {
+ : Control(engine, key, CONTROL_PUSHTGL),
+ _countTo(2),
+ _cursor(CursorIndex_Active),
+ _event(Common::EVENT_LBUTTONUP) {
+
+ _hotspots.clear();
+
// Loop until we find the closing brace
Common::String line = stream.readLine();
- trimCommentsAndWhiteSpace(&line);
+ _engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
+ Common::String param;
+ Common::String values;
+ getParams(line, param, values);
while (!stream.eos() && !line.contains('}')) {
- if (line.matchString("*_hotspot*", true)) {
+ if (param.matchString("*_hotspot", true)) {
uint x;
uint y;
uint width;
uint height;
- sscanf(line.c_str(), "%*[^(](%u,%u,%u,%u)", &x, &y, &width, &height);
-
- _hotspot = Common::Rect(x, y, x + width, y + height);
- } else if (line.matchString("cursor*", true)) {
- char nameBuffer[25];
-
- sscanf(line.c_str(), "%*[^(](%25[^)])", nameBuffer);
-
- _hoverCursor = Common::String(nameBuffer);
+ sscanf(values.c_str(), "%u,%u,%u,%u", &x, &y, &width, &height);
+
+ _hotspots.push_back(Common::Rect(x, y, x + width + 1, y + height + 1));
+ } else if (param.matchString("cursor", true)) {
+ _cursor = _engine->getCursorManager()->getCursorId(values);
+ } else if (param.matchString("animation", true)) {
+ // Not used
+ } else if (param.matchString("sound", true)) {
+ // Not used
+ } else if (param.matchString("count_to", true)) {
+ sscanf(values.c_str(), "%u", &_countTo);
+ } else if (param.matchString("mouse_event", true)) {
+ if (values.equalsIgnoreCase("up")) {
+ _event = Common::EVENT_LBUTTONUP;
+ } else if (values.equalsIgnoreCase("down")) {
+ _event = Common::EVENT_LBUTTONDOWN;
+ } else if (values.equalsIgnoreCase("double")) {
+ // Not used
+ }
+ } else if (param.matchString("venus_id", true)) {
+ _venusId = atoi(values.c_str());
}
line = stream.readLine();
- trimCommentsAndWhiteSpace(&line);
+ _engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
+ getParams(line, param, values);
}
- if (_hotspot.isEmpty() || _hoverCursor.empty()) {
- warning("Push_toggle cursor %u was parsed incorrectly", key);
+ if (_hotspots.size() == 0) {
+ warning("Push_toggle %u was parsed incorrectly", key);
}
}
PushToggleControl::~PushToggleControl() {
- // Clear the state value back to 0
- _engine->getScriptManager()->setStateValue(_key, 0);
+ _hotspots.clear();
}
-void PushToggleControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
- if (!_enabled) {
- return;
+bool PushToggleControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ if (_event != Common::EVENT_LBUTTONUP)
+ return false;
+
+ if (contain(backgroundImageSpacePos)) {
+ setVenus();
+ int32 val = _engine->getScriptManager()->getStateValue(_key);
+ val = (val + 1) % _countTo;
+ _engine->getScriptManager()->setStateValue(_key, val);
+ return true;
}
-
- if (_hotspot.contains(backgroundImageSpacePos)) {
- _engine->getScriptManager()->setStateValue(_key, 1);
+ return false;
+}
+
+bool PushToggleControl::onMouseDown(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ if (_event != Common::EVENT_LBUTTONDOWN)
+ return false;
+
+ if (contain(backgroundImageSpacePos)) {
+ setVenus();
+ int32 val = _engine->getScriptManager()->getStateValue(_key);
+ val = (val + 1) % _countTo;
+ _engine->getScriptManager()->setStateValue(_key, val);
+ return true;
}
+ return false;
}
bool PushToggleControl::onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
- if (!_enabled) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
return false;
- }
-
- if (_hotspot.contains(backgroundImageSpacePos)) {
- _engine->getCursorManager()->changeCursor(_hoverCursor);
+
+ if (contain(backgroundImageSpacePos)) {
+ _engine->getCursorManager()->changeCursor(_cursor);
return true;
}
return false;
}
+bool PushToggleControl::contain(const Common::Point &point) {
+ for (uint i = 0; i < _hotspots.size(); i++)
+ if (_hotspots[i].contains(point))
+ return true;
+ return false;
+}
+
} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/push_toggle_control.h b/engines/zvision/scripting/controls/push_toggle_control.h
index 3854fc2005..9444c77cb6 100644
--- a/engines/zvision/scripting/controls/push_toggle_control.h
+++ b/engines/zvision/scripting/controls/push_toggle_control.h
@@ -26,7 +26,8 @@
#include "zvision/scripting/control.h"
#include "common/rect.h"
-
+#include "common/events.h"
+#include "common/array.h"
namespace ZVision {
@@ -36,12 +37,19 @@ public:
~PushToggleControl();
/**
+ * Called when LeftMouse is pushed. Default is NOP.
+ *
+ * @param screenSpacePos The position of the mouse in screen space
+ * @param backgroundImageSpacePos The position of the mouse in background image space
+ */
+ bool onMouseDown(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+ /**
* Called when LeftMouse is lifted. Calls ScriptManager::setStateValue(_key, 1);
*
* @param screenSpacePos The position of the mouse in screen space
* @param backgroundImageSpacePos The position of the mouse in background image space
*/
- void onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+ bool onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
/**
* Called on every MouseMove. Tests if the mouse is inside _hotspot, and if so, sets the cursor.
*
@@ -57,9 +65,15 @@ private:
* The area that will trigger the event
* This is in image space coordinates, NOT screen space
*/
- Common::Rect _hotspot;
+ Common::Array<Common::Rect> _hotspots;
/** The cursor to use when hovering over _hotspot */
- Common::String _hoverCursor;
+ int _cursor;
+ /** Button maximal values count */
+ uint _countTo;
+
+ Common::EventType _event;
+
+ bool contain(const Common::Point &point);
};
} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/safe_control.cpp b/engines/zvision/scripting/controls/safe_control.cpp
new file mode 100644
index 0000000000..4d2a91a1ad
--- /dev/null
+++ b/engines/zvision/scripting/controls/safe_control.cpp
@@ -0,0 +1,180 @@
+/* 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 "zvision/scripting/controls/safe_control.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/graphics/cursors/cursor_manager.h"
+
+#include "common/stream.h"
+#include "common/file.h"
+#include "common/tokenizer.h"
+#include "common/system.h"
+#include "graphics/surface.h"
+#include "video/video_decoder.h"
+
+namespace ZVision {
+
+SafeControl::SafeControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
+ : Control(engine, key, CONTROL_SAFE) {
+ _statesCount = 0;
+ _curState = 0;
+ _animation = NULL;
+ _innerRaduis = 0;
+ _innerRadiusSqr = 0;
+ _outerRadius = 0;
+ _outerRadiusSqr = 0;
+ _zeroPointer = 0;
+ _startPointer = 0;
+ _targetFrame = 0;
+
+ // Loop until we find the closing brace
+ Common::String line = stream.readLine();
+ _engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
+ Common::String param;
+ Common::String values;
+ getParams(line, param, values);
+
+ 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;
+ int width;
+ int height;
+
+ sscanf(values.c_str(), "%d %d %d %d", &x, &y, &width, &height);
+
+ _rectangle = Common::Rect(x, y, width, height);
+ } else if (param.matchString("num_states", true)) {
+ _statesCount = atoi(values.c_str());
+ } else if (param.matchString("center", true)) {
+ int x;
+ int y;
+
+ sscanf(values.c_str(), "%d %d", &x, &y);
+ _center = Common::Point(x, y);
+ } else if (param.matchString("dial_inner_radius", true)) {
+ _innerRaduis = atoi(values.c_str());
+ _innerRadiusSqr = _innerRaduis * _innerRaduis;
+ } else if (param.matchString("radius", true)) {
+ _outerRadius = atoi(values.c_str());
+ _outerRadiusSqr = _outerRadius * _outerRadius;
+ } else if (param.matchString("zero_radians_offset", true)) {
+ _zeroPointer = atoi(values.c_str());
+ } else if (param.matchString("pointer_offset", true)) {
+ _startPointer = atoi(values.c_str());
+ _curState = _startPointer;
+ } else if (param.matchString("cursor", true)) {
+ // Not used
+ } else if (param.matchString("mirrored", true)) {
+ // Not used
+ } else if (param.matchString("venus_id", true)) {
+ _venusId = atoi(values.c_str());
+ }
+
+ line = stream.readLine();
+ _engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
+ getParams(line, param, values);
+ }
+
+ if (_animation)
+ _animation->seekToFrame(_curState);
+}
+
+SafeControl::~SafeControl() {
+ if (_animation)
+ delete _animation;
+
+}
+
+bool SafeControl::process(uint32 deltaTimeInMillis) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ 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;
+}
+
+bool SafeControl::onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ if (_rectangle.contains(backgroundImageSpacePos)) {
+ int32 mR = backgroundImageSpacePos.sqrDist(_center);
+ if (mR <= _outerRadiusSqr && mR >= _innerRadiusSqr) {
+ _engine->getCursorManager()->changeCursor(CursorIndex_Active);
+ return true;
+ }
+ }
+ return false;
+}
+
+bool SafeControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ if (_rectangle.contains(backgroundImageSpacePos)) {
+ int32 mR = backgroundImageSpacePos.sqrDist(_center);
+ if (mR <= _outerRadiusSqr && mR >= _innerRadiusSqr) {
+ setVenus();
+
+ Common::Point tmp = backgroundImageSpacePos - _center;
+
+ float dd = atan2((float)tmp.x, (float)tmp.y) * 57.29578;
+
+ int16 dp_state = 360 / _statesCount;
+
+ int16 m_state = (_statesCount - ((((int16)dd + 540) % 360) / dp_state)) % _statesCount;
+
+ int16 tmp2 = (m_state + _curState - _zeroPointer + _statesCount - 1) % _statesCount;
+
+ if (_animation)
+ _animation->seekToFrame((_curState + _statesCount - _startPointer) % _statesCount);
+
+ _curState = (_statesCount * 2 + tmp2) % _statesCount;
+
+ _targetFrame = (_curState + _statesCount - _startPointer) % _statesCount;
+ return true;
+ }
+ }
+ return false;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/safe_control.h b/engines/zvision/scripting/controls/safe_control.h
new file mode 100644
index 0000000000..3e8c17635c
--- /dev/null
+++ b/engines/zvision/scripting/controls/safe_control.h
@@ -0,0 +1,65 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_SAFE_CONTROL_H
+#define ZVISION_SAFE_CONTROL_H
+
+#include "zvision/scripting/control.h"
+
+#include "common/list.h"
+#include "common/rect.h"
+
+namespace Video {
+ class VideoDecoder;
+}
+
+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);
+ ~SafeControl();
+
+private:
+ int16 _statesCount;
+ int16 _curState;
+ Video::VideoDecoder *_animation;
+ Common::Point _center;
+ Common::Rect _rectangle;
+ int16 _innerRaduis;
+ int32 _innerRadiusSqr;
+ int16 _outerRadius;
+ int32 _outerRadiusSqr;
+ int16 _zeroPointer;
+ int16 _startPointer;
+ int16 _targetFrame;
+
+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);
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/controls/save_control.cpp b/engines/zvision/scripting/controls/save_control.cpp
new file mode 100644
index 0000000000..2ac77c4776
--- /dev/null
+++ b/engines/zvision/scripting/controls/save_control.cpp
@@ -0,0 +1,123 @@
+/* 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 "zvision/scripting/controls/input_control.h"
+#include "zvision/scripting/controls/save_control.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/text/string_manager.h"
+
+#include "zvision/file/save_manager.h"
+#include "zvision/graphics/render_manager.h"
+
+#include "common/str.h"
+#include "common/stream.h"
+
+namespace ZVision {
+
+SaveControl::SaveControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
+ : Control(engine, key, CONTROL_SAVE),
+ _saveControl(false) {
+ // Loop until we find the closing brace
+ Common::String line = stream.readLine();
+ _engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
+ Common::String param;
+ Common::String values;
+ getParams(line, param, values);
+
+ while (!stream.eos() && !line.contains('}')) {
+ if (param.matchString("savebox", true)) {
+ int saveId;
+ int inputId;
+
+ sscanf(values.c_str(), "%d %d", &saveId, &inputId);
+ saveElement elmnt;
+ elmnt.inputKey = inputId;
+ elmnt.saveId = saveId;
+ elmnt.exist = false;
+ _inputs.push_back(elmnt);
+ } else if (param.matchString("control_type", true)) {
+ if (values.contains("save"))
+ _saveControl = true;
+ else
+ _saveControl = false;
+ }
+
+ line = stream.readLine();
+ _engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
+ getParams(line, param, values);
+ }
+
+ for (saveElmntList::iterator iter = _inputs.begin(); iter != _inputs.end(); ++iter) {
+ Control *ctrl = _engine->getScriptManager()->getControl(iter->inputKey);
+ if (ctrl && ctrl->getType() == Control::CONTROL_INPUT) {
+ InputControl *inp = (InputControl *)ctrl;
+ inp->setReadOnly(!_saveControl);
+ Common::SeekableReadStream *save = _engine->getSaveManager()->getSlotFile(iter->saveId);
+ if (save) {
+ SaveGameHeader header;
+ if (_engine->getSaveManager()->readSaveGameHeader(save, header)) {
+ inp->setText(header.saveName);
+ iter->exist = true;
+ }
+ delete save;
+ }
+ }
+ }
+}
+
+bool SaveControl::process(uint32 deltaTimeInMillis) {
+ for (saveElmntList::iterator iter = _inputs.begin(); iter != _inputs.end(); ++iter) {
+ Control *ctrl = _engine->getScriptManager()->getControl(iter->inputKey);
+ if (ctrl && ctrl->getType() == Control::CONTROL_INPUT) {
+ InputControl *inp = (InputControl *)ctrl;
+ if (inp->enterPress()) {
+ if (_saveControl) {
+ if (inp->getText().size() > 0) {
+ bool toSave = true;
+ if (iter->exist)
+ if (!_engine->getRenderManager()->askQuestion(_engine->getStringManager()->getTextLine(StringManager::ZVISION_STR_SAVEEXIST)))
+ toSave = false;
+
+ if (toSave) {
+ _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->getRenderManager()->timedMessage(_engine->getStringManager()->getTextLine(StringManager::ZVISION_STR_SAVEEMPTY), 2000);
+ }
+ } else {
+ _engine->getSaveManager()->loadGame(iter->saveId);
+ return true;
+ }
+ break;
+ }
+ }
+ }
+ return false;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/save_control.h b/engines/zvision/scripting/controls/save_control.h
new file mode 100644
index 0000000000..cdc50eb54d
--- /dev/null
+++ b/engines/zvision/scripting/controls/save_control.h
@@ -0,0 +1,55 @@
+/* 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_SAVE_CONTROL_H
+#define ZVISION_SAVE_CONTROL_H
+
+#include "zvision/scripting/control.h"
+
+#include "common/list.h"
+
+namespace ZVision {
+
+class SaveControl : public Control {
+public:
+ SaveControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
+
+private:
+ struct saveElement {
+ int saveId;
+ int inputKey;
+ bool exist;
+ };
+ typedef Common::List<saveElement> saveElmntList;
+ saveElmntList _inputs;
+
+ bool _saveControl;
+
+public:
+
+ bool process(uint32 deltaTimeInMillis);
+
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/controls/slot_control.cpp b/engines/zvision/scripting/controls/slot_control.cpp
new file mode 100644
index 0000000000..42b54a9ab5
--- /dev/null
+++ b/engines/zvision/scripting/controls/slot_control.cpp
@@ -0,0 +1,219 @@
+/* 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 "zvision/scripting/controls/slot_control.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/graphics/cursors/cursor_manager.h"
+#include "zvision/graphics/render_manager.h"
+
+#include "common/stream.h"
+
+namespace ZVision {
+
+SlotControl::SlotControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
+ : Control(engine, key, CONTROL_SLOT),
+ _cursor(CursorIndex_Active),
+ _distanceId('0') {
+
+ _renderedItem = 0;
+ _bkg = NULL;
+
+ // Loop until we find the closing brace
+ Common::String line = stream.readLine();
+ _engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
+ Common::String param;
+ Common::String values;
+ getParams(line, param, values);
+
+ while (!stream.eos() && !line.contains('}')) {
+ if (param.matchString("hotspot", true)) {
+ int x;
+ int y;
+ int width;
+ int height;
+
+ sscanf(values.c_str(), "%d %d %d %d", &x, &y, &width, &height);
+
+ _hotspot = Common::Rect(x, y, width, height);
+ } else if (param.matchString("rectangle", true)) {
+ int x;
+ int y;
+ int width;
+ int height;
+
+ sscanf(values.c_str(), "%d %d %d %d", &x, &y, &width, &height);
+
+ _rectangle = Common::Rect(x, y, width, height);
+ } else if (param.matchString("cursor", true)) {
+ _cursor = _engine->getCursorManager()->getCursorId(values);
+ } else if (param.matchString("distance_id", true)) {
+ sscanf(values.c_str(), "%c", &_distanceId);
+ } else if (param.matchString("venus_id", true)) {
+ _venusId = atoi(values.c_str());
+ } else if (param.matchString("eligible_objects", true)) {
+ char buf[256];
+ memset(buf, 0, 256);
+ strncpy(buf, values.c_str(), 255);
+
+ char *curpos = buf;
+ char *strend = buf + strlen(buf);
+ while (true) {
+ char *st = curpos;
+
+ if (st >= strend)
+ break;
+
+ while (*curpos != ' ' && curpos < strend)
+ curpos++;
+
+ *curpos = 0;
+ curpos++;
+
+ int obj = atoi(st);
+
+ _eligibleObjects.push_back(obj);
+ }
+ }
+
+ line = stream.readLine();
+ _engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
+ getParams(line, param, values);
+ }
+
+ if (_hotspot.isEmpty() || _rectangle.isEmpty()) {
+ warning("Slot %u was parsed incorrectly", key);
+ }
+}
+
+SlotControl::~SlotControl() {
+ // Clear the state value back to 0
+ //_engine->getScriptManager()->setStateValue(_key, 0);
+
+ if (_bkg)
+ delete _bkg;
+}
+
+bool SlotControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ if (_hotspot.contains(backgroundImageSpacePos)) {
+ setVenus();
+
+ int item = _engine->getScriptManager()->getStateValue(_key);
+ int mouseItem = _engine->getScriptManager()->getStateValue(StateKey_InventoryItem);
+ if (item != 0) {
+ if (mouseItem != 0) {
+ if (eligeblity(mouseItem)) {
+ _engine->getScriptManager()->inventoryDrop(mouseItem);
+ _engine->getScriptManager()->inventoryAdd(item);
+ _engine->getScriptManager()->setStateValue(_key, mouseItem);
+ }
+ } else {
+ _engine->getScriptManager()->inventoryAdd(item);
+ _engine->getScriptManager()->setStateValue(_key, 0);
+ }
+ } else if (mouseItem == 0) {
+ if (eligeblity(0)) {
+ _engine->getScriptManager()->inventoryDrop(0);
+ _engine->getScriptManager()->setStateValue(_key, 0);
+ }
+ } else if (eligeblity(mouseItem)) {
+ _engine->getScriptManager()->setStateValue(_key, mouseItem);
+ _engine->getScriptManager()->inventoryDrop(mouseItem);
+ }
+ }
+ return false;
+}
+
+bool SlotControl::onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ if (_hotspot.contains(backgroundImageSpacePos)) {
+ _engine->getCursorManager()->changeCursor(_cursor);
+ return true;
+ }
+
+ return false;
+}
+
+bool SlotControl::process(uint32 deltaTimeInMillis) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ if (_engine->canRender()) {
+ int curItem = _engine->getScriptManager()->getStateValue(_key);
+ if (curItem != _renderedItem) {
+ if (_renderedItem != 0 && curItem == 0) {
+ _engine->getRenderManager()->blitSurfaceToBkg(*_bkg, _rectangle.left, _rectangle.top);
+ _renderedItem = curItem;
+ } else {
+ if (_renderedItem == 0) {
+ if (_bkg)
+ delete _bkg;
+
+ _bkg = _engine->getRenderManager()->getBkgRect(_rectangle);
+ } else {
+ _engine->getRenderManager()->blitSurfaceToBkg(*_bkg, _rectangle.left, _rectangle.top);
+ }
+
+ char buf[16];
+ if (_engine->getGameId() == GID_NEMESIS)
+ sprintf(buf, "%d%cobj.tga", curItem, _distanceId);
+ else
+ sprintf(buf, "g0z%cu%2.2x1.tga", _distanceId, curItem);
+
+ Graphics::Surface *srf = _engine->getRenderManager()->loadImage(buf);
+
+ int16 drawx = _rectangle.left;
+ int16 drawy = _rectangle.top;
+
+ if (_rectangle.width() > srf->w)
+ drawx = _rectangle.left + (_rectangle.width() - srf->w) / 2;
+
+ if (_rectangle.height() > srf->h)
+ drawy = _rectangle.top + (_rectangle.height() - srf->h) / 2;
+
+ _engine->getRenderManager()->blitSurfaceToBkg(*srf, drawx, drawy, 0);
+
+ delete srf;
+
+ _renderedItem = curItem;
+ }
+ }
+ }
+ return false;
+}
+
+bool SlotControl::eligeblity(int itemId) {
+ for (Common::List<int>::iterator it = _eligibleObjects.begin(); it != _eligibleObjects.end(); it++)
+ if (*it == itemId)
+ return true;
+ return false;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/slot_control.h b/engines/zvision/scripting/controls/slot_control.h
new file mode 100644
index 0000000000..e776d99311
--- /dev/null
+++ b/engines/zvision/scripting/controls/slot_control.h
@@ -0,0 +1,84 @@
+/* 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_SLOT_CONTROL_H
+#define ZVISION_SLOT_CONTROL_H
+
+#include "zvision/scripting/control.h"
+
+#include "graphics/surface.h"
+
+#include "common/rect.h"
+#include "common/list.h"
+
+namespace ZVision {
+
+class SlotControl : public Control {
+public:
+ SlotControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
+ ~SlotControl();
+
+ /**
+ * Called when LeftMouse is lifted. Calls ScriptManager::setStateValue(_key, 1);
+ *
+ * @param screenSpacePos The position of the mouse in screen space
+ * @param backgroundImageSpacePos The position of the mouse in background image space
+ */
+ bool onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+ /**
+ * Called on every MouseMove. Tests if the mouse is inside _hotspot, and if so, sets the cursor.
+ *
+ * @param engine The base engine
+ * @param screenSpacePos The position of the mouse in screen space
+ * @param backgroundImageSpacePos The position of the mouse in background image space
+ * @return Was the cursor changed?
+ */
+ bool onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+
+ bool process(uint32 deltaTimeInMillis);
+
+private:
+ /**
+ * The area that will trigger the event
+ * This is in image space coordinates, NOT screen space
+ */
+ Common::Rect _rectangle;
+ Common::Rect _hotspot;
+
+ int _cursor;
+ char _distanceId;
+
+ int _renderedItem;
+
+ Common::List<int> _eligibleObjects;
+
+ bool eligeblity(int itemId);
+
+ Graphics::Surface *_bkg;
+
+ /** The cursor to use when hovering over _hotspot */
+ Common::String _hoverCursor;
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/controls/titler_control.cpp b/engines/zvision/scripting/controls/titler_control.cpp
new file mode 100644
index 0000000000..683d6660af
--- /dev/null
+++ b/engines/zvision/scripting/controls/titler_control.cpp
@@ -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.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/scripting/controls/titler_control.h"
+
+#include "zvision/zvision.h"
+#include "zvision/text/text.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/graphics/render_manager.h"
+
+#include "common/stream.h"
+
+namespace ZVision {
+
+TitlerControl::TitlerControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
+ : Control(engine, key, CONTROL_TITLER) {
+
+ _surface = NULL;
+ _curString = -1;
+
+ // Loop until we find the closing brace
+ Common::String line = stream.readLine();
+ _engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
+ Common::String param;
+ Common::String values;
+ getParams(line, param, values);
+
+ while (!stream.eos() && !line.contains('}')) {
+ if (param.matchString("string_resource_file", true)) {
+ readStringsFile(values);
+ } else if (param.matchString("rectangle", true)) {
+ int x;
+ int y;
+ int x2;
+ int y2;
+
+ sscanf(values.c_str(), "%d %d %d %d", &x, &y, &x2, &y2);
+
+ _rectangle = Common::Rect(x, y, x2, y2);
+ }
+
+ line = stream.readLine();
+ _engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
+ getParams(line, param, values);
+ }
+
+ if (!_rectangle.isEmpty()) {
+ _surface = new Graphics::Surface;
+ _surface->create(_rectangle.width(), _rectangle.height(), _engine->_resourcePixelFormat);
+ _surface->fillRect(Common::Rect(_surface->w, _surface->h), 0);
+ }
+}
+
+TitlerControl::~TitlerControl() {
+ 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()->drawTextWithWordWrapping(_strings[strLine], *_surface);
+ _engine->getRenderManager()->blitSurfaceToBkg(*_surface, _rectangle.left, _rectangle.top);
+ _curString = strLine;
+ }
+}
+
+void TitlerControl::readStringsFile(const Common::String &fileName) {
+ Common::File file;
+ if (!_engine->getSearchManager()->openFile(file, fileName)) {
+ warning("String_resource_file %s could could be opened", fileName.c_str());
+ return;
+ }
+
+ _strings.clear();
+
+ while (!file.eos()) {
+
+ Common::String line = readWideLine(file);
+ _strings.push_back(line);
+ }
+ file.close();
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/titler_control.h b/engines/zvision/scripting/controls/titler_control.h
new file mode 100644
index 0000000000..dd96e4a846
--- /dev/null
+++ b/engines/zvision/scripting/controls/titler_control.h
@@ -0,0 +1,55 @@
+/* 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_TITLER_CONTROL_H
+#define ZVISION_TITLER_CONTROL_H
+
+#include "zvision/scripting/control.h"
+
+#include "graphics/surface.h"
+
+#include "common/rect.h"
+#include "common/array.h"
+
+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);
+ ~TitlerControl();
+
+ void setString(int strLine);
+
+private:
+
+ Common::Array< Common::String > _strings;
+ Common::Rect _rectangle;
+ int16 _curString;
+ Graphics::Surface *_surface;
+
+ void readStringsFile(const Common::String &fileName);
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/effects/animation_effect.cpp b/engines/zvision/scripting/effects/animation_effect.cpp
new file mode 100644
index 0000000000..511a0db353
--- /dev/null
+++ b/engines/zvision/scripting/effects/animation_effect.cpp
@@ -0,0 +1,217 @@
+/* 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 "zvision/scripting/effects/animation_effect.h"
+
+#include "zvision/zvision.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/scripting/script_manager.h"
+
+#include "graphics/surface.h"
+#include "video/video_decoder.h"
+
+namespace ZVision {
+
+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);
+
+ 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;
+ }
+}
+
+AnimationEffect::~AnimationEffect() {
+ if (_animation)
+ delete _animation;
+
+ _engine->getScriptManager()->setStateValue(_key, 2);
+
+ PlayNodes::iterator it = _playList.begin();
+ if (it != _playList.end()) {
+ _engine->getScriptManager()->setStateValue((*it).slot, 2);
+
+ if ((*it)._scaled) {
+ (*it)._scaled->free();
+ delete(*it)._scaled;
+ }
+ }
+
+ _playList.clear();
+}
+
+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);
+
+ 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;
+ }
+
+ 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 (needsUpdate) {
+ const Graphics::Surface *frame = _animation->decodeNextFrame();
+
+ if (frame) {
+ uint32 dstw;
+ uint32 dsth;
+ if (isPanorama) {
+ dstw = nod->pos.height();
+ dsth = nod->pos.width();
+ } else {
+ dstw = nod->pos.width();
+ dsth = nod->pos.height();
+ }
+
+ // We only scale down the animation to fit its frame, not up, otherwise we
+ // end up with distorted animations - e.g. the armor visor in location cz1e
+ // in Nemesis (one of the armors inside Irondune), or the planet in location
+ // aa10 in Nemesis (Juperon, outside the asylum). We do allow scaling up only
+ // when a simple 2x filter is requested (e.g. the alchemists and cup sequence
+ // in Nemesis)
+ 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;
+ }
+
+ if (!nod->_scaled) {
+ nod->_scaled = new Graphics::Surface;
+ nod->_scaled->create(dstw, dsth, frame->format);
+ }
+
+ renderManager->scaleBuffer(frame->getPixels(), nod->_scaled->getPixels(), frame->w, frame->h, frame->format.bytesPerPixel, dstw, dsth);
+ frame = nod->_scaled;
+ }
+
+ if (isPanorama) {
+ Graphics::Surface *transposed = RenderManager::tranposeSurface(frame);
+ renderManager->blitSurfaceToBkg(*transposed, nod->pos.left, nod->pos.top, _mask);
+ transposed->free();
+ delete transposed;
+ } else {
+ renderManager->blitSurfaceToBkg(*frame, nod->pos.left, nod->pos.top, _mask);
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+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 = CLIP<int>(endFrame, 0, _animation->getFrameCount() - 1);
+ nod.slot = slot;
+ nod._curFrame = -1;
+ nod._delay = 0;
+ nod._scaled = NULL;
+ _playList.push_back(nod);
+}
+
+bool AnimationEffect::stop() {
+ PlayNodes::iterator it = _playList.begin();
+ if (it != _playList.end()) {
+ _engine->getScriptManager()->setStateValue((*it).slot, 2);
+ if ((*it)._scaled) {
+ (*it)._scaled->free();
+ delete(*it)._scaled;
+ }
+ }
+
+ _playList.clear();
+
+ // We don't need to delete, it's may be reused
+ return false;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/animation_control.h b/engines/zvision/scripting/effects/animation_effect.h
index 6c4d6dfcf7..fd6e24ab8b 100644
--- a/engines/zvision/scripting/controls/animation_control.h
+++ b/engines/zvision/scripting/effects/animation_effect.h
@@ -8,78 +8,70 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
- *
+
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+
* You should have received a copy of the GNU General Public 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_ANIMATION_CONTROL_H
-#define ZVISION_ANIMATION_CONTROL_H
+#ifndef ZVISION_ANIMATION_NODE_H
+#define ZVISION_ANIMATION_NODE_H
-#include "zvision/scripting/control.h"
+#include "zvision/scripting/scripting_effect.h"
+#include "common/rect.h"
+#include "common/list.h"
-
-namespace Common {
-class String;
+namespace Graphics {
+struct Surface;
}
namespace Video {
-class VideoDecoder;
-}
-
-namespace Graphics {
-struct Surface;
+ class VideoDecoder;
}
namespace ZVision {
class ZVision;
-class RlfAnimation;
-class AnimationControl : public Control {
+class AnimationEffect : public ScriptingEffect {
public:
- AnimationControl(ZVision *engine, uint32 controlKey, const Common::String &fileName);
- ~AnimationControl();
-
-private:
- enum FileType {
- RLF = 1,
- AVI = 2
+ AnimationEffect(ZVision *engine, uint32 controlKey, const Common::String &fileName, int32 mask, int32 frate, bool disposeAfterUse = true);
+ ~AnimationEffect();
+
+ struct playnode {
+ Common::Rect pos;
+ int32 slot;
+ int32 start;
+ int32 stop;
+ int32 loop;
+ int32 _curFrame;
+ int32 _delay;
+ Graphics::Surface *_scaled;
};
private:
- uint32 _animationKey;
-
- union {
- RlfAnimation *rlf;
- Video::VideoDecoder *avi;
- } _animation;
+ typedef Common::List<playnode> PlayNodes;
- FileType _fileType;
- uint _loopCount;
- int32 _x;
- int32 _y;
+ PlayNodes _playList;
- uint _accumulatedTime;
- uint _currentLoop;
+ int32 _mask;
+ bool _disposeAfterUse;
- Graphics::Surface *_cachedFrame;
- bool _cachedFrameNeedsDeletion;
+ Video::VideoDecoder *_animation;
+ int32 _frmDelayOverride;
public:
bool process(uint32 deltaTimeInMillis);
- void setAnimationKey(uint32 animationKey) { _animationKey = animationKey; }
- void setLoopCount(uint loopCount) { _loopCount = loopCount; }
- void setXPos(int32 x) { _x = x; }
- void setYPost(int32 y) { _y = y; }
+ void addPlayNode(int32 slot, int x, int y, int x2, int y2, int startFrame, int endFrame, int loops = 1);
+
+ bool stop();
};
} // End of namespace ZVision
diff --git a/engines/zvision/scripting/effects/distort_effect.cpp b/engines/zvision/scripting/effects/distort_effect.cpp
new file mode 100644
index 0000000000..113b5d048d
--- /dev/null
+++ b/engines/zvision/scripting/effects/distort_effect.cpp
@@ -0,0 +1,104 @@
+/* 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 "zvision/scripting/effects/distort_effect.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/graphics/render_table.h"
+
+#include "common/stream.h"
+
+namespace ZVision {
+
+DistortNode::DistortNode(ZVision *engine, uint32 key, int16 speed, float startAngle, float endAngle, float startLineScale, float endLineScale)
+ : ScriptingEffect(engine, key, SCRIPTING_EFFECT_DISTORT) {
+
+ _angle = _engine->getRenderManager()->getRenderTable()->getAngle();
+ _linScale = _engine->getRenderManager()->getRenderTable()->getLinscale();
+
+ _speed = speed;
+ _incr = true;
+ _startAngle = startAngle;
+ _endAngle = endAngle;
+ _startLineScale = startLineScale;
+ _endLineScale = endLineScale;
+
+ _curFrame = 1.0;
+
+ _diffAngle = endAngle - startAngle;
+ _diffLinScale = endLineScale - startLineScale;
+
+ _frmSpeed = (float)speed / 15.0;
+ _frames = (int)ceil((5.0 - _frmSpeed * 2.0) / _frmSpeed);
+ if (_frames <= 0)
+ _frames = 1;
+
+ if (_key != StateKey_NotSet)
+ _engine->getScriptManager()->setStateValue(_key, 1);
+}
+
+DistortNode::~DistortNode() {
+ setParams(_angle, _linScale);
+}
+
+bool DistortNode::process(uint32 deltaTimeInMillis) {
+ float updTime = deltaTimeInMillis / (1000.0 / 60.0);
+
+ if (_incr)
+ _curFrame += updTime;
+ else
+ _curFrame -= updTime;
+
+ if (_curFrame < 1.0) {
+ _curFrame = 1.0;
+ _incr = true;
+ } else if (_curFrame > _frames) {
+ _curFrame = _frames;
+ _incr = false;
+ }
+
+ float diff = (1.0 / (5.0 - (_curFrame * _frmSpeed))) / (5.0 - _frmSpeed);
+ setParams(_startAngle + diff * _diffAngle, _startLineScale + diff * _diffLinScale);
+
+ return false;
+}
+
+void DistortNode::setParams(float angl, float linScale) {
+ RenderTable *table = _engine->getRenderManager()->getRenderTable();
+ if (table->getRenderState() == RenderTable::PANORAMA) {
+ table->setPanoramaFoV(angl);
+ table->setPanoramaScale(linScale);
+ table->generateRenderTable();
+ _engine->getRenderManager()->markDirty();
+ } else if (table->getRenderState() == RenderTable::TILT) {
+ table->setTiltFoV(angl);
+ table->setTiltScale(linScale);
+ table->generateRenderTable();
+ _engine->getRenderManager()->markDirty();
+ }
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/effects/distort_effect.h b/engines/zvision/scripting/effects/distort_effect.h
new file mode 100644
index 0000000000..c64f10e6ff
--- /dev/null
+++ b/engines/zvision/scripting/effects/distort_effect.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 ZVISION_DISTORT_NODE_H
+#define ZVISION_DISTORT_NODE_H
+
+#include "zvision/scripting/scripting_effect.h"
+
+namespace ZVision {
+
+class ZVision;
+
+class DistortNode : public ScriptingEffect {
+public:
+ DistortNode(ZVision *engine, uint32 key, int16 speed, float startAngle, float endAngle, float startLineScale, float endLineScale);
+ ~DistortNode();
+
+ bool process(uint32 deltaTimeInMillis);
+
+private:
+ int16 _speed;
+ float _startAngle;
+ float _endAngle;
+ float _startLineScale;
+ float _endLineScale;
+
+ float _frmSpeed;
+ float _diffAngle;
+ float _diffLinScale;
+ bool _incr;
+ int16 _frames;
+
+ float _curFrame;
+
+ float _angle;
+ float _linScale;
+
+private:
+ void setParams(float angl, float linScale);
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/effects/music_effect.cpp b/engines/zvision/scripting/effects/music_effect.cpp
new file mode 100644
index 0000000000..e3fdc96dba
--- /dev/null
+++ b/engines/zvision/scripting/effects/music_effect.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 "common/scummsys.h"
+
+#include "zvision/scripting/effects/music_effect.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/sound/midi.h"
+#include "zvision/sound/zork_raw.h"
+
+#include "common/stream.h"
+#include "common/file.h"
+#include "audio/decoders/wave.h"
+
+namespace ZVision {
+
+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;
+ _sub = NULL;
+ _stereo = false;
+ _loaded = false;
+
+ Audio::RewindableAudioStream *audioStream = NULL;
+
+ if (filename.contains(".wav")) {
+ Common::File *file = new Common::File();
+ if (_engine->getSearchManager()->openFile(*file, filename)) {
+ audioStream = Audio::makeWAVStream(file, DisposeAfterUse::YES);
+ }
+ } else {
+ audioStream = makeRawZorkStream(filename, _engine);
+ }
+
+ if (audioStream) {
+ _stereo = audioStream->isStereo();
+
+ if (_loop) {
+ Audio::LoopingAudioStream *loopingAudioStream = new Audio::LoopingAudioStream(audioStream, 0, DisposeAfterUse::YES);
+ _engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_handle, loopingAudioStream, -1, dbMapLinear[_volume]);
+ } else {
+ _engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_handle, audioStream, -1, dbMapLinear[_volume]);
+ }
+
+ if (_key != StateKey_NotSet)
+ _engine->getScriptManager()->setStateValue(_key, 1);
+
+ // Change filename.raw into filename.sub
+ Common::String subname = filename;
+ subname.setChar('s', subname.size() - 3);
+ subname.setChar('u', subname.size() - 2);
+ subname.setChar('b', subname.size() - 1);
+
+ if (_engine->getSearchManager()->hasFile(subname))
+ _sub = new Subtitle(_engine, subname);
+
+ _loaded = true;
+ }
+}
+
+MusicNode::~MusicNode() {
+ if (_loaded)
+ _engine->_mixer->stopHandle(_handle);
+ if (_key != StateKey_NotSet)
+ _engine->getScriptManager()->setStateValue(_key, 2);
+ if (_sub)
+ delete _sub;
+ debug(1, "MusicNode: %d destroyed", _key);
+}
+
+void MusicNode::setDeltaVolume(uint8 volume) {
+ _deltaVolume = volume;
+ setVolume(_volume);
+}
+
+void MusicNode::setBalance(int8 balance) {
+ _balance = balance;
+ _engine->_mixer->setChannelBalance(_handle, _balance);
+}
+
+void MusicNode::setFade(int32 time, uint8 target) {
+ _crossfadeTarget = target;
+ _crossfadeTime = time;
+ _crossfade = true;
+}
+
+bool MusicNode::process(uint32 deltaTimeInMillis) {
+ if (!_loaded || ! _engine->_mixer->isSoundHandleActive(_handle))
+ return stop();
+ else {
+ uint8 _newvol = _volume;
+
+ if (_crossfade) {
+ if (_crossfadeTime > 0) {
+ if ((int32)deltaTimeInMillis > _crossfadeTime)
+ deltaTimeInMillis = _crossfadeTime;
+ _newvol += (int)(floor(((float)(_crossfadeTarget - _newvol) / (float)_crossfadeTime)) * (float)deltaTimeInMillis);
+ _crossfadeTime -= deltaTimeInMillis;
+ } else {
+ _crossfade = false;
+ _newvol = _crossfadeTarget;
+ }
+ }
+
+ if (_volume != _newvol)
+ setVolume(_newvol);
+
+ if (_sub && _engine->getScriptManager()->getStateValue(StateKey_Subtitles) == 1)
+ _sub->process(_engine->_mixer->getSoundElapsedTime(_handle) / 100);
+ }
+ return false;
+}
+
+void MusicNode::setVolume(uint8 newVolume) {
+ if (!_loaded)
+ return;
+
+ _volume = newVolume;
+
+ if (_deltaVolume >= _volume)
+ _engine->_mixer->setChannelVolume(_handle, 0);
+ else
+ _engine->_mixer->setChannelVolume(_handle, dbMapLinear[_volume - _deltaVolume]);
+}
+
+uint8 MusicNode::getVolume() {
+ return _volume;
+}
+
+PanTrackNode::PanTrackNode(ZVision *engine, uint32 key, uint32 slot, int16 pos)
+ : ScriptingEffect(engine, key, SCRIPTING_EFFECT_PANTRACK) {
+ _slot = slot;
+ _position = pos;
+
+ // Try to set pan value for music node immediately
+ process(0);
+}
+
+PanTrackNode::~PanTrackNode() {
+}
+
+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;
+
+ 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, SCRIPTING_EFFECT_AUDIO) {
+ _volume = volume;
+ _prog = program;
+ _noteNumber = note;
+ _pan = 0;
+
+ _chan = _engine->getMidiManager()->getFreeChannel();
+
+ if (_chan >= 0) {
+ _engine->getMidiManager()->setVolume(_chan, _volume);
+ _engine->getMidiManager()->setPan(_chan, _pan);
+ _engine->getMidiManager()->setProgram(_chan, _prog);
+ _engine->getMidiManager()->noteOn(_chan, _noteNumber, _volume);
+ }
+
+ if (_key != StateKey_NotSet)
+ _engine->getScriptManager()->setStateValue(_key, 1);
+}
+
+MusicMidiNode::~MusicMidiNode() {
+ if (_chan >= 0) {
+ _engine->getMidiManager()->noteOff(_chan);
+ }
+ if (_key != StateKey_NotSet)
+ _engine->getScriptManager()->setStateValue(_key, 2);
+}
+
+void MusicMidiNode::setDeltaVolume(uint8 volume) {
+}
+
+void MusicMidiNode::setBalance(int8 balance) {
+}
+
+void MusicMidiNode::setFade(int32 time, uint8 target) {
+}
+
+bool MusicMidiNode::process(uint32 deltaTimeInMillis) {
+ return false;
+}
+
+void MusicMidiNode::setVolume(uint8 newVolume) {
+ if (_chan >= 0) {
+ _engine->getMidiManager()->setVolume(_chan, newVolume);
+ }
+ _volume = newVolume;
+}
+
+uint8 MusicMidiNode::getVolume() {
+ return _volume;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/effects/music_effect.h b/engines/zvision/scripting/effects/music_effect.h
new file mode 100644
index 0000000000..7657be8e09
--- /dev/null
+++ b/engines/zvision/scripting/effects/music_effect.h
@@ -0,0 +1,137 @@
+/* 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_MUSIC_NODE_H
+#define ZVISION_MUSIC_NODE_H
+
+#include "audio/mixer.h"
+#include "zvision/scripting/scripting_effect.h"
+#include "zvision/text/subtitles.h"
+
+namespace Common {
+class String;
+}
+
+namespace ZVision {
+
+class MusicNodeBASE : public ScriptingEffect {
+public:
+ MusicNodeBASE(ZVision *engine, uint32 key, ScriptingEffectType type) : ScriptingEffect(engine, key, type) {}
+ ~MusicNodeBASE() {}
+
+ /**
+ * Decrement the timer by the delta time. If the timer is finished, set the status
+ * in _globalState and let this node be deleted
+ *
+ * @param deltaTimeInMillis The number of milliseconds that have passed since last frame
+ * @return If true, the node can be deleted after process() finishes
+ */
+ virtual bool process(uint32 deltaTimeInMillis) = 0;
+
+ virtual void setVolume(uint8 volume) = 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, uint8 volume);
+ ~MusicNode();
+
+ /**
+ * Decrement the timer by the delta time. If the timer is finished, set the status
+ * in _globalState and let this node be deleted
+ *
+ * @param deltaTimeInMillis The number of milliseconds that have passed since last frame
+ * @return If true, the node can be deleted after process() finishes
+ */
+ bool process(uint32 deltaTimeInMillis);
+
+ void setVolume(uint8 volume);
+ uint8 getVolume();
+ void setDeltaVolume(uint8 volume);
+ void setBalance(int8 balance);
+
+ void setFade(int32 time, uint8 target);
+
+private:
+ uint8 _volume;
+ uint8 _deltaVolume;
+ int8 _balance;
+ bool _loop;
+ bool _crossfade;
+ uint8 _crossfadeTarget;
+ int32 _crossfadeTime;
+ bool _stereo;
+ Audio::SoundHandle _handle;
+ Subtitle *_sub;
+ 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);
+ ~MusicMidiNode();
+
+ /**
+ * Decrement the timer by the delta time. If the timer is finished, set the status
+ * in _globalState and let this node be deleted
+ *
+ * @param deltaTimeInMillis The number of milliseconds that have passed since last frame
+ * @return If true, the node can be deleted after process() finishes
+ */
+ bool process(uint32 deltaTimeInMillis);
+
+ void setVolume(uint8 volume);
+ uint8 getVolume();
+ void setDeltaVolume(uint8 volume);
+ void setBalance(int8 balance);
+
+ void setFade(int32 time, uint8 target);
+
+private:
+ int8 _chan;
+ int8 _noteNumber;
+ int8 _pan;
+ int8 _volume;
+ int8 _prog;
+};
+
+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
+
+#endif
diff --git a/engines/zvision/scripting/effects/region_effect.cpp b/engines/zvision/scripting/effects/region_effect.cpp
new file mode 100644
index 0000000000..78061cf4de
--- /dev/null
+++ b/engines/zvision/scripting/effects/region_effect.cpp
@@ -0,0 +1,56 @@
+/* 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 "zvision/scripting/effects/region_effect.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/graphics/render_manager.h"
+
+namespace ZVision {
+
+RegionNode::RegionNode(ZVision *engine, uint32 key, GraphicsEffect *effect, uint32 delay)
+ : ScriptingEffect(engine, key, SCRIPTING_EFFECT_REGION) {
+ _effect = effect;
+ _delay = delay;
+ _timeLeft = 0;
+}
+
+RegionNode::~RegionNode() {
+ _engine->getRenderManager()->deleteEffect(_key);
+}
+
+bool RegionNode::process(uint32 deltaTimeInMillis) {
+ _timeLeft -= deltaTimeInMillis;
+
+ if (_timeLeft <= 0) {
+ _timeLeft = _delay;
+ if (_effect)
+ _effect->update();
+ }
+
+ return false;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/effects/region_effect.h b/engines/zvision/scripting/effects/region_effect.h
new file mode 100644
index 0000000000..4fc16224ff
--- /dev/null
+++ b/engines/zvision/scripting/effects/region_effect.h
@@ -0,0 +1,57 @@
+/* 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_REGION_NODE_H
+#define ZVISION_REGION_NODE_H
+
+#include "graphics/surface.h"
+
+#include "zvision/scripting/scripting_effect.h"
+#include "zvision/graphics/graphics_effect.h"
+
+namespace ZVision {
+
+class ZVision;
+
+class RegionNode : public ScriptingEffect {
+public:
+ RegionNode(ZVision *engine, uint32 key, GraphicsEffect *effect, uint32 delay);
+ ~RegionNode();
+
+ /**
+ * Decrement the timer by the delta time. If the timer is finished, set the status
+ * in _globalState and let this node be deleted
+ *
+ * @param deltaTimeInMillis The number of milliseconds that have passed since last frame
+ * @return If true, the node can be deleted after process() finishes
+ */
+ bool process(uint32 deltaTimeInMillis);
+
+private:
+ int32 _timeLeft;
+ uint32 _delay;
+ GraphicsEffect *_effect;
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/effects/syncsound_effect.cpp b/engines/zvision/scripting/effects/syncsound_effect.cpp
new file mode 100644
index 0000000000..70ba97deb8
--- /dev/null
+++ b/engines/zvision/scripting/effects/syncsound_effect.cpp
@@ -0,0 +1,85 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/scripting/effects/syncsound_effect.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/sound/zork_raw.h"
+
+#include "common/stream.h"
+#include "common/file.h"
+#include "audio/decoders/wave.h"
+
+namespace ZVision {
+
+SyncSoundNode::SyncSoundNode(ZVision *engine, uint32 key, Common::String &filename, int32 syncto)
+ : ScriptingEffect(engine, key, SCRIPTING_EFFECT_AUDIO) {
+ _syncto = syncto;
+ _sub = NULL;
+
+ Audio::RewindableAudioStream *audioStream = NULL;
+
+ if (filename.contains(".wav")) {
+ Common::File *file = new Common::File();
+ if (_engine->getSearchManager()->openFile(*file, filename)) {
+ audioStream = Audio::makeWAVStream(file, DisposeAfterUse::YES);
+ }
+ } else {
+ audioStream = makeRawZorkStream(filename, _engine);
+ }
+
+ _engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_handle, audioStream);
+
+ Common::String subname = filename;
+ subname.setChar('s', subname.size() - 3);
+ subname.setChar('u', subname.size() - 2);
+ subname.setChar('b', subname.size() - 1);
+
+ if (_engine->getSearchManager()->hasFile(subname))
+ _sub = new Subtitle(_engine, subname);
+}
+
+SyncSoundNode::~SyncSoundNode() {
+ _engine->_mixer->stopHandle(_handle);
+ if (_sub)
+ delete _sub;
+}
+
+bool SyncSoundNode::process(uint32 deltaTimeInMillis) {
+ if (! _engine->_mixer->isSoundHandleActive(_handle))
+ return stop();
+ else {
+
+ if (_engine->getScriptManager()->getSideFX(_syncto) == NULL)
+ return stop();
+
+ if (_sub && _engine->getScriptManager()->getStateValue(StateKey_Subtitles) == 1)
+ _sub->process(_engine->_mixer->getSoundElapsedTime(_handle) / 100);
+ }
+ return false;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/effects/syncsound_effect.h b/engines/zvision/scripting/effects/syncsound_effect.h
new file mode 100644
index 0000000000..0eabff77a3
--- /dev/null
+++ b/engines/zvision/scripting/effects/syncsound_effect.h
@@ -0,0 +1,56 @@
+/* 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_SYNCSOUND_NODE_H
+#define ZVISION_SYNCSOUND_NODE_H
+
+#include "audio/mixer.h"
+#include "zvision/scripting/scripting_effect.h"
+#include "zvision/text/subtitles.h"
+
+namespace Common {
+class String;
+}
+
+namespace ZVision {
+class SyncSoundNode : public ScriptingEffect {
+public:
+ SyncSoundNode(ZVision *engine, uint32 key, Common::String &file, int32 syncto);
+ ~SyncSoundNode();
+
+ /**
+ * Decrement the timer by the delta time. If the timer is finished, set the status
+ * in _globalState and let this node be deleted
+ *
+ * @param deltaTimeInMillis The number of milliseconds that have passed since last frame
+ * @return If true, the node can be deleted after process() finishes
+ */
+ bool process(uint32 deltaTimeInMillis);
+private:
+ int32 _syncto;
+ Audio::SoundHandle _handle;
+ Subtitle *_sub;
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/controls/timer_node.cpp b/engines/zvision/scripting/effects/timer_effect.cpp
index c8c8a85d34..778f9dec6c 100644
--- a/engines/zvision/scripting/controls/timer_node.cpp
+++ b/engines/zvision/scripting/effects/timer_effect.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.
@@ -22,46 +22,54 @@
#include "common/scummsys.h"
-#include "zvision/scripting/controls/timer_node.h"
+#include "zvision/scripting/effects/timer_effect.h"
#include "zvision/zvision.h"
#include "zvision/scripting/script_manager.h"
#include "common/stream.h"
-
namespace ZVision {
-
+
TimerNode::TimerNode(ZVision *engine, uint32 key, uint timeInSeconds)
- : Control(engine, key) {
- if (_engine->getGameId() == GID_NEMESIS) {
+ : ScriptingEffect(engine, key, SCRIPTING_EFFECT_TIMER) {
+ _timeLeft = 0;
+
+ if (_engine->getGameId() == GID_NEMESIS)
_timeLeft = timeInSeconds * 1000;
- } else if (_engine->getGameId() == GID_GRANDINQUISITOR) {
+ else if (_engine->getGameId() == GID_GRANDINQUISITOR)
_timeLeft = timeInSeconds * 100;
- }
- _engine->getScriptManager()->setStateValue(_key, 1);
+ if (_key != StateKey_NotSet)
+ _engine->getScriptManager()->setStateValue(_key, 1);
}
TimerNode::~TimerNode() {
- if (_timeLeft <= 0)
+ if (_key != StateKey_NotSet)
_engine->getScriptManager()->setStateValue(_key, 2);
- else
- _engine->getScriptManager()->setStateValue(_key, _timeLeft); // If timer was stopped by stop or kill
+ int32 timeLeft = _timeLeft / (_engine->getGameId() == GID_NEMESIS ? 1000 : 100);
+ if (timeLeft > 0)
+ _engine->getScriptManager()->setStateValue(_key, timeLeft); // If timer was stopped by stop or kill
}
bool TimerNode::process(uint32 deltaTimeInMillis) {
_timeLeft -= deltaTimeInMillis;
- if (_timeLeft <= 0) {
- // Let the destructor reset the state value
- return true;
- }
+ if (_timeLeft <= 0)
+ return stop();
return false;
}
+bool TimerNode::stop() {
+ if (_key != StateKey_NotSet)
+ _engine->getScriptManager()->setStateValue(_key, 2);
+ return true;
+}
+
void TimerNode::serialize(Common::WriteStream *stream) {
+ stream->writeUint32BE(MKTAG('T', 'I', 'M', 'R'));
+ stream->writeUint32LE(8); // size
stream->writeUint32LE(_key);
stream->writeUint32LE(_timeLeft);
}
diff --git a/engines/zvision/scripting/controls/timer_node.h b/engines/zvision/scripting/effects/timer_effect.h
index 48b5fad1e9..5e45d54d7d 100644
--- a/engines/zvision/scripting/controls/timer_node.h
+++ b/engines/zvision/scripting/effects/timer_effect.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.
@@ -23,13 +23,13 @@
#ifndef ZVISION_TIMER_NODE_H
#define ZVISION_TIMER_NODE_H
-#include "zvision/scripting/control.h"
+#include "zvision/scripting/scripting_effect.h"
namespace ZVision {
class ZVision;
-class TimerNode : public Control {
+class TimerNode : public ScriptingEffect {
public:
TimerNode(ZVision *engine, uint32 key, uint timeInSeconds);
~TimerNode();
@@ -44,7 +44,11 @@ public:
bool process(uint32 deltaTimeInMillis);
void serialize(Common::WriteStream *stream);
void deserialize(Common::SeekableReadStream *stream);
- inline bool needsSerialization() { return true; }
+ inline bool needsSerialization() {
+ return true;
+ }
+
+ bool stop();
private:
int32 _timeLeft;
diff --git a/engines/zvision/scripting/effects/ttytext_effect.cpp b/engines/zvision/scripting/effects/ttytext_effect.cpp
new file mode 100644
index 0000000000..8d340dae39
--- /dev/null
+++ b/engines/zvision/scripting/effects/ttytext_effect.cpp
@@ -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.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/scripting/effects/ttytext_effect.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/text/text.h"
+
+#include "common/stream.h"
+#include "common/file.h"
+
+namespace ZVision {
+
+ttyTextNode::ttyTextNode(ZVision *engine, uint32 key, const Common::String &file, const Common::Rect &r, int32 delay) :
+ ScriptingEffect(engine, key, SCRIPTING_EFFECT_TTYTXT),
+ _fnt(engine) {
+ _delay = delay;
+ _r = r;
+ _txtpos = 0;
+ _nexttime = 0;
+ _dx = 0;
+ _dy = 0;
+
+ Common::File *infile = _engine->getSearchManager()->openFile(file);
+ if (infile) {
+ while (!infile->eos()) {
+ Common::String asciiLine = readWideLine(*infile);
+ if (asciiLine.empty()) {
+ continue;
+ }
+ _txtbuf += asciiLine;
+ }
+
+ delete infile;
+ }
+ _img.create(_r.width(), _r.height(), _engine->_resourcePixelFormat);
+ _state._sharp = true;
+ _state.readAllStyles(_txtbuf);
+ _state.updateFontWithTextState(_fnt);
+ _engine->getScriptManager()->setStateValue(_key, 1);
+}
+
+ttyTextNode::~ttyTextNode() {
+ _engine->getScriptManager()->setStateValue(_key, 2);
+ _img.free();
+}
+
+bool ttyTextNode::process(uint32 deltaTimeInMillis) {
+ _nexttime -= deltaTimeInMillis;
+
+ if (_nexttime < 0) {
+ if (_txtpos < _txtbuf.size()) {
+ if (_txtbuf[_txtpos] == '<') {
+ int32 start = _txtpos;
+ int32 end = 0;
+ int16 ret = 0;
+ while (_txtbuf[_txtpos] != '>' && _txtpos < _txtbuf.size())
+ _txtpos++;
+ 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 & TEXT_CHANGE_HAS_STATE_BOX) {
+ Common::String buf;
+ buf = Common::String::format("%d", _engine->getScriptManager()->getStateValue(_state._statebox));
+
+ for (uint8 j = 0; j < buf.size(); j++)
+ outchar(buf[j]);
+ }
+
+ _txtpos++;
+ } else {
+ int8 charsz = getUtf8CharSize(_txtbuf[_txtpos]);
+
+ uint16 chr = readUtf8Char(_txtbuf.c_str() + _txtpos);
+
+ if (chr == ' ') {
+ uint32 i = _txtpos + charsz;
+ uint16 width = _fnt.getCharWidth(chr);
+
+ while (i < _txtbuf.size() && _txtbuf[i] != ' ' && _txtbuf[i] != '<') {
+
+ int8 chsz = getUtf8CharSize(_txtbuf[i]);
+ uint16 uchr = readUtf8Char(_txtbuf.c_str() + _txtpos);
+
+ width += _fnt.getCharWidth(uchr);
+
+ i += chsz;
+ }
+
+ if (_dx + width > _r.width())
+ newline();
+ else
+ outchar(chr);
+ } else
+ outchar(chr);
+
+ _txtpos += charsz;
+ }
+ _nexttime = _delay;
+ _engine->getRenderManager()->blitSurfaceToBkg(_img, _r.left, _r.top);
+ } else
+ return stop();
+ }
+
+ return false;
+}
+
+void ttyTextNode::scroll() {
+ int32 scrl = 0;
+ while (_dy - scrl > _r.height() - _fnt.getFontHeight())
+ scrl += _fnt.getFontHeight();
+ int8 *pixels = (int8 *)_img.getPixels();
+ for (uint16 h = scrl; h < _img.h; h++)
+ memcpy(pixels + _img.pitch * (h - scrl), pixels + _img.pitch * h, _img.pitch);
+
+ _img.fillRect(Common::Rect(0, _img.h - scrl, _img.w, _img.h), 0);
+ _dy -= scrl;
+}
+
+void ttyTextNode::newline() {
+ _dy += _fnt.getFontHeight();
+ _dx = 0;
+}
+
+void ttyTextNode::outchar(uint16 chr) {
+ uint32 clr = _engine->_resourcePixelFormat.RGBToColor(_state._red, _state._green, _state._blue);
+
+ if (_dx + _fnt.getCharWidth(chr) > _r.width())
+ newline();
+
+ if (_dy + _fnt.getFontHeight() >= _r.height())
+ scroll();
+
+ _fnt.drawChar(&_img, chr, _dx, _dy, clr);
+
+ _dx += _fnt.getCharWidth(chr);
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/effects/ttytext_effect.h b/engines/zvision/scripting/effects/ttytext_effect.h
new file mode 100644
index 0000000000..18cbbbaee3
--- /dev/null
+++ b/engines/zvision/scripting/effects/ttytext_effect.h
@@ -0,0 +1,73 @@
+/* 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_TTYTEXT_NODE_H
+#define ZVISION_TTYTEXT_NODE_H
+
+#include "common/rect.h"
+#include "graphics/surface.h"
+
+#include "zvision/scripting/scripting_effect.h"
+#include "zvision/text/text.h"
+#include "zvision/text/truetype_font.h"
+
+namespace Common {
+class String;
+}
+
+namespace ZVision {
+class ttyTextNode : public ScriptingEffect {
+public:
+ ttyTextNode(ZVision *engine, uint32 key, const Common::String &file, const Common::Rect &r, int32 delay);
+ ~ttyTextNode();
+
+ /**
+ * Decrement the timer by the delta time. If the timer is finished, set the status
+ * in _globalState and let this node be deleted
+ *
+ * @param deltaTimeInMillis The number of milliseconds that have passed since last frame
+ * @return If true, the node can be deleted after process() finishes
+ */
+ bool process(uint32 deltaTimeInMillis);
+private:
+ Common::Rect _r;
+
+ TextStyleState _state;
+ StyledTTFont _fnt;
+ Common::String _txtbuf;
+ uint32 _txtpos;
+
+ int32 _delay;
+ int32 _nexttime;
+ Graphics::Surface _img;
+ int16 _dx;
+ int16 _dy;
+private:
+
+ void newline();
+ void scroll();
+ void outchar(uint16 chr);
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/inventory.cpp b/engines/zvision/scripting/inventory.cpp
new file mode 100644
index 0000000000..76d43b200b
--- /dev/null
+++ b/engines/zvision/scripting/inventory.cpp
@@ -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 distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public 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 "zvision/scripting/script_manager.h"
+
+namespace ZVision {
+
+int8 ScriptManager::inventoryGetCount() {
+ return getStateValue(StateKey_Inv_Cnt_Slot);
+}
+
+void ScriptManager::inventorySetCount(int8 cnt) {
+ setStateValue(StateKey_Inv_Cnt_Slot, cnt);
+}
+
+int16 ScriptManager::inventoryGetItem(int8 id) {
+ if (id < 49 && id >= 0)
+ return getStateValue(StateKey_Inv_1_Slot + id);
+ return -1;
+}
+
+void ScriptManager::inventorySetItem(int8 id, int16 item) {
+ if (id < 49 && id >= 0)
+ setStateValue(StateKey_Inv_1_Slot + id, item);
+}
+
+void ScriptManager::inventoryAdd(int16 item) {
+ int8 cnt = inventoryGetCount();
+
+ if (cnt < 49) {
+ bool notExist = true;
+
+ if (cnt == 0) {
+ inventorySetItem(0, 0);
+ inventorySetCount(1); // we needed empty item for cycle code
+ cnt = 1;
+ }
+
+ for (int8 cur = 0; cur < cnt; cur++)
+ if (inventoryGetItem(cur) == item) {
+ notExist = false;
+ break;
+ }
+
+ if (notExist) {
+ for (int8 i = cnt; i > 0; i--)
+ inventorySetItem(i, inventoryGetItem(i - 1));
+
+ inventorySetItem(0, item);
+
+ setStateValue(StateKey_InventoryItem, item);
+
+ inventorySetCount(cnt + 1);
+ }
+ }
+}
+
+void ScriptManager::inventoryDrop(int16 item) {
+ int8 itemCount = inventoryGetCount();
+
+ // if items in inventory > 0
+ if (itemCount != 0) {
+ int8 index = 0;
+
+ // finding needed item
+ while (index < itemCount) {
+ if (inventoryGetItem(index) == item)
+ break;
+
+ index++;
+ }
+
+ // if item in the inventory
+ if (itemCount != index) {
+ // shift all items left with rewrite founded item
+ for (int8 v = index; v < itemCount - 1 ; v++)
+ inventorySetItem(v, inventoryGetItem(v + 1));
+
+ // del last item
+ inventorySetItem(itemCount - 1, 0);
+ inventorySetCount(inventoryGetCount() - 1);
+
+ setStateValue(StateKey_InventoryItem, inventoryGetItem(0));
+ }
+ }
+}
+void ScriptManager::inventoryCycle() {
+ int8 itemCount = inventoryGetCount();
+ int8 curItem = inventoryGetItem(0);
+ if (itemCount > 1) {
+ for (int8 i = 0; i < itemCount - 1; i++)
+ inventorySetItem(i, inventoryGetItem(i + 1));
+
+ inventorySetItem(itemCount - 1, curItem);
+
+ setStateValue(StateKey_InventoryItem, inventoryGetItem(0));
+
+ }
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/menu.cpp b/engines/zvision/scripting/menu.cpp
new file mode 100644
index 0000000000..e7775cbe3f
--- /dev/null
+++ b/engines/zvision/scripting/menu.cpp
@@ -0,0 +1,761 @@
+/* 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 "zvision/graphics/render_manager.h"
+#include "zvision/scripting/menu.h"
+
+namespace ZVision {
+
+enum {
+ kMainMenuSave = 0,
+ kMainMenuLoad = 1,
+ kMainMenuPrefs = 2,
+ kMainMenuExit = 3
+};
+
+enum {
+ kMenuItem = 0,
+ kMenuMagic = 1,
+ kMenuMain = 2
+};
+
+MenuHandler::MenuHandler(ZVision *engine) {
+ _engine = engine;
+ menuBarFlag = 0xFFFF;
+}
+
+MenuZGI::MenuZGI(ZVision *engine) :
+ MenuHandler(engine) {
+ menuMouseFocus = -1;
+ inmenu = false;
+ scrolled[0] = false;
+ scrolled[1] = false;
+ scrolled[2] = false;
+ scrollPos[0] = 0;
+ scrollPos[1] = 0;
+ scrollPos[2] = 0;
+ mouseOnItem = -1;
+ redraw = false;
+ clean = false;
+
+ 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);
+ sprintf(buf, "gmzau%2.2x1.tga", i + 0x10);
+ _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);
+ sprintf(buf, "gmznu%2.2x1.tga", i);
+ _engine->getRenderManager()->readImageToSurface(buf, menubar[i][1], false);
+ }
+
+ for (int i = 0; i < 50; i++) {
+ items[i][0] = NULL;
+ items[i][1] = NULL;
+ itemId[i] = 0;
+ }
+
+ for (int i = 0; i < 12; i++) {
+ magic[i][0] = NULL;
+ magic[i][1] = NULL;
+ magicId[i] = 0;
+ }
+}
+
+MenuZGI::~MenuZGI() {
+ for (int i = 0; i < 3; i++) {
+ menuback[i][0].free();
+ menuback[i][1].free();
+ }
+ for (int i = 0; i < 4; i++) {
+ menubar[i][0].free();
+ menubar[i][1].free();
+ }
+ for (int i = 0; i < 50; i++) {
+ if (items[i][0]) {
+ items[i][0]->free();
+ delete items[i][0];
+ }
+ if (items[i][1]) {
+ items[i][1]->free();
+ delete items[i][1];
+ }
+ }
+ for (int i = 0; i < 12; i++) {
+ if (magic[i][0]) {
+ magic[i][0]->free();
+ delete magic[i][0];
+ }
+ if (magic[i][1]) {
+ magic[i][1]->free();
+ delete magic[i][1];
+ }
+ }
+}
+
+void MenuZGI::onMouseUp(const Common::Point &Pos) {
+ if (Pos.y < 40) {
+ switch (menuMouseFocus) {
+ case kMenuItem:
+ if (menuBarFlag & kMenubarItems) {
+ int itemCount = _engine->getScriptManager()->getStateValue(StateKey_Inv_TotalSlots);
+ if (itemCount == 0)
+ itemCount = 20;
+
+ for (int i = 0; i < itemCount; i++) {
+ int itemspace = (600 - 28) / itemCount;
+
+ 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(StateKey_Inv_StartSlot + i));
+ _engine->getScriptManager()->setStateValue(StateKey_Inv_StartSlot + i, mouseItem);
+
+ redraw = true;
+ }
+ }
+ }
+ }
+ break;
+
+ case kMenuMagic:
+ if (menuBarFlag & kMenubarMagic) {
+ for (int i = 0; i < 12; i++) {
+
+ uint itemnum = _engine->getScriptManager()->getStateValue(StateKey_Spell_1 + i);
+ if (itemnum != 0) {
+ 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[kMenuMagic], 0,
+ 668 + 47 * i - scrollPos[kMenuMagic] + 28, 32).contains(Pos))
+ _engine->getScriptManager()->setStateValue(StateKey_Active_Spell, itemnum);
+ }
+
+ }
+ break;
+
+ case kMenuMain:
+
+ // Exit
+ if (menuBarFlag & kMenubarExit)
+ if (Common::Rect(320 + 135,
+ scrollPos[kMenuMain],
+ 320 + 135 + 135,
+ scrollPos[kMenuMain] + 32).contains(Pos)) {
+ _engine->ifQuit();
+ }
+
+ // Settings
+ if (menuBarFlag & kMenubarSettings)
+ if (Common::Rect(320 ,
+ scrollPos[kMenuMain],
+ 320 + 135,
+ scrollPos[kMenuMain] + 32).contains(Pos)) {
+ _engine->getScriptManager()->changeLocation('g', 'j', 'p', 'e', 0);
+ }
+
+ // Load
+ if (menuBarFlag & kMenubarRestore)
+ if (Common::Rect(320 - 135,
+ scrollPos[kMenuMain],
+ 320,
+ scrollPos[kMenuMain] + 32).contains(Pos)) {
+ _engine->getScriptManager()->changeLocation('g', 'j', 'r', 'e', 0);
+ }
+
+ // Save
+ if (menuBarFlag & kMenubarSave)
+ if (Common::Rect(320 - 135 * 2,
+ scrollPos[kMenuMain],
+ 320 - 135,
+ scrollPos[kMenuMain] + 32).contains(Pos)) {
+ _engine->getScriptManager()->changeLocation('g', 'j', 's', 'e', 0);
+ }
+ break;
+ }
+ }
+}
+
+void MenuZGI::onMouseMove(const Common::Point &Pos) {
+ if (Pos.y < 40) {
+
+ if (!inmenu)
+ redraw = true;
+ inmenu = true;
+ switch (menuMouseFocus) {
+ case kMenuItem:
+ if (menuBarFlag & kMenubarItems) {
+ int itemCount = _engine->getScriptManager()->getStateValue(StateKey_Inv_TotalSlots);
+ if (itemCount == 0)
+ itemCount = 20;
+ else if (itemCount > 50)
+ itemCount = 50;
+
+ int lastItem = mouseOnItem;
+
+ mouseOnItem = -1;
+
+ for (int i = 0; i < itemCount; i++) {
+ int itemspace = (600 - 28) / itemCount;
+
+ 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(StateKey_Inv_StartSlot + mouseOnItem) ||
+ _engine->getScriptManager()->getStateValue(StateKey_Inv_StartSlot + lastItem))
+ redraw = true;
+ }
+ break;
+
+ case kMenuMagic:
+ if (menuBarFlag & kMenubarMagic) {
+ int lastItem = mouseOnItem;
+ mouseOnItem = -1;
+ for (int i = 0; i < 12; i++) {
+ 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(StateKey_Spell_1 + mouseOnItem) ||
+ _engine->getScriptManager()->getStateValue(StateKey_Spell_1 + lastItem))
+ redraw = true;
+
+ }
+ break;
+
+ case kMenuMain: {
+ int lastItem = mouseOnItem;
+ mouseOnItem = -1;
+
+ // Exit
+ if (menuBarFlag & kMenubarExit)
+ if (Common::Rect(320 + 135,
+ scrollPos[kMenuMain],
+ 320 + 135 + 135,
+ scrollPos[kMenuMain] + 32).contains(Pos)) {
+ mouseOnItem = kMainMenuExit;
+ }
+
+ // Settings
+ if (menuBarFlag & kMenubarSettings)
+ if (Common::Rect(320 ,
+ scrollPos[kMenuMain],
+ 320 + 135,
+ scrollPos[kMenuMain] + 32).contains(Pos)) {
+ mouseOnItem = kMainMenuPrefs;
+ }
+
+ // Load
+ if (menuBarFlag & kMenubarRestore)
+ if (Common::Rect(320 - 135,
+ scrollPos[kMenuMain],
+ 320,
+ scrollPos[kMenuMain] + 32).contains(Pos)) {
+ mouseOnItem = kMainMenuLoad;
+ }
+
+ // Save
+ if (menuBarFlag & kMenubarSave)
+ if (Common::Rect(320 - 135 * 2,
+ scrollPos[kMenuMain],
+ 320 - 135,
+ scrollPos[kMenuMain] + 32).contains(Pos)) {
+ mouseOnItem = kMainMenuSave;
+ }
+
+ if (lastItem != mouseOnItem)
+ redraw = true;
+ }
+ break;
+
+ default:
+ int cur_menu = menuMouseFocus;
+ if (Common::Rect(64, 0, 64 + 512, 8).contains(Pos)) { // Main
+ menuMouseFocus = kMenuMain;
+ scrolled[kMenuMain] = false;
+ scrollPos[kMenuMain] = menuback[kMenuMain][1].h - menuback[kMenuMain][0].h;
+ _engine->getScriptManager()->setStateValue(StateKey_MenuState, 2);
+ }
+
+ if (menuBarFlag & kMenubarMagic)
+ if (Common::Rect(640 - 28, 0, 640, 32).contains(Pos)) { // Magic
+ menuMouseFocus = kMenuMagic;
+ scrolled[kMenuMagic] = false;
+ scrollPos[kMenuMagic] = 28;
+ _engine->getScriptManager()->setStateValue(StateKey_MenuState, 3);
+ }
+
+ if (menuBarFlag & kMenubarItems)
+ if (Common::Rect(0, 0, 28, 32).contains(Pos)) { // Items
+ menuMouseFocus = kMenuItem;
+ scrolled[kMenuItem] = false;
+ scrollPos[kMenuItem] = 28 - 600;
+ _engine->getScriptManager()->setStateValue(StateKey_MenuState, 1);
+ }
+
+ if (cur_menu != menuMouseFocus)
+ clean = true;
+
+ break;
+ }
+ } else {
+ if (inmenu)
+ clean = true;
+ inmenu = false;
+ if (_engine->getScriptManager()->getStateValue(StateKey_MenuState) != 0)
+ _engine->getScriptManager()->setStateValue(StateKey_MenuState, 0);
+ menuMouseFocus = -1;
+ }
+}
+
+void MenuZGI::process(uint32 deltatime) {
+ if (clean) {
+ _engine->getRenderManager()->clearMenuSurface();
+ clean = false;
+ }
+ switch (menuMouseFocus) {
+ case kMenuItem:
+ if (menuBarFlag & kMenubarItems)
+ if (!scrolled[kMenuItem]) {
+ redraw = true;
+ float scrl = 600.0 * (deltatime / 1000.0);
+
+ if (scrl == 0)
+ scrl = 1.0;
+
+ scrollPos[kMenuItem] += (int)scrl;
+
+ if (scrollPos[kMenuItem] >= 0) {
+ scrolled[kMenuItem] = true;
+ scrollPos[kMenuItem] = 0;
+ }
+ }
+ if (redraw) {
+ _engine->getRenderManager()->blitSurfaceToMenu(menuback[kMenuItem][0], scrollPos[kMenuItem], 0);
+
+ int itemCount = _engine->getScriptManager()->getStateValue(StateKey_Inv_TotalSlots);
+ if (itemCount == 0)
+ itemCount = 20;
+ else if (itemCount > 50)
+ itemCount = 50;
+
+ for (int i = 0; i < itemCount; i++) {
+ int itemspace = (600 - 28) / itemCount;
+
+ bool inrect = false;
+
+ if (mouseOnItem == i)
+ inrect = true;
+
+ uint curItemId = _engine->getScriptManager()->getStateValue(StateKey_Inv_StartSlot + i);
+
+ if (curItemId != 0) {
+ if (itemId[i] != curItemId) {
+ char buf[16];
+ sprintf(buf, "gmzwu%2.2x1.tga", curItemId);
+ items[i][0] = _engine->getRenderManager()->loadImage(buf, false);
+ sprintf(buf, "gmzxu%2.2x1.tga", curItemId);
+ items[i][1] = _engine->getRenderManager()->loadImage(buf, false);
+ itemId[i] = curItemId;
+ }
+
+ if (inrect)
+ _engine->getRenderManager()->blitSurfaceToMenu(*items[i][1], scrollPos[kMenuItem] + itemspace * i, 0, 0);
+ else
+ _engine->getRenderManager()->blitSurfaceToMenu(*items[i][0], scrollPos[kMenuItem] + itemspace * i, 0, 0);
+
+ } else {
+ if (items[i][0]) {
+ items[i][0]->free();
+ delete items[i][0];
+ items[i][0] = NULL;
+ }
+ if (items[i][1]) {
+ items[i][1]->free();
+ delete items[i][1];
+ items[i][1] = NULL;
+ }
+ itemId[i] = 0;
+ }
+ }
+
+ redraw = false;
+ }
+ break;
+
+ case kMenuMagic:
+ if (menuBarFlag & kMenubarMagic)
+ if (!scrolled[kMenuMagic]) {
+ redraw = true;
+ float scrl = 600.0 * (deltatime / 1000.0);
+
+ if (scrl == 0)
+ scrl = 1.0;
+
+ scrollPos[kMenuMagic] += (int)scrl;
+
+ if (scrollPos[kMenuMagic] >= 600) {
+ scrolled[kMenuMagic] = true;
+ scrollPos[kMenuMagic] = 600;
+ }
+ }
+ if (redraw) {
+ _engine->getRenderManager()->blitSurfaceToMenu(menuback[kMenuMagic][0], 640 - scrollPos[kMenuMagic], 0);
+
+ for (int i = 0; i < 12; i++) {
+ bool inrect = false;
+
+ if (mouseOnItem == i)
+ inrect = true;
+
+ uint curItemId = _engine->getScriptManager()->getStateValue(StateKey_Spell_1 + i);
+ if (curItemId) {
+ if (_engine->getScriptManager()->getStateValue(StateKey_Reversed_Spellbooc) == 1)
+ curItemId = 0xEE + i;
+ else
+ curItemId = 0xE0 + i;
+ }
+
+ if (curItemId != 0) {
+ if (itemId[i] != curItemId) {
+ char buf[16];
+ sprintf(buf, "gmzwu%2.2x1.tga", curItemId);
+ magic[i][0] = _engine->getRenderManager()->loadImage(buf, false);
+ sprintf(buf, "gmzxu%2.2x1.tga", curItemId);
+ magic[i][1] = _engine->getRenderManager()->loadImage(buf, false);
+ magicId[i] = curItemId;
+ }
+
+ if (inrect)
+ _engine->getRenderManager()->blitSurfaceToMenu(*magic[i][1], 668 + 47 * i - scrollPos[kMenuMagic], 0, 0);
+ else
+ _engine->getRenderManager()->blitSurfaceToMenu(*magic[i][0], 668 + 47 * i - scrollPos[kMenuMagic], 0, 0);
+
+ } else {
+ if (magic[i][0]) {
+ magic[i][0]->free();
+ delete magic[i][0];
+ magic[i][0] = NULL;
+ }
+ if (magic[i][1]) {
+ magic[i][1]->free();
+ delete magic[i][1];
+ magic[i][1] = NULL;
+ }
+ magicId[i] = 0;
+ }
+ }
+ redraw = false;
+ }
+ break;
+
+ case kMenuMain:
+ if (!scrolled[kMenuMain]) {
+ redraw = true;
+ float scrl = 32.0 * 2.0 * (deltatime / 1000.0);
+
+ if (scrl == 0)
+ scrl = 1.0;
+
+ scrollPos[kMenuMain] += (int)scrl;
+
+ if (scrollPos[kMenuMain] >= 0) {
+ scrolled[kMenuMain] = true;
+ scrollPos[kMenuMain] = 0;
+ }
+ }
+ if (redraw) {
+ _engine->getRenderManager()->blitSurfaceToMenu(menuback[kMenuMain][0], 30, scrollPos[kMenuMain]);
+
+ if (menuBarFlag & kMenubarExit) {
+ if (mouseOnItem == kMainMenuExit)
+ _engine->getRenderManager()->blitSurfaceToMenu(menubar[kMainMenuExit][1], 320 + 135, scrollPos[kMenuMain]);
+ else
+ _engine->getRenderManager()->blitSurfaceToMenu(menubar[kMainMenuExit][0], 320 + 135, scrollPos[kMenuMain]);
+ }
+ if (menuBarFlag & kMenubarSettings) {
+ if (mouseOnItem == kMainMenuPrefs)
+ _engine->getRenderManager()->blitSurfaceToMenu(menubar[kMainMenuPrefs][1], 320, scrollPos[kMenuMain]);
+ else
+ _engine->getRenderManager()->blitSurfaceToMenu(menubar[kMainMenuPrefs][0], 320, scrollPos[kMenuMain]);
+ }
+ if (menuBarFlag & kMenubarRestore) {
+ if (mouseOnItem == kMainMenuLoad)
+ _engine->getRenderManager()->blitSurfaceToMenu(menubar[kMainMenuLoad][1], 320 - 135, scrollPos[kMenuMain]);
+ else
+ _engine->getRenderManager()->blitSurfaceToMenu(menubar[kMainMenuLoad][0], 320 - 135, scrollPos[kMenuMain]);
+ }
+ if (menuBarFlag & kMenubarSave) {
+ if (mouseOnItem == kMainMenuSave)
+ _engine->getRenderManager()->blitSurfaceToMenu(menubar[kMainMenuSave][1], 320 - 135 * 2, scrollPos[kMenuMain]);
+ else
+ _engine->getRenderManager()->blitSurfaceToMenu(menubar[kMainMenuSave][0], 320 - 135 * 2, scrollPos[kMenuMain]);
+ }
+ redraw = false;
+ }
+ break;
+ default:
+ if (redraw) {
+ if (inmenu) {
+ _engine->getRenderManager()->blitSurfaceToMenu(menuback[kMenuMain][1], 30, 0);
+
+ if (menuBarFlag & kMenubarItems)
+ _engine->getRenderManager()->blitSurfaceToMenu(menuback[kMenuItem][1], 0, 0);
+
+ if (menuBarFlag & kMenubarMagic)
+ _engine->getRenderManager()->blitSurfaceToMenu(menuback[kMenuMagic][1], 640 - 28, 0);
+ }
+ redraw = false;
+ }
+ break;
+ }
+}
+
+MenuNemesis::MenuNemesis(ZVision *engine) :
+ MenuHandler(engine) {
+ inmenu = false;
+ scrolled = false;
+ scrollPos = 0;
+ mouseOnItem = -1;
+ redraw = false;
+ delay = 0;
+
+ char buf[24];
+ for (int i = 0; i < 4; i++)
+ for (int j = 0; j < 6; j++) {
+ sprintf(buf, "butfrm%d%d.tga", i + 1, j);
+ _engine->getRenderManager()->readImageToSurface(buf, but[i][j], false);
+ }
+
+ _engine->getRenderManager()->readImageToSurface("bar.tga", menubar, false);
+
+ frm = 0;
+}
+
+MenuNemesis::~MenuNemesis() {
+ for (int i = 0; i < 4; i++)
+ for (int j = 0; j < 6; j++)
+ but[i][j].free();
+
+ menubar.free();
+}
+
+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 & kMenubarExit)
+ if (Common::Rect(buts[3][1],
+ scrollPos,
+ buts[3][0] + buts[3][1],
+ scrollPos + 32).contains(Pos)) {
+ _engine->ifQuit();
+ frm = 5;
+ redraw = true;
+ }
+
+ // Settings
+ if (menuBarFlag & kMenubarSettings)
+ if (Common::Rect(buts[2][1],
+ scrollPos,
+ buts[2][0] + buts[2][1],
+ scrollPos + 32).contains(Pos)) {
+ _engine->getScriptManager()->changeLocation('g', 'j', 'p', 'e', 0);
+ frm = 5;
+ redraw = true;
+ }
+
+ // Load
+ if (menuBarFlag & kMenubarRestore)
+ if (Common::Rect(buts[1][1],
+ scrollPos,
+ buts[1][0] + buts[1][1],
+ scrollPos + 32).contains(Pos)) {
+ _engine->getScriptManager()->changeLocation('g', 'j', 'r', 'e', 0);
+ frm = 5;
+ redraw = true;
+ }
+
+ // Save
+ if (menuBarFlag & kMenubarSave)
+ if (Common::Rect(buts[0][1],
+ scrollPos,
+ buts[0][0] + buts[0][1],
+ scrollPos + 32).contains(Pos)) {
+ _engine->getScriptManager()->changeLocation('g', 'j', 's', 'e', 0);
+ frm = 5;
+ redraw = true;
+ }
+ }
+}
+
+void MenuNemesis::onMouseMove(const Common::Point &Pos) {
+ if (Pos.y < 40) {
+
+ inmenu = true;
+
+ if (_engine->getScriptManager()->getStateValue(StateKey_MenuState) != 2)
+ _engine->getScriptManager()->setStateValue(StateKey_MenuState, 2);
+
+ int lastItem = mouseOnItem;
+ mouseOnItem = -1;
+
+ // Exit
+ if (menuBarFlag & kMenubarExit)
+ if (Common::Rect(buts[3][1],
+ scrollPos,
+ buts[3][0] + buts[3][1],
+ scrollPos + 32).contains(Pos)) {
+ mouseOnItem = kMainMenuExit;
+ }
+
+ // Settings
+ if (menuBarFlag & kMenubarSettings)
+ if (Common::Rect(buts[2][1],
+ scrollPos,
+ buts[2][0] + buts[2][1],
+ scrollPos + 32).contains(Pos)) {
+ mouseOnItem = kMainMenuPrefs;
+ }
+
+ // Load
+ if (menuBarFlag & kMenubarRestore)
+ if (Common::Rect(buts[1][1],
+ scrollPos,
+ buts[1][0] + buts[1][1],
+ scrollPos + 32).contains(Pos)) {
+ mouseOnItem = kMainMenuLoad;
+ }
+
+ // Save
+ if (menuBarFlag & kMenubarSave)
+ if (Common::Rect(buts[0][1],
+ scrollPos,
+ buts[0][0] + buts[0][1],
+ scrollPos + 32).contains(Pos)) {
+ mouseOnItem = kMainMenuSave;
+ }
+
+ if (lastItem != mouseOnItem) {
+ redraw = true;
+ frm = 0;
+ delay = 200;
+ }
+ } else {
+ inmenu = false;
+ if (_engine->getScriptManager()->getStateValue(StateKey_MenuState) != 0)
+ _engine->getScriptManager()->setStateValue(StateKey_MenuState, 0);
+ mouseOnItem = -1;
+ }
+}
+
+void MenuNemesis::process(uint32 deltatime) {
+ if (inmenu) {
+ if (!scrolled) {
+ float scrl = 32.0 * 2.0 * (deltatime / 1000.0);
+
+ if (scrl == 0)
+ scrl = 1.0;
+
+ scrollPos += (int)scrl;
+ redraw = true;
+ }
+
+ if (scrollPos >= 0) {
+ scrolled = true;
+ scrollPos = 0;
+ }
+
+ if (mouseOnItem != -1) {
+ delay -= deltatime;
+ if (delay <= 0 && frm < 4) {
+ delay = 200;
+ frm++;
+ redraw = true;
+ }
+ }
+
+ if (redraw) {
+ _engine->getRenderManager()->blitSurfaceToMenu(menubar, 64, scrollPos);
+
+ if (menuBarFlag & kMenubarExit)
+ if (mouseOnItem == kMainMenuExit)
+ _engine->getRenderManager()->blitSurfaceToMenu(but[3][frm], buts[3][1], scrollPos);
+
+ if (menuBarFlag & kMenubarSettings)
+ if (mouseOnItem == kMainMenuPrefs)
+ _engine->getRenderManager()->blitSurfaceToMenu(but[2][frm], buts[2][1], scrollPos);
+
+ if (menuBarFlag & kMenubarRestore)
+ if (mouseOnItem == kMainMenuLoad)
+ _engine->getRenderManager()->blitSurfaceToMenu(but[1][frm], buts[1][1], scrollPos);
+
+ if (menuBarFlag & kMenubarSave)
+ if (mouseOnItem == kMainMenuSave)
+ _engine->getRenderManager()->blitSurfaceToMenu(but[0][frm], buts[0][1], scrollPos);
+
+ redraw = false;
+ }
+ } else {
+ scrolled = false;
+ if (scrollPos > -32) {
+ float scrl = 32.0 * 2.0 * (deltatime / 1000.0);
+
+ if (scrl == 0)
+ scrl = 1.0;
+
+ Common::Rect cl(64, (int16)(32 + scrollPos - scrl), 64 + 512, 32 + scrollPos + 1);
+ _engine->getRenderManager()->clearMenuSurface(cl);
+
+ scrollPos -= (int)scrl;
+ redraw = true;
+ } else
+ scrollPos = -32;
+
+ if (redraw) {
+ _engine->getRenderManager()->blitSurfaceToMenu(menubar, 64, scrollPos);
+ redraw = false;
+ }
+ }
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/menu.h b/engines/zvision/scripting/menu.h
new file mode 100644
index 0000000000..a88587966f
--- /dev/null
+++ b/engines/zvision/scripting/menu.h
@@ -0,0 +1,119 @@
+/* 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_MENU_H
+#define ZVISION_MENU_H
+
+#include "graphics/surface.h"
+#include "common/rect.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+
+namespace ZVision {
+
+enum menuBar {
+ kMenubarExit = 0x1,
+ kMenubarSettings = 0x2,
+ kMenubarRestore = 0x4,
+ kMenubarSave = 0x8,
+ kMenubarItems = 0x100,
+ kMenubarMagic = 0x200
+};
+
+class MenuHandler {
+public:
+ MenuHandler(ZVision *engine);
+ virtual ~MenuHandler() {};
+ virtual void onMouseMove(const Common::Point &Pos) {};
+ virtual void onMouseDown(const Common::Point &Pos) {};
+ virtual void onMouseUp(const Common::Point &Pos) {};
+ virtual void process(uint32 deltaTimeInMillis) {};
+
+ void setEnable(uint16 flags) {
+ menuBarFlag = flags;
+ }
+ uint16 getEnable() {
+ return menuBarFlag;
+ }
+protected:
+ uint16 menuBarFlag;
+ ZVision *_engine;
+};
+
+class MenuZGI: public MenuHandler {
+public:
+ MenuZGI(ZVision *engine);
+ ~MenuZGI();
+ void onMouseMove(const Common::Point &Pos);
+ void onMouseUp(const Common::Point &Pos);
+ void process(uint32 deltaTimeInMillis);
+private:
+ Graphics::Surface menuback[3][2];
+ Graphics::Surface menubar[4][2];
+ Graphics::Surface *items[50][2];
+ uint itemId[50];
+
+ Graphics::Surface *magic[12][2];
+ uint magicId[12];
+
+ int menuMouseFocus;
+ bool inmenu;
+
+ int mouseOnItem;
+
+ bool scrolled[3];
+ int16 scrollPos[3];
+
+ bool clean;
+ bool redraw;
+
+};
+
+class MenuNemesis: public MenuHandler {
+public:
+ MenuNemesis(ZVision *engine);
+ ~MenuNemesis();
+ void onMouseMove(const Common::Point &Pos);
+ void onMouseUp(const Common::Point &Pos);
+ void process(uint32 deltaTimeInMillis);
+private:
+ Graphics::Surface but[4][6];
+ Graphics::Surface menubar;
+
+ bool inmenu;
+
+ int mouseOnItem;
+
+ bool scrolled;
+ int16 scrollPos;
+
+ bool redraw;
+
+ int frm;
+ int16 delay;
+
+};
+
+}
+
+#endif
diff --git a/engines/zvision/scripting/puzzle.h b/engines/zvision/scripting/puzzle.h
index ee9ce521c9..7d64357b0a 100644
--- a/engines/zvision/scripting/puzzle.h
+++ b/engines/zvision/scripting/puzzle.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,11 +28,10 @@
#include "common/list.h"
#include "common/ptr.h"
-
namespace ZVision {
struct Puzzle {
- Puzzle() : key(0) {}
+ Puzzle() : key(0), addedBySetState(false) {}
~Puzzle() {
for (Common::List<ResultAction *>::iterator iter = resultActions.begin(); iter != resultActions.end(); ++iter) {
@@ -63,10 +62,17 @@ struct Puzzle {
bool argumentIsAKey;
};
+ enum StateFlags {
+ ONCE_PER_INST = 0x01,
+ DISABLED = 0x02,
+ DO_ME_NOW = 0x04
+ };
+
uint32 key;
Common::List<Common::List <CriteriaEntry> > criteriaList;
// This has to be list of pointers because ResultAction is abstract
Common::List<ResultAction *> resultActions;
+ bool addedBySetState;
};
} // End of namespace ZVision
diff --git a/engines/zvision/scripting/scr_file_handling.cpp b/engines/zvision/scripting/scr_file_handling.cpp
index 753ce4ac6a..edc1b8622c 100644
--- a/engines/zvision/scripting/scr_file_handling.cpp
+++ b/engines/zvision/scripting/scr_file_handling.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.
@@ -22,33 +22,38 @@
#include "common/scummsys.h"
+#include "zvision/zvision.h"
#include "zvision/scripting/script_manager.h"
-#include "zvision/utility/utility.h"
#include "zvision/scripting/puzzle.h"
#include "zvision/scripting/actions.h"
#include "zvision/scripting/controls/push_toggle_control.h"
#include "zvision/scripting/controls/lever_control.h"
+#include "zvision/scripting/controls/slot_control.h"
+#include "zvision/scripting/controls/save_control.h"
+#include "zvision/scripting/controls/input_control.h"
+#include "zvision/scripting/controls/safe_control.h"
+#include "zvision/scripting/controls/hotmov_control.h"
+#include "zvision/scripting/controls/fist_control.h"
+#include "zvision/scripting/controls/paint_control.h"
+#include "zvision/scripting/controls/titler_control.h"
#include "common/textconsole.h"
#include "common/file.h"
#include "common/tokenizer.h"
-
namespace ZVision {
-void ScriptManager::parseScrFile(const Common::String &fileName, bool isGlobal) {
+void ScriptManager::parseScrFile(const Common::String &fileName, ScriptScope &scope) {
Common::File file;
- if (!file.open(fileName)) {
- warning("Script file not found: %s", fileName.c_str());
- return;
+ if (!_engine->getSearchManager()->openFile(file, fileName)) {
+ error("Script file not found: %s", fileName.c_str());
}
- while(!file.eos()) {
+ 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);
@@ -57,18 +62,19 @@ void ScriptManager::parseScrFile(const Common::String &fileName, bool isGlobal)
if (line.matchString("puzzle:*", true)) {
Puzzle *puzzle = new Puzzle();
- sscanf(line.c_str(),"puzzle:%u",&(puzzle->key));
-
+ sscanf(line.c_str(), "puzzle:%u", &(puzzle->key));
+ if (getStateFlag(puzzle->key) & Puzzle::ONCE_PER_INST)
+ setStateValue(puzzle->key, 0);
parsePuzzle(puzzle, file);
- if (isGlobal) {
- _globalPuzzles.push_back(puzzle);
- } else {
- _activePuzzles.push_back(puzzle);
- }
+ scope.puzzles.push_back(puzzle);
+
} else if (line.matchString("control:*", true)) {
- parseControl(line, file);
+ Control *ctrl = parseControl(line, file);
+ if (ctrl)
+ scope.controls.push_back(ctrl);
}
}
+ scope.procCount = 0;
}
void ScriptManager::parsePuzzle(Puzzle *puzzle, Common::SeekableReadStream &stream) {
@@ -77,23 +83,41 @@ 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)) {
- setStateFlags(puzzle->key, parseFlags(stream));
+ setStateFlag(puzzle->key, parseFlags(stream));
}
line = stream.readLine();
trimCommentsAndWhiteSpace(&line);
}
+
+ 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;
@@ -102,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;
@@ -113,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] == '=')
@@ -124,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;
@@ -148,103 +202,154 @@ void ScriptManager::parseResults(Common::SeekableReadStream &stream, Common::Lis
// Loop until we find the closing brace
Common::String line = stream.readLine();
trimCommentsAndWhiteSpace(&line);
+ line.toLowercase();
// TODO: Re-order the if-then statements in order of highest occurrence
while (!stream.eos() && !line.contains('}')) {
if (line.empty()) {
line = stream.readLine();
trimCommentsAndWhiteSpace(&line);
-
+ line.toLowercase();
continue;
}
- // Parse for the action type
- if (line.matchString("*:add*", true)) {
- actionList.push_back(new ActionAdd(line));
- } else if (line.matchString("*:animplay*", true)) {
- actionList.push_back(new ActionPlayAnimation(line));
- } else if (line.matchString("*:animpreload*", true)) {
- actionList.push_back(new ActionPreloadAnimation(line));
- } else if (line.matchString("*:animunload*", true)) {
- //actionList.push_back(new ActionUnloadAnimation(line));
- } else if (line.matchString("*:attenuate*", true)) {
- // TODO: Implement ActionAttenuate
- } else if (line.matchString("*:assign*", true)) {
- actionList.push_back(new ActionAssign(line));
- } else if (line.matchString("*:change_location*", true)) {
- actionList.push_back(new ActionChangeLocation(line));
- } else if (line.matchString("*:crossfade*", true)) {
- // TODO: Implement ActionCrossfade
- } else if (line.matchString("*:debug*", true)) {
- // TODO: Implement ActionDebug
- } else if (line.matchString("*:delay_render*", true)) {
- // TODO: Implement ActionDelayRender
- } else if (line.matchString("*:disable_control*", true)) {
- actionList.push_back(new ActionDisableControl(line));
- } else if (line.matchString("*:disable_venus*", true)) {
- // TODO: Implement ActionDisableVenus
- } else if (line.matchString("*:display_message*", true)) {
- // TODO: Implement ActionDisplayMessage
- } else if (line.matchString("*:dissolve*", true)) {
- // TODO: Implement ActionDissolve
- } else if (line.matchString("*:distort*", true)) {
- // TODO: Implement ActionDistort
- } else if (line.matchString("*:enable_control*", true)) {
- actionList.push_back(new ActionEnableControl(line));
- } else if (line.matchString("*:flush_mouse_events*", true)) {
- // TODO: Implement ActionFlushMouseEvents
- } else if (line.matchString("*:inventory*", true)) {
- // TODO: Implement ActionInventory
- } else if (line.matchString("*:kill*", true)) {
- // TODO: Implement ActionKill
- } else if (line.matchString("*:menu_bar_enable*", true)) {
- // TODO: Implement ActionMenuBarEnable
- } else if (line.matchString("*:music*", true)) {
- actionList.push_back(new ActionMusic(line));
- } else if (line.matchString("*:pan_track*", true)) {
- // TODO: Implement ActionPanTrack
- } else if (line.matchString("*:playpreload*", true)) {
- actionList.push_back(new ActionPlayPreloadAnimation(line));
- } else if (line.matchString("*:preferences*", true)) {
- // TODO: Implement ActionPreferences
- } else if (line.matchString("*:quit*", true)) {
- actionList.push_back(new ActionQuit());
- } else if (line.matchString("*:random*", true)) {
- actionList.push_back(new ActionRandom(line));
- } else if (line.matchString("*:region*", true)) {
- // TODO: Implement ActionRegion
- } else if (line.matchString("*:restore_game*", true)) {
- // TODO: Implement ActionRestoreGame
- } else if (line.matchString("*:rotate_to*", true)) {
- // TODO: Implement ActionRotateTo
- } else if (line.matchString("*:save_game*", true)) {
- // TODO: Implement ActionSaveGame
- } else if (line.matchString("*:set_partial_screen*", true)) {
- actionList.push_back(new ActionSetPartialScreen(line));
- } else if (line.matchString("*:set_screen*", true)) {
- actionList.push_back(new ActionSetScreen(line));
- } else if (line.matchString("*:set_venus*", true)) {
- // TODO: Implement ActionSetVenus
- } else if (line.matchString("*:stop*", true)) {
- // TODO: Implement ActionStop
- } else if (line.matchString("*:streamvideo*", true)) {
- actionList.push_back(new ActionStreamVideo(line));
- } else if (line.matchString("*:syncsound*", true)) {
- // TODO: Implement ActionSyncSound
- } else if (line.matchString("*:timer*", true)) {
- actionList.push_back(new ActionTimer(line));
- } else if (line.matchString("*:ttytext*", true)) {
- // TODO: Implement ActionTTYText
- } else if (line.matchString("*:universe_music*", true)) {
- // TODO: Implement ActionUniverseMusic
- } else if (line.matchString("*:copy_file*", true)) {
- // Not used. Purposely left empty
- } else {
- warning("Unhandled result action type: %s", line.c_str());
+ const char *chrs = line.c_str();
+ uint pos;
+ for (pos = 0; pos < line.size(); pos++)
+ if (chrs[pos] == ':')
+ break;
+
+ if (pos < line.size()) {
+
+ uint startpos = pos + 1;
+
+ for (pos = startpos; pos < line.size(); pos++)
+ if (chrs[pos] == ':' || chrs[pos] == '(')
+ break;
+
+ if (pos < line.size()) {
+ int32 slot = 11;
+ Common::String args = "";
+ Common::String act(chrs + startpos, chrs + pos);
+
+ startpos = pos + 1;
+
+ if (chrs[pos] == ':') {
+ for (pos = startpos; pos < line.size(); pos++)
+ if (chrs[pos] == '(')
+ break;
+ Common::String strSlot(chrs + startpos, chrs + pos);
+ slot = atoi(strSlot.c_str());
+
+ startpos = pos + 1;
+ }
+
+ if (pos < line.size()) {
+ for (pos = startpos; pos < line.size(); pos++)
+ if (chrs[pos] == ')')
+ break;
+
+ args = Common::String(chrs + startpos, chrs + pos);
+ }
+
+ // Parse for the action type
+ if (act.matchString("add", true)) {
+ actionList.push_back(new ActionAdd(_engine, slot, args));
+ } else if (act.matchString("animplay", true)) {
+ actionList.push_back(new ActionPlayAnimation(_engine, slot, args));
+ } 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));
+ } else if (act.matchString("assign", true)) {
+ actionList.push_back(new ActionAssign(_engine, slot, args));
+ } else if (act.matchString("change_location", true)) {
+ actionList.push_back(new ActionChangeLocation(_engine, slot, args));
+ } else if (act.matchString("crossfade", true)) {
+ actionList.push_back(new ActionCrossfade(_engine, slot, args));
+ } else if (act.matchString("cursor", true)) {
+ actionList.push_back(new ActionCursor(_engine, slot, args));
+ } else if (act.matchString("debug", true)) {
+ // Not used. Purposely left empty
+ } else if (act.matchString("delay_render", true)) {
+ actionList.push_back(new ActionDelayRender(_engine, slot, args));
+ } else if (act.matchString("disable_control", true)) {
+ actionList.push_back(new ActionDisableControl(_engine, slot, args));
+ } else if (act.matchString("disable_venus", true)) {
+ // 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));
+ } else if (act.matchString("flush_mouse_events", true)) {
+ actionList.push_back(new ActionFlushMouseEvents(_engine, slot));
+ } 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));
+ } else if (act.matchString("music", true)) {
+ actionList.push_back(new ActionMusic(_engine, slot, args, false));
+ } else if (act.matchString("pan_track", true)) {
+ actionList.push_back(new ActionPanTrack(_engine, slot, args));
+ } else if (act.matchString("playpreload", true)) {
+ actionList.push_back(new ActionPlayPreloadAnimation(_engine, slot, args));
+ } else if (act.matchString("preferences", true)) {
+ actionList.push_back(new ActionPreferences(_engine, slot, args));
+ } else if (act.matchString("quit", true)) {
+ actionList.push_back(new ActionQuit(_engine, slot));
+ } 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));
+ } else if (act.matchString("save_game", true)) {
+ // Not used. Purposely left empty
+ } else if (act.matchString("set_partial_screen", true)) {
+ actionList.push_back(new ActionSetPartialScreen(_engine, slot, args));
+ } else if (act.matchString("set_screen", true)) {
+ actionList.push_back(new ActionSetScreen(_engine, slot, args));
+ } else if (act.matchString("set_venus", true)) {
+ // 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)) {
+ actionList.push_back(new ActionStreamVideo(_engine, slot, args));
+ } else if (act.matchString("syncsound", true)) {
+ actionList.push_back(new ActionSyncSound(_engine, slot, args));
+ } else if (act.matchString("timer", true)) {
+ actionList.push_back(new ActionTimer(_engine, slot, args));
+ } else if (act.matchString("ttytext", true)) {
+ actionList.push_back(new ActionTtyText(_engine, slot, args));
+ } else if (act.matchString("universe_music", true)) {
+ actionList.push_back(new ActionMusic(_engine, slot, args, true));
+ } else if (act.matchString("copy_file", true)) {
+ // Not used. Purposely left empty
+ } else {
+ warning("Unhandled result action type: %s", line.c_str());
+ }
+ }
}
line = stream.readLine();
trimCommentsAndWhiteSpace(&line);
+ line.toLowercase();
}
return;
@@ -259,11 +364,11 @@ uint ScriptManager::parseFlags(Common::SeekableReadStream &stream) const {
while (!stream.eos() && !line.contains('}')) {
if (line.matchString("ONCE_PER_INST", true)) {
- flags |= ONCE_PER_INST;
+ flags |= Puzzle::ONCE_PER_INST;
} else if (line.matchString("DO_ME_NOW", true)) {
- flags |= DO_ME_NOW;
+ flags |= Puzzle::DO_ME_NOW;
} else if (line.matchString("DISABLED", true)) {
- flags |= DISABLED;
+ flags |= Puzzle::DISABLED;
}
line = stream.readLine();
@@ -273,7 +378,7 @@ uint ScriptManager::parseFlags(Common::SeekableReadStream &stream) const {
return flags;
}
-void ScriptManager::parseControl(Common::String &line, Common::SeekableReadStream &stream) {
+Control *ScriptManager::parseControl(Common::String &line, Common::SeekableReadStream &stream) {
uint32 key;
char controlTypeBuffer[20];
@@ -282,21 +387,53 @@ void ScriptManager::parseControl(Common::String &line, Common::SeekableReadStrea
Common::String controlType(controlTypeBuffer);
if (controlType.equalsIgnoreCase("push_toggle")) {
- _activeControls.push_back(new PushToggleControl(_engine, key, stream));
- return;
+ // 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);
- return;
+ return NULL;
} else if (controlType.equalsIgnoreCase("pana")) {
Control::parsePanoramaControl(_engine, stream);
- return;
+ 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;
+ return NULL;
+ } 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")) {
- _activeControls.push_back(new LeverControl(_engine, key, stream));
- return;
+ // 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;
}
} // End of namespace ZVision
diff --git a/engines/zvision/scripting/script_manager.cpp b/engines/zvision/scripting/script_manager.cpp
index 41b835e550..70eaab2a0a 100644
--- a/engines/zvision/scripting/script_manager.cpp
+++ b/engines/zvision/scripting/script_manager.cpp
@@ -1,24 +1,24 @@
/* 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.
- *
- */
+*
+* 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"
@@ -26,172 +26,254 @@
#include "zvision/zvision.h"
#include "zvision/graphics/render_manager.h"
-#include "zvision/cursors/cursor_manager.h"
-#include "zvision/core/save_manager.h"
+#include "zvision/graphics/cursors/cursor_manager.h"
+#include "zvision/file/save_manager.h"
#include "zvision/scripting/actions.h"
-#include "zvision/utility/utility.h"
+#include "zvision/scripting/menu.h"
+#include "zvision/scripting/effects/timer_effect.h"
#include "common/algorithm.h"
#include "common/hashmap.h"
#include "common/debug.h"
#include "common/stream.h"
-
+#include "common/config-manager.h"
namespace ZVision {
ScriptManager::ScriptManager(ZVision *engine)
: _engine(engine),
- _currentlyFocusedControl(0) {
+ _currentlyFocusedControl(0),
+ _activeControls(NULL) {
}
ScriptManager::~ScriptManager() {
- for (PuzzleList::iterator iter = _activePuzzles.begin(); iter != _activePuzzles.end(); ++iter) {
- delete (*iter);
- }
- for (PuzzleList::iterator iter = _globalPuzzles.begin(); iter != _globalPuzzles.end(); ++iter) {
- delete (*iter);
- }
- for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
- delete (*iter);
- }
+ cleanScriptScope(universe);
+ cleanScriptScope(world);
+ cleanScriptScope(room);
+ cleanScriptScope(nodeview);
+ _controlEvents.clear();
}
void ScriptManager::initialize() {
- parseScrFile("universe.scr", true);
+ cleanScriptScope(universe);
+ cleanScriptScope(world);
+ cleanScriptScope(room);
+ cleanScriptScope(nodeview);
+
+ _currentLocation.node = 0;
+ _currentLocation.world = 0;
+ _currentLocation.room = 0;
+ _currentLocation.view = 0;
+
+ parseScrFile("universe.scr", universe);
changeLocation('g', 'a', 'r', 'y', 0);
+
+ _controlEvents.clear();
}
void ScriptManager::update(uint deltaTimeMillis) {
+ if (_currentLocation != _nextLocation) {
+ ChangeLocationReal(false);
+ }
+
updateNodes(deltaTimeMillis);
- checkPuzzleCriteria();
+ if (!execScope(nodeview)) {
+ return;
+ }
+ if (!execScope(room)) {
+ return;
+ }
+ if (!execScope(world)) {
+ return;
+ }
+ if (!execScope(universe)) {
+ return;
+ }
+ updateControls(deltaTimeMillis);
}
-void ScriptManager::createReferenceTable() {
- // Iterate through each local Puzzle
- for (PuzzleList::iterator activePuzzleIter = _activePuzzles.begin(); activePuzzleIter != _activePuzzles.end(); ++activePuzzleIter) {
- Puzzle *puzzlePtr = (*activePuzzleIter);
+bool ScriptManager::execScope(ScriptScope &scope) {
+ // Swap queues
+ PuzzleList *tmp = scope.execQueue;
+ scope.execQueue = scope.scopeQueue;
+ scope.scopeQueue = tmp;
+ scope.scopeQueue->clear();
- // Iterate through each CriteriaEntry and add a reference from the criteria key to the Puzzle
- for (Common::List<Common::List<Puzzle::CriteriaEntry> >::iterator criteriaIter = (*activePuzzleIter)->criteriaList.begin(); criteriaIter != (*activePuzzleIter)->criteriaList.end(); ++criteriaIter) {
- for (Common::List<Puzzle::CriteriaEntry>::iterator entryIter = criteriaIter->begin(); entryIter != criteriaIter->end(); ++entryIter) {
- _referenceTable[entryIter->key].push_back(puzzlePtr);
+ for (PuzzleList::iterator PuzzleIter = scope.puzzles.begin(); PuzzleIter != scope.puzzles.end(); ++PuzzleIter) {
+ (*PuzzleIter)->addedBySetState = false;
+ }
- // If the argument is a key, add a reference to it as well
- if (entryIter->argumentIsAKey) {
- _referenceTable[entryIter->argument].push_back(puzzlePtr);
- }
+ if (scope.procCount < 2 || getStateValue(StateKey_ExecScopeStyle)) {
+ 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)) {
+ return false;
}
}
}
- // Iterate through each global Puzzle
- for (PuzzleList::iterator globalPuzzleIter = _globalPuzzles.begin(); globalPuzzleIter != _globalPuzzles.end(); ++globalPuzzleIter) {
- Puzzle *puzzlePtr = (*globalPuzzleIter);
-
- // Iterate through each CriteriaEntry and add a reference from the criteria key to the Puzzle
- for (Common::List<Common::List<Puzzle::CriteriaEntry> >::iterator criteriaIter = (*globalPuzzleIter)->criteriaList.begin(); criteriaIter != (*globalPuzzleIter)->criteriaList.end(); ++criteriaIter) {
- for (Common::List<Puzzle::CriteriaEntry>::iterator entryIter = criteriaIter->begin(); entryIter != criteriaIter->end(); ++entryIter) {
- _referenceTable[entryIter->key].push_back(puzzlePtr);
+ if (scope.procCount < 2) {
+ scope.procCount++;
+ }
+ return true;
+}
- // If the argument is a key, add a reference to it as well
- if (entryIter->argumentIsAKey) {
- _referenceTable[entryIter->argument].push_back(puzzlePtr);
- }
+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) {
+ return;
}
}
}
- // Remove duplicate entries
- for (PuzzleMap::iterator referenceTableIter = _referenceTable.begin(); referenceTableIter != _referenceTable.end(); ++referenceTableIter) {
- removeDuplicateEntries(referenceTableIter->_value);
+ _referenceTable[key].push_back(ref);
+}
+
+void ScriptManager::addPuzzlesToReferenceTable(ScriptScope &scope) {
+ // Iterate through each local Puzzle
+ for (PuzzleList::iterator PuzzleIter = scope.puzzles.begin(); PuzzleIter != scope.puzzles.end(); ++PuzzleIter) {
+ Puzzle *puzzlePtr = (*PuzzleIter);
+
+ PuzzleRef ref;
+ ref.scope = &scope;
+ ref.puz = puzzlePtr;
+
+ 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) {
+ referenceTableAddPuzzle(entryIter->key, ref);
+ }
+ }
}
}
void ScriptManager::updateNodes(uint deltaTimeMillis) {
// If process() returns true, it means the node can be deleted
- for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end();) {
+ for (SideFXList::iterator iter = _activeSideFx.begin(); iter != _activeSideFx.end();) {
if ((*iter)->process(deltaTimeMillis)) {
- delete (*iter);
+ delete(*iter);
// Remove the node
- iter = _activeControls.erase(iter);
+ iter = _activeSideFx.erase(iter);
} else {
++iter;
}
}
}
-void ScriptManager::checkPuzzleCriteria() {
- while (!_puzzlesToCheck.empty()) {
- Puzzle *puzzle = _puzzlesToCheck.pop();
+void ScriptManager::updateControls(uint deltaTimeMillis) {
+ if (!_activeControls) {
+ return;
+ }
- // Check if the puzzle is already finished
- // Also check that the puzzle isn't disabled
- if (getStateValue(puzzle->key) == 1 && (getStateFlags(puzzle->key) & DISABLED) == 0) {
- continue;
+ // Process only one event
+ if (!_controlEvents.empty()) {
+ Common::Event _event = _controlEvents.front();
+ Common::Point imageCoord;
+ switch (_event.type) {
+ case Common::EVENT_LBUTTONDOWN:
+ imageCoord = _engine->getRenderManager()->screenSpaceToImageSpace(_event.mouse);
+ onMouseDown(_event.mouse, imageCoord);
+ break;
+ case Common::EVENT_LBUTTONUP:
+ imageCoord = _engine->getRenderManager()->screenSpaceToImageSpace(_event.mouse);
+ onMouseUp(_event.mouse, imageCoord);
+ break;
+ case Common::EVENT_KEYDOWN:
+ onKeyDown(_event.kbd);
+ break;
+ case Common::EVENT_KEYUP:
+ onKeyUp(_event.kbd);
+ break;
+ default:
+ break;
}
+ _controlEvents.pop_front();
+ }
+
+ for (ControlList::iterator iter = _activeControls->begin(); iter != _activeControls->end(); iter++) {
+ if ((*iter)->process(deltaTimeMillis)) {
+ break;
+ }
+ }
+}
- // Check each Criteria
+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)) {
+ return true;
+ }
- bool criteriaMet = false;
- for (Common::List<Common::List<Puzzle::CriteriaEntry> >::iterator criteriaIter = puzzle->criteriaList.begin(); criteriaIter != puzzle->criteriaList.end(); ++criteriaIter) {
- criteriaMet = false;
+ // Check each Criteria
+ if (counter == 0 && (getStateFlag(puzzle->key) & Puzzle::DO_ME_NOW) == 0) {
+ return true;
+ }
- for (Common::List<Puzzle::CriteriaEntry>::iterator entryIter = criteriaIter->begin(); entryIter != criteriaIter->end(); ++entryIter) {
- // Get the value to compare against
- uint argumentValue;
- if (entryIter->argumentIsAKey)
- argumentValue = getStateValue(entryIter->argument);
- else
- argumentValue = entryIter->argument;
-
- // Do the comparison
- switch (entryIter->criteriaOperator) {
- case Puzzle::EQUAL_TO:
- criteriaMet = getStateValue(entryIter->key) == argumentValue;
- break;
- case Puzzle::NOT_EQUAL_TO:
- criteriaMet = getStateValue(entryIter->key) != argumentValue;
- break;
- case Puzzle::GREATER_THAN:
- criteriaMet = getStateValue(entryIter->key) > argumentValue;
- break;
- case Puzzle::LESS_THAN:
- criteriaMet = getStateValue(entryIter->key) < argumentValue;
- break;
- }
-
- // If one check returns false, don't keep checking
- if (!criteriaMet) {
- break;
- }
+ bool criteriaMet = false;
+ for (Common::List<Common::List<Puzzle::CriteriaEntry> >::iterator criteriaIter = puzzle->criteriaList.begin(); criteriaIter != puzzle->criteriaList.end(); ++criteriaIter) {
+ criteriaMet = false;
+
+ for (Common::List<Puzzle::CriteriaEntry>::iterator entryIter = criteriaIter->begin(); entryIter != criteriaIter->end(); ++entryIter) {
+ // Get the value to compare against
+ int argumentValue;
+ if (entryIter->argumentIsAKey) {
+ argumentValue = getStateValue(entryIter->argument);
+ } else {
+ argumentValue = entryIter->argument;
+ }
+
+ // Do the comparison
+ switch (entryIter->criteriaOperator) {
+ case Puzzle::EQUAL_TO:
+ criteriaMet = getStateValue(entryIter->key) == argumentValue;
+ break;
+ case Puzzle::NOT_EQUAL_TO:
+ criteriaMet = getStateValue(entryIter->key) != argumentValue;
+ break;
+ case Puzzle::GREATER_THAN:
+ criteriaMet = getStateValue(entryIter->key) > argumentValue;
+ break;
+ case Puzzle::LESS_THAN:
+ criteriaMet = getStateValue(entryIter->key) < argumentValue;
+ break;
}
- // If any of the Criteria are *fully* met, then execute the results
- if (criteriaMet) {
+ // If one check returns false, don't keep checking
+ if (!criteriaMet) {
break;
}
}
- // criteriaList can be empty. Aka, the puzzle should be executed immediately
- if (puzzle->criteriaList.empty() || criteriaMet) {
- debug(1, "Puzzle %u criteria passed. Executing its ResultActions", puzzle->key);
+ // If any of the Criteria are *fully* met, then execute the results
+ if (criteriaMet) {
+ break;
+ }
+ }
- // Set the puzzle as completed
- setStateValue(puzzle->key, 1);
+ // criteriaList can be empty. Aka, the puzzle should be executed immediately
+ if (puzzle->criteriaList.empty() || criteriaMet) {
+ debug(1, "Puzzle %u criteria passed. Executing its ResultActions", puzzle->key);
- bool shouldContinue = true;
- for (Common::List<ResultAction *>::iterator resultIter = puzzle->resultActions.begin(); resultIter != puzzle->resultActions.end(); ++resultIter) {
- shouldContinue = shouldContinue && (*resultIter)->execute(_engine);
- if (!shouldContinue) {
- break;
- }
- }
+ // Set the puzzle as completed
+ setStateValue(puzzle->key, 1);
- if (!shouldContinue) {
- break;
+ for (Common::List<ResultAction *>::iterator resultIter = puzzle->resultActions.begin(); resultIter != puzzle->resultActions.end(); ++resultIter) {
+ if (!(*resultIter)->execute()) {
+ return false;
}
}
}
+
+ return true;
}
void ScriptManager::cleanStateTable() {
@@ -205,52 +287,102 @@ void ScriptManager::cleanStateTable() {
}
}
-uint ScriptManager::getStateValue(uint32 key) {
- if (_globalState.contains(key))
+void ScriptManager::cleanScriptScope(ScriptScope &scope) {
+ scope.privQueueOne.clear();
+ scope.privQueueTwo.clear();
+ scope.scopeQueue = &scope.privQueueOne;
+ scope.execQueue = &scope.privQueueTwo;
+ 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) {
+ delete(*iter);
+ }
+
+ scope.controls.clear();
+
+ scope.procCount = 0;
+}
+
+int ScriptManager::getStateValue(uint32 key) {
+ if (_globalState.contains(key)) {
return _globalState[key];
- else
+ } else {
return 0;
+ }
}
-void ScriptManager::setStateValue(uint32 key, uint value) {
- _globalState[key] = value;
-
+void ScriptManager::queuePuzzles(uint32 key) {
if (_referenceTable.contains(key)) {
- for (Common::Array<Puzzle *>::iterator iter = _referenceTable[key].begin(); iter != _referenceTable[key].end(); ++iter) {
- _puzzlesToCheck.push((*iter));
+ Common::Array<PuzzleRef> *arr = &_referenceTable[key];
+ 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;
+ }
}
}
}
-uint ScriptManager::getStateFlags(uint32 key) {
- if (_globalStateFlags.contains(key))
+void ScriptManager::setStateValue(uint32 key, int value) {
+ if (value == 0) {
+ _globalState.erase(key);
+ } else {
+ _globalState[key] = value;
+ }
+
+ queuePuzzles(key);
+}
+
+void ScriptManager::setStateValueSilent(uint32 key, int value) {
+ if (value == 0) {
+ _globalState.erase(key);
+ } else {
+ _globalState[key] = value;
+ }
+}
+
+uint ScriptManager::getStateFlag(uint32 key) {
+ if (_globalStateFlags.contains(key)) {
return _globalStateFlags[key];
- else
+ } else {
return 0;
+ }
}
-void ScriptManager::setStateFlags(uint32 key, uint flags) {
- _globalStateFlags[key] = flags;
+void ScriptManager::setStateFlag(uint32 key, uint value) {
+ queuePuzzles(key);
- if (_referenceTable.contains(key)) {
- for (Common::Array<Puzzle *>::iterator iter = _referenceTable[key].begin(); iter != _referenceTable[key].end(); ++iter) {
- _puzzlesToCheck.push((*iter));
- }
- }
+ _globalStateFlags[key] |= value;
}
-void ScriptManager::addToStateValue(uint32 key, uint valueToAdd) {
- _globalState[key] += valueToAdd;
+void ScriptManager::setStateFlagSilent(uint32 key, uint value) {
+ if (value == 0) {
+ _globalStateFlags.erase(key);
+ } else {
+ _globalStateFlags[key] = value;
+ }
}
-void ScriptManager::addControl(Control *control) {
- _activeControls.push_back(control);
+void ScriptManager::unsetStateFlag(uint32 key, uint value) {
+ queuePuzzles(key);
+
+ if (_globalStateFlags.contains(key)) {
+ _globalStateFlags[key] &= ~value;
+
+ if (_globalStateFlags[key] == 0) {
+ _globalStateFlags.erase(key);
+ }
+ }
}
Control *ScriptManager::getControl(uint32 key) {
- for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
+ for (ControlList::iterator iter = _activeControls->begin(); iter != _activeControls->end(); ++iter) {
if ((*iter)->getKey() == key) {
- return (*iter);
+ return *iter;
}
}
@@ -258,9 +390,15 @@ Control *ScriptManager::getControl(uint32 key) {
}
void ScriptManager::focusControl(uint32 key) {
- for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
+ if (!_activeControls) {
+ return;
+ }
+ if (_currentlyFocusedControl == key) {
+ return;
+ }
+ for (ControlList::iterator iter = _activeControls->begin(); iter != _activeControls->end(); ++iter) {
uint32 controlKey = (*iter)->getKey();
-
+
if (controlKey == key) {
(*iter)->focus();
} else if (controlKey == _currentlyFocusedControl) {
@@ -271,167 +409,415 @@ void ScriptManager::focusControl(uint32 key) {
_currentlyFocusedControl = key;
}
+void ScriptManager::setFocusControlKey(uint32 key) {
+ _currentlyFocusedControl = key;
+}
+
+void ScriptManager::addSideFX(ScriptingEffect *fx) {
+ _activeSideFx.push_back(fx);
+}
+
+ScriptingEffect *ScriptManager::getSideFX(uint32 key) {
+ for (SideFXList::iterator iter = _activeSideFx.begin(); iter != _activeSideFx.end(); ++iter) {
+ if ((*iter)->getKey() == key) {
+ return (*iter);
+ }
+ }
+
+ return nullptr;
+}
+
+void ScriptManager::deleteSideFx(uint32 key) {
+ for (SideFXList::iterator iter = _activeSideFx.begin(); iter != _activeSideFx.end(); ++iter) {
+ if ((*iter)->getKey() == key) {
+ delete(*iter);
+ _activeSideFx.erase(iter);
+ break;
+ }
+ }
+}
+
+void ScriptManager::stopSideFx(uint32 key) {
+ for (SideFXList::iterator iter = _activeSideFx.begin(); iter != _activeSideFx.end(); ++iter) {
+ if ((*iter)->getKey() == key) {
+ bool ret = (*iter)->stop();
+ if (ret) {
+ delete(*iter);
+ _activeSideFx.erase(iter);
+ }
+ break;
+ }
+ }
+}
+
+void ScriptManager::killSideFx(uint32 key) {
+ for (SideFXList::iterator iter = _activeSideFx.begin(); iter != _activeSideFx.end(); ++iter) {
+ if ((*iter)->getKey() == key) {
+ (*iter)->kill();
+ delete(*iter);
+ _activeSideFx.erase(iter);
+ break;
+ }
+ }
+}
+
+void ScriptManager::killSideFxType(ScriptingEffect::ScriptingEffectType type) {
+ for (SideFXList::iterator iter = _activeSideFx.begin(); iter != _activeSideFx.end();) {
+ if ((*iter)->getType() & type) {
+ (*iter)->kill();
+ delete(*iter);
+ iter = _activeSideFx.erase(iter);
+ } else {
+ ++iter;
+ }
+ }
+}
+
void ScriptManager::onMouseDown(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
- for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
- (*iter)->onMouseDown(screenSpacePos, backgroundImageSpacePos);
+ if (!_activeControls) {
+ return;
+ }
+ for (ControlList::iterator iter = _activeControls->reverse_begin(); iter != _activeControls->end(); iter--) {
+ if ((*iter)->onMouseDown(screenSpacePos, backgroundImageSpacePos)) {
+ return;
+ }
}
}
void ScriptManager::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
- for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
- (*iter)->onMouseUp(screenSpacePos, backgroundImageSpacePos);
+ if (!_activeControls) {
+ return;
+ }
+ for (ControlList::iterator iter = _activeControls->reverse_begin(); iter != _activeControls->end(); iter--) {
+ if ((*iter)->onMouseUp(screenSpacePos, backgroundImageSpacePos)) {
+ return;
+ }
}
}
bool ScriptManager::onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
- bool cursorWasChanged = false;
- for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
- cursorWasChanged = cursorWasChanged || (*iter)->onMouseMove(screenSpacePos, backgroundImageSpacePos);
+ if (!_activeControls) {
+ return false;
}
- return cursorWasChanged;
+ for (ControlList::iterator iter = _activeControls->reverse_begin(); iter != _activeControls->end(); iter--) {
+ if ((*iter)->onMouseMove(screenSpacePos, backgroundImageSpacePos)) {
+ return true;
+ }
+ }
+
+ return false;
}
void ScriptManager::onKeyDown(Common::KeyState keyState) {
- for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
- (*iter)->onKeyDown(keyState);
+ if (!_activeControls) {
+ return;
+ }
+ for (ControlList::iterator iter = _activeControls->begin(); iter != _activeControls->end(); ++iter) {
+ if ((*iter)->onKeyDown(keyState)) {
+ return;
+ }
}
}
void ScriptManager::onKeyUp(Common::KeyState keyState) {
- for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
- (*iter)->onKeyUp(keyState);
+ if (!_activeControls) {
+ return;
+ }
+ for (ControlList::iterator iter = _activeControls->begin(); iter != _activeControls->end(); ++iter) {
+ if ((*iter)->onKeyUp(keyState)) {
+ return;
+ }
}
}
-void ScriptManager::changeLocation(char world, char room, char node, char view, uint32 offset) {
- assert(world != 0);
- debug(1, "Changing location to: %c %c %c %c %u", world, room, node, view, offset);
+void ScriptManager::changeLocation(const Location &_newLocation) {
+ changeLocation(_newLocation.world, _newLocation.room, _newLocation.node, _newLocation.view, _newLocation.offset);
+}
- // Auto save
- _engine->getSaveManager()->autoSave();
+void ScriptManager::changeLocation(char _world, char _room, char _node, char _view, uint32 offset) {
+ _nextLocation.world = _world;
+ _nextLocation.room = _room;
+ _nextLocation.node = _node;
+ _nextLocation.view = _view;
+ _nextLocation.offset = offset;
+ // 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);
+ _nextLocation.node = getStateValue(StateKey_LastNode);
+ _nextLocation.view = getStateValue(StateKey_LastView);
+ _nextLocation.offset = getStateValue(StateKey_LastViewPos);
+ } else {
+ _nextLocation.world = getStateValue(StateKey_Menu_LastWorld);
+ _nextLocation.room = getStateValue(StateKey_Menu_LastRoom);
+ _nextLocation.node = getStateValue(StateKey_Menu_LastNode);
+ _nextLocation.view = getStateValue(StateKey_Menu_LastView);
+ _nextLocation.offset = getStateValue(StateKey_Menu_LastViewPos);
+ }
+ }
+}
- // Clear all the containers
- _referenceTable.clear();
- _puzzlesToCheck.clear();
- for (PuzzleList::iterator iter = _activePuzzles.begin(); iter != _activePuzzles.end(); ++iter) {
- delete (*iter);
+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);
+
+ 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 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;
+
+ return;
+ } else {
+ _currentLocation.world = 'g';
+ _currentLocation.room = '0';
+ _currentLocation.node = '0';
+ _currentLocation.view = '0';
+ _currentLocation.offset = 0;
+ }
+ }
}
- _activePuzzles.clear();
- for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
- delete (*iter);
+
+ _engine->setRenderDelay(2);
+
+ if (!leavingMenu) {
+ if (!isLoading && !enteringMenu) {
+ setStateValue(StateKey_LastWorld, getStateValue(StateKey_World));
+ setStateValue(StateKey_LastRoom, getStateValue(StateKey_Room));
+ setStateValue(StateKey_LastNode, getStateValue(StateKey_Node));
+ setStateValue(StateKey_LastView, getStateValue(StateKey_View));
+ setStateValue(StateKey_LastViewPos, getStateValue(StateKey_ViewPos));
+ } else {
+ setStateValue(StateKey_Menu_LastWorld, getStateValue(StateKey_World));
+ setStateValue(StateKey_Menu_LastRoom, getStateValue(StateKey_Room));
+ setStateValue(StateKey_Menu_LastNode, getStateValue(StateKey_Node));
+ setStateValue(StateKey_Menu_LastView, getStateValue(StateKey_View));
+ setStateValue(StateKey_Menu_LastViewPos, getStateValue(StateKey_ViewPos));
+ }
}
- _activeControls.clear();
- // Revert to the idle cursor
- _engine->getCursorManager()->revertToIdle();
+ if (enteringMenu) {
+ if (isSaveScreen && !leavingMenu) {
+ _engine->getSaveManager()->prepareSaveBuffer();
+ }
+ } else {
+ if (leavingMenu) {
+ _engine->getSaveManager()->flushSaveBuffer();
+ }
+ }
- // Reset the background velocity
- _engine->getRenderManager()->setBackgroundVelocity(0);
+ setStateValue(StateKey_World, _nextLocation.world);
+ setStateValue(StateKey_Room, _nextLocation.room);
+ setStateValue(StateKey_Node, _nextLocation.node);
+ setStateValue(StateKey_View, _nextLocation.view);
+ setStateValue(StateKey_ViewPos, _nextLocation.offset);
- // Remove any alphaEntries
- _engine->getRenderManager()->clearAlphaEntries();
+ _referenceTable.clear();
+ addPuzzlesToReferenceTable(universe);
- // Clean the global state table
- cleanStateTable();
+ _engine->getMenuHandler()->setEnable(0xFFFF);
- // Parse into puzzles and controls
- Common::String fileName = Common::String::format("%c%c%c%c.scr", world, room, node, view);
- parseScrFile(fileName);
+ if (_nextLocation.world != _currentLocation.world) {
+ cleanScriptScope(nodeview);
+ cleanScriptScope(room);
+ cleanScriptScope(world);
- // Change the background position
- _engine->getRenderManager()->setBackgroundPosition(offset);
+ Common::String fileName = Common::String::format("%c%c%c%c.scr", _nextLocation.world, _nextLocation.room, _nextLocation.node, _nextLocation.view);
+ parseScrFile(fileName, nodeview);
+ addPuzzlesToReferenceTable(nodeview);
- // Enable all the controls
- for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
- (*iter)->enable();
+ fileName = Common::String::format("%c%c.scr", _nextLocation.world, _nextLocation.room);
+ parseScrFile(fileName, room);
+ addPuzzlesToReferenceTable(room);
+
+ fileName = Common::String::format("%c.scr", _nextLocation.world);
+ parseScrFile(fileName, world);
+ addPuzzlesToReferenceTable(world);
+ } else if (_nextLocation.room != _currentLocation.room) {
+ cleanScriptScope(nodeview);
+ cleanScriptScope(room);
+
+ addPuzzlesToReferenceTable(world);
+
+ Common::String fileName = Common::String::format("%c%c%c%c.scr", _nextLocation.world, _nextLocation.room, _nextLocation.node, _nextLocation.view);
+ parseScrFile(fileName, nodeview);
+ addPuzzlesToReferenceTable(nodeview);
+
+ fileName = Common::String::format("%c%c.scr", _nextLocation.world, _nextLocation.room);
+ parseScrFile(fileName, room);
+ addPuzzlesToReferenceTable(room);
+
+ } else if (_nextLocation.node != _currentLocation.node || _nextLocation.view != _currentLocation.view) {
+ cleanScriptScope(nodeview);
+
+ addPuzzlesToReferenceTable(room);
+ addPuzzlesToReferenceTable(world);
+
+ Common::String fileName = Common::String::format("%c%c%c%c.scr", _nextLocation.world, _nextLocation.room, _nextLocation.node, _nextLocation.view);
+ parseScrFile(fileName, nodeview);
+ addPuzzlesToReferenceTable(nodeview);
}
- // Add all the local puzzles to the queue to be checked
- for (PuzzleList::iterator iter = _activePuzzles.begin(); iter != _activePuzzles.end(); ++iter) {
- // Reset any Puzzles that have the flag ONCE_PER_INST
- if ((getStateFlags((*iter)->key) & ONCE_PER_INST) == ONCE_PER_INST) {
- setStateValue((*iter)->key, 0);
- }
+ _activeControls = &nodeview.controls;
+
+ // Revert to the idle cursor
+ _engine->getCursorManager()->changeCursor(CursorIndex_Idle);
- _puzzlesToCheck.push((*iter));
+ // Change the background position
+ _engine->getRenderManager()->setBackgroundPosition(_nextLocation.offset);
+
+ if (_currentLocation == "0000") {
+ _currentLocation = _nextLocation;
+ execScope(world);
+ execScope(room);
+ execScope(nodeview);
+ } else if (_nextLocation.world != _currentLocation.world) {
+ _currentLocation = _nextLocation;
+ execScope(room);
+ execScope(nodeview);
+ } else if (_nextLocation.room != _currentLocation.room) {
+ _currentLocation = _nextLocation;
+ execScope(room);
+ execScope(nodeview);
+ } else if (_nextLocation.node != _currentLocation.node || _nextLocation.view != _currentLocation.view) {
+ _currentLocation = _nextLocation;
+ execScope(nodeview);
}
- // Add all the global puzzles to the queue to be checked
- for (PuzzleList::iterator iter = _globalPuzzles.begin(); iter != _globalPuzzles.end(); ++iter) {
- // Reset any Puzzles that have the flag ONCE_PER_INST
- if ((getStateFlags((*iter)->key) & ONCE_PER_INST) == ONCE_PER_INST) {
- setStateValue((*iter)->key, 0);
- }
+ _engine->getRenderManager()->checkBorders();
+}
- _puzzlesToCheck.push((*iter));
+void ScriptManager::serialize(Common::WriteStream *stream) {
+ stream->writeUint32BE(MKTAG('Z', 'N', 'S', 'G'));
+ stream->writeUint32LE(4);
+ stream->writeUint32LE(0);
+ stream->writeUint32BE(MKTAG('L', 'O', 'C', ' '));
+ stream->writeUint32LE(8);
+ stream->writeByte(getStateValue(StateKey_World));
+ stream->writeByte(getStateValue(StateKey_Room));
+ stream->writeByte(getStateValue(StateKey_Node));
+ stream->writeByte(getStateValue(StateKey_View));
+ stream->writeUint32LE(getStateValue(StateKey_ViewPos));
+
+ for (SideFXList::iterator iter = _activeSideFx.begin(); iter != _activeSideFx.end(); ++iter) {
+ (*iter)->serialize(stream);
}
- // Create the puzzle reference table
- createReferenceTable();
+ stream->writeUint32BE(MKTAG('F', 'L', 'A', 'G'));
- // Update _currentLocation
- _currentLocation.world = world;
- _currentLocation.room = room;
- _currentLocation.node = node;
- _currentLocation.view = view;
- _currentLocation.offset = offset;
-}
+ int32 slots = 20000;
+ if (_engine->getGameId() == GID_NEMESIS) {
+ slots = 30000;
+ }
-void ScriptManager::serializeStateTable(Common::WriteStream *stream) {
- // Write the number of state value entries
- stream->writeUint32LE(_globalState.size());
+ stream->writeUint32LE(slots * 2);
- for (StateMap::iterator iter = _globalState.begin(); iter != _globalState.end(); ++iter) {
- // Write out the key/value pair
- stream->writeUint32LE(iter->_key);
- stream->writeUint32LE(iter->_value);
+ 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++) {
+ stream->writeSint16LE(getStateValue(i));
}
}
-void ScriptManager::deserializeStateTable(Common::SeekableReadStream *stream) {
+void ScriptManager::deserialize(Common::SeekableReadStream *stream) {
// Clear out the current table values
_globalState.clear();
+ _globalStateFlags.clear();
- // Read the number of key/value pairs
- uint32 numberOfPairs = stream->readUint32LE();
+ cleanScriptScope(nodeview);
+ cleanScriptScope(room);
+ cleanScriptScope(world);
- for (uint32 i = 0; i < numberOfPairs; ++i) {
- uint32 key = stream->readUint32LE();
- uint32 value = stream->readUint32LE();
- // Directly access the state table so we don't trigger Puzzle checks
- _globalState[key] = value;
- }
-}
+ _currentLocation.node = 0;
+ _currentLocation.world = 0;
+ _currentLocation.room = 0;
+ _currentLocation.view = 0;
-void ScriptManager::serializeControls(Common::WriteStream *stream) {
- // Count how many controls need to save their data
- // Because WriteStream isn't seekable
- uint32 numberOfControlsNeedingSerialization = 0;
- for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
- if ((*iter)->needsSerialization()) {
- numberOfControlsNeedingSerialization++;
- }
+ for (SideFXList::iterator iter = _activeSideFx.begin(); iter != _activeSideFx.end(); iter++) {
+ delete(*iter);
}
- stream->writeUint32LE(numberOfControlsNeedingSerialization);
- for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
- (*iter)->serialize(stream);
+ _activeSideFx.clear();
+
+ _referenceTable.clear();
+
+ if (stream->readUint32BE() != MKTAG('Z', 'N', 'S', 'G') || stream->readUint32LE() != 4) {
+ changeLocation('g', 'a', 'r', 'y', 0);
+ return;
}
-}
-void ScriptManager::deserializeControls(Common::SeekableReadStream *stream) {
- uint32 numberOfControls = stream->readUint32LE();
+ stream->seek(4, SEEK_CUR);
- for (uint32 i = 0; i < numberOfControls; ++i) {
- uint32 key = stream->readUint32LE();
- for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
- if ((*iter)->getKey() == key) {
- (*iter)->deserialize(stream);
- break;
+ if (stream->readUint32BE() != MKTAG('L', 'O', 'C', ' ') || stream->readUint32LE() != 8) {
+ changeLocation('g', 'a', 'r', 'y', 0);
+ return;
+ }
+
+ Location nextLocation;
+
+ nextLocation.world = stream->readByte();
+ nextLocation.room = stream->readByte();
+ nextLocation.node = stream->readByte();
+ nextLocation.view = stream->readByte();
+ nextLocation.offset = stream->readUint32LE() & 0x0000FFFF;
+
+ while (stream->pos() < stream->size()) {
+ uint32 tag = stream->readUint32BE();
+ uint32 tagSize = stream->readUint32LE();
+ switch (tag) {
+ case MKTAG('T', 'I', 'M', 'R'): {
+ uint32 key = stream->readUint32LE();
+ uint32 time = stream->readUint32LE();
+ if (_engine->getGameId() == GID_GRANDINQUISITOR) {
+ time /= 100;
+ } 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++) {
+ setStateFlagSilent(i, stream->readUint16LE());
+ }
+ break;
+ case MKTAG('P', 'U', 'Z', 'Z'):
+ for (uint32 i = 0; i < tagSize / 2; i++) {
+ setStateValueSilent(i, stream->readUint16LE());
}
+ break;
+ default:
+ stream->seek(tagSize, SEEK_CUR);
}
}
+
+ _nextLocation = nextLocation;
+
+ ChangeLocationReal(true);
+
+ _engine->setRenderDelay(10);
+ setStateValue(StateKey_RestoreFlag, 1);
+
+ _engine->loadSettings();
}
Location ScriptManager::getCurrentLocation() const {
@@ -441,4 +827,78 @@ Location ScriptManager::getCurrentLocation() const {
return location;
}
+Location ScriptManager::getLastLocation() {
+ Location location;
+ location.world = getStateValue(StateKey_LastWorld);
+ location.room = getStateValue(StateKey_LastRoom);
+ location.node = getStateValue(StateKey_LastNode);
+ location.view = getStateValue(StateKey_LastView);
+ location.offset = getStateValue(StateKey_LastViewPos);
+
+ return location;
+}
+
+Location ScriptManager::getLastMenuLocation() {
+ Location location;
+ location.world = getStateValue(StateKey_Menu_LastWorld);
+ location.room = getStateValue(StateKey_Menu_LastRoom);
+ location.node = getStateValue(StateKey_Menu_LastNode);
+ location.view = getStateValue(StateKey_Menu_LastView);
+ location.offset = getStateValue(StateKey_Menu_LastViewPos);
+
+ return location;
+}
+
+void ScriptManager::addEvent(Common::Event event) {
+ _controlEvents.push_back(event);
+}
+
+void ScriptManager::flushEvent(Common::EventType type) {
+ EventList::iterator it = _controlEvents.begin();
+ while (it != _controlEvents.end()) {
+
+ if ((*it).type == type) {
+ it = _controlEvents.erase(it);
+ } else {
+ it++;
+ }
+ }
+}
+
+void ScriptManager::trimCommentsAndWhiteSpace(Common::String *string) const {
+ for (int i = string->size() - 1; i >= 0; i--) {
+ if ((*string)[i] == '#') {
+ string->erase(i);
+ }
+ }
+
+ string->trim();
+}
+
+ValueSlot::ValueSlot(ScriptManager *scriptManager, const char *slotValue):
+ _scriptManager(scriptManager) {
+ value = 0;
+ slot = false;
+ const char *isSlot = strstr(slotValue, "[");
+ if (isSlot) {
+ slot = true;
+ value = atoi(isSlot + 1);
+ } else {
+ slot = false;
+ value = atoi(slotValue);
+ }
+}
+int16 ValueSlot::getValue() {
+ if (slot) {
+ if (value >= 0) {
+ return _scriptManager->getStateValue(value);
+ }
+ else {
+ return 0;
+ }
+ } else {
+ return value;
+ }
+}
+
} // End of namespace ZVision
diff --git a/engines/zvision/scripting/script_manager.h b/engines/zvision/scripting/script_manager.h
index 4d1b1f359b..7c276bf917 100644
--- a/engines/zvision/scripting/script_manager.h
+++ b/engines/zvision/scripting/script_manager.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.
@@ -25,10 +25,11 @@
#include "zvision/scripting/puzzle.h"
#include "zvision/scripting/control.h"
+#include "zvision/scripting/scripting_effect.h"
#include "common/hashmap.h"
#include "common/queue.h"
-
+#include "common/events.h"
namespace Common {
class String;
@@ -39,6 +40,69 @@ namespace ZVision {
class ZVision;
+enum StateKey {
+ StateKey_World = 3,
+ StateKey_Room = 4,
+ StateKey_Node = 5,
+ StateKey_View = 6,
+ StateKey_ViewPos = 7,
+ StateKey_KeyPress = 8,
+ StateKey_InventoryItem = 9,
+ StateKey_LMouse = 10,
+ StateKey_NotSet = 11, // This key doesn't set
+ StateKey_Rounds = 12,
+ StateKey_Venus = 13,
+ StateKey_RMouse = 18,
+ StateKey_MenuState = 19,
+ StateKey_RestoreFlag = 20,
+ StateKey_Quitting = 39,
+ StateKey_LastWorld = 40,
+ StateKey_LastRoom = 41,
+ StateKey_LastNode = 42,
+ StateKey_LastView = 43,
+ StateKey_LastViewPos = 44,
+ StateKey_Menu_LastWorld = 45,
+ StateKey_Menu_LastRoom = 46,
+ StateKey_Menu_LastNode = 47,
+ StateKey_Menu_LastView = 48,
+ StateKey_Menu_LastViewPos = 49,
+ StateKey_KbdRotateSpeed = 50,
+ StateKey_Subtitles = 51,
+ StateKey_StreamSkipKey = 52,
+ StateKey_RotateSpeed = 53,
+ StateKey_Volume = 56,
+ StateKey_Qsound = 57,
+ StateKey_VenusEnable = 58,
+ StateKey_HighQuality = 59,
+ StateKey_VideoLineSkip = 65,
+ StateKey_Platform = 66,
+ StateKey_InstallLevel = 67,
+ StateKey_CountryCode = 68,
+ StateKey_CPU = 69,
+ StateKey_MovieCursor = 70,
+ StateKey_NoTurnAnim = 71,
+ StateKey_WIN958 = 72,
+ StateKey_ShowErrorDlg = 73,
+ StateKey_DebugCheats = 74,
+ StateKey_JapanFonts = 75,
+ StateKey_ExecScopeStyle = 76,
+ StateKey_Brightness = 77,
+ StateKey_MPEGMovies = 78,
+ StateKey_EF9_R = 91,
+ StateKey_EF9_G = 92,
+ StateKey_EF9_B = 93,
+ StateKey_EF9_Speed = 94,
+ StateKey_Inv_Cnt_Slot = 100,
+ StateKey_Inv_1_Slot = 101,
+ StateKey_Inv_49_Slot = 149,
+ // ZGI only
+ StateKey_Inv_TotalSlots = 150,
+ StateKey_Inv_StartSlot = 151,
+ StateKey_Spell_1 = 191,
+ StateKey_Active_Spell = 205,
+ StateKey_Reversed_Spellbooc = 206
+};
+
struct Location {
Location() : world('g'), room('a'), node('r'), view('y'), offset(0) {}
@@ -49,68 +113,121 @@ struct Location {
uint32 offset;
};
-typedef Common::HashMap<uint32, Common::Array<Puzzle *> > PuzzleMap;
+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, uint32> StateMap;
-typedef Common::HashMap<uint32, uint> StateFlagMap;
+typedef Common::HashMap<uint32, int32> StateMap;
+typedef Common::List<ScriptingEffect *> SideFXList;
+typedef Common::List<Common::Event> EventList;
class ScriptManager {
public:
ScriptManager(ZVision *engine);
~ScriptManager();
-public:
- enum StateFlags {
- ONCE_PER_INST = 0x01,
- DO_ME_NOW = 0x02, // Somewhat useless flag since anything that needs to be done immediately has no criteria
- DISABLED = 0x04
- };
-
private:
ZVision *_engine;
+
+ struct ScriptScope {
+ uint32 procCount;
+
+ PuzzleList *scopeQueue; // For adding puzzles to queue
+ PuzzleList *execQueue; // Switch to it when execute
+ PuzzleList privQueueOne;
+ PuzzleList privQueueTwo;
+
+ PuzzleList puzzles;
+ ControlList controls;
+ };
+
+ struct PuzzleRef {
+ Puzzle *puz;
+ ScriptScope *scope;
+ };
+
+ typedef Common::HashMap<uint32, Common::Array<PuzzleRef> > PuzzleMap;
+
/**
* Holds the global state variable. Do NOT directly modify this. Use the accessors and
* mutators getStateValue() and setStateValue(). This ensures that Puzzles that reference a
* particular state key are checked after the key is modified.
*/
StateMap _globalState;
- /**
- * Holds the flags for the global states. This is used to enable/disable puzzles and/or
- * controls as well as which puzzles should are allowed to be re-executed
- */
- StateFlagMap _globalStateFlags;
+ /** Holds execute flags */
+ StateMap _globalStateFlags;
/** References _globalState keys to Puzzles */
PuzzleMap _referenceTable;
- /** Holds the Puzzles that should be checked this frame */
- PuzzleQueue _puzzlesToCheck;
- /** Holds the currently active puzzles */
- PuzzleList _activePuzzles;
- /** Holds the global puzzles */
- PuzzleList _globalPuzzles;
/** Holds the currently active controls */
- ControlList _activeControls;
+ ControlList *_activeControls;
+
+ EventList _controlEvents;
+
+ ScriptScope universe;
+ ScriptScope world;
+ ScriptScope room;
+ ScriptScope nodeview;
+
+ /** Holds the currently active timers, musics, other */
+ SideFXList _activeSideFx;
Location _currentLocation;
+ Location _nextLocation;
uint32 _currentlyFocusedControl;
public:
void initialize();
void update(uint deltaTimeMillis);
+ void queuePuzzles(uint32 key);
- uint getStateValue(uint32 key);
- void setStateValue(uint32 key, uint value);
- void addToStateValue(uint32 key, uint valueToAdd);
+ int getStateValue(uint32 key);
+ void setStateValue(uint32 key, int value);
- uint getStateFlags(uint32 key);
- void setStateFlags(uint32 key, uint flags);
+ uint getStateFlag(uint32 key);
+ void setStateFlag(uint32 key, uint value);
+ void unsetStateFlag(uint32 key, uint value);
void addControl(Control *control);
Control *getControl(uint32 key);
+ void enableControl(uint32 key);
+ void disableControl(uint32 key);
+
void focusControl(uint32 key);
+ // Only change focus control without call focus/unfocus.
+ void setFocusControlKey(uint32 key);
+
+ void addSideFX(ScriptingEffect *fx);
+ ScriptingEffect *getSideFX(uint32 key);
+ void deleteSideFx(uint32 key);
+ void stopSideFx(uint32 key);
+ void killSideFx(uint32 key);
+ void killSideFxType(ScriptingEffect::ScriptingEffectType type);
+
+ void addEvent(Common::Event);
+ void flushEvent(Common::EventType type);
/**
* Called when LeftMouse is pushed.
@@ -147,32 +264,61 @@ public:
*/
void onKeyUp(Common::KeyState keyState);
+ /** Mark next location */
void changeLocation(char world, char room, char node, char view, uint32 offset);
+ void changeLocation(const Location &_newLocation);
- void serializeStateTable(Common::WriteStream *stream);
- void deserializeStateTable(Common::SeekableReadStream *stream);
- void serializeControls(Common::WriteStream *stream);
- void deserializeControls(Common::SeekableReadStream *stream);
+ void serialize(Common::WriteStream *stream);
+ void deserialize(Common::SeekableReadStream *stream);
Location getCurrentLocation() const;
+ Location getLastLocation();
+ Location getLastMenuLocation();
+
+ /**
+ * Removes any line comments using '#' as a sequence start.
+ * Then removes any trailing and leading 'whitespace' using String::trim()
+ * Note: String::trim uses isspace() to determine what is whitespace and what is not.
+ *
+ * @param string The string to modify. It is modified in place
+ */
+ void trimCommentsAndWhiteSpace(Common::String *string) const;
private:
- void createReferenceTable();
+ void referenceTableAddPuzzle(uint32 key, PuzzleRef ref);
+ void addPuzzlesToReferenceTable(ScriptScope &scope);
void updateNodes(uint deltaTimeMillis);
- void checkPuzzleCriteria();
+ void updateControls(uint deltaTimeMillis);
+ bool checkPuzzleCriteria(Puzzle *puzzle, uint counter);
void cleanStateTable();
+ void cleanScriptScope(ScriptScope &scope);
+ bool execScope(ScriptScope &scope);
+
+ /** Perform change location */
+ void ChangeLocationReal(bool isLoading);
+
+ int8 inventoryGetCount();
+ void inventorySetCount(int8 cnt);
+ int16 inventoryGetItem(int8 id);
+ void inventorySetItem(int8 id, int16 item);
+
+ void setStateFlagSilent(uint32 key, uint value);
+ void setStateValueSilent(uint32 key, int value);
-// TODO: Make this private. It was only made public so Console::cmdParseAllScrFiles() could use it
public:
+ void inventoryAdd(int16 item);
+ void inventoryDrop(int16 item);
+ void inventoryCycle();
+
+private:
/**
* Parses a script file into triggers and events
*
* @param fileName Name of the .scr file
* @param isGlobal Are the puzzles included in the file global (true). AKA, the won't be purged during location changes
*/
- void parseScrFile(const Common::String &fileName, bool isGlobal = false);
+ void parseScrFile(const Common::String &fileName, ScriptScope &scope);
-private:
/**
* Parses the stream into a Puzzle object
* Helper method for parseScrFile.
@@ -188,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
@@ -216,9 +363,18 @@ private:
* @param line The line initially read
* @param stream Scr file stream
*/
- void parseControl(Common::String &line, Common::SeekableReadStream &stream);
+ Control *parseControl(Common::String &line, Common::SeekableReadStream &stream);
};
+class ValueSlot {
+public:
+ ValueSlot(ScriptManager *scriptManager, const char *slotValue);
+ int16 getValue();
+private:
+ int16 value;
+ bool slot;
+ ScriptManager *_scriptManager;
+};
} // End of namespace ZVision
diff --git a/engines/zvision/scripting/scripting_effect.h b/engines/zvision/scripting/scripting_effect.h
new file mode 100644
index 0000000000..2a2153204f
--- /dev/null
+++ b/engines/zvision/scripting/scripting_effect.h
@@ -0,0 +1,124 @@
+/* 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 SCRIPTING_EFFECT_H_INCLUDED
+#define SCRIPTING_EFFECT_H_INCLUDED
+
+namespace Common {
+class SeekableReadStream;
+struct Point;
+class WriteStream;
+}
+
+namespace ZVision {
+
+class ZVision;
+
+/**
+ * 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 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
+ };
+
+ 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;
+ }
+ ScriptingEffectType getType() {
+ return _type;
+ }
+
+ virtual bool process(uint32 deltaTimeInMillis) {
+ return false;
+ }
+ /**
+ * Serialize a SideFX for save game use. This should only be used if a SideFX needs
+ * to save values that would be different from initialization. AKA a TimerNode needs to
+ * store the amount of time left on the timer. Any Controls overriding this *MUST* write
+ * their key as the first data outputted. The default implementation is NOP.
+ *
+ * NOTE: If this method is overridden, you MUST also override deserialize()
+ * and needsSerialization()
+ *
+ * @param stream Stream to write any needed data to
+ */
+ virtual void serialize(Common::WriteStream *stream) {}
+ /**
+ * De-serialize data from a save game stream. This should only be implemented if the
+ * SideFX also implements serialize(). The calling method assumes the size of the
+ * data read from the stream exactly equals that written in serialize(). The default
+ * implementation is NOP.
+ *
+ * NOTE: If this method is overridden, you MUST also override serialize()
+ * and needsSerialization()
+ *
+ * @param stream Save game file stream
+ */
+ virtual void deserialize(Common::SeekableReadStream *stream) {}
+ /**
+ * If a SideFX overrides serialize() and deserialize(), this should return true
+ *
+ * @return Does the SideFX need save game serialization?
+ */
+ virtual inline bool needsSerialization() {
+ return false;
+ }
+
+ virtual bool stop() {
+ return true;
+ }
+ virtual void kill() {}
+
+protected:
+ ZVision *_engine;
+ uint32 _key;
+ ScriptingEffectType _type;
+
+// Static member functions
+public:
+
+};
+} // End of namespace ZVision
+
+#endif // SCRIPTING_EFFECT_H_INCLUDED
diff --git a/engines/zvision/sound/midi.cpp b/engines/zvision/sound/midi.cpp
new file mode 100644
index 0000000000..3dd66ff2d4
--- /dev/null
+++ b/engines/zvision/sound/midi.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 "common/scummsys.h"
+#include "common/textconsole.h"
+
+#include "zvision/sound/midi.h"
+
+namespace ZVision {
+
+MidiManager::MidiManager() {
+ MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB);
+ _driver = MidiDriver::createMidi(dev);
+ if (_driver->open())
+ warning("Can't open MIDI, no MIDI output!");
+}
+
+MidiManager::~MidiManager() {
+ stop();
+ _driver->close();
+ delete _driver;
+}
+
+void MidiManager::stop() {
+ for (int8 i = 0; i < 16; i++)
+ if (_playChannels[i].playing)
+ noteOff(i);
+}
+
+void MidiManager::noteOn(int8 channel, int8 note, int8 velocity) {
+ assert(channel <= 15);
+
+ _playChannels[channel].playing = true;
+ _playChannels[channel].note = note;
+ _driver->send(channel | (velocity << 16) | (note << 8) | 0x90);
+}
+
+void MidiManager::noteOff(int8 channel) {
+ assert(channel <= 15);
+
+ if (_playChannels[channel].playing) {
+ _playChannels[channel].playing = false;
+ _driver->send(channel | (_playChannels[channel].note << 8) | 0x80);
+ }
+}
+
+int8 MidiManager::getFreeChannel() {
+ for (int8 i = 0; i < 16; i++)
+ if (!_playChannels[i].playing)
+ return i;
+ return -1;
+}
+
+void MidiManager::setPan(int8 channel, int8 pan) {
+ assert(channel <= 15);
+
+ _driver->send(channel | (pan << 16) | 0xAB0);
+}
+
+void MidiManager::setVolume(int8 channel, int8 volume) {
+ assert(channel <= 15);
+
+ _driver->send(channel | (volume << 16) | 0x7B0);
+}
+
+void MidiManager::setProgram(int8 channel, int8 prog) {
+ assert(channel <= 15);
+
+ _driver->send(channel | (prog << 8) | 0xC0);
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/sound/midi.h b/engines/zvision/sound/midi.h
new file mode 100644
index 0000000000..a3bac19636
--- /dev/null
+++ b/engines/zvision/sound/midi.h
@@ -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.
+ *
+ */
+
+#ifndef ZVISION_MIDI_H
+#define ZVISION_MIDI_H
+
+#include "audio/mididrv.h"
+
+namespace ZVision {
+
+class MidiManager {
+public:
+ MidiManager();
+ ~MidiManager();
+
+ void stop();
+ void noteOn(int8 channel, int8 noteNumber, int8 velocity);
+ void noteOff(int8 channel);
+ void setPan(int8 channel, int8 pan);
+ void setVolume(int8 channel, int8 volume);
+ void setProgram(int8 channel, int8 prog);
+
+ int8 getFreeChannel();
+
+protected:
+
+ struct chan {
+ bool playing;
+ int8 note;
+
+ chan() : playing(false), note(0) {};
+ };
+
+ MidiDriver *_driver;
+ chan _playChannels[16];
+};
+
+}
+
+#endif
diff --git a/engines/zvision/sound/zork_raw.cpp b/engines/zvision/sound/zork_raw.cpp
index edee1fd16e..7bdd4875fc 100644
--- a/engines/zvision/sound/zork_raw.cpp
+++ b/engines/zvision/sound/zork_raw.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,85 +21,78 @@
*/
#include "common/scummsys.h"
-
-#include "zvision/sound/zork_raw.h"
-
-#include "zvision/zvision.h"
-#include "zvision/detection.h"
-#include "zvision/utility/utility.h"
-
#include "common/file.h"
#include "common/str.h"
#include "common/stream.h"
#include "common/memstream.h"
#include "common/bufferedstream.h"
#include "common/util.h"
-
+#include "common/tokenizer.h"
#include "audio/audiostream.h"
#include "audio/decoders/raw.h"
+#include "zvision/sound/zork_raw.h"
+#include "zvision/zvision.h"
+#include "zvision/detection.h"
namespace ZVision {
-const int16 RawZorkStream::_stepAdjustmentTable[8] = {-1, -1, -1, 1, 4, 7, 10, 12};
-
-const int32 RawZorkStream::_amplitudeLookupTable[89] = {0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E,
- 0x0010, 0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001C, 0x001F,
- 0x0022, 0x0025, 0x0029, 0x002D, 0x0032, 0x0037, 0x003C, 0x0042,
- 0x0049, 0x0050, 0x0058, 0x0061, 0x006B, 0x0076, 0x0082, 0x008F,
- 0x009D, 0x00AD, 0x00BE, 0x00D1, 0x00E6, 0x00FD, 0x0117, 0x0133,
- 0x0151, 0x0173, 0x0198, 0x01C1, 0x01EE, 0x0220, 0x0256, 0x0292,
- 0x02D4, 0x031C, 0x036C, 0x03C3, 0x0424, 0x048E, 0x0502, 0x0583,
- 0x0610, 0x06AB, 0x0756, 0x0812, 0x08E0, 0x09C3, 0x0ABD, 0x0BD0,
- 0x0CFF, 0x0E4C, 0x0FBA, 0x114C, 0x1307, 0x14EE, 0x1706, 0x1954,
- 0x1BDC, 0x1EA5, 0x21B6, 0x2515, 0x28CA, 0x2CDF, 0x315B, 0x364B,
- 0x3BB9, 0x41B2, 0x4844, 0x4F7E, 0x5771, 0x602F, 0x69CE, 0x7462, 0x7FFF};
-
-const SoundParams RawZorkStream::_zNemSoundParamLookupTable[6] = {{'6', 0x2B11, false, false},
- {'a', 0x5622, false, true},
- {'b', 0x5622, true, true},
- {'n', 0x2B11, false, true},
- {'s', 0x5622, false, true},
- {'t', 0x5622, true, true}
-};
-
-const SoundParams RawZorkStream::_zgiSoundParamLookupTable[5] = {{'a',0x5622, false, false},
- {'k',0x2B11, true, true},
- {'p',0x5622, false, true},
- {'q',0x5622, true, true},
- {'u',0xAC44, true, true}
-};
-
-RawZorkStream::RawZorkStream(uint32 rate, bool stereo, DisposeAfterUse::Flag disposeStream, Common::SeekableReadStream *stream)
- : _rate(rate),
- _stereo(0),
- _stream(stream, disposeStream),
- _endOfData(false) {
+const int16 RawChunkStream::_stepAdjustmentTable[8] = { -1, -1, -1, 1, 4, 7, 10, 12};
+
+const int32 RawChunkStream::_amplitudeLookupTable[89] = {0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E,
+ 0x0010, 0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001C, 0x001F,
+ 0x0022, 0x0025, 0x0029, 0x002D, 0x0032, 0x0037, 0x003C, 0x0042,
+ 0x0049, 0x0050, 0x0058, 0x0061, 0x006B, 0x0076, 0x0082, 0x008F,
+ 0x009D, 0x00AD, 0x00BE, 0x00D1, 0x00E6, 0x00FD, 0x0117, 0x0133,
+ 0x0151, 0x0173, 0x0198, 0x01C1, 0x01EE, 0x0220, 0x0256, 0x0292,
+ 0x02D4, 0x031C, 0x036C, 0x03C3, 0x0424, 0x048E, 0x0502, 0x0583,
+ 0x0610, 0x06AB, 0x0756, 0x0812, 0x08E0, 0x09C3, 0x0ABD, 0x0BD0,
+ 0x0CFF, 0x0E4C, 0x0FBA, 0x114C, 0x1307, 0x14EE, 0x1706, 0x1954,
+ 0x1BDC, 0x1EA5, 0x21B6, 0x2515, 0x28CA, 0x2CDF, 0x315B, 0x364B,
+ 0x3BB9, 0x41B2, 0x4844, 0x4F7E, 0x5771, 0x602F, 0x69CE, 0x7462, 0x7FFF
+ };
+
+RawChunkStream::RawChunkStream(bool stereo) {
if (stereo)
_stereo = 1;
+ else
+ _stereo = 0;
+ init();
+}
+
+void RawChunkStream::init() {
_lastSample[0].index = 0;
_lastSample[0].sample = 0;
_lastSample[1].index = 0;
_lastSample[1].sample = 0;
+}
- // Calculate the total playtime of the stream
- if (stereo)
- _playtime = Audio::Timestamp(0, _stream->size() / 2, rate);
- else
- _playtime = Audio::Timestamp(0, _stream->size(), rate);
+RawChunkStream::RawChunk RawChunkStream::readNextChunk(Common::SeekableReadStream *stream) {
+ RawChunk tmp;
+ tmp.size = 0;
+ tmp.data = NULL;
+
+ if (!stream || stream->size() == 0 || stream->eos())
+ return tmp;
+
+ tmp.size = (stream->size() - stream->pos()) * 2;
+ tmp.data = (int16 *)calloc(tmp.size, 1);
+
+ readBuffer(tmp.data, stream, stream->size() - stream->pos());
+
+ return tmp;
}
-int RawZorkStream::readBuffer(int16 *buffer, const int numSamples) {
- int bytesRead = 0;
+int RawChunkStream::readBuffer(int16 *buffer, Common::SeekableReadStream *stream, const int numSamples) {
+ int32 bytesRead = 0;
// 0: Left, 1: Right
uint channel = 0;
while (bytesRead < numSamples) {
- byte encodedSample = _stream->readByte();
- if (_stream->eos()) {
- _endOfData = true;
+ byte encodedSample = stream->readByte();
+ if (stream->eos()) {
return bytesRead;
}
bytesRead++;
@@ -140,6 +133,90 @@ int RawZorkStream::readBuffer(int16 *buffer, const int numSamples) {
// Increment and wrap the channel
channel = (channel + 1) & _stereo;
}
+ return bytesRead;
+}
+
+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},
+ {'4', 0x2B11, false, false, false},
+ {'5', 0x2B11, true, false, false},
+ {'6', 0x2B11, false, false, true},
+ {'7', 0x2B11, true, false, true},
+ {'8', 0x5622, false, false, false},
+ {'9', 0x5622, true, false, false},
+ {'a', 0x5622, false, false, true},
+ {'b', 0x5622, true, false, true},
+ {'c', 0xAC44, false, false, false},
+ {'d', 0xAC44, true, false, false},
+ {'e', 0xAC44, false, false, true},
+ {'f', 0xAC44, true, false, true},
+ {'g', 0x1F40, false, true, false},
+ {'h', 0x1F40, true, true, false},
+ {'j', 0x1F40, false, true, true},
+ {'k', 0x1F40, true, true, true},
+ {'l', 0x2B11, false, true, false},
+ {'m', 0x2B11, true, true, false},
+ {'n', 0x2B11, false, true, true},
+ {'p', 0x2B11, true, true, true},
+ {'q', 0x5622, false, true, false},
+ {'r', 0x5622, true, true, false},
+ {'s', 0x5622, false, true, true},
+ {'t', 0x5622, true, true, true},
+ {'u', 0xAC44, false, true, false},
+ {'v', 0xAC44, true, true, false},
+ {'w', 0xAC44, false, true, true},
+ {'x', 0xAC44, true, true, true}
+};
+
+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},
+ {'8', 0x5622, false, false, false},
+ {'9', 0x5622, true, false, false},
+ {'a', 0x5622, false, false, true},
+ {'b', 0x5622, true, false, true},
+ {'c', 0xAC44, false, false, false},
+ {'d', 0xAC44, true, false, false},
+ {'e', 0xAC44, false, false, true},
+ {'f', 0xAC44, true, false, true},
+ {'g', 0x2B11, false, true, false},
+ {'h', 0x2B11, true, true, false},
+ {'j', 0x2B11, false, true, true},
+ {'k', 0x2B11, true, true, true},
+ {'m', 0x5622, false, true, false},
+ {'n', 0x5622, true, true, false},
+ {'p', 0x5622, false, true, true},
+ {'q', 0x5622, true, true, true},
+ {'r', 0xAC44, false, true, false},
+ {'s', 0xAC44, true, true, false},
+ {'t', 0xAC44, false, true, true},
+ {'u', 0xAC44, true, true, true}
+};
+
+RawZorkStream::RawZorkStream(uint32 rate, bool stereo, DisposeAfterUse::Flag disposeStream, Common::SeekableReadStream *stream)
+ : _rate(rate),
+ _stereo(0),
+ _stream(stream, disposeStream),
+ _endOfData(false),
+ _streamReader(stereo) {
+ if (stereo)
+ _stereo = 1;
+
+ // Calculate the total playtime of the stream
+ if (stereo)
+ _playtime = Audio::Timestamp(0, _stream->size() / 2, rate);
+ else
+ _playtime = Audio::Timestamp(0, _stream->size(), rate);
+}
+
+int RawZorkStream::readBuffer(int16 *buffer, const int numSamples) {
+ int32 bytesRead = _streamReader.readBuffer(buffer, _stream.get(), numSamples);
+
+ if (_stream->eos())
+ _endOfData = true;
return bytesRead;
}
@@ -148,69 +225,78 @@ bool RawZorkStream::rewind() {
_stream->seek(0, 0);
_stream->clearErr();
_endOfData = false;
- _lastSample[0].index = 0;
- _lastSample[0].sample = 0;
- _lastSample[1].index = 0;
- _lastSample[1].sample = 0;
+ _streamReader.init();
return true;
}
Audio::RewindableAudioStream *makeRawZorkStream(Common::SeekableReadStream *stream,
- int rate,
- bool stereo,
- DisposeAfterUse::Flag disposeAfterUse) {
+ int rate,
+ bool stereo,
+ DisposeAfterUse::Flag disposeAfterUse) {
if (stereo)
assert(stream->size() % 2 == 0);
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(file->open(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(actualName, "/\\");
+ Common::String fileName;
+ while (!tokenizer.empty()) {
+ fileName = tokenizer.nextToken();
+ }
- Common::String fileName = getFileName(filePath);
fileName.toLowercase();
- SoundParams soundParams = { ' ', 0, false, false };
- bool foundParams = false;
- char fileIdentifier = (engine->getGameId() == GID_NEMESIS) ? fileName[6] : fileName[7];
+ const SoundParams *soundParams = NULL;
if (engine->getGameId() == GID_NEMESIS) {
- for (uint i = 0; i < ARRAYSIZE(RawZorkStream::_zNemSoundParamLookupTable); ++i) {
- if (RawZorkStream::_zNemSoundParamLookupTable[i].identifier == fileIdentifier) {
- soundParams = RawZorkStream::_zNemSoundParamLookupTable[i];
- foundParams = true;
- }
+ for (int i = 0; i < 32; ++i) {
+ if (RawZorkStream::_zNemSoundParamLookupTable[i].identifier == (fileName[6]))
+ soundParams = &RawZorkStream::_zNemSoundParamLookupTable[i];
}
} else if (engine->getGameId() == GID_GRANDINQUISITOR) {
- for (uint i = 0; i < ARRAYSIZE(RawZorkStream::_zgiSoundParamLookupTable); ++i) {
- if (RawZorkStream::_zgiSoundParamLookupTable[i].identifier == fileIdentifier) {
- soundParams = RawZorkStream::_zgiSoundParamLookupTable[i];
- foundParams = true;
- }
+ for (int i = 0; i < 24; ++i) {
+ if (RawZorkStream::_zgiSoundParamLookupTable[i].identifier == (fileName[7]))
+ soundParams = &RawZorkStream::_zgiSoundParamLookupTable[i];
}
}
- if (!foundParams)
- error("Unable to find sound params for file '%s'. File identifier is '%c'", filePath.c_str(), fileIdentifier);
+ if (soundParams == NULL)
+ return NULL;
- if (soundParams.packed) {
- return makeRawZorkStream(wrapBufferedSeekableReadStream(file, 2048, DisposeAfterUse::YES), soundParams.rate, soundParams.stereo, DisposeAfterUse::YES);
+ if (soundParams->packed) {
+ return makeRawZorkStream(wrapBufferedSeekableReadStream(file, 2048, DisposeAfterUse::YES), soundParams->rate, soundParams->stereo, DisposeAfterUse::YES);
} else {
byte flags = 0;
- if (soundParams.stereo)
+ if (soundParams->bits16)
+ flags |= Audio::FLAG_16BITS | Audio::FLAG_LITTLE_ENDIAN;
+ if (soundParams->stereo)
flags |= Audio::FLAG_STEREO;
- return Audio::makeRawStream(file, soundParams.rate, flags, DisposeAfterUse::YES);
+ return Audio::makeRawStream(file, soundParams->rate, flags, DisposeAfterUse::YES);
}
}
diff --git a/engines/zvision/sound/zork_raw.h b/engines/zvision/sound/zork_raw.h
index ef98e3e1ef..892bad4d5f 100644
--- a/engines/zvision/sound/zork_raw.h
+++ b/engines/zvision/sound/zork_raw.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.
@@ -25,7 +25,6 @@
#include "audio/audiostream.h"
-
namespace Common {
class SeekableReadStream;
}
@@ -39,27 +38,19 @@ struct SoundParams {
uint32 rate;
bool stereo;
bool packed;
+ bool bits16;
};
/**
- * This is a stream, which allows for playing raw ADPCM data from a stream.
+ * This is a ADPCM stream-reader, this class holds context for multi-chunk reading and no buffers.
*/
-class RawZorkStream : public Audio::RewindableAudioStream {
+class RawChunkStream {
public:
- RawZorkStream(uint32 rate, bool stereo, DisposeAfterUse::Flag disposeStream, Common::SeekableReadStream *stream);
+ RawChunkStream(bool stereo);
- ~RawZorkStream() {
+ ~RawChunkStream() {
}
-
-public:
- static const SoundParams _zNemSoundParamLookupTable[6];
- static const SoundParams _zgiSoundParamLookupTable[5];
-
private:
- const int _rate; // Sample rate of stream
- Audio::Timestamp _playtime; // Calculated total play time
- Common::DisposablePtr<Common::SeekableReadStream> _stream; // Stream to read data from
- bool _endOfData; // Whether the stream end has been reached
uint _stereo;
/**
@@ -75,30 +66,61 @@ private:
static const int32 _amplitudeLookupTable[89];
public:
- int readBuffer(int16 *buffer, const int numSamples);
- bool isStereo() const { return true; }
- bool endOfData() const { return _endOfData; }
+ struct RawChunk {
+ int16 *data;
+ uint32 size;
+ };
- int getRate() const { return _rate; }
- Audio::Timestamp getLength() const { return _playtime; }
-
- bool rewind();
+ void init();
+ //Read next audio portion in new stream (needed for avi), return structure with buffer
+ RawChunk readNextChunk(Common::SeekableReadStream *stream);
+ //Read numSamples from stream to buffer
+ int readBuffer(int16 *buffer, Common::SeekableReadStream *stream, const int numSamples);
};
/**
- * 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).
+ * This is a stream, which allows for playing raw ADPCM data from a stream.
*/
-Audio::RewindableAudioStream *makeRawZorkStream(const byte *buffer, uint32 size,
- int rate,
- bool stereo,
- DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES);
+class RawZorkStream : public Audio::RewindableAudioStream {
+public:
+ RawZorkStream(uint32 rate, bool stereo, DisposeAfterUse::Flag disposeStream, Common::SeekableReadStream *stream);
+
+ ~RawZorkStream() {
+ }
+
+public:
+ static const SoundParams _zNemSoundParamLookupTable[32];
+ static const SoundParams _zgiSoundParamLookupTable[24];
+
+private:
+ const int _rate; // Sample rate of stream
+ Audio::Timestamp _playtime; // Calculated total play time
+ Common::DisposablePtr<Common::SeekableReadStream> _stream; // Stream to read data from
+ bool _endOfData; // Whether the stream end has been reached
+ uint _stereo;
+
+ RawChunkStream _streamReader;
+
+public:
+ int readBuffer(int16 *buffer, const int numSamples);
+
+ bool isStereo() const {
+ return _stereo;
+ }
+ bool endOfData() const {
+ return _endOfData;
+ }
+
+ int getRate() const {
+ return _rate;
+ }
+ Audio::Timestamp getLength() const {
+ return _playtime;
+ }
+
+ bool rewind();
+};
/**
* Creates an audio stream, which plays from the given stream.
@@ -109,9 +131,9 @@ Audio::RewindableAudioStream *makeRawZorkStream(const byte *buffer, uint32 size,
* @return The new SeekableAudioStream (or 0 on failure).
*/
Audio::RewindableAudioStream *makeRawZorkStream(Common::SeekableReadStream *stream,
- int rate,
- bool stereo,
- DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES);
+ int rate,
+ bool stereo,
+ DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES);
Audio::RewindableAudioStream *makeRawZorkStream(const Common::String &filePath, ZVision *engine);
diff --git a/engines/zvision/strings/string_manager.cpp b/engines/zvision/strings/string_manager.cpp
deleted file mode 100644
index 22331d8a24..0000000000
--- a/engines/zvision/strings/string_manager.cpp
+++ /dev/null
@@ -1,255 +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 "zvision/strings/string_manager.h"
-
-#include "zvision/fonts/truetype_font.h"
-
-#include "common/file.h"
-#include "common/tokenizer.h"
-#include "common/debug.h"
-
-#include "graphics/fontman.h"
-#include "graphics/colormasks.h"
-
-
-namespace ZVision {
-
-StringManager::StringManager(ZVision *engine)
- : _engine(engine) {
-}
-
-StringManager::~StringManager() {
- for (Common::HashMap<Common::String, TruetypeFont *>::iterator iter = _fonts.begin(); iter != _fonts.end(); ++iter) {
- delete iter->_value;
- }
-}
-
-void StringManager::initialize(ZVisionGameId gameId) {
- if (gameId == GID_NEMESIS) {
- // TODO: Check this hardcoded filename against all versions of Nemesis
- parseStrFile("nemesis.str");
- } else if (gameId == GID_GRANDINQUISITOR) {
- // TODO: Check this hardcoded filename against all versions of Grand Inquisitor
- parseStrFile("inquis.str");
- }
-}
-
-void StringManager::parseStrFile(const Common::String &fileName) {
- Common::File file;
- if (!file.open(fileName)) {
- warning("%s does not exist. String parsing failed", fileName.c_str());
- return;
- }
-
- uint lineNumber = 0;
- while (!file.eos()) {
- _lastStyle.align = Graphics::kTextAlignLeft;
- _lastStyle.color = 0;
- _lastStyle.font = nullptr;
-
- Common::String asciiLine = readWideLine(file);
- if (asciiLine.empty()) {
- continue;
- }
-
- char tagString[150];
- uint tagStringCursor = 0;
- char textString[150];
- uint textStringCursor = 0;
- bool inTag = false;
-
- for (uint i = 0; i < asciiLine.size(); ++i) {
- switch (asciiLine[i]) {
- case '<':
- inTag = true;
- if (!_inGameText[lineNumber].fragments.empty()) {
- _inGameText[lineNumber].fragments.back().text = Common::String(textString, textStringCursor);
- textStringCursor = 0;
- }
- break;
- case '>':
- inTag = false;
- parseTag(Common::String(tagString, tagStringCursor), lineNumber);
- tagStringCursor = 0;
- break;
- default:
- if (inTag) {
- tagString[tagStringCursor] = asciiLine[i];
- tagStringCursor++;
- } else {
- textString[textStringCursor] = asciiLine[i];
- textStringCursor++;
- }
- break;
- }
- }
-
- if (textStringCursor > 0) {
- _inGameText[lineNumber].fragments.back().text = Common::String(textString, textStringCursor);
- }
-
- lineNumber++;
- assert(lineNumber <= NUM_TEXT_LINES);
- }
-}
-
-void StringManager::parseTag(const Common::String &tagString, uint lineNumber) {
- Common::StringTokenizer tokenizer(tagString);
-
- Common::String token = tokenizer.nextToken();
-
- Common::String fontName;
- bool bold = false;
- Graphics::TextAlign align = _lastStyle.align;
- int point = _lastStyle.font != nullptr ? _lastStyle.font->_fontHeight : 12;
- int red = 0;
- int green = 0;
- int blue = 0;
-
- while (!token.empty()) {
- if (token.matchString("font", true)) {
- fontName = tokenizer.nextToken();
- } else if (token.matchString("bold", true)) {
- token = tokenizer.nextToken();
- if (token.matchString("on", false)) {
- bold = true;
- }
- } else if (token.matchString("justify", true)) {
- token = tokenizer.nextToken();
- if (token.matchString("center", false)) {
- align = Graphics::kTextAlignCenter;
- } else if (token.matchString("right", false)) {
- align = Graphics::kTextAlignRight;
- }
- } else if (token.matchString("point", true)) {
- point = atoi(tokenizer.nextToken().c_str());
- } else if (token.matchString("red", true)) {
- red = atoi(tokenizer.nextToken().c_str());
- } else if (token.matchString("green", true)) {
- green = atoi(tokenizer.nextToken().c_str());
- } else if (token.matchString("blue", true)) {
- blue = atoi(tokenizer.nextToken().c_str());
- }
-
- token = tokenizer.nextToken();
- }
-
- TextFragment fragment;
-
- if (fontName.empty()) {
- fragment.style.font = _lastStyle.font;
- } else {
- Common::String newFontName;
- if (fontName.matchString("*times new roman*", true)) {
- if (bold) {
- newFontName = "timesbd.ttf";
- } else {
- newFontName = "times.ttf";
- }
- } else if (fontName.matchString("*courier new*", true)) {
- if (bold) {
- newFontName = "courbd.ttf";
- } else {
- newFontName = "cour.ttf";
- }
- } else if (fontName.matchString("*century schoolbook*", true)) {
- if (bold) {
- newFontName = "censcbkbd.ttf";
- } else {
- newFontName = "censcbk.ttf";
- }
- } else if (fontName.matchString("*garamond*", true)) {
- if (bold) {
- newFontName = "garabd.ttf";
- } else {
- newFontName = "gara.ttf";
- }
- } else {
- debug("Could not identify font: %s. Reverting to Arial", fontName.c_str());
- if (bold) {
- newFontName = "zorknorm.ttf";
- } else {
- newFontName = "arial.ttf";
- }
- }
-
- Common::String fontKey = Common::String::format("%s-%d", newFontName.c_str(), point);
- if (_fonts.contains(fontKey)) {
- fragment.style.font = _fonts[fontKey];
- } else {
- fragment.style.font = new TruetypeFont(_engine, point);
- fragment.style.font->loadFile(newFontName);
- _fonts[fontKey] = fragment.style.font;
- }
- }
-
- fragment.style.align = align;
- fragment.style.color = Graphics::ARGBToColor<Graphics::ColorMasks<565> >(0, red, green, blue);
- _inGameText[lineNumber].fragments.push_back(fragment);
-
- _lastStyle = fragment.style;
-}
-
-Common::String StringManager::readWideLine(Common::SeekableReadStream &stream) {
- Common::String asciiString;
-
- // Don't spam the user with warnings about UTF-16 support.
- // Just do one warning per String
- bool charOverflowWarning = false;
-
- uint16 value = stream.readUint16LE();
- while (!stream.eos()) {
- // Check for CRLF
- if (value == 0x0A0D) {
- // Read in the extra NULL char
- stream.readByte(); // \0
- // End of the line. Break
- break;
- }
-
- // Crush each octet pair to a single octet with a simple cast
- if (value > 255) {
- charOverflowWarning = true;
- value = '?';
- }
- char charValue = (char)value;
-
- asciiString += charValue;
-
- value = stream.readUint16LE();
- }
-
- if (charOverflowWarning) {
- warning("UTF-16 is not supported. Characters greater than 255 are replaced with '?'");
- }
-
- return asciiString;
-}
-
-StringManager::TextStyle StringManager::getTextStyle(uint stringNumber) {
- return _inGameText[stringNumber].fragments.front().style;
-}
-
-} // End of namespace ZVision
diff --git a/engines/zvision/text/string_manager.cpp b/engines/zvision/text/string_manager.cpp
new file mode 100644
index 0000000000..c62e18f4b0
--- /dev/null
+++ b/engines/zvision/text/string_manager.cpp
@@ -0,0 +1,70 @@
+/* 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/file.h"
+#include "common/tokenizer.h"
+#include "common/debug.h"
+#include "graphics/fontman.h"
+#include "graphics/colormasks.h"
+
+#include "zvision/zvision.h"
+#include "zvision/file/search_manager.h"
+#include "zvision/text/string_manager.h"
+#include "zvision/text/text.h"
+
+namespace ZVision {
+
+StringManager::StringManager(ZVision *engine)
+ : _engine(engine) {
+}
+
+StringManager::~StringManager() {
+
+}
+
+void StringManager::initialize(ZVisionGameId gameId) {
+ if (gameId == GID_NEMESIS)
+ loadStrFile("nemesis.str");
+ else if (gameId == GID_GRANDINQUISITOR)
+ loadStrFile("inquis.str");
+}
+
+void StringManager::loadStrFile(const Common::String &fileName) {
+ Common::File file;
+ 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);
+
+ lineNumber++;
+ assert(lineNumber <= NUM_TEXT_LINES);
+ }
+}
+
+const Common::String StringManager::getTextLine(uint stringNumber) {
+ return _lines[stringNumber];
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/strings/string_manager.h b/engines/zvision/text/string_manager.h
index af8324b890..f4564ee1ec 100644
--- a/engines/zvision/strings/string_manager.h
+++ b/engines/zvision/text/string_manager.h
@@ -24,8 +24,7 @@
#define ZVISION_STRING_MANAGER_H
#include "zvision/detection.h"
-#include "zvision/fonts/truetype_font.h"
-
+#include "zvision/text/truetype_font.h"
namespace Graphics {
class FontManager;
@@ -41,42 +40,28 @@ public:
~StringManager();
public:
- struct TextStyle {
- TruetypeFont *font;
- uint16 color; // In RBG 565
- Graphics::TextAlign align;
- };
-
- struct TextFragment {
- TextStyle style;
- Common::String text;
+ enum {
+ ZVISION_STR_SAVEEXIST = 23,
+ ZVISION_STR_SAVED = 4,
+ ZVISION_STR_SAVEEMPTY = 21,
+ ZVISION_STR_EXITPROMT = 6
};
private:
- struct InGameText {
- Common::List<TextFragment> fragments;
- };
-
enum {
NUM_TEXT_LINES = 56 // Max number of lines in a .str file. We hardcode this number because we know ZNem uses 42 strings and ZGI uses 56
};
private:
ZVision *_engine;
- InGameText _inGameText[NUM_TEXT_LINES];
- Common::HashMap<Common::String, TruetypeFont *> _fonts;
-
- TextStyle _lastStyle;
+ Common::String _lines[NUM_TEXT_LINES];
public:
void initialize(ZVisionGameId gameId);
- StringManager::TextStyle getTextStyle(uint stringNumber);
+ const Common::String getTextLine(uint stringNumber);
private:
- void parseStrFile(const Common::String &fileName);
- void parseTag(const Common::String &tagString, uint lineNumber);
-
- static Common::String readWideLine(Common::SeekableReadStream &stream);
+ void loadStrFile(const Common::String &fileName);
};
} // End of namespace ZVision
diff --git a/engines/zvision/text/subtitles.cpp b/engines/zvision/text/subtitles.cpp
new file mode 100644
index 0000000000..ffc9e2b808
--- /dev/null
+++ b/engines/zvision/text/subtitles.cpp
@@ -0,0 +1,115 @@
+/* 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 "zvision/graphics/render_manager.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, bool upscaleToHires) :
+ _engine(engine),
+ _areaId(-1),
+ _subId(-1) {
+ Common::File file;
+ if (_engine->getSearchManager()->openFile(file, subname)) {
+ while (!file.eos()) {
+ Common::String str = file.readLine();
+ if (str.lastChar() == '~')
+ str.deleteLastChar();
+
+ if (str.matchString("*Initialization*", true)) {
+ // Not used
+ } else if (str.matchString("*Rectangle*", true)) {
+ 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];
+ sscanf(str.c_str(), "%*[^:]:%s", filename);
+ Common::File txt;
+ if (_engine->getSearchManager()->openFile(txt, filename)) {
+ while (!txt.eos()) {
+ Common::String txtline = readWideLine(txt);
+ sub curSubtitle;
+ curSubtitle.start = -1;
+ curSubtitle.stop = -1;
+ curSubtitle.subStr = txtline;
+
+ _subs.push_back(curSubtitle);
+ }
+ txt.close();
+ }
+ } else {
+ int32 st;
+ int32 en;
+ 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;
+ }
+ }
+ }
+ }
+ }
+}
+
+Subtitle::~Subtitle() {
+ if (_areaId != -1)
+ _engine->getRenderManager()->deleteSubArea(_areaId);
+
+ _subs.clear();
+}
+
+void Subtitle::process(int32 time) {
+ int16 j = -1;
+ for (uint16 i = 0; i < _subs.size(); i++)
+ if (time >= _subs[i].start && time <= _subs[i].stop) {
+ j = i;
+ break;
+ }
+
+ if (j == -1 && _subId != -1) {
+ if (_areaId != -1)
+ _engine->getRenderManager()->updateSubArea(_areaId, "");
+ _subId = -1;
+ }
+
+ if (j != -1 && j != _subId) {
+ if (_subs[j].subStr.size())
+ if (_areaId != -1)
+ _engine->getRenderManager()->updateSubArea(_areaId, _subs[j].subStr);
+ _subId = j;
+ }
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/subtitles/subtitles.h b/engines/zvision/text/subtitles.h
index 776ddd3a97..329339be55 100644
--- a/engines/zvision/subtitles/subtitles.h
+++ b/engines/zvision/text/subtitles.h
@@ -23,6 +23,32 @@
#ifndef ZVISION_SUBTITLES_H
#define ZVISION_SUBTITLES_H
-// TODO: Implement Subtitles
+#include "zvision/zvision.h"
+
+namespace ZVision {
+
+class ZVision;
+
+class Subtitle {
+public:
+ Subtitle(ZVision *engine, const Common::String &subname, bool upscaleToHires = false);
+ ~Subtitle();
+
+ void process(int32 time);
+private:
+ ZVision *_engine;
+ int32 _areaId;
+ int16 _subId;
+
+ struct sub {
+ int start;
+ int stop;
+ Common::String subStr;
+ };
+
+ Common::Array<sub> _subs;
+};
+
+}
#endif
diff --git a/engines/zvision/text/text.cpp b/engines/zvision/text/text.cpp
new file mode 100644
index 0000000000..868ee4f1ae
--- /dev/null
+++ b/engines/zvision/text/text.cpp
@@ -0,0 +1,578 @@
+/* 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/file.h"
+#include "common/tokenizer.h"
+#include "common/debug.h"
+#include "common/rect.h"
+#include "graphics/fontman.h"
+#include "graphics/colormasks.h"
+#include "graphics/surface.h"
+#include "graphics/font.h"
+#include "graphics/fonts/ttf.h"
+
+#include "zvision/text/text.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/text/truetype_font.h"
+#include "zvision/scripting/script_manager.h"
+
+namespace ZVision {
+
+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;
+}
+
+TextChange TextStyleState::parseStyle(const Common::String &str, int16 len) {
+ Common::String buf = Common::String(str.c_str(), len);
+
+ uint retval = TEXT_CHANGE_NONE;
+
+ Common::StringTokenizer tokenizer(buf, " ");
+ Common::String token;
+
+ while (!tokenizer.empty()) {
+ token = tokenizer.nextToken();
+
+ if (token.matchString("font", true)) {
+ token = tokenizer.nextToken();
+ if (token[0] == '"') {
+ Common::String _tmp = Common::String(token.c_str() + 1);
+
+ while (token.lastChar() != '"' && !tokenizer.empty()) {
+ token = tokenizer.nextToken();
+ _tmp += " " + token;
+ }
+
+ if (_tmp.lastChar() == '"')
+ _tmp.deleteLastChar();
+
+ _fontname = _tmp;
+ } else {
+ if (!tokenizer.empty())
+ _fontname = token;
+ }
+ 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 |= 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 |= 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 |= TEXT_CHANGE_FONT_STYLE;
+ }
+ }
+ } else if (token.matchString("newline", true)) {
+#if 0
+ if ((retval & TXT_RET_NEWLN) == 0)
+ _newline = 0;
+
+ _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 |= 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;
+#endif
+ }
+ } else if (token.matchString("italic", true)) {
+ if (!tokenizer.empty()) {
+ token = tokenizer.nextToken();
+ if (token.matchString("on", true)) {
+ if (_italic != true) {
+ _italic = true;
+ retval |= TEXT_CHANGE_FONT_STYLE;
+ }
+ } else if (token.matchString("off", true)) {
+ if (_italic != false) {
+ _italic = false;
+ retval |= TEXT_CHANGE_FONT_STYLE;
+ }
+ }
+ }
+ } else if (token.matchString("underline", true)) {
+ if (!tokenizer.empty()) {
+ token = tokenizer.nextToken();
+ if (token.matchString("on", true)) {
+ if (_underline != true) {
+ _underline = true;
+ retval |= TEXT_CHANGE_FONT_STYLE;
+ }
+ } else if (token.matchString("off", true)) {
+ if (_underline != false) {
+ _underline = false;
+ retval |= TEXT_CHANGE_FONT_STYLE;
+ }
+ }
+ }
+ } else if (token.matchString("strikeout", true)) {
+ if (!tokenizer.empty()) {
+ token = tokenizer.nextToken();
+ if (token.matchString("on", true)) {
+ if (_strikeout != true) {
+ _strikeout = true;
+ retval |= TEXT_CHANGE_FONT_STYLE;
+ }
+ } else if (token.matchString("off", true)) {
+ if (_strikeout != false) {
+ _strikeout = false;
+ retval |= TEXT_CHANGE_FONT_STYLE;
+ }
+ }
+ }
+ } else if (token.matchString("bold", true)) {
+ if (!tokenizer.empty()) {
+ token = tokenizer.nextToken();
+ if (token.matchString("on", true)) {
+ if (_bold != true) {
+ _bold = true;
+ retval |= TEXT_CHANGE_FONT_STYLE;
+ }
+ } else if (token.matchString("off", true)) {
+ 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;
+ } else if (token.matchString("off", true)) {
+ _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 |= TEXT_CHANGE_HAS_STATE_BOX;
+ }
+ } else if (token.matchString("justify", true)) {
+ if (!tokenizer.empty()) {
+ token = tokenizer.nextToken();
+ if (token.matchString("center", true))
+ _justification = TEXT_JUSTIFY_CENTER;
+ else if (token.matchString("left", true))
+ _justification = TEXT_JUSTIFY_LEFT;
+ else if (token.matchString("right", true))
+ _justification = TEXT_JUSTIFY_RIGHT;
+ }
+ }
+ }
+ return (TextChange)retval;
+}
+
+void TextStyleState::readAllStyles(const Common::String &txt) {
+ int16 startTextPosition = -1;
+ int16 endTextPosition = -1;
+
+ for (uint16 i = 0; i < txt.size(); i++) {
+ if (txt[i] == '<')
+ startTextPosition = i;
+ else if (txt[i] == '>') {
+ endTextPosition = i;
+ if (startTextPosition != -1) {
+ if ((endTextPosition - startTextPosition - 1) > 0) {
+ parseStyle(Common::String(txt.c_str() + startTextPosition + 1), endTextPosition - startTextPosition - 1);
+ }
+ }
+ }
+
+ }
+}
+
+void TextStyleState::updateFontWithTextState(StyledTTFont &font) {
+ uint tempStyle = 0;
+
+ 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.loadFont(_fontname, _size, tempStyle);
+}
+
+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);
+}
+
+int32 TextRenderer::drawText(const Common::String &text, TextStyleState &state, Graphics::Surface &dest) {
+ StyledTTFont font(_engine);
+ state.updateFontWithTextState(font);
+
+ uint32 color = _engine->_resourcePixelFormat.RGBToColor(state._red, state._green, state._blue);
+ drawTextWithJustification(text, font, color, dest, 0, state._justification);
+
+ return font.getStringWidth(text);
+}
+
+struct TextSurface {
+ TextSurface(Graphics::Surface *surface, Common::Point surfaceOffset, uint lineNumber)
+ : _surface(surface),
+ _surfaceOffset(surfaceOffset),
+ _lineNumber(lineNumber) {
+ }
+
+ Graphics::Surface *_surface;
+ Common::Point _surfaceOffset;
+ uint _lineNumber;
+};
+
+void TextRenderer::drawTextWithWordWrapping(const Common::String &text, Graphics::Surface &dest) {
+ Common::Array<TextSurface> textSurfaces;
+ Common::Array<uint> lineWidths;
+ Common::Array<TextJustification> lineJustifications;
+
+ // Create the initial text state
+ TextStyleState currentState;
+
+ // Create an empty font and bind it to the state
+ StyledTTFont font(_engine);
+ currentState.updateFontWithTextState(font);
+
+ 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();
+
+ uint currentLineNumber = 0u;
+
+ uint numSpaces = 0u;
+ int spaceWidth = 0;
+
+ // The pixel offset to the currentSentence
+ Common::Point sentencePixelOffset;
+
+ uint i = 0u;
+ uint stringlen = text.size();
+
+ 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;
+
+ uint32 textColor = currentState.getTextColor(_engine);
+
+ uint stateChanges = 0u;
+ if ((endTextPosition - startTextPosition - 1) > 0) {
+ stateChanges = currentState.parseStyle(Common::String(text.c_str() + startTextPosition + 1), endTextPosition - startTextPosition - 1);
+ }
+
+ 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));
+
+ lineWidth += sentenceWidth;
+ sentencePixelOffset.x += sentenceWidth;
+
+ // Reset the sentence variables
+ currentSentence.clear();
+ sentenceWidth = 0;
+ }
+
+ // Update the current state with the style information
+ currentState.updateFontWithTextState(font);
+
+ 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 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));
+
+ // 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);
+ }
+ }
+ } else {
+ currentWord += text[i];
+ wordWidth += font.getCharWidth(text[i]);
+
+ if (text[i] == ' ') {
+ // When we hit the first space, flush the current word to the sentence
+ if (!currentWord.empty()) {
+ currentSentence += currentWord;
+ sentenceWidth += wordWidth;
+
+ currentWord.clear();
+ wordWidth = 0;
+ }
+
+ // 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));
+ }
+
+ // 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++;
+ }
+
+ // 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));
+ }
+
+ lineWidths.push_back(lineWidth + sentenceWidth);
+ lineJustifications.push_back(currentState._justification);
+
+ for (Common::Array<TextSurface>::iterator iter = textSurfaces.begin(); iter != textSurfaces.end(); ++iter) {
+ Common::Rect empty;
+
+ 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);
+ }
+
+ // Release memory
+ iter->_surface->free();
+ delete iter->_surface;
+ }
+}
+
+Common::String readWideLine(Common::SeekableReadStream &stream) {
+ Common::String asciiString;
+
+ while (true) {
+ uint32 value = stream.readUint16LE();
+ if (stream.eos())
+ break;
+ // Check for CRLF
+ if (value == 0x0A0D) {
+ // Read in the extra NULL char
+ stream.readByte(); // \0
+ // End of the line. Break
+ break;
+ }
+
+ // Crush each octet pair to a UTF-8 sequence
+ if (value < 0x80) {
+ asciiString += (char)(value & 0x7F);
+ } else if (value >= 0x80 && value < 0x800) {
+ asciiString += (char)(0xC0 | ((value >> 6) & 0x1F));
+ asciiString += (char)(0x80 | (value & 0x3F));
+ } 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));
+ asciiString += (char)(0x80 | ((value >> 6) & 0x3F));
+ asciiString += (char)(0x80 | (value & 0x3F));
+ }
+ }
+
+ return asciiString;
+}
+
+int8 getUtf8CharSize(char chr) {
+ if ((chr & 0x80) == 0)
+ return 1;
+ else if ((chr & 0xE0) == 0xC0)
+ return 2;
+ else if ((chr & 0xF0) == 0xE0)
+ return 3;
+ else if ((chr & 0xF8) == 0xF0)
+ return 4;
+ else if ((chr & 0xFC) == 0xF8)
+ return 5;
+ else if ((chr & 0xFE) == 0xFC)
+ return 6;
+
+ return 1;
+}
+
+uint16 readUtf8Char(const char *chr) {
+ uint16 result = 0;
+ if ((chr[0] & 0x80) == 0)
+ result = chr[0];
+ else if ((chr[0] & 0xE0) == 0xC0)
+ result = ((chr[0] & 0x1F) << 6) | (chr[1] & 0x3F);
+ else if ((chr[0] & 0xF0) == 0xE0)
+ result = ((chr[0] & 0x0F) << 12) | ((chr[1] & 0x3F) << 6) | (chr[2] & 0x3F);
+ else
+ result = chr[0];
+
+ return result;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/text/text.h b/engines/zvision/text/text.h
new file mode 100644
index 0000000000..d35b90499d
--- /dev/null
+++ b/engines/zvision/text/text.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 ZVISION_TEXT_H
+#define ZVISION_TEXT_H
+
+#include "zvision/detection.h"
+#include "zvision/text/truetype_font.h"
+#include "zvision/zvision.h"
+
+namespace ZVision {
+
+class ZVision;
+
+enum TextJustification {
+ TEXT_JUSTIFY_CENTER = 0,
+ TEXT_JUSTIFY_LEFT = 1,
+ TEXT_JUSTIFY_RIGHT = 2
+};
+
+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 TextStyleState {
+public:
+ 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;
+ TextJustification _justification; // 0 - center, 1-left, 2-right
+ 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 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;
+};
+
+Common::String readWideLine(Common::SeekableReadStream &stream);
+int8 getUtf8CharSize(char chr);
+uint16 readUtf8Char(const char *chr);
+
+} // End of namespace ZVision
+
+#endif
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/fonts/truetype_font.h b/engines/zvision/text/truetype_font.h
index 64f53a2c3b..6abe05cda6 100644
--- a/engines/zvision/fonts/truetype_font.h
+++ b/engines/zvision/text/truetype_font.h
@@ -28,52 +28,65 @@
#include "graphics/font.h"
#include "graphics/pixelformat.h"
-
namespace Graphics {
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;
-class TruetypeFont {
+// Styled TTF
+class StyledTTFont {
public:
- TruetypeFont(ZVision *engine, int32 fontHeight);
- ~TruetypeFont();
+ StyledTTFont(ZVision *engine);
+ ~StyledTTFont();
+
+ enum {
+ TTF_STYLE_BOLD = 0x01,
+ TTF_STYLE_ITALIC = 0x02,
+ TTF_STYLE_UNDERLINE = 0x04,
+ TTF_STYLE_STRIKETHROUGH = 0x08,
+ TTF_STYLE_SHARP = 0x10
+ };
private:
-// ZVision *_engine;
+ ZVision *_engine;
Graphics::Font *_font;
int _lineHeight;
-
-// size_t _maxCharWidth;
-// size_t _maxCharHeight;
+ uint _style;
+ Common::String _fontName;
public:
- int32 _fontHeight;
+ bool loadFont(const Common::String &fontName, int32 point, uint style);
-public:
- /**
- * Loads a .ttf file into memory. This must be called
- * before any calls to drawTextToSurface
- *
- * @param filename The file name of the .ttf file to load
- */
- bool loadFile(const Common::String &filename);
- /**
- * Renders the supplied text to a Surface using 0x0 as the
- * background color.
- *
- * @param text The to render
- * @param textColor The color to render the text with
- * @param maxWidth The max width the text should take up.
- * @param maxHeight The max height the text should take up.
- * @param align The alignment of the text within the bounds of maxWidth
- * @param wrap If true, any words extending past maxWidth will wrap to a new line. If false, ellipses will be rendered to show that the text didn't fit
- * @return A Surface containing the rendered text
- */
- Graphics::Surface *drawTextToSurface(const Common::String &text, uint16 textColor, int maxWidth, int maxHeight, Graphics::TextAlign align, bool wrap);
+ 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);
+ int getStringWidth(const Common::String &str);
+
+ Graphics::Surface *renderSolidText(const Common::String &str, uint32 color);
+
+ bool isLoaded() {
+ return _font != NULL;
+ };
};
} // End of namespace ZVision
diff --git a/engines/zvision/utility/single_value_container.cpp b/engines/zvision/utility/single_value_container.cpp
deleted file mode 100644
index e609474285..0000000000
--- a/engines/zvision/utility/single_value_container.cpp
+++ /dev/null
@@ -1,348 +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 "zvision/utility/single_value_container.h"
-
-#include "common/textconsole.h"
-#include "common/str.h"
-
-
-namespace ZVision {
-
-SingleValueContainer::SingleValueContainer(ValueType type) : _objectType(type) { }
-
-SingleValueContainer::SingleValueContainer(bool value) : _objectType(BOOL) {
- _value.boolVal = value;
-}
-
-SingleValueContainer::SingleValueContainer(byte value) : _objectType(BYTE) {
- _value.byteVal = value;
-}
-
-SingleValueContainer::SingleValueContainer(int16 value) : _objectType(INT16) {
- _value.int16Val = value;
-}
-
-SingleValueContainer::SingleValueContainer(uint16 value) : _objectType(UINT16) {
- _value.uint16Val = value;
-}
-
-SingleValueContainer::SingleValueContainer(int32 value) : _objectType(INT32) {
- _value.int32Val = value;
-}
-
-SingleValueContainer::SingleValueContainer(uint32 value) : _objectType(UINT32) {
- _value.uint32Val = value;
-}
-
-SingleValueContainer::SingleValueContainer(float value) : _objectType(FLOAT) {
- _value.floatVal = value;
-}
-
-SingleValueContainer::SingleValueContainer(double value) : _objectType(DOUBLE) {
- _value.doubleVal = value;
-}
-
-SingleValueContainer::SingleValueContainer(Common::String value) : _objectType(BYTE) {
- _value.stringVal = new char[value.size() + 1];
- memcpy(_value.stringVal, value.c_str(), value.size() + 1);
-}
-
-SingleValueContainer::SingleValueContainer(const SingleValueContainer &other) {
- _objectType = other._objectType;
-
- switch (_objectType) {
- case BOOL:
- _value.boolVal = other._value.boolVal;
- break;
- case BYTE:
- _value.byteVal = other._value.byteVal;
- break;
- case INT16:
- _value.int16Val = other._value.int16Val;
- break;
- case UINT16:
- _value.uint16Val = other._value.uint16Val;
- break;
- case INT32:
- _value.int32Val = other._value.int32Val;
- break;
- case UINT32:
- _value.uint32Val = other._value.uint32Val;
- break;
- case FLOAT:
- _value.floatVal = other._value.floatVal;
- break;
- case DOUBLE:
- _value.doubleVal = other._value.doubleVal;
- break;
- case STRING:
- uint32 length = strlen(other._value.stringVal);
- _value.stringVal = new char[length + 1];
- memcpy(_value.stringVal, other._value.stringVal, length + 1);
- break;
- }
-}
-
-SingleValueContainer::~SingleValueContainer() {
- deleteCharPointer();
-}
-
-void SingleValueContainer::deleteCharPointer() {
- if (_objectType == STRING)
- delete[] _value.stringVal;
-}
-
-
-SingleValueContainer &SingleValueContainer::operator=(const bool &rhs) {
- if (_objectType == BOOL) {
- _value.boolVal = rhs;
- return *this;
- }
-
- deleteCharPointer();
- _objectType = BOOL;
- _value.boolVal = rhs;
-
- return *this;
-}
-
-SingleValueContainer &SingleValueContainer::operator=(const byte &rhs) {
- if (_objectType == BYTE) {
- _value.byteVal = rhs;
- return *this;
- }
-
- deleteCharPointer();
- _objectType = BYTE;
- _value.byteVal = rhs;
-
- return *this;
-}
-
-SingleValueContainer &SingleValueContainer::operator=(const int16 &rhs) {
- if (_objectType == INT16) {
- _value.int16Val = rhs;
- return *this;
- }
-
- deleteCharPointer();
- _objectType = INT16;
- _value.int16Val = rhs;
-
- return *this;
-}
-
-SingleValueContainer &SingleValueContainer::operator=(const uint16 &rhs) {
- if (_objectType == UINT16) {
- _value.uint16Val = rhs;
- return *this;
- }
-
- deleteCharPointer();
- _objectType = UINT16;
- _value.uint16Val = rhs;
-
- return *this;
-}
-
-SingleValueContainer &SingleValueContainer::operator=(const int32 &rhs) {
- if (_objectType == INT32) {
- _value.int32Val = rhs;
- return *this;
- }
-
- deleteCharPointer();
- _objectType = INT32;
- _value.int32Val = rhs;
-
- return *this;
-}
-
-SingleValueContainer &SingleValueContainer::operator=(const uint32 &rhs) {
- if (_objectType == UINT32) {
- _value.uint32Val = rhs;
- return *this;
- }
-
- deleteCharPointer();
- _objectType = UINT32;
- _value.uint32Val = rhs;
-
- return *this;
-}
-
-SingleValueContainer &SingleValueContainer::operator=(const float &rhs) {
- if (_objectType == FLOAT) {
- _value.floatVal = rhs;
- return *this;
- }
-
- deleteCharPointer();
- _objectType = FLOAT;
- _value.floatVal = rhs;
-
- return *this;
-}
-
-SingleValueContainer &SingleValueContainer::operator=(const double &rhs) {
- if (_objectType == DOUBLE) {
- _value.doubleVal = rhs;
- return *this;
- }
-
- deleteCharPointer();
- _objectType = DOUBLE;
- _value.doubleVal = rhs;
-
- return *this;
-}
-
-SingleValueContainer &SingleValueContainer::operator=(const Common::String &rhs) {
- if (_objectType != STRING) {
- _objectType = STRING;
- _value.stringVal = new char[rhs.size() + 1];
- memcpy(_value.stringVal, rhs.c_str(), rhs.size() + 1);
-
- return *this;
- }
-
- uint32 length = strlen(_value.stringVal);
- if (length <= rhs.size() + 1) {
- memcpy(_value.stringVal, rhs.c_str(), rhs.size() + 1);
- } else {
- delete[] _value.stringVal;
- _value.stringVal = new char[rhs.size() + 1];
- memcpy(_value.stringVal, rhs.c_str(), rhs.size() + 1);
- }
-
- return *this;
-}
-
-SingleValueContainer &SingleValueContainer::operator=(const SingleValueContainer &rhs) {
- switch (_objectType) {
- case BOOL:
- return operator=(rhs._value.boolVal);
- case BYTE:
- return operator=(rhs._value.byteVal);
- case INT16:
- return operator=(rhs._value.int16Val);
- case UINT16:
- return operator=(rhs._value.uint16Val);
- case INT32:
- return operator=(rhs._value.int32Val);
- case UINT32:
- return operator=(rhs._value.uint32Val);
- case FLOAT:
- return operator=(rhs._value.floatVal);
- case DOUBLE:
- return operator=(rhs._value.doubleVal);
- case STRING:
- uint32 length = strlen(rhs._value.stringVal);
-
- _value.stringVal = new char[length + 1];
- memcpy(_value.stringVal, rhs._value.stringVal, length + 1);
-
- return *this;
- }
-
- return *this;
-}
-
-
-bool SingleValueContainer::getBoolValue(bool *returnValue) const {
- if (_objectType != BOOL) {
- warning("'Object' is not storing a bool.");
- return false;
- }
-
- *returnValue = _value.boolVal;
- return true;
-}
-
-bool SingleValueContainer::getByteValue(byte *returnValue) const {
- if (_objectType != BYTE)
- warning("'Object' is not storing a byte.");
-
- *returnValue = _value.byteVal;
- return true;
-}
-
-bool SingleValueContainer::getInt16Value(int16 *returnValue) const {
- if (_objectType != INT16)
- warning("'Object' is not storing an int16.");
-
- *returnValue = _value.int16Val;
- return true;
-}
-
-bool SingleValueContainer::getUInt16Value(uint16 *returnValue) const {
- if (_objectType != UINT16)
- warning("'Object' is not storing a uint16.");
-
- *returnValue = _value.uint16Val;
- return true;
-}
-
-bool SingleValueContainer::getInt32Value(int32 *returnValue) const {
- if (_objectType != INT32)
- warning("'Object' is not storing an int32.");
-
- *returnValue = _value.int32Val;
- return true;
-}
-
-bool SingleValueContainer::getUInt32Value(uint32 *returnValue) const {
- if (_objectType != UINT32)
- warning("'Object' is not storing a uint32.");
-
- *returnValue = _value.uint32Val;
- return true;
-}
-
-bool SingleValueContainer::getFloatValue(float *returnValue) const {
- if (_objectType != FLOAT)
- warning("'Object' is not storing a float.");
-
- *returnValue = _value.floatVal;
- return true;
-}
-
-bool SingleValueContainer::getDoubleValue(double *returnValue) const {
- if (_objectType != DOUBLE)
- warning("'Object' is not storing a double.");
-
- *returnValue = _value.doubleVal;
- return true;
-}
-
-bool SingleValueContainer::getStringValue(Common::String *returnValue) const {
- if (_objectType != STRING)
- warning("'Object' is not storing a Common::String.");
-
- *returnValue = _value.stringVal;
- return true;
-}
-
-} // End of namespace ZVision
diff --git a/engines/zvision/utility/single_value_container.h b/engines/zvision/utility/single_value_container.h
deleted file mode 100644
index 951383661a..0000000000
--- a/engines/zvision/utility/single_value_container.h
+++ /dev/null
@@ -1,183 +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.
- *
- */
-
-#ifndef ZVISION_SINGLE_VALUE_CONTAINER_H
-#define ZVISION_SINGLE_VALUE_CONTAINER_H
-
-namespace Common {
-class String;
-}
-
-namespace ZVision {
-
-/**
- * A generic single value storage class. It is useful for storing different
- * value types in a single List, Hashmap, etc.
- */
-class SingleValueContainer {
-public:
- enum ValueType {
- BOOL,
- BYTE,
- INT16,
- UINT16,
- INT32,
- UINT32,
- FLOAT,
- DOUBLE,
- STRING
- };
-
- // Constructors
- explicit SingleValueContainer(ValueType type);
- explicit SingleValueContainer(bool value);
- explicit SingleValueContainer(byte value);
- explicit SingleValueContainer(int16 value);
- explicit SingleValueContainer(uint16 value);
- explicit SingleValueContainer(int32 value);
- explicit SingleValueContainer(uint32 value);
- explicit SingleValueContainer(float value);
- explicit SingleValueContainer(double value);
- explicit SingleValueContainer(Common::String value);
-
- // Copy constructor
- explicit SingleValueContainer(const SingleValueContainer& other);
-
- // Destructor
- ~SingleValueContainer();
-
-private:
- ValueType _objectType;
-
- union {
- bool boolVal;
- byte byteVal;
- int16 int16Val;
- uint16 uint16Val;
- int32 int32Val;
- uint32 uint32Val;
- float floatVal;
- double doubleVal;
- char *stringVal;
- } _value;
-
-public:
- SingleValueContainer &operator=(const bool &rhs);
- SingleValueContainer &operator=(const byte &rhs);
- SingleValueContainer &operator=(const int16 &rhs);
- SingleValueContainer &operator=(const uint16 &rhs);
- SingleValueContainer &operator=(const int32 &rhs);
- SingleValueContainer &operator=(const uint32 &rhs);
- SingleValueContainer &operator=(const float &rhs);
- SingleValueContainer &operator=(const double &rhs);
- SingleValueContainer &operator=(const Common::String &rhs);
-
- SingleValueContainer& operator=(const SingleValueContainer &rhs);
-
- /**
- * Retrieve a bool from the container. If the container is not storing a
- * bool, this will return false and display a warning().
- *
- * @param returnValue Pointer to where you want the value stored
- * @return Value indicating whether the value assignment was successful
- */
- bool getBoolValue(bool *returnValue) const;
- /**
- * Retrieve a byte from the container. If the container is not storing a
- * byte, this will return false and display a warning().
- *
- * @param returnValue Pointer to where you want the value stored
- * @return Value indicating whether the value assignment was successful
- */
- bool getByteValue(byte *returnValue) const;
- /**
- * Retrieve an int16 from the container. If the container is not storing an
- * int16, this will return false and display a warning().
- *
- * @param returnValue Pointer to where you want the value stored
- * @return Value indicating whether the value assignment was successful
- */
- bool getInt16Value(int16 *returnValue) const;
- /**
- * Retrieve a uint16 from the container. If the container is not storing a
- * uint16, this will return false and display a warning().
- *
- * @param returnValue Pointer to where you want the value stored
- * @return Value indicating whether the value assignment was successful
- */
- bool getUInt16Value(uint16 *returnValue) const;
- /**
- * Retrieve an int32 from the container. If the container is not storing an
- * int32, this will return false and display a warning().
- *
- * @param returnValue Pointer to where you want the value stored
- * @return Value indicating whether the value assignment was successful
- */
- bool getInt32Value(int32 *returnValue) const;
- /**
- * Retrieve a uint32 from the container. If the container is not storing a
- * uint32, this will return false and display a warning().
- *
- * @param returnValue Pointer to where you want the value stored
- * @return Value indicating whether the value assignment was successful
- */
- bool getUInt32Value(uint32 *returnValue) const;
- /**
- * Retrieve a float from the container. If the container is not storing a
- * float, this will return false and display a warning().
- *
- * @param returnValue Pointer to where you want the value stored
- * @return Value indicating whether the value assignment was successful
- */
- bool getFloatValue(float *returnValue) const;
- /**
- * Retrieve a double from the container. If the container is not storing a
- * double, this will return false and display a warning().
- *
- * @param returnValue Pointer to where you want the value stored
- * @return Value indicating whether the value assignment was successful
- */
- bool getDoubleValue(double *returnValue) const;
- /**
- * Retrieve a String from the container. If the container is not storing a
- * string, this will return false and display a warning().
- *
- * Caution: Strings are internally stored as char[]. getStringValue uses
- * Common::String::operator=(char *) to do the assigment, which uses both
- * strlen() AND memmove().
- *
- * @param returnValue Pointer to where you want the value stored
- * @return Value indicating whether the value assignment was successful
- */
- bool getStringValue(Common::String *returnValue) const;
-
-private:
- /**
- * Helper method for destruction and assignment. It checks to see
- * if the char pointer is being used, and if so calls delete on it
- */
- void deleteCharPointer();
-};
-
-} // End of namespace ZVision
-
-#endif
diff --git a/engines/zvision/utility/utility.cpp b/engines/zvision/utility/utility.cpp
deleted file mode 100644
index 905bc4513a..0000000000
--- a/engines/zvision/utility/utility.cpp
+++ /dev/null
@@ -1,237 +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 "zvision/utility/utility.h"
-
-#include "zvision/zvision.h"
-#include "zvision/sound/zork_raw.h"
-
-#include "common/tokenizer.h"
-#include "common/file.h"
-
-
-namespace ZVision {
-
-void writeFileContentsToFile(const Common::String &sourceFile, const Common::String &destFile) {
- Common::File f;
- if (!f.open(sourceFile)) {
- return;
- }
-
- byte* buffer = new byte[f.size()];
- f.read(buffer, f.size());
-
- Common::DumpFile dumpFile;
- dumpFile.open(destFile);
-
- dumpFile.write(buffer, f.size());
- dumpFile.flush();
- dumpFile.close();
-
- delete[] buffer;
-}
-
-void trimCommentsAndWhiteSpace(Common::String *string) {
- for (int i = string->size() - 1; i >= 0; i--) {
- if ((*string)[i] == '#') {
- string->erase(i);
- }
- }
-
- string->trim();
-}
-
-void tryToDumpLine(const Common::String &key,
- Common::String &line,
- Common::HashMap<Common::String, byte> *count,
- Common::HashMap<Common::String, bool> *fileAlreadyUsed,
- Common::DumpFile &output) {
- const byte numberOfExamplesPerType = 8;
-
- if ((*count)[key] < numberOfExamplesPerType && !(*fileAlreadyUsed)[key]) {
- output.writeString(line);
- output.writeByte('\n');
- (*count)[key]++;
- (*fileAlreadyUsed)[key] = true;
- }
-}
-
-void dumpEveryResultAction(const Common::String &destFile) {
- Common::HashMap<Common::String, byte> count;
- Common::HashMap<Common::String, bool> fileAlreadyUsed;
-
- Common::DumpFile output;
- output.open(destFile);
-
- // Find scr files
- Common::ArchiveMemberList list;
- SearchMan.listMatchingMembers(list, "*.scr");
-
- for (Common::ArchiveMemberList::iterator iter = list.begin(); iter != list.end(); ++iter) {
- Common::SeekableReadStream *stream = (*iter)->createReadStream();
-
- Common::String line = stream->readLine();
- trimCommentsAndWhiteSpace(&line);
-
- while (!stream->eos()) {
- if (line.matchString("*:add*", true)) {
- tryToDumpLine("add", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:animplay*", true)) {
- tryToDumpLine("animplay", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:animpreload*", true)) {
- tryToDumpLine("animpreload", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:animunload*", true)) {
- tryToDumpLine("animunload", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:attenuate*", true)) {
- tryToDumpLine("attenuate", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:assign*", true)) {
- tryToDumpLine("assign", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:change_location*", true)) {
- tryToDumpLine("change_location", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:crossfade*", true) && !fileAlreadyUsed["add"]) {
- tryToDumpLine("crossfade", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:debug*", true)) {
- tryToDumpLine("debug", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:delay_render*", true)) {
- tryToDumpLine("delay_render", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:disable_control*", true)) {
- tryToDumpLine("disable_control", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:disable_venus*", true)) {
- tryToDumpLine("disable_venus", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:display_message*", true)) {
- tryToDumpLine("display_message", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:dissolve*", true)) {
- tryToDumpLine("dissolve", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:distort*", true)) {
- tryToDumpLine("distort", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:enable_control*", true)) {
- tryToDumpLine("enable_control", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:flush_mouse_events*", true)) {
- tryToDumpLine("flush_mouse_events", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:inventory*", true)) {
- tryToDumpLine("inventory", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:kill*", true)) {
- tryToDumpLine("kill", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:menu_bar_enable*", true)) {
- tryToDumpLine("menu_bar_enable", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:music*", true)) {
- tryToDumpLine("music", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:pan_track*", true)) {
- tryToDumpLine("pan_track", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:playpreload*", true)) {
- tryToDumpLine("playpreload", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:preferences*", true)) {
- tryToDumpLine("preferences", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:quit*", true)) {
- tryToDumpLine("quit", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:random*", true)) {
- tryToDumpLine("random", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:region*", true)) {
- tryToDumpLine("region", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:restore_game*", true)) {
- tryToDumpLine("restore_game", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:rotate_to*", true)) {
- tryToDumpLine("rotate_to", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:save_game*", true)) {
- tryToDumpLine("save_game", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:set_partial_screen*", true)) {
- tryToDumpLine("set_partial_screen", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:set_screen*", true)) {
- tryToDumpLine("set_screen", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:set_venus*", true)) {
- tryToDumpLine("set_venus", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:stop*", true)) {
- tryToDumpLine("stop", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:streamvideo*", true)) {
- tryToDumpLine("streamvideo", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:syncsound*", true)) {
- tryToDumpLine("syncsound", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:timer*", true)) {
- tryToDumpLine("timer", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:ttytext*", true)) {
- tryToDumpLine("ttytext", line, &count, &fileAlreadyUsed, output);
- } else if (line.matchString("*:universe_music*", true)) {
- tryToDumpLine("universe_music", line, &count, &fileAlreadyUsed, output);
- }
-
- line = stream->readLine();
- trimCommentsAndWhiteSpace(&line);
- }
-
- for (Common::HashMap<Common::String, bool>::iterator fileUsedIter = fileAlreadyUsed.begin(); fileUsedIter != fileAlreadyUsed.end(); ++fileUsedIter) {
- fileUsedIter->_value = false;
- }
- }
-
- output.close();
-}
-
-Common::String getFileName(const Common::String &fullPath) {
- Common::StringTokenizer tokenizer(fullPath, "/\\");
- Common::String token;
- while (!tokenizer.empty()) {
- token = tokenizer.nextToken();
- }
-
- return token;
-}
-
-void convertRawToWav(const Common::String &inputFile, ZVision *engine, const Common::String &outputFile) {
- Common::File file;
- if (!file.open(inputFile))
- return;
-
- Audio::AudioStream *audioStream = makeRawZorkStream(inputFile, engine);
-
- Common::DumpFile output;
- output.open(outputFile);
-
- output.writeUint32BE(MKTAG('R', 'I', 'F', 'F'));
- output.writeUint32LE(file.size() * 2 + 36);
- output.writeUint32BE(MKTAG('W', 'A', 'V', 'E'));
- output.writeUint32BE(MKTAG('f', 'm', 't', ' '));
- output.writeUint32LE(16);
- output.writeUint16LE(1);
- uint16 numChannels;
- if (audioStream->isStereo()) {
- numChannels = 2;
- output.writeUint16LE(2);
- } else {
- numChannels = 1;
- output.writeUint16LE(1);
- }
- output.writeUint32LE(audioStream->getRate());
- output.writeUint32LE(audioStream->getRate() * numChannels * 2);
- output.writeUint16LE(numChannels * 2);
- output.writeUint16LE(16);
- output.writeUint32BE(MKTAG('d', 'a', 't', 'a'));
- output.writeUint32LE(file.size() * 2);
- int16 *buffer = new int16[file.size()];
- audioStream->readBuffer(buffer, file.size());
- output.write(buffer, file.size() * 2);
-
- delete[] buffer;
-}
-
-} // End of namespace ZVision
diff --git a/engines/zvision/utility/utility.h b/engines/zvision/utility/utility.h
deleted file mode 100644
index 063d4c0663..0000000000
--- a/engines/zvision/utility/utility.h
+++ /dev/null
@@ -1,114 +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.
- *
- */
-
-#ifndef ZVISION_UTILITY_H
-#define ZVISION_UTILITY_H
-
-#include "common/array.h"
-
-
-namespace Common {
-class String;
-}
-
-namespace ZVision {
-
-class ZVision;
-
-/**
- * Opens the sourceFile utilizing Common::File (aka SearchMan) and writes the
- * contents to destFile. destFile is created in the working directory
- *
- * @param sourceFile The 'file' you want the contents of
- * @param destFile The name of the file where the content will be written to
- */
-void writeFileContentsToFile(const Common::String &sourceFile, const Common::String &destFile);
-
-/**
- * Removes any line comments using '#' as a sequence start.
- * Then removes any trailing and leading 'whitespace' using String::trim()
- * Note: String::trim uses isspace() to determine what is whitespace and what is not.
- *
- * @param string The string to modify. It is modified in place
- */
-void trimCommentsAndWhiteSpace(Common::String *string);
-
-/**
- * Searches through all the .scr files and dumps 'numberOfExamplesPerType' examples of each type of ResultAction
- * ZVision::initialize() must have been called before this function can be used.
- *
- * @param destFile Where to write the examples
- */
-void dumpEveryResultAction(const Common::String &destFile);
-
-/**
- * Removes all duplicate entries from container. Relative order will be preserved.
- *
- * @param container The Array to remove duplicate entries from
- */
-template<class T>
-void removeDuplicateEntries(Common::Array<T> &container) {
- // Length of modified array
- uint newLength = 1;
- uint j;
-
- for(uint i = 1; i < container.size(); i++) {
- for(j = 0; j < newLength; j++) {
- if (container[i] == container[j]) {
- break;
- }
- }
-
- // If none of the values in index[0..j] of container are the same as array[i],
- // then copy the current value to corresponding new position in array
- if (j == newLength) {
- container[newLength++] = container[i];
- }
- }
-
- // Actually remove the unneeded space
- while (container.size() < newLength) {
- container.pop_back();
- }
-}
-
-/**
- * Gets the name of the file (including extension). Forward or back slashes
- * are interpreted as directory changes
- *
- * @param fullPath A full or partial path to the file. Ex: folderOne/folderTwo/file.txt
- * @return The name of the file without any preceding directories. Ex: file.txt
- */
-Common::String getFileName(const Common::String &fullPath);
-
-/**
- * Converts a ZVision .RAW file to a .WAV
- * The .WAV will be created in the working directory and will overwrite any existing file
- *
- * @param inputFile The path to the input .RAW file
- * @param outputFile The name of the output .WAV file
- */
-void convertRawToWav(const Common::String &inputFile, ZVision *engine, const Common::String &outputFile);
-
-} // End of namespace ZVision
-
-#endif
diff --git a/engines/zvision/video/rlf_decoder.cpp b/engines/zvision/video/rlf_decoder.cpp
new file mode 100644
index 0000000000..3bbf22edff
--- /dev/null
+++ b/engines/zvision/video/rlf_decoder.cpp
@@ -0,0 +1,313 @@
+/* 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 "zvision/video/rlf_decoder.h"
+
+#include "common/str.h"
+#include "common/file.h"
+#include "common/textconsole.h"
+#include "common/debug.h"
+#include "common/endian.h"
+
+namespace ZVision {
+
+RLFDecoder::~RLFDecoder() {
+ close();
+}
+
+bool RLFDecoder::loadStream(Common::SeekableReadStream *stream) {
+ close();
+
+ // 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)
+ : _readStream(stream),
+ _lastFrameRead(0),
+ _frameCount(0),
+ _width(0),
+ _height(0),
+ _frameTime(0),
+ _frames(0),
+ _displayedFrame(-1),
+ _frameBufferByteSize(0) {
+
+ if (!readHeader()) {
+ warning("Not a RLF animation file. Wrong magic number");
+ return;
+ }
+
+ _currentFrameBuffer.create(_width, _height, getPixelFormat());
+ _frameBufferByteSize = _width * _height * sizeof(uint16);
+
+ _frames = new Frame[_frameCount];
+
+ // Read in each frame
+ for (uint i = 0; i < _frameCount; ++i) {
+ _frames[i] = readNextFrame();
+ }
+}
+
+RLFDecoder::RLFVideoTrack::~RLFVideoTrack() {
+ for (uint i = 0; i < _frameCount; ++i) {
+ delete[] _frames[i].encodedData;
+ }
+ delete[] _frames;
+ delete _readStream;
+ _currentFrameBuffer.free();
+}
+
+bool RLFDecoder::RLFVideoTrack::readHeader() {
+ // Read the header
+ _readStream->readUint32LE(); // Size1
+ _readStream->readUint32LE(); // Unknown1
+ _readStream->readUint32LE(); // Unknown2
+ _frameCount = _readStream->readUint32LE(); // Frame count
+
+ // Since we don't need any of the data, we can just seek right to the
+ // entries we need rather than read in all the individual entries.
+ _readStream->seek(136, SEEK_CUR);
+
+ //// Read CIN header
+ //_readStream->readUint32BE(); // Magic number FNIC
+ //_readStream->readUint32LE(); // Size2
+ //_readStream->readUint32LE(); // Unknown3
+ //_readStream->readUint32LE(); // Unknown4
+ //_readStream->readUint32LE(); // Unknown5
+ //_readStream->seek(0x18, SEEK_CUR); // VRLE
+ //_readStream->readUint32LE(); // LRVD
+ //_readStream->readUint32LE(); // Unknown6
+ //_readStream->seek(0x18, SEEK_CUR); // HRLE
+ //_readStream->readUint32LE(); // ELHD
+ //_readStream->readUint32LE(); // Unknown7
+ //_readStream->seek(0x18, SEEK_CUR); // HKEY
+ //_readStream->readUint32LE(); // ELRH
+
+ //// Read MIN info header
+ //_readStream->readUint32BE(); // Magic number FNIM
+ //_readStream->readUint32LE(); // Size3
+ //_readStream->readUint32LE(); // OEDV
+ //_readStream->readUint32LE(); // Unknown8
+ //_readStream->readUint32LE(); // Unknown9
+ //_readStream->readUint32LE(); // Unknown10
+ _width = _readStream->readUint32LE(); // Width
+ _height = _readStream->readUint32LE(); // Height
+
+ // Read time header
+ _readStream->readUint32BE(); // Magic number EMIT
+ _readStream->readUint32LE(); // Size4
+ _readStream->readUint32LE(); // Unknown11
+ _frameTime = _readStream->readUint32LE() / 10; // Frame time in microseconds
+
+ return true;
+}
+
+RLFDecoder::RLFVideoTrack::Frame RLFDecoder::RLFVideoTrack::readNextFrame() {
+ RLFDecoder::RLFVideoTrack::Frame frame;
+
+ _readStream->readUint32BE(); // Magic number MARF
+ uint32 size = _readStream->readUint32LE(); // Size
+ _readStream->readUint32LE(); // Unknown1
+ _readStream->readUint32LE(); // Unknown2
+ uint32 type = _readStream->readUint32BE(); // Either ELHD or ELRH
+ uint32 headerSize = _readStream->readUint32LE(); // Offset from the beginning of this frame to the frame data. Should always be 28
+ _readStream->readUint32LE(); // Unknown3
+
+ frame.encodedSize = size - headerSize;
+ frame.encodedData = new int8[frame.encodedSize];
+ _readStream->read(frame.encodedData, frame.encodedSize);
+
+ if (type == MKTAG('E', 'L', 'H', 'D')) {
+ frame.type = Masked;
+ } else if (type == MKTAG('E', 'L', 'R', 'H')) {
+ frame.type = Simple;
+ _completeFrames.push_back(_lastFrameRead);
+ } else {
+ warning("Frame %u doesn't have type that can be decoded", _lastFrameRead);
+ }
+
+ _lastFrameRead++;
+ return frame;
+}
+
+bool RLFDecoder::RLFVideoTrack::seek(const Audio::Timestamp &time) {
+ uint frame = getFrameAtTime(time);
+ assert(frame < _frameCount);
+
+ if ((uint)_displayedFrame == frame)
+ return true;
+
+ int closestFrame = _displayedFrame;
+ int distance = (int)frame - closestFrame;
+
+ if (distance < 0) {
+ for (uint i = 0; i < _completeFrames.size(); ++i) {
+ if (_completeFrames[i] > frame)
+ break;
+ closestFrame = _completeFrames[i];
+ }
+ } else {
+ for (uint i = 0; i < _completeFrames.size(); ++i) {
+ int newDistance = (int)frame - (int)(_completeFrames[i]);
+ if (newDistance < 0)
+ break;
+ if (newDistance < distance) {
+ closestFrame = _completeFrames[i];
+ distance = newDistance;
+ }
+ }
+ }
+
+ for (uint i = closestFrame; i < frame; ++i) {
+ applyFrameToCurrent(i);
+ }
+
+ _displayedFrame = frame - 1;
+
+ return true;
+}
+
+const Graphics::Surface *RLFDecoder::RLFVideoTrack::decodeNextFrame() {
+ if (_displayedFrame >= (int)_frameCount)
+ return NULL;
+
+ _displayedFrame++;
+ applyFrameToCurrent(_displayedFrame);
+
+ return &_currentFrameBuffer;
+}
+
+void RLFDecoder::RLFVideoTrack::applyFrameToCurrent(uint frameNumber) {
+ if (_frames[frameNumber].type == Masked) {
+ decodeMaskedRunLengthEncoding(_frames[frameNumber].encodedData, (int8 *)_currentFrameBuffer.getPixels(), _frames[frameNumber].encodedSize, _frameBufferByteSize);
+ } else if (_frames[frameNumber].type == Simple) {
+ decodeSimpleRunLengthEncoding(_frames[frameNumber].encodedData, (int8 *)_currentFrameBuffer.getPixels(), _frames[frameNumber].encodedSize, _frameBufferByteSize);
+ }
+}
+
+void RLFDecoder::RLFVideoTrack::decodeMaskedRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const {
+ uint32 sourceOffset = 0;
+ uint32 destOffset = 0;
+ int16 numberOfCopy = 0;
+
+ while (sourceOffset < sourceSize) {
+ int8 numberOfSamples = source[sourceOffset];
+ sourceOffset++;
+
+ // If numberOfSamples is negative, the next abs(numberOfSamples) samples should
+ // be copied directly from source to dest
+ if (numberOfSamples < 0) {
+ numberOfCopy = -numberOfSamples;
+
+ while (numberOfCopy > 0) {
+ if (sourceOffset + 1 >= sourceSize) {
+ return;
+ } else if (destOffset + 1 >= destSize) {
+ debug(2, "Frame decoding overflow\n\tsourceOffset=%u\tsourceSize=%u\n\tdestOffset=%u\tdestSize=%u", sourceOffset, sourceSize, destOffset, destSize);
+ return;
+ }
+
+ WRITE_UINT16(dest + destOffset, READ_LE_UINT16(source + sourceOffset));
+
+ sourceOffset += 2;
+ destOffset += 2;
+ numberOfCopy--;
+ }
+
+ // If numberOfSamples is >= 0, move destOffset forward ((numberOfSamples * 2) + 2)
+ // This function assumes the dest buffer has been memset with 0's.
+ } else {
+ if (sourceOffset + 1 >= sourceSize) {
+ return;
+ } else if (destOffset + 1 >= destSize) {
+ debug(2, "Frame decoding overflow\n\tsourceOffset=%u\tsourceSize=%u\n\tdestOffset=%u\tdestSize=%u", sourceOffset, sourceSize, destOffset, destSize);
+ return;
+ }
+
+ destOffset += (numberOfSamples * 2) + 2;
+ }
+ }
+}
+
+void RLFDecoder::RLFVideoTrack::decodeSimpleRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const {
+ uint32 sourceOffset = 0;
+ uint32 destOffset = 0;
+ int16 numberOfCopy = 0;
+
+ while (sourceOffset < sourceSize) {
+ int8 numberOfSamples = source[sourceOffset];
+ sourceOffset++;
+
+ // If numberOfSamples is negative, the next abs(numberOfSamples) samples should
+ // be copied directly from source to dest
+ if (numberOfSamples < 0) {
+ numberOfCopy = -numberOfSamples;
+
+ while (numberOfCopy > 0) {
+ if (sourceOffset + 1 >= sourceSize) {
+ return;
+ } else if (destOffset + 1 >= destSize) {
+ debug(2, "Frame decoding overflow\n\tsourceOffset=%u\tsourceSize=%u\n\tdestOffset=%u\tdestSize=%u", sourceOffset, sourceSize, destOffset, destSize);
+ return;
+ }
+
+ WRITE_UINT16(dest + destOffset, READ_LE_UINT16(source + sourceOffset));
+
+ sourceOffset += 2;
+ destOffset += 2;
+ numberOfCopy--;
+ }
+
+ // If numberOfSamples is >= 0, copy one sample from source to the
+ // next (numberOfSamples + 2) dest spots
+ } else {
+ if (sourceOffset + 1 >= sourceSize) {
+ return;
+ }
+
+ uint16 sampleColor = READ_LE_UINT16(source + sourceOffset);
+ sourceOffset += 2;
+
+ numberOfCopy = numberOfSamples + 2;
+ while (numberOfCopy > 0) {
+ if (destOffset + 1 >= destSize) {
+ debug(2, "Frame decoding overflow\n\tsourceOffset=%u\tsourceSize=%u\n\tdestOffset=%u\tdestSize=%u", sourceOffset, sourceSize, destOffset, destSize);
+ return;
+ }
+
+ WRITE_UINT16(dest + destOffset, sampleColor);
+ destOffset += 2;
+ numberOfCopy--;
+ }
+ }
+ }
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/video/rlf_decoder.h b/engines/zvision/video/rlf_decoder.h
new file mode 100644
index 0000000000..8b8cbaecd5
--- /dev/null
+++ b/engines/zvision/video/rlf_decoder.h
@@ -0,0 +1,134 @@
+/* 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_RLF_DECODER_H
+#define ZVISION_RLF_DECODER_H
+
+#include "common/file.h"
+#include "video/video_decoder.h"
+
+#include "graphics/surface.h"
+
+namespace ZVision {
+
+class RLFDecoder : public Video::VideoDecoder {
+public:
+ RLFDecoder() {}
+ ~RLFDecoder();
+
+ bool loadStream(Common::SeekableReadStream *stream);
+
+private:
+ class RLFVideoTrack : public FixedRateVideoTrack {
+ public:
+ RLFVideoTrack(Common::SeekableReadStream *stream);
+ ~RLFVideoTrack();
+
+ uint16 getWidth() const { return _width; }
+ uint16 getHeight() const { return _height; }
+ 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(1000, _frameTime); }
+
+ private:
+ enum EncodingType {
+ Masked,
+ Simple
+ };
+
+ struct Frame {
+ EncodingType type;
+ int8 *encodedData;
+ uint32 encodedSize;
+ };
+
+ /**
+ * Reads in the header of the RLF file
+ *
+ * @return Will return false if the header magic number is wrong
+ */
+ bool readHeader();
+
+ /**
+ * Reads the next frame from the RLF file, stores the data in
+ * a Frame object, then returns the object
+ *
+ * @return A Frame object representing the frame data
+ */
+ Frame readNextFrame();
+
+ /**
+ * Applies the frame corresponding to frameNumber on top of _currentFrameBuffer.
+ * This function requires _stream = false so it can look up the Frame object
+ * referenced by frameNumber.
+ *
+ * @param frameNumber The frame number to apply to _currentFrameBuffer
+ */
+ void applyFrameToCurrent(uint frameNumber);
+
+ /**
+ * Decode frame data that uses masked run length encoding. This is the encoding
+ * used by P-frames.
+ *
+ * @param source The source pixel data
+ * @param dest The destination buffer
+ * @param sourceSize The size of the source pixel data
+ * @param destSize The size of the destination buffer
+ */
+ void decodeMaskedRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const;
+ /**
+ * Decode frame data that uses simple run length encoding. This is the encoding
+ * used by I-frames.
+ *
+ * @param source The source pixel data
+ * @param dest The destination buffer
+ * @param sourceSize The size of the source pixel data
+ * @param destSize The size of the destination buffer
+ */
+ void decodeSimpleRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const;
+
+ uint _lastFrameRead;
+
+ uint _frameCount;
+ uint _width;
+ uint _height;
+ uint32 _frameTime; // In milliseconds
+ Frame *_frames;
+ Common::Array<uint> _completeFrames;
+
+ int _displayedFrame;
+ Graphics::Surface _currentFrameBuffer;
+ uint32 _frameBufferByteSize;
+
+ Common::SeekableReadStream *_readStream;
+ }; // RLFVideoTrack
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/video/video.cpp b/engines/zvision/video/video.cpp
index d1fff30408..1cfd0f4197 100644
--- a/engines/zvision/video/video.cpp
+++ b/engines/zvision/video/video.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,107 +21,78 @@
*/
#include "common/scummsys.h"
-
-#include "zvision/zvision.h"
-
-#include "zvision/utility/clock.h"
-#include "zvision/graphics/render_manager.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/scripting/script_manager.h"
+#include "zvision/text/subtitles.h"
+#include "zvision/video/rlf_decoder.h"
+#include "zvision/video/zork_avi_decoder.h"
namespace ZVision {
-// Taken/modified from SCI
-void scaleBuffer(const byte *src, byte *dst, uint32 srcWidth, uint32 srcHeight, byte bytesPerPixel, uint scaleAmount) {
- assert(bytesPerPixel == 1 || bytesPerPixel == 2);
-
- const uint32 newWidth = srcWidth * scaleAmount;
- const uint32 pitch = newWidth * bytesPerPixel;
- const byte *srcPtr = src;
-
- if (bytesPerPixel == 1) {
- for (uint32 y = 0; y < srcHeight; ++y) {
- for (uint32 x = 0; x < srcWidth; ++x) {
- const byte color = *srcPtr++;
-
- for (uint i = 0; i < scaleAmount; ++i) {
- dst[i] = color;
- dst[pitch + i] = color;
- }
- dst += scaleAmount;
- }
- dst += pitch;
- }
- } else if (bytesPerPixel == 2) {
- for (uint32 y = 0; y < srcHeight; ++y) {
- for (uint32 x = 0; x < srcWidth; ++x) {
- const byte color = *srcPtr++;
- const byte color2 = *srcPtr++;
-
- for (uint i = 0; i < scaleAmount; ++i) {
- uint index = i *2;
-
- dst[index] = color;
- dst[index + 1] = color2;
- dst[pitch + index] = color;
- dst[pitch + index + 1] = color2;
- }
- dst += 2 * scaleAmount;
- }
- dst += pitch;
- }
- }
+Video::VideoDecoder *ZVision::loadAnimation(const Common::String &fileName) {
+ Common::String tmpFileName = fileName;
+ tmpFileName.toLowercase();
+ Video::VideoDecoder *animation = NULL;
+
+ if (tmpFileName.hasSuffix(".rlf"))
+ 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);
+ 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;
}
-void ZVision::playVideo(Video::VideoDecoder &videoDecoder, const Common::Rect &destRect, bool skippable) {
- byte bytesPerPixel = videoDecoder.getPixelFormat().bytesPerPixel;
-
- uint16 origWidth = videoDecoder.getWidth();
- uint16 origHeight = videoDecoder.getHeight();
-
- uint scale = 1;
+void ZVision::playVideo(Video::VideoDecoder &vid, const Common::Rect &destRect, bool skippable, Subtitle *sub) {
+ Common::Rect dst = destRect;
// If destRect is empty, no specific scaling was requested. However, we may choose to do scaling anyway
- if (destRect.isEmpty()) {
- // Most videos are very small. Therefore we do a simple 2x scale
- if (origWidth * 2 <= 640 && origHeight * 2 <= 480) {
- scale = 2;
- }
- } else {
- // Assume bilinear scaling. AKA calculate the scale from just the width.
- // Also assume that the scaling is in integral intervals. AKA no 1.5x scaling
- // TODO: Test ^these^ assumptions
- scale = destRect.width() / origWidth;
-
- // TODO: Test if we need to support downscale.
- }
-
- uint16 pitch = origWidth * bytesPerPixel;
+ if (dst.isEmpty())
+ dst = Common::Rect(vid.getWidth(), vid.getHeight());
- uint16 finalWidth = origWidth * scale;
- uint16 finalHeight = origHeight * scale;
+ Graphics::Surface *scaled = NULL;
- byte *scaledVideoFrameBuffer = 0;
- if (scale != 1) {
- scaledVideoFrameBuffer = new byte[finalWidth * finalHeight * bytesPerPixel];
+ if (vid.getWidth() != dst.width() || vid.getHeight() != dst.height()) {
+ scaled = new Graphics::Surface;
+ scaled->create(dst.width(), dst.height(), vid.getPixelFormat());
}
- uint16 x = ((WINDOW_WIDTH - finalWidth) / 2) + destRect.left;
- uint16 y = ((WINDOW_HEIGHT - finalHeight) / 2) + destRect.top;
+ uint16 x = _workingWindow.left + dst.left;
+ 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();
- videoDecoder.start();
+ vid.start();
+ _videoIsPlaying = true;
// Only continue while the video is still playing
- while (!shouldQuit() && !videoDecoder.endOfVideo() && videoDecoder.isPlaying()) {
+ while (!shouldQuit() && !vid.endOfVideo() && vid.isPlaying()) {
// Check for engine quit and video stop key presses
- while (!videoDecoder.endOfVideo() && videoDecoder.isPlaying() && _eventMan->pollEvent(_event)) {
+ while (_eventMan->pollEvent(_event)) {
switch (_event.type) {
case Common::EVENT_KEYDOWN:
switch (_event.kbd.keycode) {
@@ -131,7 +102,7 @@ void ZVision::playVideo(Video::VideoDecoder &videoDecoder, const Common::Rect &d
break;
case Common::KEYCODE_SPACE:
if (skippable) {
- videoDecoder.stop();
+ vid.stop();
}
break;
default:
@@ -142,29 +113,34 @@ void ZVision::playVideo(Video::VideoDecoder &videoDecoder, const Common::Rect &d
}
}
- if (videoDecoder.needsUpdate()) {
- const Graphics::Surface *frame = videoDecoder.decodeNextFrame();
+ if (vid.needsUpdate()) {
+ const Graphics::Surface *frame = vid.decodeNextFrame();
+ if (sub && showSubs)
+ sub->process(vid.getCurFrame());
if (frame) {
- if (scale != 1) {
- scaleBuffer((const byte *)frame->getPixels(), scaledVideoFrameBuffer, origWidth, origHeight, bytesPerPixel, scale);
- _system->copyRectToScreen(scaledVideoFrameBuffer, pitch * 2, x, y, finalWidth, finalHeight);
- } else {
- _system->copyRectToScreen((const byte *)frame->getPixels(), pitch, x, y, finalWidth, finalHeight);
+ if (scaled) {
+ _renderManager->scaleBuffer(frame->getPixels(), scaled->getPixels(), frame->w, frame->h, frame->format.bytesPerPixel, scaled->w, scaled->h);
+ frame = scaled;
}
+ Common::Rect rect = Common::Rect(x, y, x + finalWidth, y + finalHeight);
+ _renderManager->copyToScreen(*frame, rect, 0, 0);
+ _renderManager->processSubs(0);
}
}
// Always update the screen so the mouse continues to render
_system->updateScreen();
- _system->delayMillis(videoDecoder.getTimeToNextFrame());
+ _system->delayMillis(vid.getTimeToNextFrame() / 2);
}
+ _videoIsPlaying = false;
_clock.start();
- if (scale != 1) {
- delete[] scaledVideoFrameBuffer;
+ if (scaled) {
+ scaled->free();
+ delete scaled;
}
}
diff --git a/engines/zvision/video/zork_avi_decoder.cpp b/engines/zvision/video/zork_avi_decoder.cpp
index f22a4203ab..cf8505ec82 100644
--- a/engines/zvision/video/zork_avi_decoder.cpp
+++ b/engines/zvision/video/zork_avi_decoder.cpp
@@ -29,7 +29,7 @@
#include "common/stream.h"
#include "audio/audiostream.h"
-
+#include "audio/decoders/raw.h"
namespace ZVision {
@@ -39,14 +39,39 @@ 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);
- _audStream->queueAudioStream(makeRawZorkStream(stream, _wvInfo.samplesPerSec, _audStream->isStereo(), DisposeAfterUse::YES), DisposeAfterUse::YES);
+ RawChunkStream::RawChunk chunk = decoder->readNextChunk(stream);
+ delete stream;
+
+ 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++;
+ }
+}
+
+void ZorkAVIDecoder::ZorkAVIAudioTrack::resetStream() {
+ decoder->init();
}
} // End of namespace ZVision
diff --git a/engines/zvision/video/zork_avi_decoder.h b/engines/zvision/video/zork_avi_decoder.h
index c47f007f9b..89c0d1e4b9 100644
--- a/engines/zvision/video/zork_avi_decoder.h
+++ b/engines/zvision/video/zork_avi_decoder.h
@@ -8,41 +8,53 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
- *
+
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+
* You should have received a copy of the GNU General Public 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 ZORK_AVI_DECODER_H
#define ZORK_AVI_DECODER_H
#include "video/avi_decoder.h"
-
+#include "zvision/sound/zork_raw.h"
namespace ZVision {
class ZorkAVIDecoder : public Video::AVIDecoder {
public:
ZorkAVIDecoder(Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType) :
- Video::AVIDecoder(soundType) {}
+ Video::AVIDecoder(soundType) {}
- virtual ~ZorkAVIDecoder() {}
+ virtual ~ZorkAVIDecoder() {}
private:
class ZorkAVIAudioTrack : public Video::AVIDecoder::AVIAudioTrack {
public:
ZorkAVIAudioTrack(const AVIStreamHeader &streamHeader, const PCMWaveFormat &waveFormat, Audio::Mixer::SoundType soundType) :
- Video::AVIDecoder::AVIAudioTrack(streamHeader, waveFormat, soundType) {}
- virtual ~ZorkAVIAudioTrack() {}
+ Video::AVIDecoder::AVIAudioTrack(streamHeader, waveFormat, soundType),
+ decoder(NULL) {
+ if (_audStream) {
+ decoder = new RawChunkStream(_audStream->isStereo());
+ }
+ }
+ virtual ~ZorkAVIAudioTrack() {
+ if (decoder)
+ delete decoder;
+ }
void queueSound(Common::SeekableReadStream *stream);
+ void resetStream();
+ private:
+ RawChunkStream *decoder;
};
Video::AVIDecoder::AVIAudioTrack *createAudioTrack(Video::AVIDecoder::AVIStreamHeader sHeader, Video::AVIDecoder::PCMWaveFormat wvInfo);
@@ -50,7 +62,7 @@ private:
private:
// Audio Codecs
enum {
- kWaveFormatZorkPCM = 17 // special Zork PCM audio format (clashes with MS IMA ADPCM)
+ kWaveFormatZorkPCM = 17 // special Zork PCM audio format (clashes with MS IMA ADPCM)
};
};
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
index b464f6ee81..da80ff9d02 100644
--- a/engines/zvision/zvision.cpp
+++ b/engines/zvision/zvision.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.
@@ -23,17 +23,22 @@
#include "common/scummsys.h"
#include "zvision/zvision.h"
-
#include "zvision/core/console.h"
#include "zvision/scripting/script_manager.h"
#include "zvision/graphics/render_manager.h"
-#include "zvision/cursors/cursor_manager.h"
-#include "zvision/core/save_manager.h"
-#include "zvision/strings/string_manager.h"
-#include "zvision/archives/zfs_archive.h"
+#include "zvision/graphics/cursors/cursor_manager.h"
+#include "zvision/file/save_manager.h"
+#include "zvision/text/string_manager.h"
#include "zvision/detection.h"
+#include "zvision/scripting/menu.h"
+#include "zvision/file/search_manager.h"
+#include "zvision/text/text.h"
+#include "zvision/text/truetype_font.h"
+#include "zvision/sound/midi.h"
+#include "zvision/file/zfs_archive.h"
#include "common/config-manager.h"
+#include "common/str.h"
#include "common/debug.h"
#include "common/debug-channels.h"
#include "common/textconsole.h"
@@ -41,28 +46,67 @@
#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 12
+
+struct zvisionIniSettings {
+ const char *name;
+ int16 slot;
+ int16 defaultValue; // -1: use the bool value
+ bool defaultBoolValue;
+ bool allowEditing;
+} settingsKeys[ZVISION_SETTINGS_KEYS_COUNT] = {
+ // 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),
- _workingWindow(gameDesc->gameId == GID_NEMESIS ? Common::Rect((WINDOW_WIDTH - ZNEM_WORKING_WINDOW_WIDTH) / 2, (WINDOW_HEIGHT - ZNEM_WORKING_WINDOW_HEIGHT) / 2, ((WINDOW_WIDTH - ZNEM_WORKING_WINDOW_WIDTH) / 2) + ZNEM_WORKING_WINDOW_WIDTH, ((WINDOW_HEIGHT - ZNEM_WORKING_WINDOW_HEIGHT) / 2) + ZNEM_WORKING_WINDOW_HEIGHT) :
- Common::Rect((WINDOW_WIDTH - ZGI_WORKING_WINDOW_WIDTH) / 2, (WINDOW_HEIGHT - ZGI_WORKING_WINDOW_HEIGHT) / 2, ((WINDOW_WIDTH - ZGI_WORKING_WINDOW_WIDTH) / 2) + ZGI_WORKING_WINDOW_WIDTH, ((WINDOW_HEIGHT - ZGI_WORKING_WINDOW_HEIGHT) / 2) + ZGI_WORKING_WINDOW_HEIGHT)),
- _pixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0), /*RGB 565*/
- _desiredFrameTime(33), /* ~30 fps */
- _clock(_system),
- _scriptManager(nullptr),
- _renderManager(nullptr),
- _saveManager(nullptr),
- _stringManager(nullptr),
- _cursorManager(nullptr) {
+ : Engine(syst),
+ _gameDescription(gameDesc),
+ _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),
+ _renderManager(nullptr),
+ _saveManager(nullptr),
+ _stringManager(nullptr),
+ _cursorManager(nullptr),
+ _midiManager(nullptr),
+ _rnd(nullptr),
+ _console(nullptr),
+ _menu(nullptr),
+ _searchManager(nullptr),
+ _textRenderer(nullptr),
+ _doubleFPS(false),
+ _audioId(0),
+ _frameRenderDelay(2),
+ _keyboardVelocity(0),
+ _mouseVelocity(0),
+ _videoIsPlaying(false),
+ _renderedFrameCount(0),
+ _fps(0) {
debug(1, "ZVision::ZVision");
+
+ memset(_cheatBuffer, 0, sizeof(_cheatBuffer));
}
ZVision::~ZVision() {
@@ -73,90 +117,237 @@ 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++) {
+ 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() {
+ 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);
+ else
+ _scriptManager->setStateValue(StateKey_ExecScopeStyle, 0);
+}
+
+void ZVision::saveSettings() {
+ 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();
+}
+
void ZVision::initialize() {
const Common::FSNode gameDataDir(ConfMan.get("path"));
- // TODO: There are 10 file clashes when we flatten the directories.
- // From a quick look, the files are exactly the same, so it shouldn't matter.
- // But I'm noting it here just in-case it does become a problem.
- SearchMan.addSubDirectoryMatching(gameDataDir, "data1", 0, 4, true);
- SearchMan.addSubDirectoryMatching(gameDataDir, "data2", 0, 4, true);
- SearchMan.addSubDirectoryMatching(gameDataDir, "data3", 0, 4, true);
- SearchMan.addSubDirectoryMatching(gameDataDir, "zassets1", 0, 2, true);
- SearchMan.addSubDirectoryMatching(gameDataDir, "zassets2", 0, 2, true);
- SearchMan.addSubDirectoryMatching(gameDataDir, "znemmx", 0, 1, true);
- SearchMan.addSubDirectoryMatching(gameDataDir, "zgi", 0, 4, true);
- SearchMan.addSubDirectoryMatching(gameDataDir, "fonts", 0, 1, true);
-
- // Find zfs archive files
- Common::ArchiveMemberList list;
- SearchMan.listMatchingMembers(list, "*.zfs");
-
- // Register the file entries within the zfs archives with the SearchMan
- for (Common::ArchiveMemberList::iterator iter = list.begin(); iter != list.end(); ++iter) {
- Common::String name = (*iter)->getName();
- Common::SeekableReadStream *stream = (*iter)->createReadStream();
- ZfsArchive *archive = new ZfsArchive(name, stream);
-
- delete stream;
-
- SearchMan.add(name, archive);
+
+ _searchManager = new SearchManager(ConfMan.get("path"), 6);
+
+ _searchManager->addDir("FONTS");
+ _searchManager->addDir("addon");
+
+ if (_gameDescription->gameId == GID_GRANDINQUISITOR) {
+ if (!_searchManager->loadZix("INQUIS.ZIX"))
+ error("Unable to load file INQUIS.ZIX");
+ } else if (_gameDescription->gameId == 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");
+ }
}
- initGraphics(WINDOW_WIDTH, WINDOW_HEIGHT, true, &_pixelFormat);
+ initScreen();
// Register random source
_rnd = new Common::RandomSource("zvision");
// Create managers
_scriptManager = new ScriptManager(this);
- _renderManager = new RenderManager(_system, 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)
+ _menu = new MenuZGI(this);
+ else
+ _menu = new MenuNemesis(this);
// Initialize the managers
_cursorManager->initialize();
_scriptManager->initialize();
_stringManager->initialize(_gameDescription->gameId);
+ 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);
+ _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();
+ // Check if a saved game is to be loaded from the launcher
+ 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();
uint32 currentTime = _clock.getLastMeasuredTime();
uint32 deltaTime = _clock.getDeltaTime();
+ _cursorManager->setItemID(_scriptManager->getStateValue(StateKey_InventoryItem));
+
processEvents();
+ _renderManager->updateRotation();
- // Call _renderManager->update() first so the background renders
- // before anything that puzzles/controls will render
- _renderManager->update(deltaTime);
_scriptManager->update(deltaTime);
+ _menu->process(deltaTime);
// Render the backBuffer to the screen
- _renderManager->renderBackbufferToScreen();
+ _renderManager->prepareBackground();
+ _renderManager->renderMenuToScreen();
+ _renderManager->processSubs(deltaTime);
+ _renderManager->renderSceneToScreen();
// Update the screen
- _system->updateScreen();
+ if (canRender()) {
+ _system->updateScreen();
+ _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 (_doubleFPS) {
+ delay >>= 1;
+ }
+
+ if (canSaveGameStateCurrently() && shouldPerformAutoSave(_saveManager->getLastSaveTime())) {
+ _saveManager->autoSave();
+ }
+
_system->delayMillis(delay);
}
@@ -174,11 +365,53 @@ void ZVision::pauseEngineIntern(bool pause) {
}
Common::String ZVision::generateSaveFileName(uint slot) {
- return Common::String::format("%s.%02u", _targetName.c_str(), slot);
+ return Common::String::format("%s.%03u", _targetName.c_str(), slot);
+}
+
+void ZVision::setRenderDelay(uint delay) {
+ _frameRenderDelay = delay;
}
-Common::String ZVision::generateAutoSaveFileName() {
- return Common::String::format("%s.auto", _targetName.c_str());
+bool ZVision::canRender() {
+ return _frameRenderDelay <= 0;
+}
+
+GUI::Debugger *ZVision::getDebugger() {
+ return _console;
+}
+
+void ZVision::syncSoundSettings() {
+ Engine::syncSoundSettings();
+
+ _scriptManager->setStateValue(StateKey_Subtitles, ConfMan.getBool("subtitles") ? 1 : 0);
+}
+
+void ZVision::fpsTimerCallback(void *refCon) {
+ ((ZVision *)refCon)->fpsTimer();
+}
+
+void ZVision::fpsTimer() {
+ _fps = _renderedFrameCount;
+ _renderedFrameCount = 0;
+}
+
+void ZVision::initScreen() {
+ uint16 workingWindowWidth = (_gameDescription->gameId == GID_NEMESIS) ? ZNM_WORKING_WINDOW_WIDTH : ZGI_WORKING_WINDOW_WIDTH;
+ uint16 workingWindowHeight = (_gameDescription->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
+ );
+
+ initGraphics(WINDOW_WIDTH, WINDOW_HEIGHT, true, &_screenPixelFormat);
+}
+
+void ZVision::initHiresScreen() {
+ _renderManager->upscaleRect(_workingWindow);
+
+ 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 0b5a86f370..854cd77bb8 100644
--- a/engines/zvision/zvision.h
+++ b/engines/zvision/zvision.h
@@ -8,24 +8,25 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
- *
+
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+
* You should have received a copy of the GNU General Public 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_ZVISION_H
#define ZVISION_ZVISION_H
-#include "zvision/core/console.h"
#include "zvision/detection.h"
-#include "zvision/utility/clock.h"
+#include "zvision/core/clock.h"
+#include "zvision/file/search_manager.h"
#include "common/random.h"
#include "common/events.h"
@@ -36,20 +37,56 @@
#include "gui/debugger.h"
-
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;
+class Console;
class ScriptManager;
class RenderManager;
class CursorManager;
class StringManager;
class SaveManager;
-class RlfAnimation;
+class RLFDecoder;
+class MenuHandler;
+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
+};
class ZVision : public Engine {
public:
@@ -62,26 +99,11 @@ public:
* are given in this coordinate space. Also, all images are clipped to the
* edges of this Rectangle
*/
- const Common::Rect _workingWindow;
- const Graphics::PixelFormat _pixelFormat;
+ Common::Rect _workingWindow;
+ const Graphics::PixelFormat _resourcePixelFormat;
+ const Graphics::PixelFormat _screenPixelFormat;
private:
- enum {
- WINDOW_WIDTH = 640,
- WINDOW_HEIGHT = 480,
-
- //Zork nemesis working window sizes
- ZNEM_WORKING_WINDOW_WIDTH = 512,
- ZNEM_WORKING_WINDOW_HEIGHT = 320,
-
- //ZGI(and default) 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
- };
-
Console *_console;
const ZVisionGameDescription *_gameDescription;
@@ -96,27 +118,87 @@ private:
CursorManager *_cursorManager;
SaveManager *_saveManager;
StringManager *_stringManager;
+ MenuHandler *_menu;
+ SearchManager *_searchManager;
+ TextRenderer *_textRenderer;
+ MidiManager *_midiManager;
// Clock
Clock _clock;
+ // Audio ID
+ int _audioId;
+
// To prevent allocation every time we process events
Common::Event _event;
+ int _frameRenderDelay;
+ int _renderedFrameCount;
+ int _fps;
+ int16 _mouseVelocity;
+ int16 _keyboardVelocity;
+ bool _doubleFPS;
+ bool _videoIsPlaying;
+
+ uint8 _cheatBuffer[KEYBUF_SIZE];
public:
uint32 getFeatures() const;
Common::Language getLanguage() const;
Common::Error run();
void pauseEngineIntern(bool pause);
- ScriptManager *getScriptManager() const { return _scriptManager; }
- RenderManager *getRenderManager() const { return _renderManager; }
- CursorManager *getCursorManager() const { return _cursorManager; }
- SaveManager *getSaveManager() const { return _saveManager; }
- StringManager *getStringManager() const { return _stringManager; }
- Common::RandomSource *getRandomSource() const { return _rnd; }
- ZVisionGameId getGameId() const { return _gameDescription->gameId; }
- GUI::Debugger *getDebugger() { return _console; }
+ ScriptManager *getScriptManager() const {
+ return _scriptManager;
+ }
+ RenderManager *getRenderManager() const {
+ return _renderManager;
+ }
+ CursorManager *getCursorManager() const {
+ return _cursorManager;
+ }
+ SaveManager *getSaveManager() const {
+ return _saveManager;
+ }
+ StringManager *getStringManager() const {
+ return _stringManager;
+ }
+ SearchManager *getSearchManager() const {
+ return _searchManager;
+ }
+ TextRenderer *getTextRenderer() const {
+ return _textRenderer;
+ }
+ 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
@@ -127,11 +209,33 @@ public:
* @param destRect Where to put the video. (In working window coords)
* @param skippable If true, the video can be skipped at any time using [Spacebar]
*/
- void playVideo(Video::VideoDecoder &videoDecoder, const Common::Rect &destRect = Common::Rect(0, 0, 0, 0), bool skippable = true);
+ 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);
Common::String generateSaveFileName(uint slot);
- Common::String generateAutoSaveFileName();
+ 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();
+
+ bool ifQuit();
+
+ // 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();
@@ -141,9 +245,15 @@ private:
/** Called every frame from ZVision::run() to process any events from EventMan */
void processEvents();
- void onMouseDown(const Common::Point &pos);
- void onMouseUp(const Common::Point &pos);
void onMouseMove(const Common::Point &pos);
+
+ void registerDefaultSettings();
+ void shortKeys(Common::Event);
+
+ void cheatCodes(uint8 key);
+ void pushKeyToCheatBuf(uint8 key);
+ bool checkCode(const char *code);
+ uint8 getBufferedKey(uint8 pos);
};
} // End of namespace ZVision
diff --git a/graphics/VectorRenderer.h b/graphics/VectorRenderer.h
index 703da68182..6b657f758d 100644
--- a/graphics/VectorRenderer.h
+++ b/graphics/VectorRenderer.h
@@ -105,7 +105,7 @@ VectorRenderer *createRenderer(int mode);
*/
class VectorRenderer {
public:
- VectorRenderer() : _activeSurface(NULL), _fillMode(kFillDisabled), _shadowOffset(0), _shadowFillMode(kShadowExponential),
+ VectorRenderer() : _activeSurface(NULL), _fillMode(kFillDisabled), _shadowOffset(0), _shadowFillMode(kShadowExponential),
_disableShadows(false), _strokeWidth(1), _gradientFactor(1) {
}
diff --git a/graphics/VectorRendererSpec.cpp b/graphics/VectorRendererSpec.cpp
index a9594f7dd2..81a0c04441 100644
--- a/graphics/VectorRendererSpec.cpp
+++ b/graphics/VectorRendererSpec.cpp
@@ -1134,7 +1134,7 @@ void VectorRendererSpec<PixelType>::
drawTabShadow(int x1, int y1, int w, int h, int r) {
int offset = 3;
int pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel;
-
+
// "Harder" shadows when having lower BPP, since we will have artifacts (greenish tint on the modern theme)
uint8 expFactor = 3;
uint16 alpha = (_activeSurface->format.bytesPerPixel > 2) ? 4 : 8;
@@ -1162,7 +1162,7 @@ drawTabShadow(int x1, int y1, int w, int h, int r) {
// this is ok on filled circles, but when blending on surfaces,
// we cannot let it blend twice. awful.
uint32 hb = 0;
-
+
while (x++ < y) {
BE_ALGORITHM();
@@ -1176,7 +1176,7 @@ drawTabShadow(int x1, int y1, int w, int h, int r) {
hb |= (1 << y);
}
}
-
+
ptr_fill += pitch * r;
while (short_h--) {
blendFill(ptr_fill, ptr_fill + width + 1, color, (uint8)alpha);
@@ -1189,7 +1189,7 @@ drawTabShadow(int x1, int y1, int w, int h, int r) {
alpha = (alpha * (expFactor << 8)) >> 9;
}
}
-
+
/** BEVELED TABS FOR CLASSIC THEME **/
template<typename PixelType>
void VectorRendererSpec<PixelType>::
@@ -1647,7 +1647,7 @@ drawBorderRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color,
BE_RESET();
r--;
-
+
int alphaStep_tr = ((alpha_t - alpha_r)/(y+1));
int alphaStep_br = ((alpha_r - alpha_b)/(y+1));
int alphaStep_bl = ((alpha_b - alpha_l)/(y+1));
@@ -1657,16 +1657,16 @@ drawBorderRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color,
while (x++ < (y - 2)) {
BE_ALGORITHM();
- BE_DRAWCIRCLE_BCOLOR_TR_CW(ptr_tr, x, y, px, py, (uint8)(alpha_r + (alphaStep_tr * x)));
+ BE_DRAWCIRCLE_BCOLOR_TR_CW(ptr_tr, x, y, px, py, (uint8)(alpha_r + (alphaStep_tr * x)));
BE_DRAWCIRCLE_BCOLOR_BR_CW(ptr_br, x, y, px, py, (uint8)(alpha_b + (alphaStep_br * x)));
BE_DRAWCIRCLE_BCOLOR_BL_CW(ptr_bl, x, y, px, py, (uint8)(alpha_l + (alphaStep_bl * x)));
BE_DRAWCIRCLE_BCOLOR_TL_CW(ptr_tl, x, y, px, py, (uint8)(alpha_t + (alphaStep_tl * x)));
-
+
BE_DRAWCIRCLE_BCOLOR_TR_CCW(ptr_tr, x, y, px, py, (uint8)(alpha_t - (alphaStep_tr * x)));
BE_DRAWCIRCLE_BCOLOR_BR_CCW(ptr_br, x, y, px, py, (uint8)(alpha_r - (alphaStep_br * x)));
BE_DRAWCIRCLE_BCOLOR_BL_CCW(ptr_bl, x, y, px, py, (uint8)(alpha_b - (alphaStep_bl * x)));
BE_DRAWCIRCLE_BCOLOR_TL_CCW(ptr_tl, x, y, px, py, (uint8)(alpha_l - (alphaStep_tl * x)));
-
+
if (Base::_strokeWidth > 1) {
BE_DRAWCIRCLE_BCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x - 1, y, px, py);
BE_DRAWCIRCLE_BCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px - pitch, py);
@@ -1754,7 +1754,7 @@ void VectorRendererSpec<PixelType>::
drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m) {
const uint8 borderAlpha_t = 0;
const uint8 borderAlpha_r = 127;
- const uint8 borderAlpha_b = 255;
+ const uint8 borderAlpha_b = 255;
const uint8 borderAlpha_l = 63;
const uint8 bevelAlpha_t = 255;
@@ -1876,7 +1876,7 @@ drawRoundedSquareShadow(int x1, int y1, int r, int w, int h, int offset) {
// "Harder" shadows when having lower BPP, since we will have artifacts (greenish tint on the modern theme)
uint8 expFactor = 3;
uint16 alpha = (_activeSurface->format.bytesPerPixel > 2) ? 4 : 8;
-
+
// These constants ensure a border of 2px on the left and of each rounded square
int xstart = (x1 > 2) ? x1 - 2 : x1;
int ystart = y1;
@@ -1886,7 +1886,7 @@ drawRoundedSquareShadow(int x1, int y1, int r, int w, int h, int offset) {
for (int i = offset; i >= 0; i--) {
int f, ddF_x, ddF_y;
int x, y, px, py;
-
+
PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(xstart + r, ystart + r);
PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(xstart + width - r, ystart + r);
PixelType *ptr_bl = (PixelType *)Base::_activeSurface->getBasePtr(xstart + r, ystart + height - r);
@@ -1903,14 +1903,14 @@ drawRoundedSquareShadow(int x1, int y1, int r, int w, int h, int offset) {
// this is ok on filled circles, but when blending on surfaces,
// we cannot let it blend twice. awful.
uint32 hb = 0;
-
+
while (x++ < y) {
BE_ALGORITHM();
if (((1 << x) & hb) == 0) {
blendFill(ptr_tl - y - px, ptr_tr + y - px, color, (uint8)alpha);
-
+
// Will create a dark line of pixles if left out
if (hb > 0) {
blendFill(ptr_bl - y + px, ptr_br + y + px, color, (uint8)alpha);
@@ -1924,7 +1924,7 @@ drawRoundedSquareShadow(int x1, int y1, int r, int w, int h, int offset) {
hb |= (1 << y);
}
}
-
+
ptr_fill += pitch * r;
while (short_h--) {
blendFill(ptr_fill, ptr_fill + width + 1, color, (uint8)alpha);
@@ -1936,7 +1936,7 @@ drawRoundedSquareShadow(int x1, int y1, int r, int w, int h, int offset) {
ystart += 1;
width -= 2;
height -= 2;
-
+
if (_shadowFillMode == kShadowExponential)
// Multiply with expfactor
alpha = (alpha * (expFactor << 8)) >> 9;
@@ -2178,14 +2178,14 @@ drawBorderRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color,
// only when the inside isn't filled
if (sw != strokeWidth || fill_m != Base::kFillDisabled)
a2 = 255;
-
- // inner arc
- WU_DRAWCIRCLE_BCOLOR_TR_CW(ptr_tr, (x - 1), y, (px - pitch), py, (uint8)((uint32)(((alpha_t - (alphaStep_tr * y)) << 8) * a2) >> 16));
+
+ // inner arc
+ WU_DRAWCIRCLE_BCOLOR_TR_CW(ptr_tr, (x - 1), y, (px - pitch), py, (uint8)((uint32)(((alpha_t - (alphaStep_tr * y)) << 8) * a2) >> 16));
WU_DRAWCIRCLE_BCOLOR_BR_CW(ptr_br, (x - 1), y, (px - pitch), py, (uint8)((uint32)(((alpha_r - (alphaStep_br * y)) << 8) * a2) >> 16));
WU_DRAWCIRCLE_BCOLOR_BL_CW(ptr_bl, (x - 1), y, (px - pitch), py, (uint8)((uint32)(((alpha_b - (alphaStep_bl * y)) << 8) * a2) >> 16));
WU_DRAWCIRCLE_BCOLOR_TL_CW(ptr_tl, (x - 1), y, (px - pitch), py, (uint8)((uint32)(((alpha_l - (alphaStep_tl * y)) << 8) * a2) >> 16));
-
- WU_DRAWCIRCLE_BCOLOR_TR_CCW(ptr_tr, (x - 1), y, (px - pitch), py, (uint8)((uint32)(((alpha_r + (alphaStep_tr * y)) << 8) * a2) >> 16));
+
+ WU_DRAWCIRCLE_BCOLOR_TR_CCW(ptr_tr, (x - 1), y, (px - pitch), py, (uint8)((uint32)(((alpha_r + (alphaStep_tr * y)) << 8) * a2) >> 16));
WU_DRAWCIRCLE_BCOLOR_BR_CCW(ptr_br, (x - 1), y, (px - pitch), py, (uint8)((uint32)(((alpha_b + (alphaStep_br * y)) << 8) * a2) >> 16));
WU_DRAWCIRCLE_BCOLOR_BL_CCW(ptr_bl, (x - 1), y, (px - pitch), py, (uint8)((uint32)(((alpha_l + (alphaStep_bl * y)) << 8) * a2) >> 16));
WU_DRAWCIRCLE_BCOLOR_TL_CCW(ptr_tl, (x - 1), y, (px - pitch), py, (uint8)((uint32)(((alpha_t + (alphaStep_tl * y)) << 8) * a2) >> 16));
@@ -2196,8 +2196,8 @@ drawBorderRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color,
WU_DRAWCIRCLE_BCOLOR_BR_CW(ptr_br, x, y, px, py, (uint8)((uint32)(((alpha_r - (alphaStep_br * y)) << 8) * a1) >> 16));
WU_DRAWCIRCLE_BCOLOR_BL_CW(ptr_bl, x, y, px, py, (uint8)((uint32)(((alpha_b - (alphaStep_bl * y)) << 8) * a1) >> 16));
WU_DRAWCIRCLE_BCOLOR_TL_CW(ptr_tl, x, y, px, py, (uint8)((uint32)(((alpha_l - (alphaStep_tl * y)) << 8) * a1) >> 16));
-
- WU_DRAWCIRCLE_BCOLOR_TR_CCW(ptr_tr, x, y, px, py, (uint8)((uint32)(((alpha_r + (alphaStep_tr * y)) << 8) * a1) >> 16));
+
+ WU_DRAWCIRCLE_BCOLOR_TR_CCW(ptr_tr, x, y, px, py, (uint8)((uint32)(((alpha_r + (alphaStep_tr * y)) << 8) * a1) >> 16));
WU_DRAWCIRCLE_BCOLOR_BR_CCW(ptr_br, x, y, px, py, (uint8)((uint32)(((alpha_b + (alphaStep_br * y)) << 8) * a1) >> 16));
WU_DRAWCIRCLE_BCOLOR_BL_CCW(ptr_bl, x, y, px, py, (uint8)((uint32)(((alpha_l + (alphaStep_bl * y)) << 8) * a1) >> 16));
WU_DRAWCIRCLE_BCOLOR_TL_CCW(ptr_tl, x, y, px, py, (uint8)((uint32)(((alpha_t + (alphaStep_tl * y)) << 8) * a1) >> 16));
@@ -2220,7 +2220,7 @@ drawInteriorRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType colo
int x, y;
const int pitch = Base::_activeSurface->pitch / Base::_activeSurface->format.bytesPerPixel;
int px, py;
-
+
uint32 rsq = r*r;
frac_t T = 0, oldT;
uint8 a1, a2;
@@ -2318,14 +2318,14 @@ void VectorRendererAA<PixelType>::
drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m) {
const uint8 borderAlpha_t = 0;
const uint8 borderAlpha_r = 127;
- const uint8 borderAlpha_b = 255;
+ const uint8 borderAlpha_b = 255;
const uint8 borderAlpha_l = 63;
const uint8 bevelAlpha_t = 255;
const uint8 bevelAlpha_r = 31;
const uint8 bevelAlpha_b = 0;
const uint8 bevelAlpha_l = 127;
-
+
if (Base::_strokeWidth) {
if (r != 0 && Base::_bevel > 0) {
drawBorderRoundedSquareAlg(x1, y1, r, w, h, color, fill_m, borderAlpha_t, borderAlpha_r, borderAlpha_b, borderAlpha_l);
@@ -2334,7 +2334,7 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, Vecto
drawBorderRoundedSquareAlg(x1, y1, r, w, h, color, fill_m, 255, 255, 255, 255);
}
}
-
+
// If only border is visible
if ((!(w <= 0 || h <= 0)) && (fill_m != Base::kFillDisabled)) {
if (fill_m == Base::kFillBackground)
diff --git a/graphics/VectorRendererSpec.h b/graphics/VectorRendererSpec.h
index c035ca0e19..f47cc3997a 100644
--- a/graphics/VectorRendererSpec.h
+++ b/graphics/VectorRendererSpec.h
@@ -301,7 +301,7 @@ protected:
virtual void drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m);
virtual void drawBorderRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m, uint8 alpha_t, uint8 alpha_l, uint8 alpha_r, uint8 alpha_b);
-
+
virtual void drawInteriorRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m);
virtual void drawRoundedSquareShadow(int x, int y, int r, int w, int h, int offset) {
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/graphics/surface.h b/graphics/surface.h
index ad15944361..aaa386b168 100644
--- a/graphics/surface.h
+++ b/graphics/surface.h
@@ -228,7 +228,7 @@ public:
* @param srcSurface The source of the bitmap data
* @param destX The x coordinate of the destination rectangle
* @param destY The y coordinate of the destination rectangle
- * @param subRect The subRect of surface to be blitted
+ * @param subRect The subRect of surface to be blitted
*/
void copyRectToSurface(const Graphics::Surface &srcSurface, int destX, int destY, const Common::Rect subRect);
diff --git a/graphics/transform_struct.h b/graphics/transform_struct.h
index 640daf9f4c..1d37492de4 100644
--- a/graphics/transform_struct.h
+++ b/graphics/transform_struct.h
@@ -48,7 +48,7 @@ const int32 kDefaultHotspotX = 0;
const int32 kDefaultHotspotY = 0;
const int32 kDefaultOffsetX = 0;
const int32 kDefaultOffsetY = 0;
-const int32 kDefaultAngle = 0;
+const int32 kDefaultAngle = 0;
struct TransformStruct {
private:
diff --git a/graphics/transform_tools.h b/graphics/transform_tools.h
index a51c8ee229..ec739f9ad0 100644
--- a/graphics/transform_tools.h
+++ b/graphics/transform_tools.h
@@ -28,7 +28,7 @@
namespace Graphics {
- static const float kEpsilon = 0.00001; // arbitrarily taken number
+ static const float kEpsilon = 0.00001f; // arbitrarily taken number
struct FloatPoint {
float x;
diff --git a/gui/EventRecorder.cpp b/gui/EventRecorder.cpp
index ab284aaa6e..d0371f5e78 100644
--- a/gui/EventRecorder.cpp
+++ b/gui/EventRecorder.cpp
@@ -49,7 +49,6 @@ namespace GUI {
const int kMaxRecordsNames = 0x64;
const int kDefaultScreenshotPeriod = 60000;
-const int kDefaultBPP = 2;
uint32 readTime(Common::ReadStream *inFile) {
uint32 d = inFile->readByte();
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 fe726df750..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.",
@@ -241,7 +241,7 @@ void AboutDialog::drawDialog() {
while (*str && *str == ' ')
str++;
- if (*str)
+ if (*str)
g_gui.theme()->drawText(Common::Rect(_x + _xOff, y, _x + _w - _xOff, y + g_gui.theme()->getFontHeight()), str, state, align, ThemeEngine::kTextInversionNone, 0, false, ThemeEngine::kFontStyleBold, ThemeEngine::kFontColorNormal, true, _textDrawableArea);
y += _lineHeight;
}
diff --git a/gui/browser_osx.mm b/gui/browser_osx.mm
index 0e80410032..18cbd134f3 100644
--- a/gui/browser_osx.mm
+++ b/gui/browser_osx.mm
@@ -154,7 +154,11 @@ int BrowserDialog::runModal() {
[showHiddenFilesButton setAction:@selector(showHiddenFiles:)];
}
+#if MAC_OS_X_VERSION_MAX_ALLOWED <= 1090
if ([panel runModal] == NSOKButton) {
+#else
+ if ([panel runModal] == NSModalResponseOK) {
+#endif
NSURL *url = [panel URL];
if ([url isFileURL]) {
const char *filename = [[url path] UTF8String];
diff --git a/gui/credits.h b/gui/credits.h
index e32a0705bf..12e75b01fc 100644
--- a/gui/credits.h
+++ b/gui/credits.h
@@ -320,9 +320,12 @@ static const char *credits[] = {
"C1""Wintermute",
"A0""Einar Johan T. Somaaen",
"C0""Einar Johan T. S\370m\345en",
+"C0""Tobia Tesan",
"",
"C1""ZVision",
"C0""Adrian Astley",
+"C0""Filippos Karapetis",
+"C0""Anton Yarcev",
"",
"",
"C1""Backend Teams",
@@ -629,6 +632,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",
@@ -679,6 +694,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",
@@ -810,7 +827,7 @@ static const char *credits[] = {
"C0""DOSBox Team",
"C2""For their awesome OPL2 and OPL3 emulator",
"C0""Yusuke Kamiyamane",
-"C2""For contributing some GUI icons ",
+"C2""For contributing some GUI icons",
"C0""Till Kresslein",
"C2""For design of modern ScummVM GUI",
"C0""Jezar",
@@ -850,7 +867,7 @@ static const char *credits[] = {
"C0""",
"C0""Neil Dodwell and David Dew from Creative Reality for providing the source of Dreamweb and for their tremendous support.",
"C0""",
-"C0""Janusz Wisniewski and Miroslaw Liminowicz from Laboratorium Komputerowe Avalon for providing full source code for Soltys and letting us redistribute the game.",
+"C0""Janusz Wisniewski and Miroslaw Liminowicz from Laboratorium Komputerowe Avalon for providing full source code for Soltys and Sfinx and letting us redistribute the games.",
"C0""",
"C0""Jan Nedoma for providing the sources to the Wintermute-engine, and for his support while porting the engine to ScummVM.",
"C0""",
diff --git a/gui/debugger.cpp b/gui/debugger.cpp
index dcdc18d7b9..466681e89d 100644
--- a/gui/debugger.cpp
+++ b/gui/debugger.cpp
@@ -27,6 +27,13 @@
#include "common/debug-channels.h"
#include "common/system.h"
+#ifndef DISABLE_MD5
+#include "common/md5.h"
+#include "common/archive.h"
+#include "common/macresman.h"
+#include "common/stream.h"
+#endif
+
#include "engines/engine.h"
#include "gui/debugger.h"
@@ -61,6 +68,10 @@ Debugger::Debugger() {
registerCmd("help", WRAP_METHOD(Debugger, cmdHelp));
registerCmd("openlog", WRAP_METHOD(Debugger, cmdOpenLog));
+#ifndef DISABLE_MD5
+ registerCmd("md5", WRAP_METHOD(Debugger, cmdMd5));
+ registerCmd("md5mac", WRAP_METHOD(Debugger, cmdMd5Mac));
+#endif
registerCmd("debuglevel", WRAP_METHOD(Debugger, cmdDebugLevel));
registerCmd("debugflag_list", WRAP_METHOD(Debugger, cmdDebugFlagsList));
@@ -502,6 +513,104 @@ bool Debugger::cmdOpenLog(int argc, const char **argv) {
return true;
}
+#ifndef DISABLE_MD5
+struct ArchiveMemberLess {
+ bool operator()(const Common::ArchiveMemberPtr &x, const Common::ArchiveMemberPtr &y) const {
+ return (*x).getDisplayName().compareToIgnoreCase((*y).getDisplayName()) < 0;
+ }
+};
+
+bool Debugger::cmdMd5(int argc, const char **argv) {
+ if (argc < 2) {
+ 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 + paramOffset];
+ for (int i = 2 + paramOffset; i < argc; i++) {
+ filename = filename + " " + argv[i];
+ }
+ Common::ArchiveMemberList list;
+ SearchMan.listMatchingMembers(list, filename);
+ if (list.empty()) {
+ debugPrintf("File '%s' not found\n", filename.c_str());
+ } else {
+ sort(list.begin(), list.end(), ArchiveMemberLess());
+ for (Common::ArchiveMemberList::iterator iter = list.begin(); iter != list.end(); ++iter) {
+ 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;
+ }
+ }
+ }
+ return true;
+}
+
+bool Debugger::cmdMd5Mac(int argc, const char **argv) {
+ if (argc < 2) {
+ 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 + paramOffset];
+ for (int i = 2 + paramOffset; i < argc; i++) {
+ filename = filename + " " + argv[i];
+ }
+ Common::MacResManager macResMan;
+ // FIXME: There currently isn't any way to tell the Mac resource
+ // manager to open a specific file. Instead, it takes a "base name"
+ // and constructs a file name out of that. While usually a desirable
+ // thing, it's not ideal here.
+ if (!macResMan.open(filename)) {
+ debugPrintf("Resource file '%s' not found\n", filename.c_str());
+ } else {
+ if (!macResMan.hasResFork() && !macResMan.hasDataFork()) {
+ debugPrintf("'%s' has neither data not resource fork\n", macResMan.getBaseFileName().c_str());
+ } else {
+ // The resource fork is probably the most relevant one.
+ if (macResMan.hasResFork()) {
+ 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::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();
+ }
+ }
+ return true;
+}
+#endif
bool Debugger::cmdDebugLevel(int argc, const char **argv) {
if (argc == 1) { // print level
diff --git a/gui/debugger.h b/gui/debugger.h
index 175eb33960..ef6f900974 100644
--- a/gui/debugger.h
+++ b/gui/debugger.h
@@ -213,6 +213,10 @@ protected:
bool cmdExit(int argc, const char **argv);
bool cmdHelp(int argc, const char **argv);
bool cmdOpenLog(int argc, const char **argv);
+#ifndef DISABLE_MD5
+ bool cmdMd5(int argc, const char **argv);
+ bool cmdMd5Mac(int argc, const char **argv);
+#endif
bool cmdDebugLevel(int argc, const char **argv);
bool cmdDebugFlagsList(int argc, const char **argv);
bool cmdDebugFlagEnable(int argc, const char **argv);
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/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/scummmodern.zip b/gui/themes/scummmodern.zip
index e40e8b1e26..c7c585654d 100644
--- a/gui/themes/scummmodern.zip
+++ b/gui/themes/scummmodern.zip
Binary files differ
diff --git a/gui/themes/scummmodern/scummmodern_layout.stx b/gui/themes/scummmodern/scummmodern_layout.stx
index b760e15919..7e61d6820e 100644
--- a/gui/themes/scummmodern/scummmodern_layout.stx
+++ b/gui/themes/scummmodern/scummmodern_layout.stx
@@ -1169,9 +1169,9 @@
height = 'Globals.Line.Height'
/>
<widget name = 'HelpText'
- height = '220'
+ height = '228'
/>
- <layout type = 'horizontal' padding = '0, 0, 16, 0'>
+ <layout type = 'horizontal' padding = '0, 0, 8, 0'>
<widget name = 'Prev'
type = 'Button'
/>
diff --git a/gui/themes/translations.dat b/gui/themes/translations.dat
index abd745bb2b..bfa33d4feb 100644
--- a/gui/themes/translations.dat
+++ b/gui/themes/translations.dat
Binary files differ
diff --git a/gui/widgets/edittext.cpp b/gui/widgets/edittext.cpp
index 3e72350c99..550b1bd153 100644
--- a/gui/widgets/edittext.cpp
+++ b/gui/widgets/edittext.cpp
@@ -94,7 +94,7 @@ void EditTextWidget::drawWidget() {
// Draw the text
adjustOffset();
-
+
const Common::Rect &r = Common::Rect(_x + 2 + _leftPadding, _y + 2, _x + _leftPadding + getEditRect().width() + 8, _y + _h);
setTextDrawableArea(r);
diff --git a/gui/widgets/tab.h b/gui/widgets/tab.h
index a01ee2d9dc..148f164fbb 100644
--- a/gui/widgets/tab.h
+++ b/gui/widgets/tab.h
@@ -28,7 +28,7 @@
#include "common/array.h"
namespace GUI {
-
+
enum {
kTabForwards = 1,
kTabBackwards = -1
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..32f6be2cd5 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,9 +429,12 @@ 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];
+ 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);
}
}
@@ -166,7 +478,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 +518,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 +530,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..dc8172ea0f 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 {
@@ -72,14 +73,31 @@ 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 *_rgbLookup;
+ 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/mjpeg.cpp b/image/codecs/mjpeg.cpp
index 4ad72f259d..6e7faf1045 100644
--- a/image/codecs/mjpeg.cpp
+++ b/image/codecs/mjpeg.cpp
@@ -87,9 +87,11 @@ static const byte s_mjpegValDC[12] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
};
+#if 0
static const byte s_mjpegBitsDCChrominance[17] = {
/* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0
};
+#endif
static const byte s_mjpegBitsACLuminance[17] = {
/* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
diff --git a/image/codecs/mpeg.h b/image/codecs/mpeg.h
index 6cb10f21ac..82c3ad19ac 100644
--- a/image/codecs/mpeg.h
+++ b/image/codecs/mpeg.h
@@ -62,7 +62,7 @@ namespace Graphics {
struct Surface;
}
-namespace Image {
+namespace Image {
/**
* MPEG 1/2 video decoder.
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/image/iff.cpp b/image/iff.cpp
index d93e9ff878..d75fffb31f 100644
--- a/image/iff.cpp
+++ b/image/iff.cpp
@@ -31,7 +31,7 @@ namespace Image {
IFFDecoder::IFFDecoder() {
_surface = 0;
_palette = 0;
-
+
// these 2 properties are not reset by destroy(), so the default is set here.
_numRelevantPlanes = 8;
_pixelPacking = false;
diff --git a/image/image_decoder.h b/image/image_decoder.h
index 4d3512e0f6..2018cebd37 100644
--- a/image/image_decoder.h
+++ b/image/image_decoder.h
@@ -48,7 +48,7 @@ public:
/**
* Load an image from the specified stream
- *
+ *
* loadStream() should implicitly call destroy() to free the memory
* of the last loadStream() call.
*
diff --git a/po/be_BY.po b/po/be_BY.po
index 868ade94fb..1403a8a052 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.
#
diff --git a/po/ca_ES.po b/po/ca_ES.po
index 86f8bbed86..12a86b5db7 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.
#
diff --git a/po/cs_CZ.po b/po/cs_CZ.po
index 0b5a3c88bf..4832a1f107 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.
#
diff --git a/po/da_DA.po b/po/da_DA.po
index 480e2005d0..554694f66d 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.
#
diff --git a/po/de_DE.po b/po/de_DE.po
index c127f109bf..d757050d6e 100644
--- a/po/de_DE.po
+++ b/po/de_DE.po
@@ -1,5 +1,5 @@
# 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.
#
diff --git a/po/es_ES.po b/po/es_ES.po
index 479747bb20..9f070de306 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.
#
diff --git a/po/eu.po b/po/eu.po
index 7babff50b6..41318f72b6 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.
#
diff --git a/po/fi_FI.po b/po/fi_FI.po
index 1958be3139..e00799e1d6 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.
#
diff --git a/po/fr_FR.po b/po/fr_FR.po
index 6e47183fe3..4e2654e706 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.
#
diff --git a/po/gl_ES.po b/po/gl_ES.po
index cc8569d2f1..971e6be4b8 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.
#
diff --git a/po/hu_HU.po b/po/hu_HU.po
index ef3507be98..614fe401fc 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.
#
diff --git a/po/it_IT.po b/po/it_IT.po
index a0192b29bb..3db0122682 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.
#
diff --git a/po/nb_NO.po b/po/nb_NO.po
index cf211a46a4..fe04c50aca 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.
#
diff --git a/po/nl_NL.po b/po/nl_NL.po
index 43ac274ac5..48527ebe9c 100644
--- a/po/nl_NL.po
+++ b/po/nl_NL.po
@@ -1,21 +1,21 @@
# 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 <EMAIL@ADDRESS>, YEAR.
+# FIRST AUTHOR scummvm@bencastricum.nl, 2014.
#
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"
-"PO-Revision-Date: 2014-09-03 07:42+0100\n"
+"POT-Creation-Date: 2014-11-25 20:41+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"
"Language: Nederlands\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=iso-8859-1\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 1.5.3\n"
+"X-Generator: Poedit 1.6.10\n"
"X-Poedit-SourceCharset: iso-8859-1\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -34,11 +34,11 @@ msgstr "Beschikbare engines:"
#: gui/browser.cpp:68
msgid "Show hidden files"
-msgstr "Verborgen bestanden weergeven"
+msgstr "Toon verborgen bestanden"
#: gui/browser.cpp:68
msgid "Show files marked with the hidden attribute"
-msgstr "Toon de bestanden die met het verborgen kenmerk hebben."
+msgstr "Toon bestanden die het verborgen kenmerk hebben."
#: gui/browser.cpp:72
msgid "Go up"
@@ -108,7 +108,7 @@ msgstr "Koppel"
#: 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/groovie/script.cpp:408 engines/parallaction/saveload.cpp:274
#: engines/scumm/dialogs.cpp:193 engines/scumm/scumm.cpp:1825
#: engines/scumm/players/player_v3m.cpp:130
#: engines/scumm/players/player_v5m.cpp:108 engines/sky/compact.cpp:131
@@ -214,7 +214,7 @@ msgstr "Engine"
#: gui/launcher.cpp:245 gui/options.cpp:1073 gui/options.cpp:1090
msgid "Graphics"
-msgstr "Grafisch"
+msgstr "Beeld"
#: gui/launcher.cpp:245 gui/options.cpp:1073 gui/options.cpp:1090
msgid "GFX"
@@ -231,7 +231,7 @@ msgstr "Negeer algemene grafische instellingen"
#: gui/launcher.cpp:257 gui/options.cpp:1096
msgid "Audio"
-msgstr "Audio"
+msgstr "Geluid"
#: gui/launcher.cpp:260
msgid "Override global audio settings"
@@ -319,7 +319,7 @@ msgstr "Extra Pad:"
#: gui/launcher.cpp:339 gui/options.cpp:1134
msgid "Save Path:"
-msgstr "Save Pad:"
+msgstr "Bewaar Pad:"
#: gui/launcher.cpp:339 gui/launcher.cpp:341 gui/launcher.cpp:342
#: gui/options.cpp:1134 gui/options.cpp:1136 gui/options.cpp:1137
@@ -329,7 +329,7 @@ msgstr "Bepaalt waar opgeslagen spellen worden bewaard."
#: gui/launcher.cpp:341 gui/options.cpp:1136
msgctxt "lowres"
msgid "Save Path:"
-msgstr "Save Pad:"
+msgstr "Bewaar Pad:"
#: gui/launcher.cpp:360 gui/launcher.cpp:459 gui/launcher.cpp:517
#: gui/launcher.cpp:571 gui/options.cpp:1145 gui/options.cpp:1153
@@ -604,8 +604,7 @@ msgstr "Geen"
#: gui/options.cpp:389
msgid "Failed to apply some of the graphic options changes:"
-msgstr ""
-"Het is niet gelukt om enkele veranderingen in grafische opties toe te passen:"
+msgstr "Sommige grafische opties konden niet worden toegepast:"
#: gui/options.cpp:401
msgid "the video mode could not be changed."
@@ -781,7 +780,7 @@ msgstr "Geen Roland MT-32 muziek gebruiken"
#: gui/options.cpp:927
msgid "Text and Speech:"
-msgstr "Spraak en/of ondertitels:"
+msgstr "Spraak en/of tekst:"
#: gui/options.cpp:931 gui/options.cpp:941
msgid "Speech"
@@ -789,7 +788,7 @@ msgstr "Spraak"
#: gui/options.cpp:932 gui/options.cpp:942
msgid "Subtitles"
-msgstr "Ondertitels"
+msgstr "Tekst"
#: gui/options.cpp:933
msgid "Both"
@@ -797,7 +796,7 @@ msgstr "Beide"
#: gui/options.cpp:935
msgid "Subtitle speed:"
-msgstr "Snelheid ondertitels:"
+msgstr "Snelheid tekst:"
#: gui/options.cpp:937
msgctxt "lowres"
@@ -819,7 +818,7 @@ msgstr "Beide"
#: gui/options.cpp:943
msgid "Show subtitles and play speech"
-msgstr "Toon ondertitels en speel spraak af"
+msgstr "Toon tekst en speel spraak af"
#: gui/options.cpp:945
msgctxt "lowres"
@@ -1277,17 +1276,17 @@ msgstr "O~v~er"
#: engines/dialogs.cpp:105 engines/dialogs.cpp:181
msgid "~R~eturn to Launcher"
-msgstr "~T~erug naar het startmenu"
+msgstr "Terug naar s~t~artmenu"
#: engines/dialogs.cpp:107 engines/dialogs.cpp:183
msgctxt "lowres"
msgid "~R~eturn to Launcher"
-msgstr "~T~erug naar startmenu"
+msgstr "S~t~artmenu"
#: 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 "Spel opslaan:"
@@ -1300,7 +1299,7 @@ msgstr "Spel opslaan:"
#: 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 "Opslaan"
@@ -1540,7 +1539,7 @@ msgstr "~I~ndy vecht besturing"
#: backends/platform/ds/arm9/source/dsoptions.cpp:65
msgid "Show mouse cursor"
-msgstr "Toon muis wijzer"
+msgstr "Toon muiswijzer"
#: backends/platform/ds/arm9/source/dsoptions.cpp:66
msgid "Snap to edges"
@@ -1769,7 +1768,7 @@ msgstr "Video"
#: backends/platform/wii/options.cpp:54
msgid "Current video mode:"
-msgstr "Huidige video modus:"
+msgstr "Huidige videomodus:"
#: backends/platform/wii/options.cpp:56
msgid "Double-strike"
@@ -2113,13 +2112,13 @@ 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 "Laad opgeslagen 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 "Laad"
@@ -2161,14 +2160,13 @@ msgstr ""
msgid "Cutscene file '%s' not found!"
msgstr "Cutscene bestand '%s' niet gevonden!"
-#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:81
-#, fuzzy
+#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:91
msgid "Color Blind Mode"
-msgstr "Klik Modus"
+msgstr "Kleurenblind Modus"
-#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:82
+#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:92
msgid "Enable Color Blind Mode by default"
-msgstr ""
+msgstr "Schakel Kleurenblind modus standaard in"
#: engines/drascula/saveload.cpp:47
msgid ""
@@ -2218,17 +2216,17 @@ msgstr "Film snel afspelen"
msgid "Play movies at an increased speed"
msgstr "Speel films sneller af"
-#: engines/groovie/script.cpp:399
+#: engines/groovie/script.cpp:408
msgid "Failed to save game"
msgstr "Opslaan van spel mislukt."
#: engines/hopkins/detection.cpp:76 engines/hopkins/detection.cpp:86
msgid "Gore Mode"
-msgstr ""
+msgstr "Gore Modus"
#: engines/hopkins/detection.cpp:77 engines/hopkins/detection.cpp:87
msgid "Enable Gore Mode when available"
-msgstr ""
+msgstr "Gore modus inschakelen waar mogelijk"
#. I18N: Studio audience adds an applause and cheering sounds whenever
#. Malcolm makes a joke.
@@ -2359,6 +2357,12 @@ msgid ""
"Do you wish to use this save game file with ScummVM?\n"
"\n"
msgstr ""
+"Het volgende originele opgeslagen spel was gevonden in uw spel pad:\n"
+"\n"
+"%s %s\n"
+"\n"
+"Wilt u dit opgeslagen spel gebruiken in ScummVM?\n"
+"\n"
#: engines/kyra/saveload_eob.cpp:590
#, c-format
@@ -2366,6 +2370,8 @@ msgid ""
"A save game file was found in the specified slot %d. Overwrite?\n"
"\n"
msgstr ""
+"Er is al een opgeslagen spel in slot %d. Deze overschrijven?\n"
+"\n"
#: engines/kyra/saveload_eob.cpp:623
#, c-format
@@ -2377,6 +2383,12 @@ msgid ""
"'import_savefile'.\n"
"\n"
msgstr ""
+"%d origneel opgeslagen spellen zijn succesvol geimporteerd in ScummVM.\n"
+"Als u later handmatig origineel opgeslagen spellen wilt importeren dan zult "
+"u de\n"
+"ScummVM debug console moeten openen en het commando 'import_savefile' "
+"gebruiken.\n"
+"\n"
#. I18N: Option for fast scene switching
#: engines/mohawk/dialogs.cpp:92 engines/mohawk/dialogs.cpp:167
@@ -2433,7 +2445,7 @@ msgstr ""
#: engines/parallaction/saveload.cpp:204
msgid "Loading game..."
-msgstr "Laden spel..."
+msgstr "Spel laden..."
#: engines/parallaction/saveload.cpp:219
msgid "Saving game..."
@@ -2510,12 +2522,12 @@ msgstr "Toon/Verberg Pauze-Menu"
#: engines/queen/detection.cpp:56
msgid "Alternative intro"
-msgstr ""
+msgstr "Alternatieve intro"
#: engines/queen/detection.cpp:57
-#, fuzzy
msgid "Use an alternative game intro (CD version only)"
-msgstr "Gebruik de floppy versie van de intro (alleen voor de CD versie)"
+msgstr ""
+"Gebruik een alternatieve versie van de intro (alleen voor de CD versie)"
#: engines/sci/detection.cpp:374
msgid "EGA undithering"
@@ -2598,12 +2610,12 @@ msgstr "Spel is gepauzeerd. Druk op de spatiebalk om verder te gaan."
#. "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 "Weet u zeker dat u opnieuw wilt beginnen? (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 "Weet u zeker dat u wilt stoppen? (J/N)J"
#: engines/scumm/dialogs.cpp:190
@@ -3224,12 +3236,16 @@ msgid ""
"Could not find the 'Loom' Macintosh executable to read the\n"
"instruments from. Music will be disabled."
msgstr ""
+"De 'Loom' Macintosh executable is niet gevonden om de instrumenten van te "
+"laden. Muziek wordt uitgeschakeld."
#: 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 ""
+"De 'Monkey Island' Macintosh executable is niet gevonden om de instrumenten "
+"van te laden. Muziek wordt uitgeschakeld."
#: engines/sky/compact.cpp:130
msgid ""
@@ -3312,7 +3328,7 @@ msgstr "Houd de nieuwe"
#: engines/sword1/logic.cpp:1633
msgid "This is the end of the Broken Sword 1 Demo"
-msgstr "Dit is het einde van de Broken Sword 1 Demo"
+msgstr "Dit is het einde van de Broken Sword 1 demo."
#: engines/sword2/animation.cpp:425
msgid ""
@@ -3346,8 +3362,8 @@ msgstr ""
#: engines/wintermute/detection.cpp:58
msgid "Show FPS-counter"
-msgstr ""
+msgstr "Toon FPS-teller"
#: engines/wintermute/detection.cpp:59
msgid "Show the current number of frames per second in the upper left corner"
-msgstr ""
+msgstr "Toon de huidige Frames Per Second teller in de linkerbovenhoek"
diff --git a/po/nn_NO.po b/po/nn_NO.po
index de5698e61d..13a19fe8d3 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.
#
diff --git a/po/pl_PL.po b/po/pl_PL.po
index 83df595da5..87163748cd 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.
#
diff --git a/po/pt_BR.po b/po/pt_BR.po
index 71161bde14..aa517ef1ed 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.
#
diff --git a/po/ru_RU.po b/po/ru_RU.po
index 89ee15e7ce..adc5fcdc1d 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
#
diff --git a/po/scummvm.pot b/po/scummvm.pot
index 72600ff994..3c780ac0bd 100644
--- a/po/scummvm.pot
+++ b/po/scummvm.pot
@@ -1,5 +1,5 @@
# LANGUAGE translation for ScummVM.
-# Copyright (C) YEAR ScummVM Team
+# Copyright (C) YEAR The ScummVM Team
# This file is distributed under the same license as the ScummVM package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
diff --git a/po/se_SE.po b/po/se_SE.po
index d08f6962c9..5e746a3fd7 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.
#
diff --git a/po/uk_UA.po b/po/uk_UA.po
index 5a7554189e..865bb48db8 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
diff --git a/ports.mk b/ports.mk
index 97b43fe92e..398a0c4b5a 100644
--- a/ports.mk
+++ b/ports.mk
@@ -12,6 +12,8 @@ install:
$(INSTALL) -c -m 644 "$(srcdir)/dists/scummvm.6" "$(DESTDIR)$(mandir)/man6/scummvm.6"
$(INSTALL) -d "$(DESTDIR)$(datarootdir)/pixmaps/"
$(INSTALL) -c -m 644 "$(srcdir)/icons/scummvm.xpm" "$(DESTDIR)$(datarootdir)/pixmaps/scummvm.xpm"
+ $(INSTALL) -d "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/apps/"
+ $(INSTALL) -c -m 644 "$(srcdir)/icons/scummvm.svg" "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/apps/scummvm.svg"
$(INSTALL) -d "$(DESTDIR)$(docdir)"
$(INSTALL) -c -m 644 $(DIST_FILES_DOCS) "$(DESTDIR)$(docdir)"
$(INSTALL) -d "$(DESTDIR)$(datadir)"
@@ -28,6 +30,8 @@ install-strip:
$(INSTALL) -c -m 644 "$(srcdir)/dists/scummvm.6" "$(DESTDIR)$(mandir)/man6/scummvm.6"
$(INSTALL) -d "$(DESTDIR)$(datarootdir)/pixmaps/"
$(INSTALL) -c -m 644 "$(srcdir)/icons/scummvm.xpm" "$(DESTDIR)$(datarootdir)/pixmaps/scummvm.xpm"
+ $(INSTALL) -d "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/apps/"
+ $(INSTALL) -c -m 644 "$(srcdir)/icons/scummvm.svg" "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/apps/scummvm.svg"
$(INSTALL) -d "$(DESTDIR)$(docdir)"
$(INSTALL) -c -m 644 $(DIST_FILES_DOCS) "$(DESTDIR)$(docdir)"
$(INSTALL) -d "$(DESTDIR)$(datadir)"
@@ -41,6 +45,7 @@ uninstall:
rm -f "$(DESTDIR)$(bindir)/$(EXECUTABLE)"
rm -f "$(DESTDIR)$(mandir)/man6/scummvm.6"
rm -f "$(DESTDIR)$(datarootdir)/pixmaps/scummvm.xpm"
+ rm -f "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/apps/scummvm.svg"
rm -rf "$(DESTDIR)$(docdir)"
rm -rf "$(DESTDIR)$(datadir)"
ifdef DYNAMIC_MODULES
@@ -319,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 d9761e1c38..700975d9a2 100644
--- a/video/avi_decoder.cpp
+++ b/video/avi_decoder.cpp
@@ -149,7 +149,7 @@ bool AVIDecoder::parseNextChunk() {
skipChunk(size);
break;
case ID_IDX1:
- readOldIndex(size);
+ readOldIndex(size);
break;
default:
error("Unknown tag \'%s\' found", tag2str(tag));
@@ -319,8 +319,25 @@ bool AVIDecoder::loadStream(Common::SeekableReadStream *stream) {
return false;
}
- // Seek back to the start of the MOVI list
- _fileStream->seek(_movieListStart);
+ // Create the status entries
+ uint32 index = 0;
+ for (TrackListIterator it = getTrackListBegin(); it != getTrackListEnd(); it++, index++) {
+ TrackStatus status;
+ status.track = *it;
+ status.index = index;
+ status.chunkSearchOffset = _movieListStart;
+
+ if ((*it)->getTrackType() == Track::kTrackTypeVideo)
+ _videoTracks.push_back(status);
+ else
+ _audioTracks.push_back(status);
+ }
+
+ if (_videoTracks.size() != 1) {
+ warning("Unhandled AVI video track count: %d", _videoTracks.size());
+ close();
+ return false;
+ }
// Check if this is a special Duck Truemotion video
checkTruemotion1();
@@ -340,79 +357,138 @@ void AVIDecoder::close() {
_indexEntries.clear();
memset(&_header, 0, sizeof(_header));
+
+ _videoTracks.clear();
+ _audioTracks.clear();
}
void AVIDecoder::readNextPacket() {
- if ((uint32)_fileStream->pos() >= _movieListEnd) {
- // Ugh, reached the end premature.
- forceVideoEnd();
+ // Shouldn't get this unless called on a non-open video
+ if (_videoTracks.empty())
return;
- }
- uint32 nextTag = _fileStream->readUint32BE();
- uint32 size = _fileStream->readUint32LE();
+ // Get the video frame first
+ handleNextPacket(_videoTracks[0]);
+
+ // Handle audio tracks next
+ for (uint32 i = 0; i < _audioTracks.size(); i++)
+ handleNextPacket(_audioTracks[i]);
+}
+
+void AVIDecoder::handleNextPacket(TrackStatus &status) {
+ // If there's no more to search, bail out
+ if (status.chunkSearchOffset + 8 >= _movieListEnd) {
+ if (status.track->getTrackType() == Track::kTrackTypeVideo) {
+ // Horrible AVI video has a premature end
+ // Force the frame to be the last frame
+ debug(0, "Forcing end of AVI video");
+ ((AVIVideoTrack *)status.track)->forceTrackEnd();
+ }
- if (_fileStream->eos()) {
- // Also premature end.
- forceVideoEnd();
return;
}
- if (nextTag == ID_LIST) {
- // A list of audio/video chunks
- int32 startPos = _fileStream->pos();
+ // See if audio needs to be buffered and break out if not
+ if (status.track->getTrackType() == Track::kTrackTypeAudio && !shouldQueueAudio(status))
+ return;
- if (_fileStream->readUint32BE() != ID_REC)
- error("Expected 'rec ' LIST");
+ // Seek to where we shall start searching
+ _fileStream->seek(status.chunkSearchOffset);
+
+ for (;;) {
+ // If there's no more to search, bail out
+ if ((uint32)_fileStream->pos() + 8 >= _movieListEnd) {
+ if (status.track->getTrackType() == Track::kTrackTypeVideo) {
+ // Horrible AVI video has a premature end
+ // Force the frame to be the last frame
+ debug(0, "Forcing end of AVI video");
+ ((AVIVideoTrack *)status.track)->forceTrackEnd();
+ }
- size -= 4; // subtract list type
+ break;
+ }
- // Decode chunks in the list
- while (_fileStream->pos() < startPos + (int32)size)
- readNextPacket();
+ uint32 nextTag = _fileStream->readUint32BE();
+ uint32 size = _fileStream->readUint32LE();
- return;
- } else if (nextTag == ID_JUNK || nextTag == ID_IDX1) {
- skipChunk(size);
- return;
- }
+ if (nextTag == ID_LIST) {
+ // A list of audio/video chunks
+ if (_fileStream->readUint32BE() != ID_REC)
+ error("Expected 'rec ' LIST");
- Track *track = getTrack(getStreamIndex(nextTag));
+ continue;
+ } else if (nextTag == ID_JUNK || nextTag == ID_IDX1) {
+ skipChunk(size);
+ continue;
+ }
- if (!track)
- error("Cannot get track from tag '%s'", tag2str(nextTag));
+ // Only accept chunks for this stream
+ uint32 streamIndex = getStreamIndex(nextTag);
+ if (streamIndex != status.index) {
+ skipChunk(size);
+ continue;
+ }
- Common::SeekableReadStream *chunk = 0;
+ Common::SeekableReadStream *chunk = 0;
- if (size != 0) {
- chunk = _fileStream->readStream(size);
- _fileStream->skip(size & 1);
- }
+ if (size != 0) {
+ chunk = _fileStream->readStream(size);
+ _fileStream->skip(size & 1);
+ }
- if (track->getTrackType() == Track::kTrackTypeAudio) {
- if (getStreamType(nextTag) != kStreamTypeAudio)
- error("Invalid audio track tag '%s'", tag2str(nextTag));
+ if (status.track->getTrackType() == Track::kTrackTypeAudio) {
+ if (getStreamType(nextTag) != kStreamTypeAudio)
+ error("Invalid audio track tag '%s'", tag2str(nextTag));
- assert(chunk);
- ((AVIAudioTrack *)track)->queueSound(chunk);
- } else {
- AVIVideoTrack *videoTrack = (AVIVideoTrack *)track;
+ assert(chunk);
+ ((AVIAudioTrack *)status.track)->queueSound(chunk);
- if (getStreamType(nextTag) == kStreamTypePaletteChange) {
- // Palette Change
- videoTrack->loadPaletteFromChunk(chunk);
+ // Break out if we have enough audio
+ if (!shouldQueueAudio(status))
+ break;
} else {
- // Otherwise, assume it's a compressed frame
- videoTrack->decodeFrame(chunk);
+ AVIVideoTrack *videoTrack = (AVIVideoTrack *)status.track;
+
+ if (getStreamType(nextTag) == kStreamTypePaletteChange) {
+ // Palette Change
+ videoTrack->loadPaletteFromChunk(chunk);
+ } else {
+ // Otherwise, assume it's a compressed frame
+ videoTrack->decodeFrame(chunk);
+ break;
+ }
}
}
+
+ // Start us off in this position next time
+ status.chunkSearchOffset = _fileStream->pos();
+}
+
+bool AVIDecoder::shouldQueueAudio(TrackStatus& status) {
+ // Sanity check:
+ if (status.track->getTrackType() != Track::kTrackTypeAudio)
+ return false;
+
+ // If video is done, make sure that the rest of the audio is queued
+ // (I guess this is also really a sanity check)
+ AVIVideoTrack *videoTrack = (AVIVideoTrack *)_videoTracks[0].track;
+ if (videoTrack->endOfTrack())
+ return true;
+
+ // Being three frames ahead should be enough for any video.
+ return ((AVIAudioTrack *)status.track)->getCurChunk() < (uint32)(videoTrack->getCurFrame() + 3);
}
bool AVIDecoder::rewind() {
if (!VideoDecoder::rewind())
return false;
- _fileStream->seek(_movieListStart);
+ for (uint32 i = 0; i < _videoTracks.size(); i++)
+ _videoTracks[i].chunkSearchOffset = _movieListStart;
+
+ for (uint32 i = 0; i < _audioTracks.size(); i++)
+ _audioTracks[i].chunkSearchOffset = _movieListStart;
+
return true;
}
@@ -421,29 +497,9 @@ bool AVIDecoder::seekIntern(const Audio::Timestamp &time) {
if (time > getDuration())
return false;
- // Track down our video track.
- // We only support seeking with one video track right now.
- AVIVideoTrack *videoTrack = 0;
- int videoIndex = -1;
- uint trackID = 0;
-
- for (TrackListIterator it = getTrackListBegin(); it != getTrackListEnd(); it++, trackID++) {
- if ((*it)->getTrackType() == Track::kTrackTypeVideo) {
- if (videoTrack) {
- // Already have one
- // -> Not supported
- return false;
- }
-
- videoTrack = (AVIVideoTrack *)*it;
- videoIndex = trackID;
- }
- }
-
- // Need a video track to go forwards
- // If there isn't a video track, why would anyone be using AVI then?
- if (!videoTrack)
- return false;
+ // Get our video
+ AVIVideoTrack *videoTrack = (AVIVideoTrack *)_videoTracks[0].track;
+ uint32 videoIndex = _videoTracks[0].index;
// If we seek directly to the end, just mark the tracks as over
if (time == getDuration()) {
@@ -464,7 +520,6 @@ bool AVIDecoder::seekIntern(const Audio::Timestamp &time) {
int lastKeyFrame = -1;
int frameIndex = -1;
- int lastRecord = -1;
uint curFrame = 0;
// Go through and figure out where we should be
@@ -472,40 +527,40 @@ bool AVIDecoder::seekIntern(const Audio::Timestamp &time) {
for (uint32 i = 0; i < _indexEntries.size(); i++) {
const OldIndex &index = _indexEntries[i];
- if (index.id == ID_REC) {
- // Keep track of any records we find
- lastRecord = i;
- } else {
- if (getStreamIndex(index.id) != videoIndex)
- continue;
+ // We don't care about RECs
+ if (index.id == ID_REC)
+ continue;
- uint16 streamType = getStreamType(index.id);
+ // We're only looking at entries for this track
+ if (getStreamIndex(index.id) != videoIndex)
+ continue;
- if (streamType == kStreamTypePaletteChange) {
- // We need to handle any palette change we see since there's no
- // flag to tell if this is a "key" palette.
- // Decode the palette
- _fileStream->seek(_indexEntries[i].offset + 8);
- Common::SeekableReadStream *chunk = 0;
+ uint16 streamType = getStreamType(index.id);
- if (_indexEntries[i].size != 0)
- chunk = _fileStream->readStream(_indexEntries[i].size);
+ if (streamType == kStreamTypePaletteChange) {
+ // We need to handle any palette change we see since there's no
+ // flag to tell if this is a "key" palette.
+ // Decode the palette
+ _fileStream->seek(_indexEntries[i].offset + 8);
+ Common::SeekableReadStream *chunk = 0;
- videoTrack->loadPaletteFromChunk(chunk);
- } else {
- // Check to see if this is a keyframe
- // The first frame has to be a keyframe
- if ((_indexEntries[i].flags & AVIIF_INDEX) || curFrame == 0)
- lastKeyFrame = i;
-
- // Did we find the target frame?
- if (frame == curFrame) {
- frameIndex = i;
- break;
- }
+ if (_indexEntries[i].size != 0)
+ chunk = _fileStream->readStream(_indexEntries[i].size);
- curFrame++;
+ videoTrack->loadPaletteFromChunk(chunk);
+ } else {
+ // Check to see if this is a keyframe
+ // The first frame has to be a keyframe
+ if ((_indexEntries[i].flags & AVIIF_INDEX) || curFrame == 0)
+ lastKeyFrame = i;
+
+ // Did we find the target frame?
+ if (frame == curFrame) {
+ frameIndex = i;
+ break;
}
+
+ curFrame++;
}
}
@@ -513,57 +568,36 @@ bool AVIDecoder::seekIntern(const Audio::Timestamp &time) {
return false;
// Update all the audio tracks
- uint audioIndex = 0;
-
- for (TrackListIterator it = getTrackListBegin(); it != getTrackListEnd(); it++, audioIndex++) {
- if ((*it)->getTrackType() != Track::kTrackTypeAudio)
- continue;
-
- AVIAudioTrack *audioTrack = (AVIAudioTrack *)*it;
-
- // We need to find where the start of audio should be.
- // Which is exactly 'initialFrames' audio chunks back from where
- // our found frame is.
+ for (uint32 i = 0; i < _audioTracks.size(); i++) {
+ AVIAudioTrack *audioTrack = (AVIAudioTrack *)_audioTracks[i].track;
// Recreate the audio stream
audioTrack->resetStream();
- uint framesNeeded = _header.initialFrames;
- if (framesNeeded == 0)
- framesNeeded = 1;
+ // Set the chunk index for the track
+ audioTrack->setCurChunk(frame);
- uint startAudioChunk = 0;
- int startAudioSearch = (lastRecord < 0) ? (frameIndex - 1) : (lastRecord - 1);
+ uint32 chunksFound = 0;
+ for (uint32 j = 0; j < _indexEntries.size(); j++) {
+ const OldIndex &index = _indexEntries[j];
- for (int i = startAudioSearch; i >= 0; i--) {
- if (getStreamIndex(_indexEntries[i].id) != audioIndex)
+ // Continue ignoring RECs
+ if (index.id == ID_REC)
continue;
- assert(getStreamType(_indexEntries[i].id) == kStreamTypeAudio);
-
- framesNeeded--;
+ if (getStreamIndex(index.id) == _audioTracks[i].index) {
+ if (chunksFound == frame) {
+ _fileStream->seek(index.offset + 8);
+ Common::SeekableReadStream *audioChunk = _fileStream->readStream(index.size);
+ audioTrack->queueSound(audioChunk);
+ _audioTracks[i].chunkSearchOffset = (j == _indexEntries.size() - 1) ? _movieListEnd : _indexEntries[j + 1].offset;
+ break;
+ }
- if (framesNeeded == 0) {
- startAudioChunk = i;
- break;
+ chunksFound++;
}
}
- // Now go forward and queue them all
- for (int i = startAudioChunk; i <= startAudioSearch; i++) {
- if (_indexEntries[i].id == ID_REC)
- continue;
-
- if (getStreamIndex(_indexEntries[i].id) != audioIndex)
- continue;
-
- assert(getStreamType(_indexEntries[i].id) == kStreamTypeAudio);
-
- _fileStream->seek(_indexEntries[i].offset + 8);
- Common::SeekableReadStream *chunk = _fileStream->readStream(_indexEntries[i].size);
- audioTrack->queueSound(chunk);
- }
-
// Skip any audio to bring us to the right time
audioTrack->skipAudio(time, videoTrack->getFrameTime(frame));
}
@@ -592,15 +626,11 @@ bool AVIDecoder::seekIntern(const Audio::Timestamp &time) {
videoTrack->decodeFrame(chunk);
}
- // Seek to the right spot
- // To the beginning of the last record, or frame if that doesn't exist
- if (lastRecord >= 0)
- _fileStream->seek(_indexEntries[lastRecord].offset);
- else
- _fileStream->seek(_indexEntries[frameIndex].offset);
-
+ // Set the video track's frame
videoTrack->setCurFrame((int)frame - 1);
+ // Set the video track's search offset to the right spot
+ _videoTracks[0].chunkSearchOffset = _indexEntries[frameIndex].offset;
return true;
}
@@ -623,7 +653,7 @@ void AVIDecoder::readOldIndex(uint32 size) {
OldIndex firstEntry;
firstEntry.id = _fileStream->readUint32BE();
firstEntry.flags = _fileStream->readUint32LE();
- firstEntry.offset = _fileStream->readUint32LE();
+ firstEntry.offset = _fileStream->readUint32LE();
firstEntry.size = _fileStream->readUint32LE();
// Check if the offset is already absolute
@@ -654,45 +684,22 @@ void AVIDecoder::readOldIndex(uint32 size) {
}
}
-void AVIDecoder::forceVideoEnd() {
- // Horrible AVI video has a premature end
- // Force the frame to be the last frame
- debug(0, "Forcing end of AVI video");
-
- for (TrackListIterator it = getTrackListBegin(); it != getTrackListEnd(); it++)
- if ((*it)->getTrackType() == Track::kTrackTypeVideo)
- ((AVIVideoTrack *)*it)->forceTrackEnd();
-}
-
void AVIDecoder::checkTruemotion1() {
- AVIVideoTrack *track = 0;
+ // If we got here from loadStream(), we know the track is valid
+ assert(!_videoTracks.empty());
- for (TrackListIterator it = getTrackListBegin(); it != getTrackListEnd(); it++) {
- if ((*it)->getTrackType() == Track::kTrackTypeVideo) {
- if (track) {
- // Multiple tracks; isn't going to be truemotion 1
- return;
- }
-
- track = (AVIVideoTrack *)*it;
- }
- }
-
- // No track found?
- if (!track)
- return;
+ TrackStatus &status = _videoTracks[0];
+ AVIVideoTrack *track = (AVIVideoTrack *)status.track;
// Ignore non-truemotion tracks
if (!track->isTruemotion1())
return;
- // Search for a non-empty frame
- const Graphics::Surface *frame = 0;
- for (int i = 0; i < 10 && !frame; i++)
- frame = decodeNextFrame();
+ // Read the next video packet
+ handleNextPacket(status);
+ const Graphics::Surface *frame = track->decodeNextFrame();
if (!frame) {
- // Probably shouldn't happen
rewind();
return;
}
@@ -808,8 +815,32 @@ 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) {
+ : _audsHeader(streamHeader), _wvInfo(waveFormat), _soundType(soundType), _curChunk(0) {
_audStream = createAudioStream();
}
@@ -836,12 +867,12 @@ void AVIDecoder::AVIAudioTrack::queueSound(Common::SeekableReadStream *stream) {
_audStream->queueAudioStream(Audio::makeADPCMStream(stream, DisposeAfterUse::YES, stream->size(), Audio::kADPCMMSIma, _wvInfo.samplesPerSec, _wvInfo.channels, _wvInfo.blockAlign), DisposeAfterUse::YES);
} else if (_wvInfo.tag == kWaveFormatDK3) {
_audStream->queueAudioStream(Audio::makeADPCMStream(stream, DisposeAfterUse::YES, stream->size(), Audio::kADPCMDK3, _wvInfo.samplesPerSec, _wvInfo.channels, _wvInfo.blockAlign), DisposeAfterUse::YES);
- } else if (_wvInfo.tag == kWaveFormatMP3) {
- warning("AVI: MP3 audio stream is not supported");
}
} else {
delete stream;
}
+
+ _curChunk++;
}
void AVIDecoder::AVIAudioTrack::skipAudio(const Audio::Timestamp &time, const Audio::Timestamp &frameTime) {
@@ -862,6 +893,7 @@ void AVIDecoder::AVIAudioTrack::skipAudio(const Audio::Timestamp &time, const Au
void AVIDecoder::AVIAudioTrack::resetStream() {
delete _audStream;
_audStream = createAudioStream();
+ _curChunk = 0;
}
bool AVIDecoder::AVIAudioTrack::rewind() {
@@ -874,12 +906,17 @@ Audio::AudioStream *AVIDecoder::AVIAudioTrack::getAudioStream() const {
}
Audio::QueuingAudioStream *AVIDecoder::AVIAudioTrack::createAudioStream() {
- if (_wvInfo.tag == kWaveFormatPCM || _wvInfo.tag == kWaveFormatMSADPCM || _wvInfo.tag == kWaveFormatMSIMAADPCM || _wvInfo.tag == kWaveFormatDK3 || _wvInfo.tag == kWaveFormatMP3)
+ if (_wvInfo.tag == kWaveFormatPCM || _wvInfo.tag == kWaveFormatMSADPCM || _wvInfo.tag == kWaveFormatMSIMAADPCM || _wvInfo.tag == kWaveFormatDK3)
return Audio::makeQueuingAudioStream(_wvInfo.samplesPerSec, _wvInfo.channels == 2);
+ else if (_wvInfo.tag == kWaveFormatMP3)
+ warning("Unsupported AVI MP3 tracks");
else if (_wvInfo.tag != kWaveFormatNone) // No sound
warning("Unsupported AVI audio format %d", _wvInfo.tag);
return 0;
}
+AVIDecoder::TrackStatus::TrackStatus() : track(0), chunkSearchOffset(0) {
+}
+
} // End of namespace Video
diff --git a/video/avi_decoder.h b/video/avi_decoder.h
index 4461e537c5..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);
@@ -215,7 +218,9 @@ protected:
virtual void queueSound(Common::SeekableReadStream *stream);
Audio::Mixer::SoundType getSoundType() const { return _soundType; }
void skipAudio(const Audio::Timestamp &time, const Audio::Timestamp &frameTime);
- void resetStream();
+ virtual void resetStream();
+ uint32 getCurChunk() const { return _curChunk; }
+ void setCurChunk(uint32 chunk) { _curChunk = chunk; }
bool isRewindable() const { return true; }
bool rewind();
@@ -238,6 +243,15 @@ protected:
Audio::Mixer::SoundType _soundType;
Audio::QueuingAudioStream *_audStream;
Audio::QueuingAudioStream *createAudioStream();
+ uint32 _curChunk;
+ };
+
+ struct TrackStatus {
+ TrackStatus();
+
+ Track *track;
+ uint32 index;
+ uint32 chunkSearchOffset;
};
AVIHeader _header;
@@ -260,9 +274,12 @@ protected:
void handleStreamHeader(uint32 size);
uint16 getStreamType(uint32 tag) const { return tag & 0xFFFF; }
byte getStreamIndex(uint32 tag) const;
- void forceVideoEnd();
void checkTruemotion1();
+ void handleNextPacket(TrackStatus& status);
+ bool shouldQueueAudio(TrackStatus& status);
+ Common::Array<TrackStatus> _videoTracks, _audioTracks;
+
public:
virtual AVIAudioTrack *createAudioTrack(AVIStreamHeader sHeader, PCMWaveFormat wvInfo);
};
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;